@spectrum-web-components/picker 0.36.0 → 0.37.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 +319 -265
- package/package.json +13 -13
- package/src/Picker.d.ts +37 -43
- package/src/Picker.dev.js +239 -218
- package/src/Picker.dev.js.map +3 -3
- package/src/Picker.js +69 -54
- package/src/Picker.js.map +3 -3
- package/src/picker.css.dev.js +1 -1
- package/src/picker.css.dev.js.map +1 -1
- package/src/picker.css.js +1 -1
- package/src/picker.css.js.map +1 -1
- package/stories/picker-sizes.stories.js +0 -1
- package/stories/picker-sizes.stories.js.map +2 -2
- package/stories/picker.stories.js +0 -7
- package/stories/picker.stories.js.map +2 -2
- package/sync/index.d.ts +3 -1
- package/sync/index.dev.js +3 -7
- package/sync/index.dev.js.map +2 -2
- package/sync/index.js +1 -1
- package/sync/index.js.map +3 -3
- package/test/index.js +247 -161
- package/test/index.js.map +2 -2
- package/test/picker-reparenting.test.js +13 -17
- package/test/picker-reparenting.test.js.map +2 -2
- package/test/picker-responsive.test.js +3 -2
- package/test/picker-responsive.test.js.map +2 -2
- package/test/picker.test.js +1 -1
- package/test/picker.test.js.map +2 -2
package/src/Picker.dev.js
CHANGED
|
@@ -13,12 +13,12 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
13
13
|
import {
|
|
14
14
|
html,
|
|
15
15
|
nothing,
|
|
16
|
-
render,
|
|
17
16
|
SizedMixin
|
|
18
17
|
} from "@spectrum-web-components/base";
|
|
19
18
|
import {
|
|
20
19
|
classMap,
|
|
21
|
-
ifDefined
|
|
20
|
+
ifDefined,
|
|
21
|
+
styleMap
|
|
22
22
|
} from "@spectrum-web-components/base/src/directives.js";
|
|
23
23
|
import {
|
|
24
24
|
property,
|
|
@@ -28,15 +28,9 @@ import {
|
|
|
28
28
|
import pickerStyles from "./picker.css.js";
|
|
29
29
|
import chevronStyles from "@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js";
|
|
30
30
|
import { Focusable } from "@spectrum-web-components/shared/src/focusable.js";
|
|
31
|
-
import { reparentChildren } from "@spectrum-web-components/shared/src/reparent-children.js";
|
|
32
31
|
import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js";
|
|
33
32
|
import "@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js";
|
|
34
33
|
import "@spectrum-web-components/menu/sp-menu.js";
|
|
35
|
-
import "@spectrum-web-components/tray/sp-tray.js";
|
|
36
|
-
import "@spectrum-web-components/popover/sp-popover.js";
|
|
37
|
-
import {
|
|
38
|
-
openOverlay
|
|
39
|
-
} from "@spectrum-web-components/overlay";
|
|
40
34
|
import {
|
|
41
35
|
IS_MOBILE,
|
|
42
36
|
MatchMediaController
|
|
@@ -49,21 +43,22 @@ const chevronClass = {
|
|
|
49
43
|
};
|
|
50
44
|
export class PickerBase extends SizedMixin(Focusable) {
|
|
51
45
|
constructor() {
|
|
52
|
-
super();
|
|
46
|
+
super(...arguments);
|
|
53
47
|
this.isMobile = new MatchMediaController(this, IS_MOBILE);
|
|
48
|
+
this.deprecatedMenu = null;
|
|
54
49
|
this.disabled = false;
|
|
55
50
|
this.focused = false;
|
|
56
51
|
this.invalid = false;
|
|
57
52
|
this.open = false;
|
|
58
53
|
this.readonly = false;
|
|
59
54
|
this.selects = "single";
|
|
60
|
-
this.menuItems = [];
|
|
61
55
|
this.placement = "bottom-start";
|
|
62
56
|
this.quiet = false;
|
|
63
57
|
this.value = "";
|
|
64
58
|
this.listRole = "listbox";
|
|
65
59
|
this.itemRole = "option";
|
|
66
|
-
this.
|
|
60
|
+
this.preventNextToggle = "no";
|
|
61
|
+
this.handleKeydown = (event) => {
|
|
67
62
|
this.focused = true;
|
|
68
63
|
if (event.code !== "ArrowDown" && event.code !== "ArrowUp") {
|
|
69
64
|
return;
|
|
@@ -71,31 +66,49 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
71
66
|
event.preventDefault();
|
|
72
67
|
this.toggle(true);
|
|
73
68
|
};
|
|
74
|
-
this.overlayOpenCallback = async () => {
|
|
75
|
-
this.updateMenuItems();
|
|
76
|
-
await this.itemsUpdated;
|
|
77
|
-
await this.optionsMenu.updateComplete;
|
|
78
|
-
requestAnimationFrame(() => this.menuStateResolver());
|
|
79
|
-
};
|
|
80
|
-
this.overlayCloseCallback = async () => {
|
|
81
|
-
if (this.restoreChildren) {
|
|
82
|
-
this.restoreChildren();
|
|
83
|
-
this.restoreChildren = void 0;
|
|
84
|
-
}
|
|
85
|
-
this.close();
|
|
86
|
-
requestAnimationFrame(() => this.menuStateResolver());
|
|
87
|
-
};
|
|
88
69
|
this.applyFocusElementLabel = (value) => {
|
|
89
70
|
this.appliedLabel = value;
|
|
90
71
|
};
|
|
91
|
-
this.
|
|
92
|
-
this.
|
|
93
|
-
this.menuStatePromise = Promise.resolve();
|
|
72
|
+
this.hasOpened = false;
|
|
73
|
+
this.willManageSelection = false;
|
|
94
74
|
this.selectionPromise = Promise.resolve();
|
|
95
|
-
this.
|
|
75
|
+
this.recentlyConnected = false;
|
|
76
|
+
this.enterKeydownOn = null;
|
|
77
|
+
this.handleEnterKeydown = (event) => {
|
|
78
|
+
if (event.code !== "Enter") {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (this.enterKeydownOn) {
|
|
82
|
+
event.preventDefault();
|
|
83
|
+
return;
|
|
84
|
+
} else {
|
|
85
|
+
this.addEventListener(
|
|
86
|
+
"keyup",
|
|
87
|
+
(keyupEvent) => {
|
|
88
|
+
if (keyupEvent.code !== "Enter") {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.enterKeydownOn = null;
|
|
92
|
+
},
|
|
93
|
+
{ once: true }
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
this.enterKeydownOn = this.enterKeydownOn || event.target;
|
|
97
|
+
};
|
|
96
98
|
}
|
|
97
|
-
get
|
|
98
|
-
return this.
|
|
99
|
+
get menuItems() {
|
|
100
|
+
return this.optionsMenu.childItems;
|
|
101
|
+
}
|
|
102
|
+
get selectedItem() {
|
|
103
|
+
return this._selectedItem;
|
|
104
|
+
}
|
|
105
|
+
set selectedItem(selectedItem) {
|
|
106
|
+
this.selectedItemContent = selectedItem ? selectedItem.itemChildren : void 0;
|
|
107
|
+
if (selectedItem === this.selectedItem)
|
|
108
|
+
return;
|
|
109
|
+
const oldSelectedItem = this.selectedItem;
|
|
110
|
+
this._selectedItem = selectedItem;
|
|
111
|
+
this.requestUpdate("selectedItem", oldSelectedItem);
|
|
99
112
|
}
|
|
100
113
|
get focusElement() {
|
|
101
114
|
if (this.open) {
|
|
@@ -106,14 +119,33 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
106
119
|
forceFocusVisible() {
|
|
107
120
|
this.focused = true;
|
|
108
121
|
}
|
|
109
|
-
|
|
122
|
+
handleButtonBlur() {
|
|
110
123
|
this.focused = false;
|
|
111
|
-
this.target.removeEventListener(
|
|
112
|
-
"keydown",
|
|
113
|
-
this.onKeydown
|
|
114
|
-
);
|
|
115
124
|
}
|
|
116
|
-
|
|
125
|
+
handlebuttonPointerdown() {
|
|
126
|
+
this.preventNextToggle = "maybe";
|
|
127
|
+
const cleanup = () => {
|
|
128
|
+
document.removeEventListener("pointerup", cleanup);
|
|
129
|
+
document.removeEventListener("pointercancel", cleanup);
|
|
130
|
+
requestAnimationFrame(() => {
|
|
131
|
+
this.preventNextToggle = "no";
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
document.addEventListener("pointerup", cleanup);
|
|
135
|
+
document.addEventListener("pointercancel", cleanup);
|
|
136
|
+
}
|
|
137
|
+
handleButtonFocus(event) {
|
|
138
|
+
if (this.preventNextToggle === "maybe" && event.relatedTarget === this.optionsMenu) {
|
|
139
|
+
this.preventNextToggle = "yes";
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
handleButtonClick() {
|
|
143
|
+
if (this.enterKeydownOn && this.enterKeydownOn !== this.button) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (this.preventNextToggle === "yes") {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
117
149
|
this.toggle();
|
|
118
150
|
}
|
|
119
151
|
focus(options) {
|
|
@@ -122,41 +154,36 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
122
154
|
this.focused = this.hasVisibleFocusInTree();
|
|
123
155
|
}
|
|
124
156
|
}
|
|
125
|
-
|
|
157
|
+
handleHelperFocus() {
|
|
126
158
|
this.focused = true;
|
|
127
159
|
this.button.focus();
|
|
128
160
|
}
|
|
129
|
-
onButtonFocus() {
|
|
130
|
-
this.target.addEventListener(
|
|
131
|
-
"keydown",
|
|
132
|
-
this.onKeydown
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
161
|
handleChange(event) {
|
|
136
162
|
const target = event.target;
|
|
137
163
|
const [selected] = target.selectedItems;
|
|
164
|
+
event.stopPropagation();
|
|
138
165
|
if (event.cancelable) {
|
|
139
|
-
event.stopPropagation();
|
|
140
166
|
this.setValueFromItem(selected, event);
|
|
141
167
|
} else {
|
|
142
168
|
this.open = false;
|
|
143
169
|
}
|
|
144
170
|
}
|
|
145
171
|
async setValueFromItem(item, menuChangeEvent) {
|
|
172
|
+
this.open = false;
|
|
146
173
|
const oldSelectedItem = this.selectedItem;
|
|
147
174
|
const oldValue = this.value;
|
|
148
175
|
this.selectedItem = item;
|
|
149
176
|
this.value = item.value;
|
|
150
|
-
this.open = false;
|
|
151
177
|
await this.updateComplete;
|
|
152
178
|
const applyDefault = this.dispatchEvent(
|
|
153
179
|
new Event("change", {
|
|
154
180
|
bubbles: true,
|
|
181
|
+
// Allow it to be prevented.
|
|
155
182
|
cancelable: true,
|
|
156
183
|
composed: true
|
|
157
184
|
})
|
|
158
185
|
);
|
|
159
|
-
if (!applyDefault) {
|
|
186
|
+
if (!applyDefault && this.selects) {
|
|
160
187
|
if (menuChangeEvent) {
|
|
161
188
|
menuChangeEvent.preventDefault();
|
|
162
189
|
}
|
|
@@ -168,6 +195,10 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
168
195
|
this.value = oldValue;
|
|
169
196
|
this.open = true;
|
|
170
197
|
return;
|
|
198
|
+
} else if (!this.selects) {
|
|
199
|
+
this.selectedItem = oldSelectedItem;
|
|
200
|
+
this.value = oldValue;
|
|
201
|
+
return;
|
|
171
202
|
}
|
|
172
203
|
if (oldSelectedItem) {
|
|
173
204
|
this.setMenuItemSelected(oldSelectedItem, false);
|
|
@@ -191,74 +222,23 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
191
222
|
}
|
|
192
223
|
this.open = false;
|
|
193
224
|
}
|
|
194
|
-
|
|
195
|
-
if (!this.popoverFragment) {
|
|
196
|
-
this.popoverFragment = document.createDocumentFragment();
|
|
197
|
-
}
|
|
198
|
-
render(this.renderPopover, this.popoverFragment, { host: this });
|
|
199
|
-
this.popoverEl = this.popoverFragment.children[0];
|
|
200
|
-
this.optionsMenu = this.popoverEl.children[1];
|
|
201
|
-
}
|
|
202
|
-
async openMenu() {
|
|
203
|
-
let reparentableChildren = [];
|
|
204
|
-
const deprecatedMenu = this.querySelector(":scope > sp-menu");
|
|
205
|
-
await this.generatePopover();
|
|
206
|
-
if (deprecatedMenu) {
|
|
207
|
-
reparentableChildren = Array.from(deprecatedMenu.children);
|
|
208
|
-
} else {
|
|
209
|
-
reparentableChildren = Array.from(this.children).filter(
|
|
210
|
-
(element) => {
|
|
211
|
-
return !element.hasAttribute("slot");
|
|
212
|
-
}
|
|
213
|
-
);
|
|
214
|
-
}
|
|
215
|
-
if (reparentableChildren.length === 0) {
|
|
216
|
-
this.menuStateResolver();
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
this.restoreChildren = reparentChildren(reparentableChildren, this.optionsMenu, {
|
|
220
|
-
position: "beforeend",
|
|
221
|
-
prepareCallback: (el) => {
|
|
222
|
-
if (this.value === el.value) {
|
|
223
|
-
this.setMenuItemSelected(el, true);
|
|
224
|
-
}
|
|
225
|
-
return (el2) => {
|
|
226
|
-
if (typeof el2.focused !== "undefined") {
|
|
227
|
-
el2.focused = false;
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
this.sizePopover(this.popoverEl);
|
|
233
|
-
if (true) {
|
|
234
|
-
window.__swc.ignoreWarningLevels.deprecation = true;
|
|
235
|
-
}
|
|
236
|
-
this.closeOverlay = Picker.openOverlay(this, "modal", this.popoverEl, {
|
|
237
|
-
placement: this.isMobile.matches ? "none" : this.placement,
|
|
238
|
-
receivesFocus: "auto"
|
|
239
|
-
});
|
|
240
|
-
if (true) {
|
|
241
|
-
window.__swc.ignoreWarningLevels.deprecation = false;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
sizePopover(popover) {
|
|
225
|
+
get containerStyles() {
|
|
245
226
|
if (this.isMobile.matches) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
async closeMenu() {
|
|
251
|
-
if (this.closeOverlay) {
|
|
252
|
-
const closeOverlay = this.closeOverlay;
|
|
253
|
-
delete this.closeOverlay;
|
|
254
|
-
(await closeOverlay)();
|
|
227
|
+
return {
|
|
228
|
+
"--swc-menu-width": "100%"
|
|
229
|
+
};
|
|
255
230
|
}
|
|
231
|
+
return {};
|
|
256
232
|
}
|
|
257
233
|
get selectedItemContent() {
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
234
|
+
return this._selectedItemContent || { icon: [], content: [] };
|
|
235
|
+
}
|
|
236
|
+
set selectedItemContent(selectedItemContent) {
|
|
237
|
+
if (selectedItemContent === this.selectedItemContent)
|
|
238
|
+
return;
|
|
239
|
+
const oldContent = this.selectedItemContent;
|
|
240
|
+
this._selectedItemContent = selectedItemContent;
|
|
241
|
+
this.requestUpdate("selectedItemContent", oldContent);
|
|
262
242
|
}
|
|
263
243
|
renderLabelContent(content) {
|
|
264
244
|
if (this.value && this.selectedItem) {
|
|
@@ -284,7 +264,6 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
284
264
|
const appliedLabel = this.appliedLabel || this.label;
|
|
285
265
|
return [
|
|
286
266
|
html`
|
|
287
|
-
</span>
|
|
288
267
|
<span id="icon" ?hidden=${this.icons === "none"}>
|
|
289
268
|
${this.selectedItemContent.icon}
|
|
290
269
|
</span>
|
|
@@ -292,38 +271,63 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
292
271
|
${this.renderLabelContent(this.selectedItemContent.content)}
|
|
293
272
|
</span>
|
|
294
273
|
${this.value && this.selectedItem ? html`
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
</span>
|
|
307
|
-
`}
|
|
274
|
+
<span
|
|
275
|
+
aria-hidden="true"
|
|
276
|
+
class="visually-hidden"
|
|
277
|
+
id="applied-label"
|
|
278
|
+
>
|
|
279
|
+
${appliedLabel}
|
|
280
|
+
<slot name="label"></slot>
|
|
281
|
+
</span>
|
|
282
|
+
` : html`
|
|
283
|
+
<span hidden id="applied-label">${appliedLabel}</span>
|
|
284
|
+
`}
|
|
308
285
|
${this.invalid ? html`
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
286
|
+
<sp-icon-alert
|
|
287
|
+
class="validation-icon"
|
|
288
|
+
></sp-icon-alert>
|
|
289
|
+
` : nothing}
|
|
313
290
|
<sp-icon-chevron100
|
|
314
291
|
class="picker ${chevronClass[this.size]}"
|
|
315
292
|
></sp-icon-chevron100>
|
|
316
293
|
`
|
|
317
294
|
];
|
|
318
295
|
}
|
|
296
|
+
renderOverlay(menu) {
|
|
297
|
+
import("@spectrum-web-components/overlay/sp-overlay.js");
|
|
298
|
+
return html`
|
|
299
|
+
<sp-overlay
|
|
300
|
+
.triggerElement=${this}
|
|
301
|
+
.offset=${0}
|
|
302
|
+
?open=${this.open}
|
|
303
|
+
.placement=${this.placement}
|
|
304
|
+
type="auto"
|
|
305
|
+
.receivesFocus=${"true"}
|
|
306
|
+
@beforetoggle=${(event) => {
|
|
307
|
+
if (event.composedPath()[0] !== event.target) {
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (event.newState === "closed") {
|
|
311
|
+
this.open = false;
|
|
312
|
+
}
|
|
313
|
+
if (!this.open) {
|
|
314
|
+
this.optionsMenu.updateSelectedItemIndex();
|
|
315
|
+
this.optionsMenu.closeDescendentOverlays();
|
|
316
|
+
}
|
|
317
|
+
}}
|
|
318
|
+
>
|
|
319
|
+
${this.renderContainer(menu)}
|
|
320
|
+
</sp-overlay>
|
|
321
|
+
`;
|
|
322
|
+
}
|
|
319
323
|
// a helper to throw focus to the button is needed because Safari
|
|
320
324
|
// won't include buttons in the tab order even with tabindex="0"
|
|
321
325
|
render() {
|
|
322
326
|
return html`
|
|
323
327
|
<span
|
|
324
328
|
id="focus-helper"
|
|
325
|
-
tabindex="${this.focused ? "-1" : "0"}"
|
|
326
|
-
@focus=${this.
|
|
329
|
+
tabindex="${this.focused || this.open ? "-1" : "0"}"
|
|
330
|
+
@focus=${this.handleHelperFocus}
|
|
327
331
|
></span>
|
|
328
332
|
<button
|
|
329
333
|
aria-haspopup="true"
|
|
@@ -332,38 +336,40 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
332
336
|
aria-labelledby="icon label applied-label"
|
|
333
337
|
id="button"
|
|
334
338
|
class="button"
|
|
335
|
-
@blur=${this.
|
|
336
|
-
@
|
|
337
|
-
@focus=${this.
|
|
339
|
+
@blur=${this.handleButtonBlur}
|
|
340
|
+
@pointerdown=${this.handlebuttonPointerdown}
|
|
341
|
+
@focus=${this.handleButtonFocus}
|
|
342
|
+
@click=${this.handleButtonClick}
|
|
343
|
+
@keydown=${{
|
|
344
|
+
handleEvent: this.handleEnterKeydown,
|
|
345
|
+
capture: true
|
|
346
|
+
}}
|
|
338
347
|
?disabled=${this.disabled}
|
|
339
348
|
tabindex="-1"
|
|
340
349
|
>
|
|
341
350
|
${this.buttonContent}
|
|
342
351
|
</button>
|
|
352
|
+
${this.renderMenu}
|
|
343
353
|
`;
|
|
344
354
|
}
|
|
345
355
|
update(changes) {
|
|
356
|
+
var _a, _b;
|
|
346
357
|
if (this.selects) {
|
|
347
358
|
this.selects = "single";
|
|
348
359
|
}
|
|
349
360
|
if (changes.has("disabled") && this.disabled) {
|
|
350
361
|
this.open = false;
|
|
351
362
|
}
|
|
352
|
-
if (changes.has("
|
|
353
|
-
this.
|
|
354
|
-
(res) => this.menuStateResolver = res
|
|
355
|
-
);
|
|
356
|
-
if (this.open) {
|
|
357
|
-
this.openMenu();
|
|
358
|
-
} else {
|
|
359
|
-
this.closeMenu();
|
|
360
|
-
}
|
|
363
|
+
if (changes.has("value")) {
|
|
364
|
+
this.shouldScheduleManageSelection();
|
|
361
365
|
}
|
|
362
|
-
if (
|
|
363
|
-
this.
|
|
366
|
+
if (!this.hasUpdated) {
|
|
367
|
+
this.deprecatedMenu = this.querySelector(":scope > sp-menu");
|
|
368
|
+
(_a = this.deprecatedMenu) == null ? void 0 : _a.toggleAttribute("ignore", true);
|
|
369
|
+
(_b = this.deprecatedMenu) == null ? void 0 : _b.setAttribute("selects", "inherit");
|
|
364
370
|
}
|
|
365
371
|
if (true) {
|
|
366
|
-
if (!this.hasUpdated && this.querySelector("sp-menu")) {
|
|
372
|
+
if (!this.hasUpdated && this.querySelector(":scope > sp-menu")) {
|
|
367
373
|
const { localName } = this;
|
|
368
374
|
window.__swc.warn(
|
|
369
375
|
this,
|
|
@@ -375,6 +381,13 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
375
381
|
}
|
|
376
382
|
super.update(changes);
|
|
377
383
|
}
|
|
384
|
+
bindButtonKeydownListener() {
|
|
385
|
+
this.button.addEventListener("keydown", this.handleKeydown);
|
|
386
|
+
}
|
|
387
|
+
firstUpdated(changes) {
|
|
388
|
+
super.firstUpdated(changes);
|
|
389
|
+
this.bindButtonKeydownListener();
|
|
390
|
+
}
|
|
378
391
|
get dismissHelper() {
|
|
379
392
|
return html`
|
|
380
393
|
<div class="visually-hidden">
|
|
@@ -386,85 +399,88 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
386
399
|
</div>
|
|
387
400
|
`;
|
|
388
401
|
}
|
|
389
|
-
|
|
390
|
-
const
|
|
391
|
-
${this.dismissHelper}
|
|
392
|
-
<sp-menu
|
|
393
|
-
id="menu"
|
|
394
|
-
role="${this.listRole}"
|
|
395
|
-
@change=${this.handleChange}
|
|
396
|
-
.selects=${this.selects}
|
|
397
|
-
size=${this.size}
|
|
398
|
-
></sp-menu>
|
|
399
|
-
${this.dismissHelper}
|
|
402
|
+
renderContainer(menu) {
|
|
403
|
+
const accessibleMenu = html`
|
|
404
|
+
${this.dismissHelper} ${menu} ${this.dismissHelper}
|
|
400
405
|
`;
|
|
401
406
|
if (this.isMobile.matches) {
|
|
407
|
+
import("@spectrum-web-components/tray/sp-tray.js");
|
|
402
408
|
return html`
|
|
403
409
|
<sp-tray
|
|
404
410
|
id="popover"
|
|
405
411
|
role="presentation"
|
|
406
|
-
|
|
407
|
-
.overlayOpenCallback=${this.overlayOpenCallback}
|
|
408
|
-
.overlayCloseCallback=${this.overlayCloseCallback}
|
|
412
|
+
style=${styleMap(this.containerStyles)}
|
|
409
413
|
>
|
|
410
|
-
${
|
|
414
|
+
${accessibleMenu}
|
|
411
415
|
</sp-tray>
|
|
412
416
|
`;
|
|
413
417
|
}
|
|
418
|
+
import("@spectrum-web-components/popover/sp-popover.js");
|
|
414
419
|
return html`
|
|
415
420
|
<sp-popover
|
|
416
421
|
id="popover"
|
|
417
422
|
role="presentation"
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
.overlayCloseCallback=${this.overlayCloseCallback}
|
|
423
|
+
style=${styleMap(this.containerStyles)}
|
|
424
|
+
placement=${this.placement}
|
|
421
425
|
>
|
|
422
|
-
${
|
|
426
|
+
${accessibleMenu}
|
|
423
427
|
</sp-popover>
|
|
424
428
|
`;
|
|
425
429
|
}
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
430
|
+
get renderMenu() {
|
|
431
|
+
const menu = html`
|
|
432
|
+
<sp-menu
|
|
433
|
+
aria-labelledby="applied-label"
|
|
434
|
+
@change=${this.handleChange}
|
|
435
|
+
id="menu"
|
|
436
|
+
@keydown=${{
|
|
437
|
+
handleEvent: this.handleEnterKeydown,
|
|
438
|
+
capture: true
|
|
439
|
+
}}
|
|
440
|
+
role=${this.listRole}
|
|
441
|
+
.selects=${this.selects}
|
|
442
|
+
.selected=${this.value ? [this.value] : []}
|
|
443
|
+
size=${this.size}
|
|
444
|
+
@sp-menu-item-added-or-updated=${this.shouldManageSelection}
|
|
445
|
+
>
|
|
446
|
+
<slot @slotchange=${this.shouldScheduleManageSelection}></slot>
|
|
447
|
+
</sp-menu>
|
|
448
|
+
`;
|
|
449
|
+
this.hasOpened = this.hasOpened || this.open || !!this.deprecatedMenu;
|
|
450
|
+
if (this.hasOpened) {
|
|
451
|
+
return this.renderOverlay(menu);
|
|
439
452
|
}
|
|
440
|
-
|
|
453
|
+
return menu;
|
|
454
|
+
}
|
|
455
|
+
shouldScheduleManageSelection(event) {
|
|
456
|
+
if (!this.willManageSelection && (!event || event.target.getRootNode().host === this)) {
|
|
457
|
+
this.willManageSelection = true;
|
|
458
|
+
requestAnimationFrame(() => {
|
|
459
|
+
requestAnimationFrame(() => {
|
|
460
|
+
this.manageSelection();
|
|
461
|
+
});
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
shouldManageSelection() {
|
|
466
|
+
if (this.willManageSelection) {
|
|
441
467
|
return;
|
|
442
|
-
}
|
|
443
|
-
this.
|
|
444
|
-
|
|
445
|
-
if (this.open) {
|
|
446
|
-
await this.optionsMenu.updateComplete;
|
|
447
|
-
this.menuItems = this.optionsMenu.childItems;
|
|
448
|
-
} else {
|
|
449
|
-
this.menuItems = [
|
|
450
|
-
...this.querySelectorAll(
|
|
451
|
-
'sp-menu-item:not([slot="submenu"] *)'
|
|
452
|
-
)
|
|
453
|
-
];
|
|
454
|
-
}
|
|
455
|
-
this.manageSelection();
|
|
456
|
-
resolve();
|
|
457
|
-
this._willUpdateItems = false;
|
|
458
|
-
});
|
|
468
|
+
}
|
|
469
|
+
this.willManageSelection = true;
|
|
470
|
+
this.manageSelection();
|
|
459
471
|
}
|
|
460
472
|
async manageSelection() {
|
|
461
473
|
if (this.selects == null)
|
|
462
474
|
return;
|
|
463
|
-
await this.menuStatePromise;
|
|
464
475
|
this.selectionPromise = new Promise(
|
|
465
476
|
(res) => this.selectionResolver = res
|
|
466
477
|
);
|
|
467
478
|
let selectedItem;
|
|
479
|
+
await this.optionsMenu.updateComplete;
|
|
480
|
+
if (this.recentlyConnected) {
|
|
481
|
+
await new Promise((res) => requestAnimationFrame(() => res(true)));
|
|
482
|
+
this.recentlyConnected = false;
|
|
483
|
+
}
|
|
468
484
|
this.menuItems.forEach((item) => {
|
|
469
485
|
if (this.value === item.value && !item.disabled) {
|
|
470
486
|
selectedItem = item;
|
|
@@ -484,34 +500,25 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
484
500
|
this.optionsMenu.updateSelectedItemIndex();
|
|
485
501
|
}
|
|
486
502
|
this.selectionResolver();
|
|
503
|
+
this.willManageSelection = false;
|
|
487
504
|
}
|
|
488
505
|
async getUpdateComplete() {
|
|
489
506
|
const complete = await super.getUpdateComplete();
|
|
490
|
-
await this.menuStatePromise;
|
|
491
|
-
await this.itemsUpdated;
|
|
492
507
|
await this.selectionPromise;
|
|
508
|
+
if (this.overlayElement) {
|
|
509
|
+
await this.overlayElement.updateComplete;
|
|
510
|
+
}
|
|
493
511
|
return complete;
|
|
494
512
|
}
|
|
495
513
|
connectedCallback() {
|
|
496
|
-
this.updateMenuItems();
|
|
497
|
-
this.addEventListener(
|
|
498
|
-
"sp-menu-item-added-or-updated",
|
|
499
|
-
this.updateMenuItems
|
|
500
|
-
);
|
|
501
|
-
this.addEventListener("sp-menu-item-removed", this.updateMenuItems);
|
|
502
514
|
super.connectedCallback();
|
|
515
|
+
this.recentlyConnected = this.hasUpdated;
|
|
503
516
|
}
|
|
504
517
|
disconnectedCallback() {
|
|
505
518
|
this.close();
|
|
506
519
|
super.disconnectedCallback();
|
|
507
520
|
}
|
|
508
521
|
}
|
|
509
|
-
/**
|
|
510
|
-
* @private
|
|
511
|
-
*/
|
|
512
|
-
PickerBase.openOverlay = async (target, interaction, content, options) => {
|
|
513
|
-
return await openOverlay(target, interaction, content, options);
|
|
514
|
-
};
|
|
515
522
|
__decorateClass([
|
|
516
523
|
state()
|
|
517
524
|
], PickerBase.prototype, "appliedLabel", 2);
|
|
@@ -539,6 +546,12 @@ __decorateClass([
|
|
|
539
546
|
__decorateClass([
|
|
540
547
|
property({ type: Boolean, reflect: true })
|
|
541
548
|
], PickerBase.prototype, "readonly", 2);
|
|
549
|
+
__decorateClass([
|
|
550
|
+
query("sp-menu")
|
|
551
|
+
], PickerBase.prototype, "optionsMenu", 2);
|
|
552
|
+
__decorateClass([
|
|
553
|
+
query("sp-overlay")
|
|
554
|
+
], PickerBase.prototype, "overlayElement", 2);
|
|
542
555
|
__decorateClass([
|
|
543
556
|
property()
|
|
544
557
|
], PickerBase.prototype, "placement", 2);
|
|
@@ -550,13 +563,20 @@ __decorateClass([
|
|
|
550
563
|
], PickerBase.prototype, "value", 2);
|
|
551
564
|
__decorateClass([
|
|
552
565
|
property({ attribute: false })
|
|
553
|
-
], PickerBase.prototype, "selectedItem",
|
|
566
|
+
], PickerBase.prototype, "selectedItem", 1);
|
|
567
|
+
__decorateClass([
|
|
568
|
+
property({ attribute: false })
|
|
569
|
+
], PickerBase.prototype, "selectedItemContent", 1);
|
|
554
570
|
export class Picker extends PickerBase {
|
|
555
571
|
constructor() {
|
|
556
572
|
super(...arguments);
|
|
557
|
-
this.
|
|
573
|
+
this.handleKeydown = (event) => {
|
|
558
574
|
const { code } = event;
|
|
559
575
|
this.focused = true;
|
|
576
|
+
if (code === "ArrowUp" || code === "ArrowDown") {
|
|
577
|
+
this.toggle(true);
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
560
580
|
if (!code.startsWith("Arrow") || this.readonly) {
|
|
561
581
|
return;
|
|
562
582
|
}
|
|
@@ -582,11 +602,12 @@ export class Picker extends PickerBase {
|
|
|
582
602
|
static get styles() {
|
|
583
603
|
return [pickerStyles, chevronStyles];
|
|
584
604
|
}
|
|
585
|
-
|
|
586
|
-
super.
|
|
587
|
-
if (this.quiet)
|
|
588
|
-
|
|
589
|
-
|
|
605
|
+
get containerStyles() {
|
|
606
|
+
const styles = super.containerStyles;
|
|
607
|
+
if (!this.quiet) {
|
|
608
|
+
styles["min-width"] = `${this.offsetWidth}px`;
|
|
609
|
+
}
|
|
610
|
+
return styles;
|
|
590
611
|
}
|
|
591
612
|
}
|
|
592
613
|
//# sourceMappingURL=Picker.dev.js.map
|