@spectrum-web-components/picker 0.11.5 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/custom-elements.json +62 -78
  2. package/package.json +39 -22
  3. package/sp-picker.dev.js +3 -0
  4. package/sp-picker.dev.js.map +7 -0
  5. package/sp-picker.js +3 -14
  6. package/sp-picker.js.map +7 -1
  7. package/src/Picker.dev.js +501 -0
  8. package/src/Picker.dev.js.map +7 -0
  9. package/src/Picker.js +406 -435
  10. package/src/Picker.js.map +7 -1
  11. package/src/index.dev.js +2 -0
  12. package/src/index.dev.js.map +7 -0
  13. package/src/index.js +2 -13
  14. package/src/index.js.map +7 -1
  15. package/src/picker.css.dev.js +304 -0
  16. package/src/picker.css.dev.js.map +7 -0
  17. package/src/picker.css.js +4 -15
  18. package/src/picker.css.js.map +7 -1
  19. package/src/spectrum-picker.css.dev.js +300 -0
  20. package/src/spectrum-picker.css.dev.js.map +7 -0
  21. package/src/spectrum-picker.css.js +4 -15
  22. package/src/spectrum-picker.css.js.map +7 -1
  23. package/stories/picker-sizes.stories.js +22 -30
  24. package/stories/picker-sizes.stories.js.map +7 -1
  25. package/stories/picker.stories.js +84 -95
  26. package/stories/picker.stories.js.map +7 -1
  27. package/stories/states.js +225 -236
  28. package/stories/states.js.map +7 -1
  29. package/sync/index.dev.js +8 -0
  30. package/sync/index.dev.js.map +7 -0
  31. package/sync/index.js +6 -15
  32. package/sync/index.js.map +7 -1
  33. package/sync/sp-picker.dev.js +3 -0
  34. package/sync/sp-picker.dev.js.map +7 -0
  35. package/sync/sp-picker.js +3 -14
  36. package/sync/sp-picker.js.map +7 -1
  37. package/test/benchmark/basic-test.js +256 -267
  38. package/test/benchmark/basic-test.js.map +7 -1
  39. package/test/index.js +896 -839
  40. package/test/index.js.map +7 -1
  41. package/test/picker-reparenting.test.js +71 -76
  42. package/test/picker-reparenting.test.js.map +7 -1
  43. package/test/picker-responsive.test.js +41 -53
  44. package/test/picker-responsive.test.js.map +7 -1
  45. package/test/picker-sizes.test-vrt.js +4 -15
  46. package/test/picker-sizes.test-vrt.js.map +7 -1
  47. package/test/picker-sync.test.js +5 -16
  48. package/test/picker-sync.test.js.map +7 -1
  49. package/test/picker.test-vrt.js +4 -15
  50. package/test/picker.test-vrt.js.map +7 -1
  51. package/test/picker.test.js +5 -16
  52. package/test/picker.test.js.map +7 -1
package/src/Picker.js CHANGED
@@ -1,290 +1,277 @@
1
- /*
2
- Copyright 2020 Adobe. All rights reserved.
3
- This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
- you may not use this file except in compliance with the License. You may obtain a copy
5
- of the License at http://www.apache.org/licenses/LICENSE-2.0
6
-
7
- Unless required by applicable law or agreed to in writing, software distributed under
8
- the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
- OF ANY KIND, either express or implied. See the License for the specific language
10
- governing permissions and limitations under the License.
11
- */
12
- var _a;
13
- import { __decorate } from "tslib";
14
- import { html, nothing, render, SizedMixin, } from '@spectrum-web-components/base';
15
- import { classMap } from '@spectrum-web-components/base/src/directives.js';
16
- import { property, query, } from '@spectrum-web-components/base/src/decorators.js';
17
- import pickerStyles from './picker.css.js';
18
- import chevronStyles from '@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js';
19
- import { Focusable } from '@spectrum-web-components/shared/src/focusable.js';
20
- import { reparentChildren } from '@spectrum-web-components/shared/src/reparent-children.js';
21
- import '@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js';
22
- import '@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js';
23
- import '@spectrum-web-components/menu/sp-menu.js';
24
- import '@spectrum-web-components/tray/sp-tray.js';
25
- import '@spectrum-web-components/popover/sp-popover.js';
26
- import { openOverlay, } from '@spectrum-web-components/overlay';
27
- import { IS_MOBILE, MatchMediaController, } from '@spectrum-web-components/reactive-controllers/src/MatchMedia.js';
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __decorateClass = (decorators, target, key, kind) => {
4
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
+ if (decorator = decorators[i])
7
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
+ if (kind && result)
9
+ __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 { classMap } from "@spectrum-web-components/base/src/directives.js";
19
+ import {
20
+ property,
21
+ query
22
+ } from "@spectrum-web-components/base/src/decorators.js";
23
+ import pickerStyles from "./picker.css.js";
24
+ import chevronStyles from "@spectrum-web-components/icon/src/spectrum-icon-chevron.css.js";
25
+ import { Focusable } from "@spectrum-web-components/shared/src/focusable.js";
26
+ import { reparentChildren } from "@spectrum-web-components/shared/src/reparent-children.js";
27
+ import "@spectrum-web-components/icons-ui/icons/sp-icon-chevron100.js";
28
+ import "@spectrum-web-components/icons-workflow/icons/sp-icon-alert.js";
29
+ import "@spectrum-web-components/menu/sp-menu.js";
30
+ import "@spectrum-web-components/tray/sp-tray.js";
31
+ import "@spectrum-web-components/popover/sp-popover.js";
32
+ import {
33
+ openOverlay
34
+ } from "@spectrum-web-components/overlay";
35
+ import {
36
+ IS_MOBILE,
37
+ MatchMediaController
38
+ } from "@spectrum-web-components/reactive-controllers/src/MatchMedia.js";
28
39
  const chevronClass = {
29
- s: 'spectrum-UIIcon-ChevronDown75',
30
- m: 'spectrum-UIIcon-ChevronDown100',
31
- l: 'spectrum-UIIcon-ChevronDown200',
32
- xl: 'spectrum-UIIcon-ChevronDown300',
40
+ s: "spectrum-UIIcon-ChevronDown75",
41
+ m: "spectrum-UIIcon-ChevronDown100",
42
+ l: "spectrum-UIIcon-ChevronDown200",
43
+ xl: "spectrum-UIIcon-ChevronDown300"
33
44
  };
34
- /**
35
- * @element sp-picker
36
- *
37
- * @slot label - The placeholder content for the Picker
38
- * @slot - menu items to be listed in the Picker
39
- * @fires change - Announces that the `value` of the element has changed
40
- * @fires sp-opened - Announces that the overlay has been opened
41
- * @fires sp-closed - Announces that the overlay has been closed
42
- */
43
45
  export class PickerBase extends SizedMixin(Focusable) {
44
- constructor() {
45
- super();
46
- this.isMobile = new MatchMediaController(this, IS_MOBILE);
47
- this.disabled = false;
48
- this.focused = false;
49
- this.invalid = false;
50
- this.open = false;
51
- this.readonly = false;
52
- this.selects = 'single';
53
- this.menuItems = [];
54
- /**
55
- * @type {"auto" | "auto-start" | "auto-end" | "top" | "bottom" | "right" | "left" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end" | "none"}
56
- * @attr
57
- */
58
- this.placement = 'bottom-start';
59
- this.quiet = false;
60
- this.value = '';
61
- this.listRole = 'listbox';
62
- this.itemRole = 'option';
63
- this.onKeydown = (event) => {
64
- this.focused = true;
65
- if (event.code !== 'ArrowDown' && event.code !== 'ArrowUp') {
66
- return;
67
- }
68
- event.preventDefault();
69
- this.toggle(true);
70
- };
71
- this.overlayOpenCallback = async () => {
72
- this.updateMenuItems();
73
- await this.itemsUpdated;
74
- await this.optionsMenu.updateComplete;
75
- requestAnimationFrame(() => this.menuStateResolver());
76
- };
77
- this.overlayCloseCallback = async () => {
78
- if (this.restoreChildren) {
79
- this.restoreChildren();
80
- this.restoreChildren = undefined;
81
- }
82
- this.close();
83
- requestAnimationFrame(() => this.menuStateResolver());
84
- };
85
- this._willUpdateItems = false;
86
- this.itemsUpdated = Promise.resolve();
87
- this.menuStatePromise = Promise.resolve();
88
- this.selectionPromise = Promise.resolve();
89
- this.onKeydown = this.onKeydown.bind(this);
46
+ constructor() {
47
+ super();
48
+ this.isMobile = new MatchMediaController(this, IS_MOBILE);
49
+ this.disabled = false;
50
+ this.focused = false;
51
+ this.invalid = false;
52
+ this.open = false;
53
+ this.readonly = false;
54
+ this.selects = "single";
55
+ this.menuItems = [];
56
+ this.placement = "bottom-start";
57
+ this.quiet = false;
58
+ this.value = "";
59
+ this.listRole = "listbox";
60
+ this.itemRole = "option";
61
+ this.onKeydown = (event) => {
62
+ this.focused = true;
63
+ if (event.code !== "ArrowDown" && event.code !== "ArrowUp") {
64
+ return;
65
+ }
66
+ event.preventDefault();
67
+ this.toggle(true);
68
+ };
69
+ this.overlayOpenCallback = async () => {
70
+ this.updateMenuItems();
71
+ await this.itemsUpdated;
72
+ await this.optionsMenu.updateComplete;
73
+ requestAnimationFrame(() => this.menuStateResolver());
74
+ };
75
+ this.overlayCloseCallback = async () => {
76
+ if (this.restoreChildren) {
77
+ this.restoreChildren();
78
+ this.restoreChildren = void 0;
79
+ }
80
+ this.close();
81
+ requestAnimationFrame(() => this.menuStateResolver());
82
+ };
83
+ this._willUpdateItems = false;
84
+ this.itemsUpdated = Promise.resolve();
85
+ this.menuStatePromise = Promise.resolve();
86
+ this.selectionPromise = Promise.resolve();
87
+ this.onKeydown = this.onKeydown.bind(this);
88
+ }
89
+ get target() {
90
+ return this.button;
91
+ }
92
+ get focusElement() {
93
+ if (this.open) {
94
+ return this.optionsMenu;
90
95
  }
91
- get target() {
92
- return this.button;
96
+ return this.button;
97
+ }
98
+ forceFocusVisible() {
99
+ this.focused = true;
100
+ }
101
+ onButtonBlur() {
102
+ this.focused = false;
103
+ this.target.removeEventListener("keydown", this.onKeydown);
104
+ }
105
+ onButtonClick() {
106
+ this.toggle();
107
+ }
108
+ focus(options) {
109
+ super.focus(options);
110
+ if (!this.disabled && this.focusElement) {
111
+ this.focused = this.hasVisibleFocusInTree();
93
112
  }
94
- get focusElement() {
95
- if (this.open) {
96
- return this.optionsMenu;
97
- }
98
- return this.button;
99
- }
100
- forceFocusVisible() {
101
- this.focused = true;
113
+ }
114
+ onHelperFocus() {
115
+ this.focused = true;
116
+ this.button.focus();
117
+ }
118
+ onButtonFocus() {
119
+ this.target.addEventListener("keydown", this.onKeydown);
120
+ }
121
+ handleChange(event) {
122
+ event.stopPropagation();
123
+ const target = event.target;
124
+ const [selected] = target.selectedItems;
125
+ this.setValueFromItem(selected, event);
126
+ }
127
+ async setValueFromItem(item, menuChangeEvent) {
128
+ const oldSelectedItem = this.selectedItem;
129
+ const oldValue = this.value;
130
+ this.selectedItem = item;
131
+ this.value = item.value;
132
+ this.open = false;
133
+ await this.updateComplete;
134
+ const applyDefault = this.dispatchEvent(new Event("change", {
135
+ bubbles: true,
136
+ cancelable: true,
137
+ composed: true
138
+ }));
139
+ if (!applyDefault) {
140
+ if (menuChangeEvent) {
141
+ menuChangeEvent.preventDefault();
142
+ }
143
+ this.selectedItem.selected = false;
144
+ if (oldSelectedItem) {
145
+ oldSelectedItem.selected = true;
146
+ }
147
+ this.selectedItem = oldSelectedItem;
148
+ this.value = oldValue;
149
+ this.open = true;
150
+ return;
102
151
  }
103
- onButtonBlur() {
104
- this.focused = false;
105
- this.target.removeEventListener('keydown', this.onKeydown);
152
+ if (oldSelectedItem) {
153
+ oldSelectedItem.selected = false;
106
154
  }
107
- onButtonClick() {
108
- this.toggle();
155
+ item.selected = !!this.selects;
156
+ }
157
+ toggle(target) {
158
+ if (this.readonly) {
159
+ return;
109
160
  }
110
- focus(options) {
111
- super.focus(options);
112
- if (!this.disabled && this.focusElement) {
113
- this.focused = this.hasVisibleFocusInTree();
114
- }
161
+ this.open = typeof target !== "undefined" ? target : !this.open;
162
+ }
163
+ close() {
164
+ if (this.readonly) {
165
+ return;
115
166
  }
116
- onHelperFocus() {
117
- // set focused to true here instead of onButtonFocus so clicks don't flash a focus outline
118
- this.focused = true;
119
- this.button.focus();
167
+ this.open = false;
168
+ }
169
+ async generatePopover() {
170
+ if (!this.popoverFragment) {
171
+ this.popoverFragment = document.createDocumentFragment();
120
172
  }
121
- onButtonFocus() {
122
- this.target.addEventListener('keydown', this.onKeydown);
173
+ render(this.renderPopover, this.popoverFragment, { host: this });
174
+ this.popover = this.popoverFragment.children[0];
175
+ this.optionsMenu = this.popover.children[1];
176
+ }
177
+ async openMenu() {
178
+ let reparentableChildren = [];
179
+ const deprecatedMenu = this.querySelector(":scope > sp-menu");
180
+ await this.generatePopover();
181
+ if (deprecatedMenu) {
182
+ reparentableChildren = Array.from(deprecatedMenu.children);
183
+ } else {
184
+ reparentableChildren = Array.from(this.children).filter((element) => {
185
+ return !element.hasAttribute("slot");
186
+ });
123
187
  }
124
- handleChange(event) {
125
- event.stopPropagation();
126
- const target = event.target;
127
- const [selected] = target.selectedItems;
128
- this.setValueFromItem(selected, event);
188
+ if (reparentableChildren.length === 0) {
189
+ this.menuStateResolver();
190
+ return;
129
191
  }
130
- async setValueFromItem(item, menuChangeEvent) {
131
- const oldSelectedItem = this.selectedItem;
132
- const oldValue = this.value;
133
- this.selectedItem = item;
134
- this.value = item.value;
135
- this.open = false;
136
- await this.updateComplete;
137
- const applyDefault = this.dispatchEvent(new Event('change', {
138
- bubbles: true,
139
- cancelable: true,
140
- composed: true,
141
- }));
142
- if (!applyDefault) {
143
- if (menuChangeEvent) {
144
- menuChangeEvent.preventDefault();
145
- }
146
- this.selectedItem.selected = false;
147
- if (oldSelectedItem) {
148
- oldSelectedItem.selected = true;
149
- }
150
- this.selectedItem = oldSelectedItem;
151
- this.value = oldValue;
152
- this.open = true;
153
- return;
192
+ this.restoreChildren = reparentChildren(reparentableChildren, this.optionsMenu, {
193
+ position: "beforeend",
194
+ prepareCallback: (el) => {
195
+ if (this.value === el.value) {
196
+ el.selected = true;
154
197
  }
155
- if (oldSelectedItem) {
156
- oldSelectedItem.selected = false;
157
- }
158
- item.selected = !!this.selects;
159
- }
160
- toggle(target) {
161
- if (this.readonly) {
162
- return;
163
- }
164
- this.open = typeof target !== 'undefined' ? target : !this.open;
165
- }
166
- close() {
167
- if (this.readonly) {
168
- return;
169
- }
170
- this.open = false;
171
- }
172
- async generatePopover(deprecatedMenu) {
173
- if (!this.popoverFragment) {
174
- this.popoverFragment = document.createDocumentFragment();
175
- }
176
- render(this.renderPopover, this.popoverFragment, { host: this });
177
- this.popover = this.popoverFragment.children[0];
178
- this.optionsMenu = this.popover.children[1];
179
- if (deprecatedMenu) {
180
- console.warn(`Deprecation Notice: You no longer need to provide an sp-menu child to ${this.tagName.toLowerCase()}. Any styling or attributes on the sp-menu will be ignored.`);
181
- }
182
- }
183
- async openMenu() {
184
- /* c8 ignore next 9 */
185
- let reparentableChildren = [];
186
- const deprecatedMenu = this.querySelector(':scope > sp-menu');
187
- await this.generatePopover(deprecatedMenu);
188
- if (deprecatedMenu) {
189
- reparentableChildren = Array.from(deprecatedMenu.children);
190
- }
191
- else {
192
- reparentableChildren = Array.from(this.children).filter((element) => {
193
- return !element.hasAttribute('slot');
194
- });
195
- }
196
- if (reparentableChildren.length === 0) {
197
- this.menuStateResolver();
198
- return;
199
- }
200
- this.restoreChildren = reparentChildren(reparentableChildren, this.optionsMenu, {
201
- position: 'beforeend',
202
- prepareCallback: (el) => {
203
- if (this.value === el.value) {
204
- el.selected = true;
205
- }
206
- return (el) => {
207
- if (typeof el.focused !== 'undefined') {
208
- el.focused = false;
209
- }
210
- };
211
- },
212
- });
213
- this.sizePopover(this.popover);
214
- this.closeOverlay = Picker.openOverlay(this, 'modal', this.popover, {
215
- placement: this.isMobile.matches ? 'none' : this.placement,
216
- receivesFocus: 'auto',
217
- });
198
+ return (el2) => {
199
+ if (typeof el2.focused !== "undefined") {
200
+ el2.focused = false;
201
+ }
202
+ };
203
+ }
204
+ });
205
+ this.sizePopover(this.popover);
206
+ this.closeOverlay = Picker.openOverlay(this, "modal", this.popover, {
207
+ placement: this.isMobile.matches ? "none" : this.placement,
208
+ receivesFocus: "auto"
209
+ });
210
+ }
211
+ sizePopover(popover) {
212
+ if (this.isMobile.matches) {
213
+ popover.style.setProperty("--swc-menu-width", `100%`);
214
+ return;
218
215
  }
219
- sizePopover(popover) {
220
- if (this.isMobile.matches) {
221
- popover.style.setProperty('--swc-menu-width', `100%`);
222
- return;
223
- }
224
- if (this.quiet)
225
- return;
226
- // only use `this.offsetWidth` when Standard variant
227
- popover.style.setProperty('min-width', `${this.offsetWidth}px`);
216
+ if (this.quiet)
217
+ return;
218
+ popover.style.setProperty("min-width", `${this.offsetWidth}px`);
219
+ }
220
+ async closeMenu() {
221
+ if (this.closeOverlay) {
222
+ const closeOverlay = this.closeOverlay;
223
+ delete this.closeOverlay;
224
+ (await closeOverlay)();
228
225
  }
229
- async closeMenu() {
230
- if (this.closeOverlay) {
231
- const closeOverlay = this.closeOverlay;
232
- delete this.closeOverlay;
233
- (await closeOverlay)();
234
- }
226
+ }
227
+ get selectedItemContent() {
228
+ if (this.selectedItem) {
229
+ return this.selectedItem.itemChildren;
235
230
  }
236
- get selectedItemContent() {
237
- if (this.selectedItem) {
238
- return this.selectedItem.itemChildren;
239
- }
240
- return { icon: [], content: [] };
231
+ return { icon: [], content: [] };
232
+ }
233
+ renderLabelContent(content) {
234
+ if (this.value && this.selectedItem) {
235
+ return content;
241
236
  }
242
- renderLabelContent(content) {
243
- if (this.value && this.selectedItem) {
244
- return content;
245
- }
246
- return html `
237
+ return html`
247
238
  <slot name="label">${this.label}</slot>
248
239
  `;
249
- }
250
- get buttonContent() {
251
- const labelClasses = {
252
- 'visually-hidden': this.icons === 'only' && !!this.value,
253
- placeholder: !this.value,
254
- };
255
- return [
256
- html `
257
- <span id="icon" ?hidden=${this.icons === 'none'}>
240
+ }
241
+ get buttonContent() {
242
+ const labelClasses = {
243
+ "visually-hidden": this.icons === "only" && !!this.value,
244
+ placeholder: !this.value
245
+ };
246
+ return [
247
+ html`
248
+ <span id="icon" ?hidden=${this.icons === "none"}>
258
249
  ${this.selectedItemContent.icon}
259
250
  </span>
260
251
  <span id="label" class=${classMap(labelClasses)}>
261
252
  ${this.renderLabelContent(this.selectedItemContent.content)}
262
253
  </span>
263
- ${this.invalid
264
- ? html `
254
+ ${this.invalid ? html`
265
255
  <sp-icon-alert
266
256
  class="validation-icon"
267
257
  ></sp-icon-alert>
268
- `
269
- : nothing}
258
+ ` : nothing}
270
259
  <sp-icon-chevron100
271
260
  class="picker ${chevronClass[this.size]}"
272
261
  ></sp-icon-chevron100>
273
- `,
274
- ];
275
- }
276
- // a helper to throw focus to the button is needed because Safari
277
- // won't include buttons in the tab order even with tabindex="0"
278
- render() {
279
- return html `
262
+ `
263
+ ];
264
+ }
265
+ render() {
266
+ return html`
280
267
  <span
281
268
  id="focus-helper"
282
- tabindex="${this.focused ? '-1' : '0'}"
269
+ tabindex="${this.focused ? "-1" : "0"}"
283
270
  @focus=${this.onHelperFocus}
284
271
  ></span>
285
272
  <button
286
273
  aria-haspopup="true"
287
- aria-expanded=${this.open ? 'true' : 'false'}
274
+ aria-expanded=${this.open ? "true" : "false"}
288
275
  aria-labelledby="button icon label"
289
276
  id="button"
290
277
  class="button"
@@ -297,33 +284,35 @@ export class PickerBase extends SizedMixin(Focusable) {
297
284
  ${this.buttonContent}
298
285
  </button>
299
286
  `;
287
+ }
288
+ update(changes) {
289
+ if (this.selects) {
290
+ this.selects = "single";
300
291
  }
301
- update(changes) {
302
- if (this.selects) {
303
- // Always force `selects` to "single" when set.
304
- // TODO: Add support functionally and visually for "multiple"
305
- this.selects = 'single';
306
- }
307
- if (changes.has('disabled') && this.disabled) {
308
- this.open = false;
309
- }
310
- if (changes.has('open') &&
311
- (this.open || typeof changes.get('open') !== 'undefined')) {
312
- this.menuStatePromise = new Promise((res) => (this.menuStateResolver = res));
313
- if (this.open) {
314
- this.openMenu();
315
- }
316
- else {
317
- this.closeMenu();
318
- }
319
- }
320
- if (changes.has('value') && !changes.has('selectedItem')) {
321
- this.updateMenuItems();
322
- }
323
- super.update(changes);
292
+ if (changes.has("disabled") && this.disabled) {
293
+ this.open = false;
324
294
  }
325
- get dismissHelper() {
326
- return html `
295
+ if (changes.has("open") && (this.open || typeof changes.get("open") !== "undefined")) {
296
+ this.menuStatePromise = new Promise((res) => this.menuStateResolver = res);
297
+ if (this.open) {
298
+ this.openMenu();
299
+ } else {
300
+ this.closeMenu();
301
+ }
302
+ }
303
+ if (changes.has("value") && !changes.has("selectedItem")) {
304
+ this.updateMenuItems();
305
+ }
306
+ if (false) {
307
+ if (!this.hasUpdated && this.querySelector("sp-menu")) {
308
+ const { localName } = this;
309
+ window.__swc.warn(this, `You no longer need to provide an <sp-menu> child to ${localName}. Any styling or attributes on the <sp-menu> will be ignored.`, "https://opensource.adobe.com/spectrum-web-components/components/picker/#sizes", { level: "deprecation" });
310
+ }
311
+ }
312
+ super.update(changes);
313
+ }
314
+ get dismissHelper() {
315
+ return html`
327
316
  <div class="visually-hidden">
328
317
  <button
329
318
  tabindex="-1"
@@ -332,9 +321,9 @@ export class PickerBase extends SizedMixin(Focusable) {
332
321
  ></button>
333
322
  </div>
334
323
  `;
335
- }
336
- get renderPopover() {
337
- const content = html `
324
+ }
325
+ get renderPopover() {
326
+ const content = html`
338
327
  ${this.dismissHelper}
339
328
  <sp-menu
340
329
  id="menu"
@@ -344,8 +333,8 @@ export class PickerBase extends SizedMixin(Focusable) {
344
333
  ></sp-menu>
345
334
  ${this.dismissHelper}
346
335
  `;
347
- if (this.isMobile.matches) {
348
- return html `
336
+ if (this.isMobile.matches) {
337
+ return html`
349
338
  <sp-tray
350
339
  id="popover"
351
340
  role="dialog"
@@ -356,8 +345,8 @@ export class PickerBase extends SizedMixin(Focusable) {
356
345
  ${content}
357
346
  </sp-tray>
358
347
  `;
359
- }
360
- return html `
348
+ }
349
+ return html`
361
350
  <sp-popover
362
351
  id="popover"
363
352
  role="dialog"
@@ -368,163 +357,145 @@ export class PickerBase extends SizedMixin(Focusable) {
368
357
  ${content}
369
358
  </sp-popover>
370
359
  `;
360
+ }
361
+ updateMenuItems(event) {
362
+ if (this.open && (event == null ? void 0 : event.type) === "sp-menu-item-removed")
363
+ return;
364
+ if (this._willUpdateItems)
365
+ return;
366
+ this._willUpdateItems = true;
367
+ if ((event == null ? void 0 : event.item) === this.selectedItem) {
368
+ this.requestUpdate();
371
369
  }
372
- /**
373
- * Acquire the available MenuItems in the Picker by
374
- * direct element query or by assuming the list managed
375
- * by the Menu within the open options overlay.
376
- */
377
- updateMenuItems(event) {
378
- if (this.open && (event === null || event === void 0 ? void 0 : event.type) === 'sp-menu-item-removed')
379
- return;
380
- if (this._willUpdateItems)
381
- return;
382
- this._willUpdateItems = true;
383
- if ((event === null || event === void 0 ? void 0 : event.item) === this.selectedItem) {
384
- this.requestUpdate();
385
- }
386
- let resolve = () => {
387
- return;
388
- };
389
- this.itemsUpdated = new Promise((res) => (resolve = res));
390
- // Debounce the update so we only update once
391
- // if multiple items have changed
392
- window.requestAnimationFrame(async () => {
393
- if (this.open) {
394
- await this.optionsMenu.updateComplete;
395
- this.menuItems = this.optionsMenu.childItems;
396
- }
397
- else {
398
- this.menuItems = [
399
- ...this.querySelectorAll('sp-menu-item'),
400
- ];
401
- }
402
- this.manageSelection();
403
- resolve();
404
- this._willUpdateItems = false;
405
- });
406
- }
407
- async manageSelection() {
408
- await this.menuStatePromise;
409
- this.selectionPromise = new Promise((res) => (this.selectionResolver = res));
410
- let selectedItem;
411
- this.menuItems.forEach((item) => {
412
- if (this.value === item.value && !item.disabled) {
413
- selectedItem = item;
414
- }
415
- else {
416
- item.selected = false;
417
- }
418
- });
419
- if (selectedItem) {
420
- selectedItem.selected = !!this.selects;
421
- this.selectedItem = selectedItem;
422
- }
423
- else {
424
- this.value = '';
425
- this.selectedItem = undefined;
426
- }
427
- if (this.open) {
428
- await this.optionsMenu.updateComplete;
429
- this.optionsMenu.updateSelectedItemIndex();
430
- }
431
- this.selectionResolver();
432
- }
433
- async getUpdateComplete() {
434
- const complete = (await super.getUpdateComplete());
435
- await this.menuStatePromise;
436
- await this.itemsUpdated;
437
- await this.selectionPromise;
438
- return complete;
439
- }
440
- connectedCallback() {
441
- this.updateMenuItems();
442
- this.addEventListener('sp-menu-item-added-or-updated', this.updateMenuItems);
443
- this.addEventListener('sp-menu-item-removed', this.updateMenuItems);
444
- super.connectedCallback();
370
+ let resolve = () => {
371
+ return;
372
+ };
373
+ this.itemsUpdated = new Promise((res) => resolve = res);
374
+ window.requestAnimationFrame(async () => {
375
+ if (this.open) {
376
+ await this.optionsMenu.updateComplete;
377
+ this.menuItems = this.optionsMenu.childItems;
378
+ } else {
379
+ this.menuItems = [
380
+ ...this.querySelectorAll('sp-menu-item:not([slot="submenu"] *)')
381
+ ];
382
+ }
383
+ this.manageSelection();
384
+ resolve();
385
+ this._willUpdateItems = false;
386
+ });
387
+ }
388
+ async manageSelection() {
389
+ await this.menuStatePromise;
390
+ this.selectionPromise = new Promise((res) => this.selectionResolver = res);
391
+ let selectedItem;
392
+ this.menuItems.forEach((item) => {
393
+ if (this.value === item.value && !item.disabled) {
394
+ selectedItem = item;
395
+ } else {
396
+ item.selected = false;
397
+ }
398
+ });
399
+ if (selectedItem) {
400
+ selectedItem.selected = !!this.selects;
401
+ this.selectedItem = selectedItem;
402
+ } else {
403
+ this.value = "";
404
+ this.selectedItem = void 0;
445
405
  }
446
- disconnectedCallback() {
447
- this.close();
448
- super.disconnectedCallback();
406
+ if (this.open) {
407
+ await this.optionsMenu.updateComplete;
408
+ this.optionsMenu.updateSelectedItemIndex();
449
409
  }
410
+ this.selectionResolver();
411
+ }
412
+ async getUpdateComplete() {
413
+ const complete = await super.getUpdateComplete();
414
+ await this.menuStatePromise;
415
+ await this.itemsUpdated;
416
+ await this.selectionPromise;
417
+ return complete;
418
+ }
419
+ connectedCallback() {
420
+ this.updateMenuItems();
421
+ this.addEventListener("sp-menu-item-added-or-updated", this.updateMenuItems);
422
+ this.addEventListener("sp-menu-item-removed", this.updateMenuItems);
423
+ super.connectedCallback();
424
+ }
425
+ disconnectedCallback() {
426
+ this.close();
427
+ super.disconnectedCallback();
428
+ }
450
429
  }
451
- _a = PickerBase;
452
- /**
453
- * @private
454
- */
455
430
  PickerBase.openOverlay = async (target, interaction, content, options) => {
456
- return await openOverlay(target, interaction, content, options);
431
+ return await openOverlay(target, interaction, content, options);
457
432
  };
458
- __decorate([
459
- query('#button')
460
- ], PickerBase.prototype, "button", void 0);
461
- __decorate([
462
- property({ type: Boolean, reflect: true })
463
- ], PickerBase.prototype, "disabled", void 0);
464
- __decorate([
465
- property({ type: Boolean, reflect: true })
466
- ], PickerBase.prototype, "focused", void 0);
467
- __decorate([
468
- property({ type: String, reflect: true })
469
- ], PickerBase.prototype, "icons", void 0);
470
- __decorate([
471
- property({ type: Boolean, reflect: true })
472
- ], PickerBase.prototype, "invalid", void 0);
473
- __decorate([
474
- property()
475
- ], PickerBase.prototype, "label", void 0);
476
- __decorate([
477
- property({ type: Boolean, reflect: true })
478
- ], PickerBase.prototype, "open", void 0);
479
- __decorate([
480
- property({ type: Boolean, reflect: true })
481
- ], PickerBase.prototype, "readonly", void 0);
482
- __decorate([
483
- property()
484
- ], PickerBase.prototype, "placement", void 0);
485
- __decorate([
486
- property({ type: Boolean, reflect: true })
487
- ], PickerBase.prototype, "quiet", void 0);
488
- __decorate([
489
- property({ type: String })
490
- ], PickerBase.prototype, "value", void 0);
491
- __decorate([
492
- property({ attribute: false })
493
- ], PickerBase.prototype, "selectedItem", void 0);
433
+ __decorateClass([
434
+ query("#button")
435
+ ], PickerBase.prototype, "button", 2);
436
+ __decorateClass([
437
+ property({ type: Boolean, reflect: true })
438
+ ], PickerBase.prototype, "disabled", 2);
439
+ __decorateClass([
440
+ property({ type: Boolean, reflect: true })
441
+ ], PickerBase.prototype, "focused", 2);
442
+ __decorateClass([
443
+ property({ type: String, reflect: true })
444
+ ], PickerBase.prototype, "icons", 2);
445
+ __decorateClass([
446
+ property({ type: Boolean, reflect: true })
447
+ ], PickerBase.prototype, "invalid", 2);
448
+ __decorateClass([
449
+ property()
450
+ ], PickerBase.prototype, "label", 2);
451
+ __decorateClass([
452
+ property({ type: Boolean, reflect: true })
453
+ ], PickerBase.prototype, "open", 2);
454
+ __decorateClass([
455
+ property({ type: Boolean, reflect: true })
456
+ ], PickerBase.prototype, "readonly", 2);
457
+ __decorateClass([
458
+ property()
459
+ ], PickerBase.prototype, "placement", 2);
460
+ __decorateClass([
461
+ property({ type: Boolean, reflect: true })
462
+ ], PickerBase.prototype, "quiet", 2);
463
+ __decorateClass([
464
+ property({ type: String })
465
+ ], PickerBase.prototype, "value", 2);
466
+ __decorateClass([
467
+ property({ attribute: false })
468
+ ], PickerBase.prototype, "selectedItem", 2);
494
469
  export class Picker extends PickerBase {
495
- constructor() {
496
- super(...arguments);
497
- this.onKeydown = (event) => {
498
- const { code } = event;
499
- this.focused = true;
500
- if (!code.startsWith('Arrow') || this.readonly) {
501
- return;
502
- }
503
- event.preventDefault();
504
- if (code === 'ArrowUp' || code === 'ArrowDown') {
505
- this.toggle(true);
506
- return;
507
- }
508
- const selectedIndex = this.selectedItem
509
- ? this.menuItems.indexOf(this.selectedItem)
510
- : -1;
511
- // use a positive offset to find the first non-disabled item when no selection is available.
512
- const nextOffset = !this.value || code === 'ArrowRight' ? 1 : -1;
513
- let nextIndex = selectedIndex + nextOffset;
514
- while (this.menuItems[nextIndex] &&
515
- this.menuItems[nextIndex].disabled) {
516
- nextIndex += nextOffset;
517
- }
518
- if (!this.menuItems[nextIndex] || this.menuItems[nextIndex].disabled) {
519
- return;
520
- }
521
- if (!this.value || nextIndex !== selectedIndex) {
522
- this.setValueFromItem(this.menuItems[nextIndex]);
523
- }
524
- };
525
- }
526
- static get styles() {
527
- return [pickerStyles, chevronStyles];
528
- }
470
+ constructor() {
471
+ super(...arguments);
472
+ this.onKeydown = (event) => {
473
+ const { code } = event;
474
+ this.focused = true;
475
+ if (!code.startsWith("Arrow") || this.readonly) {
476
+ return;
477
+ }
478
+ event.preventDefault();
479
+ if (code === "ArrowUp" || code === "ArrowDown") {
480
+ this.toggle(true);
481
+ return;
482
+ }
483
+ const selectedIndex = this.selectedItem ? this.menuItems.indexOf(this.selectedItem) : -1;
484
+ const nextOffset = !this.value || code === "ArrowRight" ? 1 : -1;
485
+ let nextIndex = selectedIndex + nextOffset;
486
+ while (this.menuItems[nextIndex] && this.menuItems[nextIndex].disabled) {
487
+ nextIndex += nextOffset;
488
+ }
489
+ if (!this.menuItems[nextIndex] || this.menuItems[nextIndex].disabled) {
490
+ return;
491
+ }
492
+ if (!this.value || nextIndex !== selectedIndex) {
493
+ this.setValueFromItem(this.menuItems[nextIndex]);
494
+ }
495
+ };
496
+ }
497
+ static get styles() {
498
+ return [pickerStyles, chevronStyles];
499
+ }
529
500
  }
530
- //# sourceMappingURL=Picker.js.map
501
+ //# sourceMappingURL=Picker.js.map