@spectrum-web-components/picker 0.11.5 → 0.11.6-devmode.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 (51) hide show
  1. package/package.json +38 -21
  2. package/sp-picker.dev.js +3 -0
  3. package/sp-picker.dev.js.map +7 -0
  4. package/sp-picker.js +3 -14
  5. package/sp-picker.js.map +7 -1
  6. package/src/Picker.dev.js +501 -0
  7. package/src/Picker.dev.js.map +7 -0
  8. package/src/Picker.js +405 -434
  9. package/src/Picker.js.map +7 -1
  10. package/src/index.dev.js +2 -0
  11. package/src/index.dev.js.map +7 -0
  12. package/src/index.js +2 -13
  13. package/src/index.js.map +7 -1
  14. package/src/picker.css.dev.js +304 -0
  15. package/src/picker.css.dev.js.map +7 -0
  16. package/src/picker.css.js +3 -14
  17. package/src/picker.css.js.map +7 -1
  18. package/src/spectrum-picker.css.dev.js +300 -0
  19. package/src/spectrum-picker.css.dev.js.map +7 -0
  20. package/src/spectrum-picker.css.js +3 -14
  21. package/src/spectrum-picker.css.js.map +7 -1
  22. package/stories/picker-sizes.stories.js +22 -30
  23. package/stories/picker-sizes.stories.js.map +7 -1
  24. package/stories/picker.stories.js +84 -95
  25. package/stories/picker.stories.js.map +7 -1
  26. package/stories/states.js +225 -236
  27. package/stories/states.js.map +7 -1
  28. package/sync/index.dev.js +8 -0
  29. package/sync/index.dev.js.map +7 -0
  30. package/sync/index.js +6 -15
  31. package/sync/index.js.map +7 -1
  32. package/sync/sp-picker.dev.js +3 -0
  33. package/sync/sp-picker.dev.js.map +7 -0
  34. package/sync/sp-picker.js +3 -14
  35. package/sync/sp-picker.js.map +7 -1
  36. package/test/benchmark/basic-test.js +256 -267
  37. package/test/benchmark/basic-test.js.map +7 -1
  38. package/test/index.js +830 -844
  39. package/test/index.js.map +7 -1
  40. package/test/picker-reparenting.test.js +71 -76
  41. package/test/picker-reparenting.test.js.map +7 -1
  42. package/test/picker-responsive.test.js +41 -53
  43. package/test/picker-responsive.test.js.map +7 -1
  44. package/test/picker-sizes.test-vrt.js +4 -15
  45. package/test/picker-sizes.test-vrt.js.map +7 -1
  46. package/test/picker-sync.test.js +5 -16
  47. package/test/picker-sync.test.js.map +7 -1
  48. package/test/picker.test-vrt.js +4 -15
  49. package/test/picker.test-vrt.js.map +7 -1
  50. package/test/picker.test.js +5 -16
  51. package/test/picker.test.js.map +7 -1
package/src/Picker.js CHANGED
@@ -1,290 +1,283 @@
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);
90
- }
91
- get target() {
92
- return this.button;
93
- }
94
- get focusElement() {
95
- if (this.open) {
96
- return this.optionsMenu;
97
- }
98
- return this.button;
99
- }
100
- forceFocusVisible() {
101
- this.focused = true;
102
- }
103
- onButtonBlur() {
104
- this.focused = false;
105
- this.target.removeEventListener('keydown', this.onKeydown);
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;
106
95
  }
107
- onButtonClick() {
108
- this.toggle();
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();
109
112
  }
110
- focus(options) {
111
- super.focus(options);
112
- if (!this.disabled && this.focusElement) {
113
- this.focused = this.hasVisibleFocusInTree();
114
- }
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;
115
151
  }
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();
152
+ if (oldSelectedItem) {
153
+ oldSelectedItem.selected = false;
120
154
  }
121
- onButtonFocus() {
122
- this.target.addEventListener('keydown', this.onKeydown);
155
+ item.selected = !!this.selects;
156
+ }
157
+ toggle(target) {
158
+ if (this.readonly) {
159
+ return;
123
160
  }
124
- handleChange(event) {
125
- event.stopPropagation();
126
- const target = event.target;
127
- const [selected] = target.selectedItems;
128
- this.setValueFromItem(selected, event);
161
+ this.open = typeof target !== "undefined" ? target : !this.open;
162
+ }
163
+ close() {
164
+ if (this.readonly) {
165
+ return;
129
166
  }
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;
154
- }
155
- if (oldSelectedItem) {
156
- oldSelectedItem.selected = false;
157
- }
158
- item.selected = !!this.selects;
167
+ this.open = false;
168
+ }
169
+ async generatePopover(deprecatedMenu) {
170
+ if (!this.popoverFragment) {
171
+ this.popoverFragment = document.createDocumentFragment();
159
172
  }
160
- toggle(target) {
161
- if (this.readonly) {
162
- return;
163
- }
164
- this.open = typeof target !== 'undefined' ? target : !this.open;
173
+ render(this.renderPopover, this.popoverFragment, { host: this });
174
+ this.popover = this.popoverFragment.children[0];
175
+ this.optionsMenu = this.popover.children[1];
176
+ if (false) {
177
+ if (deprecatedMenu) {
178
+ const { localName } = this;
179
+ window.__swc.issueWarning(`${localName}:api:deprecation`, `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");
180
+ }
165
181
  }
166
- close() {
167
- if (this.readonly) {
168
- return;
169
- }
170
- this.open = false;
182
+ }
183
+ async openMenu() {
184
+ let reparentableChildren = [];
185
+ const deprecatedMenu = this.querySelector(":scope > sp-menu");
186
+ await this.generatePopover(deprecatedMenu);
187
+ if (deprecatedMenu) {
188
+ reparentableChildren = Array.from(deprecatedMenu.children);
189
+ } else {
190
+ reparentableChildren = Array.from(this.children).filter((element) => {
191
+ return !element.hasAttribute("slot");
192
+ });
171
193
  }
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
- }
194
+ if (reparentableChildren.length === 0) {
195
+ this.menuStateResolver();
196
+ return;
182
197
  }
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;
198
+ this.restoreChildren = reparentChildren(reparentableChildren, this.optionsMenu, {
199
+ position: "beforeend",
200
+ prepareCallback: (el) => {
201
+ if (this.value === el.value) {
202
+ el.selected = true;
199
203
  }
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
- });
204
+ return (el2) => {
205
+ if (typeof el2.focused !== "undefined") {
206
+ el2.focused = false;
207
+ }
208
+ };
209
+ }
210
+ });
211
+ this.sizePopover(this.popover);
212
+ this.closeOverlay = Picker.openOverlay(this, "modal", this.popover, {
213
+ placement: this.isMobile.matches ? "none" : this.placement,
214
+ receivesFocus: "auto"
215
+ });
216
+ }
217
+ sizePopover(popover) {
218
+ if (this.isMobile.matches) {
219
+ popover.style.setProperty("--swc-menu-width", `100%`);
220
+ return;
218
221
  }
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`);
222
+ if (this.quiet)
223
+ return;
224
+ popover.style.setProperty("min-width", `${this.offsetWidth}px`);
225
+ }
226
+ async closeMenu() {
227
+ if (this.closeOverlay) {
228
+ const closeOverlay = this.closeOverlay;
229
+ delete this.closeOverlay;
230
+ (await closeOverlay)();
228
231
  }
229
- async closeMenu() {
230
- if (this.closeOverlay) {
231
- const closeOverlay = this.closeOverlay;
232
- delete this.closeOverlay;
233
- (await closeOverlay)();
234
- }
232
+ }
233
+ get selectedItemContent() {
234
+ if (this.selectedItem) {
235
+ return this.selectedItem.itemChildren;
235
236
  }
236
- get selectedItemContent() {
237
- if (this.selectedItem) {
238
- return this.selectedItem.itemChildren;
239
- }
240
- return { icon: [], content: [] };
237
+ return { icon: [], content: [] };
238
+ }
239
+ renderLabelContent(content) {
240
+ if (this.value && this.selectedItem) {
241
+ return content;
241
242
  }
242
- renderLabelContent(content) {
243
- if (this.value && this.selectedItem) {
244
- return content;
245
- }
246
- return html `
243
+ return html`
247
244
  <slot name="label">${this.label}</slot>
248
245
  `;
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'}>
246
+ }
247
+ get buttonContent() {
248
+ const labelClasses = {
249
+ "visually-hidden": this.icons === "only" && !!this.value,
250
+ placeholder: !this.value
251
+ };
252
+ return [
253
+ html`
254
+ <span id="icon" ?hidden=${this.icons === "none"}>
258
255
  ${this.selectedItemContent.icon}
259
256
  </span>
260
257
  <span id="label" class=${classMap(labelClasses)}>
261
258
  ${this.renderLabelContent(this.selectedItemContent.content)}
262
259
  </span>
263
- ${this.invalid
264
- ? html `
260
+ ${this.invalid ? html`
265
261
  <sp-icon-alert
266
262
  class="validation-icon"
267
263
  ></sp-icon-alert>
268
- `
269
- : nothing}
264
+ ` : nothing}
270
265
  <sp-icon-chevron100
271
266
  class="picker ${chevronClass[this.size]}"
272
267
  ></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 `
268
+ `
269
+ ];
270
+ }
271
+ render() {
272
+ return html`
280
273
  <span
281
274
  id="focus-helper"
282
- tabindex="${this.focused ? '-1' : '0'}"
275
+ tabindex="${this.focused ? "-1" : "0"}"
283
276
  @focus=${this.onHelperFocus}
284
277
  ></span>
285
278
  <button
286
279
  aria-haspopup="true"
287
- aria-expanded=${this.open ? 'true' : 'false'}
280
+ aria-expanded=${this.open ? "true" : "false"}
288
281
  aria-labelledby="button icon label"
289
282
  id="button"
290
283
  class="button"
@@ -297,33 +290,29 @@ export class PickerBase extends SizedMixin(Focusable) {
297
290
  ${this.buttonContent}
298
291
  </button>
299
292
  `;
293
+ }
294
+ update(changes) {
295
+ if (this.selects) {
296
+ this.selects = "single";
300
297
  }
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);
298
+ if (changes.has("disabled") && this.disabled) {
299
+ this.open = false;
300
+ }
301
+ if (changes.has("open") && (this.open || typeof changes.get("open") !== "undefined")) {
302
+ this.menuStatePromise = new Promise((res) => this.menuStateResolver = res);
303
+ if (this.open) {
304
+ this.openMenu();
305
+ } else {
306
+ this.closeMenu();
307
+ }
308
+ }
309
+ if (changes.has("value") && !changes.has("selectedItem")) {
310
+ this.updateMenuItems();
324
311
  }
325
- get dismissHelper() {
326
- return html `
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")
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