diff --git a/packages/fiori/cypress/specs/Search.cy.tsx b/packages/fiori/cypress/specs/Search.cy.tsx
index b56b95f8647a..3afede92279d 100644
--- a/packages/fiori/cypress/specs/Search.cy.tsx
+++ b/packages/fiori/cypress/specs/Search.cy.tsx
@@ -4,7 +4,6 @@ import SearchItem from "../../src/SearchItem.js";
import SearchItemGroup from "../../src/SearchItemGroup.js";
import history from "@ui5/webcomponents-icons/dist/history.js";
import IllustratedMessage from "../../src/IllustratedMessage.js";
-import SearchPopupMode from "@ui5/webcomponents/dist/types/SearchPopupMode.js";
import searchIcon from "@ui5/webcomponents-icons/dist/search.js";
import SearchMessageArea from "../../src/SearchMessageArea.js";
import Button from "@ui5/webcomponents/dist/Button.js";
diff --git a/packages/fiori/cypress/specs/SearchField.cy.tsx b/packages/fiori/cypress/specs/SearchField.cy.tsx
index b1398b77f721..4b70e8ee1c13 100644
--- a/packages/fiori/cypress/specs/SearchField.cy.tsx
+++ b/packages/fiori/cypress/specs/SearchField.cy.tsx
@@ -4,6 +4,7 @@ import {
SEARCH_FIELD_SCOPE_SELECT_LABEL,
SEARCH_FIELD_CLEAR_ICON,
SEARCH_FIELD_SEARCH_ICON,
+ SEARCH_FIELD_LABEL
} from "../../src/generated/i18n/i18n-defaults.js";
describe("SearchField general interaction", () => {
@@ -40,6 +41,24 @@ describe("SearchField general interaction", () => {
.find("input")
.should("have.attr", "aria-label", attributeValue);
});
+
+ it("accessibleName should have default value if not set", () => {
+ cy.mount();
+
+ cy.get("[ui5-search-field]")
+ .shadow()
+ .find("input")
+ .should("have.attr", "aria-label", SEARCH_FIELD_LABEL.defaultText);
+ });
+
+ it("accessibleDescription should propagate if set", () => {
+ cy.mount();
+
+ cy.get("[ui5-search-field]")
+ .shadow()
+ .find("input")
+ .should("have.attr", "aria-description", "Test");
+ });
});
describe("Collapsed Search Field", () => {
diff --git a/packages/fiori/cypress/specs/ShellBarSearch.cy.tsx b/packages/fiori/cypress/specs/ShellBarSearch.cy.tsx
new file mode 100644
index 000000000000..e4e2fa169425
--- /dev/null
+++ b/packages/fiori/cypress/specs/ShellBarSearch.cy.tsx
@@ -0,0 +1,65 @@
+import ShellBarSearch from "../../src/ShellBarSearch.js";
+import {
+ SHELLBAR_SEARCH_COLLAPSED,
+ SEARCH_FIELD_SEARCH_ICON,
+ SHELLBAR_SEARCH_EXPANDED,
+} from "../../src/generated/i18n/i18n-defaults.js";
+
+describe("Behaviour", () => {
+ it ("Toggles collapsed property upon icon press", () => {
+ cy.mount();
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-icon]")
+ .as("searchIcon");
+
+ cy.get("@searchIcon")
+ .realClick();
+
+ cy.get("[ui5-shellbar-search]")
+ .should("have.prop", "collapsed", true);
+
+ cy.get("@searchIcon")
+ .realClick();
+
+ cy.get("[ui5-shellbar-search]")
+ .should("not.have.a.property", "collapsed");
+ });
+
+ it ("Tests icon tooltips for diffrent states", () => {
+ cy.mount();
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-icon]")
+ .as("searchIcon");
+
+ cy.get("@searchIcon")
+ .should("have.attr", "accessible-name", SHELLBAR_SEARCH_EXPANDED.defaultText);
+
+ cy.get("@searchIcon")
+ .realClick();
+
+ cy.get("[ui5-shellbar-search]")
+ .should("have.prop", "collapsed", true);
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-button]")
+ .should("have.attr", "accessible-name", SHELLBAR_SEARCH_COLLAPSED.defaultText);
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-button]")
+ .realClick();
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("input")
+ .type("test");
+
+ cy.get("@searchIcon")
+ .should("have.attr", "accessible-name", SEARCH_FIELD_SEARCH_ICON.defaultText);
+ });
+});
\ No newline at end of file
diff --git a/packages/fiori/cypress/specs/ShellBarSearch.mobile.cy.tsx b/packages/fiori/cypress/specs/ShellBarSearch.mobile.cy.tsx
new file mode 100644
index 000000000000..cc1ddec6756e
--- /dev/null
+++ b/packages/fiori/cypress/specs/ShellBarSearch.mobile.cy.tsx
@@ -0,0 +1,98 @@
+import SearchItem from "../../src/SearchItem.js";
+import ShellBarSearch from "../../src/ShellBarSearch.js";
+
+describe("Mobile Behaviour", () => {
+ beforeEach(() => {
+ cy.ui5SimulateDevice();
+ });
+
+ it("Should not close dialog upon focus out", () => {
+ cy.mount();
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-button]")
+ .realClick();
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-responsive-popover] header input")
+ .type("test");
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-responsive-popover] header input")
+ .blur();
+
+ cy.get("[ui5-shellbar-search]")
+ .should("have.prop", "open", true);
+ });
+
+ it("Should select typed ahead item when typing", () => {
+ cy.mount(
+ <>
+
+
+
+
+
+
+
+
+ >
+ );
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-button]")
+ .realClick();
+
+ cy.get("[ui5-shellbar-search]")
+ .should("have.prop", "open", true);
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-responsive-popover] header input")
+ .type("item 1");
+
+ cy.get("[ui5-search-item]:first")
+ .should("have.attr", "selected");
+ });
+
+ it("Should type ahead internal input", () => {
+ cy.mount(
+ <>
+
+
+
+
+
+
+
+
+ >
+ );
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-button]")
+ .realClick();
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-responsive-popover] header input")
+ .type("ite");
+
+ cy.get("[ui5-shellbar-search]")
+ .shadow()
+ .find("[ui5-responsive-popover] header input")
+ .should("have.value", "Item 1");
+ });
+
+ it("is collapsed by default", () => {
+ cy.mount();
+
+ cy.get("[ui5-shellbar-search]")
+ .should("have.prop", "collapsed", true);
+ });
+});
\ No newline at end of file
diff --git a/packages/fiori/src/Search.ts b/packages/fiori/src/Search.ts
index bf2a3d103e16..0a23f31f1dd9 100644
--- a/packages/fiori/src/Search.ts
+++ b/packages/fiori/src/Search.ts
@@ -66,7 +66,7 @@ type SearchEventDetails = {
*
* ### ES6 Module Import
*
- * `import "@ui5/webcomponents/fiori/dist/Search.js";`
+ * `import "@ui5/webcomponents-fiori/dist/Search.js";`
*
* @constructor
* @extends SearchField
@@ -287,13 +287,11 @@ class Search extends SearchField {
_handleMobileInput(e: CustomEvent) {
this.value = (e.target as Input).value;
- this._performItemSelectionOnMobile = this._shouldPerformSelectionOnMobile(e);
+ this._performItemSelectionOnMobile = this._shouldPerformSelectionOnMobile(e.detail.inputType);
this.fireDecoratorEvent("input");
}
-
- _shouldPerformSelectionOnMobile(e: CustomEvent): boolean {
- const eventType = e.detail.inputType;
+ _shouldPerformSelectionOnMobile(inputType: string): boolean {
const allowedEventTypes = [
"deleteWordBackward",
"deleteWordForward",
@@ -310,7 +308,7 @@ class Search extends SearchField {
"historyUndo",
];
- return !this.noTypeahead && !allowedEventTypes.includes(eventType || "");
+ return !this.noTypeahead && !allowedEventTypes.includes(inputType || "");
}
_handleTypeAhead(item: ISearchSuggestionItem) {
@@ -430,7 +428,11 @@ class Search extends SearchField {
_handleInput(e: InputEvent) {
super._handleInput(e);
- this.open = !isPhone() && ((e.currentTarget as HTMLInputElement).value.length > 0) && this._popoupHasAnyContent();
+ if (isPhone()) {
+ return;
+ }
+
+ this.open = ((e.currentTarget as HTMLInputElement).value.length > 0) && this._popoupHasAnyContent();
}
_popoupHasAnyContent() {
@@ -606,7 +608,7 @@ class Search extends SearchField {
get nativeInput() {
const domRef = this.getDomRef();
- return domRef ? domRef.querySelector(`input`) : null;
+ return domRef?.querySelector(`input`);
}
get mobileInput() {
diff --git a/packages/fiori/src/SearchField.ts b/packages/fiori/src/SearchField.ts
index eb80edb98c18..7d981dcb30e5 100644
--- a/packages/fiori/src/SearchField.ts
+++ b/packages/fiori/src/SearchField.ts
@@ -18,6 +18,7 @@ import {
SEARCH_FIELD_SCOPE_SELECT_LABEL,
SEARCH_FIELD_CLEAR_ICON,
SEARCH_FIELD_SEARCH_ICON,
+ SEARCH_FIELD_LABEL,
} from "./generated/i18n/i18n-defaults.js";
/**
@@ -49,7 +50,7 @@ type SearchFieldScopeSelectionChangeDetails = {
*
* ### ES6 Module Import
*
- * `import "@ui5/webcomponents/fiori/dist/SearchField.js";`
+ * `import "@ui5/webcomponents-fiori/dist/SearchField.js";`
*
* @constructor
* @extends UI5Element
@@ -111,7 +112,7 @@ class SearchField extends UI5Element {
* Defines whether the component is collapsed.
*
* @default false
- * @public
+ * @private
*/
@property({ type: Boolean })
collapsed = false;
@@ -144,12 +145,12 @@ class SearchField extends UI5Element {
accessibleName?: string;
/**
- * Defines the tooltip of the search icon component.
+ * Defines the accessible ARIA description of the field.
* @public
* @default undefined
*/
@property()
- searchIconTooltip?: string;
+ accessibleDescription?: string;
/**
* Defines the component scope options.
@@ -248,11 +249,12 @@ class SearchField extends UI5Element {
scope: SearchField.i18nBundle.getText(SEARCH_FIELD_SCOPE_SELECT_LABEL),
searchIcon: SearchField.i18nBundle.getText(SEARCH_FIELD_SEARCH_ICON),
clearIcon: SearchField.i18nBundle.getText(SEARCH_FIELD_CLEAR_ICON),
+ searchFieldAriaLabel: SearchField.i18nBundle.getText(SEARCH_FIELD_LABEL),
};
}
get _effectiveIconTooltip() {
- return this.searchIconTooltip || this._translations.searchIcon;
+ return this._translations.searchIcon;
}
captureRef(ref: HTMLElement & { scopeOption?: UI5Element} | null) {
diff --git a/packages/fiori/src/SearchFieldTemplate.tsx b/packages/fiori/src/SearchFieldTemplate.tsx
index 5f0be6805098..93949fc59e89 100644
--- a/packages/fiori/src/SearchFieldTemplate.tsx
+++ b/packages/fiori/src/SearchFieldTemplate.tsx
@@ -7,9 +7,16 @@ import decline from "@ui5/webcomponents-icons/dist/decline.js";
import search from "@ui5/webcomponents-icons/dist/search.js";
import ButtonDesign from "@ui5/webcomponents/dist/types/ButtonDesign.js";
-export default function SearchFieldTemplate(this: SearchField) {
+export type SearchFieldTemplateOptions = {
+ /**
+ * If set to true, the search field will be expanded.
+ */
+ forceExpanded?: boolean;
+};
+
+export default function SearchFieldTemplate(this: SearchField, options?: SearchFieldTemplateOptions) {
return (
- this.collapsed ? (
+ !options?.forceExpanded && this.collapsed ? (