@umbraco-ui/uui-range-slider 1.5.0-rc.1 → 1.5.0-rc.3

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/lib/index.js CHANGED
@@ -1,9 +1,9 @@
1
- import { UUIHorizontalPulseKeyframes } from '@umbraco-ui/uui-base/lib/animations';
2
- import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
3
1
  import { defineElement } from '@umbraco-ui/uui-base/lib/registration';
4
- import { LitElement, html, svg, nothing, css } from 'lit';
2
+ import { LitElement, html, svg, css } from 'lit';
3
+ import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
5
4
  import { property, state, query } from 'lit/decorators.js';
6
5
  import { UUIEvent } from '@umbraco-ui/uui-base/lib/events';
6
+ import { clamp } from '@umbraco-ui/uui-base/lib/utils';
7
7
 
8
8
  var __defProp$1 = Object.defineProperty;
9
9
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
@@ -53,858 +53,797 @@ var __privateMethod = (obj, member, method) => {
53
53
  __accessCheck(obj, member, "access private method");
54
54
  return method;
55
55
  };
56
- var _setValue, setValue_fn;
56
+ var _transferValueToInternalValues, transferValueToInternalValues_fn;
57
+ const Z_INDEX = {
58
+ TOP: 3,
59
+ CENTER: 2,
60
+ BACK: 1
61
+ };
62
+ const THUMB_SIZE = 18;
57
63
  const TRACK_PADDING = 12;
58
64
  const STEP_MIN_WIDTH = 24;
59
65
  let UUIRangeSliderElement = class extends FormControlMixin(LitElement) {
60
- /** Constructor */
66
+ /** Constructor and Validator */
61
67
  constructor() {
62
68
  super();
63
- __privateAdd(this, _setValue);
69
+ __privateAdd(this, _transferValueToInternalValues);
64
70
  this.disabled = false;
65
- this.step = 1;
71
+ this._min = 0;
72
+ this._max = 0;
66
73
  this.hideStepValues = false;
67
- this.min = 0;
68
- this.max = 100;
69
- this._valueLow = 0;
70
- this._valueHigh = 100;
74
+ this._step = 1;
75
+ this._movement = false;
76
+ this.startPoint = {
77
+ mouse: 0,
78
+ low: 0,
79
+ high: 0
80
+ };
81
+ this._lowInputValue = 0;
82
+ this._highInputValue = 0;
71
83
  this._trackWidth = 0;
72
- this._currentThumbFocus = "low";
73
- this._startPos = 0;
74
- this._startLow = 0;
75
- this._startHigh = 0;
76
- /** Mouse events */
77
- this._onMouseDown = (e) => {
78
- e.preventDefault();
84
+ this._lowValuePercentStart = 0;
85
+ this._highValuePercentEnd = 100;
86
+ /** Events */
87
+ this._onKeypress = (e) => {
88
+ if (e.key == "Enter") {
89
+ this.submit();
90
+ }
91
+ };
92
+ /** Touch Event */
93
+ this._onTouchStart = (e) => {
79
94
  if (this.disabled)
80
95
  return;
81
- window.addEventListener("mouseup", this._onMouseUp);
82
- window.addEventListener("mousemove", this._onMouseMove);
83
96
  const target = e.composedPath()[0];
84
- const pageX = e.pageX;
85
- target == this._bothThumbsTarget ? this._grabbingBoth = true : this._grabbingBoth = false;
86
- if (this._grabbingBoth) {
87
- this._saveStartPoint(pageX, this.valueLow, this.valueHigh);
97
+ if (target === this._outerTrack)
88
98
  return;
99
+ if (target === this._innerColor || target === this._innerColorThumb) {
100
+ window.addEventListener("touchend", this._onTouchEnd);
101
+ window.addEventListener("touchcancel", this._onTouchEnd);
102
+ window.addEventListener("touchmove", this._onTouchMove);
103
+ this._movement = true;
104
+ this._saveStartPoints(e.touches[0].pageX);
105
+ } else {
106
+ const value = this._getClickedValue(e.touches[0].pageX);
107
+ const diffLow = Math.abs(this._lowInputValue - value);
108
+ const diffHigh = Math.abs(this._highInputValue - value);
109
+ if (diffLow < diffHigh) {
110
+ this.setValueLow(value);
111
+ } else {
112
+ this.setValueHigh(value);
113
+ }
89
114
  }
90
- this._moveThumb(pageX);
91
115
  };
92
- this._onMouseMove = (e) => {
93
- e.preventDefault();
94
- const pageX = e.pageX;
95
- const val = this._getValue(pageX);
96
- if (!this._grabbingBoth)
97
- this._setValueBasedOnCurrentThumb(
98
- this._validateValueBasedOnCurrentThumb(val)
99
- );
100
- else
101
- this._moveBoth(pageX);
102
- this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.INPUT));
116
+ this._onTouchMove = (e) => {
117
+ this._dragBothValuesByMousePos(e.touches[0].pageX);
103
118
  };
104
- this._onMouseUp = () => {
105
- this._stop();
106
- window.removeEventListener("mouseup", this._onMouseUp);
107
- window.removeEventListener("mousemove", this._onMouseMove);
119
+ this._onTouchEnd = () => {
120
+ this._movement = false;
121
+ this.onChanged();
122
+ window.removeEventListener("touchend", this._onTouchEnd);
123
+ window.removeEventListener("touchcancel", this._onTouchEnd);
124
+ window.removeEventListener("touchmove", this._onTouchMove);
108
125
  };
109
- /** Touch / mobile events */
110
- this._onTouchStart = (e) => {
111
- e.preventDefault();
126
+ /** Mouse Event */
127
+ this._onMouseDown = (e) => {
112
128
  if (this.disabled)
113
129
  return;
114
- window.addEventListener("touchend", this._onTouchEnd);
115
- window.addEventListener("touchmove", this._onTouchMove);
116
130
  const target = e.composedPath()[0];
117
- const pageX = e.touches[0].pageX;
118
- target == this._bothThumbsTarget ? this._grabbingBoth = true : this._grabbingBoth = false;
119
- if (this._grabbingBoth) {
120
- this._saveStartPoint(pageX, this.valueLow, this.valueHigh);
131
+ if (target === this._outerTrack)
121
132
  return;
133
+ if (target === this._innerColor || target === this._innerColorThumb) {
134
+ window.addEventListener("mouseup", this._onMouseUp);
135
+ window.addEventListener("mousemove", this._onMouseMove);
136
+ this._movement = true;
137
+ this._saveStartPoints(e.pageX);
138
+ } else {
139
+ const value = this._getClickedValue(e.pageX);
140
+ const diffLow = Math.abs(this._lowInputValue - value);
141
+ const diffHigh = Math.abs(this._highInputValue - value);
142
+ if (diffLow < diffHigh) {
143
+ this.setValueLow(value);
144
+ } else {
145
+ this.setValueHigh(value);
146
+ }
122
147
  }
123
- this._moveThumb(pageX);
124
148
  };
125
- this._onTouchMove = (e) => {
126
- const pageX = e.touches[0].pageX;
127
- const val = this._getValue(pageX);
128
- if (!this._grabbingBoth)
129
- this._setValueBasedOnCurrentThumb(
130
- this._validateValueBasedOnCurrentThumb(val)
131
- );
132
- else
133
- this._moveBoth(pageX);
134
- this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.INPUT));
149
+ this._onMouseMove = (e) => {
150
+ e.preventDefault();
151
+ this._dragBothValuesByMousePos(e.pageX);
135
152
  };
136
- this._onTouchEnd = () => {
137
- this._stop();
138
- window.removeEventListener("touchend", this._onTouchEnd);
139
- window.removeEventListener("touchmove", this._onTouchMove);
153
+ this._onMouseUp = () => {
154
+ this._movement = false;
155
+ this.onChanged();
156
+ window.removeEventListener("mouseup", this._onMouseUp);
157
+ window.removeEventListener("mousemove", this._onMouseMove);
140
158
  };
141
159
  this.addEventListener("keypress", this._onKeypress);
142
160
  this.addEventListener("mousedown", this._onMouseDown);
143
161
  this.addEventListener("touchstart", this._onTouchStart);
144
- this.addValidator(
145
- "stepMismatch",
146
- () => `Step property needs to be higher than 0`,
147
- () => this.step <= 0
148
- );
149
- this.addValidator(
150
- "stepMismatch",
151
- () => `Maxmimum gap needs to be higher than minimum gap`,
152
- () => !!this.maxGap && !!this.minGap && this.maxGap <= this.minGap
153
- );
154
- this.addValidator(
155
- "rangeUnderflow",
156
- () => `The lower end value (${this.valueLow}) cannot be below the the minimum value setting (${this.min})`,
157
- () => this.valueLow < this.min
158
- );
159
- this.addValidator(
160
- "rangeOverflow",
161
- () => `The higher end value (${this.valueHigh}) cannot be above the the maximum value setting (${this.max})`,
162
- () => this.valueHigh > this.max
163
- );
162
+ window.addEventListener("resize", () => {
163
+ var _a;
164
+ this._trackWidth = (_a = this._outerTrack) == null ? void 0 : _a.offsetWidth;
165
+ });
164
166
  }
165
- get value() {
166
- return this._value;
167
+ get min() {
168
+ return this._min;
167
169
  }
168
- set value(newVal) {
169
- if (newVal instanceof String) {
170
- super.value = newVal;
171
- const values = newVal.split(",");
172
- this.valueLow = parseInt(values[0]);
173
- this.valueHigh = parseInt(values[1]);
174
- }
170
+ set min(newVal) {
171
+ this._min = newVal;
172
+ __privateMethod(this, _transferValueToInternalValues, transferValueToInternalValues_fn).call(this);
175
173
  }
176
- set valueLow(newLow) {
177
- const old = this._valueHigh;
178
- if (newLow <= this.min) {
179
- this._valueLow = this.min;
180
- super.value = `${this.min},${this.valueHigh}`;
181
- this.requestUpdate("valueLow", old);
182
- return;
183
- }
184
- if (newLow >= this.valueHigh - this.step) {
185
- this._valueLow = this.valueHigh - this.step;
186
- super.value = `${this.valueHigh - this.step},${this.valueHigh}`;
187
- this.requestUpdate("valueLow", old);
188
- return;
189
- }
190
- this._valueLow = newLow;
191
- super.value = `${newLow},${this.valueHigh}`;
192
- this.requestUpdate("valueLow", old);
193
- }
194
- get valueLow() {
195
- return this._valueLow;
196
- }
197
- set valueHigh(newHigh) {
198
- const old = this._valueHigh;
199
- if (newHigh >= this.max) {
200
- this._valueHigh = this.max;
201
- super.value = `${this.valueLow},${this.max}`;
202
- this.requestUpdate("valueHigh", old);
203
- return;
204
- }
205
- if (newHigh <= this.valueLow + this.step) {
206
- this._valueHigh = this.valueLow + this.step;
207
- super.value = `${this.valueLow},${this.valueLow + this.step}`;
208
- this.requestUpdate("valueHigh", old);
209
- return;
210
- }
211
- this._valueHigh = newHigh;
212
- super.value = `${this.valueLow},${newHigh}`;
213
- this.requestUpdate("valueHigh", old);
174
+ get max() {
175
+ return this._max;
214
176
  }
215
- get valueHigh() {
216
- return this._valueHigh;
177
+ set max(newVal) {
178
+ this._max = newVal;
179
+ __privateMethod(this, _transferValueToInternalValues, transferValueToInternalValues_fn).call(this);
217
180
  }
218
- getFormElement() {
219
- return this._currentInputFocus ? this._currentInputFocus : this._inputLow;
181
+ get step() {
182
+ return this._step;
220
183
  }
221
- focus() {
222
- this._currentInputFocus ? this._currentInputFocus.focus() : this._inputLow.focus();
184
+ set step(newVal) {
185
+ this._step = newVal;
186
+ __privateMethod(this, _transferValueToInternalValues, transferValueToInternalValues_fn).call(this);
223
187
  }
224
- _onKeypress(e) {
225
- if (e.key == "Enter") {
226
- this.submit();
227
- }
188
+ get minGap() {
189
+ return this._minGap;
190
+ }
191
+ set minGap(newVal) {
192
+ this._minGap = newVal;
193
+ __privateMethod(this, _transferValueToInternalValues, transferValueToInternalValues_fn).call(this);
194
+ }
195
+ get maxGap() {
196
+ return this._maxGap;
228
197
  }
229
- /** Thumb position */
230
- _sliderLowThumbPosition() {
231
- const ratio = (this.valueLow - this.min) / (this.max - this.min);
232
- const valueLowPercent = `${Math.floor(ratio * 1e5) / 1e3}%`;
233
- return valueLowPercent;
234
- }
235
- _sliderHighThumbPosition() {
236
- const ratio = (this.valueHigh - this.min) / (this.max - this.min);
237
- const valueHighPercent = `${Math.floor(ratio * 1e5) / 1e3}%`;
238
- return valueHighPercent;
239
- }
240
- /** Coloring of the line between thumbs */
241
- _fillColor() {
242
- const percentStart = (this.valueLow - this.min) / (this.max - this.min) * 100;
243
- const percentEnd = (this.valueHigh - this.min) / (this.max - this.min) * 100;
244
- this._innerColor.style.left = `${percentStart}%`;
245
- this._innerColor.style.right = `${100 - percentEnd}%`;
246
- }
247
- /** Moving thumb */
248
- _moveThumb(pageX) {
249
- const value = this._getValue(pageX);
250
- if (value >= this.valueHigh)
251
- this._setThumb(this._thumbHigh);
252
- if (value <= this.valueLow)
253
- this._setThumb(this._thumbLow);
254
- this._setValueBasedOnCurrentThumb(
255
- this._validateValueBasedOnCurrentThumb(value)
198
+ set maxGap(newVal) {
199
+ this._maxGap = newVal;
200
+ __privateMethod(this, _transferValueToInternalValues, transferValueToInternalValues_fn).call(this);
201
+ }
202
+ get value() {
203
+ return this._value;
204
+ }
205
+ set value(newVal) {
206
+ super.value = newVal;
207
+ __privateMethod(this, _transferValueToInternalValues, transferValueToInternalValues_fn).call(this);
208
+ }
209
+ setValueLow(low) {
210
+ low = clamp(
211
+ low,
212
+ this.maxGap ? this._highInputValue - this.maxGap > this.min ? this._highInputValue - this.maxGap : this.min : this.min,
213
+ this.minGap ? this._highInputValue - this.minGap : this._highInputValue - this.step
256
214
  );
215
+ this.setValue(low, this._highInputValue);
257
216
  }
258
- /** */
259
- _stop() {
260
- this._grabbingBoth = false;
261
- this.pristine = false;
262
- this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.CHANGE));
217
+ setValueHigh(high) {
218
+ high = clamp(
219
+ high,
220
+ this.minGap ? this._lowInputValue + this.minGap : this._lowInputValue + this.step,
221
+ this.maxGap ? this.maxGap + this._lowInputValue < this.max ? this.maxGap + this._lowInputValue : this.max : this.max
222
+ );
223
+ this.setValue(this._lowInputValue, high);
263
224
  }
264
- /** The latest thumb in use */
265
- _setThumb(target) {
266
- this._currentThumbFocus = target === this._thumbLow ? "low" : "high";
267
- this._currentThumbFocus === "low" ? this._currentInputFocus = this._inputLow : this._currentInputFocus = this._inputHigh;
268
- this.focus();
225
+ setValue(low, high, lockValueRange) {
226
+ if (lockValueRange) {
227
+ const length = this.startPoint.high - this.startPoint.low;
228
+ low = clamp(low, this.min, this.max - length);
229
+ high = clamp(high, this.min + length, this.max);
230
+ }
231
+ this._inputLow.value = low.toString();
232
+ this._inputHigh.value = high.toString();
233
+ this.value = `${low},${high}`;
269
234
  }
270
- _setValueBasedOnCurrentThumb(val) {
271
- this._currentThumbFocus === "low" ? this.valueLow = val : this.valueHigh = val;
235
+ getFormElement() {
236
+ return this._currentFocus ? this._currentFocus : this._inputLow;
272
237
  }
273
- /** Get the value depends on where clicked/touched */
274
- _getValue(pageX) {
275
- const mouseXPosition = pageX - this._innerTrack.getBoundingClientRect().left;
276
- const clickPercent = mouseXPosition / (this._trackWidth - TRACK_PADDING * 2);
277
- const clickedValue = clickPercent * (this.max - this.min) + this.min;
278
- const newValue = Math.round(clickedValue / this.step) * this.step;
279
- return newValue;
280
- }
281
- _validateLowByMinGap(value) {
282
- if (!this.minGap || this.minGap <= this.step)
283
- return value;
284
- return value + this.minGap >= this.valueHigh ? this.valueHigh - this.minGap : value;
285
- }
286
- _validateLowByMaxGap(value) {
287
- if (!this.maxGap)
288
- return value;
289
- return this.valueHigh - value >= this.maxGap ? this.valueHigh - this.maxGap : value;
290
- }
291
- _validateHighByMinGap(value) {
292
- if (!this.minGap || this.minGap <= this.step)
293
- return value;
294
- return value <= this.valueLow + this.minGap ? this.valueLow + this.minGap : value;
295
- }
296
- _validateHighByMaxGap(value) {
297
- if (!this.maxGap)
298
- return value;
299
- return value >= this.valueLow + this.maxGap ? this.valueLow + this.maxGap : value;
300
- }
301
- _validateValueBasedOnCurrentThumb(newValue) {
302
- if (this._currentThumbFocus == "low") {
303
- let newLow;
304
- newLow = newValue < this.valueHigh - this.step ? newValue : this.valueHigh - this.step;
305
- newLow = newLow >= this.min ? newLow : this.min;
306
- newLow = this.minGap ? this._validateLowByMinGap(newLow) : newLow;
307
- newLow = this.maxGap ? this._validateLowByMaxGap(newLow) : newLow;
308
- return newLow;
238
+ connectedCallback() {
239
+ super.connectedCallback();
240
+ if (!this.value) {
241
+ this.value = `${this._min},${this._max}`;
242
+ }
243
+ }
244
+ firstUpdated(changedProperties) {
245
+ super.updated(changedProperties);
246
+ this._trackWidth = this._outerTrack.offsetWidth;
247
+ this._runPropertiesChecks();
248
+ }
249
+ _runPropertiesChecks() {
250
+ const regex = new RegExp(/^-?\d+(\.\d+)?,-?\d+(\.\d+)?$/);
251
+ if (!regex.test(this.value))
252
+ console.error(`Range slider (Value error occurred): Bad input`);
253
+ if (this._highInputValue === this._lowInputValue) {
254
+ console.error(
255
+ `Range slider (Value error occurred): Low-end and high-end value should never be equal. Use <uui-slider></uui-slider> instead.`
256
+ );
257
+ }
258
+ if (this._lowInputValue > this._highInputValue) {
259
+ console.error(
260
+ `Range slider (Value error occurred): Low-end value should never be higher than high-end value.`
261
+ );
262
+ }
263
+ if (this._highInputValue > this._max || this._highInputValue < this._min) {
264
+ this.setValueHigh(this._max);
265
+ console.warn(
266
+ `Conflict with the high-end value and max value. High-end value has been converted to the max value (${this._max})`
267
+ );
268
+ }
269
+ if (this._lowInputValue < this._min || this._lowInputValue > this._max) {
270
+ this.setValueLow(this._min);
271
+ console.warn(
272
+ `Conflict with the low-end value and min value. Low-end value has been converted to the min value (${this._min})`
273
+ );
274
+ }
275
+ if (this._step <= 0) {
276
+ this._step = 1;
277
+ console.warn(
278
+ `Property step needs a value higher than 0. Converted the step value to 1 (default)`
279
+ );
280
+ }
281
+ if ((this._max - this._min) / this._step % 1 !== 0) {
282
+ console.error(
283
+ `Conflict with step value and the min and max values. May experience bad side effects`
284
+ );
285
+ }
286
+ if (this._minGap && this._minGap < this._step) {
287
+ this._minGap = void 0;
288
+ console.warn(
289
+ `Conflict with min-gap and step value. The min-gap needs to be higher than the step value. Removed the min-gap property.`
290
+ );
291
+ }
292
+ if (this._minGap && this._maxGap && this._minGap > this._maxGap) {
293
+ this._minGap = void 0;
294
+ this._maxGap = void 0;
295
+ console.warn(
296
+ `Conflict with min-gap and max-gap. Removed the min-gap and max-gap properties.`
297
+ );
298
+ }
299
+ if (this._minGap && this._max - this._min < this._minGap) {
300
+ this._minGap = void 0;
301
+ console.warn(
302
+ `Conflict with the min-gap and the total range. Removed the min-gap.`
303
+ );
309
304
  }
310
- let newHigh;
311
- newHigh = newValue > this.valueLow + this.step ? newValue : this.valueLow + this.step;
312
- newHigh = newHigh <= this.max ? newHigh : this.max;
313
- newHigh = this.minGap ? this._validateHighByMinGap(newHigh) : newHigh;
314
- newHigh = this.maxGap ? this._validateHighByMaxGap(newHigh) : newHigh;
315
- return newHigh;
316
- }
317
- /** Methods when moving both thumbs */
318
- _saveStartPoint(pageX, lowVal, highVal) {
319
- this._startPos = pageX;
320
- this._startLow = lowVal;
321
- this._startHigh = highVal;
322
- }
323
- _moveBoth(pageX) {
324
- const drag = pageX - this._startPos;
325
- const trackDiff = this.max - this.min;
326
- const dragPercent = drag / (this._trackWidth + TRACK_PADDING * 2);
327
- const dragValue = Math.round(dragPercent * trackDiff / this.step) * this.step;
328
- const newValueLow = this._startLow + dragValue;
329
- const newValueHigh = this._startHigh + dragValue;
330
- const value = this._getValidatedValues(newValueLow, newValueHigh);
331
- if (newValueLow === value.low && newValueHigh === value.high) {
332
- this.valueLow = newValueLow;
333
- this.valueHigh = newValueHigh;
334
- this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.INPUT));
305
+ if (this._maxGap && this._highInputValue - this._lowInputValue > this._maxGap) {
306
+ this.setValueHigh(this._lowInputValue + this._maxGap);
307
+ console.warn(
308
+ `Conflict with value and max-gap. High-end value has been converted to the highest possible value based on the low-end value and the max gap value (${this._highInputValue})`
309
+ );
310
+ }
311
+ if (this._minGap && this._highInputValue - this._lowInputValue < this._minGap) {
312
+ const minGap = this._minGap;
313
+ if (this._highInputValue - minGap < this._min) {
314
+ this.setValueHigh(this._lowInputValue + minGap);
315
+ console.warn(
316
+ `Conflict with value and min gap. High-end value has been converted to the lowest possible value based on the low-end value and the min gap value (${this._highInputValue}).`
317
+ );
318
+ } else {
319
+ this.setValueLow(this._highInputValue - minGap);
320
+ console.warn(
321
+ `Conflict with value and min gap. Low-end value has been converted to the highest possible value based on the high-end value and the min gap value (${this._lowInputValue}).`
322
+ );
323
+ }
335
324
  }
336
325
  }
337
- _getValidatedValues(low, high) {
338
- const validatedLow = low > this.min ? low : this.min;
339
- const validatedHigh = high < this.max ? high : this.max;
340
- return { low: validatedLow, high: validatedHigh };
326
+ _updateInnerColor() {
327
+ const scopeLength = this._max - this._min;
328
+ const scopedLow = this._lowInputValue - this._min;
329
+ const scopedHigh = this._highInputValue - this._min;
330
+ const leftPercent = scopedLow / scopeLength * 100;
331
+ const rightPercent = 100 - scopedHigh / scopeLength * 100;
332
+ this._lowValuePercentStart = clamp(leftPercent, 0, 100);
333
+ this._highValuePercentEnd = clamp(rightPercent, 0, 100);
334
+ }
335
+ _getClickedValue(pageX) {
336
+ const outerTrackMargin = this._outerTrack.getBoundingClientRect().left;
337
+ const mouseXPosition = pageX - outerTrackMargin - TRACK_PADDING;
338
+ const clickPercent = mouseXPosition / (this._trackWidth - TRACK_PADDING * 2);
339
+ const clickedValue = clickPercent * (this._max - this._min) + this._min;
340
+ return Math.round(clickedValue / this._step) * this._step;
341
+ }
342
+ /** Drag both thumbs logics */
343
+ _saveStartPoints(pageX) {
344
+ this.startPoint = {
345
+ mouse: pageX,
346
+ low: this._lowInputValue,
347
+ high: this._highInputValue
348
+ };
341
349
  }
342
- /** CHANGE AND INPUT EVENT LISTENERS */
343
- _onChange(e) {
344
- e.stopPropagation();
345
- this.pristine = false;
346
- this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.CHANGE));
350
+ _dragBothValuesByMousePos(pageX) {
351
+ const trackWidth = this._outerTrack.offsetWidth;
352
+ const drag = pageX - this.startPoint.mouse;
353
+ const trackDiff = this._max - this._min;
354
+ const dragPercent = drag / (trackWidth + TRACK_PADDING * 2);
355
+ const dragValue = Math.round(dragPercent * trackDiff / this._step) * this._step;
356
+ const newValueLow = this.startPoint.low + dragValue;
357
+ const newValueHigh = this.startPoint.high + dragValue;
358
+ this.setValue(newValueLow, newValueHigh, true);
359
+ this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.INPUT));
347
360
  }
361
+ /** Input Events */
348
362
  _onLowInput(e) {
349
- e.stopPropagation();
350
- let value = parseInt(this._inputLow.value);
351
- value = this._validateLowByMinGap(value);
352
- value = this._validateLowByMaxGap(value);
353
- this._inputLow.value = String(value);
354
- this.valueLow = value;
363
+ if (this.disabled)
364
+ e.preventDefault();
365
+ this._currentFocus = this._inputLow;
366
+ const newValue = Number(e.target.value);
367
+ this.setValueLow(newValue);
355
368
  this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.INPUT));
356
369
  }
357
370
  _onHighInput(e) {
358
- e.stopPropagation();
359
- let value = parseInt(this._inputHigh.value);
360
- value = this._validateHighByMinGap(value);
361
- value = this._validateHighByMaxGap(value);
362
- this._inputHigh.value = String(value);
363
- this.valueHigh = value;
371
+ if (this.disabled)
372
+ e.preventDefault();
373
+ this._currentFocus = this._inputHigh;
374
+ const newValue = Number(e.target.value);
375
+ this.setValueHigh(newValue);
364
376
  this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.INPUT));
365
377
  }
366
- connectedCallback() {
367
- super.connectedCallback();
368
- __privateMethod(this, _setValue, setValue_fn).call(this);
369
- window.addEventListener("resize", () => {
370
- this._trackWidth = this._outerTrack.offsetWidth;
371
- });
378
+ /** Change Events */
379
+ _onLowChange() {
380
+ this.setValueLow(Number(this._inputLow.value));
381
+ this.onChanged();
372
382
  }
373
- updated(changedProperties) {
374
- super.updated(changedProperties);
375
- this._trackWidth = this._outerTrack.offsetWidth;
376
- this._fillColor();
383
+ _onHighChange() {
384
+ this.setValueHigh(Number(this._inputHigh.value));
385
+ this.onChanged();
386
+ }
387
+ onChanged() {
388
+ this.pristine = false;
389
+ this.dispatchEvent(new UUIRangeSliderEvent(UUIRangeSliderEvent.CHANGE));
377
390
  }
378
- /** RENDER */
391
+ /** Render */
379
392
  render() {
380
393
  return html`
381
394
  <div id="range-slider">
382
- ${this.renderNativeInputs()}
395
+ ${this._renderNativeInputs()}
383
396
  <div id="inner-track">
384
- <span class="color"><span class="color-target"></span></span>
385
- ${this.renderStepsOutput()} ${this.renderThumbs()}
397
+ <div
398
+ id="inner-color-thumb"
399
+ class="${this._movement ? "active" : ""}"
400
+ style="left: ${this._lowValuePercentStart}%; right: ${this._highValuePercentEnd}%">
401
+ ${this._renderThumbValues()}
402
+ <div class="${this._movement ? "color active" : "color"}"></div>
403
+ </div>
404
+ ${this._renderSteps()}
386
405
  </div>
387
- <div id="step-values">${this.renderStepValues()}</div>
388
406
  </div>
389
407
  `;
390
408
  }
391
- renderNativeInputs() {
392
- return html`<input
393
- id="low-input"
394
- class="slider"
395
- type="range"
396
- .value="${String(this.valueLow)}"
397
- min="${this.min}"
398
- max="${this.max}"
399
- step="${this.step}"
400
- aria-label="${this.label} low value"
401
- ?disabled="${this.disabled}"
402
- @change="${this._onChange}"
403
- @input="${this._onLowInput}" />
404
- <input
405
- id="high-input"
406
- class="slider"
407
- type="range"
408
- .value="${String(this.valueHigh)}"
409
- min="${this.min}"
410
- max="${this.max}"
411
- step="${this.step}"
412
- aria-label="${this.label} high value"
413
- ?disabled="${this.disabled}"
414
- @change="${this._onChange}"
415
- @input="${this._onHighInput}" />`;
416
- }
417
- renderThumbs() {
418
- return html`<div
419
- id="low-thumb"
420
- class="thumb"
421
- style="left: ${this._sliderLowThumbPosition()}">
422
- <div class="value value-min">${this.valueLow}</div>
423
- </div>
424
- <div
425
- id="high-thumb"
426
- class="thumb"
427
- style="left: ${this._sliderHighThumbPosition()}">
428
- <div class="value value-max">${this.valueHigh}</div>
429
- </div>`;
430
- }
431
- /** RENDER STEPS & STEP VALUES */
432
- renderStepsOutput() {
433
- return html`<div class="svg-wrapper">
409
+ _renderThumbValues() {
410
+ return html`<div class="thumb-values">
411
+ <span><span>${this._lowInputValue}</span></span>
412
+ <span><span>${this._highInputValue}</span></span>
413
+ </div>`;
414
+ }
415
+ _renderSteps() {
416
+ const stepAmount = (this._max - this._min) / this._step;
417
+ const stepWidth = (this._trackWidth - TRACK_PADDING * 2) / stepAmount;
418
+ if (stepWidth < STEP_MIN_WIDTH)
419
+ return;
420
+ if (stepAmount % 1 !== 0)
421
+ return;
422
+ let index = 0;
423
+ const stepPositions = new Array(stepAmount + 1).fill(stepWidth).map((stepWidth2) => stepWidth2 * index++);
424
+ return html`<div class="step-wrapper">
434
425
  <svg height="100%" width="100%">
435
426
  <rect x="9" y="9" height="3" rx="2" />
436
- ${this.renderSteps()}
427
+ ${this._renderStepCircles(stepPositions)}
437
428
  </svg>
429
+ ${this._renderStepValues(stepAmount)}
438
430
  </div>`;
439
431
  }
440
- renderSteps() {
441
- const stepAmount = (this.max - this.min) / this.step;
442
- const stepWidth = (this._trackWidth - TRACK_PADDING * 2) / stepAmount;
443
- const trackValue = this._trackWidth / (this.max - this.min);
444
- if (stepWidth >= STEP_MIN_WIDTH) {
445
- let i = 0;
446
- const steps = [];
447
- for (i; i <= stepAmount; i++) {
448
- steps.push(i * stepWidth);
449
- }
450
- const colorClass = this.disabled == false ? `filled` : `filled-disabled`;
451
- return svg`
452
- ${steps.map((position) => {
453
- const x = position + TRACK_PADDING;
454
- if (x / trackValue > this.valueLow - this.min && x / trackValue < this.valueHigh - this.min) {
455
- return svg`<circle class="track-step ${colorClass}" cx="${x}" cy="50%" r="4.5" />`;
456
- } else {
457
- return svg`<circle class="track-step" cx="${x}" cy="50%" r="4.5" />`;
458
- }
459
- })}`;
460
- } else {
461
- return svg``;
462
- }
432
+ _renderStepValues(stepAmount) {
433
+ if (this.hideStepValues || stepAmount > 20)
434
+ return;
435
+ let index = 0;
436
+ const stepValues = new Array(stepAmount + 1).fill(this._step).map((step) => this._min + step * index++);
437
+ return html`<div class="step-values">
438
+ ${stepValues.map((value) => html`<span><span>${value}</span></span>`)}
439
+ </div>`;
463
440
  }
464
- renderStepValues() {
465
- if (this.hideStepValues)
466
- return nothing;
467
- const stepAmount = (this.max - this.min) / this.step;
468
- const stepWidth = (this._trackWidth - TRACK_PADDING * 2) / stepAmount;
469
- if (stepWidth >= STEP_MIN_WIDTH && stepAmount <= 20) {
470
- let i = 0;
471
- const stepValues = [];
472
- for (i; i <= stepAmount; i++) {
473
- stepValues.push(i * this.step + this.min);
474
- }
475
- return html` ${stepValues.map((stepValue) => {
476
- return html`<span><span>${stepValue}</span></span>`;
477
- })}`;
478
- } else {
479
- return nothing;
480
- }
441
+ _renderStepCircles(stepPositionArray) {
442
+ const trackValue = this._trackWidth / (this._max - this._min);
443
+ return svg`${stepPositionArray.map((position) => {
444
+ const cx = position + TRACK_PADDING;
445
+ const colorStart = this._lowInputValue - this._min;
446
+ const colorEnd = this._highInputValue - this._min;
447
+ if (cx / trackValue >= colorStart && cx / trackValue <= colorEnd) {
448
+ return svg`<circle class="track-step filled" cx="${cx}" cy="5" r="4.5" />`;
449
+ } else {
450
+ return svg`<circle class="track-step regular" cx="${cx}" cy="5" r="4.5" />`;
451
+ }
452
+ })}`;
453
+ }
454
+ _renderNativeInputs() {
455
+ return html` <div class="native-wrapper">
456
+ <input
457
+ id="inputLow"
458
+ class="${this._movement ? "focus" : ""}"
459
+ type="range"
460
+ min=${this._min}
461
+ max=${this._max}
462
+ step=${this._step}
463
+ .value=${this._lowInputValue.toString()}
464
+ aria-label="${this.label} low-end value"
465
+ ?disabled="${this.disabled}"
466
+ @input=${this._onLowInput}
467
+ @change=${this._onLowChange} />
468
+ <input
469
+ id="inputHigh"
470
+ class="${this._movement ? "focus" : ""}"
471
+ type="range"
472
+ min="${this._min}"
473
+ max="${this._max}"
474
+ step="${this._step}"
475
+ .value=${this._highInputValue.toString()}
476
+ aria-label="${this.label} high-end value"
477
+ ?disabled="${this.disabled}"
478
+ @input=${this._onHighInput}
479
+ @change=${this._onHighChange} />
480
+ </div>`;
481
481
  }
482
482
  };
483
- _setValue = new WeakSet();
484
- setValue_fn = function(val) {
485
- this._value = val ? val : `${this.valueLow},${this.valueHigh}`;
483
+ _transferValueToInternalValues = new WeakSet();
484
+ transferValueToInternalValues_fn = function() {
485
+ const valueSplit = this.value.split(",");
486
+ let low = Number(valueSplit[0]) || 0;
487
+ let high = Number(valueSplit[1]) || 0;
488
+ high = clamp(high, this._min, this._max);
489
+ low = this._min + Math.round((low - this._min) / this._step) * this._step;
490
+ high = this._min + Math.round((high - this._min) / this._step) * this._step;
491
+ this._lowInputValue = clamp(
492
+ low,
493
+ this._min,
494
+ this._minGap ? high - this._minGap : high - this._step
495
+ );
496
+ this._highInputValue = clamp(
497
+ high,
498
+ this._minGap ? this._lowInputValue + this._minGap : this._lowInputValue + this._step,
499
+ Math.min(this._maxGap ? low + this._maxGap : this._max, this._max)
500
+ );
501
+ this._updateInnerColor();
502
+ this.requestUpdate();
486
503
  };
487
504
  UUIRangeSliderElement.formAssociated = true;
505
+ /** Style */
488
506
  UUIRangeSliderElement.styles = [
489
- UUIHorizontalPulseKeyframes,
490
507
  css`
491
508
  :host {
492
- display: block;
493
- min-height: 50px;
494
- width: 100%;
495
- place-items: center;
496
- -webkit-user-select: none; /* Safari */
497
- -moz-user-select: none; /* Firefox */
498
- -ms-user-select: none; /* IE10+/Edge */
499
- user-select: none;
500
- cursor: pointer;
509
+ --color-interactive: var(--uui-color-selected,#3544b1);
510
+ --color-hover: var(--uui-color-selected-emphasis,rgb(70, 86, 200));
511
+ --color-focus: var(--uui-color-focus,#3879ff);
512
+ min-height: 30px;
501
513
  }
502
514
 
503
- :host([disabled]) {
504
- cursor: default;
505
- }
506
-
507
- /** NATIVE INPUT STYLING */
508
-
509
- input {
510
- -webkit-appearance: none;
511
- -moz-appearance: none;
512
- appearance: none;
513
- position: absolute;
514
- top: 0;
515
- background-color: transparent;
516
- pointer-events: none;
517
- left: 0;
518
- right: 0;
519
- border-radius: 20px;
515
+ :host([error]) {
516
+ --color-interactive: var(--uui-color-danger-standalone,rgb(191, 33, 78));
517
+ --color-hover: var(--uui-color-danger,#d42054);
520
518
  }
521
519
 
522
- input::-webkit-slider-thumb {
523
- pointer-events: all;
520
+ #range-slider {
521
+ min-height: 30px;
522
+ box-sizing: border-box;
524
523
  position: relative;
525
- z-index: 1;
526
- outline: 0;
524
+ display: flex;
525
+ align-items: center;
527
526
  }
528
527
 
529
- input::-moz-range-thumb {
530
- pointer-events: all;
531
- position: relative;
532
- z-index: 10;
533
- -moz-appearance: none;
534
- background: linear-gradient(to bottom, #ededed 0%, #dedede 100%);
535
- width: 11px;
536
- }
528
+ /** Track */
537
529
 
538
- input::-moz-range-track {
539
- position: relative;
540
- z-index: -1;
541
- background-color: rgba(0, 0, 0, 0.15);
542
- border: 0;
530
+ #inner-track {
531
+ user-select: none;
532
+ background-color: var(--uui-color-border-standalone,#c2c2c2);
533
+ position: absolute;
534
+ height: 3px;
535
+ left: ${TRACK_PADDING}px; /* Match TRACK_MARGIN */
536
+ right: ${TRACK_PADDING}px; /* Match TRACK_MARGIN */
543
537
  }
544
538
 
545
- input:last-of-type::-moz-range-track {
546
- -moz-appearance: none;
547
- background: none transparent;
548
- border: 0;
539
+ :host(:not([disabled]):hover) #inner-track,
540
+ :host(:not([disabled]):active) #inner-track {
541
+ background-color: var(--uui-color-border-emphasis,#a1a1a1);
549
542
  }
550
543
 
551
- /** TRACK */
552
-
553
- #inner-track .color-target {
544
+ #inner-color-thumb {
545
+ margin: -9px 0 0;
554
546
  position: absolute;
555
- z-index: 2;
556
- left: 0;
557
- right: 0;
558
- height: 25px;
559
- transform: translateY(-50%);
547
+ display: flex;
548
+ flex-direction: column;
549
+ justify-content: center;
550
+ height: ${THUMB_SIZE}px;
551
+ cursor: grab;
552
+ user-select: none;
553
+ z-index: ${Z_INDEX.CENTER};
560
554
  }
561
555
 
562
- #inner-track .color {
563
- height: 3px;
564
- position: absolute;
565
- transition: background-color 320ms ease-out;
556
+ :host([disabled]) #inner-color-thumb {
557
+ cursor: default;
566
558
  }
567
559
 
568
- :host(:not([disabled]))
569
- #range-slider
570
- #inner-track
571
- .color:has(.color-target:hover),
572
- :host(:not([disabled]))
573
- #range-slider
574
- #inner-track
575
- .color:has(.color-target:active) {
576
- background-color: var(--uui-color-focus,#3879ff);
577
- }
560
+ /** Colored part of track */
578
561
 
579
- :host(:not([disabled])) #range-slider .color {
580
- background-color: var(--uui-color-selected,#3544b1);
562
+ :host([disabled]) #range-slider #inner-color-thumb .color {
563
+ background-color: var(--uui-palette-mine-grey,#3e3e3e) !important;
581
564
  }
582
565
 
583
- :host([disabled]) #range-slider .color {
584
- background-color: #555;
566
+ #inner-color-thumb:focus .color {
567
+ background-color: var(--color-focus);
585
568
  }
586
-
587
- #range-slider {
588
- transform: translateY(50%);
589
- position: relative;
590
- height: 18px;
591
- display: flex;
592
- flex-direction: column;
593
- width: 100%;
569
+ #inner-color-thumb:hover .color,
570
+ #inner-color-thumb .color.active {
571
+ background-color: var(--color-hover);
572
+ }
573
+ #inner-color-thumb:hover .color {
574
+ height: 5px;
575
+ background-color: var(--color-hover);
594
576
  }
595
577
 
596
- #inner-track {
597
- border-radius: 10px;
578
+ .color {
579
+ user-select: none;
598
580
  position: absolute;
581
+ inset-inline: 0;
599
582
  height: 3px;
600
- background-color: var(--uui-color-border-standalone,#c2c2c2);
601
- left: ${TRACK_PADDING}px; /* Match TRACK_MARGIN */
602
- right: ${TRACK_PADDING}px; /* Match TRACK_MARGIN */
583
+ transform: translateY(2px);
584
+ background-color: var(--color-interactive);
585
+ transition: height 60ms;
603
586
  }
604
587
 
605
- #range-slider:hover #inner-track,
606
- #range-slider:active #inner-track {
607
- background-color: #a1a1a1;
588
+ :host([error]) .color {
589
+ background-color: var(--uui-color-danger-standalone,rgb(191, 33, 78));
590
+ }
591
+ :host([error]) #inner-color-thumb:hover ~ .color,
592
+ :host([error]) #inner-color-thumb:focus ~ .color {
593
+ background-color: var(--uui-color-danger-emphasis,rgb(226, 60, 107));
608
594
  }
609
595
 
610
- /** STEP VALUES */
596
+ /** Steps */
597
+ .step-wrapper {
598
+ margin: 0 ${-1 * TRACK_PADDING}px;
599
+ height: 11px;
600
+ position: absolute;
601
+ left: 0;
602
+ right: 0;
603
+ top: -10px;
604
+ }
611
605
 
606
+ /** Step circles */
612
607
  .track-step {
613
608
  fill: var(--uui-color-border,#d8d7d9);
614
609
  }
615
610
 
611
+ :host(:not([disabled]):hover) #inner-track .track-step.regular,
612
+ :host(:not([disabled]):active) #inner-track .track-step.regular {
613
+ fill: var(--uui-color-border-emphasis,#a1a1a1);
614
+ }
615
+
616
616
  :host .track-step.filled {
617
- fill: var(--uui-color-selected,#3544b1) !important;
617
+ fill: var(--color-interactive);
618
618
  }
619
619
 
620
- :host .track-step.filled-disabled {
621
- fill: var(--uui-palette-mine-grey,#3e3e3e) !important;
620
+ :host([error]) .track-step.filled {
621
+ fill: var(--uui-color-danger-emphasis,rgb(226, 60, 107));
622
622
  }
623
623
 
624
- #range-slider:hover .track-step,
625
- #range-slider:active .track-step {
626
- fill: #a1a1a1;
624
+ :host #inner-color-thumb.active ~ .step-wrapper .track-step.filled,
625
+ :host #inner-color-thumb:hover ~ .step-wrapper .track-step.filled {
626
+ fill: var(--color-hover);
627
627
  }
628
628
 
629
- #step-values {
629
+ :host([disabled]) #range-slider .track-step.filled {
630
+ fill: var(--uui-palette-mine-grey,#3e3e3e) !important;
631
+ }
632
+
633
+ /** Step values */
634
+
635
+ .step-values {
636
+ box-sizing: border-box;
630
637
  margin: 0 ${TRACK_PADDING}px; /* Match TRACK_MARGIN */
631
- padding-top: ${TRACK_PADDING + 3}px;
632
638
  display: flex;
633
- align-items: flex-end;
634
- box-sizing: border-box;
639
+ justify-content: space-between;
640
+ font-size: var(--uui-type-small-size,12px);
635
641
  }
636
642
 
637
- #step-values > span {
638
- flex-basis: 0;
639
- flex-grow: 1;
643
+ .step-values > span {
644
+ position: relative;
640
645
  color: var(--uui-color-disabled-contrast,#c4c4c4);
641
646
  }
642
647
 
643
- #step-values > span > span {
648
+ .step-values > span > span {
649
+ position: absolute;
644
650
  transform: translateX(-50%);
645
- display: inline-block;
646
- text-align: center;
647
- font-size: var(--uui-type-small-size,12px);
648
651
  }
649
652
 
650
- #step-values > span:last-child {
651
- width: 0;
652
- flex-grow: 0;
653
- }
654
-
655
- .svg-wrapper {
656
- margin: 0 ${-1 * TRACK_PADDING}px;
657
- height: 18px;
658
- transform: translateY(-75%);
659
- }
653
+ /** Input */
660
654
 
661
- .svg-wrapper svg {
662
- margin-top: ${TRACK_PADDING / 2}px;
655
+ .native-wrapper {
656
+ position: relative;
657
+ width: 100%;
658
+ inset-inline: 0px;
659
+ margin: -22px 5px 0 1px;
663
660
  }
664
661
 
665
- /** FOCUS */
666
-
667
- input[type='range'] {
662
+ input {
663
+ -webkit-appearance: none;
664
+ -moz-appearance: none;
665
+ appearance: none;
666
+ pointer-events: none;
668
667
  position: absolute;
669
- left: 0;
670
- right: 0;
671
- top: -50%;
668
+ cursor: pointer;
669
+ background-color: transparent;
670
+ inset-inline: 0;
671
+ width: 100%;
672
+ border-radius: 20px;
672
673
  }
673
674
 
674
- input[type='range']:focus-visible {
675
+ input:focus-within {
675
676
  outline: none;
676
677
  }
677
678
 
678
- #low-input:focus-visible ~ #inner-track #low-thumb,
679
- #high-input:focus-visible ~ #inner-track #high-thumb,
680
- #low-input:focus ~ #inner-track #low.thumb,
681
- #high-input:focus ~ #inner-track #high-thumb,
682
- #low-input:active ~ #inner-track #low.thumb,
683
- #high-input:active ~ #inner-track #high-thumb {
684
- outline: calc(2px * var(--uui-show-focus-outline, 1)) solid
685
- var(--uui-color-focus,#3879ff);
686
- }
687
-
688
- input[type='range']:focus + .thumb {
689
- outline: calc(2px * var(--uui-show-focus-outline, 1)) solid
690
- var(--uui-color-focus,#3879ff);
691
- }
692
-
693
- :host(:not([disabled]))
694
- #range-slider
695
- #inner-track
696
- .color:has(.color-target:hover)
697
- ~ #low-thumb,
698
- :host(:not([disabled]))
699
- #range-slider
700
- #inner-track
701
- .color:has(.color-target:active)
702
- ~ #low-thumb,
703
- :host(:not([disabled]))
704
- #range-slider
705
- #inner-track
706
- .color:has(.color-target:hover)
707
- ~ #high-thumb,
708
- :host(:not([disabled]))
709
- #range-slider
710
- #inner-track
711
- .color:has(.color-target:active)
712
- ~ #high-thumb {
713
- outline: calc(2px * var(--uui-show-focus-outline, 1)) solid
714
- var(--uui-color-focus,#3879ff);
715
- }
716
-
717
- /** THUMBS */
718
-
719
- .thumb {
720
- z-index: 3;
721
- transform: translateY(-50%);
722
- position: absolute;
723
- top: 2px;
724
- bottom: 0px;
725
- left: 0px;
726
- height: 17px;
727
- width: 17px;
728
- margin-left: -8px;
729
- margin-right: -8px;
730
- border-radius: 50%;
679
+ /** Thumb values */
680
+ .thumb-values {
731
681
  box-sizing: border-box;
732
- background-color: var(--uui-color-surface, #fff);
733
- border: 2px solid var(--uui-color-selected, #3544b1);
734
- transition: left 120ms ease 0s;
735
- }
736
-
737
- .thumb:after {
738
- content: '';
739
- position: absolute;
740
- top: 2px;
741
- left: 2px;
742
- height: 9px;
743
- width: 9px;
744
- border-radius: 50%;
745
- background-color: var(--uui-color-selected,#3544b1);
682
+ display: flex;
683
+ justify-content: space-between;
684
+ color: var(--color-interactive);
685
+ font-weight: bold;
686
+ transition: 120ms opacity;
687
+ opacity: 0;
746
688
  }
747
689
 
748
- :host([disabled]) .thumb {
749
- background-color: var(--uui-color-disabled,#f3f3f5);
750
- border-color: var(--uui-palette-mine-grey,#3e3e3e);
751
- }
752
- :host([disabled]) .thumb:after {
753
- background-color: var(--uui-palette-mine-grey,#3e3e3e);
690
+ .thumb-values > span {
691
+ width: 0;
754
692
  }
755
693
 
756
- .thumb .value {
757
- position: absolute;
758
- box-sizing: border-box;
759
- font-weight: 700;
694
+ .thumb-values > span > span {
760
695
  bottom: 15px;
761
- left: 50%;
762
- width: 40px;
763
- margin-left: -20px;
764
- text-align: center;
765
- opacity: 1;
766
- transition: 120ms opacity;
767
- color: var(--uui-color-selected,#3544b1);
768
- visibility: hidden;
769
- opacity: 0;
696
+ position: absolute;
697
+ transform: translateX(-50%);
770
698
  }
771
699
 
772
- :host([disabled]) .thumb .value {
700
+ :host([disabled]) .thumb-values {
773
701
  color: var(--uui-palette-mine-grey,#3e3e3e);
774
702
  }
775
703
 
776
- #range-slider:active .thumb .value,
777
- #range-slider:focus .thumb .value,
778
- #range-slider:hover .thumb .value {
779
- visibility: visible;
704
+ #range-slider:hover .thumb-values {
780
705
  opacity: 1;
781
706
  }
782
707
 
783
- /** NATIVE THUMB STYLING */
784
-
785
- input[type='range']::-webkit-slider-thumb {
708
+ /** Native thumbs */
709
+ /** Chrome */
710
+ input::-webkit-slider-thumb {
786
711
  -webkit-appearance: none;
787
- appearance: none;
788
- width: 17px;
789
- height: 17px;
790
- background-color: transparent;
791
- display: block;
792
- border-radius: 100%;
793
- pointer-events: auto;
794
- cursor: pointer;
795
- }
796
- input[type='range']:disabled::-webkit-slider-thumb {
712
+ pointer-events: all;
713
+ cursor: grab;
714
+ position: relative;
715
+ z-index: ${Z_INDEX.TOP};
716
+ width: ${THUMB_SIZE}px;
717
+ height: ${THUMB_SIZE}px;
718
+ border-radius: 24px;
719
+ border: none;
720
+ background-color: var(--color-interactive);
721
+ overflow: visible;
722
+ box-shadow: inset 0 0 0 2px var(--color-interactive),
723
+ inset 0 0 0 4px var(--uui-color-surface,#fff);
724
+ }
725
+ :host([disabled]) input::-webkit-slider-thumb {
797
726
  cursor: default;
798
727
  }
799
728
 
800
- input[type='range']::-moz-range-thumb {
801
- -moz-appearance: none;
802
- appearance: none;
803
- width: 17px;
804
- height: 17px;
805
- background-color: transparent;
806
- display: block;
807
- border-radius: 100%;
808
- pointer-events: auto;
809
- cursor: pointer;
729
+ input:focus-within::-webkit-slider-thumb,
730
+ input.focus::-webkit-slider-thumb {
731
+ background-color: var(--color-focus);
732
+ box-shadow: inset 0 0 0 2px var(--color-focus),
733
+ inset 0 0 0 4px var(--uui-color-surface,#fff), 0 0 0 2px var(--color-focus);
810
734
  }
811
- input[type='range']:disabled::-moz-range-thumb {
812
- cursor: default;
735
+ input::-webkit-slider-thumb:hover {
736
+ background-color: var(--color-hover);
737
+ box-shadow: inset 0 0 0 2px var(--color-hover),
738
+ inset 0 0 0 4px var(--uui-color-surface,#fff);
813
739
  }
814
740
 
815
- input[type='range']::-ms-thumb {
816
- appearance: none;
817
- width: 17px;
818
- height: 17px;
819
- background-color: transparent;
820
- display: block;
821
- border-radius: 100%;
822
- pointer-events: auto;
823
- cursor: pointer;
741
+ :host([disabled]) #range-slider input::-webkit-slider-thumb {
742
+ background-color: var(--uui-palette-mine-grey,#3e3e3e);
743
+ box-shadow: inset 0 0 0 2px var(--uui-palette-mine-grey,#3e3e3e),
744
+ inset 0 0 0 4px var(--uui-color-surface,#fff);
824
745
  }
825
- input[type='range']:disabled::-ms-thumb {
746
+
747
+ /** Mozilla */
748
+
749
+ input::-moz-range-thumb {
750
+ -moz-appearance: none;
751
+ pointer-events: all;
752
+ cursor: grab;
753
+ position: relative;
754
+ z-index: ${Z_INDEX.TOP};
755
+ width: ${THUMB_SIZE}px;
756
+ height: ${THUMB_SIZE}px;
757
+ border-radius: 24px;
758
+ border: none;
759
+ background-color: var(--color-interactive);
760
+ overflow: visible;
761
+ box-shadow: inset 0 0 0 2px var(--color-interactive),
762
+ inset 0 0 0 4px var(--uui-color-surface,#fff);
763
+ }
764
+ :host([disabled]) input::-moz-range-thumb {
826
765
  cursor: default;
827
766
  }
767
+
768
+ input:focus-within::-moz-range-thumb,
769
+ input.focus::-moz-range-thumb {
770
+ background-color: var(--color-focus);
771
+ box-shadow: inset 0 0 0 2px var(--color-focus),
772
+ inset 0 0 0 4px var(--uui-color-surface,#fff), 0 0 0 2px var(--color-focus);
773
+ }
774
+ input::-moz-range-thumb:hover {
775
+ background-color: var(--color-hover);
776
+ box-shadow: inset 0 0 0 2px var(--color-hover),
777
+ inset 0 0 0 4px var(--uui-color-surface,#fff);
778
+ }
779
+
780
+ :host([disabled]) #range-slider input::-moz-range-thumb {
781
+ background-color: var(--uui-palette-mine-grey,#3e3e3e);
782
+ box-shadow: inset 0 0 0 2px var(--uui-palette-mine-grey,#3e3e3e),
783
+ inset 0 0 0 4px var(--uui-color-surface,#fff);
784
+ }
828
785
  `
829
786
  ];
787
+ __decorateClass([
788
+ property({ type: String })
789
+ ], UUIRangeSliderElement.prototype, "label", 2);
830
790
  __decorateClass([
831
791
  property({ type: Boolean, reflect: true })
832
792
  ], UUIRangeSliderElement.prototype, "disabled", 2);
833
793
  __decorateClass([
834
- property({ type: String })
835
- ], UUIRangeSliderElement.prototype, "label", 2);
794
+ property({ type: Number })
795
+ ], UUIRangeSliderElement.prototype, "min", 1);
836
796
  __decorateClass([
837
797
  property({ type: Number })
838
- ], UUIRangeSliderElement.prototype, "step", 2);
798
+ ], UUIRangeSliderElement.prototype, "max", 1);
839
799
  __decorateClass([
840
800
  property({ type: Boolean, attribute: "hide-step-values" })
841
801
  ], UUIRangeSliderElement.prototype, "hideStepValues", 2);
842
802
  __decorateClass([
843
803
  property({ type: Number })
844
- ], UUIRangeSliderElement.prototype, "min", 2);
845
- __decorateClass([
846
- property({ type: Number })
847
- ], UUIRangeSliderElement.prototype, "max", 2);
804
+ ], UUIRangeSliderElement.prototype, "step", 1);
848
805
  __decorateClass([
849
806
  property({ type: Number, attribute: "min-gap" })
850
- ], UUIRangeSliderElement.prototype, "minGap", 2);
807
+ ], UUIRangeSliderElement.prototype, "minGap", 1);
851
808
  __decorateClass([
852
809
  property({ type: Number, attribute: "max-gap" })
853
- ], UUIRangeSliderElement.prototype, "maxGap", 2);
810
+ ], UUIRangeSliderElement.prototype, "maxGap", 1);
854
811
  __decorateClass([
855
812
  property({ type: String })
856
813
  ], UUIRangeSliderElement.prototype, "value", 1);
857
- __decorateClass([
858
- property({ type: Number, attribute: "value-low" })
859
- ], UUIRangeSliderElement.prototype, "valueLow", 1);
860
- __decorateClass([
861
- property({ type: Number, attribute: "value-high" })
862
- ], UUIRangeSliderElement.prototype, "valueHigh", 1);
863
- __decorateClass([
864
- state()
865
- ], UUIRangeSliderElement.prototype, "_trackWidth", 2);
866
814
  __decorateClass([
867
815
  state()
868
- ], UUIRangeSliderElement.prototype, "_currentInputFocus", 2);
816
+ ], UUIRangeSliderElement.prototype, "_movement", 2);
869
817
  __decorateClass([
870
818
  state()
871
- ], UUIRangeSliderElement.prototype, "_currentThumbFocus", 2);
819
+ ], UUIRangeSliderElement.prototype, "_lowInputValue", 2);
872
820
  __decorateClass([
873
821
  state()
874
- ], UUIRangeSliderElement.prototype, "_grabbingBoth", 2);
822
+ ], UUIRangeSliderElement.prototype, "_highInputValue", 2);
875
823
  __decorateClass([
876
824
  state()
877
- ], UUIRangeSliderElement.prototype, "_startPos", 2);
825
+ ], UUIRangeSliderElement.prototype, "_trackWidth", 2);
878
826
  __decorateClass([
879
827
  state()
880
- ], UUIRangeSliderElement.prototype, "_startLow", 2);
828
+ ], UUIRangeSliderElement.prototype, "_lowValuePercentStart", 2);
881
829
  __decorateClass([
882
830
  state()
883
- ], UUIRangeSliderElement.prototype, "_startHigh", 2);
884
- __decorateClass([
885
- query("#low-input")
886
- ], UUIRangeSliderElement.prototype, "_inputLow", 2);
887
- __decorateClass([
888
- query("#high-input")
889
- ], UUIRangeSliderElement.prototype, "_inputHigh", 2);
831
+ ], UUIRangeSliderElement.prototype, "_highValuePercentEnd", 2);
890
832
  __decorateClass([
891
833
  query("#range-slider")
892
834
  ], UUIRangeSliderElement.prototype, "_outerTrack", 2);
893
835
  __decorateClass([
894
- query("#inner-track")
895
- ], UUIRangeSliderElement.prototype, "_innerTrack", 2);
896
- __decorateClass([
897
- query("#low-thumb")
898
- ], UUIRangeSliderElement.prototype, "_thumbLow", 2);
836
+ query("#inputLow")
837
+ ], UUIRangeSliderElement.prototype, "_inputLow", 2);
899
838
  __decorateClass([
900
- query("#high-thumb")
901
- ], UUIRangeSliderElement.prototype, "_thumbHigh", 2);
839
+ query("#inputHigh")
840
+ ], UUIRangeSliderElement.prototype, "_inputHigh", 2);
902
841
  __decorateClass([
903
842
  query(".color")
904
843
  ], UUIRangeSliderElement.prototype, "_innerColor", 2);
905
844
  __decorateClass([
906
- query(".color-target")
907
- ], UUIRangeSliderElement.prototype, "_bothThumbsTarget", 2);
845
+ query("#inner-color-thumb")
846
+ ], UUIRangeSliderElement.prototype, "_innerColorThumb", 2);
908
847
  UUIRangeSliderElement = __decorateClass([
909
848
  defineElement("uui-range-slider")
910
849
  ], UUIRangeSliderElement);