@spectrum-web-components/menu 0.36.0 → 0.38.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 (48) hide show
  1. package/custom-elements.json +459 -159
  2. package/package.json +9 -9
  3. package/src/Menu.d.ts +16 -6
  4. package/src/Menu.dev.js +179 -65
  5. package/src/Menu.dev.js.map +2 -2
  6. package/src/Menu.js +7 -3
  7. package/src/Menu.js.map +3 -3
  8. package/src/MenuGroup.d.ts +0 -2
  9. package/src/MenuGroup.dev.js +8 -12
  10. package/src/MenuGroup.dev.js.map +2 -2
  11. package/src/MenuGroup.js +3 -5
  12. package/src/MenuGroup.js.map +3 -3
  13. package/src/MenuItem.d.ts +30 -23
  14. package/src/MenuItem.dev.js +209 -215
  15. package/src/MenuItem.dev.js.map +3 -3
  16. package/src/MenuItem.js +36 -18
  17. package/src/MenuItem.js.map +3 -3
  18. package/src/menu-item.css.dev.js +9 -9
  19. package/src/menu-item.css.dev.js.map +1 -1
  20. package/src/menu-item.css.js +9 -9
  21. package/src/menu-item.css.js.map +1 -1
  22. package/src/menu.css.dev.js +1 -1
  23. package/src/menu.css.dev.js.map +1 -1
  24. package/src/menu.css.js +1 -1
  25. package/src/menu.css.js.map +1 -1
  26. package/src/spectrum-config.js +27 -1
  27. package/src/spectrum-menu-item.css.dev.js +8 -8
  28. package/src/spectrum-menu-item.css.dev.js.map +1 -1
  29. package/src/spectrum-menu-item.css.js +8 -8
  30. package/src/spectrum-menu-item.css.js.map +1 -1
  31. package/stories/index.js +4 -0
  32. package/stories/index.js.map +2 -2
  33. package/stories/menu-item.stories.js +10 -0
  34. package/stories/menu-item.stories.js.map +2 -2
  35. package/stories/menu.stories.js +47 -0
  36. package/stories/menu.stories.js.map +2 -2
  37. package/stories/submenu.stories.js +117 -104
  38. package/stories/submenu.stories.js.map +3 -3
  39. package/test/menu-group.test.js +14 -1
  40. package/test/menu-group.test.js.map +2 -2
  41. package/test/menu-item.test.js +36 -0
  42. package/test/menu-item.test.js.map +2 -2
  43. package/test/menu-selects.test.js +3 -1
  44. package/test/menu-selects.test.js.map +2 -2
  45. package/test/menu.test.js +9 -1
  46. package/test/menu.test.js.map +2 -2
  47. package/test/submenu.test.js +208 -84
  48. package/test/submenu.test.js.map +2 -2
@@ -11,7 +11,8 @@ var __decorateClass = (decorators, target, key, kind) => {
11
11
  return result;
12
12
  };
13
13
  import {
14
- html
14
+ html,
15
+ nothing
15
16
  } from "@spectrum-web-components/base";
16
17
  import {
17
18
  ObserveSlotPresence,
@@ -26,85 +27,39 @@ import { LikeAnchor } from "@spectrum-web-components/shared/src/like-anchor.js";
26
27
  import { Focusable } from "@spectrum-web-components/shared/src/focusable.js";
27
28
  import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js";
28
29
  import chevronStyles from "@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js";
29
- import { openOverlay } from "@spectrum-web-components/overlay/src/loader.js";
30
- import { OverlayCloseEvent } from "@spectrum-web-components/overlay/src/overlay-events.js";
31
30
  import menuItemStyles from "./menu-item.css.js";
32
31
  import checkmarkStyles from "@spectrum-web-components/icon/src/spectrum-icon-checkmark.css.js";
33
- import { reparentChildren } from "@spectrum-web-components/shared/src/reparent-children.js";
34
32
  import { MutationController } from "@lit-labs/observers/mutation-controller.js";
35
33
  const POINTERLEAVE_TIMEOUT = 100;
36
- export class MenuItemRemovedEvent extends Event {
37
- constructor() {
38
- super("sp-menu-item-removed", {
39
- bubbles: true,
40
- composed: true
41
- });
42
- this.focused = false;
43
- }
44
- get item() {
45
- return this._item;
46
- }
47
- reset(item) {
48
- this._item = item;
49
- }
50
- }
51
34
  export class MenuItemAddedOrUpdatedEvent extends Event {
52
- constructor() {
35
+ constructor(item) {
53
36
  super("sp-menu-item-added-or-updated", {
54
37
  bubbles: true,
55
38
  composed: true
56
39
  });
40
+ this.menuCascade = /* @__PURE__ */ new WeakMap();
41
+ this.clear(item);
57
42
  }
58
- set focusRoot(root) {
59
- this.item.menuData.focusRoot = this.item.menuData.focusRoot || root;
60
- }
61
- set selectionRoot(root) {
62
- this.item.menuData.selectionRoot = this.item.menuData.selectionRoot || root;
63
- }
64
- get item() {
65
- return this._item;
66
- }
67
- set currentAncestorWithSelects(ancestor) {
68
- this._currentAncestorWithSelects = ancestor;
69
- }
70
- get currentAncestorWithSelects() {
71
- return this._currentAncestorWithSelects;
72
- }
73
- reset(item) {
43
+ clear(item) {
74
44
  this._item = item;
75
- this._currentAncestorWithSelects = void 0;
45
+ this.currentAncestorWithSelects = void 0;
76
46
  item.menuData = {
47
+ cleanupSteps: [],
77
48
  focusRoot: void 0,
78
- selectionRoot: void 0
49
+ selectionRoot: void 0,
50
+ parentMenu: void 0
79
51
  };
52
+ this.menuCascade = /* @__PURE__ */ new WeakMap();
80
53
  }
81
- }
82
- let addOrUpdateEvent = new MenuItemAddedOrUpdatedEvent();
83
- let removeEvent = new MenuItemRemovedEvent();
84
- let addOrUpdateEventRafId = 0;
85
- function resetAddOrUpdateEvent() {
86
- if (addOrUpdateEventRafId === 0) {
87
- addOrUpdateEventRafId = requestAnimationFrame(() => {
88
- addOrUpdateEvent = new MenuItemAddedOrUpdatedEvent();
89
- addOrUpdateEventRafId = 0;
90
- });
91
- }
92
- }
93
- let removeEventEventtRafId = 0;
94
- function resetRemoveEvent() {
95
- if (removeEventEventtRafId === 0) {
96
- removeEventEventtRafId = requestAnimationFrame(() => {
97
- removeEvent = new MenuItemRemovedEvent();
98
- removeEventEventtRafId = 0;
99
- });
54
+ get item() {
55
+ return this._item;
100
56
  }
101
57
  }
102
- const _MenuItem = class _MenuItem extends LikeAnchor(
58
+ export class MenuItem extends LikeAnchor(
103
59
  ObserveSlotText(ObserveSlotPresence(Focusable, '[slot="icon"]'))
104
60
  ) {
105
61
  constructor() {
106
62
  super();
107
- this.isInSubmenu = false;
108
63
  this.active = false;
109
64
  this.focused = false;
110
65
  this.selected = false;
@@ -112,28 +67,27 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
112
67
  this.hasSubmenu = false;
113
68
  this.noWrap = false;
114
69
  this.open = false;
115
- /**
116
- * When there is a `change` event in the submenu for this item
117
- * then we "click" this item to cascade the selection up the
118
- * menu tree allowing all submenus between the initial selection
119
- * and the root of the tree to have their selection changes and
120
- * be closed.
121
- */
122
- this.handleSubmenuChange = () => {
123
- var _a;
124
- (_a = this.menuData.selectionRoot) == null ? void 0 : _a.selectOrToggleItem(this);
70
+ this.proxyFocus = () => {
71
+ this.focus();
125
72
  };
126
- this.handleSubmenuPointerenter = () => {
127
- if (this.leaveTimeout) {
128
- clearTimeout(this.leaveTimeout);
129
- delete this.leaveTimeout;
73
+ this.handleBeforetoggle = (event) => {
74
+ if (event.newState === "closed") {
75
+ this.open = true;
76
+ this.overlayElement.manuallyKeepOpen();
77
+ this.overlayElement.removeEventListener(
78
+ "beforetoggle",
79
+ this.handleBeforetoggle
80
+ );
130
81
  }
131
82
  };
83
+ this.recentlyLeftChild = false;
84
+ this.willDispatchUpdate = false;
132
85
  this.menuData = {
133
86
  focusRoot: void 0,
134
- selectionRoot: void 0
87
+ parentMenu: void 0,
88
+ selectionRoot: void 0,
89
+ cleanupSteps: []
135
90
  };
136
- this.proxyFocus = this.proxyFocus.bind(this);
137
91
  this.addEventListener("click", this.handleClickCapture, {
138
92
  capture: true
139
93
  });
@@ -181,23 +135,16 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
181
135
  return this.slotContentIsPresent;
182
136
  }
183
137
  get itemChildren() {
184
- var _a, _b;
185
138
  if (this._itemChildren) {
186
139
  return this._itemChildren;
187
140
  }
188
- const iconSlot = (_a = this.shadowRoot) == null ? void 0 : _a.querySelector(
189
- 'slot[name="icon"]'
190
- );
191
- const icon = !iconSlot ? [] : iconSlot.assignedElements().map((element) => {
141
+ const icon = this.iconSlot.assignedElements().map((element) => {
192
142
  const newElement = element.cloneNode(true);
193
143
  newElement.removeAttribute("slot");
194
144
  newElement.classList.toggle("icon");
195
145
  return newElement;
196
146
  });
197
- const contentSlot = (_b = this.shadowRoot) == null ? void 0 : _b.querySelector(
198
- "slot:not([name])"
199
- );
200
- const content = !contentSlot ? [] : contentSlot.assignedNodes().map((node) => node.cloneNode(true));
147
+ const content = this.contentSlot.assignedNodes().map((node) => node.cloneNode(true));
201
148
  this._itemChildren = { icon, content };
202
149
  return this._itemChildren;
203
150
  }
@@ -218,9 +165,6 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
218
165
  return false;
219
166
  }
220
167
  }
221
- proxyFocus() {
222
- this.focus();
223
- }
224
168
  shouldProxyClick() {
225
169
  let handled = false;
226
170
  if (this.anchorElement) {
@@ -233,6 +177,52 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
233
177
  this._itemChildren = void 0;
234
178
  this.triggerUpdate();
235
179
  }
180
+ renderSubmenu() {
181
+ const slot = html`
182
+ <slot
183
+ name="submenu"
184
+ @slotchange=${this.manageSubmenu}
185
+ @sp-menu-item-added-or-updated=${{
186
+ handleEvent: (event) => {
187
+ event.clear(event.item);
188
+ },
189
+ capture: true
190
+ }}
191
+ @focusin=${(event) => event.stopPropagation()}
192
+ ></slot>
193
+ `;
194
+ if (!this.hasSubmenu) {
195
+ return slot;
196
+ }
197
+ import("@spectrum-web-components/overlay/sp-overlay.js");
198
+ import("@spectrum-web-components/popover/sp-popover.js");
199
+ return html`
200
+ <sp-overlay
201
+ .triggerElement=${this}
202
+ ?disabled=${!this.hasSubmenu}
203
+ ?open=${this.hasSubmenu && this.open}
204
+ .placement=${this.isLTR ? "right-start" : "left-start"}
205
+ .offset=${[-10, -4]}
206
+ .type=${"auto"}
207
+ @close=${(event) => event.stopPropagation()}
208
+ >
209
+ <sp-popover
210
+ @change=${(event) => {
211
+ this.handleSubmenuChange(event);
212
+ this.open = false;
213
+ }}
214
+ @pointerenter=${this.handleSubmenuPointerenter}
215
+ @pointerleave=${this.handleSubmenuPointerleave}
216
+ @sp-menu-item-added-or-updated=${(event) => event.stopPropagation()}
217
+ >
218
+ ${slot}
219
+ </sp-popover>
220
+ </sp-overlay>
221
+ <sp-icon-chevron100
222
+ class="spectrum-UIIcon-ChevronRight100 chevron icon"
223
+ ></sp-icon-chevron100>
224
+ `;
225
+ }
236
226
  render() {
237
227
  return html`
238
228
  ${this.selected ? html`
@@ -243,70 +233,74 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
243
233
  checkmark
244
234
  ${this.hasIcon ? "checkmark--withAdjacentIcon" : ""}"
245
235
  ></sp-icon-checkmark100>
246
- ` : html``}
236
+ ` : nothing}
247
237
  <slot name="icon"></slot>
248
238
  <div id="label">
249
239
  <slot id="slot"></slot>
250
240
  </div>
241
+ <slot name="description"></slot>
251
242
  <slot name="value"></slot>
252
243
  ${this.href && this.href.length > 0 ? super.renderAnchor({
253
244
  id: "button",
254
245
  ariaHidden: true,
255
246
  className: "button anchor hidden"
256
- }) : html``}
257
-
258
- <slot
259
- hidden
260
- name="submenu"
261
- @slotchange=${this.manageSubmenu}
262
- ></slot>
263
- ${this.hasSubmenu ? html`
264
- <sp-icon-chevron100
265
- class="spectrum-UIIcon-ChevronRight100
266
- chevron
267
- icon"
268
- ></sp-icon-chevron100>
269
- ` : html``}
247
+ }) : nothing}
248
+ ${this.renderSubmenu()}
270
249
  `;
271
250
  }
272
251
  manageSubmenu(event) {
273
252
  const assignedElements = event.target.assignedElements({
274
253
  flatten: true
275
254
  });
276
- this.hasSubmenu = this.open || !!assignedElements;
255
+ this.hasSubmenu = !!assignedElements.length;
277
256
  if (this.hasSubmenu) {
278
257
  this.setAttribute("aria-haspopup", "true");
279
258
  }
280
259
  }
281
- handleRemoveActive(event) {
282
- if (event.type === "pointerleave" && this.hasSubmenu || this.hasSubmenu || this.open) {
260
+ handleRemoveActive() {
261
+ if (this.open) {
283
262
  return;
284
263
  }
285
264
  this.active = false;
286
265
  }
287
- handlePointerdown() {
266
+ handlePointerdown(event) {
288
267
  this.active = true;
268
+ if (event.target === this && this.hasSubmenu && this.open) {
269
+ this.addEventListener("focus", this.handleSubmenuFocus, {
270
+ once: true
271
+ });
272
+ this.overlayElement.addEventListener(
273
+ "beforetoggle",
274
+ this.handleBeforetoggle
275
+ );
276
+ }
289
277
  }
290
278
  firstUpdated(changes) {
291
279
  super.firstUpdated(changes);
292
280
  this.setAttribute("tabindex", "-1");
293
281
  this.addEventListener("pointerdown", this.handlePointerdown);
282
+ this.addEventListener("pointerenter", this.closeOverlaysForRoot);
294
283
  if (!this.hasAttribute("id")) {
295
- this.id = `sp-menu-item-${_MenuItem.instanceCount++}`;
284
+ this.id = `sp-menu-item-${crypto.randomUUID().slice(0, 8)}`;
296
285
  }
297
- this.addEventListener("pointerenter", this.closeOverlaysForRoot);
298
286
  }
299
287
  closeOverlaysForRoot() {
288
+ var _a;
300
289
  if (this.open)
301
290
  return;
302
- const overalyCloseEvent = new OverlayCloseEvent({
303
- root: this.menuData.focusRoot
304
- });
305
- this.dispatchEvent(overalyCloseEvent);
291
+ (_a = this.menuData.parentMenu) == null ? void 0 : _a.closeDescendentOverlays();
306
292
  }
307
- handleSubmenuClick() {
293
+ handleSubmenuClick(event) {
294
+ if (event.composedPath().includes(this.overlayElement)) {
295
+ return;
296
+ }
308
297
  this.openOverlay();
309
298
  }
299
+ handleSubmenuFocus() {
300
+ requestAnimationFrame(() => {
301
+ this.overlayElement.open = this.open;
302
+ });
303
+ }
310
304
  handlePointerenter() {
311
305
  if (this.leaveTimeout) {
312
306
  clearTimeout(this.leaveTimeout);
@@ -316,14 +310,44 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
316
310
  this.openOverlay();
317
311
  }
318
312
  handlePointerleave() {
319
- if (this.hasSubmenu && this.open) {
313
+ if (this.open && !this.recentlyLeftChild) {
320
314
  this.leaveTimeout = setTimeout(() => {
321
315
  delete this.leaveTimeout;
322
- if (this.closeOverlay)
323
- this.closeOverlay();
316
+ this.open = false;
324
317
  }, POINTERLEAVE_TIMEOUT);
325
318
  }
326
319
  }
320
+ /**
321
+ * When there is a `change` event in the submenu for this item
322
+ * then we "click" this item to cascade the selection up the
323
+ * menu tree allowing all submenus between the initial selection
324
+ * and the root of the tree to have their selection changes and
325
+ * be closed.
326
+ */
327
+ handleSubmenuChange(event) {
328
+ var _a;
329
+ event.stopPropagation();
330
+ (_a = this.menuData.selectionRoot) == null ? void 0 : _a.selectOrToggleItem(this);
331
+ }
332
+ handleSubmenuPointerenter() {
333
+ this.recentlyLeftChild = true;
334
+ }
335
+ async handleSubmenuPointerleave() {
336
+ requestAnimationFrame(() => {
337
+ this.recentlyLeftChild = false;
338
+ });
339
+ }
340
+ handleSubmenuOpen(event) {
341
+ this.focused = false;
342
+ const parentOverlay = event.composedPath().find((el) => {
343
+ return el !== this.overlayElement && el.localName === "sp-overlay";
344
+ });
345
+ this.overlayElement.parentOverlayToForceClose = parentOverlay;
346
+ }
347
+ cleanup() {
348
+ this.open = false;
349
+ this.active = false;
350
+ }
327
351
  async openOverlay() {
328
352
  if (!this.hasSubmenu || this.open || this.disabled) {
329
353
  return;
@@ -331,55 +355,9 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
331
355
  this.open = true;
332
356
  this.active = true;
333
357
  this.setAttribute("aria-expanded", "true");
334
- const submenu = this.shadowRoot.querySelector(
335
- 'slot[name="submenu"]'
336
- ).assignedElements()[0];
337
- submenu.addEventListener(
338
- "pointerenter",
339
- this.handleSubmenuPointerenter
340
- );
341
- submenu.addEventListener("change", this.handleSubmenuChange);
342
- if (!submenu.id) {
343
- submenu.setAttribute("id", `${this.id}-submenu`);
344
- }
345
- this.setAttribute("aria-controls", submenu.id);
346
- const popover = document.createElement("sp-popover");
347
- const returnSubmenu = reparentChildren([submenu], popover, {
348
- position: "beforeend",
349
- prepareCallback: (el) => {
350
- const slotName = el.slot;
351
- el.tabIndex = 0;
352
- el.removeAttribute("slot");
353
- el.isSubmenu = true;
354
- return (el2) => {
355
- el2.tabIndex = -1;
356
- el2.slot = slotName;
357
- el2.isSubmenu = false;
358
- };
359
- }
360
- });
361
- const closeOverlay = openOverlay(this, "click", popover, {
362
- placement: this.isLTR ? "right-start" : "left-start",
363
- receivesFocus: "auto",
364
- root: this.menuData.focusRoot
365
- });
366
- const closeSubmenu = async () => {
367
- this.setAttribute("aria-expanded", "false");
368
- delete this.closeOverlay;
369
- (await closeOverlay)();
370
- };
371
- this.closeOverlay = closeSubmenu;
372
- const cleanup = (event) => {
373
- event.stopPropagation();
374
- delete this.closeOverlay;
375
- returnSubmenu();
376
- this.open = false;
377
- this.active = false;
378
- };
379
- this.addEventListener("sp-closed", cleanup, {
358
+ this.addEventListener("sp-closed", this.cleanup, {
380
359
  once: true
381
360
  });
382
- popover.addEventListener("change", closeSubmenu);
383
361
  }
384
362
  updateAriaSelected() {
385
363
  const role = this.getAttribute("role");
@@ -397,25 +375,33 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
397
375
  this.updateAriaSelected();
398
376
  }
399
377
  updated(changes) {
378
+ var _a, _b, _c;
400
379
  super.updated(changes);
401
- if (changes.has("label")) {
380
+ if (changes.has("label") && (this.label || typeof changes.get("label") !== "undefined")) {
402
381
  this.setAttribute("aria-label", this.label || "");
403
382
  }
404
- if (changes.has("active")) {
383
+ if (changes.has("active") && (this.active || typeof changes.get("active") !== "undefined")) {
405
384
  if (this.active) {
406
- this.addEventListener("pointerup", this.handleRemoveActive);
407
- this.addEventListener("pointerleave", this.handleRemoveActive);
408
- this.addEventListener("pointercancel", this.handleRemoveActive);
409
- } else {
410
- this.removeEventListener("pointerup", this.handleRemoveActive);
411
- this.removeEventListener(
385
+ (_a = this.menuData.selectionRoot) == null ? void 0 : _a.closeDescendentOverlays();
386
+ this.abortControllerPointer = new AbortController();
387
+ const options = { signal: this.abortControllerPointer.signal };
388
+ this.addEventListener(
389
+ "pointerup",
390
+ this.handleRemoveActive,
391
+ options
392
+ );
393
+ this.addEventListener(
412
394
  "pointerleave",
413
- this.handleRemoveActive
395
+ this.handleRemoveActive,
396
+ options
414
397
  );
415
- this.removeEventListener(
398
+ this.addEventListener(
416
399
  "pointercancel",
417
- this.handleRemoveActive
400
+ this.handleRemoveActive,
401
+ options
418
402
  );
403
+ } else {
404
+ (_b = this.abortControllerPointer) == null ? void 0 : _b.abort();
419
405
  }
420
406
  }
421
407
  if (this.anchorElement) {
@@ -425,71 +411,77 @@ const _MenuItem = class _MenuItem extends LikeAnchor(
425
411
  if (changes.has("selected")) {
426
412
  this.updateAriaSelected();
427
413
  }
428
- if (changes.has("hasSubmenu")) {
414
+ if (changes.has("hasSubmenu") && (this.hasSubmenu || typeof changes.get("hasSubmenu") !== "undefined")) {
429
415
  if (this.hasSubmenu) {
430
- this.addEventListener("click", this.handleSubmenuClick);
431
- this.addEventListener("pointerenter", this.handlePointerenter);
432
- this.addEventListener("pointerleave", this.handlePointerleave);
433
- } else if (!this.closeOverlay) {
434
- this.removeEventListener("click", this.handleSubmenuClick);
435
- this.removeEventListener(
416
+ this.abortControllerSubmenu = new AbortController();
417
+ const options = { signal: this.abortControllerSubmenu.signal };
418
+ this.addEventListener(
419
+ "click",
420
+ this.handleSubmenuClick,
421
+ options
422
+ );
423
+ this.addEventListener(
436
424
  "pointerenter",
437
- this.handlePointerenter
425
+ this.handlePointerenter,
426
+ options
438
427
  );
439
- this.removeEventListener(
428
+ this.addEventListener(
440
429
  "pointerleave",
441
- this.handlePointerleave
430
+ this.handlePointerleave,
431
+ options
432
+ );
433
+ this.addEventListener(
434
+ "sp-opened",
435
+ this.handleSubmenuOpen,
436
+ options
442
437
  );
438
+ } else {
439
+ (_c = this.abortControllerSubmenu) == null ? void 0 : _c.abort();
443
440
  }
444
441
  }
445
442
  }
446
443
  connectedCallback() {
447
444
  super.connectedCallback();
448
- this.isInSubmenu = !!this.closest('[slot="submenu"]');
449
- if (this.isInSubmenu) {
450
- return;
451
- }
452
- addOrUpdateEvent.reset(this);
453
- this.dispatchEvent(addOrUpdateEvent);
454
- resetAddOrUpdateEvent();
455
- this._parentElement = this.parentElement;
445
+ this.triggerUpdate();
456
446
  }
457
447
  disconnectedCallback() {
458
- if (!this.isInSubmenu && this._parentElement) {
459
- removeEvent.reset(this);
460
- this._parentElement.dispatchEvent(removeEvent);
461
- resetRemoveEvent();
462
- }
463
- this.isInSubmenu = false;
464
- this._itemChildren = void 0;
448
+ this.menuData.cleanupSteps.forEach((removal) => removal(this));
465
449
  super.disconnectedCallback();
466
450
  }
467
451
  async triggerUpdate() {
468
- if (this.isInSubmenu) {
452
+ if (this.willDispatchUpdate) {
469
453
  return;
470
454
  }
455
+ this.willDispatchUpdate = true;
471
456
  await new Promise((ready) => requestAnimationFrame(ready));
472
- addOrUpdateEvent.reset(this);
473
- this.dispatchEvent(addOrUpdateEvent);
474
- resetAddOrUpdateEvent();
457
+ this.dispatchUpdate();
475
458
  }
476
- };
477
- _MenuItem.instanceCount = 0;
459
+ dispatchUpdate() {
460
+ this.dispatchEvent(new MenuItemAddedOrUpdatedEvent(this));
461
+ this.willDispatchUpdate = false;
462
+ }
463
+ }
478
464
  __decorateClass([
479
465
  property({ type: Boolean, reflect: true })
480
- ], _MenuItem.prototype, "active", 2);
466
+ ], MenuItem.prototype, "active", 2);
481
467
  __decorateClass([
482
468
  property({ type: Boolean, reflect: true })
483
- ], _MenuItem.prototype, "focused", 2);
469
+ ], MenuItem.prototype, "focused", 2);
484
470
  __decorateClass([
485
471
  property({ type: Boolean, reflect: true })
486
- ], _MenuItem.prototype, "selected", 2);
472
+ ], MenuItem.prototype, "selected", 2);
487
473
  __decorateClass([
488
474
  property({ type: String })
489
- ], _MenuItem.prototype, "value", 1);
475
+ ], MenuItem.prototype, "value", 1);
490
476
  __decorateClass([
491
477
  property({ type: Boolean, reflect: true, attribute: "has-submenu" })
492
- ], _MenuItem.prototype, "hasSubmenu", 2);
478
+ ], MenuItem.prototype, "hasSubmenu", 2);
479
+ __decorateClass([
480
+ query("slot:not([name])")
481
+ ], MenuItem.prototype, "contentSlot", 2);
482
+ __decorateClass([
483
+ query('slot[name="icon"]')
484
+ ], MenuItem.prototype, "iconSlot", 2);
493
485
  __decorateClass([
494
486
  property({
495
487
  type: Boolean,
@@ -499,12 +491,14 @@ __decorateClass([
499
491
  return false;
500
492
  }
501
493
  })
502
- ], _MenuItem.prototype, "noWrap", 2);
494
+ ], MenuItem.prototype, "noWrap", 2);
503
495
  __decorateClass([
504
496
  query(".anchor")
505
- ], _MenuItem.prototype, "anchorElement", 2);
497
+ ], MenuItem.prototype, "anchorElement", 2);
498
+ __decorateClass([
499
+ query("sp-overlay")
500
+ ], MenuItem.prototype, "overlayElement", 2);
506
501
  __decorateClass([
507
- property({ type: Boolean })
508
- ], _MenuItem.prototype, "open", 2);
509
- export let MenuItem = _MenuItem;
502
+ property({ type: Boolean, reflect: true })
503
+ ], MenuItem.prototype, "open", 2);
510
504
  //# sourceMappingURL=MenuItem.dev.js.map