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