@@ -182,6 +182,292 @@ describe("Event firing", () => {
182
182
} ) ;
183
183
} ) ;
184
184
185
+ describe ( "MultiComboBox RTL/LTR Arrow Navigation" , ( ) => {
186
+ it ( "should focus last token on arrow right in RTL mode when input is at start" , ( ) => {
187
+ cy . mount (
188
+ < div dir = "rtl" >
189
+ < MultiComboBox noValidation = { true } >
190
+ < MultiComboBoxItem selected text = "Token 1" > </ MultiComboBoxItem >
191
+ < MultiComboBoxItem selected text = "Token 2" > </ MultiComboBoxItem >
192
+ < MultiComboBoxItem selected text = "Token 3" > </ MultiComboBoxItem >
193
+ < MultiComboBoxItem text = "Item 4" > </ MultiComboBoxItem >
194
+ < MultiComboBoxItem text = "Item 5" > </ MultiComboBoxItem >
195
+ </ MultiComboBox >
196
+ </ div >
197
+ ) ;
198
+
199
+ cy . get ( "[ui5-multi-combobox]" )
200
+ . as ( "mcb" )
201
+ . realClick ( ) ;
202
+ cy . get ( "@mcb" )
203
+ . should ( "be.focused" ) ;
204
+
205
+ cy . get ( "@mcb" )
206
+ . shadow ( )
207
+ . find ( "input" )
208
+ . as ( "input" )
209
+ . then ( ( $input ) => {
210
+ ( $input [ 0 ] as HTMLInputElement ) . setSelectionRange ( 0 , 0 ) ;
211
+ } )
212
+ . should ( ( $input ) => {
213
+ expect ( ( $input [ 0 ] as HTMLInputElement ) . selectionStart ) . to . equal ( 0 ) ;
214
+ } ) ;
215
+
216
+ cy . get ( "@mcb" ) . realPress ( "ArrowRight" ) ;
217
+ cy . get ( "@mcb" )
218
+ . shadow ( )
219
+ . find ( "[ui5-tokenizer]" )
220
+ . find ( "[ui5-token]" )
221
+ . last ( )
222
+ . should ( "be.visible" )
223
+ . should ( "be.focused" ) ;
224
+ } ) ;
225
+
226
+ it ( "should focus last token on arrow left in LTR mode when input is at start" , ( ) => {
227
+ cy . mount (
228
+ < div dir = "ltr" >
229
+ < MultiComboBox noValidation = { true } >
230
+ < MultiComboBoxItem selected text = "Token 1" > </ MultiComboBoxItem >
231
+ < MultiComboBoxItem selected text = "Token 2" > </ MultiComboBoxItem >
232
+ < MultiComboBoxItem selected text = "Token 3" > </ MultiComboBoxItem >
233
+ < MultiComboBoxItem text = "Item 4" > </ MultiComboBoxItem >
234
+ < MultiComboBoxItem text = "Item 5" > </ MultiComboBoxItem >
235
+ </ MultiComboBox >
236
+ </ div >
237
+ ) ;
238
+
239
+ cy . get ( "[ui5-multi-combobox]" )
240
+ . as ( "mcb" )
241
+ . realClick ( ) ;
242
+
243
+ cy . get ( "@mcb" )
244
+ . should ( "be.focused" ) ;
245
+
246
+ cy . get ( "@mcb" )
247
+ . shadow ( )
248
+ . find ( "input" )
249
+ . as ( "input" )
250
+ . realClick ( )
251
+ . should ( "have.focus" )
252
+ . then ( ( $input ) => {
253
+ ( $input [ 0 ] as HTMLInputElement ) . setSelectionRange ( 0 , 0 ) ;
254
+ } )
255
+ . should ( ( $input ) => {
256
+ expect ( ( $input [ 0 ] as HTMLInputElement ) . selectionStart ) . to . equal ( 0 ) ;
257
+ } ) ;
258
+
259
+ cy . get ( "@mcb" ) . realPress ( "ArrowLeft" ) ;
260
+
261
+ cy . get ( "@mcb" )
262
+ . shadow ( )
263
+ . find ( "[ui5-tokenizer]" )
264
+ . find ( "[ui5-token]" )
265
+ . last ( )
266
+ . should ( "be.visible" )
267
+ . should ( "be.focused" ) ;
268
+ } ) ;
269
+
270
+ it ( "should not focus token when cursor is not at start of input in RTL mode" , ( ) => {
271
+ cy . mount (
272
+ < div dir = "rtl" >
273
+ < MultiComboBox noValidation = { true } value = "test text" >
274
+ < MultiComboBoxItem selected text = "Token 1" > </ MultiComboBoxItem >
275
+ < MultiComboBoxItem selected text = "Token 2" > </ MultiComboBoxItem >
276
+ < MultiComboBoxItem text = "Item 3" > </ MultiComboBoxItem >
277
+ </ MultiComboBox >
278
+ </ div >
279
+ ) ;
280
+
281
+ cy . get ( "[ui5-multi-combobox]" )
282
+ . as ( "mcb" )
283
+ . realClick ( ) ;
284
+
285
+ cy . get ( "@mcb" ) . should ( "be.focused" ) ;
286
+
287
+
288
+ cy . get ( "@mcb" )
289
+ . shadow ( )
290
+ . find ( "input" )
291
+ . as ( "input" )
292
+ . realClick ( )
293
+ . should ( "be.focused" )
294
+ . then ( ( $input ) => {
295
+ ( $input [ 0 ] as HTMLInputElement ) . setSelectionRange ( 2 , 2 ) ;
296
+ } ) ;
297
+
298
+ cy . get ( "@mcb" ) . realPress ( "ArrowRight" ) ;
299
+
300
+ cy . get ( "@mcb" )
301
+ . shadow ( )
302
+ . find ( "input" )
303
+ . as ( "input" )
304
+ . realClick ( ) ;
305
+
306
+ cy . get ( "@input" )
307
+ . should ( "be.focused" )
308
+ . should ( ( $input ) => {
309
+ expect ( ( $input [ 0 ] as HTMLInputElement ) . selectionStart ) . to . equal ( 3 ) ;
310
+ } ) ;
311
+
312
+ cy . get ( "@mcb" )
313
+ . shadow ( )
314
+ . find ( "[ui5-tokenizer]" )
315
+ . find ( "[ui5-token]" )
316
+ . should ( "not.be.focused" ) ;
317
+ } ) ;
318
+
319
+ it ( "should not focus token when text is selected in RTL mode" , ( ) => {
320
+ cy . mount (
321
+ < div dir = "rtl" >
322
+ < MultiComboBox noValidation = { true } value = "test" >
323
+ < MultiComboBoxItem selected text = "Token 1" > </ MultiComboBoxItem >
324
+ < MultiComboBoxItem selected text = "Token 2" > </ MultiComboBoxItem >
325
+ < MultiComboBoxItem text = "Item 3" > </ MultiComboBoxItem >
326
+ </ MultiComboBox >
327
+ </ div >
328
+ ) ;
329
+
330
+ cy . get ( "[ui5-multi-combobox]" )
331
+ . as ( "mcb" )
332
+ . realClick ( ) ;
333
+
334
+ cy . get ( "@mcb" ) . should ( "be.focused" ) ;
335
+
336
+ cy . get ( "@mcb" )
337
+ . shadow ( )
338
+ . find ( "input" )
339
+ . as ( "input" )
340
+ . realClick ( )
341
+ . realPress ( [ "Control" , "a" ] ) ;
342
+
343
+ cy . get ( "@input" )
344
+ . should ( ( $input ) => {
345
+ expect ( ( $input [ 0 ] as HTMLInputElement ) . selectionStart ) . to . equal ( 0 ) ;
346
+ expect ( ( $input [ 0 ] as HTMLInputElement ) . selectionEnd ) . to . equal ( 4 ) ;
347
+ } ) ;
348
+
349
+ cy . get ( "@mcb" )
350
+ . shadow ( )
351
+ . find ( "[ui5-tokenizer]" )
352
+ . find ( "[ui5-token]" )
353
+ . should ( "not.have.focus" ) ;
354
+ } ) ;
355
+
356
+ it ( "should navigate from last token back to input with arrow left in RTL mode" , ( ) => {
357
+ cy . mount (
358
+ < div dir = "rtl" >
359
+ < MultiComboBox noValidation = { true } >
360
+ < MultiComboBoxItem selected text = "Token 1" > </ MultiComboBoxItem >
361
+ < MultiComboBoxItem selected text = "Token 2" > </ MultiComboBoxItem >
362
+ < MultiComboBoxItem selected text = "Token 3" > </ MultiComboBoxItem >
363
+ < MultiComboBoxItem text = "Item 4" > </ MultiComboBoxItem >
364
+ </ MultiComboBox >
365
+ </ div >
366
+ ) ;
367
+
368
+ cy . get ( "[ui5-multi-combobox]" )
369
+ . as ( "mcb" )
370
+ . realClick ( )
371
+
372
+ cy . get ( "@mcb" )
373
+ . should ( "be.focused" )
374
+ . realPress ( "ArrowRight" ) ;
375
+
376
+ cy . get ( "@mcb" )
377
+ . shadow ( )
378
+ . find ( "[ui5-tokenizer]" )
379
+ . find ( "[ui5-token]" )
380
+ . last ( )
381
+ . as ( "lastToken" )
382
+ . should ( "have.focus" ) ;
383
+
384
+ cy . get ( "@lastToken" )
385
+ . should ( "be.focused" )
386
+ . realPress ( "ArrowLeft" ) ;
387
+
388
+ cy . get ( "@mcb" )
389
+ . shadow ( )
390
+ . find ( "input" )
391
+ . should ( "be.focused" ) ;
392
+ } ) ;
393
+
394
+ it ( "should navigate from last token back to input with arrow right in LTR mode" , ( ) => {
395
+ cy . mount (
396
+ < div dir = "ltr" >
397
+ < MultiComboBox noValidation = { true } >
398
+ < MultiComboBoxItem selected text = "Token 1" > </ MultiComboBoxItem >
399
+ < MultiComboBoxItem selected text = "Token 2" > </ MultiComboBoxItem >
400
+ < MultiComboBoxItem selected text = "Token 3" > </ MultiComboBoxItem >
401
+ < MultiComboBoxItem text = "Item 4" > </ MultiComboBoxItem >
402
+ </ MultiComboBox >
403
+ </ div >
404
+ ) ;
405
+
406
+ cy . get ( "[ui5-multi-combobox]" )
407
+ . as ( "mcb" )
408
+ . realClick ( ) ;
409
+
410
+ cy . get ( "@mcb" )
411
+ . should ( "be.focused" )
412
+ . realPress ( "ArrowLeft" ) ;
413
+
414
+ cy . get ( "@mcb" )
415
+ . shadow ( )
416
+ . find ( "[ui5-tokenizer]" )
417
+ . find ( "[ui5-token]" )
418
+ . last ( )
419
+ . as ( "lastToken" )
420
+ . should ( "be.focused" ) ;
421
+
422
+ cy . get ( "@lastToken" ) . realPress ( "ArrowRight" ) ;
423
+
424
+ cy . get ( "@mcb" )
425
+ . shadow ( )
426
+ . find ( "input" )
427
+ . should ( "be.focused" ) ;
428
+ } ) ;
429
+
430
+ it ( "should handle empty input case in RTL mode" , ( ) => {
431
+ cy . mount (
432
+ < div dir = "rtl" >
433
+ < MultiComboBox noValidation = { true } >
434
+ < MultiComboBoxItem selected text = "Token 1" > </ MultiComboBoxItem >
435
+ < MultiComboBoxItem selected text = "Token 2" > </ MultiComboBoxItem >
436
+ < MultiComboBoxItem text = "Item 3" > </ MultiComboBoxItem >
437
+ </ MultiComboBox >
438
+ </ div >
439
+ ) ;
440
+
441
+ cy . get ( "[ui5-multi-combobox]" )
442
+ . as ( "mcb" )
443
+ . realClick ( ) ;
444
+
445
+ cy . get ( "@mcb" ) . should ( "be.focused" ) ;
446
+
447
+ cy . get ( "@mcb" )
448
+ . shadow ( )
449
+ . find ( "input" )
450
+ . as ( "input" )
451
+ . realClick ( )
452
+ . should ( "have.focus" )
453
+
454
+ cy . get ( "@input" )
455
+ . should ( "have.value" , "" )
456
+ . should ( ( $input ) => {
457
+ expect ( ( $input [ 0 ] as HTMLInputElement ) . selectionStart ) . to . equal ( 0 ) ;
458
+ } ) ;
459
+
460
+ cy . get ( "@mcb" ) . realPress ( "ArrowRight" ) ;
461
+
462
+ cy . get ( "@mcb" )
463
+ . shadow ( )
464
+ . find ( "[ui5-tokenizer]" )
465
+ . find ( "[ui5-token]" )
466
+ . last ( )
467
+ . should ( "have.focus" ) ;
468
+ } ) ;
469
+ } ) ;
470
+
185
471
describe ( "Accessibility" , ( ) => {
186
472
it ( "should announce the associated label when MultiComboBox is focused" , ( ) => {
187
473
const label = "MultiComboBox aria-label" ;
0 commit comments