@spectrum-web-components/slider 0.12.14 → 0.12.15-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.
- package/package.json +40 -15
- package/sp-slider-handle.dev.js +3 -0
- package/sp-slider-handle.dev.js.map +7 -0
- package/sp-slider-handle.js +3 -14
- package/sp-slider-handle.js.map +7 -1
- package/sp-slider.dev.js +4 -0
- package/sp-slider.dev.js.map +7 -0
- package/sp-slider.js +4 -15
- package/sp-slider.js.map +7 -1
- package/src/HandleController.dev.js +434 -0
- package/src/HandleController.dev.js.map +7 -0
- package/src/HandleController.js +402 -453
- package/src/HandleController.js.map +7 -1
- package/src/Slider.dev.js +367 -0
- package/src/Slider.dev.js.map +7 -0
- package/src/Slider.js +280 -304
- package/src/Slider.js.map +7 -1
- package/src/SliderHandle.dev.js +184 -0
- package/src/SliderHandle.dev.js.map +7 -0
- package/src/SliderHandle.js +171 -179
- package/src/SliderHandle.js.map +7 -1
- package/src/index.dev.js +4 -0
- package/src/index.dev.js.map +7 -0
- package/src/index.js +4 -15
- package/src/index.js.map +7 -1
- package/src/slider.css.dev.js +234 -0
- package/src/slider.css.dev.js.map +7 -0
- package/src/slider.css.js +3 -14
- package/src/slider.css.js.map +7 -1
- package/src/spectrum-slider.css.dev.js +216 -0
- package/src/spectrum-slider.css.dev.js.map +7 -0
- package/src/spectrum-slider.css.js +3 -14
- package/src/spectrum-slider.css.js.map +7 -1
- package/stories/slider.stories.js +224 -269
- package/stories/slider.stories.js.map +7 -1
- package/sync/sp-slider.dev.js +3 -0
- package/sync/sp-slider.dev.js.map +7 -0
- package/sync/sp-slider.js +3 -14
- package/sync/sp-slider.js.map +7 -1
- package/test/benchmark/test-basic.js +5 -16
- package/test/benchmark/test-basic.js.map +7 -1
- package/test/slider-editable-sync.test.js +132 -144
- package/test/slider-editable-sync.test.js.map +7 -1
- package/test/slider-editable.test.js +151 -159
- package/test/slider-editable.test.js.map +7 -1
- package/test/slider-handle-upgrade.test.js +10 -21
- package/test/slider-handle-upgrade.test.js.map +7 -1
- package/test/slider.test-vrt.js +4 -15
- package/test/slider.test-vrt.js.map +7 -1
- package/test/slider.test.js +686 -700
- package/test/slider.test.js.map +7 -1
package/src/HandleController.js
CHANGED
|
@@ -1,364 +1,315 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*/
|
|
12
|
-
import { html } from '@spectrum-web-components/base';
|
|
13
|
-
import { classMap, ifDefined, styleMap, } from '@spectrum-web-components/base/src/directives.js';
|
|
14
|
-
import { MutationController } from '@lit-labs/observers/mutation_controller.js';
|
|
15
|
-
import { SliderHandle, } from './SliderHandle.js';
|
|
1
|
+
import { html } from "@spectrum-web-components/base";
|
|
2
|
+
import {
|
|
3
|
+
classMap,
|
|
4
|
+
ifDefined,
|
|
5
|
+
styleMap
|
|
6
|
+
} from "@spectrum-web-components/base/src/directives.js";
|
|
7
|
+
import { MutationController } from "@lit-labs/observers/mutation_controller.js";
|
|
8
|
+
import {
|
|
9
|
+
SliderHandle
|
|
10
|
+
} from "./SliderHandle.js";
|
|
16
11
|
export class HandleController {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
handles.forEach((handle, index) => {
|
|
38
|
-
var _a;
|
|
39
|
-
/* c8 ignore next */
|
|
40
|
-
if (!((_a = handle.handleName) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
41
|
-
handle.name = `handle${index + 1}`;
|
|
42
|
-
}
|
|
43
|
-
this.handles.set(handle.handleName, handle);
|
|
44
|
-
this.handleOrder.push(handle.handleName);
|
|
45
|
-
handle.handleController = this;
|
|
46
|
-
});
|
|
47
|
-
this.requestUpdate();
|
|
48
|
-
};
|
|
49
|
-
/**
|
|
50
|
-
* Keep the slider value property in sync with the input element's value
|
|
51
|
-
*/
|
|
52
|
-
this.onInputChange = (event) => {
|
|
53
|
-
const input = event.target;
|
|
54
|
-
input.model.handle.value = input.valueAsNumber;
|
|
55
|
-
this.requestUpdate();
|
|
56
|
-
this.dispatchChangeEvent(input, input.model.handle);
|
|
57
|
-
};
|
|
58
|
-
this.onInputFocus = (event) => {
|
|
59
|
-
const input = event.target;
|
|
60
|
-
let isFocusVisible;
|
|
61
|
-
try {
|
|
62
|
-
isFocusVisible =
|
|
63
|
-
input.matches(':focus-visible') ||
|
|
64
|
-
this.host.matches('.focus-visible');
|
|
65
|
-
/* c8 ignore next 3 */
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
isFocusVisible = this.host.matches('.focus-visible');
|
|
69
|
-
}
|
|
70
|
-
input.model.handle.highlight = isFocusVisible;
|
|
71
|
-
this.requestUpdate();
|
|
72
|
-
};
|
|
73
|
-
this.onInputBlur = (event) => {
|
|
74
|
-
const input = event.target;
|
|
75
|
-
input.model.handle.highlight = false;
|
|
76
|
-
this.requestUpdate();
|
|
77
|
-
};
|
|
78
|
-
this.onInputKeydown = (event) => {
|
|
79
|
-
const input = event.target;
|
|
80
|
-
input.model.handle.highlight = true;
|
|
81
|
-
this.requestUpdate();
|
|
82
|
-
};
|
|
83
|
-
this.host = host;
|
|
84
|
-
new MutationController(this.host, {
|
|
85
|
-
config: {
|
|
86
|
-
subtree: true,
|
|
87
|
-
childList: true,
|
|
88
|
-
},
|
|
89
|
-
callback: () => {
|
|
90
|
-
this.extractModelFromLightDom();
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
this.extractModelFromLightDom();
|
|
94
|
-
}
|
|
95
|
-
get values() {
|
|
96
|
-
const result = {};
|
|
97
|
-
for (const model of this.handles.values()) {
|
|
98
|
-
result[model.handleName] = model.value;
|
|
99
|
-
}
|
|
100
|
-
return result;
|
|
101
|
-
}
|
|
102
|
-
get size() {
|
|
103
|
-
return this.handles.size;
|
|
104
|
-
}
|
|
105
|
-
inputForHandle(handle) {
|
|
106
|
-
if (this.handles.has(handle.handleName)) {
|
|
107
|
-
const { input } = this.getHandleElements(handle);
|
|
108
|
-
return input;
|
|
109
|
-
}
|
|
110
|
-
/* c8 ignore next 2 */
|
|
111
|
-
throw new Error(`No input for handle "${handle.name}"`);
|
|
112
|
-
}
|
|
113
|
-
requestUpdate() {
|
|
114
|
-
if (this.host.hasUpdated) {
|
|
115
|
-
this.host.requestUpdate();
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* It is possible for value attributes to be set programmatically. The <input>
|
|
120
|
-
* for a particular slider needs to have an opportunity to validate any such
|
|
121
|
-
* values
|
|
122
|
-
*
|
|
123
|
-
* @param handle Handle who's value needs validation
|
|
124
|
-
*/
|
|
125
|
-
setValueFromHandle(handle) {
|
|
126
|
-
const elements = this.getHandleElements(handle);
|
|
127
|
-
/* c8 ignore next */
|
|
128
|
-
if (!elements)
|
|
129
|
-
return;
|
|
130
|
-
const { input } = elements;
|
|
131
|
-
if (input.valueAsNumber === handle.value) {
|
|
132
|
-
if (handle.dragging) {
|
|
133
|
-
handle.dispatchInputEvent();
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
input.valueAsNumber = handle.value;
|
|
138
|
-
this.requestUpdate();
|
|
139
|
-
}
|
|
140
|
-
handle.value = input.valueAsNumber;
|
|
141
|
-
}
|
|
142
|
-
handleHasChanged(handle) {
|
|
143
|
-
if (handle !== this.host) {
|
|
144
|
-
this.requestUpdate();
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
formattedValueForHandle(model) {
|
|
12
|
+
constructor(host) {
|
|
13
|
+
this.handles = /* @__PURE__ */ new Map();
|
|
14
|
+
this.model = [];
|
|
15
|
+
this.handleOrder = [];
|
|
16
|
+
this.handleOrientation = () => {
|
|
17
|
+
this.updateBoundingRect();
|
|
18
|
+
};
|
|
19
|
+
this.extractModelFromLightDom = () => {
|
|
20
|
+
let handles = [
|
|
21
|
+
...this.host.querySelectorAll('[slot="handle"]')
|
|
22
|
+
];
|
|
23
|
+
if (handles.length === 0) {
|
|
24
|
+
handles = [this.host];
|
|
25
|
+
}
|
|
26
|
+
if (handles.some((h) => this.waitForUpgrade(h))) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
this.handles = /* @__PURE__ */ new Map();
|
|
30
|
+
this.handleOrder = [];
|
|
31
|
+
handles.forEach((handle, index) => {
|
|
148
32
|
var _a;
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return handle.getAriaHandleText(model.value, numberFormat);
|
|
152
|
-
}
|
|
153
|
-
get formattedValues() {
|
|
154
|
-
const result = new Map();
|
|
155
|
-
for (const model of this.model) {
|
|
156
|
-
result.set(model.name, this.formattedValueForHandle(model));
|
|
157
|
-
}
|
|
158
|
-
return result;
|
|
159
|
-
}
|
|
160
|
-
get focusElement() {
|
|
161
|
-
const { input } = this.getActiveHandleElements();
|
|
162
|
-
if (this.host.editable &&
|
|
163
|
-
!input.model.handle.dragging) {
|
|
164
|
-
return this.host.numberField;
|
|
165
|
-
}
|
|
166
|
-
return input;
|
|
167
|
-
}
|
|
168
|
-
hostConnected() {
|
|
169
|
-
if ('orientation' in screen) {
|
|
170
|
-
screen.orientation.addEventListener('change', this.handleOrientation);
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
window.addEventListener('orientationchange', this.handleOrientation);
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
hostDisconnected() {
|
|
177
|
-
if ('orientation' in screen) {
|
|
178
|
-
screen.orientation.removeEventListener('change', this.handleOrientation);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
window.removeEventListener('orientationchange', this.handleOrientation);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
hostUpdate() {
|
|
185
|
-
this.updateModel();
|
|
186
|
-
}
|
|
187
|
-
// Since extractModelFromLightDom bails on the first un-upgraded handle,
|
|
188
|
-
// a maximum of one listener will be set up per extraction attempt.
|
|
189
|
-
waitForUpgrade(handle) {
|
|
190
|
-
if (handle instanceof SliderHandle) {
|
|
191
|
-
return false;
|
|
192
|
-
}
|
|
193
|
-
handle.addEventListener('sp-slider-handle-ready', () => this.extractModelFromLightDom(), { once: true, passive: true });
|
|
194
|
-
return true;
|
|
195
|
-
}
|
|
196
|
-
get activeHandle() {
|
|
197
|
-
return this.handleOrder[this.handleOrder.length - 1];
|
|
198
|
-
}
|
|
199
|
-
get activeHandleInputId() {
|
|
200
|
-
const active = this.activeHandle;
|
|
201
|
-
const index = this.model.findIndex((model) => model.name === active);
|
|
202
|
-
return `input-${index}`;
|
|
203
|
-
}
|
|
204
|
-
activateHandle(name) {
|
|
205
|
-
const index = this.handleOrder.findIndex((item) => item === name);
|
|
206
|
-
if (index >= 0) {
|
|
207
|
-
this.handleOrder.splice(index, 1);
|
|
208
|
-
}
|
|
209
|
-
this.handleOrder.push(name);
|
|
210
|
-
}
|
|
211
|
-
getActiveHandleElements() {
|
|
212
|
-
const name = this.activeHandle;
|
|
213
|
-
const handleSlider = this.handles.get(name);
|
|
214
|
-
const elements = this.getHandleElements(handleSlider);
|
|
215
|
-
return Object.assign({ model: handleSlider }, elements);
|
|
216
|
-
}
|
|
217
|
-
getHandleElements(sliderHandle) {
|
|
218
|
-
if (!this.handleRefMap) {
|
|
219
|
-
this.handleRefMap = new WeakMap();
|
|
220
|
-
const inputNodes = this.host.shadowRoot.querySelectorAll('.handle > input');
|
|
221
|
-
for (const inputNode of inputNodes) {
|
|
222
|
-
const input = inputNode;
|
|
223
|
-
const handle = input.parentElement;
|
|
224
|
-
const model = this.handles.get(handle.getAttribute('name'));
|
|
225
|
-
if (model) {
|
|
226
|
-
this.handleRefMap.set(model, { input, handle });
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
const components = this.handleRefMap.get(sliderHandle);
|
|
231
|
-
return components;
|
|
232
|
-
}
|
|
233
|
-
clearHandleComponentCache() {
|
|
234
|
-
delete this.handleRefMap;
|
|
235
|
-
}
|
|
236
|
-
get boundingClientRect() {
|
|
237
|
-
if (!this._boundingClientRect) {
|
|
238
|
-
this._boundingClientRect = this.host.track.getBoundingClientRect();
|
|
33
|
+
if (!((_a = handle.handleName) == null ? void 0 : _a.length)) {
|
|
34
|
+
handle.name = `handle${index + 1}`;
|
|
239
35
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
36
|
+
this.handles.set(handle.handleName, handle);
|
|
37
|
+
this.handleOrder.push(handle.handleName);
|
|
38
|
+
handle.handleController = this;
|
|
39
|
+
});
|
|
40
|
+
this.requestUpdate();
|
|
41
|
+
};
|
|
42
|
+
this.onInputChange = (event) => {
|
|
43
|
+
const input = event.target;
|
|
44
|
+
input.model.handle.value = input.valueAsNumber;
|
|
45
|
+
this.requestUpdate();
|
|
46
|
+
this.dispatchChangeEvent(input, input.model.handle);
|
|
47
|
+
};
|
|
48
|
+
this.onInputFocus = (event) => {
|
|
49
|
+
const input = event.target;
|
|
50
|
+
let isFocusVisible;
|
|
51
|
+
try {
|
|
52
|
+
isFocusVisible = input.matches(":focus-visible") || this.host.matches(".focus-visible");
|
|
53
|
+
} catch (error) {
|
|
54
|
+
isFocusVisible = this.host.matches(".focus-visible");
|
|
55
|
+
}
|
|
56
|
+
input.model.handle.highlight = isFocusVisible;
|
|
57
|
+
this.requestUpdate();
|
|
58
|
+
};
|
|
59
|
+
this.onInputBlur = (event) => {
|
|
60
|
+
const input = event.target;
|
|
61
|
+
input.model.handle.highlight = false;
|
|
62
|
+
this.requestUpdate();
|
|
63
|
+
};
|
|
64
|
+
this.onInputKeydown = (event) => {
|
|
65
|
+
const input = event.target;
|
|
66
|
+
input.model.handle.highlight = true;
|
|
67
|
+
this.requestUpdate();
|
|
68
|
+
};
|
|
69
|
+
this.host = host;
|
|
70
|
+
new MutationController(this.host, {
|
|
71
|
+
config: {
|
|
72
|
+
subtree: true,
|
|
73
|
+
childList: true
|
|
74
|
+
},
|
|
75
|
+
callback: () => {
|
|
76
|
+
this.extractModelFromLightDom();
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
this.extractModelFromLightDom();
|
|
80
|
+
}
|
|
81
|
+
get values() {
|
|
82
|
+
const result = {};
|
|
83
|
+
for (const model of this.handles.values()) {
|
|
84
|
+
result[model.handleName] = model.value;
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
get size() {
|
|
89
|
+
return this.handles.size;
|
|
90
|
+
}
|
|
91
|
+
inputForHandle(handle) {
|
|
92
|
+
if (this.handles.has(handle.handleName)) {
|
|
93
|
+
const { input } = this.getHandleElements(handle);
|
|
94
|
+
return input;
|
|
95
|
+
}
|
|
96
|
+
throw new Error(`No input for handle "${handle.name}"`);
|
|
97
|
+
}
|
|
98
|
+
requestUpdate() {
|
|
99
|
+
if (this.host.hasUpdated) {
|
|
100
|
+
this.host.requestUpdate();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
setValueFromHandle(handle) {
|
|
104
|
+
const elements = this.getHandleElements(handle);
|
|
105
|
+
if (!elements)
|
|
106
|
+
return;
|
|
107
|
+
const { input } = elements;
|
|
108
|
+
if (input.valueAsNumber === handle.value) {
|
|
109
|
+
if (handle.dragging) {
|
|
110
|
+
handle.dispatchInputEvent();
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
input.valueAsNumber = handle.value;
|
|
114
|
+
this.requestUpdate();
|
|
115
|
+
}
|
|
116
|
+
handle.value = input.valueAsNumber;
|
|
117
|
+
}
|
|
118
|
+
handleHasChanged(handle) {
|
|
119
|
+
if (handle !== this.host) {
|
|
120
|
+
this.requestUpdate();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
formattedValueForHandle(model) {
|
|
124
|
+
var _a;
|
|
125
|
+
const { handle } = model;
|
|
126
|
+
const numberFormat = (_a = handle.numberFormat) != null ? _a : this.host.numberFormat;
|
|
127
|
+
return handle.getAriaHandleText(model.value, numberFormat);
|
|
128
|
+
}
|
|
129
|
+
get formattedValues() {
|
|
130
|
+
const result = /* @__PURE__ */ new Map();
|
|
131
|
+
for (const model of this.model) {
|
|
132
|
+
result.set(model.name, this.formattedValueForHandle(model));
|
|
133
|
+
}
|
|
134
|
+
return result;
|
|
135
|
+
}
|
|
136
|
+
get focusElement() {
|
|
137
|
+
const { input } = this.getActiveHandleElements();
|
|
138
|
+
if (this.host.editable && !input.model.handle.dragging) {
|
|
139
|
+
return this.host.numberField;
|
|
140
|
+
}
|
|
141
|
+
return input;
|
|
142
|
+
}
|
|
143
|
+
hostConnected() {
|
|
144
|
+
if ("orientation" in screen) {
|
|
145
|
+
screen.orientation.addEventListener("change", this.handleOrientation);
|
|
146
|
+
} else {
|
|
147
|
+
window.addEventListener("orientationchange", this.handleOrientation);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
hostDisconnected() {
|
|
151
|
+
if ("orientation" in screen) {
|
|
152
|
+
screen.orientation.removeEventListener("change", this.handleOrientation);
|
|
153
|
+
} else {
|
|
154
|
+
window.removeEventListener("orientationchange", this.handleOrientation);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
hostUpdate() {
|
|
158
|
+
this.updateModel();
|
|
159
|
+
}
|
|
160
|
+
waitForUpgrade(handle) {
|
|
161
|
+
if (handle instanceof SliderHandle) {
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
handle.addEventListener("sp-slider-handle-ready", () => this.extractModelFromLightDom(), { once: true, passive: true });
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
get activeHandle() {
|
|
168
|
+
return this.handleOrder[this.handleOrder.length - 1];
|
|
169
|
+
}
|
|
170
|
+
get activeHandleInputId() {
|
|
171
|
+
const active = this.activeHandle;
|
|
172
|
+
const index = this.model.findIndex((model) => model.name === active);
|
|
173
|
+
return `input-${index}`;
|
|
174
|
+
}
|
|
175
|
+
activateHandle(name) {
|
|
176
|
+
const index = this.handleOrder.findIndex((item) => item === name);
|
|
177
|
+
if (index >= 0) {
|
|
178
|
+
this.handleOrder.splice(index, 1);
|
|
179
|
+
}
|
|
180
|
+
this.handleOrder.push(name);
|
|
181
|
+
}
|
|
182
|
+
getActiveHandleElements() {
|
|
183
|
+
const name = this.activeHandle;
|
|
184
|
+
const handleSlider = this.handles.get(name);
|
|
185
|
+
const elements = this.getHandleElements(handleSlider);
|
|
186
|
+
return { model: handleSlider, ...elements };
|
|
187
|
+
}
|
|
188
|
+
getHandleElements(sliderHandle) {
|
|
189
|
+
if (!this.handleRefMap) {
|
|
190
|
+
this.handleRefMap = /* @__PURE__ */ new WeakMap();
|
|
191
|
+
const inputNodes = this.host.shadowRoot.querySelectorAll(".handle > input");
|
|
192
|
+
for (const inputNode of inputNodes) {
|
|
193
|
+
const input = inputNode;
|
|
194
|
+
const handle = input.parentElement;
|
|
195
|
+
const model = this.handles.get(handle.getAttribute("name"));
|
|
196
|
+
if (model) {
|
|
197
|
+
this.handleRefMap.set(model, { input, handle });
|
|
306
198
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
const components = this.handleRefMap.get(sliderHandle);
|
|
202
|
+
return components;
|
|
203
|
+
}
|
|
204
|
+
clearHandleComponentCache() {
|
|
205
|
+
delete this.handleRefMap;
|
|
206
|
+
}
|
|
207
|
+
get boundingClientRect() {
|
|
208
|
+
if (!this._boundingClientRect) {
|
|
209
|
+
this._boundingClientRect = this.host.track.getBoundingClientRect();
|
|
210
|
+
}
|
|
211
|
+
return this._boundingClientRect;
|
|
212
|
+
}
|
|
213
|
+
updateBoundingRect() {
|
|
214
|
+
delete this._boundingClientRect;
|
|
215
|
+
}
|
|
216
|
+
extractDataFromEvent(event) {
|
|
217
|
+
if (!this._activePointerEventData) {
|
|
218
|
+
let input = event.target.querySelector(":scope > .input");
|
|
219
|
+
const resolvedInput = !input;
|
|
220
|
+
const model = input ? input.model : this.model.find((item) => item.name === this.activeHandle);
|
|
221
|
+
if (!input && !!model) {
|
|
222
|
+
input = model.handle.focusElement;
|
|
223
|
+
}
|
|
224
|
+
this._activePointerEventData = {
|
|
225
|
+
input,
|
|
226
|
+
model,
|
|
227
|
+
resolvedInput
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
return this._activePointerEventData;
|
|
231
|
+
}
|
|
232
|
+
handlePointerdown(event) {
|
|
233
|
+
const { resolvedInput, model } = this.extractDataFromEvent(event);
|
|
234
|
+
if (!model || this.host.disabled || event.button !== 0) {
|
|
235
|
+
event.preventDefault();
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
this.host.track.setPointerCapture(event.pointerId);
|
|
239
|
+
this.updateBoundingRect();
|
|
240
|
+
this.host.labelEl.click();
|
|
241
|
+
this.draggingHandle = model.handle;
|
|
242
|
+
model.handle.dragging = true;
|
|
243
|
+
this.activateHandle(model.name);
|
|
244
|
+
if (resolvedInput) {
|
|
245
|
+
this.handlePointermove(event);
|
|
246
|
+
}
|
|
247
|
+
this.requestUpdate();
|
|
248
|
+
}
|
|
249
|
+
handlePointerup(event) {
|
|
250
|
+
const { input, model } = this.extractDataFromEvent(event);
|
|
251
|
+
delete this._activePointerEventData;
|
|
252
|
+
if (!model)
|
|
253
|
+
return;
|
|
254
|
+
this.host.labelEl.click();
|
|
255
|
+
this.cancelDrag(model);
|
|
256
|
+
this.requestUpdate();
|
|
257
|
+
this.host.track.releasePointerCapture(event.pointerId);
|
|
258
|
+
this.dispatchChangeEvent(input, model.handle);
|
|
259
|
+
}
|
|
260
|
+
handlePointermove(event) {
|
|
261
|
+
const { input, model } = this.extractDataFromEvent(event);
|
|
262
|
+
if (!model)
|
|
263
|
+
return;
|
|
264
|
+
if (!this.draggingHandle) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
event.stopPropagation();
|
|
268
|
+
input.value = this.calculateHandlePosition(event, model).toString();
|
|
269
|
+
model.handle.value = parseFloat(input.value);
|
|
270
|
+
this.host.indeterminate = false;
|
|
271
|
+
this.requestUpdate();
|
|
272
|
+
}
|
|
273
|
+
cancelDrag(model) {
|
|
274
|
+
model = model || this.model.find((item) => item.name === this.activeHandle);
|
|
275
|
+
if (!model)
|
|
276
|
+
return;
|
|
277
|
+
model.handle.highlight = false;
|
|
278
|
+
delete this.draggingHandle;
|
|
279
|
+
model.handle.dragging = false;
|
|
280
|
+
}
|
|
281
|
+
dispatchChangeEvent(input, handle) {
|
|
282
|
+
input.valueAsNumber = handle.value;
|
|
283
|
+
const changeEvent = new Event("change", {
|
|
284
|
+
bubbles: true,
|
|
285
|
+
composed: true
|
|
286
|
+
});
|
|
287
|
+
handle.dispatchEvent(changeEvent);
|
|
288
|
+
}
|
|
289
|
+
calculateHandlePosition(event, model) {
|
|
290
|
+
const rect = this.boundingClientRect;
|
|
291
|
+
const minOffset = rect.left;
|
|
292
|
+
const offset = event.clientX;
|
|
293
|
+
const size = rect.width;
|
|
294
|
+
const directionalOffset = this.host.isLTR ? offset - minOffset : size - (offset - minOffset);
|
|
295
|
+
const normalized = directionalOffset / size;
|
|
296
|
+
return model.normalization.fromNormalized(normalized, model.range.min, model.range.max);
|
|
297
|
+
}
|
|
298
|
+
renderHandle(model, index, zIndex, isMultiHandle) {
|
|
299
|
+
var _a;
|
|
300
|
+
const classes = {
|
|
301
|
+
handle: true,
|
|
302
|
+
dragging: ((_a = this.draggingHandle) == null ? void 0 : _a.handleName) === model.name,
|
|
303
|
+
"handle-highlight": model.highlight
|
|
304
|
+
};
|
|
305
|
+
const style = {
|
|
306
|
+
[this.host.isLTR ? "left" : "right"]: `${model.normalizedValue * 100}%`,
|
|
307
|
+
"z-index": zIndex.toString(),
|
|
308
|
+
"background-color": `var(--spectrum-slider-handle-background-color-${index}, var(--spectrum-slider-handle-default-background-color))`,
|
|
309
|
+
"border-color": `var(--spectrum-slider-handle-border-color-${index}, var(-spectrum-slider-handle-default-border-color))`
|
|
310
|
+
};
|
|
311
|
+
const ariaLabelledBy = isMultiHandle ? `label input-${index}` : "label";
|
|
312
|
+
return html`
|
|
362
313
|
<div
|
|
363
314
|
class=${classMap(classes)}
|
|
364
315
|
name=${model.name}
|
|
@@ -373,8 +324,8 @@ export class HandleController {
|
|
|
373
324
|
max=${model.clamp.max}
|
|
374
325
|
step=${model.step}
|
|
375
326
|
value=${model.value}
|
|
376
|
-
aria-disabled=${ifDefined(this.host.disabled ?
|
|
377
|
-
tabindex=${ifDefined(this.host.editable ? -1 :
|
|
327
|
+
aria-disabled=${ifDefined(this.host.disabled ? "true" : void 0)}
|
|
328
|
+
tabindex=${ifDefined(this.host.editable ? -1 : void 0)}
|
|
378
329
|
aria-label=${ifDefined(model.ariaLabel)}
|
|
379
330
|
aria-labelledby=${ariaLabelledBy}
|
|
380
331
|
aria-valuetext=${this.formattedValueForHandle(model)}
|
|
@@ -386,100 +337,98 @@ export class HandleController {
|
|
|
386
337
|
/>
|
|
387
338
|
</div>
|
|
388
339
|
`;
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
const
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
range: { min: min, max: max },
|
|
429
|
-
clamp: { min: min, max: max },
|
|
430
|
-
};
|
|
431
|
-
if (handle.min === 'previous') {
|
|
432
|
-
if (previous) {
|
|
433
|
-
for (let j = index - 1; j >= 0; j--) {
|
|
434
|
-
const item = handles[j];
|
|
435
|
-
if (typeof item.min === 'number') {
|
|
436
|
-
result.range.min = item.min;
|
|
437
|
-
break;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
result.clamp.min = Math.max(previous.value, result.range.min);
|
|
441
|
-
/* c8 ignore next 5 */
|
|
442
|
-
}
|
|
443
|
-
else {
|
|
444
|
-
console.warn('First slider handle cannot have attribute min="previous"');
|
|
445
|
-
}
|
|
340
|
+
}
|
|
341
|
+
render() {
|
|
342
|
+
this.clearHandleComponentCache();
|
|
343
|
+
return this.model.map((model, index) => {
|
|
344
|
+
const zIndex = this.handleOrder.indexOf(model.name) + 1;
|
|
345
|
+
return this.renderHandle(model, index, zIndex, this.model.length > 1);
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
trackSegments() {
|
|
349
|
+
const values = this.model.map((model) => model.normalizedValue);
|
|
350
|
+
values.sort((a, b) => a - b);
|
|
351
|
+
values.unshift(0);
|
|
352
|
+
return values.map((value, index, array) => {
|
|
353
|
+
var _a;
|
|
354
|
+
return [
|
|
355
|
+
value,
|
|
356
|
+
(_a = array[index + 1]) != null ? _a : 1
|
|
357
|
+
];
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
updateModel() {
|
|
361
|
+
const handles = [...this.handles.values()];
|
|
362
|
+
const getRangeAndClamp = (index) => {
|
|
363
|
+
const handle = handles[index];
|
|
364
|
+
const previous = handles[index - 1];
|
|
365
|
+
const next = handles[index + 1];
|
|
366
|
+
const min = typeof handle.min === "number" ? handle.min : this.host.min;
|
|
367
|
+
const max = typeof handle.max === "number" ? handle.max : this.host.max;
|
|
368
|
+
const result = {
|
|
369
|
+
range: { min, max },
|
|
370
|
+
clamp: { min, max }
|
|
371
|
+
};
|
|
372
|
+
if (handle.min === "previous") {
|
|
373
|
+
if (previous) {
|
|
374
|
+
for (let j = index - 1; j >= 0; j--) {
|
|
375
|
+
const item = handles[j];
|
|
376
|
+
if (typeof item.min === "number") {
|
|
377
|
+
result.range.min = item.min;
|
|
378
|
+
break;
|
|
446
379
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
380
|
+
}
|
|
381
|
+
result.clamp.min = Math.max(previous.value, result.range.min);
|
|
382
|
+
}
|
|
383
|
+
if (false) {
|
|
384
|
+
if (!previous) {
|
|
385
|
+
window.__swc.issueWarning("slider:api:default", 'First slider handle cannot have attribute min="previous"', "https://opensource.adobe.com/spectrum-web-components/components/slider-handle/#multi-handle-slider-with-ordered-handles");
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (handle.max === "next") {
|
|
390
|
+
if (next) {
|
|
391
|
+
for (let j = index + 1; j < handles.length; j++) {
|
|
392
|
+
const item = handles[j];
|
|
393
|
+
if (typeof item.max === "number") {
|
|
394
|
+
result.range.max = item.max;
|
|
395
|
+
break;
|
|
462
396
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
397
|
+
}
|
|
398
|
+
result.clamp.max = Math.min(next.value, result.range.max);
|
|
399
|
+
}
|
|
400
|
+
if (false) {
|
|
401
|
+
if (!next) {
|
|
402
|
+
window.__swc.issueWarning("slider:api:default", 'Last slider handle cannot have attribute max="next"', "This needs a URL!");
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return result;
|
|
407
|
+
};
|
|
408
|
+
const modelValues = handles.map((handle, index) => {
|
|
409
|
+
var _a;
|
|
410
|
+
const rangeAndClamp = getRangeAndClamp(index);
|
|
411
|
+
const { toNormalized } = handle.normalization;
|
|
412
|
+
const clampedValue = Math.max(Math.min(handle.value, rangeAndClamp.clamp.max), rangeAndClamp.clamp.min);
|
|
413
|
+
const normalizedValue = toNormalized(clampedValue, rangeAndClamp.range.min, rangeAndClamp.range.max);
|
|
414
|
+
const model = {
|
|
415
|
+
name: handle.handleName,
|
|
416
|
+
value: clampedValue,
|
|
417
|
+
normalizedValue,
|
|
418
|
+
highlight: handle.highlight,
|
|
419
|
+
step: (_a = handle.step) != null ? _a : this.host.step,
|
|
420
|
+
normalization: handle.normalization,
|
|
421
|
+
handle,
|
|
422
|
+
ariaLabel: handle !== this.host && (handle == null ? void 0 : handle.label.length) > 0 ? handle.label : void 0,
|
|
423
|
+
...rangeAndClamp
|
|
424
|
+
};
|
|
425
|
+
return model;
|
|
426
|
+
});
|
|
427
|
+
this.model = modelValues;
|
|
428
|
+
}
|
|
429
|
+
async handleUpdatesComplete() {
|
|
430
|
+
const updates = [...this.handles.values()].filter((handle) => handle !== this.host).map((handle) => handle.updateComplete);
|
|
431
|
+
await Promise.all(updates);
|
|
432
|
+
}
|
|
484
433
|
}
|
|
485
|
-
//# sourceMappingURL=HandleController.js.map
|
|
434
|
+
//# sourceMappingURL=HandleController.js.map
|