@spectrum-web-components/menu 0.14.2 → 0.14.5-devmode.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 (111) hide show
  1. package/custom-elements.json +11 -1
  2. package/package.json +55 -20
  3. package/sp-menu-divider.dev.js +3 -0
  4. package/sp-menu-divider.dev.js.map +7 -0
  5. package/sp-menu-divider.js +3 -14
  6. package/sp-menu-divider.js.map +7 -1
  7. package/sp-menu-group.dev.js +3 -0
  8. package/sp-menu-group.dev.js.map +7 -0
  9. package/sp-menu-group.js +3 -14
  10. package/sp-menu-group.js.map +7 -1
  11. package/sp-menu-item.dev.js +3 -0
  12. package/sp-menu-item.dev.js.map +7 -0
  13. package/sp-menu-item.js +3 -14
  14. package/sp-menu-item.js.map +7 -1
  15. package/sp-menu.dev.js +3 -0
  16. package/sp-menu.dev.js.map +7 -0
  17. package/sp-menu.js +3 -14
  18. package/sp-menu.js.map +7 -1
  19. package/src/Menu.dev.js +495 -0
  20. package/src/Menu.dev.js.map +7 -0
  21. package/src/Menu.js +487 -574
  22. package/src/Menu.js.map +7 -1
  23. package/src/MenuDivider.dev.js +13 -0
  24. package/src/MenuDivider.dev.js.map +7 -0
  25. package/src/MenuDivider.js +11 -25
  26. package/src/MenuDivider.js.map +7 -1
  27. package/src/MenuGroup.dev.js +82 -0
  28. package/src/MenuGroup.dev.js.map +7 -0
  29. package/src/MenuGroup.js +67 -71
  30. package/src/MenuGroup.js.map +7 -1
  31. package/src/MenuItem.d.ts +2 -1
  32. package/src/MenuItem.dev.js +424 -0
  33. package/src/MenuItem.dev.js.map +7 -0
  34. package/src/MenuItem.js +399 -415
  35. package/src/MenuItem.js.map +7 -1
  36. package/src/index.dev.js +5 -0
  37. package/src/index.dev.js.map +7 -0
  38. package/src/index.js +5 -16
  39. package/src/index.js.map +7 -1
  40. package/src/menu-divider.css.dev.js +6 -0
  41. package/src/menu-divider.css.dev.js.map +7 -0
  42. package/src/menu-divider.css.js +3 -14
  43. package/src/menu-divider.css.js.map +7 -1
  44. package/src/menu-group.css.dev.js +8 -0
  45. package/src/menu-group.css.dev.js.map +7 -0
  46. package/src/menu-group.css.js +3 -14
  47. package/src/menu-group.css.js.map +7 -1
  48. package/src/menu-item.css.dev.js +73 -0
  49. package/src/menu-item.css.dev.js.map +7 -0
  50. package/src/menu-item.css.js +3 -14
  51. package/src/menu-item.css.js.map +7 -1
  52. package/src/menu.css.dev.js +61 -0
  53. package/src/menu.css.dev.js.map +7 -0
  54. package/src/menu.css.js +3 -14
  55. package/src/menu.css.js.map +7 -1
  56. package/src/spectrum-checkmark.css.dev.js +10 -0
  57. package/src/spectrum-checkmark.css.dev.js.map +7 -0
  58. package/src/spectrum-checkmark.css.js +3 -14
  59. package/src/spectrum-checkmark.css.js.map +7 -1
  60. package/src/spectrum-chevron.css.dev.js +10 -0
  61. package/src/spectrum-chevron.css.dev.js.map +7 -0
  62. package/src/spectrum-chevron.css.js +3 -14
  63. package/src/spectrum-chevron.css.js.map +7 -1
  64. package/src/spectrum-itemLabel.css.dev.js +6 -0
  65. package/src/spectrum-itemLabel.css.dev.js.map +7 -0
  66. package/src/spectrum-itemLabel.css.js +3 -14
  67. package/src/spectrum-itemLabel.css.js.map +7 -1
  68. package/src/spectrum-menu-divider.css.dev.js +6 -0
  69. package/src/spectrum-menu-divider.css.dev.js.map +7 -0
  70. package/src/spectrum-menu-divider.css.js +3 -14
  71. package/src/spectrum-menu-divider.css.js.map +7 -1
  72. package/src/spectrum-menu-item.css.dev.js +65 -0
  73. package/src/spectrum-menu-item.css.dev.js.map +7 -0
  74. package/src/spectrum-menu-item.css.js +3 -14
  75. package/src/spectrum-menu-item.css.js.map +7 -1
  76. package/src/spectrum-menu-sectionHeading.css.dev.js +8 -0
  77. package/src/spectrum-menu-sectionHeading.css.dev.js.map +7 -0
  78. package/src/spectrum-menu-sectionHeading.css.js +3 -14
  79. package/src/spectrum-menu-sectionHeading.css.js.map +7 -1
  80. package/src/spectrum-menu.css.dev.js +61 -0
  81. package/src/spectrum-menu.css.dev.js.map +7 -0
  82. package/src/spectrum-menu.css.js +3 -14
  83. package/src/spectrum-menu.css.js.map +7 -1
  84. package/stories/menu-group.stories.js +51 -58
  85. package/stories/menu-group.stories.js.map +7 -1
  86. package/stories/menu-item.stories.js +12 -32
  87. package/stories/menu-item.stories.js.map +7 -1
  88. package/stories/menu.stories.js +22 -33
  89. package/stories/menu.stories.js.map +7 -1
  90. package/stories/submenu.stories.js +125 -136
  91. package/stories/submenu.stories.js.map +7 -1
  92. package/test/benchmark/test-basic.js +8 -19
  93. package/test/benchmark/test-basic.js.map +7 -1
  94. package/test/menu-group.test-vrt.js +4 -15
  95. package/test/menu-group.test-vrt.js.map +7 -1
  96. package/test/menu-group.test.js +161 -168
  97. package/test/menu-group.test.js.map +7 -1
  98. package/test/menu-item.test-vrt.js +4 -15
  99. package/test/menu-item.test-vrt.js.map +7 -1
  100. package/test/menu-item.test.js +93 -99
  101. package/test/menu-item.test.js.map +7 -1
  102. package/test/menu-selects.test.js +488 -494
  103. package/test/menu-selects.test.js.map +7 -1
  104. package/test/menu.test-vrt.js +4 -15
  105. package/test/menu.test-vrt.js.map +7 -1
  106. package/test/menu.test.js +240 -257
  107. package/test/menu.test.js.map +7 -1
  108. package/test/submenu.test-vrt.js +4 -15
  109. package/test/submenu.test-vrt.js.map +7 -1
  110. package/test/submenu.test.js +480 -464
  111. package/test/submenu.test.js.map +7 -1
package/src/MenuItem.js CHANGED
@@ -1,440 +1,424 @@
1
- /*
2
- Copyright 2020 Adobe. All rights reserved.
3
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License. You may obtain a copy
5
- of the License at http://www.apache.org/licenses/LICENSE-2.0
6
-
7
- Unless required by applicable law or agreed to in writing, software distributed under
8
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- OF ANY KIND, either express or implied. See the License for the specific language
10
- governing permissions and limitations under the License.
11
- */
12
- import { __decorate } from "tslib";
13
- import { html, } from '@spectrum-web-components/base';
14
- import { property, query, } from '@spectrum-web-components/base/src/decorators.js';
15
- import '@spectrum-web-components/icons-ui/icons/sp-icon-checkmark100.js';
16
- import { LikeAnchor } from '@spectrum-web-components/shared/src/like-anchor.js';
17
- import { Focusable } from '@spectrum-web-components/shared/src/focusable.js';
18
- import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js';
19
- import chevronStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js';
20
- import { openOverlay } from '@spectrum-web-components/overlay/src/loader.js';
21
- import menuItemStyles from './menu-item.css.js';
22
- import checkmarkStyles from '@spectrum-web-components/icon/src/spectrum-icon-checkmark.css.js';
23
- import { reparentChildren } from '@spectrum-web-components/shared/src/reparent-children.js';
24
- /**
25
- * Duration during which a pointing device can leave an `<sp-menu-item>` element
26
- * and return to it or to the submenu opened from it before closing that submenu.
27
- **/
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
+ } from "@spectrum-web-components/base";
15
+ import {
16
+ property,
17
+ query
18
+ } from "@spectrum-web-components/base/src/decorators.js";
19
+ import "@spectrum-web-components/icons-ui/icons/sp-icon-checkmark100.js";
20
+ import { LikeAnchor } from "@spectrum-web-components/shared/src/like-anchor.js";
21
+ import { Focusable } from "@spectrum-web-components/shared/src/focusable.js";
22
+ import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js";
23
+ import chevronStyles from "@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js";
24
+ import { openOverlay } from "@spectrum-web-components/overlay/src/loader.js";
25
+ import { OverlayCloseEvent } from "@spectrum-web-components/overlay/src/overlay-events.js";
26
+ import menuItemStyles from "./menu-item.css.js";
27
+ import checkmarkStyles from "@spectrum-web-components/icon/src/spectrum-icon-checkmark.css.js";
28
+ import { reparentChildren } from "@spectrum-web-components/shared/src/reparent-children.js";
29
+ import { MutationController } from "@lit-labs/observers/mutation_controller.js";
28
30
  const POINTERLEAVE_TIMEOUT = 100;
29
31
  export class MenuItemRemovedEvent extends Event {
30
- constructor() {
31
- super('sp-menu-item-removed', {
32
- bubbles: true,
33
- composed: true,
34
- });
35
- this.focused = false;
36
- }
37
- get item() {
38
- return this._item;
39
- }
40
- reset(item) {
41
- this._item = item;
42
- }
32
+ constructor() {
33
+ super("sp-menu-item-removed", {
34
+ bubbles: true,
35
+ composed: true
36
+ });
37
+ this.focused = false;
38
+ }
39
+ get item() {
40
+ return this._item;
41
+ }
42
+ reset(item) {
43
+ this._item = item;
44
+ }
43
45
  }
44
46
  export class MenuItemAddedOrUpdatedEvent extends Event {
45
- constructor() {
46
- super('sp-menu-item-added-or-updated', {
47
- bubbles: true,
48
- composed: true,
49
- });
50
- }
51
- set focusRoot(root) {
52
- this.item.menuData.focusRoot = this.item.menuData.focusRoot || root;
53
- }
54
- set selectionRoot(root) {
55
- this.item.menuData.selectionRoot =
56
- this.item.menuData.selectionRoot || root;
57
- }
58
- get item() {
59
- return this._item;
60
- }
61
- set currentAncestorWithSelects(ancestor) {
62
- this._currentAncestorWithSelects = ancestor;
63
- }
64
- get currentAncestorWithSelects() {
65
- return this._currentAncestorWithSelects;
66
- }
67
- reset(item) {
68
- this._item = item;
69
- this._currentAncestorWithSelects = undefined;
70
- item.menuData = {
71
- focusRoot: undefined,
72
- selectionRoot: undefined,
73
- };
74
- }
47
+ constructor() {
48
+ super("sp-menu-item-added-or-updated", {
49
+ bubbles: true,
50
+ composed: true
51
+ });
52
+ }
53
+ set focusRoot(root) {
54
+ this.item.menuData.focusRoot = this.item.menuData.focusRoot || root;
55
+ }
56
+ set selectionRoot(root) {
57
+ this.item.menuData.selectionRoot = this.item.menuData.selectionRoot || root;
58
+ }
59
+ get item() {
60
+ return this._item;
61
+ }
62
+ set currentAncestorWithSelects(ancestor) {
63
+ this._currentAncestorWithSelects = ancestor;
64
+ }
65
+ get currentAncestorWithSelects() {
66
+ return this._currentAncestorWithSelects;
67
+ }
68
+ reset(item) {
69
+ this._item = item;
70
+ this._currentAncestorWithSelects = void 0;
71
+ item.menuData = {
72
+ focusRoot: void 0,
73
+ selectionRoot: void 0
74
+ };
75
+ }
75
76
  }
76
77
  const addOrUpdateEvent = new MenuItemAddedOrUpdatedEvent();
77
78
  const removeEvent = new MenuItemRemovedEvent();
78
- /**
79
- * @element sp-menu-item
80
- *
81
- * @slot - text content to display within the Menu Item
82
- * @slot icon - icon element to be placed at the start of the Menu Item
83
- * @slot value - content placed at the end of the Menu Item like values, keyboard shortcuts, etc.
84
- * @fires sp-menu-item-added - announces the item has been added so a parent menu can take ownerships
85
- * @fires sp-menu-item-removed - announces when removed from the DOM so the parent menu can remove ownership and update selected state
86
- */
87
- export class MenuItem extends LikeAnchor(Focusable) {
88
- constructor() {
89
- super();
90
- this.isInSubmenu = false;
91
- this.active = false;
92
- this.focused = false;
93
- this.selected = false;
94
- this._value = '';
95
- this.hasSubmenu = false;
96
- this.noWrap = false;
97
- this.open = false;
98
- /**
99
- * When there is a `change` event in the submenu for this item
100
- * then we "click" this item to cascade the selection up the
101
- * menu tree allowing all submenus between the initial selection
102
- * and the root of the tree to have their selection changes and
103
- * be closed.
104
- */
105
- this.handleSubmenuChange = () => {
106
- var _a;
107
- (_a = this.menuData.selectionRoot) === null || _a === void 0 ? void 0 : _a.selectOrToggleItem(this);
108
- };
109
- this.handleSubmenuPointerenter = () => {
110
- if (this.leaveTimeout) {
111
- clearTimeout(this.leaveTimeout);
112
- delete this.leaveTimeout;
113
- }
114
- };
115
- this.menuData = {
116
- focusRoot: undefined,
117
- selectionRoot: undefined,
118
- };
119
- this.proxyFocus = this.proxyFocus.bind(this);
120
- this.addEventListener('click', this.handleClickCapture, {
121
- capture: true,
122
- });
123
- }
124
- static get styles() {
125
- return [menuItemStyles, checkmarkStyles, chevronStyles];
126
- }
127
- get value() {
128
- return this._value || this.itemText;
129
- }
130
- set value(value) {
131
- if (value === this._value) {
132
- return;
133
- }
134
- this._value = value || '';
135
- if (this._value) {
136
- this.setAttribute('value', this._value);
137
- }
138
- else {
139
- this.removeAttribute('value');
140
- }
141
- }
142
- /**
143
- * @private
144
- */
145
- get itemText() {
146
- return this.itemChildren.content.reduce((acc, node) => acc + (node.textContent || '').trim(), '');
147
- }
148
- get focusElement() {
149
- return this;
150
- }
151
- get itemChildren() {
152
- if (this._itemChildren) {
153
- return this._itemChildren;
154
- }
155
- const iconSlot = this.shadowRoot.querySelector('slot[name="icon"]');
156
- const icon = !iconSlot
157
- ? []
158
- : iconSlot.assignedElements().map((element) => {
159
- const newElement = element.cloneNode(true);
160
- newElement.removeAttribute('slot');
161
- newElement.classList.toggle('icon');
162
- return newElement;
163
- });
164
- const contentSlot = this.shadowRoot.querySelector('slot:not([name])');
165
- const content = !contentSlot
166
- ? []
167
- : contentSlot.assignedNodes().map((node) => node.cloneNode(true));
168
- this._itemChildren = { icon, content };
169
- return this._itemChildren;
170
- }
171
- click() {
172
- if (this.disabled) {
173
- return;
174
- }
175
- if (this.shouldProxyClick()) {
176
- return;
177
- }
178
- super.click();
179
- }
180
- handleClickCapture(event) {
181
- if (this.disabled) {
182
- event.preventDefault();
183
- event.stopImmediatePropagation();
184
- event.stopPropagation();
185
- return false;
186
- }
187
- }
188
- proxyFocus() {
189
- this.focus();
190
- }
191
- shouldProxyClick() {
192
- let handled = false;
193
- if (this.anchorElement) {
194
- this.anchorElement.click();
195
- handled = true;
196
- }
197
- return handled;
198
- }
199
- breakItemChildrenCache() {
200
- this._itemChildren = undefined;
201
- this.triggerUpdate();
202
- }
203
- render() {
204
- return html `
205
- <slot name="icon" @slotchange=${this.breakItemChildrenCache}></slot>
79
+ const _MenuItem = class extends LikeAnchor(Focusable) {
80
+ constructor() {
81
+ super();
82
+ this.isInSubmenu = false;
83
+ this.active = false;
84
+ this.focused = false;
85
+ this.selected = false;
86
+ this._value = "";
87
+ this.hasSubmenu = false;
88
+ this.noWrap = false;
89
+ this.open = false;
90
+ this.handleSubmenuChange = () => {
91
+ var _a;
92
+ (_a = this.menuData.selectionRoot) == null ? void 0 : _a.selectOrToggleItem(this);
93
+ };
94
+ this.handleSubmenuPointerenter = () => {
95
+ if (this.leaveTimeout) {
96
+ clearTimeout(this.leaveTimeout);
97
+ delete this.leaveTimeout;
98
+ }
99
+ };
100
+ this.menuData = {
101
+ focusRoot: void 0,
102
+ selectionRoot: void 0
103
+ };
104
+ this.proxyFocus = this.proxyFocus.bind(this);
105
+ this.addEventListener("click", this.handleClickCapture, {
106
+ capture: true
107
+ });
108
+ new MutationController(this, {
109
+ config: {
110
+ characterData: true,
111
+ childList: true,
112
+ subtree: true
113
+ },
114
+ callback: () => {
115
+ this.breakItemChildrenCache();
116
+ }
117
+ });
118
+ }
119
+ static get styles() {
120
+ return [menuItemStyles, checkmarkStyles, chevronStyles];
121
+ }
122
+ get value() {
123
+ return this._value || this.itemText;
124
+ }
125
+ set value(value) {
126
+ if (value === this._value) {
127
+ return;
128
+ }
129
+ this._value = value || "";
130
+ if (this._value) {
131
+ this.setAttribute("value", this._value);
132
+ } else {
133
+ this.removeAttribute("value");
134
+ }
135
+ }
136
+ get itemText() {
137
+ return this.itemChildren.content.reduce((acc, node) => acc + (node.textContent || "").trim(), "");
138
+ }
139
+ get focusElement() {
140
+ return this;
141
+ }
142
+ get itemChildren() {
143
+ if (this._itemChildren) {
144
+ return this._itemChildren;
145
+ }
146
+ const iconSlot = this.shadowRoot.querySelector('slot[name="icon"]');
147
+ const icon = !iconSlot ? [] : iconSlot.assignedElements().map((element) => {
148
+ const newElement = element.cloneNode(true);
149
+ newElement.removeAttribute("slot");
150
+ newElement.classList.toggle("icon");
151
+ return newElement;
152
+ });
153
+ const contentSlot = this.shadowRoot.querySelector("slot:not([name])");
154
+ const content = !contentSlot ? [] : contentSlot.assignedNodes().map((node) => node.cloneNode(true));
155
+ this._itemChildren = { icon, content };
156
+ return this._itemChildren;
157
+ }
158
+ click() {
159
+ if (this.disabled) {
160
+ return;
161
+ }
162
+ if (this.shouldProxyClick()) {
163
+ return;
164
+ }
165
+ super.click();
166
+ }
167
+ handleClickCapture(event) {
168
+ if (this.disabled) {
169
+ event.preventDefault();
170
+ event.stopImmediatePropagation();
171
+ event.stopPropagation();
172
+ return false;
173
+ }
174
+ }
175
+ proxyFocus() {
176
+ this.focus();
177
+ }
178
+ shouldProxyClick() {
179
+ let handled = false;
180
+ if (this.anchorElement) {
181
+ this.anchorElement.click();
182
+ handled = true;
183
+ }
184
+ return handled;
185
+ }
186
+ breakItemChildrenCache() {
187
+ this._itemChildren = void 0;
188
+ this.triggerUpdate();
189
+ }
190
+ render() {
191
+ return html`
192
+ <slot name="icon"></slot>
206
193
  <div id="label">
207
- <slot
208
- id="slot"
209
- @slotchange=${this.breakItemChildrenCache}
210
- ></slot>
194
+ <slot id="slot"></slot>
211
195
  </div>
212
196
  <slot name="value"></slot>
213
- ${this.selected
214
- ? html `
197
+ ${this.selected ? html`
215
198
  <sp-icon-checkmark100
216
199
  id="selected"
217
200
  class="spectrum-UIIcon-Checkmark100 icon checkmark"
218
201
  ></sp-icon-checkmark100>
219
- `
220
- : html ``}
221
- ${this.href && this.href.length > 0
222
- ? super.renderAnchor({
223
- id: 'button',
224
- ariaHidden: true,
225
- className: 'button anchor hidden',
226
- })
227
- : html ``}
202
+ ` : html``}
203
+ ${this.href && this.href.length > 0 ? super.renderAnchor({
204
+ id: "button",
205
+ ariaHidden: true,
206
+ className: "button anchor hidden"
207
+ }) : html``}
228
208
  <slot
229
209
  hidden
230
210
  name="submenu"
231
211
  @slotchange=${this.manageSubmenu}
232
212
  ></slot>
233
- ${this.hasSubmenu
234
- ? html `
213
+ ${this.hasSubmenu ? html`
235
214
  <sp-icon-chevron100
236
215
  class="spectrum-UIIcon-ChevronRight100 chevron icon"
237
216
  ></sp-icon-chevron100>
238
- `
239
- : html ``}
217
+ ` : html``}
240
218
  `;
241
- }
242
- manageSubmenu(event) {
243
- const assignedElements = event.target.assignedElements({
244
- flatten: true,
245
- });
246
- this.hasSubmenu = this.open || !!assignedElements.length;
247
- }
248
- handleRemoveActive(event) {
249
- if ((event.type === 'pointerleave' && this.hasSubmenu) ||
250
- this.hasSubmenu ||
251
- this.open) {
252
- return;
253
- }
254
- this.active = false;
255
- }
256
- handlePointerdown() {
257
- this.active = true;
258
- }
259
- firstUpdated(changes) {
260
- super.firstUpdated(changes);
261
- this.setAttribute('tabindex', '-1');
262
- this.addEventListener('pointerdown', this.handlePointerdown);
263
- if (!this.hasAttribute('id')) {
264
- this.id = `sp-menu-item-${MenuItem.instanceCount++}`;
265
- }
266
- }
267
- handleSubmenuClick() {
268
- this.openOverlay();
269
- }
270
- handlePointerenter() {
271
- if (this.leaveTimeout) {
272
- clearTimeout(this.leaveTimeout);
273
- delete this.leaveTimeout;
274
- return;
275
- }
276
- this.openOverlay();
277
- }
278
- handlePointerleave() {
279
- if (this.hasSubmenu && this.open) {
280
- this.leaveTimeout = setTimeout(() => {
281
- delete this.leaveTimeout;
282
- if (this.closeOverlay)
283
- this.closeOverlay(true);
284
- }, POINTERLEAVE_TIMEOUT);
285
- }
286
- }
287
- async openOverlay() {
288
- if (!this.hasSubmenu || this.open || this.disabled) {
289
- return;
290
- }
291
- this.open = true;
292
- this.active = true;
293
- const submenu = this.shadowRoot.querySelector('slot[name="submenu"]').assignedElements()[0];
294
- submenu.addEventListener('pointerenter', this.handleSubmenuPointerenter);
295
- submenu.addEventListener('change', this.handleSubmenuChange);
296
- const popover = document.createElement('sp-popover');
297
- const returnSubmenu = reparentChildren([submenu], popover, {
298
- position: 'beforeend',
299
- prepareCallback: (el) => {
300
- const slotName = el.slot;
301
- el.tabIndex = 0;
302
- el.removeAttribute('slot');
303
- el.isSubmenu = true;
304
- return (el) => {
305
- el.tabIndex = -1;
306
- el.slot = slotName;
307
- el.isSubmenu = false;
308
- };
309
- },
310
- });
311
- const closeOverlay = openOverlay(this, 'click', popover, {
312
- placement: this.isLTR ? 'right-start' : 'left-start',
313
- receivesFocus: 'auto',
314
- root: this.menuData.focusRoot,
315
- });
316
- const closeSubmenu = async () => {
317
- delete this.closeOverlay;
318
- (await closeOverlay)();
319
- };
320
- this.closeOverlay = closeSubmenu;
321
- const cleanup = (event) => {
322
- event.stopPropagation();
323
- returnSubmenu();
324
- this.open = false;
325
- this.active = false;
219
+ }
220
+ manageSubmenu(event) {
221
+ const assignedElements = event.target.assignedElements({
222
+ flatten: true
223
+ });
224
+ this.hasSubmenu = this.open || !!assignedElements.length;
225
+ }
226
+ handleRemoveActive(event) {
227
+ if (event.type === "pointerleave" && this.hasSubmenu || this.hasSubmenu || this.open) {
228
+ return;
229
+ }
230
+ this.active = false;
231
+ }
232
+ handlePointerdown() {
233
+ this.active = true;
234
+ }
235
+ firstUpdated(changes) {
236
+ super.firstUpdated(changes);
237
+ this.setAttribute("tabindex", "-1");
238
+ this.addEventListener("pointerdown", this.handlePointerdown);
239
+ if (!this.hasAttribute("id")) {
240
+ this.id = `sp-menu-item-${_MenuItem.instanceCount++}`;
241
+ }
242
+ this.addEventListener("pointerenter", this.closeOverlaysForRoot);
243
+ }
244
+ closeOverlaysForRoot() {
245
+ if (this.open)
246
+ return;
247
+ const overalyCloseEvent = new OverlayCloseEvent({
248
+ root: this.menuData.focusRoot
249
+ });
250
+ this.dispatchEvent(overalyCloseEvent);
251
+ }
252
+ handleSubmenuClick() {
253
+ this.openOverlay();
254
+ }
255
+ handlePointerenter() {
256
+ if (this.leaveTimeout) {
257
+ clearTimeout(this.leaveTimeout);
258
+ delete this.leaveTimeout;
259
+ return;
260
+ }
261
+ this.openOverlay();
262
+ }
263
+ handlePointerleave() {
264
+ if (this.hasSubmenu && this.open) {
265
+ this.leaveTimeout = setTimeout(() => {
266
+ delete this.leaveTimeout;
267
+ if (this.closeOverlay)
268
+ this.closeOverlay();
269
+ }, POINTERLEAVE_TIMEOUT);
270
+ }
271
+ }
272
+ async openOverlay() {
273
+ if (!this.hasSubmenu || this.open || this.disabled) {
274
+ return;
275
+ }
276
+ this.open = true;
277
+ this.active = true;
278
+ const submenu = this.shadowRoot.querySelector('slot[name="submenu"]').assignedElements()[0];
279
+ submenu.addEventListener("pointerenter", this.handleSubmenuPointerenter);
280
+ submenu.addEventListener("change", this.handleSubmenuChange);
281
+ const popover = document.createElement("sp-popover");
282
+ const returnSubmenu = reparentChildren([submenu], popover, {
283
+ position: "beforeend",
284
+ prepareCallback: (el) => {
285
+ const slotName = el.slot;
286
+ el.tabIndex = 0;
287
+ el.removeAttribute("slot");
288
+ el.isSubmenu = true;
289
+ return (el2) => {
290
+ el2.tabIndex = -1;
291
+ el2.slot = slotName;
292
+ el2.isSubmenu = false;
326
293
  };
327
- this.addEventListener('sp-closed', cleanup, {
328
- once: true,
329
- });
330
- popover.addEventListener('change', closeSubmenu);
331
- }
332
- updateAriaSelected() {
333
- const role = this.getAttribute('role');
334
- if (role === 'option') {
335
- this.setAttribute('aria-selected', this.selected ? 'true' : 'false');
336
- }
337
- else if (role === 'menuitemcheckbox' || role === 'menuitemradio') {
338
- this.setAttribute('aria-checked', this.selected ? 'true' : 'false');
339
- }
340
- }
341
- setRole(role) {
342
- this.setAttribute('role', role);
343
- this.updateAriaSelected();
344
- }
345
- updated(changes) {
346
- super.updated(changes);
347
- if (changes.has('label')) {
348
- this.setAttribute('aria-label', this.label || '');
349
- }
350
- if (changes.has('active')) {
351
- if (this.active) {
352
- this.addEventListener('pointerup', this.handleRemoveActive);
353
- this.addEventListener('pointerleave', this.handleRemoveActive);
354
- }
355
- else {
356
- this.removeEventListener('pointerup', this.handleRemoveActive);
357
- this.removeEventListener('pointerleave', this.handleRemoveActive);
358
- }
359
- }
360
- if (this.anchorElement) {
361
- this.anchorElement.addEventListener('focus', this.proxyFocus);
362
- this.anchorElement.tabIndex = -1;
363
- }
364
- if (changes.has('selected')) {
365
- this.updateAriaSelected();
366
- }
367
- if (changes.has('hasSubmenu')) {
368
- if (this.hasSubmenu) {
369
- this.addEventListener('click', this.handleSubmenuClick);
370
- this.addEventListener('pointerenter', this.handlePointerenter);
371
- this.addEventListener('pointerleave', this.handlePointerleave);
372
- }
373
- else if (!this.closeOverlay) {
374
- this.removeEventListener('click', this.handleSubmenuClick);
375
- this.removeEventListener('pointerenter', this.handlePointerenter);
376
- this.removeEventListener('pointerleave', this.handlePointerleave);
377
- }
378
- }
379
- }
380
- connectedCallback() {
381
- super.connectedCallback();
382
- this.isInSubmenu = !!this.closest('[slot="submenu"]');
383
- if (this.isInSubmenu) {
384
- return;
385
- }
386
- addOrUpdateEvent.reset(this);
387
- this.dispatchEvent(addOrUpdateEvent);
388
- this._parentElement = this.parentElement;
389
- }
390
- disconnectedCallback() {
391
- var _a;
392
- removeEvent.reset(this);
393
- if (!this.isInSubmenu) {
394
- (_a = this._parentElement) === null || _a === void 0 ? void 0 : _a.dispatchEvent(removeEvent);
395
- }
396
- this.isInSubmenu = false;
397
- super.disconnectedCallback();
398
- }
399
- async triggerUpdate() {
400
- if (this.isInSubmenu) {
401
- return;
402
- }
403
- await new Promise((ready) => requestAnimationFrame(ready));
404
- addOrUpdateEvent.reset(this);
405
- this.dispatchEvent(addOrUpdateEvent);
406
- }
407
- }
294
+ }
295
+ });
296
+ const closeOverlay = openOverlay(this, "click", popover, {
297
+ placement: this.isLTR ? "right-start" : "left-start",
298
+ receivesFocus: "auto",
299
+ root: this.menuData.focusRoot
300
+ });
301
+ const closeSubmenu = async () => {
302
+ delete this.closeOverlay;
303
+ (await closeOverlay)();
304
+ };
305
+ this.closeOverlay = closeSubmenu;
306
+ const cleanup = (event) => {
307
+ event.stopPropagation();
308
+ delete this.closeOverlay;
309
+ returnSubmenu();
310
+ this.open = false;
311
+ this.active = false;
312
+ };
313
+ this.addEventListener("sp-closed", cleanup, {
314
+ once: true
315
+ });
316
+ popover.addEventListener("change", closeSubmenu);
317
+ }
318
+ updateAriaSelected() {
319
+ const role = this.getAttribute("role");
320
+ if (role === "option") {
321
+ this.setAttribute("aria-selected", this.selected ? "true" : "false");
322
+ } else if (role === "menuitemcheckbox" || role === "menuitemradio") {
323
+ this.setAttribute("aria-checked", this.selected ? "true" : "false");
324
+ }
325
+ }
326
+ setRole(role) {
327
+ this.setAttribute("role", role);
328
+ this.updateAriaSelected();
329
+ }
330
+ updated(changes) {
331
+ super.updated(changes);
332
+ if (changes.has("label")) {
333
+ this.setAttribute("aria-label", this.label || "");
334
+ }
335
+ if (changes.has("active")) {
336
+ if (this.active) {
337
+ this.addEventListener("pointerup", this.handleRemoveActive);
338
+ this.addEventListener("pointerleave", this.handleRemoveActive);
339
+ } else {
340
+ this.removeEventListener("pointerup", this.handleRemoveActive);
341
+ this.removeEventListener("pointerleave", this.handleRemoveActive);
342
+ }
343
+ }
344
+ if (this.anchorElement) {
345
+ this.anchorElement.addEventListener("focus", this.proxyFocus);
346
+ this.anchorElement.tabIndex = -1;
347
+ }
348
+ if (changes.has("selected")) {
349
+ this.updateAriaSelected();
350
+ }
351
+ if (changes.has("hasSubmenu")) {
352
+ if (this.hasSubmenu) {
353
+ this.addEventListener("click", this.handleSubmenuClick);
354
+ this.addEventListener("pointerenter", this.handlePointerenter);
355
+ this.addEventListener("pointerleave", this.handlePointerleave);
356
+ } else if (!this.closeOverlay) {
357
+ this.removeEventListener("click", this.handleSubmenuClick);
358
+ this.removeEventListener("pointerenter", this.handlePointerenter);
359
+ this.removeEventListener("pointerleave", this.handlePointerleave);
360
+ }
361
+ }
362
+ }
363
+ connectedCallback() {
364
+ super.connectedCallback();
365
+ this.isInSubmenu = !!this.closest('[slot="submenu"]');
366
+ if (this.isInSubmenu) {
367
+ return;
368
+ }
369
+ addOrUpdateEvent.reset(this);
370
+ this.dispatchEvent(addOrUpdateEvent);
371
+ this._parentElement = this.parentElement;
372
+ }
373
+ disconnectedCallback() {
374
+ var _a;
375
+ removeEvent.reset(this);
376
+ if (!this.isInSubmenu) {
377
+ (_a = this._parentElement) == null ? void 0 : _a.dispatchEvent(removeEvent);
378
+ }
379
+ this.isInSubmenu = false;
380
+ super.disconnectedCallback();
381
+ }
382
+ async triggerUpdate() {
383
+ if (this.isInSubmenu) {
384
+ return;
385
+ }
386
+ await new Promise((ready) => requestAnimationFrame(ready));
387
+ addOrUpdateEvent.reset(this);
388
+ this.dispatchEvent(addOrUpdateEvent);
389
+ }
390
+ };
391
+ export let MenuItem = _MenuItem;
408
392
  MenuItem.instanceCount = 0;
409
- __decorate([
410
- property({ type: Boolean, reflect: true })
411
- ], MenuItem.prototype, "active", void 0);
412
- __decorate([
413
- property({ type: Boolean, reflect: true })
414
- ], MenuItem.prototype, "focused", void 0);
415
- __decorate([
416
- property({ type: Boolean, reflect: true })
417
- ], MenuItem.prototype, "selected", void 0);
418
- __decorate([
419
- property({ type: String })
420
- ], MenuItem.prototype, "value", null);
421
- __decorate([
422
- property({ type: Boolean })
423
- ], MenuItem.prototype, "hasSubmenu", void 0);
424
- __decorate([
425
- property({
426
- type: Boolean,
427
- reflect: true,
428
- attribute: 'no-wrap',
429
- hasChanged() {
430
- return false;
431
- },
432
- })
433
- ], MenuItem.prototype, "noWrap", void 0);
434
- __decorate([
435
- query('.anchor')
436
- ], MenuItem.prototype, "anchorElement", void 0);
437
- __decorate([
438
- property({ type: Boolean })
439
- ], MenuItem.prototype, "open", void 0);
440
- //# sourceMappingURL=MenuItem.js.map
393
+ __decorateClass([
394
+ property({ type: Boolean, reflect: true })
395
+ ], MenuItem.prototype, "active", 2);
396
+ __decorateClass([
397
+ property({ type: Boolean, reflect: true })
398
+ ], MenuItem.prototype, "focused", 2);
399
+ __decorateClass([
400
+ property({ type: Boolean, reflect: true })
401
+ ], MenuItem.prototype, "selected", 2);
402
+ __decorateClass([
403
+ property({ type: String })
404
+ ], MenuItem.prototype, "value", 1);
405
+ __decorateClass([
406
+ property({ type: Boolean })
407
+ ], MenuItem.prototype, "hasSubmenu", 2);
408
+ __decorateClass([
409
+ property({
410
+ type: Boolean,
411
+ reflect: true,
412
+ attribute: "no-wrap",
413
+ hasChanged() {
414
+ return false;
415
+ }
416
+ })
417
+ ], MenuItem.prototype, "noWrap", 2);
418
+ __decorateClass([
419
+ query(".anchor")
420
+ ], MenuItem.prototype, "anchorElement", 2);
421
+ __decorateClass([
422
+ property({ type: Boolean })
423
+ ], MenuItem.prototype, "open", 2);
424
+ //# sourceMappingURL=MenuItem.js.map