@vaadin/slider 25.1.0-alpha2

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.
@@ -0,0 +1,190 @@
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 { css, html, LitElement, render } from 'lit';
7
+ import { styleMap } from 'lit/directives/style-map.js';
8
+ import { FocusMixin } from '@vaadin/a11y-base/src/focus-mixin.js';
9
+ import { defineCustomElement } from '@vaadin/component-base/src/define.js';
10
+ import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
11
+ import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
12
+ import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
13
+ import { LumoInjectionMixin } from '@vaadin/vaadin-themable-mixin/lumo-injection-mixin.js';
14
+ import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
15
+ import { sliderStyles } from './styles/vaadin-slider-base-styles.js';
16
+ import { SliderMixin } from './vaadin-slider-mixin.js';
17
+
18
+ /**
19
+ * `<vaadin-slider>` is a web component that represents a range slider
20
+ * for selecting numerical values within a defined range.
21
+ *
22
+ * ```html
23
+ * <vaadin-slider min="0" max="100" step="1"></vaadin-slider>
24
+ * ```
25
+ *
26
+ * @fires {Event} change - Fired when the user commits a value change.
27
+ * @fires {CustomEvent} value-changed - Fired when the `value` property changes.
28
+ *
29
+ * @customElement
30
+ * @extends HTMLElement
31
+ * @mixes ElementMixin
32
+ * @mixes FocusMixin
33
+ * @mixes SliderMixin
34
+ * @mixes ThemableMixin
35
+ */
36
+ class Slider extends SliderMixin(
37
+ FocusMixin(ElementMixin(ThemableMixin(PolylitMixin(LumoInjectionMixin(LitElement))))),
38
+ ) {
39
+ static get is() {
40
+ return 'vaadin-slider';
41
+ }
42
+
43
+ static get styles() {
44
+ return [
45
+ sliderStyles,
46
+ css`
47
+ :host([focus-ring]) [part='thumb'] {
48
+ outline: var(--vaadin-focus-ring-width) solid var(--vaadin-focus-ring-color);
49
+ outline-offset: 1px;
50
+ }
51
+
52
+ :host([readonly][focus-ring]) [part~='thumb'] {
53
+ outline-style: dashed;
54
+ }
55
+ `,
56
+ ];
57
+ }
58
+
59
+ static get experimental() {
60
+ return 'sliderComponent';
61
+ }
62
+
63
+ static get properties() {
64
+ return {
65
+ /**
66
+ * The value of the slider.
67
+ */
68
+ value: {
69
+ type: Number,
70
+ value: 0,
71
+ notify: true,
72
+ sync: true,
73
+ },
74
+ };
75
+ }
76
+
77
+ /** @protected */
78
+ render() {
79
+ const [value] = this.__value;
80
+ const percent = this.__getPercentFromValue(value);
81
+
82
+ return html`
83
+ <div part="track">
84
+ <div
85
+ part="track-fill"
86
+ style="${styleMap({
87
+ insetInlineStart: 0,
88
+ insetInlineEnd: `${100 - percent}%`,
89
+ })}"
90
+ ></div>
91
+ </div>
92
+ <div part="thumb" style="${styleMap({ insetInlineStart: `${percent}%` })}"></div>
93
+ <slot name="input"></slot>
94
+ `;
95
+ }
96
+
97
+ constructor() {
98
+ super();
99
+
100
+ this.__value = [this.value];
101
+ this.__inputId = `slider-${generateUniqueId()}`;
102
+ }
103
+
104
+ /** @protected */
105
+ firstUpdated() {
106
+ super.firstUpdated();
107
+
108
+ const input = this.querySelector('[slot="input"]');
109
+ this._inputElement = input;
110
+ }
111
+
112
+ /**
113
+ * Override update to render slotted `<input type="range" />`
114
+ * into light DOM after rendering shadow DOM.
115
+ * @protected
116
+ */
117
+ update(props) {
118
+ super.update(props);
119
+
120
+ const [value] = this.__value;
121
+ const { min, max, step } = this.__getConstraints();
122
+
123
+ render(
124
+ html`
125
+ <input
126
+ type="range"
127
+ id="${this.__inputId}"
128
+ slot="input"
129
+ .min="${min}"
130
+ .max="${max}"
131
+ .value="${value}"
132
+ .step="${step}"
133
+ .disabled="${this.disabled}"
134
+ tabindex="${this.disabled ? -1 : 0}"
135
+ @keydown="${this.__onKeyDown}"
136
+ @input="${this.__onInput}"
137
+ @change="${this.__onChange}"
138
+ />
139
+ `,
140
+ this,
141
+ { host: this },
142
+ );
143
+ }
144
+
145
+ /** @protected */
146
+ updated(props) {
147
+ super.updated(props);
148
+
149
+ if (props.has('value') || props.has('min') || props.has('max')) {
150
+ this.__updateValue(this.value);
151
+ }
152
+ }
153
+
154
+ /**
155
+ * @param {FocusOptions=} options
156
+ * @protected
157
+ * @override
158
+ */
159
+ focus(options) {
160
+ if (this.disabled) {
161
+ return;
162
+ }
163
+
164
+ if (this._inputElement) {
165
+ this._inputElement.focus();
166
+ }
167
+
168
+ super.focus(options);
169
+ }
170
+
171
+ /**
172
+ * @private
173
+ * @override
174
+ */
175
+ __commitValue() {
176
+ this.value = this.__value[0];
177
+ }
178
+
179
+ /** @private */
180
+ __onKeyDown(event) {
181
+ const arrowKeys = ['ArrowLeft', 'ArrowDown', 'ArrowRight', 'ArrowUp'];
182
+ if (this.readonly && arrowKeys.includes(event.key)) {
183
+ event.preventDefault();
184
+ }
185
+ }
186
+ }
187
+
188
+ defineCustomElement(Slider);
189
+
190
+ export { Slider };
@@ -0,0 +1 @@
1
+ export * from './src/vaadin-range-slider.js';
@@ -0,0 +1,2 @@
1
+ import './src/vaadin-range-slider.js';
2
+ export * from './src/vaadin-range-slider.js';
@@ -0,0 +1 @@
1
+ export * from './src/vaadin-slider.js';
@@ -0,0 +1,2 @@
1
+ import './src/vaadin-slider.js';
2
+ export * from './src/vaadin-slider.js';
package/web-types.json ADDED
@@ -0,0 +1,327 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/web-types",
3
+ "name": "@vaadin/slider",
4
+ "version": "25.1.0-alpha2",
5
+ "description-markup": "markdown",
6
+ "contributions": {
7
+ "html": {
8
+ "elements": [
9
+ {
10
+ "name": "vaadin-range-slider",
11
+ "description": "`<vaadin-range-slider>` is a web component that represents a range slider\nfor selecting a subset of the given range.\n\n```html\n<vaadin-range-slider min=\"0\" max=\"100\" step=\"1\"></vaadin-range-slider>\n```",
12
+ "attributes": [
13
+ {
14
+ "name": "disabled",
15
+ "description": "If true, the user cannot interact with this element.",
16
+ "value": {
17
+ "type": [
18
+ "boolean",
19
+ "null",
20
+ "undefined"
21
+ ]
22
+ }
23
+ },
24
+ {
25
+ "name": "min",
26
+ "description": "The minimum allowed value.",
27
+ "value": {
28
+ "type": [
29
+ "number",
30
+ "null",
31
+ "undefined"
32
+ ]
33
+ }
34
+ },
35
+ {
36
+ "name": "max",
37
+ "description": "The maximum allowed value.",
38
+ "value": {
39
+ "type": [
40
+ "number",
41
+ "null",
42
+ "undefined"
43
+ ]
44
+ }
45
+ },
46
+ {
47
+ "name": "step",
48
+ "description": "The stepping interval of the slider.",
49
+ "value": {
50
+ "type": [
51
+ "number",
52
+ "null",
53
+ "undefined"
54
+ ]
55
+ }
56
+ },
57
+ {
58
+ "name": "readonly",
59
+ "description": "When true, the user cannot modify the value of the slider.\nThe difference between `disabled` and `readonly` is that the\nread-only slider remains focusable and is announced by screen\nreaders.",
60
+ "value": {
61
+ "type": [
62
+ "boolean",
63
+ "null",
64
+ "undefined"
65
+ ]
66
+ }
67
+ },
68
+ {
69
+ "name": "theme",
70
+ "description": "The theme variants to apply to the component.",
71
+ "value": {
72
+ "type": [
73
+ "string",
74
+ "null",
75
+ "undefined"
76
+ ]
77
+ }
78
+ }
79
+ ],
80
+ "js": {
81
+ "properties": [
82
+ {
83
+ "name": "disabled",
84
+ "description": "If true, the user cannot interact with this element.",
85
+ "value": {
86
+ "type": [
87
+ "boolean",
88
+ "null",
89
+ "undefined"
90
+ ]
91
+ }
92
+ },
93
+ {
94
+ "name": "min",
95
+ "description": "The minimum allowed value.",
96
+ "value": {
97
+ "type": [
98
+ "number",
99
+ "null",
100
+ "undefined"
101
+ ]
102
+ }
103
+ },
104
+ {
105
+ "name": "max",
106
+ "description": "The maximum allowed value.",
107
+ "value": {
108
+ "type": [
109
+ "number",
110
+ "null",
111
+ "undefined"
112
+ ]
113
+ }
114
+ },
115
+ {
116
+ "name": "step",
117
+ "description": "The stepping interval of the slider.",
118
+ "value": {
119
+ "type": [
120
+ "number",
121
+ "null",
122
+ "undefined"
123
+ ]
124
+ }
125
+ },
126
+ {
127
+ "name": "readonly",
128
+ "description": "When true, the user cannot modify the value of the slider.\nThe difference between `disabled` and `readonly` is that the\nread-only slider remains focusable and is announced by screen\nreaders.",
129
+ "value": {
130
+ "type": [
131
+ "boolean",
132
+ "null",
133
+ "undefined"
134
+ ]
135
+ }
136
+ },
137
+ {
138
+ "name": "value",
139
+ "description": "The value of the slider.",
140
+ "value": {
141
+ "type": [
142
+ "Array",
143
+ "null",
144
+ "undefined"
145
+ ]
146
+ }
147
+ }
148
+ ],
149
+ "events": [
150
+ {
151
+ "name": "change",
152
+ "description": "Fired when the user commits a value change."
153
+ },
154
+ {
155
+ "name": "value-changed",
156
+ "description": "Fired when the `value` property changes."
157
+ }
158
+ ]
159
+ }
160
+ },
161
+ {
162
+ "name": "vaadin-slider",
163
+ "description": "`<vaadin-slider>` is a web component that represents a range slider\nfor selecting numerical values within a defined range.\n\n```html\n<vaadin-slider min=\"0\" max=\"100\" step=\"1\"></vaadin-slider>\n```",
164
+ "attributes": [
165
+ {
166
+ "name": "disabled",
167
+ "description": "If true, the user cannot interact with this element.",
168
+ "value": {
169
+ "type": [
170
+ "boolean",
171
+ "null",
172
+ "undefined"
173
+ ]
174
+ }
175
+ },
176
+ {
177
+ "name": "min",
178
+ "description": "The minimum allowed value.",
179
+ "value": {
180
+ "type": [
181
+ "number",
182
+ "null",
183
+ "undefined"
184
+ ]
185
+ }
186
+ },
187
+ {
188
+ "name": "max",
189
+ "description": "The maximum allowed value.",
190
+ "value": {
191
+ "type": [
192
+ "number",
193
+ "null",
194
+ "undefined"
195
+ ]
196
+ }
197
+ },
198
+ {
199
+ "name": "step",
200
+ "description": "The stepping interval of the slider.",
201
+ "value": {
202
+ "type": [
203
+ "number",
204
+ "null",
205
+ "undefined"
206
+ ]
207
+ }
208
+ },
209
+ {
210
+ "name": "readonly",
211
+ "description": "When true, the user cannot modify the value of the slider.\nThe difference between `disabled` and `readonly` is that the\nread-only slider remains focusable and is announced by screen\nreaders.",
212
+ "value": {
213
+ "type": [
214
+ "boolean",
215
+ "null",
216
+ "undefined"
217
+ ]
218
+ }
219
+ },
220
+ {
221
+ "name": "value",
222
+ "description": "The value of the slider.",
223
+ "value": {
224
+ "type": [
225
+ "number",
226
+ "null",
227
+ "undefined"
228
+ ]
229
+ }
230
+ },
231
+ {
232
+ "name": "theme",
233
+ "description": "The theme variants to apply to the component.",
234
+ "value": {
235
+ "type": [
236
+ "string",
237
+ "null",
238
+ "undefined"
239
+ ]
240
+ }
241
+ }
242
+ ],
243
+ "js": {
244
+ "properties": [
245
+ {
246
+ "name": "disabled",
247
+ "description": "If true, the user cannot interact with this element.",
248
+ "value": {
249
+ "type": [
250
+ "boolean",
251
+ "null",
252
+ "undefined"
253
+ ]
254
+ }
255
+ },
256
+ {
257
+ "name": "min",
258
+ "description": "The minimum allowed value.",
259
+ "value": {
260
+ "type": [
261
+ "number",
262
+ "null",
263
+ "undefined"
264
+ ]
265
+ }
266
+ },
267
+ {
268
+ "name": "max",
269
+ "description": "The maximum allowed value.",
270
+ "value": {
271
+ "type": [
272
+ "number",
273
+ "null",
274
+ "undefined"
275
+ ]
276
+ }
277
+ },
278
+ {
279
+ "name": "step",
280
+ "description": "The stepping interval of the slider.",
281
+ "value": {
282
+ "type": [
283
+ "number",
284
+ "null",
285
+ "undefined"
286
+ ]
287
+ }
288
+ },
289
+ {
290
+ "name": "readonly",
291
+ "description": "When true, the user cannot modify the value of the slider.\nThe difference between `disabled` and `readonly` is that the\nread-only slider remains focusable and is announced by screen\nreaders.",
292
+ "value": {
293
+ "type": [
294
+ "boolean",
295
+ "null",
296
+ "undefined"
297
+ ]
298
+ }
299
+ },
300
+ {
301
+ "name": "value",
302
+ "description": "The value of the slider.",
303
+ "value": {
304
+ "type": [
305
+ "number",
306
+ "null",
307
+ "undefined"
308
+ ]
309
+ }
310
+ }
311
+ ],
312
+ "events": [
313
+ {
314
+ "name": "change",
315
+ "description": "Fired when the user commits a value change."
316
+ },
317
+ {
318
+ "name": "value-changed",
319
+ "description": "Fired when the `value` property changes."
320
+ }
321
+ ]
322
+ }
323
+ }
324
+ ]
325
+ }
326
+ }
327
+ }
@@ -0,0 +1,146 @@
1
+ {
2
+ "$schema": "https://json.schemastore.org/web-types",
3
+ "name": "@vaadin/slider",
4
+ "version": "25.1.0-alpha2",
5
+ "description-markup": "markdown",
6
+ "framework": "lit",
7
+ "framework-config": {
8
+ "enable-when": {
9
+ "node-packages": [
10
+ "lit"
11
+ ]
12
+ }
13
+ },
14
+ "contributions": {
15
+ "html": {
16
+ "elements": [
17
+ {
18
+ "name": "vaadin-range-slider",
19
+ "description": "`<vaadin-range-slider>` is a web component that represents a range slider\nfor selecting a subset of the given range.\n\n```html\n<vaadin-range-slider min=\"0\" max=\"100\" step=\"1\"></vaadin-range-slider>\n```",
20
+ "extension": true,
21
+ "attributes": [
22
+ {
23
+ "name": "?disabled",
24
+ "description": "If true, the user cannot interact with this element.",
25
+ "value": {
26
+ "kind": "expression"
27
+ }
28
+ },
29
+ {
30
+ "name": "?readonly",
31
+ "description": "When true, the user cannot modify the value of the slider.\nThe difference between `disabled` and `readonly` is that the\nread-only slider remains focusable and is announced by screen\nreaders.",
32
+ "value": {
33
+ "kind": "expression"
34
+ }
35
+ },
36
+ {
37
+ "name": ".min",
38
+ "description": "The minimum allowed value.",
39
+ "value": {
40
+ "kind": "expression"
41
+ }
42
+ },
43
+ {
44
+ "name": ".max",
45
+ "description": "The maximum allowed value.",
46
+ "value": {
47
+ "kind": "expression"
48
+ }
49
+ },
50
+ {
51
+ "name": ".step",
52
+ "description": "The stepping interval of the slider.",
53
+ "value": {
54
+ "kind": "expression"
55
+ }
56
+ },
57
+ {
58
+ "name": ".value",
59
+ "description": "The value of the slider.",
60
+ "value": {
61
+ "kind": "expression"
62
+ }
63
+ },
64
+ {
65
+ "name": "@change",
66
+ "description": "Fired when the user commits a value change.",
67
+ "value": {
68
+ "kind": "expression"
69
+ }
70
+ },
71
+ {
72
+ "name": "@value-changed",
73
+ "description": "Fired when the `value` property changes.",
74
+ "value": {
75
+ "kind": "expression"
76
+ }
77
+ }
78
+ ]
79
+ },
80
+ {
81
+ "name": "vaadin-slider",
82
+ "description": "`<vaadin-slider>` is a web component that represents a range slider\nfor selecting numerical values within a defined range.\n\n```html\n<vaadin-slider min=\"0\" max=\"100\" step=\"1\"></vaadin-slider>\n```",
83
+ "extension": true,
84
+ "attributes": [
85
+ {
86
+ "name": "?disabled",
87
+ "description": "If true, the user cannot interact with this element.",
88
+ "value": {
89
+ "kind": "expression"
90
+ }
91
+ },
92
+ {
93
+ "name": "?readonly",
94
+ "description": "When true, the user cannot modify the value of the slider.\nThe difference between `disabled` and `readonly` is that the\nread-only slider remains focusable and is announced by screen\nreaders.",
95
+ "value": {
96
+ "kind": "expression"
97
+ }
98
+ },
99
+ {
100
+ "name": ".min",
101
+ "description": "The minimum allowed value.",
102
+ "value": {
103
+ "kind": "expression"
104
+ }
105
+ },
106
+ {
107
+ "name": ".max",
108
+ "description": "The maximum allowed value.",
109
+ "value": {
110
+ "kind": "expression"
111
+ }
112
+ },
113
+ {
114
+ "name": ".step",
115
+ "description": "The stepping interval of the slider.",
116
+ "value": {
117
+ "kind": "expression"
118
+ }
119
+ },
120
+ {
121
+ "name": ".value",
122
+ "description": "The value of the slider.",
123
+ "value": {
124
+ "kind": "expression"
125
+ }
126
+ },
127
+ {
128
+ "name": "@change",
129
+ "description": "Fired when the user commits a value change.",
130
+ "value": {
131
+ "kind": "expression"
132
+ }
133
+ },
134
+ {
135
+ "name": "@value-changed",
136
+ "description": "Fired when the `value` property changes.",
137
+ "value": {
138
+ "kind": "expression"
139
+ }
140
+ }
141
+ ]
142
+ }
143
+ ]
144
+ }
145
+ }
146
+ }