@spectrum-web-components/picker 0.11.3 → 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 (52) hide show
  1. package/package.json +39 -22
  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.d.ts +0 -1
  7. package/src/Picker.dev.js +501 -0
  8. package/src/Picker.dev.js.map +7 -0
  9. package/src/Picker.js +424 -457
  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 +17 -38
  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 +17 -38
  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 +830 -836
  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,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);
106
- }
107
- onButtonClick() {
108
- this.toggle();
109
- }
110
- focus(options) {
111
- super.focus(options);
112
- if (!this.disabled && this.focusElement) {
113
- this.focused = this.hasVisibleFocusInTree();
114
- }
115
- }
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();
120
- }
121
- onButtonFocus() {
122
- this.target.addEventListener('keydown', this.onKeydown);
123
- }
124
- handleChange(event) {
125
- event.stopPropagation();
126
- const target = event.target;
127
- const [selected] = target.selectedItems;
128
- this.setValueFromItem(selected, event);
129
- }
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;
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
- });
218
- }
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`);
228
- }
229
- async closeMenu() {
230
- if (this.closeOverlay) {
231
- const closeOverlay = this.closeOverlay;
232
- delete this.closeOverlay;
233
- (await closeOverlay)();
234
- }
235
- }
236
- get selectedItemContent() {
237
- if (this.selectedItem) {
238
- return this.selectedItem.itemChildren;
239
- }
240
- return { icon: [], content: [] };
241
- }
242
- renderLabelContent(content) {
243
- if (this.value && this.selectedItem) {
244
- return content;
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;
95
+ }
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();
112
+ }
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;
151
+ }
152
+ if (oldSelectedItem) {
153
+ oldSelectedItem.selected = false;
154
+ }
155
+ item.selected = !!this.selects;
156
+ }
157
+ toggle(target) {
158
+ if (this.readonly) {
159
+ return;
160
+ }
161
+ this.open = typeof target !== "undefined" ? target : !this.open;
162
+ }
163
+ close() {
164
+ if (this.readonly) {
165
+ return;
166
+ }
167
+ this.open = false;
168
+ }
169
+ async generatePopover(deprecatedMenu) {
170
+ if (!this.popoverFragment) {
171
+ this.popoverFragment = document.createDocumentFragment();
172
+ }
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
+ }
181
+ }
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
+ });
193
+ }
194
+ if (reparentableChildren.length === 0) {
195
+ this.menuStateResolver();
196
+ return;
197
+ }
198
+ this.restoreChildren = reparentChildren(reparentableChildren, this.optionsMenu, {
199
+ position: "beforeend",
200
+ prepareCallback: (el) => {
201
+ if (this.value === el.value) {
202
+ el.selected = true;
245
203
  }
246
- return html `
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;
221
+ }
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)();
231
+ }
232
+ }
233
+ get selectedItemContent() {
234
+ if (this.selectedItem) {
235
+ return this.selectedItem.itemChildren;
236
+ }
237
+ return { icon: [], content: [] };
238
+ }
239
+ renderLabelContent(content) {
240
+ if (this.value && this.selectedItem) {
241
+ return content;
242
+ }
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,17 +290,29 @@ export class PickerBase extends SizedMixin(Focusable) {
297
290
  ${this.buttonContent}
298
291
  </button>
299
292
  `;
300
- }
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
- super.update(changes);
308
- }
309
- get dismissHelper() {
310
- return html `
293
+ }
294
+ update(changes) {
295
+ if (this.selects) {
296
+ this.selects = "single";
297
+ }
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();
311
+ }
312
+ super.update(changes);
313
+ }
314
+ get dismissHelper() {
315
+ return html`
311
316
  <div class="visually-hidden">
312
317
  <button
313
318
  tabindex="-1"
@@ -316,9 +321,9 @@ export class PickerBase extends SizedMixin(Focusable) {
316
321
  ></button>
317
322
  </div>
318
323
  `;
319
- }
320
- get renderPopover() {
321
- const content = html `
324
+ }
325
+ get renderPopover() {
326
+ const content = html`
322
327
  ${this.dismissHelper}
323
328
  <sp-menu
324
329
  id="menu"
@@ -328,8 +333,8 @@ export class PickerBase extends SizedMixin(Focusable) {
328
333
  ></sp-menu>
329
334
  ${this.dismissHelper}
330
335
  `;
331
- if (this.isMobile.matches) {
332
- return html `
336
+ if (this.isMobile.matches) {
337
+ return html`
333
338
  <sp-tray
334
339
  id="popover"
335
340
  role="dialog"
@@ -340,8 +345,8 @@ export class PickerBase extends SizedMixin(Focusable) {
340
345
  ${content}
341
346
  </sp-tray>
342
347
  `;
343
- }
344
- return html `
348
+ }
349
+ return html`
345
350
  <sp-popover
346
351
  id="popover"
347
352
  role="dialog"
@@ -352,183 +357,145 @@ export class PickerBase extends SizedMixin(Focusable) {
352
357
  ${content}
353
358
  </sp-popover>
354
359
  `;
355
- }
356
- /**
357
- * Acquire the available MenuItems in the Picker by
358
- * direct element query or by assuming the list managed
359
- * by the Menu within the open options overlay.
360
- */
361
- updateMenuItems(event) {
362
- if (this.open && (event === null || event === void 0 ? void 0 : event.type) === 'sp-menu-item-removed')
363
- return;
364
- if (this._willUpdateItems)
365
- return;
366
- this._willUpdateItems = true;
367
- if ((event === null || event === void 0 ? void 0 : event.item) === this.selectedItem) {
368
- this.requestUpdate();
369
- }
370
- let resolve = () => {
371
- return;
372
- };
373
- this.itemsUpdated = new Promise((res) => (resolve = res));
374
- // Debounce the update so we only update once
375
- // if multiple items have changed
376
- window.requestAnimationFrame(async () => {
377
- if (this.open) {
378
- await this.optionsMenu.updateComplete;
379
- this.menuItems = this.optionsMenu.childItems;
380
- }
381
- else {
382
- this.menuItems = [
383
- ...this.querySelectorAll('sp-menu-item'),
384
- ];
385
- }
386
- this.manageSelection();
387
- resolve();
388
- this._willUpdateItems = false;
389
- });
390
- }
391
- updated(changedProperties) {
392
- super.updated(changedProperties);
393
- if (changedProperties.has('disabled') && this.disabled) {
394
- this.open = false;
395
- }
396
- if (changedProperties.has('open') &&
397
- (this.open || typeof changedProperties.get('open') !== 'undefined')) {
398
- this.menuStatePromise = new Promise((res) => (this.menuStateResolver = res));
399
- if (this.open) {
400
- this.openMenu();
401
- }
402
- else {
403
- this.closeMenu();
404
- }
405
- }
406
- if (changedProperties.has('value') &&
407
- !changedProperties.has('selectedItem')) {
408
- this.updateMenuItems();
409
- }
410
- }
411
- async manageSelection() {
412
- await this.menuStatePromise;
413
- this.selectionPromise = new Promise((res) => (this.selectionResolver = res));
414
- let selectedItem;
415
- this.menuItems.forEach((item) => {
416
- if (this.value === item.value && !item.disabled) {
417
- selectedItem = item;
418
- }
419
- else {
420
- item.selected = false;
421
- }
422
- });
423
- if (selectedItem) {
424
- selectedItem.selected = !!this.selects;
425
- this.selectedItem = selectedItem;
426
- }
427
- else {
428
- this.value = '';
429
- this.selectedItem = undefined;
430
- }
431
- if (this.open) {
432
- await this.optionsMenu.updateComplete;
433
- this.optionsMenu.updateSelectedItemIndex();
434
- }
435
- this.selectionResolver();
436
- }
437
- async getUpdateComplete() {
438
- const complete = (await super.getUpdateComplete());
439
- await this.menuStatePromise;
440
- await this.itemsUpdated;
441
- await this.selectionPromise;
442
- return complete;
443
- }
444
- connectedCallback() {
445
- this.updateMenuItems();
446
- this.addEventListener('sp-menu-item-added-or-updated', this.updateMenuItems);
447
- this.addEventListener('sp-menu-item-removed', this.updateMenuItems);
448
- super.connectedCallback();
449
- }
450
- disconnectedCallback() {
451
- this.close();
452
- super.disconnectedCallback();
453
- }
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();
369
+ }
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;
405
+ }
406
+ if (this.open) {
407
+ await this.optionsMenu.updateComplete;
408
+ this.optionsMenu.updateSelectedItemIndex();
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
+ }
454
429
  }
455
- _a = PickerBase;
456
- /**
457
- * @private
458
- */
459
430
  PickerBase.openOverlay = async (target, interaction, content, options) => {
460
- return await openOverlay(target, interaction, content, options);
431
+ return await openOverlay(target, interaction, content, options);
461
432
  };
462
- __decorate([
463
- query('#button')
464
- ], PickerBase.prototype, "button", void 0);
465
- __decorate([
466
- property({ type: Boolean, reflect: true })
467
- ], PickerBase.prototype, "disabled", void 0);
468
- __decorate([
469
- property({ type: Boolean, reflect: true })
470
- ], PickerBase.prototype, "focused", void 0);
471
- __decorate([
472
- property({ type: String, reflect: true })
473
- ], PickerBase.prototype, "icons", void 0);
474
- __decorate([
475
- property({ type: Boolean, reflect: true })
476
- ], PickerBase.prototype, "invalid", void 0);
477
- __decorate([
478
- property()
479
- ], PickerBase.prototype, "label", void 0);
480
- __decorate([
481
- property({ type: Boolean, reflect: true })
482
- ], PickerBase.prototype, "open", void 0);
483
- __decorate([
484
- property({ type: Boolean, reflect: true })
485
- ], PickerBase.prototype, "readonly", void 0);
486
- __decorate([
487
- property()
488
- ], PickerBase.prototype, "placement", void 0);
489
- __decorate([
490
- property({ type: Boolean, reflect: true })
491
- ], PickerBase.prototype, "quiet", void 0);
492
- __decorate([
493
- property({ type: String })
494
- ], PickerBase.prototype, "value", void 0);
495
- __decorate([
496
- property({ attribute: false })
497
- ], 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);
498
469
  export class Picker extends PickerBase {
499
- constructor() {
500
- super(...arguments);
501
- this.onKeydown = (event) => {
502
- const { code } = event;
503
- this.focused = true;
504
- if (!code.startsWith('Arrow') || this.readonly) {
505
- return;
506
- }
507
- event.preventDefault();
508
- if (code === 'ArrowUp' || code === 'ArrowDown') {
509
- this.toggle(true);
510
- return;
511
- }
512
- const selectedIndex = this.selectedItem
513
- ? this.menuItems.indexOf(this.selectedItem)
514
- : -1;
515
- // use a positive offset to find the first non-disabled item when no selection is available.
516
- const nextOffset = !this.value || code === 'ArrowRight' ? 1 : -1;
517
- let nextIndex = selectedIndex + nextOffset;
518
- while (this.menuItems[nextIndex] &&
519
- this.menuItems[nextIndex].disabled) {
520
- nextIndex += nextOffset;
521
- }
522
- if (!this.menuItems[nextIndex] || this.menuItems[nextIndex].disabled) {
523
- return;
524
- }
525
- if (!this.value || nextIndex !== selectedIndex) {
526
- this.setValueFromItem(this.menuItems[nextIndex]);
527
- }
528
- };
529
- }
530
- static get styles() {
531
- return [pickerStyles, chevronStyles];
532
- }
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
+ }
533
500
  }
534
- //# sourceMappingURL=Picker.js.map
501
+ //# sourceMappingURL=Picker.js.map