Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b9a55d6
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 4, 2026
2b9ca8e
Merge branch 'main' of https://github.com/SAP/ui5-webcomponents into …
Vonahz Jun 4, 2026
983f1f5
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 4, 2026
ce4a62f
Merge branch 'main' of https://github.com/SAP/ui5-webcomponents into …
Vonahz Jun 4, 2026
02fb8ce
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 4, 2026
c129bc8
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 4, 2026
e677fae
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 4, 2026
e51aaf2
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 9, 2026
c7d4eb0
Merge branch 'main' of https://github.com/SAP/ui5-webcomponents into …
Vonahz Jun 9, 2026
6d6763f
Merge branch 'main' of https://github.com/SAP/ui5-webcomponents into …
Vonahz Jun 9, 2026
0cbfa2f
Merge branch 'combobox_custom_items' of https://github.com/SAP/ui5-we…
Vonahz Jun 9, 2026
bdffd79
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 11, 2026
bc8f75e
Merge branch 'main' of https://github.com/SAP/ui5-webcomponents into …
Vonahz Jun 11, 2026
6b0c55f
Merge branch 'main' of https://github.com/SAP/ui5-webcomponents into …
Vonahz Jun 15, 2026
74681b0
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 15, 2026
ec88d68
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 15, 2026
77c71af
feat(ui5-comobobox, ui5-multi-combobox): add custom items
Vonahz Jun 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 221 additions & 0 deletions packages/main/cypress/specs/ComboBox.cy.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import ValueState from "@ui5/webcomponents-base/dist/types/ValueState.js";
import ComboBox from "../../src/ComboBox.js";
import ComboBoxItem from "../../src/ComboBoxItem.js";
import ComboBoxItemCustom from "../../src/ComboBoxItemCustom.js";
import ComboBoxItemGroup from "../../src/ComboBoxItemGroup.js";
import ResponsivePopover from "../../src/ResponsivePopover.js";
import Link from "../../src/Link.js";
Expand Down Expand Up @@ -3992,3 +3993,223 @@ describe("Highlighting", () => {
.should("contain.html", "<b>AFR</b>");
});
});

describe("ComboBoxItemCustom - Rendering", () => {
it("should render custom content correctly", () => {
cy.mount(
<ComboBox>
<ComboBoxItemCustom text="Germany">
<span role="img" aria-label="Flag">🇩🇪</span> Germany
</ComboBoxItemCustom>
<ComboBoxItemCustom text="France">
<span role="img" aria-label="Flag">🇫🇷</span> France
</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]")
.as("combobox")
.shadow()
.find("[ui5-icon]")
.realClick();

cy.get("[ui5-cb-item-custom]").eq(0).should("contain.text", "🇩🇪 Germany");
cy.get("[ui5-cb-item-custom]").eq(1).should("contain.text", "🇫🇷 France");
});

it("should mix regular and custom items", () => {
cy.mount(
<ComboBox>
<ComboBoxItem text="Standard Item"></ComboBoxItem>
<ComboBoxItemCustom text="Custom Item">
<strong>Custom Item</strong>
</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]")
.shadow()
.find("[ui5-icon]")
.realClick();

cy.get("[ui5-cb-item]").should("have.length", 1);
cy.get("[ui5-cb-item-custom]").should("have.length", 1);
});

it("should have role='option'", () => {
cy.mount(
<ComboBox>
<ComboBoxItemCustom text="Test">Test Item</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]")
.shadow()
.find("[ui5-icon]")
.realClick();

cy.get("[ui5-cb-item-custom]").shadow().find("li").should("have.attr", "role", "option");
});
});

describe("ComboBoxItemCustom - Filtering", () => {
it("should filter custom items by text property", () => {
cy.mount(
<ComboBox>
<ComboBoxItemCustom text="Germany">🇩🇪 Germany</ComboBoxItemCustom>
<ComboBoxItemCustom text="France">🇫🇷 France</ComboBoxItemCustom>
<ComboBoxItemCustom text="Spain">🇪🇸 Spain</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]")
.as("combobox")
.realClick();

cy.get("@combobox").realPress("G");

cy.get("[ui5-cb-item-custom]").eq(0).should("have.prop", "_isVisible", true);
cy.get("[ui5-cb-item-custom]").eq(1).should("not.have.prop", "_isVisible", true);
cy.get("[ui5-cb-item-custom]").eq(2).should("not.have.prop", "_isVisible", true);
});

it("should filter mixed regular and custom items", () => {
cy.mount(
<ComboBox>
<ComboBoxItem text="Austria"></ComboBoxItem>
<ComboBoxItemCustom text="Germany">🇩🇪 Germany</ComboBoxItemCustom>
<ComboBoxItem text="France"></ComboBoxItem>
</ComboBox>
);

cy.get("[ui5-combobox]")
.as("combobox")
.realClick();

cy.get("@combobox").realPress("G");

cy.get("[ui5-cb-item]").eq(0).should("not.have.prop", "_isVisible", true);
cy.get("[ui5-cb-item-custom]").eq(0).should("have.prop", "_isVisible", true);
cy.get("[ui5-cb-item]").eq(1).should("not.have.prop", "_isVisible", true);
});
});

describe("ComboBoxItemCustom - Selection", () => {
it("should select custom item on click", () => {
cy.mount(
<ComboBox>
<ComboBoxItemCustom text="Germany">🇩🇪 Germany</ComboBoxItemCustom>
<ComboBoxItemCustom text="France">🇫🇷 France</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]")
.as("combobox")
.shadow()
.find("[ui5-icon]")
.realClick();

cy.get("[ui5-cb-item-custom]").eq(0).shadow().find("li").realClick();

cy.get("@combobox").should("have.prop", "value", "Germany");
});

it("should select custom item with Enter key", () => {
cy.mount(
<ComboBox>
<ComboBoxItemCustom text="Germany">🇩🇪 Germany</ComboBoxItemCustom>
<ComboBoxItemCustom text="France">🇫🇷 France</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]")
.as("combobox")
.realClick();

cy.get("@combobox").realPress("ArrowDown");
cy.get("@combobox").realPress("Enter");

cy.get("@combobox").should("have.prop", "value", "Germany");
});

it("should work with value property for programmatic selection", () => {
cy.mount(
<ComboBox selectedValue="FR">
<ComboBoxItemCustom text="Germany" value="DE">🇩🇪 Germany</ComboBoxItemCustom>
<ComboBoxItemCustom text="France" value="FR">🇫🇷 France</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]").should("have.prop", "value", "France");
cy.get("[ui5-combobox]").should("have.prop", "selectedValue", "FR");
});
});

describe("ComboBoxItemCustom - Navigation", () => {
it("should navigate through custom items with arrow keys", () => {
cy.mount(
<ComboBox>
<ComboBoxItemCustom text="Germany">🇩🇪 Germany</ComboBoxItemCustom>
<ComboBoxItemCustom text="France">🇫🇷 France</ComboBoxItemCustom>
<ComboBoxItemCustom text="Spain">🇪🇸 Spain</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]")
.as("combobox")
.shadow()
.find("[ui5-icon]")
.realClick();

cy.get("@combobox").shadow().find("input").realPress("ArrowDown");
cy.get("[ui5-cb-item-custom]").eq(0).should("have.prop", "focused", true);

cy.get("@combobox").shadow().find("input").realPress("ArrowDown");
cy.get("[ui5-cb-item-custom]").eq(1).should("have.prop", "focused", true);

cy.get("@combobox").shadow().find("input").realPress("ArrowUp");
cy.get("[ui5-cb-item-custom]").eq(0).should("have.prop", "focused", true);
});

it("should navigate through mixed items", () => {
cy.mount(
<ComboBox>
<ComboBoxItem text="Austria"></ComboBoxItem>
<ComboBoxItemCustom text="Germany">🇩🇪 Germany</ComboBoxItemCustom>
<ComboBoxItem text="France"></ComboBoxItem>
</ComboBox>
);

cy.get("[ui5-combobox]")
.as("combobox")
.shadow()
.find("[ui5-icon]")
.realClick();

cy.get("@combobox").shadow().find("input").realPress("ArrowDown");
cy.get("[ui5-cb-item]").eq(0).should("have.prop", "focused", true);

cy.get("@combobox").shadow().find("input").realPress("ArrowDown");
cy.get("[ui5-cb-item-custom]").eq(0).should("have.prop", "focused", true);

cy.get("@combobox").shadow().find("input").realPress("ArrowDown");
cy.get("[ui5-cb-item]").eq(1).should("have.prop", "focused", true);
});
});

describe("ComboBoxItemCustom - Accessibility", () => {
it("should have correct tabindex", () => {
cy.mount(
<ComboBox>
<ComboBoxItemCustom text="Test">Test Item</ComboBoxItemCustom>
</ComboBox>
);

cy.get("[ui5-combobox]")
.shadow()
.find("[ui5-icon]")
.realClick();

cy.get("[ui5-cb-item-custom]").shadow().find("li").should("not.have.attr", "tabindex", "0");
});
});
Loading
Loading