@bug-on/m3-expressive 1.0.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.
Files changed (98) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/README.md +110 -0
  3. package/dist/assets/fonts/GoogleSansFlex-VariableFont.woff2 +0 -0
  4. package/dist/assets/fonts/MaterialSymbolsOutlined-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  5. package/dist/assets/fonts/MaterialSymbolsRounded-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  6. package/dist/assets/fonts/MaterialSymbolsSharp-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  7. package/dist/assets/loading-indicator.svg +19 -0
  8. package/dist/assets/material-symbols-cdn.css +65 -0
  9. package/dist/assets/material-symbols-self-hosted.css +94 -0
  10. package/dist/buttons.d.mts +180 -0
  11. package/dist/buttons.d.ts +180 -0
  12. package/dist/buttons.js +4282 -0
  13. package/dist/buttons.js.map +1 -0
  14. package/dist/buttons.mjs +4227 -0
  15. package/dist/buttons.mjs.map +1 -0
  16. package/dist/core.d.mts +422 -0
  17. package/dist/core.d.ts +422 -0
  18. package/dist/core.js +2581 -0
  19. package/dist/core.js.map +1 -0
  20. package/dist/core.mjs +2547 -0
  21. package/dist/core.mjs.map +1 -0
  22. package/dist/feedback.d.mts +600 -0
  23. package/dist/feedback.d.ts +600 -0
  24. package/dist/feedback.js +2357 -0
  25. package/dist/feedback.js.map +1 -0
  26. package/dist/feedback.mjs +2321 -0
  27. package/dist/feedback.mjs.map +1 -0
  28. package/dist/forms.d.mts +40 -0
  29. package/dist/forms.d.ts +40 -0
  30. package/dist/forms.js +4263 -0
  31. package/dist/forms.js.map +1 -0
  32. package/dist/forms.mjs +4228 -0
  33. package/dist/forms.mjs.map +1 -0
  34. package/dist/icon-button-D-gs0gfj.d.mts +136 -0
  35. package/dist/icon-button-D-gs0gfj.d.ts +136 -0
  36. package/dist/index.css +309 -0
  37. package/dist/index.css.d.ts +2 -0
  38. package/dist/index.d.mts +24 -0
  39. package/dist/index.d.ts +24 -0
  40. package/dist/index.js +23972 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/index.mjs +23668 -0
  43. package/dist/index.mjs.map +1 -0
  44. package/dist/layout.d.mts +610 -0
  45. package/dist/layout.d.ts +610 -0
  46. package/dist/layout.js +5091 -0
  47. package/dist/layout.js.map +1 -0
  48. package/dist/layout.mjs +5042 -0
  49. package/dist/layout.mjs.map +1 -0
  50. package/dist/material-symbols-cdn.css +65 -0
  51. package/dist/material-symbols-cdn.css.d.ts +2 -0
  52. package/dist/material-symbols-self-hosted.css +94 -0
  53. package/dist/material-symbols-self-hosted.css.d.ts +2 -0
  54. package/dist/md3-DFhj-NZj.d.mts +17 -0
  55. package/dist/md3-DFhj-NZj.d.ts +17 -0
  56. package/dist/navigation.d.mts +2766 -0
  57. package/dist/navigation.d.ts +2766 -0
  58. package/dist/navigation.js +6684 -0
  59. package/dist/navigation.js.map +1 -0
  60. package/dist/navigation.mjs +6573 -0
  61. package/dist/navigation.mjs.map +1 -0
  62. package/dist/overlays.d.mts +161 -0
  63. package/dist/overlays.d.ts +161 -0
  64. package/dist/overlays.js +3298 -0
  65. package/dist/overlays.js.map +1 -0
  66. package/dist/overlays.mjs +3244 -0
  67. package/dist/overlays.mjs.map +1 -0
  68. package/dist/pickers.d.mts +1074 -0
  69. package/dist/pickers.d.ts +1074 -0
  70. package/dist/pickers.js +4240 -0
  71. package/dist/pickers.js.map +1 -0
  72. package/dist/pickers.mjs +4200 -0
  73. package/dist/pickers.mjs.map +1 -0
  74. package/dist/plugin.d.mts +1 -0
  75. package/dist/plugin.d.ts +1 -0
  76. package/dist/plugin.js +13 -0
  77. package/dist/plugin.js.map +1 -0
  78. package/dist/plugin.mjs +3 -0
  79. package/dist/plugin.mjs.map +1 -0
  80. package/dist/scroll-area-CVS6HyLl.d.mts +33 -0
  81. package/dist/scroll-area-CVS6HyLl.d.ts +33 -0
  82. package/dist/shapes.d.mts +1119 -0
  83. package/dist/shapes.d.ts +1119 -0
  84. package/dist/shapes.js +2941 -0
  85. package/dist/shapes.js.map +1 -0
  86. package/dist/shapes.mjs +2889 -0
  87. package/dist/shapes.mjs.map +1 -0
  88. package/dist/side-sheet-modal-BY6VCC8p.d.mts +553 -0
  89. package/dist/side-sheet-modal-CglP6KYA.d.ts +553 -0
  90. package/dist/split-button-trailing-uncheckable-C5CLCIKP.d.ts +731 -0
  91. package/dist/split-button-trailing-uncheckable-MXj_kyNt.d.mts +731 -0
  92. package/dist/text-field-eAIpz9z1.d.mts +1038 -0
  93. package/dist/text-field-eAIpz9z1.d.ts +1038 -0
  94. package/dist/typography-339RV6v7.d.mts +486 -0
  95. package/dist/typography-339RV6v7.d.ts +486 -0
  96. package/dist/typography.css +22 -0
  97. package/dist/typography.css.d.ts +2 -0
  98. package/package.json +207 -0
package/dist/forms.js ADDED
@@ -0,0 +1,4263 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('motion/react');
5
+ var React4 = require('react');
6
+ var clsx = require('clsx');
7
+ var tailwindMerge = require('tailwind-merge');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+ var classVarianceAuthority = require('class-variance-authority');
10
+ var RadixScrollArea = require('@radix-ui/react-scroll-area');
11
+
12
+ function _interopNamespace(e) {
13
+ if (e && e.__esModule) return e;
14
+ var n = Object.create(null);
15
+ if (e) {
16
+ Object.keys(e).forEach(function (k) {
17
+ if (k !== 'default') {
18
+ var d = Object.getOwnPropertyDescriptor(e, k);
19
+ Object.defineProperty(n, k, d.get ? d : {
20
+ enumerable: true,
21
+ get: function () { return e[k]; }
22
+ });
23
+ }
24
+ });
25
+ }
26
+ n.default = e;
27
+ return Object.freeze(n);
28
+ }
29
+
30
+ var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
31
+ var RadixScrollArea__namespace = /*#__PURE__*/_interopNamespace(RadixScrollArea);
32
+
33
+ var __defProp = Object.defineProperty;
34
+ var __defProps = Object.defineProperties;
35
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
36
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
37
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
38
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
39
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
40
+ var __spreadValues = (a, b) => {
41
+ for (var prop in b || (b = {}))
42
+ if (__hasOwnProp.call(b, prop))
43
+ __defNormalProp(a, prop, b[prop]);
44
+ if (__getOwnPropSymbols)
45
+ for (var prop of __getOwnPropSymbols(b)) {
46
+ if (__propIsEnum.call(b, prop))
47
+ __defNormalProp(a, prop, b[prop]);
48
+ }
49
+ return a;
50
+ };
51
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
52
+ var __objRest = (source, exclude) => {
53
+ var target = {};
54
+ for (var prop in source)
55
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
56
+ target[prop] = source[prop];
57
+ if (source != null && __getOwnPropSymbols)
58
+ for (var prop of __getOwnPropSymbols(source)) {
59
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
60
+ target[prop] = source[prop];
61
+ }
62
+ return target;
63
+ };
64
+ function cn(...inputs) {
65
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
66
+ }
67
+ var RippleItem = React4__namespace.memo(function RippleItem2({
68
+ ripple,
69
+ onDone
70
+ }) {
71
+ return /* @__PURE__ */ jsxRuntime.jsx(
72
+ react.m.span,
73
+ {
74
+ "aria-hidden": "true",
75
+ style: {
76
+ position: "absolute",
77
+ left: ripple.x - ripple.size / 2,
78
+ top: ripple.y - ripple.size / 2,
79
+ width: ripple.size,
80
+ height: ripple.size,
81
+ borderRadius: "50%",
82
+ backgroundColor: "currentColor",
83
+ pointerEvents: "none",
84
+ transformOrigin: "center"
85
+ },
86
+ initial: { scale: 0, opacity: 0.12 },
87
+ animate: { scale: 1, opacity: 0 },
88
+ exit: { opacity: 0 },
89
+ transition: {
90
+ scale: { duration: 0.5, ease: [0.2, 0, 0, 1] },
91
+ opacity: { duration: 0.4, ease: "easeOut", delay: 0.1 }
92
+ },
93
+ onAnimationComplete: () => onDone(ripple.id)
94
+ },
95
+ ripple.id
96
+ );
97
+ });
98
+ function Ripple({
99
+ ripples,
100
+ onRippleDone,
101
+ disabled = false,
102
+ respectSystemMotion = true
103
+ }) {
104
+ const prefersReduced = react.useReducedMotion();
105
+ if (disabled) return null;
106
+ if (respectSystemMotion && prefersReduced) return null;
107
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: ripples.map((r) => /* @__PURE__ */ jsxRuntime.jsx(RippleItem, { ripple: r, onDone: onRippleDone }, r.id)) });
108
+ }
109
+ function useRippleState(options = {}) {
110
+ const { disabled = false } = options;
111
+ const [ripples, setRipples] = React4__namespace.useState([]);
112
+ const onPointerDown = React4__namespace.useCallback(
113
+ (e) => {
114
+ if (disabled) return;
115
+ const rect = e.currentTarget.getBoundingClientRect();
116
+ const x = e.clientX - rect.left;
117
+ const y = e.clientY - rect.top;
118
+ const rippleSize = Math.hypot(rect.width, rect.height) * 2;
119
+ setRipples((prev) => [
120
+ ...prev,
121
+ { id: Date.now(), x, y, size: rippleSize }
122
+ ]);
123
+ },
124
+ [disabled]
125
+ );
126
+ const removeRipple = React4__namespace.useCallback((id) => {
127
+ setRipples((prev) => prev.filter((r) => r.id !== id));
128
+ }, []);
129
+ return { ripples, onPointerDown, removeRipple };
130
+ }
131
+ var MD3_STANDARD = [0.2, 0, 0, 1];
132
+ var MD3_FAST_EFFECTS = [0.3, 0, 1, 1];
133
+ var CHECKMARK_PATH = "M 4.5 9.5 L 7.5 12.5 L 13.5 5.5";
134
+ var DASH_PATH = "M 4.5 9 L 9 9 L 13.5 9";
135
+ function resolveState(checked, indeterminate, state) {
136
+ if (state !== void 0) return state;
137
+ return checked ? "checked" : "unchecked";
138
+ }
139
+ var NEXT_STATE = {
140
+ unchecked: "checked",
141
+ checked: "indeterminate",
142
+ indeterminate: "unchecked"
143
+ };
144
+ var CheckboxVisual = React4__namespace.memo(function CheckboxVisual2({
145
+ isSelected,
146
+ isIndeterminate,
147
+ containerBg,
148
+ containerBorderColor,
149
+ containerBorderWidth,
150
+ iconColor,
151
+ svgPath,
152
+ pathLength,
153
+ fillDuration,
154
+ drawDuration,
155
+ morphDuration,
156
+ prefersReduced
157
+ }) {
158
+ return /* @__PURE__ */ jsxRuntime.jsx(
159
+ react.m.div,
160
+ {
161
+ "aria-hidden": "true",
162
+ className: "relative flex items-center justify-center w-4.5 h-4.5 rounded-sm overflow-hidden",
163
+ animate: {
164
+ backgroundColor: containerBg,
165
+ borderColor: containerBorderColor,
166
+ borderWidth: containerBorderWidth
167
+ },
168
+ transition: {
169
+ backgroundColor: {
170
+ duration: fillDuration,
171
+ ease: isSelected ? MD3_FAST_EFFECTS : "easeOut"
172
+ },
173
+ borderColor: { duration: fillDuration, ease: "easeOut" },
174
+ borderWidth: { duration: fillDuration, ease: "easeOut" }
175
+ },
176
+ style: { borderStyle: "solid" },
177
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: isSelected && /* @__PURE__ */ jsxRuntime.jsx(
178
+ react.m.svg,
179
+ {
180
+ viewBox: "0 0 18 18",
181
+ fill: "none",
182
+ strokeLinecap: "round",
183
+ strokeLinejoin: "round",
184
+ width: 18,
185
+ height: 18,
186
+ initial: { opacity: 0 },
187
+ animate: { opacity: 1 },
188
+ exit: { opacity: 0 },
189
+ transition: { duration: prefersReduced ? 0 : 0.1 },
190
+ "aria-hidden": "true",
191
+ children: /* @__PURE__ */ jsxRuntime.jsx(
192
+ react.m.path,
193
+ {
194
+ d: svgPath,
195
+ stroke: iconColor,
196
+ strokeWidth: 2,
197
+ animate: {
198
+ d: svgPath,
199
+ pathLength: isIndeterminate ? 1 : pathLength
200
+ },
201
+ initial: { pathLength: 0 },
202
+ transition: {
203
+ d: { duration: morphDuration, ease: MD3_STANDARD },
204
+ pathLength: { duration: drawDuration, ease: MD3_STANDARD }
205
+ }
206
+ }
207
+ )
208
+ },
209
+ "icon"
210
+ ) })
211
+ }
212
+ );
213
+ });
214
+ function useMergedRef(externalRef, internalRef) {
215
+ return React4__namespace.useCallback(
216
+ (node) => {
217
+ internalRef.current = node;
218
+ if (!externalRef) return;
219
+ if (typeof externalRef === "function") {
220
+ externalRef(node);
221
+ } else {
222
+ externalRef.current = node;
223
+ }
224
+ },
225
+ [externalRef, internalRef]
226
+ );
227
+ }
228
+ var CheckboxComponent = React4__namespace.forwardRef(
229
+ ({
230
+ checked,
231
+ defaultChecked = false,
232
+ indeterminate = false,
233
+ onCheckedChange,
234
+ state: stateProp,
235
+ onStateChange,
236
+ disabled = false,
237
+ error = false,
238
+ label,
239
+ "aria-label": ariaLabel,
240
+ "aria-labelledby": ariaLabelledby,
241
+ "aria-describedby": ariaDescribedby,
242
+ "aria-required": ariaRequired,
243
+ name,
244
+ value,
245
+ id: idProp,
246
+ className
247
+ }, ref) => {
248
+ var _a;
249
+ const prefersReduced = (_a = react.useReducedMotion()) != null ? _a : false;
250
+ const generatedId = React4__namespace.useId();
251
+ const inputId = idProp != null ? idProp : label ? `checkbox-${generatedId}` : void 0;
252
+ const [internalState, setInternalState] = React4__namespace.useState(
253
+ () => defaultChecked ? "checked" : "unchecked"
254
+ );
255
+ const isControlled = stateProp !== void 0 || checked !== void 0;
256
+ const baseState = isControlled ? resolveState(checked, false, stateProp) : internalState;
257
+ const effectiveState = indeterminate ? "indeterminate" : baseState;
258
+ const [ripples, setRipples] = React4__namespace.useState([]);
259
+ const removeRipple = React4__namespace.useCallback(
260
+ (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
261
+ []
262
+ );
263
+ const onPointerDown = React4__namespace.useCallback(
264
+ (e) => {
265
+ if (disabled) return;
266
+ const rect = e.currentTarget.getBoundingClientRect();
267
+ const x = e.clientX - rect.left - 4;
268
+ const y = e.clientY - rect.top - 4;
269
+ const rippleSize = Math.hypot(40, 40) * 2;
270
+ setRipples((prev) => [
271
+ ...prev,
272
+ { id: Date.now(), x, y, size: rippleSize }
273
+ ]);
274
+ },
275
+ [disabled]
276
+ );
277
+ const handleChange = React4__namespace.useCallback(
278
+ (e) => {
279
+ if (disabled) return;
280
+ if (stateProp !== void 0) {
281
+ onStateChange == null ? void 0 : onStateChange(NEXT_STATE[effectiveState]);
282
+ } else if (checked !== void 0) {
283
+ onCheckedChange == null ? void 0 : onCheckedChange(e.target.checked);
284
+ } else {
285
+ const next = NEXT_STATE[effectiveState];
286
+ setInternalState(next);
287
+ if (next === "indeterminate") {
288
+ onStateChange == null ? void 0 : onStateChange(next);
289
+ } else {
290
+ onCheckedChange == null ? void 0 : onCheckedChange(next === "checked");
291
+ }
292
+ }
293
+ },
294
+ [
295
+ disabled,
296
+ stateProp,
297
+ checked,
298
+ effectiveState,
299
+ onStateChange,
300
+ onCheckedChange
301
+ ]
302
+ );
303
+ const inputRef = React4__namespace.useRef(null);
304
+ const mergedRef = useMergedRef(ref, inputRef);
305
+ React4__namespace.useEffect(() => {
306
+ if (inputRef.current) {
307
+ inputRef.current.indeterminate = effectiveState === "indeterminate";
308
+ }
309
+ }, [effectiveState]);
310
+ const isChecked = effectiveState === "checked";
311
+ const isIndeterminate = effectiveState === "indeterminate";
312
+ const isSelected = isChecked || isIndeterminate;
313
+ const ariaChecked = isIndeterminate ? "mixed" : isChecked;
314
+ const accentColor = error ? "var(--color-m3-error)" : "var(--color-m3-primary)";
315
+ const onAccentColor = error ? "var(--color-m3-on-error)" : "var(--color-m3-on-primary)";
316
+ const outlineColor = error ? "var(--color-m3-error)" : "rgba(0, 0, 0, 0.38)";
317
+ const containerBg = isSelected ? accentColor : "rgba(0, 0, 0, 0)";
318
+ const containerBorderColor = isSelected ? "rgba(0, 0, 0, 0)" : outlineColor;
319
+ const containerBorderWidth = isSelected ? 0 : 2;
320
+ const iconColor = isSelected ? onAccentColor : "rgba(0, 0, 0, 0)";
321
+ const svgPath = isIndeterminate ? DASH_PATH : CHECKMARK_PATH;
322
+ const pathLength = isSelected ? 1 : 0;
323
+ const fillDuration = prefersReduced ? 0 : isSelected ? 0.15 : 0.1;
324
+ const drawDuration = prefersReduced ? 0 : isSelected ? 0.2 : 0.1;
325
+ const morphDuration = prefersReduced ? 0 : 0.2;
326
+ const stateLayerBg = isSelected ? error ? "before:bg-m3-error" : "before:bg-m3-primary" : error ? "before:bg-m3-error" : "before:bg-m3-on-surface";
327
+ const stateLayerClass = cn(
328
+ "before:absolute before:inset-0 before:rounded-full before:pointer-events-none",
329
+ "before:transition-opacity before:duration-150 before:opacity-0",
330
+ "group-hover/cbx:before:opacity-[0.08]",
331
+ "group-focus-within/cbx:before:opacity-[0.10]",
332
+ "group-active/cbx:before:opacity-[0.10]",
333
+ stateLayerBg
334
+ );
335
+ const visualProps = {
336
+ isSelected,
337
+ isIndeterminate,
338
+ containerBg,
339
+ containerBorderColor,
340
+ containerBorderWidth,
341
+ iconColor,
342
+ svgPath,
343
+ pathLength,
344
+ fillDuration,
345
+ drawDuration,
346
+ morphDuration,
347
+ prefersReduced
348
+ };
349
+ const touchTargetClass = cn(
350
+ "relative inline-flex items-center justify-center outline-none shrink-0",
351
+ "w-12 h-12 group/cbx",
352
+ disabled && "pointer-events-none"
353
+ );
354
+ const stateLayerAndRipple = /* @__PURE__ */ jsxRuntime.jsx(
355
+ "div",
356
+ {
357
+ className: cn(
358
+ "absolute flex items-center justify-center w-10 h-10 m-auto inset-0 rounded-full overflow-hidden pointer-events-none",
359
+ stateLayerClass
360
+ ),
361
+ "aria-hidden": "true",
362
+ children: /* @__PURE__ */ jsxRuntime.jsx(
363
+ Ripple,
364
+ {
365
+ ripples,
366
+ onRippleDone: removeRipple,
367
+ disabled
368
+ }
369
+ )
370
+ }
371
+ );
372
+ const hiddenInput = /* @__PURE__ */ jsxRuntime.jsx(
373
+ "input",
374
+ {
375
+ ref: mergedRef,
376
+ type: "checkbox",
377
+ id: inputId,
378
+ name,
379
+ value,
380
+ checked: isChecked,
381
+ disabled,
382
+ "aria-checked": ariaChecked,
383
+ "aria-disabled": disabled || void 0,
384
+ "aria-invalid": error || void 0,
385
+ "aria-label": ariaLabel,
386
+ "aria-labelledby": ariaLabelledby,
387
+ "aria-describedby": ariaDescribedby,
388
+ "aria-required": ariaRequired,
389
+ onChange: handleChange,
390
+ className: "sr-only"
391
+ }
392
+ );
393
+ if (label) {
394
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
395
+ "label",
396
+ {
397
+ htmlFor: inputId,
398
+ className: cn(
399
+ "inline-flex items-center gap-2 cursor-pointer select-none",
400
+ disabled && "cursor-not-allowed opacity-[0.38] pointer-events-none",
401
+ className
402
+ ),
403
+ children: [
404
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: touchTargetClass, onPointerDown, children: [
405
+ stateLayerAndRipple,
406
+ hiddenInput,
407
+ /* @__PURE__ */ jsxRuntime.jsx(CheckboxVisual, __spreadValues({}, visualProps))
408
+ ] }),
409
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-none text-m3-on-surface", children: label })
410
+ ]
411
+ }
412
+ ) });
413
+ }
414
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
415
+ "label",
416
+ {
417
+ htmlFor: inputId,
418
+ className: cn(touchTargetClass, "cursor-pointer", className),
419
+ onPointerDown,
420
+ children: [
421
+ stateLayerAndRipple,
422
+ hiddenInput,
423
+ /* @__PURE__ */ jsxRuntime.jsx(CheckboxVisual, __spreadValues({}, visualProps))
424
+ ]
425
+ }
426
+ ) });
427
+ }
428
+ );
429
+ CheckboxComponent.displayName = "Checkbox";
430
+ var Checkbox = React4__namespace.memo(CheckboxComponent);
431
+ var TriStateCheckboxComponent = React4__namespace.forwardRef((_a, ref) => {
432
+ var _b = _a, { state, onStateChange } = _b, rest = __objRest(_b, ["state", "onStateChange"]);
433
+ return /* @__PURE__ */ jsxRuntime.jsx(Checkbox, __spreadValues({ ref, state, onStateChange }, rest));
434
+ });
435
+ TriStateCheckboxComponent.displayName = "TriStateCheckbox";
436
+ var TriStateCheckbox = React4__namespace.memo(TriStateCheckboxComponent);
437
+ function CheckIcon({ className }) {
438
+ return /* @__PURE__ */ jsxRuntime.jsx(
439
+ "svg",
440
+ {
441
+ xmlns: "http://www.w3.org/2000/svg",
442
+ viewBox: "0 0 24 24",
443
+ width: 18,
444
+ height: 18,
445
+ fill: "none",
446
+ stroke: "currentColor",
447
+ strokeWidth: 2.5,
448
+ strokeLinecap: "round",
449
+ strokeLinejoin: "round",
450
+ "aria-hidden": "true",
451
+ className,
452
+ children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" })
453
+ }
454
+ );
455
+ }
456
+ function CloseIcon({ className }) {
457
+ return /* @__PURE__ */ jsxRuntime.jsxs(
458
+ "svg",
459
+ {
460
+ xmlns: "http://www.w3.org/2000/svg",
461
+ viewBox: "0 0 24 24",
462
+ width: 18,
463
+ height: 18,
464
+ fill: "none",
465
+ stroke: "currentColor",
466
+ strokeWidth: 2.5,
467
+ strokeLinecap: "round",
468
+ strokeLinejoin: "round",
469
+ "aria-hidden": "true",
470
+ className,
471
+ children: [
472
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
473
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
474
+ ]
475
+ }
476
+ );
477
+ }
478
+ var chipVariants = classVarianceAuthority.cva(
479
+ [
480
+ // Base layout
481
+ "inline-flex items-center h-8 rounded-lg",
482
+ // Typography: LabelLarge
483
+ "text-sm font-medium leading-none",
484
+ // Interaction
485
+ "relative overflow-hidden cursor-pointer select-none",
486
+ "transition-all duration-200 ease-in-out",
487
+ // Remove browser default focus; use MD3 focus ring
488
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-1",
489
+ "focus-visible:ring-m3-secondary",
490
+ // Expressive scale feedback (MD3 "bouncy" press)
491
+ "active:scale-[0.98]",
492
+ // MD3 State Layer (pseudo-element overlay)
493
+ // Use inset-[-1px] to ensure the state layer covers the 1px border perfectly
494
+ "before:absolute before:inset-[-1px] before:pointer-events-none before:rounded-lg",
495
+ "before:transition-opacity before:duration-200 before:opacity-0",
496
+ "hover:before:opacity-[0.08] focus-visible:before:opacity-[0.10] active:before:opacity-[0.10]"
497
+ ].join(" "),
498
+ {
499
+ variants: {
500
+ /**
501
+ * Chip variant controlling default colors and border behavior.
502
+ * Selected/elevated state overrides are applied via `cn()` at runtime.
503
+ */
504
+ variant: {
505
+ /**
506
+ * Assist chip – FlatOutlineColor: outline-variant, LabelTextColor: on-surface
507
+ * Leading icon color: primary (AssistChipTokens.IconColor)
508
+ */
509
+ assist: "border border-m3-outline-variant text-m3-on-surface before:bg-m3-on-surface",
510
+ /**
511
+ * Filter chip (unselected) – FlatUnselectedOutlineColor: outline-variant
512
+ * UnselectedLabelTextColor: on-surface-variant
513
+ */
514
+ filter: "border border-m3-outline-variant text-m3-on-surface-variant before:bg-m3-on-surface-variant",
515
+ /**
516
+ * Input chip (unselected) – UnselectedOutlineColor: outline-variant
517
+ * UnselectedLabelTextColor: on-surface-variant
518
+ */
519
+ input: "border border-m3-outline-variant text-m3-on-surface-variant before:bg-m3-on-surface-variant",
520
+ /**
521
+ * Suggestion chip – FlatOutlineColor: outline-variant
522
+ * LabelTextColor: on-surface-variant (SuggestionChipTokens)
523
+ */
524
+ suggestion: "border border-m3-outline-variant text-m3-on-surface-variant before:bg-m3-on-surface-variant"
525
+ }
526
+ },
527
+ defaultVariants: { variant: "assist" }
528
+ }
529
+ );
530
+ var ChipImpl = React4__namespace.forwardRef(
531
+ (_a, ref) => {
532
+ var _b = _a, {
533
+ variant = "assist",
534
+ elevated = false,
535
+ selected = false,
536
+ disabled = false,
537
+ label,
538
+ leadingIcon,
539
+ trailingIcon,
540
+ avatar,
541
+ onRemove,
542
+ className,
543
+ onClick
544
+ } = _b, props = __objRest(_b, [
545
+ "variant",
546
+ "elevated",
547
+ "selected",
548
+ "disabled",
549
+ "label",
550
+ "leadingIcon",
551
+ "trailingIcon",
552
+ "avatar",
553
+ "onRemove",
554
+ "className",
555
+ "onClick"
556
+ ]);
557
+ const { ripples, onPointerDown, removeRipple } = useRippleState({
558
+ disabled
559
+ });
560
+ const isFilter = variant === "filter";
561
+ const isInput = variant === "input";
562
+ const resolvedLeadingIcon = isInput && avatar ? avatar : leadingIcon;
563
+ const showCheckmark = isFilter && selected;
564
+ const hasTrailingContent = !!trailingIcon || !!onRemove;
565
+ const hasLeadingContent = isFilter || !!resolvedLeadingIcon;
566
+ const paddingClass = React4__namespace.useMemo(
567
+ () => cn(
568
+ !isInput && !hasLeadingContent && !hasTrailingContent && "px-4",
569
+ !isInput && hasLeadingContent && !hasTrailingContent && "pl-2 pr-4",
570
+ !isInput && !hasLeadingContent && hasTrailingContent && "pl-4 pr-2",
571
+ !isInput && hasLeadingContent && hasTrailingContent && "px-2",
572
+ isInput && !hasLeadingContent && !hasTrailingContent && "px-3",
573
+ isInput && hasLeadingContent && !hasTrailingContent && "pl-1 pr-3",
574
+ isInput && !hasLeadingContent && hasTrailingContent && "pl-3 pr-2",
575
+ isInput && hasLeadingContent && hasTrailingContent && "pl-1 pr-2"
576
+ ),
577
+ [isInput, hasLeadingContent, hasTrailingContent]
578
+ );
579
+ const stateClass = React4__namespace.useMemo(
580
+ () => cn(
581
+ (isFilter || isInput) && selected && "bg-m3-secondary-container text-m3-on-secondary-container border-none before:bg-m3-on-secondary-container",
582
+ elevated && !selected && "bg-m3-surface-container-low border-none elevation-1",
583
+ elevated && isFilter && selected && "elevation-1",
584
+ disabled && "opacity-[0.38] pointer-events-none cursor-not-allowed",
585
+ disabled && !selected && "border-m3-outline-variant/[.12]",
586
+ disabled && selected && "bg-m3-on-surface/[.12] text-m3-on-surface border-none"
587
+ ),
588
+ [isFilter, isInput, selected, elevated, disabled]
589
+ );
590
+ const leadingIconColorClass = React4__namespace.useMemo(
591
+ () => cn(
592
+ (variant === "assist" || variant === "suggestion") && "text-m3-primary",
593
+ isFilter && !selected && "text-m3-primary",
594
+ isFilter && selected && "text-m3-on-secondary-container",
595
+ isInput && !selected && "text-m3-on-surface-variant",
596
+ isInput && selected && "text-m3-primary"
597
+ ),
598
+ [variant, isFilter, isInput, selected]
599
+ );
600
+ const isCompound = !!onRemove;
601
+ const Root2 = isCompound ? "div" : "button";
602
+ const containerClass = cn(
603
+ chipVariants({ variant }),
604
+ !isCompound && paddingClass,
605
+ !isCompound && "gap-2",
606
+ stateClass,
607
+ // When compound, the root div handles the overall shape but not the main interaction
608
+ // We disable the root's state layer (hover/focus) to avoid the 1px gap issue
609
+ isCompound && "items-stretch cursor-default active:scale-100 before:opacity-0 gap-0",
610
+ className
611
+ );
612
+ const mainContent = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
613
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { initial: false, mode: "wait", children: isFilter ? showCheckmark ? /* @__PURE__ */ jsxRuntime.jsx(
614
+ react.m.span,
615
+ {
616
+ initial: { width: 0, opacity: 0 },
617
+ animate: { width: 18, opacity: 1 },
618
+ exit: { width: 0, opacity: 0 },
619
+ transition: {
620
+ width: { duration: 0.2, ease: [0.2, 0, 0, 1] },
621
+ opacity: { duration: 0.15, ease: "easeOut" }
622
+ },
623
+ className: "flex items-center justify-center shrink-0 overflow-hidden",
624
+ "aria-hidden": "true",
625
+ children: /* @__PURE__ */ jsxRuntime.jsx(CheckIcon, {})
626
+ },
627
+ "checkmark"
628
+ ) : resolvedLeadingIcon ? /* @__PURE__ */ jsxRuntime.jsx(
629
+ react.m.span,
630
+ {
631
+ initial: { width: 0, opacity: 0 },
632
+ animate: { width: 18, opacity: 1 },
633
+ exit: { width: 0, opacity: 0 },
634
+ transition: {
635
+ width: { duration: 0.2, ease: [0.2, 0, 0, 1] },
636
+ opacity: { duration: 0.15, ease: "easeOut" }
637
+ },
638
+ className: cn(
639
+ "flex items-center justify-center shrink-0 overflow-hidden [&_.md-icon]:text-[length:inherit]!",
640
+ leadingIconColorClass
641
+ ),
642
+ style: { fontSize: 18 },
643
+ "aria-hidden": "true",
644
+ children: resolvedLeadingIcon
645
+ },
646
+ "leading-icon"
647
+ ) : null : resolvedLeadingIcon ? isInput && avatar ? /* @__PURE__ */ jsxRuntime.jsx(
648
+ "span",
649
+ {
650
+ className: "flex items-center justify-center shrink-0 w-6 h-6 rounded-full overflow-hidden",
651
+ "aria-hidden": "true",
652
+ children: resolvedLeadingIcon
653
+ },
654
+ "avatar"
655
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
656
+ "span",
657
+ {
658
+ className: cn(
659
+ "flex items-center justify-center shrink-0 w-4.5 h-4.5 [&_.md-icon]:text-[length:inherit]!",
660
+ leadingIconColorClass
661
+ ),
662
+ style: { fontSize: 18 },
663
+ "aria-hidden": "true",
664
+ children: resolvedLeadingIcon
665
+ },
666
+ "leading-icon"
667
+ ) : null }),
668
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-nowrap", children: label })
669
+ ] });
670
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
671
+ Root2,
672
+ __spreadProps(__spreadValues(__spreadProps(__spreadValues({
673
+ ref: !isCompound ? ref : void 0,
674
+ type: !isCompound ? "button" : void 0
675
+ }, isFilter ? {
676
+ role: "checkbox",
677
+ "aria-checked": selected
678
+ } : isInput && !isCompound && selected ? { role: "button", "aria-pressed": true } : isCompound ? { role: "group" } : { role: "button" }), {
679
+ "aria-disabled": disabled || void 0,
680
+ tabIndex: isCompound ? -1 : disabled ? -1 : 0,
681
+ disabled: !isCompound ? disabled : void 0,
682
+ onClick: !isCompound ? onClick : void 0,
683
+ onPointerDown: !isCompound ? onPointerDown : void 0,
684
+ className: containerClass
685
+ }), isCompound ? {} : props), {
686
+ children: [
687
+ !isCompound && /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
688
+ isCompound ? /* @__PURE__ */ jsxRuntime.jsxs(
689
+ "button",
690
+ {
691
+ ref,
692
+ type: "button",
693
+ tabIndex: disabled ? -1 : 0,
694
+ disabled,
695
+ onClick,
696
+ onPointerDown,
697
+ className: cn(
698
+ "flex items-center h-full grow focus:outline-none appearance-none bg-transparent border-none",
699
+ "text-inherit font-inherit cursor-pointer",
700
+ // Move padding here; keep horizontal padding but remove trailing to fit next to X
701
+ paddingClass,
702
+ "gap-2",
703
+ "pr-0",
704
+ // Re-apply focus ring to internal button instead of root div
705
+ "focus-visible:ring-2 focus-visible:ring-m3-secondary focus-visible:ring-inset",
706
+ "rounded-l-[7px] rounded-r-none",
707
+ // State layer for main area
708
+ "relative overflow-hidden",
709
+ "before:absolute before:-inset-px before:pointer-events-none before:bg-current",
710
+ "before:transition-opacity before:duration-200 before:opacity-0 before:rounded-l-[7px]",
711
+ "hover:before:opacity-[0.08] focus-visible:before:opacity-[0.10] active:before:opacity-[0.10]"
712
+ ),
713
+ children: [
714
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
715
+ mainContent
716
+ ]
717
+ }
718
+ ) : mainContent,
719
+ hasTrailingContent && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex items-center justify-center shrink-0", children: onRemove ? /* @__PURE__ */ jsxRuntime.jsx(
720
+ "button",
721
+ {
722
+ type: "button",
723
+ tabIndex: disabled ? -1 : 0,
724
+ "aria-label": typeof label === "string" ? `Remove ${label}` : "Remove",
725
+ onClick: (e) => {
726
+ e.stopPropagation();
727
+ onRemove(e);
728
+ },
729
+ onPointerDown: (e) => e.stopPropagation(),
730
+ className: cn(
731
+ "flex items-center justify-center w-8.5 h-full",
732
+ // 18px icon + 8px left + 8px right padding
733
+ "cursor-pointer focus-visible:outline-none",
734
+ "transition-all duration-150",
735
+ "relative overflow-hidden rounded-r-[7px] rounded-l-none",
736
+ "before:absolute before:-inset-px before:pointer-events-none before:bg-current",
737
+ "before:transition-opacity before:duration-200 before:opacity-0 before:rounded-r-[7px]",
738
+ "hover:before:opacity-[0.08] active:before:opacity-[0.12]",
739
+ // TrailingIcon color tokens
740
+ selected ? "text-m3-on-secondary-container" : "text-m3-on-surface-variant"
741
+ ),
742
+ children: /* @__PURE__ */ jsxRuntime.jsx(CloseIcon, {})
743
+ }
744
+ ) : trailingIcon ? /* @__PURE__ */ jsxRuntime.jsx(
745
+ "span",
746
+ {
747
+ className: cn(
748
+ "flex items-center justify-center w-4.5 h-4.5 [&_.md-icon]:text-[length:inherit]!",
749
+ selected ? "text-m3-on-secondary-container" : "text-m3-on-surface-variant"
750
+ ),
751
+ style: { fontSize: 18 },
752
+ "aria-hidden": "true",
753
+ children: trailingIcon
754
+ }
755
+ ) : null })
756
+ ]
757
+ })
758
+ ) });
759
+ }
760
+ );
761
+ ChipImpl.displayName = "Chip";
762
+ var Chip = React4__namespace.memo(ChipImpl);
763
+ var MD3_FAST_EFFECTS2 = [0.3, 0, 1, 1];
764
+ var RadioGroupContext = React4__namespace.createContext(
765
+ null
766
+ );
767
+ function useMergedRef2(externalRef, internalRef) {
768
+ return React4__namespace.useCallback(
769
+ (node) => {
770
+ internalRef.current = node;
771
+ if (!externalRef) return;
772
+ if (typeof externalRef === "function") {
773
+ externalRef(node);
774
+ } else {
775
+ externalRef.current = node;
776
+ }
777
+ },
778
+ [externalRef, internalRef]
779
+ );
780
+ }
781
+ var RadioVisual = React4__namespace.memo(function RadioVisual2({
782
+ isSelected,
783
+ disabled,
784
+ error,
785
+ isHovered,
786
+ prefersReduced
787
+ }) {
788
+ const accentColor = error ? "var(--color-m3-error)" : "var(--color-m3-primary)";
789
+ const disabledColor = "rgba(0, 0, 0, 0.38)";
790
+ const outerStroke = disabled ? disabledColor : isSelected ? accentColor : isHovered ? "var(--color-m3-on-surface)" : "var(--color-m3-on-surface-variant)";
791
+ const dotFill = disabled ? disabledColor : isSelected ? accentColor : "rgba(0, 0, 0, 0)";
792
+ const ringDuration = prefersReduced ? 0 : 0.15;
793
+ const dotDuration = prefersReduced ? 0 : isSelected ? 0.2 : 0.1;
794
+ const dotEase = isSelected ? MD3_FAST_EFFECTS2 : "easeOut";
795
+ return /* @__PURE__ */ jsxRuntime.jsxs(
796
+ "svg",
797
+ {
798
+ viewBox: "0 0 20 20",
799
+ width: 20,
800
+ height: 20,
801
+ fill: "none",
802
+ "aria-hidden": "true",
803
+ children: [
804
+ /* @__PURE__ */ jsxRuntime.jsx(
805
+ react.m.circle,
806
+ {
807
+ cx: 10,
808
+ cy: 10,
809
+ r: 9,
810
+ strokeWidth: 2,
811
+ fill: "none",
812
+ animate: { stroke: outerStroke },
813
+ transition: { duration: ringDuration, ease: "easeOut" }
814
+ }
815
+ ),
816
+ /* @__PURE__ */ jsxRuntime.jsx(
817
+ react.m.circle,
818
+ {
819
+ cx: 10,
820
+ cy: 10,
821
+ initial: { r: 0 },
822
+ animate: { r: isSelected ? 5 : 0, fill: dotFill },
823
+ transition: {
824
+ r: { duration: dotDuration, ease: dotEase },
825
+ fill: { duration: ringDuration, ease: "easeOut" }
826
+ },
827
+ stroke: "none"
828
+ }
829
+ )
830
+ ]
831
+ }
832
+ );
833
+ });
834
+ var RadioButtonComponent = React4__namespace.forwardRef(
835
+ ({
836
+ selected,
837
+ defaultSelected = false,
838
+ onClick,
839
+ disabled: disabledProp = false,
840
+ color,
841
+ error: errorProp = false,
842
+ label,
843
+ value,
844
+ name: nameProp,
845
+ id: idProp,
846
+ className,
847
+ "aria-label": ariaLabel,
848
+ "aria-labelledby": ariaLabelledby,
849
+ "aria-describedby": ariaDescribedby,
850
+ required: requiredProp
851
+ }, ref) => {
852
+ var _a, _b;
853
+ const group = React4__namespace.useContext(RadioGroupContext);
854
+ const prefersReduced = (_a = react.useReducedMotion()) != null ? _a : false;
855
+ const generatedId = React4__namespace.useId();
856
+ const inputId = idProp != null ? idProp : label ? `radio-${generatedId}` : void 0;
857
+ const name = (_b = group == null ? void 0 : group.name) != null ? _b : nameProp;
858
+ const disabled = (group == null ? void 0 : group.disabled) || disabledProp;
859
+ const error = (group == null ? void 0 : group.error) || errorProp || color === "error";
860
+ const required = (group == null ? void 0 : group.required) || requiredProp;
861
+ const [internalSelected, setInternalSelected] = React4__namespace.useState(defaultSelected);
862
+ const isControlled = selected !== void 0;
863
+ const isSelected = group ? group.selectedValue === value : isControlled ? selected != null ? selected : false : internalSelected;
864
+ const [ripples, setRipples] = React4__namespace.useState([]);
865
+ const removeRipple = React4__namespace.useCallback(
866
+ (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
867
+ []
868
+ );
869
+ const onPointerDown = React4__namespace.useCallback(
870
+ (e) => {
871
+ if (disabled) return;
872
+ const rect = e.currentTarget.getBoundingClientRect();
873
+ const x = e.clientX - rect.left - 4;
874
+ const y = e.clientY - rect.top - 4;
875
+ const rippleSize = Math.hypot(40, 40) * 2;
876
+ setRipples((prev) => [
877
+ ...prev,
878
+ { id: Date.now(), x, y, size: rippleSize }
879
+ ]);
880
+ },
881
+ [disabled]
882
+ );
883
+ const [isHovered, setIsHovered] = React4__namespace.useState(false);
884
+ const onPointerEnter = React4__namespace.useCallback(() => {
885
+ if (!disabled) setIsHovered(true);
886
+ }, [disabled]);
887
+ const onPointerLeave = React4__namespace.useCallback(() => setIsHovered(false), []);
888
+ const handleChange = React4__namespace.useCallback(
889
+ (_e) => {
890
+ if (disabled || onClick === null) return;
891
+ if (group) {
892
+ if (value !== void 0) group.onValueChange(value);
893
+ } else if (!isControlled) {
894
+ setInternalSelected(true);
895
+ onClick == null ? void 0 : onClick();
896
+ } else {
897
+ onClick == null ? void 0 : onClick();
898
+ }
899
+ },
900
+ [disabled, onClick, group, value, isControlled]
901
+ );
902
+ const inputRef = React4__namespace.useRef(null);
903
+ const mergedRef = useMergedRef2(ref, inputRef);
904
+ const stateLayerBg = error ? "before:bg-m3-error" : "before:bg-m3-primary";
905
+ const stateLayerClass = cn(
906
+ "before:absolute before:inset-0 before:rounded-full before:pointer-events-none",
907
+ "before:transition-opacity before:duration-150 before:opacity-0",
908
+ "group-hover/radio:before:opacity-[0.08]",
909
+ "group-focus-within/radio:before:opacity-[0.10]",
910
+ "group-active/radio:before:opacity-[0.10]",
911
+ stateLayerBg
912
+ );
913
+ const touchTargetClass = cn(
914
+ "relative inline-flex items-center justify-center outline-none shrink-0",
915
+ "w-12 h-12 group/radio cursor-pointer",
916
+ disabled && "pointer-events-none"
917
+ );
918
+ const stateLayerAndRipple = /* @__PURE__ */ jsxRuntime.jsx(
919
+ "div",
920
+ {
921
+ className: cn(
922
+ "absolute flex items-center justify-center w-10 h-10 m-auto inset-0 rounded-full overflow-hidden pointer-events-none",
923
+ stateLayerClass
924
+ ),
925
+ "aria-hidden": "true",
926
+ children: /* @__PURE__ */ jsxRuntime.jsx(
927
+ Ripple,
928
+ {
929
+ ripples,
930
+ onRippleDone: removeRipple,
931
+ disabled
932
+ }
933
+ )
934
+ }
935
+ );
936
+ const hiddenInput = /* @__PURE__ */ jsxRuntime.jsx(
937
+ "input",
938
+ {
939
+ ref: mergedRef,
940
+ type: "radio",
941
+ id: inputId,
942
+ name,
943
+ value,
944
+ checked: isSelected,
945
+ disabled,
946
+ "aria-disabled": disabled || void 0,
947
+ "aria-label": ariaLabel,
948
+ "aria-labelledby": ariaLabelledby,
949
+ "aria-describedby": ariaDescribedby,
950
+ required,
951
+ onChange: handleChange,
952
+ className: "sr-only"
953
+ }
954
+ );
955
+ const visual = /* @__PURE__ */ jsxRuntime.jsx(
956
+ RadioVisual,
957
+ {
958
+ isSelected,
959
+ disabled,
960
+ error,
961
+ isHovered,
962
+ prefersReduced
963
+ }
964
+ );
965
+ if (label) {
966
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
967
+ "label",
968
+ {
969
+ htmlFor: inputId,
970
+ className: cn(
971
+ "inline-flex items-center gap-2 cursor-pointer select-none",
972
+ disabled && "cursor-not-allowed opacity-[0.38] pointer-events-none",
973
+ className
974
+ ),
975
+ children: [
976
+ /* @__PURE__ */ jsxRuntime.jsxs(
977
+ "div",
978
+ {
979
+ className: touchTargetClass,
980
+ onPointerDown,
981
+ onPointerEnter,
982
+ onPointerLeave,
983
+ children: [
984
+ stateLayerAndRipple,
985
+ hiddenInput,
986
+ visual
987
+ ]
988
+ }
989
+ ),
990
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-none text-m3-on-surface", children: label })
991
+ ]
992
+ }
993
+ ) });
994
+ }
995
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
996
+ "label",
997
+ {
998
+ htmlFor: inputId,
999
+ className: cn(touchTargetClass, className),
1000
+ onPointerDown,
1001
+ onPointerEnter,
1002
+ onPointerLeave,
1003
+ children: [
1004
+ stateLayerAndRipple,
1005
+ hiddenInput,
1006
+ visual
1007
+ ]
1008
+ }
1009
+ ) });
1010
+ }
1011
+ );
1012
+ RadioButtonComponent.displayName = "RadioButton";
1013
+ var RadioButton = React4__namespace.memo(RadioButtonComponent);
1014
+ var RadioGroupComponent = React4__namespace.forwardRef(
1015
+ ({
1016
+ name,
1017
+ value: valueProp,
1018
+ defaultValue,
1019
+ onValueChange,
1020
+ disabled = false,
1021
+ error = false,
1022
+ label,
1023
+ "aria-labelledby": ariaLabelledby,
1024
+ required = false,
1025
+ orientation = "vertical",
1026
+ children,
1027
+ className
1028
+ }, ref) => {
1029
+ const [internalValue, setInternalValue] = React4__namespace.useState(defaultValue);
1030
+ const isControlled = valueProp !== void 0;
1031
+ const selectedValue = isControlled ? valueProp : internalValue;
1032
+ const handleValueChange = React4__namespace.useCallback(
1033
+ (val) => {
1034
+ if (!isControlled) setInternalValue(val);
1035
+ onValueChange == null ? void 0 : onValueChange(val);
1036
+ },
1037
+ [isControlled, onValueChange]
1038
+ );
1039
+ const groupRef = React4__namespace.useRef(null);
1040
+ const mergedRef = useMergedRef2(ref, groupRef);
1041
+ const onKeyDown = React4__namespace.useCallback(
1042
+ (e) => {
1043
+ var _a, _b;
1044
+ if (disabled) return;
1045
+ const isNext = e.key === "ArrowDown" || e.key === "ArrowRight";
1046
+ const isPrev = e.key === "ArrowUp" || e.key === "ArrowLeft";
1047
+ if (!isNext && !isPrev) return;
1048
+ e.preventDefault();
1049
+ const inputs = Array.from(
1050
+ (_b = (_a = groupRef.current) == null ? void 0 : _a.querySelectorAll(
1051
+ 'input[type="radio"]:not(:disabled)'
1052
+ )) != null ? _b : []
1053
+ );
1054
+ if (inputs.length === 0) return;
1055
+ const currentIdx = inputs.indexOf(
1056
+ document.activeElement
1057
+ );
1058
+ const nextIdx = isNext ? currentIdx < inputs.length - 1 ? currentIdx + 1 : 0 : currentIdx > 0 ? currentIdx - 1 : inputs.length - 1;
1059
+ const target = inputs[nextIdx];
1060
+ target.focus();
1061
+ handleValueChange(target.value);
1062
+ },
1063
+ [disabled, handleValueChange]
1064
+ );
1065
+ const contextValue = React4__namespace.useMemo(
1066
+ () => ({
1067
+ name,
1068
+ selectedValue,
1069
+ onValueChange: handleValueChange,
1070
+ disabled,
1071
+ error,
1072
+ required
1073
+ }),
1074
+ [name, selectedValue, handleValueChange, disabled, error, required]
1075
+ );
1076
+ return /* @__PURE__ */ jsxRuntime.jsx(RadioGroupContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsxs(
1077
+ "div",
1078
+ {
1079
+ ref: mergedRef,
1080
+ role: "radiogroup",
1081
+ "aria-label": label && !ariaLabelledby ? label : void 0,
1082
+ "aria-labelledby": ariaLabelledby,
1083
+ "aria-disabled": disabled || void 0,
1084
+ "aria-required": required || void 0,
1085
+ className: cn(
1086
+ "flex",
1087
+ orientation === "horizontal" ? "flex-row gap-4" : "flex-col gap-1",
1088
+ className
1089
+ ),
1090
+ onKeyDown,
1091
+ children: [
1092
+ label && !ariaLabelledby && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "sr-only", children: label }),
1093
+ children
1094
+ ]
1095
+ }
1096
+ ) });
1097
+ }
1098
+ );
1099
+ RadioGroupComponent.displayName = "RadioGroup";
1100
+ var RadioGroup = React4__namespace.memo(RadioGroupComponent);
1101
+ function coerceValue(value, min, max) {
1102
+ return Math.max(min, Math.min(max, value));
1103
+ }
1104
+ function snapToStep(value, min, step) {
1105
+ if (step <= 0) return value;
1106
+ const steps = Math.round((value - min) / step);
1107
+ return Number((min + steps * step).toPrecision(10));
1108
+ }
1109
+ function valueToPercent(value, min, max) {
1110
+ if (max === min) return 0;
1111
+ return (value - min) / (max - min);
1112
+ }
1113
+ function percentToValue(percent, min, max, step) {
1114
+ const raw = min + percent * (max - min);
1115
+ const snapped = snapToStep(raw, min, step);
1116
+ return coerceValue(snapped, min, max);
1117
+ }
1118
+ function getKeyboardDelta(key, step, min, max) {
1119
+ const range = max - min;
1120
+ const discreteStep = step > 0 ? step : range / 100;
1121
+ switch (key) {
1122
+ case "ArrowRight":
1123
+ case "ArrowUp":
1124
+ return discreteStep;
1125
+ case "ArrowLeft":
1126
+ case "ArrowDown":
1127
+ return -discreteStep;
1128
+ case "PageUp":
1129
+ return step > 0 ? snapToStep(range * 0.1, 0, step) : range * 0.1;
1130
+ case "PageDown":
1131
+ return step > 0 ? -snapToStep(range * 0.1, 0, step) : -(range * 0.1);
1132
+ default:
1133
+ return null;
1134
+ }
1135
+ }
1136
+ function generateTicks(min, max, step) {
1137
+ if (step <= 0) return [];
1138
+ const ticks = [];
1139
+ let current = min;
1140
+ while (current <= max) {
1141
+ ticks.push(Number(current.toPrecision(10)));
1142
+ current += step;
1143
+ }
1144
+ if (ticks[ticks.length - 1] !== max) {
1145
+ ticks.push(max);
1146
+ }
1147
+ return ticks;
1148
+ }
1149
+ function useSliderMath({
1150
+ min,
1151
+ max,
1152
+ step
1153
+ }) {
1154
+ return React4.useMemo(
1155
+ () => ({
1156
+ coerce: (v) => coerceValue(v, min, max),
1157
+ snap: (v) => snapToStep(v, min, step),
1158
+ toPercent: (v) => valueToPercent(v, min, max),
1159
+ fromPercent: (pct) => percentToValue(pct, min, max, step),
1160
+ getKeyDelta: (key) => getKeyboardDelta(key, step, min, max),
1161
+ ticks: generateTicks(min, max, step)
1162
+ }),
1163
+ [min, max, step]
1164
+ );
1165
+ }
1166
+
1167
+ // src/ui/slider/slider.tokens.ts
1168
+ var SliderTokens = {
1169
+ // ── Track sizes (height for horizontal, width for vertical) ────────────────
1170
+ trackSizes: {
1171
+ xs: 16,
1172
+ s: 24,
1173
+ m: 40,
1174
+ l: 56,
1175
+ xl: 96
1176
+ },
1177
+ // ── Track shapes (border radius) ──────────────────────────────────────────
1178
+ trackShapes: {
1179
+ xs: 8,
1180
+ s: 8,
1181
+ m: 12,
1182
+ l: 16,
1183
+ xl: 28
1184
+ },
1185
+ // ── Thumb (handle) ────────────────────────────────────────────────────────
1186
+ /** Thumb height grows with track size */
1187
+ thumbHeights: {
1188
+ xs: 44,
1189
+ s: 44,
1190
+ m: 52,
1191
+ l: 68,
1192
+ xl: 108
1193
+ },
1194
+ /**
1195
+ * Thumb width at rest and on hover.
1196
+ * MD3 Expressive handle pill: 4dp wide.
1197
+ */
1198
+ thumbWidthDefault: 4,
1199
+ /**
1200
+ * Thumb width while pressed/dragging.
1201
+ * "Squeeze" animation: 4dp → 2dp (M3 Expressive behavior).
1202
+ */
1203
+ thumbWidthPressed: 2,
1204
+ // ── Track–thumb gap ───────────────────────────────────────────────────────
1205
+ /**
1206
+ * Transparent gap between the active/inactive track segments and the thumb.
1207
+ * Maps to ActiveHandleLeadingSpace / ActiveHandleTrailingSpace = 6dp.
1208
+ *
1209
+ * This gap is rendered by mathematically subtracting it from the track
1210
+ * segment width — NOT using margin/padding.
1211
+ */
1212
+ thumbGap: 6,
1213
+ // ── Track corner radii ────────────────────────────────────────────────────
1214
+ /**
1215
+ * Corner radius on the INNER ends of each track segment (facing the thumb).
1216
+ * Fixed to 2px according to MD3 Expressive Slider specs (TrackInsideCornerSize).
1217
+ * Outer ends use `trackSize / 2` (pill cap) — computed inline per component.
1218
+ */
1219
+ trackInnerRadius: 2,
1220
+ // ── Stop indicator / Tick ─────────────────────────────────────────────────
1221
+ /** Tick dot size (width and height). = 4dp. */
1222
+ tickSize: 4,
1223
+ // ── Touch target ─────────────────────────────────────────────────────────
1224
+ /**
1225
+ * Minimum touch target for the thumb wrapper.
1226
+ * MD3 requires 48dp minimum touch target for interactive elements.
1227
+ */
1228
+ thumbTouchTarget: 48,
1229
+ // ── Value indicator ───────────────────────────────────────────────────────
1230
+ /** Offset above the thumb center for the value indicator tooltip. */
1231
+ valueIndicatorOffset: 52,
1232
+ // ── Inset icon ────────────────────────────────────────────────────────────
1233
+ /** Standard icon size map for inset icons inside the track. */
1234
+ insetIconSizes: {
1235
+ xs: 0,
1236
+ s: 0,
1237
+ m: 24,
1238
+ l: 24,
1239
+ xl: 32
1240
+ },
1241
+ /**
1242
+ * Padding between icon and track edge (horizontal).
1243
+ * Keeps the icon visually centered within the pill track.
1244
+ */
1245
+ insetIconPadding: 4
1246
+ };
1247
+ var SliderColors = {
1248
+ // ── Track ─────────────────────────────────────────────────────────────────
1249
+ /** Active track color. Maps to ActiveTrackColor token. */
1250
+ activeTrack: "var(--md-sys-color-primary)",
1251
+ /** Inactive track color. Maps to InactiveTrackColor token. */
1252
+ inactiveTrack: "var(--md-sys-color-secondary-container)",
1253
+ /**
1254
+ * Disabled track color.
1255
+ * Uses opacity + on-surface per MD3 disabled state spec.
1256
+ */
1257
+ disabledActiveTrack: "var(--md-sys-color-on-surface)",
1258
+ disabledInactiveTrack: "var(--md-sys-color-on-surface)",
1259
+ // ── Thumb ─────────────────────────────────────────────────────────────────
1260
+ /** Thumb (handle) color. Maps to HandleColor token. */
1261
+ thumb: "var(--md-sys-color-primary)",
1262
+ /** Disabled thumb color. */
1263
+ disabledThumb: "var(--md-sys-color-on-surface)",
1264
+ // ── Value indicator ───────────────────────────────────────────────────────
1265
+ /** Value indicator (tooltip) background. Maps to InverseSurface. */
1266
+ valueIndicatorBg: "var(--md-sys-color-inverse-surface)",
1267
+ /** Value indicator (tooltip) text. Maps to InverseOnSurface. */
1268
+ valueIndicatorText: "var(--md-sys-color-inverse-on-surface)",
1269
+ // ── Ticks ────────────────────────────────────────────────────────────────
1270
+ /**
1271
+ * Tick on the INACTIVE portion of the track.
1272
+ * Maps to TickMarkActiveContainerColor (in spec: primary color stands out).
1273
+ */
1274
+ tickOnInactive: "var(--md-sys-color-primary)",
1275
+ /**
1276
+ * Tick on the ACTIVE portion of the track.
1277
+ * Maps to TickMarkInactiveContainerColor (secondary-container blends in).
1278
+ */
1279
+ tickOnActive: "var(--md-sys-color-secondary-container)",
1280
+ disabledTick: "var(--md-sys-color-on-surface)"
1281
+ };
1282
+ var SLIDER_THUMB_SPRING = {
1283
+ type: "spring",
1284
+ stiffness: 500,
1285
+ damping: 40
1286
+ };
1287
+ var SLIDER_INDICATOR_TRANSITION = {
1288
+ type: "spring",
1289
+ stiffness: 450,
1290
+ damping: 32
1291
+ };
1292
+ var ValueIndicator = React4__namespace.memo(function ValueIndicator2({
1293
+ value,
1294
+ visible,
1295
+ orientation,
1296
+ formatValue,
1297
+ prefersReduced,
1298
+ trackSize
1299
+ }) {
1300
+ const label = formatValue ? formatValue(value) : String(Math.round(value));
1301
+ const isHorizontal = orientation === "horizontal";
1302
+ const thumbHeight = SliderTokens.thumbHeights[trackSize];
1303
+ const offsetFromCenter = thumbHeight / 2 + 8;
1304
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: visible && /* @__PURE__ */ jsxRuntime.jsx(
1305
+ react.m.div,
1306
+ {
1307
+ role: "tooltip",
1308
+ "aria-hidden": "true",
1309
+ initial: prefersReduced ? false : {
1310
+ scale: 0,
1311
+ opacity: 0,
1312
+ y: isHorizontal ? 6 : 0,
1313
+ x: !isHorizontal ? -6 : 0
1314
+ },
1315
+ animate: { scale: 1, opacity: 1, y: 0, x: 0 },
1316
+ exit: prefersReduced ? {} : {
1317
+ scale: 0,
1318
+ opacity: 0,
1319
+ y: isHorizontal ? 6 : 0,
1320
+ x: !isHorizontal ? -6 : 0
1321
+ },
1322
+ transition: prefersReduced ? { duration: 0 } : SLIDER_INDICATOR_TRANSITION,
1323
+ className: cn(
1324
+ "absolute pointer-events-none select-none",
1325
+ "rounded-full px-2.5 py-1 text-xs font-medium leading-none whitespace-nowrap",
1326
+ // Position: above for horizontal, right for vertical
1327
+ isHorizontal ? "-translate-x-1/2 left-1/2" : "translate-y-1/2 bottom-1/2"
1328
+ ),
1329
+ style: __spreadValues({
1330
+ backgroundColor: SliderColors.valueIndicatorBg,
1331
+ color: SliderColors.valueIndicatorText,
1332
+ transformOrigin: isHorizontal ? "bottom center" : "center left"
1333
+ }, isHorizontal ? { bottom: `calc(50% + ${offsetFromCenter}px)` } : { left: `calc(50% + ${offsetFromCenter}px)` }),
1334
+ children: label
1335
+ },
1336
+ "value-indicator"
1337
+ ) });
1338
+ });
1339
+ var SliderThumb = React4__namespace.memo(function SliderThumb2({
1340
+ value,
1341
+ percent,
1342
+ min,
1343
+ max,
1344
+ step,
1345
+ disabled,
1346
+ orientation,
1347
+ showValueIndicator,
1348
+ trackRef,
1349
+ onValueChange,
1350
+ onValueChangeEnd,
1351
+ formatValue,
1352
+ thumbId,
1353
+ trackSize,
1354
+ variant,
1355
+ zIndex = 1,
1356
+ "aria-label": ariaLabel,
1357
+ "aria-labelledby": ariaLabelledBy
1358
+ }) {
1359
+ var _a;
1360
+ const isHorizontal = orientation === "horizontal";
1361
+ const insetLimit = SliderTokens.thumbGap + SliderTokens.thumbWidthDefault / 2;
1362
+ const trackInset = Math.min(
1363
+ SliderTokens.trackSizes[trackSize] / 2,
1364
+ insetLimit
1365
+ );
1366
+ const posTarget = isHorizontal ? "left" : "bottom";
1367
+ const motionStyle = {
1368
+ [posTarget]: `calc(${trackInset}px + ${percent} * (100% - ${trackInset * 2}px))`
1369
+ };
1370
+ const prefersReduced = (_a = react.useReducedMotion()) != null ? _a : false;
1371
+ const [isDragging, setIsDragging] = React4__namespace.useState(false);
1372
+ const [isHovered, setIsHovered] = React4__namespace.useState(false);
1373
+ const [isFocused, setIsFocused] = React4__namespace.useState(false);
1374
+ const pointerIdRef = React4__namespace.useRef(null);
1375
+ const thumbRef = React4__namespace.useRef(null);
1376
+ const showIndicator = showValueIndicator && (isDragging || isHovered || isFocused);
1377
+ const positionStyle = isHorizontal ? __spreadProps(__spreadValues({
1378
+ position: "absolute"
1379
+ }, motionStyle), {
1380
+ top: "50%",
1381
+ transform: "translate(-50%, -50%)",
1382
+ zIndex
1383
+ }) : __spreadProps(__spreadValues({
1384
+ position: "absolute"
1385
+ }, motionStyle), {
1386
+ left: "50%",
1387
+ transform: "translate(-50%, 50%)",
1388
+ zIndex
1389
+ });
1390
+ const getDeltaFromPointer = React4__namespace.useCallback(
1391
+ (e) => {
1392
+ const trackEl = trackRef.current;
1393
+ if (!trackEl) return percent;
1394
+ const rect = trackEl.getBoundingClientRect();
1395
+ const space = isHorizontal ? rect.width : rect.height;
1396
+ const insetLimit2 = SliderTokens.thumbGap + SliderTokens.thumbWidthDefault / 2;
1397
+ const trackInset2 = Math.min(
1398
+ SliderTokens.trackSizes[trackSize] / 2,
1399
+ insetLimit2
1400
+ );
1401
+ const safeSpace = space - trackInset2 * 2;
1402
+ if (safeSpace <= 0) return percent;
1403
+ let rawPercent;
1404
+ if (isHorizontal) {
1405
+ rawPercent = (e.clientX - rect.left - trackInset2) / safeSpace;
1406
+ } else {
1407
+ rawPercent = (rect.bottom - e.clientY - trackInset2) / safeSpace;
1408
+ }
1409
+ const clamped = Math.max(0, Math.min(1, rawPercent));
1410
+ const range = max - min;
1411
+ const rawValue = min + clamped * range;
1412
+ const snapped = step > 0 ? Math.round((rawValue - min) / step) * step + min : rawValue;
1413
+ return Math.max(min, Math.min(max, snapped));
1414
+ },
1415
+ [isHorizontal, max, min, percent, step, trackRef, trackSize]
1416
+ );
1417
+ const handlePointerDown = React4__namespace.useCallback(
1418
+ (e) => {
1419
+ if (disabled) return;
1420
+ e.preventDefault();
1421
+ e.stopPropagation();
1422
+ e.currentTarget.setPointerCapture(e.pointerId);
1423
+ pointerIdRef.current = e.pointerId;
1424
+ setIsDragging(true);
1425
+ },
1426
+ [disabled]
1427
+ );
1428
+ const handlePointerMove = React4__namespace.useCallback(
1429
+ (e) => {
1430
+ if (!isDragging || e.pointerId !== pointerIdRef.current) return;
1431
+ const newValue = getDeltaFromPointer(e.nativeEvent);
1432
+ onValueChange(newValue);
1433
+ },
1434
+ [isDragging, getDeltaFromPointer, onValueChange]
1435
+ );
1436
+ const handlePointerUp = React4__namespace.useCallback(
1437
+ (e) => {
1438
+ if (e.pointerId !== pointerIdRef.current) return;
1439
+ e.currentTarget.releasePointerCapture(e.pointerId);
1440
+ pointerIdRef.current = null;
1441
+ setIsDragging(false);
1442
+ onValueChangeEnd == null ? void 0 : onValueChangeEnd(value);
1443
+ },
1444
+ [onValueChangeEnd, value]
1445
+ );
1446
+ const handleKeyDown = React4__namespace.useCallback(
1447
+ (e) => {
1448
+ if (disabled) return;
1449
+ if (e.key === "Home") {
1450
+ e.preventDefault();
1451
+ onValueChange(min);
1452
+ onValueChangeEnd == null ? void 0 : onValueChangeEnd(min);
1453
+ return;
1454
+ }
1455
+ if (e.key === "End") {
1456
+ e.preventDefault();
1457
+ onValueChange(max);
1458
+ onValueChangeEnd == null ? void 0 : onValueChangeEnd(max);
1459
+ return;
1460
+ }
1461
+ const delta = getKeyboardDelta(e.key, step, min, max);
1462
+ if (delta === null) return;
1463
+ e.preventDefault();
1464
+ const newValue = Math.max(min, Math.min(max, value + delta));
1465
+ onValueChange(newValue);
1466
+ onValueChangeEnd == null ? void 0 : onValueChangeEnd(newValue);
1467
+ },
1468
+ [disabled, max, min, onValueChange, onValueChangeEnd, step, value]
1469
+ );
1470
+ const thumbColor = disabled ? SliderColors.disabledThumb : `var(--md-sys-color-${variant})`;
1471
+ const squeezeSize = isDragging ? SliderTokens.thumbWidthPressed : SliderTokens.thumbWidthDefault;
1472
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1473
+ "div",
1474
+ {
1475
+ style: __spreadProps(__spreadValues({}, positionStyle), {
1476
+ width: SliderTokens.thumbTouchTarget,
1477
+ height: SliderTokens.thumbTouchTarget,
1478
+ display: "flex",
1479
+ alignItems: "center",
1480
+ justifyContent: "center",
1481
+ touchAction: "none"
1482
+ }),
1483
+ className: cn(
1484
+ "cursor-grab",
1485
+ isDragging && "cursor-grabbing",
1486
+ disabled && "cursor-not-allowed"
1487
+ ),
1488
+ onPointerDown: handlePointerDown,
1489
+ onPointerMove: handlePointerMove,
1490
+ onPointerUp: handlePointerUp,
1491
+ onPointerCancel: handlePointerUp,
1492
+ children: [
1493
+ /* @__PURE__ */ jsxRuntime.jsx(
1494
+ ValueIndicator,
1495
+ {
1496
+ value,
1497
+ visible: showIndicator,
1498
+ orientation,
1499
+ formatValue,
1500
+ prefersReduced,
1501
+ trackSize
1502
+ }
1503
+ ),
1504
+ /* @__PURE__ */ jsxRuntime.jsx(
1505
+ react.m.div,
1506
+ {
1507
+ ref: thumbRef,
1508
+ id: thumbId,
1509
+ role: "slider",
1510
+ "aria-valuemin": min,
1511
+ "aria-valuemax": max,
1512
+ "aria-valuenow": value,
1513
+ "aria-orientation": orientation,
1514
+ "aria-disabled": disabled || void 0,
1515
+ "aria-label": ariaLabel,
1516
+ "aria-labelledby": ariaLabelledBy,
1517
+ tabIndex: disabled ? -1 : 0,
1518
+ onKeyDown: handleKeyDown,
1519
+ onFocus: () => setIsFocused(true),
1520
+ onBlur: () => setIsFocused(false),
1521
+ onMouseEnter: () => !disabled && setIsHovered(true),
1522
+ onMouseLeave: () => setIsHovered(false),
1523
+ animate: __spreadProps(__spreadValues({}, isHorizontal ? { width: squeezeSize } : { height: squeezeSize }), {
1524
+ backgroundColor: thumbColor,
1525
+ opacity: disabled ? 0.38 : 1
1526
+ }),
1527
+ transition: prefersReduced ? { duration: 0 } : SLIDER_THUMB_SPRING,
1528
+ className: cn(
1529
+ "relative shrink-0 rounded-full select-none outline-none",
1530
+ "focus-visible:outline-2 focus-visible:outline-offset-2",
1531
+ "focus-visible:outline-(--md-sys-color-secondary)"
1532
+ ),
1533
+ style: __spreadProps(__spreadValues({}, isHorizontal ? {
1534
+ height: SliderTokens.thumbHeights[trackSize],
1535
+ width: SliderTokens.thumbWidthDefault,
1536
+ willChange: "width"
1537
+ } : {
1538
+ width: SliderTokens.thumbHeights[trackSize],
1539
+ height: SliderTokens.thumbWidthDefault,
1540
+ willChange: "height"
1541
+ }), {
1542
+ backgroundColor: thumbColor
1543
+ })
1544
+ }
1545
+ )
1546
+ ]
1547
+ }
1548
+ );
1549
+ });
1550
+ var RangeTrack = React4__namespace.memo(function RangeTrack2({
1551
+ startPercent,
1552
+ endPercent,
1553
+ trackSize,
1554
+ orientation,
1555
+ variant,
1556
+ disabled,
1557
+ ticks,
1558
+ min,
1559
+ max,
1560
+ trackShape = "md3",
1561
+ trackRef,
1562
+ onTrackPointerDown
1563
+ }) {
1564
+ const isHorizontal = orientation === "horizontal";
1565
+ const size = SliderTokens.trackSizes[trackSize];
1566
+ const thumbHeight = SliderTokens.thumbHeights[trackSize];
1567
+ const { thumbGap, thumbWidthDefault, tickSize } = SliderTokens;
1568
+ const thumbHalfWidth = thumbWidthDefault / 2;
1569
+ const activeTrack = disabled ? SliderColors.disabledActiveTrack : `var(--md-sys-color-${variant})`;
1570
+ const inactiveTrack = disabled ? SliderColors.disabledInactiveTrack : `var(--md-sys-color-${variant}-container)`;
1571
+ const innerR = SliderTokens.trackInnerRadius;
1572
+ let outerR = size / 2;
1573
+ if (trackShape === "md3") {
1574
+ outerR = Math.min(SliderTokens.trackShapes[trackSize], size / 2);
1575
+ } else if (typeof trackShape === "number") {
1576
+ outerR = Math.min(trackShape, size / 2);
1577
+ }
1578
+ if (isHorizontal) {
1579
+ const insetLimit2 = thumbGap + thumbWidthDefault / 2;
1580
+ const trackInset2 = Math.min(size / 2, insetLimit2);
1581
+ const cxStart = `calc(${trackInset2}px + ${startPercent} * (100% - ${trackInset2 * 2}px))`;
1582
+ const cxEnd = `calc(${trackInset2}px + ${endPercent} * (100% - ${trackInset2 * 2}px))`;
1583
+ const gapWithThumbStr2 = `${thumbGap + thumbHalfWidth}px`;
1584
+ const leadingWidth = `max(0px, calc(${cxStart} - ${gapWithThumbStr2}))`;
1585
+ const activeLeft = `calc(${cxStart} + ${gapWithThumbStr2})`;
1586
+ const activeWidth = `max(0px, calc(${cxEnd} - ${cxStart} - ${gapWithThumbStr2} * 2))`;
1587
+ const trailingLeft = `calc(${cxEnd} + ${gapWithThumbStr2})`;
1588
+ const trailingWidth = `max(0px, calc(100% - (${cxEnd} + ${gapWithThumbStr2})))`;
1589
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1590
+ "div",
1591
+ {
1592
+ ref: trackRef,
1593
+ className: cn(
1594
+ "relative w-full",
1595
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
1596
+ ),
1597
+ style: { height: thumbHeight },
1598
+ onPointerDown: onTrackPointerDown,
1599
+ "aria-hidden": "true",
1600
+ children: [
1601
+ /* @__PURE__ */ jsxRuntime.jsx(
1602
+ "div",
1603
+ {
1604
+ "aria-hidden": "true",
1605
+ style: {
1606
+ position: "absolute",
1607
+ left: 0,
1608
+ top: "50%",
1609
+ transform: "translateY(-50%)",
1610
+ width: leadingWidth,
1611
+ height: size,
1612
+ backgroundColor: inactiveTrack,
1613
+ opacity: disabled ? 0.38 : 1,
1614
+ borderTopLeftRadius: outerR,
1615
+ borderBottomLeftRadius: outerR,
1616
+ borderTopRightRadius: innerR,
1617
+ borderBottomRightRadius: innerR
1618
+ }
1619
+ }
1620
+ ),
1621
+ /* @__PURE__ */ jsxRuntime.jsx(
1622
+ "div",
1623
+ {
1624
+ "aria-hidden": "true",
1625
+ style: {
1626
+ position: "absolute",
1627
+ left: activeLeft,
1628
+ top: "50%",
1629
+ transform: "translateY(-50%)",
1630
+ width: activeWidth,
1631
+ height: size,
1632
+ backgroundColor: activeTrack,
1633
+ opacity: disabled ? 0.38 : 1,
1634
+ borderTopLeftRadius: startPercent <= 0 ? outerR : innerR,
1635
+ borderBottomLeftRadius: startPercent <= 0 ? outerR : innerR,
1636
+ borderTopRightRadius: endPercent >= 1 ? outerR : innerR,
1637
+ borderBottomRightRadius: endPercent >= 1 ? outerR : innerR
1638
+ }
1639
+ }
1640
+ ),
1641
+ /* @__PURE__ */ jsxRuntime.jsx(
1642
+ "div",
1643
+ {
1644
+ "aria-hidden": "true",
1645
+ style: {
1646
+ position: "absolute",
1647
+ left: trailingLeft,
1648
+ top: "50%",
1649
+ transform: "translateY(-50%)",
1650
+ width: trailingWidth,
1651
+ height: size,
1652
+ backgroundColor: inactiveTrack,
1653
+ opacity: disabled ? 0.38 : 1,
1654
+ borderTopLeftRadius: innerR,
1655
+ borderBottomLeftRadius: innerR,
1656
+ borderTopRightRadius: outerR,
1657
+ borderBottomRightRadius: outerR
1658
+ }
1659
+ }
1660
+ ),
1661
+ ticks.map((tick) => {
1662
+ const tickPct = (tick - min) / (max - min);
1663
+ const isActive = tickPct > startPercent && tickPct < endPercent;
1664
+ return /* @__PURE__ */ jsxRuntime.jsx(
1665
+ "div",
1666
+ {
1667
+ "aria-hidden": "true",
1668
+ style: {
1669
+ position: "absolute",
1670
+ width: tickSize,
1671
+ height: tickSize,
1672
+ borderRadius: "50%",
1673
+ backgroundColor: disabled ? SliderColors.disabledTick : isActive ? `var(--md-sys-color-${variant}-container)` : `var(--md-sys-color-${variant})`,
1674
+ opacity: disabled ? 0.38 : 1,
1675
+ left: `calc(${trackInset2}px + ${tickPct} * (100% - ${trackInset2 * 2}px) - ${tickSize / 2}px)`,
1676
+ top: "50%",
1677
+ transform: "translateY(-50%)"
1678
+ }
1679
+ },
1680
+ tick
1681
+ );
1682
+ })
1683
+ ]
1684
+ }
1685
+ );
1686
+ }
1687
+ const insetLimit = thumbGap + thumbWidthDefault / 2;
1688
+ const trackInset = Math.min(size / 2, insetLimit);
1689
+ const cyStart = `calc(${trackInset}px + ${startPercent} * (100% - ${trackInset * 2}px))`;
1690
+ const cyEnd = `calc(${trackInset}px + ${endPercent} * (100% - ${trackInset * 2}px))`;
1691
+ const gapWithThumbStr = `${thumbGap + thumbHalfWidth}px`;
1692
+ const leadingHeight = `max(0px, calc(${cyStart} - ${gapWithThumbStr}))`;
1693
+ const activeBottom = `calc(${cyStart} + ${gapWithThumbStr})`;
1694
+ const activeHeight = `max(0px, calc(${cyEnd} - ${cyStart} - ${gapWithThumbStr} * 2))`;
1695
+ const trailingBottom = `calc(${cyEnd} + ${gapWithThumbStr})`;
1696
+ const trailingHeight = `max(0px, calc(100% - (${cyEnd} + ${gapWithThumbStr})))`;
1697
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1698
+ "div",
1699
+ {
1700
+ ref: trackRef,
1701
+ className: cn(
1702
+ "relative h-full",
1703
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
1704
+ ),
1705
+ style: { width: thumbHeight },
1706
+ onPointerDown: onTrackPointerDown,
1707
+ "aria-hidden": "true",
1708
+ children: [
1709
+ /* @__PURE__ */ jsxRuntime.jsx(
1710
+ "div",
1711
+ {
1712
+ "aria-hidden": "true",
1713
+ style: {
1714
+ position: "absolute",
1715
+ bottom: 0,
1716
+ left: "50%",
1717
+ transform: "translateX(-50%)",
1718
+ height: leadingHeight,
1719
+ width: size,
1720
+ backgroundColor: inactiveTrack,
1721
+ opacity: disabled ? 0.38 : 1,
1722
+ borderBottomLeftRadius: outerR,
1723
+ borderBottomRightRadius: outerR,
1724
+ borderTopLeftRadius: innerR,
1725
+ borderTopRightRadius: innerR
1726
+ }
1727
+ }
1728
+ ),
1729
+ /* @__PURE__ */ jsxRuntime.jsx(
1730
+ "div",
1731
+ {
1732
+ "aria-hidden": "true",
1733
+ style: {
1734
+ position: "absolute",
1735
+ bottom: activeBottom,
1736
+ left: "50%",
1737
+ transform: "translateX(-50%)",
1738
+ height: activeHeight,
1739
+ width: size,
1740
+ backgroundColor: activeTrack,
1741
+ opacity: disabled ? 0.38 : 1,
1742
+ borderBottomLeftRadius: startPercent <= 0 ? outerR : innerR,
1743
+ borderBottomRightRadius: startPercent <= 0 ? outerR : innerR,
1744
+ borderTopLeftRadius: endPercent >= 1 ? outerR : innerR,
1745
+ borderTopRightRadius: endPercent >= 1 ? outerR : innerR
1746
+ }
1747
+ }
1748
+ ),
1749
+ /* @__PURE__ */ jsxRuntime.jsx(
1750
+ "div",
1751
+ {
1752
+ "aria-hidden": "true",
1753
+ style: {
1754
+ position: "absolute",
1755
+ bottom: trailingBottom,
1756
+ left: "50%",
1757
+ transform: "translateX(-50%)",
1758
+ height: trailingHeight,
1759
+ width: size,
1760
+ backgroundColor: inactiveTrack,
1761
+ opacity: disabled ? 0.38 : 1,
1762
+ borderTopLeftRadius: outerR,
1763
+ borderTopRightRadius: outerR,
1764
+ borderBottomLeftRadius: innerR,
1765
+ borderBottomRightRadius: innerR
1766
+ }
1767
+ }
1768
+ ),
1769
+ ticks.map((tick) => {
1770
+ const tickPct = (tick - min) / (max - min);
1771
+ const isActive = tickPct > startPercent && tickPct < endPercent;
1772
+ return /* @__PURE__ */ jsxRuntime.jsx(
1773
+ "div",
1774
+ {
1775
+ "aria-hidden": "true",
1776
+ style: {
1777
+ position: "absolute",
1778
+ width: tickSize,
1779
+ height: tickSize,
1780
+ borderRadius: "50%",
1781
+ backgroundColor: disabled ? SliderColors.disabledTick : isActive ? `var(--md-sys-color-${variant}-container)` : `var(--md-sys-color-${variant})`,
1782
+ opacity: disabled ? 0.38 : 1,
1783
+ bottom: `calc(${trackInset}px + ${tickPct} * (100% - ${trackInset * 2}px) - ${tickSize / 2}px)`,
1784
+ left: "50%",
1785
+ transform: "translateX(-50%)"
1786
+ }
1787
+ },
1788
+ tick
1789
+ );
1790
+ })
1791
+ ]
1792
+ }
1793
+ );
1794
+ });
1795
+ var RangeSliderComponent = React4__namespace.forwardRef(
1796
+ ({
1797
+ value: controlledValue,
1798
+ defaultValue,
1799
+ onValueChange,
1800
+ onValueChangeEnd,
1801
+ min = 0,
1802
+ max = 100,
1803
+ step = 0,
1804
+ orientation = "horizontal",
1805
+ trackSize = "m",
1806
+ trackShape = "md3",
1807
+ variant = "primary",
1808
+ disabled = false,
1809
+ showValueIndicator = false,
1810
+ showTicks = false,
1811
+ formatValue,
1812
+ className,
1813
+ "aria-label": ariaLabel
1814
+ }, ref) => {
1815
+ var _a, _b;
1816
+ const isHorizontal = orientation === "horizontal";
1817
+ const defaultStart = (_a = defaultValue == null ? void 0 : defaultValue[0]) != null ? _a : min;
1818
+ const defaultEnd = (_b = defaultValue == null ? void 0 : defaultValue[1]) != null ? _b : max;
1819
+ const [internalValue, setInternalValue] = React4__namespace.useState([
1820
+ defaultStart,
1821
+ defaultEnd
1822
+ ]);
1823
+ const resolvedValue = controlledValue !== void 0 ? controlledValue : internalValue;
1824
+ const { coerce, snap, toPercent, ticks } = useSliderMath({
1825
+ min,
1826
+ max,
1827
+ step
1828
+ });
1829
+ const startValue = snap(coerce(resolvedValue[0]));
1830
+ const endValue = snap(coerce(resolvedValue[1]));
1831
+ const startPercent = toPercent(startValue);
1832
+ const endPercent = toPercent(endValue);
1833
+ const [topThumb, setTopThumb] = React4__namespace.useState("end");
1834
+ const trackRef = React4__namespace.useRef(null);
1835
+ const minGap = step > 0 ? step : (max - min) / 1e3;
1836
+ const handleStartChange = React4__namespace.useCallback(
1837
+ (newStart) => {
1838
+ setTopThumb("start");
1839
+ const clamped = Math.min(newStart, endValue - minGap);
1840
+ const final = snap(coerce(clamped));
1841
+ if (controlledValue === void 0) {
1842
+ setInternalValue([final, endValue]);
1843
+ }
1844
+ onValueChange == null ? void 0 : onValueChange([final, endValue]);
1845
+ },
1846
+ [controlledValue, coerce, endValue, minGap, onValueChange, snap]
1847
+ );
1848
+ const handleEndChange = React4__namespace.useCallback(
1849
+ (newEnd) => {
1850
+ setTopThumb("end");
1851
+ const clamped = Math.max(newEnd, startValue + minGap);
1852
+ const final = snap(coerce(clamped));
1853
+ if (controlledValue === void 0) {
1854
+ setInternalValue([startValue, final]);
1855
+ }
1856
+ onValueChange == null ? void 0 : onValueChange([startValue, final]);
1857
+ },
1858
+ [controlledValue, coerce, minGap, onValueChange, snap, startValue]
1859
+ );
1860
+ const handleStartChangeEnd = React4__namespace.useCallback(
1861
+ (v) => onValueChangeEnd == null ? void 0 : onValueChangeEnd([v, endValue]),
1862
+ [endValue, onValueChangeEnd]
1863
+ );
1864
+ const handleEndChangeEnd = React4__namespace.useCallback(
1865
+ (v) => onValueChangeEnd == null ? void 0 : onValueChangeEnd([startValue, v]),
1866
+ [onValueChangeEnd, startValue]
1867
+ );
1868
+ const handleTrackPointerDown = React4__namespace.useCallback(
1869
+ (e) => {
1870
+ if (disabled) return;
1871
+ const trackEl = trackRef.current;
1872
+ if (!trackEl) return;
1873
+ const rect = trackEl.getBoundingClientRect();
1874
+ let clickPercent;
1875
+ const insetLimit = SliderTokens.thumbGap + SliderTokens.thumbWidthDefault / 2;
1876
+ const trackInset = Math.min(
1877
+ SliderTokens.trackSizes[trackSize] / 2,
1878
+ insetLimit
1879
+ );
1880
+ if (isHorizontal) {
1881
+ const x = e.clientX - rect.left;
1882
+ clickPercent = (x - trackInset) / (rect.width - trackInset * 2);
1883
+ } else {
1884
+ const y = rect.bottom - e.clientY;
1885
+ clickPercent = (y - trackInset) / (rect.height - trackInset * 2);
1886
+ }
1887
+ const clamped = Math.max(0, Math.min(1, clickPercent));
1888
+ const rawValue = min + clamped * (max - min);
1889
+ const clickValue = snap(coerce(rawValue));
1890
+ const distStart = Math.abs(clickValue - startValue);
1891
+ const distEnd = Math.abs(clickValue - endValue);
1892
+ if (distStart <= distEnd) {
1893
+ handleStartChange(clickValue);
1894
+ } else {
1895
+ handleEndChange(clickValue);
1896
+ }
1897
+ },
1898
+ [
1899
+ coerce,
1900
+ disabled,
1901
+ endValue,
1902
+ handleEndChange,
1903
+ handleStartChange,
1904
+ isHorizontal,
1905
+ max,
1906
+ min,
1907
+ snap,
1908
+ startValue,
1909
+ trackSize
1910
+ ]
1911
+ );
1912
+ const id = React4__namespace.useId();
1913
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1914
+ "div",
1915
+ {
1916
+ ref,
1917
+ className: cn(
1918
+ "relative flex items-center",
1919
+ isHorizontal ? "w-full flex-row" : "h-full flex-col",
1920
+ disabled && "pointer-events-none",
1921
+ className
1922
+ ),
1923
+ style: isHorizontal ? { minWidth: 0 } : { minHeight: 0 },
1924
+ children: [
1925
+ /* @__PURE__ */ jsxRuntime.jsx(
1926
+ RangeTrack,
1927
+ {
1928
+ startPercent,
1929
+ endPercent,
1930
+ trackSize,
1931
+ trackShape,
1932
+ orientation,
1933
+ variant,
1934
+ disabled,
1935
+ ticks: showTicks ? ticks : [],
1936
+ min,
1937
+ max,
1938
+ trackRef,
1939
+ onTrackPointerDown: handleTrackPointerDown
1940
+ }
1941
+ ),
1942
+ /* @__PURE__ */ jsxRuntime.jsx(
1943
+ SliderThumb,
1944
+ {
1945
+ value: startValue,
1946
+ percent: startPercent,
1947
+ min,
1948
+ max,
1949
+ step,
1950
+ disabled,
1951
+ orientation,
1952
+ trackSize,
1953
+ variant,
1954
+ showValueIndicator,
1955
+ trackRef,
1956
+ onValueChange: handleStartChange,
1957
+ onValueChangeEnd: handleStartChangeEnd,
1958
+ formatValue,
1959
+ thumbId: `${id}-start`,
1960
+ zIndex: topThumb === "start" ? 2 : 1,
1961
+ "aria-label": ariaLabel ? `${ariaLabel} start` : "Range start"
1962
+ }
1963
+ ),
1964
+ /* @__PURE__ */ jsxRuntime.jsx(
1965
+ SliderThumb,
1966
+ {
1967
+ value: endValue,
1968
+ percent: endPercent,
1969
+ min,
1970
+ max,
1971
+ step,
1972
+ disabled,
1973
+ orientation,
1974
+ trackSize,
1975
+ variant,
1976
+ showValueIndicator,
1977
+ trackRef,
1978
+ onValueChange: handleEndChange,
1979
+ onValueChangeEnd: handleEndChangeEnd,
1980
+ formatValue,
1981
+ thumbId: `${id}-end`,
1982
+ zIndex: topThumb === "end" ? 2 : 1,
1983
+ "aria-label": ariaLabel ? `${ariaLabel} end` : "Range end"
1984
+ }
1985
+ )
1986
+ ]
1987
+ }
1988
+ ) });
1989
+ }
1990
+ );
1991
+ RangeSliderComponent.displayName = "RangeSlider";
1992
+ var RangeSlider = React4__namespace.memo(RangeSliderComponent);
1993
+ function getHorizontalRadius(isLeading, innerR, outerR) {
1994
+ if (isLeading) {
1995
+ return {
1996
+ borderTopLeftRadius: outerR,
1997
+ borderBottomLeftRadius: outerR,
1998
+ borderTopRightRadius: innerR,
1999
+ borderBottomRightRadius: innerR
2000
+ };
2001
+ }
2002
+ return {
2003
+ borderTopLeftRadius: innerR,
2004
+ borderBottomLeftRadius: innerR,
2005
+ borderTopRightRadius: outerR,
2006
+ borderBottomRightRadius: outerR
2007
+ };
2008
+ }
2009
+ function getVerticalRadius(isLeading, innerR, outerR) {
2010
+ if (isLeading) {
2011
+ return {
2012
+ borderBottomLeftRadius: outerR,
2013
+ borderBottomRightRadius: outerR,
2014
+ borderTopLeftRadius: innerR,
2015
+ borderTopRightRadius: innerR
2016
+ };
2017
+ }
2018
+ return {
2019
+ borderTopLeftRadius: outerR,
2020
+ borderTopRightRadius: outerR,
2021
+ borderBottomLeftRadius: innerR,
2022
+ borderBottomRightRadius: innerR
2023
+ };
2024
+ }
2025
+ var allInnerRadius = (innerR) => ({
2026
+ borderTopLeftRadius: innerR,
2027
+ borderBottomLeftRadius: innerR,
2028
+ borderTopRightRadius: innerR,
2029
+ borderBottomRightRadius: innerR
2030
+ });
2031
+ var InsetIcon = React4__namespace.memo(function InsetIcon2({
2032
+ icon,
2033
+ isOnActiveSegment,
2034
+ position,
2035
+ orientation,
2036
+ trackSize,
2037
+ trackSizeToken,
2038
+ disabled,
2039
+ variant,
2040
+ prefersReduced
2041
+ }) {
2042
+ const iconSize = Math.min(
2043
+ SliderTokens.insetIconSizes[trackSizeToken],
2044
+ Math.max(4, trackSize - SliderTokens.insetIconPadding * 2)
2045
+ );
2046
+ const activeColor = `var(--md-sys-color-on-${variant})`;
2047
+ const inactiveColor = `var(--md-sys-color-${variant})`;
2048
+ const isHorizontal = orientation === "horizontal";
2049
+ const fastFade = prefersReduced ? { duration: 0 } : { duration: 0.12 };
2050
+ return /* @__PURE__ */ jsxRuntime.jsx(
2051
+ react.m.div,
2052
+ {
2053
+ "aria-hidden": "true",
2054
+ className: "[&_svg]:w-full [&_svg]:h-full",
2055
+ initial: __spreadValues({
2056
+ opacity: 0
2057
+ }, isHorizontal ? { left: position } : { bottom: position }),
2058
+ animate: {
2059
+ [isHorizontal ? "left" : "bottom"]: position,
2060
+ opacity: disabled ? 0.38 : 1,
2061
+ color: isOnActiveSegment ? activeColor : inactiveColor
2062
+ },
2063
+ exit: { opacity: 0, transition: fastFade },
2064
+ transition: prefersReduced ? { duration: 0 } : {
2065
+ left: { type: "spring", stiffness: 500, damping: 40 },
2066
+ bottom: { type: "spring", stiffness: 500, damping: 40 },
2067
+ opacity: fastFade,
2068
+ color: fastFade
2069
+ },
2070
+ style: __spreadValues({
2071
+ position: "absolute",
2072
+ width: iconSize,
2073
+ height: iconSize,
2074
+ display: "flex",
2075
+ alignItems: "center",
2076
+ justifyContent: "center",
2077
+ pointerEvents: "none",
2078
+ zIndex: 1,
2079
+ willChange: isHorizontal ? "left" : "bottom"
2080
+ }, isHorizontal ? { top: "50%", transform: "translateY(-50%)" } : { left: "50%", transform: "translateX(-50%)" }),
2081
+ children: icon
2082
+ }
2083
+ );
2084
+ });
2085
+ function Ticks({
2086
+ ticks,
2087
+ min,
2088
+ max,
2089
+ percent,
2090
+ orientation,
2091
+ variant,
2092
+ isCentered,
2093
+ disabled,
2094
+ trackInset
2095
+ }) {
2096
+ if (ticks.length === 0) return null;
2097
+ const { thumbGap, thumbWidthDefault, tickSize } = SliderTokens;
2098
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: ticks.map((tick) => {
2099
+ const tickPercent = (tick - min) / (max - min);
2100
+ const isOnActive = isCentered ? percent >= 0.5 ? tickPercent >= 0.5 && tickPercent <= percent : tickPercent <= 0.5 && tickPercent >= percent : tickPercent <= percent;
2101
+ const thumbStart = percent - (thumbGap + thumbWidthDefault / 2) / 100;
2102
+ const thumbEnd = percent + (thumbGap + thumbWidthDefault / 2) / 100;
2103
+ if (tickPercent > thumbStart && tickPercent < thumbEnd) return null;
2104
+ const color = disabled ? SliderColors.disabledTick : isOnActive ? `var(--md-sys-color-${variant}-container)` : `var(--md-sys-color-${variant})`;
2105
+ const style = __spreadValues({
2106
+ position: "absolute",
2107
+ width: tickSize,
2108
+ height: tickSize,
2109
+ borderRadius: "50%",
2110
+ backgroundColor: color,
2111
+ opacity: disabled ? 0.38 : 1
2112
+ }, orientation === "horizontal" ? {
2113
+ left: `calc(${trackInset}px + ${tickPercent} * (100% - ${trackInset * 2}px) - ${tickSize / 2}px)`,
2114
+ top: "50%",
2115
+ transform: "translateY(-50%)"
2116
+ } : {
2117
+ // Vertical: bottom=0%, top=100% (inverted Y-axis)
2118
+ bottom: `calc(${trackInset}px + ${tickPercent} * (100% - ${trackInset * 2}px) - ${tickSize / 2}px)`,
2119
+ left: "50%",
2120
+ transform: "translateX(-50%)"
2121
+ });
2122
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, "aria-hidden": "true" }, tick);
2123
+ }) });
2124
+ }
2125
+ var SliderTrack = React4__namespace.memo(function SliderTrack2({
2126
+ percent,
2127
+ trackSize,
2128
+ orientation,
2129
+ variant,
2130
+ isCentered,
2131
+ min,
2132
+ max,
2133
+ disabled,
2134
+ trackRef,
2135
+ onTrackPointerDown,
2136
+ ticks = [],
2137
+ insetIcon,
2138
+ insetIconAtMin,
2139
+ insetIconTrailing,
2140
+ insetIconAtMax,
2141
+ value,
2142
+ trackShape = "md3"
2143
+ }) {
2144
+ var _a;
2145
+ const isHorizontal = orientation === "horizontal";
2146
+ const size = SliderTokens.trackSizes[trackSize];
2147
+ const thumbHeight = SliderTokens.thumbHeights[trackSize];
2148
+ const { thumbGap, thumbWidthDefault, trackInnerRadius } = SliderTokens;
2149
+ const innerR = trackInnerRadius;
2150
+ let outerR = size / 2;
2151
+ if (trackShape === "md3") {
2152
+ outerR = Math.min(SliderTokens.trackShapes[trackSize], size / 2);
2153
+ } else if (typeof trackShape === "number") {
2154
+ outerR = Math.min(trackShape, size / 2);
2155
+ }
2156
+ const thumbHalfWidth = thumbWidthDefault / 2;
2157
+ const gapWithThumbStr = `${thumbGap + thumbHalfWidth}px`;
2158
+ const hasAnyInsetIcon = Boolean(insetIcon || insetIconTrailing);
2159
+ const prefersReduced = (_a = react.useReducedMotion()) != null ? _a : false;
2160
+ const [trackWidth, setTrackWidth] = React4__namespace.useState(0);
2161
+ React4__namespace.useLayoutEffect(() => {
2162
+ const el = trackRef.current;
2163
+ if (!el || !hasAnyInsetIcon) return;
2164
+ setTrackWidth(isHorizontal ? el.clientWidth : el.clientHeight);
2165
+ const ro = new ResizeObserver(() => {
2166
+ setTrackWidth(isHorizontal ? el.clientWidth : el.clientHeight);
2167
+ });
2168
+ ro.observe(el);
2169
+ return () => ro.disconnect();
2170
+ }, [hasAnyInsetIcon, isHorizontal, trackRef]);
2171
+ const activeIconSize = Math.min(
2172
+ SliderTokens.insetIconSizes[trackSize],
2173
+ Math.max(4, size - SliderTokens.insetIconPadding * 2)
2174
+ );
2175
+ const iconTotalWidth = activeIconSize + SliderTokens.insetIconPadding * 2 + thumbGap + thumbHalfWidth;
2176
+ const iconThreshold = trackWidth > 0 ? iconTotalWidth / trackWidth : 0.15;
2177
+ const HYSTERESIS_GAP = 0.04;
2178
+ const trailingActiveRef = React4__namespace.useRef(1 - percent <= iconThreshold);
2179
+ const leadingActiveRef = React4__namespace.useRef(percent > iconThreshold);
2180
+ const trailingPercent = 1 - percent;
2181
+ if (trailingActiveRef.current) {
2182
+ if (trailingPercent > iconThreshold + HYSTERESIS_GAP) {
2183
+ trailingActiveRef.current = false;
2184
+ }
2185
+ } else {
2186
+ if (trailingPercent <= iconThreshold) {
2187
+ trailingActiveRef.current = true;
2188
+ }
2189
+ }
2190
+ const trailingOnActive = trailingActiveRef.current;
2191
+ if (leadingActiveRef.current) {
2192
+ if (percent <= iconThreshold - HYSTERESIS_GAP) {
2193
+ leadingActiveRef.current = false;
2194
+ }
2195
+ } else {
2196
+ if (percent > iconThreshold) {
2197
+ leadingActiveRef.current = true;
2198
+ }
2199
+ }
2200
+ const leadingOnActive = leadingActiveRef.current;
2201
+ const isAtMin = value !== void 0 && value <= min;
2202
+ const resolvedLeadingIcon = isAtMin && insetIconAtMin ? insetIconAtMin : insetIcon;
2203
+ const isAtMax = value !== void 0 && value >= max;
2204
+ const resolvedTrailingIcon = isAtMax && insetIconAtMax ? insetIconAtMax : insetIconTrailing;
2205
+ const activeColor = disabled ? SliderColors.disabledActiveTrack : `var(--md-sys-color-${variant})`;
2206
+ const inactiveColor = disabled ? SliderColors.disabledInactiveTrack : `var(--md-sys-color-${variant}-container)`;
2207
+ const insetLimit = SliderTokens.thumbGap + SliderTokens.thumbWidthDefault / 2;
2208
+ const trackInset = Math.min(size / 2, insetLimit);
2209
+ const gapTotal = thumbGap + thumbHalfWidth;
2210
+ const thumbCenter = `calc(${trackInset}px + ${percent} * (100% - ${trackInset * 2}px))`;
2211
+ const leadingActiveLeft = `${trackInset + SliderTokens.insetIconPadding}px`;
2212
+ const leadingInactiveLeft = `calc(${thumbCenter} + ${gapTotal}px + ${SliderTokens.insetIconPadding}px)`;
2213
+ const trailingInactiveLeft = `calc(100% - ${trackInset}px - ${activeIconSize}px - ${SliderTokens.insetIconPadding}px)`;
2214
+ const trailingActiveLeft = `calc(${thumbCenter} - ${gapTotal}px - ${activeIconSize}px - ${SliderTokens.insetIconPadding}px)`;
2215
+ if (isHorizontal) {
2216
+ const cxStr = `calc(${trackInset}px + ${percent} * (100% - ${trackInset * 2}px))`;
2217
+ const segments2 = [];
2218
+ if (!isCentered) {
2219
+ const leftSegmentWidth = `max(0px, calc(${cxStr} - ${gapWithThumbStr}))`;
2220
+ const rightSegmentLeft = `calc(${cxStr} + ${gapWithThumbStr})`;
2221
+ const rightSegmentWidth = `max(0px, calc(100% - (${cxStr} + ${gapWithThumbStr})))`;
2222
+ segments2.push(
2223
+ /* @__PURE__ */ jsxRuntime.jsx(
2224
+ "div",
2225
+ {
2226
+ "aria-hidden": "true",
2227
+ style: __spreadValues({
2228
+ position: "absolute",
2229
+ left: 0,
2230
+ top: "50%",
2231
+ transform: "translateY(-50%)",
2232
+ width: leftSegmentWidth,
2233
+ height: size,
2234
+ backgroundColor: activeColor,
2235
+ opacity: disabled ? 0.38 : 1
2236
+ }, getHorizontalRadius(true, innerR, outerR))
2237
+ },
2238
+ "left"
2239
+ )
2240
+ );
2241
+ segments2.push(
2242
+ /* @__PURE__ */ jsxRuntime.jsx(
2243
+ "div",
2244
+ {
2245
+ "aria-hidden": "true",
2246
+ style: __spreadValues({
2247
+ position: "absolute",
2248
+ left: rightSegmentLeft,
2249
+ top: "50%",
2250
+ transform: "translateY(-50%)",
2251
+ width: rightSegmentWidth,
2252
+ height: size,
2253
+ backgroundColor: inactiveColor,
2254
+ opacity: disabled ? 0.38 : 1
2255
+ }, getHorizontalRadius(false, innerR, outerR))
2256
+ },
2257
+ "right"
2258
+ )
2259
+ );
2260
+ } else {
2261
+ const halfCenterGap = SliderTokens.thumbGap / 2;
2262
+ if (percent >= 0.5) {
2263
+ const leftBaseWidth = `max(0px, min(calc(50% - ${halfCenterGap}px), calc(${cxStr} - ${gapWithThumbStr})))`;
2264
+ segments2.push(
2265
+ /* @__PURE__ */ jsxRuntime.jsx(
2266
+ "div",
2267
+ {
2268
+ "aria-hidden": "true",
2269
+ style: __spreadValues({
2270
+ position: "absolute",
2271
+ left: 0,
2272
+ top: "50%",
2273
+ transform: "translateY(-50%)",
2274
+ width: leftBaseWidth,
2275
+ height: size,
2276
+ backgroundColor: inactiveColor,
2277
+ opacity: disabled ? 0.38 : 1
2278
+ }, getHorizontalRadius(true, innerR, outerR))
2279
+ },
2280
+ "left-base"
2281
+ )
2282
+ );
2283
+ const centerActiveLeft = `calc(50% + ${halfCenterGap}px)`;
2284
+ const centerActiveWidth = `max(0px, calc(${cxStr} - ${gapWithThumbStr} - (50% + ${halfCenterGap}px)))`;
2285
+ segments2.push(
2286
+ /* @__PURE__ */ jsxRuntime.jsx(
2287
+ "div",
2288
+ {
2289
+ "aria-hidden": "true",
2290
+ style: __spreadValues({
2291
+ position: "absolute",
2292
+ left: centerActiveLeft,
2293
+ top: "50%",
2294
+ transform: "translateY(-50%)",
2295
+ width: centerActiveWidth,
2296
+ height: size,
2297
+ backgroundColor: activeColor,
2298
+ opacity: disabled ? 0.38 : 1
2299
+ }, allInnerRadius(innerR))
2300
+ },
2301
+ "center-active"
2302
+ )
2303
+ );
2304
+ const rightBaseLeft = `calc(${cxStr} + ${gapWithThumbStr})`;
2305
+ const rightBaseWidth = `max(0px, calc(100% - (${cxStr} + ${gapWithThumbStr})))`;
2306
+ segments2.push(
2307
+ /* @__PURE__ */ jsxRuntime.jsx(
2308
+ "div",
2309
+ {
2310
+ "aria-hidden": "true",
2311
+ style: __spreadValues({
2312
+ position: "absolute",
2313
+ left: rightBaseLeft,
2314
+ top: "50%",
2315
+ transform: "translateY(-50%)",
2316
+ width: rightBaseWidth,
2317
+ height: size,
2318
+ backgroundColor: inactiveColor,
2319
+ opacity: disabled ? 0.38 : 1
2320
+ }, getHorizontalRadius(false, innerR, outerR))
2321
+ },
2322
+ "right-base"
2323
+ )
2324
+ );
2325
+ } else {
2326
+ const leftBaseWidth = `max(0px, calc(${cxStr} - ${gapWithThumbStr}))`;
2327
+ segments2.push(
2328
+ /* @__PURE__ */ jsxRuntime.jsx(
2329
+ "div",
2330
+ {
2331
+ "aria-hidden": "true",
2332
+ style: __spreadValues({
2333
+ position: "absolute",
2334
+ left: 0,
2335
+ top: "50%",
2336
+ transform: "translateY(-50%)",
2337
+ width: leftBaseWidth,
2338
+ height: size,
2339
+ backgroundColor: inactiveColor,
2340
+ opacity: disabled ? 0.38 : 1
2341
+ }, getHorizontalRadius(true, innerR, outerR))
2342
+ },
2343
+ "left-base"
2344
+ )
2345
+ );
2346
+ const centerActiveLeft = `calc(${cxStr} + ${gapWithThumbStr})`;
2347
+ const centerActiveWidth = `max(0px, calc(50% - ${halfCenterGap}px - (${cxStr} + ${gapWithThumbStr})))`;
2348
+ segments2.push(
2349
+ /* @__PURE__ */ jsxRuntime.jsx(
2350
+ "div",
2351
+ {
2352
+ "aria-hidden": "true",
2353
+ style: __spreadValues({
2354
+ position: "absolute",
2355
+ left: centerActiveLeft,
2356
+ top: "50%",
2357
+ transform: "translateY(-50%)",
2358
+ width: centerActiveWidth,
2359
+ height: size,
2360
+ backgroundColor: activeColor,
2361
+ opacity: disabled ? 0.38 : 1
2362
+ }, allInnerRadius(innerR))
2363
+ },
2364
+ "center-active"
2365
+ )
2366
+ );
2367
+ const rightBaseLeft = `max(calc(50% + ${halfCenterGap}px), calc(${cxStr} + ${gapWithThumbStr}))`;
2368
+ const rightBaseWidth = `max(0px, calc(100% - max(calc(50% + ${halfCenterGap}px), calc(${cxStr} + ${gapWithThumbStr}))))`;
2369
+ segments2.push(
2370
+ /* @__PURE__ */ jsxRuntime.jsx(
2371
+ "div",
2372
+ {
2373
+ "aria-hidden": "true",
2374
+ style: __spreadValues({
2375
+ position: "absolute",
2376
+ left: rightBaseLeft,
2377
+ top: "50%",
2378
+ transform: "translateY(-50%)",
2379
+ width: rightBaseWidth,
2380
+ height: size,
2381
+ backgroundColor: inactiveColor,
2382
+ opacity: disabled ? 0.38 : 1
2383
+ }, getHorizontalRadius(false, innerR, outerR))
2384
+ },
2385
+ "right-base"
2386
+ )
2387
+ );
2388
+ }
2389
+ }
2390
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2391
+ "div",
2392
+ {
2393
+ ref: trackRef,
2394
+ className: cn(
2395
+ "relative w-full",
2396
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
2397
+ ),
2398
+ style: { height: thumbHeight },
2399
+ onPointerDown: onTrackPointerDown,
2400
+ "aria-hidden": "true",
2401
+ children: [
2402
+ segments2,
2403
+ ticks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
2404
+ Ticks,
2405
+ {
2406
+ ticks,
2407
+ min,
2408
+ max,
2409
+ percent,
2410
+ orientation,
2411
+ disabled,
2412
+ variant,
2413
+ isCentered,
2414
+ trackInset
2415
+ }
2416
+ ),
2417
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: resolvedLeadingIcon && /* @__PURE__ */ jsxRuntime.jsx(
2418
+ InsetIcon,
2419
+ {
2420
+ icon: resolvedLeadingIcon,
2421
+ isOnActiveSegment: leadingOnActive,
2422
+ position: leadingOnActive ? leadingActiveLeft : leadingInactiveLeft,
2423
+ orientation,
2424
+ trackSize: size,
2425
+ trackSizeToken: trackSize,
2426
+ disabled,
2427
+ variant,
2428
+ prefersReduced
2429
+ },
2430
+ isAtMin ? "lead-min" : leadingOnActive ? "lead-active" : "lead-inactive"
2431
+ ) }),
2432
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: resolvedTrailingIcon && /* @__PURE__ */ jsxRuntime.jsx(
2433
+ InsetIcon,
2434
+ {
2435
+ icon: resolvedTrailingIcon,
2436
+ isOnActiveSegment: trailingOnActive,
2437
+ position: trailingOnActive ? trailingActiveLeft : trailingInactiveLeft,
2438
+ orientation,
2439
+ trackSize: size,
2440
+ trackSizeToken: trackSize,
2441
+ disabled,
2442
+ variant,
2443
+ prefersReduced
2444
+ },
2445
+ isAtMax ? "trail-max" : trailingOnActive ? "trail-active" : "trail-inactive"
2446
+ ) })
2447
+ ]
2448
+ }
2449
+ );
2450
+ }
2451
+ const cyStr = `calc(${trackInset}px + ${percent} * (100% - ${trackInset * 2}px))`;
2452
+ const segments = [];
2453
+ if (!isCentered) {
2454
+ const bottomSegmentHeight = `max(0px, calc(${cyStr} - ${gapWithThumbStr}))`;
2455
+ const topSegmentBottom = `calc(${cyStr} + ${gapWithThumbStr})`;
2456
+ const topSegmentHeight = `max(0px, calc(100% - (${cyStr} + ${gapWithThumbStr})))`;
2457
+ segments.push(
2458
+ /* @__PURE__ */ jsxRuntime.jsx(
2459
+ "div",
2460
+ {
2461
+ "aria-hidden": "true",
2462
+ style: __spreadValues({
2463
+ position: "absolute",
2464
+ bottom: 0,
2465
+ left: "50%",
2466
+ transform: "translateX(-50%)",
2467
+ height: bottomSegmentHeight,
2468
+ width: size,
2469
+ backgroundColor: activeColor,
2470
+ opacity: disabled ? 0.38 : 1
2471
+ }, getVerticalRadius(true, innerR, outerR))
2472
+ },
2473
+ "bottom"
2474
+ )
2475
+ );
2476
+ segments.push(
2477
+ /* @__PURE__ */ jsxRuntime.jsx(
2478
+ "div",
2479
+ {
2480
+ "aria-hidden": "true",
2481
+ style: __spreadValues({
2482
+ position: "absolute",
2483
+ bottom: topSegmentBottom,
2484
+ left: "50%",
2485
+ transform: "translateX(-50%)",
2486
+ height: topSegmentHeight,
2487
+ width: size,
2488
+ backgroundColor: inactiveColor,
2489
+ opacity: disabled ? 0.38 : 1
2490
+ }, getVerticalRadius(false, innerR, outerR))
2491
+ },
2492
+ "top"
2493
+ )
2494
+ );
2495
+ } else {
2496
+ const halfCenterGap = SliderTokens.thumbGap / 2;
2497
+ if (percent >= 0.5) {
2498
+ const bottomBaseHeight = `max(0px, min(calc(50% - ${halfCenterGap}px), calc(${cyStr} - ${gapWithThumbStr})))`;
2499
+ segments.push(
2500
+ /* @__PURE__ */ jsxRuntime.jsx(
2501
+ "div",
2502
+ {
2503
+ "aria-hidden": "true",
2504
+ style: __spreadValues({
2505
+ position: "absolute",
2506
+ bottom: 0,
2507
+ left: "50%",
2508
+ transform: "translateX(-50%)",
2509
+ height: bottomBaseHeight,
2510
+ width: size,
2511
+ backgroundColor: inactiveColor,
2512
+ opacity: disabled ? 0.38 : 1
2513
+ }, getVerticalRadius(true, innerR, outerR))
2514
+ },
2515
+ "bottom-base"
2516
+ )
2517
+ );
2518
+ const centerActiveBottom = `calc(50% + ${halfCenterGap}px)`;
2519
+ const centerActiveHeight = `max(0px, calc(${cyStr} - ${gapWithThumbStr} - (50% + ${halfCenterGap}px)))`;
2520
+ segments.push(
2521
+ /* @__PURE__ */ jsxRuntime.jsx(
2522
+ "div",
2523
+ {
2524
+ "aria-hidden": "true",
2525
+ style: __spreadValues({
2526
+ position: "absolute",
2527
+ bottom: centerActiveBottom,
2528
+ left: "50%",
2529
+ transform: "translateX(-50%)",
2530
+ height: centerActiveHeight,
2531
+ width: size,
2532
+ backgroundColor: activeColor,
2533
+ opacity: disabled ? 0.38 : 1
2534
+ }, allInnerRadius(innerR))
2535
+ },
2536
+ "center-active"
2537
+ )
2538
+ );
2539
+ const topBaseBottom = `calc(${cyStr} + ${gapWithThumbStr})`;
2540
+ const topBaseHeight = `max(0px, calc(100% - (${cyStr} + ${gapWithThumbStr})))`;
2541
+ segments.push(
2542
+ /* @__PURE__ */ jsxRuntime.jsx(
2543
+ "div",
2544
+ {
2545
+ "aria-hidden": "true",
2546
+ style: __spreadValues({
2547
+ position: "absolute",
2548
+ bottom: topBaseBottom,
2549
+ left: "50%",
2550
+ transform: "translateX(-50%)",
2551
+ height: topBaseHeight,
2552
+ width: size,
2553
+ backgroundColor: inactiveColor,
2554
+ opacity: disabled ? 0.38 : 1
2555
+ }, getVerticalRadius(false, innerR, outerR))
2556
+ },
2557
+ "top-base"
2558
+ )
2559
+ );
2560
+ } else {
2561
+ const bottomBaseHeight = `max(0px, calc(${cyStr} - ${gapWithThumbStr}))`;
2562
+ segments.push(
2563
+ /* @__PURE__ */ jsxRuntime.jsx(
2564
+ "div",
2565
+ {
2566
+ "aria-hidden": "true",
2567
+ style: __spreadValues({
2568
+ position: "absolute",
2569
+ bottom: 0,
2570
+ left: "50%",
2571
+ transform: "translateX(-50%)",
2572
+ height: bottomBaseHeight,
2573
+ width: size,
2574
+ backgroundColor: inactiveColor,
2575
+ opacity: disabled ? 0.38 : 1
2576
+ }, getVerticalRadius(true, innerR, outerR))
2577
+ },
2578
+ "bottom-base"
2579
+ )
2580
+ );
2581
+ const centerActiveBottom = `calc(${cyStr} + ${gapWithThumbStr})`;
2582
+ const centerActiveHeight = `max(0px, calc(50% - ${halfCenterGap}px - (${cyStr} + ${gapWithThumbStr})))`;
2583
+ segments.push(
2584
+ /* @__PURE__ */ jsxRuntime.jsx(
2585
+ "div",
2586
+ {
2587
+ "aria-hidden": "true",
2588
+ style: __spreadValues({
2589
+ position: "absolute",
2590
+ bottom: centerActiveBottom,
2591
+ left: "50%",
2592
+ transform: "translateX(-50%)",
2593
+ height: centerActiveHeight,
2594
+ width: size,
2595
+ backgroundColor: activeColor,
2596
+ opacity: disabled ? 0.38 : 1
2597
+ }, allInnerRadius(innerR))
2598
+ },
2599
+ "center-active"
2600
+ )
2601
+ );
2602
+ const topBaseBottom = `max(calc(50% + ${halfCenterGap}px), calc(${cyStr} + ${gapWithThumbStr}))`;
2603
+ const topBaseHeight = `max(0px, calc(100% - max(calc(50% + ${halfCenterGap}px), calc(${cyStr} + ${gapWithThumbStr}))))`;
2604
+ segments.push(
2605
+ /* @__PURE__ */ jsxRuntime.jsx(
2606
+ "div",
2607
+ {
2608
+ "aria-hidden": "true",
2609
+ style: __spreadValues({
2610
+ position: "absolute",
2611
+ bottom: topBaseBottom,
2612
+ left: "50%",
2613
+ transform: "translateX(-50%)",
2614
+ height: topBaseHeight,
2615
+ width: size,
2616
+ backgroundColor: inactiveColor,
2617
+ opacity: disabled ? 0.38 : 1
2618
+ }, getVerticalRadius(false, innerR, outerR))
2619
+ },
2620
+ "top-base"
2621
+ )
2622
+ );
2623
+ }
2624
+ }
2625
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2626
+ "div",
2627
+ {
2628
+ ref: trackRef,
2629
+ className: cn(
2630
+ "relative h-full",
2631
+ disabled ? "cursor-not-allowed" : "cursor-pointer"
2632
+ ),
2633
+ style: { width: thumbHeight },
2634
+ onPointerDown: onTrackPointerDown,
2635
+ "aria-hidden": "true",
2636
+ children: [
2637
+ segments,
2638
+ ticks.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
2639
+ Ticks,
2640
+ {
2641
+ ticks,
2642
+ min,
2643
+ max,
2644
+ percent,
2645
+ orientation,
2646
+ disabled,
2647
+ variant,
2648
+ isCentered,
2649
+ trackInset
2650
+ }
2651
+ ),
2652
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: resolvedLeadingIcon && /* @__PURE__ */ jsxRuntime.jsx(
2653
+ InsetIcon,
2654
+ {
2655
+ icon: resolvedLeadingIcon,
2656
+ isOnActiveSegment: leadingOnActive,
2657
+ position: leadingOnActive ? leadingActiveLeft : leadingInactiveLeft,
2658
+ orientation,
2659
+ trackSize: size,
2660
+ trackSizeToken: trackSize,
2661
+ disabled,
2662
+ variant,
2663
+ prefersReduced
2664
+ },
2665
+ isAtMin ? "lead-min" : leadingOnActive ? "lead-active" : "lead-inactive"
2666
+ ) }),
2667
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: resolvedTrailingIcon && /* @__PURE__ */ jsxRuntime.jsx(
2668
+ InsetIcon,
2669
+ {
2670
+ icon: resolvedTrailingIcon,
2671
+ isOnActiveSegment: trailingOnActive,
2672
+ position: trailingOnActive ? trailingActiveLeft : trailingInactiveLeft,
2673
+ orientation,
2674
+ trackSize: size,
2675
+ trackSizeToken: trackSize,
2676
+ disabled,
2677
+ variant,
2678
+ prefersReduced
2679
+ },
2680
+ isAtMax ? "trail-max" : trailingOnActive ? "trail-active" : "trail-inactive"
2681
+ ) })
2682
+ ]
2683
+ }
2684
+ );
2685
+ });
2686
+ var SliderComponent = React4__namespace.forwardRef(
2687
+ ({
2688
+ value: controlledValue,
2689
+ defaultValue,
2690
+ onValueChange,
2691
+ onValueChangeEnd,
2692
+ min = 0,
2693
+ max = 100,
2694
+ step = 0,
2695
+ orientation = "horizontal",
2696
+ trackSize = "m",
2697
+ trackShape = "md3",
2698
+ variant = "primary",
2699
+ isCentered = false,
2700
+ disabled = false,
2701
+ showValueIndicator = false,
2702
+ showTicks = false,
2703
+ insetIcon,
2704
+ insetIconAtMin,
2705
+ insetIconTrailing,
2706
+ insetIconAtMax,
2707
+ formatValue,
2708
+ className,
2709
+ "aria-label": ariaLabel,
2710
+ "aria-labelledby": ariaLabelledBy
2711
+ }, ref) => {
2712
+ const isHorizontal = orientation === "horizontal";
2713
+ const midpoint = min + (max - min) / 2;
2714
+ const initialValue = defaultValue != null ? defaultValue : midpoint;
2715
+ const [internalValue, setInternalValue] = React4__namespace.useState(initialValue);
2716
+ const resolvedValue = controlledValue !== void 0 ? controlledValue : internalValue;
2717
+ const { coerce, snap, toPercent, ticks } = useSliderMath({
2718
+ min,
2719
+ max,
2720
+ step
2721
+ });
2722
+ const safeValue = snap(coerce(resolvedValue));
2723
+ const percent = toPercent(safeValue);
2724
+ const trackRef = React4__namespace.useRef(null);
2725
+ const handleValueChange = React4__namespace.useCallback(
2726
+ (newValue) => {
2727
+ const clamped = snap(coerce(newValue));
2728
+ if (controlledValue === void 0) {
2729
+ setInternalValue(clamped);
2730
+ }
2731
+ onValueChange == null ? void 0 : onValueChange(clamped);
2732
+ },
2733
+ [coerce, controlledValue, onValueChange, snap]
2734
+ );
2735
+ const handleValueChangeEnd = React4__namespace.useCallback(
2736
+ (newValue) => {
2737
+ onValueChangeEnd == null ? void 0 : onValueChangeEnd(snap(coerce(newValue)));
2738
+ },
2739
+ [coerce, onValueChangeEnd, snap]
2740
+ );
2741
+ const handleTrackPointerDown = React4__namespace.useCallback(
2742
+ (e) => {
2743
+ if (disabled) return;
2744
+ const trackEl = trackRef.current;
2745
+ if (!trackEl) return;
2746
+ const rect = trackEl.getBoundingClientRect();
2747
+ let clickPercent;
2748
+ const insetLimit = SliderTokens.thumbGap + SliderTokens.thumbWidthDefault / 2;
2749
+ const trackInset = Math.min(
2750
+ SliderTokens.trackSizes[trackSize] / 2,
2751
+ insetLimit
2752
+ );
2753
+ if (isHorizontal) {
2754
+ const x = e.clientX - rect.left;
2755
+ clickPercent = (x - trackInset) / (rect.width - trackInset * 2);
2756
+ } else {
2757
+ const y = rect.bottom - e.clientY;
2758
+ clickPercent = (y - trackInset) / (rect.height - trackInset * 2);
2759
+ }
2760
+ const clamped = Math.max(0, Math.min(1, clickPercent));
2761
+ const rawValue = min + clamped * (max - min);
2762
+ const newValue = snap(coerce(rawValue));
2763
+ handleValueChange(newValue);
2764
+ },
2765
+ [
2766
+ coerce,
2767
+ disabled,
2768
+ handleValueChange,
2769
+ isHorizontal,
2770
+ max,
2771
+ min,
2772
+ snap,
2773
+ trackSize
2774
+ ]
2775
+ );
2776
+ const id = React4__namespace.useId();
2777
+ const thumbId = `slider-thumb-${id}`;
2778
+ const supportsInsetIcon = !isCentered && SliderTokens.trackSizes[trackSize] >= 40;
2779
+ const hasAnyInsetIcon = !!(insetIcon || insetIconTrailing);
2780
+ if (hasAnyInsetIcon && !supportsInsetIcon) {
2781
+ console.warn(
2782
+ "[Slider] insetIcon is only supported on track sizes >= 40dp (e.g. xl track sizes). See MD3 spec: https://m3.material.io/components/sliders/specs"
2783
+ );
2784
+ }
2785
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
2786
+ "div",
2787
+ {
2788
+ ref,
2789
+ className: cn(
2790
+ "relative flex items-center",
2791
+ isHorizontal ? "w-full flex-row" : "h-full flex-col",
2792
+ disabled && "pointer-events-none",
2793
+ className
2794
+ ),
2795
+ style: isHorizontal ? { minWidth: 0 } : { minHeight: 0 },
2796
+ children: [
2797
+ /* @__PURE__ */ jsxRuntime.jsx(
2798
+ SliderTrack,
2799
+ {
2800
+ percent,
2801
+ trackSize,
2802
+ trackShape,
2803
+ orientation,
2804
+ isCentered,
2805
+ min,
2806
+ max,
2807
+ disabled,
2808
+ variant,
2809
+ trackRef,
2810
+ onTrackPointerDown: handleTrackPointerDown,
2811
+ ticks: showTicks ? ticks : [],
2812
+ insetIcon: supportsInsetIcon ? insetIcon : void 0,
2813
+ insetIconAtMin: supportsInsetIcon ? insetIconAtMin : void 0,
2814
+ insetIconTrailing: supportsInsetIcon ? insetIconTrailing : void 0,
2815
+ insetIconAtMax: supportsInsetIcon ? insetIconAtMax : void 0,
2816
+ value: safeValue
2817
+ }
2818
+ ),
2819
+ /* @__PURE__ */ jsxRuntime.jsx(
2820
+ SliderThumb,
2821
+ {
2822
+ value: safeValue,
2823
+ percent,
2824
+ min,
2825
+ max,
2826
+ step,
2827
+ disabled,
2828
+ orientation,
2829
+ trackSize,
2830
+ variant,
2831
+ showValueIndicator,
2832
+ trackRef,
2833
+ onValueChange: handleValueChange,
2834
+ onValueChangeEnd: handleValueChangeEnd,
2835
+ formatValue,
2836
+ thumbId,
2837
+ zIndex: 1,
2838
+ "aria-label": ariaLabel,
2839
+ "aria-labelledby": ariaLabelledBy
2840
+ }
2841
+ )
2842
+ ]
2843
+ }
2844
+ ) });
2845
+ }
2846
+ );
2847
+ SliderComponent.displayName = "Slider";
2848
+ var Slider = React4__namespace.memo(SliderComponent);
2849
+
2850
+ // src/ui/shared/motion-tokens.ts
2851
+ var FAST_SPATIAL_SPRING = {
2852
+ type: "spring",
2853
+ stiffness: 800,
2854
+ damping: 33.94
2855
+ };
2856
+ var FAST_EFFECTS_SPRING = {
2857
+ type: "spring",
2858
+ stiffness: 3800,
2859
+ damping: 123.29
2860
+ };
2861
+
2862
+ // src/ui/switch/switch.tokens.ts
2863
+ var SwitchTokens = {
2864
+ // ── Track ─────────────────────────────────────────────────────────────────
2865
+ /** SwitchTokens.TrackWidth = 52dp */
2866
+ trackWidth: 52,
2867
+ /** SwitchTokens.TrackHeight = 32dp */
2868
+ trackHeight: 32,
2869
+ /** SwitchTokens.TrackOutlineWidth = 2dp */
2870
+ trackOutlineWidth: 2,
2871
+ // ── Handle (Thumb) ────────────────────────────────────────────────────────
2872
+ /** SwitchTokens.SelectedHandleWidth/Height = 24dp */
2873
+ selectedHandleSize: 24,
2874
+ /** SwitchTokens.UnselectedHandleWidth/Height = 16dp */
2875
+ unselectedHandleSize: 16,
2876
+ /** SwitchTokens.IconHandleWidth/Height = 24dp (when thumb has icon content) */
2877
+ iconHandleSize: 24,
2878
+ /** SwitchTokens.PressedHandleWidth/Height = 28dp */
2879
+ pressedHandleSize: 28,
2880
+ // ── State Layer ───────────────────────────────────────────────────────────
2881
+ /** SwitchTokens.StateLayerSize = 40dp */
2882
+ stateLayerSize: 40,
2883
+ // ── Icon ──────────────────────────────────────────────────────────────────
2884
+ /** SwitchTokens.SelectedIconSize / UnselectedIconSize = 16dp */
2885
+ iconSize: 16,
2886
+ // ── Opacity (disabled states) ─────────────────────────────────────────────
2887
+ /** SwitchTokens.DisabledTrackOpacity = 0.12 */
2888
+ disabledTrackOpacity: 0.12,
2889
+ /** SwitchTokens.DisabledSelectedHandleOpacity = 1.0 */
2890
+ disabledSelectedHandleOpacity: 1,
2891
+ /** SwitchTokens.DisabledUnselectedHandleOpacity = 0.38 */
2892
+ disabledUnselectedHandleOpacity: 0.38,
2893
+ /** SwitchTokens.DisabledSelectedIconOpacity = 0.38 */
2894
+ disabledSelectedIconOpacity: 0.38,
2895
+ /** SwitchTokens.DisabledUnselectedIconOpacity = 0.38 */
2896
+ disabledUnselectedIconOpacity: 0.38
2897
+ };
2898
+ var SwitchColors = {
2899
+ // Track
2900
+ checkedTrack: "var(--md-sys-color-primary)",
2901
+ uncheckedTrack: "var(--md-sys-color-surface-container-highest)",
2902
+ uncheckedTrackOutline: "var(--md-sys-color-outline)",
2903
+ // Thumb
2904
+ checkedThumb: "var(--md-sys-color-on-primary)",
2905
+ uncheckedThumb: "var(--md-sys-color-outline)",
2906
+ hoverCheckedThumb: "var(--md-sys-color-primary-container)",
2907
+ hoverUncheckedThumb: "var(--md-sys-color-on-surface-variant)",
2908
+ disabledCheckedThumb: "var(--md-sys-color-surface)",
2909
+ // Icon
2910
+ checkedIcon: "var(--md-sys-color-on-primary-container)",
2911
+ uncheckedIcon: "var(--md-sys-color-surface-container-highest)",
2912
+ // State layer
2913
+ checkedStateLayer: "var(--md-sys-color-primary)",
2914
+ uncheckedStateLayer: "var(--md-sys-color-on-surface)",
2915
+ // Focus indicator
2916
+ focusIndicator: "var(--md-sys-color-secondary)"
2917
+ };
2918
+ var SNAP_TRANSITION = { duration: 0 };
2919
+ var COLOR_TRANSITION = {
2920
+ duration: 0.15,
2921
+ ease: [0.31, 0.94, 0.34, 1]
2922
+ };
2923
+ function resolveThumbSize(isPressed, checked, hasIcon) {
2924
+ if (isPressed) return SwitchTokens.pressedHandleSize;
2925
+ if (checked || hasIcon) return SwitchTokens.selectedHandleSize;
2926
+ return SwitchTokens.unselectedHandleSize;
2927
+ }
2928
+ function resolveThumbX(checked, isPressed, thumbSize) {
2929
+ const { trackHeight, trackWidth, trackOutlineWidth, selectedHandleSize } = SwitchTokens;
2930
+ const thumbPaddingStart = (trackHeight - thumbSize) / 2;
2931
+ const thumbPadding = (trackHeight - selectedHandleSize) / 2;
2932
+ const maxBound = trackWidth - selectedHandleSize - thumbPadding;
2933
+ if (isPressed && checked) return maxBound - trackOutlineWidth;
2934
+ if (isPressed) return thumbPaddingStart + trackOutlineWidth;
2935
+ if (checked) return maxBound;
2936
+ return thumbPaddingStart;
2937
+ }
2938
+ function resolveThumbColor(checked, disabled, isInteracting, checkedThumbColor, uncheckedThumbColor) {
2939
+ if (disabled) {
2940
+ return checked ? SwitchColors.disabledCheckedThumb : "rgba(28, 27, 31, 0.38)";
2941
+ }
2942
+ if (checked) {
2943
+ return isInteracting ? checkedThumbColor != null ? checkedThumbColor : SwitchColors.hoverCheckedThumb : checkedThumbColor != null ? checkedThumbColor : SwitchColors.checkedThumb;
2944
+ }
2945
+ return isInteracting ? uncheckedThumbColor != null ? uncheckedThumbColor : SwitchColors.hoverUncheckedThumb : uncheckedThumbColor != null ? uncheckedThumbColor : SwitchColors.uncheckedThumb;
2946
+ }
2947
+ function isIconVisible(thumbContent, icons, showOnlySelectedIcon, checked) {
2948
+ if (thumbContent == null) return false;
2949
+ if (icons) return true;
2950
+ return showOnlySelectedIcon && checked;
2951
+ }
2952
+ var SwitchVisual = React4__namespace.memo(function SwitchVisual2({
2953
+ checked,
2954
+ disabled,
2955
+ isPressed,
2956
+ isHovered,
2957
+ isFocused,
2958
+ thumbContent,
2959
+ icons,
2960
+ showOnlySelectedIcon,
2961
+ prefersReduced,
2962
+ checkedTrackColor,
2963
+ uncheckedTrackColor,
2964
+ checkedThumbColor,
2965
+ uncheckedThumbColor
2966
+ }) {
2967
+ const hasIcon = icons && thumbContent != null;
2968
+ const thumbSize = resolveThumbSize(isPressed, checked, hasIcon);
2969
+ const thumbX = resolveThumbX(checked, isPressed, thumbSize);
2970
+ const trackBg = checked ? checkedTrackColor != null ? checkedTrackColor : SwitchColors.checkedTrack : uncheckedTrackColor != null ? uncheckedTrackColor : SwitchColors.uncheckedTrack;
2971
+ const trackBorderColor = checked ? "rgba(0, 0, 0, 0)" : SwitchColors.uncheckedTrackOutline;
2972
+ const trackBorderWidth = checked ? 0 : SwitchTokens.trackOutlineWidth;
2973
+ const trackOpacity = disabled ? SwitchTokens.disabledTrackOpacity : 1;
2974
+ const isInteracting = isHovered || isFocused || isPressed;
2975
+ const thumbBg = resolveThumbColor(
2976
+ checked,
2977
+ disabled,
2978
+ isInteracting,
2979
+ checkedThumbColor,
2980
+ uncheckedThumbColor
2981
+ );
2982
+ const iconColor = disabled ? checked ? "rgba(28, 27, 31, 0.38)" : "rgba(230, 225, 229, 0.38)" : checked ? SwitchColors.checkedIcon : SwitchColors.uncheckedIcon;
2983
+ const stateLayerColor = checked ? SwitchColors.checkedStateLayer : SwitchColors.uncheckedStateLayer;
2984
+ const stateLayerOpacity = isPressed || isFocused ? 0.12 : isHovered ? 0.08 : 0;
2985
+ const stateLayerX = thumbX + thumbSize / 2 - SwitchTokens.stateLayerSize / 2;
2986
+ const showIcon = isIconVisible(
2987
+ thumbContent,
2988
+ icons,
2989
+ showOnlySelectedIcon,
2990
+ checked
2991
+ );
2992
+ const colorTransition = prefersReduced ? { duration: 0 } : COLOR_TRANSITION;
2993
+ const stateLayerTransition = prefersReduced ? { duration: 0 } : FAST_EFFECTS_SPRING;
2994
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2995
+ "div",
2996
+ {
2997
+ className: "relative",
2998
+ style: {
2999
+ width: SwitchTokens.trackWidth,
3000
+ height: SwitchTokens.trackHeight
3001
+ },
3002
+ "aria-hidden": "true",
3003
+ children: [
3004
+ /* @__PURE__ */ jsxRuntime.jsx(
3005
+ react.m.div,
3006
+ {
3007
+ className: "absolute inset-0 rounded-full",
3008
+ style: { borderStyle: "solid", opacity: trackOpacity },
3009
+ animate: {
3010
+ backgroundColor: trackBg,
3011
+ borderColor: trackBorderColor,
3012
+ borderWidth: trackBorderWidth
3013
+ },
3014
+ transition: colorTransition
3015
+ }
3016
+ ),
3017
+ /* @__PURE__ */ jsxRuntime.jsx(
3018
+ react.m.div,
3019
+ {
3020
+ className: "absolute rounded-full pointer-events-none",
3021
+ style: {
3022
+ width: SwitchTokens.stateLayerSize,
3023
+ height: SwitchTokens.stateLayerSize,
3024
+ top: (SwitchTokens.trackHeight - SwitchTokens.stateLayerSize) / 2,
3025
+ backgroundColor: stateLayerColor
3026
+ },
3027
+ animate: { x: stateLayerX, opacity: stateLayerOpacity },
3028
+ transition: stateLayerTransition
3029
+ }
3030
+ ),
3031
+ /* @__PURE__ */ jsxRuntime.jsx(
3032
+ react.m.div,
3033
+ {
3034
+ className: "absolute rounded-full flex items-center justify-center overflow-hidden",
3035
+ style: { top: "50%", left: 0, y: "-50%" },
3036
+ animate: {
3037
+ x: thumbX,
3038
+ width: thumbSize,
3039
+ height: thumbSize,
3040
+ backgroundColor: thumbBg
3041
+ },
3042
+ transition: prefersReduced ? { duration: 0 } : isPressed ? SNAP_TRANSITION : {
3043
+ x: FAST_SPATIAL_SPRING,
3044
+ width: FAST_SPATIAL_SPRING,
3045
+ height: FAST_SPATIAL_SPRING,
3046
+ backgroundColor: colorTransition
3047
+ },
3048
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: showIcon && /* @__PURE__ */ jsxRuntime.jsx(
3049
+ react.m.span,
3050
+ {
3051
+ className: "flex items-center justify-center",
3052
+ style: {
3053
+ width: SwitchTokens.iconSize,
3054
+ height: SwitchTokens.iconSize,
3055
+ color: iconColor,
3056
+ fontSize: SwitchTokens.iconSize
3057
+ },
3058
+ initial: prefersReduced ? false : { opacity: 0, scale: 0.5 },
3059
+ animate: { opacity: 1, scale: 1 },
3060
+ exit: prefersReduced ? {} : { opacity: 0, scale: 0.5 },
3061
+ transition: prefersReduced ? { duration: 0 } : { duration: 0.15 },
3062
+ children: thumbContent
3063
+ },
3064
+ checked ? "icon-on" : "icon-off"
3065
+ ) })
3066
+ }
3067
+ )
3068
+ ]
3069
+ }
3070
+ );
3071
+ });
3072
+ var SwitchComponent = React4__namespace.forwardRef(
3073
+ ({
3074
+ checked,
3075
+ onCheckedChange,
3076
+ disabled = false,
3077
+ thumbContent,
3078
+ icons = false,
3079
+ showOnlySelectedIcon = false,
3080
+ label,
3081
+ ariaLabel,
3082
+ className,
3083
+ checkedTrackColor,
3084
+ uncheckedTrackColor,
3085
+ checkedThumbColor,
3086
+ uncheckedThumbColor
3087
+ }, ref) => {
3088
+ var _a;
3089
+ const prefersReduced = (_a = react.useReducedMotion()) != null ? _a : false;
3090
+ const [isPressed, setIsPressed] = React4__namespace.useState(false);
3091
+ const [isHovered, setIsHovered] = React4__namespace.useState(false);
3092
+ const [isFocused, setIsFocused] = React4__namespace.useState(false);
3093
+ const [ripples, setRipples] = React4__namespace.useState([]);
3094
+ const generatedId = React4__namespace.useId();
3095
+ const switchId = label ? `switch-${generatedId}` : void 0;
3096
+ const handleClick = React4__namespace.useCallback(() => {
3097
+ if (!disabled) onCheckedChange(!checked);
3098
+ }, [disabled, checked, onCheckedChange]);
3099
+ const handleKeyDown = React4__namespace.useCallback(
3100
+ (e) => {
3101
+ if (disabled) return;
3102
+ if (e.key === " " || e.key === "Enter") {
3103
+ e.preventDefault();
3104
+ onCheckedChange(!checked);
3105
+ }
3106
+ },
3107
+ [disabled, checked, onCheckedChange]
3108
+ );
3109
+ const handlePointerDown = React4__namespace.useCallback(
3110
+ (e) => {
3111
+ if (disabled) return;
3112
+ setIsPressed(true);
3113
+ const rect = e.currentTarget.getBoundingClientRect();
3114
+ const x = e.clientX - rect.left;
3115
+ const y = e.clientY - rect.top;
3116
+ const rippleSize = Math.hypot(rect.width, rect.height) * 2;
3117
+ setRipples((prev) => [
3118
+ ...prev,
3119
+ { id: Date.now(), x, y, size: rippleSize }
3120
+ ]);
3121
+ },
3122
+ [disabled]
3123
+ );
3124
+ const handlePointerUp = React4__namespace.useCallback(() => {
3125
+ setIsPressed(false);
3126
+ }, []);
3127
+ const handlePointerEnter = React4__namespace.useCallback(() => {
3128
+ if (!disabled) setIsHovered(true);
3129
+ }, [disabled]);
3130
+ const handlePointerLeave = React4__namespace.useCallback(() => {
3131
+ setIsHovered(false);
3132
+ setIsPressed(false);
3133
+ }, []);
3134
+ const handleFocus = React4__namespace.useCallback(() => setIsFocused(true), []);
3135
+ const handleBlur = React4__namespace.useCallback(() => setIsFocused(false), []);
3136
+ const removeRipple = React4__namespace.useCallback(
3137
+ (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
3138
+ []
3139
+ );
3140
+ const buttonAriaLabel = label ? void 0 : ariaLabel;
3141
+ const switchButton = /* @__PURE__ */ jsxRuntime.jsx(
3142
+ "button",
3143
+ {
3144
+ ref,
3145
+ id: switchId,
3146
+ type: "button",
3147
+ role: "switch",
3148
+ "aria-checked": checked,
3149
+ "aria-disabled": disabled || void 0,
3150
+ "aria-label": buttonAriaLabel,
3151
+ tabIndex: disabled ? -1 : 0,
3152
+ disabled,
3153
+ onClick: handleClick,
3154
+ onKeyDown: handleKeyDown,
3155
+ onPointerDown: handlePointerDown,
3156
+ onPointerUp: handlePointerUp,
3157
+ onPointerLeave: handlePointerLeave,
3158
+ onPointerEnter: handlePointerEnter,
3159
+ onFocus: handleFocus,
3160
+ onBlur: handleBlur,
3161
+ className: cn(
3162
+ "relative inline-flex items-center justify-center cursor-pointer select-none",
3163
+ // Touch target: 48×48 minimum (pad around 32px track)
3164
+ "min-w-12 min-h-12",
3165
+ // Focus ring — MD3 FocusIndicatorColor = secondary
3166
+ "focus-visible:outline-2 focus-visible:outline-offset-2 rounded-full",
3167
+ "focus-visible:outline-(--md-sys-color-secondary)",
3168
+ // Disabled
3169
+ disabled && "pointer-events-none cursor-not-allowed",
3170
+ !label && className
3171
+ ),
3172
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative overflow-hidden rounded-full", children: [
3173
+ /* @__PURE__ */ jsxRuntime.jsx(
3174
+ SwitchVisual,
3175
+ {
3176
+ checked,
3177
+ disabled,
3178
+ isPressed,
3179
+ isHovered,
3180
+ isFocused,
3181
+ thumbContent,
3182
+ icons,
3183
+ showOnlySelectedIcon,
3184
+ prefersReduced,
3185
+ checkedTrackColor,
3186
+ uncheckedTrackColor,
3187
+ checkedThumbColor,
3188
+ uncheckedThumbColor
3189
+ }
3190
+ ),
3191
+ /* @__PURE__ */ jsxRuntime.jsx(
3192
+ Ripple,
3193
+ {
3194
+ ripples,
3195
+ onRippleDone: removeRipple,
3196
+ disabled
3197
+ }
3198
+ )
3199
+ ] })
3200
+ }
3201
+ );
3202
+ const content = label ? /* @__PURE__ */ jsxRuntime.jsxs(
3203
+ "label",
3204
+ {
3205
+ htmlFor: switchId,
3206
+ className: cn(
3207
+ "inline-flex items-center gap-3 cursor-pointer select-none",
3208
+ disabled && "cursor-not-allowed pointer-events-none opacity-[0.38]",
3209
+ className
3210
+ ),
3211
+ children: [
3212
+ switchButton,
3213
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm leading-none text-(--md-sys-color-on-surface)", children: label })
3214
+ ]
3215
+ }
3216
+ ) : switchButton;
3217
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: content });
3218
+ }
3219
+ );
3220
+ SwitchComponent.displayName = "Switch";
3221
+ var Switch = React4__namespace.memo(SwitchComponent);
3222
+ var ScrollArea = React4__namespace.forwardRef(
3223
+ (_a, ref) => {
3224
+ var _b = _a, {
3225
+ className,
3226
+ viewportClassName,
3227
+ children,
3228
+ type = "hover",
3229
+ orientation = "vertical",
3230
+ scrollHideDelay = 600,
3231
+ viewportRef,
3232
+ viewportProps
3233
+ } = _b, props = __objRest(_b, [
3234
+ "className",
3235
+ "viewportClassName",
3236
+ "children",
3237
+ "type",
3238
+ "orientation",
3239
+ "scrollHideDelay",
3240
+ "viewportRef",
3241
+ "viewportProps"
3242
+ ]);
3243
+ const [isTouchDevice, setIsTouchDevice] = React4__namespace.useState(false);
3244
+ React4__namespace.useEffect(() => {
3245
+ if (typeof window !== "undefined") {
3246
+ setIsTouchDevice(
3247
+ "ontouchstart" in window || navigator.maxTouchPoints > 0
3248
+ );
3249
+ }
3250
+ }, []);
3251
+ const resolvedType = React4__namespace.useMemo(() => {
3252
+ if (type === "hover" && isTouchDevice) {
3253
+ return "scroll";
3254
+ }
3255
+ return type;
3256
+ }, [type, isTouchDevice]);
3257
+ const radixType = resolvedType === "none" ? "always" : resolvedType;
3258
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3259
+ RadixScrollArea__namespace.Root,
3260
+ __spreadProps(__spreadValues({
3261
+ ref,
3262
+ type: radixType,
3263
+ scrollHideDelay,
3264
+ className: cn("relative overflow-hidden flex flex-col", className)
3265
+ }, props), {
3266
+ children: [
3267
+ /* @__PURE__ */ jsxRuntime.jsx(
3268
+ RadixScrollArea__namespace.Viewport,
3269
+ __spreadProps(__spreadValues({
3270
+ ref: viewportRef
3271
+ }, viewportProps), {
3272
+ className: cn(
3273
+ "h-full w-full flex-1 min-h-0 min-w-0 rounded-[inherit]",
3274
+ "outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-1",
3275
+ viewportClassName,
3276
+ viewportProps == null ? void 0 : viewportProps.className
3277
+ ),
3278
+ children
3279
+ })
3280
+ ),
3281
+ (orientation === "vertical" || orientation === "both") && /* @__PURE__ */ jsxRuntime.jsx(
3282
+ ScrollAreaScrollbar,
3283
+ {
3284
+ orientation: "vertical",
3285
+ className: resolvedType === "none" ? "hidden" : void 0
3286
+ }
3287
+ ),
3288
+ (orientation === "horizontal" || orientation === "both") && /* @__PURE__ */ jsxRuntime.jsx(
3289
+ ScrollAreaScrollbar,
3290
+ {
3291
+ orientation: "horizontal",
3292
+ className: resolvedType === "none" ? "hidden" : void 0
3293
+ }
3294
+ ),
3295
+ /* @__PURE__ */ jsxRuntime.jsx(RadixScrollArea__namespace.Corner, { className: "bg-m3-surface-container" })
3296
+ ]
3297
+ })
3298
+ );
3299
+ }
3300
+ );
3301
+ ScrollArea.displayName = "ScrollArea";
3302
+ var ScrollAreaScrollbar = React4__namespace.forwardRef((_a, ref) => {
3303
+ var _b = _a, { className, orientation = "vertical" } = _b, props = __objRest(_b, ["className", "orientation"]);
3304
+ return /* @__PURE__ */ jsxRuntime.jsx(
3305
+ RadixScrollArea__namespace.Scrollbar,
3306
+ __spreadProps(__spreadValues({
3307
+ ref,
3308
+ orientation,
3309
+ className: cn(
3310
+ "flex touch-none select-none transition-all duration-300 ease-in-out",
3311
+ "absolute z-50",
3312
+ orientation === "vertical" && "right-0 top-0 bottom-0 w-2.5 border-l border-l-transparent p-px",
3313
+ orientation === "horizontal" && "bottom-0 left-0 right-0 h-2.5 flex-col border-t border-t-transparent p-px",
3314
+ "data-[state=hidden]:opacity-0 data-[state=visible]:opacity-100",
3315
+ className
3316
+ )
3317
+ }, props), {
3318
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3319
+ RadixScrollArea__namespace.Thumb,
3320
+ {
3321
+ className: cn(
3322
+ "relative flex-1 rounded-full bg-m3-on-surface/25 transition-colors duration-200",
3323
+ "hover:bg-m3-on-surface/40 active:bg-m3-on-surface/55",
3324
+ "before:absolute before:left-1/2 before:top-1/2 before:min-h-11 before:min-w-11 before:-translate-x-1/2 before:-translate-y-1/2"
3325
+ )
3326
+ }
3327
+ )
3328
+ })
3329
+ );
3330
+ });
3331
+ ScrollAreaScrollbar.displayName = RadixScrollArea__namespace.Scrollbar.displayName;
3332
+ var ScrollAreaCorner = React4__namespace.forwardRef((_a, ref) => {
3333
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
3334
+ return /* @__PURE__ */ jsxRuntime.jsx(
3335
+ RadixScrollArea__namespace.Corner,
3336
+ __spreadValues({
3337
+ ref,
3338
+ className: cn("bg-m3-surface-container", className)
3339
+ }, props)
3340
+ );
3341
+ });
3342
+ ScrollAreaCorner.displayName = "ScrollAreaCorner";
3343
+ var ToolbarContext = React4__namespace.createContext(
3344
+ null
3345
+ );
3346
+ function useToolbarContext() {
3347
+ return React4__namespace.useContext(ToolbarContext);
3348
+ }
3349
+
3350
+ // src/ui/shared/constants.ts
3351
+ var MD3_STANDARD_EASING = [
3352
+ 0.2,
3353
+ 0,
3354
+ 0,
3355
+ 1
3356
+ ];
3357
+ var MD3_LABEL_FLOAT_DURATION = 0.15;
3358
+ var MD3_INDICATOR_DURATION = 0.2;
3359
+ var MD3_SUPPORTING_DURATION = 0.12;
3360
+ var MD3_ICON_SWAP_DURATION = 0.1;
3361
+
3362
+ // src/ui/text-field/text-field.tokens.ts
3363
+ var TF_COLORS = {
3364
+ /** Input text color */
3365
+ inputText: "var(--md-sys-color-on-surface)",
3366
+ /** Label (unfloated) + icons + prefix/suffix + supporting text */
3367
+ onSurfaceVariant: "var(--md-sys-color-on-surface-variant)",
3368
+ /** Focused active indicator / outline, floated label */
3369
+ primary: "var(--md-sys-color-primary)",
3370
+ /** Error indicator / outline / label / icon / supporting text */
3371
+ error: "var(--md-sys-color-error)",
3372
+ /** Outlined border (enabled) */
3373
+ outline: "var(--md-sys-color-outline)"};
3374
+ var TF_SIZE = {
3375
+ /** Container height — normal */
3376
+ height: 56,
3377
+ /** Container height — dense variant */
3378
+ denseHeight: 48,
3379
+ /** Active indicator height — enabled */
3380
+ indicatorThin: 1,
3381
+ /** Active indicator height — focused */
3382
+ indicatorThick: 2,
3383
+ /** Outline stroke width — enabled */
3384
+ outlineThin: 1,
3385
+ /** Outline stroke width — focused */
3386
+ outlineThick: 2,
3387
+ /** Padding inline start (no leading icon) */
3388
+ paddingStart: 16,
3389
+ /** Notch extra padding per side on outlined label gap */
3390
+ notchPadding: 4
3391
+ };
3392
+ var TF_TYPOGRAPHY = {
3393
+ /** Scale ratio when label floats: 12/16 = 0.75 */
3394
+ labelScaleRatio: 12 / 16
3395
+ };
3396
+ var TF_CLASSES = {
3397
+ // Prefix / Suffix
3398
+ prefixSuffix: "text-base text-[var(--md-sys-color-on-surface-variant)] select-none shrink-0"};
3399
+ var ActiveIndicator = React4__namespace.memo(function ActiveIndicator2({
3400
+ isFocused,
3401
+ isError,
3402
+ isDisabled,
3403
+ isHovered,
3404
+ prefersReduced
3405
+ }) {
3406
+ const duration = prefersReduced ? 0 : MD3_INDICATOR_DURATION;
3407
+ const ease = MD3_STANDARD_EASING;
3408
+ const height = isFocused || isError ? TF_SIZE.indicatorThick : TF_SIZE.indicatorThin;
3409
+ let backgroundColor;
3410
+ if (isError) {
3411
+ backgroundColor = TF_COLORS.error;
3412
+ } else if (isFocused) {
3413
+ backgroundColor = TF_COLORS.primary;
3414
+ } else if (isHovered && !isDisabled) {
3415
+ backgroundColor = TF_COLORS.inputText;
3416
+ } else {
3417
+ backgroundColor = TF_COLORS.onSurfaceVariant;
3418
+ }
3419
+ return /* @__PURE__ */ jsxRuntime.jsx(
3420
+ react.m.div,
3421
+ {
3422
+ "aria-hidden": "true",
3423
+ className: "absolute bottom-0 left-0 right-0 origin-center",
3424
+ animate: { height, backgroundColor },
3425
+ transition: { duration, ease }
3426
+ }
3427
+ );
3428
+ });
3429
+ ActiveIndicator.displayName = "ActiveIndicator";
3430
+ function getFloatedY(variant, containerHeight) {
3431
+ const labelSmallHeight = 16;
3432
+ const paddingTop = 8;
3433
+ if (variant === "filled") {
3434
+ const floatedCenter = paddingTop + labelSmallHeight / 2;
3435
+ const unfloatedCenter = containerHeight / 2;
3436
+ return -(unfloatedCenter - floatedCenter);
3437
+ }
3438
+ return -(containerHeight / 2);
3439
+ }
3440
+ function getLabelColor(isFloated, isFocused, isError, isDisabled) {
3441
+ if (isDisabled) return TF_COLORS.onSurfaceVariant;
3442
+ if (isError) return TF_COLORS.error;
3443
+ if (isFloated && isFocused) return TF_COLORS.primary;
3444
+ return TF_COLORS.onSurfaceVariant;
3445
+ }
3446
+ var FloatingLabel = React4__namespace.memo(function FloatingLabel2({
3447
+ text,
3448
+ isFloated,
3449
+ isFocused,
3450
+ isError,
3451
+ isDisabled,
3452
+ variant,
3453
+ containerHeight,
3454
+ prefersReduced,
3455
+ showAsterisk,
3456
+ htmlFor,
3457
+ labelRef,
3458
+ hasLeading = false
3459
+ }) {
3460
+ const duration = prefersReduced ? 0 : MD3_LABEL_FLOAT_DURATION;
3461
+ const ease = MD3_STANDARD_EASING;
3462
+ const y = isFloated ? getFloatedY(variant, containerHeight) : 0;
3463
+ const x = variant === "outlined" && isFloated && hasLeading ? -36 : 0;
3464
+ const scale = isFloated ? TF_TYPOGRAPHY.labelScaleRatio : 1;
3465
+ const color = getLabelColor(isFloated, isFocused, isError, isDisabled);
3466
+ return /* @__PURE__ */ jsxRuntime.jsx(
3467
+ react.m.label,
3468
+ {
3469
+ htmlFor,
3470
+ className: cn(
3471
+ "absolute pointer-events-none select-none origin-[left_center] leading-6 text-base whitespace-nowrap",
3472
+ "px-1 -mx-1",
3473
+ // Clear the notch gap and keep text aligned
3474
+ variant === "outlined" && isFloated && "bg-m3-surface",
3475
+ "left-4",
3476
+ isDisabled && "opacity-[0.38]"
3477
+ ),
3478
+ animate: { y, x, scale, color },
3479
+ transition: { duration, ease },
3480
+ style: {
3481
+ top: (containerHeight - 24) / 2,
3482
+ // 24px is the resting line-height
3483
+ transformOrigin: "left center",
3484
+ zIndex: 1
3485
+ },
3486
+ children: /* @__PURE__ */ jsxRuntime.jsxs("span", { ref: labelRef, className: "inline-block relative", children: [
3487
+ text,
3488
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: showAsterisk && /* @__PURE__ */ jsxRuntime.jsx(
3489
+ react.m.span,
3490
+ {
3491
+ "aria-hidden": "true",
3492
+ initial: { opacity: 0 },
3493
+ animate: { opacity: 1 },
3494
+ exit: { opacity: 0 },
3495
+ transition: { duration: prefersReduced ? 0 : 0.1 },
3496
+ className: "ml-0.5 text-m3-error",
3497
+ children: "*"
3498
+ },
3499
+ "asterisk"
3500
+ ) })
3501
+ ] })
3502
+ }
3503
+ );
3504
+ });
3505
+ FloatingLabel.displayName = "FloatingLabel";
3506
+ var LeadingIcon = React4__namespace.memo(function LeadingIcon2({
3507
+ children,
3508
+ isError,
3509
+ isDisabled
3510
+ }) {
3511
+ const color = isError && !isDisabled ? TF_COLORS.error : TF_COLORS.onSurfaceVariant;
3512
+ return /* @__PURE__ */ jsxRuntime.jsx(
3513
+ "div",
3514
+ {
3515
+ "aria-hidden": "true",
3516
+ className: "flex items-center justify-center shrink-0 w-6 h-6 ml-3",
3517
+ style: { color },
3518
+ children
3519
+ }
3520
+ );
3521
+ });
3522
+ LeadingIcon.displayName = "LeadingIcon";
3523
+ function getOutlineColor(isFocused, isError, isHovered, isDisabled) {
3524
+ if (isDisabled) return TF_COLORS.onSurfaceVariant;
3525
+ if (isError) return TF_COLORS.error;
3526
+ if (isFocused) return TF_COLORS.primary;
3527
+ if (isHovered) return TF_COLORS.inputText;
3528
+ return TF_COLORS.outline;
3529
+ }
3530
+ var OutlineContainer = React4__namespace.memo(function OutlineContainer2({
3531
+ isFloated,
3532
+ isFocused,
3533
+ isError,
3534
+ isDisabled,
3535
+ isHovered,
3536
+ labelWidth,
3537
+ prefersReduced
3538
+ }) {
3539
+ const colorDuration = prefersReduced ? 0 : MD3_INDICATOR_DURATION;
3540
+ const notchDuration = prefersReduced ? 0 : MD3_LABEL_FLOAT_DURATION;
3541
+ const ease = MD3_STANDARD_EASING;
3542
+ const borderColor = getOutlineColor(
3543
+ isFocused,
3544
+ isError,
3545
+ isHovered,
3546
+ isDisabled
3547
+ );
3548
+ const borderWidth = isFocused || isError ? TF_SIZE.outlineThick : TF_SIZE.outlineThin;
3549
+ const leftSegmentWidth = TF_SIZE.paddingStart;
3550
+ const notchWidth = isFloated ? labelWidth * TF_TYPOGRAPHY.labelScaleRatio + TF_SIZE.notchPadding * 2 : 0;
3551
+ const borderTransition = { duration: colorDuration, ease };
3552
+ const notchTransition = { duration: notchDuration, ease };
3553
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3554
+ "div",
3555
+ {
3556
+ "aria-hidden": "true",
3557
+ className: "absolute inset-0 pointer-events-none flex rounded-[inherit]",
3558
+ children: [
3559
+ /* @__PURE__ */ jsxRuntime.jsx(
3560
+ react.m.div,
3561
+ {
3562
+ className: "rounded-tl-[inherit] rounded-bl-[inherit]",
3563
+ style: { width: leftSegmentWidth - TF_SIZE.notchPadding },
3564
+ animate: {
3565
+ borderColor,
3566
+ borderWidth,
3567
+ borderStyle: "solid",
3568
+ borderRightWidth: 0
3569
+ },
3570
+ transition: borderTransition
3571
+ }
3572
+ ),
3573
+ /* @__PURE__ */ jsxRuntime.jsxs(
3574
+ react.m.div,
3575
+ {
3576
+ className: "flex flex-col shrink-0",
3577
+ style: { minWidth: 0 },
3578
+ animate: { width: notchWidth },
3579
+ transition: notchTransition,
3580
+ children: [
3581
+ /* @__PURE__ */ jsxRuntime.jsx(
3582
+ react.m.div,
3583
+ {
3584
+ className: "shrink-0",
3585
+ style: { height: borderWidth },
3586
+ animate: {
3587
+ borderTopColor: borderColor,
3588
+ opacity: isFloated ? 0 : 1,
3589
+ borderTopWidth: borderWidth,
3590
+ borderTopStyle: "solid"
3591
+ },
3592
+ transition: borderTransition
3593
+ }
3594
+ ),
3595
+ /* @__PURE__ */ jsxRuntime.jsx(
3596
+ react.m.div,
3597
+ {
3598
+ className: "flex-1",
3599
+ animate: {
3600
+ borderBottomColor: borderColor,
3601
+ borderBottomWidth: borderWidth,
3602
+ borderBottomStyle: "solid"
3603
+ },
3604
+ transition: borderTransition
3605
+ }
3606
+ )
3607
+ ]
3608
+ }
3609
+ ),
3610
+ /* @__PURE__ */ jsxRuntime.jsx(
3611
+ react.m.div,
3612
+ {
3613
+ className: "flex-1 rounded-tr-[inherit] rounded-br-[inherit]",
3614
+ animate: {
3615
+ borderColor,
3616
+ borderWidth,
3617
+ borderStyle: "solid",
3618
+ borderLeftWidth: 0
3619
+ },
3620
+ transition: borderTransition
3621
+ }
3622
+ )
3623
+ ]
3624
+ }
3625
+ );
3626
+ });
3627
+ OutlineContainer.displayName = "OutlineContainer";
3628
+ var PrefixSuffix = React4__namespace.memo(function PrefixSuffix2({
3629
+ text,
3630
+ type,
3631
+ visible,
3632
+ prefersReduced
3633
+ }) {
3634
+ const duration = prefersReduced ? 0 : MD3_LABEL_FLOAT_DURATION;
3635
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: visible && /* @__PURE__ */ jsxRuntime.jsx(
3636
+ react.m.span,
3637
+ {
3638
+ "aria-hidden": "true",
3639
+ className: `${TF_CLASSES.prefixSuffix} ${type === "suffix" ? "ml-0.5" : "mr-0.5"}`,
3640
+ initial: { opacity: 0 },
3641
+ animate: { opacity: 1 },
3642
+ exit: { opacity: 0 },
3643
+ transition: { duration, ease: MD3_STANDARD_EASING },
3644
+ children: text
3645
+ }
3646
+ ) });
3647
+ });
3648
+ PrefixSuffix.displayName = "PrefixSuffix";
3649
+ function AnimatedText({
3650
+ text,
3651
+ motionKey,
3652
+ className,
3653
+ ariaLive,
3654
+ duration
3655
+ }) {
3656
+ return /* @__PURE__ */ jsxRuntime.jsx(
3657
+ react.m.span,
3658
+ {
3659
+ className,
3660
+ initial: { opacity: 0, y: -4 },
3661
+ animate: { opacity: 1, y: 0 },
3662
+ exit: { opacity: 0, y: -4 },
3663
+ transition: { duration, ease: MD3_STANDARD_EASING },
3664
+ "aria-live": ariaLive,
3665
+ children: text
3666
+ },
3667
+ motionKey
3668
+ );
3669
+ }
3670
+ var SupportingText = React4__namespace.memo(function SupportingText2({
3671
+ supportingText,
3672
+ errorText,
3673
+ isError,
3674
+ charCount,
3675
+ maxLength,
3676
+ id,
3677
+ prefersReduced
3678
+ }) {
3679
+ const duration = prefersReduced ? 0 : MD3_SUPPORTING_DURATION;
3680
+ const activeText = isError && errorText ? errorText : supportingText;
3681
+ const isOverLimit = maxLength !== void 0 && (charCount != null ? charCount : 0) > maxLength;
3682
+ const counterColor = isOverLimit ? TF_COLORS.error : TF_COLORS.onSurfaceVariant;
3683
+ if (!activeText && maxLength === void 0) return null;
3684
+ return /* @__PURE__ */ jsxRuntime.jsxs(
3685
+ react.m.div,
3686
+ {
3687
+ className: "flex items-start justify-between gap-2 mt-1 px-4",
3688
+ initial: { opacity: 0, height: 0 },
3689
+ animate: { opacity: 1, height: "auto" },
3690
+ exit: { opacity: 0, height: 0 },
3691
+ transition: { duration, ease: MD3_STANDARD_EASING },
3692
+ children: [
3693
+ /* @__PURE__ */ jsxRuntime.jsx("div", { id, className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: activeText && /* @__PURE__ */ jsxRuntime.jsx(
3694
+ AnimatedText,
3695
+ {
3696
+ motionKey: isError && errorText ? `error-${errorText}` : `helper-${supportingText}`,
3697
+ text: activeText,
3698
+ className: `text-xs leading-4 block ${isError ? "text-m3-error" : "text-m3-on-surface-variant"}`,
3699
+ ariaLive: "polite",
3700
+ duration
3701
+ },
3702
+ isError && errorText ? "error" : "helper"
3703
+ ) }) }),
3704
+ maxLength !== void 0 && typeof charCount === "number" && /* @__PURE__ */ jsxRuntime.jsxs(
3705
+ react.m.span,
3706
+ {
3707
+ className: "text-xs leading-4 tabular-nums shrink-0",
3708
+ animate: { color: counterColor },
3709
+ transition: { duration, ease: MD3_STANDARD_EASING },
3710
+ "aria-live": "polite",
3711
+ "aria-atomic": "true",
3712
+ children: [
3713
+ charCount,
3714
+ " / ",
3715
+ maxLength
3716
+ ]
3717
+ }
3718
+ )
3719
+ ]
3720
+ }
3721
+ );
3722
+ });
3723
+ SupportingText.displayName = "SupportingText";
3724
+ function AnimatedIconSlot({
3725
+ children,
3726
+ motionKey,
3727
+ duration
3728
+ }) {
3729
+ return /* @__PURE__ */ jsxRuntime.jsx(
3730
+ react.m.span,
3731
+ {
3732
+ className: "flex items-center justify-center",
3733
+ initial: { opacity: 0, scale: 0 },
3734
+ animate: { opacity: 1, scale: 1 },
3735
+ exit: { opacity: 0, scale: 0 },
3736
+ transition: { duration, ease: MD3_STANDARD_EASING },
3737
+ children
3738
+ },
3739
+ motionKey
3740
+ );
3741
+ }
3742
+ function EyeOpenIcon() {
3743
+ return /* @__PURE__ */ jsxRuntime.jsx(
3744
+ "svg",
3745
+ {
3746
+ width: "24",
3747
+ height: "24",
3748
+ viewBox: "0 0 24 24",
3749
+ fill: "currentColor",
3750
+ "aria-hidden": "true",
3751
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5zM12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z" })
3752
+ }
3753
+ );
3754
+ }
3755
+ function EyeOffIcon() {
3756
+ return /* @__PURE__ */ jsxRuntime.jsx(
3757
+ "svg",
3758
+ {
3759
+ width: "24",
3760
+ height: "24",
3761
+ viewBox: "0 0 24 24",
3762
+ fill: "currentColor",
3763
+ "aria-hidden": "true",
3764
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 7c2.76 0 5 2.24 5 5 0 .65-.13 1.26-.36 1.83l2.92 2.92c1.51-1.26 2.7-2.89 3.43-4.75-1.73-4.39-6-7.5-11-7.5-1.4 0-2.74.25-3.98.7l2.16 2.16C10.74 7.13 11.35 7 12 7zM2 4.27l2.28 2.28.46.46C3.08 8.3 1.78 10.02 1 12c1.73 4.39 6 7.5 11 7.5 1.55 0 3.03-.3 4.38-.84l.42.42L19.73 22 21 20.73 3.27 3 2 4.27zM7.53 9.8l1.55 1.55c-.05.21-.08.43-.08.65 0 1.66 1.34 3 3 3 .22 0 .44-.03.65-.08l1.55 1.55c-.67.33-1.41.53-2.2.53-2.76 0-5-2.24-5-5 0-.79.2-1.53.53-2.2zm4.31-.78l3.15 3.15.02-.16c0-1.66-1.34-3-3-3l-.17.01z" })
3765
+ }
3766
+ );
3767
+ }
3768
+ function ClearIcon() {
3769
+ return /* @__PURE__ */ jsxRuntime.jsx(
3770
+ "svg",
3771
+ {
3772
+ width: "20",
3773
+ height: "20",
3774
+ viewBox: "0 0 24 24",
3775
+ fill: "currentColor",
3776
+ "aria-hidden": "true",
3777
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" })
3778
+ }
3779
+ );
3780
+ }
3781
+ var TrailingIcon = React4__namespace.memo(function TrailingIcon2({
3782
+ mode,
3783
+ children,
3784
+ value,
3785
+ showPassword = false,
3786
+ onClear,
3787
+ onPasswordToggle,
3788
+ isError,
3789
+ isDisabled,
3790
+ prefersReduced
3791
+ }) {
3792
+ const duration = prefersReduced ? 0 : MD3_ICON_SWAP_DURATION;
3793
+ const iconColor = isError && !isDisabled ? TF_COLORS.error : TF_COLORS.onSurfaceVariant;
3794
+ const btnClass = "relative flex items-center justify-center w-12 h-12 -mr-1 rounded-full cursor-pointer outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-m3-primary)] transition-colors hover:bg-[var(--color-m3-on-surface)]/8 active:bg-[var(--color-m3-on-surface)]/12 disabled:pointer-events-none";
3795
+ if (mode === "clear") {
3796
+ const hasValue = value.length > 0;
3797
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: hasValue && /* @__PURE__ */ jsxRuntime.jsx(AnimatedIconSlot, { motionKey: "clear", duration, children: /* @__PURE__ */ jsxRuntime.jsx(
3798
+ "button",
3799
+ {
3800
+ type: "button",
3801
+ "aria-label": "Clear input",
3802
+ onClick: onClear,
3803
+ disabled: isDisabled,
3804
+ tabIndex: isDisabled ? -1 : 0,
3805
+ className: btnClass,
3806
+ style: { color: iconColor },
3807
+ children: /* @__PURE__ */ jsxRuntime.jsx(ClearIcon, {})
3808
+ }
3809
+ ) }) });
3810
+ }
3811
+ if (mode === "password-toggle") {
3812
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: /* @__PURE__ */ jsxRuntime.jsx(
3813
+ AnimatedIconSlot,
3814
+ {
3815
+ motionKey: showPassword ? "eye-off" : "eye-on",
3816
+ duration,
3817
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3818
+ "button",
3819
+ {
3820
+ type: "button",
3821
+ "aria-label": showPassword ? "Hide password" : "Show password",
3822
+ onClick: onPasswordToggle,
3823
+ disabled: isDisabled,
3824
+ tabIndex: isDisabled ? -1 : 0,
3825
+ className: btnClass,
3826
+ style: { color: iconColor },
3827
+ children: showPassword ? /* @__PURE__ */ jsxRuntime.jsx(EyeOffIcon, {}) : /* @__PURE__ */ jsxRuntime.jsx(EyeOpenIcon, {})
3828
+ }
3829
+ )
3830
+ }
3831
+ ) });
3832
+ }
3833
+ if (mode === "custom" && children) {
3834
+ return /* @__PURE__ */ jsxRuntime.jsx(
3835
+ "div",
3836
+ {
3837
+ className: "flex items-center justify-center w-6 h-6 mr-3",
3838
+ style: { color: iconColor },
3839
+ children
3840
+ }
3841
+ );
3842
+ }
3843
+ return null;
3844
+ });
3845
+ TrailingIcon.displayName = "TrailingIcon";
3846
+ var LINE_HEIGHT_PX = 24;
3847
+ var TextFieldComponent = React4__namespace.forwardRef(
3848
+ ({
3849
+ // Core
3850
+ variant = "filled",
3851
+ label,
3852
+ value: valueProp,
3853
+ defaultValue = "",
3854
+ onChange,
3855
+ // Input config
3856
+ type = "text",
3857
+ placeholder,
3858
+ name,
3859
+ id: idProp,
3860
+ autoComplete,
3861
+ inputMode,
3862
+ autoResize = false,
3863
+ maxRows,
3864
+ rows = autoResize ? 1 : 2,
3865
+ cols,
3866
+ textDirection,
3867
+ // Validation
3868
+ required = false,
3869
+ noAsterisk = false,
3870
+ error: errorProp = false,
3871
+ errorText,
3872
+ minLength,
3873
+ maxLength,
3874
+ min,
3875
+ max,
3876
+ step,
3877
+ pattern,
3878
+ multiple,
3879
+ // Supporting text
3880
+ supportingText,
3881
+ // Decorators
3882
+ prefixText,
3883
+ suffixText,
3884
+ leadingIcon,
3885
+ trailingIcon,
3886
+ trailingIconMode = "none",
3887
+ // States
3888
+ disabled = false,
3889
+ readOnly = false,
3890
+ noSpinner = false,
3891
+ // Form
3892
+ form,
3893
+ // Accessibility
3894
+ "aria-label": ariaLabel,
3895
+ "aria-describedby": ariaDescribedby,
3896
+ "aria-labelledby": ariaLabelledby,
3897
+ // Layout
3898
+ className,
3899
+ fullWidth = true,
3900
+ dense = false,
3901
+ // ScrollArea
3902
+ scrollAreaType = "hover",
3903
+ // Callbacks
3904
+ onFocus,
3905
+ onBlur,
3906
+ onKeyDown,
3907
+ onKeyUp
3908
+ }, ref) => {
3909
+ var _a;
3910
+ const prefersReduced = (_a = react.useReducedMotion()) != null ? _a : false;
3911
+ const toolbarContext = useToolbarContext();
3912
+ const isInToolbar = !!toolbarContext;
3913
+ const resolvedDense = isInToolbar ? true : dense;
3914
+ const resolvedLabel = isInToolbar ? void 0 : label;
3915
+ const generatedId = React4__namespace.useId();
3916
+ const inputId = idProp != null ? idProp : `tf-${generatedId}`;
3917
+ const supportingId = `${inputId}-supporting`;
3918
+ const isControlled = valueProp !== void 0;
3919
+ const [internalValue, setInternalValue] = React4__namespace.useState(defaultValue);
3920
+ const currentValue = isControlled ? valueProp : internalValue;
3921
+ const [isFocused, setIsFocused] = React4__namespace.useState(false);
3922
+ const [showPassword, setShowPassword] = React4__namespace.useState(false);
3923
+ const resolvedInputType = type === "password" && showPassword ? "text" : type;
3924
+ const [nativeError, setNativeError] = React4__namespace.useState("");
3925
+ const [labelWidth, setLabelWidth] = React4__namespace.useState(0);
3926
+ const hasValue = currentValue.length > 0;
3927
+ const isFloated = isFocused || hasValue;
3928
+ const isError = errorProp || !!nativeError || maxLength !== void 0 && currentValue.length > maxLength;
3929
+ const containerHeight = resolvedDense ? TF_SIZE.denseHeight : TF_SIZE.height;
3930
+ const showAsterisk = required && !noAsterisk;
3931
+ const inputRef = React4__namespace.useRef(null);
3932
+ const labelSpanRef = React4__namespace.useRef(null);
3933
+ React4__namespace.useLayoutEffect(() => {
3934
+ if (labelSpanRef.current) {
3935
+ setLabelWidth(labelSpanRef.current.offsetWidth);
3936
+ }
3937
+ }, []);
3938
+ React4__namespace.useLayoutEffect(() => {
3939
+ if (type !== "textarea" || !inputRef.current) return;
3940
+ const textarea = inputRef.current;
3941
+ if (autoResize) {
3942
+ textarea.style.height = "auto";
3943
+ textarea.style.height = `${textarea.scrollHeight}px`;
3944
+ if (maxRows) {
3945
+ textarea.style.maxHeight = `${maxRows * LINE_HEIGHT_PX}px`;
3946
+ }
3947
+ }
3948
+ textarea.style.overflowY = "hidden";
3949
+ }, [type, autoResize, maxRows, currentValue]);
3950
+ const handleValueChange = React4__namespace.useCallback(
3951
+ (newValue) => {
3952
+ var _a2, _b;
3953
+ if (!isControlled) setInternalValue(newValue);
3954
+ setNativeError("");
3955
+ (_b = (_a2 = inputRef.current) == null ? void 0 : _a2.setCustomValidity) == null ? void 0 : _b.call(_a2, "");
3956
+ },
3957
+ [isControlled]
3958
+ );
3959
+ const handleChange = React4__namespace.useCallback(
3960
+ (e) => {
3961
+ const newVal = e.target.value;
3962
+ handleValueChange(newVal);
3963
+ onChange == null ? void 0 : onChange(newVal, e);
3964
+ },
3965
+ [handleValueChange, onChange]
3966
+ );
3967
+ const handleFocus = React4__namespace.useCallback(
3968
+ (e) => {
3969
+ setIsFocused(true);
3970
+ onFocus == null ? void 0 : onFocus(e);
3971
+ },
3972
+ [onFocus]
3973
+ );
3974
+ const handleBlur = React4__namespace.useCallback(
3975
+ (e) => {
3976
+ setIsFocused(false);
3977
+ const el = inputRef.current;
3978
+ if (el && !el.validity.valid) {
3979
+ setNativeError(el.validationMessage);
3980
+ } else {
3981
+ setNativeError("");
3982
+ }
3983
+ onBlur == null ? void 0 : onBlur(e);
3984
+ },
3985
+ [onBlur]
3986
+ );
3987
+ const handleClear = React4__namespace.useCallback(() => {
3988
+ var _a2;
3989
+ handleValueChange("");
3990
+ onChange == null ? void 0 : onChange("", {
3991
+ target: { value: "" }
3992
+ });
3993
+ (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
3994
+ }, [handleValueChange, onChange]);
3995
+ const handlePasswordToggle = React4__namespace.useCallback(() => {
3996
+ var _a2;
3997
+ setShowPassword((prev) => !prev);
3998
+ (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
3999
+ }, []);
4000
+ React4__namespace.useImperativeHandle(
4001
+ ref,
4002
+ () => ({
4003
+ focus: () => {
4004
+ var _a2;
4005
+ return (_a2 = inputRef.current) == null ? void 0 : _a2.focus();
4006
+ },
4007
+ blur: () => {
4008
+ var _a2;
4009
+ return (_a2 = inputRef.current) == null ? void 0 : _a2.blur();
4010
+ },
4011
+ select: () => {
4012
+ var _a2, _b;
4013
+ return (_b = (_a2 = inputRef.current) == null ? void 0 : _a2.select) == null ? void 0 : _b.call(_a2);
4014
+ },
4015
+ clear: () => handleValueChange(""),
4016
+ setCustomValidity: (msg) => {
4017
+ var _a2, _b;
4018
+ return (_b = (_a2 = inputRef.current) == null ? void 0 : _a2.setCustomValidity) == null ? void 0 : _b.call(_a2, msg);
4019
+ },
4020
+ checkValidity: () => {
4021
+ var _a2, _b, _c;
4022
+ return (_c = (_b = (_a2 = inputRef.current) == null ? void 0 : _a2.checkValidity) == null ? void 0 : _b.call(_a2)) != null ? _c : true;
4023
+ },
4024
+ reportValidity: () => {
4025
+ var _a2, _b, _c;
4026
+ const el = inputRef.current;
4027
+ const valid = (_b = (_a2 = el == null ? void 0 : el.reportValidity) == null ? void 0 : _a2.call(el)) != null ? _b : true;
4028
+ if (!valid) setNativeError((_c = el == null ? void 0 : el.validationMessage) != null ? _c : "");
4029
+ return valid;
4030
+ },
4031
+ getValue: () => currentValue,
4032
+ getInputElement: () => inputRef.current
4033
+ }),
4034
+ [currentValue, handleValueChange]
4035
+ );
4036
+ const hasSupporting = !!(supportingText || errorText || maxLength !== void 0);
4037
+ const computedDescribedby = [hasSupporting ? supportingId : "", ariaDescribedby != null ? ariaDescribedby : ""].filter(Boolean).join(" ") || void 0;
4038
+ const inputClass = cn(
4039
+ "bg-transparent outline-none w-full",
4040
+ isInToolbar ? "self-center" : "self-end",
4041
+ "text-base leading-6 text-m3-on-surface",
4042
+ "caret-[var(--color-m3-primary)]",
4043
+ "placeholder:text-m3-on-surface-variant/60",
4044
+ noSpinner && type === "number" && "[appearance:textfield] [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:appearance-none",
4045
+ disabled && "cursor-not-allowed"
4046
+ );
4047
+ const inputProps = {
4048
+ id: inputId,
4049
+ name,
4050
+ value: currentValue,
4051
+ placeholder: isFloated ? placeholder != null ? placeholder : "" : "",
4052
+ disabled,
4053
+ readOnly,
4054
+ required,
4055
+ minLength,
4056
+ maxLength,
4057
+ autoComplete,
4058
+ inputMode,
4059
+ form,
4060
+ "aria-label": ariaLabel,
4061
+ "aria-labelledby": ariaLabelledby,
4062
+ "aria-describedby": computedDescribedby,
4063
+ "aria-invalid": isError || void 0,
4064
+ "aria-required": required || void 0,
4065
+ onChange: handleChange,
4066
+ onFocus: handleFocus,
4067
+ onBlur: handleBlur,
4068
+ onKeyDown,
4069
+ onKeyUp
4070
+ };
4071
+ const hasLeading = !!leadingIcon;
4072
+ const paddingStart = "pl-4";
4073
+ const paddingEnd = "pr-4";
4074
+ const containerClass = cn(
4075
+ "relative flex items-center",
4076
+ variant === "filled" ? isInToolbar ? "bg-transparent" : "bg-[var(--color-m3-surface-container-highest)] rounded-tl-sm rounded-tr-sm" : "bg-transparent rounded-sm",
4077
+ fullWidth ? "w-full" : "w-fit"
4078
+ );
4079
+ const innerClass = cn(
4080
+ "relative flex flex-col flex-1 min-w-0 h-full",
4081
+ paddingStart,
4082
+ paddingEnd,
4083
+ isInToolbar ? "justify-center" : variant === "filled" ? resolvedDense ? "pt-5 pb-2" : "pt-6 pb-2" : resolvedDense ? "py-3" : "py-4"
4084
+ );
4085
+ const wrapperClass = cn(
4086
+ "group/tf inline-flex flex-col",
4087
+ fullWidth ? "w-full" : "w-fit",
4088
+ disabled && "opacity-[0.38] pointer-events-none",
4089
+ className
4090
+ );
4091
+ const containerHeightClass = resolvedDense ? "h-12" : "h-14";
4092
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: wrapperClass, children: [
4093
+ /* @__PURE__ */ jsxRuntime.jsxs(
4094
+ "div",
4095
+ {
4096
+ className: cn(
4097
+ containerClass,
4098
+ type !== "textarea" && containerHeightClass
4099
+ ),
4100
+ children: [
4101
+ variant === "outlined" && !isInToolbar && /* @__PURE__ */ jsxRuntime.jsx(
4102
+ OutlineContainer,
4103
+ {
4104
+ isFloated,
4105
+ isFocused,
4106
+ isError,
4107
+ isDisabled: disabled,
4108
+ isHovered: false,
4109
+ labelWidth,
4110
+ prefersReduced
4111
+ }
4112
+ ),
4113
+ variant === "filled" && !isInToolbar && /* @__PURE__ */ jsxRuntime.jsx(
4114
+ "div",
4115
+ {
4116
+ "aria-hidden": "true",
4117
+ className: cn(
4118
+ "absolute inset-0 pointer-events-none rounded-[inherit] bg-m3-on-surface",
4119
+ "opacity-0 transition-opacity duration-150",
4120
+ "group-hover/tf:opacity-[0.08]"
4121
+ )
4122
+ }
4123
+ ),
4124
+ leadingIcon && /* @__PURE__ */ jsxRuntime.jsx(LeadingIcon, { isError, isDisabled: disabled, children: leadingIcon }),
4125
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: innerClass, children: [
4126
+ resolvedLabel && /* @__PURE__ */ jsxRuntime.jsx(
4127
+ FloatingLabel,
4128
+ {
4129
+ text: resolvedLabel,
4130
+ isFloated,
4131
+ isFocused,
4132
+ isError,
4133
+ isDisabled: disabled,
4134
+ variant,
4135
+ containerHeight,
4136
+ prefersReduced,
4137
+ showAsterisk,
4138
+ htmlFor: inputId,
4139
+ labelRef: labelSpanRef,
4140
+ hasLeading
4141
+ }
4142
+ ),
4143
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center w-full", children: [
4144
+ prefixText && /* @__PURE__ */ jsxRuntime.jsx(
4145
+ PrefixSuffix,
4146
+ {
4147
+ text: prefixText,
4148
+ type: "prefix",
4149
+ visible: isFloated,
4150
+ prefersReduced
4151
+ }
4152
+ ),
4153
+ type === "textarea" ? /* @__PURE__ */ jsxRuntime.jsx(
4154
+ ScrollArea,
4155
+ {
4156
+ type: scrollAreaType,
4157
+ className: "w-full flex-1",
4158
+ style: {
4159
+ height: !autoResize ? rows * LINE_HEIGHT_PX : void 0,
4160
+ maxHeight: autoResize && maxRows ? maxRows * LINE_HEIGHT_PX : void 0
4161
+ },
4162
+ viewportClassName: "max-h-[inherit]",
4163
+ children: /* @__PURE__ */ jsxRuntime.jsx(
4164
+ "textarea",
4165
+ __spreadValues({
4166
+ ref: inputRef,
4167
+ rows,
4168
+ cols,
4169
+ className: cn(
4170
+ inputClass,
4171
+ "resize-none mt-2",
4172
+ autoResize ? "h-auto" : "h-full"
4173
+ ),
4174
+ style: { direction: textDirection || void 0 }
4175
+ }, inputProps)
4176
+ )
4177
+ }
4178
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
4179
+ "input",
4180
+ __spreadValues({
4181
+ ref: inputRef,
4182
+ type: type === "password" ? resolvedInputType : type,
4183
+ min,
4184
+ max,
4185
+ step,
4186
+ pattern,
4187
+ multiple,
4188
+ className: inputClass,
4189
+ style: { direction: textDirection || void 0 }
4190
+ }, inputProps)
4191
+ ),
4192
+ suffixText && /* @__PURE__ */ jsxRuntime.jsx(
4193
+ PrefixSuffix,
4194
+ {
4195
+ text: suffixText,
4196
+ type: "suffix",
4197
+ visible: isFloated,
4198
+ prefersReduced
4199
+ }
4200
+ )
4201
+ ] })
4202
+ ] }),
4203
+ (trailingIconMode !== "none" || trailingIcon) && /* @__PURE__ */ jsxRuntime.jsx(
4204
+ TrailingIcon,
4205
+ {
4206
+ mode: trailingIcon ? "custom" : trailingIconMode,
4207
+ value: currentValue,
4208
+ showPassword,
4209
+ onClear: handleClear,
4210
+ onPasswordToggle: handlePasswordToggle,
4211
+ isError,
4212
+ isDisabled: disabled,
4213
+ prefersReduced,
4214
+ children: trailingIcon
4215
+ }
4216
+ ),
4217
+ variant === "filled" && !isInToolbar && /* @__PURE__ */ jsxRuntime.jsx(
4218
+ ActiveIndicator,
4219
+ {
4220
+ isFocused,
4221
+ isError,
4222
+ isDisabled: disabled,
4223
+ isHovered: false,
4224
+ prefersReduced
4225
+ }
4226
+ )
4227
+ ]
4228
+ }
4229
+ ),
4230
+ hasSupporting && /* @__PURE__ */ jsxRuntime.jsx(
4231
+ SupportingText,
4232
+ {
4233
+ supportingText,
4234
+ errorText: errorText != null ? errorText : nativeError || void 0,
4235
+ isError,
4236
+ charCount: maxLength !== void 0 ? currentValue.length : void 0,
4237
+ maxLength,
4238
+ id: supportingId,
4239
+ prefersReduced
4240
+ }
4241
+ )
4242
+ ] }) });
4243
+ }
4244
+ );
4245
+ TextFieldComponent.displayName = "TextField";
4246
+ var TextField = React4__namespace.memo(TextFieldComponent);
4247
+
4248
+ exports.Checkbox = Checkbox;
4249
+ exports.Chip = Chip;
4250
+ exports.RadioButton = RadioButton;
4251
+ exports.RadioGroup = RadioGroup;
4252
+ exports.RangeSlider = RangeSlider;
4253
+ exports.Slider = Slider;
4254
+ exports.SliderColors = SliderColors;
4255
+ exports.SliderThumb = SliderThumb;
4256
+ exports.SliderTokens = SliderTokens;
4257
+ exports.Switch = Switch;
4258
+ exports.SwitchColors = SwitchColors;
4259
+ exports.SwitchTokens = SwitchTokens;
4260
+ exports.TextField = TextField;
4261
+ exports.TriStateCheckbox = TriStateCheckbox;
4262
+ //# sourceMappingURL=forms.js.map
4263
+ //# sourceMappingURL=forms.js.map