@fab1o978/react-ui 0.1.5 → 0.1.7

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,268 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+
6
+ // src/components/SliderControl/SliderControl.tsx
7
+
8
+ // src/components/SliderControl/SliderControl.module.scss
9
+ var SliderControl_module_default = {
10
+ wrapper: "SliderControl_module_wrapper3",
11
+ disabled: "SliderControl_module_disabled3",
12
+ icon: "SliderControl_module_icon3",
13
+ trackArea: "SliderControl_module_trackArea3",
14
+ groove: "SliderControl_module_groove3",
15
+ rail: "SliderControl_module_rail3",
16
+ fill: "SliderControl_module_fill3",
17
+ thumb: "SliderControl_module_thumb3",
18
+ thumbDragging: "SliderControl_module_thumbDragging3",
19
+ tooltip: "SliderControl_module_tooltip3",
20
+ tooltipVisible: "SliderControl_module_tooltipVisible3"
21
+ };
22
+
23
+ // src/utils/color.ts
24
+ function hexToHsl(hex) {
25
+ const r = parseInt(hex.slice(1, 3), 16) / 255;
26
+ const g = parseInt(hex.slice(3, 5), 16) / 255;
27
+ const b = parseInt(hex.slice(5, 7), 16) / 255;
28
+ const max = Math.max(r, g, b);
29
+ const min = Math.min(r, g, b);
30
+ const l = (max + min) / 2;
31
+ let h = 0;
32
+ let s = 0;
33
+ if (max !== min) {
34
+ const d = max - min;
35
+ s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
36
+ switch (max) {
37
+ case r:
38
+ h = ((g - b) / d + (g < b ? 6 : 0)) / 6;
39
+ break;
40
+ case g:
41
+ h = ((b - r) / d + 2) / 6;
42
+ break;
43
+ case b:
44
+ h = ((r - g) / d + 4) / 6;
45
+ break;
46
+ }
47
+ }
48
+ return [h * 360, s * 100, l * 100];
49
+ }
50
+ function hslToHex(h, s, l) {
51
+ const sl = s / 100;
52
+ const ll = l / 100;
53
+ const a = sl * Math.min(ll, 1 - ll);
54
+ const f = (n) => {
55
+ const k = (n + h / 30) % 12;
56
+ const color = ll - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
57
+ return Math.round(255 * color).toString(16).padStart(2, "0");
58
+ };
59
+ return `#${f(0)}${f(8)}${f(4)}`;
60
+ }
61
+ function hslToRgb(h, s, l) {
62
+ const sl = s / 100;
63
+ const ll = l / 100;
64
+ const a = sl * Math.min(ll, 1 - ll);
65
+ const f = (n) => {
66
+ const k = (n + h / 30) % 12;
67
+ return Math.round(255 * (ll - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)));
68
+ };
69
+ return { r: f(0), g: f(8), b: f(4) };
70
+ }
71
+ function hslToRgba(h, s, l, alpha) {
72
+ const { r, g, b } = hslToRgb(h, s, l);
73
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
74
+ }
75
+ function deriveAccent(hex) {
76
+ const [h, s, l] = hexToHsl(hex);
77
+ return {
78
+ base: hex,
79
+ dot: hslToHex(h, s, Math.min(l + 12, 95)),
80
+ track: hex,
81
+ ring: hex,
82
+ glow: hslToRgba(h, s, l, 0.3),
83
+ light: hslToHex(h, Math.max(s - 20, 0), Math.min(l + 45, 96))
84
+ };
85
+ }
86
+ function accentToCssVars(tokens, prefix) {
87
+ return {
88
+ [`--${prefix}-accent`]: tokens.base,
89
+ [`--${prefix}-accent-dot`]: tokens.dot,
90
+ [`--${prefix}-accent-track`]: tokens.track,
91
+ [`--${prefix}-accent-ring`]: tokens.ring,
92
+ [`--${prefix}-accent-glow`]: tokens.glow,
93
+ [`--${prefix}-accent-light`]: tokens.light
94
+ };
95
+ }
96
+ function clamp(v, min, max) {
97
+ return Math.min(Math.max(v, min), max);
98
+ }
99
+ function snapToStep(v, min, step) {
100
+ return Math.round((v - min) / step) * step + min;
101
+ }
102
+ var SliderControl = ({
103
+ value: controlledValue,
104
+ defaultValue = 50,
105
+ min = 0,
106
+ max = 100,
107
+ step = 1,
108
+ onChange,
109
+ showTooltip = "drag",
110
+ leftIcon,
111
+ rightIcon,
112
+ railBackground,
113
+ accent,
114
+ className,
115
+ disabled = false
116
+ }) => {
117
+ const isControlled = controlledValue !== void 0;
118
+ const [internalValue, setInternalValue] = react.useState(defaultValue);
119
+ const [isDragging, setIsDragging] = react.useState(false);
120
+ const [isFocused, setIsFocused] = react.useState(false);
121
+ const trackRef = react.useRef(null);
122
+ const thumbRef = react.useRef(null);
123
+ const value = isControlled ? controlledValue : internalValue;
124
+ const pct = (clamp(value, min, max) - min) / (max - min);
125
+ const accentVars = accent ? accentToCssVars(deriveAccent(accent), "slider") : {};
126
+ const setValue = react.useCallback(
127
+ (next) => {
128
+ const snapped = clamp(snapToStep(next, min, step), min, max);
129
+ if (!isControlled) setInternalValue(snapped);
130
+ onChange?.(snapped);
131
+ },
132
+ [isControlled, min, max, step, onChange]
133
+ );
134
+ const valueFromPointer = react.useCallback(
135
+ (e) => {
136
+ const rect = trackRef.current.getBoundingClientRect();
137
+ const ratio = clamp((e.clientX - rect.left) / rect.width, 0, 1);
138
+ return min + ratio * (max - min);
139
+ },
140
+ [min, max]
141
+ );
142
+ const handlePointerDown = react.useCallback(
143
+ (e) => {
144
+ if (disabled) return;
145
+ e.currentTarget.setPointerCapture(e.pointerId);
146
+ setIsDragging(true);
147
+ thumbRef.current?.focus();
148
+ setValue(valueFromPointer(e.nativeEvent));
149
+ },
150
+ [disabled, setValue, valueFromPointer]
151
+ );
152
+ const handlePointerMove = react.useCallback(
153
+ (e) => {
154
+ if (!isDragging || disabled) return;
155
+ setValue(valueFromPointer(e.nativeEvent));
156
+ },
157
+ [isDragging, disabled, setValue, valueFromPointer]
158
+ );
159
+ const handlePointerUp = react.useCallback(() => {
160
+ setIsDragging(false);
161
+ thumbRef.current?.blur();
162
+ }, []);
163
+ react.useEffect(() => {
164
+ const el = trackRef.current;
165
+ if (!el) return;
166
+ const onWheel = (e) => {
167
+ if (disabled) return;
168
+ e.preventDefault();
169
+ setValue(value + (e.deltaY < 0 ? step : -step));
170
+ };
171
+ el.addEventListener("wheel", onWheel, { passive: false });
172
+ return () => el.removeEventListener("wheel", onWheel);
173
+ }, [disabled, value, step, setValue]);
174
+ const handleKeyDown = react.useCallback(
175
+ (e) => {
176
+ if (disabled) return;
177
+ const map = {
178
+ ArrowRight: step,
179
+ ArrowUp: step,
180
+ ArrowLeft: -step,
181
+ ArrowDown: -step,
182
+ PageUp: step * 10,
183
+ PageDown: -step * 10
184
+ };
185
+ if (e.key === "Home") {
186
+ setValue(min);
187
+ e.preventDefault();
188
+ return;
189
+ }
190
+ if (e.key === "End") {
191
+ setValue(max);
192
+ e.preventDefault();
193
+ return;
194
+ }
195
+ if (map[e.key] !== void 0) {
196
+ setValue(value + map[e.key]);
197
+ e.preventDefault();
198
+ }
199
+ },
200
+ [disabled, step, min, max, value, setValue]
201
+ );
202
+ const tooltipVisible = showTooltip === "always" || showTooltip === "drag" && (isDragging || isFocused);
203
+ const displayValue = `${Math.round(value)}%`;
204
+ const tooltipOffset = `calc(${pct * 100}% + ${(0.5 - pct) * 20}px)`;
205
+ return /* @__PURE__ */ jsxRuntime.jsxs(
206
+ "div",
207
+ {
208
+ className: [SliderControl_module_default.wrapper, disabled ? SliderControl_module_default.disabled : "", className ?? ""].filter(Boolean).join(" "),
209
+ style: accentVars,
210
+ children: [
211
+ leftIcon !== null && leftIcon !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: SliderControl_module_default.icon, children: leftIcon }),
212
+ /* @__PURE__ */ jsxRuntime.jsxs(
213
+ "div",
214
+ {
215
+ ref: trackRef,
216
+ className: SliderControl_module_default.trackArea,
217
+ onPointerDown: handlePointerDown,
218
+ onPointerMove: handlePointerMove,
219
+ onPointerUp: handlePointerUp,
220
+ onPointerCancel: handlePointerUp,
221
+ children: [
222
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: SliderControl_module_default.groove, children: /* @__PURE__ */ jsxRuntime.jsx(
223
+ "div",
224
+ {
225
+ className: SliderControl_module_default.rail,
226
+ style: railBackground ? { background: railBackground } : void 0,
227
+ children: !railBackground && /* @__PURE__ */ jsxRuntime.jsx("div", { className: SliderControl_module_default.fill, style: { width: `${pct * 100}%` } })
228
+ }
229
+ ) }),
230
+ /* @__PURE__ */ jsxRuntime.jsx(
231
+ "div",
232
+ {
233
+ ref: thumbRef,
234
+ role: "slider",
235
+ tabIndex: disabled ? -1 : 0,
236
+ "aria-valuenow": Math.round(value),
237
+ "aria-valuemin": min,
238
+ "aria-valuemax": max,
239
+ "aria-disabled": disabled,
240
+ className: [SliderControl_module_default.thumb, isDragging ? SliderControl_module_default.thumbDragging : ""].filter(Boolean).join(" "),
241
+ style: { left: `calc(${pct * 100}% + ${(0.5 - pct) * 24}px)` },
242
+ onKeyDown: handleKeyDown,
243
+ onFocus: () => setIsFocused(true),
244
+ onBlur: () => setIsFocused(false)
245
+ }
246
+ ),
247
+ /* @__PURE__ */ jsxRuntime.jsx(
248
+ "div",
249
+ {
250
+ className: [SliderControl_module_default.tooltip, tooltipVisible ? SliderControl_module_default.tooltipVisible : ""].filter(Boolean).join(" "),
251
+ style: { left: tooltipOffset },
252
+ "aria-hidden": "true",
253
+ children: displayValue
254
+ }
255
+ )
256
+ ]
257
+ }
258
+ ),
259
+ rightIcon !== null && rightIcon !== void 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: SliderControl_module_default.icon, children: rightIcon })
260
+ ]
261
+ }
262
+ );
263
+ };
264
+ SliderControl.displayName = "SliderControl";
265
+
266
+ exports.SliderControl = SliderControl;
267
+ //# sourceMappingURL=index.cjs.map
268
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/SliderControl/SliderControl.module.scss","../../../src/utils/color.ts","../../../src/components/SliderControl/SliderControl.tsx"],"names":["wrapper","disabled","icon","trackArea","groove","rail","fill","thumb","thumbDragging","tooltip","tooltipVisible","useState","useRef","useCallback","useEffect","jsxs","jsx"],"mappings":"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","file":"index.cjs","sourcesContent":["@import url(\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap\");\n:root {\n --accent: #3b82f6;\n --accent-dot: rgb(82.52, 145, 247.08);\n --accent-track: #3b82f6;\n --accent-ring: #3b82f6;\n --accent-glow: rgba(59, 130, 246, 0.3);\n --accent-light: rgb(157.485, 188.725, 239.765);\n --color-primary-50: rgb(169.3455, 194.6925, 236.1045);\n --color-primary-100: rgb(149.4545, 184.4575, 241.6455);\n --color-primary-400: rgb(82.52, 145, 247.08);\n --color-primary-500: #3b82f6;\n --color-primary-600: rgb(29.8390243902, 111.4024390244, 244.6609756098);\n --color-primary-700: rgb(10.712195122, 95.2195121951, 233.287804878);\n --color-neutral-0: #ffffff;\n --color-neutral-100: #f3f4f6;\n --color-neutral-200: #e5e7eb;\n --color-neutral-400: #9ca3af;\n --color-neutral-600: #4b5563;\n --color-neutral-900: #111827;\n --color-success-500: #22c55e;\n --color-success-600: #16a34a;\n --color-danger-500: #ef4444;\n --color-danger-600: #dc2626;\n --color-warning-500: #f59e0b;\n --color-warning-600: #d97706;\n --font-family-base: \"Inter\", system-ui, -apple-system, sans-serif;\n --font-size-xs: 0.75rem;\n --font-size-sm: 0.875rem;\n --font-size-md: 1rem;\n --font-size-lg: 1.125rem;\n --spacing-1: 0.25rem;\n --spacing-2: 0.5rem;\n --spacing-3: 0.75rem;\n --spacing-4: 1rem;\n --radius-sm: 0.25rem;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --radius-full: 9999px;\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n --transition-fast: 150ms ease;\n --color-surface: #ffffff;\n --color-surface-elevated: #ffffff;\n}\n\n[data-theme=dark] {\n --color-neutral-0: #0f172a;\n --color-neutral-100: #1e293b;\n --color-neutral-200: #334155;\n --color-neutral-400: #94a3b8;\n --color-neutral-600: #cbd5e1;\n --color-neutral-900: #f8fafc;\n --color-surface: #1e293b;\n --color-surface-elevated: #273549;\n --color-primary-50: #172554;\n --color-primary-100: #1e3a8a;\n --accent-light: #172554;\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.4);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.5), 0 2px 4px -2px rgb(0 0 0 / 0.4);\n}\n\n.wrapper {\n display: flex;\n align-items: center;\n gap: 10px;\n font-family: var(--font-family-base);\n user-select: none;\n -webkit-user-select: none;\n}\n\n.disabled {\n opacity: 0.45;\n pointer-events: none;\n}\n\n.icon {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-neutral-400);\n flex-shrink: 0;\n line-height: 0;\n}\n\n.trackArea {\n position: relative;\n flex: 1;\n height: 36px;\n display: flex;\n align-items: center;\n cursor: pointer;\n}\n\n.groove {\n position: relative;\n width: 100%;\n height: 22px;\n border-radius: var(--radius-full);\n background: var(--color-neutral-300);\n display: flex;\n align-items: center;\n box-shadow: inset 0 4px 8px rgba(0, 0, 0, 0.14), inset 0 2px 4px rgba(0, 0, 0, 0.06), inset 0 -2px 3px rgba(255, 255, 255, 0.1);\n}\n\n.rail {\n position: absolute;\n left: 8px;\n right: 8px;\n height: 6px;\n border-radius: var(--radius-full);\n background: var(--color-neutral-400);\n box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), inset 0 1px 1px rgba(0, 0, 0, 0.18);\n overflow: hidden;\n}\n\n.fill {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: var(--slider-accent-track, var(--accent-track));\n border-radius: var(--radius-full);\n transition: width 60ms linear;\n}\n\n.thumb {\n position: absolute;\n top: 50%;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n transform: translate(-50%, -50%);\n background: #dde0e6;\n border: 1px solid rgba(0, 0, 0, 0.1);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);\n cursor: grab;\n transition: box-shadow 120ms ease, transform 120ms ease;\n outline: none;\n z-index: 2;\n}\n\n.thumb:focus-visible {\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22), 0 0 0 3px var(--slider-accent-ring, var(--accent-ring));\n}\n\n.thumbDragging {\n cursor: grabbing;\n transform: translate(-50%, -50%) scale(1.08);\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.28), 0 0 0 3px var(--slider-accent-ring, var(--accent-ring)), 0 0 0 6px var(--slider-accent-glow, var(--accent-glow));\n}\n\n.tooltip {\n position: absolute;\n bottom: calc(100% + 6px);\n transform: translateX(-50%);\n background: rgba(18, 18, 26, 0.85);\n backdrop-filter: blur(6px);\n -webkit-backdrop-filter: blur(6px);\n color: #fff;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n padding: 3px 8px;\n border-radius: 6px;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 120ms ease;\n z-index: 10;\n}\n.tooltip::after {\n content: \"\";\n position: absolute;\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border: 4px solid transparent;\n border-top-color: rgba(18, 18, 26, 0.85);\n}\n\n.tooltipVisible {\n opacity: 1;\n}\n\n[data-theme=dark] .groove {\n box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07), inset 0 3px 7px rgba(0, 0, 0, 0.32), inset 0 1px 3px rgba(0, 0, 0, 0.22), inset 0 -2px 3px rgba(255, 255, 255, 0.04);\n}\n[data-theme=dark] .thumb {\n background: #4a4f5c;\n border-color: rgba(255, 255, 255, 0.08);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);\n}\n[data-theme=dark] .thumbDragging {\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.5), 0 0 0 3px var(--slider-accent-ring, var(--accent-ring)), 0 0 0 6px var(--slider-accent-glow, var(--accent-glow));\n}\n/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3N0eWxlcy90b2tlbnMuc2NzcyIsIlNsaWRlckNvbnRyb2wubW9kdWxlLnNjc3MiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRVE7QUFLUjtFQUVFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUdBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUdBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUdBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUdBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFHQTtFQUNBO0VBQ0E7RUFDQTtFQUdBO0VBQ0E7RUFDQTtFQUNBO0VBR0E7RUFDQTtFQUdBO0VBR0E7RUFDQTs7O0FBUUY7RUFFRTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFHQTtFQUNBO0VBR0E7RUFDQTtFQUlBO0VBR0E7RUFDQTs7O0FDeEZGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtFQUNFO0VBQ0E7OztBQUdGO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFJRjtFQUNFO0VBQ0E7RUFDQSxRQTdCYztFQThCZDtFQUNBO0VBQ0E7OztBQUlGO0VBQ0U7RUFDQTtFQUNBLFFBMUNjO0VBMkNkO0VBQ0E7RUFDQTtFQUNBO0VBRUEsWUFDRTs7O0FBTUo7RUFDRTtFQUNBO0VBQ0E7RUFDQSxRQTFEZTtFQTJEZjtFQUNBO0VBQ0EsWUFDRTtFQUVGOzs7QUFJRjtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0EsWUE5RWE7RUErRWI7RUFDQTs7O0FBSUY7RUFDRTtFQUNBO0VBQ0EsT0FqRmM7RUFrRmQsUUFsRmM7RUFtRmQ7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFHRjtFQUNFLFlBQ0U7OztBQUlKO0VBQ0U7RUFDQTtFQUNBLFlBQ0U7OztBQU1KO0VBQ0U7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7QUFFQTtFQUNFO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOzs7QUFJSjtFQUNFOzs7QUFLQTtFQUNFLFlBQ0U7O0FBTUo7RUFDRTtFQUNBO0VBQ0E7O0FBR0Y7RUFDRSxZQUNFIiwic291cmNlc0NvbnRlbnQiOlsiQHVzZSBcInNhc3M6Y29sb3JcIjtcblxuQGltcG9ydCB1cmwoXCJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2NzczI/ZmFtaWx5PUludGVyOndnaHRANDAwOzUwMDs2MDAmZGlzcGxheT1zd2FwXCIpO1xuXG4vLyBBY2NlbnQgZGkgZGVmYXVsdCDigJQgY2FtYmlhIHF1aSBwZXIgYWdnaW9ybmFyZSB0dXR0YSBsYSBsaWJyZXJpYVxuJGFjY2VudDogIzNiODJmNjtcblxuOnJvb3Qge1xuICAvLyBBY2NlbnQgc2NhbGUg4oCUIGRlcml2YXRhIGRhICRhY2NlbnQgYSBjb21waWxlIHRpbWVcbiAgLS1hY2NlbnQ6ICAgICAgICAjeyRhY2NlbnR9O1xuICAtLWFjY2VudC1kb3Q6ICAgICN7Y29sb3Iuc2NhbGUoJGFjY2VudCwgJGxpZ2h0bmVzczogMTIlKX07XG4gIC0tYWNjZW50LXRyYWNrOiAgI3skYWNjZW50fTtcbiAgLS1hY2NlbnQtcmluZzogICAjeyRhY2NlbnR9O1xuICAtLWFjY2VudC1nbG93OiAgICN7Y29sb3IuY2hhbmdlKCRhY2NlbnQsICRhbHBoYTogMC4zKX07XG4gIC0tYWNjZW50LWxpZ2h0OiAgI3tjb2xvci5zY2FsZSgkYWNjZW50LCAkbGlnaHRuZXNzOiA0NSUsICRzYXR1cmF0aW9uOiAtMjAlKX07XG5cbiAgLy8gUHJpbWFyeSBzY2FsZSAobWFudGVudXRhIHBlciByZXRyb2NvbXBhdGliaWxpdMOgIGNvbiBCdXR0b24sIEJhZGdlLCBJbnB1dClcbiAgLS1jb2xvci1wcmltYXJ5LTUwOiAgI3tjb2xvci5zY2FsZSgkYWNjZW50LCAkbGlnaHRuZXNzOiA0OSUsICRzYXR1cmF0aW9uOiAtMzAlKX07XG4gIC0tY29sb3ItcHJpbWFyeS0xMDA6ICN7Y29sb3Iuc2NhbGUoJGFjY2VudCwgJGxpZ2h0bmVzczogNDIlLCAkc2F0dXJhdGlvbjogLTE1JSl9O1xuICAtLWNvbG9yLXByaW1hcnktNDAwOiAje2NvbG9yLnNjYWxlKCRhY2NlbnQsICRsaWdodG5lc3M6IDEyJSl9O1xuICAtLWNvbG9yLXByaW1hcnktNTAwOiAjeyRhY2NlbnR9O1xuICAtLWNvbG9yLXByaW1hcnktNjAwOiAje2NvbG9yLnNjYWxlKCRhY2NlbnQsICRsaWdodG5lc3M6IC0xMCUpfTtcbiAgLS1jb2xvci1wcmltYXJ5LTcwMDogI3tjb2xvci5zY2FsZSgkYWNjZW50LCAkbGlnaHRuZXNzOiAtMjAlKX07XG5cbiAgLy8gTmV1dHJhbFxuICAtLWNvbG9yLW5ldXRyYWwtMDogICAjZmZmZmZmO1xuICAtLWNvbG9yLW5ldXRyYWwtMTAwOiAjZjNmNGY2O1xuICAtLWNvbG9yLW5ldXRyYWwtMjAwOiAjZTVlN2ViO1xuICAtLWNvbG9yLW5ldXRyYWwtNDAwOiAjOWNhM2FmO1xuICAtLWNvbG9yLW5ldXRyYWwtNjAwOiAjNGI1NTYzO1xuICAtLWNvbG9yLW5ldXRyYWwtOTAwOiAjMTExODI3O1xuXG4gIC8vIFNlbWFudGljXG4gIC0tY29sb3Itc3VjY2Vzcy01MDA6ICMyMmM1NWU7XG4gIC0tY29sb3Itc3VjY2Vzcy02MDA6ICMxNmEzNGE7XG4gIC0tY29sb3ItZGFuZ2VyLTUwMDogICNlZjQ0NDQ7XG4gIC0tY29sb3ItZGFuZ2VyLTYwMDogICNkYzI2MjY7XG4gIC0tY29sb3Itd2FybmluZy01MDA6ICNmNTllMGI7XG4gIC0tY29sb3Itd2FybmluZy02MDA6ICNkOTc3MDY7XG5cbiAgLy8gVHlwb2dyYXBoeVxuICAtLWZvbnQtZmFtaWx5LWJhc2U6IFwiSW50ZXJcIiwgc3lzdGVtLXVpLCAtYXBwbGUtc3lzdGVtLCBzYW5zLXNlcmlmO1xuICAtLWZvbnQtc2l6ZS14czogMC43NXJlbTtcbiAgLS1mb250LXNpemUtc206IDAuODc1cmVtO1xuICAtLWZvbnQtc2l6ZS1tZDogMXJlbTtcbiAgLS1mb250LXNpemUtbGc6IDEuMTI1cmVtO1xuXG4gIC8vIFNwYWNpbmdcbiAgLS1zcGFjaW5nLTE6IDAuMjVyZW07XG4gIC0tc3BhY2luZy0yOiAwLjVyZW07XG4gIC0tc3BhY2luZy0zOiAwLjc1cmVtO1xuICAtLXNwYWNpbmctNDogMXJlbTtcblxuICAvLyBSYWRpdXNcbiAgLS1yYWRpdXMtc206ICAgMC4yNXJlbTtcbiAgLS1yYWRpdXMtbWQ6ICAgMC4zNzVyZW07XG4gIC0tcmFkaXVzLWxnOiAgIDAuNXJlbTtcbiAgLS1yYWRpdXMtZnVsbDogOTk5OXB4O1xuXG4gIC8vIFNoYWRvd3NcbiAgLS1zaGFkb3ctc206IDAgMXB4IDJweCAwIHJnYigwIDAgMCAvIDAuMDUpO1xuICAtLXNoYWRvdy1tZDogMCA0cHggNnB4IC0xcHggcmdiKDAgMCAwIC8gMC4xKSwgMCAycHggNHB4IC0ycHggcmdiKDAgMCAwIC8gMC4xKTtcblxuICAvLyBUcmFuc2l0aW9uc1xuICAtLXRyYW5zaXRpb24tZmFzdDogMTUwbXMgZWFzZTtcblxuICAvLyBTdXJmYWNlIChiYWNrZ3JvdW5kIGRpIGNhcmQvcGFuZWwpXG4gIC0tY29sb3Itc3VyZmFjZTogICAgICAgICAgI2ZmZmZmZjtcbiAgLS1jb2xvci1zdXJmYWNlLWVsZXZhdGVkOiAjZmZmZmZmO1xufVxuXG4vLyDilIDilIDilIAgRGFyayB0aGVtZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbi8vIEFwcGxpY2F0byB2aWEgZGF0YS10aGVtZT1cImRhcmtcIiBzdWxsJ2VsZW1lbnRvIHJvb3QgKGdlc3RpdG8gZGEgU3Rvcnlib29rIGRlY29yYXRvclxuLy8gZSBkYWxsJ2FwcCBjb25zdW1lcikuIEkgY29tcG9uZW50aSBub24gZGV2b25vIGZhcmUgbnVsbGEgZGkgc3BlY2lhbGU6IGJhc3RhIGNoZVxuLy8gdXNpbm8gaSB0b2tlbiB2YXIoKSBlIHJpY2V2ZXJhbm5vIGF1dG9tYXRpY2FtZW50ZSBpIHZhbG9yaSBkYXJrLlxuXG5bZGF0YS10aGVtZT1cImRhcmtcIl0ge1xuICAvLyBOZXV0cmFsIChzY2FsYSBpbnZlcnRpdGEpXG4gIC0tY29sb3ItbmV1dHJhbC0wOiAgICMwZjE3MmE7XG4gIC0tY29sb3ItbmV1dHJhbC0xMDA6ICMxZTI5M2I7XG4gIC0tY29sb3ItbmV1dHJhbC0yMDA6ICMzMzQxNTU7XG4gIC0tY29sb3ItbmV1dHJhbC00MDA6ICM5NGEzYjg7XG4gIC0tY29sb3ItbmV1dHJhbC02MDA6ICNjYmQ1ZTE7XG4gIC0tY29sb3ItbmV1dHJhbC05MDA6ICNmOGZhZmM7XG5cbiAgLy8gU3VyZmFjZVxuICAtLWNvbG9yLXN1cmZhY2U6ICAgICAgICAgICMxZTI5M2I7XG4gIC0tY29sb3Itc3VyZmFjZS1lbGV2YXRlZDogIzI3MzU0OTtcblxuICAvLyBQcmltYXJ5IHNjYWxlIGRhcmsgKHBlciBpbCBkZWZhdWx0IGFjY2VudCBibHUg4oCUIGxlIHNmdW1hdHVyZSBjaGlhcmUgZGl2ZW50YW5vIHNjdXJlKVxuICAtLWNvbG9yLXByaW1hcnktNTA6ICAjMTcyNTU0O1xuICAtLWNvbG9yLXByaW1hcnktMTAwOiAjMWUzYThhO1xuICAvLyA0MDAgLyA1MDAgLyA2MDAgLyA3MDAgcmltYW5nb25vIGludmFyaWF0aSAoYWJiYXN0YW56YSBzYXR1cmkgc3UgYmcgc2N1cm8pXG5cbiAgLy8gQWNjZW50IGxpZ2h0OiB2YXJpYW50ZSBzY3VyYVxuICAtLWFjY2VudC1saWdodDogIzE3MjU1NDtcblxuICAvLyBTaGFkb3dzIChwacO5IGZvcnRpIHN1IGJnIHNjdXJvKVxuICAtLXNoYWRvdy1zbTogMCAxcHggMnB4IDAgcmdiKDAgMCAwIC8gMC40KTtcbiAgLS1zaGFkb3ctbWQ6IDAgNHB4IDZweCAtMXB4IHJnYigwIDAgMCAvIDAuNSksIDAgMnB4IDRweCAtMnB4IHJnYigwIDAgMCAvIDAuNCk7XG59XG4iLCJAdXNlIFwiLi4vLi4vc3R5bGVzL3Rva2Vuc1wiIGFzICo7XG5cbiRhY2NlbnQtdHJhY2s6IHZhcigtLXNsaWRlci1hY2NlbnQtdHJhY2ssIHZhcigtLWFjY2VudC10cmFjaykpO1xuJGFjY2VudC1yaW5nOiAgdmFyKC0tc2xpZGVyLWFjY2VudC1yaW5nLCAgdmFyKC0tYWNjZW50LXJpbmcpKTtcbiRhY2NlbnQtZ2xvdzogIHZhcigtLXNsaWRlci1hY2NlbnQtZ2xvdywgIHZhcigtLWFjY2VudC1nbG93KSk7XG5cbiRncm9vdmUtaGVpZ2h0OiAyMnB4O1xuJHJhaWwtaGVpZ2h0OiAgICA2cHg7XG4kdGh1bWItc2l6ZTogICAgMThweDtcbiRoaXQtem9uZTogICAgICAzNnB4O1xuXG4ud3JhcHBlciB7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGdhcDogMTBweDtcbiAgZm9udC1mYW1pbHk6IHZhcigtLWZvbnQtZmFtaWx5LWJhc2UpO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcbn1cblxuLmRpc2FibGVkIHtcbiAgb3BhY2l0eTogMC40NTtcbiAgcG9pbnRlci1ldmVudHM6IG5vbmU7XG59XG5cbi5pY29uIHtcbiAgZGlzcGxheTogZmxleDtcbiAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gIGNvbG9yOiB2YXIoLS1jb2xvci1uZXV0cmFsLTQwMCk7XG4gIGZsZXgtc2hyaW5rOiAwO1xuICBsaW5lLWhlaWdodDogMDtcbn1cblxuLy8g4pSA4pSAIEhpdCB6b25lIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLnRyYWNrQXJlYSB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgZmxleDogMTtcbiAgaGVpZ2h0OiAkaGl0LXpvbmU7XG4gIGRpc3BsYXk6IGZsZXg7XG4gIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gIGN1cnNvcjogcG9pbnRlcjtcbn1cblxuLy8g4pSA4pSAIEdyb292ZSDigJQgdGhlIGNhcnZlZCBjaGFubmVsLCA+PSB0aHVtYiBzaXplIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLmdyb292ZSB7XG4gIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgd2lkdGg6IDEwMCU7XG4gIGhlaWdodDogJGdyb292ZS1oZWlnaHQ7XG4gIGJvcmRlci1yYWRpdXM6IHZhcigtLXJhZGl1cy1mdWxsKTtcbiAgYmFja2dyb3VuZDogdmFyKC0tY29sb3ItbmV1dHJhbC0zMDApO1xuICBkaXNwbGF5OiBmbGV4O1xuICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAvLyBwdXJlbHkgaW5zZXQ6IG5vIG91dGVyIHNoYWRvd1xuICBib3gtc2hhZG93OlxuICAgIGluc2V0IDAgNHB4IDhweCByZ2JhKDAsIDAsIDAsIDAuMTQpLFxuICAgIGluc2V0IDAgMnB4IDRweCByZ2JhKDAsIDAsIDAsIDAuMDYpLFxuICAgIGluc2V0IDAgLTJweCAzcHggcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjEwKTtcbn1cblxuLy8g4pSA4pSAIFJhaWwg4oCUIHRoaW4gbGluZSBpbnNpZGUgdGhlIGdyb292ZSB3aGVyZSBmaWxsIHJ1bnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4ucmFpbCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgbGVmdDogOHB4O1xuICByaWdodDogOHB4O1xuICBoZWlnaHQ6ICRyYWlsLWhlaWdodDtcbiAgYm9yZGVyLXJhZGl1czogdmFyKC0tcmFkaXVzLWZ1bGwpO1xuICBiYWNrZ3JvdW5kOiB2YXIoLS1jb2xvci1uZXV0cmFsLTQwMCk7XG4gIGJveC1zaGFkb3c6XG4gICAgaW5zZXQgMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC4zMCksXG4gICAgaW5zZXQgMCAxcHggMXB4IHJnYmEoMCwgMCwgMCwgMC4xOCk7XG4gIG92ZXJmbG93OiBoaWRkZW47XG59XG5cbi8vIOKUgOKUgCBGaWxsIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuLmZpbGwge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogMDtcbiAgbGVmdDogMDtcbiAgaGVpZ2h0OiAxMDAlO1xuICBiYWNrZ3JvdW5kOiAkYWNjZW50LXRyYWNrO1xuICBib3JkZXItcmFkaXVzOiB2YXIoLS1yYWRpdXMtZnVsbCk7XG4gIHRyYW5zaXRpb246IHdpZHRoIDYwbXMgbGluZWFyO1xufVxuXG4vLyDilIDilIAgVGh1bWIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4udGh1bWIge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIHRvcDogNTAlO1xuICB3aWR0aDogJHRodW1iLXNpemU7XG4gIGhlaWdodDogJHRodW1iLXNpemU7XG4gIGJvcmRlci1yYWRpdXM6IDUwJTtcbiAgdHJhbnNmb3JtOiB0cmFuc2xhdGUoLTUwJSwgLTUwJSk7XG4gIGJhY2tncm91bmQ6ICNkZGUwZTY7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHJnYmEoMCwgMCwgMCwgMC4xMCk7XG4gIGJveC1zaGFkb3c6IDAgMXB4IDNweCByZ2JhKDAsIDAsIDAsIDAuMjIpO1xuICBjdXJzb3I6IGdyYWI7XG4gIHRyYW5zaXRpb246IGJveC1zaGFkb3cgMTIwbXMgZWFzZSwgdHJhbnNmb3JtIDEyMG1zIGVhc2U7XG4gIG91dGxpbmU6IG5vbmU7XG4gIHotaW5kZXg6IDI7XG59XG5cbi50aHVtYjpmb2N1cy12aXNpYmxlIHtcbiAgYm94LXNoYWRvdzpcbiAgICAwIDFweCAzcHggcmdiYSgwLCAwLCAwLCAwLjIyKSxcbiAgICAwIDAgMCAzcHggJGFjY2VudC1yaW5nO1xufVxuXG4udGh1bWJEcmFnZ2luZyB7XG4gIGN1cnNvcjogZ3JhYmJpbmc7XG4gIHRyYW5zZm9ybTogdHJhbnNsYXRlKC01MCUsIC01MCUpIHNjYWxlKDEuMDgpO1xuICBib3gtc2hhZG93OlxuICAgIDAgMXB4IDRweCByZ2JhKDAsIDAsIDAsIDAuMjgpLFxuICAgIDAgMCAwIDNweCAkYWNjZW50LXJpbmcsXG4gICAgMCAwIDAgNnB4ICRhY2NlbnQtZ2xvdztcbn1cblxuLy8g4pSA4pSAIFRvb2x0aXAg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4udG9vbHRpcCB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgYm90dG9tOiBjYWxjKDEwMCUgKyA2cHgpO1xuICB0cmFuc2Zvcm06IHRyYW5zbGF0ZVgoLTUwJSk7XG4gIGJhY2tncm91bmQ6IHJnYmEoMTgsIDE4LCAyNiwgMC44NSk7XG4gIGJhY2tkcm9wLWZpbHRlcjogYmx1cig2cHgpO1xuICAtd2Via2l0LWJhY2tkcm9wLWZpbHRlcjogYmx1cig2cHgpO1xuICBjb2xvcjogI2ZmZjtcbiAgZm9udC1zaXplOiAxMXB4O1xuICBmb250LXdlaWdodDogNjAwO1xuICBsZXR0ZXItc3BhY2luZzogMC4wMmVtO1xuICBwYWRkaW5nOiAzcHggOHB4O1xuICBib3JkZXItcmFkaXVzOiA2cHg7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIHBvaW50ZXItZXZlbnRzOiBub25lO1xuICBvcGFjaXR5OiAwO1xuICB0cmFuc2l0aW9uOiBvcGFjaXR5IDEyMG1zIGVhc2U7XG4gIHotaW5kZXg6IDEwO1xuXG4gICY6OmFmdGVyIHtcbiAgICBjb250ZW50OiBcIlwiO1xuICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICB0b3A6IDEwMCU7XG4gICAgbGVmdDogNTAlO1xuICAgIHRyYW5zZm9ybTogdHJhbnNsYXRlWCgtNTAlKTtcbiAgICBib3JkZXI6IDRweCBzb2xpZCB0cmFuc3BhcmVudDtcbiAgICBib3JkZXItdG9wLWNvbG9yOiByZ2JhKDE4LCAxOCwgMjYsIDAuODUpO1xuICB9XG59XG5cbi50b29sdGlwVmlzaWJsZSB7XG4gIG9wYWNpdHk6IDE7XG59XG5cbi8vIOKUgOKUgCBEYXJrIG1vZGUg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5bZGF0YS10aGVtZT1cImRhcmtcIl0ge1xuICAuZ3Jvb3ZlIHtcbiAgICBib3gtc2hhZG93OlxuICAgICAgaW5zZXQgMCAxcHggMCByZ2JhKDI1NSwgMjU1LCAyNTUsIDAuMDcpLFxuICAgICAgaW5zZXQgMCAzcHggN3B4IHJnYmEoMCwgMCwgMCwgMC4zMiksXG4gICAgICBpbnNldCAwIDFweCAzcHggcmdiYSgwLCAwLCAwLCAwLjIyKSxcbiAgICAgIGluc2V0IDAgLTJweCAzcHggcmdiYSgyNTUsIDI1NSwgMjU1LCAwLjA0KTtcbiAgfVxuXG4gIC50aHVtYiB7XG4gICAgYmFja2dyb3VuZDogIzRhNGY1YztcbiAgICBib3JkZXItY29sb3I6IHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4wOCk7XG4gICAgYm94LXNoYWRvdzogMCAxcHggM3B4IHJnYmEoMCwgMCwgMCwgMC40NSk7XG4gIH1cblxuICAudGh1bWJEcmFnZ2luZyB7XG4gICAgYm94LXNoYWRvdzpcbiAgICAgIDAgMXB4IDRweCByZ2JhKDAsIDAsIDAsIDAuNSksXG4gICAgICAwIDAgMCAzcHggJGFjY2VudC1yaW5nLFxuICAgICAgMCAwIDAgNnB4ICRhY2NlbnQtZ2xvdztcbiAgfVxufVxuIl19 */","export function hexToHsl(hex: string): [number, number, number] {\n const r = parseInt(hex.slice(1, 3), 16) / 255;\n const g = parseInt(hex.slice(3, 5), 16) / 255;\n const b = parseInt(hex.slice(5, 7), 16) / 255;\n\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n const l = (max + min) / 2;\n let h = 0;\n let s = 0;\n\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;\n case g: h = ((b - r) / d + 2) / 6; break;\n case b: h = ((r - g) / d + 4) / 6; break;\n }\n }\n\n return [h * 360, s * 100, l * 100];\n}\n\nexport function hslToHex(h: number, s: number, l: number): string {\n const sl = s / 100;\n const ll = l / 100;\n const a = sl * Math.min(ll, 1 - ll);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n const color = ll - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);\n return Math.round(255 * color).toString(16).padStart(2, \"0\");\n };\n return `#${f(0)}${f(8)}${f(4)}`;\n}\n\nexport function hslToRgb(h: number, s: number, l: number): { r: number; g: number; b: number } {\n const sl = s / 100;\n const ll = l / 100;\n const a = sl * Math.min(ll, 1 - ll);\n const f = (n: number) => {\n const k = (n + h / 30) % 12;\n return Math.round(255 * (ll - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)));\n };\n return { r: f(0), g: f(8), b: f(4) };\n}\n\nexport function rgbToHsl(r: number, g: number, b: number): [number, number, number] {\n const rr = r / 255, gg = g / 255, bb = b / 255;\n const max = Math.max(rr, gg, bb);\n const min = Math.min(rr, gg, bb);\n const l = (max + min) / 2;\n let h = 0, s = 0;\n if (max !== min) {\n const d = max - min;\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n switch (max) {\n case rr: h = ((gg - bb) / d + (gg < bb ? 6 : 0)) / 6; break;\n case gg: h = ((bb - rr) / d + 2) / 6; break;\n case bb: h = ((rr - gg) / d + 4) / 6; break;\n }\n }\n return [h * 360, s * 100, l * 100];\n}\n\nfunction hslToRgba(h: number, s: number, l: number, alpha: number): string {\n const { r, g, b } = hslToRgb(h, s, l);\n return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\nexport interface AccentTokens {\n base: string;\n dot: string;\n track: string;\n ring: string;\n glow: string;\n light: string;\n}\n\nexport interface ColorValue {\n hex: string;\n hexa: string;\n hsl: string;\n hsla: string;\n rgb: string;\n rgba: string;\n h: number;\n s: number;\n l: number;\n a: number;\n}\n\nexport function buildColorValue(h: number, s: number, l: number, a: number): ColorValue {\n const { r, g, b } = hslToRgb(h, s, l);\n const hex = hslToHex(h, s, l);\n const alphaHex = Math.round(a * 255).toString(16).padStart(2, \"0\");\n const hR = Math.round(h), sR = Math.round(s), lR = Math.round(l);\n const aR = Math.round(a * 100) / 100;\n return {\n hex,\n hexa: `${hex}${alphaHex}`,\n hsl: `hsl(${hR}, ${sR}%, ${lR}%)`,\n hsla: `hsla(${hR}, ${sR}%, ${lR}%, ${aR})`,\n rgb: `rgb(${r}, ${g}, ${b})`,\n rgba: `rgba(${r}, ${g}, ${b}, ${aR})`,\n h, s, l, a,\n };\n}\n\nexport function deriveAccent(hex: string): AccentTokens {\n const [h, s, l] = hexToHsl(hex);\n return {\n base: hex,\n dot: hslToHex(h, s, Math.min(l + 12, 95)),\n track: hex,\n ring: hex,\n glow: hslToRgba(h, s, l, 0.3),\n light: hslToHex(h, Math.max(s - 20, 0), Math.min(l + 45, 96)),\n };\n}\n\nexport function accentToCssVars(\n tokens: AccentTokens,\n prefix: string\n): Record<string, string> {\n return {\n [`--${prefix}-accent`]: tokens.base,\n [`--${prefix}-accent-dot`]: tokens.dot,\n [`--${prefix}-accent-track`]: tokens.track,\n [`--${prefix}-accent-ring`]: tokens.ring,\n [`--${prefix}-accent-glow`]: tokens.glow,\n [`--${prefix}-accent-light`]: tokens.light,\n };\n}\n","import React, { useCallback, useEffect, useRef, useState } from \"react\";\nimport styles from \"./SliderControl.module.scss\";\nimport { deriveAccent, accentToCssVars } from \"../../utils/color\";\n\nexport const VolumeDownIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M2 6h2l3-3v10L4 10H2a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M10 5.5a3 3 0 0 1 0 5\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport const VolumeUpIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M2 6h2l3-3v10L4 10H2a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Z\"\n fill=\"currentColor\"\n />\n <path\n d=\"M10 5.5a3 3 0 0 1 0 5M12 3.5a6 6 0 0 1 0 9\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n strokeLinecap=\"round\"\n />\n </svg>\n);\n\nexport interface SliderControlProps {\n value?: number;\n defaultValue?: number;\n min?: number;\n max?: number;\n step?: number;\n onChange?: (value: number) => void;\n showTooltip?: \"always\" | \"drag\" | \"never\";\n leftIcon?: React.ReactNode;\n rightIcon?: React.ReactNode;\n /** CSS background value applied to the rail — replaces the fill with a full-width gradient */\n railBackground?: string;\n accent?: string;\n className?: string;\n disabled?: boolean;\n}\n\nfunction clamp(v: number, min: number, max: number) {\n return Math.min(Math.max(v, min), max);\n}\n\nfunction snapToStep(v: number, min: number, step: number) {\n return Math.round((v - min) / step) * step + min;\n}\n\nexport const SliderControl: React.FC<SliderControlProps> = ({\n value: controlledValue,\n defaultValue = 50,\n min = 0,\n max = 100,\n step = 1,\n onChange,\n showTooltip = \"drag\",\n leftIcon,\n rightIcon,\n railBackground,\n accent,\n className,\n disabled = false,\n}) => {\n const isControlled = controlledValue !== undefined;\n const [internalValue, setInternalValue] = useState(defaultValue);\n const [isDragging, setIsDragging] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const trackRef = useRef<HTMLDivElement>(null);\n const thumbRef = useRef<HTMLDivElement>(null);\n\n const value = isControlled ? controlledValue! : internalValue;\n const pct = (clamp(value, min, max) - min) / (max - min);\n\n const accentVars = accent\n ? accentToCssVars(deriveAccent(accent), \"slider\")\n : {};\n\n const setValue = useCallback(\n (next: number) => {\n const snapped = clamp(snapToStep(next, min, step), min, max);\n if (!isControlled) setInternalValue(snapped);\n onChange?.(snapped);\n },\n [isControlled, min, max, step, onChange]\n );\n\n const valueFromPointer = useCallback(\n (e: PointerEvent) => {\n const rect = trackRef.current!.getBoundingClientRect();\n const ratio = clamp((e.clientX - rect.left) / rect.width, 0, 1);\n return min + ratio * (max - min);\n },\n [min, max]\n );\n\n const handlePointerDown = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (disabled) return;\n e.currentTarget.setPointerCapture(e.pointerId);\n setIsDragging(true);\n thumbRef.current?.focus();\n setValue(valueFromPointer(e.nativeEvent));\n },\n [disabled, setValue, valueFromPointer]\n );\n\n const handlePointerMove = useCallback(\n (e: React.PointerEvent<HTMLDivElement>) => {\n if (!isDragging || disabled) return;\n setValue(valueFromPointer(e.nativeEvent));\n },\n [isDragging, disabled, setValue, valueFromPointer]\n );\n\n const handlePointerUp = useCallback(() => {\n setIsDragging(false);\n thumbRef.current?.blur();\n }, []);\n\n useEffect(() => {\n const el = trackRef.current;\n if (!el) return;\n const onWheel = (e: WheelEvent) => {\n if (disabled) return;\n e.preventDefault();\n setValue(value + (e.deltaY < 0 ? step : -step));\n };\n el.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => el.removeEventListener(\"wheel\", onWheel);\n }, [disabled, value, step, setValue]);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (disabled) return;\n const map: Record<string, number> = {\n ArrowRight: step,\n ArrowUp: step,\n ArrowLeft: -step,\n ArrowDown: -step,\n PageUp: step * 10,\n PageDown: -step * 10,\n };\n if (e.key === \"Home\") { setValue(min); e.preventDefault(); return; }\n if (e.key === \"End\") { setValue(max); e.preventDefault(); return; }\n if (map[e.key] !== undefined) {\n setValue(value + map[e.key]);\n e.preventDefault();\n }\n },\n [disabled, step, min, max, value, setValue]\n );\n\n const tooltipVisible =\n showTooltip === \"always\" ||\n (showTooltip === \"drag\" && (isDragging || isFocused));\n\n const displayValue = `${Math.round(value)}%`;\n\n // Clamp tooltip so it doesn't overflow the track edges\n const tooltipOffset = `calc(${pct * 100}% + ${(0.5 - pct) * 20}px)`;\n\n return (\n <div\n className={[styles.wrapper, disabled ? styles.disabled : \"\", className ?? \"\"].filter(Boolean).join(\" \")}\n style={accentVars as React.CSSProperties}\n >\n {leftIcon !== null && leftIcon !== undefined && (\n <span className={styles.icon}>{leftIcon}</span>\n )}\n\n <div\n ref={trackRef}\n className={styles.trackArea}\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n >\n <div className={styles.groove}>\n <div\n className={styles.rail}\n style={railBackground ? { background: railBackground } : undefined}\n >\n {!railBackground && (\n <div className={styles.fill} style={{ width: `${pct * 100}%` }} />\n )}\n </div>\n </div>\n\n <div\n ref={thumbRef}\n role=\"slider\"\n tabIndex={disabled ? -1 : 0}\n aria-valuenow={Math.round(value)}\n aria-valuemin={min}\n aria-valuemax={max}\n aria-disabled={disabled}\n className={[styles.thumb, isDragging ? styles.thumbDragging : \"\"].filter(Boolean).join(\" \")}\n style={{ left: `calc(${pct * 100}% + ${(0.5 - pct) * 24}px)` }}\n onKeyDown={handleKeyDown}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n />\n\n <div\n className={[styles.tooltip, tooltipVisible ? styles.tooltipVisible : \"\"].filter(Boolean).join(\" \")}\n style={{ left: tooltipOffset }}\n aria-hidden=\"true\"\n >\n {displayValue}\n </div>\n </div>\n\n {rightIcon !== null && rightIcon !== undefined && (\n <span className={styles.icon}>{rightIcon}</span>\n )}\n </div>\n );\n};\n\nSliderControl.displayName = \"SliderControl\";\n"]}
@@ -0,0 +1,202 @@
1
+ @import "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap";
2
+
3
+ /* src/components/SliderControl/SliderControl.module.scss */
4
+ :root {
5
+ --accent: #3b82f6;
6
+ --accent-dot: rgb(82.52, 145, 247.08);
7
+ --accent-track: #3b82f6;
8
+ --accent-ring: #3b82f6;
9
+ --accent-glow: rgba(59, 130, 246, 0.3);
10
+ --accent-light: rgb(157.485, 188.725, 239.765);
11
+ --color-primary-50: rgb(169.3455, 194.6925, 236.1045);
12
+ --color-primary-100: rgb(149.4545, 184.4575, 241.6455);
13
+ --color-primary-400: rgb(82.52, 145, 247.08);
14
+ --color-primary-500: #3b82f6;
15
+ --color-primary-600: rgb(29.8390243902, 111.4024390244, 244.6609756098);
16
+ --color-primary-700: rgb(10.712195122, 95.2195121951, 233.287804878);
17
+ --color-neutral-0: #ffffff;
18
+ --color-neutral-100: #f3f4f6;
19
+ --color-neutral-200: #e5e7eb;
20
+ --color-neutral-400: #9ca3af;
21
+ --color-neutral-600: #4b5563;
22
+ --color-neutral-900: #111827;
23
+ --color-success-500: #22c55e;
24
+ --color-success-600: #16a34a;
25
+ --color-danger-500: #ef4444;
26
+ --color-danger-600: #dc2626;
27
+ --color-warning-500: #f59e0b;
28
+ --color-warning-600: #d97706;
29
+ --font-family-base:
30
+ "Inter",
31
+ system-ui,
32
+ -apple-system,
33
+ sans-serif;
34
+ --font-size-xs: 0.75rem;
35
+ --font-size-sm: 0.875rem;
36
+ --font-size-md: 1rem;
37
+ --font-size-lg: 1.125rem;
38
+ --spacing-1: 0.25rem;
39
+ --spacing-2: 0.5rem;
40
+ --spacing-3: 0.75rem;
41
+ --spacing-4: 1rem;
42
+ --radius-sm: 0.25rem;
43
+ --radius-md: 0.375rem;
44
+ --radius-lg: 0.5rem;
45
+ --radius-full: 9999px;
46
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
47
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
48
+ --transition-fast: 150ms ease;
49
+ --color-surface: #ffffff;
50
+ --color-surface-elevated: #ffffff;
51
+ }
52
+ [data-theme=dark] {
53
+ --color-neutral-0: #0f172a;
54
+ --color-neutral-100: #1e293b;
55
+ --color-neutral-200: #334155;
56
+ --color-neutral-400: #94a3b8;
57
+ --color-neutral-600: #cbd5e1;
58
+ --color-neutral-900: #f8fafc;
59
+ --color-surface: #1e293b;
60
+ --color-surface-elevated: #273549;
61
+ --color-primary-50: #172554;
62
+ --color-primary-100: #1e3a8a;
63
+ --accent-light: #172554;
64
+ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.4);
65
+ --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.5), 0 2px 4px -2px rgb(0 0 0 / 0.4);
66
+ }
67
+ .SliderControl_module_wrapper3 {
68
+ display: flex;
69
+ align-items: center;
70
+ gap: 10px;
71
+ font-family: var(--font-family-base);
72
+ user-select: none;
73
+ -webkit-user-select: none;
74
+ }
75
+ .SliderControl_module_disabled3 {
76
+ opacity: 0.45;
77
+ pointer-events: none;
78
+ }
79
+ .SliderControl_module_icon3 {
80
+ display: flex;
81
+ align-items: center;
82
+ justify-content: center;
83
+ color: var(--color-neutral-400);
84
+ flex-shrink: 0;
85
+ line-height: 0;
86
+ }
87
+ .SliderControl_module_trackArea3 {
88
+ position: relative;
89
+ flex: 1;
90
+ height: 36px;
91
+ display: flex;
92
+ align-items: center;
93
+ cursor: pointer;
94
+ }
95
+ .SliderControl_module_groove3 {
96
+ position: relative;
97
+ width: 100%;
98
+ height: 22px;
99
+ border-radius: var(--radius-full);
100
+ background: var(--color-neutral-300);
101
+ display: flex;
102
+ align-items: center;
103
+ box-shadow:
104
+ inset 0 4px 8px rgba(0, 0, 0, 0.14),
105
+ inset 0 2px 4px rgba(0, 0, 0, 0.06),
106
+ inset 0 -2px 3px rgba(255, 255, 255, 0.1);
107
+ }
108
+ .SliderControl_module_rail3 {
109
+ position: absolute;
110
+ left: 8px;
111
+ right: 8px;
112
+ height: 6px;
113
+ border-radius: var(--radius-full);
114
+ background: var(--color-neutral-400);
115
+ box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.3), inset 0 1px 1px rgba(0, 0, 0, 0.18);
116
+ overflow: hidden;
117
+ }
118
+ .SliderControl_module_fill3 {
119
+ position: absolute;
120
+ top: 0;
121
+ left: 0;
122
+ height: 100%;
123
+ background: var(--slider-accent-track, var(--accent-track));
124
+ border-radius: var(--radius-full);
125
+ transition: width 60ms linear;
126
+ }
127
+ .SliderControl_module_thumb3 {
128
+ position: absolute;
129
+ top: 50%;
130
+ width: 18px;
131
+ height: 18px;
132
+ border-radius: 50%;
133
+ transform: translate(-50%, -50%);
134
+ background: #dde0e6;
135
+ border: 1px solid rgba(0, 0, 0, 0.1);
136
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);
137
+ cursor: grab;
138
+ transition: box-shadow 120ms ease, transform 120ms ease;
139
+ outline: none;
140
+ z-index: 2;
141
+ }
142
+ .SliderControl_module_thumb3:focus-visible {
143
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22), 0 0 0 3px var(--slider-accent-ring, var(--accent-ring));
144
+ }
145
+ .SliderControl_module_thumbDragging3 {
146
+ cursor: grabbing;
147
+ transform: translate(-50%, -50%) scale(1.08);
148
+ box-shadow:
149
+ 0 1px 4px rgba(0, 0, 0, 0.28),
150
+ 0 0 0 3px var(--slider-accent-ring, var(--accent-ring)),
151
+ 0 0 0 6px var(--slider-accent-glow, var(--accent-glow));
152
+ }
153
+ .SliderControl_module_tooltip3 {
154
+ position: absolute;
155
+ bottom: calc(100% + 6px);
156
+ transform: translateX(-50%);
157
+ background: rgba(18, 18, 26, 0.85);
158
+ backdrop-filter: blur(6px);
159
+ -webkit-backdrop-filter: blur(6px);
160
+ color: #fff;
161
+ font-size: 11px;
162
+ font-weight: 600;
163
+ letter-spacing: 0.02em;
164
+ padding: 3px 8px;
165
+ border-radius: 6px;
166
+ white-space: nowrap;
167
+ pointer-events: none;
168
+ opacity: 0;
169
+ transition: opacity 120ms ease;
170
+ z-index: 10;
171
+ }
172
+ .SliderControl_module_tooltip3::after {
173
+ content: "";
174
+ position: absolute;
175
+ top: 100%;
176
+ left: 50%;
177
+ transform: translateX(-50%);
178
+ border: 4px solid transparent;
179
+ border-top-color: rgba(18, 18, 26, 0.85);
180
+ }
181
+ .SliderControl_module_tooltipVisible3 {
182
+ opacity: 1;
183
+ }
184
+ [data-theme=dark] .SliderControl_module_groove3 {
185
+ box-shadow:
186
+ inset 0 1px 0 rgba(255, 255, 255, 0.07),
187
+ inset 0 3px 7px rgba(0, 0, 0, 0.32),
188
+ inset 0 1px 3px rgba(0, 0, 0, 0.22),
189
+ inset 0 -2px 3px rgba(255, 255, 255, 0.04);
190
+ }
191
+ [data-theme=dark] .SliderControl_module_thumb3 {
192
+ background: #4a4f5c;
193
+ border-color: rgba(255, 255, 255, 0.08);
194
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);
195
+ }
196
+ [data-theme=dark] .SliderControl_module_thumbDragging3 {
197
+ box-shadow:
198
+ 0 1px 4px rgba(0, 0, 0, 0.5),
199
+ 0 0 0 3px var(--slider-accent-ring, var(--accent-ring)),
200
+ 0 0 0 6px var(--slider-accent-glow, var(--accent-glow));
201
+ }
202
+ /*# sourceMappingURL=index.css.map */
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/styles/tokens.scss","../../../src/components/SliderControl/SliderControl.module.scss"],"sourcesContent":["@use \"sass:color\";\n\n@import url(\"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap\");\n\n// Accent di default — cambia qui per aggiornare tutta la libreria\n$accent: #3b82f6;\n\n:root {\n // Accent scale — derivata da $accent a compile time\n --accent: #{$accent};\n --accent-dot: #{color.scale($accent, $lightness: 12%)};\n --accent-track: #{$accent};\n --accent-ring: #{$accent};\n --accent-glow: #{color.change($accent, $alpha: 0.3)};\n --accent-light: #{color.scale($accent, $lightness: 45%, $saturation: -20%)};\n\n // Primary scale (mantenuta per retrocompatibilità con Button, Badge, Input)\n --color-primary-50: #{color.scale($accent, $lightness: 49%, $saturation: -30%)};\n --color-primary-100: #{color.scale($accent, $lightness: 42%, $saturation: -15%)};\n --color-primary-400: #{color.scale($accent, $lightness: 12%)};\n --color-primary-500: #{$accent};\n --color-primary-600: #{color.scale($accent, $lightness: -10%)};\n --color-primary-700: #{color.scale($accent, $lightness: -20%)};\n\n // Neutral\n --color-neutral-0: #ffffff;\n --color-neutral-100: #f3f4f6;\n --color-neutral-200: #e5e7eb;\n --color-neutral-400: #9ca3af;\n --color-neutral-600: #4b5563;\n --color-neutral-900: #111827;\n\n // Semantic\n --color-success-500: #22c55e;\n --color-success-600: #16a34a;\n --color-danger-500: #ef4444;\n --color-danger-600: #dc2626;\n --color-warning-500: #f59e0b;\n --color-warning-600: #d97706;\n\n // Typography\n --font-family-base: \"Inter\", system-ui, -apple-system, sans-serif;\n --font-size-xs: 0.75rem;\n --font-size-sm: 0.875rem;\n --font-size-md: 1rem;\n --font-size-lg: 1.125rem;\n\n // Spacing\n --spacing-1: 0.25rem;\n --spacing-2: 0.5rem;\n --spacing-3: 0.75rem;\n --spacing-4: 1rem;\n\n // Radius\n --radius-sm: 0.25rem;\n --radius-md: 0.375rem;\n --radius-lg: 0.5rem;\n --radius-full: 9999px;\n\n // Shadows\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);\n\n // Transitions\n --transition-fast: 150ms ease;\n\n // Surface (background di card/panel)\n --color-surface: #ffffff;\n --color-surface-elevated: #ffffff;\n}\n\n// ─── Dark theme ────────────────────────────────────────────────────────────────\n// Applicato via data-theme=\"dark\" sull'elemento root (gestito da Storybook decorator\n// e dall'app consumer). I componenti non devono fare nulla di speciale: basta che\n// usino i token var() e riceveranno automaticamente i valori dark.\n\n[data-theme=\"dark\"] {\n // Neutral (scala invertita)\n --color-neutral-0: #0f172a;\n --color-neutral-100: #1e293b;\n --color-neutral-200: #334155;\n --color-neutral-400: #94a3b8;\n --color-neutral-600: #cbd5e1;\n --color-neutral-900: #f8fafc;\n\n // Surface\n --color-surface: #1e293b;\n --color-surface-elevated: #273549;\n\n // Primary scale dark (per il default accent blu — le sfumature chiare diventano scure)\n --color-primary-50: #172554;\n --color-primary-100: #1e3a8a;\n // 400 / 500 / 600 / 700 rimangono invariati (abbastanza saturi su bg scuro)\n\n // Accent light: variante scura\n --accent-light: #172554;\n\n // Shadows (più forti su bg scuro)\n --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.4);\n --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.5), 0 2px 4px -2px rgb(0 0 0 / 0.4);\n}\n","@use \"../../styles/tokens\" as *;\n\n$accent-track: var(--slider-accent-track, var(--accent-track));\n$accent-ring: var(--slider-accent-ring, var(--accent-ring));\n$accent-glow: var(--slider-accent-glow, var(--accent-glow));\n\n$groove-height: 22px;\n$rail-height: 6px;\n$thumb-size: 18px;\n$hit-zone: 36px;\n\n.wrapper {\n display: flex;\n align-items: center;\n gap: 10px;\n font-family: var(--font-family-base);\n user-select: none;\n -webkit-user-select: none;\n}\n\n.disabled {\n opacity: 0.45;\n pointer-events: none;\n}\n\n.icon {\n display: flex;\n align-items: center;\n justify-content: center;\n color: var(--color-neutral-400);\n flex-shrink: 0;\n line-height: 0;\n}\n\n// ── Hit zone ───────────────────────────────────────────────────────────────────\n.trackArea {\n position: relative;\n flex: 1;\n height: $hit-zone;\n display: flex;\n align-items: center;\n cursor: pointer;\n}\n\n// ── Groove — the carved channel, >= thumb size ─────────────────────────────────\n.groove {\n position: relative;\n width: 100%;\n height: $groove-height;\n border-radius: var(--radius-full);\n background: var(--color-neutral-300);\n display: flex;\n align-items: center;\n // purely inset: no outer shadow\n box-shadow:\n inset 0 4px 8px rgba(0, 0, 0, 0.14),\n inset 0 2px 4px rgba(0, 0, 0, 0.06),\n inset 0 -2px 3px rgba(255, 255, 255, 0.10);\n}\n\n// ── Rail — thin line inside the groove where fill runs ─────────────────────────\n.rail {\n position: absolute;\n left: 8px;\n right: 8px;\n height: $rail-height;\n border-radius: var(--radius-full);\n background: var(--color-neutral-400);\n box-shadow:\n inset 0 1px 3px rgba(0, 0, 0, 0.30),\n inset 0 1px 1px rgba(0, 0, 0, 0.18);\n overflow: hidden;\n}\n\n// ── Fill ───────────────────────────────────────────────────────────────────────\n.fill {\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n background: $accent-track;\n border-radius: var(--radius-full);\n transition: width 60ms linear;\n}\n\n// ── Thumb ──────────────────────────────────────────────────────────────────────\n.thumb {\n position: absolute;\n top: 50%;\n width: $thumb-size;\n height: $thumb-size;\n border-radius: 50%;\n transform: translate(-50%, -50%);\n background: #dde0e6;\n border: 1px solid rgba(0, 0, 0, 0.10);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.22);\n cursor: grab;\n transition: box-shadow 120ms ease, transform 120ms ease;\n outline: none;\n z-index: 2;\n}\n\n.thumb:focus-visible {\n box-shadow:\n 0 1px 3px rgba(0, 0, 0, 0.22),\n 0 0 0 3px $accent-ring;\n}\n\n.thumbDragging {\n cursor: grabbing;\n transform: translate(-50%, -50%) scale(1.08);\n box-shadow:\n 0 1px 4px rgba(0, 0, 0, 0.28),\n 0 0 0 3px $accent-ring,\n 0 0 0 6px $accent-glow;\n}\n\n// ── Tooltip ────────────────────────────────────────────────────────────────────\n.tooltip {\n position: absolute;\n bottom: calc(100% + 6px);\n transform: translateX(-50%);\n background: rgba(18, 18, 26, 0.85);\n backdrop-filter: blur(6px);\n -webkit-backdrop-filter: blur(6px);\n color: #fff;\n font-size: 11px;\n font-weight: 600;\n letter-spacing: 0.02em;\n padding: 3px 8px;\n border-radius: 6px;\n white-space: nowrap;\n pointer-events: none;\n opacity: 0;\n transition: opacity 120ms ease;\n z-index: 10;\n\n &::after {\n content: \"\";\n position: absolute;\n top: 100%;\n left: 50%;\n transform: translateX(-50%);\n border: 4px solid transparent;\n border-top-color: rgba(18, 18, 26, 0.85);\n }\n}\n\n.tooltipVisible {\n opacity: 1;\n}\n\n// ── Dark mode ──────────────────────────────────────────────────────────────────\n[data-theme=\"dark\"] {\n .groove {\n box-shadow:\n inset 0 1px 0 rgba(255, 255, 255, 0.07),\n inset 0 3px 7px rgba(0, 0, 0, 0.32),\n inset 0 1px 3px rgba(0, 0, 0, 0.22),\n inset 0 -2px 3px rgba(255, 255, 255, 0.04);\n }\n\n .thumb {\n background: #4a4f5c;\n border-color: rgba(255, 255, 255, 0.08);\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.45);\n }\n\n .thumbDragging {\n box-shadow:\n 0 1px 4px rgba(0, 0, 0, 0.5),\n 0 0 0 3px $accent-ring,\n 0 0 0 6px $accent-glow;\n }\n}\n"],"mappings":"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","names":["wrapper","disabled","icon","trackArea","groove","rail","fill","thumb","thumbDragging","tooltip","tooltipVisible"]}
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+
3
+ interface SliderControlProps {
4
+ value?: number;
5
+ defaultValue?: number;
6
+ min?: number;
7
+ max?: number;
8
+ step?: number;
9
+ onChange?: (value: number) => void;
10
+ showTooltip?: "always" | "drag" | "never";
11
+ leftIcon?: React.ReactNode;
12
+ rightIcon?: React.ReactNode;
13
+ /** CSS background value applied to the rail — replaces the fill with a full-width gradient */
14
+ railBackground?: string;
15
+ accent?: string;
16
+ className?: string;
17
+ disabled?: boolean;
18
+ }
19
+ declare const SliderControl: React.FC<SliderControlProps>;
20
+
21
+ export { SliderControl, type SliderControlProps };
@@ -0,0 +1,21 @@
1
+ import React from 'react';
2
+
3
+ interface SliderControlProps {
4
+ value?: number;
5
+ defaultValue?: number;
6
+ min?: number;
7
+ max?: number;
8
+ step?: number;
9
+ onChange?: (value: number) => void;
10
+ showTooltip?: "always" | "drag" | "never";
11
+ leftIcon?: React.ReactNode;
12
+ rightIcon?: React.ReactNode;
13
+ /** CSS background value applied to the rail — replaces the fill with a full-width gradient */
14
+ railBackground?: string;
15
+ accent?: string;
16
+ className?: string;
17
+ disabled?: boolean;
18
+ }
19
+ declare const SliderControl: React.FC<SliderControlProps>;
20
+
21
+ export { SliderControl, type SliderControlProps };