diff --git a/packages/main/src/ListItemBase.ts b/packages/main/src/ListItemBase.ts index 3b80487df952..65c2d71e528f 100644 --- a/packages/main/src/ListItemBase.ts +++ b/packages/main/src/ListItemBase.ts @@ -122,6 +122,8 @@ class ListItemBase extends UI5Element implements ITabbable { onBeforeRendering(): void { this.actionable = true; + + this._toggleSelectedState(); } _onfocusin(e: FocusEvent) { @@ -133,6 +135,14 @@ class ListItemBase extends UI5Element implements ITabbable { this.fireDecoratorEvent("_focused", e); } + _toggleSelectedState() { + if (this.selected) { + this._internals.states.add("selected"); + } else { + this._internals.states.delete("selected"); + } + } + _onkeydown(e: KeyboardEvent) { if (isTabNext(e)) { return this._handleTabNext(e); diff --git a/packages/main/src/Menu.ts b/packages/main/src/Menu.ts index af035d4281f9..ed5fdd43bfcc 100644 --- a/packages/main/src/Menu.ts +++ b/packages/main/src/Menu.ts @@ -267,9 +267,7 @@ class Menu extends UI5Element { this.fireEvent("before-open", { item, }, false, false); - item._popover.opener = item; - item._popover.open = true; - item.selected = true; + item.open = true; } _closeItemSubMenu(item: MenuItem) { @@ -279,8 +277,7 @@ class Menu extends UI5Element { this._closeItemSubMenu(openedSibling); } - item._popover.open = false; - item.selected = false; + item.open = false; } } @@ -356,7 +353,7 @@ class Menu extends UI5Element { if (shouldOpenMenu) { this._openItemSubMenu(item); } else if (shouldCloseMenu && parentElement.hasAttribute("ui5-menu-item") && parentElement._popover) { - parentElement._popover.open = false; + parentElement.open = false; parentElement.selected = false; (parentElement._popover.opener as HTMLElement)?.focus(); } diff --git a/packages/main/src/MenuItem.hbs b/packages/main/src/MenuItem.hbs index 012631ac8e74..9e132b0c8675 100644 --- a/packages/main/src/MenuItem.hbs +++ b/packages/main/src/MenuItem.hbs @@ -48,6 +48,8 @@ prevent-initial-focus prevent-focus-restore hide-arrow + .opener={{_opener}} + ?open={{open}} allow-target-overlap sub-menu placement={{placement}} diff --git a/packages/main/src/MenuItem.ts b/packages/main/src/MenuItem.ts index dd2f218bff82..5532d2b0cbd0 100644 --- a/packages/main/src/MenuItem.ts +++ b/packages/main/src/MenuItem.ts @@ -108,6 +108,15 @@ class MenuItem extends ListItem implements IMenuItem { @property({ type: Boolean }) disabled = false; + /** + * Indicates if the menu is open + * @public + * @default false + * @since 1.10.0 + */ + @property({ type: Boolean }) + open = false; + /** * Defines the delay in milliseconds, after which the loading indicator will be displayed inside the corresponding ui5-menu popover. * @@ -255,6 +264,9 @@ class MenuItem extends ListItem implements IMenuItem { } onBeforeRendering() { + // super.onBeforeRendering(); + this._toggleSelectedState(); + const siblingsWithIcon = this._menuItems.some(menuItem => !!menuItem.icon); this._menuItems.forEach(item => { @@ -262,6 +274,18 @@ class MenuItem extends ListItem implements IMenuItem { }); } + get _opener() { + return this.getDomRef(); + } + + _toggleSelectedState() { + if (this.open) { + this._internals.states.add("selected"); + } else { + this._internals.states.delete("selected"); + } + } + async focus(focusOptions?: FocusOptions): Promise { await renderFinished(); @@ -296,17 +320,12 @@ class MenuItem extends ListItem implements IMenuItem { } _closeAll() { - if (this._popover) { - this._popover.open = false; - } - this.selected = false; + this.open = false; this.fireEvent("close-menu", {}); } _close() { - if (this._popover) { - this._popover.open = false; - } + this.open = false; this.selected = false; } diff --git a/packages/main/src/themes/ListItemBase.css b/packages/main/src/themes/ListItemBase.css index fd03a490727a..94bff0ae5582 100644 --- a/packages/main/src/themes/ListItemBase.css +++ b/packages/main/src/themes/ListItemBase.css @@ -24,7 +24,7 @@ } /* selected */ -:host([selected]) { +:host(:state(selected)) { background-color: var(--sapList_SelectionBackgroundColor); border-bottom: var(--ui5-listitem-selected-border-bottom); @@ -34,7 +34,7 @@ } /* hovered */ -:host([actionable]:not([active]):not([selected]):not([ui5-li-group-header]):hover) { +:host([actionable]:not([active]):not(:state(selected)):not([ui5-li-group-header]):hover) { background-color: var(--sapList_Hover_Background); .ui5-li-additional-text { @@ -43,13 +43,13 @@ } /* selected and hovered */ -:host([actionable][selected]:not([active], [data-moving]):hover) { +:host([actionable]:state(selected):not([active], [data-moving]):hover) { background-color: var(--sapList_Hover_SelectionBackground); } /* selected and active */ :host([active][actionable]:not([data-moving])), -:host([active][actionable][selected]:not([data-moving])) { +:host([active][actionable]:state(selected):not([data-moving])) { background-color: var(--sapList_Active_Background); } diff --git a/packages/main/src/themes/MenuItem.css b/packages/main/src/themes/MenuItem.css index 0d14f2ea3184..f72a8d8321f9 100644 --- a/packages/main/src/themes/MenuItem.css +++ b/packages/main/src/themes/MenuItem.css @@ -20,7 +20,7 @@ } /* hovered and active */ -:host([disabled][actionable]:not([active]):not([selected]):hover), +:host([disabled][actionable]:not([active]):not(:state(selected)):hover), :host([disabled][active][actionable]) { background: var(--ui5-listitem-background-color); } @@ -30,7 +30,7 @@ background-color: var(--sapList_Active_Background); } -:host(:not([active]):not([selected]):not([disabled]):hover) { +:host(:not([active]):not(:state(selected)):not([disabled]):hover) { background-color: var(--sapList_Hover_Background); }