diff --git a/packages/fiori/cypress/specs/SideNavigation.cy.tsx b/packages/fiori/cypress/specs/SideNavigation.cy.tsx index dd4a157392aae..22ce1568af4f9 100644 --- a/packages/fiori/cypress/specs/SideNavigation.cy.tsx +++ b/packages/fiori/cypress/specs/SideNavigation.cy.tsx @@ -2051,6 +2051,78 @@ describe("Focusable items", () => { .should("exist") .should("have.text", "New"); }); + + it("shows the full tag in the collapsed popover (not clamped to 6rem)", () => { + cy.mount( + + + + Beta Long Text Beta Long Text Beta Long Text + + + + + ); + + cy.get("#item1").realClick(); + + cy.get("#sideNav") + .shadow() + .find("[ui5-responsive-popover] [ui5-side-navigation-item] > [ui5-tag]") + .then($tag => { + // the popover tag is not truncated: it renders wider than the 6rem rail clamp + expect($tag[0].getBoundingClientRect().width).to.be.greaterThan(96); + }); + }); + + it("renders the overflow menu item tag inline right after the text", () => { + cy.mount( + + + + Beta + + + ); + + cy.get("#sideNav").invoke("attr", "style", "height: 90px"); + + cy.get("#sideNav") + .shadow() + .find(".ui5-sn-item-overflow:not(.ui5-sn-item-hidden)") + .realClick(); + + cy.get("#sideNav") + .shadow() + .find(".ui5-side-navigation-overflow-menu [ui5-navigation-menu-item][text='Contacts']") + .as("menuItem"); + + // the tag renders inline right after the text (tag.left close to text.right) + cy.get("@menuItem").shadow().find(".ui5-navmenu-item-text").then($text => { + const textRight = $text[0].getBoundingClientRect().right; + cy.get("@menuItem").find("[ui5-tag]").should("have.text", "Beta").then($tag => { + const tagLeft = $tag[0].getBoundingClientRect().left; + expect(tagLeft - textRight).to.be.lessThan(16); + }); + }); + }); + + it("forces the rail item tag onto a single line when collapsed", () => { + cy.mount( + + + Beta Long Text Beta Long Text + + + ); + + // collapsed: the tag is rendered non-wrapping so max-width truncates it + cy.get("#item1").find("[ui5-tag]").should("have.attr", "wrapping-type", "None"); + + // expanded: the author's wrapping is restored (no forced None) + cy.get("#sideNav").invoke("prop", "collapsed", false); + cy.get("#item1").find("[ui5-tag]").should("not.have.attr", "wrapping-type"); + }); }); describe("Side Navigation no match", () => { @@ -2399,6 +2471,33 @@ describe("Side Navigation highlightedText", () => { cy.window().its("__xss").should("not.exist"); }); + + it("does not highlight the tag text when the term matches a tag", () => { + cy.mount( + + + Beta + + + ); + + // the item stays visible + cy.get("#item1").should("be.visible"); + + // no highlight span is rendered inside the item (text does not match) + cy.get("#item1") + .shadow() + .find(".ui5-sn-item-highlight") + .should("not.exist"); + + // the slotted tag text is not wrapped in a highlight span + cy.get("#item1") + .find("[ui5-tag] .ui5-sn-item-highlight") + .should("not.exist"); + cy.get("#item1") + .find("[ui5-tag]") + .should("have.text", "Beta"); + }); }); describe("Side Navigation search match announcement", () => { diff --git a/packages/fiori/cypress/specs/SideNavigationItem.cy.tsx b/packages/fiori/cypress/specs/SideNavigationItem.cy.tsx new file mode 100644 index 0000000000000..69eab0fd30c9a --- /dev/null +++ b/packages/fiori/cypress/specs/SideNavigationItem.cy.tsx @@ -0,0 +1,110 @@ +import SideNavigation from "../../src/SideNavigation.js"; +import SideNavigationItem from "../../src/SideNavigationItem.js"; +import SideNavigationSubItem from "../../src/SideNavigationSubItem.js"; +import Tag from "@ui5/webcomponents/dist/Tag.js"; + +describe("SideNavigationItem - indication tag positioning", () => { + it("renders the tag inline right after the text, not right-aligned", () => { + cy.mount( + + + Beta + + + + ); + + // text and tag share the text-tag container + cy.get("#item") + .shadow() + .find(".ui5-sn-item-text-tag-container") + .as("container"); + + cy.get("@container").find(".ui5-sn-item-text").should("exist"); + cy.get("@container").find(".ui5-sn-item-tag-slot").should("exist"); + + // the tag sits next to the text, not pushed to the item's trailing edge + cy.get("#item").shadow().find(".ui5-sn-item-text").then($text => { + const textRight = $text[0].getBoundingClientRect().right; + + cy.get("#item").shadow().find(".ui5-sn-item-tag-slot").then($tag => { + const tagLeft = $tag[0].getBoundingClientRect().left; + const itemWidth = $text[0].closest(".ui5-sn-item")!.getBoundingClientRect().width; + + // tag starts close to where the text ends (within ~1rem gap) + expect(tagLeft - textRight).to.be.lessThan(16); + // and well before the item's trailing edge (not right-aligned) + expect(tagLeft).to.be.lessThan(itemWidth / 2); + }); + }); + }); + + it("wraps the tag to a second line when text and tag do not fit inline", () => { + cy.mount( + + + Beta Version + + + ); + + cy.get("#item").shadow().find(".ui5-sn-item-text").then($text => { + const textRect = $text[0].getBoundingClientRect(); + + cy.get("#item").shadow().find(".ui5-sn-item-tag-slot").then($tag => { + const tagRect = $tag[0].getBoundingClientRect(); + + // tag dropped to a second line (below the text) + expect(tagRect.top).to.be.greaterThan(textRect.top); + // vertical gap between text and tag is ~0.5rem (8px) + expect(tagRect.top - textRect.bottom).to.be.closeTo(8, 2); + }); + }); + }); + + it("describes the item via an invisible 'Tag {text}' string, not the visible tag", () => { + cy.mount( + + + Beta + + + ); + + cy.get("#item").shadow().find(".ui5-sn-item") + .invoke("attr", "aria-describedby") + .then(describedBy => { + const tagId = describedBy!.split(" ").find(id => id.endsWith("-tag"))!; + cy.get("#item").shadow().find(`#${CSS.escape(tagId)}`) + .should("have.class", "ui5-hidden-text") + .and("have.text", "Tag Beta"); + }); + + cy.get("#item").shadow().find(".ui5-sn-item-tag-slot") + .should("have.attr", "aria-hidden", "true"); + }); + + it("describes a sub-item via the invisible 'Tag {text}' string", () => { + cy.mount( + + + + Beta + + + + ); + + cy.get("#sub").shadow().find(".ui5-sn-item") + .invoke("attr", "aria-describedby") + .then(describedBy => { + const tagId = describedBy!.split(" ").find(id => id.endsWith("-tag"))!; + cy.get("#sub").shadow().find(`#${CSS.escape(tagId)}`) + .should("have.class", "ui5-hidden-text") + .and("have.text", "Tag Beta"); + }); + + cy.get("#sub").shadow().find(".ui5-sn-item-tag-slot") + .should("have.attr", "aria-hidden", "true"); + }); +}); diff --git a/packages/fiori/cypress/specs/visuals/SideNavigationItem.cy.tsx b/packages/fiori/cypress/specs/visuals/SideNavigationItem.cy.tsx index 78e1d6b310989..54443c851d45c 100644 --- a/packages/fiori/cypress/specs/visuals/SideNavigationItem.cy.tsx +++ b/packages/fiori/cypress/specs/visuals/SideNavigationItem.cy.tsx @@ -105,6 +105,50 @@ describe("SideNavigationItem visual", () => { cy.screenshot(); }); + it("with tag and trailing toggle icon", () => { + cy.mount( + + + New + + + + ); + cy.screenshot(); + }); + + it("tag wraps to the second line on long text", () => { + cy.mount( + + + Beta Version + + + ); + cy.screenshot(); + }); + + it("collapsed popover — wrapped tag keeps vertical spacing", () => { + cy.viewport(650, 400); + cy.mount( + + + Beta Long Text Beta Long Text Beta Long Text + + Active Long Text Active Long Text Active Long Text Active Long Text + + + Pending + + + + + ); + cy.get("#parentItem").realClick(); + cy.get("#sideNav").shadow().find("[ui5-responsive-popover]").ui5ResponsivePopoverOpened(); + cy.screenshot(); + }); + it("collapsed side navigation", () => { cy.mount( diff --git a/packages/fiori/src/NavigationMenuItem.ts b/packages/fiori/src/NavigationMenuItem.ts index 9ece1ac60dfb4..1d3555a157331 100644 --- a/packages/fiori/src/NavigationMenuItem.ts +++ b/packages/fiori/src/NavigationMenuItem.ts @@ -25,6 +25,7 @@ import navigationMenuItemCss from "./generated/themes/NavigationMenuItem.css.js" import { NAVIGATION_MENU_SELECTABLE_ITEM_HIDDEN_TEXT, + SIDE_NAVIGATION_LIST_ITEM_TAG_TEXT, } from "./generated/i18n/i18n-defaults.js"; /** @@ -114,13 +115,25 @@ class NavigationMenuItem extends MenuItem { return `${this._id}-tag-container`; } + get _tagTextId() { + return `${this._id}-tag-text`; + } + + get _tagText() { + return this.tag[0]?.textContent?.trim() ?? ""; + } + + get _tagDescriptionText() { + return this.hasTag ? NavigationMenuItem.i18nBundleFiori.getText(SIDE_NAVIGATION_LIST_ITEM_TAG_TEXT, this._tagText) : undefined; + } + get _ariaDescribedByIds() { const ids = [ `${this._id}-invisibleText-describedby`, ]; if (this.hasTag) { - ids.push(this._tagContainerId); + ids.push(this._tagTextId); } return ids.filter(Boolean).join(" "); diff --git a/packages/fiori/src/NavigationMenuItemTemplate.tsx b/packages/fiori/src/NavigationMenuItemTemplate.tsx index 73da8899c4e48..256c4762261b3 100644 --- a/packages/fiori/src/NavigationMenuItemTemplate.tsx +++ b/packages/fiori/src/NavigationMenuItemTemplate.tsx @@ -30,7 +30,19 @@ export default function NavigationMenuItemTemplate(this: NavigationMenuItem, hoo } function listItemContent(this: NavigationMenuItem) { - return <>{this.text}; + return ( +
+ {this.text} + {this.hasTag && + + } + {this.hasTag && + {this._tagDescriptionText} + } +
+ ); } function iconBegin(this: NavigationMenuItem) { @@ -48,11 +60,6 @@ function iconBegin(this: NavigationMenuItem) { function iconEnd(this: NavigationMenuItem) { return (<> - {this.hasTag && - - - - } {this.hasSubmenu && { const clonedTag = tagEl.cloneNode(true) as HTMLElement; clonedTag.setAttribute("slot", "tag"); + // the popover shows the full tag inline (like expanded mode), so it must + // not inherit the collapsed single-line wrapping forced on the rail item; + // restore the author's original wrapping-type (if any) + const authorWrapping = clonedTag.getAttribute("data-ui5-tag-wrapping-synced"); + clonedTag.removeAttribute("data-ui5-tag-wrapping-synced"); + if (authorWrapping) { + clonedTag.setAttribute("wrapping-type", authorWrapping); + } else { + clonedTag.removeAttribute("wrapping-type"); + } ref.appendChild(clonedTag); }); } diff --git a/packages/fiori/src/SideNavigationItem.ts b/packages/fiori/src/SideNavigationItem.ts index 9ede15fba169c..15f49aadc6b64 100644 --- a/packages/fiori/src/SideNavigationItem.ts +++ b/packages/fiori/src/SideNavigationItem.ts @@ -19,6 +19,7 @@ import { SIDE_NAVIGATION_ICON_EXPAND, SIDE_NAVIGATION_OVERFLOW_ITEM_LABEL, SIDE_NAVIGATION_PARENT_ITEM_SELECTABLE_DESCRIPTION, + SIDE_NAVIGATION_LIST_ITEM_TAG_TEXT, } from "./generated/i18n/i18n-defaults.js"; import type { DefaultSlot, Slot } from "@ui5/webcomponents-base/dist/UI5Element.js"; import "@ui5/webcomponents/dist/Tag.js"; @@ -110,6 +111,8 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { this.items.forEach(item => { item._parentDisabled = this.effectiveDisabled; }); + + this._syncTagWrapping(); } get overflowItems() : Array { @@ -233,6 +236,14 @@ class SideNavigationItem extends SideNavigationSelectableItemBase { return !!this.tag.length; } + get _tagText() { + return this.tag[0]?.textContent?.trim() ?? ""; + } + + get _tagDescriptionText() { + return this.hasTag ? SideNavigationItem.i18nBundle.getText(SIDE_NAVIGATION_LIST_ITEM_TAG_TEXT, this._tagText) : undefined; + } + get _textId() { return `${this._id}-text`; } diff --git a/packages/fiori/src/SideNavigationItemTemplate.tsx b/packages/fiori/src/SideNavigationItemTemplate.tsx index b40e5b9d7647c..50bfcd788c8dd 100644 --- a/packages/fiori/src/SideNavigationItemTemplate.tsx +++ b/packages/fiori/src/SideNavigationItemTemplate.tsx @@ -52,12 +52,14 @@ function ItemTemplate(this: SideNavigationItem) { : this.icon && } -
- {this.hasTag && -
- -
- } +
+
+ {this.hasTag && + + } +
{this.sideNavCollapsed ? !!this.items.length && {this._selectableItemDescriptionText} } + {this.hasTag && + {this._tagDescriptionText} + } ); } diff --git a/packages/fiori/src/SideNavigationSelectableItemBase.ts b/packages/fiori/src/SideNavigationSelectableItemBase.ts index 68138d81cbbe4..9ccc5a7b224e2 100644 --- a/packages/fiori/src/SideNavigationSelectableItemBase.ts +++ b/packages/fiori/src/SideNavigationSelectableItemBase.ts @@ -258,6 +258,32 @@ class SideNavigationSelectableItemBase extends SideNavigationItemBase { return `${this._id}-tag`; } + /** + * Forces the slotted tag onto a single line (truncated) in collapsed mode, + * and restores the author's wrapping when expanded. + */ + _syncTagWrapping() { + const tag = this.querySelector(`[slot="tag"]`); + if (!tag) { + return; + } + + if (this.sideNavCollapsed) { + if (!tag.hasAttribute("data-ui5-tag-wrapping-synced")) { + tag.setAttribute("data-ui5-tag-wrapping-synced", tag.getAttribute("wrapping-type") ?? ""); + } + tag.setAttribute("wrapping-type", "None"); + } else if (tag.hasAttribute("data-ui5-tag-wrapping-synced")) { + const original = tag.getAttribute("data-ui5-tag-wrapping-synced"); + if (original) { + tag.setAttribute("wrapping-type", original); + } else { + tag.removeAttribute("wrapping-type"); + } + tag.removeAttribute("data-ui5-tag-wrapping-synced"); + } + } + _onkeydown(e: KeyboardEvent) { const isRTL = this.effectiveDir === "rtl"; diff --git a/packages/fiori/src/SideNavigationSubItem.ts b/packages/fiori/src/SideNavigationSubItem.ts index b3430c49dfd72..185bb662cee4f 100644 --- a/packages/fiori/src/SideNavigationSubItem.ts +++ b/packages/fiori/src/SideNavigationSubItem.ts @@ -1,9 +1,12 @@ import customElement from "@ui5/webcomponents-base/dist/decorators/customElement.js"; import jsxRender from "@ui5/webcomponents-base/dist/renderer/JsxRenderer.js"; import slot from "@ui5/webcomponents-base/dist/decorators/slot-strict.js"; +import i18n from "@ui5/webcomponents-base/dist/decorators/i18n.js"; +import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js"; import type { Slot } from "@ui5/webcomponents-base/dist/UI5Element.js"; import SideNavigationSelectableItemBase from "./SideNavigationSelectableItemBase.js"; import SideNavigationSubItemTemplate from "./SideNavigationSubItemTemplate.js"; +import { SIDE_NAVIGATION_LIST_ITEM_TAG_TEXT } from "./generated/i18n/i18n-defaults.js"; import "@ui5/webcomponents/dist/Tag.js"; // Styles @@ -33,6 +36,9 @@ import SideNavigationSubItemCss from "./generated/themes/SideNavigationSubItem.c styles: SideNavigationSubItemCss, }) class SideNavigationSubItem extends SideNavigationSelectableItemBase { + @i18n("@ui5/webcomponents-fiori") + static i18nBundle: I18nBundle; + /** * Defines the tag to be displayed. * @@ -58,6 +64,18 @@ class SideNavigationSubItem extends SideNavigationSelectableItemBase { return !!this.tag.length; } + onBeforeRendering() { + this._syncTagWrapping(); + } + + get _tagText() { + return this.tag[0]?.textContent?.trim() ?? ""; + } + + get _tagDescriptionText() { + return this.hasTag ? SideNavigationSubItem.i18nBundle.getText(SIDE_NAVIGATION_LIST_ITEM_TAG_TEXT, this._tagText) : undefined; + } + get _textId() { return `${this._id}-text`; } diff --git a/packages/fiori/src/SideNavigationSubItemTemplate.tsx b/packages/fiori/src/SideNavigationSubItemTemplate.tsx index d8b60865ad68e..390319986516e 100644 --- a/packages/fiori/src/SideNavigationSubItemTemplate.tsx +++ b/packages/fiori/src/SideNavigationSubItemTemplate.tsx @@ -29,18 +29,23 @@ export default function SideNavigationSubItemTemplate(this: SideNavigationSubIte {this.icon && } -
- {this.hasTag && -
- -
- } +
+
+ {this.hasTag && + + } +
{this.isExternalLink && } + {this.hasTag && + {this._tagDescriptionText} + } ); } diff --git a/packages/fiori/src/i18n/messagebundle.properties b/packages/fiori/src/i18n/messagebundle.properties index b2af72f926923..fc4c6727d6a5d 100644 --- a/packages/fiori/src/i18n/messagebundle.properties +++ b/packages/fiori/src/i18n/messagebundle.properties @@ -515,6 +515,9 @@ SIDE_NAVIGATION_SEARCH_FIELD_PLACEHOLDER=Find in Navigation #XACT: Default ARIA label for the side navigation search field SIDE_NAVIGATION_SEARCH_FIELD_LABEL=Side navigation filter +#XACT: Accessible description of a side navigation item's indication tag, where {0} is the tag text +SIDE_NAVIGATION_LIST_ITEM_TAG_TEXT=Tag {0} + #XACT: Default ARIA description for the side navigation search field SIDE_NAVIGATION_SEARCH_DESCRIPTION=Results update as you type. Press Enter for the number of results diff --git a/packages/fiori/src/themes/NavigationMenuItem.css b/packages/fiori/src/themes/NavigationMenuItem.css index cb69064a32205..d92d0219a5dcc 100644 --- a/packages/fiori/src/themes/NavigationMenuItem.css +++ b/packages/fiori/src/themes/NavigationMenuItem.css @@ -1,3 +1,5 @@ +@import "./InvisibleTextStyles.css"; + :host::part(native-li)::after { border-radius: 0.375rem; inset: 0; @@ -92,10 +94,25 @@ margin-block-end: var(--_ui5_side_navigation_item_bottom_margin); } +.ui5-navmenu-item-text-tag-container { + flex: 1; + min-width: 0; + display: flex; + align-items: center; + flex-wrap: wrap; + column-gap: 0.5rem; + row-gap: 0.25rem; +} + +.ui5-navmenu-item-text { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; +} + .ui5-navmenu-item-tag-container { display: inline-flex; align-items: center; - margin-inline-start: 0.5rem; - height: 1.375rem; + margin-inline-start: 0; min-width: 1.375rem; } diff --git a/packages/fiori/src/themes/SideNavigationGroup.css b/packages/fiori/src/themes/SideNavigationGroup.css index c28a6eb844165..36bb241ffe60d 100644 --- a/packages/fiori/src/themes/SideNavigationGroup.css +++ b/packages/fiori/src/themes/SideNavigationGroup.css @@ -7,11 +7,18 @@ .ui5-sn-item.ui5-sn-item-group { min-height: 2rem; - padding-inline-start: var(--_ui5_side_navigation_group_padding);; + padding-inline-start: var(--_ui5_side_navigation_group_padding); font-family: var(--sapFontFamily); font-size: var(--sapFontSize); } +/* group has no text-tag container: the text fills the row (pushing the toggle icon to the end) + and carries the vertical margin that gives the group its height. */ +.ui5-sn-item.ui5-sn-item-group .ui5-sn-item-text { + flex: 1; + margin-block: var(--_ui5_side_navigation_item_margin); +} + .ui5-sn-item.ui5-sn-item-group:hover .ui5-sn-item-toggle-icon, .ui5-sn-item.ui5-sn-item-group:focus .ui5-sn-item-toggle-icon { display: block; diff --git a/packages/fiori/src/themes/SideNavigationItem.css b/packages/fiori/src/themes/SideNavigationItem.css index df99e0eda5aa0..a61b63954193c 100644 --- a/packages/fiori/src/themes/SideNavigationItem.css +++ b/packages/fiori/src/themes/SideNavigationItem.css @@ -1,5 +1,4 @@ @import "./SideNavigationItemBase.css"; -@import "./InvisibleTextStyles.css"; :host { color: var(--sapList_TextColor); @@ -17,10 +16,14 @@ } :host([in-popover]) .ui5-sn-item-level1 .ui5-sn-item-text { - margin: 0 0.375rem 0 0; + margin: 0; line-height: var(--_ui5_side_navigation_popup_title_line_height); } +:host([in-popover]) .ui5-sn-item-level1 .ui5-sn-item-text-tag-container { + padding-inline-end: 0.5rem; +} + .ui5-sn-item.ui5-sn-item-level1.ui5-sn-item-overflow { margin-top: auto; } diff --git a/packages/fiori/src/themes/SideNavigationItemBase.css b/packages/fiori/src/themes/SideNavigationItemBase.css index 206f489c6e0e7..1a549ad84da85 100644 --- a/packages/fiori/src/themes/SideNavigationItemBase.css +++ b/packages/fiori/src/themes/SideNavigationItemBase.css @@ -1,3 +1,5 @@ +@import "./InvisibleTextStyles.css"; + :host { display: block; } @@ -212,7 +214,6 @@ and there is an additional border that appears on hover. */ :host(:not([side-nav-collapsed])) .ui5-sn-item-toggle-icon { width: var(--_ui5_side_navigation_expand_icon_width); padding-inline-end: 0.375rem; - padding-block: var(--_ui5_side_navigation_item_expand_arrow_padding); margin-inline-start: 0.5rem; height: var(--sapElement_Condensed_Height); } @@ -336,9 +337,17 @@ and there is an additional border that appears on hover. */ display: none; } -.ui5-sn-item-text { +.ui5-sn-item-text-tag-container { flex: 1; min-width: 0; + display: flex; + align-items: center; + flex-wrap: wrap; + gap: 0.5rem; +} + +.ui5-sn-item-text { + min-width: 0; } :host([side-nav-collapsed]) .ui5-sn-item-text, @@ -354,28 +363,25 @@ and there is an additional border that appears on hover. */ white-space: nowrap; } -:host(:not([side-nav-collapsed]):not([in-popover])) .ui5-sn-item-text { - margin: var(--_ui5_side_navigation_item_margin) 0; +:host(:not([side-nav-collapsed])) .ui5-sn-item-text { + margin: 0; +} + +:host(:not([side-nav-collapsed]):not([design="Action"])) .ui5-sn-item:not(.ui5-sn-item-group) { + padding-block: var(--_ui5_side_navigation_item_margin); } -:host(:not([side-nav-collapsed])) .ui5-sn-item:not(.ui5-sn-item-group):not(.ui5-sn-item-with-expander) .ui5-sn-item-text { +:host(:not([side-nav-collapsed]):not([in-popover])) .ui5-sn-item:not(.ui5-sn-item-group):not(.ui5-sn-item-with-expander) .ui5-sn-item-text-tag-container:not(:has(+ .ui5-sn-item-toggle-icon)):not(:has(+ .ui5-sn-item-external-link-icon)) { padding-inline-end: 0.375rem; } .ui5-sn-item-tag-slot { - padding-inline-start: 0.5rem; - padding-inline-end: 0.375rem; display: inline-flex; align-items: center; } -.ui5-sn-item-tag-slot:has(+ .ui5-sn-item-toggle-icon), -.ui5-sn-item-tag-slot:has(+ .ui5-sn-item-external-link-icon) { - padding-inline-end: 0; -} - -.ui5-sn-item-tag-slot + .ui5-sn-item-toggle-icon, -.ui5-sn-item-tag-slot + .ui5-sn-item-external-link-icon { +.ui5-sn-item-text-tag-container + .ui5-sn-item-toggle-icon, +.ui5-sn-item-text-tag-container + .ui5-sn-item-external-link-icon { margin-inline-start: 0.375rem; } @@ -390,7 +396,21 @@ and there is an additional border that appears on hover. */ :host([in-popover]) .ui5-sn-item-tag-slot { display: inline-flex; - padding-inline-end: 0.5rem; +} + +/* Collapsed rail hover/focus flyout: tag stays on one line and truncates at 6rem. + The popover (in-popover) is NOT clamped - the tag shows full and the popover widens. */ +:host([side-nav-collapsed]) .ui5-sn-item-text-tag-container { + flex-wrap: nowrap; +} + +:host([side-nav-collapsed]) .ui5-sn-item-tag-slot { + max-width: 6rem; + overflow: hidden; +} + +:host([side-nav-collapsed]) .ui5-sn-item-tag-slot ::slotted([slot="tag"]) { + max-width: 6rem; } :host([side-nav-collapsed]) .ui5-sn-item-with-expander .ui5-sn-item-icon::after { diff --git a/packages/fiori/src/themes/base/SideNavigation-parameters.css b/packages/fiori/src/themes/base/SideNavigation-parameters.css index fa33dfaf370dc..fed771104e54f 100644 --- a/packages/fiori/src/themes/base/SideNavigation-parameters.css +++ b/packages/fiori/src/themes/base/SideNavigation-parameters.css @@ -24,7 +24,6 @@ --_ui5_side_navigation_item_border_width: 0; --_ui5_side_navigation_item_height: 2.75rem; --_ui5_side_navigation_item_margin: 0.875rem; - --_ui5_side_navigation_item_expand_arrow_padding: 0.6875rem; --_ui5_side_navigation_item_border_radius: 0; --_ui5_side_navigation_item_bottom_margin: 0; --_ui5_side_navigation_item_padding_start_in_popup: var(--_ui5_side_navigation_group_icon_width); @@ -69,7 +68,6 @@ @ui5-compact-size { :host { --_ui5_side_navigation_item_height: 2rem; - --_ui5_side_navigation_item_expand_arrow_padding: 0.3125rem; --_ui5_side_navigation_item_margin: 0.5rem; } } \ No newline at end of file diff --git a/packages/fiori/test/pages/SideNavigationTags.html b/packages/fiori/test/pages/SideNavigationTags.html index 6e11c033ce35f..0ba65f0ebb1db 100644 --- a/packages/fiori/test/pages/SideNavigationTags.html +++ b/packages/fiori/test/pages/SideNavigationTags.html @@ -155,7 +155,7 @@

Side Navigation Indication Tags - PoC

- Experimental + Experimental @@ -179,6 +179,86 @@

Side Navigation Indication Tags - PoC

+ +
+
+
+ + + Beta + + + + Beta Long Text Beta Long Text Beta Long Text + + Active Long Text Active Long Text Active Long Text Active Long Text + + + Pending + + + + + + + New + + + Updated + + + + + + New + + Beta + + + Deprecated + + + + + + Updated + + + + + + Info + + + + Nightly + + + + Experimental + + + + Updated + + + + Long tag Long tag + + + + + 24/7 Long Text 24/7 Long Text 24/7 Long Text + + + +
+
+ Toggle Collapsed +
+
+
+
@@ -194,7 +274,7 @@

Side Navigation Indication Tags - PoC

- Alpha Release + Alpha Release New Feature @@ -238,7 +318,12 @@

Side Navigation Indication Tags - PoC

sn.collapsed = !sn.collapsed; }); - ['sn-expanded', 'sn-collapsed', 'sn-wrapping'].forEach(id => { + document.getElementById('toggle-sn-ui5-tags').addEventListener('click', () => { + const sn = document.getElementById('sn-ui5-tags'); + sn.collapsed = !sn.collapsed; + }); + + ['sn-expanded', 'sn-collapsed', 'sn-wrapping', 'sn-ui5-tags'].forEach(id => { document.getElementById(id).addEventListener('selection-change', (e) => { console.log(`[${id}] Selection changed to:`, e.detail.item.text); });