@spectrum-web-components/menu 1.8.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +71 -4
- package/package.json +11 -11
- package/src/MenuItem.d.ts +15 -0
- package/src/MenuItem.dev.js +58 -1
- package/src/MenuItem.dev.js.map +2 -2
- package/src/MenuItem.js +4 -4
- package/src/MenuItem.js.map +3 -3
- package/src/menu-item.css.dev.js +1 -1
- package/src/menu-item.css.dev.js.map +1 -1
- package/src/menu-item.css.js +1 -1
- package/src/menu-item.css.js.map +1 -1
- package/src/spectrum-menu-item.css.dev.js +1 -1
- package/src/spectrum-menu-item.css.dev.js.map +1 -1
- package/src/spectrum-menu-item.css.js +1 -1
- package/src/spectrum-menu-item.css.js.map +1 -1
package/custom-elements.json
CHANGED
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"text": "object"
|
|
85
85
|
},
|
|
86
86
|
"static": true,
|
|
87
|
-
"default": "{
|
|
87
|
+
"default": "{ ...SpectrumElement.shadowRootOptions, delegatesFocus: true, }"
|
|
88
88
|
},
|
|
89
89
|
{
|
|
90
90
|
"kind": "field",
|
|
@@ -1121,7 +1121,7 @@
|
|
|
1121
1121
|
"text": "object"
|
|
1122
1122
|
},
|
|
1123
1123
|
"static": true,
|
|
1124
|
-
"default": "{
|
|
1124
|
+
"default": "{ ...SpectrumElement.shadowRootOptions, delegatesFocus: true, }",
|
|
1125
1125
|
"inheritedFrom": {
|
|
1126
1126
|
"name": "Menu",
|
|
1127
1127
|
"module": "src/Menu.js"
|
|
@@ -2386,7 +2386,7 @@
|
|
|
2386
2386
|
"type": {
|
|
2387
2387
|
"text": "MenuItem | undefined"
|
|
2388
2388
|
},
|
|
2389
|
-
"default": "
|
|
2389
|
+
"default": "this.getRootNode()"
|
|
2390
2390
|
},
|
|
2391
2391
|
{
|
|
2392
2392
|
"kind": "field",
|
|
@@ -2813,6 +2813,16 @@
|
|
|
2813
2813
|
}
|
|
2814
2814
|
]
|
|
2815
2815
|
},
|
|
2816
|
+
{
|
|
2817
|
+
"kind": "method",
|
|
2818
|
+
"name": "getActiveElementSafely",
|
|
2819
|
+
"privacy": "private",
|
|
2820
|
+
"return": {
|
|
2821
|
+
"type": {
|
|
2822
|
+
"text": "HTMLElement | null"
|
|
2823
|
+
}
|
|
2824
|
+
}
|
|
2825
|
+
},
|
|
2816
2826
|
{
|
|
2817
2827
|
"kind": "method",
|
|
2818
2828
|
"name": "handleMouseover",
|
|
@@ -2830,6 +2840,63 @@
|
|
|
2830
2840
|
}
|
|
2831
2841
|
]
|
|
2832
2842
|
},
|
|
2843
|
+
{
|
|
2844
|
+
"kind": "method",
|
|
2845
|
+
"name": "isInputElement",
|
|
2846
|
+
"privacy": "private",
|
|
2847
|
+
"return": {
|
|
2848
|
+
"type": {
|
|
2849
|
+
"text": "boolean"
|
|
2850
|
+
}
|
|
2851
|
+
},
|
|
2852
|
+
"parameters": [
|
|
2853
|
+
{
|
|
2854
|
+
"name": "element",
|
|
2855
|
+
"type": {
|
|
2856
|
+
"text": "HTMLElement"
|
|
2857
|
+
}
|
|
2858
|
+
}
|
|
2859
|
+
],
|
|
2860
|
+
"description": "Determines if an element is an input field that should retain focus.\nUses multiple detection strategies to identify input elements generically."
|
|
2861
|
+
},
|
|
2862
|
+
{
|
|
2863
|
+
"kind": "method",
|
|
2864
|
+
"name": "isNativeInputElement",
|
|
2865
|
+
"privacy": "private",
|
|
2866
|
+
"return": {
|
|
2867
|
+
"type": {
|
|
2868
|
+
"text": "boolean"
|
|
2869
|
+
}
|
|
2870
|
+
},
|
|
2871
|
+
"parameters": [
|
|
2872
|
+
{
|
|
2873
|
+
"name": "element",
|
|
2874
|
+
"type": {
|
|
2875
|
+
"text": "HTMLElement"
|
|
2876
|
+
}
|
|
2877
|
+
}
|
|
2878
|
+
],
|
|
2879
|
+
"description": "Checks if an element is a native HTML input element."
|
|
2880
|
+
},
|
|
2881
|
+
{
|
|
2882
|
+
"kind": "method",
|
|
2883
|
+
"name": "isSpectrumInputComponent",
|
|
2884
|
+
"privacy": "private",
|
|
2885
|
+
"return": {
|
|
2886
|
+
"type": {
|
|
2887
|
+
"text": "boolean"
|
|
2888
|
+
}
|
|
2889
|
+
},
|
|
2890
|
+
"parameters": [
|
|
2891
|
+
{
|
|
2892
|
+
"name": "element",
|
|
2893
|
+
"type": {
|
|
2894
|
+
"text": "HTMLElement"
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
],
|
|
2898
|
+
"description": "Checks if an element is a Spectrum Web Component with input behavior.\nUses ARIA roles and component patterns for generic detection."
|
|
2899
|
+
},
|
|
2833
2900
|
{
|
|
2834
2901
|
"kind": "field",
|
|
2835
2902
|
"name": "handleKeydown",
|
|
@@ -3127,7 +3194,7 @@
|
|
|
3127
3194
|
"text": "{\n focusRoot?: Menu;\n parentMenu?: Menu;\n selectionRoot?: Menu;\n cleanupSteps: ((item: MenuItem) => void)[];\n }"
|
|
3128
3195
|
},
|
|
3129
3196
|
"privacy": "public",
|
|
3130
|
-
"default": "{
|
|
3197
|
+
"default": "{ // menu that controls ArrowUp/ArrowDown navigation focusRoot: undefined, parentMenu: undefined, // menu or menu group that controls selection selectionRoot: undefined, cleanupSteps: [], }"
|
|
3131
3198
|
}
|
|
3132
3199
|
],
|
|
3133
3200
|
"events": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectrum-web-components/menu",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -95,16 +95,16 @@
|
|
|
95
95
|
"css"
|
|
96
96
|
],
|
|
97
97
|
"dependencies": {
|
|
98
|
-
"@lit-labs/observers": "
|
|
99
|
-
"@spectrum-web-components/action-button": "1.
|
|
100
|
-
"@spectrum-web-components/base": "1.
|
|
101
|
-
"@spectrum-web-components/divider": "1.
|
|
102
|
-
"@spectrum-web-components/icon": "1.
|
|
103
|
-
"@spectrum-web-components/icons-ui": "1.
|
|
104
|
-
"@spectrum-web-components/overlay": "1.
|
|
105
|
-
"@spectrum-web-components/popover": "1.
|
|
106
|
-
"@spectrum-web-components/reactive-controllers": "1.
|
|
107
|
-
"@spectrum-web-components/shared": "1.
|
|
98
|
+
"@lit-labs/observers": "2.0.2",
|
|
99
|
+
"@spectrum-web-components/action-button": "1.9.0",
|
|
100
|
+
"@spectrum-web-components/base": "1.9.0",
|
|
101
|
+
"@spectrum-web-components/divider": "1.9.0",
|
|
102
|
+
"@spectrum-web-components/icon": "1.9.0",
|
|
103
|
+
"@spectrum-web-components/icons-ui": "1.9.0",
|
|
104
|
+
"@spectrum-web-components/overlay": "1.9.0",
|
|
105
|
+
"@spectrum-web-components/popover": "1.9.0",
|
|
106
|
+
"@spectrum-web-components/reactive-controllers": "1.9.0",
|
|
107
|
+
"@spectrum-web-components/shared": "1.9.0"
|
|
108
108
|
},
|
|
109
109
|
"types": "./src/index.d.ts",
|
|
110
110
|
"customElements": "custom-elements.json",
|
package/src/MenuItem.d.ts
CHANGED
|
@@ -149,7 +149,22 @@ export declare class MenuItem extends MenuItem_base {
|
|
|
149
149
|
}): void;
|
|
150
150
|
private handlePointerdown;
|
|
151
151
|
protected firstUpdated(changes: PropertyValues): void;
|
|
152
|
+
private getActiveElementSafely;
|
|
152
153
|
handleMouseover(event: MouseEvent): void;
|
|
154
|
+
/**
|
|
155
|
+
* Determines if an element is an input field that should retain focus.
|
|
156
|
+
* Uses multiple detection strategies to identify input elements generically.
|
|
157
|
+
*/
|
|
158
|
+
private isInputElement;
|
|
159
|
+
/**
|
|
160
|
+
* Checks if an element is a native HTML input element.
|
|
161
|
+
*/
|
|
162
|
+
private isNativeInputElement;
|
|
163
|
+
/**
|
|
164
|
+
* Checks if an element is a Spectrum Web Component with input behavior.
|
|
165
|
+
* Uses ARIA roles and component patterns for generic detection.
|
|
166
|
+
*/
|
|
167
|
+
private isSpectrumInputComponent;
|
|
153
168
|
/**
|
|
154
169
|
* forward key info from keydown event to parent menu
|
|
155
170
|
*/
|
package/src/MenuItem.dev.js
CHANGED
|
@@ -11,6 +11,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
11
11
|
};
|
|
12
12
|
import {
|
|
13
13
|
html,
|
|
14
|
+
INPUT_COMPONENT_PATTERN,
|
|
14
15
|
nothing
|
|
15
16
|
} from "@spectrum-web-components/base";
|
|
16
17
|
import {
|
|
@@ -376,13 +377,69 @@ export class MenuItem extends LikeAnchor(
|
|
|
376
377
|
this.id = `sp-menu-item-${randomID()}`;
|
|
377
378
|
}
|
|
378
379
|
}
|
|
380
|
+
getActiveElementSafely() {
|
|
381
|
+
let root = this.getRootNode();
|
|
382
|
+
let activeElement = root.activeElement;
|
|
383
|
+
if (!activeElement && root !== document) {
|
|
384
|
+
while (root && root !== document && "host" in root) {
|
|
385
|
+
root = root.host.getRootNode();
|
|
386
|
+
activeElement = root.activeElement;
|
|
387
|
+
if (activeElement) break;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
return activeElement;
|
|
391
|
+
}
|
|
379
392
|
handleMouseover(event) {
|
|
380
393
|
const target = event.target;
|
|
381
394
|
if (target === this) {
|
|
382
|
-
this.
|
|
395
|
+
const activeElement = this.getActiveElementSafely();
|
|
396
|
+
if (!activeElement || !this.isInputElement(activeElement)) {
|
|
397
|
+
this.focus();
|
|
398
|
+
}
|
|
383
399
|
this.focused = false;
|
|
384
400
|
}
|
|
385
401
|
}
|
|
402
|
+
/**
|
|
403
|
+
* Determines if an element is an input field that should retain focus.
|
|
404
|
+
* Uses multiple detection strategies to identify input elements generically.
|
|
405
|
+
*/
|
|
406
|
+
isInputElement(element) {
|
|
407
|
+
if (this.isNativeInputElement(element)) {
|
|
408
|
+
return true;
|
|
409
|
+
}
|
|
410
|
+
if (element.contentEditable === "true") {
|
|
411
|
+
return true;
|
|
412
|
+
}
|
|
413
|
+
if (this.isSpectrumInputComponent(element)) {
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
return false;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Checks if an element is a native HTML input element.
|
|
420
|
+
*/
|
|
421
|
+
isNativeInputElement(element) {
|
|
422
|
+
return element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Checks if an element is a Spectrum Web Component with input behavior.
|
|
426
|
+
* Uses ARIA roles and component patterns for generic detection.
|
|
427
|
+
*/
|
|
428
|
+
isSpectrumInputComponent(element) {
|
|
429
|
+
if (!element.tagName.startsWith("SP-")) {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
const role = element.getAttribute("role");
|
|
433
|
+
const inputRoles = ["textbox", "searchbox", "combobox", "slider"];
|
|
434
|
+
if (role && inputRoles.includes(role)) {
|
|
435
|
+
return true;
|
|
436
|
+
}
|
|
437
|
+
const inputComponentPattern = INPUT_COMPONENT_PATTERN;
|
|
438
|
+
if (inputComponentPattern.test(element.tagName)) {
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
386
443
|
closeOverlaysForRoot() {
|
|
387
444
|
var _a;
|
|
388
445
|
if (this.open) return;
|
package/src/MenuItem.dev.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["MenuItem.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n CSSResultArray,\n html,\n nothing,\n PropertyValues,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {\n ObserveSlotPresence,\n ObserveSlotText,\n randomID,\n} from '@spectrum-web-components/shared';\nimport {\n property,\n query,\n} from '@spectrum-web-components/base/src/decorators.js';\n\nimport '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark100.js';\nimport { LikeAnchor } from '@spectrum-web-components/shared/src/like-anchor.js';\nimport { Focusable } from '@spectrum-web-components/shared/src/focusable.js';\nimport '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js';\nimport chevronStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js';\nimport { DependencyManagerController } from '@spectrum-web-components/reactive-controllers/src/DependencyManger.js';\n\nimport menuItemStyles from './menu-item.css.js';\nimport checkmarkStyles from '@spectrum-web-components/icon/src/spectrum-icon-checkmark.css.js';\nimport type { Menu } from './Menu.dev.js'\nimport { MutationController } from '@lit-labs/observers/mutation-controller.js';\nimport type { Overlay } from '@spectrum-web-components/overlay';\nimport { SlottableRequestEvent } from '@spectrum-web-components/overlay/src/slottable-request-event.js';\n\n/**\n * Duration during which a pointing device can leave an `<sp-menu-item>` element\n * and return to it or to the submenu opened from it before closing that submenu.\n **/\nconst POINTERLEAVE_TIMEOUT = 100;\n\ntype MenuCascadeItem = {\n hadFocusRoot: boolean;\n ancestorWithSelects?: HTMLElement;\n};\n\n/**\n * Fires when a menu item is added or updated so that a parent menu can track it.\n */\nexport class MenuItemAddedOrUpdatedEvent extends Event {\n constructor(item: MenuItem) {\n super('sp-menu-item-added-or-updated', {\n bubbles: true,\n composed: true,\n });\n this.clear(item);\n }\n clear(item: MenuItem): void {\n this._item = item;\n this.currentAncestorWithSelects = undefined;\n item.menuData = {\n cleanupSteps: [],\n focusRoot: undefined,\n selectionRoot: undefined,\n parentMenu: undefined,\n };\n this.menuCascade = new WeakMap<HTMLElement, MenuCascadeItem>();\n }\n menuCascade = new WeakMap<HTMLElement, MenuCascadeItem>();\n get item(): MenuItem {\n return this._item;\n }\n private _item!: MenuItem;\n currentAncestorWithSelects?: Menu;\n}\n\n/**\n * Fires to forward keyboard event information to parent menu.\n */\nexport class MenuItemKeydownEvent extends KeyboardEvent {\n root?: MenuItem;\n private _event?: KeyboardEvent;\n constructor({ root, event }: { root?: MenuItem; event?: KeyboardEvent }) {\n super('sp-menu-item-keydown', { bubbles: true, composed: true });\n this.root = root;\n this._event = event;\n }\n\n public override get altKey(): boolean {\n return this._event?.altKey || false;\n }\n\n public override get code(): string {\n return this._event?.code || '';\n }\n\n public override get ctrlKey(): boolean {\n return this._event?.ctrlKey || false;\n }\n\n public override get isComposing(): boolean {\n return this._event?.isComposing || false;\n }\n\n public override get key(): string {\n return this._event?.key || '';\n }\n\n public override get location(): number {\n return this._event?.location || 0;\n }\n\n public override get metaKey(): boolean {\n return this._event?.metaKey || false;\n }\n\n public override get repeat(): boolean {\n return this._event?.repeat || false;\n }\n\n public override get shiftKey(): boolean {\n return this._event?.shiftKey || false;\n }\n}\n\nexport type MenuItemChildren = { icon: Element[]; content: Node[] };\n\n/**\n * @element sp-menu-item\n *\n * @slot - text content to display within the Menu Item\n * @slot description - description to be placed below the label of the Menu Item\n * @slot icon - icon element to be placed at the start of the Menu Item\n * @slot value - content placed at the end of the Menu Item like values, keyboard shortcuts, etc.\n * @slot submenu - content placed in a submenu\n * @fires sp-menu-item-added - announces the item has been added so a parent menu can take ownerships\n */\nexport class MenuItem extends LikeAnchor(\n ObserveSlotText(ObserveSlotPresence(Focusable, '[slot=\"icon\"]'))\n) {\n public static override get styles(): CSSResultArray {\n return [menuItemStyles, checkmarkStyles, chevronStyles];\n }\n\n abortControllerSubmenu!: AbortController;\n\n /**\n * whether the menu item is active or has an active descendant\n */\n @property({ type: Boolean, reflect: true })\n public active = false;\n\n private dependencyManager = new DependencyManagerController(this);\n\n /**\n * whether the menu item has keyboard focus\n */\n @property({ type: Boolean, reflect: true })\n public focused = false;\n\n /**\n * whether the menu item is selected\n */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /**\n * value of the menu item which is used for selection\n */\n @property({ type: String })\n public get value(): string {\n return this._value || this.itemText;\n }\n\n public set value(value: string) {\n if (value === this._value) {\n return;\n }\n this._value = value || '';\n if (this._value) {\n this.setAttribute('value', this._value);\n } else {\n this.removeAttribute('value');\n }\n }\n\n private _value = '';\n\n /**\n * @private\n * text content of the menu item minus whitespace\n */\n public get itemText(): string {\n return this.itemChildren.content.reduce(\n (acc, node) => acc + (node.textContent || '').trim(),\n ''\n );\n }\n\n /**\n * whether the menu item has a submenu\n */\n @property({ type: Boolean, reflect: true, attribute: 'has-submenu' })\n public hasSubmenu = false;\n\n @query('slot:not([name])')\n contentSlot!: HTMLSlotElement;\n\n @query('slot[name=\"icon\"]')\n iconSlot!: HTMLSlotElement;\n\n /**\n * whether menu item text content should not wrap\n */\n @property({\n type: Boolean,\n reflect: true,\n attribute: 'no-wrap',\n hasChanged() {\n return false;\n },\n })\n public noWrap = false;\n\n @query('.anchor')\n private anchorElement!: HTMLAnchorElement;\n\n @query('sp-overlay')\n public overlayElement!: Overlay;\n\n private submenuElement?: HTMLElement;\n\n /**\n * the focusable element of the menu item\n */\n public override get focusElement(): HTMLElement {\n return this;\n }\n\n protected get hasIcon(): boolean {\n return this.slotContentIsPresent;\n }\n\n public get itemChildren(): MenuItemChildren {\n if (!this.iconSlot || !this.contentSlot) {\n return {\n icon: [],\n content: [],\n };\n }\n if (this._itemChildren) {\n return this._itemChildren;\n }\n const icon = this.iconSlot.assignedElements().map((element) => {\n const newElement = element.cloneNode(true) as HTMLElement;\n newElement.removeAttribute('slot');\n newElement.classList.toggle('icon');\n return newElement;\n });\n const content = this.contentSlot\n .assignedNodes()\n .map((node) => node.cloneNode(true));\n this._itemChildren = { icon, content };\n\n return this._itemChildren;\n }\n\n private _itemChildren?: MenuItemChildren;\n\n constructor() {\n super();\n this.addEventListener('click', this.handleClickCapture, {\n capture: true,\n });\n this.addEventListener('focus', this.handleFocus);\n this.addEventListener('blur', this.handleBlur);\n\n new MutationController(this, {\n config: {\n characterData: true,\n childList: true,\n subtree: true,\n attributeFilter: ['src'],\n },\n callback: (mutations) => {\n const isSubmenu = mutations.every(\n (mutation) =>\n (mutation.target as HTMLElement).slot === 'submenu'\n );\n if (isSubmenu) {\n return;\n }\n this.breakItemChildrenCache();\n },\n });\n }\n\n /**\n * whether submenu is open\n */\n @property({ type: Boolean, reflect: true })\n public open = false;\n\n /**\n * whether menu item's submenu is opened via keyboard\n */\n private _openedViaKeyboard = false;\n\n /**\n * whether menu item's submenu is closed via pointer leave\n */\n private _closedViaPointer = false;\n\n private handleClickCapture(event: Event): void | boolean {\n if (this.disabled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n event.stopPropagation();\n return false;\n }\n\n if (this.shouldProxyClick()) {\n return;\n }\n }\n\n private handleSlottableRequest = (event: SlottableRequestEvent): void => {\n this.submenuElement?.dispatchEvent(\n new SlottableRequestEvent(event.name, event.data)\n );\n };\n\n private proxyFocus = (): void => {\n this.focus();\n };\n\n private shouldProxyClick(): boolean {\n let handled = false;\n if (this.anchorElement) {\n this.anchorElement.click();\n handled = true;\n }\n return handled;\n }\n\n protected breakItemChildrenCache(): void {\n this._itemChildren = undefined;\n this.triggerUpdate();\n }\n\n protected renderSubmenu(): TemplateResult {\n const slot = html`\n <slot\n name=\"submenu\"\n @slotchange=${this.manageSubmenu}\n @sp-menu-item-added-or-updated=${{\n handleEvent: (event: MenuItemAddedOrUpdatedEvent) => {\n event.clear(event.item);\n },\n capture: true,\n }}\n @focusin=${(event: Event) => event.stopPropagation()}\n ></slot>\n `;\n if (!this.hasSubmenu) {\n return slot;\n }\n this.dependencyManager.add('sp-overlay');\n this.dependencyManager.add('sp-popover');\n import('@spectrum-web-components/overlay/sp-overlay.js');\n import('@spectrum-web-components/popover/sp-popover.js');\n return html`\n <sp-overlay\n receives-focus=\"false\"\n .triggerElement=${this as HTMLElement}\n ?disabled=${!this.hasSubmenu}\n ?open=${this.hasSubmenu &&\n this.open &&\n this.dependencyManager.loaded}\n .placement=${this.isLTR ? 'right-start' : 'left-start'}\n receives-focus=\"false\"\n .offset=${[-10, -5] as [number, number]}\n .type=${'auto'}\n @close=${(event: Event) => event.stopPropagation()}\n @slottable-request=${this.handleSlottableRequest}\n >\n <sp-popover\n @change=${(event: Event) => {\n this.handleSubmenuChange(event);\n this.open = false;\n }}\n @pointerenter=${this.handleSubmenuPointerenter}\n @pointerleave=${this.handleSubmenuPointerleave}\n @sp-menu-item-added-or-updated=${(event: Event) =>\n event.stopPropagation()}\n >\n ${slot}\n </sp-popover>\n </sp-overlay>\n <sp-icon-chevron100\n class=\"spectrum-UIIcon-ChevronRight100 chevron icon\"\n ></sp-icon-chevron100>\n `;\n }\n\n protected override render(): TemplateResult {\n return html`\n ${this.selected\n ? html`\n <sp-icon-checkmark100\n id=\"selected\"\n class=\"spectrum-UIIcon-Checkmark100\n icon\n checkmark\n ${this.hasIcon\n ? 'checkmark--withAdjacentIcon'\n : ''}\"\n ></sp-icon-checkmark100>\n `\n : nothing}\n <slot name=\"icon\"></slot>\n <div id=\"label\">\n <slot id=\"slot\"></slot>\n </div>\n <slot name=\"description\"></slot>\n <slot name=\"value\"></slot>\n ${this.href && this.href.length > 0\n ? super.renderAnchor({\n id: 'button',\n ariaHidden: true,\n className: 'button anchor hidden',\n })\n : nothing}\n ${this.renderSubmenu()}\n `;\n }\n\n /**\n * determines if item has a submenu and updates the `aria-haspopup` attribute\n */\n protected manageSubmenu(event: Event & { target: HTMLSlotElement }): void {\n this.submenuElement = event.target.assignedElements({\n flatten: true,\n })[0] as HTMLElement;\n this.hasSubmenu = !!this.submenuElement;\n if (this.hasSubmenu) {\n this.setAttribute('aria-haspopup', 'true');\n }\n }\n\n private handlePointerdown(event: PointerEvent): void {\n if (event.target === this && this.hasSubmenu && this.open) {\n this.addEventListener('focus', this.handleSubmenuFocus, {\n once: true,\n });\n this.overlayElement.addEventListener(\n 'beforetoggle',\n this.handleBeforetoggle\n );\n }\n }\n\n protected override firstUpdated(changes: PropertyValues): void {\n super.firstUpdated(changes);\n this.setAttribute('tabindex', '-1');\n this.addEventListener('keydown', this.handleKeydown);\n this.addEventListener('mouseover', this.handleMouseover);\n this.addEventListener('pointerdown', this.handlePointerdown);\n this.addEventListener('pointerenter', this.closeOverlaysForRoot);\n if (!this.hasAttribute('id')) {\n this.id = `sp-menu-item-${randomID()}`;\n }\n }\n handleMouseover(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n if (target === this) {\n this.focus();\n this.focused = false;\n }\n }\n /**\n * forward key info from keydown event to parent menu\n */\n handleKeydown = (event: KeyboardEvent): void => {\n const { target, key } = event;\n const openSubmenuKey =\n this.hasSubmenu && !this.open && [' ', 'Enter'].includes(key);\n if (target === this) {\n if (\n ['ArrowLeft', 'ArrowRight', 'Escape'].includes(key) ||\n openSubmenuKey\n )\n event.preventDefault();\n this.dispatchEvent(\n new MenuItemKeydownEvent({ root: this, event: event })\n );\n }\n };\n\n protected closeOverlaysForRoot(): void {\n if (this.open) return;\n this.menuData.parentMenu?.closeDescendentOverlays();\n }\n\n protected handleFocus(event: FocusEvent): void {\n const { target } = event;\n if (target === this) {\n this.focused = true;\n }\n }\n\n protected handleBlur(event: FocusEvent): void {\n const { target } = event;\n if (target === this) {\n this.focused = false;\n }\n }\n\n protected handleSubmenuClick(event: Event): void {\n if (event.composedPath().includes(this.overlayElement)) {\n return;\n }\n this.openOverlay(true);\n }\n\n protected handleSubmenuFocus(): void {\n requestAnimationFrame(() => {\n // Wait till after `closeDescendentOverlays` has happened in Menu\n // to reopen (keep open) the direct descendent of this Menu Item\n this.overlayElement.open = this.open;\n this.focused = false;\n });\n }\n\n protected handleBeforetoggle = (event: Event): void => {\n if ((event as Event & { newState: string }).newState === 'closed') {\n this.open = true;\n this.overlayElement.manuallyKeepOpen();\n this.overlayElement.removeEventListener(\n 'beforetoggle',\n this.handleBeforetoggle\n );\n }\n };\n\n protected handlePointerenter(): void {\n if (this.leaveTimeout) {\n clearTimeout(this.leaveTimeout);\n delete this.leaveTimeout;\n this.recentlyLeftChild = false;\n return;\n }\n this.focus();\n this.openOverlay();\n }\n\n protected leaveTimeout?: ReturnType<typeof setTimeout>;\n protected recentlyLeftChild = false;\n\n protected handlePointerleave(): void {\n this._closedViaPointer = true;\n if (this.open && !this.recentlyLeftChild) {\n this.leaveTimeout = setTimeout(() => {\n delete this.leaveTimeout;\n this.open = false;\n }, POINTERLEAVE_TIMEOUT);\n }\n }\n\n /**\n * When there is a `change` event in the submenu for this item\n * then we \"click\" this item to cascade the selection up the\n * menu tree allowing all submenus between the initial selection\n * and the root of the tree to have their selection changes and\n * be closed.\n */\n protected handleSubmenuChange(event: Event): void {\n event.stopPropagation();\n this.menuData.selectionRoot?.selectOrToggleItem(this);\n }\n\n protected handleSubmenuPointerenter(): void {\n this.recentlyLeftChild = true;\n }\n\n protected async handleSubmenuPointerleave(): Promise<void> {\n this.recentlyLeftChild = false;\n }\n\n protected handleSubmenuOpen(event: Event): void {\n const parentOverlay = event.composedPath().find((el) => {\n return (\n el !== this.overlayElement &&\n (el as HTMLElement).localName === 'sp-overlay'\n );\n }) as Overlay;\n if (this._openedViaKeyboard) {\n this.submenuElement?.focus();\n }\n this.overlayElement.parentOverlayToForceClose = parentOverlay;\n }\n\n protected cleanup(): void {\n this._closedViaPointer = false;\n this.setAttribute('aria-expanded', 'false');\n this.open = false;\n this.active = false;\n }\n\n public async openOverlay(shouldFocus: boolean = false): Promise<void> {\n if (!this.hasSubmenu || this.open || this.disabled) {\n return;\n }\n this.open = true;\n this.active = true;\n this.setAttribute('aria-expanded', 'true');\n this._openedViaKeyboard = shouldFocus;\n this.addEventListener('sp-closed', this.cleanup, {\n once: true,\n });\n }\n\n updateAriaSelected(): void {\n const role = this.getAttribute('role');\n if (role === 'option') {\n this.setAttribute(\n 'aria-selected',\n this.selected ? 'true' : 'false'\n );\n } else if (role === 'menuitemcheckbox' || role === 'menuitemradio') {\n this.setAttribute('aria-checked', this.selected ? 'true' : 'false');\n }\n }\n\n public setRole(role: string): void {\n this.setAttribute('role', role);\n this.updateAriaSelected();\n }\n\n protected override willUpdate(changes: PropertyValues<this>): void {\n super.updated(changes);\n\n // make sure focus returns to the anchor element when submenu is closed\n if (\n changes.has('open') &&\n !this.open &&\n this.hasSubmenu &&\n !this._closedViaPointer &&\n this.matches(':focus-within')\n ) {\n this.focus();\n }\n }\n\n protected override updated(changes: PropertyValues<this>): void {\n super.updated(changes);\n if (\n changes.has('label') &&\n (this.label || typeof changes.get('label') !== 'undefined')\n ) {\n this.setAttribute('aria-label', this.label || '');\n }\n if (\n changes.has('active') &&\n (this.active || typeof changes.get('active') !== 'undefined')\n ) {\n if (this.active) {\n this.menuData.selectionRoot?.closeDescendentOverlays();\n }\n }\n if (this.anchorElement) {\n this.anchorElement.addEventListener('focus', this.proxyFocus);\n this.anchorElement.tabIndex = -1;\n }\n if (changes.has('selected')) {\n this.updateAriaSelected();\n }\n if (\n changes.has('hasSubmenu') &&\n (this.hasSubmenu ||\n typeof changes.get('hasSubmenu') !== 'undefined')\n ) {\n if (this.hasSubmenu) {\n this.abortControllerSubmenu = new AbortController();\n const options = { signal: this.abortControllerSubmenu.signal };\n this.addEventListener(\n 'click',\n this.handleSubmenuClick,\n options\n );\n this.addEventListener(\n 'pointerenter',\n this.handlePointerenter,\n options\n );\n this.addEventListener(\n 'pointerleave',\n this.handlePointerleave,\n options\n );\n this.addEventListener(\n 'sp-opened',\n this.handleSubmenuOpen,\n options\n );\n } else {\n this.abortControllerSubmenu?.abort();\n }\n }\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.triggerUpdate();\n }\n\n _parentElement!: HTMLElement;\n\n public override disconnectedCallback(): void {\n this.menuData.cleanupSteps.forEach((removal) => removal(this));\n this.menuData = {\n focusRoot: undefined,\n parentMenu: undefined,\n selectionRoot: undefined,\n cleanupSteps: [],\n };\n super.disconnectedCallback();\n }\n\n private willDispatchUpdate = false;\n\n public async triggerUpdate(): Promise<void> {\n if (this.willDispatchUpdate) {\n return;\n }\n this.willDispatchUpdate = true;\n await new Promise((ready) => requestAnimationFrame(ready));\n this.dispatchUpdate();\n }\n\n public override focus(): void {\n super.focus();\n // ensure focus event fires in Chromium for tests\n this.dispatchEvent(new FocusEvent('focus'));\n }\n\n public override blur(): void {\n // ensure focus event fires in Chromium for tests\n this.dispatchEvent(new FocusEvent('blur'));\n super.blur();\n }\n\n public dispatchUpdate(): void {\n if (!this.isConnected) {\n return;\n }\n this.dispatchEvent(new MenuItemAddedOrUpdatedEvent(this));\n this.willDispatchUpdate = false;\n }\n\n public menuData: {\n focusRoot?: Menu;\n parentMenu?: Menu;\n selectionRoot?: Menu;\n cleanupSteps: ((item: MenuItem) => void)[];\n } = {\n // menu that controls ArrowUp/ArrowDown navigation\n focusRoot: undefined,\n parentMenu: undefined,\n // menu or menu group that controls selection\n selectionRoot: undefined,\n cleanupSteps: [],\n };\n}\n\ndeclare global {\n interface GlobalEventHandlersEventMap {\n 'sp-menu-item-added-or-updated': MenuItemAddedOrUpdatedEvent;\n }\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;AAYA;AAAA,EAEI;AAAA,EACA;AAAA,OAGG;AACP;AAAA,EACI;AAAA,EACA;AAAA,EACA;AAAA,OACG;AACP;AAAA,EACI;AAAA,EACA;AAAA,OACG;AAEP,OAAO;AACP,SAAS,kBAAkB;AAC3B,SAAS,iBAAiB;AAC1B,OAAO;AACP,OAAO,mBAAmB;AAC1B,SAAS,mCAAmC;AAE5C,OAAO,oBAAoB;AAC3B,OAAO,qBAAqB;AAE5B,SAAS,0BAA0B;AAEnC,SAAS,6BAA6B;AAMtC,MAAM,uBAAuB;AAUtB,aAAM,oCAAoC,MAAM;AAAA,EACnD,YAAY,MAAgB;AACxB,UAAM,iCAAiC;AAAA,MACnC,SAAS;AAAA,MACT,UAAU;AAAA,IACd,CAAC;AAcL,uBAAc,oBAAI,QAAsC;AAbpD,SAAK,MAAM,IAAI;AAAA,EACnB;AAAA,EACA,MAAM,MAAsB;AACxB,SAAK,QAAQ;AACb,SAAK,6BAA6B;AAClC,SAAK,WAAW;AAAA,MACZ,cAAc,CAAC;AAAA,MACf,WAAW;AAAA,MACX,eAAe;AAAA,MACf,YAAY;AAAA,IAChB;AACA,SAAK,cAAc,oBAAI,QAAsC;AAAA,EACjE;AAAA,EAEA,IAAI,OAAiB;AACjB,WAAO,KAAK;AAAA,EAChB;AAGJ;AAKO,aAAM,6BAA6B,cAAc;AAAA,EAGpD,YAAY,EAAE,MAAM,MAAM,GAA+C;AACrE,UAAM,wBAAwB,EAAE,SAAS,MAAM,UAAU,KAAK,CAAC;AAC/D,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,IAAoB,SAAkB;AAhG1C;AAiGQ,aAAO,UAAK,WAAL,mBAAa,WAAU;AAAA,EAClC;AAAA,EAEA,IAAoB,OAAe;AApGvC;AAqGQ,aAAO,UAAK,WAAL,mBAAa,SAAQ;AAAA,EAChC;AAAA,EAEA,IAAoB,UAAmB;AAxG3C;AAyGQ,aAAO,UAAK,WAAL,mBAAa,YAAW;AAAA,EACnC;AAAA,EAEA,IAAoB,cAAuB;AA5G/C;AA6GQ,aAAO,UAAK,WAAL,mBAAa,gBAAe;AAAA,EACvC;AAAA,EAEA,IAAoB,MAAc;AAhHtC;AAiHQ,aAAO,UAAK,WAAL,mBAAa,QAAO;AAAA,EAC/B;AAAA,EAEA,IAAoB,WAAmB;AApH3C;AAqHQ,aAAO,UAAK,WAAL,mBAAa,aAAY;AAAA,EACpC;AAAA,EAEA,IAAoB,UAAmB;AAxH3C;AAyHQ,aAAO,UAAK,WAAL,mBAAa,YAAW;AAAA,EACnC;AAAA,EAEA,IAAoB,SAAkB;AA5H1C;AA6HQ,aAAO,UAAK,WAAL,mBAAa,WAAU;AAAA,EAClC;AAAA,EAEA,IAAoB,WAAoB;AAhI5C;AAiIQ,aAAO,UAAK,WAAL,mBAAa,aAAY;AAAA,EACpC;AACJ;AAcO,aAAM,iBAAiB;AAAA,EAC1B,gBAAgB,oBAAoB,WAAW,eAAe,CAAC;AACnE,EAAE;AAAA,EAkIE,cAAc;AACV,UAAM;AAxHV,SAAO,SAAS;AAEhB,SAAQ,oBAAoB,IAAI,4BAA4B,IAAI;AAMhE,SAAO,UAAU;AAMjB,SAAO,WAAW;AAsBlB,SAAQ,SAAS;AAiBjB,SAAO,aAAa;AAmBpB,SAAO,SAAS;AA+EhB,SAAO,OAAO;AAKd;AAAA;AAAA;AAAA,SAAQ,qBAAqB;AAK7B;AAAA;AAAA;AAAA,SAAQ,oBAAoB;AAe5B,SAAQ,yBAAyB,CAAC,UAAuC;AA9U7E;AA+UQ,iBAAK,mBAAL,mBAAqB;AAAA,QACjB,IAAI,sBAAsB,MAAM,MAAM,MAAM,IAAI;AAAA;AAAA,IAExD;AAEA,SAAQ,aAAa,MAAY;AAC7B,WAAK,MAAM;AAAA,IACf;AAqJA;AAAA;AAAA;AAAA,yBAAgB,CAAC,UAA+B;AAC5C,YAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,YAAM,iBACF,KAAK,cAAc,CAAC,KAAK,QAAQ,CAAC,KAAK,OAAO,EAAE,SAAS,GAAG;AAChE,UAAI,WAAW,MAAM;AACjB,YACI,CAAC,aAAa,cAAc,QAAQ,EAAE,SAAS,GAAG,KAClD;AAEA,gBAAM,eAAe;AACzB,aAAK;AAAA,UACD,IAAI,qBAAqB,EAAE,MAAM,MAAM,MAAa,CAAC;AAAA,QACzD;AAAA,MACJ;AAAA,IACJ;AAqCA,SAAU,qBAAqB,CAAC,UAAuB;AACnD,UAAK,MAAuC,aAAa,UAAU;AAC/D,aAAK,OAAO;AACZ,aAAK,eAAe,iBAAiB;AACrC,aAAK,eAAe;AAAA,UAChB;AAAA,UACA,KAAK;AAAA,QACT;AAAA,MACJ;AAAA,IACJ;AAcA,SAAU,oBAAoB;AA4K9B,SAAQ,qBAAqB;AA+B7B,SAAO,WAKH;AAAA;AAAA,MAEA,WAAW;AAAA,MACX,YAAY;AAAA;AAAA,MAEZ,eAAe;AAAA,MACf,cAAc,CAAC;AAAA,IACnB;AArfI,SAAK,iBAAiB,SAAS,KAAK,oBAAoB;AAAA,MACpD,SAAS;AAAA,IACb,CAAC;AACD,SAAK,iBAAiB,SAAS,KAAK,WAAW;AAC/C,SAAK,iBAAiB,QAAQ,KAAK,UAAU;AAE7C,QAAI,mBAAmB,MAAM;AAAA,MACzB,QAAQ;AAAA,QACJ,eAAe;AAAA,QACf,WAAW;AAAA,QACX,SAAS;AAAA,QACT,iBAAiB,CAAC,KAAK;AAAA,MAC3B;AAAA,MACA,UAAU,CAAC,cAAc;AACrB,cAAM,YAAY,UAAU;AAAA,UACxB,CAAC,aACI,SAAS,OAAuB,SAAS;AAAA,QAClD;AACA,YAAI,WAAW;AACX;AAAA,QACJ;AACA,aAAK,uBAAuB;AAAA,MAChC;AAAA,IACJ,CAAC;AAAA,EACL;AAAA,EA3JA,WAA2B,SAAyB;AAChD,WAAO,CAAC,gBAAgB,iBAAiB,aAAa;AAAA,EAC1D;AAAA,EA4BA,IAAW,QAAgB;AACvB,WAAO,KAAK,UAAU,KAAK;AAAA,EAC/B;AAAA,EAEA,IAAW,MAAM,OAAe;AAC5B,QAAI,UAAU,KAAK,QAAQ;AACvB;AAAA,IACJ;AACA,SAAK,SAAS,SAAS;AACvB,QAAI,KAAK,QAAQ;AACb,WAAK,aAAa,SAAS,KAAK,MAAM;AAAA,IAC1C,OAAO;AACH,WAAK,gBAAgB,OAAO;AAAA,IAChC;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAW,WAAmB;AAC1B,WAAO,KAAK,aAAa,QAAQ;AAAA,MAC7B,CAAC,KAAK,SAAS,OAAO,KAAK,eAAe,IAAI,KAAK;AAAA,MACnD;AAAA,IACJ;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAsCA,IAAoB,eAA4B;AAC5C,WAAO;AAAA,EACX;AAAA,EAEA,IAAc,UAAmB;AAC7B,WAAO,KAAK;AAAA,EAChB;AAAA,EAEA,IAAW,eAAiC;AACxC,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,aAAa;AACrC,aAAO;AAAA,QACH,MAAM,CAAC;AAAA,QACP,SAAS,CAAC;AAAA,MACd;AAAA,IACJ;AACA,QAAI,KAAK,eAAe;AACpB,aAAO,KAAK;AAAA,IAChB;AACA,UAAM,OAAO,KAAK,SAAS,iBAAiB,EAAE,IAAI,CAAC,YAAY;AAC3D,YAAM,aAAa,QAAQ,UAAU,IAAI;AACzC,iBAAW,gBAAgB,MAAM;AACjC,iBAAW,UAAU,OAAO,MAAM;AAClC,aAAO;AAAA,IACX,CAAC;AACD,UAAM,UAAU,KAAK,YAChB,cAAc,EACd,IAAI,CAAC,SAAS,KAAK,UAAU,IAAI,CAAC;AACvC,SAAK,gBAAgB,EAAE,MAAM,QAAQ;AAErC,WAAO,KAAK;AAAA,EAChB;AAAA,EAgDQ,mBAAmB,OAA8B;AACrD,QAAI,KAAK,UAAU;AACf,YAAM,eAAe;AACrB,YAAM,yBAAyB;AAC/B,YAAM,gBAAgB;AACtB,aAAO;AAAA,IACX;AAEA,QAAI,KAAK,iBAAiB,GAAG;AACzB;AAAA,IACJ;AAAA,EACJ;AAAA,EAYQ,mBAA4B;AAChC,QAAI,UAAU;AACd,QAAI,KAAK,eAAe;AACpB,WAAK,cAAc,MAAM;AACzB,gBAAU;AAAA,IACd;AACA,WAAO;AAAA,EACX;AAAA,EAEU,yBAA+B;AACrC,SAAK,gBAAgB;AACrB,SAAK,cAAc;AAAA,EACvB;AAAA,EAEU,gBAAgC;AACtC,UAAM,OAAO;AAAA;AAAA;AAAA,8BAGS,KAAK,aAAa;AAAA,iDACC;AAAA,MAC7B,aAAa,CAAC,UAAuC;AACjD,cAAM,MAAM,MAAM,IAAI;AAAA,MAC1B;AAAA,MACA,SAAS;AAAA,IACb,CAAC;AAAA,2BACU,CAAC,UAAiB,MAAM,gBAAgB,CAAC;AAAA;AAAA;AAG5D,QAAI,CAAC,KAAK,YAAY;AAClB,aAAO;AAAA,IACX;AACA,SAAK,kBAAkB,IAAI,YAAY;AACvC,SAAK,kBAAkB,IAAI,YAAY;AACvC,WAAO,gDAAgD;AACvD,WAAO,gDAAgD;AACvD,WAAO;AAAA;AAAA;AAAA,kCAGmB,IAAmB;AAAA,4BACzB,CAAC,KAAK,UAAU;AAAA,wBACpB,KAAK,cACb,KAAK,QACL,KAAK,kBAAkB,MAAM;AAAA,6BAChB,KAAK,QAAQ,gBAAgB,YAAY;AAAA;AAAA,0BAE5C,CAAC,KAAK,EAAE,CAAqB;AAAA,wBAC/B,MAAM;AAAA,yBACL,CAAC,UAAiB,MAAM,gBAAgB,CAAC;AAAA,qCAC7B,KAAK,sBAAsB;AAAA;AAAA;AAAA,8BAGlC,CAAC,UAAiB;AACxB,WAAK,oBAAoB,KAAK;AAC9B,WAAK,OAAO;AAAA,IAChB,CAAC;AAAA,oCACe,KAAK,yBAAyB;AAAA,oCAC9B,KAAK,yBAAyB;AAAA,qDACb,CAAC,UAC9B,MAAM,gBAAgB,CAAC;AAAA;AAAA,sBAEzB,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtB;AAAA,EAEmB,SAAyB;AACxC,WAAO;AAAA,cACD,KAAK,WACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8BAMY,KAAK,UACH,gCACA,EAAE;AAAA;AAAA,sBAGhB,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAOX,KAAK,QAAQ,KAAK,KAAK,SAAS,IAC5B,MAAM,aAAa;AAAA,MACf,IAAI;AAAA,MACJ,YAAY;AAAA,MACZ,WAAW;AAAA,IACf,CAAC,IACD,OAAO;AAAA,cACX,KAAK,cAAc,CAAC;AAAA;AAAA,EAE9B;AAAA;AAAA;AAAA;AAAA,EAKU,cAAc,OAAkD;AACtE,SAAK,iBAAiB,MAAM,OAAO,iBAAiB;AAAA,MAChD,SAAS;AAAA,IACb,CAAC,EAAE,CAAC;AACJ,SAAK,aAAa,CAAC,CAAC,KAAK;AACzB,QAAI,KAAK,YAAY;AACjB,WAAK,aAAa,iBAAiB,MAAM;AAAA,IAC7C;AAAA,EACJ;AAAA,EAEQ,kBAAkB,OAA2B;AACjD,QAAI,MAAM,WAAW,QAAQ,KAAK,cAAc,KAAK,MAAM;AACvD,WAAK,iBAAiB,SAAS,KAAK,oBAAoB;AAAA,QACpD,MAAM;AAAA,MACV,CAAC;AACD,WAAK,eAAe;AAAA,QAChB;AAAA,QACA,KAAK;AAAA,MACT;AAAA,IACJ;AAAA,EACJ;AAAA,EAEmB,aAAa,SAA+B;AAC3D,UAAM,aAAa,OAAO;AAC1B,SAAK,aAAa,YAAY,IAAI;AAClC,SAAK,iBAAiB,WAAW,KAAK,aAAa;AACnD,SAAK,iBAAiB,aAAa,KAAK,eAAe;AACvD,SAAK,iBAAiB,eAAe,KAAK,iBAAiB;AAC3D,SAAK,iBAAiB,gBAAgB,KAAK,oBAAoB;AAC/D,QAAI,CAAC,KAAK,aAAa,IAAI,GAAG;AAC1B,WAAK,KAAK,gBAAgB,SAAS,CAAC;AAAA,IACxC;AAAA,EACJ;AAAA,EACA,gBAAgB,OAAyB;AACrC,UAAM,SAAS,MAAM;AACrB,QAAI,WAAW,MAAM;AACjB,WAAK,MAAM;AACX,WAAK,UAAU;AAAA,IACnB;AAAA,EACJ;AAAA,EAoBU,uBAA6B;AA3f3C;AA4fQ,QAAI,KAAK,KAAM;AACf,eAAK,SAAS,eAAd,mBAA0B;AAAA,EAC9B;AAAA,EAEU,YAAY,OAAyB;AAC3C,UAAM,EAAE,OAAO,IAAI;AACnB,QAAI,WAAW,MAAM;AACjB,WAAK,UAAU;AAAA,IACnB;AAAA,EACJ;AAAA,EAEU,WAAW,OAAyB;AAC1C,UAAM,EAAE,OAAO,IAAI;AACnB,QAAI,WAAW,MAAM;AACjB,WAAK,UAAU;AAAA,IACnB;AAAA,EACJ;AAAA,EAEU,mBAAmB,OAAoB;AAC7C,QAAI,MAAM,aAAa,EAAE,SAAS,KAAK,cAAc,GAAG;AACpD;AAAA,IACJ;AACA,SAAK,YAAY,IAAI;AAAA,EACzB;AAAA,EAEU,qBAA2B;AACjC,0BAAsB,MAAM;AAGxB,WAAK,eAAe,OAAO,KAAK;AAChC,WAAK,UAAU;AAAA,IACnB,CAAC;AAAA,EACL;AAAA,EAaU,qBAA2B;AACjC,QAAI,KAAK,cAAc;AACnB,mBAAa,KAAK,YAAY;AAC9B,aAAO,KAAK;AACZ,WAAK,oBAAoB;AACzB;AAAA,IACJ;AACA,SAAK,MAAM;AACX,SAAK,YAAY;AAAA,EACrB;AAAA,EAKU,qBAA2B;AACjC,SAAK,oBAAoB;AACzB,QAAI,KAAK,QAAQ,CAAC,KAAK,mBAAmB;AACtC,WAAK,eAAe,WAAW,MAAM;AACjC,eAAO,KAAK;AACZ,aAAK,OAAO;AAAA,MAChB,GAAG,oBAAoB;AAAA,IAC3B;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASU,oBAAoB,OAAoB;AAxkBtD;AAykBQ,UAAM,gBAAgB;AACtB,eAAK,SAAS,kBAAd,mBAA6B,mBAAmB;AAAA,EACpD;AAAA,EAEU,4BAAkC;AACxC,SAAK,oBAAoB;AAAA,EAC7B;AAAA,EAEA,MAAgB,4BAA2C;AACvD,SAAK,oBAAoB;AAAA,EAC7B;AAAA,EAEU,kBAAkB,OAAoB;AArlBpD;AAslBQ,UAAM,gBAAgB,MAAM,aAAa,EAAE,KAAK,CAAC,OAAO;AACpD,aACI,OAAO,KAAK,kBACX,GAAmB,cAAc;AAAA,IAE1C,CAAC;AACD,QAAI,KAAK,oBAAoB;AACzB,iBAAK,mBAAL,mBAAqB;AAAA,IACzB;AACA,SAAK,eAAe,4BAA4B;AAAA,EACpD;AAAA,EAEU,UAAgB;AACtB,SAAK,oBAAoB;AACzB,SAAK,aAAa,iBAAiB,OAAO;AAC1C,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAClB;AAAA,EAEA,MAAa,YAAY,cAAuB,OAAsB;AAClE,QAAI,CAAC,KAAK,cAAc,KAAK,QAAQ,KAAK,UAAU;AAChD;AAAA,IACJ;AACA,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,aAAa,iBAAiB,MAAM;AACzC,SAAK,qBAAqB;AAC1B,SAAK,iBAAiB,aAAa,KAAK,SAAS;AAAA,MAC7C,MAAM;AAAA,IACV,CAAC;AAAA,EACL;AAAA,EAEA,qBAA2B;AACvB,UAAM,OAAO,KAAK,aAAa,MAAM;AACrC,QAAI,SAAS,UAAU;AACnB,WAAK;AAAA,QACD;AAAA,QACA,KAAK,WAAW,SAAS;AAAA,MAC7B;AAAA,IACJ,WAAW,SAAS,sBAAsB,SAAS,iBAAiB;AAChE,WAAK,aAAa,gBAAgB,KAAK,WAAW,SAAS,OAAO;AAAA,IACtE;AAAA,EACJ;AAAA,EAEO,QAAQ,MAAoB;AAC/B,SAAK,aAAa,QAAQ,IAAI;AAC9B,SAAK,mBAAmB;AAAA,EAC5B;AAAA,EAEmB,WAAW,SAAqC;AAC/D,UAAM,QAAQ,OAAO;AAGrB,QACI,QAAQ,IAAI,MAAM,KAClB,CAAC,KAAK,QACN,KAAK,cACL,CAAC,KAAK,qBACN,KAAK,QAAQ,eAAe,GAC9B;AACE,WAAK,MAAM;AAAA,IACf;AAAA,EACJ;AAAA,EAEmB,QAAQ,SAAqC;AAtpBpE;AAupBQ,UAAM,QAAQ,OAAO;AACrB,QACI,QAAQ,IAAI,OAAO,MAClB,KAAK,SAAS,OAAO,QAAQ,IAAI,OAAO,MAAM,cACjD;AACE,WAAK,aAAa,cAAc,KAAK,SAAS,EAAE;AAAA,IACpD;AACA,QACI,QAAQ,IAAI,QAAQ,MACnB,KAAK,UAAU,OAAO,QAAQ,IAAI,QAAQ,MAAM,cACnD;AACE,UAAI,KAAK,QAAQ;AACb,mBAAK,SAAS,kBAAd,mBAA6B;AAAA,MACjC;AAAA,IACJ;AACA,QAAI,KAAK,eAAe;AACpB,WAAK,cAAc,iBAAiB,SAAS,KAAK,UAAU;AAC5D,WAAK,cAAc,WAAW;AAAA,IAClC;AACA,QAAI,QAAQ,IAAI,UAAU,GAAG;AACzB,WAAK,mBAAmB;AAAA,IAC5B;AACA,QACI,QAAQ,IAAI,YAAY,MACvB,KAAK,cACF,OAAO,QAAQ,IAAI,YAAY,MAAM,cAC3C;AACE,UAAI,KAAK,YAAY;AACjB,aAAK,yBAAyB,IAAI,gBAAgB;AAClD,cAAM,UAAU,EAAE,QAAQ,KAAK,uBAAuB,OAAO;AAC7D,aAAK;AAAA,UACD;AAAA,UACA,KAAK;AAAA,UACL;AAAA,QACJ;AACA,aAAK;AAAA,UACD;AAAA,UACA,KAAK;AAAA,UACL;AAAA,QACJ;AACA,aAAK;AAAA,UACD;AAAA,UACA,KAAK;AAAA,UACL;AAAA,QACJ;AACA,aAAK;AAAA,UACD;AAAA,UACA,KAAK;AAAA,UACL;AAAA,QACJ;AAAA,MACJ,OAAO;AACH,mBAAK,2BAAL,mBAA6B;AAAA,MACjC;AAAA,IACJ;AAAA,EACJ;AAAA,EAEgB,oBAA0B;AACtC,UAAM,kBAAkB;AACxB,SAAK,cAAc;AAAA,EACvB;AAAA,EAIgB,uBAA6B;AACzC,SAAK,SAAS,aAAa,QAAQ,CAAC,YAAY,QAAQ,IAAI,CAAC;AAC7D,SAAK,WAAW;AAAA,MACZ,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,cAAc,CAAC;AAAA,IACnB;AACA,UAAM,qBAAqB;AAAA,EAC/B;AAAA,EAIA,MAAa,gBAA+B;AACxC,QAAI,KAAK,oBAAoB;AACzB;AAAA,IACJ;AACA,SAAK,qBAAqB;AAC1B,UAAM,IAAI,QAAQ,CAAC,UAAU,sBAAsB,KAAK,CAAC;AACzD,SAAK,eAAe;AAAA,EACxB;AAAA,EAEgB,QAAc;AAC1B,UAAM,MAAM;AAEZ,SAAK,cAAc,IAAI,WAAW,OAAO,CAAC;AAAA,EAC9C;AAAA,EAEgB,OAAa;AAEzB,SAAK,cAAc,IAAI,WAAW,MAAM,CAAC;AACzC,UAAM,KAAK;AAAA,EACf;AAAA,EAEO,iBAAuB;AAC1B,QAAI,CAAC,KAAK,aAAa;AACnB;AAAA,IACJ;AACA,SAAK,cAAc,IAAI,4BAA4B,IAAI,CAAC;AACxD,SAAK,qBAAqB;AAAA,EAC9B;AAeJ;AA/mBW;AAAA,EADN,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAZjC,SAaF;AAQA;AAAA,EADN,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GApBjC,SAqBF;AAMA;AAAA,EADN,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GA1BjC,SA2BF;AAMI;AAAA,EADV,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAhCjB,SAiCE;AAiCJ;AAAA,EADN,SAAS,EAAE,MAAM,SAAS,SAAS,MAAM,WAAW,cAAc,CAAC;AAAA,GAjE3D,SAkEF;AAGP;AAAA,EADC,MAAM,kBAAkB;AAAA,GApEhB,SAqET;AAGA;AAAA,EADC,MAAM,mBAAmB;AAAA,GAvEjB,SAwET;AAaO;AAAA,EARN,SAAS;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,WAAW;AAAA,IACX,aAAa;AACT,aAAO;AAAA,IACX;AAAA,EACJ,CAAC;AAAA,GApFQ,SAqFF;AAGC;AAAA,EADP,MAAM,SAAS;AAAA,GAvFP,SAwFD;AAGD;AAAA,EADN,MAAM,YAAY;AAAA,GA1FV,SA2FF;AAyEA;AAAA,EADN,SAAS,EAAE,MAAM,SAAS,SAAS,KAAK,CAAC;AAAA,GAnKjC,SAoKF;",
|
|
4
|
+
"sourcesContent": ["/**\n * Copyright 2025 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {\n CSSResultArray,\n html,\n INPUT_COMPONENT_PATTERN,\n nothing,\n PropertyValues,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {\n ObserveSlotPresence,\n ObserveSlotText,\n randomID,\n} from '@spectrum-web-components/shared';\nimport {\n property,\n query,\n} from '@spectrum-web-components/base/src/decorators.js';\n\nimport '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark100.js';\nimport { LikeAnchor } from '@spectrum-web-components/shared/src/like-anchor.js';\nimport { Focusable } from '@spectrum-web-components/shared/src/focusable.js';\nimport '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js';\nimport chevronStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js';\nimport { DependencyManagerController } from '@spectrum-web-components/reactive-controllers/src/DependencyManger.js';\n\nimport menuItemStyles from './menu-item.css.js';\nimport checkmarkStyles from '@spectrum-web-components/icon/src/spectrum-icon-checkmark.css.js';\nimport type { Menu } from './Menu.dev.js'\nimport { MutationController } from '@lit-labs/observers/mutation-controller.js';\nimport type { Overlay } from '@spectrum-web-components/overlay';\nimport { SlottableRequestEvent } from '@spectrum-web-components/overlay/src/slottable-request-event.js';\n\n/**\n * Duration during which a pointing device can leave an `<sp-menu-item>` element\n * and return to it or to the submenu opened from it before closing that submenu.\n **/\nconst POINTERLEAVE_TIMEOUT = 100;\n\ntype MenuCascadeItem = {\n hadFocusRoot: boolean;\n ancestorWithSelects?: HTMLElement;\n};\n\n/**\n * Fires when a menu item is added or updated so that a parent menu can track it.\n */\nexport class MenuItemAddedOrUpdatedEvent extends Event {\n constructor(item: MenuItem) {\n super('sp-menu-item-added-or-updated', {\n bubbles: true,\n composed: true,\n });\n this.clear(item);\n }\n clear(item: MenuItem): void {\n this._item = item;\n this.currentAncestorWithSelects = undefined;\n item.menuData = {\n cleanupSteps: [],\n focusRoot: undefined,\n selectionRoot: undefined,\n parentMenu: undefined,\n };\n this.menuCascade = new WeakMap<HTMLElement, MenuCascadeItem>();\n }\n menuCascade = new WeakMap<HTMLElement, MenuCascadeItem>();\n get item(): MenuItem {\n return this._item;\n }\n private _item!: MenuItem;\n currentAncestorWithSelects?: Menu;\n}\n\n/**\n * Fires to forward keyboard event information to parent menu.\n */\nexport class MenuItemKeydownEvent extends KeyboardEvent {\n root?: MenuItem;\n private _event?: KeyboardEvent;\n constructor({ root, event }: { root?: MenuItem; event?: KeyboardEvent }) {\n super('sp-menu-item-keydown', { bubbles: true, composed: true });\n this.root = root;\n this._event = event;\n }\n\n public override get altKey(): boolean {\n return this._event?.altKey || false;\n }\n\n public override get code(): string {\n return this._event?.code || '';\n }\n\n public override get ctrlKey(): boolean {\n return this._event?.ctrlKey || false;\n }\n\n public override get isComposing(): boolean {\n return this._event?.isComposing || false;\n }\n\n public override get key(): string {\n return this._event?.key || '';\n }\n\n public override get location(): number {\n return this._event?.location || 0;\n }\n\n public override get metaKey(): boolean {\n return this._event?.metaKey || false;\n }\n\n public override get repeat(): boolean {\n return this._event?.repeat || false;\n }\n\n public override get shiftKey(): boolean {\n return this._event?.shiftKey || false;\n }\n}\n\nexport type MenuItemChildren = { icon: Element[]; content: Node[] };\n\n/**\n * @element sp-menu-item\n *\n * @slot - text content to display within the Menu Item\n * @slot description - description to be placed below the label of the Menu Item\n * @slot icon - icon element to be placed at the start of the Menu Item\n * @slot value - content placed at the end of the Menu Item like values, keyboard shortcuts, etc.\n * @slot submenu - content placed in a submenu\n * @fires sp-menu-item-added - announces the item has been added so a parent menu can take ownerships\n */\nexport class MenuItem extends LikeAnchor(\n ObserveSlotText(ObserveSlotPresence(Focusable, '[slot=\"icon\"]'))\n) {\n public static override get styles(): CSSResultArray {\n return [menuItemStyles, checkmarkStyles, chevronStyles];\n }\n\n abortControllerSubmenu!: AbortController;\n\n /**\n * whether the menu item is active or has an active descendant\n */\n @property({ type: Boolean, reflect: true })\n public active = false;\n\n private dependencyManager = new DependencyManagerController(this);\n\n /**\n * whether the menu item has keyboard focus\n */\n @property({ type: Boolean, reflect: true })\n public focused = false;\n\n /**\n * whether the menu item is selected\n */\n @property({ type: Boolean, reflect: true })\n public selected = false;\n\n /**\n * value of the menu item which is used for selection\n */\n @property({ type: String })\n public get value(): string {\n return this._value || this.itemText;\n }\n\n public set value(value: string) {\n if (value === this._value) {\n return;\n }\n this._value = value || '';\n if (this._value) {\n this.setAttribute('value', this._value);\n } else {\n this.removeAttribute('value');\n }\n }\n\n private _value = '';\n\n /**\n * @private\n * text content of the menu item minus whitespace\n */\n public get itemText(): string {\n return this.itemChildren.content.reduce(\n (acc, node) => acc + (node.textContent || '').trim(),\n ''\n );\n }\n\n /**\n * whether the menu item has a submenu\n */\n @property({ type: Boolean, reflect: true, attribute: 'has-submenu' })\n public hasSubmenu = false;\n\n @query('slot:not([name])')\n contentSlot!: HTMLSlotElement;\n\n @query('slot[name=\"icon\"]')\n iconSlot!: HTMLSlotElement;\n\n /**\n * whether menu item text content should not wrap\n */\n @property({\n type: Boolean,\n reflect: true,\n attribute: 'no-wrap',\n hasChanged() {\n return false;\n },\n })\n public noWrap = false;\n\n @query('.anchor')\n private anchorElement!: HTMLAnchorElement;\n\n @query('sp-overlay')\n public overlayElement!: Overlay;\n\n private submenuElement?: HTMLElement;\n\n /**\n * the focusable element of the menu item\n */\n public override get focusElement(): HTMLElement {\n return this;\n }\n\n protected get hasIcon(): boolean {\n return this.slotContentIsPresent;\n }\n\n public get itemChildren(): MenuItemChildren {\n if (!this.iconSlot || !this.contentSlot) {\n return {\n icon: [],\n content: [],\n };\n }\n if (this._itemChildren) {\n return this._itemChildren;\n }\n const icon = this.iconSlot.assignedElements().map((element) => {\n const newElement = element.cloneNode(true) as HTMLElement;\n newElement.removeAttribute('slot');\n newElement.classList.toggle('icon');\n return newElement;\n });\n const content = this.contentSlot\n .assignedNodes()\n .map((node) => node.cloneNode(true));\n this._itemChildren = { icon, content };\n\n return this._itemChildren;\n }\n\n private _itemChildren?: MenuItemChildren;\n\n constructor() {\n super();\n this.addEventListener('click', this.handleClickCapture, {\n capture: true,\n });\n this.addEventListener('focus', this.handleFocus);\n this.addEventListener('blur', this.handleBlur);\n\n new MutationController(this, {\n config: {\n characterData: true,\n childList: true,\n subtree: true,\n attributeFilter: ['src'],\n },\n callback: (mutations) => {\n const isSubmenu = mutations.every(\n (mutation) =>\n (mutation.target as HTMLElement).slot === 'submenu'\n );\n if (isSubmenu) {\n return;\n }\n this.breakItemChildrenCache();\n },\n });\n }\n\n /**\n * whether submenu is open\n */\n @property({ type: Boolean, reflect: true })\n public open = false;\n\n /**\n * whether menu item's submenu is opened via keyboard\n */\n private _openedViaKeyboard = false;\n\n /**\n * whether menu item's submenu is closed via pointer leave\n */\n private _closedViaPointer = false;\n\n private handleClickCapture(event: Event): void | boolean {\n if (this.disabled) {\n event.preventDefault();\n event.stopImmediatePropagation();\n event.stopPropagation();\n return false;\n }\n\n if (this.shouldProxyClick()) {\n return;\n }\n }\n\n private handleSlottableRequest = (event: SlottableRequestEvent): void => {\n this.submenuElement?.dispatchEvent(\n new SlottableRequestEvent(event.name, event.data)\n );\n };\n\n private proxyFocus = (): void => {\n this.focus();\n };\n\n private shouldProxyClick(): boolean {\n let handled = false;\n if (this.anchorElement) {\n this.anchorElement.click();\n handled = true;\n }\n return handled;\n }\n\n protected breakItemChildrenCache(): void {\n this._itemChildren = undefined;\n this.triggerUpdate();\n }\n\n protected renderSubmenu(): TemplateResult {\n const slot = html`\n <slot\n name=\"submenu\"\n @slotchange=${this.manageSubmenu}\n @sp-menu-item-added-or-updated=${{\n handleEvent: (event: MenuItemAddedOrUpdatedEvent) => {\n event.clear(event.item);\n },\n capture: true,\n }}\n @focusin=${(event: Event) => event.stopPropagation()}\n ></slot>\n `;\n if (!this.hasSubmenu) {\n return slot;\n }\n this.dependencyManager.add('sp-overlay');\n this.dependencyManager.add('sp-popover');\n import('@spectrum-web-components/overlay/sp-overlay.js');\n import('@spectrum-web-components/popover/sp-popover.js');\n return html`\n <sp-overlay\n receives-focus=\"false\"\n .triggerElement=${this as HTMLElement}\n ?disabled=${!this.hasSubmenu}\n ?open=${this.hasSubmenu &&\n this.open &&\n this.dependencyManager.loaded}\n .placement=${this.isLTR ? 'right-start' : 'left-start'}\n receives-focus=\"false\"\n .offset=${[-10, -5] as [number, number]}\n .type=${'auto'}\n @close=${(event: Event) => event.stopPropagation()}\n @slottable-request=${this.handleSlottableRequest}\n >\n <sp-popover\n @change=${(event: Event) => {\n this.handleSubmenuChange(event);\n this.open = false;\n }}\n @pointerenter=${this.handleSubmenuPointerenter}\n @pointerleave=${this.handleSubmenuPointerleave}\n @sp-menu-item-added-or-updated=${(event: Event) =>\n event.stopPropagation()}\n >\n ${slot}\n </sp-popover>\n </sp-overlay>\n <sp-icon-chevron100\n class=\"spectrum-UIIcon-ChevronRight100 chevron icon\"\n ></sp-icon-chevron100>\n `;\n }\n\n protected override render(): TemplateResult {\n return html`\n ${this.selected\n ? html`\n <sp-icon-checkmark100\n id=\"selected\"\n class=\"spectrum-UIIcon-Checkmark100\n icon\n checkmark\n ${this.hasIcon\n ? 'checkmark--withAdjacentIcon'\n : ''}\"\n ></sp-icon-checkmark100>\n `\n : nothing}\n <slot name=\"icon\"></slot>\n <div id=\"label\">\n <slot id=\"slot\"></slot>\n </div>\n <slot name=\"description\"></slot>\n <slot name=\"value\"></slot>\n ${this.href && this.href.length > 0\n ? super.renderAnchor({\n id: 'button',\n ariaHidden: true,\n className: 'button anchor hidden',\n })\n : nothing}\n ${this.renderSubmenu()}\n `;\n }\n\n /**\n * determines if item has a submenu and updates the `aria-haspopup` attribute\n */\n protected manageSubmenu(event: Event & { target: HTMLSlotElement }): void {\n this.submenuElement = event.target.assignedElements({\n flatten: true,\n })[0] as HTMLElement;\n this.hasSubmenu = !!this.submenuElement;\n if (this.hasSubmenu) {\n this.setAttribute('aria-haspopup', 'true');\n }\n }\n\n private handlePointerdown(event: PointerEvent): void {\n if (event.target === this && this.hasSubmenu && this.open) {\n this.addEventListener('focus', this.handleSubmenuFocus, {\n once: true,\n });\n this.overlayElement.addEventListener(\n 'beforetoggle',\n this.handleBeforetoggle\n );\n }\n }\n\n protected override firstUpdated(changes: PropertyValues): void {\n super.firstUpdated(changes);\n this.setAttribute('tabindex', '-1');\n this.addEventListener('keydown', this.handleKeydown);\n this.addEventListener('mouseover', this.handleMouseover);\n this.addEventListener('pointerdown', this.handlePointerdown);\n this.addEventListener('pointerenter', this.closeOverlaysForRoot);\n if (!this.hasAttribute('id')) {\n this.id = `sp-menu-item-${randomID()}`;\n }\n }\n\n private getActiveElementSafely(): HTMLElement | null {\n let root = this.getRootNode() as Document | ShadowRoot;\n let activeElement = root.activeElement as HTMLElement;\n\n // If no active element in current context and we're in shadow DOM,\n // traverse up to find the document-level active element\n if (!activeElement && root !== document) {\n while (root && root !== document && 'host' in root) {\n root = (root as ShadowRoot).host.getRootNode() as\n | Document\n | ShadowRoot;\n activeElement = root.activeElement as HTMLElement;\n if (activeElement) break;\n }\n }\n\n return activeElement;\n }\n\n handleMouseover(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n if (target === this) {\n // Check for active input elements across shadow boundaries\n const activeElement = this.getActiveElementSafely();\n\n // Only focus this menu item if no input element is currently active\n // This prevents interrupting user input in search boxes, text fields, etc.\n if (!activeElement || !this.isInputElement(activeElement)) {\n this.focus();\n }\n this.focused = false;\n }\n }\n\n /**\n * Determines if an element is an input field that should retain focus.\n * Uses multiple detection strategies to identify input elements generically.\n */\n private isInputElement(element: HTMLElement): boolean {\n // Check for native HTML input elements\n if (this.isNativeInputElement(element)) {\n return true;\n }\n\n // Check for contenteditable elements (rich text editors)\n if (element.contentEditable === 'true') {\n return true;\n }\n\n // Check for Spectrum Web Components with input-like behavior\n if (this.isSpectrumInputComponent(element)) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Checks if an element is a native HTML input element.\n */\n private isNativeInputElement(element: HTMLElement): boolean {\n return (\n element instanceof HTMLInputElement ||\n element instanceof HTMLTextAreaElement ||\n element instanceof HTMLSelectElement\n );\n }\n\n /**\n * Checks if an element is a Spectrum Web Component with input behavior.\n * Uses ARIA roles and component patterns for generic detection.\n */\n private isSpectrumInputComponent(element: HTMLElement): boolean {\n // Check if it's a Spectrum Web Component\n if (!element.tagName.startsWith('SP-')) {\n return false;\n }\n\n // Check ARIA role for input-like behavior\n const role = element.getAttribute('role');\n const inputRoles = ['textbox', 'searchbox', 'combobox', 'slider'];\n if (role && inputRoles.includes(role)) {\n return true;\n }\n\n // Check for components that typically contain input elements\n // This covers components like sp-search, sp-textfield, sp-number-field, etc.\n const inputComponentPattern = INPUT_COMPONENT_PATTERN;\n if (inputComponentPattern.test(element.tagName)) {\n return true;\n }\n\n return false;\n }\n /**\n * forward key info from keydown event to parent menu\n */\n handleKeydown = (event: KeyboardEvent): void => {\n const { target, key } = event;\n const openSubmenuKey =\n this.hasSubmenu && !this.open && [' ', 'Enter'].includes(key);\n if (target === this) {\n if (\n ['ArrowLeft', 'ArrowRight', 'Escape'].includes(key) ||\n openSubmenuKey\n )\n event.preventDefault();\n this.dispatchEvent(\n new MenuItemKeydownEvent({ root: this, event: event })\n );\n }\n };\n\n protected closeOverlaysForRoot(): void {\n if (this.open) return;\n this.menuData.parentMenu?.closeDescendentOverlays();\n }\n\n protected handleFocus(event: FocusEvent): void {\n const { target } = event;\n if (target === this) {\n this.focused = true;\n }\n }\n\n protected handleBlur(event: FocusEvent): void {\n const { target } = event;\n if (target === this) {\n this.focused = false;\n }\n }\n\n protected handleSubmenuClick(event: Event): void {\n if (event.composedPath().includes(this.overlayElement)) {\n return;\n }\n this.openOverlay(true);\n }\n\n protected handleSubmenuFocus(): void {\n requestAnimationFrame(() => {\n // Wait till after `closeDescendentOverlays` has happened in Menu\n // to reopen (keep open) the direct descendent of this Menu Item\n this.overlayElement.open = this.open;\n this.focused = false;\n });\n }\n\n protected handleBeforetoggle = (event: Event): void => {\n if ((event as Event & { newState: string }).newState === 'closed') {\n this.open = true;\n this.overlayElement.manuallyKeepOpen();\n this.overlayElement.removeEventListener(\n 'beforetoggle',\n this.handleBeforetoggle\n );\n }\n };\n\n protected handlePointerenter(): void {\n if (this.leaveTimeout) {\n clearTimeout(this.leaveTimeout);\n delete this.leaveTimeout;\n this.recentlyLeftChild = false;\n return;\n }\n this.focus();\n this.openOverlay();\n }\n\n protected leaveTimeout?: ReturnType<typeof setTimeout>;\n protected recentlyLeftChild = false;\n\n protected handlePointerleave(): void {\n this._closedViaPointer = true;\n if (this.open && !this.recentlyLeftChild) {\n this.leaveTimeout = setTimeout(() => {\n delete this.leaveTimeout;\n this.open = false;\n }, POINTERLEAVE_TIMEOUT);\n }\n }\n\n /**\n * When there is a `change` event in the submenu for this item\n * then we \"click\" this item to cascade the selection up the\n * menu tree allowing all submenus between the initial selection\n * and the root of the tree to have their selection changes and\n * be closed.\n */\n protected handleSubmenuChange(event: Event): void {\n event.stopPropagation();\n this.menuData.selectionRoot?.selectOrToggleItem(this);\n }\n\n protected handleSubmenuPointerenter(): void {\n this.recentlyLeftChild = true;\n }\n\n protected async handleSubmenuPointerleave(): Promise<void> {\n this.recentlyLeftChild = false;\n }\n\n protected handleSubmenuOpen(event: Event): void {\n const parentOverlay = event.composedPath().find((el) => {\n return (\n el !== this.overlayElement &&\n (el as HTMLElement).localName === 'sp-overlay'\n );\n }) as Overlay;\n if (this._openedViaKeyboard) {\n this.submenuElement?.focus();\n }\n this.overlayElement.parentOverlayToForceClose = parentOverlay;\n }\n\n protected cleanup(): void {\n this._closedViaPointer = false;\n this.setAttribute('aria-expanded', 'false');\n this.open = false;\n this.active = false;\n }\n\n public async openOverlay(shouldFocus: boolean = false): Promise<void> {\n if (!this.hasSubmenu || this.open || this.disabled) {\n return;\n }\n this.open = true;\n this.active = true;\n this.setAttribute('aria-expanded', 'true');\n this._openedViaKeyboard = shouldFocus;\n this.addEventListener('sp-closed', this.cleanup, {\n once: true,\n });\n }\n\n updateAriaSelected(): void {\n const role = this.getAttribute('role');\n if (role === 'option') {\n this.setAttribute(\n 'aria-selected',\n this.selected ? 'true' : 'false'\n );\n } else if (role === 'menuitemcheckbox' || role === 'menuitemradio') {\n this.setAttribute('aria-checked', this.selected ? 'true' : 'false');\n }\n }\n\n public setRole(role: string): void {\n this.setAttribute('role', role);\n this.updateAriaSelected();\n }\n\n protected override willUpdate(changes: PropertyValues<this>): void {\n super.updated(changes);\n\n // make sure focus returns to the anchor element when submenu is closed\n if (\n changes.has('open') &&\n !this.open &&\n this.hasSubmenu &&\n !this._closedViaPointer &&\n this.matches(':focus-within')\n ) {\n this.focus();\n }\n }\n\n protected override updated(changes: PropertyValues<this>): void {\n super.updated(changes);\n if (\n changes.has('label') &&\n (this.label || typeof changes.get('label') !== 'undefined')\n ) {\n this.setAttribute('aria-label', this.label || '');\n }\n if (\n changes.has('active') &&\n (this.active || typeof changes.get('active') !== 'undefined')\n ) {\n if (this.active) {\n this.menuData.selectionRoot?.closeDescendentOverlays();\n }\n }\n if (this.anchorElement) {\n this.anchorElement.addEventListener('focus', this.proxyFocus);\n this.anchorElement.tabIndex = -1;\n }\n if (changes.has('selected')) {\n this.updateAriaSelected();\n }\n if (\n changes.has('hasSubmenu') &&\n (this.hasSubmenu ||\n typeof changes.get('hasSubmenu') !== 'undefined')\n ) {\n if (this.hasSubmenu) {\n this.abortControllerSubmenu = new AbortController();\n const options = { signal: this.abortControllerSubmenu.signal };\n this.addEventListener(\n 'click',\n this.handleSubmenuClick,\n options\n );\n this.addEventListener(\n 'pointerenter',\n this.handlePointerenter,\n options\n );\n this.addEventListener(\n 'pointerleave',\n this.handlePointerleave,\n options\n );\n this.addEventListener(\n 'sp-opened',\n this.handleSubmenuOpen,\n options\n );\n } else {\n this.abortControllerSubmenu?.abort();\n }\n }\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n this.triggerUpdate();\n }\n\n _parentElement!: HTMLElement;\n\n public override disconnectedCallback(): void {\n this.menuData.cleanupSteps.forEach((removal) => removal(this));\n this.menuData = {\n focusRoot: undefined,\n parentMenu: undefined,\n selectionRoot: undefined,\n cleanupSteps: [],\n };\n super.disconnectedCallback();\n }\n\n private willDispatchUpdate = false;\n\n public async triggerUpdate(): Promise<void> {\n if (this.willDispatchUpdate) {\n return;\n }\n this.willDispatchUpdate = true;\n await new Promise((ready) => requestAnimationFrame(ready));\n this.dispatchUpdate();\n }\n\n public override focus(): void {\n super.focus();\n // ensure focus event fires in Chromium for tests\n this.dispatchEvent(new FocusEvent('focus'));\n }\n\n public override blur(): void {\n // ensure focus event fires in Chromium for tests\n this.dispatchEvent(new FocusEvent('blur'));\n super.blur();\n }\n\n public dispatchUpdate(): void {\n if (!this.isConnected) {\n return;\n }\n this.dispatchEvent(new MenuItemAddedOrUpdatedEvent(this));\n this.willDispatchUpdate = false;\n }\n\n public menuData: {\n focusRoot?: Menu;\n parentMenu?: Menu;\n selectionRoot?: Menu;\n cleanupSteps: ((item: MenuItem) => void)[];\n } = {\n // menu that controls ArrowUp/ArrowDown navigation\n focusRoot: undefined,\n parentMenu: undefined,\n // menu or menu group that controls selection\n selectionRoot: undefined,\n cleanupSteps: [],\n };\n}\n\ndeclare global {\n interface GlobalEventHandlersEventMap {\n 'sp-menu-item-added-or-updated': MenuItemAddedOrUpdatedEvent;\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/src/MenuItem.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var h=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var r=(a,n,e,t)=>{for(var i=t>1?void 0:t?p(n,e):n,o=a.length-1,d;o>=0;o--)(d=a[o])&&(i=(t?d(n,e,i):d(i))||i);return t&&i&&h(n,e,i),i};import{html as l,INPUT_COMPONENT_PATTERN as m,nothing as c}from"@spectrum-web-components/base";import{ObserveSlotPresence as v,ObserveSlotText as f,randomID as b}from"@spectrum-web-components/shared";import{property as s,query as u}from"@spectrum-web-components/base/src/decorators.js";import"@spectrum-web-components/icons-ui/icons/sp-icon-checkmark100.js";import{LikeAnchor as E}from"@spectrum-web-components/shared/src/like-anchor.js";import{Focusable as y}from"@spectrum-web-components/shared/src/focusable.js";import"@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js";import g from"@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js";import{DependencyManagerController as S}from"@spectrum-web-components/reactive-controllers/src/DependencyManger.js";import C from"./menu-item.css.js";import M from"@spectrum-web-components/icon/src/spectrum-icon-checkmark.css.js";import{MutationController as L}from"@lit-labs/observers/mutation-controller.js";import{SlottableRequestEvent as T}from"@spectrum-web-components/overlay/src/slottable-request-event.js";const P=100;export class MenuItemAddedOrUpdatedEvent extends Event{constructor(e){super("sp-menu-item-added-or-updated",{bubbles:!0,composed:!0});this.menuCascade=new WeakMap;this.clear(e)}clear(e){this._item=e,this.currentAncestorWithSelects=void 0,e.menuData={cleanupSteps:[],focusRoot:void 0,selectionRoot:void 0,parentMenu:void 0},this.menuCascade=new WeakMap}get item(){return this._item}}export class MenuItemKeydownEvent extends KeyboardEvent{constructor({root:n,event:e}){super("sp-menu-item-keydown",{bubbles:!0,composed:!0}),this.root=n,this._event=e}get altKey(){var n;return((n=this._event)==null?void 0:n.altKey)||!1}get code(){var n;return((n=this._event)==null?void 0:n.code)||""}get ctrlKey(){var n;return((n=this._event)==null?void 0:n.ctrlKey)||!1}get isComposing(){var n;return((n=this._event)==null?void 0:n.isComposing)||!1}get key(){var n;return((n=this._event)==null?void 0:n.key)||""}get location(){var n;return((n=this._event)==null?void 0:n.location)||0}get metaKey(){var n;return((n=this._event)==null?void 0:n.metaKey)||!1}get repeat(){var n;return((n=this._event)==null?void 0:n.repeat)||!1}get shiftKey(){var n;return((n=this._event)==null?void 0:n.shiftKey)||!1}}export class MenuItem extends E(f(v(y,'[slot="icon"]'))){constructor(){super();this.active=!1;this.dependencyManager=new S(this);this.focused=!1;this.selected=!1;this._value="";this.hasSubmenu=!1;this.noWrap=!1;this.open=!1;this._openedViaKeyboard=!1;this._closedViaPointer=!1;this.handleSlottableRequest=e=>{var t;(t=this.submenuElement)==null||t.dispatchEvent(new T(e.name,e.data))};this.proxyFocus=()=>{this.focus()};this.handleKeydown=e=>{const{target:t,key:i}=e,o=this.hasSubmenu&&!this.open&&[" ","Enter"].includes(i);t===this&&((["ArrowLeft","ArrowRight","Escape"].includes(i)||o)&&e.preventDefault(),this.dispatchEvent(new MenuItemKeydownEvent({root:this,event:e})))};this.handleBeforetoggle=e=>{e.newState==="closed"&&(this.open=!0,this.overlayElement.manuallyKeepOpen(),this.overlayElement.removeEventListener("beforetoggle",this.handleBeforetoggle))};this.recentlyLeftChild=!1;this.willDispatchUpdate=!1;this.menuData={focusRoot:void 0,parentMenu:void 0,selectionRoot:void 0,cleanupSteps:[]};this.addEventListener("click",this.handleClickCapture,{capture:!0}),this.addEventListener("focus",this.handleFocus),this.addEventListener("blur",this.handleBlur),new L(this,{config:{characterData:!0,childList:!0,subtree:!0,attributeFilter:["src"]},callback:e=>{e.every(i=>i.target.slot==="submenu")||this.breakItemChildrenCache()}})}static get styles(){return[C,M,g]}get value(){return this._value||this.itemText}set value(e){e!==this._value&&(this._value=e||"",this._value?this.setAttribute("value",this._value):this.removeAttribute("value"))}get itemText(){return this.itemChildren.content.reduce((e,t)=>e+(t.textContent||"").trim(),"")}get focusElement(){return this}get hasIcon(){return this.slotContentIsPresent}get itemChildren(){if(!this.iconSlot||!this.contentSlot)return{icon:[],content:[]};if(this._itemChildren)return this._itemChildren;const e=this.iconSlot.assignedElements().map(i=>{const o=i.cloneNode(!0);return o.removeAttribute("slot"),o.classList.toggle("icon"),o}),t=this.contentSlot.assignedNodes().map(i=>i.cloneNode(!0));return this._itemChildren={icon:e,content:t},this._itemChildren}handleClickCapture(e){if(this.disabled)return e.preventDefault(),e.stopImmediatePropagation(),e.stopPropagation(),!1;this.shouldProxyClick()}shouldProxyClick(){let e=!1;return this.anchorElement&&(this.anchorElement.click(),e=!0),e}breakItemChildrenCache(){this._itemChildren=void 0,this.triggerUpdate()}renderSubmenu(){const e=l`
|
|
2
2
|
<slot
|
|
3
3
|
name="submenu"
|
|
4
4
|
@slotchange=${this.manageSubmenu}
|
|
@@ -39,14 +39,14 @@
|
|
|
39
39
|
checkmark
|
|
40
40
|
${this.hasIcon?"checkmark--withAdjacentIcon":""}"
|
|
41
41
|
></sp-icon-checkmark100>
|
|
42
|
-
`:
|
|
42
|
+
`:c}
|
|
43
43
|
<slot name="icon"></slot>
|
|
44
44
|
<div id="label">
|
|
45
45
|
<slot id="slot"></slot>
|
|
46
46
|
</div>
|
|
47
47
|
<slot name="description"></slot>
|
|
48
48
|
<slot name="value"></slot>
|
|
49
|
-
${this.href&&this.href.length>0?super.renderAnchor({id:"button",ariaHidden:!0,className:"button anchor hidden"}):
|
|
49
|
+
${this.href&&this.href.length>0?super.renderAnchor({id:"button",ariaHidden:!0,className:"button anchor hidden"}):c}
|
|
50
50
|
${this.renderSubmenu()}
|
|
51
|
-
`}manageSubmenu(e){this.submenuElement=e.target.assignedElements({flatten:!0})[0],this.hasSubmenu=!!this.submenuElement,this.hasSubmenu&&this.setAttribute("aria-haspopup","true")}handlePointerdown(e){e.target===this&&this.hasSubmenu&&this.open&&(this.addEventListener("focus",this.handleSubmenuFocus,{once:!0}),this.overlayElement.addEventListener("beforetoggle",this.handleBeforetoggle))}firstUpdated(e){super.firstUpdated(e),this.setAttribute("tabindex","-1"),this.addEventListener("keydown",this.handleKeydown),this.addEventListener("mouseover",this.handleMouseover),this.addEventListener("pointerdown",this.handlePointerdown),this.addEventListener("pointerenter",this.closeOverlaysForRoot),this.hasAttribute("id")||(this.id=`sp-menu-item-${b()}`)}handleMouseover(e){e.target===this
|
|
51
|
+
`}manageSubmenu(e){this.submenuElement=e.target.assignedElements({flatten:!0})[0],this.hasSubmenu=!!this.submenuElement,this.hasSubmenu&&this.setAttribute("aria-haspopup","true")}handlePointerdown(e){e.target===this&&this.hasSubmenu&&this.open&&(this.addEventListener("focus",this.handleSubmenuFocus,{once:!0}),this.overlayElement.addEventListener("beforetoggle",this.handleBeforetoggle))}firstUpdated(e){super.firstUpdated(e),this.setAttribute("tabindex","-1"),this.addEventListener("keydown",this.handleKeydown),this.addEventListener("mouseover",this.handleMouseover),this.addEventListener("pointerdown",this.handlePointerdown),this.addEventListener("pointerenter",this.closeOverlaysForRoot),this.hasAttribute("id")||(this.id=`sp-menu-item-${b()}`)}getActiveElementSafely(){let e=this.getRootNode(),t=e.activeElement;if(!t&&e!==document)for(;e&&e!==document&&"host"in e&&(e=e.host.getRootNode(),t=e.activeElement,!t););return t}handleMouseover(e){if(e.target===this){const i=this.getActiveElementSafely();(!i||!this.isInputElement(i))&&this.focus(),this.focused=!1}}isInputElement(e){return!!(this.isNativeInputElement(e)||e.contentEditable==="true"||this.isSpectrumInputComponent(e))}isNativeInputElement(e){return e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement}isSpectrumInputComponent(e){if(!e.tagName.startsWith("SP-"))return!1;const t=e.getAttribute("role");return!!(t&&["textbox","searchbox","combobox","slider"].includes(t)||m.test(e.tagName))}closeOverlaysForRoot(){var e;this.open||(e=this.menuData.parentMenu)==null||e.closeDescendentOverlays()}handleFocus(e){const{target:t}=e;t===this&&(this.focused=!0)}handleBlur(e){const{target:t}=e;t===this&&(this.focused=!1)}handleSubmenuClick(e){e.composedPath().includes(this.overlayElement)||this.openOverlay(!0)}handleSubmenuFocus(){requestAnimationFrame(()=>{this.overlayElement.open=this.open,this.focused=!1})}handlePointerenter(){if(this.leaveTimeout){clearTimeout(this.leaveTimeout),delete this.leaveTimeout,this.recentlyLeftChild=!1;return}this.focus(),this.openOverlay()}handlePointerleave(){this._closedViaPointer=!0,this.open&&!this.recentlyLeftChild&&(this.leaveTimeout=setTimeout(()=>{delete this.leaveTimeout,this.open=!1},P))}handleSubmenuChange(e){var t;e.stopPropagation(),(t=this.menuData.selectionRoot)==null||t.selectOrToggleItem(this)}handleSubmenuPointerenter(){this.recentlyLeftChild=!0}async handleSubmenuPointerleave(){this.recentlyLeftChild=!1}handleSubmenuOpen(e){var i;const t=e.composedPath().find(o=>o!==this.overlayElement&&o.localName==="sp-overlay");this._openedViaKeyboard&&((i=this.submenuElement)==null||i.focus()),this.overlayElement.parentOverlayToForceClose=t}cleanup(){this._closedViaPointer=!1,this.setAttribute("aria-expanded","false"),this.open=!1,this.active=!1}async openOverlay(e=!1){!this.hasSubmenu||this.open||this.disabled||(this.open=!0,this.active=!0,this.setAttribute("aria-expanded","true"),this._openedViaKeyboard=e,this.addEventListener("sp-closed",this.cleanup,{once:!0}))}updateAriaSelected(){const e=this.getAttribute("role");e==="option"?this.setAttribute("aria-selected",this.selected?"true":"false"):(e==="menuitemcheckbox"||e==="menuitemradio")&&this.setAttribute("aria-checked",this.selected?"true":"false")}setRole(e){this.setAttribute("role",e),this.updateAriaSelected()}willUpdate(e){super.updated(e),e.has("open")&&!this.open&&this.hasSubmenu&&!this._closedViaPointer&&this.matches(":focus-within")&&this.focus()}updated(e){var t,i;if(super.updated(e),e.has("label")&&(this.label||typeof e.get("label")!="undefined")&&this.setAttribute("aria-label",this.label||""),e.has("active")&&(this.active||typeof e.get("active")!="undefined")&&this.active&&((t=this.menuData.selectionRoot)==null||t.closeDescendentOverlays()),this.anchorElement&&(this.anchorElement.addEventListener("focus",this.proxyFocus),this.anchorElement.tabIndex=-1),e.has("selected")&&this.updateAriaSelected(),e.has("hasSubmenu")&&(this.hasSubmenu||typeof e.get("hasSubmenu")!="undefined"))if(this.hasSubmenu){this.abortControllerSubmenu=new AbortController;const o={signal:this.abortControllerSubmenu.signal};this.addEventListener("click",this.handleSubmenuClick,o),this.addEventListener("pointerenter",this.handlePointerenter,o),this.addEventListener("pointerleave",this.handlePointerleave,o),this.addEventListener("sp-opened",this.handleSubmenuOpen,o)}else(i=this.abortControllerSubmenu)==null||i.abort()}connectedCallback(){super.connectedCallback(),this.triggerUpdate()}disconnectedCallback(){this.menuData.cleanupSteps.forEach(e=>e(this)),this.menuData={focusRoot:void 0,parentMenu:void 0,selectionRoot:void 0,cleanupSteps:[]},super.disconnectedCallback()}async triggerUpdate(){this.willDispatchUpdate||(this.willDispatchUpdate=!0,await new Promise(e=>requestAnimationFrame(e)),this.dispatchUpdate())}focus(){super.focus(),this.dispatchEvent(new FocusEvent("focus"))}blur(){this.dispatchEvent(new FocusEvent("blur")),super.blur()}dispatchUpdate(){this.isConnected&&(this.dispatchEvent(new MenuItemAddedOrUpdatedEvent(this)),this.willDispatchUpdate=!1)}}r([s({type:Boolean,reflect:!0})],MenuItem.prototype,"active",2),r([s({type:Boolean,reflect:!0})],MenuItem.prototype,"focused",2),r([s({type:Boolean,reflect:!0})],MenuItem.prototype,"selected",2),r([s({type:String})],MenuItem.prototype,"value",1),r([s({type:Boolean,reflect:!0,attribute:"has-submenu"})],MenuItem.prototype,"hasSubmenu",2),r([u("slot:not([name])")],MenuItem.prototype,"contentSlot",2),r([u('slot[name="icon"]')],MenuItem.prototype,"iconSlot",2),r([s({type:Boolean,reflect:!0,attribute:"no-wrap",hasChanged(){return!1}})],MenuItem.prototype,"noWrap",2),r([u(".anchor")],MenuItem.prototype,"anchorElement",2),r([u("sp-overlay")],MenuItem.prototype,"overlayElement",2),r([s({type:Boolean,reflect:!0})],MenuItem.prototype,"open",2);
|
|
52
52
|
//# sourceMappingURL=MenuItem.js.map
|