Skip to content

Commit d3f9efc

Browse files
author
Workflow Bot
committed
feat(ComboBox): implement noTypeahead behavior to skip auto-selection during filtering
1 parent 768a8ca commit d3f9efc

File tree

2 files changed

+158
-1
lines changed

2 files changed

+158
-1
lines changed

packages/main/cypress/specs/ComboBox.cy.tsx

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,158 @@ describe("Keyboard navigation", () => {
596596

597597
cy.get("@input").should("have.value", "b");
598598
});
599+
600+
it("should NOT auto-select item when noTypeahead is enabled and filtering", () => {
601+
cy.mount(
602+
<ComboBox noTypeahead>
603+
<ComboBoxItem text="Argentina" />
604+
<ComboBoxItem text="Bulgaria" />
605+
<ComboBoxItem text="Canada" />
606+
</ComboBox>,
607+
);
608+
609+
cy.get("[ui5-combobox]")
610+
.as("combo")
611+
.invoke("on", "ui5-selection-change", cy.spy().as("selectionChangeSpy"));
612+
613+
cy.get("@combo").shadow().find("input").as("input");
614+
615+
// Type full item text - should NOT auto-select when noTypeahead is true
616+
cy.get("@input").realClick();
617+
cy.get("@input").realType("Bulgaria");
618+
619+
// Verify no selection was made automatically
620+
cy.get("@selectionChangeSpy").should("not.have.been.called");
621+
cy.get("@combo")
622+
.find("[ui5-cb-item]")
623+
.eq(1)
624+
.should("not.have.prop", "selected", true);
625+
});
626+
627+
it("should allow explicit selection via click when noTypeahead is enabled", () => {
628+
cy.mount(
629+
<ComboBox noTypeahead>
630+
<ComboBoxItem text="Argentina" />
631+
<ComboBoxItem text="Bulgaria" />
632+
<ComboBoxItem text="Canada" />
633+
</ComboBox>,
634+
);
635+
636+
cy.get("[ui5-combobox]")
637+
.as("combo")
638+
.invoke("on", "ui5-selection-change", cy.spy().as("selectionChangeSpy"));
639+
640+
cy.get("@combo").shadow().find("input").as("input");
641+
642+
// Type to filter, then click item - should select
643+
cy.get("@input").realClick();
644+
cy.get("@input").realType("Bulg");
645+
646+
cy.get("@combo").find("[ui5-cb-item]").eq(1).realClick();
647+
648+
// Verify selection was made via click
649+
cy.get("@selectionChangeSpy").should("have.been.calledOnce");
650+
cy.get("@selectionChangeSpy").should(
651+
"have.been.calledWithMatch",
652+
Cypress.sinon.match((event) => {
653+
return event.detail.item.text === "Bulgaria";
654+
}),
655+
);
656+
cy.get("@combo").should("have.prop", "value", "Bulgaria");
657+
});
658+
659+
it("should allow explicit selection via Enter key when noTypeahead is enabled", () => {
660+
cy.mount(
661+
<ComboBox noTypeahead>
662+
<ComboBoxItem text="Argentina" />
663+
<ComboBoxItem text="Bulgaria" />
664+
<ComboBoxItem text="Canada" />
665+
</ComboBox>,
666+
);
667+
668+
cy.get("[ui5-combobox]")
669+
.as("combo")
670+
.invoke("on", "ui5-selection-change", cy.spy().as("selectionChangeSpy"));
671+
672+
cy.get("@combo").shadow().find("input").as("input");
673+
674+
// Type to filter items - this opens the picker
675+
cy.get("@input").realClick();
676+
cy.get("@input").realType("Bul");
677+
678+
// No auto-selection should have happened yet
679+
cy.get("@selectionChangeSpy").should("not.have.been.called");
680+
681+
// Navigate to the first filtered item with arrow down
682+
cy.get("@input").realPress("ArrowDown");
683+
684+
// Selection should occur via keyboard navigation
685+
cy.get("@selectionChangeSpy").should("have.been.calledOnce");
686+
687+
// Now press Enter to confirm and close picker
688+
cy.get("@input").realPress("Enter");
689+
cy.get("@combo").should("have.prop", "value", "Bulgaria");
690+
});
691+
692+
it("should allow explicit selection via keyboard navigation when noTypeahead is enabled", () => {
693+
cy.mount(
694+
<ComboBox noTypeahead>
695+
<ComboBoxItem text="Argentina" />
696+
<ComboBoxItem text="Bulgaria" />
697+
<ComboBoxItem text="Canada" />
698+
</ComboBox>,
699+
);
700+
701+
cy.get("[ui5-combobox]")
702+
.as("combo")
703+
.invoke("on", "ui5-selection-change", cy.spy().as("selectionChangeSpy"));
704+
705+
cy.get("@combo").shadow().find("input").as("input");
706+
707+
// Open picker and use keyboard navigation to select
708+
cy.get("@combo").shadow().find(".inputIcon").realClick();
709+
710+
// Navigate with arrow keys
711+
cy.get("@input").realPress("ArrowDown");
712+
713+
// Selection should occur via keyboard navigation
714+
cy.get("@selectionChangeSpy").should("have.been.calledOnce");
715+
cy.get("@selectionChangeSpy").should(
716+
"have.been.calledWithMatch",
717+
Cypress.sinon.match((event) => {
718+
return event.detail.item.text === "Argentina";
719+
}),
720+
);
721+
cy.get("@combo").should("have.prop", "value", "Argentina");
722+
});
723+
724+
it("should auto-select when noTypeahead is false (default behavior)", () => {
725+
cy.mount(
726+
<ComboBox>
727+
<ComboBoxItem text="Argentina" />
728+
<ComboBoxItem text="Bulgaria" />
729+
<ComboBoxItem text="Canada" />
730+
</ComboBox>,
731+
);
732+
733+
cy.get("[ui5-combobox]")
734+
.as("combo")
735+
.invoke("on", "ui5-selection-change", cy.spy().as("selectionChangeSpy"));
736+
737+
cy.get("@combo").shadow().find("input").as("input");
738+
739+
// Type full item text - should auto-select when noTypeahead is false
740+
cy.get("@input").realClick();
741+
cy.get("@input").realType("Bulgaria");
742+
743+
// Verify selection was made automatically
744+
cy.get("@selectionChangeSpy").should("have.been.calledOnce");
745+
cy.get("@combo")
746+
.find("[ui5-cb-item]")
747+
.eq(1)
748+
.should("have.prop", "selected", true);
749+
cy.get("@combo").should("have.prop", "value", "Bulgaria");
750+
});
599751
});
600752

601753
describe("Grouping", () => {

packages/main/src/ComboBox.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1188,8 +1188,13 @@ class ComboBox extends UI5Element implements IFormInputElement {
11881188
}
11891189
});
11901190

1191+
// Skip auto-selection during filtering when noTypeahead is enabled
1192+
// Allow selection only through explicit user interaction (clicks, Enter key, keyboard navigation)
1193+
const isActiveFiltering = this.focused && this.value && !this._selectionPerformed && !this._isKeyNavigation;
1194+
const shouldSkipAutoSelection = this.noTypeahead && isActiveFiltering;
1195+
11911196
this._filteredItems.forEach(item => {
1192-
if (!shouldSelectionBeCleared && !itemToBeSelected) {
1197+
if (!shouldSelectionBeCleared && !itemToBeSelected && !shouldSkipAutoSelection) {
11931198
itemToBeSelected = ((!item.isGroupItem && (item.text === this.value)) ? item : item?.items?.find(i => i.text === this.value));
11941199
}
11951200
});

0 commit comments

Comments
 (0)