@spectrum-web-components/menu 1.4.1-beta.0 → 1.5.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.
@@ -220,8 +220,8 @@
220
220
  "text": "boolean"
221
221
  },
222
222
  "privacy": "public",
223
- "default": "true",
224
- "description": "whether or not to support pointerdown - drag - pointerup selection strategy\ndefault is true\nshould be false for mobile to prevent click event being captured behind the menu-tray (cz menu immediately closes on pointerup)"
223
+ "default": "false",
224
+ "description": "Whether to support the pointerdown-drag-pointerup selection strategy.\nDefaults to false to prevent click/touch events from being captured\nbehind the menu tray in mobile environments (since the menu closes\nimmediately on pointerup)."
225
225
  },
226
226
  {
227
227
  "kind": "field",
@@ -431,24 +431,6 @@
431
431
  "privacy": "private",
432
432
  "default": "null"
433
433
  },
434
- {
435
- "kind": "method",
436
- "name": "handleMouseover",
437
- "privacy": "private",
438
- "return": {
439
- "type": {
440
- "text": "void"
441
- }
442
- },
443
- "parameters": [
444
- {
445
- "name": "event",
446
- "type": {
447
- "text": "MouseEvent"
448
- }
449
- }
450
- ]
451
- },
452
434
  {
453
435
  "kind": "method",
454
436
  "name": "handleFocusout",
@@ -1227,8 +1209,8 @@
1227
1209
  "text": "boolean"
1228
1210
  },
1229
1211
  "privacy": "public",
1230
- "default": "true",
1231
- "description": "whether or not to support pointerdown - drag - pointerup selection strategy\ndefault is true\nshould be false for mobile to prevent click event being captured behind the menu-tray (cz menu immediately closes on pointerup)",
1212
+ "default": "false",
1213
+ "description": "Whether to support the pointerdown-drag-pointerup selection strategy.\nDefaults to false to prevent click/touch events from being captured\nbehind the menu tray in mobile environments (since the menu closes\nimmediately on pointerup).",
1232
1214
  "inheritedFrom": {
1233
1215
  "name": "Menu",
1234
1216
  "module": "src/Menu.js"
@@ -1484,28 +1466,6 @@
1484
1466
  "module": "src/Menu.js"
1485
1467
  }
1486
1468
  },
1487
- {
1488
- "kind": "method",
1489
- "name": "handleMouseover",
1490
- "privacy": "private",
1491
- "return": {
1492
- "type": {
1493
- "text": "void"
1494
- }
1495
- },
1496
- "parameters": [
1497
- {
1498
- "name": "event",
1499
- "type": {
1500
- "text": "MouseEvent"
1501
- }
1502
- }
1503
- ],
1504
- "inheritedFrom": {
1505
- "name": "Menu",
1506
- "module": "src/Menu.js"
1507
- }
1508
- },
1509
1469
  {
1510
1470
  "kind": "method",
1511
1471
  "name": "handleFocusout",
@@ -2486,6 +2446,26 @@
2486
2446
  "attribute": "open",
2487
2447
  "reflects": true
2488
2448
  },
2449
+ {
2450
+ "kind": "field",
2451
+ "name": "_openedViaKeyboard",
2452
+ "type": {
2453
+ "text": "boolean"
2454
+ },
2455
+ "privacy": "private",
2456
+ "default": "false",
2457
+ "description": "whether menu item's submenu is opened via keyboard"
2458
+ },
2459
+ {
2460
+ "kind": "field",
2461
+ "name": "_closedViaPointer",
2462
+ "type": {
2463
+ "text": "boolean"
2464
+ },
2465
+ "privacy": "private",
2466
+ "default": "false",
2467
+ "description": "whether menu item's submenu is closed via pointer leave"
2468
+ },
2489
2469
  {
2490
2470
  "kind": "method",
2491
2471
  "name": "handleClickCapture",
@@ -2581,6 +2561,23 @@
2581
2561
  }
2582
2562
  ]
2583
2563
  },
2564
+ {
2565
+ "kind": "method",
2566
+ "name": "handleMouseover",
2567
+ "return": {
2568
+ "type": {
2569
+ "text": "void"
2570
+ }
2571
+ },
2572
+ "parameters": [
2573
+ {
2574
+ "name": "event",
2575
+ "type": {
2576
+ "text": "MouseEvent"
2577
+ }
2578
+ }
2579
+ ]
2580
+ },
2584
2581
  {
2585
2582
  "kind": "field",
2586
2583
  "name": "handleKeydown",
@@ -2777,7 +2774,16 @@
2777
2774
  "type": {
2778
2775
  "text": "Promise<void>"
2779
2776
  }
2780
- }
2777
+ },
2778
+ "parameters": [
2779
+ {
2780
+ "name": "shouldFocus",
2781
+ "default": "false",
2782
+ "type": {
2783
+ "text": "boolean"
2784
+ }
2785
+ }
2786
+ ]
2781
2787
  },
2782
2788
  {
2783
2789
  "kind": "method",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-web-components/menu",
3
- "version": "1.4.1-beta.0",
3
+ "version": "1.5.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -11,7 +11,7 @@
11
11
  "url": "https://github.com/adobe/spectrum-web-components.git",
12
12
  "directory": "packages/menu"
13
13
  },
14
- "author": "",
14
+ "author": "Adobe",
15
15
  "homepage": "https://opensource.adobe.com/spectrum-web-components/components/menu",
16
16
  "bugs": {
17
17
  "url": "https://github.com/adobe/spectrum-web-components/issues"
@@ -83,22 +83,28 @@
83
83
  "!test/"
84
84
  ],
85
85
  "keywords": [
86
- "spectrum css",
86
+ "design-system",
87
+ "spectrum",
88
+ "adobe",
89
+ "adobe-spectrum",
87
90
  "web components",
91
+ "web-components",
88
92
  "lit-element",
89
- "lit-html"
93
+ "lit-html",
94
+ "component",
95
+ "css"
90
96
  ],
91
97
  "dependencies": {
92
98
  "@lit-labs/observers": "^2.0.2",
93
- "@spectrum-web-components/action-button": "1.4.1-beta.0",
94
- "@spectrum-web-components/base": "1.4.1-beta.0",
95
- "@spectrum-web-components/divider": "1.4.1-beta.0",
96
- "@spectrum-web-components/icon": "1.4.1-beta.0",
97
- "@spectrum-web-components/icons-ui": "1.4.1-beta.0",
98
- "@spectrum-web-components/overlay": "1.4.1-beta.0",
99
- "@spectrum-web-components/popover": "1.4.1-beta.0",
100
- "@spectrum-web-components/reactive-controllers": "1.4.1-beta.0",
101
- "@spectrum-web-components/shared": "1.4.1-beta.0"
99
+ "@spectrum-web-components/action-button": "1.5.0",
100
+ "@spectrum-web-components/base": "1.5.0",
101
+ "@spectrum-web-components/divider": "1.5.0",
102
+ "@spectrum-web-components/icon": "1.5.0",
103
+ "@spectrum-web-components/icons-ui": "1.5.0",
104
+ "@spectrum-web-components/overlay": "1.5.0",
105
+ "@spectrum-web-components/popover": "1.5.0",
106
+ "@spectrum-web-components/reactive-controllers": "1.5.0",
107
+ "@spectrum-web-components/shared": "1.5.0"
102
108
  },
103
109
  "devDependencies": {
104
110
  "@spectrum-css/menu": "9.1.1"
package/src/Menu.d.ts CHANGED
@@ -71,9 +71,10 @@ export declare class Menu extends Menu_base {
71
71
  focusedItemIndex: number;
72
72
  focusInItemIndex: number;
73
73
  /**
74
- * whether or not to support pointerdown - drag - pointerup selection strategy
75
- * default is true
76
- * should be false for mobile to prevent click event being captured behind the menu-tray (cz menu immediately closes on pointerup)
74
+ * Whether to support the pointerdown-drag-pointerup selection strategy.
75
+ * Defaults to false to prevent click/touch events from being captured
76
+ * behind the menu tray in mobile environments (since the menu closes
77
+ * immediately on pointerup).
77
78
  */
78
79
  shouldSupportDragAndSelect: boolean;
79
80
  get focusInItem(): MenuItem | undefined;
@@ -127,7 +128,6 @@ export declare class Menu extends Menu_base {
127
128
  focusOnFirstSelectedItem({ preventScroll, }?: FocusOptions): void;
128
129
  focus({ preventScroll }?: FocusOptions): void;
129
130
  private pointerUpTarget;
130
- private handleMouseover;
131
131
  private handleFocusout;
132
132
  private handleClick;
133
133
  private handlePointerup;
package/src/Menu.dev.js CHANGED
@@ -33,11 +33,12 @@ export class Menu extends SizedMixin(SpectrumElement, { noDefaultSize: true }) {
33
33
  this.focusedItemIndex = 0;
34
34
  this.focusInItemIndex = 0;
35
35
  /**
36
- * whether or not to support pointerdown - drag - pointerup selection strategy
37
- * default is true
38
- * should be false for mobile to prevent click event being captured behind the menu-tray (cz menu immediately closes on pointerup)
36
+ * Whether to support the pointerdown-drag-pointerup selection strategy.
37
+ * Defaults to false to prevent click/touch events from being captured
38
+ * behind the menu tray in mobile environments (since the menu closes
39
+ * immediately on pointerup).
39
40
  */
40
- this.shouldSupportDragAndSelect = true;
41
+ this.shouldSupportDragAndSelect = false;
41
42
  this.selectedItemsMap = /* @__PURE__ */ new Map();
42
43
  // if the click and pointerup events are on the same target, we should not
43
44
  // handle the click event.
@@ -104,7 +105,7 @@ export class Menu extends SizedMixin(SpectrumElement, { noDefaultSize: true }) {
104
105
  }
105
106
  );
106
107
  this.addEventListener("click", this.handleClick);
107
- this.addEventListener("mouseover", this.handleMouseover);
108
+ this.addEventListener("touchend", this.handlePointerup);
108
109
  this.addEventListener("focusout", this.handleFocusout);
109
110
  this.addEventListener("sp-menu-item-keydown", this.handleKeydown);
110
111
  this.addEventListener("pointerup", this.handlePointerup);
@@ -312,14 +313,6 @@ export class Menu extends SizedMixin(SpectrumElement, { noDefaultSize: true }) {
312
313
  this.rovingTabindexController.focus({ preventScroll });
313
314
  }
314
315
  }
315
- handleMouseover(event) {
316
- var _a;
317
- const { target } = event;
318
- const menuItem = target;
319
- if (this.childItems.includes(menuItem) && this.isFocusableElement(menuItem)) {
320
- (_a = this.rovingTabindexController) == null ? void 0 : _a.focusOnItem(menuItem);
321
- }
322
- }
323
316
  handleFocusout() {
324
317
  var _a;
325
318
  if (!this.matches(":focus-within"))
@@ -478,7 +471,7 @@ export class Menu extends SizedMixin(SpectrumElement, { noDefaultSize: true }) {
478
471
  if (shouldOpenSubmenu) {
479
472
  if (lastFocusedItem == null ? void 0 : lastFocusedItem.hasSubmenu) {
480
473
  event.stopPropagation();
481
- lastFocusedItem.openOverlay();
474
+ lastFocusedItem.openOverlay(true);
482
475
  }
483
476
  } else if (shouldCloseSelfAsSubmenu && this.isSubmenu) {
484
477
  event.stopPropagation();
@@ -510,7 +503,7 @@ export class Menu extends SizedMixin(SpectrumElement, { noDefaultSize: true }) {
510
503
  }
511
504
  if (openSubmenuKey && (root == null ? void 0 : root.hasSubmenu) && !root.open) {
512
505
  event.preventDefault();
513
- root.openOverlay();
506
+ root.openOverlay(true);
514
507
  return;
515
508
  }
516
509
  if (key === " " || key === "Enter") {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["Menu.ts"],
4
- "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport {\n CSSResultArray,\n html,\n PropertyValues,\n SizedMixin,\n SpectrumElement,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {\n property,\n query,\n} from '@spectrum-web-components/base/src/decorators.js';\n\nimport { MenuItem } from './MenuItem.dev.js'\nimport type {\n MenuItemAddedOrUpdatedEvent,\n MenuItemKeydownEvent,\n} from './MenuItem.dev.js'\nimport type { Overlay } from '@spectrum-web-components/overlay';\nimport menuStyles from './menu.css.js';\nimport { RovingTabindexController } from '@spectrum-web-components/reactive-controllers/src/RovingTabindex.js';\n\nexport interface MenuChildItem {\n menuItem: MenuItem;\n managed: boolean;\n active: boolean;\n focusable: boolean;\n focusRoot: Menu;\n}\n\ntype SelectsType = 'none' | 'ignore' | 'inherit' | 'multiple' | 'single';\ntype RoleType = 'group' | 'menu' | 'listbox' | 'none';\n\n/**\n * Spectrum Menu Component\n * @element sp-menu\n *\n * @slot - menu items to be listed in the menu\n * @fires change - Announces that the `value` of the element has changed\n * @attr selects - whether the element has a specific selection algorithm that it applies\n * to its item descendants. `single` allows only one descendent to be selected at a time.\n * `multiple` allows many descendants to be selected. `inherit` will be applied dynamically\n * when an ancestor of this element is actively managing the selection of its descendents.\n * When the `selects` attribute is not present a `value` will not be maintained and the Menu\n * Item children of this Menu will not have their `selected` state managed.\n */\nexport class Menu extends SizedMixin(SpectrumElement, { noDefaultSize: true }) {\n public static override get styles(): CSSResultArray {\n return [menuStyles];\n }\n\n static override shadowRootOptions = {\n ...SpectrumElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n private get isSubmenu(): boolean {\n return this.slot === 'submenu';\n }\n\n protected rovingTabindexController?: RovingTabindexController<MenuItem>;\n\n /**\n * label of the menu\n */\n @property({ type: String, reflect: true })\n public label = '';\n\n /**\n * whether menu should be ignored by roving tabindex controller\n */\n @property({ type: Boolean, reflect: true })\n public ignore = false;\n\n /**\n * how the menu allows selection of its items:\n * - `undefined` (default): no selection is allowed\n * - `\"inherit\"`: the selection behavior is managed from an ancestor\n * - `\"single\"`: only one item can be selected at a time\n * - `\"multiple\"`: multiple items can be selected\n */\n @property({ type: String, reflect: true })\n public selects: undefined | 'inherit' | 'single' | 'multiple';\n\n /**\n * value of the selected item(s)\n */\n @property({ type: String })\n public value = '';\n\n // For the multiple select case, we'll join the value strings together\n // for the value property with this separator\n @property({ type: String, attribute: 'value-separator' })\n public valueSeparator = ',';\n\n /**\n * selected items values as string\n */\n @property({ attribute: false })\n public get selected(): string[] {\n return !this.selects ? [] : this._selected;\n }\n\n public set selected(selected: string[]) {\n if (selected === this.selected) {\n return;\n }\n const old = this.selected;\n this._selected = selected;\n this.selectedItems = [];\n this.selectedItemsMap.clear();\n this.childItems.forEach((item) => {\n if (this !== item.menuData.selectionRoot) {\n return;\n }\n item.selected = this.selected.includes(item.value);\n if (item.selected) {\n this.selectedItems.push(item);\n this.selectedItemsMap.set(item, true);\n }\n });\n this.requestUpdate('selected', old);\n }\n\n protected _selected = [] as string[];\n\n /**\n * array of selected menu items\n */\n @property({ attribute: false })\n public selectedItems = [] as MenuItem[];\n\n @query('slot:not([name])')\n public menuSlot!: HTMLSlotElement;\n\n private childItemSet = new Set<MenuItem>();\n public focusedItemIndex = 0;\n public focusInItemIndex = 0;\n\n /**\n * whether or not to support pointerdown - drag - pointerup selection strategy\n * default is true\n * should be false for mobile to prevent click event being captured behind the menu-tray (cz menu immediately closes on pointerup)\n */\n public shouldSupportDragAndSelect = true;\n\n public get focusInItem(): MenuItem | undefined {\n return this.rovingTabindexController?.focusInElement;\n }\n\n protected get controlsRovingTabindex(): boolean {\n return true;\n }\n\n private selectedItemsMap = new Map<MenuItem, boolean>();\n\n /**\n * child items managed by menu\n */\n public get childItems(): MenuItem[] {\n if (!this.cachedChildItems) {\n this.cachedChildItems = this.updateCachedMenuItems();\n }\n return this.cachedChildItems;\n }\n\n private cachedChildItems: MenuItem[] | undefined;\n\n private updateCachedMenuItems(): MenuItem[] {\n if (!this.menuSlot) {\n return [];\n }\n const itemsList = [];\n const slottedElements = this.menuSlot.assignedElements({\n flatten: true,\n }) as HTMLElement[];\n // Recursively flatten <slot> and non-<sp-menu-item> elements assigned to the menu into a single array.\n for (const [i, slottedElement] of slottedElements.entries()) {\n if (this.childItemSet.has(slottedElement as MenuItem)) {\n // Assign <sp-menu-item> members of the array that are in this.childItemSet to this.chachedChildItems.\n itemsList.push(slottedElement as MenuItem);\n continue;\n }\n const isHTMLSlotElement = slottedElement.localName === 'slot';\n const flattenedChildren = isHTMLSlotElement\n ? (slottedElement as HTMLSlotElement).assignedElements({\n flatten: true,\n })\n : [...slottedElement.querySelectorAll(`:scope > *`)];\n slottedElements.splice(\n i,\n 1,\n slottedElement,\n ...(flattenedChildren as HTMLElement[])\n );\n }\n\n this.cachedChildItems = [...itemsList];\n this.rovingTabindexController?.clearElementCache();\n\n return this.cachedChildItems;\n }\n\n /**\n * Hide this getter from web-component-analyzer until\n * https://github.com/runem/web-component-analyzer/issues/131\n * has been addressed.\n *\n * @private\n */\n public get childRole(): string {\n if (this.resolvedRole === 'listbox') {\n return 'option';\n }\n switch (this.resolvedSelects) {\n case 'single':\n return 'menuitemradio';\n case 'multiple':\n return 'menuitemcheckbox';\n default:\n return 'menuitem';\n }\n }\n\n protected get ownRole(): string {\n return 'menu';\n }\n\n /**\n * menuitem role based on selection type\n */\n private resolvedSelects?: SelectsType;\n\n /**\n * menu role based on selection type\n */\n private resolvedRole?: RoleType;\n\n /**\n * When a descendant `<sp-menu-item>` element is added or updated it will dispatch\n * this event to announce its presence in the DOM. During the CAPTURE phase the first\n * Menu based element that the event encounters will manage the focus state of the\n * dispatching `<sp-menu-item>` element.\n * @param event\n */\n private onFocusableItemAddedOrUpdated(\n event: MenuItemAddedOrUpdatedEvent\n ): void {\n event.menuCascade.set(this, {\n hadFocusRoot: !!event.item.menuData.focusRoot,\n ancestorWithSelects: event.currentAncestorWithSelects,\n });\n if (this.selects) {\n event.currentAncestorWithSelects = this;\n }\n event.item.menuData.focusRoot = event.item.menuData.focusRoot || this;\n }\n\n /**\n * When a descendant `<sp-menu-item>` element is added or updated it will dispatch\n * this event to announce its presence in the DOM. During the BUBBLE phase the first\n * Menu based element that the event encounters that does not inherit selection will\n * manage the selection state of the dispatching `<sp-menu-item>` element.\n * @param event\n */\n private onSelectableItemAddedOrUpdated(\n event: MenuItemAddedOrUpdatedEvent\n ): void {\n const cascadeData = event.menuCascade.get(this);\n /* c8 ignore next 1 */\n if (!cascadeData) return;\n\n event.item.menuData.parentMenu = event.item.menuData.parentMenu || this;\n this.addChildItem(event.item);\n\n if (this.selects === 'inherit') {\n this.resolvedSelects = 'inherit';\n const ignoreMenu = event.currentAncestorWithSelects?.ignore;\n this.resolvedRole = ignoreMenu\n ? 'none'\n : ((event.currentAncestorWithSelects?.getAttribute('role') ||\n this.getAttribute('role') ||\n undefined) as RoleType);\n } else if (this.selects) {\n this.resolvedRole = this.ignore\n ? 'none'\n : ((this.getAttribute('role') || undefined) as RoleType);\n this.resolvedSelects = this.selects;\n } else {\n this.resolvedRole = this.ignore\n ? 'none'\n : ((this.getAttribute('role') || undefined) as RoleType);\n this.resolvedSelects =\n this.resolvedRole === 'none' ? 'ignore' : 'none';\n }\n\n if (this.resolvedRole === 'none') {\n return;\n }\n\n const selects =\n this.resolvedSelects === 'single' ||\n this.resolvedSelects === 'multiple';\n event.item.menuData.cleanupSteps.push((item: MenuItem) =>\n this.removeChildItem(item)\n );\n if (\n (selects || (!this.selects && this.resolvedSelects !== 'ignore')) &&\n !event.item.menuData.selectionRoot\n ) {\n event.item.setRole(this.childRole);\n event.item.menuData.selectionRoot =\n event.item.menuData.selectionRoot || this;\n if (event.item.selected) {\n this.selectedItemsMap.set(event.item, true);\n this.selectedItems = [...this.selectedItems, event.item];\n this._selected = [...this.selected, event.item.value];\n this.value = this.selected.join(this.valueSeparator);\n }\n }\n }\n\n private addChildItem(item: MenuItem): void {\n this.childItemSet.add(item);\n this.handleItemsChanged();\n }\n\n private async removeChildItem(item: MenuItem): Promise<void> {\n if (item.focused || item.hasAttribute('focused') || item.active) {\n this._updateFocus = this.getNeighboringFocusableElement(item);\n }\n this.childItemSet.delete(item);\n this.cachedChildItems = undefined;\n }\n\n public constructor() {\n super();\n\n /**\n * only create an RTI if menu controls keyboard navigation and one does not already exist\n */\n if (!this.rovingTabindexController && this.controlsRovingTabindex) {\n this.rovingTabindexController =\n new RovingTabindexController<MenuItem>(this, {\n direction: 'vertical',\n focusInIndex: (elements: MenuItem[] | undefined) => {\n let firstEnabledIndex = -1;\n const firstSelectedIndex = elements?.findIndex(\n (el, index) => {\n if (\n !elements[firstEnabledIndex] &&\n !el.disabled\n ) {\n firstEnabledIndex = index;\n }\n return el.selected && !el.disabled;\n }\n );\n return elements &&\n firstSelectedIndex &&\n elements[firstSelectedIndex]\n ? firstSelectedIndex\n : firstEnabledIndex;\n },\n elements: () => this.childItems,\n isFocusableElement: this.isFocusableElement.bind(this),\n hostDelegatesFocus: true,\n });\n }\n\n this.addEventListener(\n 'sp-menu-item-added-or-updated',\n this.onSelectableItemAddedOrUpdated\n );\n this.addEventListener(\n 'sp-menu-item-added-or-updated',\n this.onFocusableItemAddedOrUpdated,\n {\n capture: true,\n }\n );\n\n this.addEventListener('click', this.handleClick);\n this.addEventListener('mouseover', this.handleMouseover);\n this.addEventListener('focusout', this.handleFocusout);\n this.addEventListener('sp-menu-item-keydown', this.handleKeydown);\n this.addEventListener('pointerup', this.handlePointerup);\n this.addEventListener('sp-opened', this.handleSubmenuOpened);\n this.addEventListener('sp-closed', this.handleSubmenuClosed);\n }\n\n /**\n * for picker elements, will set focus on first selected item\n */\n public focusOnFirstSelectedItem({\n preventScroll,\n }: FocusOptions = {}): void {\n if (!this.rovingTabindexController) return;\n const selectedItem = this.selectedItems.find((el) =>\n this.isFocusableElement(el)\n );\n if (!selectedItem) {\n this.focus({ preventScroll });\n return;\n }\n\n if (selectedItem && !preventScroll) {\n selectedItem.scrollIntoView({ block: 'nearest' });\n }\n this.rovingTabindexController?.focusOnItem(selectedItem);\n }\n\n public override focus({ preventScroll }: FocusOptions = {}): void {\n if (this.rovingTabindexController) {\n if (\n !this.childItems.length ||\n this.childItems.every((childItem) => childItem.disabled)\n ) {\n return;\n }\n if (\n this.childItems.some(\n (childItem) => childItem.menuData.focusRoot !== this\n )\n ) {\n super.focus({ preventScroll });\n return;\n }\n this.rovingTabindexController.focus({ preventScroll });\n }\n }\n\n // if the click and pointerup events are on the same target, we should not\n // handle the click event.\n private pointerUpTarget = null as EventTarget | null;\n\n private handleMouseover(event: MouseEvent): void {\n const { target } = event;\n const menuItem = target as MenuItem;\n if (\n this.childItems.includes(menuItem) &&\n this.isFocusableElement(menuItem)\n ) {\n this.rovingTabindexController?.focusOnItem(menuItem);\n }\n }\n\n private handleFocusout(): void {\n if (!this.matches(':focus-within'))\n this.rovingTabindexController?.reset();\n }\n\n private handleClick(event: Event): void {\n if (this.pointerUpTarget === event.target) {\n this.pointerUpTarget = null;\n return;\n }\n this.handlePointerBasedSelection(event);\n }\n\n private handlePointerup(event: Event): void {\n /*\n * early return if drag and select is not supported\n * in this case, selection will be handled by the click event\n */\n if (!this.shouldSupportDragAndSelect) {\n return;\n }\n this.pointerUpTarget = event.target;\n this.handlePointerBasedSelection(event);\n }\n\n private async handlePointerBasedSelection(event: Event): Promise<void> {\n // Only handle left clicks\n if (event instanceof MouseEvent && event.button !== 0) {\n return;\n }\n\n const path = event.composedPath();\n const target = path.find((el) => {\n /* c8 ignore next 3 */\n if (!(el instanceof Element)) {\n return false;\n }\n return el.getAttribute('role') === this.childRole;\n }) as MenuItem;\n if (event.defaultPrevented) {\n const index = this.childItems.indexOf(target);\n if (target?.menuData?.focusRoot === this && index > -1) {\n this.focusedItemIndex = index;\n }\n return;\n }\n if (target?.href && target.href.length) {\n // This event will NOT ALLOW CANCELATION as link action\n // cancelation should occur on the `<sp-menu-item>` itself.\n this.dispatchEvent(\n new Event('change', {\n bubbles: true,\n composed: true,\n })\n );\n return;\n } else if (\n target?.menuData?.selectionRoot === this &&\n this.childItems.length\n ) {\n event.preventDefault();\n if (target.hasSubmenu || target.open) {\n return;\n }\n this.selectOrToggleItem(target);\n } else {\n return;\n }\n this.prepareToCleanUp();\n }\n\n private descendentOverlays = new Map<Overlay, Overlay>();\n\n protected handleDescendentOverlayOpened(event: Event): void {\n const target = event.composedPath()[0] as MenuItem;\n /* c8 ignore next 1 */\n if (!target.overlayElement) return;\n this.descendentOverlays.set(\n target.overlayElement,\n target.overlayElement\n );\n }\n\n protected handleDescendentOverlayClosed(event: Event): void {\n const target = event.composedPath()[0] as MenuItem;\n /* c8 ignore next 1 */\n if (!target.overlayElement) return;\n this.descendentOverlays.delete(target.overlayElement);\n }\n\n public handleSubmenuClosed = (event: Event): void => {\n event.stopPropagation();\n const target = event.composedPath()[0] as Overlay;\n target.dispatchEvent(\n new Event('sp-menu-submenu-closed', {\n bubbles: true,\n composed: true,\n })\n );\n };\n\n /**\n * given a menu item, returns the next focusable menu item before or after it;\n * if no menu item is provided, returns the first focusable menu item\n * @param menuItem {MenuItem}\n * @param before {boolean} return the item before; default is false\n * @returns {MenuItem}\n */\n public getNeighboringFocusableElement(\n menuItem?: MenuItem,\n before = false\n ): MenuItem {\n const diff = before ? -1 : 1;\n const elements = this.rovingTabindexController?.elements || [];\n const index = !!menuItem ? elements.indexOf(menuItem) : -1;\n let newIndex = Math.min(Math.max(0, index + diff), elements.length - 1);\n while (\n !this.isFocusableElement(elements[newIndex]) &&\n 0 < newIndex &&\n newIndex < elements.length - 1\n ) {\n newIndex += diff;\n }\n return !!this.isFocusableElement(elements[newIndex])\n ? (elements[newIndex] as MenuItem)\n : menuItem || elements[0];\n }\n\n public handleSubmenuOpened = (event: Event): void => {\n event.stopPropagation();\n const target = event.composedPath()[0] as Overlay;\n target.dispatchEvent(\n new Event('sp-menu-submenu-opened', {\n bubbles: true,\n composed: true,\n })\n );\n\n const openedItem = event\n .composedPath()\n .find((el) => this.childItemSet.has(el as MenuItem));\n /* c8 ignore next 1 */\n if (!openedItem) return;\n };\n\n public async selectOrToggleItem(targetItem: MenuItem): Promise<void> {\n const resolvedSelects = this.resolvedSelects;\n const oldSelectedItemsMap = new Map(this.selectedItemsMap);\n const oldSelected = this.selected.slice();\n const oldSelectedItems = this.selectedItems.slice();\n const oldValue = this.value;\n\n if (targetItem.menuData.selectionRoot !== this) {\n return;\n }\n\n if (resolvedSelects === 'multiple') {\n if (this.selectedItemsMap.has(targetItem)) {\n this.selectedItemsMap.delete(targetItem);\n } else {\n this.selectedItemsMap.set(targetItem, true);\n }\n\n // Match HTML select and set the first selected\n // item as the value. Also set the selected array\n // in the order of the menu items.\n const selected: string[] = [];\n const selectedItems: MenuItem[] = [];\n\n this.childItemSet.forEach((childItem) => {\n if (childItem.menuData.selectionRoot !== this) return;\n\n if (this.selectedItemsMap.has(childItem)) {\n selected.push(childItem.value);\n selectedItems.push(childItem);\n }\n });\n this._selected = selected;\n this.selectedItems = selectedItems;\n this.value = this.selected.join(this.valueSeparator);\n } else {\n this.selectedItemsMap.clear();\n this.selectedItemsMap.set(targetItem, true);\n this.value = targetItem.value;\n this._selected = [targetItem.value];\n this.selectedItems = [targetItem];\n }\n\n const applyDefault = this.dispatchEvent(\n new Event('change', {\n cancelable: true,\n bubbles: true,\n composed: true,\n })\n );\n\n if (!applyDefault) {\n // Cancel the event & don't apply the selection\n this._selected = oldSelected;\n this.selectedItems = oldSelectedItems;\n this.selectedItemsMap = oldSelectedItemsMap;\n this.value = oldValue;\n return;\n }\n // Apply the selection changes to the menu items\n if (resolvedSelects === 'single') {\n for (const oldItem of oldSelectedItemsMap.keys()) {\n if (oldItem !== targetItem) {\n oldItem.selected = false;\n }\n }\n targetItem.selected = true;\n } else if (resolvedSelects === 'multiple') {\n targetItem.selected = !targetItem.selected;\n } else if (\n !targetItem.hasSubmenu &&\n targetItem?.menuData?.focusRoot === this\n ) {\n this.dispatchEvent(new Event('close', { bubbles: true }));\n }\n }\n\n protected navigateBetweenRelatedMenus(event: MenuItemKeydownEvent): void {\n const { key, root } = event;\n const shouldOpenSubmenu =\n (this.isLTR && key === 'ArrowRight') ||\n (!this.isLTR && key === 'ArrowLeft');\n const shouldCloseSelfAsSubmenu =\n (this.isLTR && key === 'ArrowLeft') ||\n (!this.isLTR && key === 'ArrowRight') ||\n key === 'Escape';\n const lastFocusedItem = root as MenuItem;\n if (shouldOpenSubmenu) {\n if (lastFocusedItem?.hasSubmenu) {\n //open submenu and set focus\n event.stopPropagation();\n lastFocusedItem.openOverlay();\n }\n } else if (shouldCloseSelfAsSubmenu && this.isSubmenu) {\n event.stopPropagation();\n this.dispatchEvent(new Event('close', { bubbles: true }));\n this.updateSelectedItemIndex();\n }\n }\n\n public handleKeydown(event: Event): void {\n if (event.defaultPrevented || !this.rovingTabindexController) {\n return;\n }\n const { key, root, shiftKey, target } = event as MenuItemKeydownEvent;\n const openSubmenuKey = ['Enter', ' '].includes(key);\n if (shiftKey && target !== this && this.hasAttribute('tabindex')) {\n this.removeAttribute('tabindex');\n const replaceTabindex = (\n event: FocusEvent | KeyboardEvent\n ): void => {\n if (\n !(event as KeyboardEvent).shiftKey &&\n !this.hasAttribute('tabindex')\n ) {\n document.removeEventListener('keyup', replaceTabindex);\n this.removeEventListener('focusout', replaceTabindex);\n }\n };\n document.addEventListener('keyup', replaceTabindex);\n this.addEventListener('focusout', replaceTabindex);\n }\n if (key === 'Tab') {\n this.closeDescendentOverlays();\n return;\n }\n if (openSubmenuKey && root?.hasSubmenu && !root.open) {\n // Remove focus while opening overlay from keyboard or the visible focus\n // will slip back to the first item in the menu.\n event.preventDefault();\n root.openOverlay();\n return;\n }\n if (key === ' ' || key === 'Enter') {\n event.preventDefault();\n root?.focusElement?.click();\n if (root) this.selectOrToggleItem(root);\n return;\n }\n this.navigateBetweenRelatedMenus(event as MenuItemKeydownEvent);\n }\n\n private _hasUpdatedSelectedItemIndex = false;\n\n /**\n * on focus, removes focus from focus styling item, and updates the selected item index\n */\n private prepareToCleanUp(): void {\n document.addEventListener(\n 'focusout',\n () => {\n requestAnimationFrame(() => {\n const focusedItem = this.focusInItem;\n if (focusedItem) {\n focusedItem.focused = false;\n }\n });\n },\n { once: true }\n );\n }\n\n public updateSelectedItemIndex(): void {\n let firstOrFirstSelectedIndex = 0;\n const selectedItemsMap = new Map<MenuItem, boolean>();\n const selected: string[] = [];\n const selectedItems: MenuItem[] = [];\n let itemIndex = this.childItems.length;\n while (itemIndex) {\n itemIndex -= 1;\n const childItem = this.childItems[itemIndex];\n if (childItem.menuData.selectionRoot === this) {\n if (\n childItem.selected ||\n (!this._hasUpdatedSelectedItemIndex &&\n this.selected.includes(childItem.value))\n ) {\n firstOrFirstSelectedIndex = itemIndex;\n selectedItemsMap.set(childItem, true);\n selected.unshift(childItem.value);\n selectedItems.unshift(childItem);\n }\n // Remove \"focused\" from non-\"selected\" items ONLY\n // Preserve \"focused\" on index===0 when no selection\n if (itemIndex !== firstOrFirstSelectedIndex) {\n childItem.focused = false;\n }\n }\n }\n\n this.selectedItemsMap = selectedItemsMap;\n this._selected = selected;\n this.selectedItems = selectedItems;\n this.value = this.selected.join(this.valueSeparator);\n this.focusedItemIndex = firstOrFirstSelectedIndex;\n this.focusInItemIndex = firstOrFirstSelectedIndex;\n }\n\n private _willUpdateItems = false;\n private _updateFocus?: MenuItem;\n\n private handleItemsChanged(): void {\n this.cachedChildItems = undefined;\n if (!this._willUpdateItems) {\n this._willUpdateItems = true;\n this.cacheUpdated = this.updateCache();\n }\n }\n\n private async updateCache(): Promise<void> {\n if (!this.hasUpdated) {\n await Promise.all([\n new Promise((res) => requestAnimationFrame(() => res(true))),\n this.updateComplete,\n ]);\n } else {\n await new Promise((res) => requestAnimationFrame(() => res(true)));\n }\n if (this.cachedChildItems === undefined) {\n this.updateSelectedItemIndex();\n this.updateItemFocus();\n }\n\n this._willUpdateItems = false;\n }\n\n private updateItemFocus(): void {\n this.focusInItem?.setAttribute('tabindex', '0');\n if (this.childItems.length == 0) {\n return;\n }\n }\n\n public closeDescendentOverlays(): void {\n this.descendentOverlays.forEach((overlay) => {\n overlay.open = false;\n });\n this.descendentOverlays = new Map<Overlay, Overlay>();\n }\n\n private handleSlotchange({\n target,\n }: Event & { target: HTMLSlotElement }): void {\n const assignedElements = target.assignedElements({\n flatten: true,\n }) as MenuItem[];\n if (this.childItems.length !== assignedElements.length) {\n assignedElements.forEach((item) => {\n if (typeof item.triggerUpdate !== 'undefined') {\n item.triggerUpdate();\n } else if (\n typeof (item as unknown as Menu).childItems !== 'undefined'\n ) {\n (item as unknown as Menu).childItems.forEach((child) => {\n child.triggerUpdate();\n });\n }\n });\n }\n if (!!this._updateFocus) {\n this.rovingTabindexController?.focusOnItem(this._updateFocus);\n this._updateFocus = undefined;\n }\n }\n\n protected renderMenuItemSlot(): TemplateResult {\n return html`\n <slot\n @sp-menu-submenu-opened=${this.handleDescendentOverlayOpened}\n @sp-menu-submenu-closed=${this.handleDescendentOverlayClosed}\n @slotchange=${this.handleSlotchange}\n ></slot>\n `;\n }\n\n public override render(): TemplateResult {\n return this.renderMenuItemSlot();\n }\n\n protected override firstUpdated(changed: PropertyValues): void {\n super.firstUpdated(changed);\n const updates: Promise<unknown>[] = [\n new Promise((res) => requestAnimationFrame(() => res(true))),\n ];\n [...this.children].forEach((item) => {\n if ((item as MenuItem).localName === 'sp-menu-item') {\n updates.push((item as MenuItem).updateComplete);\n }\n });\n this.childItemsUpdated = Promise.all(updates);\n }\n\n protected override updated(changes: PropertyValues<this>): void {\n super.updated(changes);\n if (changes.has('selects') && this.hasUpdated) {\n this.selectsChanged();\n }\n if (\n changes.has('label') &&\n (this.label || typeof changes.get('label') !== 'undefined')\n ) {\n if (this.label) {\n this.setAttribute('aria-label', this.label);\n /* c8 ignore next 3 */\n } else {\n this.removeAttribute('aria-label');\n }\n }\n }\n\n protected selectsChanged(): void {\n const updates: Promise<unknown>[] = [\n new Promise((res) => requestAnimationFrame(() => res(true))),\n ];\n this.childItemSet.forEach((childItem) => {\n updates.push(childItem.triggerUpdate());\n });\n this.childItemsUpdated = Promise.all(updates);\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role') && !this.ignore) {\n this.setAttribute('role', this.ownRole);\n }\n this.updateComplete.then(() => this.updateItemFocus());\n }\n\n private isFocusableElement(el: MenuItem): boolean {\n return el ? !el.disabled : false;\n }\n\n public override disconnectedCallback(): void {\n this.cachedChildItems = undefined;\n this.selectedItems = [];\n this.selectedItemsMap.clear();\n this.childItemSet.clear();\n this.descendentOverlays = new Map<Overlay, Overlay>();\n super.disconnectedCallback();\n }\n\n protected childItemsUpdated!: Promise<unknown[]>;\n protected cacheUpdated = Promise.resolve();\n /* c8 ignore next 3 */\n protected resolveCacheUpdated = (): void => {\n return;\n };\n\n protected override async getUpdateComplete(): Promise<boolean> {\n const complete = (await super.getUpdateComplete()) as boolean;\n await this.childItemsUpdated;\n await this.cacheUpdated;\n return complete;\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\nCopyright 2020 Adobe. All rights reserved.\nThis file is licensed to you under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License. You may obtain a copy\nof the License at http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software distributed under\nthe License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\nOF ANY KIND, either express or implied. See the License for the specific language\ngoverning permissions and limitations under the License.\n*/\n\nimport {\n CSSResultArray,\n html,\n PropertyValues,\n SizedMixin,\n SpectrumElement,\n TemplateResult,\n} from '@spectrum-web-components/base';\nimport {\n property,\n query,\n} from '@spectrum-web-components/base/src/decorators.js';\n\nimport { MenuItem } from './MenuItem.dev.js'\nimport type {\n MenuItemAddedOrUpdatedEvent,\n MenuItemKeydownEvent,\n} from './MenuItem.dev.js'\nimport type { Overlay } from '@spectrum-web-components/overlay';\nimport menuStyles from './menu.css.js';\nimport { RovingTabindexController } from '@spectrum-web-components/reactive-controllers/src/RovingTabindex.js';\n\nexport interface MenuChildItem {\n menuItem: MenuItem;\n managed: boolean;\n active: boolean;\n focusable: boolean;\n focusRoot: Menu;\n}\n\ntype SelectsType = 'none' | 'ignore' | 'inherit' | 'multiple' | 'single';\ntype RoleType = 'group' | 'menu' | 'listbox' | 'none';\n\n/**\n * Spectrum Menu Component\n * @element sp-menu\n *\n * @slot - menu items to be listed in the menu\n * @fires change - Announces that the `value` of the element has changed\n * @attr selects - whether the element has a specific selection algorithm that it applies\n * to its item descendants. `single` allows only one descendent to be selected at a time.\n * `multiple` allows many descendants to be selected. `inherit` will be applied dynamically\n * when an ancestor of this element is actively managing the selection of its descendents.\n * When the `selects` attribute is not present a `value` will not be maintained and the Menu\n * Item children of this Menu will not have their `selected` state managed.\n */\nexport class Menu extends SizedMixin(SpectrumElement, { noDefaultSize: true }) {\n public static override get styles(): CSSResultArray {\n return [menuStyles];\n }\n\n static override shadowRootOptions = {\n ...SpectrumElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n private get isSubmenu(): boolean {\n return this.slot === 'submenu';\n }\n\n protected rovingTabindexController?: RovingTabindexController<MenuItem>;\n\n /**\n * label of the menu\n */\n @property({ type: String, reflect: true })\n public label = '';\n\n /**\n * whether menu should be ignored by roving tabindex controller\n */\n @property({ type: Boolean, reflect: true })\n public ignore = false;\n\n /**\n * how the menu allows selection of its items:\n * - `undefined` (default): no selection is allowed\n * - `\"inherit\"`: the selection behavior is managed from an ancestor\n * - `\"single\"`: only one item can be selected at a time\n * - `\"multiple\"`: multiple items can be selected\n */\n @property({ type: String, reflect: true })\n public selects: undefined | 'inherit' | 'single' | 'multiple';\n\n /**\n * value of the selected item(s)\n */\n @property({ type: String })\n public value = '';\n\n // For the multiple select case, we'll join the value strings together\n // for the value property with this separator\n @property({ type: String, attribute: 'value-separator' })\n public valueSeparator = ',';\n\n /**\n * selected items values as string\n */\n @property({ attribute: false })\n public get selected(): string[] {\n return !this.selects ? [] : this._selected;\n }\n\n public set selected(selected: string[]) {\n if (selected === this.selected) {\n return;\n }\n const old = this.selected;\n this._selected = selected;\n this.selectedItems = [];\n this.selectedItemsMap.clear();\n this.childItems.forEach((item) => {\n if (this !== item.menuData.selectionRoot) {\n return;\n }\n item.selected = this.selected.includes(item.value);\n if (item.selected) {\n this.selectedItems.push(item);\n this.selectedItemsMap.set(item, true);\n }\n });\n this.requestUpdate('selected', old);\n }\n\n protected _selected = [] as string[];\n\n /**\n * array of selected menu items\n */\n @property({ attribute: false })\n public selectedItems = [] as MenuItem[];\n\n @query('slot:not([name])')\n public menuSlot!: HTMLSlotElement;\n\n private childItemSet = new Set<MenuItem>();\n public focusedItemIndex = 0;\n public focusInItemIndex = 0;\n\n /**\n * Whether to support the pointerdown-drag-pointerup selection strategy.\n * Defaults to false to prevent click/touch events from being captured\n * behind the menu tray in mobile environments (since the menu closes\n * immediately on pointerup).\n */\n\n public shouldSupportDragAndSelect = false;\n\n public get focusInItem(): MenuItem | undefined {\n return this.rovingTabindexController?.focusInElement;\n }\n\n protected get controlsRovingTabindex(): boolean {\n return true;\n }\n\n private selectedItemsMap = new Map<MenuItem, boolean>();\n\n /**\n * child items managed by menu\n */\n public get childItems(): MenuItem[] {\n if (!this.cachedChildItems) {\n this.cachedChildItems = this.updateCachedMenuItems();\n }\n return this.cachedChildItems;\n }\n\n private cachedChildItems: MenuItem[] | undefined;\n\n private updateCachedMenuItems(): MenuItem[] {\n if (!this.menuSlot) {\n return [];\n }\n const itemsList = [];\n const slottedElements = this.menuSlot.assignedElements({\n flatten: true,\n }) as HTMLElement[];\n // Recursively flatten <slot> and non-<sp-menu-item> elements assigned to the menu into a single array.\n for (const [i, slottedElement] of slottedElements.entries()) {\n if (this.childItemSet.has(slottedElement as MenuItem)) {\n // Assign <sp-menu-item> members of the array that are in this.childItemSet to this.chachedChildItems.\n itemsList.push(slottedElement as MenuItem);\n continue;\n }\n const isHTMLSlotElement = slottedElement.localName === 'slot';\n const flattenedChildren = isHTMLSlotElement\n ? (slottedElement as HTMLSlotElement).assignedElements({\n flatten: true,\n })\n : [...slottedElement.querySelectorAll(`:scope > *`)];\n slottedElements.splice(\n i,\n 1,\n slottedElement,\n ...(flattenedChildren as HTMLElement[])\n );\n }\n\n this.cachedChildItems = [...itemsList];\n this.rovingTabindexController?.clearElementCache();\n\n return this.cachedChildItems;\n }\n\n /**\n * Hide this getter from web-component-analyzer until\n * https://github.com/runem/web-component-analyzer/issues/131\n * has been addressed.\n *\n * @private\n */\n public get childRole(): string {\n if (this.resolvedRole === 'listbox') {\n return 'option';\n }\n switch (this.resolvedSelects) {\n case 'single':\n return 'menuitemradio';\n case 'multiple':\n return 'menuitemcheckbox';\n default:\n return 'menuitem';\n }\n }\n\n protected get ownRole(): string {\n return 'menu';\n }\n\n /**\n * menuitem role based on selection type\n */\n private resolvedSelects?: SelectsType;\n\n /**\n * menu role based on selection type\n */\n private resolvedRole?: RoleType;\n\n /**\n * When a descendant `<sp-menu-item>` element is added or updated it will dispatch\n * this event to announce its presence in the DOM. During the CAPTURE phase the first\n * Menu based element that the event encounters will manage the focus state of the\n * dispatching `<sp-menu-item>` element.\n * @param event\n */\n private onFocusableItemAddedOrUpdated(\n event: MenuItemAddedOrUpdatedEvent\n ): void {\n event.menuCascade.set(this, {\n hadFocusRoot: !!event.item.menuData.focusRoot,\n ancestorWithSelects: event.currentAncestorWithSelects,\n });\n if (this.selects) {\n event.currentAncestorWithSelects = this;\n }\n event.item.menuData.focusRoot = event.item.menuData.focusRoot || this;\n }\n\n /**\n * When a descendant `<sp-menu-item>` element is added or updated it will dispatch\n * this event to announce its presence in the DOM. During the BUBBLE phase the first\n * Menu based element that the event encounters that does not inherit selection will\n * manage the selection state of the dispatching `<sp-menu-item>` element.\n * @param event\n */\n private onSelectableItemAddedOrUpdated(\n event: MenuItemAddedOrUpdatedEvent\n ): void {\n const cascadeData = event.menuCascade.get(this);\n /* c8 ignore next 1 */\n if (!cascadeData) return;\n\n event.item.menuData.parentMenu = event.item.menuData.parentMenu || this;\n this.addChildItem(event.item);\n\n if (this.selects === 'inherit') {\n this.resolvedSelects = 'inherit';\n const ignoreMenu = event.currentAncestorWithSelects?.ignore;\n this.resolvedRole = ignoreMenu\n ? 'none'\n : ((event.currentAncestorWithSelects?.getAttribute('role') ||\n this.getAttribute('role') ||\n undefined) as RoleType);\n } else if (this.selects) {\n this.resolvedRole = this.ignore\n ? 'none'\n : ((this.getAttribute('role') || undefined) as RoleType);\n this.resolvedSelects = this.selects;\n } else {\n this.resolvedRole = this.ignore\n ? 'none'\n : ((this.getAttribute('role') || undefined) as RoleType);\n this.resolvedSelects =\n this.resolvedRole === 'none' ? 'ignore' : 'none';\n }\n\n if (this.resolvedRole === 'none') {\n return;\n }\n\n const selects =\n this.resolvedSelects === 'single' ||\n this.resolvedSelects === 'multiple';\n event.item.menuData.cleanupSteps.push((item: MenuItem) =>\n this.removeChildItem(item)\n );\n if (\n (selects || (!this.selects && this.resolvedSelects !== 'ignore')) &&\n !event.item.menuData.selectionRoot\n ) {\n event.item.setRole(this.childRole);\n event.item.menuData.selectionRoot =\n event.item.menuData.selectionRoot || this;\n if (event.item.selected) {\n this.selectedItemsMap.set(event.item, true);\n this.selectedItems = [...this.selectedItems, event.item];\n this._selected = [...this.selected, event.item.value];\n this.value = this.selected.join(this.valueSeparator);\n }\n }\n }\n\n private addChildItem(item: MenuItem): void {\n this.childItemSet.add(item);\n this.handleItemsChanged();\n }\n\n private async removeChildItem(item: MenuItem): Promise<void> {\n if (item.focused || item.hasAttribute('focused') || item.active) {\n this._updateFocus = this.getNeighboringFocusableElement(item);\n }\n this.childItemSet.delete(item);\n this.cachedChildItems = undefined;\n }\n\n public constructor() {\n super();\n\n /**\n * only create an RTI if menu controls keyboard navigation and one does not already exist\n */\n if (!this.rovingTabindexController && this.controlsRovingTabindex) {\n this.rovingTabindexController =\n new RovingTabindexController<MenuItem>(this, {\n direction: 'vertical',\n focusInIndex: (elements: MenuItem[] | undefined) => {\n let firstEnabledIndex = -1;\n const firstSelectedIndex = elements?.findIndex(\n (el, index) => {\n if (\n !elements[firstEnabledIndex] &&\n !el.disabled\n ) {\n firstEnabledIndex = index;\n }\n return el.selected && !el.disabled;\n }\n );\n return elements &&\n firstSelectedIndex &&\n elements[firstSelectedIndex]\n ? firstSelectedIndex\n : firstEnabledIndex;\n },\n elements: () => this.childItems,\n isFocusableElement: this.isFocusableElement.bind(this),\n hostDelegatesFocus: true,\n });\n }\n\n this.addEventListener(\n 'sp-menu-item-added-or-updated',\n this.onSelectableItemAddedOrUpdated\n );\n this.addEventListener(\n 'sp-menu-item-added-or-updated',\n this.onFocusableItemAddedOrUpdated,\n {\n capture: true,\n }\n );\n this.addEventListener('click', this.handleClick);\n this.addEventListener('touchend', this.handlePointerup);\n this.addEventListener('focusout', this.handleFocusout);\n this.addEventListener('sp-menu-item-keydown', this.handleKeydown);\n this.addEventListener('pointerup', this.handlePointerup);\n this.addEventListener('sp-opened', this.handleSubmenuOpened);\n this.addEventListener('sp-closed', this.handleSubmenuClosed);\n }\n\n /**\n * for picker elements, will set focus on first selected item\n */\n public focusOnFirstSelectedItem({\n preventScroll,\n }: FocusOptions = {}): void {\n if (!this.rovingTabindexController) return;\n const selectedItem = this.selectedItems.find((el) =>\n this.isFocusableElement(el)\n );\n if (!selectedItem) {\n this.focus({ preventScroll });\n return;\n }\n\n if (selectedItem && !preventScroll) {\n selectedItem.scrollIntoView({ block: 'nearest' });\n }\n this.rovingTabindexController?.focusOnItem(selectedItem);\n }\n\n public override focus({ preventScroll }: FocusOptions = {}): void {\n if (this.rovingTabindexController) {\n if (\n !this.childItems.length ||\n this.childItems.every((childItem) => childItem.disabled)\n ) {\n return;\n }\n if (\n this.childItems.some(\n (childItem) => childItem.menuData.focusRoot !== this\n )\n ) {\n super.focus({ preventScroll });\n return;\n }\n this.rovingTabindexController.focus({ preventScroll });\n }\n }\n\n // if the click and pointerup events are on the same target, we should not\n // handle the click event.\n private pointerUpTarget = null as EventTarget | null;\n\n private handleFocusout(): void {\n if (!this.matches(':focus-within'))\n this.rovingTabindexController?.reset();\n }\n\n private handleClick(event: Event): void {\n if (this.pointerUpTarget === event.target) {\n this.pointerUpTarget = null;\n return;\n }\n this.handlePointerBasedSelection(event);\n }\n\n private handlePointerup(event: Event): void {\n /*\n * early return if drag and select is not supported\n * in this case, selection will be handled by the click event\n */\n if (!this.shouldSupportDragAndSelect) {\n return;\n }\n this.pointerUpTarget = event.target;\n this.handlePointerBasedSelection(event);\n }\n\n private async handlePointerBasedSelection(event: Event): Promise<void> {\n // Only handle left clicks\n if (event instanceof MouseEvent && event.button !== 0) {\n return;\n }\n\n const path = event.composedPath();\n const target = path.find((el) => {\n /* c8 ignore next 3 */\n if (!(el instanceof Element)) {\n return false;\n }\n return el.getAttribute('role') === this.childRole;\n }) as MenuItem;\n if (event.defaultPrevented) {\n const index = this.childItems.indexOf(target);\n if (target?.menuData?.focusRoot === this && index > -1) {\n this.focusedItemIndex = index;\n }\n return;\n }\n if (target?.href && target.href.length) {\n // This event will NOT ALLOW CANCELATION as link action\n // cancelation should occur on the `<sp-menu-item>` itself.\n this.dispatchEvent(\n new Event('change', {\n bubbles: true,\n composed: true,\n })\n );\n return;\n } else if (\n target?.menuData?.selectionRoot === this &&\n this.childItems.length\n ) {\n event.preventDefault();\n if (target.hasSubmenu || target.open) {\n return;\n }\n this.selectOrToggleItem(target);\n } else {\n return;\n }\n this.prepareToCleanUp();\n }\n\n private descendentOverlays = new Map<Overlay, Overlay>();\n\n protected handleDescendentOverlayOpened(event: Event): void {\n const target = event.composedPath()[0] as MenuItem;\n /* c8 ignore next 1 */\n if (!target.overlayElement) return;\n this.descendentOverlays.set(\n target.overlayElement,\n target.overlayElement\n );\n }\n\n protected handleDescendentOverlayClosed(event: Event): void {\n const target = event.composedPath()[0] as MenuItem;\n /* c8 ignore next 1 */\n if (!target.overlayElement) return;\n this.descendentOverlays.delete(target.overlayElement);\n }\n\n public handleSubmenuClosed = (event: Event): void => {\n event.stopPropagation();\n const target = event.composedPath()[0] as Overlay;\n target.dispatchEvent(\n new Event('sp-menu-submenu-closed', {\n bubbles: true,\n composed: true,\n })\n );\n };\n\n /**\n * given a menu item, returns the next focusable menu item before or after it;\n * if no menu item is provided, returns the first focusable menu item\n * @param menuItem {MenuItem}\n * @param before {boolean} return the item before; default is false\n * @returns {MenuItem}\n */\n public getNeighboringFocusableElement(\n menuItem?: MenuItem,\n before = false\n ): MenuItem {\n const diff = before ? -1 : 1;\n const elements = this.rovingTabindexController?.elements || [];\n const index = !!menuItem ? elements.indexOf(menuItem) : -1;\n let newIndex = Math.min(Math.max(0, index + diff), elements.length - 1);\n while (\n !this.isFocusableElement(elements[newIndex]) &&\n 0 < newIndex &&\n newIndex < elements.length - 1\n ) {\n newIndex += diff;\n }\n return !!this.isFocusableElement(elements[newIndex])\n ? (elements[newIndex] as MenuItem)\n : menuItem || elements[0];\n }\n\n public handleSubmenuOpened = (event: Event): void => {\n event.stopPropagation();\n const target = event.composedPath()[0] as Overlay;\n target.dispatchEvent(\n new Event('sp-menu-submenu-opened', {\n bubbles: true,\n composed: true,\n })\n );\n\n const openedItem = event\n .composedPath()\n .find((el) => this.childItemSet.has(el as MenuItem));\n /* c8 ignore next 1 */\n if (!openedItem) return;\n };\n\n public async selectOrToggleItem(targetItem: MenuItem): Promise<void> {\n const resolvedSelects = this.resolvedSelects;\n const oldSelectedItemsMap = new Map(this.selectedItemsMap);\n const oldSelected = this.selected.slice();\n const oldSelectedItems = this.selectedItems.slice();\n const oldValue = this.value;\n\n if (targetItem.menuData.selectionRoot !== this) {\n return;\n }\n\n if (resolvedSelects === 'multiple') {\n if (this.selectedItemsMap.has(targetItem)) {\n this.selectedItemsMap.delete(targetItem);\n } else {\n this.selectedItemsMap.set(targetItem, true);\n }\n\n // Match HTML select and set the first selected\n // item as the value. Also set the selected array\n // in the order of the menu items.\n const selected: string[] = [];\n const selectedItems: MenuItem[] = [];\n\n this.childItemSet.forEach((childItem) => {\n if (childItem.menuData.selectionRoot !== this) return;\n\n if (this.selectedItemsMap.has(childItem)) {\n selected.push(childItem.value);\n selectedItems.push(childItem);\n }\n });\n this._selected = selected;\n this.selectedItems = selectedItems;\n this.value = this.selected.join(this.valueSeparator);\n } else {\n this.selectedItemsMap.clear();\n this.selectedItemsMap.set(targetItem, true);\n this.value = targetItem.value;\n this._selected = [targetItem.value];\n this.selectedItems = [targetItem];\n }\n\n const applyDefault = this.dispatchEvent(\n new Event('change', {\n cancelable: true,\n bubbles: true,\n composed: true,\n })\n );\n\n if (!applyDefault) {\n // Cancel the event & don't apply the selection\n this._selected = oldSelected;\n this.selectedItems = oldSelectedItems;\n this.selectedItemsMap = oldSelectedItemsMap;\n this.value = oldValue;\n return;\n }\n // Apply the selection changes to the menu items\n if (resolvedSelects === 'single') {\n for (const oldItem of oldSelectedItemsMap.keys()) {\n if (oldItem !== targetItem) {\n oldItem.selected = false;\n }\n }\n targetItem.selected = true;\n } else if (resolvedSelects === 'multiple') {\n targetItem.selected = !targetItem.selected;\n } else if (\n !targetItem.hasSubmenu &&\n targetItem?.menuData?.focusRoot === this\n ) {\n this.dispatchEvent(new Event('close', { bubbles: true }));\n }\n }\n\n protected navigateBetweenRelatedMenus(event: MenuItemKeydownEvent): void {\n const { key, root } = event;\n const shouldOpenSubmenu =\n (this.isLTR && key === 'ArrowRight') ||\n (!this.isLTR && key === 'ArrowLeft');\n const shouldCloseSelfAsSubmenu =\n (this.isLTR && key === 'ArrowLeft') ||\n (!this.isLTR && key === 'ArrowRight') ||\n key === 'Escape';\n const lastFocusedItem = root as MenuItem;\n if (shouldOpenSubmenu) {\n if (lastFocusedItem?.hasSubmenu) {\n //open submenu and set focus\n event.stopPropagation();\n lastFocusedItem.openOverlay(true);\n }\n } else if (shouldCloseSelfAsSubmenu && this.isSubmenu) {\n event.stopPropagation();\n this.dispatchEvent(new Event('close', { bubbles: true }));\n this.updateSelectedItemIndex();\n }\n }\n\n public handleKeydown(event: Event): void {\n if (event.defaultPrevented || !this.rovingTabindexController) {\n return;\n }\n const { key, root, shiftKey, target } = event as MenuItemKeydownEvent;\n const openSubmenuKey = ['Enter', ' '].includes(key);\n if (shiftKey && target !== this && this.hasAttribute('tabindex')) {\n this.removeAttribute('tabindex');\n const replaceTabindex = (\n event: FocusEvent | KeyboardEvent\n ): void => {\n if (\n !(event as KeyboardEvent).shiftKey &&\n !this.hasAttribute('tabindex')\n ) {\n document.removeEventListener('keyup', replaceTabindex);\n this.removeEventListener('focusout', replaceTabindex);\n }\n };\n document.addEventListener('keyup', replaceTabindex);\n this.addEventListener('focusout', replaceTabindex);\n }\n if (key === 'Tab') {\n this.closeDescendentOverlays();\n return;\n }\n if (openSubmenuKey && root?.hasSubmenu && !root.open) {\n // Remove focus while opening overlay from keyboard or the visible focus\n // will slip back to the first item in the menu.\n event.preventDefault();\n root.openOverlay(true);\n return;\n }\n if (key === ' ' || key === 'Enter') {\n event.preventDefault();\n root?.focusElement?.click();\n if (root) this.selectOrToggleItem(root);\n return;\n }\n this.navigateBetweenRelatedMenus(event as MenuItemKeydownEvent);\n }\n\n private _hasUpdatedSelectedItemIndex = false;\n\n /**\n * on focus, removes focus from focus styling item, and updates the selected item index\n */\n private prepareToCleanUp(): void {\n document.addEventListener(\n 'focusout',\n () => {\n requestAnimationFrame(() => {\n const focusedItem = this.focusInItem;\n if (focusedItem) {\n focusedItem.focused = false;\n }\n });\n },\n { once: true }\n );\n }\n\n public updateSelectedItemIndex(): void {\n let firstOrFirstSelectedIndex = 0;\n const selectedItemsMap = new Map<MenuItem, boolean>();\n const selected: string[] = [];\n const selectedItems: MenuItem[] = [];\n let itemIndex = this.childItems.length;\n while (itemIndex) {\n itemIndex -= 1;\n const childItem = this.childItems[itemIndex];\n if (childItem.menuData.selectionRoot === this) {\n if (\n childItem.selected ||\n (!this._hasUpdatedSelectedItemIndex &&\n this.selected.includes(childItem.value))\n ) {\n firstOrFirstSelectedIndex = itemIndex;\n selectedItemsMap.set(childItem, true);\n selected.unshift(childItem.value);\n selectedItems.unshift(childItem);\n }\n // Remove \"focused\" from non-\"selected\" items ONLY\n // Preserve \"focused\" on index===0 when no selection\n if (itemIndex !== firstOrFirstSelectedIndex) {\n childItem.focused = false;\n }\n }\n }\n\n this.selectedItemsMap = selectedItemsMap;\n this._selected = selected;\n this.selectedItems = selectedItems;\n this.value = this.selected.join(this.valueSeparator);\n this.focusedItemIndex = firstOrFirstSelectedIndex;\n this.focusInItemIndex = firstOrFirstSelectedIndex;\n }\n\n private _willUpdateItems = false;\n private _updateFocus?: MenuItem;\n\n private handleItemsChanged(): void {\n this.cachedChildItems = undefined;\n if (!this._willUpdateItems) {\n this._willUpdateItems = true;\n this.cacheUpdated = this.updateCache();\n }\n }\n\n private async updateCache(): Promise<void> {\n if (!this.hasUpdated) {\n await Promise.all([\n new Promise((res) => requestAnimationFrame(() => res(true))),\n this.updateComplete,\n ]);\n } else {\n await new Promise((res) => requestAnimationFrame(() => res(true)));\n }\n if (this.cachedChildItems === undefined) {\n this.updateSelectedItemIndex();\n this.updateItemFocus();\n }\n\n this._willUpdateItems = false;\n }\n\n private updateItemFocus(): void {\n this.focusInItem?.setAttribute('tabindex', '0');\n if (this.childItems.length == 0) {\n return;\n }\n }\n\n public closeDescendentOverlays(): void {\n this.descendentOverlays.forEach((overlay) => {\n overlay.open = false;\n });\n this.descendentOverlays = new Map<Overlay, Overlay>();\n }\n\n private handleSlotchange({\n target,\n }: Event & { target: HTMLSlotElement }): void {\n const assignedElements = target.assignedElements({\n flatten: true,\n }) as MenuItem[];\n if (this.childItems.length !== assignedElements.length) {\n assignedElements.forEach((item) => {\n if (typeof item.triggerUpdate !== 'undefined') {\n item.triggerUpdate();\n } else if (\n typeof (item as unknown as Menu).childItems !== 'undefined'\n ) {\n (item as unknown as Menu).childItems.forEach((child) => {\n child.triggerUpdate();\n });\n }\n });\n }\n if (!!this._updateFocus) {\n this.rovingTabindexController?.focusOnItem(this._updateFocus);\n this._updateFocus = undefined;\n }\n }\n\n protected renderMenuItemSlot(): TemplateResult {\n return html`\n <slot\n @sp-menu-submenu-opened=${this.handleDescendentOverlayOpened}\n @sp-menu-submenu-closed=${this.handleDescendentOverlayClosed}\n @slotchange=${this.handleSlotchange}\n ></slot>\n `;\n }\n\n public override render(): TemplateResult {\n return this.renderMenuItemSlot();\n }\n\n protected override firstUpdated(changed: PropertyValues): void {\n super.firstUpdated(changed);\n const updates: Promise<unknown>[] = [\n new Promise((res) => requestAnimationFrame(() => res(true))),\n ];\n [...this.children].forEach((item) => {\n if ((item as MenuItem).localName === 'sp-menu-item') {\n updates.push((item as MenuItem).updateComplete);\n }\n });\n this.childItemsUpdated = Promise.all(updates);\n }\n\n protected override updated(changes: PropertyValues<this>): void {\n super.updated(changes);\n if (changes.has('selects') && this.hasUpdated) {\n this.selectsChanged();\n }\n if (\n changes.has('label') &&\n (this.label || typeof changes.get('label') !== 'undefined')\n ) {\n if (this.label) {\n this.setAttribute('aria-label', this.label);\n /* c8 ignore next 3 */\n } else {\n this.removeAttribute('aria-label');\n }\n }\n }\n\n protected selectsChanged(): void {\n const updates: Promise<unknown>[] = [\n new Promise((res) => requestAnimationFrame(() => res(true))),\n ];\n this.childItemSet.forEach((childItem) => {\n updates.push(childItem.triggerUpdate());\n });\n this.childItemsUpdated = Promise.all(updates);\n }\n\n public override connectedCallback(): void {\n super.connectedCallback();\n if (!this.hasAttribute('role') && !this.ignore) {\n this.setAttribute('role', this.ownRole);\n }\n this.updateComplete.then(() => this.updateItemFocus());\n }\n\n private isFocusableElement(el: MenuItem): boolean {\n return el ? !el.disabled : false;\n }\n\n public override disconnectedCallback(): void {\n this.cachedChildItems = undefined;\n this.selectedItems = [];\n this.selectedItemsMap.clear();\n this.childItemSet.clear();\n this.descendentOverlays = new Map<Overlay, Overlay>();\n super.disconnectedCallback();\n }\n\n protected childItemsUpdated!: Promise<unknown[]>;\n protected cacheUpdated = Promise.resolve();\n /* c8 ignore next 3 */\n protected resolveCacheUpdated = (): void => {\n return;\n };\n\n protected override async getUpdateComplete(): Promise<boolean> {\n const complete = (await super.getUpdateComplete()) as boolean;\n await this.childItemsUpdated;\n await this.cacheUpdated;\n return complete;\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["event"]
7
7
  }
package/src/Menu.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";var v=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var o=(m,c,e,s)=>{for(var t=s>1?void 0:s?I(c,e):c,i=m.length-1,n;i>=0;i--)(n=m[i])&&(t=(s?n(c,e,t):n(t))||t);return s&&t&&v(c,e,t),t};import{html as b,SizedMixin as g,SpectrumElement as f}from"@spectrum-web-components/base";import{property as u,query as E}from"@spectrum-web-components/base/src/decorators.js";import S from"./menu.css.js";import{RovingTabindexController as M}from"@spectrum-web-components/reactive-controllers/src/RovingTabindex.js";export class Menu extends g(f,{noDefaultSize:!0}){constructor(){super();this.label="";this.ignore=!1;this.value="";this.valueSeparator=",";this._selected=[];this.selectedItems=[];this.childItemSet=new Set;this.focusedItemIndex=0;this.focusInItemIndex=0;this.shouldSupportDragAndSelect=!0;this.selectedItemsMap=new Map;this.pointerUpTarget=null;this.descendentOverlays=new Map;this.handleSubmenuClosed=e=>{e.stopPropagation(),e.composedPath()[0].dispatchEvent(new Event("sp-menu-submenu-closed",{bubbles:!0,composed:!0}))};this.handleSubmenuOpened=e=>{e.stopPropagation(),e.composedPath()[0].dispatchEvent(new Event("sp-menu-submenu-opened",{bubbles:!0,composed:!0})),e.composedPath().find(i=>this.childItemSet.has(i))};this._hasUpdatedSelectedItemIndex=!1;this._willUpdateItems=!1;this.cacheUpdated=Promise.resolve();this.resolveCacheUpdated=()=>{};!this.rovingTabindexController&&this.controlsRovingTabindex&&(this.rovingTabindexController=new M(this,{direction:"vertical",focusInIndex:e=>{let s=-1;const t=e==null?void 0:e.findIndex((i,n)=>(!e[s]&&!i.disabled&&(s=n),i.selected&&!i.disabled));return e&&t&&e[t]?t:s},elements:()=>this.childItems,isFocusableElement:this.isFocusableElement.bind(this),hostDelegatesFocus:!0})),this.addEventListener("sp-menu-item-added-or-updated",this.onSelectableItemAddedOrUpdated),this.addEventListener("sp-menu-item-added-or-updated",this.onFocusableItemAddedOrUpdated,{capture:!0}),this.addEventListener("click",this.handleClick),this.addEventListener("mouseover",this.handleMouseover),this.addEventListener("focusout",this.handleFocusout),this.addEventListener("sp-menu-item-keydown",this.handleKeydown),this.addEventListener("pointerup",this.handlePointerup),this.addEventListener("sp-opened",this.handleSubmenuOpened),this.addEventListener("sp-closed",this.handleSubmenuClosed)}static get styles(){return[S]}get isSubmenu(){return this.slot==="submenu"}get selected(){return this.selects?this._selected:[]}set selected(e){if(e===this.selected)return;const s=this.selected;this._selected=e,this.selectedItems=[],this.selectedItemsMap.clear(),this.childItems.forEach(t=>{this===t.menuData.selectionRoot&&(t.selected=this.selected.includes(t.value),t.selected&&(this.selectedItems.push(t),this.selectedItemsMap.set(t,!0)))}),this.requestUpdate("selected",s)}get focusInItem(){var e;return(e=this.rovingTabindexController)==null?void 0:e.focusInElement}get controlsRovingTabindex(){return!0}get childItems(){return this.cachedChildItems||(this.cachedChildItems=this.updateCachedMenuItems()),this.cachedChildItems}updateCachedMenuItems(){var t;if(!this.menuSlot)return[];const e=[],s=this.menuSlot.assignedElements({flatten:!0});for(const[i,n]of s.entries()){if(this.childItemSet.has(n)){e.push(n);continue}const d=n.localName==="slot"?n.assignedElements({flatten:!0}):[...n.querySelectorAll(":scope > *")];s.splice(i,1,n,...d)}return this.cachedChildItems=[...e],(t=this.rovingTabindexController)==null||t.clearElementCache(),this.cachedChildItems}get childRole(){if(this.resolvedRole==="listbox")return"option";switch(this.resolvedSelects){case"single":return"menuitemradio";case"multiple":return"menuitemcheckbox";default:return"menuitem"}}get ownRole(){return"menu"}onFocusableItemAddedOrUpdated(e){e.menuCascade.set(this,{hadFocusRoot:!!e.item.menuData.focusRoot,ancestorWithSelects:e.currentAncestorWithSelects}),this.selects&&(e.currentAncestorWithSelects=this),e.item.menuData.focusRoot=e.item.menuData.focusRoot||this}onSelectableItemAddedOrUpdated(e){var i,n;if(!e.menuCascade.get(this))return;if(e.item.menuData.parentMenu=e.item.menuData.parentMenu||this,this.addChildItem(e.item),this.selects==="inherit"){this.resolvedSelects="inherit";const l=(i=e.currentAncestorWithSelects)==null?void 0:i.ignore;this.resolvedRole=l?"none":((n=e.currentAncestorWithSelects)==null?void 0:n.getAttribute("role"))||this.getAttribute("role")||void 0}else this.selects?(this.resolvedRole=this.ignore?"none":this.getAttribute("role")||void 0,this.resolvedSelects=this.selects):(this.resolvedRole=this.ignore?"none":this.getAttribute("role")||void 0,this.resolvedSelects=this.resolvedRole==="none"?"ignore":"none");if(this.resolvedRole==="none")return;const t=this.resolvedSelects==="single"||this.resolvedSelects==="multiple";e.item.menuData.cleanupSteps.push(l=>this.removeChildItem(l)),(t||!this.selects&&this.resolvedSelects!=="ignore")&&!e.item.menuData.selectionRoot&&(e.item.setRole(this.childRole),e.item.menuData.selectionRoot=e.item.menuData.selectionRoot||this,e.item.selected&&(this.selectedItemsMap.set(e.item,!0),this.selectedItems=[...this.selectedItems,e.item],this._selected=[...this.selected,e.item.value],this.value=this.selected.join(this.valueSeparator)))}addChildItem(e){this.childItemSet.add(e),this.handleItemsChanged()}async removeChildItem(e){(e.focused||e.hasAttribute("focused")||e.active)&&(this._updateFocus=this.getNeighboringFocusableElement(e)),this.childItemSet.delete(e),this.cachedChildItems=void 0}focusOnFirstSelectedItem({preventScroll:e}={}){var t;if(!this.rovingTabindexController)return;const s=this.selectedItems.find(i=>this.isFocusableElement(i));if(!s){this.focus({preventScroll:e});return}s&&!e&&s.scrollIntoView({block:"nearest"}),(t=this.rovingTabindexController)==null||t.focusOnItem(s)}focus({preventScroll:e}={}){if(this.rovingTabindexController){if(!this.childItems.length||this.childItems.every(s=>s.disabled))return;if(this.childItems.some(s=>s.menuData.focusRoot!==this)){super.focus({preventScroll:e});return}this.rovingTabindexController.focus({preventScroll:e})}}handleMouseover(e){var i;const{target:s}=e,t=s;this.childItems.includes(t)&&this.isFocusableElement(t)&&((i=this.rovingTabindexController)==null||i.focusOnItem(t))}handleFocusout(){var e;this.matches(":focus-within")||(e=this.rovingTabindexController)==null||e.reset()}handleClick(e){if(this.pointerUpTarget===e.target){this.pointerUpTarget=null;return}this.handlePointerBasedSelection(e)}handlePointerup(e){this.shouldSupportDragAndSelect&&(this.pointerUpTarget=e.target,this.handlePointerBasedSelection(e))}async handlePointerBasedSelection(e){var i,n;if(e instanceof MouseEvent&&e.button!==0)return;const t=e.composedPath().find(l=>l instanceof Element?l.getAttribute("role")===this.childRole:!1);if(e.defaultPrevented){const l=this.childItems.indexOf(t);((i=t==null?void 0:t.menuData)==null?void 0:i.focusRoot)===this&&l>-1&&(this.focusedItemIndex=l);return}if(t!=null&&t.href&&t.href.length){this.dispatchEvent(new Event("change",{bubbles:!0,composed:!0}));return}else if(((n=t==null?void 0:t.menuData)==null?void 0:n.selectionRoot)===this&&this.childItems.length){if(e.preventDefault(),t.hasSubmenu||t.open)return;this.selectOrToggleItem(t)}else return;this.prepareToCleanUp()}handleDescendentOverlayOpened(e){const s=e.composedPath()[0];s.overlayElement&&this.descendentOverlays.set(s.overlayElement,s.overlayElement)}handleDescendentOverlayClosed(e){const s=e.composedPath()[0];s.overlayElement&&this.descendentOverlays.delete(s.overlayElement)}getNeighboringFocusableElement(e,s=!1){var d;const t=s?-1:1,i=((d=this.rovingTabindexController)==null?void 0:d.elements)||[],n=e?i.indexOf(e):-1;let l=Math.min(Math.max(0,n+t),i.length-1);for(;!this.isFocusableElement(i[l])&&0<l&&l<i.length-1;)l+=t;return this.isFocusableElement(i[l])?i[l]:e||i[0]}async selectOrToggleItem(e){var a;const s=this.resolvedSelects,t=new Map(this.selectedItemsMap),i=this.selected.slice(),n=this.selectedItems.slice(),l=this.value;if(e.menuData.selectionRoot!==this)return;if(s==="multiple"){this.selectedItemsMap.has(e)?this.selectedItemsMap.delete(e):this.selectedItemsMap.set(e,!0);const r=[],p=[];this.childItemSet.forEach(h=>{h.menuData.selectionRoot===this&&this.selectedItemsMap.has(h)&&(r.push(h.value),p.push(h))}),this._selected=r,this.selectedItems=p,this.value=this.selected.join(this.valueSeparator)}else this.selectedItemsMap.clear(),this.selectedItemsMap.set(e,!0),this.value=e.value,this._selected=[e.value],this.selectedItems=[e];if(!this.dispatchEvent(new Event("change",{cancelable:!0,bubbles:!0,composed:!0}))){this._selected=i,this.selectedItems=n,this.selectedItemsMap=t,this.value=l;return}if(s==="single"){for(const r of t.keys())r!==e&&(r.selected=!1);e.selected=!0}else s==="multiple"?e.selected=!e.selected:!e.hasSubmenu&&((a=e==null?void 0:e.menuData)==null?void 0:a.focusRoot)===this&&this.dispatchEvent(new Event("close",{bubbles:!0}))}navigateBetweenRelatedMenus(e){const{key:s,root:t}=e,i=this.isLTR&&s==="ArrowRight"||!this.isLTR&&s==="ArrowLeft",n=this.isLTR&&s==="ArrowLeft"||!this.isLTR&&s==="ArrowRight"||s==="Escape",l=t;i?l!=null&&l.hasSubmenu&&(e.stopPropagation(),l.openOverlay()):n&&this.isSubmenu&&(e.stopPropagation(),this.dispatchEvent(new Event("close",{bubbles:!0})),this.updateSelectedItemIndex())}handleKeydown(e){var d;if(e.defaultPrevented||!this.rovingTabindexController)return;const{key:s,root:t,shiftKey:i,target:n}=e,l=["Enter"," "].includes(s);if(i&&n!==this&&this.hasAttribute("tabindex")){this.removeAttribute("tabindex");const a=r=>{!r.shiftKey&&!this.hasAttribute("tabindex")&&(document.removeEventListener("keyup",a),this.removeEventListener("focusout",a))};document.addEventListener("keyup",a),this.addEventListener("focusout",a)}if(s==="Tab"){this.closeDescendentOverlays();return}if(l&&(t!=null&&t.hasSubmenu)&&!t.open){e.preventDefault(),t.openOverlay();return}if(s===" "||s==="Enter"){e.preventDefault(),(d=t==null?void 0:t.focusElement)==null||d.click(),t&&this.selectOrToggleItem(t);return}this.navigateBetweenRelatedMenus(e)}prepareToCleanUp(){document.addEventListener("focusout",()=>{requestAnimationFrame(()=>{const e=this.focusInItem;e&&(e.focused=!1)})},{once:!0})}updateSelectedItemIndex(){let e=0;const s=new Map,t=[],i=[];let n=this.childItems.length;for(;n;){n-=1;const l=this.childItems[n];l.menuData.selectionRoot===this&&((l.selected||!this._hasUpdatedSelectedItemIndex&&this.selected.includes(l.value))&&(e=n,s.set(l,!0),t.unshift(l.value),i.unshift(l)),n!==e&&(l.focused=!1))}this.selectedItemsMap=s,this._selected=t,this.selectedItems=i,this.value=this.selected.join(this.valueSeparator),this.focusedItemIndex=e,this.focusInItemIndex=e}handleItemsChanged(){this.cachedChildItems=void 0,this._willUpdateItems||(this._willUpdateItems=!0,this.cacheUpdated=this.updateCache())}async updateCache(){this.hasUpdated?await new Promise(e=>requestAnimationFrame(()=>e(!0))):await Promise.all([new Promise(e=>requestAnimationFrame(()=>e(!0))),this.updateComplete]),this.cachedChildItems===void 0&&(this.updateSelectedItemIndex(),this.updateItemFocus()),this._willUpdateItems=!1}updateItemFocus(){var e;(e=this.focusInItem)==null||e.setAttribute("tabindex","0"),this.childItems.length!=0}closeDescendentOverlays(){this.descendentOverlays.forEach(e=>{e.open=!1}),this.descendentOverlays=new Map}handleSlotchange({target:e}){var t;const s=e.assignedElements({flatten:!0});this.childItems.length!==s.length&&s.forEach(i=>{typeof i.triggerUpdate!="undefined"?i.triggerUpdate():typeof i.childItems!="undefined"&&i.childItems.forEach(n=>{n.triggerUpdate()})}),this._updateFocus&&((t=this.rovingTabindexController)==null||t.focusOnItem(this._updateFocus),this._updateFocus=void 0)}renderMenuItemSlot(){return b`
1
+ "use strict";var v=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var o=(p,c,e,s)=>{for(var t=s>1?void 0:s?I(c,e):c,i=p.length-1,n;i>=0;i--)(n=p[i])&&(t=(s?n(c,e,t):n(t))||t);return s&&t&&v(c,e,t),t};import{html as b,SizedMixin as g,SpectrumElement as f}from"@spectrum-web-components/base";import{property as u,query as E}from"@spectrum-web-components/base/src/decorators.js";import S from"./menu.css.js";import{RovingTabindexController as y}from"@spectrum-web-components/reactive-controllers/src/RovingTabindex.js";export class Menu extends g(f,{noDefaultSize:!0}){constructor(){super();this.label="";this.ignore=!1;this.value="";this.valueSeparator=",";this._selected=[];this.selectedItems=[];this.childItemSet=new Set;this.focusedItemIndex=0;this.focusInItemIndex=0;this.shouldSupportDragAndSelect=!1;this.selectedItemsMap=new Map;this.pointerUpTarget=null;this.descendentOverlays=new Map;this.handleSubmenuClosed=e=>{e.stopPropagation(),e.composedPath()[0].dispatchEvent(new Event("sp-menu-submenu-closed",{bubbles:!0,composed:!0}))};this.handleSubmenuOpened=e=>{e.stopPropagation(),e.composedPath()[0].dispatchEvent(new Event("sp-menu-submenu-opened",{bubbles:!0,composed:!0})),e.composedPath().find(i=>this.childItemSet.has(i))};this._hasUpdatedSelectedItemIndex=!1;this._willUpdateItems=!1;this.cacheUpdated=Promise.resolve();this.resolveCacheUpdated=()=>{};!this.rovingTabindexController&&this.controlsRovingTabindex&&(this.rovingTabindexController=new y(this,{direction:"vertical",focusInIndex:e=>{let s=-1;const t=e==null?void 0:e.findIndex((i,n)=>(!e[s]&&!i.disabled&&(s=n),i.selected&&!i.disabled));return e&&t&&e[t]?t:s},elements:()=>this.childItems,isFocusableElement:this.isFocusableElement.bind(this),hostDelegatesFocus:!0})),this.addEventListener("sp-menu-item-added-or-updated",this.onSelectableItemAddedOrUpdated),this.addEventListener("sp-menu-item-added-or-updated",this.onFocusableItemAddedOrUpdated,{capture:!0}),this.addEventListener("click",this.handleClick),this.addEventListener("touchend",this.handlePointerup),this.addEventListener("focusout",this.handleFocusout),this.addEventListener("sp-menu-item-keydown",this.handleKeydown),this.addEventListener("pointerup",this.handlePointerup),this.addEventListener("sp-opened",this.handleSubmenuOpened),this.addEventListener("sp-closed",this.handleSubmenuClosed)}static get styles(){return[S]}get isSubmenu(){return this.slot==="submenu"}get selected(){return this.selects?this._selected:[]}set selected(e){if(e===this.selected)return;const s=this.selected;this._selected=e,this.selectedItems=[],this.selectedItemsMap.clear(),this.childItems.forEach(t=>{this===t.menuData.selectionRoot&&(t.selected=this.selected.includes(t.value),t.selected&&(this.selectedItems.push(t),this.selectedItemsMap.set(t,!0)))}),this.requestUpdate("selected",s)}get focusInItem(){var e;return(e=this.rovingTabindexController)==null?void 0:e.focusInElement}get controlsRovingTabindex(){return!0}get childItems(){return this.cachedChildItems||(this.cachedChildItems=this.updateCachedMenuItems()),this.cachedChildItems}updateCachedMenuItems(){var t;if(!this.menuSlot)return[];const e=[],s=this.menuSlot.assignedElements({flatten:!0});for(const[i,n]of s.entries()){if(this.childItemSet.has(n)){e.push(n);continue}const d=n.localName==="slot"?n.assignedElements({flatten:!0}):[...n.querySelectorAll(":scope > *")];s.splice(i,1,n,...d)}return this.cachedChildItems=[...e],(t=this.rovingTabindexController)==null||t.clearElementCache(),this.cachedChildItems}get childRole(){if(this.resolvedRole==="listbox")return"option";switch(this.resolvedSelects){case"single":return"menuitemradio";case"multiple":return"menuitemcheckbox";default:return"menuitem"}}get ownRole(){return"menu"}onFocusableItemAddedOrUpdated(e){e.menuCascade.set(this,{hadFocusRoot:!!e.item.menuData.focusRoot,ancestorWithSelects:e.currentAncestorWithSelects}),this.selects&&(e.currentAncestorWithSelects=this),e.item.menuData.focusRoot=e.item.menuData.focusRoot||this}onSelectableItemAddedOrUpdated(e){var i,n;if(!e.menuCascade.get(this))return;if(e.item.menuData.parentMenu=e.item.menuData.parentMenu||this,this.addChildItem(e.item),this.selects==="inherit"){this.resolvedSelects="inherit";const l=(i=e.currentAncestorWithSelects)==null?void 0:i.ignore;this.resolvedRole=l?"none":((n=e.currentAncestorWithSelects)==null?void 0:n.getAttribute("role"))||this.getAttribute("role")||void 0}else this.selects?(this.resolvedRole=this.ignore?"none":this.getAttribute("role")||void 0,this.resolvedSelects=this.selects):(this.resolvedRole=this.ignore?"none":this.getAttribute("role")||void 0,this.resolvedSelects=this.resolvedRole==="none"?"ignore":"none");if(this.resolvedRole==="none")return;const t=this.resolvedSelects==="single"||this.resolvedSelects==="multiple";e.item.menuData.cleanupSteps.push(l=>this.removeChildItem(l)),(t||!this.selects&&this.resolvedSelects!=="ignore")&&!e.item.menuData.selectionRoot&&(e.item.setRole(this.childRole),e.item.menuData.selectionRoot=e.item.menuData.selectionRoot||this,e.item.selected&&(this.selectedItemsMap.set(e.item,!0),this.selectedItems=[...this.selectedItems,e.item],this._selected=[...this.selected,e.item.value],this.value=this.selected.join(this.valueSeparator)))}addChildItem(e){this.childItemSet.add(e),this.handleItemsChanged()}async removeChildItem(e){(e.focused||e.hasAttribute("focused")||e.active)&&(this._updateFocus=this.getNeighboringFocusableElement(e)),this.childItemSet.delete(e),this.cachedChildItems=void 0}focusOnFirstSelectedItem({preventScroll:e}={}){var t;if(!this.rovingTabindexController)return;const s=this.selectedItems.find(i=>this.isFocusableElement(i));if(!s){this.focus({preventScroll:e});return}s&&!e&&s.scrollIntoView({block:"nearest"}),(t=this.rovingTabindexController)==null||t.focusOnItem(s)}focus({preventScroll:e}={}){if(this.rovingTabindexController){if(!this.childItems.length||this.childItems.every(s=>s.disabled))return;if(this.childItems.some(s=>s.menuData.focusRoot!==this)){super.focus({preventScroll:e});return}this.rovingTabindexController.focus({preventScroll:e})}}handleFocusout(){var e;this.matches(":focus-within")||(e=this.rovingTabindexController)==null||e.reset()}handleClick(e){if(this.pointerUpTarget===e.target){this.pointerUpTarget=null;return}this.handlePointerBasedSelection(e)}handlePointerup(e){this.shouldSupportDragAndSelect&&(this.pointerUpTarget=e.target,this.handlePointerBasedSelection(e))}async handlePointerBasedSelection(e){var i,n;if(e instanceof MouseEvent&&e.button!==0)return;const t=e.composedPath().find(l=>l instanceof Element?l.getAttribute("role")===this.childRole:!1);if(e.defaultPrevented){const l=this.childItems.indexOf(t);((i=t==null?void 0:t.menuData)==null?void 0:i.focusRoot)===this&&l>-1&&(this.focusedItemIndex=l);return}if(t!=null&&t.href&&t.href.length){this.dispatchEvent(new Event("change",{bubbles:!0,composed:!0}));return}else if(((n=t==null?void 0:t.menuData)==null?void 0:n.selectionRoot)===this&&this.childItems.length){if(e.preventDefault(),t.hasSubmenu||t.open)return;this.selectOrToggleItem(t)}else return;this.prepareToCleanUp()}handleDescendentOverlayOpened(e){const s=e.composedPath()[0];s.overlayElement&&this.descendentOverlays.set(s.overlayElement,s.overlayElement)}handleDescendentOverlayClosed(e){const s=e.composedPath()[0];s.overlayElement&&this.descendentOverlays.delete(s.overlayElement)}getNeighboringFocusableElement(e,s=!1){var d;const t=s?-1:1,i=((d=this.rovingTabindexController)==null?void 0:d.elements)||[],n=e?i.indexOf(e):-1;let l=Math.min(Math.max(0,n+t),i.length-1);for(;!this.isFocusableElement(i[l])&&0<l&&l<i.length-1;)l+=t;return this.isFocusableElement(i[l])?i[l]:e||i[0]}async selectOrToggleItem(e){var a;const s=this.resolvedSelects,t=new Map(this.selectedItemsMap),i=this.selected.slice(),n=this.selectedItems.slice(),l=this.value;if(e.menuData.selectionRoot!==this)return;if(s==="multiple"){this.selectedItemsMap.has(e)?this.selectedItemsMap.delete(e):this.selectedItemsMap.set(e,!0);const r=[],m=[];this.childItemSet.forEach(h=>{h.menuData.selectionRoot===this&&this.selectedItemsMap.has(h)&&(r.push(h.value),m.push(h))}),this._selected=r,this.selectedItems=m,this.value=this.selected.join(this.valueSeparator)}else this.selectedItemsMap.clear(),this.selectedItemsMap.set(e,!0),this.value=e.value,this._selected=[e.value],this.selectedItems=[e];if(!this.dispatchEvent(new Event("change",{cancelable:!0,bubbles:!0,composed:!0}))){this._selected=i,this.selectedItems=n,this.selectedItemsMap=t,this.value=l;return}if(s==="single"){for(const r of t.keys())r!==e&&(r.selected=!1);e.selected=!0}else s==="multiple"?e.selected=!e.selected:!e.hasSubmenu&&((a=e==null?void 0:e.menuData)==null?void 0:a.focusRoot)===this&&this.dispatchEvent(new Event("close",{bubbles:!0}))}navigateBetweenRelatedMenus(e){const{key:s,root:t}=e,i=this.isLTR&&s==="ArrowRight"||!this.isLTR&&s==="ArrowLeft",n=this.isLTR&&s==="ArrowLeft"||!this.isLTR&&s==="ArrowRight"||s==="Escape",l=t;i?l!=null&&l.hasSubmenu&&(e.stopPropagation(),l.openOverlay(!0)):n&&this.isSubmenu&&(e.stopPropagation(),this.dispatchEvent(new Event("close",{bubbles:!0})),this.updateSelectedItemIndex())}handleKeydown(e){var d;if(e.defaultPrevented||!this.rovingTabindexController)return;const{key:s,root:t,shiftKey:i,target:n}=e,l=["Enter"," "].includes(s);if(i&&n!==this&&this.hasAttribute("tabindex")){this.removeAttribute("tabindex");const a=r=>{!r.shiftKey&&!this.hasAttribute("tabindex")&&(document.removeEventListener("keyup",a),this.removeEventListener("focusout",a))};document.addEventListener("keyup",a),this.addEventListener("focusout",a)}if(s==="Tab"){this.closeDescendentOverlays();return}if(l&&(t!=null&&t.hasSubmenu)&&!t.open){e.preventDefault(),t.openOverlay(!0);return}if(s===" "||s==="Enter"){e.preventDefault(),(d=t==null?void 0:t.focusElement)==null||d.click(),t&&this.selectOrToggleItem(t);return}this.navigateBetweenRelatedMenus(e)}prepareToCleanUp(){document.addEventListener("focusout",()=>{requestAnimationFrame(()=>{const e=this.focusInItem;e&&(e.focused=!1)})},{once:!0})}updateSelectedItemIndex(){let e=0;const s=new Map,t=[],i=[];let n=this.childItems.length;for(;n;){n-=1;const l=this.childItems[n];l.menuData.selectionRoot===this&&((l.selected||!this._hasUpdatedSelectedItemIndex&&this.selected.includes(l.value))&&(e=n,s.set(l,!0),t.unshift(l.value),i.unshift(l)),n!==e&&(l.focused=!1))}this.selectedItemsMap=s,this._selected=t,this.selectedItems=i,this.value=this.selected.join(this.valueSeparator),this.focusedItemIndex=e,this.focusInItemIndex=e}handleItemsChanged(){this.cachedChildItems=void 0,this._willUpdateItems||(this._willUpdateItems=!0,this.cacheUpdated=this.updateCache())}async updateCache(){this.hasUpdated?await new Promise(e=>requestAnimationFrame(()=>e(!0))):await Promise.all([new Promise(e=>requestAnimationFrame(()=>e(!0))),this.updateComplete]),this.cachedChildItems===void 0&&(this.updateSelectedItemIndex(),this.updateItemFocus()),this._willUpdateItems=!1}updateItemFocus(){var e;(e=this.focusInItem)==null||e.setAttribute("tabindex","0"),this.childItems.length!=0}closeDescendentOverlays(){this.descendentOverlays.forEach(e=>{e.open=!1}),this.descendentOverlays=new Map}handleSlotchange({target:e}){var t;const s=e.assignedElements({flatten:!0});this.childItems.length!==s.length&&s.forEach(i=>{typeof i.triggerUpdate!="undefined"?i.triggerUpdate():typeof i.childItems!="undefined"&&i.childItems.forEach(n=>{n.triggerUpdate()})}),this._updateFocus&&((t=this.rovingTabindexController)==null||t.focusOnItem(this._updateFocus),this._updateFocus=void 0)}renderMenuItemSlot(){return b`
2
2
  <slot
3
3
  @sp-menu-submenu-opened=${this.handleDescendentOverlayOpened}
4
4
  @sp-menu-submenu-closed=${this.handleDescendentOverlayClosed}