@spectrum-web-components/slider 0.12.13 → 0.12.15-devmode.7

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 (54) hide show
  1. package/README.md +16 -0
  2. package/custom-elements.json +40 -0
  3. package/package.json +41 -16
  4. package/sp-slider-handle.dev.js +3 -0
  5. package/sp-slider-handle.dev.js.map +7 -0
  6. package/sp-slider-handle.js +3 -14
  7. package/sp-slider-handle.js.map +7 -1
  8. package/sp-slider.dev.js +4 -0
  9. package/sp-slider.dev.js.map +7 -0
  10. package/sp-slider.js +4 -15
  11. package/sp-slider.js.map +7 -1
  12. package/src/HandleController.dev.js +434 -0
  13. package/src/HandleController.dev.js.map +7 -0
  14. package/src/HandleController.js +402 -451
  15. package/src/HandleController.js.map +7 -1
  16. package/src/Slider.d.ts +8 -0
  17. package/src/Slider.dev.js +367 -0
  18. package/src/Slider.dev.js.map +7 -0
  19. package/src/Slider.js +282 -289
  20. package/src/Slider.js.map +7 -1
  21. package/src/SliderHandle.dev.js +184 -0
  22. package/src/SliderHandle.dev.js.map +7 -0
  23. package/src/SliderHandle.js +171 -179
  24. package/src/SliderHandle.js.map +7 -1
  25. package/src/index.dev.js +4 -0
  26. package/src/index.dev.js.map +7 -0
  27. package/src/index.js +4 -15
  28. package/src/index.js.map +7 -1
  29. package/src/slider.css.dev.js +234 -0
  30. package/src/slider.css.dev.js.map +7 -0
  31. package/src/slider.css.js +3 -14
  32. package/src/slider.css.js.map +7 -1
  33. package/src/spectrum-slider.css.dev.js +216 -0
  34. package/src/spectrum-slider.css.dev.js.map +7 -0
  35. package/src/spectrum-slider.css.js +3 -14
  36. package/src/spectrum-slider.css.js.map +7 -1
  37. package/stories/slider.stories.js +257 -267
  38. package/stories/slider.stories.js.map +7 -1
  39. package/sync/sp-slider.dev.js +3 -0
  40. package/sync/sp-slider.dev.js.map +7 -0
  41. package/sync/sp-slider.js +3 -14
  42. package/sync/sp-slider.js.map +7 -1
  43. package/test/benchmark/test-basic.js +5 -16
  44. package/test/benchmark/test-basic.js.map +7 -1
  45. package/test/slider-editable-sync.test.js +132 -144
  46. package/test/slider-editable-sync.test.js.map +7 -1
  47. package/test/slider-editable.test.js +151 -144
  48. package/test/slider-editable.test.js.map +7 -1
  49. package/test/slider-handle-upgrade.test.js +10 -21
  50. package/test/slider-handle-upgrade.test.js.map +7 -1
  51. package/test/slider.test-vrt.js +4 -15
  52. package/test/slider.test-vrt.js.map +7 -1
  53. package/test/slider.test.js +686 -700
  54. package/test/slider.test.js.map +7 -1
@@ -1,362 +1,315 @@
1
- /*
2
- Copyright 2021 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 { 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
- constructor(host) {
18
- this.handles = new Map();
19
- this.model = [];
20
- this.handleOrder = [];
21
- this.handleOrientation = () => {
22
- this.updateBoundingRect();
23
- };
24
- this.extractModelFromLightDom = () => {
25
- let handles = [
26
- ...this.host.querySelectorAll('[slot="handle"]'),
27
- ];
28
- if (handles.length === 0) {
29
- handles = [this.host];
30
- }
31
- // extractModelFromLightDom depends on slotted handles already having been upgraded
32
- if (handles.some((h) => this.waitForUpgrade(h))) {
33
- return;
34
- }
35
- this.handles = new Map();
36
- this.handleOrder = [];
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
- this.host.requestUpdate();
115
- }
116
- /**
117
- * It is possible for value attributes to be set programmatically. The <input>
118
- * for a particular slider needs to have an opportunity to validate any such
119
- * values
120
- *
121
- * @param handle Handle who's value needs validation
122
- */
123
- setValueFromHandle(handle) {
124
- const elements = this.getHandleElements(handle);
125
- /* c8 ignore next */
126
- if (!elements)
127
- return;
128
- const { input } = elements;
129
- if (input.valueAsNumber === handle.value) {
130
- if (handle.dragging) {
131
- handle.dispatchInputEvent();
132
- }
133
- }
134
- else {
135
- input.valueAsNumber = handle.value;
136
- handle.value = input.valueAsNumber;
137
- this.requestUpdate();
138
- }
139
- handle.value = input.valueAsNumber;
140
- }
141
- handleHasChanged(handle) {
142
- if (handle !== this.host) {
143
- this.requestUpdate();
144
- }
145
- }
146
- 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) => {
147
32
  var _a;
148
- const { handle } = model;
149
- const numberFormat = (_a = handle.numberFormat) !== null && _a !== void 0 ? _a : this.host.numberFormat;
150
- return handle.getAriaHandleText(model.value, numberFormat);
151
- }
152
- get formattedValues() {
153
- const result = new Map();
154
- for (const model of this.model) {
155
- result.set(model.name, this.formattedValueForHandle(model));
156
- }
157
- return result;
158
- }
159
- get focusElement() {
160
- const { input } = this.getActiveHandleElements();
161
- if (this.host.editable &&
162
- !input.model.handle.dragging) {
163
- return this.host.numberField;
164
- }
165
- return input;
166
- }
167
- hostConnected() {
168
- if ('orientation' in screen) {
169
- screen.orientation.addEventListener('change', this.handleOrientation);
170
- }
171
- else {
172
- window.addEventListener('orientationchange', this.handleOrientation);
173
- }
174
- }
175
- hostDisconnected() {
176
- if ('orientation' in screen) {
177
- screen.orientation.removeEventListener('change', this.handleOrientation);
178
- }
179
- else {
180
- window.removeEventListener('orientationchange', this.handleOrientation);
181
- }
182
- }
183
- hostUpdate() {
184
- this.updateModel();
185
- }
186
- // Since extractModelFromLightDom bails on the first un-upgraded handle,
187
- // a maximum of one listener will be set up per extraction attempt.
188
- waitForUpgrade(handle) {
189
- if (handle instanceof SliderHandle) {
190
- return false;
33
+ if (!((_a = handle.handleName) == null ? void 0 : _a.length)) {
34
+ handle.name = `handle${index + 1}`;
191
35
  }
192
- handle.addEventListener('sp-slider-handle-ready', () => this.extractModelFromLightDom(), { once: true, passive: true });
193
- return true;
194
- }
195
- get activeHandle() {
196
- return this.handleOrder[this.handleOrder.length - 1];
197
- }
198
- get activeHandleInputId() {
199
- const active = this.activeHandle;
200
- const index = this.model.findIndex((model) => model.name === active);
201
- return `input-${index}`;
202
- }
203
- activateHandle(name) {
204
- const index = this.handleOrder.findIndex((item) => item === name);
205
- if (index >= 0) {
206
- this.handleOrder.splice(index, 1);
207
- }
208
- this.handleOrder.push(name);
209
- }
210
- getActiveHandleElements() {
211
- const name = this.activeHandle;
212
- const handleSlider = this.handles.get(name);
213
- const elements = this.getHandleElements(handleSlider);
214
- return Object.assign({ model: handleSlider }, elements);
215
- }
216
- getHandleElements(sliderHandle) {
217
- if (!this.handleRefMap) {
218
- this.handleRefMap = new WeakMap();
219
- const inputNodes = this.host.shadowRoot.querySelectorAll('.handle > input');
220
- for (const inputNode of inputNodes) {
221
- const input = inputNode;
222
- const handle = input.parentElement;
223
- const model = this.handles.get(handle.getAttribute('name'));
224
- if (model) {
225
- this.handleRefMap.set(model, { input, handle });
226
- }
227
- }
228
- }
229
- const components = this.handleRefMap.get(sliderHandle);
230
- return components;
231
- }
232
- clearHandleComponentCache() {
233
- delete this.handleRefMap;
234
- }
235
- get boundingClientRect() {
236
- if (!this._boundingClientRect) {
237
- this._boundingClientRect = this.host.track.getBoundingClientRect();
238
- }
239
- return this._boundingClientRect;
240
- }
241
- updateBoundingRect() {
242
- delete this._boundingClientRect;
243
- }
244
- /**
245
- * Return the `input` and `model` associated with the event and
246
- * whether the `input` is a `resolvedInput` meaning it was acquired
247
- * from the `model` rather than the event.
248
- */
249
- extractDataFromEvent(event) {
250
- if (!this._activePointerEventData) {
251
- let input = event.target.querySelector(':scope > .input');
252
- const resolvedInput = !input;
253
- const model = input
254
- ? input.model
255
- : this.model.find((item) => item.name === this.activeHandle);
256
- if (!input && !!model) {
257
- input = model.handle.focusElement;
258
- }
259
- this._activePointerEventData = {
260
- input,
261
- model,
262
- resolvedInput,
263
- };
264
- }
265
- return this._activePointerEventData;
266
- }
267
- handlePointerdown(event) {
268
- const { resolvedInput, model } = this.extractDataFromEvent(event);
269
- if (!model || this.host.disabled || event.button !== 0) {
270
- event.preventDefault();
271
- return;
272
- }
273
- this.host.track.setPointerCapture(event.pointerId);
274
- this.updateBoundingRect();
275
- this.host.labelEl.click();
276
- this.draggingHandle = model.handle;
277
- model.handle.dragging = true;
278
- this.activateHandle(model.name);
279
- if (resolvedInput) {
280
- // When the input is resolved forward the pointer event to
281
- // `handlePointermove` in order to update the value/UI becuase
282
- // the pointer event was on the track not a handle
283
- this.handlePointermove(event);
284
- }
285
- this.requestUpdate();
286
- }
287
- handlePointerup(event) {
288
- const { input, model } = this.extractDataFromEvent(event);
289
- delete this._activePointerEventData;
290
- if (!model)
291
- return;
292
- this.host.labelEl.click();
293
- this.cancelDrag(model);
294
- this.requestUpdate();
295
- this.host.track.releasePointerCapture(event.pointerId);
296
- this.dispatchChangeEvent(input, model.handle);
297
- }
298
- handlePointermove(event) {
299
- const { input, model } = this.extractDataFromEvent(event);
300
- if (!model)
301
- return;
302
- /* c8 ignore next 3 */
303
- if (!this.draggingHandle) {
304
- return;
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 });
305
198
  }
306
- event.stopPropagation();
307
- input.value = this.calculateHandlePosition(event, model).toString();
308
- model.handle.value = parseFloat(input.value);
309
- this.requestUpdate();
310
- }
311
- cancelDrag(model) {
312
- model =
313
- model || this.model.find((item) => item.name === this.activeHandle);
314
- if (!model)
315
- return;
316
- model.handle.highlight = false;
317
- delete this.draggingHandle;
318
- model.handle.dragging = false;
319
- }
320
- dispatchChangeEvent(input, handle) {
321
- input.valueAsNumber = handle.value;
322
- const changeEvent = new Event('change', {
323
- bubbles: true,
324
- composed: true,
325
- });
326
- handle.dispatchEvent(changeEvent);
327
- }
328
- /**
329
- * Returns the value under the cursor
330
- * @param: PointerEvent on slider
331
- * @return: Slider value that correlates to the position under the pointer
332
- */
333
- calculateHandlePosition(event, model) {
334
- const rect = this.boundingClientRect;
335
- const minOffset = rect.left;
336
- const offset = event.clientX;
337
- const size = rect.width;
338
- const directionalOffset = this.host.isLTR
339
- ? offset - minOffset
340
- : size - (offset - minOffset);
341
- const normalized = directionalOffset / size;
342
- return model.normalization.fromNormalized(normalized, model.range.min, model.range.max);
343
- }
344
- renderHandle(model, index, zIndex, isMultiHandle) {
345
- var _a;
346
- const classes = {
347
- handle: true,
348
- dragging: ((_a = this.draggingHandle) === null || _a === void 0 ? void 0 : _a.handleName) === model.name,
349
- 'handle-highlight': model.highlight,
350
- };
351
- const style = {
352
- [this.host.isLTR ? 'left' : 'right']: `${model.normalizedValue * 100}%`,
353
- 'z-index': zIndex.toString(),
354
- // Allow setting background per-handle
355
- 'background-color': `var(--spectrum-slider-handle-background-color-${index}, var(--spectrum-slider-handle-default-background-color))`,
356
- 'border-color': `var(--spectrum-slider-handle-border-color-${index}, var(-spectrum-slider-handle-default-border-color))`,
357
- };
358
- const ariaLabelledBy = isMultiHandle ? `label input-${index}` : 'label';
359
- return html `
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`
360
313
  <div
361
314
  class=${classMap(classes)}
362
315
  name=${model.name}
@@ -371,8 +324,8 @@ export class HandleController {
371
324
  max=${model.clamp.max}
372
325
  step=${model.step}
373
326
  value=${model.value}
374
- aria-disabled=${ifDefined(this.host.disabled ? 'true' : undefined)}
375
- tabindex=${ifDefined(this.host.editable ? -1 : undefined)}
327
+ aria-disabled=${ifDefined(this.host.disabled ? "true" : void 0)}
328
+ tabindex=${ifDefined(this.host.editable ? -1 : void 0)}
376
329
  aria-label=${ifDefined(model.ariaLabel)}
377
330
  aria-labelledby=${ariaLabelledBy}
378
331
  aria-valuetext=${this.formattedValueForHandle(model)}
@@ -384,100 +337,98 @@ export class HandleController {
384
337
  />
385
338
  </div>
386
339
  `;
387
- }
388
- render() {
389
- this.clearHandleComponentCache();
390
- return this.model.map((model, index) => {
391
- const zIndex = this.handleOrder.indexOf(model.name) + 1;
392
- return this.renderHandle(model, index, zIndex, this.model.length > 1);
393
- });
394
- }
395
- /**
396
- * Returns a list of track segment [start, end] tuples where the values are
397
- * normalized to be between 0 and 1.
398
- * @returns A list of track segment tuples [start, end]
399
- */
400
- trackSegments() {
401
- const values = this.model.map((model) => model.normalizedValue);
402
- values.sort((a, b) => a - b);
403
- // The first segment always starts at 0
404
- values.unshift(0);
405
- return values.map((value, index, array) => {
406
- var _a;
407
- return [
408
- value,
409
- (_a = array[index + 1]) !== null && _a !== void 0 ? _a : 1,
410
- ];
411
- });
412
- }
413
- updateModel() {
414
- const handles = [...this.handles.values()];
415
- const getRangeAndClamp = (index) => {
416
- const handle = handles[index];
417
- const previous = handles[index - 1];
418
- const next = handles[index + 1];
419
- const min = typeof handle.min === 'number'
420
- ? handle.min
421
- : this.host.min;
422
- const max = typeof handle.max === 'number'
423
- ? handle.max
424
- : this.host.max;
425
- const result = {
426
- range: { min: min, max: max },
427
- clamp: { min: min, max: max },
428
- };
429
- if (handle.min === 'previous') {
430
- if (previous) {
431
- for (let j = index - 1; j >= 0; j--) {
432
- const item = handles[j];
433
- if (typeof item.min === 'number') {
434
- result.range.min = item.min;
435
- break;
436
- }
437
- }
438
- result.clamp.min = Math.max(previous.value, result.range.min);
439
- /* c8 ignore next 5 */
440
- }
441
- else {
442
- console.warn('First slider handle cannot have attribute min="previous"');
443
- }
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;
444
379
  }
445
- if (handle.max === 'next') {
446
- if (next) {
447
- for (let j = index + 1; j < handles.length; j++) {
448
- const item = handles[j];
449
- if (typeof item.max === 'number') {
450
- result.range.max = item.max;
451
- break;
452
- }
453
- }
454
- result.clamp.max = Math.min(next.value, result.range.max);
455
- /* c8 ignore next 5 */
456
- }
457
- else {
458
- console.warn('Last slider handle cannot have attribute max="next"');
459
- }
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;
460
396
  }
461
- return result;
462
- };
463
- const modelValues = handles.map((handle, index) => {
464
- var _a;
465
- const rangeAndClamp = getRangeAndClamp(index);
466
- const { toNormalized } = handle.normalization;
467
- const clampedValue = Math.max(Math.min(handle.value, rangeAndClamp.clamp.max), rangeAndClamp.clamp.min);
468
- const normalizedValue = toNormalized(clampedValue, rangeAndClamp.range.min, rangeAndClamp.range.max);
469
- const model = Object.assign({ name: handle.handleName, value: clampedValue, normalizedValue, highlight: handle.highlight, step: (_a = handle.step) !== null && _a !== void 0 ? _a : this.host.step, normalization: handle.normalization, handle, ariaLabel: handle !== this.host && (handle === null || handle === void 0 ? void 0 : handle.label.length) > 0
470
- ? handle.label
471
- : undefined }, rangeAndClamp);
472
- return model;
473
- });
474
- this.model = modelValues;
475
- }
476
- async handleUpdatesComplete() {
477
- const updates = [...this.handles.values()]
478
- .filter((handle) => handle !== this.host)
479
- .map((handle) => handle.updateComplete);
480
- await Promise.all(updates);
481
- }
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
+ }
482
433
  }
483
- //# sourceMappingURL=HandleController.js.map
434
+ //# sourceMappingURL=HandleController.js.map