@fluentui/web-components 3.0.0-beta.41 → 3.0.0-beta.43
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/CHANGELOG.md +22 -2
- package/dist/dts/button/button.d.ts +8 -0
- package/dist/dts/slider/slider.d.ts +180 -35
- package/dist/dts/slider/slider.options.d.ts +2 -2
- package/dist/dts/slider/slider.template.d.ts +2 -2
- package/dist/dts/styles/states/index.d.ts +5 -0
- package/dist/dts/utils/converters.d.ts +17 -0
- package/dist/dts/utils/index.d.ts +1 -0
- package/dist/esm/accordion/accordion.js.map +1 -1
- package/dist/esm/accordion-item/accordion-item.js.map +1 -1
- package/dist/esm/anchor-button/anchor-button.js.map +1 -1
- package/dist/esm/avatar/avatar.js +2 -1
- package/dist/esm/avatar/avatar.js.map +1 -1
- package/dist/esm/badge/badge.js.map +1 -1
- package/dist/esm/button/button.js +14 -2
- package/dist/esm/button/button.js.map +1 -1
- package/dist/esm/button/button.template.js +1 -1
- package/dist/esm/button/button.template.js.map +1 -1
- package/dist/esm/checkbox/checkbox.js +2 -1
- package/dist/esm/checkbox/checkbox.js.map +1 -1
- package/dist/esm/compound-button/compound-button.template.js +1 -1
- package/dist/esm/compound-button/compound-button.template.js.map +1 -1
- package/dist/esm/counter-badge/counter-badge.js.map +1 -1
- package/dist/esm/dialog/dialog.js.map +1 -1
- package/dist/esm/dialog-body/dialog-body.js.map +1 -1
- package/dist/esm/divider/divider.js.map +1 -1
- package/dist/esm/drawer/drawer.js.map +1 -1
- package/dist/esm/field/field.js.map +1 -1
- package/dist/esm/image/image.js.map +1 -1
- package/dist/esm/label/label.js.map +1 -1
- package/dist/esm/link/link.js.map +1 -1
- package/dist/esm/menu/menu.js.map +1 -1
- package/dist/esm/menu-item/menu-item.js.map +1 -1
- package/dist/esm/menu-item/menu-item.styles.js +7 -1
- package/dist/esm/menu-item/menu-item.styles.js.map +1 -1
- package/dist/esm/menu-list/menu-list.js +2 -1
- package/dist/esm/menu-list/menu-list.js.map +1 -1
- package/dist/esm/message-bar/message-bar.js.map +1 -1
- package/dist/esm/patterns/aria-globals.js.map +1 -1
- package/dist/esm/progress-bar/progress-bar.js.map +1 -1
- package/dist/esm/radio-group/radio-group.js +2 -1
- package/dist/esm/radio-group/radio-group.js.map +1 -1
- package/dist/esm/rating-display/rating-display.js.map +1 -1
- package/dist/esm/slider/slider.js +442 -220
- package/dist/esm/slider/slider.js.map +1 -1
- package/dist/esm/slider/slider.styles.js +107 -132
- package/dist/esm/slider/slider.styles.js.map +1 -1
- package/dist/esm/slider/slider.template.js +11 -28
- package/dist/esm/slider/slider.template.js.map +1 -1
- package/dist/esm/spinner/spinner.js.map +1 -1
- package/dist/esm/styles/states/index.js +5 -0
- package/dist/esm/styles/states/index.js.map +1 -1
- package/dist/esm/tab/tab.js.map +1 -1
- package/dist/esm/tabs/tabs.js.map +1 -1
- package/dist/esm/text-input/text-input.js +2 -1
- package/dist/esm/text-input/text-input.js.map +1 -1
- package/dist/esm/toggle-button/toggle-button.js.map +1 -1
- package/dist/esm/utils/converters.js +26 -0
- package/dist/esm/utils/converters.js.map +1 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/index.js.map +1 -1
- package/dist/web-components.d.ts +189 -101
- package/dist/web-components.js +377 -505
- package/dist/web-components.min.js +186 -184
- package/package.json +1 -1
|
@@ -1,17 +1,319 @@
|
|
|
1
1
|
import { __decorate } from "tslib";
|
|
2
|
-
import { attr, css,
|
|
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 {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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 "
|
|
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 = () =>
|
|
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 =
|
|
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 =
|
|
373
|
+
this.max = '';
|
|
67
374
|
/**
|
|
68
|
-
*
|
|
375
|
+
* Value to increment or decrement via arrow keys, mouse click or drag.
|
|
69
376
|
*
|
|
70
377
|
* @public
|
|
71
378
|
* @remarks
|
|
72
|
-
* HTML Attribute:
|
|
379
|
+
* HTML Attribute: step
|
|
73
380
|
*/
|
|
74
|
-
this.
|
|
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 = (
|
|
84
|
-
if (this.
|
|
390
|
+
this.keypressHandler = (event) => {
|
|
391
|
+
if (this.disabled) {
|
|
85
392
|
return;
|
|
86
393
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
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
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
414
|
+
}
|
|
415
|
+
break;
|
|
416
|
+
case keyArrowLeft:
|
|
417
|
+
case keyArrowDown:
|
|
418
|
+
if (!event.shiftKey) {
|
|
419
|
+
event.preventDefault();
|
|
109
420
|
this.decrement();
|
|
110
|
-
|
|
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.
|
|
447
|
+
this.handleThumbPointerDown = (event) => {
|
|
145
448
|
const windowFn = event !== null ? window.addEventListener : window.removeEventListener;
|
|
146
|
-
windowFn('
|
|
147
|
-
windowFn('
|
|
148
|
-
windowFn('touchmove', this.
|
|
149
|
-
windowFn('touchend', this.
|
|
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.
|
|
156
|
-
if (this.
|
|
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 &&
|
|
161
|
-
const eventValue = this.orientation === Orientation.
|
|
162
|
-
? sourceEvent.
|
|
163
|
-
: sourceEvent.
|
|
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.
|
|
472
|
+
this.handleWindowPointerUp = () => {
|
|
170
473
|
this.stopDragging();
|
|
171
474
|
};
|
|
172
475
|
this.stopDragging = () => {
|
|
173
476
|
this.isDragging = false;
|
|
174
|
-
this.
|
|
175
|
-
this.
|
|
477
|
+
this.handlePointerDown(null);
|
|
478
|
+
this.handleThumbPointerDown(null);
|
|
176
479
|
};
|
|
177
480
|
/**
|
|
178
481
|
*
|
|
179
|
-
* @param
|
|
482
|
+
* @param event - PointerEvent or null. If there is no event handler it will remove the events
|
|
180
483
|
*/
|
|
181
|
-
this.
|
|
182
|
-
if (
|
|
183
|
-
const windowFn =
|
|
184
|
-
const documentFn =
|
|
185
|
-
windowFn('
|
|
186
|
-
documentFn('mouseleave', this.
|
|
187
|
-
windowFn('
|
|
188
|
-
if (
|
|
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.
|
|
191
|
-
?
|
|
192
|
-
:
|
|
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
|
-
|
|
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.
|
|
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
|
|
321
|
-
? Number(this.value) +
|
|
322
|
-
: Number(this.value)
|
|
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 <
|
|
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
|
|
334
|
-
? Number(this.value) - Number(this.
|
|
335
|
-
: Number(this.value)
|
|
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 >
|
|
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
|
-
|
|
354
|
-
const newPct = convertPixelToPercent(
|
|
561
|
+
setSliderPosition(direction) {
|
|
562
|
+
const newPct = convertPixelToPercent(parseFloat(this.value), this.minAsNumber, this.maxAsNumber, direction);
|
|
355
563
|
const percentage = (1 - newPct) * 100;
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
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.
|
|
373
|
-
const decimalPlacesOfStep = !!(this.
|
|
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.
|
|
580
|
+
return `${this.convertToConstrainedValue((this.maxAsNumber + this.minAsNumber) / 2)}`;
|
|
378
581
|
}
|
|
379
582
|
setupDefaultValue() {
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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.
|
|
404
|
-
const newValue = (this.
|
|
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.
|
|
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.
|
|
418
|
-
const roundedConstrainedValue = Math.round(constrainedValue / this.
|
|
419
|
-
const remainderValue = constrainedValue - (roundedConstrainedValue * (this.stepMultiplier * this.
|
|
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.
|
|
422
|
-
? constrainedValue - remainderValue + Number(this.
|
|
622
|
+
remainderValue >= Number(this.stepAsNumber) / 2
|
|
623
|
+
? constrainedValue - remainderValue + Number(this.stepAsNumber)
|
|
423
624
|
: constrainedValue - remainderValue;
|
|
424
|
-
return constrainedValue + this.
|
|
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: '
|
|
432
|
-
], Slider.prototype, "
|
|
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({
|
|
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:
|
|
685
|
+
attr({ converter: numberLikeStringConverter })
|
|
465
686
|
], Slider.prototype, "max", void 0);
|
|
466
687
|
__decorate([
|
|
467
|
-
attr({ converter:
|
|
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
|