@spectrum-web-components/picker 1.1.0 → 1.1.2

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 (93) hide show
  1. package/package.json +17 -17
  2. package/sp-picker.d.ts +6 -0
  3. package/sp-picker.dev.js +5 -0
  4. package/sp-picker.dev.js.map +7 -0
  5. package/sp-picker.js +2 -0
  6. package/sp-picker.js.map +7 -0
  7. package/src/DesktopController.d.ts +7 -0
  8. package/src/DesktopController.dev.js +72 -0
  9. package/src/DesktopController.dev.js.map +7 -0
  10. package/src/DesktopController.js +2 -0
  11. package/src/DesktopController.js.map +7 -0
  12. package/src/InteractionController.d.ts +44 -0
  13. package/src/InteractionController.dev.js +122 -0
  14. package/src/InteractionController.dev.js.map +7 -0
  15. package/src/InteractionController.js +2 -0
  16. package/src/InteractionController.js.map +7 -0
  17. package/src/MobileController.d.ts +8 -0
  18. package/src/MobileController.dev.js +51 -0
  19. package/src/MobileController.dev.js.map +7 -0
  20. package/src/MobileController.js +2 -0
  21. package/src/MobileController.js.map +7 -0
  22. package/src/Picker.d.ts +139 -0
  23. package/src/Picker.dev.js +717 -0
  24. package/src/Picker.dev.js.map +7 -0
  25. package/src/Picker.js +116 -0
  26. package/src/Picker.js.map +7 -0
  27. package/src/index.d.ts +1 -0
  28. package/src/index.dev.js +3 -0
  29. package/src/index.dev.js.map +7 -0
  30. package/src/index.js +2 -0
  31. package/src/index.js.map +7 -0
  32. package/src/picker-overrides.css.d.ts +2 -0
  33. package/src/picker-overrides.css.dev.js +7 -0
  34. package/src/picker-overrides.css.dev.js.map +7 -0
  35. package/src/picker-overrides.css.js +4 -0
  36. package/src/picker-overrides.css.js.map +7 -0
  37. package/src/picker.css.d.ts +2 -0
  38. package/src/picker.css.dev.js +7 -0
  39. package/src/picker.css.dev.js.map +7 -0
  40. package/src/picker.css.js +4 -0
  41. package/src/picker.css.js.map +7 -0
  42. package/src/spectrum-picker.css.d.ts +2 -0
  43. package/src/spectrum-picker.css.dev.js +7 -0
  44. package/src/spectrum-picker.css.dev.js.map +7 -0
  45. package/src/spectrum-picker.css.js +4 -0
  46. package/src/spectrum-picker.css.js.map +7 -0
  47. package/src/strategies.d.ts +6 -0
  48. package/src/strategies.dev.js +8 -0
  49. package/src/strategies.dev.js.map +7 -0
  50. package/src/strategies.js +2 -0
  51. package/src/strategies.js.map +7 -0
  52. package/stories/args.js +56 -0
  53. package/stories/args.js.map +7 -0
  54. package/stories/picker-pending.stories.js +16 -0
  55. package/stories/picker-pending.stories.js.map +7 -0
  56. package/stories/picker-sizes.stories.js +75 -0
  57. package/stories/picker-sizes.stories.js.map +7 -0
  58. package/stories/picker.stories.js +694 -0
  59. package/stories/picker.stories.js.map +7 -0
  60. package/stories/states.js +228 -0
  61. package/stories/states.js.map +7 -0
  62. package/stories/template.js +32 -0
  63. package/stories/template.js.map +7 -0
  64. package/sync/index.d.ts +3 -0
  65. package/sync/index.dev.js +5 -0
  66. package/sync/index.dev.js.map +7 -0
  67. package/sync/index.js +2 -0
  68. package/sync/index.js.map +7 -0
  69. package/sync/sp-picker.d.ts +2 -0
  70. package/sync/sp-picker.dev.js +4 -0
  71. package/sync/sp-picker.dev.js.map +7 -0
  72. package/sync/sp-picker.js +2 -0
  73. package/sync/sp-picker.js.map +7 -0
  74. package/test/benchmark/basic-test.js +269 -0
  75. package/test/benchmark/basic-test.js.map +7 -0
  76. package/test/index.js +1680 -0
  77. package/test/index.js.map +7 -0
  78. package/test/picker-memory.test.js +5 -0
  79. package/test/picker-memory.test.js.map +7 -0
  80. package/test/picker-pending.test-vrt.js +5 -0
  81. package/test/picker-pending.test-vrt.js.map +7 -0
  82. package/test/picker-reparenting.test.js +92 -0
  83. package/test/picker-reparenting.test.js.map +7 -0
  84. package/test/picker-responsive.test.js +125 -0
  85. package/test/picker-responsive.test.js.map +7 -0
  86. package/test/picker-sizes.test-vrt.js +5 -0
  87. package/test/picker-sizes.test-vrt.js.map +7 -0
  88. package/test/picker-sync.test.js +7 -0
  89. package/test/picker-sync.test.js.map +7 -0
  90. package/test/picker.test-vrt.js +5 -0
  91. package/test/picker.test-vrt.js.map +7 -0
  92. package/test/picker.test.js +7 -0
  93. package/test/picker.test.js.map +7 -0
@@ -0,0 +1,717 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __decorateClass = (decorators, target, key, kind) => {
5
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
6
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
7
+ if (decorator = decorators[i])
8
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
9
+ if (kind && result) __defProp(target, key, result);
10
+ return result;
11
+ };
12
+ import {
13
+ html,
14
+ nothing,
15
+ render,
16
+ SizedMixin
17
+ } from "@spectrum-web-components/base";
18
+ import {
19
+ classMap,
20
+ ifDefined,
21
+ styleMap
22
+ } from "@spectrum-web-components/base/src/directives.js";
23
+ import {
24
+ property,
25
+ query,
26
+ state
27
+ } from "@spectrum-web-components/base/src/decorators.js";
28
+ import pickerStyles from "./picker.css.js";
29
+ import chevronStyles from "@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js";
30
+ import chevronIconOverrides from "@spectrum-web-components/icon/src/icon-chevron-overrides.css.js";
31
+ import { Focusable } from "@spectrum-web-components/shared/src/focusable.js";
32
+ import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js";
33
+ import "@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js";
34
+ import "@spectrum-web-components/menu/sp-menu.js";
35
+ import {
36
+ IS_MOBILE,
37
+ MatchMediaController
38
+ } from "@spectrum-web-components/reactive-controllers/src/MatchMedia.js";
39
+ import { DependencyManagerController } from "@spectrum-web-components/reactive-controllers/src/DependencyManger.js";
40
+ import { PendingStateController } from "@spectrum-web-components/reactive-controllers/src/PendingState.js";
41
+ import { strategies } from "./strategies.dev.js";
42
+ const chevronClass = {
43
+ s: "spectrum-UIIcon-ChevronDown75",
44
+ m: "spectrum-UIIcon-ChevronDown100",
45
+ l: "spectrum-UIIcon-ChevronDown200",
46
+ xl: "spectrum-UIIcon-ChevronDown300"
47
+ };
48
+ export const DESCRIPTION_ID = "option-picker";
49
+ export class PickerBase extends SizedMixin(Focusable, { noDefaultSize: true }) {
50
+ /**
51
+ * Initializes the `PendingStateController` for the Picker component.
52
+ * The `PendingStateController` manages the pending state of the Picker.
53
+ */
54
+ constructor() {
55
+ super();
56
+ this.isMobile = new MatchMediaController(this, IS_MOBILE);
57
+ this.dependencyManager = new DependencyManagerController(this);
58
+ this.deprecatedMenu = null;
59
+ this.disabled = false;
60
+ this.focused = false;
61
+ this.invalid = false;
62
+ this.forcePopover = false;
63
+ this.pending = false;
64
+ this.pendingLabel = "Pending";
65
+ this.open = false;
66
+ this.readonly = false;
67
+ this.selects = "single";
68
+ this._selfManageFocusElement = false;
69
+ this.placement = "bottom-start";
70
+ this.quiet = false;
71
+ this.value = "";
72
+ this.listRole = "listbox";
73
+ this.itemRole = "option";
74
+ this.handleKeydown = (event) => {
75
+ this.focused = true;
76
+ if (event.code !== "ArrowDown" && event.code !== "ArrowUp") {
77
+ return;
78
+ }
79
+ event.stopPropagation();
80
+ event.preventDefault();
81
+ this.toggle(true);
82
+ };
83
+ this.handleSlottableRequest = (_event) => {
84
+ };
85
+ this.applyFocusElementLabel = (value, labelElement) => {
86
+ this.appliedLabel = value;
87
+ this.labelAlignment = labelElement.sideAligned ? "inline" : void 0;
88
+ };
89
+ this.hasRenderedOverlay = false;
90
+ this.willManageSelection = false;
91
+ this.selectionPromise = Promise.resolve();
92
+ this.recentlyConnected = false;
93
+ this.enterKeydownOn = null;
94
+ this.handleEnterKeydown = (event) => {
95
+ if (event.code !== "Enter") {
96
+ return;
97
+ }
98
+ if (this.enterKeydownOn) {
99
+ event.preventDefault();
100
+ return;
101
+ }
102
+ this.enterKeydownOn = event.target;
103
+ this.addEventListener(
104
+ "keyup",
105
+ async (keyupEvent) => {
106
+ if (keyupEvent.code !== "Enter") {
107
+ return;
108
+ }
109
+ this.enterKeydownOn = null;
110
+ },
111
+ { once: true }
112
+ );
113
+ };
114
+ this.pendingStateController = new PendingStateController(this);
115
+ }
116
+ get menuItems() {
117
+ return this.optionsMenu.childItems;
118
+ }
119
+ get selfManageFocusElement() {
120
+ return this._selfManageFocusElement;
121
+ }
122
+ get selectedItem() {
123
+ return this._selectedItem;
124
+ }
125
+ set selectedItem(selectedItem) {
126
+ this.selectedItemContent = selectedItem ? selectedItem.itemChildren : void 0;
127
+ if (selectedItem === this.selectedItem) return;
128
+ const oldSelectedItem = this.selectedItem;
129
+ this._selectedItem = selectedItem;
130
+ this.requestUpdate("selectedItem", oldSelectedItem);
131
+ }
132
+ get focusElement() {
133
+ if (this.open) {
134
+ return this.optionsMenu;
135
+ }
136
+ return this.button;
137
+ }
138
+ forceFocusVisible() {
139
+ if (this.disabled) {
140
+ return;
141
+ }
142
+ this.focused = true;
143
+ }
144
+ click() {
145
+ if (this.disabled) {
146
+ return;
147
+ }
148
+ this.toggle();
149
+ }
150
+ handleButtonBlur() {
151
+ this.focused = false;
152
+ }
153
+ focus(options) {
154
+ super.focus(options);
155
+ if (!this.disabled && this.focusElement) {
156
+ this.focused = this.hasVisibleFocusInTree();
157
+ }
158
+ }
159
+ handleHelperFocus() {
160
+ this.focused = true;
161
+ this.button.focus();
162
+ }
163
+ handleChange(event) {
164
+ if (this.strategy) {
165
+ this.strategy.preventNextToggle = "no";
166
+ }
167
+ const target = event.target;
168
+ const [selected] = target.selectedItems;
169
+ event.stopPropagation();
170
+ if (event.cancelable) {
171
+ this.setValueFromItem(selected, event);
172
+ } else {
173
+ this.open = false;
174
+ if (this.strategy) {
175
+ this.strategy.open = false;
176
+ }
177
+ }
178
+ }
179
+ handleButtonFocus(event) {
180
+ var _a;
181
+ (_a = this.strategy) == null ? void 0 : _a.handleButtonFocus(event);
182
+ }
183
+ async setValueFromItem(item, menuChangeEvent) {
184
+ var _a;
185
+ this.open = false;
186
+ if (this.strategy) {
187
+ this.strategy.open = false;
188
+ }
189
+ const oldSelectedItem = this.selectedItem;
190
+ const oldValue = this.value;
191
+ this.selectedItem = item;
192
+ this.value = (_a = item == null ? void 0 : item.value) != null ? _a : "";
193
+ await this.updateComplete;
194
+ const applyDefault = this.dispatchEvent(
195
+ new Event("change", {
196
+ bubbles: true,
197
+ // Allow it to be prevented.
198
+ cancelable: true,
199
+ composed: true
200
+ })
201
+ );
202
+ if (!applyDefault && this.selects) {
203
+ if (menuChangeEvent) {
204
+ menuChangeEvent.preventDefault();
205
+ }
206
+ this.setMenuItemSelected(this.selectedItem, false);
207
+ if (oldSelectedItem) {
208
+ this.setMenuItemSelected(oldSelectedItem, true);
209
+ }
210
+ this.selectedItem = oldSelectedItem;
211
+ this.value = oldValue;
212
+ this.open = true;
213
+ if (this.strategy) {
214
+ this.strategy.open = true;
215
+ }
216
+ return;
217
+ } else if (!this.selects) {
218
+ this.selectedItem = oldSelectedItem;
219
+ this.value = oldValue;
220
+ return;
221
+ }
222
+ if (oldSelectedItem) {
223
+ this.setMenuItemSelected(oldSelectedItem, false);
224
+ }
225
+ this.setMenuItemSelected(item, !!this.selects);
226
+ }
227
+ setMenuItemSelected(item, value) {
228
+ if (this.selects == null) return;
229
+ item.selected = value;
230
+ }
231
+ toggle(target) {
232
+ if (this.readonly || this.pending) {
233
+ return;
234
+ }
235
+ this.open = typeof target !== "undefined" ? target : !this.open;
236
+ if (this.strategy) {
237
+ this.strategy.open = this.open;
238
+ }
239
+ if (this.open) {
240
+ this._selfManageFocusElement = true;
241
+ } else {
242
+ this._selfManageFocusElement = false;
243
+ }
244
+ }
245
+ close() {
246
+ if (this.readonly) {
247
+ return;
248
+ }
249
+ if (this.strategy) {
250
+ this.open = false;
251
+ this.strategy.open = false;
252
+ }
253
+ }
254
+ get containerStyles() {
255
+ if (this.isMobile.matches) {
256
+ return {
257
+ "--swc-menu-width": "100%"
258
+ };
259
+ }
260
+ return {};
261
+ }
262
+ get selectedItemContent() {
263
+ return this._selectedItemContent || { icon: [], content: [] };
264
+ }
265
+ set selectedItemContent(selectedItemContent) {
266
+ if (selectedItemContent === this.selectedItemContent) return;
267
+ const oldContent = this.selectedItemContent;
268
+ this._selectedItemContent = selectedItemContent;
269
+ this.requestUpdate("selectedItemContent", oldContent);
270
+ }
271
+ handleTooltipSlotchange(event) {
272
+ this.tooltipEl = event.target.assignedElements()[0];
273
+ }
274
+ renderLabelContent(content) {
275
+ if (this.value && this.selectedItem) {
276
+ return content;
277
+ }
278
+ return html`
279
+ <slot name="label" id="label">
280
+ <span
281
+ aria-hidden=${ifDefined(
282
+ this.appliedLabel ? void 0 : "true"
283
+ )}
284
+ >
285
+ ${this.label}
286
+ </span>
287
+ </slot>
288
+ `;
289
+ }
290
+ get buttonContent() {
291
+ const labelClasses = {
292
+ "visually-hidden": this.icons === "only" && !!this.value,
293
+ placeholder: !this.value,
294
+ label: true
295
+ };
296
+ const appliedLabel = this.appliedLabel || this.label;
297
+ return [
298
+ html`
299
+ <span id="icon" ?hidden=${this.icons === "none"}>
300
+ ${this.selectedItemContent.icon}
301
+ </span>
302
+ <span
303
+ id=${ifDefined(
304
+ this.value && this.selectedItem ? "label" : void 0
305
+ )}
306
+ class=${classMap(labelClasses)}
307
+ >
308
+ ${this.renderLabelContent(this.selectedItemContent.content)}
309
+ </span>
310
+ ${this.value && this.selectedItem ? html`
311
+ <span
312
+ aria-hidden="true"
313
+ class="visually-hidden"
314
+ id="applied-label"
315
+ >
316
+ ${appliedLabel}
317
+ <slot name="label"></slot>
318
+ </span>
319
+ ` : html`
320
+ <span hidden id="applied-label">${appliedLabel}</span>
321
+ `}
322
+ ${this.invalid && !this.pending ? html`
323
+ <sp-icon-alert
324
+ class="validation-icon"
325
+ ></sp-icon-alert>
326
+ ` : nothing}
327
+ ${this.pendingStateController.renderPendingState()}
328
+ <sp-icon-chevron100
329
+ class="picker ${chevronClass[this.size]}"
330
+ ></sp-icon-chevron100>
331
+ <slot
332
+ aria-hidden="true"
333
+ name="tooltip"
334
+ id="tooltip"
335
+ @slotchange=${this.handleTooltipSlotchange}
336
+ ></slot>
337
+ `
338
+ ];
339
+ }
340
+ renderOverlay(menu) {
341
+ var _a, _b, _c;
342
+ if (((_a = this.strategy) == null ? void 0 : _a.overlay) === void 0) {
343
+ return menu;
344
+ }
345
+ const container = this.renderContainer(menu);
346
+ render(container, (_b = this.strategy) == null ? void 0 : _b.overlay, {
347
+ host: this
348
+ });
349
+ return (_c = this.strategy) == null ? void 0 : _c.overlay;
350
+ }
351
+ get renderDescriptionSlot() {
352
+ return html`
353
+ <div id=${DESCRIPTION_ID}>
354
+ <slot name="description"></slot>
355
+ </div>
356
+ `;
357
+ }
358
+ // a helper to throw focus to the button is needed because Safari
359
+ // won't include buttons in the tab order even with tabindex="0"
360
+ render() {
361
+ if (this.tooltipEl) {
362
+ this.tooltipEl.disabled = this.open;
363
+ }
364
+ return html`
365
+ <span
366
+ id="focus-helper"
367
+ tabindex="${this.focused || this.open ? "-1" : "0"}"
368
+ @focus=${this.handleHelperFocus}
369
+ aria-describedby=${DESCRIPTION_ID}
370
+ ></span>
371
+ <button
372
+ aria-controls=${ifDefined(this.open ? "menu" : void 0)}
373
+ aria-describedby="tooltip"
374
+ aria-expanded=${this.open ? "true" : "false"}
375
+ aria-haspopup="true"
376
+ aria-labelledby="loader icon label applied-label"
377
+ id="button"
378
+ class=${ifDefined(
379
+ this.labelAlignment ? `label-${this.labelAlignment}` : void 0
380
+ )}
381
+ @blur=${this.handleButtonBlur}
382
+ @keydown=${{
383
+ handleEvent: this.handleEnterKeydown,
384
+ capture: true
385
+ }}
386
+ ?disabled=${this.disabled}
387
+ tabindex="-1"
388
+ >
389
+ ${this.buttonContent}
390
+ </button>
391
+ ${this.renderMenu} ${this.renderDescriptionSlot}
392
+ `;
393
+ }
394
+ update(changes) {
395
+ var _a, _b;
396
+ if (this.selects) {
397
+ this.selects = "single";
398
+ }
399
+ if (changes.has("disabled") && this.disabled) {
400
+ if (this.strategy) {
401
+ this.open = false;
402
+ this.strategy.open = false;
403
+ }
404
+ }
405
+ if (changes.has("pending") && this.pending) {
406
+ if (this.strategy) {
407
+ this.open = false;
408
+ this.strategy.open = false;
409
+ }
410
+ }
411
+ if (changes.has("value")) {
412
+ this.shouldScheduleManageSelection();
413
+ }
414
+ if (!this.hasUpdated) {
415
+ this.deprecatedMenu = this.querySelector(":scope > sp-menu");
416
+ (_a = this.deprecatedMenu) == null ? void 0 : _a.toggleAttribute("ignore", true);
417
+ (_b = this.deprecatedMenu) == null ? void 0 : _b.setAttribute("selects", "inherit");
418
+ }
419
+ if (true) {
420
+ if (!this.hasUpdated && this.querySelector(":scope > sp-menu")) {
421
+ const { localName } = this;
422
+ window.__swc.warn(
423
+ this,
424
+ `You no longer need to provide an <sp-menu> child to ${localName}. Any styling or attributes on the <sp-menu> will be ignored.`,
425
+ "https://opensource.adobe.com/spectrum-web-components/components/picker/#sizes",
426
+ { level: "deprecation" }
427
+ );
428
+ }
429
+ this.updateComplete.then(async () => {
430
+ await new Promise((res) => requestAnimationFrame(res));
431
+ await new Promise((res) => requestAnimationFrame(res));
432
+ if (!this.label && !this.getAttribute("aria-label") && !this.getAttribute("aria-labelledby") && !this.appliedLabel) {
433
+ window.__swc.warn(
434
+ this,
435
+ `<${this.localName}> needs one of the following to be accessible:`,
436
+ "https://opensource.adobe.com/spectrum-web-components/components/picker/#accessibility",
437
+ {
438
+ type: "accessibility",
439
+ issues: [
440
+ `an <sp-field-label> element with a \`for\` attribute referencing the \`id\` of the \`<${this.localName}>\`, or`,
441
+ 'value supplied to the "label" attribute, which will be displayed visually as placeholder text, or',
442
+ 'text content supplied in a <span> with slot="label", which will also be displayed visually as placeholder text.'
443
+ ]
444
+ }
445
+ );
446
+ }
447
+ });
448
+ }
449
+ super.update(changes);
450
+ }
451
+ bindButtonKeydownListener() {
452
+ this.button.addEventListener("keydown", this.handleKeydown);
453
+ }
454
+ updated(changes) {
455
+ super.updated(changes);
456
+ if (changes.has("open")) {
457
+ this.strategy.open = this.open;
458
+ }
459
+ }
460
+ firstUpdated(changes) {
461
+ super.firstUpdated(changes);
462
+ this.bindButtonKeydownListener();
463
+ this.bindEvents();
464
+ }
465
+ get dismissHelper() {
466
+ return html`
467
+ <div class="visually-hidden">
468
+ <button
469
+ tabindex="-1"
470
+ aria-label="Dismiss"
471
+ @click=${this.close}
472
+ ></button>
473
+ </div>
474
+ `;
475
+ }
476
+ renderContainer(menu) {
477
+ const accessibleMenu = html`
478
+ ${this.dismissHelper} ${menu} ${this.dismissHelper}
479
+ `;
480
+ if (this.isMobile.matches && !this.forcePopover) {
481
+ this.dependencyManager.add("sp-tray");
482
+ import("@spectrum-web-components/tray/sp-tray.js");
483
+ return html`
484
+ <sp-tray
485
+ id="popover"
486
+ role="presentation"
487
+ style=${styleMap(this.containerStyles)}
488
+ >
489
+ ${accessibleMenu}
490
+ </sp-tray>
491
+ `;
492
+ }
493
+ this.dependencyManager.add("sp-popover");
494
+ import("@spectrum-web-components/popover/sp-popover.js");
495
+ return html`
496
+ <sp-popover
497
+ id="popover"
498
+ role="presentation"
499
+ style=${styleMap(this.containerStyles)}
500
+ placement=${this.placement}
501
+ >
502
+ ${accessibleMenu}
503
+ </sp-popover>
504
+ `;
505
+ }
506
+ onScroll() {
507
+ this.dispatchEvent(
508
+ new Event("scroll", {
509
+ cancelable: true,
510
+ composed: true
511
+ })
512
+ );
513
+ }
514
+ get renderMenu() {
515
+ const menu = html`
516
+ <sp-menu
517
+ aria-labelledby="applied-label"
518
+ @change=${this.handleChange}
519
+ id="menu"
520
+ @keydown=${{
521
+ handleEvent: this.handleEnterKeydown,
522
+ capture: true
523
+ }}
524
+ @scroll=${this.onScroll}
525
+ role=${this.listRole}
526
+ .selects=${this.selects}
527
+ .selected=${this.value ? [this.value] : []}
528
+ size=${this.size}
529
+ @sp-menu-item-added-or-updated=${this.shouldManageSelection}
530
+ >
531
+ <slot @slotchange=${this.shouldScheduleManageSelection}></slot>
532
+ </sp-menu>
533
+ `;
534
+ this.hasRenderedOverlay = this.hasRenderedOverlay || this.focused || this.open || !!this.deprecatedMenu;
535
+ if (this.hasRenderedOverlay) {
536
+ if (this.dependencyManager.loaded) {
537
+ this.dependencyManager.add("sp-overlay");
538
+ }
539
+ return this.renderOverlay(menu);
540
+ }
541
+ return menu;
542
+ }
543
+ shouldScheduleManageSelection(event) {
544
+ if (!this.willManageSelection && (!event || event.target.getRootNode().host === this)) {
545
+ this.willManageSelection = true;
546
+ requestAnimationFrame(() => {
547
+ requestAnimationFrame(() => {
548
+ this.manageSelection();
549
+ });
550
+ });
551
+ }
552
+ }
553
+ shouldManageSelection() {
554
+ if (this.willManageSelection) {
555
+ return;
556
+ }
557
+ this.willManageSelection = true;
558
+ this.manageSelection();
559
+ }
560
+ async manageSelection() {
561
+ if (this.selects == null) return;
562
+ this.selectionPromise = new Promise(
563
+ (res) => this.selectionResolver = res
564
+ );
565
+ let selectedItem;
566
+ await this.optionsMenu.updateComplete;
567
+ if (this.recentlyConnected) {
568
+ await new Promise((res) => requestAnimationFrame(() => res(true)));
569
+ this.recentlyConnected = false;
570
+ }
571
+ this.menuItems.forEach((item) => {
572
+ if (this.value === item.value && !item.disabled) {
573
+ selectedItem = item;
574
+ } else {
575
+ item.selected = false;
576
+ }
577
+ });
578
+ if (selectedItem) {
579
+ selectedItem.selected = !!this.selects;
580
+ this.selectedItem = selectedItem;
581
+ } else {
582
+ this.value = "";
583
+ this.selectedItem = void 0;
584
+ }
585
+ if (this.open) {
586
+ await this.optionsMenu.updateComplete;
587
+ this.optionsMenu.updateSelectedItemIndex();
588
+ }
589
+ this.selectionResolver();
590
+ this.willManageSelection = false;
591
+ }
592
+ async getUpdateComplete() {
593
+ const complete = await super.getUpdateComplete();
594
+ await this.selectionPromise;
595
+ return complete;
596
+ }
597
+ bindEvents() {
598
+ var _a;
599
+ (_a = this.strategy) == null ? void 0 : _a.abort();
600
+ if (this.isMobile.matches) {
601
+ this.strategy = new strategies["mobile"](this.button, this);
602
+ } else {
603
+ this.strategy = new strategies["desktop"](this.button, this);
604
+ }
605
+ }
606
+ connectedCallback() {
607
+ super.connectedCallback();
608
+ this.recentlyConnected = this.hasUpdated;
609
+ }
610
+ disconnectedCallback() {
611
+ var _a;
612
+ this.close();
613
+ (_a = this.strategy) == null ? void 0 : _a.releaseDescription();
614
+ super.disconnectedCallback();
615
+ }
616
+ }
617
+ __decorateClass([
618
+ state()
619
+ ], PickerBase.prototype, "appliedLabel", 2);
620
+ __decorateClass([
621
+ query("#button")
622
+ ], PickerBase.prototype, "button", 2);
623
+ __decorateClass([
624
+ property({ type: Boolean, reflect: true })
625
+ ], PickerBase.prototype, "disabled", 2);
626
+ __decorateClass([
627
+ property({ type: Boolean, reflect: true })
628
+ ], PickerBase.prototype, "focused", 2);
629
+ __decorateClass([
630
+ property({ type: String, reflect: true })
631
+ ], PickerBase.prototype, "icons", 2);
632
+ __decorateClass([
633
+ property({ type: Boolean, reflect: true })
634
+ ], PickerBase.prototype, "invalid", 2);
635
+ __decorateClass([
636
+ property({ type: Boolean, reflect: true, attribute: "force-popover" })
637
+ ], PickerBase.prototype, "forcePopover", 2);
638
+ __decorateClass([
639
+ property({ type: Boolean, reflect: true })
640
+ ], PickerBase.prototype, "pending", 2);
641
+ __decorateClass([
642
+ property({ type: String, attribute: "pending-label" })
643
+ ], PickerBase.prototype, "pendingLabel", 2);
644
+ __decorateClass([
645
+ property()
646
+ ], PickerBase.prototype, "label", 2);
647
+ __decorateClass([
648
+ property({ type: Boolean, reflect: true })
649
+ ], PickerBase.prototype, "open", 2);
650
+ __decorateClass([
651
+ property({ type: Boolean, reflect: true })
652
+ ], PickerBase.prototype, "readonly", 2);
653
+ __decorateClass([
654
+ state()
655
+ ], PickerBase.prototype, "labelAlignment", 2);
656
+ __decorateClass([
657
+ query("sp-menu")
658
+ ], PickerBase.prototype, "optionsMenu", 2);
659
+ __decorateClass([
660
+ query("sp-overlay")
661
+ ], PickerBase.prototype, "overlayElement", 2);
662
+ __decorateClass([
663
+ property()
664
+ ], PickerBase.prototype, "placement", 2);
665
+ __decorateClass([
666
+ property({ type: Boolean, reflect: true })
667
+ ], PickerBase.prototype, "quiet", 2);
668
+ __decorateClass([
669
+ property({ type: String })
670
+ ], PickerBase.prototype, "value", 2);
671
+ __decorateClass([
672
+ property({ attribute: false })
673
+ ], PickerBase.prototype, "selectedItem", 1);
674
+ __decorateClass([
675
+ state()
676
+ ], PickerBase.prototype, "selectedItemContent", 1);
677
+ export class Picker extends PickerBase {
678
+ constructor() {
679
+ super(...arguments);
680
+ this.handleKeydown = (event) => {
681
+ const { code } = event;
682
+ this.focused = true;
683
+ if (!code.startsWith("Arrow") || this.readonly || this.pending) {
684
+ return;
685
+ }
686
+ if (code === "ArrowUp" || code === "ArrowDown") {
687
+ this.toggle(true);
688
+ event.preventDefault();
689
+ return;
690
+ }
691
+ event.preventDefault();
692
+ const selectedIndex = this.selectedItem ? this.menuItems.indexOf(this.selectedItem) : -1;
693
+ const nextOffset = selectedIndex < 0 || code === "ArrowRight" ? 1 : -1;
694
+ let nextIndex = selectedIndex + nextOffset;
695
+ while (this.menuItems[nextIndex] && this.menuItems[nextIndex].disabled) {
696
+ nextIndex += nextOffset;
697
+ }
698
+ if (!this.menuItems[nextIndex] || this.menuItems[nextIndex].disabled) {
699
+ return;
700
+ }
701
+ if (!this.value || nextIndex !== selectedIndex) {
702
+ this.setValueFromItem(this.menuItems[nextIndex]);
703
+ }
704
+ };
705
+ }
706
+ static get styles() {
707
+ return [pickerStyles, chevronStyles, chevronIconOverrides];
708
+ }
709
+ get containerStyles() {
710
+ const styles = super.containerStyles;
711
+ if (!this.quiet) {
712
+ styles["min-width"] = `${this.offsetWidth}px`;
713
+ }
714
+ return styles;
715
+ }
716
+ }
717
+ //# sourceMappingURL=Picker.dev.js.map