@spectrum-web-components/picker 0.10.3 → 0.10.4-express.0

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