@@ -147,17 +147,44 @@ describe('CdkOption and CdkListbox', () => {
147
147
testComponent . isMultiselectable = true ;
148
148
fixture . detectChanges ( ) ;
149
149
150
- dispatchMouseEvent ( optionEls [ 1 ] , 'click' , undefined , undefined , undefined , { shift : true } ) ;
150
+ dispatchMouseEvent (
151
+ optionEls [ 1 ] ,
152
+ 'click' ,
153
+ undefined ,
154
+ undefined ,
155
+ undefined ,
156
+ undefined ,
157
+ undefined ,
158
+ { shift : true } ,
159
+ ) ;
151
160
fixture . detectChanges ( ) ;
152
161
153
162
expect ( listbox . value ) . toEqual ( [ 'orange' ] ) ;
154
163
155
- dispatchMouseEvent ( optionEls [ 3 ] , 'click' , undefined , undefined , undefined , { shift : true } ) ;
164
+ dispatchMouseEvent (
165
+ optionEls [ 3 ] ,
166
+ 'click' ,
167
+ undefined ,
168
+ undefined ,
169
+ undefined ,
170
+ undefined ,
171
+ undefined ,
172
+ { shift : true } ,
173
+ ) ;
156
174
fixture . detectChanges ( ) ;
157
175
158
176
expect ( listbox . value ) . toEqual ( [ 'orange' , 'banana' , 'peach' ] ) ;
159
177
160
- dispatchMouseEvent ( optionEls [ 2 ] , 'click' , undefined , undefined , undefined , { shift : true } ) ;
178
+ dispatchMouseEvent (
179
+ optionEls [ 2 ] ,
180
+ 'click' ,
181
+ undefined ,
182
+ undefined ,
183
+ undefined ,
184
+ undefined ,
185
+ undefined ,
186
+ { shift : true } ,
187
+ ) ;
161
188
fixture . detectChanges ( ) ;
162
189
163
190
expect ( listbox . value ) . toEqual ( [ 'orange' ] ) ;
@@ -417,6 +444,36 @@ describe('CdkOption and CdkListbox', () => {
417
444
418
445
expect ( options [ 2 ] . isActive ( ) ) . toBeTrue ( ) ;
419
446
} ) ;
447
+
448
+ it ( 'should not skip disabled options when navigating with arrow keys when skipping is turned off' , async ( ) => {
449
+ const { testComponent, fixture, listbox, listboxEl, options} = await setupComponent (
450
+ ListboxWithOptions ,
451
+ ) ;
452
+ testComponent . navigationSkipsDisabled = false ;
453
+ testComponent . isOrangeDisabled = true ;
454
+ listbox . focus ( ) ;
455
+ fixture . detectChanges ( ) ;
456
+
457
+ expect ( options [ 0 ] . isActive ( ) ) . toBeTrue ( ) ;
458
+
459
+ dispatchKeyboardEvent ( listboxEl , 'keydown' , DOWN_ARROW ) ;
460
+ fixture . detectChanges ( ) ;
461
+
462
+ expect ( options [ 1 ] . isActive ( ) ) . toBeTrue ( ) ;
463
+ } ) ;
464
+
465
+ it ( 'should not select disabled options with CONTROL + A' , async ( ) => {
466
+ const { testComponent, fixture, listbox, listboxEl} = await setupComponent ( ListboxWithOptions ) ;
467
+ testComponent . isMultiselectable = true ;
468
+ testComponent . isOrangeDisabled = true ;
469
+ fixture . detectChanges ( ) ;
470
+
471
+ listbox . focus ( ) ;
472
+ dispatchKeyboardEvent ( listboxEl , 'keydown' , A , undefined , { control : true } ) ;
473
+ fixture . detectChanges ( ) ;
474
+
475
+ expect ( listbox . value ) . toEqual ( [ 'apple' , 'banana' , 'peach' ] ) ;
476
+ } ) ;
420
477
} ) ;
421
478
422
479
describe ( 'compare with' , ( ) => {
@@ -611,6 +668,39 @@ describe('CdkOption and CdkListbox', () => {
611
668
612
669
expect ( listbox . value ) . toEqual ( [ ] ) ;
613
670
} ) ;
671
+
672
+ it ( 'should wrap navigation when wrapping is enabled' , async ( ) => {
673
+ const { fixture, listbox, listboxEl, options} = await setupComponent ( ListboxWithOptions ) ;
674
+ listbox . focus ( ) ;
675
+ dispatchKeyboardEvent ( listboxEl , 'keydown' , END ) ;
676
+ fixture . detectChanges ( ) ;
677
+
678
+ expect ( options [ options . length - 1 ] . isActive ( ) ) . toBeTrue ( ) ;
679
+
680
+ dispatchKeyboardEvent ( listboxEl , 'keydown' , DOWN_ARROW ) ;
681
+ fixture . detectChanges ( ) ;
682
+
683
+ expect ( options [ 0 ] . isActive ( ) ) . toBeTrue ( ) ;
684
+ } ) ;
685
+
686
+ it ( 'should not wrap navigation when wrapping is not enabled' , async ( ) => {
687
+ const { testComponent, fixture, listbox, listboxEl, options} = await setupComponent (
688
+ ListboxWithOptions ,
689
+ ) ;
690
+ testComponent . navigationWraps = false ;
691
+ fixture . detectChanges ( ) ;
692
+
693
+ listbox . focus ( ) ;
694
+ dispatchKeyboardEvent ( listboxEl , 'keydown' , END ) ;
695
+ fixture . detectChanges ( ) ;
696
+
697
+ expect ( options [ options . length - 1 ] . isActive ( ) ) . toBeTrue ( ) ;
698
+
699
+ dispatchKeyboardEvent ( listboxEl , 'keydown' , DOWN_ARROW ) ;
700
+ fixture . detectChanges ( ) ;
701
+
702
+ expect ( options [ options . length - 1 ] . isActive ( ) ) . toBeTrue ( ) ;
703
+ } ) ;
614
704
} ) ;
615
705
616
706
describe ( 'with roving tabindex' , ( ) => {
@@ -818,14 +908,17 @@ describe('CdkOption and CdkListbox', () => {
818
908
[cdkListboxDisabled]="isListboxDisabled"
819
909
[cdkListboxUseActiveDescendant]="isActiveDescendant"
820
910
[cdkListboxOrientation]="orientation"
911
+ [cdkListboxKeyboardNavigationWraps]="navigationWraps"
912
+ [cdkListboxKeyboardNavigationSkipsDisabled]="navigationSkipsDisabled"
821
913
(cdkListboxValueChange)="onSelectionChange($event)">
822
914
<div cdkOption="apple"
823
- [cdkOptionDisabled]="isAppleDisabled"
824
- [id]="appleId"
825
- [tabindex]="appleTabindex">
915
+ [cdkOptionDisabled]="isAppleDisabled"
916
+ [id]="appleId"
917
+ [tabindex]="appleTabindex">
826
918
Apple
827
919
</div>
828
- <div cdkOption="orange" [cdkOptionDisabled]="isOrangeDisabled">Orange</div>
920
+ <div cdkOption="orange" [cdkOptionDisabled]="isOrangeDisabled">Orange
921
+ </div>
829
922
<div cdkOption="banana">Banana</div>
830
923
<div cdkOption="peach">Peach</div>
831
924
</div>
@@ -838,6 +931,8 @@ class ListboxWithOptions {
838
931
isOrangeDisabled = false ;
839
932
isMultiselectable = false ;
840
933
isActiveDescendant = false ;
934
+ navigationWraps = true ;
935
+ navigationSkipsDisabled = true ;
841
936
listboxId : string ;
842
937
listboxTabindex : number ;
843
938
appleId : string ;
0 commit comments