@vaadin/slider 25.1.0-alpha5 → 25.1.0-alpha7

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.
@@ -3,7 +3,9 @@
3
3
  * Copyright (c) 2026 - 2026 Vaadin Ltd.
4
4
  * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
5
  */
6
+ import './vaadin-slider-bubble.js';
6
7
  import { css, html, LitElement, render } from 'lit';
8
+ import { ifDefined } from 'lit/directives/if-defined.js';
7
9
  import { styleMap } from 'lit/directives/style-map.js';
8
10
  import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
9
11
  import { isElementFocused } from '@vaadin/a11y-base/src/focus-utils.js';
@@ -41,17 +43,23 @@ import { SliderMixin } from './vaadin-slider-mixin.js';
41
43
  * `thumb` | The slider thumb (applies to both thumbs)
42
44
  * `thumb-start` | The start (lower value) thumb
43
45
  * `thumb-end` | The end (upper value) thumb
46
+ * `marks` | Container for min/max labels
47
+ * `min` | Minimum value label
48
+ * `max` | Maximum value label
44
49
  *
45
50
  * The following state attributes are available for styling:
46
51
  *
47
- * Attribute | Description
48
- * ----------------|-------------
49
- * `disabled` | Set when the slider is disabled
50
- * `readonly` | Set when the slider is read-only
51
- * `focused` | Set when the slider has focus
52
- * `focus-ring` | Set when the slider is focused using the keyboard
53
- * `start-focused` | Set when the start thumb has focus
54
- * `end-focused` | Set when the end thumb has focus
52
+ * Attribute | Description
53
+ * -------------------|-------------
54
+ * `disabled` | Set when the slider is disabled
55
+ * `readonly` | Set when the slider is read-only
56
+ * `focused` | Set when the slider has focus
57
+ * `focus-ring` | Set when the slider is focused using the keyboard
58
+ * `start-active` | Set when the start thumb is activated with mouse or touch
59
+ * `end-active` | Set when the end thumb is activated with mouse or touch
60
+ * `start-focused` | Set when the start thumb has focus
61
+ * `end-focused` | Set when the end thumb has focus
62
+ * `min-max-visible` | Set when the min/max labels are displayed
55
63
  *
56
64
  * The following custom CSS properties are available for styling:
57
65
  *
@@ -68,20 +76,52 @@ import { SliderMixin } from './vaadin-slider-mixin.js';
68
76
  * `--vaadin-input-field-label-font-size` |
69
77
  * `--vaadin-input-field-label-font-weight` |
70
78
  * `--vaadin-input-field-required-indicator` |
79
+ * `--vaadin-slider-bubble-arrow-size` |
80
+ * `--vaadin-slider-bubble-background` |
81
+ * `--vaadin-slider-bubble-border-color` |
82
+ * `--vaadin-slider-bubble-border-radius` |
83
+ * `--vaadin-slider-bubble-border-width` |
84
+ * `--vaadin-slider-bubble-offset` |
85
+ * `--vaadin-slider-bubble-padding` |
86
+ * `--vaadin-slider-bubble-shadow` |
87
+ * `--vaadin-slider-bubble-text-color` |
88
+ * `--vaadin-slider-bubble-font-size` |
89
+ * `--vaadin-slider-bubble-font-weight` |
90
+ * `--vaadin-slider-bubble-line-height` |
71
91
  * `--vaadin-slider-fill-background` |
92
+ * `--vaadin-slider-fill-border-color` |
93
+ * `--vaadin-slider-fill-border-width` |
94
+ * `--vaadin-slider-marks-color` |
95
+ * `--vaadin-slider-marks-font-size` |
96
+ * `--vaadin-slider-marks-font-weight` |
97
+ * `--vaadin-slider-thumb-border-color` |
98
+ * `--vaadin-slider-thumb-border-radius` |
99
+ * `--vaadin-slider-thumb-border-width` |
100
+ * `--vaadin-slider-thumb-cursor` |
101
+ * `--vaadin-slider-thumb-cursor-active` |
72
102
  * `--vaadin-slider-thumb-height` |
73
103
  * `--vaadin-slider-thumb-width` |
74
104
  * `--vaadin-slider-track-background` |
105
+ * `--vaadin-slider-track-border-color` |
75
106
  * `--vaadin-slider-track-border-radius` |
107
+ * `--vaadin-slider-track-border-width` |
76
108
  * `--vaadin-slider-track-height` |
77
109
  *
110
+ * In order to style the slider bubble, use `<vaadin-slider-bubble>` shadow DOM parts:
111
+ *
112
+ * Part name | Description
113
+ * -----------------|----------------------
114
+ * `overlay` | The overlay container
115
+ * `content` | The overlay content
116
+ * `arrow` | Arrow pointing to the thumb
117
+ *
78
118
  * See [Styling Components](https://vaadin.com/docs/latest/styling/styling-components) documentation.
79
119
  *
80
120
  * @fires {Event} change - Fired when the user commits a value change.
81
121
  * @fires {Event} input - Fired when the slider value changes during user interaction.
82
122
  * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
83
123
  *
84
- * @customElement
124
+ * @customElement vaadin-range-slider
85
125
  * @extends HTMLElement
86
126
  * @mixes ElementMixin
87
127
  * @mixes FieldMixin
@@ -181,6 +221,88 @@ class RangeSlider extends FieldMixin(
181
221
  notify: true,
182
222
  sync: true,
183
223
  },
224
+
225
+ /**
226
+ * Custom accessible name for the start (minimum) input.
227
+ * When not set, defaults to "${label} min" or "min" if no label.
228
+ * @attr {string} accessible-name-start
229
+ */
230
+ accessibleNameStart: {
231
+ type: String,
232
+ },
233
+
234
+ /**
235
+ * Custom accessible name for the end (maximum) input.
236
+ * When not set, defaults to "${label} max" or "max" if no label.
237
+ * @attr {string} accessible-name-end
238
+ */
239
+ accessibleNameEnd: {
240
+ type: String,
241
+ },
242
+
243
+ /** @private */
244
+ __startActive: {
245
+ type: Boolean,
246
+ value: false,
247
+ reflectToAttribute: true,
248
+ attribute: 'start-active',
249
+ sync: true,
250
+ },
251
+
252
+ /** @private */
253
+ __endActive: {
254
+ type: Boolean,
255
+ value: false,
256
+ reflectToAttribute: true,
257
+ attribute: 'end-active',
258
+ sync: true,
259
+ },
260
+
261
+ /** @private */
262
+ __startFocused: {
263
+ type: Boolean,
264
+ value: false,
265
+ reflectToAttribute: true,
266
+ attribute: 'start-focused',
267
+ sync: true,
268
+ },
269
+
270
+ /** @private */
271
+ __endFocused: {
272
+ type: Boolean,
273
+ value: false,
274
+ reflectToAttribute: true,
275
+ attribute: 'end-focused',
276
+ sync: true,
277
+ },
278
+
279
+ /** @private */
280
+ __startHover: {
281
+ type: Boolean,
282
+ value: false,
283
+ sync: true,
284
+ },
285
+
286
+ /** @private */
287
+ __endHover: {
288
+ type: Boolean,
289
+ value: false,
290
+ sync: true,
291
+ },
292
+
293
+ /** @private */
294
+ __startBubbleOpened: {
295
+ type: Boolean,
296
+ value: false,
297
+ sync: true,
298
+ },
299
+
300
+ /** @private */
301
+ __endBubbleOpened: {
302
+ type: Boolean,
303
+ value: false,
304
+ sync: true,
305
+ },
184
306
  };
185
307
  }
186
308
 
@@ -190,6 +312,7 @@ class RangeSlider extends FieldMixin(
190
312
 
191
313
  const startPercent = this.__getPercentFromValue(startValue);
192
314
  const endPercent = this.__getPercentFromValue(endValue);
315
+ const { min, max } = this.__getConstraints();
193
316
 
194
317
  return html`
195
318
  <div class="vaadin-slider-container">
@@ -205,6 +328,12 @@ class RangeSlider extends FieldMixin(
205
328
  <div part="thumb thumb-start"></div>
206
329
  <div part="thumb thumb-end"></div>
207
330
  <slot name="input"></slot>
331
+ <slot name="bubble"></slot>
332
+ </div>
333
+
334
+ <div part="marks" aria-hidden="true">
335
+ <span part="min">${min}</span>
336
+ <span part="max">${max}</span>
208
337
  </div>
209
338
 
210
339
  <div part="helper-text">
@@ -224,6 +353,8 @@ class RangeSlider extends FieldMixin(
224
353
  this.__value = [...this.value];
225
354
  this.__inputId0 = `slider-${generateUniqueId()}`;
226
355
  this.__inputId1 = `slider-${generateUniqueId()}`;
356
+
357
+ this.__onPointerUp = this.__onPointerUp.bind(this);
227
358
  }
228
359
 
229
360
  /** @protected */
@@ -233,6 +364,33 @@ class RangeSlider extends FieldMixin(
233
364
  const inputs = this.querySelectorAll('[slot="input"]');
234
365
  this._inputElements = [...inputs];
235
366
  this.ariaTarget = this;
367
+
368
+ this.__thumbStartElement = this.shadowRoot.querySelector('[part~="thumb-start"]');
369
+ this.__thumbEndElement = this.shadowRoot.querySelector('[part~="thumb-end"]');
370
+
371
+ this.__bubbleElements = [...this.querySelectorAll('vaadin-slider-bubble')];
372
+ }
373
+
374
+ /** @private */
375
+ __onPointerDown(event) {
376
+ super.__onPointerDown(event);
377
+
378
+ const index = this._inputElements.indexOf(event.composedPath()[0]);
379
+
380
+ if (!this.readonly && index !== -1) {
381
+ this.toggleAttribute('start-active', index === 0);
382
+ this.toggleAttribute('end-active', index === 1);
383
+ window.addEventListener('pointerup', this.__onPointerUp);
384
+ window.addEventListener('pointercancel', this.__onPointerUp);
385
+ }
386
+ }
387
+
388
+ /** @private */
389
+ __onPointerUp() {
390
+ window.removeEventListener('pointerup', this.__onPointerUp);
391
+ window.removeEventListener('pointercancel', this.__onPointerUp);
392
+ this.removeAttribute('start-active');
393
+ this.removeAttribute('end-active');
236
394
  }
237
395
 
238
396
  /**
@@ -252,12 +410,16 @@ class RangeSlider extends FieldMixin(
252
410
  type="range"
253
411
  id="${this.__inputId0}"
254
412
  slot="input"
413
+ aria-label="${this.accessibleNameStart || this.__getAriaLabel('min')}"
255
414
  .min="${min}"
256
415
  .max="${max}"
257
416
  .step="${step}"
258
417
  .value="${startValue}"
259
418
  .disabled="${this.disabled}"
260
419
  tabindex="${this.disabled ? -1 : 0}"
420
+ @pointerenter="${this.__onStartPointerEnter}"
421
+ @pointermove="${this.__onStartPointerMove}"
422
+ @pointerleave="${this.__onStartPointerLeave}"
261
423
  @keydown="${this.__onKeyDown}"
262
424
  @input="${this.__onStartInput}"
263
425
  @change="${this.__onChange}"
@@ -266,22 +428,63 @@ class RangeSlider extends FieldMixin(
266
428
  type="range"
267
429
  id="${this.__inputId1}"
268
430
  slot="input"
431
+ aria-label="${this.accessibleNameEnd || this.__getAriaLabel('max')}"
269
432
  .min="${min}"
270
433
  .max="${max}"
271
434
  .step="${step}"
272
435
  .value="${endValue}"
273
436
  .disabled="${this.disabled}"
274
437
  tabindex="${this.disabled ? -1 : 0}"
438
+ @pointerenter="${this.__onEndPointerEnter}"
439
+ @pointermove="${this.__onEndPointerMove}"
440
+ @pointerleave="${this.__onEndPointerLeave}"
275
441
  @keydown="${this.__onKeyDown}"
276
442
  @input="${this.__onEndInput}"
277
443
  @change="${this.__onChange}"
278
444
  />
445
+ <vaadin-slider-bubble
446
+ slot="bubble"
447
+ .positionTarget="${this.__thumbStartElement}"
448
+ .opened="${this.valueAlwaysVisible || this.__startBubbleOpened}"
449
+ theme="${ifDefined(this._theme)}"
450
+ >
451
+ ${startValue}
452
+ </vaadin-slider-bubble>
453
+ <vaadin-slider-bubble
454
+ slot="bubble"
455
+ .positionTarget="${this.__thumbEndElement}"
456
+ .opened="${this.valueAlwaysVisible || this.__endBubbleOpened}"
457
+ theme="${ifDefined(this._theme)}"
458
+ >
459
+ ${endValue}
460
+ </vaadin-slider-bubble>
279
461
  `,
280
462
  this,
281
463
  { host: this },
282
464
  );
283
465
  }
284
466
 
467
+ /** @protected */
468
+ willUpdate(props) {
469
+ super.willUpdate(props);
470
+
471
+ this.__updateBubbleState(props, {
472
+ active: '__startActive',
473
+ focused: '__startFocused',
474
+ hover: '__startHover',
475
+ opened: '__startBubbleOpened',
476
+ otherOpened: '__endBubbleOpened',
477
+ });
478
+
479
+ this.__updateBubbleState(props, {
480
+ active: '__endActive',
481
+ focused: '__endFocused',
482
+ hover: '__endHover',
483
+ opened: '__endBubbleOpened',
484
+ otherOpened: '__startBubbleOpened',
485
+ });
486
+ }
487
+
285
488
  /** @protected */
286
489
  updated(props) {
287
490
  super.updated(props);
@@ -335,8 +538,13 @@ class RangeSlider extends FieldMixin(
335
538
  _setFocused(focused) {
336
539
  super._setFocused(focused);
337
540
 
338
- this.toggleAttribute('start-focused', isElementFocused(this._inputElements[0]));
339
- this.toggleAttribute('end-focused', isElementFocused(this._inputElements[1]));
541
+ this.__startFocused = isElementFocused(this._inputElements[0]);
542
+ this.__endFocused = isElementFocused(this._inputElements[1]);
543
+ }
544
+
545
+ /** @private */
546
+ __getAriaLabel(suffix) {
547
+ return this.label ? `${this.label} ${suffix}` : suffix;
340
548
  }
341
549
 
342
550
  /** @private */
@@ -355,6 +563,7 @@ class RangeSlider extends FieldMixin(
355
563
 
356
564
  const value = event.target.value;
357
565
  this.__updateValue(value, 0);
566
+ this.__updateBubble(0);
358
567
  this.__dispatchInputEvent();
359
568
  this.__commitValue();
360
569
  }
@@ -370,14 +579,60 @@ class RangeSlider extends FieldMixin(
370
579
 
371
580
  const value = event.target.value;
372
581
  this.__updateValue(value, 1);
582
+ this.__updateBubble(1);
373
583
  this.__dispatchInputEvent();
374
584
  this.__commitValue();
375
585
  }
376
586
 
587
+ /** @private */
588
+ __isThumbEvent(event, thumb) {
589
+ const rect = thumb.getBoundingClientRect();
590
+ return (
591
+ event.clientX >= rect.left &&
592
+ event.clientX <= rect.right &&
593
+ event.clientY >= rect.top &&
594
+ event.clientY <= rect.bottom
595
+ );
596
+ }
597
+
598
+ /** @private */
599
+ __onStartPointerEnter(event) {
600
+ if (this.__isThumbEvent(event, this.__thumbStartElement)) {
601
+ this.__startHover = true;
602
+ }
603
+ }
604
+
605
+ /** @private */
606
+ __onStartPointerMove(event) {
607
+ this.__startHover = this.__isThumbEvent(event, this.__thumbStartElement);
608
+ }
609
+
610
+ /** @private */
611
+ __onStartPointerLeave() {
612
+ this.__startHover = false;
613
+ }
614
+
615
+ /** @private */
616
+ __onEndPointerEnter(event) {
617
+ if (this.__isThumbEvent(event, this.__thumbEndElement)) {
618
+ this.__endHover = true;
619
+ }
620
+ }
621
+
622
+ /** @private */
623
+ __onEndPointerMove(event) {
624
+ this.__endHover = this.__isThumbEvent(event, this.__thumbEndElement);
625
+ }
626
+
627
+ /** @private */
628
+ __onEndPointerLeave() {
629
+ this.__endHover = false;
630
+ }
631
+
377
632
  /** @private */
378
633
  __onKeyDown(event) {
379
- const prevKeys = ['ArrowLeft', 'ArrowDown'];
380
- const nextKeys = ['ArrowRight', 'ArrowUp'];
634
+ const prevKeys = ['ArrowLeft', 'ArrowDown', 'PageDown', 'Home'];
635
+ const nextKeys = ['ArrowRight', 'ArrowUp', 'PageUp', 'End'];
381
636
 
382
637
  const isNextKey = nextKeys.includes(event.key);
383
638
  const isPrevKey = prevKeys.includes(event.key);
@@ -397,6 +652,11 @@ class RangeSlider extends FieldMixin(
397
652
  event.preventDefault();
398
653
  }
399
654
  }
655
+
656
+ /** @private */
657
+ __updateBubble(idx) {
658
+ this.__bubbleElements[idx].$.overlay._updatePosition();
659
+ }
400
660
  }
401
661
 
402
662
  defineCustomElement(RangeSlider);
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2026 - 2026 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import { html, LitElement } from 'lit';
7
+ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
8
+ import { DirMixin } from '@vaadin/component-base/src/dir-mixin.js';
9
+ import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
10
+ import { OverlayMixin } from '@vaadin/overlay/src/vaadin-overlay-mixin.js';
11
+ import { PositionMixin } from '@vaadin/overlay/src/vaadin-overlay-position-mixin.js';
12
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
13
+ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
14
+ import { sliderBubbleOverlayStyles } from './styles/vaadin-slider-bubble-overlay-base-styles.js';
15
+
16
+ /**
17
+ * An element used internally by `<vaadin-slider>`. Not intended to be used separately.
18
+ *
19
+ * @customElement vaadin-slider-bubble-overlay
20
+ * @extends HTMLElement
21
+ * @mixes DirMixin
22
+ * @mixes OverlayMixin
23
+ * @mixes PositionMixin
24
+ * @mixes ThemableMixin
25
+ * @private
26
+ */
27
+ class SliderBubbleOverlay extends PositionMixin(
28
+ OverlayMixin(DirMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))),
29
+ ) {
30
+ static get is() {
31
+ return 'vaadin-slider-bubble-overlay';
32
+ }
33
+
34
+ static get styles() {
35
+ return sliderBubbleOverlayStyles;
36
+ }
37
+
38
+ static get lumoInjector() {
39
+ return { ...super.lumoInjector, includeBaseStyles: true };
40
+ }
41
+
42
+ /** @protected */
43
+ render() {
44
+ return html`
45
+ <div part="overlay" id="overlay">
46
+ <div part="arrow"></div>
47
+ <div part="content" id="content"><slot></slot></div>
48
+ </div>
49
+ `;
50
+ }
51
+
52
+ /**
53
+ * Override method from `OverlayMixin` to not close on outside click.
54
+ * The bubble overlay `opened` is fully controlled by the slider.
55
+ * @return {boolean}
56
+ * @protected
57
+ * @override
58
+ */
59
+ _shouldCloseOnOutsideClick() {
60
+ return false;
61
+ }
62
+
63
+ /**
64
+ * @protected
65
+ * @override
66
+ */
67
+ _updatePosition() {
68
+ super._updatePosition();
69
+
70
+ if (!this.positionTarget || !this.opened) {
71
+ return;
72
+ }
73
+
74
+ const targetRect = this.positionTarget.getBoundingClientRect();
75
+ const overlayRect = this.$.overlay.getBoundingClientRect();
76
+
77
+ const offset = targetRect.width / 2 - overlayRect.width / 2;
78
+
79
+ if (this.style.left) {
80
+ const left = overlayRect.left + offset;
81
+ if (left > 0) {
82
+ this.style.left = `${left}px`;
83
+ }
84
+ }
85
+
86
+ if (this.style.right) {
87
+ const right = parseFloat(this.style.right) + offset;
88
+ if (right > 0) {
89
+ this.style.right = `${right}px`;
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ defineCustomElement(SliderBubbleOverlay);
96
+
97
+ export { SliderBubbleOverlay };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2026 - 2026 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+
7
+ /**
8
+ * An element used internally by `<vaadin-slider>`. Not intended to be used separately.
9
+ */
10
+ declare class SliderBubble extends HTMLElement {
11
+ /**
12
+ * The thumb element next to which the overlay should be aligned.
13
+ */
14
+ positionTarget: HTMLElement;
15
+
16
+ /**
17
+ * Whether the overlay is opened.
18
+ */
19
+ opened: boolean;
20
+ }
21
+
22
+ declare global {
23
+ interface HTMLElementTagNameMap {
24
+ 'vaadin-slider-bubble': SliderBubble;
25
+ }
26
+ }
27
+
28
+ export { SliderBubble };
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @license
3
+ * Copyright (c) 2026 - 2026 Vaadin Ltd.
4
+ * This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
5
+ */
6
+ import './vaadin-slider-bubble-overlay.js';
7
+ import { css, html, LitElement } from 'lit';
8
+ import { ifDefined } from 'lit/directives/if-defined.js';
9
+ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
10
+ import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
11
+ import { ThemePropertyMixin } from '@vaadin/vaadin-themable-mixin/vaadin-theme-property-mixin.js';
12
+
13
+ /**
14
+ * An element used internally by `<vaadin-slider>`. Not intended to be used separately.
15
+ *
16
+ * @customElement vaadin-slider-bubble
17
+ * @extends HTMLElement
18
+ * @private
19
+ */
20
+ class SliderBubble extends ThemePropertyMixin(PolylitMixin(LitElement)) {
21
+ static get is() {
22
+ return 'vaadin-slider-bubble';
23
+ }
24
+
25
+ static get styles() {
26
+ return css`
27
+ :host {
28
+ display: contents;
29
+ }
30
+ `;
31
+ }
32
+
33
+ static get properties() {
34
+ return {
35
+ /**
36
+ * The thumb element next to which the overlay should be aligned.
37
+ */
38
+ positionTarget: {
39
+ type: Object,
40
+ },
41
+
42
+ /**
43
+ * Whether the overlay is opened.
44
+ */
45
+ opened: {
46
+ type: Boolean,
47
+ value: false,
48
+ reflectToAttribute: true,
49
+ },
50
+ };
51
+ }
52
+
53
+ /** @protected */
54
+ render() {
55
+ return html`
56
+ <vaadin-slider-bubble-overlay
57
+ id="overlay"
58
+ .owner="${this}"
59
+ .opened="${this.opened}"
60
+ .positionTarget="${this.positionTarget}"
61
+ theme="${ifDefined(this._theme)}"
62
+ vertical-align="bottom"
63
+ no-vertical-overlap
64
+ modeless
65
+ exportparts="overlay, content, arrow"
66
+ >
67
+ <slot></slot>
68
+ </vaadin-slider-bubble-overlay>
69
+ `;
70
+ }
71
+ }
72
+
73
+ defineCustomElement(SliderBubble);
74
+
75
+ export { SliderBubble };
@@ -34,4 +34,17 @@ export declare class SliderMixinClass {
34
34
  * readers.
35
35
  */
36
36
  readonly: boolean;
37
+
38
+ /**
39
+ * When true, the value bubble is always visible,
40
+ * regardless of focus or hover state.
41
+ * @attr {boolean} value-always-visible
42
+ */
43
+ valueAlwaysVisible: boolean;
44
+
45
+ /**
46
+ * When true, displays the min and max values below the slider track.
47
+ * @attr {boolean} min-max-visible
48
+ */
49
+ minMaxVisible: boolean;
37
50
  }