@rcarls/rc-slider 0.2.0 → 0.3.0
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/README.md +3 -2
- package/dist/custom-elements.json +31 -4
- package/dist/{rc-slider-DOhtdJxO.js → rc-slider-CPApkY9I.js} +37 -42
- package/dist/rc-slider-CPApkY9I.js.map +1 -0
- package/dist/rc-slider-define.js +1 -1
- package/dist/rc-slider.js +1 -1
- package/dist/types/packages/rc-slider/src/rc-slider.d.ts +7 -11
- package/package.json +7 -10
- package/dist/demo.css +0 -85
- package/dist/demo.js +0 -40
- package/dist/rc-slider-DOhtdJxO.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# @rcarls/rc-slider
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
Single-thumb slider backed by a native `<input type="range">` with custom track and value display hooks, following the [WAI-ARIA Slider pattern](https://www.w3.org/WAI/ARIA/apg/patterns/slider/).
|
|
4
|
+
|
|
5
|
+
Docs: [https://richardcarls.github.io/rc-webcomponents/components/rc-slider](https://richardcarls.github.io/rc-webcomponents/components/rc-slider).
|
|
5
6
|
|
|
6
7
|
## Styling Hooks
|
|
7
8
|
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"declarations": [
|
|
47
47
|
{
|
|
48
48
|
"kind": "class",
|
|
49
|
-
"description": "
|
|
49
|
+
"description": "Single-thumb slider backed by a native <input type=\"range\"> with custom track and value\ndisplay hooks, following the WAI-ARIA Slider pattern.\n\nLabel association:\n- Explicit `for`/`id`: `<label for=\"vol\">Volume</label><rc-slider><input id=\"vol\" …></rc-slider>`\n- Direct `aria-label` on the input: `<input aria-label=\"Volume\" …>`\n\nThese patterns all work without JavaScript. The component does not render a\nlabel element itself — the consumer is responsible for accessible naming.\n\nForm participation is handled natively by the consumer-provided input's `name`\nattribute; no `ElementInternals` setup is required.",
|
|
50
50
|
"name": "RCSlider",
|
|
51
51
|
"cssProperties": [
|
|
52
52
|
{
|
|
@@ -274,6 +274,13 @@
|
|
|
274
274
|
"privacy": "private",
|
|
275
275
|
"default": "null"
|
|
276
276
|
},
|
|
277
|
+
{
|
|
278
|
+
"kind": "field",
|
|
279
|
+
"name": "_nativeInputController",
|
|
280
|
+
"privacy": "private",
|
|
281
|
+
"readonly": true,
|
|
282
|
+
"default": "new NativeChildController<HTMLInputElement>(this, { selector: ':scope > input[type=\"range\"]', observe: true, onChange: (input, previous) => this._setupInput(input, previous), onMissing: () => { if (import.meta.env.DEV) { warnMissingDirectChild(this, { selector: ':scope > input[type=\"range\"]', message: '[rc-slider] Requires a child <input type=\"range\"> element.', }); } }, })"
|
|
283
|
+
},
|
|
277
284
|
{
|
|
278
285
|
"kind": "field",
|
|
279
286
|
"name": "_displayText",
|
|
@@ -294,14 +301,28 @@
|
|
|
294
301
|
},
|
|
295
302
|
{
|
|
296
303
|
"kind": "method",
|
|
297
|
-
"name": "
|
|
304
|
+
"name": "_setupInput",
|
|
298
305
|
"privacy": "private",
|
|
299
306
|
"return": {
|
|
300
307
|
"type": {
|
|
301
308
|
"text": "void"
|
|
302
309
|
}
|
|
303
310
|
},
|
|
304
|
-
"
|
|
311
|
+
"parameters": [
|
|
312
|
+
{
|
|
313
|
+
"name": "input",
|
|
314
|
+
"type": {
|
|
315
|
+
"text": "HTMLInputElement | null"
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
"name": "previous",
|
|
320
|
+
"optional": true,
|
|
321
|
+
"type": {
|
|
322
|
+
"text": "HTMLInputElement | null"
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
]
|
|
305
326
|
},
|
|
306
327
|
{
|
|
307
328
|
"kind": "field",
|
|
@@ -370,7 +391,13 @@
|
|
|
370
391
|
"type": {
|
|
371
392
|
"text": "void"
|
|
372
393
|
}
|
|
373
|
-
}
|
|
394
|
+
},
|
|
395
|
+
"parameters": [
|
|
396
|
+
{
|
|
397
|
+
"name": "input",
|
|
398
|
+
"default": "this._nativeInput"
|
|
399
|
+
}
|
|
400
|
+
]
|
|
374
401
|
},
|
|
375
402
|
{
|
|
376
403
|
"kind": "method",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { LitElement as f, css as m, nothing as o, html as h } from "lit";
|
|
2
|
-
import { property as
|
|
2
|
+
import { property as n } from "lit/decorators.js";
|
|
3
3
|
import { ifDefined as y } from "lit/directives/if-defined.js";
|
|
4
|
-
import { valueToPercent as v } from "@rcarls/rc-common";
|
|
5
|
-
var
|
|
6
|
-
for (var i =
|
|
7
|
-
(c = r[u]) && (i = (
|
|
8
|
-
return
|
|
4
|
+
import { NativeChildController as b, valueToPercent as v } from "@rcarls/rc-common";
|
|
5
|
+
var _ = Object.defineProperty, g = Object.getOwnPropertyDescriptor, l = (r, t, e, s) => {
|
|
6
|
+
for (var i = s > 1 ? void 0 : s ? g(t, e) : t, u = r.length - 1, c; u >= 0; u--)
|
|
7
|
+
(c = r[u]) && (i = (s ? c(t, e, i) : c(i)) || i);
|
|
8
|
+
return s && i && _(t, e, i), i;
|
|
9
9
|
};
|
|
10
|
-
const
|
|
10
|
+
const I = {
|
|
11
11
|
fromAttribute(r) {
|
|
12
12
|
return r === null ? null : r === "" || r === "float" ? "float" : r === "inline-start" ? "inline-start" : r === "inline-end" ? "inline-end" : null;
|
|
13
13
|
},
|
|
@@ -22,8 +22,14 @@ function d(r, t) {
|
|
|
22
22
|
}
|
|
23
23
|
const p = class p extends f {
|
|
24
24
|
constructor() {
|
|
25
|
-
super(...arguments), this.min = 0, this.max = 100, this.step = 1, this._valueInitialized = !1, this.disabled = !1, this.readonly = !1, this.display = null, this.valueText = "", this.orientation = "horizontal", this._nativeInput = null, this.
|
|
26
|
-
|
|
25
|
+
super(...arguments), this.min = 0, this.max = 100, this.step = 1, this._valueInitialized = !1, this.disabled = !1, this.readonly = !1, this.display = null, this.valueText = "", this.orientation = "horizontal", this._nativeInput = null, this._nativeInputController = new b(this, {
|
|
26
|
+
selector: ':scope > input[type="range"]',
|
|
27
|
+
observe: !0,
|
|
28
|
+
onChange: (t, e) => this._setupInput(t, e),
|
|
29
|
+
onMissing: () => {
|
|
30
|
+
}
|
|
31
|
+
}), this._onDefaultSlotChange = () => {
|
|
32
|
+
this._nativeInputController.sync(), this.requestUpdate();
|
|
27
33
|
}, this._onInput = (t) => {
|
|
28
34
|
this._handleRangeEvent(t, "rc-slider-input");
|
|
29
35
|
}, this._onChange = (t) => {
|
|
@@ -55,9 +61,6 @@ const p = class p extends f {
|
|
|
55
61
|
const e = this._defaultValue;
|
|
56
62
|
this._defaultValue = t, !this._valueInitialized && this._value === void 0 && t !== void 0 && (this._applyValueToInput(t), this.requestUpdate("value", void 0)), this.requestUpdate("defaultValue", e);
|
|
57
63
|
}
|
|
58
|
-
connectedCallback() {
|
|
59
|
-
this._findInput(), super.connectedCallback();
|
|
60
|
-
}
|
|
61
64
|
disconnectedCallback() {
|
|
62
65
|
this._unwireInput(), super.disconnectedCallback();
|
|
63
66
|
}
|
|
@@ -116,20 +119,12 @@ const p = class p extends f {
|
|
|
116
119
|
const t = this._nativeInput?.valueAsNumber;
|
|
117
120
|
return t === void 0 || isNaN(t) ? 0 : t;
|
|
118
121
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
* rather than replacing it.
|
|
123
|
-
*/
|
|
124
|
-
_findInput() {
|
|
125
|
-
const t = this.querySelector('input[type="range"]');
|
|
126
|
-
if (!t) {
|
|
127
|
-
console.warn(
|
|
128
|
-
'[rc-slider] Requires a child <input type="range"> element.'
|
|
129
|
-
);
|
|
122
|
+
_setupInput(t, e) {
|
|
123
|
+
if (e && e !== t && this._unwireInput(e), !t) {
|
|
124
|
+
this._nativeInput = null;
|
|
130
125
|
return;
|
|
131
126
|
}
|
|
132
|
-
!this.hasAttribute("disabled") && t.disabled && (this.disabled = !0), this._nativeInput = t, this._applyInitialValueToInput(t), this._wireInput(t);
|
|
127
|
+
!this.hasAttribute("disabled") && t.disabled && (this.disabled = !0), this._nativeInput = t, this._applyInitialValueToInput(t), this._wireInput(t), this.requestUpdate();
|
|
133
128
|
}
|
|
134
129
|
_applyInitialValueToInput(t) {
|
|
135
130
|
if (this._value !== void 0) {
|
|
@@ -149,19 +144,19 @@ const p = class p extends f {
|
|
|
149
144
|
_wireInput(t) {
|
|
150
145
|
t.addEventListener("input", this._onInput), t.addEventListener("change", this._onChange), t.addEventListener("keydown", this._onKeydown);
|
|
151
146
|
}
|
|
152
|
-
_unwireInput() {
|
|
153
|
-
|
|
147
|
+
_unwireInput(t = this._nativeInput) {
|
|
148
|
+
t?.removeEventListener("input", this._onInput), t?.removeEventListener("change", this._onChange), t?.removeEventListener("keydown", this._onKeydown);
|
|
154
149
|
}
|
|
155
150
|
_syncAriaAttributes(t) {
|
|
156
151
|
this.valueText ? t.setAttribute("aria-valuetext", this.valueText) : t.removeAttribute("aria-valuetext"), this.orientation === "vertical" ? t.setAttribute("aria-orientation", "vertical") : t.removeAttribute("aria-orientation"), this.readonly ? t.setAttribute("aria-readonly", "true") : t.removeAttribute("aria-readonly");
|
|
157
152
|
}
|
|
158
153
|
_handleRangeEvent(t, e) {
|
|
159
|
-
const
|
|
154
|
+
const s = t.currentTarget;
|
|
160
155
|
if (this.readonly) {
|
|
161
|
-
|
|
156
|
+
s.value = String(this.value);
|
|
162
157
|
return;
|
|
163
158
|
}
|
|
164
|
-
this._commitInputValue(
|
|
159
|
+
this._commitInputValue(s), this.dispatchEvent(
|
|
165
160
|
new CustomEvent(e, {
|
|
166
161
|
bubbles: !0,
|
|
167
162
|
composed: !0,
|
|
@@ -176,13 +171,13 @@ const p = class p extends f {
|
|
|
176
171
|
_progressStyle() {
|
|
177
172
|
const t = this._nativeInput;
|
|
178
173
|
if (!t) return "";
|
|
179
|
-
const e = d(t.min, 0),
|
|
174
|
+
const e = d(t.min, 0), s = d(t.max, 100), i = v(t.valueAsNumber, e, s) * 100;
|
|
180
175
|
return this.orientation === "vertical" ? `bottom:0%;height:${i.toFixed(3)}%` : `left:0%;width:${i.toFixed(3)}%`;
|
|
181
176
|
}
|
|
182
177
|
_floatStyle() {
|
|
183
178
|
const t = this._nativeInput;
|
|
184
179
|
if (!t) return "";
|
|
185
|
-
const e = d(t.min, 0),
|
|
180
|
+
const e = d(t.min, 0), s = d(t.max, 100), i = v(t.valueAsNumber, e, s), u = (1 - i * 2).toFixed(4);
|
|
186
181
|
return this.orientation === "vertical" ? `bottom:calc(${(i * 100).toFixed(3)}% + ${u} * var(--rc-thumb-radius, 9px))` : `left:calc(${(i * 100).toFixed(3)}% + ${u} * var(--rc-thumb-radius, 9px))`;
|
|
187
182
|
}
|
|
188
183
|
};
|
|
@@ -302,36 +297,36 @@ p.styles = m`
|
|
|
302
297
|
`;
|
|
303
298
|
let a = p;
|
|
304
299
|
l([
|
|
305
|
-
|
|
300
|
+
n({ type: Number })
|
|
306
301
|
], a.prototype, "min", 2);
|
|
307
302
|
l([
|
|
308
|
-
|
|
303
|
+
n({ type: Number })
|
|
309
304
|
], a.prototype, "max", 2);
|
|
310
305
|
l([
|
|
311
|
-
|
|
306
|
+
n({ type: Number })
|
|
312
307
|
], a.prototype, "step", 2);
|
|
313
308
|
l([
|
|
314
|
-
|
|
309
|
+
n({ type: Number })
|
|
315
310
|
], a.prototype, "value", 1);
|
|
316
311
|
l([
|
|
317
|
-
|
|
312
|
+
n({ type: Number, attribute: "default-value" })
|
|
318
313
|
], a.prototype, "defaultValue", 1);
|
|
319
314
|
l([
|
|
320
|
-
|
|
315
|
+
n({ type: Boolean, reflect: !0 })
|
|
321
316
|
], a.prototype, "disabled", 2);
|
|
322
317
|
l([
|
|
323
|
-
|
|
318
|
+
n({ type: Boolean, reflect: !0 })
|
|
324
319
|
], a.prototype, "readonly", 2);
|
|
325
320
|
l([
|
|
326
|
-
|
|
321
|
+
n({ reflect: !0, converter: I })
|
|
327
322
|
], a.prototype, "display", 2);
|
|
328
323
|
l([
|
|
329
|
-
|
|
324
|
+
n({ attribute: "value-text" })
|
|
330
325
|
], a.prototype, "valueText", 2);
|
|
331
326
|
l([
|
|
332
|
-
|
|
327
|
+
n({ reflect: !0 })
|
|
333
328
|
], a.prototype, "orientation", 2);
|
|
334
329
|
export {
|
|
335
330
|
a as R
|
|
336
331
|
};
|
|
337
|
-
//# sourceMappingURL=rc-slider-
|
|
332
|
+
//# sourceMappingURL=rc-slider-CPApkY9I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-slider-CPApkY9I.js","sources":["../src/rc-slider.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport type { ComplexAttributeConverter } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { NativeChildController, valueToPercent, warnMissingDirectChild } from \"@rcarls/rc-common\";\n\nexport interface RCSliderValueEvent {\n /** Current numeric slider value. */\n value: number;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"rc-slider\": RCSlider;\n }\n\n interface HTMLElementEventMap {\n \"rc-slider-input\": CustomEvent<RCSliderValueEvent>;\n \"rc-slider-change\": CustomEvent<RCSliderValueEvent>;\n }\n}\n\ntype DisplayValue = \"float\" | \"inline-start\" | \"inline-end\" | null;\n\n/**\n * Normalises the `display` attribute.\n * A bare boolean attribute (`display` with no value) maps to `'float'` so\n * the reflected attribute is always an explicit string, never an empty string.\n */\nconst displayConverter: ComplexAttributeConverter<DisplayValue> = {\n fromAttribute(v: string | null): DisplayValue {\n if (v === null) return null;\n if (v === \"\" || v === \"float\") return \"float\";\n if (v === \"inline-start\") return \"inline-start\";\n if (v === \"inline-end\") return \"inline-end\";\n return null;\n },\n toAttribute(v: DisplayValue): string | null {\n return v;\n },\n};\n\n/**\n * Returns the numeric value of a range input's `min`, `max`, or `step`\n * attribute string, falling back to `defaultVal` when the attribute is absent\n * (empty string) or not a valid number.\n */\nfunction parseAttr(s: string, defaultVal: number): number {\n if (s === \"\") return defaultVal;\n const n = parseFloat(s);\n return isNaN(n) ? defaultVal : n;\n}\n\n/**\n * Single-thumb slider backed by a native <input type=\"range\"> with custom track and value\n * display hooks, following the WAI-ARIA Slider pattern.\n *\n * Label association:\n * - Explicit `for`/`id`: `<label for=\"vol\">Volume</label><rc-slider><input id=\"vol\" …></rc-slider>`\n * - Direct `aria-label` on the input: `<input aria-label=\"Volume\" …>`\n *\n * These patterns all work without JavaScript. The component does not render a\n * label element itself — the consumer is responsible for accessible naming.\n *\n * Form participation is handled natively by the consumer-provided input's `name`\n * attribute; no `ElementInternals` setup is required.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-slider rc-slider docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/slider/ WAI-ARIA Slider pattern}\n *\n * @slot track-background - Optional decorative content rendered inside the track before the progress fill.\n * @slot value-display - Optional replacement for the rendered value text.\n *\n * @fires rc-slider-input - Fires continuously while the value changes. Detail: `{ value }`.\n * @fires rc-slider-change - Fires when the committed value changes (on release). Detail: `{ value }`.\n *\n * @cssprop [--rc-thumb-radius=9px] - Half the thumb width; used to position the float value display.\n * @cssprop [--rc-slider-gap=var(--rc-control-gap)] - Gap between track and inline value display.\n * @cssprop [--rc-slider-control-size=var(--rc-control-block-size)] - Track hit-area block size.\n * @cssprop [--rc-slider-track-size=0.1875rem] - Visual track thickness.\n * @cssprop [--rc-slider-track-background=CanvasText] - Unfilled track color.\n * @cssprop [--rc-slider-track-opacity=0.25] - Unfilled track opacity.\n * @cssprop [--rc-slider-track-radius=var(--rc-control-radius)] - Track border radius.\n * @cssprop [--rc-slider-progress-background=var(--rc-accent)] - Filled track color.\n * @cssprop [--rc-slider-value-color=var(--rc-text-disabled)] - Value display text color.\n * @cssprop [--rc-slider-float-value-block-offset=-1.4em] - Block-axis offset for horizontal float value display.\n * @cssprop [--rc-slider-float-value-inline-offset=calc(100% + 0.5rem)] - Inline-axis offset for vertical float value display.\n *\n * @csspart root - Root layout wrapper.\n * @csspart control - Track/input positioning wrapper.\n * @csspart track - Visual slider track.\n * @csspart progress - Filled progress segment.\n * @csspart value-display - Rendered value text.\n */\nexport class RCSlider extends LitElement {\n static override styles = css`\n :host {\n display: block;\n }\n\n .rc-slider-root {\n display: grid;\n gap: var(--rc-slider-gap, var(--rc-control-gap, 0.5rem));\n align-items: center;\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n line-height: var(--rc-line-height, normal);\n }\n\n .rc-slider-root[data-display=\"inline-start\"] {\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .rc-slider-root[data-display=\"inline-end\"] {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n .rc-slider-control {\n position: relative;\n display: block;\n min-width: 0;\n min-height: var(--rc-slider-control-size, var(--rc-control-block-size, 1.5rem));\n }\n\n .rc-slider-track,\n .rc-slider-progress {\n position: absolute;\n pointer-events: none;\n }\n\n .rc-slider-track {\n inset-inline: 0;\n inset-block: calc(50% - var(--rc-slider-track-size, 0.1875rem) / 2);\n block-size: var(--rc-slider-track-size, 0.1875rem);\n background: var(--rc-slider-track-background, CanvasText);\n opacity: var(--rc-slider-track-opacity, 0.25);\n border-radius: var(--rc-slider-track-radius, var(--rc-control-radius, 0));\n overflow: hidden;\n z-index: 0;\n }\n\n ::slotted([slot=\"track-background\"]) {\n position: absolute;\n inset: 0;\n pointer-events: none;\n }\n\n .rc-slider-progress {\n inset-block: 0;\n background: var(--rc-slider-progress-background, var(--rc-accent, Highlight));\n border-radius: inherit;\n z-index: 1;\n }\n\n ::slotted(input[type=\"range\"]) {\n position: absolute;\n inset: 0;\n inline-size: 100%;\n block-size: 100%;\n margin: 0;\n background: transparent;\n z-index: 2;\n }\n\n .rc-slider-value {\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n color: var(--rc-slider-value-color, var(--rc-text-disabled, GrayText));\n }\n\n .rc-slider-root[data-display=\"float\"] .rc-slider-value {\n position: absolute;\n inset-block-start: var(--rc-slider-float-value-block-offset, -1.4em);\n transform: translateX(-50%);\n pointer-events: none;\n z-index: 3;\n }\n\n :host([orientation=\"vertical\"]) {\n display: inline-block;\n }\n\n :host([orientation=\"vertical\"]) .rc-slider-control {\n inline-size: var(--rc-slider-control-size, var(--rc-control-block-size, 1.5rem));\n block-size: var(--rc-slider-vertical-size, 12.5rem);\n }\n\n :host([orientation=\"vertical\"]) .rc-slider-track {\n inset-block: 0;\n inset-inline: calc(50% - var(--rc-slider-track-size, 0.1875rem) / 2);\n inline-size: var(--rc-slider-track-size, 0.1875rem);\n block-size: auto;\n }\n\n :host([orientation=\"vertical\"]) .rc-slider-progress {\n inset-inline: 0;\n }\n\n :host([orientation=\"vertical\"]) ::slotted(input[type=\"range\"]) {\n writing-mode: vertical-lr;\n direction: rtl;\n }\n\n :host([orientation=\"vertical\"]) .rc-slider-root[data-display=\"float\"] .rc-slider-value {\n inset-block-start: auto;\n inset-inline-start: var(--rc-slider-float-value-inline-offset, calc(100% + 0.5rem));\n transform: translateY(50%);\n }\n `;\n\n /** Minimum slider value. */\n @property({ type: Number }) min = 0;\n\n /** Maximum slider value. */\n @property({ type: Number }) max = 100;\n\n /** Slider step. */\n @property({ type: Number }) step = 1;\n\n private _value: number | undefined;\n private _defaultValue: number | undefined;\n private _valueInitialized = false;\n\n /** Current slider value. */\n @property({ type: Number })\n get value(): number {\n return this._value ?? this._defaultValue ?? this._nativeInputValue;\n }\n set value(v: number) {\n const old = this._value;\n this._value = v;\n this._valueInitialized = true;\n this._applyValueToInput(v);\n this.requestUpdate(\"value\", old);\n }\n\n /** Initial uncontrolled slider value. Has no effect after the first user interaction or `value` write. */\n @property({ type: Number, attribute: \"default-value\" })\n get defaultValue(): number | undefined {\n return this._defaultValue;\n }\n set defaultValue(v: number | undefined) {\n const old = this._defaultValue;\n this._defaultValue = v;\n if (\n !this._valueInitialized &&\n this._value === undefined &&\n v !== undefined\n ) {\n this._applyValueToInput(v);\n this.requestUpdate(\"value\", undefined);\n }\n this.requestUpdate(\"defaultValue\", old);\n }\n\n /** Disable the underlying input. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Prevents edits while preserving normal display. Not a native range attribute. */\n @property({ type: Boolean, reflect: true }) readonly = false;\n\n /**\n * Controls the live value display.\n *\n * - Absent (default) — no value shown.\n * - `display` or `display=\"float\"` — floats above the thumb.\n * - `display=\"inline-start\"` — rendered before the track, inline in the grid.\n * - `display=\"inline-end\"` — rendered after the track, inline in the grid.\n */\n @property({ reflect: true, converter: displayConverter })\n display: DisplayValue = null;\n\n /** Screen-reader value text. When set, forwarded as `aria-valuetext` on the native input. */\n @property({ attribute: \"value-text\" }) valueText = \"\";\n\n /** Orientation; reflected as an attribute and forwarded to `aria-orientation`. */\n @property({ reflect: true }) orientation: \"horizontal\" | \"vertical\" =\n \"horizontal\";\n\n private _nativeInput: HTMLInputElement | null = null;\n\n private readonly _nativeInputController = new NativeChildController<HTMLInputElement>(this, {\n selector: ':scope > input[type=\"range\"]',\n observe: true,\n onChange: (input, previous) => this._setupInput(input, previous),\n onMissing: () => {\n if (import.meta.env.DEV) {\n warnMissingDirectChild(this, {\n selector: ':scope > input[type=\"range\"]',\n message: '[rc-slider] Requires a child <input type=\"range\"> element.',\n });\n }\n },\n });\n\n override disconnectedCallback(): void {\n this._unwireInput();\n super.disconnectedCallback();\n }\n\n override updated(): void {\n const input = this._nativeInput;\n if (!input) return;\n\n input.disabled = this.disabled;\n this._syncAriaAttributes(input);\n }\n\n override render() {\n const input = this._nativeInput;\n if (!input) return nothing;\n\n const valueDisplay = html`\n <span\n part=\"value-display\"\n class=\"rc-slider-value\"\n style=${ifDefined(\n this.display === \"float\" ? this._floatStyle() : undefined,\n )}\n aria-hidden=\"true\"\n >\n <slot name=\"value-display\">${this._displayText}</slot>\n </span>\n `;\n\n return html`\n <div\n part=\"root\"\n class=\"rc-slider-root\"\n data-display=${this.display ?? nothing}\n data-orientation=${this.orientation}\n data-readonly=${this.readonly ? \"\" : nothing}\n data-disabled=${this.disabled ? \"\" : nothing}\n data-has-value-text=${this.valueText ? \"\" : nothing}\n >\n ${this.display === \"inline-start\" ? valueDisplay : nothing}\n\n <span part=\"control\" class=\"rc-slider-control\">\n <span part=\"track\" class=\"rc-slider-track\" aria-hidden=\"true\">\n <slot name=\"track-background\"></slot>\n <span\n part=\"progress\"\n class=\"rc-slider-progress\"\n style=${this._progressStyle()}\n ></span>\n </span>\n\n <slot @slotchange=${this._onDefaultSlotChange}></slot>\n ${this.display === \"float\" ? valueDisplay : nothing}\n </span>\n\n ${this.display === \"inline-end\" ? valueDisplay : nothing}\n </div>\n `;\n }\n\n private get _displayText(): string {\n return this.valueText || String(this.value);\n }\n\n private get _nativeInputValue(): number {\n const value = this._nativeInput?.valueAsNumber;\n return value === undefined || isNaN(value) ? 0 : value;\n }\n\n private _setupInput(input: HTMLInputElement | null, previous?: HTMLInputElement | null): void {\n if (previous && previous !== input) {\n this._unwireInput(previous);\n }\n\n if (!input) {\n this._nativeInput = null;\n return;\n }\n\n // Mirror disabled state from the native input if not explicitly set on the host.\n // Pre-upgrade markup may carry <input disabled> before the component upgrades.\n if (!this.hasAttribute(\"disabled\") && input.disabled) {\n this.disabled = true;\n }\n\n this._nativeInput = input;\n this._applyInitialValueToInput(input);\n this._wireInput(input);\n this.requestUpdate();\n }\n\n private _onDefaultSlotChange = (): void => {\n this._nativeInputController.sync();\n this.requestUpdate();\n };\n\n private _applyInitialValueToInput(input: HTMLInputElement): void {\n if (this._value !== undefined) {\n this._applyValueToInput(this._value);\n return;\n }\n\n if (this._defaultValue !== undefined) {\n this._applyValueToInput(this._defaultValue);\n return;\n }\n\n const value = input.valueAsNumber;\n if (!isNaN(value)) {\n this._defaultValue = value;\n }\n }\n\n private _applyValueToInput(value: number): void {\n if (!this._nativeInput) return;\n\n this._nativeInput.value = String(value);\n }\n\n private _wireInput(input: HTMLInputElement): void {\n input.addEventListener(\"input\", this._onInput);\n input.addEventListener(\"change\", this._onChange);\n input.addEventListener(\"keydown\", this._onKeydown);\n }\n\n private _unwireInput(input = this._nativeInput): void {\n input?.removeEventListener(\"input\", this._onInput);\n input?.removeEventListener(\"change\", this._onChange);\n input?.removeEventListener(\"keydown\", this._onKeydown);\n }\n\n private _syncAriaAttributes(input: HTMLInputElement): void {\n if (this.valueText) {\n input.setAttribute(\"aria-valuetext\", this.valueText);\n } else {\n input.removeAttribute(\"aria-valuetext\");\n }\n\n if (this.orientation === \"vertical\") {\n input.setAttribute(\"aria-orientation\", \"vertical\");\n } else {\n input.removeAttribute(\"aria-orientation\");\n }\n\n if (this.readonly) {\n input.setAttribute(\"aria-readonly\", \"true\");\n } else {\n input.removeAttribute(\"aria-readonly\");\n }\n }\n\n private readonly _onInput = (e: Event): void => {\n this._handleRangeEvent(e, \"rc-slider-input\");\n };\n\n private readonly _onChange = (e: Event): void => {\n this._handleRangeEvent(e, \"rc-slider-change\");\n };\n\n private _handleRangeEvent(\n e: Event,\n type: \"rc-slider-input\" | \"rc-slider-change\",\n ): void {\n const input = e.currentTarget as HTMLInputElement;\n\n if (this.readonly) {\n input.value = String(this.value);\n return;\n }\n\n this._commitInputValue(input);\n\n this.dispatchEvent(\n new CustomEvent<RCSliderValueEvent>(type, {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n private readonly _onKeydown = (e: KeyboardEvent): void => {\n if (this.disabled || this.readonly) return;\n if (e.key !== \"PageUp\" && e.key !== \"PageDown\") return;\n\n e.preventDefault();\n const input = e.currentTarget as HTMLInputElement;\n\n if (e.key === \"PageUp\") input.stepUp(10);\n else input.stepDown(10);\n\n this._commitInputValue(input);\n\n this.dispatchEvent(\n new CustomEvent<RCSliderValueEvent>(\"rc-slider-input\", {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n };\n\n private _commitInputValue(input: HTMLInputElement): void {\n const old = this.value;\n\n this._value = input.valueAsNumber;\n this._valueInitialized = true;\n\n this.requestUpdate(\"value\", old);\n }\n\n private _progressStyle(): string {\n const input = this._nativeInput;\n if (!input) return \"\";\n\n const min = parseAttr(input.min, 0);\n const max = parseAttr(input.max, 100);\n const pct = valueToPercent(input.valueAsNumber, min, max) * 100;\n\n if (this.orientation === \"vertical\") {\n return `bottom:0%;height:${pct.toFixed(3)}%`;\n }\n\n return `left:0%;width:${pct.toFixed(3)}%`;\n }\n\n private _floatStyle(): string {\n const input = this._nativeInput;\n if (!input) return \"\";\n\n const min = parseAttr(input.min, 0);\n const max = parseAttr(input.max, 100);\n const pct = valueToPercent(input.valueAsNumber, min, max);\n const k = (1 - pct * 2).toFixed(4);\n\n if (this.orientation === \"vertical\") {\n return `bottom:calc(${(pct * 100).toFixed(3)}% + ${k} * var(--rc-thumb-radius, 9px))`;\n }\n\n return `left:calc(${(pct * 100).toFixed(3)}% + ${k} * var(--rc-thumb-radius, 9px))`;\n }\n}\n\nexport default RCSlider;\n"],"names":["displayConverter","v","parseAttr","s","defaultVal","n","_RCSlider","LitElement","NativeChildController","input","previous","e","old","nothing","valueDisplay","html","ifDefined","value","type","min","max","pct","valueToPercent","k","css","RCSlider","__decorateClass","property"],"mappings":"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"}
|
package/dist/rc-slider-define.js
CHANGED
package/dist/rc-slider.js
CHANGED
|
@@ -14,10 +14,8 @@ declare global {
|
|
|
14
14
|
}
|
|
15
15
|
type DisplayValue = "float" | "inline-start" | "inline-end" | null;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* adds a styled track, optional live value display, and the APG keyboard
|
|
20
|
-
* enhancement (Page Up/Down, ±10 steps).
|
|
17
|
+
* Single-thumb slider backed by a native <input type="range"> with custom track and value
|
|
18
|
+
* display hooks, following the WAI-ARIA Slider pattern.
|
|
21
19
|
*
|
|
22
20
|
* Label association:
|
|
23
21
|
* - Explicit `for`/`id`: `<label for="vol">Volume</label><rc-slider><input id="vol" …></rc-slider>`
|
|
@@ -29,6 +27,9 @@ type DisplayValue = "float" | "inline-start" | "inline-end" | null;
|
|
|
29
27
|
* Form participation is handled natively by the consumer-provided input's `name`
|
|
30
28
|
* attribute; no `ElementInternals` setup is required.
|
|
31
29
|
*
|
|
30
|
+
* @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-slider rc-slider docs}
|
|
31
|
+
* @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/slider/ WAI-ARIA Slider pattern}
|
|
32
|
+
*
|
|
32
33
|
* @slot track-background - Optional decorative content rendered inside the track before the progress fill.
|
|
33
34
|
* @slot value-display - Optional replacement for the rendered value text.
|
|
34
35
|
*
|
|
@@ -88,18 +89,13 @@ export declare class RCSlider extends LitElement {
|
|
|
88
89
|
/** Orientation; reflected as an attribute and forwarded to `aria-orientation`. */
|
|
89
90
|
orientation: "horizontal" | "vertical";
|
|
90
91
|
private _nativeInput;
|
|
91
|
-
|
|
92
|
+
private readonly _nativeInputController;
|
|
92
93
|
disconnectedCallback(): void;
|
|
93
94
|
updated(): void;
|
|
94
95
|
render(): typeof nothing | import('lit').TemplateResult<1>;
|
|
95
96
|
private get _displayText();
|
|
96
97
|
private get _nativeInputValue();
|
|
97
|
-
|
|
98
|
-
* Finds the consumer-provided native input and wires event listeners.
|
|
99
|
-
* The input remains in the DOM permanently; the component enhances it
|
|
100
|
-
* rather than replacing it.
|
|
101
|
-
*/
|
|
102
|
-
private _findInput;
|
|
98
|
+
private _setupInput;
|
|
103
99
|
private _onDefaultSlotChange;
|
|
104
100
|
private _applyInitialValueToInput;
|
|
105
101
|
private _applyValueToInput;
|
package/package.json
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
7
|
-
"description": "
|
|
6
|
+
"version": "0.3.0",
|
|
7
|
+
"description": "Single-thumb slider backed by a native <input type=\"range\"> with custom track and value display hooks.",
|
|
8
8
|
"repository": {
|
|
9
9
|
"type": "git",
|
|
10
10
|
"url": "git+https://github.com/richardcarls/rc-webcomponents.git",
|
|
11
11
|
"directory": "packages/rc-slider"
|
|
12
12
|
},
|
|
13
|
-
"homepage": "https://github.
|
|
13
|
+
"homepage": "https://richardcarls.github.io/rc-webcomponents/components/rc-slider",
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"type": "module",
|
|
16
16
|
"files": [
|
|
@@ -37,18 +37,15 @@
|
|
|
37
37
|
],
|
|
38
38
|
"customElements": "dist/custom-elements.json",
|
|
39
39
|
"scripts": {
|
|
40
|
-
"dev": "vite",
|
|
41
40
|
"build": "tsc && vite build && cem analyze",
|
|
42
41
|
"cem:analyze": "cem analyze",
|
|
43
42
|
"preview": "vite preview",
|
|
44
|
-
"test:browser": "vitest",
|
|
45
|
-
"test:browser:chrome": "vitest --project=chromium",
|
|
46
|
-
"test:browser:firefox": "vitest --project=firefox"
|
|
47
|
-
"yalc:publish": "yalc publish --push"
|
|
43
|
+
"test:browser": "vitest --run",
|
|
44
|
+
"test:browser:chrome": "vitest --run --project=chromium",
|
|
45
|
+
"test:browser:firefox": "vitest --run --project=firefox"
|
|
48
46
|
},
|
|
49
47
|
"devDependencies": {
|
|
50
48
|
"@custom-elements-manifest/analyzer": "0.11.0",
|
|
51
|
-
"@guanghechen/rollup-plugin-copy": "^6.0.9",
|
|
52
49
|
"@vitest/browser-playwright": "4.1.5",
|
|
53
50
|
"lit": "^3.0.0",
|
|
54
51
|
"playwright": "^1.56.0",
|
|
@@ -60,7 +57,7 @@
|
|
|
60
57
|
"vitest-browser-lit": "^1.0.1"
|
|
61
58
|
},
|
|
62
59
|
"dependencies": {
|
|
63
|
-
"@rcarls/rc-common": "workspace
|
|
60
|
+
"@rcarls/rc-common": "workspace:*"
|
|
64
61
|
},
|
|
65
62
|
"peerDependencies": {
|
|
66
63
|
"lit": "^3.0.0"
|
package/dist/demo.css
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
*, *::before, *::after {
|
|
2
|
-
box-sizing: border-box;
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
:root {
|
|
6
|
-
color-scheme: light dark;
|
|
7
|
-
--rc-accent: Highlight; /* Chrome doesn't support AccentColor on the open web */
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
@supports (color: AccentColor) {
|
|
11
|
-
:root {
|
|
12
|
-
--rc-accent: AccentColor;
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
[data-theme="light"] { color-scheme: light; }
|
|
17
|
-
[data-theme="dark"] { color-scheme: dark; }
|
|
18
|
-
|
|
19
|
-
[data-theme="solarized-light"] {
|
|
20
|
-
color-scheme: light;
|
|
21
|
-
--rc-surface: #fdf6e3;
|
|
22
|
-
--rc-text: #657b83;
|
|
23
|
-
--rc-border: 1px solid #93a1a1;
|
|
24
|
-
--rc-shadow: 0 2px 8px rgba(0, 0, 0, .12);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
[data-theme="solarized-dark"] {
|
|
28
|
-
color-scheme: dark;
|
|
29
|
-
--rc-surface: #002b36;
|
|
30
|
-
--rc-text: #839496;
|
|
31
|
-
--rc-border: 1px solid #586e75;
|
|
32
|
-
--rc-shadow: 0 2px 8px rgba(0, 0, 0, .3);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
body {
|
|
36
|
-
font-family: system-ui, sans-serif;
|
|
37
|
-
margin: 0;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.demo-page {
|
|
41
|
-
max-width: 60rem;
|
|
42
|
-
margin: 0 auto;
|
|
43
|
-
padding: 2rem 1.5rem;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.demo-controls {
|
|
47
|
-
display: flex;
|
|
48
|
-
align-items: center;
|
|
49
|
-
gap: 1rem;
|
|
50
|
-
margin-bottom: 2rem;
|
|
51
|
-
padding-bottom: 1rem;
|
|
52
|
-
border-bottom: 1px solid ButtonBorder;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.demo-controls .demo-title {
|
|
56
|
-
flex: 1;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.demo-controls h1 {
|
|
60
|
-
margin: 0 0 0.15rem;
|
|
61
|
-
font-size: 1.5rem;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
.demo-controls a {
|
|
65
|
-
font-size: 0.8rem;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.demo-section {
|
|
69
|
-
margin-bottom: 2rem;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
.demo-section h2 {
|
|
73
|
-
margin: 0 0 0.5rem;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
.theme-picker {
|
|
77
|
-
padding: 0.35em 0.75em;
|
|
78
|
-
font-family: inherit;
|
|
79
|
-
font-size: 0.8rem;
|
|
80
|
-
cursor: pointer;
|
|
81
|
-
border: 1px solid ButtonBorder;
|
|
82
|
-
border-radius: 4px;
|
|
83
|
-
background: Canvas;
|
|
84
|
-
color: CanvasText;
|
|
85
|
-
}
|
package/dist/demo.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
const THEMES = ['', 'light', 'dark', 'solarized-light', 'solarized-dark'];
|
|
2
|
-
const LABELS = ['Auto', 'Light', 'Dark', 'Solarized ☀', 'Solarized ☾'];
|
|
3
|
-
|
|
4
|
-
const stored = localStorage.getItem('rc-demo-theme') ?? '';
|
|
5
|
-
applyTheme(stored);
|
|
6
|
-
|
|
7
|
-
function applyTheme(theme) {
|
|
8
|
-
if (theme) {
|
|
9
|
-
document.documentElement.dataset.theme = theme;
|
|
10
|
-
} else {
|
|
11
|
-
delete document.documentElement.dataset.theme;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function currentIndex() {
|
|
16
|
-
const current = document.documentElement.dataset.theme ?? '';
|
|
17
|
-
const idx = THEMES.indexOf(current);
|
|
18
|
-
return idx === -1 ? 0 : idx;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function updateButtons() {
|
|
22
|
-
const label = LABELS[currentIndex()];
|
|
23
|
-
document.querySelectorAll('.theme-picker').forEach((btn) => {
|
|
24
|
-
btn.textContent = label;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
window.cycleTheme = function () {
|
|
29
|
-
const next = THEMES[(currentIndex() + 1) % THEMES.length];
|
|
30
|
-
applyTheme(next);
|
|
31
|
-
localStorage.setItem('rc-demo-theme', next);
|
|
32
|
-
updateButtons();
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
document.addEventListener('DOMContentLoaded', () => {
|
|
36
|
-
updateButtons();
|
|
37
|
-
document.querySelectorAll('.theme-picker').forEach((btn) => {
|
|
38
|
-
btn.addEventListener('click', window.cycleTheme);
|
|
39
|
-
});
|
|
40
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"rc-slider-DOhtdJxO.js","sources":["../src/rc-slider.ts"],"sourcesContent":["import { LitElement, css, html, nothing } from \"lit\";\nimport type { ComplexAttributeConverter } from \"lit\";\nimport { property } from \"lit/decorators.js\";\nimport { ifDefined } from \"lit/directives/if-defined.js\";\nimport { valueToPercent } from \"@rcarls/rc-common\";\n\nexport interface RCSliderValueEvent {\n /** Current numeric slider value. */\n value: number;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n \"rc-slider\": RCSlider;\n }\n\n interface HTMLElementEventMap {\n \"rc-slider-input\": CustomEvent<RCSliderValueEvent>;\n \"rc-slider-change\": CustomEvent<RCSliderValueEvent>;\n }\n}\n\ntype DisplayValue = \"float\" | \"inline-start\" | \"inline-end\" | null;\n\n/**\n * Normalises the `display` attribute.\n * A bare boolean attribute (`display` with no value) maps to `'float'` so\n * the reflected attribute is always an explicit string, never an empty string.\n */\nconst displayConverter: ComplexAttributeConverter<DisplayValue> = {\n fromAttribute(v: string | null): DisplayValue {\n if (v === null) return null;\n if (v === \"\" || v === \"float\") return \"float\";\n if (v === \"inline-start\") return \"inline-start\";\n if (v === \"inline-end\") return \"inline-end\";\n return null;\n },\n toAttribute(v: DisplayValue): string | null {\n return v;\n },\n};\n\n/**\n * Returns the numeric value of a range input's `min`, `max`, or `step`\n * attribute string, falling back to `defaultVal` when the attribute is absent\n * (empty string) or not a valid number.\n */\nfunction parseAttr(s: string, defaultVal: number): number {\n if (s === \"\") return defaultVal;\n const n = parseFloat(s);\n return isNaN(n) ? defaultVal : n;\n}\n\n/**\n * Progressive enhancement wrapper for a consumer-provided `<input type=\"range\">`.\n * The native input must be supplied as a direct child element — the component\n * adds a styled track, optional live value display, and the APG keyboard\n * enhancement (Page Up/Down, ±10 steps).\n *\n * Label association:\n * - Explicit `for`/`id`: `<label for=\"vol\">Volume</label><rc-slider><input id=\"vol\" …></rc-slider>`\n * - Direct `aria-label` on the input: `<input aria-label=\"Volume\" …>`\n *\n * These patterns all work without JavaScript. The component does not render a\n * label element itself — the consumer is responsible for accessible naming.\n *\n * Form participation is handled natively by the consumer-provided input's `name`\n * attribute; no `ElementInternals` setup is required.\n *\n * @slot track-background - Optional decorative content rendered inside the track before the progress fill.\n * @slot value-display - Optional replacement for the rendered value text.\n *\n * @fires rc-slider-input - Fires continuously while the value changes. Detail: `{ value }`.\n * @fires rc-slider-change - Fires when the committed value changes (on release). Detail: `{ value }`.\n *\n * @cssprop [--rc-thumb-radius=9px] - Half the thumb width; used to position the float value display.\n * @cssprop [--rc-slider-gap=var(--rc-control-gap)] - Gap between track and inline value display.\n * @cssprop [--rc-slider-control-size=var(--rc-control-block-size)] - Track hit-area block size.\n * @cssprop [--rc-slider-track-size=0.1875rem] - Visual track thickness.\n * @cssprop [--rc-slider-track-background=CanvasText] - Unfilled track color.\n * @cssprop [--rc-slider-track-opacity=0.25] - Unfilled track opacity.\n * @cssprop [--rc-slider-track-radius=var(--rc-control-radius)] - Track border radius.\n * @cssprop [--rc-slider-progress-background=var(--rc-accent)] - Filled track color.\n * @cssprop [--rc-slider-value-color=var(--rc-text-disabled)] - Value display text color.\n * @cssprop [--rc-slider-float-value-block-offset=-1.4em] - Block-axis offset for horizontal float value display.\n * @cssprop [--rc-slider-float-value-inline-offset=calc(100% + 0.5rem)] - Inline-axis offset for vertical float value display.\n *\n * @csspart root - Root layout wrapper.\n * @csspart control - Track/input positioning wrapper.\n * @csspart track - Visual slider track.\n * @csspart progress - Filled progress segment.\n * @csspart value-display - Rendered value text.\n */\nexport class RCSlider extends LitElement {\n static override styles = css`\n :host {\n display: block;\n }\n\n .rc-slider-root {\n display: grid;\n gap: var(--rc-slider-gap, var(--rc-control-gap, 0.5rem));\n align-items: center;\n font-family: var(--rc-font-family, inherit);\n font-size: var(--rc-font-size, inherit);\n line-height: var(--rc-line-height, normal);\n }\n\n .rc-slider-root[data-display=\"inline-start\"] {\n grid-template-columns: auto minmax(0, 1fr);\n }\n\n .rc-slider-root[data-display=\"inline-end\"] {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n .rc-slider-control {\n position: relative;\n display: block;\n min-width: 0;\n min-height: var(--rc-slider-control-size, var(--rc-control-block-size, 1.5rem));\n }\n\n .rc-slider-track,\n .rc-slider-progress {\n position: absolute;\n pointer-events: none;\n }\n\n .rc-slider-track {\n inset-inline: 0;\n inset-block: calc(50% - var(--rc-slider-track-size, 0.1875rem) / 2);\n block-size: var(--rc-slider-track-size, 0.1875rem);\n background: var(--rc-slider-track-background, CanvasText);\n opacity: var(--rc-slider-track-opacity, 0.25);\n border-radius: var(--rc-slider-track-radius, var(--rc-control-radius, 0));\n overflow: hidden;\n z-index: 0;\n }\n\n ::slotted([slot=\"track-background\"]) {\n position: absolute;\n inset: 0;\n pointer-events: none;\n }\n\n .rc-slider-progress {\n inset-block: 0;\n background: var(--rc-slider-progress-background, var(--rc-accent, Highlight));\n border-radius: inherit;\n z-index: 1;\n }\n\n ::slotted(input[type=\"range\"]) {\n position: absolute;\n inset: 0;\n inline-size: 100%;\n block-size: 100%;\n margin: 0;\n background: transparent;\n z-index: 2;\n }\n\n .rc-slider-value {\n font-variant-numeric: tabular-nums;\n white-space: nowrap;\n color: var(--rc-slider-value-color, var(--rc-text-disabled, GrayText));\n }\n\n .rc-slider-root[data-display=\"float\"] .rc-slider-value {\n position: absolute;\n inset-block-start: var(--rc-slider-float-value-block-offset, -1.4em);\n transform: translateX(-50%);\n pointer-events: none;\n z-index: 3;\n }\n\n :host([orientation=\"vertical\"]) {\n display: inline-block;\n }\n\n :host([orientation=\"vertical\"]) .rc-slider-control {\n inline-size: var(--rc-slider-control-size, var(--rc-control-block-size, 1.5rem));\n block-size: var(--rc-slider-vertical-size, 12.5rem);\n }\n\n :host([orientation=\"vertical\"]) .rc-slider-track {\n inset-block: 0;\n inset-inline: calc(50% - var(--rc-slider-track-size, 0.1875rem) / 2);\n inline-size: var(--rc-slider-track-size, 0.1875rem);\n block-size: auto;\n }\n\n :host([orientation=\"vertical\"]) .rc-slider-progress {\n inset-inline: 0;\n }\n\n :host([orientation=\"vertical\"]) ::slotted(input[type=\"range\"]) {\n writing-mode: vertical-lr;\n direction: rtl;\n }\n\n :host([orientation=\"vertical\"]) .rc-slider-root[data-display=\"float\"] .rc-slider-value {\n inset-block-start: auto;\n inset-inline-start: var(--rc-slider-float-value-inline-offset, calc(100% + 0.5rem));\n transform: translateY(50%);\n }\n `;\n\n /** Minimum slider value. */\n @property({ type: Number }) min = 0;\n\n /** Maximum slider value. */\n @property({ type: Number }) max = 100;\n\n /** Slider step. */\n @property({ type: Number }) step = 1;\n\n private _value: number | undefined;\n private _defaultValue: number | undefined;\n private _valueInitialized = false;\n\n /** Current slider value. */\n @property({ type: Number })\n get value(): number {\n return this._value ?? this._defaultValue ?? this._nativeInputValue;\n }\n set value(v: number) {\n const old = this._value;\n this._value = v;\n this._valueInitialized = true;\n this._applyValueToInput(v);\n this.requestUpdate(\"value\", old);\n }\n\n /** Initial uncontrolled slider value. Has no effect after the first user interaction or `value` write. */\n @property({ type: Number, attribute: \"default-value\" })\n get defaultValue(): number | undefined {\n return this._defaultValue;\n }\n set defaultValue(v: number | undefined) {\n const old = this._defaultValue;\n this._defaultValue = v;\n if (\n !this._valueInitialized &&\n this._value === undefined &&\n v !== undefined\n ) {\n this._applyValueToInput(v);\n this.requestUpdate(\"value\", undefined);\n }\n this.requestUpdate(\"defaultValue\", old);\n }\n\n /** Disable the underlying input. */\n @property({ type: Boolean, reflect: true }) disabled = false;\n\n /** Prevents edits while preserving normal display. Not a native range attribute. */\n @property({ type: Boolean, reflect: true }) readonly = false;\n\n /**\n * Controls the live value display.\n *\n * - Absent (default) — no value shown.\n * - `display` or `display=\"float\"` — floats above the thumb.\n * - `display=\"inline-start\"` — rendered before the track, inline in the grid.\n * - `display=\"inline-end\"` — rendered after the track, inline in the grid.\n */\n @property({ reflect: true, converter: displayConverter })\n display: DisplayValue = null;\n\n /** Screen-reader value text. When set, forwarded as `aria-valuetext` on the native input. */\n @property({ attribute: \"value-text\" }) valueText = \"\";\n\n /** Orientation; reflected as an attribute and forwarded to `aria-orientation`. */\n @property({ reflect: true }) orientation: \"horizontal\" | \"vertical\" =\n \"horizontal\";\n\n private _nativeInput: HTMLInputElement | null = null;\n\n override connectedCallback(): void {\n this._findInput();\n super.connectedCallback();\n }\n\n override disconnectedCallback(): void {\n this._unwireInput();\n super.disconnectedCallback();\n }\n\n override updated(): void {\n const input = this._nativeInput;\n if (!input) return;\n\n input.disabled = this.disabled;\n this._syncAriaAttributes(input);\n }\n\n override render() {\n const input = this._nativeInput;\n if (!input) return nothing;\n\n const valueDisplay = html`\n <span\n part=\"value-display\"\n class=\"rc-slider-value\"\n style=${ifDefined(\n this.display === \"float\" ? this._floatStyle() : undefined,\n )}\n aria-hidden=\"true\"\n >\n <slot name=\"value-display\">${this._displayText}</slot>\n </span>\n `;\n\n return html`\n <div\n part=\"root\"\n class=\"rc-slider-root\"\n data-display=${this.display ?? nothing}\n data-orientation=${this.orientation}\n data-readonly=${this.readonly ? \"\" : nothing}\n data-disabled=${this.disabled ? \"\" : nothing}\n data-has-value-text=${this.valueText ? \"\" : nothing}\n >\n ${this.display === \"inline-start\" ? valueDisplay : nothing}\n\n <span part=\"control\" class=\"rc-slider-control\">\n <span part=\"track\" class=\"rc-slider-track\" aria-hidden=\"true\">\n <slot name=\"track-background\"></slot>\n <span\n part=\"progress\"\n class=\"rc-slider-progress\"\n style=${this._progressStyle()}\n ></span>\n </span>\n\n <slot @slotchange=${this._onDefaultSlotChange}></slot>\n ${this.display === \"float\" ? valueDisplay : nothing}\n </span>\n\n ${this.display === \"inline-end\" ? valueDisplay : nothing}\n </div>\n `;\n }\n\n private get _displayText(): string {\n return this.valueText || String(this.value);\n }\n\n private get _nativeInputValue(): number {\n const value = this._nativeInput?.valueAsNumber;\n return value === undefined || isNaN(value) ? 0 : value;\n }\n\n /**\n * Finds the consumer-provided native input and wires event listeners.\n * The input remains in the DOM permanently; the component enhances it\n * rather than replacing it.\n */\n private _findInput(): void {\n const input = this.querySelector<HTMLInputElement>('input[type=\"range\"]');\n if (!input) {\n console.warn(\n '[rc-slider] Requires a child <input type=\"range\"> element.',\n );\n return;\n }\n\n // Mirror disabled state from the native input if not explicitly set on the host.\n // Pre-upgrade markup may carry <input disabled> before the component upgrades.\n if (!this.hasAttribute(\"disabled\") && input.disabled) {\n this.disabled = true;\n }\n\n this._nativeInput = input;\n this._applyInitialValueToInput(input);\n this._wireInput(input);\n }\n\n private _onDefaultSlotChange = (): void => {\n this._unwireInput();\n this._findInput();\n this.requestUpdate();\n };\n\n private _applyInitialValueToInput(input: HTMLInputElement): void {\n if (this._value !== undefined) {\n this._applyValueToInput(this._value);\n return;\n }\n\n if (this._defaultValue !== undefined) {\n this._applyValueToInput(this._defaultValue);\n return;\n }\n\n const value = input.valueAsNumber;\n if (!isNaN(value)) {\n this._defaultValue = value;\n }\n }\n\n private _applyValueToInput(value: number): void {\n if (!this._nativeInput) return;\n\n this._nativeInput.value = String(value);\n }\n\n private _wireInput(input: HTMLInputElement): void {\n input.addEventListener(\"input\", this._onInput);\n input.addEventListener(\"change\", this._onChange);\n input.addEventListener(\"keydown\", this._onKeydown);\n }\n\n private _unwireInput(): void {\n this._nativeInput?.removeEventListener(\"input\", this._onInput);\n this._nativeInput?.removeEventListener(\"change\", this._onChange);\n this._nativeInput?.removeEventListener(\"keydown\", this._onKeydown);\n }\n\n private _syncAriaAttributes(input: HTMLInputElement): void {\n if (this.valueText) {\n input.setAttribute(\"aria-valuetext\", this.valueText);\n } else {\n input.removeAttribute(\"aria-valuetext\");\n }\n\n if (this.orientation === \"vertical\") {\n input.setAttribute(\"aria-orientation\", \"vertical\");\n } else {\n input.removeAttribute(\"aria-orientation\");\n }\n\n if (this.readonly) {\n input.setAttribute(\"aria-readonly\", \"true\");\n } else {\n input.removeAttribute(\"aria-readonly\");\n }\n }\n\n private readonly _onInput = (e: Event): void => {\n this._handleRangeEvent(e, \"rc-slider-input\");\n };\n\n private readonly _onChange = (e: Event): void => {\n this._handleRangeEvent(e, \"rc-slider-change\");\n };\n\n private _handleRangeEvent(\n e: Event,\n type: \"rc-slider-input\" | \"rc-slider-change\",\n ): void {\n const input = e.currentTarget as HTMLInputElement;\n\n if (this.readonly) {\n input.value = String(this.value);\n return;\n }\n\n this._commitInputValue(input);\n\n this.dispatchEvent(\n new CustomEvent<RCSliderValueEvent>(type, {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n }\n\n private readonly _onKeydown = (e: KeyboardEvent): void => {\n if (this.disabled || this.readonly) return;\n if (e.key !== \"PageUp\" && e.key !== \"PageDown\") return;\n\n e.preventDefault();\n const input = e.currentTarget as HTMLInputElement;\n\n if (e.key === \"PageUp\") input.stepUp(10);\n else input.stepDown(10);\n\n this._commitInputValue(input);\n\n this.dispatchEvent(\n new CustomEvent<RCSliderValueEvent>(\"rc-slider-input\", {\n bubbles: true,\n composed: true,\n detail: { value: this.value },\n }),\n );\n };\n\n private _commitInputValue(input: HTMLInputElement): void {\n const old = this.value;\n\n this._value = input.valueAsNumber;\n this._valueInitialized = true;\n\n this.requestUpdate(\"value\", old);\n }\n\n private _progressStyle(): string {\n const input = this._nativeInput;\n if (!input) return \"\";\n\n const min = parseAttr(input.min, 0);\n const max = parseAttr(input.max, 100);\n const pct = valueToPercent(input.valueAsNumber, min, max) * 100;\n\n if (this.orientation === \"vertical\") {\n return `bottom:0%;height:${pct.toFixed(3)}%`;\n }\n\n return `left:0%;width:${pct.toFixed(3)}%`;\n }\n\n private _floatStyle(): string {\n const input = this._nativeInput;\n if (!input) return \"\";\n\n const min = parseAttr(input.min, 0);\n const max = parseAttr(input.max, 100);\n const pct = valueToPercent(input.valueAsNumber, min, max);\n const k = (1 - pct * 2).toFixed(4);\n\n if (this.orientation === \"vertical\") {\n return `bottom:calc(${(pct * 100).toFixed(3)}% + ${k} * var(--rc-thumb-radius, 9px))`;\n }\n\n return `left:calc(${(pct * 100).toFixed(3)}% + ${k} * var(--rc-thumb-radius, 9px))`;\n }\n}\n\nexport default RCSlider;\n"],"names":["displayConverter","v","parseAttr","s","defaultVal","n","_RCSlider","LitElement","e","input","old","nothing","valueDisplay","html","ifDefined","value","type","min","max","pct","valueToPercent","k","css","RCSlider","__decorateClass","property"],"mappings":"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"}
|