@spectrum-web-components/picker 0.11.5 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/custom-elements.json +62 -78
- package/package.json +39 -22
- package/sp-picker.dev.js +3 -0
- package/sp-picker.dev.js.map +7 -0
- package/sp-picker.js +3 -14
- package/sp-picker.js.map +7 -1
- package/src/Picker.dev.js +501 -0
- package/src/Picker.dev.js.map +7 -0
- package/src/Picker.js +406 -435
- package/src/Picker.js.map +7 -1
- package/src/index.dev.js +2 -0
- package/src/index.dev.js.map +7 -0
- package/src/index.js +2 -13
- package/src/index.js.map +7 -1
- package/src/picker.css.dev.js +304 -0
- package/src/picker.css.dev.js.map +7 -0
- package/src/picker.css.js +4 -15
- package/src/picker.css.js.map +7 -1
- package/src/spectrum-picker.css.dev.js +300 -0
- package/src/spectrum-picker.css.dev.js.map +7 -0
- package/src/spectrum-picker.css.js +4 -15
- package/src/spectrum-picker.css.js.map +7 -1
- package/stories/picker-sizes.stories.js +22 -30
- package/stories/picker-sizes.stories.js.map +7 -1
- package/stories/picker.stories.js +84 -95
- package/stories/picker.stories.js.map +7 -1
- package/stories/states.js +225 -236
- package/stories/states.js.map +7 -1
- package/sync/index.dev.js +8 -0
- package/sync/index.dev.js.map +7 -0
- package/sync/index.js +6 -15
- package/sync/index.js.map +7 -1
- package/sync/sp-picker.dev.js +3 -0
- package/sync/sp-picker.dev.js.map +7 -0
- package/sync/sp-picker.js +3 -14
- package/sync/sp-picker.js.map +7 -1
- package/test/benchmark/basic-test.js +256 -267
- package/test/benchmark/basic-test.js.map +7 -1
- package/test/index.js +896 -839
- package/test/index.js.map +7 -1
- package/test/picker-reparenting.test.js +71 -76
- package/test/picker-reparenting.test.js.map +7 -1
- package/test/picker-responsive.test.js +41 -53
- package/test/picker-responsive.test.js.map +7 -1
- package/test/picker-sizes.test-vrt.js +4 -15
- package/test/picker-sizes.test-vrt.js.map +7 -1
- package/test/picker-sync.test.js +5 -16
- package/test/picker-sync.test.js.map +7 -1
- package/test/picker.test-vrt.js +4 -15
- package/test/picker.test-vrt.js.map +7 -1
- package/test/picker.test.js +5 -16
- package/test/picker.test.js.map +7 -1
package/src/Picker.js
CHANGED
|
@@ -1,290 +1,277 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
import
|
|
19
|
-
import {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
import
|
|
24
|
-
import
|
|
25
|
-
import
|
|
26
|
-
import {
|
|
27
|
-
import
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
46
|
+
constructor() {
|
|
47
|
+
super();
|
|
48
|
+
this.isMobile = new MatchMediaController(this, IS_MOBILE);
|
|
49
|
+
this.disabled = false;
|
|
50
|
+
this.focused = false;
|
|
51
|
+
this.invalid = false;
|
|
52
|
+
this.open = false;
|
|
53
|
+
this.readonly = false;
|
|
54
|
+
this.selects = "single";
|
|
55
|
+
this.menuItems = [];
|
|
56
|
+
this.placement = "bottom-start";
|
|
57
|
+
this.quiet = false;
|
|
58
|
+
this.value = "";
|
|
59
|
+
this.listRole = "listbox";
|
|
60
|
+
this.itemRole = "option";
|
|
61
|
+
this.onKeydown = (event) => {
|
|
62
|
+
this.focused = true;
|
|
63
|
+
if (event.code !== "ArrowDown" && event.code !== "ArrowUp") {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
event.preventDefault();
|
|
67
|
+
this.toggle(true);
|
|
68
|
+
};
|
|
69
|
+
this.overlayOpenCallback = async () => {
|
|
70
|
+
this.updateMenuItems();
|
|
71
|
+
await this.itemsUpdated;
|
|
72
|
+
await this.optionsMenu.updateComplete;
|
|
73
|
+
requestAnimationFrame(() => this.menuStateResolver());
|
|
74
|
+
};
|
|
75
|
+
this.overlayCloseCallback = async () => {
|
|
76
|
+
if (this.restoreChildren) {
|
|
77
|
+
this.restoreChildren();
|
|
78
|
+
this.restoreChildren = void 0;
|
|
79
|
+
}
|
|
80
|
+
this.close();
|
|
81
|
+
requestAnimationFrame(() => this.menuStateResolver());
|
|
82
|
+
};
|
|
83
|
+
this._willUpdateItems = false;
|
|
84
|
+
this.itemsUpdated = Promise.resolve();
|
|
85
|
+
this.menuStatePromise = Promise.resolve();
|
|
86
|
+
this.selectionPromise = Promise.resolve();
|
|
87
|
+
this.onKeydown = this.onKeydown.bind(this);
|
|
88
|
+
}
|
|
89
|
+
get target() {
|
|
90
|
+
return this.button;
|
|
91
|
+
}
|
|
92
|
+
get focusElement() {
|
|
93
|
+
if (this.open) {
|
|
94
|
+
return this.optionsMenu;
|
|
90
95
|
}
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
return this.button;
|
|
97
|
+
}
|
|
98
|
+
forceFocusVisible() {
|
|
99
|
+
this.focused = true;
|
|
100
|
+
}
|
|
101
|
+
onButtonBlur() {
|
|
102
|
+
this.focused = false;
|
|
103
|
+
this.target.removeEventListener("keydown", this.onKeydown);
|
|
104
|
+
}
|
|
105
|
+
onButtonClick() {
|
|
106
|
+
this.toggle();
|
|
107
|
+
}
|
|
108
|
+
focus(options) {
|
|
109
|
+
super.focus(options);
|
|
110
|
+
if (!this.disabled && this.focusElement) {
|
|
111
|
+
this.focused = this.hasVisibleFocusInTree();
|
|
93
112
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
113
|
+
}
|
|
114
|
+
onHelperFocus() {
|
|
115
|
+
this.focused = true;
|
|
116
|
+
this.button.focus();
|
|
117
|
+
}
|
|
118
|
+
onButtonFocus() {
|
|
119
|
+
this.target.addEventListener("keydown", this.onKeydown);
|
|
120
|
+
}
|
|
121
|
+
handleChange(event) {
|
|
122
|
+
event.stopPropagation();
|
|
123
|
+
const target = event.target;
|
|
124
|
+
const [selected] = target.selectedItems;
|
|
125
|
+
this.setValueFromItem(selected, event);
|
|
126
|
+
}
|
|
127
|
+
async setValueFromItem(item, menuChangeEvent) {
|
|
128
|
+
const oldSelectedItem = this.selectedItem;
|
|
129
|
+
const oldValue = this.value;
|
|
130
|
+
this.selectedItem = item;
|
|
131
|
+
this.value = item.value;
|
|
132
|
+
this.open = false;
|
|
133
|
+
await this.updateComplete;
|
|
134
|
+
const applyDefault = this.dispatchEvent(new Event("change", {
|
|
135
|
+
bubbles: true,
|
|
136
|
+
cancelable: true,
|
|
137
|
+
composed: true
|
|
138
|
+
}));
|
|
139
|
+
if (!applyDefault) {
|
|
140
|
+
if (menuChangeEvent) {
|
|
141
|
+
menuChangeEvent.preventDefault();
|
|
142
|
+
}
|
|
143
|
+
this.selectedItem.selected = false;
|
|
144
|
+
if (oldSelectedItem) {
|
|
145
|
+
oldSelectedItem.selected = true;
|
|
146
|
+
}
|
|
147
|
+
this.selectedItem = oldSelectedItem;
|
|
148
|
+
this.value = oldValue;
|
|
149
|
+
this.open = true;
|
|
150
|
+
return;
|
|
102
151
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
this.target.removeEventListener('keydown', this.onKeydown);
|
|
152
|
+
if (oldSelectedItem) {
|
|
153
|
+
oldSelectedItem.selected = false;
|
|
106
154
|
}
|
|
107
|
-
|
|
108
|
-
|
|
155
|
+
item.selected = !!this.selects;
|
|
156
|
+
}
|
|
157
|
+
toggle(target) {
|
|
158
|
+
if (this.readonly) {
|
|
159
|
+
return;
|
|
109
160
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
161
|
+
this.open = typeof target !== "undefined" ? target : !this.open;
|
|
162
|
+
}
|
|
163
|
+
close() {
|
|
164
|
+
if (this.readonly) {
|
|
165
|
+
return;
|
|
115
166
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
167
|
+
this.open = false;
|
|
168
|
+
}
|
|
169
|
+
async generatePopover() {
|
|
170
|
+
if (!this.popoverFragment) {
|
|
171
|
+
this.popoverFragment = document.createDocumentFragment();
|
|
120
172
|
}
|
|
121
|
-
|
|
122
|
-
|
|
173
|
+
render(this.renderPopover, this.popoverFragment, { host: this });
|
|
174
|
+
this.popover = this.popoverFragment.children[0];
|
|
175
|
+
this.optionsMenu = this.popover.children[1];
|
|
176
|
+
}
|
|
177
|
+
async openMenu() {
|
|
178
|
+
let reparentableChildren = [];
|
|
179
|
+
const deprecatedMenu = this.querySelector(":scope > sp-menu");
|
|
180
|
+
await this.generatePopover();
|
|
181
|
+
if (deprecatedMenu) {
|
|
182
|
+
reparentableChildren = Array.from(deprecatedMenu.children);
|
|
183
|
+
} else {
|
|
184
|
+
reparentableChildren = Array.from(this.children).filter((element) => {
|
|
185
|
+
return !element.hasAttribute("slot");
|
|
186
|
+
});
|
|
123
187
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
const [selected] = target.selectedItems;
|
|
128
|
-
this.setValueFromItem(selected, event);
|
|
188
|
+
if (reparentableChildren.length === 0) {
|
|
189
|
+
this.menuStateResolver();
|
|
190
|
+
return;
|
|
129
191
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
this.
|
|
134
|
-
|
|
135
|
-
this.open = false;
|
|
136
|
-
await this.updateComplete;
|
|
137
|
-
const applyDefault = this.dispatchEvent(new Event('change', {
|
|
138
|
-
bubbles: true,
|
|
139
|
-
cancelable: true,
|
|
140
|
-
composed: true,
|
|
141
|
-
}));
|
|
142
|
-
if (!applyDefault) {
|
|
143
|
-
if (menuChangeEvent) {
|
|
144
|
-
menuChangeEvent.preventDefault();
|
|
145
|
-
}
|
|
146
|
-
this.selectedItem.selected = false;
|
|
147
|
-
if (oldSelectedItem) {
|
|
148
|
-
oldSelectedItem.selected = true;
|
|
149
|
-
}
|
|
150
|
-
this.selectedItem = oldSelectedItem;
|
|
151
|
-
this.value = oldValue;
|
|
152
|
-
this.open = true;
|
|
153
|
-
return;
|
|
192
|
+
this.restoreChildren = reparentChildren(reparentableChildren, this.optionsMenu, {
|
|
193
|
+
position: "beforeend",
|
|
194
|
+
prepareCallback: (el) => {
|
|
195
|
+
if (this.value === el.value) {
|
|
196
|
+
el.selected = true;
|
|
154
197
|
}
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
async generatePopover(deprecatedMenu) {
|
|
173
|
-
if (!this.popoverFragment) {
|
|
174
|
-
this.popoverFragment = document.createDocumentFragment();
|
|
175
|
-
}
|
|
176
|
-
render(this.renderPopover, this.popoverFragment, { host: this });
|
|
177
|
-
this.popover = this.popoverFragment.children[0];
|
|
178
|
-
this.optionsMenu = this.popover.children[1];
|
|
179
|
-
if (deprecatedMenu) {
|
|
180
|
-
console.warn(`Deprecation Notice: You no longer need to provide an sp-menu child to ${this.tagName.toLowerCase()}. Any styling or attributes on the sp-menu will be ignored.`);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
async openMenu() {
|
|
184
|
-
/* c8 ignore next 9 */
|
|
185
|
-
let reparentableChildren = [];
|
|
186
|
-
const deprecatedMenu = this.querySelector(':scope > sp-menu');
|
|
187
|
-
await this.generatePopover(deprecatedMenu);
|
|
188
|
-
if (deprecatedMenu) {
|
|
189
|
-
reparentableChildren = Array.from(deprecatedMenu.children);
|
|
190
|
-
}
|
|
191
|
-
else {
|
|
192
|
-
reparentableChildren = Array.from(this.children).filter((element) => {
|
|
193
|
-
return !element.hasAttribute('slot');
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
if (reparentableChildren.length === 0) {
|
|
197
|
-
this.menuStateResolver();
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
this.restoreChildren = reparentChildren(reparentableChildren, this.optionsMenu, {
|
|
201
|
-
position: 'beforeend',
|
|
202
|
-
prepareCallback: (el) => {
|
|
203
|
-
if (this.value === el.value) {
|
|
204
|
-
el.selected = true;
|
|
205
|
-
}
|
|
206
|
-
return (el) => {
|
|
207
|
-
if (typeof el.focused !== 'undefined') {
|
|
208
|
-
el.focused = false;
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
this.sizePopover(this.popover);
|
|
214
|
-
this.closeOverlay = Picker.openOverlay(this, 'modal', this.popover, {
|
|
215
|
-
placement: this.isMobile.matches ? 'none' : this.placement,
|
|
216
|
-
receivesFocus: 'auto',
|
|
217
|
-
});
|
|
198
|
+
return (el2) => {
|
|
199
|
+
if (typeof el2.focused !== "undefined") {
|
|
200
|
+
el2.focused = false;
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
this.sizePopover(this.popover);
|
|
206
|
+
this.closeOverlay = Picker.openOverlay(this, "modal", this.popover, {
|
|
207
|
+
placement: this.isMobile.matches ? "none" : this.placement,
|
|
208
|
+
receivesFocus: "auto"
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
sizePopover(popover) {
|
|
212
|
+
if (this.isMobile.matches) {
|
|
213
|
+
popover.style.setProperty("--swc-menu-width", `100%`);
|
|
214
|
+
return;
|
|
218
215
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
216
|
+
if (this.quiet)
|
|
217
|
+
return;
|
|
218
|
+
popover.style.setProperty("min-width", `${this.offsetWidth}px`);
|
|
219
|
+
}
|
|
220
|
+
async closeMenu() {
|
|
221
|
+
if (this.closeOverlay) {
|
|
222
|
+
const closeOverlay = this.closeOverlay;
|
|
223
|
+
delete this.closeOverlay;
|
|
224
|
+
(await closeOverlay)();
|
|
228
225
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
(await closeOverlay)();
|
|
234
|
-
}
|
|
226
|
+
}
|
|
227
|
+
get selectedItemContent() {
|
|
228
|
+
if (this.selectedItem) {
|
|
229
|
+
return this.selectedItem.itemChildren;
|
|
235
230
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
231
|
+
return { icon: [], content: [] };
|
|
232
|
+
}
|
|
233
|
+
renderLabelContent(content) {
|
|
234
|
+
if (this.value && this.selectedItem) {
|
|
235
|
+
return content;
|
|
241
236
|
}
|
|
242
|
-
|
|
243
|
-
if (this.value && this.selectedItem) {
|
|
244
|
-
return content;
|
|
245
|
-
}
|
|
246
|
-
return html `
|
|
237
|
+
return html`
|
|
247
238
|
<slot name="label">${this.label}</slot>
|
|
248
239
|
`;
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
<span id="icon" ?hidden=${this.icons ===
|
|
240
|
+
}
|
|
241
|
+
get buttonContent() {
|
|
242
|
+
const labelClasses = {
|
|
243
|
+
"visually-hidden": this.icons === "only" && !!this.value,
|
|
244
|
+
placeholder: !this.value
|
|
245
|
+
};
|
|
246
|
+
return [
|
|
247
|
+
html`
|
|
248
|
+
<span id="icon" ?hidden=${this.icons === "none"}>
|
|
258
249
|
${this.selectedItemContent.icon}
|
|
259
250
|
</span>
|
|
260
251
|
<span id="label" class=${classMap(labelClasses)}>
|
|
261
252
|
${this.renderLabelContent(this.selectedItemContent.content)}
|
|
262
253
|
</span>
|
|
263
|
-
${this.invalid
|
|
264
|
-
? html `
|
|
254
|
+
${this.invalid ? html`
|
|
265
255
|
<sp-icon-alert
|
|
266
256
|
class="validation-icon"
|
|
267
257
|
></sp-icon-alert>
|
|
268
|
-
`
|
|
269
|
-
: nothing}
|
|
258
|
+
` : nothing}
|
|
270
259
|
<sp-icon-chevron100
|
|
271
260
|
class="picker ${chevronClass[this.size]}"
|
|
272
261
|
></sp-icon-chevron100>
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
render() {
|
|
279
|
-
return html `
|
|
262
|
+
`
|
|
263
|
+
];
|
|
264
|
+
}
|
|
265
|
+
render() {
|
|
266
|
+
return html`
|
|
280
267
|
<span
|
|
281
268
|
id="focus-helper"
|
|
282
|
-
tabindex="${this.focused ?
|
|
269
|
+
tabindex="${this.focused ? "-1" : "0"}"
|
|
283
270
|
@focus=${this.onHelperFocus}
|
|
284
271
|
></span>
|
|
285
272
|
<button
|
|
286
273
|
aria-haspopup="true"
|
|
287
|
-
aria-expanded=${this.open ?
|
|
274
|
+
aria-expanded=${this.open ? "true" : "false"}
|
|
288
275
|
aria-labelledby="button icon label"
|
|
289
276
|
id="button"
|
|
290
277
|
class="button"
|
|
@@ -297,33 +284,35 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
297
284
|
${this.buttonContent}
|
|
298
285
|
</button>
|
|
299
286
|
`;
|
|
287
|
+
}
|
|
288
|
+
update(changes) {
|
|
289
|
+
if (this.selects) {
|
|
290
|
+
this.selects = "single";
|
|
300
291
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
// Always force `selects` to "single" when set.
|
|
304
|
-
// TODO: Add support functionally and visually for "multiple"
|
|
305
|
-
this.selects = 'single';
|
|
306
|
-
}
|
|
307
|
-
if (changes.has('disabled') && this.disabled) {
|
|
308
|
-
this.open = false;
|
|
309
|
-
}
|
|
310
|
-
if (changes.has('open') &&
|
|
311
|
-
(this.open || typeof changes.get('open') !== 'undefined')) {
|
|
312
|
-
this.menuStatePromise = new Promise((res) => (this.menuStateResolver = res));
|
|
313
|
-
if (this.open) {
|
|
314
|
-
this.openMenu();
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
this.closeMenu();
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
if (changes.has('value') && !changes.has('selectedItem')) {
|
|
321
|
-
this.updateMenuItems();
|
|
322
|
-
}
|
|
323
|
-
super.update(changes);
|
|
292
|
+
if (changes.has("disabled") && this.disabled) {
|
|
293
|
+
this.open = false;
|
|
324
294
|
}
|
|
325
|
-
|
|
326
|
-
|
|
295
|
+
if (changes.has("open") && (this.open || typeof changes.get("open") !== "undefined")) {
|
|
296
|
+
this.menuStatePromise = new Promise((res) => this.menuStateResolver = res);
|
|
297
|
+
if (this.open) {
|
|
298
|
+
this.openMenu();
|
|
299
|
+
} else {
|
|
300
|
+
this.closeMenu();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
if (changes.has("value") && !changes.has("selectedItem")) {
|
|
304
|
+
this.updateMenuItems();
|
|
305
|
+
}
|
|
306
|
+
if (false) {
|
|
307
|
+
if (!this.hasUpdated && this.querySelector("sp-menu")) {
|
|
308
|
+
const { localName } = this;
|
|
309
|
+
window.__swc.warn(this, `You no longer need to provide an <sp-menu> child to ${localName}. Any styling or attributes on the <sp-menu> will be ignored.`, "https://opensource.adobe.com/spectrum-web-components/components/picker/#sizes", { level: "deprecation" });
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
super.update(changes);
|
|
313
|
+
}
|
|
314
|
+
get dismissHelper() {
|
|
315
|
+
return html`
|
|
327
316
|
<div class="visually-hidden">
|
|
328
317
|
<button
|
|
329
318
|
tabindex="-1"
|
|
@@ -332,9 +321,9 @@ export class PickerBase extends SizedMixin(Focusable) {
|
|
|
332
321
|
></button>
|
|
333
322
|
</div>
|
|
334
323
|
`;
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
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
|
-
|
|
348
|
-
|
|
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
|
-
|
|
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
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
async manageSelection() {
|
|
408
|
-
await this.menuStatePromise;
|
|
409
|
-
this.selectionPromise = new Promise((res) => (this.selectionResolver = res));
|
|
410
|
-
let selectedItem;
|
|
411
|
-
this.menuItems.forEach((item) => {
|
|
412
|
-
if (this.value === item.value && !item.disabled) {
|
|
413
|
-
selectedItem = item;
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
item.selected = false;
|
|
417
|
-
}
|
|
418
|
-
});
|
|
419
|
-
if (selectedItem) {
|
|
420
|
-
selectedItem.selected = !!this.selects;
|
|
421
|
-
this.selectedItem = selectedItem;
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
this.value = '';
|
|
425
|
-
this.selectedItem = undefined;
|
|
426
|
-
}
|
|
427
|
-
if (this.open) {
|
|
428
|
-
await this.optionsMenu.updateComplete;
|
|
429
|
-
this.optionsMenu.updateSelectedItemIndex();
|
|
430
|
-
}
|
|
431
|
-
this.selectionResolver();
|
|
432
|
-
}
|
|
433
|
-
async getUpdateComplete() {
|
|
434
|
-
const complete = (await super.getUpdateComplete());
|
|
435
|
-
await this.menuStatePromise;
|
|
436
|
-
await this.itemsUpdated;
|
|
437
|
-
await this.selectionPromise;
|
|
438
|
-
return complete;
|
|
439
|
-
}
|
|
440
|
-
connectedCallback() {
|
|
441
|
-
this.updateMenuItems();
|
|
442
|
-
this.addEventListener('sp-menu-item-added-or-updated', this.updateMenuItems);
|
|
443
|
-
this.addEventListener('sp-menu-item-removed', this.updateMenuItems);
|
|
444
|
-
super.connectedCallback();
|
|
370
|
+
let resolve = () => {
|
|
371
|
+
return;
|
|
372
|
+
};
|
|
373
|
+
this.itemsUpdated = new Promise((res) => resolve = res);
|
|
374
|
+
window.requestAnimationFrame(async () => {
|
|
375
|
+
if (this.open) {
|
|
376
|
+
await this.optionsMenu.updateComplete;
|
|
377
|
+
this.menuItems = this.optionsMenu.childItems;
|
|
378
|
+
} else {
|
|
379
|
+
this.menuItems = [
|
|
380
|
+
...this.querySelectorAll('sp-menu-item:not([slot="submenu"] *)')
|
|
381
|
+
];
|
|
382
|
+
}
|
|
383
|
+
this.manageSelection();
|
|
384
|
+
resolve();
|
|
385
|
+
this._willUpdateItems = false;
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
async manageSelection() {
|
|
389
|
+
await this.menuStatePromise;
|
|
390
|
+
this.selectionPromise = new Promise((res) => this.selectionResolver = res);
|
|
391
|
+
let selectedItem;
|
|
392
|
+
this.menuItems.forEach((item) => {
|
|
393
|
+
if (this.value === item.value && !item.disabled) {
|
|
394
|
+
selectedItem = item;
|
|
395
|
+
} else {
|
|
396
|
+
item.selected = false;
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
if (selectedItem) {
|
|
400
|
+
selectedItem.selected = !!this.selects;
|
|
401
|
+
this.selectedItem = selectedItem;
|
|
402
|
+
} else {
|
|
403
|
+
this.value = "";
|
|
404
|
+
this.selectedItem = void 0;
|
|
445
405
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
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
|
-
|
|
431
|
+
return await openOverlay(target, interaction, content, options);
|
|
457
432
|
};
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
], PickerBase.prototype, "button",
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
], PickerBase.prototype, "disabled",
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
], PickerBase.prototype, "focused",
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
], PickerBase.prototype, "icons",
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
], PickerBase.prototype, "invalid",
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
], PickerBase.prototype, "label",
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
], PickerBase.prototype, "open",
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
], PickerBase.prototype, "readonly",
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
], PickerBase.prototype, "placement",
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
], PickerBase.prototype, "quiet",
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
], PickerBase.prototype, "value",
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
], PickerBase.prototype, "selectedItem",
|
|
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
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
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
|