@fluentui/web-components 3.0.0-beta.41 → 3.0.0-beta.42

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 (58) hide show
  1. package/CHANGELOG.md +11 -2
  2. package/dist/dts/slider/slider.d.ts +180 -35
  3. package/dist/dts/slider/slider.options.d.ts +2 -2
  4. package/dist/dts/slider/slider.template.d.ts +2 -2
  5. package/dist/dts/styles/states/index.d.ts +5 -0
  6. package/dist/dts/utils/converters.d.ts +17 -0
  7. package/dist/dts/utils/index.d.ts +1 -0
  8. package/dist/esm/accordion/accordion.js.map +1 -1
  9. package/dist/esm/accordion-item/accordion-item.js.map +1 -1
  10. package/dist/esm/anchor-button/anchor-button.js.map +1 -1
  11. package/dist/esm/avatar/avatar.js +2 -1
  12. package/dist/esm/avatar/avatar.js.map +1 -1
  13. package/dist/esm/badge/badge.js.map +1 -1
  14. package/dist/esm/button/button.js +2 -1
  15. package/dist/esm/button/button.js.map +1 -1
  16. package/dist/esm/checkbox/checkbox.js +2 -1
  17. package/dist/esm/checkbox/checkbox.js.map +1 -1
  18. package/dist/esm/counter-badge/counter-badge.js.map +1 -1
  19. package/dist/esm/dialog/dialog.js.map +1 -1
  20. package/dist/esm/dialog-body/dialog-body.js.map +1 -1
  21. package/dist/esm/divider/divider.js.map +1 -1
  22. package/dist/esm/drawer/drawer.js.map +1 -1
  23. package/dist/esm/field/field.js.map +1 -1
  24. package/dist/esm/image/image.js.map +1 -1
  25. package/dist/esm/label/label.js.map +1 -1
  26. package/dist/esm/link/link.js.map +1 -1
  27. package/dist/esm/menu/menu.js.map +1 -1
  28. package/dist/esm/menu-item/menu-item.js.map +1 -1
  29. package/dist/esm/menu-list/menu-list.js +2 -1
  30. package/dist/esm/menu-list/menu-list.js.map +1 -1
  31. package/dist/esm/message-bar/message-bar.js.map +1 -1
  32. package/dist/esm/patterns/aria-globals.js.map +1 -1
  33. package/dist/esm/progress-bar/progress-bar.js.map +1 -1
  34. package/dist/esm/radio-group/radio-group.js +2 -1
  35. package/dist/esm/radio-group/radio-group.js.map +1 -1
  36. package/dist/esm/rating-display/rating-display.js.map +1 -1
  37. package/dist/esm/slider/slider.js +442 -220
  38. package/dist/esm/slider/slider.js.map +1 -1
  39. package/dist/esm/slider/slider.styles.js +107 -132
  40. package/dist/esm/slider/slider.styles.js.map +1 -1
  41. package/dist/esm/slider/slider.template.js +11 -28
  42. package/dist/esm/slider/slider.template.js.map +1 -1
  43. package/dist/esm/spinner/spinner.js.map +1 -1
  44. package/dist/esm/styles/states/index.js +5 -0
  45. package/dist/esm/styles/states/index.js.map +1 -1
  46. package/dist/esm/tab/tab.js.map +1 -1
  47. package/dist/esm/tabs/tabs.js.map +1 -1
  48. package/dist/esm/text-input/text-input.js +2 -1
  49. package/dist/esm/text-input/text-input.js.map +1 -1
  50. package/dist/esm/toggle-button/toggle-button.js.map +1 -1
  51. package/dist/esm/utils/converters.js +26 -0
  52. package/dist/esm/utils/converters.js.map +1 -0
  53. package/dist/esm/utils/index.js +1 -0
  54. package/dist/esm/utils/index.js.map +1 -1
  55. package/dist/web-components.d.ts +181 -101
  56. package/dist/web-components.js +368 -502
  57. package/dist/web-components.min.js +198 -196
  58. package/package.json +1 -1
@@ -1,17 +1,319 @@
1
1
  import { __decorate } from "tslib";
2
- import { attr, css, nullableNumberConverter, observable, Observable } from '@microsoft/fast-element';
2
+ import { attr, css, FASTElement, observable, Observable } from '@microsoft/fast-element';
3
3
  import { Direction, keyArrowDown, keyArrowLeft, keyArrowRight, keyArrowUp, keyEnd, keyHome, limit, Orientation, } from '@microsoft/fast-web-utilities';
4
- import { getDirection } from '../utils/index.js';
5
- import { SliderMode } from './slider.options.js';
6
- import { FormAssociatedSlider } from './slider.form-associated.js';
4
+ import { numberLikeStringConverter } from '../utils/converters.js';
5
+ import { getDirection } from '../utils/direction.js';
6
+ import { toggleState } from '../utils/element-internals.js';
7
+ import { SliderMode, SliderOrientation } from './slider.options.js';
7
8
  import { convertPixelToPercent } from './slider-utilities.js';
8
9
  /**
9
10
  * The base class used for constructing a fluent-slider custom element
11
+ *
12
+ * @slot thumb - The slot for a custom thumb element.
13
+ * @csspart thumb-container - The container element of the thumb.
14
+ * @csspart track-container - The container element of the track.
15
+ * @fire change - Fires a custom 'change' event when the value changes.
16
+ *
10
17
  * @public
11
18
  */
12
- export class Slider extends FormAssociatedSlider {
19
+ class Slider extends FASTElement {
20
+ /**
21
+ * A reference to all associated `<label>` elements.
22
+ *
23
+ * @public
24
+ */
25
+ get labels() {
26
+ return Object.freeze(Array.from(this.elementInternals.labels));
27
+ }
28
+ sizeChanged(prev, next) {
29
+ if (prev) {
30
+ toggleState(this.elementInternals, `${prev}`, false);
31
+ }
32
+ if (next) {
33
+ toggleState(this.elementInternals, `${next}`, true);
34
+ }
35
+ }
36
+ handleChange(_, propertyName) {
37
+ switch (propertyName) {
38
+ case 'min':
39
+ case 'max':
40
+ this.setSliderPosition(this.direction);
41
+ case 'step':
42
+ this.handleStepStyles();
43
+ break;
44
+ }
45
+ }
46
+ /**
47
+ * Handles changes to step styling based on the step value
48
+ * NOTE: This function is not a changed callback, stepStyles is not observable
49
+ */
50
+ handleStepStyles() {
51
+ if (this.step) {
52
+ const totalSteps = (100 / Math.floor((this.maxAsNumber - this.minAsNumber) / this.stepAsNumber));
53
+ if (this.stepStyles !== undefined) {
54
+ this.$fastController.removeStyles(this.stepStyles);
55
+ }
56
+ this.stepStyles = css /**css*/ `
57
+ :host {
58
+ --step-rate: ${totalSteps}%;
59
+ }
60
+ `;
61
+ this.$fastController.addStyles(this.stepStyles);
62
+ }
63
+ else if (this.stepStyles !== undefined) {
64
+ this.$fastController.removeStyles(this.stepStyles);
65
+ }
66
+ }
67
+ /**
68
+ * Sets the value of the input when the value attribute changes.
69
+ *
70
+ * @param prev - The previous value
71
+ * @param next - The current value
72
+ * @internal
73
+ */
74
+ initialValueChanged(_, next) {
75
+ if (this.$fastController.isConnected) {
76
+ this.value = next;
77
+ }
78
+ else {
79
+ this._value = next;
80
+ }
81
+ }
82
+ /**
83
+ * The element's validity state.
84
+ *
85
+ * @public
86
+ * @remarks
87
+ * Reflects the {@link https://developer.mozilla.org/docs/Web/API/ElementInternals/validity | `ElementInternals.validity`} property.
88
+ */
89
+ get validity() {
90
+ return this.elementInternals.validity;
91
+ }
92
+ /**
93
+ * The element's validation message.
94
+ *
95
+ * @public
96
+ * @remarks
97
+ * Reflects the {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/validationMessage | `ElemenentInternals.validationMessage`} property.
98
+ */
99
+ get validationMessage() {
100
+ return this.elementInternals.validationMessage;
101
+ }
102
+ /**
103
+ * Whether the element is a candidate for its owning form's constraint validation.
104
+ *
105
+ * @public
106
+ * @remarks
107
+ * Reflects the {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/willValidate | `ElemenentInternals.willValidate`} property.
108
+ */
109
+ get willValidate() {
110
+ return this.elementInternals.willValidate;
111
+ }
112
+ /**
113
+ * Checks the element's validity.
114
+ * @public
115
+ * @remarks
116
+ * Reflects the {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/checkValidity | `ElemenentInternals.checkValidity`} method.
117
+ */
118
+ checkValidity() {
119
+ return this.elementInternals.checkValidity();
120
+ }
121
+ /**
122
+ * Reports the element's validity.
123
+ * @public
124
+ * @remarks
125
+ * Reflects the {@link https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/reportValidity | `ElemenentInternals.reportValidity`} method.
126
+ */
127
+ reportValidity() {
128
+ return this.elementInternals.reportValidity();
129
+ }
130
+ /**
131
+ * Sets a custom validity message.
132
+ * @public
133
+ */
134
+ setCustomValidity(message) {
135
+ this.setValidity({ customError: !!message }, message);
136
+ }
137
+ /**
138
+ * Sets the validity of the control.
139
+ *
140
+ * @param flags - Validity flags to set.
141
+ * @param message - Optional message to supply. If not provided, the control's `validationMessage` will be used.
142
+ * @param anchor - Optional anchor to use for the validation message.
143
+ *
144
+ * @internal
145
+ */
146
+ setValidity(flags, message, anchor) {
147
+ if (this.$fastController.isConnected) {
148
+ if (this.disabled) {
149
+ this.elementInternals.setValidity({});
150
+ return;
151
+ }
152
+ this.elementInternals.setValidity({ customError: !!message, ...flags }, message !== null && message !== void 0 ? message : this.validationMessage, anchor);
153
+ }
154
+ }
155
+ /**
156
+ * The current value of the input.
157
+ *
158
+ * @public
159
+ */
160
+ get value() {
161
+ Observable.track(this, 'value');
162
+ return this._value.toString();
163
+ }
164
+ set value(value) {
165
+ if (!this.$fastController.isConnected) {
166
+ this._value = value.toString();
167
+ return;
168
+ }
169
+ const nextAsNumber = parseFloat(value);
170
+ const newValue = limit(this.minAsNumber, this.maxAsNumber, this.convertToConstrainedValue(nextAsNumber)).toString();
171
+ if (newValue !== value) {
172
+ this.value = newValue;
173
+ return;
174
+ }
175
+ this._value = value.toString();
176
+ this.elementInternals.ariaValueNow = this._value;
177
+ this.elementInternals.ariaValueText = this.valueTextFormatter(this._value);
178
+ this.setSliderPosition(this.direction);
179
+ this.$emit('change');
180
+ this.setFormValue(value);
181
+ Observable.notify(this, 'value');
182
+ }
183
+ /**
184
+ * Resets the form value to its initial value when the form is reset.
185
+ *
186
+ * @internal
187
+ */
188
+ formResetCallback() {
189
+ var _a;
190
+ this.value = (_a = this.initialValue) !== null && _a !== void 0 ? _a : this.midpoint;
191
+ }
192
+ /**
193
+ * Disabled the component when its associated form is disabled.
194
+ *
195
+ * @internal
196
+ *
197
+ * @privateRemarks
198
+ * DO NOT change the `disabled` property or attribute here, because if the
199
+ * `disabled` attribute is present, reenabling an ancestor `<fieldset>`
200
+ * element will not reenabling this component.
201
+ */
202
+ formDisabledCallback(disabled) {
203
+ this.setDisabledSideEffect(disabled);
204
+ }
205
+ /**
206
+ * Reflects the {@link https://developer.mozilla.org/docs/Web/API/ElementInternals/setFormValue | `ElementInternals.setFormValue()`} method.
207
+ *
208
+ * @internal
209
+ */
210
+ setFormValue(value, state) {
211
+ this.elementInternals.setFormValue(value, value !== null && value !== void 0 ? value : state);
212
+ }
213
+ /**
214
+ * The value property, typed as a number.
215
+ *
216
+ * @public
217
+ */
218
+ get valueAsNumber() {
219
+ return parseFloat(this.value);
220
+ }
221
+ set valueAsNumber(next) {
222
+ this.value = next.toString();
223
+ }
224
+ valueTextFormatterChanged() {
225
+ if (typeof this.valueTextFormatter === 'function') {
226
+ this.elementInternals.ariaValueText = this.valueTextFormatter(this._value);
227
+ }
228
+ else {
229
+ this.elementInternals.ariaValueText = '';
230
+ }
231
+ }
232
+ disabledChanged() {
233
+ this.setDisabledSideEffect(this.disabled);
234
+ }
235
+ minChanged() {
236
+ this.elementInternals.ariaValueMin = `${this.minAsNumber}`;
237
+ if (this.$fastController.isConnected && this.minAsNumber > this.valueAsNumber) {
238
+ this.value = this.min;
239
+ }
240
+ }
241
+ /**
242
+ * Returns the min property or the default value
243
+ *
244
+ * @internal
245
+ */
246
+ get minAsNumber() {
247
+ if (this.min !== undefined) {
248
+ const parsed = parseFloat(this.min);
249
+ if (!Number.isNaN(parsed)) {
250
+ return parsed;
251
+ }
252
+ }
253
+ return 0;
254
+ }
255
+ maxChanged() {
256
+ this.elementInternals.ariaValueMax = `${this.maxAsNumber}`;
257
+ if (this.$fastController.isConnected && this.maxAsNumber < this.valueAsNumber) {
258
+ this.value = this.max;
259
+ }
260
+ }
261
+ /**
262
+ * Returns the max property or the default value
263
+ *
264
+ * @internal
265
+ */
266
+ get maxAsNumber() {
267
+ if (this.max !== undefined) {
268
+ const parsed = parseFloat(this.max);
269
+ if (!Number.isNaN(parsed)) {
270
+ return parsed;
271
+ }
272
+ }
273
+ return 100;
274
+ }
275
+ stepChanged() {
276
+ this.updateStepMultiplier();
277
+ // Update value to align with the new step if needed.
278
+ if (this.$fastController.isConnected) {
279
+ this.value = this._value;
280
+ }
281
+ }
282
+ /**
283
+ * Returns the step property as a number.
284
+ *
285
+ * @internal
286
+ */
287
+ get stepAsNumber() {
288
+ if (this.step !== undefined) {
289
+ const parsed = parseFloat(this.step);
290
+ if (!Number.isNaN(parsed) && parsed > 0) {
291
+ return parsed;
292
+ }
293
+ }
294
+ return 1;
295
+ }
296
+ orientationChanged(prev, next) {
297
+ this.elementInternals.ariaOrientation = next !== null && next !== void 0 ? next : Orientation.horizontal;
298
+ if (prev) {
299
+ toggleState(this.elementInternals, `${prev}`, false);
300
+ }
301
+ if (next) {
302
+ toggleState(this.elementInternals, `${next}`, true);
303
+ }
304
+ if (this.$fastController.isConnected) {
305
+ this.setSliderPosition(this.direction);
306
+ }
307
+ }
13
308
  constructor() {
14
- super(...arguments);
309
+ var _a;
310
+ super();
311
+ /**
312
+ * The internal {@link https://developer.mozilla.org/docs/Web/API/ElementInternals | `ElementInternals`} instance for the component.
313
+ *
314
+ * @internal
315
+ */
316
+ this.elementInternals = this.attachInternals();
15
317
  /**
16
318
  * @internal
17
319
  */
@@ -41,37 +343,42 @@ export class Slider extends FormAssociatedSlider {
41
343
  */
42
344
  this.trackMinHeight = 0;
43
345
  /**
44
- * Custom function that generates a string for the component's "aria-valuetext" attribute based on the current value.
346
+ * Custom function that generates a string for the component's "ariaValueText" on element internals based on the current value.
45
347
  *
46
348
  * @public
47
349
  */
48
- this.valueTextFormatter = () => null;
350
+ this.valueTextFormatter = () => '';
351
+ /**
352
+ * The element's disabled state.
353
+ * @public
354
+ * @remarks
355
+ * HTML Attribute: `disabled`
356
+ */
357
+ this.disabled = false;
49
358
  /**
50
359
  * The minimum allowed value.
51
360
  *
52
- * @defaultValue - 0
53
361
  * @public
54
362
  * @remarks
55
363
  * HTML Attribute: min
56
364
  */
57
- this.min = 0; // Map to proxy element.
365
+ this.min = '';
58
366
  /**
59
367
  * The maximum allowed value.
60
368
  *
61
- * @defaultValue - 10
62
369
  * @public
63
370
  * @remarks
64
371
  * HTML Attribute: max
65
372
  */
66
- this.max = 10; // Map to proxy element.
373
+ this.max = '';
67
374
  /**
68
- * The orientation of the slider.
375
+ * Value to increment or decrement via arrow keys, mouse click or drag.
69
376
  *
70
377
  * @public
71
378
  * @remarks
72
- * HTML Attribute: orientation
379
+ * HTML Attribute: step
73
380
  */
74
- this.orientation = Orientation.horizontal;
381
+ this.step = '';
75
382
  /**
76
383
  * The selection mode.
77
384
  *
@@ -80,35 +387,39 @@ export class Slider extends FormAssociatedSlider {
80
387
  * HTML Attribute: mode
81
388
  */
82
389
  this.mode = SliderMode.singleValue;
83
- this.keypressHandler = (e) => {
84
- if (this.readOnly || this.disabled) {
390
+ this.keypressHandler = (event) => {
391
+ if (this.disabled) {
85
392
  return;
86
393
  }
87
- if (e.key === keyHome) {
88
- e.preventDefault();
89
- this.direction !== Direction.rtl && this.orientation !== Orientation.vertical
90
- ? (this.value = `${this.min}`)
91
- : (this.value = `${this.max}`);
92
- }
93
- else if (e.key === keyEnd) {
94
- e.preventDefault();
95
- this.direction !== Direction.rtl && this.orientation !== Orientation.vertical
96
- ? (this.value = `${this.max}`)
97
- : (this.value = `${this.min}`);
98
- }
99
- else if (!e.shiftKey) {
100
- switch (e.key) {
101
- case keyArrowRight:
102
- case keyArrowUp:
103
- e.preventDefault();
394
+ switch (event.key) {
395
+ case keyHome:
396
+ event.preventDefault();
397
+ this.value =
398
+ this.direction !== Direction.rtl && this.orientation !== Orientation.vertical
399
+ ? `${this.minAsNumber}`
400
+ : `${this.maxAsNumber}`;
401
+ break;
402
+ case keyEnd:
403
+ event.preventDefault();
404
+ this.value =
405
+ this.direction !== Direction.rtl && this.orientation !== Orientation.vertical
406
+ ? `${this.maxAsNumber}`
407
+ : `${this.minAsNumber}`;
408
+ break;
409
+ case keyArrowRight:
410
+ case keyArrowUp:
411
+ if (!event.shiftKey) {
412
+ event.preventDefault();
104
413
  this.increment();
105
- break;
106
- case keyArrowLeft:
107
- case keyArrowDown:
108
- e.preventDefault();
414
+ }
415
+ break;
416
+ case keyArrowLeft:
417
+ case keyArrowDown:
418
+ if (!event.shiftKey) {
419
+ event.preventDefault();
109
420
  this.decrement();
110
- break;
111
- }
421
+ }
422
+ break;
112
423
  }
113
424
  };
114
425
  this.setupTrackConstraints = () => {
@@ -122,180 +433,85 @@ export class Slider extends FormAssociatedSlider {
122
433
  this.trackWidth = 1;
123
434
  }
124
435
  };
125
- //Remove
126
436
  this.setupListeners = (remove = false) => {
127
437
  //TODO Bug: https://github.com/microsoft/fluentui/issues/30087
128
438
  this.addEventListener('keydown', this.keypressHandler);
129
- this.addEventListener('mousedown', this.handleMouseDown);
130
- // removes handlers attached by mousedown handlers
131
439
  if (remove) {
132
440
  this.removeEventListener('keydown', this.keypressHandler);
133
- this.removeEventListener('mousedown', this.handleMouseDown);
134
441
  }
135
442
  };
136
- /**
137
- * @internal
138
- */
139
- this.initialValue = '';
140
443
  /**
141
444
  * Handle mouse moves during a thumb drag operation
142
445
  * If the event handler is null it removes the events
143
446
  */
144
- this.handleThumbMouseDown = (event) => {
447
+ this.handleThumbPointerDown = (event) => {
145
448
  const windowFn = event !== null ? window.addEventListener : window.removeEventListener;
146
- windowFn('mouseup', this.handleWindowMouseUp);
147
- windowFn('mousemove', this.handleMouseMove, { passive: true });
148
- windowFn('touchmove', this.handleMouseMove, { passive: true });
149
- windowFn('touchend', this.handleWindowMouseUp);
449
+ windowFn('pointerup', this.handleWindowPointerUp);
450
+ windowFn('pointermove', this.handlePointerMove, { passive: true });
451
+ windowFn('touchmove', this.handlePointerMove, { passive: true });
452
+ windowFn('touchend', this.handleWindowPointerUp);
150
453
  this.isDragging = event !== null;
151
454
  };
152
455
  /**
153
456
  * Handle mouse moves during a thumb drag operation
154
457
  */
155
- this.handleMouseMove = (e) => {
156
- if (this.readOnly || this.disabled || e.defaultPrevented) {
458
+ this.handlePointerMove = (event) => {
459
+ if (this.disabled || event.defaultPrevented) {
157
460
  return;
158
461
  }
159
462
  // update the value based on current position
160
- const sourceEvent = window.TouchEvent && e instanceof TouchEvent ? e.touches[0] : e;
161
- const eventValue = this.orientation === Orientation.horizontal
162
- ? sourceEvent.pageX - document.documentElement.scrollLeft - this.trackLeft
163
- : sourceEvent.pageY - document.documentElement.scrollTop;
463
+ const sourceEvent = window.TouchEvent && event instanceof TouchEvent ? event.touches[0] : event;
464
+ const eventValue = this.orientation === Orientation.vertical
465
+ ? sourceEvent.pageY - document.documentElement.scrollTop
466
+ : sourceEvent.pageX - document.documentElement.scrollLeft - this.trackLeft;
164
467
  this.value = `${this.calculateNewValue(eventValue)}`;
165
468
  };
166
469
  /**
167
470
  * Handle a window mouse up during a drag operation
168
471
  */
169
- this.handleWindowMouseUp = (event) => {
472
+ this.handleWindowPointerUp = () => {
170
473
  this.stopDragging();
171
474
  };
172
475
  this.stopDragging = () => {
173
476
  this.isDragging = false;
174
- this.handleMouseDown(null);
175
- this.handleThumbMouseDown(null);
477
+ this.handlePointerDown(null);
478
+ this.handleThumbPointerDown(null);
176
479
  };
177
480
  /**
178
481
  *
179
- * @param e - MouseEvent or null. If there is no event handler it will remove the events
482
+ * @param event - PointerEvent or null. If there is no event handler it will remove the events
180
483
  */
181
- this.handleMouseDown = (e) => {
182
- if (e === null || (!this.disabled && !this.readOnly)) {
183
- const windowFn = e !== null ? window.addEventListener : window.removeEventListener;
184
- const documentFn = e !== null ? document.addEventListener : document.removeEventListener;
185
- windowFn('mouseup', this.handleWindowMouseUp);
186
- documentFn('mouseleave', this.handleWindowMouseUp);
187
- windowFn('mousemove', this.handleMouseMove);
188
- if (e) {
484
+ this.handlePointerDown = (event) => {
485
+ if (event === null || !this.disabled) {
486
+ const windowFn = event !== null ? window.addEventListener : window.removeEventListener;
487
+ const documentFn = event !== null ? document.addEventListener : document.removeEventListener;
488
+ windowFn('pointerup', this.handleWindowPointerUp);
489
+ documentFn('mouseleave', this.handleWindowPointerUp);
490
+ windowFn('pointermove', this.handlePointerMove);
491
+ if (event) {
189
492
  this.setupTrackConstraints();
190
- const controlValue = this.orientation === Orientation.horizontal
191
- ? e.pageX - document.documentElement.scrollLeft - this.trackLeft
192
- : e.pageY - document.documentElement.scrollTop;
493
+ const controlValue = this.orientation === Orientation.vertical
494
+ ? event.pageY - document.documentElement.scrollTop
495
+ : event.pageX - document.documentElement.scrollLeft - this.trackLeft;
193
496
  this.value = `${this.calculateNewValue(controlValue)}`;
194
497
  }
195
498
  }
196
499
  };
197
- }
198
- handleChange(source, propertyName) {
199
- switch (propertyName) {
200
- case 'min':
201
- case 'max':
202
- case 'step':
203
- this.handleStepStyles();
204
- break;
205
- default:
206
- break;
207
- }
208
- }
209
- /**
210
- * Handles changes to step styling based on the step value
211
- * NOTE: This function is not a changed callback, stepStyles is not observable
212
- */
213
- handleStepStyles() {
214
- if (this.step) {
215
- const totalSteps = (100 / Math.floor((this.max - this.min) / this.step));
216
- if (this.stepStyles !== undefined) {
217
- this.$fastController.removeStyles(this.stepStyles);
218
- }
219
- this.stepStyles = css /**css*/ `
220
- :host {
221
- --step-rate: ${totalSteps}%;
222
- color: blue;
223
- }
224
- `;
225
- this.$fastController.addStyles(this.stepStyles);
226
- }
227
- else if (this.stepStyles !== undefined) {
228
- this.$fastController.removeStyles(this.stepStyles);
229
- }
230
- }
231
- readOnlyChanged() {
232
- if (this.proxy instanceof HTMLInputElement) {
233
- this.proxy.readOnly = this.readOnly;
234
- }
235
- }
236
- /**
237
- * The value property, typed as a number.
238
- *
239
- * @public
240
- */
241
- get valueAsNumber() {
242
- return parseFloat(super.value);
243
- }
244
- set valueAsNumber(next) {
245
- this.value = next.toString();
246
- }
247
- /**
248
- * @internal
249
- */
250
- valueChanged(previous, next) {
251
- if (this.$fastController.isConnected) {
252
- const nextAsNumber = parseFloat(next);
253
- const value = limit(this.min, this.max, this.convertToConstrainedValue(nextAsNumber)).toString();
254
- if (value !== next) {
255
- this.value = value;
256
- return;
257
- }
258
- super.valueChanged(previous, next);
259
- this.setThumbPositionForOrientation(this.direction);
260
- this.$emit('change');
261
- }
262
- }
263
- minChanged() {
264
- if (this.proxy instanceof HTMLInputElement) {
265
- this.proxy.min = `${this.min}`;
266
- }
267
- this.validate();
268
- }
269
- maxChanged() {
270
- if (this.proxy instanceof HTMLInputElement) {
271
- this.proxy.max = `${this.max}`;
272
- }
273
- this.validate();
274
- }
275
- stepChanged() {
276
- if (this.proxy instanceof HTMLInputElement) {
277
- this.proxy.step = `${this.step}`;
278
- }
279
- this.updateStepMultiplier();
280
- this.validate();
281
- }
282
- orientationChanged() {
283
- if (this.$fastController.isConnected) {
284
- this.setThumbPositionForOrientation(this.direction);
285
- }
500
+ this.elementInternals.role = 'slider';
501
+ this.elementInternals.ariaOrientation = (_a = this.orientation) !== null && _a !== void 0 ? _a : SliderOrientation.horizontal;
286
502
  }
287
503
  /**
288
504
  * @internal
289
505
  */
290
506
  connectedCallback() {
291
507
  super.connectedCallback();
292
- this.proxy.setAttribute('type', 'range');
293
508
  this.direction = getDirection(this);
509
+ this.setDisabledSideEffect(this.disabled);
294
510
  this.updateStepMultiplier();
295
511
  this.setupTrackConstraints();
296
512
  this.setupListeners();
297
513
  this.setupDefaultValue();
298
- this.setThumbPositionForOrientation(this.direction);
514
+ this.setSliderPosition(this.direction);
299
515
  Observable.getNotifier(this).subscribe(this, 'max');
300
516
  Observable.getNotifier(this).subscribe(this, 'min');
301
517
  Observable.getNotifier(this).subscribe(this, 'step');
@@ -317,11 +533,11 @@ export class Slider extends FormAssociatedSlider {
317
533
  * @public
318
534
  */
319
535
  increment() {
320
- const newVal = this.direction !== Direction.rtl && this.orientation !== Orientation.vertical
321
- ? Number(this.value) + Number(this.stepValue)
322
- : Number(this.value) + Number(this.stepValue);
536
+ const newVal = this.direction !== Direction.rtl
537
+ ? Number(this.value) + this.stepAsNumber
538
+ : Number(this.value) - this.stepAsNumber;
323
539
  const incrementedVal = this.convertToConstrainedValue(newVal);
324
- const incrementedValString = incrementedVal < Number(this.max) ? `${incrementedVal}` : `${this.max}`;
540
+ const incrementedValString = incrementedVal < this.maxAsNumber ? `${incrementedVal}` : `${this.maxAsNumber}`;
325
541
  this.value = incrementedValString;
326
542
  }
327
543
  /**
@@ -330,64 +546,49 @@ export class Slider extends FormAssociatedSlider {
330
546
  * @public
331
547
  */
332
548
  decrement() {
333
- const newVal = this.direction !== Direction.rtl && this.orientation !== Orientation.vertical
334
- ? Number(this.value) - Number(this.stepValue)
335
- : Number(this.value) - Number(this.stepValue);
549
+ const newVal = this.direction !== Direction.rtl
550
+ ? Number(this.value) - Number(this.stepAsNumber)
551
+ : Number(this.value) + Number(this.stepAsNumber);
336
552
  const decrementedVal = this.convertToConstrainedValue(newVal);
337
- const decrementedValString = decrementedVal > Number(this.min) ? `${decrementedVal}` : `${this.min}`;
553
+ const decrementedValString = decrementedVal > this.minAsNumber ? `${decrementedVal}` : `${this.minAsNumber}`;
338
554
  this.value = decrementedValString;
339
555
  }
340
- /**
341
- * Gets the actual step value for the slider
342
- *
343
- */
344
- get stepValue() {
345
- return this.step === undefined ? 1 : this.step;
346
- }
347
556
  /**
348
557
  * Places the thumb based on the current value
349
558
  *
350
- * @public
351
559
  * @param direction - writing mode
352
560
  */
353
- setThumbPositionForOrientation(direction) {
354
- const newPct = convertPixelToPercent(Number(this.value), Number(this.min), Number(this.max), direction);
561
+ setSliderPosition(direction) {
562
+ const newPct = convertPixelToPercent(parseFloat(this.value), this.minAsNumber, this.maxAsNumber, direction);
355
563
  const percentage = (1 - newPct) * 100;
356
- if (this.orientation === Orientation.horizontal) {
357
- this.position = this.isDragging
358
- ? `right: ${percentage}%; transition: none;`
359
- : `right: ${percentage}%; transition: all 0.2s ease;`;
360
- }
361
- else {
362
- this.position = this.isDragging
363
- ? `top: ${percentage}%; transition: none;`
364
- : `top: ${percentage}%; transition: all 0.2s ease;`;
365
- }
564
+ const thumbPosition = `calc(100% - ${percentage}%)`;
565
+ const trackProgress = !(this.orientation === Orientation.vertical) && direction === Direction.rtl
566
+ ? `${percentage}%`
567
+ : `calc(100% - ${percentage}%)`;
568
+ this.position = `--slider-thumb: ${thumbPosition}; --slider-progress: ${trackProgress}`;
366
569
  }
367
570
  /**
368
571
  * Update the step multiplier used to ensure rounding errors from steps that
369
572
  * are not whole numbers
370
573
  */
371
574
  updateStepMultiplier() {
372
- const stepString = this.stepValue + '';
373
- const decimalPlacesOfStep = !!(this.stepValue % 1) ? stepString.length - stepString.indexOf('.') - 1 : 0;
575
+ const stepString = this.stepAsNumber + '';
576
+ const decimalPlacesOfStep = !!(this.stepAsNumber % 1) ? stepString.length - stepString.indexOf('.') - 1 : 0;
374
577
  this.stepMultiplier = Math.pow(10, decimalPlacesOfStep);
375
578
  }
376
579
  get midpoint() {
377
- return `${this.convertToConstrainedValue((this.max + this.min) / 2)}`;
580
+ return `${this.convertToConstrainedValue((this.maxAsNumber + this.minAsNumber) / 2)}`;
378
581
  }
379
582
  setupDefaultValue() {
380
- if (typeof this.value === 'string') {
381
- if (this.value.length === 0) {
382
- this.initialValue = this.midpoint;
383
- }
384
- else {
385
- const value = parseFloat(this.value);
386
- if (!Number.isNaN(value) && (value < this.min || value > this.max)) {
387
- this.value = this.midpoint;
388
- }
389
- }
583
+ var _a;
584
+ if (!this._value) {
585
+ this.value = (_a = this.initialValue) !== null && _a !== void 0 ? _a : this.midpoint;
390
586
  }
587
+ if (!Number.isNaN(this.valueAsNumber) &&
588
+ (this.valueAsNumber < this.minAsNumber || this.valueAsNumber > this.maxAsNumber)) {
589
+ this.value = this.midpoint;
590
+ }
591
+ this.elementInternals.ariaValueNow = this.value;
391
592
  }
392
593
  /**
393
594
  * Calculate the new value based on the given raw pixel value.
@@ -400,13 +601,13 @@ export class Slider extends FormAssociatedSlider {
400
601
  calculateNewValue(rawValue) {
401
602
  this.setupTrackConstraints();
402
603
  // update the value based on current position
403
- const newPosition = convertPixelToPercent(rawValue, this.orientation === Orientation.horizontal ? this.trackMinWidth : this.trackMinHeight, this.orientation === Orientation.horizontal ? this.trackWidth : this.trackHeight, this.direction);
404
- const newValue = (this.max - this.min) * newPosition + this.min;
604
+ const newPosition = convertPixelToPercent(rawValue, this.orientation === Orientation.vertical ? this.trackMinHeight : this.trackMinWidth, this.orientation === Orientation.vertical ? this.trackHeight : this.trackWidth, this.direction);
605
+ const newValue = (this.maxAsNumber - this.minAsNumber) * newPosition + this.minAsNumber;
405
606
  return this.convertToConstrainedValue(newValue);
406
607
  }
407
608
  convertToConstrainedValue(value) {
408
609
  if (isNaN(value)) {
409
- value = this.min;
610
+ value = this.minAsNumber;
410
611
  }
411
612
  /**
412
613
  * The following logic intends to overcome the issue with math in JavaScript with regards to floating point numbers.
@@ -414,22 +615,39 @@ export class Slider extends FormAssociatedSlider {
414
615
  * and is converted to an integer by determining the number of decimal places it represent, multiplying it until it is an
415
616
  * integer and then dividing it to get back to the correct number.
416
617
  */
417
- let constrainedValue = value - this.min;
418
- const roundedConstrainedValue = Math.round(constrainedValue / this.stepValue);
419
- const remainderValue = constrainedValue - (roundedConstrainedValue * (this.stepMultiplier * this.stepValue)) / this.stepMultiplier;
618
+ let constrainedValue = value - this.minAsNumber;
619
+ const roundedConstrainedValue = Math.round(constrainedValue / this.stepAsNumber);
620
+ const remainderValue = constrainedValue - (roundedConstrainedValue * (this.stepMultiplier * this.stepAsNumber)) / this.stepMultiplier;
420
621
  constrainedValue =
421
- remainderValue >= Number(this.stepValue) / 2
422
- ? constrainedValue - remainderValue + Number(this.stepValue)
622
+ remainderValue >= Number(this.stepAsNumber) / 2
623
+ ? constrainedValue - remainderValue + Number(this.stepAsNumber)
423
624
  : constrainedValue - remainderValue;
424
- return constrainedValue + this.min;
625
+ return constrainedValue + this.minAsNumber;
626
+ }
627
+ /**
628
+ * Makes sure the side effects of set up when the disabled state changes.
629
+ */
630
+ setDisabledSideEffect(disabled) {
631
+ if (!this.$fastController.isConnected) {
632
+ return;
633
+ }
634
+ this.elementInternals.ariaDisabled = disabled.toString();
635
+ this.tabIndex = disabled ? -1 : 0;
425
636
  }
426
637
  }
638
+ /**
639
+ * The form-associated flag.
640
+ * @see {@link https://html.spec.whatwg.org/multipage/custom-elements.html#custom-elements-face-example | Form-associated custom elements}
641
+ *
642
+ * @public
643
+ */
644
+ Slider.formAssociated = true;
427
645
  __decorate([
428
646
  attr
429
647
  ], Slider.prototype, "size", void 0);
430
648
  __decorate([
431
- attr({ attribute: 'readonly', mode: 'boolean' })
432
- ], Slider.prototype, "readOnly", void 0);
649
+ attr({ attribute: 'value', mode: 'fromView' })
650
+ ], Slider.prototype, "initialValue", void 0);
433
651
  __decorate([
434
652
  observable
435
653
  ], Slider.prototype, "direction", void 0);
@@ -458,13 +676,16 @@ __decorate([
458
676
  observable
459
677
  ], Slider.prototype, "valueTextFormatter", void 0);
460
678
  __decorate([
461
- attr({ converter: nullableNumberConverter })
679
+ attr({ mode: 'boolean' })
680
+ ], Slider.prototype, "disabled", void 0);
681
+ __decorate([
682
+ attr({ converter: numberLikeStringConverter })
462
683
  ], Slider.prototype, "min", void 0);
463
684
  __decorate([
464
- attr({ converter: nullableNumberConverter })
685
+ attr({ converter: numberLikeStringConverter })
465
686
  ], Slider.prototype, "max", void 0);
466
687
  __decorate([
467
- attr({ converter: nullableNumberConverter })
688
+ attr({ converter: numberLikeStringConverter })
468
689
  ], Slider.prototype, "step", void 0);
469
690
  __decorate([
470
691
  attr
@@ -472,4 +693,5 @@ __decorate([
472
693
  __decorate([
473
694
  attr
474
695
  ], Slider.prototype, "mode", void 0);
696
+ export { Slider };
475
697
  //# sourceMappingURL=slider.js.map