From fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 03:14:29 +0200 Subject: Merging upstream version 125.0.1. Signed-off-by: Daniel Baumann --- .../content/widgets/panel-list/README.stories.md | 22 +++++++- toolkit/content/widgets/panel-list/panel-list.css | 4 ++ toolkit/content/widgets/panel-list/panel-list.js | 59 ++++++++++------------ .../widgets/panel-list/panel-list.stories.mjs | 45 +++++++++++++---- 4 files changed, 87 insertions(+), 43 deletions(-) (limited to 'toolkit/content/widgets/panel-list') diff --git a/toolkit/content/widgets/panel-list/README.stories.md b/toolkit/content/widgets/panel-list/README.stories.md index b8800e2b5f..3e8617958e 100644 --- a/toolkit/content/widgets/panel-list/README.stories.md +++ b/toolkit/content/widgets/panel-list/README.stories.md @@ -6,7 +6,7 @@ children and optional `hr` elements as separators. The `panel-list` will anchor itself to the target of the initiating event when opened with `panelList.toggle(event)`. -Note: Nested menus are not currently supported. XUL is currently required to +Note: XUL is currently required to support accesskey underlining (although using `moz-label` could change that). Shortcuts are not displayed automatically in the `panel-item`. @@ -229,3 +229,23 @@ grow larger than its containing window if needed. ``` + +### Submenus + +`panel-list` supports nested submenus. Submenus can be created by nesting a second `panel-list` in a `panel-item`'s `submenu` slot and specifying a `submenu` attribute on that `panel-item` that points to the nested list's ID. For example: + +```html + + No submenu + No submenu + + Has a submenu + + I'm a submenu item! + I'm also a submenu item! + + + +``` + +As of February 2024 submenus are only in use in Firefox View and support for nesting beyond one submenu may be limited. diff --git a/toolkit/content/widgets/panel-list/panel-list.css b/toolkit/content/widgets/panel-list/panel-list.css index 4358fc0cf8..619e6919a3 100644 --- a/toolkit/content/widgets/panel-list/panel-list.css +++ b/toolkit/content/widgets/panel-list/panel-list.css @@ -26,6 +26,10 @@ box-sizing: border-box; } +:host([has-submenu]) { + overflow-y: visible; +} + :host(:not([slot=submenu])) { max-height: 100%; } diff --git a/toolkit/content/widgets/panel-list/panel-list.js b/toolkit/content/widgets/panel-list/panel-list.js index 1cc1f865c3..2e93b4ddc3 100644 --- a/toolkit/content/widgets/panel-list/panel-list.js +++ b/toolkit/content/widgets/panel-list/panel-list.js @@ -308,7 +308,7 @@ } addHideListeners() { - if (this.hasAttribute("stay-open") && !this.lastAnchorNode.hasSubmenu) { + if (this.hasAttribute("stay-open") && !this.lastAnchorNode?.hasSubmenu) { // This is intended for inspection in Storybook. return; } @@ -631,31 +631,12 @@ this.#defaultSlot = document.createElement("slot"); this.#defaultSlot.style.display = "none"; - if (this.hasSubmenu) { - this.icon = document.createElement("div"); - this.icon.setAttribute("class", "submenu-icon"); - this.label.setAttribute("class", "submenu-label"); - - this.button.setAttribute("class", "submenu-container"); - this.button.appendChild(this.icon); - - this.submenuSlot = document.createElement("slot"); - this.submenuSlot.name = "submenu"; - - this.shadowRoot.append( - style, - this.button, - this.#defaultSlot, - this.submenuSlot - ); - } else { - this.shadowRoot.append( - style, - this.button, - supportLinkSlot, - this.#defaultSlot - ); - } + this.shadowRoot.append( + style, + this.button, + supportLinkSlot, + this.#defaultSlot + ); } connectedCallback() { @@ -664,6 +645,10 @@ this._l10nRootConnected = true; } + this.panel = + this.getRootNode()?.host?.closest("panel-list") || + this.closest("panel-list"); + if (!this.#initialized) { this.#initialized = true; // When click listeners are added to the panel-item it creates a node in @@ -683,18 +668,28 @@ }); if (this.hasSubmenu) { + this.panel.setAttribute("has-submenu", ""); + this.icon = document.createElement("div"); + this.icon.setAttribute("class", "submenu-icon"); + this.label.setAttribute("class", "submenu-label"); + + this.button.setAttribute("class", "submenu-container"); + this.button.appendChild(this.icon); + + this.submenuSlot = document.createElement("slot"); + this.submenuSlot.name = "submenu"; + + this.shadowRoot.append(this.submenuSlot); + this.setSubmenuContents(); } } - this.panel = - this.getRootNode()?.host?.closest("panel-list") || - this.closest("panel-list"); - if (this.panel) { this.panel.addEventListener("hidden", this); this.panel.addEventListener("shown", this); } + if (this.hasSubmenu) { this.addEventListener("mouseenter", this); this.addEventListener("mouseleave", this); @@ -762,7 +757,9 @@ setSubmenuContents() { this.submenuPanel = this.submenuSlot.assignedNodes()[0]; - this.shadowRoot.append(this.submenuPanel); + if (this.submenuPanel) { + this.shadowRoot.append(this.submenuPanel); + } } get disabled() { diff --git a/toolkit/content/widgets/panel-list/panel-list.stories.mjs b/toolkit/content/widgets/panel-list/panel-list.stories.mjs index 9c5a4cbe1f..db0ab7597c 100644 --- a/toolkit/content/widgets/panel-list/panel-list.stories.mjs +++ b/toolkit/content/widgets/panel-list/panel-list.stories.mjs @@ -22,6 +22,9 @@ panel-list-checked = Checked panel-list-badged = Badged, look at me panel-list-passwords = Passwords panel-list-settings = Settings +submenu-item-one = Submenu Item One +submenu-item-two = Submenu Item Two +submenu-item-three = Submenu Item Three `, }, }; @@ -36,7 +39,7 @@ function openMenu(event) { } } -const Template = ({ isOpen, items, wideAnchor }) => +const Template = ({ isOpen, items, wideAnchor, hasSubMenu }) => html`