@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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectrum-web-components/menu",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.36.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -85,16 +85,16 @@
|
|
|
85
85
|
],
|
|
86
86
|
"dependencies": {
|
|
87
87
|
"@lit-labs/observers": "^2.0.0",
|
|
88
|
-
"@spectrum-web-components/action-button": "^0.
|
|
89
|
-
"@spectrum-web-components/base": "^0.
|
|
90
|
-
"@spectrum-web-components/divider": "^0.
|
|
91
|
-
"@spectrum-web-components/icon": "^0.
|
|
92
|
-
"@spectrum-web-components/icons-ui": "^0.
|
|
93
|
-
"@spectrum-web-components/overlay": "^0.
|
|
94
|
-
"@spectrum-web-components/shared": "^0.
|
|
88
|
+
"@spectrum-web-components/action-button": "^0.36.0",
|
|
89
|
+
"@spectrum-web-components/base": "^0.36.0",
|
|
90
|
+
"@spectrum-web-components/divider": "^0.36.0",
|
|
91
|
+
"@spectrum-web-components/icon": "^0.36.0",
|
|
92
|
+
"@spectrum-web-components/icons-ui": "^0.36.0",
|
|
93
|
+
"@spectrum-web-components/overlay": "^0.36.0",
|
|
94
|
+
"@spectrum-web-components/shared": "^0.36.0"
|
|
95
95
|
},
|
|
96
96
|
"devDependencies": {
|
|
97
|
-
"@spectrum-css/menu": "^
|
|
97
|
+
"@spectrum-css/menu": "^5.0.2"
|
|
98
98
|
},
|
|
99
99
|
"types": "./src/index.d.ts",
|
|
100
100
|
"customElements": "custom-elements.json",
|
|
@@ -102,5 +102,5 @@
|
|
|
102
102
|
"./sp-*.js",
|
|
103
103
|
"./**/*.dev.js"
|
|
104
104
|
],
|
|
105
|
-
"gitHead": "
|
|
105
|
+
"gitHead": "a532ff8a410abeefb54d9638a2316ae82570566e"
|
|
106
106
|
}
|
package/src/Menu.d.ts
CHANGED
|
@@ -7,6 +7,10 @@ export interface MenuChildItem {
|
|
|
7
7
|
focusable: boolean;
|
|
8
8
|
focusRoot: Menu;
|
|
9
9
|
}
|
|
10
|
+
declare const Menu_base: typeof SpectrumElement & {
|
|
11
|
+
new (...args: any[]): import("@spectrum-web-components/base").SizedElementInterface;
|
|
12
|
+
prototype: import("@spectrum-web-components/base").SizedElementInterface;
|
|
13
|
+
};
|
|
10
14
|
/**
|
|
11
15
|
* Spectrum Menu Component
|
|
12
16
|
* @element sp-menu
|
|
@@ -20,9 +24,9 @@ export interface MenuChildItem {
|
|
|
20
24
|
* When the `selects` attribute is not present a `value` will not be maintained and the Menu
|
|
21
25
|
* Item children of this Menu will not have their `selected` state managed.
|
|
22
26
|
*/
|
|
23
|
-
export declare class Menu extends
|
|
27
|
+
export declare class Menu extends Menu_base {
|
|
24
28
|
static get styles(): CSSResultArray;
|
|
25
|
-
|
|
29
|
+
isSubmenu: boolean;
|
|
26
30
|
label: string;
|
|
27
31
|
ignore: boolean;
|
|
28
32
|
selects: undefined | 'inherit' | 'single' | 'multiple';
|
|
@@ -51,7 +55,7 @@ export declare class Menu extends SpectrumElement {
|
|
|
51
55
|
private resolvedRole?;
|
|
52
56
|
/**
|
|
53
57
|
* When a descendant `<sp-menu-item>` element is added or updated it will dispatch
|
|
54
|
-
* this event to announce its presence in the DOM. During the
|
|
58
|
+
* this event to announce its presence in the DOM. During the capture phase the first
|
|
55
59
|
* Menu based element that the event encounters will manage the focus state of the
|
|
56
60
|
* dispatching `<sp-menu-item>` element.
|
|
57
61
|
* @param event
|
|
@@ -59,7 +63,7 @@ export declare class Menu extends SpectrumElement {
|
|
|
59
63
|
private onFocusableItemAddedOrUpdated;
|
|
60
64
|
/**
|
|
61
65
|
* When a descendant `<sp-menu-item>` element is added or updated it will dispatch
|
|
62
|
-
* this event to announce its presence in the DOM. During the
|
|
66
|
+
* this event to announce its presence in the DOM. During the bubble phase the first
|
|
63
67
|
* Menu based element that the event encounters that does not inherit selection will
|
|
64
68
|
* manage the selection state of the dispatching `<sp-menu-item>` element.
|
|
65
69
|
* @param event
|
|
@@ -69,33 +73,24 @@ export declare class Menu extends SpectrumElement {
|
|
|
69
73
|
private removeChildItem;
|
|
70
74
|
constructor();
|
|
71
75
|
focus({ preventScroll }?: FocusOptions): void;
|
|
72
|
-
private
|
|
76
|
+
private onClick;
|
|
73
77
|
handleFocusin(event: FocusEvent): void;
|
|
74
78
|
startListeningToKeyboard(): void;
|
|
75
79
|
handleFocusout(event: FocusEvent): void;
|
|
76
80
|
stopListeningToKeyboard(): void;
|
|
77
|
-
private descendentOverlays;
|
|
78
|
-
protected handleDescendentOverlayOpened(event: Event): void;
|
|
79
|
-
protected handleDescendentOverlayClosed(event: Event): void;
|
|
80
|
-
handleSubmenuClosed: (event: Event) => void;
|
|
81
|
-
handleSubmenuOpened: (event: Event) => void;
|
|
82
81
|
selectOrToggleItem(targetItem: MenuItem): Promise<void>;
|
|
83
82
|
protected navigateWithinMenu(event: KeyboardEvent): void;
|
|
84
|
-
protected navigateBetweenRelatedMenus(
|
|
83
|
+
protected navigateBetweenRelatedMenus(code: string): void;
|
|
85
84
|
handleKeydown(event: KeyboardEvent): void;
|
|
86
85
|
focusMenuItemByOffset(offset: number): MenuItem;
|
|
87
86
|
private prepareToCleanUp;
|
|
88
|
-
private _hasUpdatedSelectedItemIndex;
|
|
89
87
|
updateSelectedItemIndex(): void;
|
|
90
88
|
private _willUpdateItems;
|
|
91
89
|
private handleItemsChanged;
|
|
92
|
-
private updateCache;
|
|
93
90
|
private updateItemFocus;
|
|
94
|
-
closeDescendentOverlays(): void;
|
|
95
91
|
private forwardFocusVisibleToItem;
|
|
96
|
-
private handleSlotchange;
|
|
97
|
-
protected renderMenuItemSlot(): TemplateResult;
|
|
98
92
|
render(): TemplateResult;
|
|
93
|
+
private _notFirstUpdated;
|
|
99
94
|
protected firstUpdated(changed: PropertyValues): void;
|
|
100
95
|
protected updated(changes: PropertyValues<this>): void;
|
|
101
96
|
protected selectsChanged(): void;
|
|
@@ -103,6 +98,6 @@ export declare class Menu extends SpectrumElement {
|
|
|
103
98
|
disconnectedCallback(): void;
|
|
104
99
|
protected childItemsUpdated: Promise<unknown[]>;
|
|
105
100
|
protected cacheUpdated: Promise<void>;
|
|
106
|
-
protected resolveCacheUpdated: () => void;
|
|
107
101
|
protected getUpdateComplete(): Promise<boolean>;
|
|
108
102
|
}
|
|
103
|
+
export {};
|
package/src/Menu.dev.js
CHANGED
|
@@ -12,6 +12,7 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
12
12
|
};
|
|
13
13
|
import {
|
|
14
14
|
html,
|
|
15
|
+
SizedMixin,
|
|
15
16
|
SpectrumElement
|
|
16
17
|
} from "@spectrum-web-components/base";
|
|
17
18
|
import {
|
|
@@ -23,9 +24,10 @@ import menuStyles from "./menu.css.js";
|
|
|
23
24
|
function elementIsOrContains(el, isOrContains) {
|
|
24
25
|
return !!isOrContains && (el === isOrContains || el.contains(isOrContains));
|
|
25
26
|
}
|
|
26
|
-
export class Menu extends SpectrumElement {
|
|
27
|
+
export class Menu extends SizedMixin(SpectrumElement) {
|
|
27
28
|
constructor() {
|
|
28
29
|
super();
|
|
30
|
+
this.isSubmenu = false;
|
|
29
31
|
this.label = "";
|
|
30
32
|
this.ignore = false;
|
|
31
33
|
this.value = "";
|
|
@@ -36,44 +38,9 @@ export class Menu extends SpectrumElement {
|
|
|
36
38
|
this.focusedItemIndex = 0;
|
|
37
39
|
this.focusInItemIndex = 0;
|
|
38
40
|
this.selectedItemsMap = /* @__PURE__ */ new Map();
|
|
39
|
-
this.descendentOverlays = /* @__PURE__ */ new Map();
|
|
40
|
-
this.handleSubmenuClosed = (event) => {
|
|
41
|
-
event.stopPropagation();
|
|
42
|
-
const target = event.composedPath()[0];
|
|
43
|
-
target.dispatchEvent(
|
|
44
|
-
new Event("sp-menu-submenu-closed", {
|
|
45
|
-
bubbles: true,
|
|
46
|
-
composed: true
|
|
47
|
-
})
|
|
48
|
-
);
|
|
49
|
-
};
|
|
50
|
-
this.handleSubmenuOpened = (event) => {
|
|
51
|
-
event.stopPropagation();
|
|
52
|
-
const target = event.composedPath()[0];
|
|
53
|
-
target.dispatchEvent(
|
|
54
|
-
new Event("sp-menu-submenu-opened", {
|
|
55
|
-
bubbles: true,
|
|
56
|
-
composed: true
|
|
57
|
-
})
|
|
58
|
-
);
|
|
59
|
-
const focusedItem = this.childItems[this.focusedItemIndex];
|
|
60
|
-
if (focusedItem) {
|
|
61
|
-
focusedItem.focused = false;
|
|
62
|
-
}
|
|
63
|
-
const openedItem = event.composedPath().find((el) => this.childItemSet.has(el));
|
|
64
|
-
if (!openedItem)
|
|
65
|
-
return;
|
|
66
|
-
const openedItemIndex = this.childItems.indexOf(openedItem);
|
|
67
|
-
this.focusedItemIndex = openedItemIndex;
|
|
68
|
-
this.focusInItemIndex = openedItemIndex;
|
|
69
|
-
};
|
|
70
|
-
this._hasUpdatedSelectedItemIndex = false;
|
|
71
41
|
this._willUpdateItems = false;
|
|
42
|
+
this._notFirstUpdated = false;
|
|
72
43
|
this.cacheUpdated = Promise.resolve();
|
|
73
|
-
/* c8 ignore next 3 */
|
|
74
|
-
this.resolveCacheUpdated = () => {
|
|
75
|
-
return;
|
|
76
|
-
};
|
|
77
44
|
this.addEventListener(
|
|
78
45
|
"sp-menu-item-added-or-updated",
|
|
79
46
|
this.onSelectableItemAddedOrUpdated
|
|
@@ -85,18 +52,13 @@ export class Menu extends SpectrumElement {
|
|
|
85
52
|
capture: true
|
|
86
53
|
}
|
|
87
54
|
);
|
|
88
|
-
this.addEventListener("
|
|
55
|
+
this.addEventListener("sp-menu-item-removed", this.removeChildItem);
|
|
56
|
+
this.addEventListener("click", this.onClick);
|
|
89
57
|
this.addEventListener("focusin", this.handleFocusin);
|
|
90
|
-
this.addEventListener("focusout", this.handleFocusout);
|
|
91
|
-
this.addEventListener("sp-opened", this.handleSubmenuOpened);
|
|
92
|
-
this.addEventListener("sp-closed", this.handleSubmenuClosed);
|
|
93
58
|
}
|
|
94
59
|
static get styles() {
|
|
95
60
|
return [menuStyles];
|
|
96
61
|
}
|
|
97
|
-
get isSubmenu() {
|
|
98
|
-
return this.slot === "submenu";
|
|
99
|
-
}
|
|
100
62
|
get childItems() {
|
|
101
63
|
if (!this.cachedChildItems) {
|
|
102
64
|
this.cachedChildItems = this.updateCachedMenuItems();
|
|
@@ -105,7 +67,7 @@ export class Menu extends SpectrumElement {
|
|
|
105
67
|
}
|
|
106
68
|
updateCachedMenuItems() {
|
|
107
69
|
this.cachedChildItems = [];
|
|
108
|
-
const slotElements = this.menuSlot.assignedElements({ flatten: true });
|
|
70
|
+
const slotElements = this.menuSlot ? this.menuSlot.assignedElements({ flatten: true }) : [];
|
|
109
71
|
for (const slotElement of slotElements) {
|
|
110
72
|
const childMenuItems = slotElement instanceof MenuItem ? [slotElement] : [...slotElement.querySelectorAll(`*`)];
|
|
111
73
|
for (const childMenuItem of childMenuItems) {
|
|
@@ -141,37 +103,17 @@ export class Menu extends SpectrumElement {
|
|
|
141
103
|
}
|
|
142
104
|
/**
|
|
143
105
|
* When a descendant `<sp-menu-item>` element is added or updated it will dispatch
|
|
144
|
-
* this event to announce its presence in the DOM. During the
|
|
106
|
+
* this event to announce its presence in the DOM. During the capture phase the first
|
|
145
107
|
* Menu based element that the event encounters will manage the focus state of the
|
|
146
108
|
* dispatching `<sp-menu-item>` element.
|
|
147
109
|
* @param event
|
|
148
110
|
*/
|
|
149
111
|
onFocusableItemAddedOrUpdated(event) {
|
|
150
|
-
event.menuCascade.set(this, {
|
|
151
|
-
hadFocusRoot: !!event.item.menuData.focusRoot,
|
|
152
|
-
ancestorWithSelects: event.currentAncestorWithSelects
|
|
153
|
-
});
|
|
154
|
-
if (this.selects) {
|
|
155
|
-
event.currentAncestorWithSelects = this;
|
|
156
|
-
}
|
|
157
|
-
event.item.menuData.focusRoot = event.item.menuData.focusRoot || this;
|
|
158
|
-
}
|
|
159
|
-
/**
|
|
160
|
-
* When a descendant `<sp-menu-item>` element is added or updated it will dispatch
|
|
161
|
-
* this event to announce its presence in the DOM. During the BUBBLE phase the first
|
|
162
|
-
* Menu based element that the event encounters that does not inherit selection will
|
|
163
|
-
* manage the selection state of the dispatching `<sp-menu-item>` element.
|
|
164
|
-
* @param event
|
|
165
|
-
*/
|
|
166
|
-
onSelectableItemAddedOrUpdated(event) {
|
|
167
112
|
var _a, _b;
|
|
168
|
-
|
|
169
|
-
if (!cascadeData)
|
|
170
|
-
return;
|
|
171
|
-
event.item.menuData.parentMenu = event.item.menuData.parentMenu || this;
|
|
172
|
-
if (cascadeData.hadFocusRoot && !this.ignore) {
|
|
113
|
+
if (event.item.menuData.focusRoot && !this.ignore) {
|
|
173
114
|
this.tabIndex = -1;
|
|
174
115
|
}
|
|
116
|
+
event.focusRoot = this;
|
|
175
117
|
this.addChildItem(event.item);
|
|
176
118
|
if (this.selects === "inherit") {
|
|
177
119
|
this.resolvedSelects = "inherit";
|
|
@@ -180,33 +122,34 @@ export class Menu extends SpectrumElement {
|
|
|
180
122
|
} else if (this.selects) {
|
|
181
123
|
this.resolvedRole = this.ignore ? "none" : this.getAttribute("role") || void 0;
|
|
182
124
|
this.resolvedSelects = this.selects;
|
|
125
|
+
event.currentAncestorWithSelects = this;
|
|
183
126
|
} else {
|
|
184
127
|
this.resolvedRole = this.ignore ? "none" : this.getAttribute("role") || void 0;
|
|
185
128
|
this.resolvedSelects = this.resolvedRole === "none" ? "ignore" : "none";
|
|
186
129
|
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* When a descendant `<sp-menu-item>` element is added or updated it will dispatch
|
|
133
|
+
* this event to announce its presence in the DOM. During the bubble phase the first
|
|
134
|
+
* Menu based element that the event encounters that does not inherit selection will
|
|
135
|
+
* manage the selection state of the dispatching `<sp-menu-item>` element.
|
|
136
|
+
* @param event
|
|
137
|
+
*/
|
|
138
|
+
onSelectableItemAddedOrUpdated(event) {
|
|
187
139
|
const selects = this.resolvedSelects === "single" || this.resolvedSelects === "multiple";
|
|
188
|
-
event.item.menuData.cleanupSteps.push(
|
|
189
|
-
(item) => this.removeChildItem(item)
|
|
190
|
-
);
|
|
191
140
|
if ((selects || !this.selects && this.resolvedSelects !== "ignore") && !event.item.menuData.selectionRoot) {
|
|
192
141
|
event.item.setRole(this.childRole);
|
|
193
|
-
event.
|
|
194
|
-
if (event.item.selected) {
|
|
195
|
-
this.selectedItemsMap.set(event.item, true);
|
|
196
|
-
this.selectedItems = [...this.selectedItems, event.item];
|
|
197
|
-
this.selected = [...this.selected, event.item.value];
|
|
198
|
-
this.value = this.selected.join(this.valueSeparator);
|
|
199
|
-
}
|
|
142
|
+
event.selectionRoot = this;
|
|
200
143
|
}
|
|
201
144
|
}
|
|
202
145
|
addChildItem(item) {
|
|
203
146
|
this.childItemSet.add(item);
|
|
204
147
|
this.handleItemsChanged();
|
|
205
148
|
}
|
|
206
|
-
async removeChildItem(
|
|
207
|
-
this.childItemSet.delete(item);
|
|
149
|
+
async removeChildItem(event) {
|
|
150
|
+
this.childItemSet.delete(event.item);
|
|
208
151
|
this.cachedChildItems = void 0;
|
|
209
|
-
if (item.focused) {
|
|
152
|
+
if (event.item.focused) {
|
|
210
153
|
this.handleItemsChanged();
|
|
211
154
|
await this.updateComplete;
|
|
212
155
|
this.focus();
|
|
@@ -224,12 +167,12 @@ export class Menu extends SpectrumElement {
|
|
|
224
167
|
}
|
|
225
168
|
this.focusMenuItemByOffset(0);
|
|
226
169
|
super.focus({ preventScroll });
|
|
227
|
-
const selectedItem = this.
|
|
170
|
+
const selectedItem = this.querySelector("[selected]");
|
|
228
171
|
if (selectedItem && !preventScroll) {
|
|
229
172
|
selectedItem.scrollIntoView({ block: "nearest" });
|
|
230
173
|
}
|
|
231
174
|
}
|
|
232
|
-
|
|
175
|
+
onClick(event) {
|
|
233
176
|
if (event.defaultPrevented) {
|
|
234
177
|
return;
|
|
235
178
|
}
|
|
@@ -261,18 +204,18 @@ export class Menu extends SpectrumElement {
|
|
|
261
204
|
}
|
|
262
205
|
handleFocusin(event) {
|
|
263
206
|
var _a;
|
|
264
|
-
const
|
|
207
|
+
const isOrContainsRelatedTarget = elementIsOrContains(
|
|
265
208
|
this,
|
|
266
209
|
event.relatedTarget
|
|
267
210
|
);
|
|
268
|
-
if (this.childItems.some(
|
|
211
|
+
if (isOrContainsRelatedTarget || this.childItems.some(
|
|
269
212
|
(childItem) => childItem.menuData.focusRoot !== this
|
|
270
213
|
)) {
|
|
271
214
|
return;
|
|
272
215
|
}
|
|
273
216
|
const activeElement = this.getRootNode().activeElement;
|
|
274
217
|
const selectionRoot = ((_a = this.childItems[this.focusedItemIndex]) == null ? void 0 : _a.menuData.selectionRoot) || this;
|
|
275
|
-
if (activeElement !== selectionRoot || !
|
|
218
|
+
if (activeElement !== selectionRoot || !isOrContainsRelatedTarget) {
|
|
276
219
|
selectionRoot.focus({ preventScroll: true });
|
|
277
220
|
if (activeElement && this.focusedItemIndex === 0) {
|
|
278
221
|
const offset = this.childItems.findIndex(
|
|
@@ -287,32 +230,27 @@ export class Menu extends SpectrumElement {
|
|
|
287
230
|
}
|
|
288
231
|
startListeningToKeyboard() {
|
|
289
232
|
this.addEventListener("keydown", this.handleKeydown);
|
|
233
|
+
this.addEventListener("focusout", this.handleFocusout);
|
|
290
234
|
}
|
|
291
235
|
handleFocusout(event) {
|
|
292
236
|
if (elementIsOrContains(this, event.relatedTarget)) {
|
|
237
|
+
event.composedPath()[0].focused = false;
|
|
293
238
|
return;
|
|
294
239
|
}
|
|
295
240
|
this.stopListeningToKeyboard();
|
|
296
|
-
this.childItems.
|
|
241
|
+
if (event.target === this && this.childItems.some(
|
|
242
|
+
(childItem) => childItem.menuData.focusRoot === this
|
|
243
|
+
)) {
|
|
244
|
+
const focusedItem = this.childItems[this.focusedItemIndex];
|
|
245
|
+
if (focusedItem) {
|
|
246
|
+
focusedItem.focused = false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
297
249
|
this.removeAttribute("aria-activedescendant");
|
|
298
250
|
}
|
|
299
251
|
stopListeningToKeyboard() {
|
|
300
252
|
this.removeEventListener("keydown", this.handleKeydown);
|
|
301
|
-
|
|
302
|
-
handleDescendentOverlayOpened(event) {
|
|
303
|
-
const target = event.composedPath()[0];
|
|
304
|
-
if (!target.overlayElement)
|
|
305
|
-
return;
|
|
306
|
-
this.descendentOverlays.set(
|
|
307
|
-
target.overlayElement,
|
|
308
|
-
target.overlayElement
|
|
309
|
-
);
|
|
310
|
-
}
|
|
311
|
-
handleDescendentOverlayClosed(event) {
|
|
312
|
-
const target = event.composedPath()[0];
|
|
313
|
-
if (!target.overlayElement)
|
|
314
|
-
return;
|
|
315
|
-
this.descendentOverlays.delete(target.overlayElement);
|
|
253
|
+
this.removeEventListener("focusout", this.handleFocusout);
|
|
316
254
|
}
|
|
317
255
|
async selectOrToggleItem(targetItem) {
|
|
318
256
|
const resolvedSelects = this.resolvedSelects;
|
|
@@ -321,7 +259,6 @@ export class Menu extends SpectrumElement {
|
|
|
321
259
|
const oldSelectedItems = this.selectedItems.slice();
|
|
322
260
|
const oldValue = this.value;
|
|
323
261
|
this.childItems[this.focusedItemIndex].focused = false;
|
|
324
|
-
this.childItems[this.focusedItemIndex].active = false;
|
|
325
262
|
this.focusedItemIndex = this.childItems.indexOf(targetItem);
|
|
326
263
|
this.forwardFocusVisibleToItem(targetItem);
|
|
327
264
|
if (resolvedSelects === "multiple") {
|
|
@@ -385,31 +322,23 @@ export class Menu extends SpectrumElement {
|
|
|
385
322
|
return;
|
|
386
323
|
}
|
|
387
324
|
event.preventDefault();
|
|
388
|
-
event.stopPropagation();
|
|
389
325
|
itemToFocus.scrollIntoView({ block: "nearest" });
|
|
390
326
|
}
|
|
391
|
-
navigateBetweenRelatedMenus(
|
|
392
|
-
const { code } = event;
|
|
327
|
+
navigateBetweenRelatedMenus(code) {
|
|
393
328
|
const shouldOpenSubmenu = this.isLTR && code === "ArrowRight" || !this.isLTR && code === "ArrowLeft";
|
|
394
329
|
const shouldCloseSelfAsSubmenu = this.isLTR && code === "ArrowLeft" || !this.isLTR && code === "ArrowRight";
|
|
395
330
|
if (shouldOpenSubmenu) {
|
|
396
|
-
event.stopPropagation();
|
|
397
331
|
const lastFocusedItem = this.childItems[this.focusedItemIndex];
|
|
398
332
|
if (lastFocusedItem == null ? void 0 : lastFocusedItem.hasSubmenu) {
|
|
333
|
+
this.blur();
|
|
399
334
|
lastFocusedItem.openOverlay();
|
|
400
335
|
}
|
|
401
336
|
} else if (shouldCloseSelfAsSubmenu && this.isSubmenu) {
|
|
402
|
-
event.stopPropagation();
|
|
403
337
|
this.dispatchEvent(new Event("close", { bubbles: true }));
|
|
404
|
-
this.updateSelectedItemIndex();
|
|
405
338
|
}
|
|
406
339
|
}
|
|
407
340
|
handleKeydown(event) {
|
|
408
341
|
var _a;
|
|
409
|
-
const isNotThisOrDirectChild = event.target !== this && this !== event.target.parentElement;
|
|
410
|
-
if (isNotThisOrDirectChild || event.defaultPrevented) {
|
|
411
|
-
return;
|
|
412
|
-
}
|
|
413
342
|
const { code } = event;
|
|
414
343
|
if (code === "Tab") {
|
|
415
344
|
this.prepareToCleanUp();
|
|
@@ -418,6 +347,7 @@ export class Menu extends SpectrumElement {
|
|
|
418
347
|
if (code === "Space") {
|
|
419
348
|
const lastFocusedItem = this.childItems[this.focusedItemIndex];
|
|
420
349
|
if (lastFocusedItem == null ? void 0 : lastFocusedItem.hasSubmenu) {
|
|
350
|
+
this.blur();
|
|
421
351
|
lastFocusedItem.openOverlay();
|
|
422
352
|
return;
|
|
423
353
|
}
|
|
@@ -430,15 +360,12 @@ export class Menu extends SpectrumElement {
|
|
|
430
360
|
this.navigateWithinMenu(event);
|
|
431
361
|
return;
|
|
432
362
|
}
|
|
433
|
-
this.navigateBetweenRelatedMenus(
|
|
363
|
+
this.navigateBetweenRelatedMenus(code);
|
|
434
364
|
}
|
|
435
365
|
focusMenuItemByOffset(offset) {
|
|
436
366
|
const step = offset || 1;
|
|
437
367
|
const focusedItem = this.childItems[this.focusedItemIndex];
|
|
438
|
-
|
|
439
|
-
focusedItem.focused = false;
|
|
440
|
-
focusedItem.active = focusedItem.open;
|
|
441
|
-
}
|
|
368
|
+
focusedItem.focused = false;
|
|
442
369
|
this.focusedItemIndex = (this.childItems.length + this.focusedItemIndex + offset) % this.childItems.length;
|
|
443
370
|
let itemToFocus = this.childItems[this.focusedItemIndex];
|
|
444
371
|
let availableItems = this.childItems.length;
|
|
@@ -477,7 +404,7 @@ export class Menu extends SpectrumElement {
|
|
|
477
404
|
itemIndex -= 1;
|
|
478
405
|
const childItem = this.childItems[itemIndex];
|
|
479
406
|
if (childItem.menuData.selectionRoot === this) {
|
|
480
|
-
if (childItem.selected
|
|
407
|
+
if (childItem.selected) {
|
|
481
408
|
firstOrFirstSelectedIndex = itemIndex;
|
|
482
409
|
selectedItemsMap.set(childItem, true);
|
|
483
410
|
selected.unshift(childItem.value);
|
|
@@ -503,17 +430,20 @@ export class Menu extends SpectrumElement {
|
|
|
503
430
|
handleItemsChanged() {
|
|
504
431
|
this.cachedChildItems = void 0;
|
|
505
432
|
if (!this._willUpdateItems) {
|
|
433
|
+
let resolve = () => {
|
|
434
|
+
return;
|
|
435
|
+
};
|
|
436
|
+
this.cacheUpdated = new Promise((res) => resolve = res);
|
|
506
437
|
this._willUpdateItems = true;
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
438
|
+
window.requestAnimationFrame(() => {
|
|
439
|
+
if (this.cachedChildItems === void 0) {
|
|
440
|
+
this.updateSelectedItemIndex();
|
|
441
|
+
this.updateItemFocus();
|
|
442
|
+
}
|
|
443
|
+
this._willUpdateItems = false;
|
|
444
|
+
resolve();
|
|
445
|
+
});
|
|
515
446
|
}
|
|
516
|
-
this._willUpdateItems = false;
|
|
517
447
|
}
|
|
518
448
|
updateItemFocus() {
|
|
519
449
|
if (this.childItems.length == 0) {
|
|
@@ -524,52 +454,21 @@ export class Menu extends SpectrumElement {
|
|
|
524
454
|
this.forwardFocusVisibleToItem(focusInItem);
|
|
525
455
|
}
|
|
526
456
|
}
|
|
527
|
-
closeDescendentOverlays() {
|
|
528
|
-
this.descendentOverlays.forEach((overlay) => {
|
|
529
|
-
overlay.open = false;
|
|
530
|
-
});
|
|
531
|
-
this.descendentOverlays = /* @__PURE__ */ new Map();
|
|
532
|
-
}
|
|
533
457
|
forwardFocusVisibleToItem(item) {
|
|
534
458
|
if (item.menuData.focusRoot !== this) {
|
|
535
459
|
return;
|
|
536
460
|
}
|
|
537
|
-
this.
|
|
538
|
-
const focused = this.hasVisibleFocusInTree() || !!this.childItems.find((child) => {
|
|
539
|
-
return child.hasVisibleFocusInTree();
|
|
540
|
-
});
|
|
541
|
-
item.focused = focused;
|
|
461
|
+
item.focused = this.hasVisibleFocusInTree();
|
|
542
462
|
this.setAttribute("aria-activedescendant", item.id);
|
|
543
463
|
if (item.menuData.selectionRoot && item.menuData.selectionRoot !== this) {
|
|
544
464
|
item.menuData.selectionRoot.focus();
|
|
545
465
|
}
|
|
546
466
|
}
|
|
547
|
-
|
|
548
|
-
target
|
|
549
|
-
}) {
|
|
550
|
-
const assignedElement = target.assignedElements({
|
|
551
|
-
flatten: true
|
|
552
|
-
});
|
|
553
|
-
if (this.childItems.length !== assignedElement.length) {
|
|
554
|
-
assignedElement.forEach((item) => {
|
|
555
|
-
if (typeof item.triggerUpdate !== "undefined") {
|
|
556
|
-
item.triggerUpdate();
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
renderMenuItemSlot() {
|
|
467
|
+
render() {
|
|
562
468
|
return html`
|
|
563
|
-
<slot
|
|
564
|
-
@sp-menu-submenu-opened=${this.handleDescendentOverlayOpened}
|
|
565
|
-
@sp-menu-submenu-closed=${this.handleDescendentOverlayClosed}
|
|
566
|
-
@slotchange=${this.handleSlotchange}
|
|
567
|
-
></slot>
|
|
469
|
+
<slot></slot>
|
|
568
470
|
`;
|
|
569
471
|
}
|
|
570
|
-
render() {
|
|
571
|
-
return this.renderMenuItemSlot();
|
|
572
|
-
}
|
|
573
472
|
firstUpdated(changed) {
|
|
574
473
|
super.firstUpdated(changed);
|
|
575
474
|
if (!this.hasAttribute("tabindex") && !this.ignore) {
|
|
@@ -592,16 +491,17 @@ export class Menu extends SpectrumElement {
|
|
|
592
491
|
}
|
|
593
492
|
updated(changes) {
|
|
594
493
|
super.updated(changes);
|
|
595
|
-
if (changes.has("selects") && this.
|
|
494
|
+
if (changes.has("selects") && this._notFirstUpdated) {
|
|
596
495
|
this.selectsChanged();
|
|
597
496
|
}
|
|
598
|
-
if (changes.has("label")
|
|
497
|
+
if (changes.has("label")) {
|
|
599
498
|
if (this.label) {
|
|
600
499
|
this.setAttribute("aria-label", this.label);
|
|
601
500
|
} else {
|
|
602
501
|
this.removeAttribute("aria-label");
|
|
603
502
|
}
|
|
604
503
|
}
|
|
504
|
+
this._notFirstUpdated = true;
|
|
605
505
|
}
|
|
606
506
|
selectsChanged() {
|
|
607
507
|
const updates = [
|