@@ -47,6 +47,7 @@ import List from "./List.js";
47
47
import BusyIndicator from "./BusyIndicator.js" ;
48
48
import Button from "./Button.js" ;
49
49
import StandardListItem from "./StandardListItem.js" ;
50
+ import ComboBoxGroupItem from "./ComboBoxGroupItem.js" ;
50
51
51
52
/**
52
53
* @public
@@ -338,7 +339,7 @@ const metadata = {
338
339
* @alias sap.ui.webcomponents.main.ComboBox
339
340
* @extends UI5Element
340
341
* @tagname ui5-combobox
341
- * @appenddocs ComboBoxItem
342
+ * @appenddocs ComboBoxItem ComboBoxGroupItem
342
343
* @public
343
344
* @since 1.0.0-rc.6
344
345
*/
@@ -373,7 +374,6 @@ class ComboBox extends UI5Element {
373
374
this . _filteredItems = [ ] ;
374
375
this . _initialRendering = true ;
375
376
this . _itemFocused = false ;
376
- this . _tempFilterValue = "" ;
377
377
this . _selectionChanged = false ;
378
378
this . i18nBundle = getI18nBundle ( "@ui5/webcomponents" ) ;
379
379
}
@@ -389,6 +389,12 @@ class ComboBox extends UI5Element {
389
389
390
390
this . _selectMatchingItem ( ) ;
391
391
392
+ if ( this . _isKeyNavigation && this . responsivePopover && this . responsivePopover . opened ) {
393
+ this . focused = false ;
394
+ } else if ( this . shadowRoot . activeElement ) {
395
+ this . focused = this . shadowRoot . activeElement . id === "ui5-combobox-input" ;
396
+ }
397
+
392
398
this . _initialRendering = false ;
393
399
this . _isKeyNavigation = false ;
394
400
}
@@ -405,7 +411,6 @@ class ComboBox extends UI5Element {
405
411
}
406
412
407
413
this . _itemFocused = false ;
408
-
409
414
this . toggleValueStatePopover ( this . shouldOpenValueStateMessagePopover ) ;
410
415
this . storeResponsivePopoverWidth ( ) ;
411
416
}
@@ -437,7 +442,6 @@ class ComboBox extends UI5Element {
437
442
_afterClosePopover ( ) {
438
443
this . _iconPressed = false ;
439
444
this . _filteredItems = this . items ;
440
- this . _tempFilterValue = "" ;
441
445
442
446
// close device's keyboard and prevent further typing
443
447
if ( isPhone ( ) ) {
@@ -508,6 +512,7 @@ class ComboBox extends UI5Element {
508
512
}
509
513
510
514
this . _filteredItems = this . _filterItems ( value ) ;
515
+
511
516
this . value = value ;
512
517
this . filterValue = value ;
513
518
@@ -517,7 +522,7 @@ class ComboBox extends UI5Element {
517
522
if ( this . _autocomplete && value !== "" ) {
518
523
const item = this . _autoCompleteValue ( value ) ;
519
524
520
- if ( ! this . _selectionChanged && ( item && ! item . selected ) ) {
525
+ if ( ! this . _selectionChanged && ( item && ! item . selected && ! item . isGroupItem ) ) {
521
526
this . fireEvent ( "selection-change" , {
522
527
item,
523
528
} ) ;
@@ -553,7 +558,7 @@ class ComboBox extends UI5Element {
553
558
} ) ;
554
559
}
555
560
556
- handleArrowKeyPress ( event ) {
561
+ async handleArrowKeyPress ( event ) {
557
562
if ( this . readonly || ! this . _filteredItems . length ) {
558
563
return ;
559
564
}
@@ -575,15 +580,23 @@ class ComboBox extends UI5Element {
575
580
576
581
indexOfItem += isArrowDown ? 1 : - 1 ;
577
582
indexOfItem = indexOfItem < 0 ? 0 : indexOfItem ;
583
+ this . _filteredItems [ indexOfItem ] . focused = true ;
578
584
579
585
if ( this . responsivePopover . opened ) {
580
586
this . announceSelectedItem ( indexOfItem ) ;
581
587
}
582
588
583
- this . _filteredItems [ indexOfItem ] . focused = true ;
584
- this . _filteredItems [ indexOfItem ] . selected = true ;
589
+ this . value = this . _filteredItems [ indexOfItem ] . isGroupItem ? this . filterValue : this . _filteredItems [ indexOfItem ] . text ;
585
590
586
- this . value = this . _filteredItems [ indexOfItem ] . text ;
591
+ this . _isKeyNavigation = true ;
592
+ this . _itemFocused = true ;
593
+ this . _selectionChanged = true ;
594
+
595
+ if ( this . _filteredItems [ indexOfItem ] . isGroupItem ) {
596
+ return ;
597
+ }
598
+
599
+ this . _filteredItems [ indexOfItem ] . selected = true ;
587
600
588
601
// autocomplete
589
602
const item = this . _autoCompleteValue ( this . value ) ;
@@ -594,12 +607,8 @@ class ComboBox extends UI5Element {
594
607
} ) ;
595
608
}
596
609
597
- this . _isKeyNavigation = true ;
598
- this . _itemFocused = true ;
599
610
this . fireEvent ( "input" ) ;
600
611
this . _fireChangeEvent ( ) ;
601
-
602
- this . _selectionChanged = true ;
603
612
}
604
613
605
614
_keydown ( event ) {
@@ -642,11 +651,40 @@ class ComboBox extends UI5Element {
642
651
}
643
652
644
653
_filterItems ( str ) {
645
- return ( Filters [ this . filter ] || Filters . StartsWithPerTerm ) ( str , this . items ) ;
654
+ const itemsToFilter = this . items . filter ( item => ! item . isGroupItem ) ;
655
+ const filteredItems = ( Filters [ this . filter ] || Filters . StartsWithPerTerm ) ( str , itemsToFilter ) ;
656
+
657
+ // Return the filtered items and their group items
658
+ return this . items . filter ( ( item , idx , allItems ) => ComboBox . _groupItemFilter ( item , ++ idx , allItems , filteredItems ) || filteredItems . indexOf ( item ) !== - 1 ) ;
659
+ }
660
+
661
+ /**
662
+ * Returns true if the group header should be shown (if there is a filtered suggestion item for this group item)
663
+ *
664
+ * @private
665
+ */
666
+ static _groupItemFilter ( item , idx , allItems , filteredItems ) {
667
+ if ( item . isGroupItem ) {
668
+ let groupHasFilteredItems ;
669
+
670
+ while ( allItems [ idx ] && ! allItems [ idx ] . isGroupItem && ! groupHasFilteredItems ) {
671
+ groupHasFilteredItems = filteredItems . indexOf ( allItems [ idx ] ) !== - 1 ;
672
+ idx ++ ;
673
+ }
674
+
675
+ return groupHasFilteredItems ;
676
+ }
646
677
}
647
678
648
679
_autoCompleteValue ( current ) {
649
- const matchingItems = this . _startsWithMatchingItems ( current ) ;
680
+ const currentlyFocusedItem = this . items . find ( item => item . focused === true ) ;
681
+
682
+ if ( currentlyFocusedItem && currentlyFocusedItem . isGroupItem ) {
683
+ this . value = this . filterValue ;
684
+ return ;
685
+ }
686
+
687
+ const matchingItems = this . _startsWithMatchingItems ( current ) . filter ( item => ! item . isGroupItem ) ;
650
688
651
689
if ( matchingItems . length ) {
652
690
this . value = matchingItems [ 0 ] ? matchingItems [ 0 ] . text : current ;
@@ -656,7 +694,7 @@ class ComboBox extends UI5Element {
656
694
657
695
if ( this . _isKeyNavigation ) {
658
696
setTimeout ( ( ) => {
659
- this . inner . setSelectionRange ( 0 , this . value . length ) ;
697
+ this . inner . setSelectionRange ( this . filterValue . length , this . value . length ) ;
660
698
} , 0 ) ;
661
699
} else if ( matchingItems . length ) {
662
700
setTimeout ( ( ) => {
@@ -670,9 +708,11 @@ class ComboBox extends UI5Element {
670
708
}
671
709
672
710
_selectMatchingItem ( ) {
673
- this . _filteredItems = this . _filteredItems . map ( item => {
674
- item . selected = ( item . text === this . value ) ;
711
+ const currentlyFocusedItem = this . items . find ( item => item . focused ) ;
712
+ const shouldSelectionBeCleared = currentlyFocusedItem && currentlyFocusedItem . isGroupItem ;
675
713
714
+ this . _filteredItems = this . _filteredItems . map ( item => {
715
+ item . selected = ! item . isGroupItem && ( item . text === this . value ) && ! shouldSelectionBeCleared ;
676
716
return item ;
677
717
} ) ;
678
718
}
@@ -716,8 +756,7 @@ class ComboBox extends UI5Element {
716
756
}
717
757
718
758
this . _filteredItems . map ( item => {
719
- item . selected = ( item === listItem . mappedItem ) ;
720
-
759
+ item . selected = ( item === listItem . mappedItem && ! item . isGroupItem ) ;
721
760
return item ;
722
761
} ) ;
723
762
@@ -825,6 +864,7 @@ class ComboBox extends UI5Element {
825
864
Button ,
826
865
StandardListItem ,
827
866
Popover ,
867
+ ComboBoxGroupItem ,
828
868
] ;
829
869
}
830
870
0 commit comments