@spectrum-web-components/menu 0.16.0-devmode.0 → 0.16.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.
Files changed (69) hide show
  1. package/package.json +9 -9
  2. package/sp-menu-divider.js +1 -2
  3. package/sp-menu-divider.js.map +1 -1
  4. package/sp-menu-group.js +1 -2
  5. package/sp-menu-group.js.map +1 -1
  6. package/sp-menu-item.js +1 -2
  7. package/sp-menu-item.js.map +1 -1
  8. package/sp-menu.js +1 -2
  9. package/sp-menu.js.map +1 -1
  10. package/src/Menu.js +2 -493
  11. package/src/Menu.js.map +1 -1
  12. package/src/MenuDivider.js +1 -12
  13. package/src/MenuDivider.js.map +1 -1
  14. package/src/MenuGroup.js +2 -71
  15. package/src/MenuGroup.js.map +1 -1
  16. package/src/MenuItem.js +7 -406
  17. package/src/MenuItem.js.map +1 -1
  18. package/src/index.js +1 -4
  19. package/src/index.js.map +1 -1
  20. package/src/menu-divider.css.js +2 -4
  21. package/src/menu-divider.css.js.map +1 -1
  22. package/src/menu-group.css.js +2 -4
  23. package/src/menu-group.css.js.map +1 -1
  24. package/src/menu-item.css.js +2 -4
  25. package/src/menu-item.css.js.map +1 -1
  26. package/src/menu.css.js +2 -4
  27. package/src/menu.css.js.map +1 -1
  28. package/src/spectrum-checkmark.css.js +2 -4
  29. package/src/spectrum-checkmark.css.js.map +1 -1
  30. package/src/spectrum-chevron.css.js +2 -4
  31. package/src/spectrum-chevron.css.js.map +1 -1
  32. package/src/spectrum-itemLabel.css.js +2 -4
  33. package/src/spectrum-itemLabel.css.js.map +1 -1
  34. package/src/spectrum-menu-divider.css.js +2 -4
  35. package/src/spectrum-menu-divider.css.js.map +1 -1
  36. package/src/spectrum-menu-item.css.js +2 -4
  37. package/src/spectrum-menu-item.css.js.map +1 -1
  38. package/src/spectrum-menu-sectionHeading.css.js +2 -4
  39. package/src/spectrum-menu-sectionHeading.css.js.map +1 -1
  40. package/src/spectrum-menu.css.js +2 -4
  41. package/src/spectrum-menu.css.js.map +1 -1
  42. package/stories/menu-group.stories.js +9 -60
  43. package/stories/menu-group.stories.js.map +1 -1
  44. package/stories/menu-item.stories.js +4 -24
  45. package/stories/menu-item.stories.js.map +1 -1
  46. package/stories/menu.stories.js +8 -46
  47. package/stories/menu.stories.js.map +1 -1
  48. package/stories/submenu.stories.js +16 -153
  49. package/stories/submenu.stories.js.map +1 -1
  50. package/test/benchmark/test-basic.js +1 -7
  51. package/test/benchmark/test-basic.js.map +1 -1
  52. package/test/menu-group.test-vrt.js +1 -3
  53. package/test/menu-group.test-vrt.js.map +1 -1
  54. package/test/menu-group.test.js +6 -170
  55. package/test/menu-group.test.js.map +1 -1
  56. package/test/menu-item.test-vrt.js +1 -3
  57. package/test/menu-item.test-vrt.js.map +1 -1
  58. package/test/menu-item.test.js +8 -101
  59. package/test/menu-item.test.js.map +1 -1
  60. package/test/menu-selects.test.js +5 -504
  61. package/test/menu-selects.test.js.map +1 -1
  62. package/test/menu.test-vrt.js +1 -3
  63. package/test/menu.test-vrt.js.map +1 -1
  64. package/test/menu.test.js +17 -258
  65. package/test/menu.test.js.map +1 -1
  66. package/test/submenu.test-vrt.js +1 -3
  67. package/test/submenu.test-vrt.js.map +1 -1
  68. package/test/submenu.test.js +21 -482
  69. package/test/submenu.test.js.map +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spectrum-web-components/menu",
3
- "version": "0.16.0-devmode.0+7b0ea531e",
3
+ "version": "0.16.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -85,13 +85,13 @@
85
85
  ],
86
86
  "dependencies": {
87
87
  "@lit-labs/observers": "^1.0.1",
88
- "@spectrum-web-components/action-button": "^0.10.0-devmode.0+7b0ea531e",
89
- "@spectrum-web-components/base": "^0.6.0",
90
- "@spectrum-web-components/divider": "^0.5.0-devmode.0+7b0ea531e",
91
- "@spectrum-web-components/icon": "^0.12.0-devmode.0+7b0ea531e",
92
- "@spectrum-web-components/icons-ui": "^0.9.0-devmode.0+7b0ea531e",
93
- "@spectrum-web-components/overlay": "^0.18.0-devmode.0+7b0ea531e",
94
- "@spectrum-web-components/shared": "^0.15.0-devmode.0+7b0ea531e",
88
+ "@spectrum-web-components/action-button": "^0.10.0",
89
+ "@spectrum-web-components/base": "^0.7.0",
90
+ "@spectrum-web-components/divider": "^0.5.0",
91
+ "@spectrum-web-components/icon": "^0.12.0",
92
+ "@spectrum-web-components/icons-ui": "^0.9.0",
93
+ "@spectrum-web-components/overlay": "^0.18.0",
94
+ "@spectrum-web-components/shared": "^0.15.0",
95
95
  "tslib": "^2.0.0"
96
96
  },
97
97
  "devDependencies": {
@@ -103,5 +103,5 @@
103
103
  "./sp-*.js",
104
104
  "./**/*.dev.js"
105
105
  ],
106
- "gitHead": "7b0ea531e9c7225c8964c5429bc5fd005618b80e"
106
+ "gitHead": "05c81318844160db3f8156144106e643507fef97"
107
107
  }
@@ -1,3 +1,2 @@
1
- import { MenuDivider } from "./src/MenuDivider.js";
2
- customElements.define("sp-menu-divider", MenuDivider);
1
+ import{MenuDivider as e}from"./src/MenuDivider.js";customElements.define("sp-menu-divider",e);
3
2
  //# sourceMappingURL=sp-menu-divider.js.map
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["sp-menu-divider.ts"],
4
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*/\nimport { MenuDivider } from './src/MenuDivider.js';\n\ncustomElements.define('sp-menu-divider', MenuDivider);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-menu-divider': MenuDivider;\n }\n}\n"],
5
- "mappings": "AAWA;AAEA,eAAe,OAAO,mBAAmB,WAAW;",
5
+ "mappings": "AAWA,mDAEA,eAAe,OAAO,kBAAmB,CAAW",
6
6
  "names": []
7
7
  }
package/sp-menu-group.js CHANGED
@@ -1,3 +1,2 @@
1
- import { MenuGroup } from "./src/MenuGroup.js";
2
- customElements.define("sp-menu-group", MenuGroup);
1
+ import{MenuGroup as e}from"./src/MenuGroup.js";customElements.define("sp-menu-group",e);
3
2
  //# sourceMappingURL=sp-menu-group.js.map
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["sp-menu-group.ts"],
4
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*/\nimport { MenuGroup } from './src/MenuGroup.js';\n\ncustomElements.define('sp-menu-group', MenuGroup);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-menu-group': MenuGroup;\n }\n}\n"],
5
- "mappings": "AAWA;AAEA,eAAe,OAAO,iBAAiB,SAAS;",
5
+ "mappings": "AAWA,+CAEA,eAAe,OAAO,gBAAiB,CAAS",
6
6
  "names": []
7
7
  }
package/sp-menu-item.js CHANGED
@@ -1,3 +1,2 @@
1
- import { MenuItem } from "./src/MenuItem.js";
2
- customElements.define("sp-menu-item", MenuItem);
1
+ import{MenuItem as e}from"./src/MenuItem.js";customElements.define("sp-menu-item",e);
3
2
  //# sourceMappingURL=sp-menu-item.js.map
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["sp-menu-item.ts"],
4
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*/\nimport { MenuItem } from './src/MenuItem.js';\n\ncustomElements.define('sp-menu-item', MenuItem);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-menu-item': MenuItem;\n }\n}\n"],
5
- "mappings": "AAWA;AAEA,eAAe,OAAO,gBAAgB,QAAQ;",
5
+ "mappings": "AAWA,6CAEA,eAAe,OAAO,eAAgB,CAAQ",
6
6
  "names": []
7
7
  }
package/sp-menu.js CHANGED
@@ -1,3 +1,2 @@
1
- import { Menu } from "./src/Menu.js";
2
- customElements.define("sp-menu", Menu);
1
+ import{Menu as e}from"./src/Menu.js";customElements.define("sp-menu",e);
3
2
  //# sourceMappingURL=sp-menu.js.map
package/sp-menu.js.map CHANGED
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["sp-menu.ts"],
4
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*/\nimport { Menu } from './src/Menu.js';\n\ncustomElements.define('sp-menu', Menu);\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'sp-menu': Menu;\n }\n}\n"],
5
- "mappings": "AAWA;AAEA,eAAe,OAAO,WAAW,IAAI;",
5
+ "mappings": "AAWA,qCAEA,eAAe,OAAO,UAAW,CAAI",
6
6
  "names": []
7
7
  }
package/src/Menu.js CHANGED
@@ -1,495 +1,4 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
- var __decorateClass = (decorators, target, key, kind) => {
4
- var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
- for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
- if (decorator = decorators[i])
7
- result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
- if (kind && result)
9
- __defProp(target, key, result);
10
- return result;
11
- };
12
- import {
13
- html,
14
- SpectrumElement
15
- } from "@spectrum-web-components/base";
16
- import {
17
- property,
18
- query
19
- } from "@spectrum-web-components/base/src/decorators.js";
20
- import { MenuItem } from "./MenuItem.js";
21
- import menuStyles from "./menu.css.js";
22
- function elementIsOrContains(el, isOrContains) {
23
- return !!isOrContains && (el === isOrContains || el.contains(isOrContains));
24
- }
25
- export class Menu extends SpectrumElement {
26
- constructor() {
27
- super();
28
- this.isSubmenu = false;
29
- this.label = "";
30
- this.value = "";
31
- this.valueSeparator = ",";
32
- this.selected = [];
33
- this.selectedItems = [];
34
- this.childItemSet = /* @__PURE__ */ new Set();
35
- this.focusedItemIndex = 0;
36
- this.focusInItemIndex = 0;
37
- this.selectedItemsMap = /* @__PURE__ */ new Map();
38
- this._willUpdateItems = false;
39
- this._notFirstUpdated = false;
40
- this.cacheUpdated = Promise.resolve();
41
- this.addEventListener("sp-menu-item-added-or-updated", this.onSelectableItemAddedOrUpdated);
42
- this.addEventListener("sp-menu-item-added-or-updated", this.onFocusableItemAddedOrUpdated, {
43
- capture: true
44
- });
45
- this.addEventListener("sp-menu-item-removed", this.removeChildItem);
46
- this.addEventListener("click", this.onClick);
47
- this.addEventListener("focusin", this.handleFocusin);
48
- }
49
- static get styles() {
50
- return [menuStyles];
51
- }
52
- get childItems() {
53
- if (!this.cachedChildItems) {
54
- this.cachedChildItems = this.updateCachedMenuItems();
55
- }
56
- return this.cachedChildItems;
57
- }
58
- updateCachedMenuItems() {
59
- this.cachedChildItems = [];
60
- const slotElements = this.menuSlot ? this.menuSlot.assignedElements({ flatten: true }) : [];
61
- for (const slotElement of slotElements) {
62
- const childMenuItems = slotElement instanceof MenuItem ? [slotElement] : [...slotElement.querySelectorAll(`*`)];
63
- for (const childMenuItem of childMenuItems) {
64
- if (this.childItemSet.has(childMenuItem)) {
65
- this.cachedChildItems.push(childMenuItem);
66
- }
67
- }
68
- }
69
- return this.cachedChildItems;
70
- }
71
- get childRole() {
72
- if (this.resolvedRole === "listbox") {
73
- return "option";
74
- }
75
- switch (this.resolvedSelects) {
76
- case "single":
77
- return "menuitemradio";
78
- case "multiple":
79
- return "menuitemcheckbox";
80
- default:
81
- return "menuitem";
82
- }
83
- }
84
- get ownRole() {
85
- return "menu";
86
- }
87
- onFocusableItemAddedOrUpdated(event) {
88
- var _a;
89
- if (event.item.menuData.focusRoot) {
90
- this.tabIndex = -1;
91
- }
92
- event.focusRoot = this;
93
- this.addChildItem(event.item);
94
- if (this.selects === "inherit") {
95
- this.resolvedSelects = "inherit";
96
- this.resolvedRole = ((_a = event.currentAncestorWithSelects) == null ? void 0 : _a.getAttribute("role")) || this.getAttribute("role") || void 0;
97
- } else if (this.selects) {
98
- this.resolvedRole = this.getAttribute("role") || void 0;
99
- this.resolvedSelects = this.selects;
100
- event.currentAncestorWithSelects = this;
101
- } else {
102
- this.resolvedRole = this.getAttribute("role") || void 0;
103
- this.resolvedSelects = this.resolvedRole === "none" ? "ignore" : "none";
104
- }
105
- }
106
- onSelectableItemAddedOrUpdated(event) {
107
- const selects = this.resolvedSelects === "single" || this.resolvedSelects === "multiple";
108
- if ((selects || !this.selects && this.resolvedSelects !== "ignore") && !event.item.menuData.selectionRoot) {
109
- event.item.setRole(this.childRole);
110
- event.selectionRoot = this;
111
- }
112
- }
113
- addChildItem(item) {
114
- this.childItemSet.add(item);
115
- this.handleItemsChanged();
116
- }
117
- async removeChildItem(event) {
118
- this.childItemSet.delete(event.item);
119
- this.cachedChildItems = void 0;
120
- if (event.item.focused) {
121
- this.handleItemsChanged();
122
- await this.updateComplete;
123
- this.focus();
124
- }
125
- }
126
- focus({ preventScroll } = {}) {
127
- if (!this.childItems.length || this.childItems.every((childItem) => childItem.disabled)) {
128
- return;
129
- }
130
- if (this.childItems.some((childItem) => childItem.menuData.focusRoot !== this)) {
131
- super.focus({ preventScroll });
132
- return;
133
- }
134
- this.focusMenuItemByOffset(0);
135
- super.focus({ preventScroll });
136
- const selectedItem = this.querySelector("[selected]");
137
- if (selectedItem && !preventScroll) {
138
- selectedItem.scrollIntoView({ block: "nearest" });
139
- }
140
- }
141
- onClick(event) {
142
- if (event.defaultPrevented) {
143
- return;
144
- }
145
- const path = event.composedPath();
146
- const target = path.find((el) => {
147
- if (!(el instanceof Element)) {
148
- return false;
149
- }
150
- return el.getAttribute("role") === this.childRole;
151
- });
152
- if ((target == null ? void 0 : target.href) && target.href.length) {
153
- return;
154
- } else if ((target == null ? void 0 : target.menuData.selectionRoot) === this && this.childItems.length) {
155
- event.preventDefault();
156
- if (target.hasSubmenu || target.open) {
157
- return;
158
- }
159
- this.selectOrToggleItem(target);
160
- } else {
161
- return;
162
- }
163
- this.prepareToCleanUp();
164
- }
165
- handleFocusin(event) {
166
- var _a;
167
- const isOrContainsRelatedTarget = elementIsOrContains(this, event.relatedTarget);
168
- if (isOrContainsRelatedTarget || this.childItems.some((childItem) => childItem.menuData.focusRoot !== this)) {
169
- return;
170
- }
171
- const activeElement = this.getRootNode().activeElement;
172
- const selectionRoot = ((_a = this.childItems[this.focusedItemIndex]) == null ? void 0 : _a.menuData.selectionRoot) || this;
173
- if (activeElement !== selectionRoot || !isOrContainsRelatedTarget) {
174
- selectionRoot.focus({ preventScroll: true });
175
- if (activeElement && this.focusedItemIndex === 0) {
176
- const offset = this.childItems.findIndex((childItem) => childItem === activeElement);
177
- if (offset > 0) {
178
- this.focusMenuItemByOffset(offset);
179
- }
180
- }
181
- }
182
- this.startListeningToKeyboard();
183
- }
184
- startListeningToKeyboard() {
185
- this.addEventListener("keydown", this.handleKeydown);
186
- this.addEventListener("focusout", this.handleFocusout);
187
- }
188
- handleFocusout(event) {
189
- if (elementIsOrContains(this, event.relatedTarget)) {
190
- event.composedPath()[0].focused = false;
191
- return;
192
- }
193
- this.stopListeningToKeyboard();
194
- if (event.target === this && this.childItems.some((childItem) => childItem.menuData.focusRoot === this)) {
195
- const focusedItem = this.childItems[this.focusedItemIndex];
196
- if (focusedItem) {
197
- focusedItem.focused = false;
198
- }
199
- }
200
- this.removeAttribute("aria-activedescendant");
201
- }
202
- stopListeningToKeyboard() {
203
- this.removeEventListener("keydown", this.handleKeydown);
204
- this.removeEventListener("focusout", this.handleFocusout);
205
- }
206
- async selectOrToggleItem(targetItem) {
207
- const resolvedSelects = this.resolvedSelects;
208
- const oldSelectedItemsMap = new Map(this.selectedItemsMap);
209
- const oldSelected = this.selected.slice();
210
- const oldSelectedItems = this.selectedItems.slice();
211
- const oldValue = this.value;
212
- this.childItems[this.focusedItemIndex].focused = false;
213
- this.focusedItemIndex = this.childItems.indexOf(targetItem);
214
- this.forwardFocusVisibleToItem(targetItem);
215
- if (resolvedSelects === "multiple") {
216
- if (this.selectedItemsMap.has(targetItem)) {
217
- this.selectedItemsMap.delete(targetItem);
218
- } else {
219
- this.selectedItemsMap.set(targetItem, true);
220
- }
221
- const selected = [];
222
- const selectedItems = [];
223
- this.childItemSet.forEach((childItem) => {
224
- if (childItem.menuData.selectionRoot !== this)
225
- return;
226
- if (this.selectedItemsMap.has(childItem)) {
227
- selected.push(childItem.value);
228
- selectedItems.push(childItem);
229
- }
230
- });
231
- this.selected = selected;
232
- this.selectedItems = selectedItems;
233
- this.value = this.selected.join(this.valueSeparator);
234
- } else {
235
- this.selectedItemsMap.clear();
236
- this.selectedItemsMap.set(targetItem, true);
237
- this.value = targetItem.value;
238
- this.selected = [targetItem.value];
239
- this.selectedItems = [targetItem];
240
- }
241
- await this.updateComplete;
242
- const applyDefault = this.dispatchEvent(new Event("change", {
243
- cancelable: true,
244
- bubbles: true,
245
- composed: true
246
- }));
247
- if (!applyDefault) {
248
- this.selected = oldSelected;
249
- this.selectedItems = oldSelectedItems;
250
- this.selectedItemsMap = oldSelectedItemsMap;
251
- this.value = oldValue;
252
- return;
253
- }
254
- if (resolvedSelects === "single") {
255
- for (const oldItem of oldSelectedItemsMap.keys()) {
256
- if (oldItem !== targetItem) {
257
- oldItem.selected = false;
258
- }
259
- }
260
- targetItem.selected = true;
261
- } else if (resolvedSelects === "multiple") {
262
- targetItem.selected = !targetItem.selected;
263
- }
264
- }
265
- navigateWithinMenu(event) {
266
- const { code } = event;
267
- const lastFocusedItem = this.childItems[this.focusedItemIndex];
268
- const direction = code === "ArrowDown" ? 1 : -1;
269
- const itemToFocus = this.focusMenuItemByOffset(direction);
270
- if (itemToFocus === lastFocusedItem) {
271
- return;
272
- }
273
- event.preventDefault();
274
- itemToFocus.scrollIntoView({ block: "nearest" });
275
- }
276
- navigateBetweenRelatedMenus(code) {
277
- const shouldOpenSubmenu = this.isLTR && code === "ArrowRight" || !this.isLTR && code === "ArrowLeft";
278
- const shouldCloseSelfAsSubmenu = this.isLTR && code === "ArrowLeft" || !this.isLTR && code === "ArrowRight";
279
- if (shouldOpenSubmenu) {
280
- const lastFocusedItem = this.childItems[this.focusedItemIndex];
281
- if (lastFocusedItem.hasSubmenu) {
282
- this.blur();
283
- lastFocusedItem.openOverlay();
284
- }
285
- } else if (shouldCloseSelfAsSubmenu && this.isSubmenu) {
286
- this.dispatchEvent(new Event("close", { bubbles: true }));
287
- }
288
- }
289
- handleKeydown(event) {
290
- var _a;
291
- const { code } = event;
292
- if (code === "Tab") {
293
- this.prepareToCleanUp();
294
- return;
295
- }
296
- if (code === "Space") {
297
- const lastFocusedItem = this.childItems[this.focusedItemIndex];
298
- if (lastFocusedItem.hasSubmenu) {
299
- this.blur();
300
- lastFocusedItem.openOverlay();
301
- return;
302
- }
303
- }
304
- if (code === "Space" || code === "Enter") {
305
- (_a = this.childItems[this.focusedItemIndex]) == null ? void 0 : _a.click();
306
- return;
307
- }
308
- if (code === "ArrowDown" || code === "ArrowUp") {
309
- this.navigateWithinMenu(event);
310
- return;
311
- }
312
- this.navigateBetweenRelatedMenus(code);
313
- }
314
- focusMenuItemByOffset(offset) {
315
- const step = offset || 1;
316
- const focusedItem = this.childItems[this.focusedItemIndex];
317
- focusedItem.focused = false;
318
- this.focusedItemIndex = (this.childItems.length + this.focusedItemIndex + offset) % this.childItems.length;
319
- let itemToFocus = this.childItems[this.focusedItemIndex];
320
- let availableItems = this.childItems.length;
321
- while (itemToFocus.disabled && availableItems) {
322
- availableItems -= 1;
323
- this.focusedItemIndex = (this.childItems.length + this.focusedItemIndex + step) % this.childItems.length;
324
- itemToFocus = this.childItems[this.focusedItemIndex];
325
- }
326
- if (!(itemToFocus == null ? void 0 : itemToFocus.disabled)) {
327
- this.forwardFocusVisibleToItem(itemToFocus);
328
- }
329
- return itemToFocus;
330
- }
331
- prepareToCleanUp() {
332
- document.addEventListener("focusout", () => {
333
- requestAnimationFrame(() => {
334
- const focusedItem = this.childItems[this.focusedItemIndex];
335
- if (focusedItem) {
336
- focusedItem.focused = false;
337
- this.updateSelectedItemIndex();
338
- }
339
- });
340
- }, { once: true });
341
- }
342
- updateSelectedItemIndex() {
343
- let firstOrFirstSelectedIndex = 0;
344
- const selectedItemsMap = /* @__PURE__ */ new Map();
345
- const selected = [];
346
- const selectedItems = [];
347
- let itemIndex = this.childItems.length;
348
- while (itemIndex) {
349
- itemIndex -= 1;
350
- const childItem = this.childItems[itemIndex];
351
- if (childItem.menuData.selectionRoot === this) {
352
- if (childItem.selected) {
353
- firstOrFirstSelectedIndex = itemIndex;
354
- selectedItemsMap.set(childItem, true);
355
- selected.unshift(childItem.value);
356
- selectedItems.unshift(childItem);
357
- }
358
- if (itemIndex !== firstOrFirstSelectedIndex) {
359
- childItem.focused = false;
360
- }
361
- }
362
- }
363
- selectedItems.map((item, i) => {
364
- if (i > 0) {
365
- item.focused = false;
366
- }
367
- });
368
- this.selectedItemsMap = selectedItemsMap;
369
- this.selected = selected;
370
- this.selectedItems = selectedItems;
371
- this.value = this.selected.join(this.valueSeparator);
372
- this.focusedItemIndex = firstOrFirstSelectedIndex;
373
- this.focusInItemIndex = firstOrFirstSelectedIndex;
374
- }
375
- handleItemsChanged() {
376
- this.cachedChildItems = void 0;
377
- if (!this._willUpdateItems) {
378
- let resolve = () => {
379
- return;
380
- };
381
- this.cacheUpdated = new Promise((res) => resolve = res);
382
- this._willUpdateItems = true;
383
- window.requestAnimationFrame(() => {
384
- if (this.cachedChildItems === void 0) {
385
- this.updateSelectedItemIndex();
386
- this.updateItemFocus();
387
- }
388
- this._willUpdateItems = false;
389
- resolve();
390
- });
391
- }
392
- }
393
- updateItemFocus() {
394
- if (this.childItems.length == 0) {
395
- return;
396
- }
397
- const focusInItem = this.childItems[this.focusInItemIndex];
398
- if (this.getRootNode().activeElement === focusInItem.menuData.focusRoot) {
399
- this.forwardFocusVisibleToItem(focusInItem);
400
- }
401
- }
402
- forwardFocusVisibleToItem(item) {
403
- if (item.menuData.focusRoot !== this) {
404
- return;
405
- }
406
- item.focused = this.hasVisibleFocusInTree();
407
- this.setAttribute("aria-activedescendant", item.id);
408
- if (item.menuData.selectionRoot && item.menuData.selectionRoot !== this) {
409
- item.menuData.selectionRoot.focus();
410
- }
411
- }
412
- render() {
413
- return html`
1
+ var p=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var l=(n,e,t,s)=>{for(var i=s>1?void 0:s?f(e,t):e,o=n.length-1,d;o>=0;o--)(d=n[o])&&(i=(s?d(e,t,i):d(i))||i);return s&&i&&p(e,t,i),i};import{html as I,SpectrumElement as v}from"@spectrum-web-components/base";import{property as c,query as b}from"@spectrum-web-components/base/src/decorators.js";import{MenuItem as S}from"./MenuItem.js";import g from"./menu.css.js";function m(n,e){return!!e&&(n===e||n.contains(e))}export class Menu extends v{constructor(){super();this.isSubmenu=!1;this.label="";this.value="";this.valueSeparator=",";this.selected=[];this.selectedItems=[];this.childItemSet=new Set;this.focusedItemIndex=0;this.focusInItemIndex=0;this.selectedItemsMap=new Map;this._willUpdateItems=!1;this._notFirstUpdated=!1;this.cacheUpdated=Promise.resolve();this.addEventListener("sp-menu-item-added-or-updated",this.onSelectableItemAddedOrUpdated),this.addEventListener("sp-menu-item-added-or-updated",this.onFocusableItemAddedOrUpdated,{capture:!0}),this.addEventListener("sp-menu-item-removed",this.removeChildItem),this.addEventListener("click",this.onClick),this.addEventListener("focusin",this.handleFocusin)}static get styles(){return[g]}get childItems(){return this.cachedChildItems||(this.cachedChildItems=this.updateCachedMenuItems()),this.cachedChildItems}updateCachedMenuItems(){this.cachedChildItems=[];const e=this.menuSlot?this.menuSlot.assignedElements({flatten:!0}):[];for(const t of e){const s=t instanceof S?[t]:[...t.querySelectorAll("*")];for(const i of s)this.childItemSet.has(i)&&this.cachedChildItems.push(i)}return 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){var t;e.item.menuData.focusRoot&&(this.tabIndex=-1),e.focusRoot=this,this.addChildItem(e.item),this.selects==="inherit"?(this.resolvedSelects="inherit",this.resolvedRole=((t=e.currentAncestorWithSelects)==null?void 0:t.getAttribute("role"))||this.getAttribute("role")||void 0):this.selects?(this.resolvedRole=this.getAttribute("role")||void 0,this.resolvedSelects=this.selects,e.currentAncestorWithSelects=this):(this.resolvedRole=this.getAttribute("role")||void 0,this.resolvedSelects=this.resolvedRole==="none"?"ignore":"none")}onSelectableItemAddedOrUpdated(e){(this.resolvedSelects==="single"||this.resolvedSelects==="multiple"||!this.selects&&this.resolvedSelects!=="ignore")&&!e.item.menuData.selectionRoot&&(e.item.setRole(this.childRole),e.selectionRoot=this)}addChildItem(e){this.childItemSet.add(e),this.handleItemsChanged()}async removeChildItem(e){this.childItemSet.delete(e.item),this.cachedChildItems=void 0,e.item.focused&&(this.handleItemsChanged(),await this.updateComplete,this.focus())}focus({preventScroll:e}={}){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.focusMenuItemByOffset(0),super.focus({preventScroll:e});const t=this.querySelector("[selected]");t&&!e&&t.scrollIntoView({block:"nearest"})}onClick(e){if(e.defaultPrevented)return;const s=e.composedPath().find(i=>i instanceof Element?i.getAttribute("role")===this.childRole:!1);if(!((s==null?void 0:s.href)&&s.href.length)){if((s==null?void 0:s.menuData.selectionRoot)===this&&this.childItems.length){if(e.preventDefault(),s.hasSubmenu||s.open)return;this.selectOrToggleItem(s)}else return;this.prepareToCleanUp()}}handleFocusin(e){var o;const t=m(this,e.relatedTarget);if(t||this.childItems.some(d=>d.menuData.focusRoot!==this))return;const s=this.getRootNode().activeElement,i=((o=this.childItems[this.focusedItemIndex])==null?void 0:o.menuData.selectionRoot)||this;if((s!==i||!t)&&(i.focus({preventScroll:!0}),s&&this.focusedItemIndex===0)){const d=this.childItems.findIndex(u=>u===s);d>0&&this.focusMenuItemByOffset(d)}this.startListeningToKeyboard()}startListeningToKeyboard(){this.addEventListener("keydown",this.handleKeydown),this.addEventListener("focusout",this.handleFocusout)}handleFocusout(e){if(m(this,e.relatedTarget)){e.composedPath()[0].focused=!1;return}if(this.stopListeningToKeyboard(),e.target===this&&this.childItems.some(t=>t.menuData.focusRoot===this)){const t=this.childItems[this.focusedItemIndex];t&&(t.focused=!1)}this.removeAttribute("aria-activedescendant")}stopListeningToKeyboard(){this.removeEventListener("keydown",this.handleKeydown),this.removeEventListener("focusout",this.handleFocusout)}async selectOrToggleItem(e){const t=this.resolvedSelects,s=new Map(this.selectedItemsMap),i=this.selected.slice(),o=this.selectedItems.slice(),d=this.value;if(this.childItems[this.focusedItemIndex].focused=!1,this.focusedItemIndex=this.childItems.indexOf(e),this.forwardFocusVisibleToItem(e),t==="multiple"){this.selectedItemsMap.has(e)?this.selectedItemsMap.delete(e):this.selectedItemsMap.set(e,!0);const a=[],r=[];this.childItemSet.forEach(h=>{h.menuData.selectionRoot===this&&this.selectedItemsMap.has(h)&&(a.push(h.value),r.push(h))}),this.selected=a,this.selectedItems=r,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(await this.updateComplete,!this.dispatchEvent(new Event("change",{cancelable:!0,bubbles:!0,composed:!0}))){this.selected=i,this.selectedItems=o,this.selectedItemsMap=s,this.value=d;return}if(t==="single"){for(const a of s.keys())a!==e&&(a.selected=!1);e.selected=!0}else t==="multiple"&&(e.selected=!e.selected)}navigateWithinMenu(e){const{code:t}=e,s=this.childItems[this.focusedItemIndex],i=t==="ArrowDown"?1:-1,o=this.focusMenuItemByOffset(i);o!==s&&(e.preventDefault(),o.scrollIntoView({block:"nearest"}))}navigateBetweenRelatedMenus(e){const t=this.isLTR&&e==="ArrowRight"||!this.isLTR&&e==="ArrowLeft",s=this.isLTR&&e==="ArrowLeft"||!this.isLTR&&e==="ArrowRight";if(t){const i=this.childItems[this.focusedItemIndex];i.hasSubmenu&&(this.blur(),i.openOverlay())}else s&&this.isSubmenu&&this.dispatchEvent(new Event("close",{bubbles:!0}))}handleKeydown(e){var s;const{code:t}=e;if(t==="Tab"){this.prepareToCleanUp();return}if(t==="Space"){const i=this.childItems[this.focusedItemIndex];if(i.hasSubmenu){this.blur(),i.openOverlay();return}}if(t==="Space"||t==="Enter"){(s=this.childItems[this.focusedItemIndex])==null||s.click();return}if(t==="ArrowDown"||t==="ArrowUp"){this.navigateWithinMenu(e);return}this.navigateBetweenRelatedMenus(t)}focusMenuItemByOffset(e){const t=e||1,s=this.childItems[this.focusedItemIndex];s.focused=!1,this.focusedItemIndex=(this.childItems.length+this.focusedItemIndex+e)%this.childItems.length;let i=this.childItems[this.focusedItemIndex],o=this.childItems.length;for(;i.disabled&&o;)o-=1,this.focusedItemIndex=(this.childItems.length+this.focusedItemIndex+t)%this.childItems.length,i=this.childItems[this.focusedItemIndex];return i!=null&&i.disabled||this.forwardFocusVisibleToItem(i),i}prepareToCleanUp(){document.addEventListener("focusout",()=>{requestAnimationFrame(()=>{const e=this.childItems[this.focusedItemIndex];e&&(e.focused=!1,this.updateSelectedItemIndex())})},{once:!0})}updateSelectedItemIndex(){let e=0;const t=new Map,s=[],i=[];let o=this.childItems.length;for(;o;){o-=1;const d=this.childItems[o];d.menuData.selectionRoot===this&&(d.selected&&(e=o,t.set(d,!0),s.unshift(d.value),i.unshift(d)),o!==e&&(d.focused=!1))}i.map((d,u)=>{u>0&&(d.focused=!1)}),this.selectedItemsMap=t,this.selected=s,this.selectedItems=i,this.value=this.selected.join(this.valueSeparator),this.focusedItemIndex=e,this.focusInItemIndex=e}handleItemsChanged(){if(this.cachedChildItems=void 0,!this._willUpdateItems){let e=()=>{};this.cacheUpdated=new Promise(t=>e=t),this._willUpdateItems=!0,window.requestAnimationFrame(()=>{this.cachedChildItems===void 0&&(this.updateSelectedItemIndex(),this.updateItemFocus()),this._willUpdateItems=!1,e()})}}updateItemFocus(){if(this.childItems.length==0)return;const e=this.childItems[this.focusInItemIndex];this.getRootNode().activeElement===e.menuData.focusRoot&&this.forwardFocusVisibleToItem(e)}forwardFocusVisibleToItem(e){e.menuData.focusRoot===this&&(e.focused=this.hasVisibleFocusInTree(),this.setAttribute("aria-activedescendant",e.id),e.menuData.selectionRoot&&e.menuData.selectionRoot!==this&&e.menuData.selectionRoot.focus())}render(){return I`
414
2
  <slot></slot>
415
- `;
416
- }
417
- firstUpdated(changed) {
418
- super.firstUpdated(changed);
419
- if (!this.hasAttribute("tabindex")) {
420
- const role = this.getAttribute("role");
421
- if (role === "group") {
422
- this.tabIndex = -1;
423
- } else if (role !== "none") {
424
- this.tabIndex = 0;
425
- }
426
- }
427
- const updates = [
428
- new Promise((res) => requestAnimationFrame(() => res(true)))
429
- ];
430
- [...this.children].forEach((item) => {
431
- if (item.localName === "sp-menu-item") {
432
- updates.push(item.updateComplete);
433
- }
434
- });
435
- this.childItemsUpdated = Promise.all(updates);
436
- }
437
- updated(changes) {
438
- super.updated(changes);
439
- if (changes.has("selects") && this._notFirstUpdated) {
440
- this.selectsChanged();
441
- }
442
- if (changes.has("label")) {
443
- if (this.label) {
444
- this.setAttribute("aria-label", this.label);
445
- } else {
446
- this.removeAttribute("aria-label");
447
- }
448
- }
449
- this._notFirstUpdated = true;
450
- }
451
- selectsChanged() {
452
- const updates = [
453
- new Promise((res) => requestAnimationFrame(() => res(true)))
454
- ];
455
- this.childItemSet.forEach((childItem) => {
456
- updates.push(childItem.triggerUpdate());
457
- });
458
- this.childItemsUpdated = Promise.all(updates);
459
- }
460
- connectedCallback() {
461
- super.connectedCallback();
462
- if (!this.hasAttribute("role")) {
463
- this.setAttribute("role", this.ownRole);
464
- }
465
- this.updateComplete.then(() => this.updateItemFocus());
466
- }
467
- async getUpdateComplete() {
468
- const complete = await super.getUpdateComplete();
469
- await this.childItemsUpdated;
470
- await this.cacheUpdated;
471
- return complete;
472
- }
473
- }
474
- __decorateClass([
475
- property({ type: String, reflect: true })
476
- ], Menu.prototype, "label", 2);
477
- __decorateClass([
478
- property({ type: String, reflect: true })
479
- ], Menu.prototype, "selects", 2);
480
- __decorateClass([
481
- property({ type: String })
482
- ], Menu.prototype, "value", 2);
483
- __decorateClass([
484
- property({ type: String, attribute: "value-separator" })
485
- ], Menu.prototype, "valueSeparator", 2);
486
- __decorateClass([
487
- property({ attribute: false })
488
- ], Menu.prototype, "selected", 2);
489
- __decorateClass([
490
- property({ attribute: false })
491
- ], Menu.prototype, "selectedItems", 2);
492
- __decorateClass([
493
- query("slot:not([name])")
494
- ], Menu.prototype, "menuSlot", 2);
3
+ `}firstUpdated(e){if(super.firstUpdated(e),!this.hasAttribute("tabindex")){const s=this.getAttribute("role");s==="group"?this.tabIndex=-1:s!=="none"&&(this.tabIndex=0)}const t=[new Promise(s=>requestAnimationFrame(()=>s(!0)))];[...this.children].forEach(s=>{s.localName==="sp-menu-item"&&t.push(s.updateComplete)}),this.childItemsUpdated=Promise.all(t)}updated(e){super.updated(e),e.has("selects")&&this._notFirstUpdated&&this.selectsChanged(),e.has("label")&&(this.label?this.setAttribute("aria-label",this.label):this.removeAttribute("aria-label")),this._notFirstUpdated=!0}selectsChanged(){const e=[new Promise(t=>requestAnimationFrame(()=>t(!0)))];this.childItemSet.forEach(t=>{e.push(t.triggerUpdate())}),this.childItemsUpdated=Promise.all(e)}connectedCallback(){super.connectedCallback(),this.hasAttribute("role")||this.setAttribute("role",this.ownRole),this.updateComplete.then(()=>this.updateItemFocus())}async getUpdateComplete(){const e=await super.getUpdateComplete();return await this.childItemsUpdated,await this.cacheUpdated,e}}l([c({type:String,reflect:!0})],Menu.prototype,"label",2),l([c({type:String,reflect:!0})],Menu.prototype,"selects",2),l([c({type:String})],Menu.prototype,"value",2),l([c({type:String,attribute:"value-separator"})],Menu.prototype,"valueSeparator",2),l([c({attribute:!1})],Menu.prototype,"selected",2),l([c({attribute:!1})],Menu.prototype,"selectedItems",2),l([b("slot:not([name])")],Menu.prototype,"menuSlot",2);
495
4
  //# sourceMappingURL=Menu.js.map