From e33ec098c5117d8fd3e79e80580248dc64f4aade Mon Sep 17 00:00:00 2001 From: Elena Stoyanova Date: Fri, 21 Mar 2025 13:44:39 +0200 Subject: [PATCH 1/2] fix(ui5-search): change growing list to footer button --- packages/fiori/cypress/specs/Search.cy.tsx | 19 ++++++----- packages/fiori/src/Search.ts | 34 ++++++++++++++++---- packages/fiori/src/SearchPopoverTemplate.tsx | 15 +++++++-- packages/fiori/src/themes/Search.css | 11 +++---- packages/fiori/src/themes/SearchField.css | 16 ++++----- 5 files changed, 61 insertions(+), 34 deletions(-) diff --git a/packages/fiori/cypress/specs/Search.cy.tsx b/packages/fiori/cypress/specs/Search.cy.tsx index ad5642ca76f5..5570f4cf121d 100644 --- a/packages/fiori/cypress/specs/Search.cy.tsx +++ b/packages/fiori/cypress/specs/Search.cy.tsx @@ -403,12 +403,12 @@ describe("Properties", () => { cy.get("[ui5-search]") .shadow() .find("[ui5-responsive-popover]") - .find("[ui5-list]") - .as("list"); + .find(".ui5-search-footer-button") + .as("button"); - cy.get("@list") - .should("have.attr", "growing", "Button") - .and("have.attr", "growing-button-text", "Show All"); + cy.get("@button") + .should("exist") + .and("have.text", "Show All"); }); }); @@ -610,12 +610,11 @@ describe("Events", () => { cy.get("[ui5-search]") .shadow() - .find("[ui5-list]") - .as("list"); + .find("[ui5-responsive-popover]") + .as("popup"); - cy.get("@list") - .shadow() - .find(".ui5-growing-button") + cy.get("@popup") + .find(".ui5-search-footer-button") .realClick(); cy.get("@actionPressed") diff --git a/packages/fiori/src/Search.ts b/packages/fiori/src/Search.ts index 48d784fb9a01..2b7d79c6b245 100644 --- a/packages/fiori/src/Search.ts +++ b/packages/fiori/src/Search.ts @@ -18,6 +18,7 @@ import { isHome, isEnd, isRight, + isTabPrevious, } from "@ui5/webcomponents-base/dist/Keys.js"; import SearchTemplate from "./SearchTemplate.js"; @@ -28,7 +29,7 @@ import type UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js"; import type SearchItem from "./SearchItem.js"; import { renderFinished } from "@ui5/webcomponents-base/dist/Render.js"; import jsxRenderer from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; -import ListGrowingMode from "@ui5/webcomponents/dist/types/ListGrowingMode.js"; +import type Button from "@ui5/webcomponents/dist/Button.js"; interface ISearchSuggestionItem extends UI5Element { selected: boolean; @@ -137,6 +138,7 @@ class Search extends SearchField { /** * Defines whether the popup footer action button is shown. + * Note: The footer action button is displayed only when the `popupMode` is set to `List`. * @default false * @public */ @@ -383,11 +385,21 @@ class Search extends SearchField { this._openPickerOnInput = false; } + _onFooterButtonKeyDown(e: KeyboardEvent) { + if (isUp(e)) { + this._flattenItems[this._flattenItems.length - 1].focus(); + } + if (isTabPrevious(e)) { + this._getItemsList().focus(); + } + } + _onItemKeydown(e: KeyboardEvent) { - const items = this._getItemsList()?.getSlottedNodes("items"); - const isFirstItemGroup = items[1] === e.target && items[0]?.hasAttribute("ui5-li-group"); - const isFirstItem = items[0] === e.target || isFirstItemGroup; + const isFirstItem = this._flattenItems[0] === e.target; + const isLastItem = this._flattenItems[this._flattenItems.length - 1] === e.target; const isArrowUp = isUp(e); + const isArrowDown = isDown(e); + const isTab = isTabNext(e); e.preventDefault(); @@ -395,6 +407,10 @@ class Search extends SearchField { this.nativeInput?.focus(); this._shouldAutocomplete = true; } + + if ((isLastItem && isArrowDown) || isTab) { + this._getFooterButton()?.focus(); + } } _onItemClick(e: CustomEvent) { @@ -470,7 +486,7 @@ class Search extends SearchField { this.fireDecoratorEvent("open"); } - _handleMore() { + _onFooterButtonClick() { this.fireDecoratorEvent("popup-action-press"); } @@ -503,6 +519,10 @@ class Search extends SearchField { return this._getPicker().querySelector(".ui5-search-list") as List; } + _getFooterButton(): Button { + return this._getPicker().querySelector(".ui5-search-footer-button") as Button; + } + get _flattenItems(): Array { return this.getSlottedNodes("items").flatMap(item => { return this._isGroupItem(item) ? [item, ...item.items!] : [item]; @@ -527,8 +547,8 @@ class Search extends SearchField { return !!this.headerText; } - get _effectiveGrowing() { - return this.showPopupAction ? ListGrowingMode.Button : ListGrowingMode.None; + get _showFooter() { + return !!this.showPopupAction && this.popupMode === SearchPopupMode.List; } } diff --git a/packages/fiori/src/SearchPopoverTemplate.tsx b/packages/fiori/src/SearchPopoverTemplate.tsx index aea29714eb39..e189d5cbc6d5 100644 --- a/packages/fiori/src/SearchPopoverTemplate.tsx +++ b/packages/fiori/src/SearchPopoverTemplate.tsx @@ -8,6 +8,7 @@ import ListSeparator from "@ui5/webcomponents/dist/types/ListSeparator.js"; import TitleLevel from "@ui5/webcomponents/dist/types/TitleLevel.js"; import PopoverHorizontalAlign from "@ui5/webcomponents/dist/types/PopoverHorizontalAlign.js"; import PopoverPlacement from "@ui5/webcomponents/dist/types/PopoverPlacement.js"; +import Button from "@ui5/webcomponents/dist/Button.js"; export default function SearchPopoverTemplate(this: Search) { return ( @@ -41,15 +42,23 @@ export default function SearchPopoverTemplate(this: Search) {
+ + {this._showFooter && + + } ) )} diff --git a/packages/fiori/src/themes/Search.css b/packages/fiori/src/themes/Search.css index 1f1a1b5ab5fc..405f9c156cdc 100644 --- a/packages/fiori/src/themes/Search.css +++ b/packages/fiori/src/themes/Search.css @@ -53,12 +53,11 @@ width: auto; } -.ui5-search-list::part(growing-button-inner) { - border-radius: .5rem; +.ui5-search-popover::part(footer) { + padding-bottom: 0.25rem; + padding-top: 0.5rem; } -.ui5-search-list::part(growing-button) { - border-bottom: none; - padding-top: .25rem; - box-sizing: border-box; +.ui5-search-footer-button { + width: 100%; } \ No newline at end of file diff --git a/packages/fiori/src/themes/SearchField.css b/packages/fiori/src/themes/SearchField.css index 46d80427e452..78ea69fcdede 100644 --- a/packages/fiori/src/themes/SearchField.css +++ b/packages/fiori/src/themes/SearchField.css @@ -178,14 +178,14 @@ } /* copy paste all button styles - could be simplified */ -[ui5-button][desktop]:not([active])::part(button):after, -[ui5-button]:not([active])::part(button):focus-visible:after, -[ui5-button][desktop][active][design="Emphasized"]::part(button):focus-within:after, -[ui5-button][active][design="Emphasized"]::part(button):focus-visible:after, -[ui5-button][desktop][active]::part(button):focus-within:before, -[ui5-button][active]::part(button):focus-visible:before, -[ui5-button][design="Emphasized"][desktop]::part(button):focus-within:before, -[ui5-button][design="Emphasized"]::part(button):focus-visible:before { +.ui5-shell-search-field-button[desktop]:not([active])::part(button):after, +.ui5-shell-search-field-button:not([active])::part(button):focus-visible:after, +.ui5-shell-search-field-button[desktop][active][design="Emphasized"]::part(button):focus-within:after, +.ui5-shell-search-field-button[active][design="Emphasized"]::part(button):focus-visible:after, +.ui5-shell-search-field-button[desktop][active]::part(button):focus-within:before, +.ui5-shell-search-field-button[active]::part(button):focus-visible:before, +.ui5-shell-search-field-button[design="Emphasized"][desktop]::part(button):focus-within:before, +.ui5-shell-search-field-button[design="Emphasized"]::part(button):focus-visible:before { border-radius: var(--_ui5_search_icon_border_radius); } From ad4ff25a16fd6b028524dfa4b7287ac9ffac6f0b Mon Sep 17 00:00:00 2001 From: Elena Stoyanova Date: Tue, 25 Mar 2025 14:08:37 +0200 Subject: [PATCH 2/2] fix: apply comments --- packages/fiori/src/SearchPopoverTemplate.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/fiori/src/SearchPopoverTemplate.tsx b/packages/fiori/src/SearchPopoverTemplate.tsx index e189d5cbc6d5..7730ce19d732 100644 --- a/packages/fiori/src/SearchPopoverTemplate.tsx +++ b/packages/fiori/src/SearchPopoverTemplate.tsx @@ -9,6 +9,7 @@ import TitleLevel from "@ui5/webcomponents/dist/types/TitleLevel.js"; import PopoverHorizontalAlign from "@ui5/webcomponents/dist/types/PopoverHorizontalAlign.js"; import PopoverPlacement from "@ui5/webcomponents/dist/types/PopoverPlacement.js"; import Button from "@ui5/webcomponents/dist/Button.js"; +import ButtonDesign from "@ui5/webcomponents/dist/types/ButtonDesign.js"; export default function SearchPopoverTemplate(this: Search) { return ( @@ -52,7 +53,7 @@ export default function SearchPopoverTemplate(this: Search) { {this._showFooter &&