@bug-on/m3-expressive 1.3.0 → 1.3.2

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 (69) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/README.md +88 -60
  3. package/dist/buttons.d.mts +3 -3
  4. package/dist/buttons.d.ts +3 -3
  5. package/dist/buttons.js +185 -40
  6. package/dist/buttons.js.map +1 -1
  7. package/dist/buttons.mjs +186 -41
  8. package/dist/buttons.mjs.map +1 -1
  9. package/dist/{core-CAU8g2HY.d.mts → core-D8FdHY6I.d.mts} +1 -1
  10. package/dist/{core-DRrLnsnJ.d.ts → core-DyEy8H9Z.d.ts} +1 -1
  11. package/dist/core.d.mts +2 -2
  12. package/dist/core.d.ts +2 -2
  13. package/dist/core.js +156 -25
  14. package/dist/core.js.map +1 -1
  15. package/dist/core.mjs +157 -26
  16. package/dist/core.mjs.map +1 -1
  17. package/dist/feedback.d.mts +20 -0
  18. package/dist/feedback.d.ts +20 -0
  19. package/dist/feedback.js +157 -26
  20. package/dist/feedback.js.map +1 -1
  21. package/dist/feedback.mjs +158 -27
  22. package/dist/feedback.mjs.map +1 -1
  23. package/dist/forms.d.mts +4 -2
  24. package/dist/forms.d.ts +4 -2
  25. package/dist/forms.js +5065 -2980
  26. package/dist/forms.js.map +1 -1
  27. package/dist/forms.mjs +5064 -2982
  28. package/dist/forms.mjs.map +1 -1
  29. package/dist/{icon-button-USJo7AqO.d.mts → icon-button-CxyJv7UV.d.mts} +1 -1
  30. package/dist/{icon-button-CqdQBsRe.d.ts → icon-button-Di8VX6ou.d.ts} +1 -1
  31. package/dist/index.d.mts +12 -82
  32. package/dist/index.d.ts +12 -82
  33. package/dist/index.js +2875 -1226
  34. package/dist/index.js.map +1 -1
  35. package/dist/index.mjs +2723 -1086
  36. package/dist/index.mjs.map +1 -1
  37. package/dist/layout.d.mts +481 -33
  38. package/dist/layout.d.ts +481 -33
  39. package/dist/layout.js +1653 -243
  40. package/dist/layout.js.map +1 -1
  41. package/dist/layout.mjs +1626 -232
  42. package/dist/layout.mjs.map +1 -1
  43. package/dist/{md3-D0_Z7IXj.d.mts → md3-BQhRygSi.d.mts} +1 -1
  44. package/dist/{md3-D0_Z7IXj.d.ts → md3-BQhRygSi.d.ts} +1 -1
  45. package/dist/menu-types-rZNQFO7Y.d.mts +315 -0
  46. package/dist/menu-types-rZNQFO7Y.d.ts +315 -0
  47. package/dist/navigation.d.mts +5 -289
  48. package/dist/navigation.d.ts +5 -289
  49. package/dist/navigation.js +575 -271
  50. package/dist/navigation.js.map +1 -1
  51. package/dist/navigation.mjs +568 -265
  52. package/dist/navigation.mjs.map +1 -1
  53. package/dist/overlays.d.mts +2 -2
  54. package/dist/overlays.d.ts +2 -2
  55. package/dist/overlays.js +156 -25
  56. package/dist/overlays.js.map +1 -1
  57. package/dist/overlays.mjs +157 -26
  58. package/dist/overlays.mjs.map +1 -1
  59. package/dist/pickers.js +156 -25
  60. package/dist/pickers.js.map +1 -1
  61. package/dist/pickers.mjs +157 -26
  62. package/dist/pickers.mjs.map +1 -1
  63. package/dist/{side-sheet-modal-Dgjt739k.d.mts → side-sheet-modal-64FGhDxL.d.mts} +1 -1
  64. package/dist/{side-sheet-modal-DdEZR6Vl.d.ts → side-sheet-modal-Bd5Qqvp9.d.ts} +1 -1
  65. package/dist/{split-button-trailing-uncheckable-26qlZvKT.d.mts → split-button-trailing-uncheckable-CGzk7KcG.d.ts} +3 -1
  66. package/dist/{split-button-trailing-uncheckable-CXUVrH64.d.ts → split-button-trailing-uncheckable-gAz6OAIi.d.mts} +3 -1
  67. package/dist/{text-field-DWC7qOvp.d.ts → text-field-4OlT9o8s.d.mts} +206 -55
  68. package/dist/{text-field-DWC7qOvp.d.mts → text-field-DARNdj14.d.ts} +206 -55
  69. package/package.json +3 -3
package/dist/layout.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { Slot } from '@radix-ui/react-slot';
3
3
  import { cva } from 'class-variance-authority';
4
- import { m, LazyMotion, domMax, useAnimationFrame, useMotionValue, animate, AnimatePresence, useReducedMotion } from 'motion/react';
5
- import * as React18 from 'react';
4
+ import { m, LazyMotion, domMax, useMotionValue, animate, useAnimationFrame, AnimatePresence, useReducedMotion } from 'motion/react';
5
+ import * as React23 from 'react';
6
6
  import { createContext, useState, useCallback, useMemo, useEffect, useContext, createElement } from 'react';
7
7
  import { clsx } from 'clsx';
8
8
  import { twMerge } from 'tailwind-merge';
@@ -55,7 +55,7 @@ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "acce
55
55
  function cn(...inputs) {
56
56
  return twMerge(clsx(inputs));
57
57
  }
58
- var RippleItem = React18.memo(function RippleItem2({
58
+ var RippleItem = React23.memo(function RippleItem2({
59
59
  ripple,
60
60
  onDone
61
61
  }) {
@@ -99,8 +99,8 @@ function Ripple({
99
99
  }
100
100
  function useRippleState(options = {}) {
101
101
  const { disabled = false } = options;
102
- const [ripples, setRipples] = React18.useState([]);
103
- const onPointerDown = React18.useCallback(
102
+ const [ripples, setRipples] = React23.useState([]);
103
+ const onPointerDown = React23.useCallback(
104
104
  (e) => {
105
105
  if (disabled) return;
106
106
  const rect = e.currentTarget.getBoundingClientRect();
@@ -117,21 +117,36 @@ function useRippleState(options = {}) {
117
117
  },
118
118
  [disabled]
119
119
  );
120
- const removeRipple = React18.useCallback((id) => {
120
+ const removeRipple = React23.useCallback((id) => {
121
121
  setRipples((prev) => prev.filter((r) => r.id !== id));
122
122
  }, []);
123
123
  return { ripples, onPointerDown, removeRipple };
124
124
  }
125
+
126
+ // src/ui/cards/card/card-tokens.ts
125
127
  var SHADOW = {
126
128
  level0: "none",
127
129
  level1: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 1px 3px 1px rgba(0,0,0,.15)",
128
- level2: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 2px 6px 2px rgba(0,0,0,.15)"
130
+ level2: "0px 1px 2px 0px rgba(0,0,0,.3), 0px 2px 6px 2px rgba(0,0,0,.15)",
131
+ level3: "0px 4px 8px 3px rgba(0,0,0,.15), 0px 1px 3px 0px rgba(0,0,0,.3)",
132
+ level4: "0px 6px 10px 4px rgba(0,0,0,.15), 0px 2px 3px 0px rgba(0,0,0,.3)",
133
+ level5: "0px 8px 12px 6px rgba(0,0,0,.15), 0px 4px 4px 0px rgba(0,0,0,.3)"
129
134
  };
135
+ function resolveElevationShadow(level) {
136
+ var _a;
137
+ if (level === void 0) return void 0;
138
+ if (typeof level === "number") {
139
+ const key = `level${level}`;
140
+ return (_a = SHADOW[key]) != null ? _a : SHADOW.level0;
141
+ }
142
+ return level;
143
+ }
130
144
  var VARIANT_ELEVATION = {
131
145
  elevated: {
132
146
  rest: SHADOW.level1,
133
147
  hover: SHADOW.level2,
134
148
  pressed: SHADOW.level1,
149
+ dragged: SHADOW.level3,
135
150
  disabled: SHADOW.level1
136
151
  // ElevatedCardTokens.DisabledContainerElevation = Level1
137
152
  },
@@ -139,78 +154,177 @@ var VARIANT_ELEVATION = {
139
154
  rest: SHADOW.level0,
140
155
  hover: SHADOW.level1,
141
156
  pressed: SHADOW.level0,
157
+ dragged: SHADOW.level3,
142
158
  disabled: SHADOW.level0
143
159
  },
144
160
  outlined: {
145
161
  rest: SHADOW.level0,
146
162
  hover: SHADOW.level1,
147
163
  pressed: SHADOW.level0,
164
+ dragged: SHADOW.level3,
148
165
  disabled: SHADOW.level0
149
166
  }
150
167
  };
168
+ function useCardElevation({
169
+ variant = "elevated",
170
+ disabled = false,
171
+ draggable = false,
172
+ elevation,
173
+ disableElevation = false,
174
+ hoverEffect = true
175
+ }) {
176
+ var _a, _b, _c, _d, _e, _f, _g;
177
+ const defaultLevels = VARIANT_ELEVATION[variant] || VARIANT_ELEVATION.elevated;
178
+ let restShadow = defaultLevels.rest;
179
+ let hoverShadow = defaultLevels.hover;
180
+ let pressedShadow = defaultLevels.pressed;
181
+ let draggedShadow = defaultLevels.dragged;
182
+ if (disableElevation) {
183
+ restShadow = SHADOW.level0;
184
+ hoverShadow = SHADOW.level0;
185
+ pressedShadow = SHADOW.level0;
186
+ draggedShadow = SHADOW.level0;
187
+ } else if (typeof elevation === "number") {
188
+ const resolved = (_a = resolveElevationShadow(elevation)) != null ? _a : SHADOW.level0;
189
+ restShadow = resolved;
190
+ const hoverLevel = hoverEffect ? Math.min(elevation + 1, 5) : elevation;
191
+ hoverShadow = (_b = resolveElevationShadow(hoverLevel)) != null ? _b : resolved;
192
+ pressedShadow = resolved;
193
+ draggedShadow = (_c = resolveElevationShadow(
194
+ Math.min(elevation + 2, 5)
195
+ )) != null ? _c : resolved;
196
+ } else if (elevation && typeof elevation === "object") {
197
+ if (elevation.rest !== void 0) {
198
+ restShadow = (_d = resolveElevationShadow(elevation.rest)) != null ? _d : restShadow;
199
+ }
200
+ if (elevation.hover !== void 0) {
201
+ hoverShadow = (_e = resolveElevationShadow(elevation.hover)) != null ? _e : hoverShadow;
202
+ }
203
+ if (elevation.pressed !== void 0) {
204
+ pressedShadow = (_f = resolveElevationShadow(elevation.pressed)) != null ? _f : pressedShadow;
205
+ }
206
+ if (elevation.dragged !== void 0) {
207
+ draggedShadow = (_g = resolveElevationShadow(elevation.dragged)) != null ? _g : draggedShadow;
208
+ }
209
+ }
210
+ if (!hoverEffect) {
211
+ hoverShadow = restShadow;
212
+ }
213
+ const animateShadow = disabled ? disableElevation ? SHADOW.level0 : defaultLevels.disabled : restShadow;
214
+ return {
215
+ animate: { boxShadow: animateShadow },
216
+ whileHover: disabled || !hoverEffect ? void 0 : { boxShadow: hoverShadow },
217
+ whileTap: disabled ? void 0 : { boxShadow: pressedShadow },
218
+ whileFocus: disabled || !hoverEffect ? void 0 : { boxShadow: hoverShadow },
219
+ whileDrag: !disabled && draggable ? { boxShadow: draggedShadow } : void 0,
220
+ transition: {
221
+ boxShadow: {
222
+ // Incoming: 120ms (from Elevation.kt DefaultIncomingSpec)
223
+ duration: 0.12,
224
+ ease: [0.4, 0, 0.2, 1]
225
+ }
226
+ }
227
+ };
228
+ }
151
229
  var cardVariants = cva(
152
- "rounded-m3-lg flex flex-col relative overflow-hidden transition-colors duration-200",
230
+ "rounded-m3-lg flex flex-col relative overflow-hidden transition-all duration-200",
153
231
  {
154
232
  variants: {
155
233
  variant: {
156
234
  // ElevatedCardTokens.ContainerColor = SurfaceContainerLow
157
- elevated: "bg-m3-surface-container-low",
235
+ elevated: "bg-m3-surface-container-low text-m3-on-surface",
158
236
  // FilledCardTokens.ContainerColor = SurfaceContainerHighest
159
- filled: "bg-m3-surface-container-highest",
237
+ filled: "bg-m3-surface-container-highest text-m3-on-surface",
160
238
  // OutlinedCardTokens.ContainerColor = Surface, OutlineColor = OutlineVariant
161
- outlined: "bg-m3-surface border border-m3-outline-variant"
239
+ outlined: "bg-m3-surface text-m3-on-surface border border-m3-outline-variant"
162
240
  }
163
241
  },
164
242
  defaultVariants: { variant: "elevated" }
165
243
  }
166
244
  );
167
- function useCardElevation(variant, disabled) {
168
- const levels = VARIANT_ELEVATION[variant];
169
- return {
170
- animate: { boxShadow: disabled ? levels.disabled : levels.rest },
171
- whileHover: disabled ? void 0 : { boxShadow: levels.hover },
172
- whileTap: disabled ? void 0 : { boxShadow: levels.pressed },
173
- whileFocus: disabled ? void 0 : { boxShadow: levels.hover },
174
- transition: {
175
- boxShadow: {
176
- // Incoming: 120ms (from Elevation.kt DefaultIncomingSpec)
177
- duration: 0.12,
178
- ease: [0.4, 0, 0.2, 1]
179
- }
180
- }
181
- };
182
- }
183
- var CardImpl = React18.forwardRef(
245
+ var CardImpl = React23.forwardRef(
184
246
  (_a, ref) => {
185
247
  var _b = _a, {
186
248
  className,
187
249
  variant = "elevated",
250
+ elevation,
251
+ disableElevation = false,
252
+ ripple = true,
253
+ disableRipple = false,
254
+ hoverEffect = true,
255
+ disableHoverEffect = false,
256
+ stateLayer = true,
257
+ disableStateLayer = false,
188
258
  disabled = false,
189
259
  interactive = false,
260
+ draggable = false,
190
261
  href,
191
262
  target,
192
263
  rel: relProp,
193
264
  onClick,
265
+ onPointerDown: userOnPointerDown,
266
+ whileHover,
267
+ whileTap,
268
+ whileFocus,
269
+ whileDrag,
270
+ transition,
194
271
  asChild = false,
195
272
  children
196
273
  } = _b, props = __objRest(_b, [
197
274
  "className",
198
275
  "variant",
276
+ "elevation",
277
+ "disableElevation",
278
+ "ripple",
279
+ "disableRipple",
280
+ "hoverEffect",
281
+ "disableHoverEffect",
282
+ "stateLayer",
283
+ "disableStateLayer",
199
284
  "disabled",
200
285
  "interactive",
286
+ "draggable",
201
287
  "href",
202
288
  "target",
203
289
  "rel",
204
290
  "onClick",
291
+ "onPointerDown",
292
+ "whileHover",
293
+ "whileTap",
294
+ "whileFocus",
295
+ "whileDrag",
296
+ "transition",
205
297
  "asChild",
206
298
  "children"
207
299
  ]);
208
- const safeVariant = variant;
300
+ const safeVariant = variant || "elevated";
209
301
  const isInteractive = !!onClick || !!href || interactive || asChild;
210
- const elevationProps = useCardElevation(safeVariant, disabled);
211
- const { ripples, onPointerDown, removeRipple } = useRippleState();
302
+ const isHoverEnabled = hoverEffect !== false && !disableHoverEffect;
303
+ const isRippleEnabled = ripple !== false && !disableRipple && isInteractive && !disabled;
304
+ const isStateLayerEnabled = stateLayer !== false && !disableStateLayer && isInteractive && !disabled;
305
+ const elevationProps = useCardElevation({
306
+ variant: safeVariant,
307
+ disabled,
308
+ draggable,
309
+ elevation,
310
+ disableElevation,
311
+ hoverEffect: isHoverEnabled
312
+ });
313
+ const {
314
+ ripples,
315
+ onPointerDown: rippleOnPointerDown,
316
+ removeRipple
317
+ } = useRippleState();
318
+ const handlePointerDown = (event) => {
319
+ if (isRippleEnabled) {
320
+ rippleOnPointerDown(event);
321
+ }
322
+ userOnPointerDown == null ? void 0 : userOnPointerDown(
323
+ event
324
+ );
325
+ };
212
326
  const baseClass = cn(
213
- cardVariants({ variant }),
327
+ cardVariants({ variant: safeVariant }),
214
328
  // Disabled state:
215
329
  // - pointer-events-none → disable interactions completely
216
330
  // - opacity-[0.38] → MD3 DisabledContainerOpacity
@@ -220,17 +334,25 @@ var CardImpl = React18.forwardRef(
220
334
  const interactiveClass = cn(
221
335
  // Remove default outline, use MD3 state overlay & elevation for focus
222
336
  "focus-visible:outline-none focus:outline-none group",
223
- // Base pseudo-element overlay layer
224
- "before:absolute before:inset-0 before:pointer-events-none before:bg-m3-on-surface before:opacity-0 before:transition-opacity before:duration-200",
225
- // Interactive state opacities
226
- "hover:before:opacity-[0.08] focus-visible:before:opacity-[0.10] active:before:opacity-[0.10]",
227
- // Outlined interactive card: change border color to m3-outline on focus/press/hover
228
- variant === "outlined" && "hover:border-m3-outline focus-visible:border-m3-outline active:border-m3-outline"
337
+ // Base pseudo-element overlay layer (when stateLayer is enabled)
338
+ isStateLayerEnabled && [
339
+ "before:absolute before:inset-0 before:pointer-events-none before:bg-m3-on-surface before:opacity-0 before:transition-opacity before:duration-200",
340
+ isHoverEnabled && "hover:before:opacity-[0.08]",
341
+ "focus-visible:before:opacity-[0.10] active:before:opacity-[0.10]",
342
+ draggable && "active:before:opacity-[0.16]"
343
+ ],
344
+ // Outlined interactive card: smooth transition of border color to m3-outline on hover/focus/press
345
+ safeVariant === "outlined" && "transition-colors duration-200 hover:border-m3-outline focus-visible:border-m3-outline active:border-m3-outline"
229
346
  );
347
+ const mergedWhileHover = elevationProps.whileHover || whileHover ? __spreadValues(__spreadValues({}, elevationProps.whileHover), typeof whileHover === "object" ? whileHover : {}) : void 0;
348
+ const mergedWhileTap = elevationProps.whileTap || whileTap ? __spreadValues(__spreadValues({}, elevationProps.whileTap), typeof whileTap === "object" ? whileTap : {}) : void 0;
349
+ const mergedWhileFocus = elevationProps.whileFocus || whileFocus ? __spreadValues(__spreadValues({}, elevationProps.whileFocus), typeof whileFocus === "object" ? whileFocus : {}) : void 0;
350
+ const mergedWhileDrag = elevationProps.whileDrag || whileDrag ? __spreadValues(__spreadValues({}, elevationProps.whileDrag), typeof whileDrag === "object" ? whileDrag : {}) : void 0;
351
+ const mergedTransition = elevationProps.transition || transition ? __spreadValues(__spreadValues({}, elevationProps.transition), typeof transition === "object" ? transition : {}) : void 0;
230
352
  if (asChild) {
231
- const child = React18.Children.only(children);
353
+ const child = React23.Children.only(children);
232
354
  const innerContent = /* @__PURE__ */ jsxs(Fragment, { children: [
233
- /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
355
+ isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
234
356
  child.props.children
235
357
  ] });
236
358
  return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(
@@ -240,22 +362,26 @@ var CardImpl = React18.forwardRef(
240
362
  className: cn(baseClass, interactiveClass),
241
363
  "aria-disabled": disabled ? true : void 0,
242
364
  tabIndex: disabled ? -1 : 0,
243
- onPointerDown,
365
+ onPointerDown: handlePointerDown,
244
366
  onClick
245
367
  }, props), {
246
- children: React18.cloneElement(child, { children: innerContent })
368
+ children: React23.cloneElement(child, { children: innerContent })
247
369
  })
248
370
  ) });
249
371
  }
250
372
  if (!isInteractive) {
251
373
  return /* @__PURE__ */ jsx(
252
374
  "div",
253
- {
375
+ __spreadProps(__spreadValues({
254
376
  ref,
255
377
  className: baseClass,
256
- "aria-disabled": disabled ? true : void 0,
378
+ style: __spreadValues({
379
+ boxShadow: elevationProps.animate.boxShadow
380
+ }, props.style || {}),
381
+ "aria-disabled": disabled ? true : void 0
382
+ }, props), {
257
383
  children
258
- }
384
+ })
259
385
  );
260
386
  }
261
387
  const safeRel = href ? relProp != null ? relProp : target === "_blank" ? "noreferrer" : void 0 : void 0;
@@ -270,10 +396,16 @@ var CardImpl = React18.forwardRef(
270
396
  className: cn(baseClass, interactiveClass),
271
397
  "aria-disabled": disabled ? true : void 0,
272
398
  tabIndex: disabled ? -1 : 0,
273
- onPointerDown
274
- }, elevationProps), {
399
+ onPointerDown: handlePointerDown,
400
+ animate: elevationProps.animate,
401
+ whileHover: mergedWhileHover,
402
+ whileTap: mergedWhileTap,
403
+ whileFocus: mergedWhileFocus,
404
+ whileDrag: mergedWhileDrag,
405
+ transition: mergedTransition
406
+ }, props), {
275
407
  children: [
276
- /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
408
+ isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
277
409
  children
278
410
  ]
279
411
  })
@@ -281,7 +413,7 @@ var CardImpl = React18.forwardRef(
281
413
  }
282
414
  return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsxs(
283
415
  m.button,
284
- __spreadProps(__spreadValues(__spreadValues({
416
+ __spreadProps(__spreadValues({
285
417
  ref,
286
418
  type: "button",
287
419
  disabled,
@@ -289,10 +421,16 @@ var CardImpl = React18.forwardRef(
289
421
  className: cn(baseClass, interactiveClass),
290
422
  "aria-disabled": disabled ? true : void 0,
291
423
  tabIndex: disabled ? -1 : 0,
292
- onPointerDown
293
- }, elevationProps), props), {
424
+ onPointerDown: handlePointerDown,
425
+ animate: elevationProps.animate,
426
+ whileHover: mergedWhileHover,
427
+ whileTap: mergedWhileTap,
428
+ whileFocus: mergedWhileFocus,
429
+ whileDrag: mergedWhileDrag,
430
+ transition: mergedTransition
431
+ }, props), {
294
432
  children: [
295
- /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
433
+ isRippleEnabled && /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
296
434
  children
297
435
  ]
298
436
  })
@@ -300,7 +438,1132 @@ var CardImpl = React18.forwardRef(
300
438
  }
301
439
  );
302
440
  CardImpl.displayName = "Card";
303
- var Card = React18.memo(CardImpl);
441
+ var Card = React23.memo(CardImpl);
442
+ var CardHeader = React23.forwardRef(
443
+ (_a, ref) => {
444
+ var _b = _a, { className, avatar, title, subheader, action, children } = _b, props = __objRest(_b, ["className", "avatar", "title", "subheader", "action", "children"]);
445
+ return /* @__PURE__ */ jsxs(
446
+ "div",
447
+ __spreadProps(__spreadValues({
448
+ ref,
449
+ className: cn(
450
+ "flex items-center gap-4 px-6 pt-6 pb-2 relative z-1",
451
+ className
452
+ )
453
+ }, props), {
454
+ children: [
455
+ avatar && /* @__PURE__ */ jsx("div", { className: "shrink-0 flex items-center", children: avatar }),
456
+ title || subheader ? /* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
457
+ title && /* @__PURE__ */ jsx("div", { className: "text-base font-medium text-m3-on-surface truncate", children: title }),
458
+ subheader && /* @__PURE__ */ jsx("div", { className: "text-sm text-m3-on-surface-variant truncate", children: subheader })
459
+ ] }) : null,
460
+ children,
461
+ action && /* @__PURE__ */ jsx("div", { className: "shrink-0 ml-auto flex items-center", children: action })
462
+ ]
463
+ })
464
+ );
465
+ }
466
+ );
467
+ CardHeader.displayName = "CardHeader";
468
+ var ASPECT_RATIO_CLASSES = {
469
+ video: "aspect-video",
470
+ square: "aspect-square",
471
+ wide: "aspect-[21/9]",
472
+ auto: ""
473
+ };
474
+ var CardMedia = React23.forwardRef(
475
+ (_a, ref) => {
476
+ var _b = _a, {
477
+ className,
478
+ src,
479
+ alt = "",
480
+ aspectRatio = "video",
481
+ component,
482
+ children
483
+ } = _b, props = __objRest(_b, [
484
+ "className",
485
+ "src",
486
+ "alt",
487
+ "aspectRatio",
488
+ "component",
489
+ "children"
490
+ ]);
491
+ const ratioClass = aspectRatio in ASPECT_RATIO_CLASSES ? ASPECT_RATIO_CLASSES[aspectRatio] : "";
492
+ const Component = component || (src && !children ? "img" : "div");
493
+ return /* @__PURE__ */ jsx(
494
+ "div",
495
+ __spreadProps(__spreadValues({
496
+ ref,
497
+ className: cn(
498
+ "relative w-full overflow-hidden shrink-0",
499
+ ratioClass,
500
+ className
501
+ )
502
+ }, props), {
503
+ children: children ? children : src ? /* @__PURE__ */ jsx(
504
+ Component,
505
+ {
506
+ src,
507
+ alt,
508
+ className: "w-full h-full object-cover"
509
+ }
510
+ ) : null
511
+ })
512
+ );
513
+ }
514
+ );
515
+ CardMedia.displayName = "CardMedia";
516
+ var CardContent = React23.forwardRef(
517
+ (_a, ref) => {
518
+ var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
519
+ return /* @__PURE__ */ jsx(
520
+ "div",
521
+ __spreadProps(__spreadValues({
522
+ ref,
523
+ className: cn(
524
+ "px-6 py-4 text-sm text-m3-on-surface-variant flex-1 relative z-1",
525
+ className
526
+ )
527
+ }, props), {
528
+ children
529
+ })
530
+ );
531
+ }
532
+ );
533
+ CardContent.displayName = "CardContent";
534
+ var ALIGN_CLASSES = {
535
+ start: "justify-start",
536
+ center: "justify-center",
537
+ end: "justify-end",
538
+ between: "justify-between"
539
+ };
540
+ var CardFooter = React23.forwardRef(
541
+ (_a, ref) => {
542
+ var _b = _a, { className, align = "end", children } = _b, props = __objRest(_b, ["className", "align", "children"]);
543
+ return /* @__PURE__ */ jsx(
544
+ "div",
545
+ __spreadProps(__spreadValues({
546
+ ref,
547
+ className: cn(
548
+ "flex items-center gap-2 px-6 pb-6 pt-2 relative z-1",
549
+ ALIGN_CLASSES[align],
550
+ className
551
+ )
552
+ }, props), {
553
+ children
554
+ })
555
+ );
556
+ }
557
+ );
558
+ CardFooter.displayName = "CardFooter";
559
+ function CarouselGrid(_a) {
560
+ var _b = _a, {
561
+ children,
562
+ items,
563
+ renderItem,
564
+ preferredItemWidth = 240,
565
+ className,
566
+ style
567
+ } = _b, props = __objRest(_b, [
568
+ "children",
569
+ "items",
570
+ "renderItem",
571
+ "preferredItemWidth",
572
+ "className",
573
+ "style"
574
+ ]);
575
+ const gridStyle = __spreadValues({
576
+ display: "grid",
577
+ gridTemplateColumns: `repeat(auto-fill, minmax(${preferredItemWidth}px, 1fr))`,
578
+ gap: "8px",
579
+ padding: "8px 16px",
580
+ width: "100%",
581
+ boxSizing: "border-box"
582
+ }, style);
583
+ const itemStyle = {
584
+ position: "relative",
585
+ width: "100%",
586
+ minHeight: "180px",
587
+ borderRadius: "28px",
588
+ overflow: "hidden"
589
+ };
590
+ if (items && renderItem) {
591
+ return /* @__PURE__ */ jsx(
592
+ "section",
593
+ __spreadProps(__spreadValues({
594
+ className,
595
+ style: gridStyle,
596
+ "aria-label": "Expanded carousel grid"
597
+ }, props), {
598
+ children: items.map((item, index) => {
599
+ const itemKey = typeof item === "object" && item !== null && "id" in item ? item.id : typeof item === "object" && item !== null && "key" in item ? item.key : index;
600
+ return /* @__PURE__ */ jsx("div", { style: itemStyle, children: renderItem(item, index) }, itemKey);
601
+ })
602
+ })
603
+ );
604
+ }
605
+ return /* @__PURE__ */ jsx(
606
+ "section",
607
+ __spreadProps(__spreadValues({
608
+ className,
609
+ style: gridStyle,
610
+ "aria-label": "Expanded carousel grid"
611
+ }, props), {
612
+ children: React23.Children.map(children, (child, index) => {
613
+ const childKey = React23.isValidElement(child) && child.key != null ? child.key : index;
614
+ return /* @__PURE__ */ jsx("div", { style: itemStyle, children: child }, childKey);
615
+ })
616
+ })
617
+ );
618
+ }
619
+ var CarouselItem = React23.forwardRef(
620
+ function CarouselItem2(_a, ref) {
621
+ var _b = _a, {
622
+ index,
623
+ totalItems,
624
+ layout = "multi-browse",
625
+ width,
626
+ minContentWidth,
627
+ maskClipPercent = 0,
628
+ parallaxOffset = 0,
629
+ isFocused = false,
630
+ isScrolling = false,
631
+ disabled = false,
632
+ className,
633
+ style,
634
+ children,
635
+ onClick,
636
+ onPointerDown
637
+ } = _b, props = __objRest(_b, [
638
+ "index",
639
+ "totalItems",
640
+ "layout",
641
+ "width",
642
+ "minContentWidth",
643
+ "maskClipPercent",
644
+ "parallaxOffset",
645
+ "isFocused",
646
+ "isScrolling",
647
+ "disabled",
648
+ "className",
649
+ "style",
650
+ "children",
651
+ "onClick",
652
+ "onPointerDown"
653
+ ]);
654
+ const {
655
+ ripples,
656
+ onPointerDown: handleRipplePointerDown,
657
+ removeRipple
658
+ } = useRippleState();
659
+ const itemNumber = index + 1;
660
+ const ariaLabel = props["aria-label"] || `Item ${itemNumber} of ${totalItems}`;
661
+ const isFullScreen = layout === "full-screen";
662
+ const isCenterHero = layout === "center-aligned-hero";
663
+ const combinedStyle = __spreadValues({
664
+ width: isFullScreen ? "100%" : width ? `${width}px` : void 0,
665
+ height: isFullScreen ? "100%" : void 0,
666
+ flexShrink: 0
667
+ }, style);
668
+ const handlePointerDown = (e) => {
669
+ if (!disabled) {
670
+ handleRipplePointerDown(e);
671
+ }
672
+ onPointerDown == null ? void 0 : onPointerDown(e);
673
+ };
674
+ const handleKeyDown = (e) => {
675
+ var _a2;
676
+ if (!disabled && (e.key === "Enter" || e.key === " ")) {
677
+ e.preventDefault();
678
+ onClick == null ? void 0 : onClick(e);
679
+ }
680
+ (_a2 = props.onKeyDown) == null ? void 0 : _a2.call(props, e);
681
+ };
682
+ return (
683
+ // biome-ignore lint/a11y/useSemanticElements: ARIA carousel pattern requires role="group" for slide items
684
+ /* @__PURE__ */ jsxs(
685
+ "div",
686
+ __spreadProps(__spreadValues({
687
+ ref,
688
+ role: "group",
689
+ "aria-roledescription": "slide",
690
+ "aria-label": ariaLabel,
691
+ tabIndex: disabled ? -1 : isFocused ? 0 : -1,
692
+ className: cn(
693
+ // Base item styles: overflow-hidden + rounded 28px acts as MD3 keyline mask
694
+ "relative flex flex-col overflow-hidden rounded-[28px] cursor-pointer select-none box-border outline-none shrink-0",
695
+ // GPU Composition & Layout Containment
696
+ "will-change-[transform,clip-path] contain-[layout_paint_style] [user-select:none] [-webkit-user-drag:none] [&_img]:pointer-events-none [&_img]:select-none [&_img]:[-webkit-user-drag:none]",
697
+ // Scroll snap: center-aligned hero snaps to center, all others snap start
698
+ isCenterHero ? "snap-center" : "snap-start",
699
+ // Full-screen: no rounding, fill height
700
+ isFullScreen && "rounded-none",
701
+ // State layers via ::after pseudo-element
702
+ "after:absolute after:inset-0 after:rounded-[inherit] after:bg-black after:opacity-0 after:pointer-events-none after:z-2 after:transition-opacity after:duration-150 after:motion-reduce:transition-none",
703
+ "hover:after:opacity-[0.08]",
704
+ "active:after:opacity-[0.10]",
705
+ // Focus ring
706
+ "focus-visible:outline-[3px] focus-visible:outline-(--md-sys-color-secondary,#625b71) focus-visible:outline-offset-2 focus-visible:z-3",
707
+ // Disabled
708
+ disabled && "opacity-[0.38] pointer-events-none",
709
+ className
710
+ ),
711
+ style: combinedStyle,
712
+ onPointerDown: handlePointerDown,
713
+ onKeyDown: handleKeyDown,
714
+ onClick: disabled ? void 0 : onClick
715
+ }, props), {
716
+ children: [
717
+ /* @__PURE__ */ jsx(
718
+ "div",
719
+ {
720
+ className: "w-full flex-1 flex flex-col will-change-transform select-none",
721
+ style: {
722
+ width: isFullScreen ? "100%" : minContentWidth ? `${minContentWidth}px` : "100%",
723
+ minWidth: isFullScreen ? "100%" : minContentWidth ? `${minContentWidth}px` : void 0,
724
+ transform: parallaxOffset !== 0 ? `translateX(${parallaxOffset}px)` : void 0
725
+ },
726
+ children
727
+ }
728
+ ),
729
+ /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple })
730
+ ]
731
+ })
732
+ )
733
+ );
734
+ }
735
+ );
736
+ CarouselItem.displayName = "CarouselItem";
737
+ function useCarouselA11y({
738
+ totalItems,
739
+ onItemSelect,
740
+ onExitNavigation,
741
+ scrollToIndex
742
+ }) {
743
+ const [focusedIndex, setFocusedIndex] = useState(0);
744
+ const handleKeyDown = useCallback(
745
+ (event) => {
746
+ if (totalItems === 0) return;
747
+ switch (event.key) {
748
+ case "ArrowRight":
749
+ case "ArrowDown": {
750
+ if (event.key === "ArrowDown" && onExitNavigation) {
751
+ onExitNavigation();
752
+ return;
753
+ }
754
+ event.preventDefault();
755
+ setFocusedIndex((prev) => {
756
+ const next = Math.min(totalItems - 1, prev + 1);
757
+ scrollToIndex == null ? void 0 : scrollToIndex(next);
758
+ return next;
759
+ });
760
+ break;
761
+ }
762
+ case "ArrowLeft":
763
+ case "ArrowUp": {
764
+ if (event.key === "ArrowUp" && onExitNavigation) {
765
+ onExitNavigation();
766
+ return;
767
+ }
768
+ event.preventDefault();
769
+ setFocusedIndex((prev) => {
770
+ const next = Math.max(0, prev - 1);
771
+ scrollToIndex == null ? void 0 : scrollToIndex(next);
772
+ return next;
773
+ });
774
+ break;
775
+ }
776
+ case "Home": {
777
+ event.preventDefault();
778
+ setFocusedIndex(0);
779
+ scrollToIndex == null ? void 0 : scrollToIndex(0);
780
+ break;
781
+ }
782
+ case "End": {
783
+ event.preventDefault();
784
+ const lastIndex = totalItems - 1;
785
+ setFocusedIndex(lastIndex);
786
+ scrollToIndex == null ? void 0 : scrollToIndex(lastIndex);
787
+ break;
788
+ }
789
+ case " ":
790
+ case "Enter": {
791
+ event.preventDefault();
792
+ onItemSelect == null ? void 0 : onItemSelect(focusedIndex);
793
+ break;
794
+ }
795
+ }
796
+ },
797
+ [totalItems, focusedIndex, onItemSelect, onExitNavigation, scrollToIndex]
798
+ );
799
+ const getItemA11yProps = useCallback(
800
+ (index, customLabel) => {
801
+ const itemNumber = index + 1;
802
+ const defaultLabel = `Item ${itemNumber} of ${totalItems}`;
803
+ return {
804
+ role: "group",
805
+ "aria-roledescription": "slide",
806
+ "aria-label": customLabel ? `${customLabel} (${itemNumber} of ${totalItems})` : defaultLabel,
807
+ tabIndex: index === focusedIndex ? 0 : -1,
808
+ onFocus: () => setFocusedIndex(index)
809
+ };
810
+ },
811
+ [focusedIndex, totalItems]
812
+ );
813
+ return {
814
+ focusedIndex,
815
+ setFocusedIndex,
816
+ handleKeyDown,
817
+ getItemA11yProps
818
+ };
819
+ }
820
+
821
+ // src/ui/carousel/carousel.tokens.ts
822
+ var CarouselTokens = {
823
+ /** Corner radius shape (M3 extraLarge shape: 28dp) */
824
+ containerRadius: 28,
825
+ /** Small item dimension limits (dp) */
826
+ smallItemMin: 40,
827
+ smallItemMax: 56,
828
+ /** Layout defaults (dp) */
829
+ itemSpacing: 8,
830
+ contentPadding: 16,
831
+ verticalPadding: 8,
832
+ /** Interactive state overlays */
833
+ hoverOpacity: 0.08,
834
+ focusOpacity: 0.1,
835
+ pressedOpacity: 0.1,
836
+ disabledOpacity: 0.38,
837
+ /** Focus indicator dimensions */
838
+ focusThickness: 3,
839
+ focusOffset: 2,
840
+ /** Touch target minimum size for accessibility (WCAG 2.1 AAA / M3) */
841
+ minTouchTargetSize: 48,
842
+ /** CSS Custom Property token maps for fallback and runtime injection */
843
+ cssVars: {
844
+ shape: "--carousel-item-shape",
845
+ spacing: "--carousel-item-spacing",
846
+ contentPadding: "--carousel-content-padding",
847
+ verticalPadding: "--carousel-vertical-padding",
848
+ smallMin: "--carousel-small-item-min",
849
+ smallMax: "--carousel-small-item-max",
850
+ hoverOpacity: "--carousel-hover-opacity",
851
+ focusThickness: "--carousel-focus-thickness",
852
+ focusOffset: "--carousel-focus-offset",
853
+ pressedOpacity: "--carousel-pressed-opacity",
854
+ disabledOpacity: "--carousel-disabled-opacity"
855
+ }
856
+ };
857
+
858
+ // src/ui/carousel/hooks/useCarouselKeylines.ts
859
+ function useCarouselKeylines({
860
+ containerWidth,
861
+ preferredItemWidth = 300,
862
+ layout = "multi-browse",
863
+ itemSpacing = CarouselTokens.itemSpacing,
864
+ contentPadding = CarouselTokens.contentPadding,
865
+ totalItems,
866
+ scrollX: _scrollX = 0
867
+ }) {
868
+ return useMemo(() => {
869
+ const safeContainerWidth = Math.max(containerWidth, 100);
870
+ const smallWidth = Math.min(
871
+ Math.max(
872
+ CarouselTokens.smallItemMin,
873
+ Math.round(safeContainerWidth * 0.1)
874
+ ),
875
+ CarouselTokens.smallItemMax
876
+ );
877
+ let largeWidth = preferredItemWidth;
878
+ let mediumWidth = Math.round(preferredItemWidth * 0.65);
879
+ switch (layout) {
880
+ case "hero": {
881
+ const availableWidth = safeContainerWidth - contentPadding * 2 - smallWidth - itemSpacing;
882
+ largeWidth = Math.max(160, availableWidth);
883
+ mediumWidth = largeWidth;
884
+ break;
885
+ }
886
+ case "center-aligned-hero": {
887
+ const availableWidth = safeContainerWidth - contentPadding * 2 - smallWidth * 2 - itemSpacing * 2;
888
+ largeWidth = Math.max(160, availableWidth);
889
+ mediumWidth = largeWidth;
890
+ break;
891
+ }
892
+ case "uncontained":
893
+ case "uncontained-multi-aspect": {
894
+ largeWidth = Math.min(
895
+ preferredItemWidth,
896
+ safeContainerWidth - contentPadding * 2
897
+ );
898
+ mediumWidth = largeWidth;
899
+ break;
900
+ }
901
+ case "full-screen": {
902
+ largeWidth = safeContainerWidth;
903
+ mediumWidth = safeContainerWidth;
904
+ break;
905
+ }
906
+ default: {
907
+ const maxLargeWidth = safeContainerWidth - contentPadding * 2 - smallWidth - itemSpacing;
908
+ largeWidth = Math.min(preferredItemWidth, Math.max(160, maxLargeWidth));
909
+ mediumWidth = Math.max(smallWidth + 16, Math.round(largeWidth * 0.65));
910
+ break;
911
+ }
912
+ }
913
+ const keylines = [];
914
+ if (layout === "hero") {
915
+ const smallMask = Math.max(
916
+ 0,
917
+ Math.min(
918
+ 100,
919
+ Math.round((largeWidth - smallWidth) / largeWidth * 100)
920
+ )
921
+ );
922
+ keylines.push(
923
+ {
924
+ offset: contentPadding,
925
+ width: largeWidth,
926
+ type: "large",
927
+ maskClip: 0
928
+ },
929
+ {
930
+ offset: contentPadding + largeWidth + itemSpacing,
931
+ width: smallWidth,
932
+ type: "small",
933
+ maskClip: smallMask
934
+ }
935
+ );
936
+ } else if (layout === "center-aligned-hero") {
937
+ const smallMask = Math.max(
938
+ 0,
939
+ Math.min(
940
+ 100,
941
+ Math.round((largeWidth - smallWidth) / largeWidth * 100)
942
+ )
943
+ );
944
+ keylines.push(
945
+ {
946
+ offset: contentPadding,
947
+ width: smallWidth,
948
+ type: "small",
949
+ maskClip: smallMask
950
+ },
951
+ {
952
+ offset: contentPadding + smallWidth + itemSpacing,
953
+ width: largeWidth,
954
+ type: "large",
955
+ maskClip: 0
956
+ },
957
+ {
958
+ offset: contentPadding + smallWidth + itemSpacing + largeWidth + itemSpacing,
959
+ width: smallWidth,
960
+ type: "small",
961
+ maskClip: smallMask
962
+ }
963
+ );
964
+ } else if (layout === "multi-browse") {
965
+ const mediumMask = Math.max(
966
+ 0,
967
+ Math.min(
968
+ 100,
969
+ Math.round((largeWidth - mediumWidth) / largeWidth * 100)
970
+ )
971
+ );
972
+ const smallMask = Math.max(
973
+ 0,
974
+ Math.min(
975
+ 100,
976
+ Math.round((largeWidth - smallWidth) / largeWidth * 100)
977
+ )
978
+ );
979
+ const availableWidth = safeContainerWidth - contentPadding * 2;
980
+ const numLarge = Math.max(
981
+ 1,
982
+ Math.floor((availableWidth + itemSpacing) / (largeWidth + itemSpacing))
983
+ );
984
+ let offset = contentPadding;
985
+ for (let k = 0; k < numLarge; k++) {
986
+ keylines.push({
987
+ offset,
988
+ width: largeWidth,
989
+ type: "large",
990
+ maskClip: 0
991
+ });
992
+ offset += largeWidth + itemSpacing;
993
+ }
994
+ keylines.push({
995
+ offset,
996
+ width: mediumWidth,
997
+ type: "medium",
998
+ maskClip: mediumMask
999
+ });
1000
+ offset += mediumWidth + itemSpacing;
1001
+ keylines.push({
1002
+ offset,
1003
+ width: smallWidth,
1004
+ type: "small",
1005
+ maskClip: smallMask
1006
+ });
1007
+ } else {
1008
+ keylines.push({
1009
+ offset: contentPadding,
1010
+ width: largeWidth,
1011
+ type: "large",
1012
+ maskClip: 0
1013
+ });
1014
+ }
1015
+ const getItemRestWidth = (i) => {
1016
+ if (layout === "full-screen") return safeContainerWidth;
1017
+ if (layout === "uncontained") return largeWidth;
1018
+ if (layout === "uncontained-multi-aspect") {
1019
+ const ratios = [1.77, 1.33, 1, 0.56];
1020
+ const ratio = ratios[i % ratios.length];
1021
+ return Math.round(Math.min(largeWidth, 220 * ratio));
1022
+ }
1023
+ if (layout === "hero") return i === 0 ? largeWidth : smallWidth;
1024
+ if (layout === "center-aligned-hero")
1025
+ return i === 0 || i === totalItems - 1 ? smallWidth : largeWidth;
1026
+ const pattern = [largeWidth, largeWidth, mediumWidth, smallWidth];
1027
+ return pattern[i % pattern.length];
1028
+ };
1029
+ const snapPositions = [];
1030
+ let currentOffset = 0;
1031
+ const itemLayoutWidth = layout === "full-screen" ? safeContainerWidth : largeWidth;
1032
+ for (let i = 0; i < totalItems; i++) {
1033
+ snapPositions.push(currentOffset);
1034
+ currentOffset += itemLayoutWidth + itemSpacing;
1035
+ }
1036
+ const getItemWidth = (_index) => {
1037
+ if (layout === "full-screen") return safeContainerWidth;
1038
+ return largeWidth;
1039
+ };
1040
+ const getItemMaskClip = (index) => {
1041
+ if (layout === "full-screen" || layout === "uncontained" || layout === "uncontained-multi-aspect") {
1042
+ return 0;
1043
+ }
1044
+ const itemW = getItemRestWidth(index);
1045
+ if (itemW >= largeWidth || largeWidth <= 0) return 0;
1046
+ return Math.max(
1047
+ 0,
1048
+ Math.min(100, Math.round((largeWidth - itemW) / largeWidth * 100))
1049
+ );
1050
+ };
1051
+ const getItemParallaxOffset = (index) => {
1052
+ const maskClip = getItemMaskClip(index);
1053
+ if (maskClip <= 0) return 0;
1054
+ return calculateParallaxOffset(0, maskClip, largeWidth);
1055
+ };
1056
+ let maxAccumulatedShift = 0;
1057
+ if (layout === "hero") {
1058
+ maxAccumulatedShift = Math.max(
1059
+ 0,
1060
+ (totalItems - 1) * (largeWidth - smallWidth)
1061
+ );
1062
+ } else if (layout === "center-aligned-hero") {
1063
+ maxAccumulatedShift = Math.max(
1064
+ 0,
1065
+ Math.min(totalItems, 2) * (largeWidth - smallWidth)
1066
+ );
1067
+ } else if (layout === "multi-browse") {
1068
+ const availableWidth = safeContainerWidth - contentPadding * 2;
1069
+ const numLarge = Math.max(
1070
+ 1,
1071
+ Math.floor((availableWidth + itemSpacing) / (largeWidth + itemSpacing))
1072
+ );
1073
+ const nonLargeItems = Math.max(0, totalItems - numLarge);
1074
+ if (nonLargeItems > 0) {
1075
+ const mediumClipped = largeWidth - mediumWidth;
1076
+ const smallClipped = largeWidth - smallWidth;
1077
+ const numSmall = Math.max(0, nonLargeItems - 1);
1078
+ maxAccumulatedShift = mediumClipped + numSmall * smallClipped;
1079
+ }
1080
+ }
1081
+ return {
1082
+ largeWidth,
1083
+ mediumWidth,
1084
+ smallWidth,
1085
+ keylines,
1086
+ snapPositions,
1087
+ maxAccumulatedShift,
1088
+ getItemWidth,
1089
+ getItemMaskClip,
1090
+ getItemParallaxOffset
1091
+ };
1092
+ }, [
1093
+ containerWidth,
1094
+ preferredItemWidth,
1095
+ layout,
1096
+ itemSpacing,
1097
+ contentPadding,
1098
+ totalItems
1099
+ ]);
1100
+ }
1101
+ function calculateMaskClipForOffset(itemLeftInViewport, containerWidth, largeWidth, mediumWidth, smallWidth, contentPadding = 16, layout = "multi-browse") {
1102
+ if (layout === "full-screen" || layout === "uncontained" || layout === "uncontained-multi-aspect" || largeWidth <= 0) {
1103
+ return 0;
1104
+ }
1105
+ const mediumMask = Math.max(
1106
+ 0,
1107
+ Math.min(100, (largeWidth - mediumWidth) / largeWidth * 100)
1108
+ );
1109
+ const smallMask = Math.max(
1110
+ 0,
1111
+ Math.min(100, (largeWidth - smallWidth) / largeWidth * 100)
1112
+ );
1113
+ const trailingFocalThreshold = containerWidth - contentPadding - mediumWidth - (largeWidth - mediumWidth);
1114
+ const trailingMediumThreshold = containerWidth - contentPadding - smallWidth;
1115
+ const trailingEndThreshold = containerWidth - contentPadding;
1116
+ const leadingThreshold = contentPadding;
1117
+ if (itemLeftInViewport < leadingThreshold) {
1118
+ const dist = leadingThreshold - itemLeftInViewport;
1119
+ const progress = Math.min(1, Math.max(0, dist / largeWidth));
1120
+ return Math.min(100, Math.max(0, progress * smallMask));
1121
+ }
1122
+ if (itemLeftInViewport > trailingFocalThreshold) {
1123
+ if (itemLeftInViewport < trailingMediumThreshold) {
1124
+ const range2 = Math.max(
1125
+ 1,
1126
+ trailingMediumThreshold - trailingFocalThreshold
1127
+ );
1128
+ const progress2 = Math.min(
1129
+ 1,
1130
+ Math.max(0, (itemLeftInViewport - trailingFocalThreshold) / range2)
1131
+ );
1132
+ return progress2 * mediumMask;
1133
+ }
1134
+ const range = Math.max(1, trailingEndThreshold - trailingMediumThreshold);
1135
+ const progress = Math.min(
1136
+ 1,
1137
+ Math.max(0, (itemLeftInViewport - trailingMediumThreshold) / range)
1138
+ );
1139
+ return mediumMask + progress * (smallMask - mediumMask);
1140
+ }
1141
+ return 0;
1142
+ }
1143
+ function calculateParallaxOffset(_itemLeftInViewport, maskClipPercent, largeWidth) {
1144
+ if (maskClipPercent <= 0 || largeWidth <= 0) return 0;
1145
+ return -Math.round(maskClipPercent / 100 * (largeWidth * 0.2));
1146
+ }
1147
+ function CarouselScrollClient(_a) {
1148
+ var _b = _a, {
1149
+ children,
1150
+ items,
1151
+ renderItem,
1152
+ layout = "multi-browse",
1153
+ preferredItemWidth = 300,
1154
+ itemSpacing = 8,
1155
+ contentPadding = 16,
1156
+ verticalPadding = 8,
1157
+ userScrollEnabled = true,
1158
+ totalItemsCount,
1159
+ className,
1160
+ style
1161
+ } = _b, props = __objRest(_b, [
1162
+ "children",
1163
+ "items",
1164
+ "renderItem",
1165
+ "layout",
1166
+ "preferredItemWidth",
1167
+ "itemSpacing",
1168
+ "contentPadding",
1169
+ "verticalPadding",
1170
+ "userScrollEnabled",
1171
+ "totalItemsCount",
1172
+ "className",
1173
+ "style"
1174
+ ]);
1175
+ const trackRef = React23.useRef(null);
1176
+ const [containerWidth, setContainerWidth] = React23.useState(600);
1177
+ const rafIdRef = React23.useRef(null);
1178
+ const isDraggingRef = React23.useRef(false);
1179
+ const hasMovedRef = React23.useRef(false);
1180
+ const startPosRef = React23.useRef(0);
1181
+ const startScrollRef = React23.useRef(0);
1182
+ const keylines = useCarouselKeylines({
1183
+ containerWidth,
1184
+ preferredItemWidth,
1185
+ layout,
1186
+ itemSpacing,
1187
+ contentPadding,
1188
+ totalItems: totalItemsCount
1189
+ });
1190
+ const handleScroll = React23.useCallback(() => {
1191
+ if (rafIdRef.current !== null) return;
1192
+ rafIdRef.current = requestAnimationFrame(() => {
1193
+ var _a2, _b2;
1194
+ const track = trackRef.current;
1195
+ if (track) {
1196
+ const scrollVal = layout === "full-screen" ? track.scrollTop : track.scrollLeft;
1197
+ track.style.setProperty("--carousel-scroll-left", `${scrollVal}px`);
1198
+ if (layout !== "full-screen") {
1199
+ const prefersReducedMotion = typeof window !== "undefined" && ((_b2 = (_a2 = window.matchMedia) == null ? void 0 : _a2.call(window, "(prefers-reduced-motion: reduce)")) == null ? void 0 : _b2.matches);
1200
+ let accumulatedShift = 0;
1201
+ const items2 = track.children;
1202
+ for (let i = 0; i < items2.length; i++) {
1203
+ const itemEl = items2[i];
1204
+ if (!itemEl || itemEl.getAttribute("role") !== "group") continue;
1205
+ if (prefersReducedMotion) {
1206
+ itemEl.style.clipPath = "none";
1207
+ itemEl.style.transform = "none";
1208
+ const innerContent2 = itemEl.firstElementChild;
1209
+ if (innerContent2) innerContent2.style.transform = "none";
1210
+ continue;
1211
+ }
1212
+ const nativeOffset = itemEl.offsetLeft - scrollVal;
1213
+ const visualOffset = nativeOffset - accumulatedShift;
1214
+ const maskPercent = calculateMaskClipForOffset(
1215
+ visualOffset,
1216
+ containerWidth,
1217
+ keylines.largeWidth,
1218
+ keylines.mediumWidth,
1219
+ keylines.smallWidth,
1220
+ contentPadding,
1221
+ layout
1222
+ );
1223
+ const clippedPixels = maskPercent / 100 * keylines.largeWidth;
1224
+ itemEl.style.transform = accumulatedShift > 0 ? `translateX(${-accumulatedShift}px)` : "none";
1225
+ itemEl.style.clipPath = maskPercent > 0 ? `inset(0px ${maskPercent}% 0px 0px round 28px)` : "none";
1226
+ const innerContent = itemEl.firstElementChild;
1227
+ if (innerContent) {
1228
+ const parallaxX = calculateParallaxOffset(
1229
+ visualOffset,
1230
+ maskPercent,
1231
+ keylines.largeWidth
1232
+ );
1233
+ innerContent.style.transform = parallaxX !== 0 ? `translateX(${parallaxX}px)` : "none";
1234
+ }
1235
+ accumulatedShift += clippedPixels;
1236
+ }
1237
+ }
1238
+ }
1239
+ rafIdRef.current = null;
1240
+ });
1241
+ }, [
1242
+ layout,
1243
+ containerWidth,
1244
+ keylines.largeWidth,
1245
+ keylines.mediumWidth,
1246
+ keylines.smallWidth,
1247
+ contentPadding
1248
+ ]);
1249
+ React23.useEffect(() => {
1250
+ const track = trackRef.current;
1251
+ if (!track) return;
1252
+ const updateWidth = () => {
1253
+ if (track.clientWidth > 0) {
1254
+ setContainerWidth(track.clientWidth);
1255
+ }
1256
+ };
1257
+ updateWidth();
1258
+ const observer = new ResizeObserver(updateWidth);
1259
+ observer.observe(track);
1260
+ return () => observer.disconnect();
1261
+ }, []);
1262
+ React23.useEffect(() => {
1263
+ handleScroll();
1264
+ }, [handleScroll]);
1265
+ React23.useEffect(() => {
1266
+ return () => {
1267
+ if (rafIdRef.current !== null) {
1268
+ cancelAnimationFrame(rafIdRef.current);
1269
+ }
1270
+ };
1271
+ }, []);
1272
+ const handlePointerDown = React23.useCallback(
1273
+ (e) => {
1274
+ var _a2, _b2;
1275
+ if (!userScrollEnabled || e.button !== 0) return;
1276
+ const track = trackRef.current;
1277
+ if (!track) return;
1278
+ isDraggingRef.current = true;
1279
+ hasMovedRef.current = false;
1280
+ startPosRef.current = layout === "full-screen" ? e.clientY : e.clientX;
1281
+ startScrollRef.current = layout === "full-screen" ? track.scrollTop : track.scrollLeft;
1282
+ try {
1283
+ (_b2 = (_a2 = e.target).setPointerCapture) == null ? void 0 : _b2.call(_a2, e.pointerId);
1284
+ } catch (e2) {
1285
+ }
1286
+ },
1287
+ [userScrollEnabled, layout]
1288
+ );
1289
+ const handlePointerMove = React23.useCallback(
1290
+ (e) => {
1291
+ if (!isDraggingRef.current || !trackRef.current) return;
1292
+ const currentPos = layout === "full-screen" ? e.clientY : e.clientX;
1293
+ const delta = currentPos - startPosRef.current;
1294
+ if (Math.abs(delta) > 4) {
1295
+ hasMovedRef.current = true;
1296
+ }
1297
+ if (hasMovedRef.current) {
1298
+ if (layout === "full-screen") {
1299
+ trackRef.current.scrollTop = startScrollRef.current - delta;
1300
+ } else {
1301
+ trackRef.current.scrollLeft = startScrollRef.current - delta;
1302
+ }
1303
+ }
1304
+ },
1305
+ [layout]
1306
+ );
1307
+ const handlePointerUp = React23.useCallback(
1308
+ (e) => {
1309
+ var _a2, _b2;
1310
+ if (!isDraggingRef.current) return;
1311
+ isDraggingRef.current = false;
1312
+ try {
1313
+ (_b2 = (_a2 = e.target).releasePointerCapture) == null ? void 0 : _b2.call(_a2, e.pointerId);
1314
+ } catch (e2) {
1315
+ }
1316
+ },
1317
+ []
1318
+ );
1319
+ const handleClickCapture = React23.useCallback((e) => {
1320
+ if (hasMovedRef.current) {
1321
+ e.stopPropagation();
1322
+ e.preventDefault();
1323
+ hasMovedRef.current = false;
1324
+ }
1325
+ }, []);
1326
+ const scrollToIndex = React23.useCallback(
1327
+ (index) => {
1328
+ const track = trackRef.current;
1329
+ if (!track) return;
1330
+ const itemEl = track.children[index];
1331
+ if (!itemEl) return;
1332
+ const targetPos = Math.max(0, itemEl.offsetLeft - contentPadding);
1333
+ track.scrollTo({
1334
+ left: targetPos,
1335
+ behavior: "smooth"
1336
+ });
1337
+ },
1338
+ [contentPadding]
1339
+ );
1340
+ const { focusedIndex, handleKeyDown, getItemA11yProps } = useCarouselA11y({
1341
+ totalItems: totalItemsCount,
1342
+ scrollToIndex
1343
+ });
1344
+ const isFullScreen = layout === "full-screen";
1345
+ const isHero = layout === "hero" || layout === "center-aligned-hero";
1346
+ const trackClasses = cn(
1347
+ // Base layout & GPU containment
1348
+ "relative box-border select-none [contain:layout_style]",
1349
+ userScrollEnabled && "cursor-grab active:cursor-grabbing",
1350
+ // Scrollbar hide
1351
+ "[scrollbar-width:none] [&::-webkit-scrollbar]:hidden",
1352
+ // Full-screen: vertical snap column
1353
+ isFullScreen ? "flex flex-col flex-1 min-h-0 overflow-x-hidden overflow-y-auto p-0 gap-0 [scroll-snap-type:y_mandatory] [touch-action:pan-y]" : "flex flex-row items-stretch overflow-x-auto overflow-y-hidden [-webkit-overflow-scrolling:touch] [touch-action:pan-x]",
1354
+ // Snap for hero/center-aligned-hero
1355
+ isHero && !isFullScreen && "[scroll-snap-type:x_mandatory]",
1356
+ // Disabled
1357
+ !userScrollEnabled && "overflow-x-hidden pointer-events-none [touch-action:none]",
1358
+ className
1359
+ );
1360
+ const trackStyle = isFullScreen ? __spreadValues({}, style) : __spreadValues({
1361
+ paddingLeft: `${contentPadding}px`,
1362
+ paddingRight: layout === "uncontained" || layout === "uncontained-multi-aspect" ? 0 : `${contentPadding}px`,
1363
+ scrollPaddingLeft: `${contentPadding}px`,
1364
+ scrollPaddingRight: `${contentPadding}px`,
1365
+ paddingTop: `${verticalPadding}px`,
1366
+ paddingBottom: `${verticalPadding}px`,
1367
+ gap: `${itemSpacing}px`
1368
+ }, style);
1369
+ const renderSlides = () => {
1370
+ if (items && renderItem) {
1371
+ return items.map((item, index) => {
1372
+ const itemWidth = keylines.largeWidth;
1373
+ const maskClip = keylines.getItemMaskClip(index);
1374
+ const parallax = keylines.getItemParallaxOffset(index);
1375
+ const a11yProps = getItemA11yProps(index);
1376
+ const itemKey = typeof item === "object" && item !== null && "id" in item ? item.id : typeof item === "object" && item !== null && "key" in item ? item.key : index;
1377
+ return /* @__PURE__ */ jsx(
1378
+ CarouselItem,
1379
+ __spreadProps(__spreadValues({
1380
+ index,
1381
+ totalItems: totalItemsCount,
1382
+ layout,
1383
+ width: itemWidth,
1384
+ minContentWidth: keylines.largeWidth,
1385
+ maskClipPercent: maskClip,
1386
+ parallaxOffset: parallax,
1387
+ isFocused: focusedIndex === index
1388
+ }, a11yProps), {
1389
+ children: renderItem(item, index)
1390
+ }),
1391
+ itemKey
1392
+ );
1393
+ });
1394
+ }
1395
+ return React23.Children.map(children, (child, index) => {
1396
+ if (!React23.isValidElement(child)) return child;
1397
+ const itemWidth = keylines.largeWidth;
1398
+ const maskClip = keylines.getItemMaskClip(index);
1399
+ const parallax = keylines.getItemParallaxOffset(index);
1400
+ const a11yProps = getItemA11yProps(index);
1401
+ const childKey = child.key != null ? child.key : index;
1402
+ return /* @__PURE__ */ jsx(
1403
+ CarouselItem,
1404
+ __spreadProps(__spreadValues({
1405
+ index,
1406
+ totalItems: totalItemsCount,
1407
+ layout,
1408
+ width: itemWidth,
1409
+ minContentWidth: keylines.largeWidth,
1410
+ maskClipPercent: maskClip,
1411
+ parallaxOffset: parallax,
1412
+ isFocused: focusedIndex === index
1413
+ }, a11yProps), {
1414
+ children: child
1415
+ }),
1416
+ childKey
1417
+ );
1418
+ });
1419
+ };
1420
+ return /* @__PURE__ */ jsxs(
1421
+ "section",
1422
+ __spreadProps(__spreadValues({
1423
+ ref: trackRef,
1424
+ "aria-roledescription": "carousel",
1425
+ "aria-label": props["aria-label"] || "Content carousel",
1426
+ tabIndex: 0,
1427
+ className: trackClasses,
1428
+ style: trackStyle,
1429
+ onScroll: handleScroll,
1430
+ onPointerDown: handlePointerDown,
1431
+ onPointerMove: handlePointerMove,
1432
+ onPointerUp: handlePointerUp,
1433
+ onPointerCancel: handlePointerUp,
1434
+ onClickCapture: handleClickCapture,
1435
+ onKeyDown: handleKeyDown
1436
+ }, props), {
1437
+ children: [
1438
+ renderSlides(),
1439
+ !isFullScreen && /* @__PURE__ */ jsx(
1440
+ "div",
1441
+ {
1442
+ "aria-hidden": "true",
1443
+ className: "shrink-0 pointer-events-none",
1444
+ style: {
1445
+ width: 0,
1446
+ marginRight: keylines.maxAccumulatedShift > 0 ? `-${keylines.maxAccumulatedShift}px` : void 0
1447
+ }
1448
+ }
1449
+ )
1450
+ ]
1451
+ })
1452
+ );
1453
+ }
1454
+ function Carousel(_a) {
1455
+ var _b = _a, {
1456
+ children,
1457
+ items,
1458
+ renderItem,
1459
+ layout = "multi-browse",
1460
+ preferredItemWidth = 300,
1461
+ itemSpacing = 8,
1462
+ contentPadding = 16,
1463
+ verticalPadding = 8,
1464
+ isExpanded: controlledExpanded,
1465
+ onShowAllClick,
1466
+ showAllLabel = "Show all",
1467
+ userScrollEnabled = true,
1468
+ className,
1469
+ style
1470
+ } = _b, props = __objRest(_b, [
1471
+ "children",
1472
+ "items",
1473
+ "renderItem",
1474
+ "layout",
1475
+ "preferredItemWidth",
1476
+ "itemSpacing",
1477
+ "contentPadding",
1478
+ "verticalPadding",
1479
+ "isExpanded",
1480
+ "onShowAllClick",
1481
+ "showAllLabel",
1482
+ "userScrollEnabled",
1483
+ "className",
1484
+ "style"
1485
+ ]);
1486
+ const [internalExpanded, setInternalExpanded] = React23.useState(false);
1487
+ const isExpanded = controlledExpanded != null ? controlledExpanded : internalExpanded;
1488
+ const totalItemsCount = React23.useMemo(() => {
1489
+ if (items) return items.length;
1490
+ return React23.Children.count(children);
1491
+ }, [items, children]);
1492
+ const handleShowAllToggle = React23.useCallback(() => {
1493
+ if (onShowAllClick) {
1494
+ onShowAllClick();
1495
+ } else {
1496
+ setInternalExpanded((prev) => !prev);
1497
+ }
1498
+ }, [onShowAllClick]);
1499
+ const isFullScreen = layout === "full-screen";
1500
+ return /* @__PURE__ */ jsxs(
1501
+ "div",
1502
+ {
1503
+ className: cn(
1504
+ "relative w-full flex flex-col gap-3 box-border min-h-0",
1505
+ // Full-screen: propagate height to track
1506
+ isFullScreen && "flex-1",
1507
+ className
1508
+ ),
1509
+ style,
1510
+ children: [
1511
+ !isFullScreen && /* @__PURE__ */ jsxs(
1512
+ "div",
1513
+ {
1514
+ className: "flex items-center justify-between",
1515
+ style: { padding: `0 ${contentPadding}px` },
1516
+ children: [
1517
+ props["aria-label"] && /* @__PURE__ */ jsx("h3", { className: "m-0 text-(length:--md-sys-typescale-title-medium-size,1.125rem) font-medium text-(--md-sys-color-on-surface,currentColor)", children: props["aria-label"] }),
1518
+ /* @__PURE__ */ jsx(
1519
+ "button",
1520
+ {
1521
+ type: "button",
1522
+ className: cn(
1523
+ "inline-flex items-center justify-center min-h-12 min-w-12 px-4 py-2",
1524
+ "rounded-[20px] border border-(--md-sys-color-outline-variant,rgba(121,116,126,0.3))",
1525
+ "bg-transparent text-(--md-sys-color-primary,#6750a4) font-medium text-[0.875rem]",
1526
+ "cursor-pointer outline-none transition-colors duration-200",
1527
+ "hover:bg-(--md-sys-color-surface-container-high,rgba(103,80,164,0.08))",
1528
+ "focus-visible:outline-[3px] focus-visible:outline-(--md-sys-color-secondary,#625b71) focus-visible:outline-offset-2"
1529
+ ),
1530
+ onClick: handleShowAllToggle,
1531
+ "aria-expanded": isExpanded,
1532
+ "aria-label": isExpanded ? "Collapse carousel view" : `${showAllLabel} (${totalItemsCount} items)`,
1533
+ children: isExpanded ? "Show carousel" : showAllLabel
1534
+ }
1535
+ )
1536
+ ]
1537
+ }
1538
+ ),
1539
+ isExpanded ? /* @__PURE__ */ jsx(
1540
+ CarouselGrid,
1541
+ {
1542
+ items,
1543
+ renderItem,
1544
+ preferredItemWidth,
1545
+ children
1546
+ }
1547
+ ) : /* @__PURE__ */ jsx(
1548
+ CarouselScrollClient,
1549
+ __spreadProps(__spreadValues({
1550
+ items,
1551
+ renderItem,
1552
+ layout,
1553
+ preferredItemWidth,
1554
+ itemSpacing,
1555
+ contentPadding,
1556
+ verticalPadding,
1557
+ userScrollEnabled,
1558
+ totalItemsCount
1559
+ }, props), {
1560
+ children
1561
+ })
1562
+ )
1563
+ ]
1564
+ }
1565
+ );
1566
+ }
304
1567
  var SHAPE_KEY_TIMES = "0; 0.14; 0.14; 0.29; 0.29; 0.43; 0.43; 0.57; 0.57; 0.71; 0.71; 0.86; 0.86; 1";
305
1568
  var SHAPE_KEY_SPLINES = [
306
1569
  "0.5 0.2 0 0.8",
@@ -346,11 +1609,11 @@ var ROTATE_KEY_SPLINES = [
346
1609
  var ROTATE_VALUES = "0 24 24; 154 24 24; 309 24 24; 463 24 24; 617 24 24; 771 24 24; 926 24 24; 1080 24 24";
347
1610
  var DETERMINATE_CIRCLE = "M24 7 C34.49 7 41 13.51 41 24 C41 34.49 34.49 41 24 41 C13.51 41 7 34.49 7 24 C7 13.51 13.51 7 24 7 Z";
348
1611
  var DETERMINATE_SOFT_BURST = "M20.9 10.4 21.4 9.5 21.9 8.7 22.5 7.8 23.2 7.2 24.2 7 25.1 7.4 25.7 8.1 26.2 9 26.8 9.8 27.3 10.6 28.1 11.2 29 11.3 30 11 30.9 10.6 31.8 10.3 32.8 9.9 33.7 10 34.5 10.6 34.9 11.5 34.8 12.5 34.8 13.5 34.7 14.5 34.7 15.5 35.2 16.3 36 16.8 37 17.1 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.4 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.5 38.9 26.2 39.6 27 40.2 27.7 40.5 28.7 40.3 29.6 39.5 30.3 38.6 30.6 37.6 30.8 36.7 31 35.7 31.3 35 31.9 34.6 32.8 34.7 33.8 34.8 34.8 34.9 35.8 34.8 36.8 34.3 37.6 33.4 38.1 32.4 38 31.5 37.6 30.6 37.2 29.7 36.9 28.7 36.6 27.8 36.9 27.1 37.6 26.6 38.5 26.1 39.3 25.5 40.2 24.8 40.8 23.8 41 22.9 40.6 22.3 39.9 21.8 39 21.2 38.2 20.7 37.4 19.9 36.8 19 36.7 18 37 17.1 37.4 16.2 37.7 15.2 38.1 14.3 38 13.5 37.4 13.1 36.5 13.2 35.5 13.2 34.5 13.3 33.5 13.3 32.5 12.8 31.7 12 31.2 11 31 10.1 30.7 9.1 30.5 8.2 30.1 7.6 29.3 7.5 28.3 8 27.5 8.7 26.7 9.3 26 9.9 25.2 10.4 24.3 10.3 23.4 9.7 22.5 9.1 21.8 8.4 21 7.8 20.3 7.5 19.3 7.7 18.4 8.5 17.7 9.4 17.4 10.4 17.2 11.3 17 12.3 16.7 13 16.1 13.4 15.2 13.3 14.2 13.2 13.2 13.1 12.2 13.2 11.2 13.7 10.4 14.6 9.9 15.6 10 16.5 10.4 17.4 10.8 18.3 11.1 19.3 11.4 20.2 11.1Z";
349
- var IndeterminateSvg = React18.memo(function IndeterminateSvg2({
1612
+ var IndeterminateSvg = React23.memo(function IndeterminateSvg2({
350
1613
  size
351
1614
  }) {
352
- const [ready, setReady] = React18.useState(false);
353
- React18.useEffect(() => {
1615
+ const [ready, setReady] = React23.useState(false);
1616
+ React23.useEffect(() => {
354
1617
  const raf = requestAnimationFrame(() => setReady(true));
355
1618
  return () => cancelAnimationFrame(raf);
356
1619
  }, []);
@@ -395,7 +1658,7 @@ var IndeterminateSvg = React18.memo(function IndeterminateSvg2({
395
1658
  }
396
1659
  );
397
1660
  });
398
- var DeterminateSvg = React18.memo(function DeterminateSvg2({
1661
+ var DeterminateSvg = React23.memo(function DeterminateSvg2({
399
1662
  size,
400
1663
  progress
401
1664
  }) {
@@ -420,7 +1683,7 @@ var DeterminateSvg = React18.memo(function DeterminateSvg2({
420
1683
  }
421
1684
  );
422
1685
  });
423
- var LoadingIndicator = React18.forwardRef(
1686
+ var LoadingIndicator = React23.forwardRef(
424
1687
  (_a, ref) => {
425
1688
  var _b = _a, {
426
1689
  variant = "uncontained",
@@ -488,7 +1751,7 @@ LoadingIndicator.displayName = "LoadingIndicator";
488
1751
  function easeInOutCubic(x) {
489
1752
  return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;
490
1753
  }
491
- function generateWavyCircularPath(center, radius, amplitude, wavelength) {
1754
+ function generateWavyCircularPath(center, radius, amplitude, wavelength, phase = 0) {
492
1755
  const circumference = 2 * Math.PI * radius;
493
1756
  const numWaves = Math.max(
494
1757
  3,
@@ -496,8 +1759,8 @@ function generateWavyCircularPath(center, radius, amplitude, wavelength) {
496
1759
  );
497
1760
  const steps = numWaves * 4;
498
1761
  const dt = 2 * Math.PI / steps;
499
- const rAt = (t) => radius + amplitude * Math.sin(numWaves * t);
500
- const drAt = (t) => amplitude * numWaves * Math.cos(numWaves * t);
1762
+ const rAt = (t) => radius + amplitude * Math.sin(numWaves * t + phase);
1763
+ const drAt = (t) => amplitude * numWaves * Math.cos(numWaves * t + phase);
501
1764
  const xAt = (t) => center + rAt(t) * Math.cos(t);
502
1765
  const yAt = (t) => center + rAt(t) * Math.sin(t);
503
1766
  const dxAt = (t) => drAt(t) * Math.cos(t) - rAt(t) * Math.sin(t);
@@ -555,22 +1818,25 @@ var ADDITIONAL_ROTATION_EASE_DURATION = 500;
555
1818
  var DEFAULT_MIN_PROGRESS = 0.1;
556
1819
  var DEFAULT_MAX_PROGRESS = 0.8;
557
1820
  var PROGRESS_CYCLE_DURATION = 1500;
558
- var CircularProgress = React18.forwardRef(
1821
+ var CircularProgress = React23.forwardRef(
559
1822
  (_a, ref) => {
560
1823
  var _b = _a, {
561
1824
  value,
562
1825
  size = 48,
563
1826
  trackHeight = 4,
564
1827
  shape = "flat",
1828
+ trackShape = "flat",
565
1829
  amplitude,
566
1830
  wavelength,
567
1831
  gapSize = 4,
1832
+ waveSpeed = 1,
568
1833
  crawlerSpeed = 1,
569
1834
  color,
570
1835
  trackColor,
571
1836
  showTrack = "auto",
572
1837
  minProgress = DEFAULT_MIN_PROGRESS,
573
1838
  maxProgress = DEFAULT_MAX_PROGRESS,
1839
+ determinateAnimation = "md3",
574
1840
  amplitudeRange,
575
1841
  className,
576
1842
  "aria-label": ariaLabel
@@ -579,15 +1845,18 @@ var CircularProgress = React18.forwardRef(
579
1845
  "size",
580
1846
  "trackHeight",
581
1847
  "shape",
1848
+ "trackShape",
582
1849
  "amplitude",
583
1850
  "wavelength",
584
1851
  "gapSize",
1852
+ "waveSpeed",
585
1853
  "crawlerSpeed",
586
1854
  "color",
587
1855
  "trackColor",
588
1856
  "showTrack",
589
1857
  "minProgress",
590
1858
  "maxProgress",
1859
+ "determinateAnimation",
591
1860
  "amplitudeRange",
592
1861
  "className",
593
1862
  "aria-label"
@@ -600,21 +1869,22 @@ var CircularProgress = React18.forwardRef(
600
1869
  const bgTrackColor = trackColor || "var(--md-sys-color-indicator-track)";
601
1870
  const isWavy = shape === "wavy";
602
1871
  const shouldShowIndeterminateTrack = showTrack === "auto" ? isWavy : showTrack;
1872
+ const shouldShowDeterminateTrack = showTrack === "auto" ? true : showTrack;
603
1873
  const BASELINE_SIZE = 48;
604
1874
  const scaleFactor = size / BASELINE_SIZE;
605
- const effectiveAmplitude = React18.useMemo(
1875
+ const effectiveAmplitude = React23.useMemo(
606
1876
  () => amplitude != null ? amplitude : 1.6 * scaleFactor,
607
1877
  [amplitude, scaleFactor]
608
1878
  );
609
- const effectiveWavelength = React18.useMemo(
1879
+ const effectiveWavelength = React23.useMemo(
610
1880
  () => wavelength != null ? wavelength : 15 * scaleFactor,
611
1881
  [wavelength, scaleFactor]
612
1882
  );
613
- const resolvedAmplitudeRange = React18.useMemo(
1883
+ const resolvedAmplitudeRange = React23.useMemo(
614
1884
  () => amplitudeRange != null ? amplitudeRange : [0, effectiveAmplitude],
615
1885
  [amplitudeRange, effectiveAmplitude]
616
1886
  );
617
- const wavyActivePath = React18.useMemo(
1887
+ const wavyActivePath = React23.useMemo(
618
1888
  () => isWavy ? generateWavyCircularPath(
619
1889
  center,
620
1890
  radius,
@@ -623,8 +1893,8 @@ var CircularProgress = React18.forwardRef(
623
1893
  ) : null,
624
1894
  [isWavy, center, radius, effectiveAmplitude, effectiveWavelength]
625
1895
  );
626
- const circumference = React18.useMemo(() => 2 * Math.PI * radius, [radius]);
627
- const gapForTrack = React18.useMemo(
1896
+ const circumference = React23.useMemo(() => 2 * Math.PI * radius, [radius]);
1897
+ const gapForTrack = React23.useMemo(
628
1898
  () => (gapSize + trackHeight) / circumference,
629
1899
  [gapSize, trackHeight, circumference]
630
1900
  );
@@ -632,19 +1902,50 @@ var CircularProgress = React18.forwardRef(
632
1902
  const trackOffset = isDeterminate ? activeAngularFraction + gapForTrack : 0;
633
1903
  const trackLength = isDeterminate ? Math.max(1e-3, 1 - activeAngularFraction - 2 * gapForTrack) : 1;
634
1904
  const ActiveCircleElem = m.circle;
635
- const ActivePathElem = m.path;
636
- const indeterminateSvgRef = React18.useRef(null);
637
- const indeterminateTrackRef = React18.useRef(null);
638
- const indeterminateActiveRef = React18.useRef(null);
639
- const indeterminateWavyTrackPathRef = React18.useRef(null);
640
- const indeterminateWavyActivePathRef = React18.useRef(null);
641
- const cachedPathLengthRef = React18.useRef(0);
642
- React18.useLayoutEffect(() => {
1905
+ const indeterminateSvgRef = React23.useRef(null);
1906
+ const indeterminateTrackRef = React23.useRef(null);
1907
+ const indeterminateActiveRef = React23.useRef(null);
1908
+ const indeterminateWavyTrackPathRef = React23.useRef(null);
1909
+ const indeterminateWavyActivePathRef = React23.useRef(null);
1910
+ const determinateWavyActivePathRef = React23.useRef(null);
1911
+ const determinateWavyTrackPathRef = React23.useRef(null);
1912
+ const cachedPathLengthRef = React23.useRef(0);
1913
+ const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 0);
1914
+ const amplitudeMV = useMotionValue(isWavy ? effectiveAmplitude : 0);
1915
+ React23.useEffect(() => {
1916
+ if (isDeterminate) {
1917
+ animate(fractionMV, clampedValue / 100, {
1918
+ duration: 0.4,
1919
+ ease: [0.2, 0, 0, 1]
1920
+ });
1921
+ }
1922
+ }, [clampedValue, isDeterminate, fractionMV]);
1923
+ React23.useEffect(() => {
1924
+ if (!isDeterminate || !isWavy) return;
1925
+ const fraction = clampedValue / 100;
1926
+ let targetAmp = effectiveAmplitude;
1927
+ if (determinateAnimation === "md3") {
1928
+ targetAmp = fraction <= 0.1 || fraction >= 0.95 ? 0 : effectiveAmplitude;
1929
+ }
1930
+ animate(amplitudeMV, targetAmp, {
1931
+ type: "spring",
1932
+ bounce: 0,
1933
+ duration: 0.5
1934
+ });
1935
+ }, [
1936
+ clampedValue,
1937
+ isDeterminate,
1938
+ isWavy,
1939
+ effectiveAmplitude,
1940
+ amplitudeMV,
1941
+ determinateAnimation
1942
+ ]);
1943
+ React23.useLayoutEffect(() => {
643
1944
  if (!isWavy || !wavyActivePath) {
644
1945
  cachedPathLengthRef.current = circumference;
645
1946
  return;
646
1947
  }
647
- const el = indeterminateActiveRef.current;
1948
+ const el = indeterminateActiveRef.current || determinateWavyActivePathRef.current;
648
1949
  if (el && "getTotalLength" in el) {
649
1950
  try {
650
1951
  const len = el.getTotalLength();
@@ -658,7 +1959,65 @@ var CircularProgress = React18.forwardRef(
658
1959
  cachedPathLengthRef.current = circumference;
659
1960
  }, [isWavy, circumference, wavyActivePath]);
660
1961
  useAnimationFrame((time) => {
661
- if (isDeterminate) return;
1962
+ const safeWaveSpeed = Math.max(0.1, waveSpeed);
1963
+ const wavePhase = time / 1e3 * safeWaveSpeed * 2 * Math.PI;
1964
+ if (isDeterminate) {
1965
+ if (isWavy) {
1966
+ const currentAmp = amplitudeMV.get();
1967
+ const dynamicPath = generateWavyCircularPath(
1968
+ center,
1969
+ radius,
1970
+ currentAmp,
1971
+ effectiveWavelength,
1972
+ wavePhase
1973
+ );
1974
+ if (determinateWavyActivePathRef.current) {
1975
+ determinateWavyActivePathRef.current.setAttribute("d", dynamicPath);
1976
+ }
1977
+ if (trackShape === "wavy" && determinateWavyTrackPathRef.current) {
1978
+ determinateWavyTrackPathRef.current.setAttribute("d", dynamicPath);
1979
+ }
1980
+ const pathEl = determinateWavyActivePathRef.current;
1981
+ let totalLen = cachedPathLengthRef.current || circumference;
1982
+ if (pathEl) {
1983
+ try {
1984
+ const len = pathEl.getTotalLength();
1985
+ if (len > 0) totalLen = len;
1986
+ } catch (e) {
1987
+ }
1988
+ }
1989
+ const activeFrac = Math.max(0, Math.min(1, fractionMV.get()));
1990
+ const activeLen = totalLen * activeFrac;
1991
+ if (determinateWavyActivePathRef.current) {
1992
+ determinateWavyActivePathRef.current.setAttribute(
1993
+ "stroke-dasharray",
1994
+ `${activeLen} ${totalLen}`
1995
+ );
1996
+ determinateWavyActivePathRef.current.setAttribute(
1997
+ "stroke-dashoffset",
1998
+ "0"
1999
+ );
2000
+ }
2001
+ if (shouldShowDeterminateTrack && trackShape === "wavy" && determinateWavyTrackPathRef.current) {
2002
+ const gapFrac = (gapSize + trackHeight) / totalLen;
2003
+ const trackStartFrac = activeFrac + gapFrac;
2004
+ const trackLen = Math.max(
2005
+ 1e-3,
2006
+ totalLen * (1 - activeFrac - 2 * gapFrac)
2007
+ );
2008
+ const trackOff = -totalLen * trackStartFrac;
2009
+ determinateWavyTrackPathRef.current.setAttribute(
2010
+ "stroke-dasharray",
2011
+ `${trackLen} ${totalLen}`
2012
+ );
2013
+ determinateWavyTrackPathRef.current.setAttribute(
2014
+ "stroke-dashoffset",
2015
+ `${trackOff}`
2016
+ );
2017
+ }
2018
+ }
2019
+ return;
2020
+ }
662
2021
  const safeCrawlerSpeed = Math.max(0.1, crawlerSpeed);
663
2022
  const scaledTime = time * safeCrawlerSpeed;
664
2023
  const globalCycle = scaledTime % GLOBAL_ROTATION_DURATION;
@@ -693,7 +2052,8 @@ var CircularProgress = React18.forwardRef(
693
2052
  center,
694
2053
  radius,
695
2054
  currentAmplitude,
696
- effectiveWavelength
2055
+ effectiveWavelength,
2056
+ wavePhase
697
2057
  );
698
2058
  if (indeterminateWavyActivePathRef.current) {
699
2059
  indeterminateWavyActivePathRef.current.setAttribute("d", dynamicPath);
@@ -788,7 +2148,7 @@ var CircularProgress = React18.forwardRef(
788
2148
  style: { width: size, height: size }
789
2149
  }, restProps), {
790
2150
  children: /* @__PURE__ */ jsxs(LazyMotion, { features: domMax, strict: true, children: [
791
- /* @__PURE__ */ jsxs(
2151
+ /* @__PURE__ */ jsx(
792
2152
  "svg",
793
2153
  {
794
2154
  width: size,
@@ -796,8 +2156,18 @@ var CircularProgress = React18.forwardRef(
796
2156
  viewBox: `0 0 ${size} ${size}`,
797
2157
  "aria-hidden": "true",
798
2158
  style: { transform: "rotate(-90deg)", overflow: "visible" },
799
- children: [
800
- isDeterminate ? /* @__PURE__ */ jsx(
2159
+ children: isDeterminate ? isWavy ? /* @__PURE__ */ jsxs(Fragment, { children: [
2160
+ shouldShowDeterminateTrack && (trackShape === "wavy" ? /* @__PURE__ */ jsx(
2161
+ "path",
2162
+ {
2163
+ ref: determinateWavyTrackPathRef,
2164
+ d: wavyActivePath != null ? wavyActivePath : "",
2165
+ fill: "none",
2166
+ stroke: bgTrackColor,
2167
+ strokeWidth: trackHeight,
2168
+ strokeLinecap: "round"
2169
+ }
2170
+ ) : /* @__PURE__ */ jsx(
801
2171
  m.circle,
802
2172
  {
803
2173
  cx: center,
@@ -806,28 +2176,52 @@ var CircularProgress = React18.forwardRef(
806
2176
  fill: "none",
807
2177
  stroke: bgTrackColor,
808
2178
  strokeWidth: trackHeight,
809
- initial: { pathLength: trackLength, pathOffset: trackOffset },
810
- animate: { pathLength: trackLength, pathOffset: trackOffset },
2179
+ initial: {
2180
+ pathLength: trackLength,
2181
+ pathOffset: trackOffset
2182
+ },
2183
+ animate: {
2184
+ pathLength: trackLength,
2185
+ pathOffset: trackOffset
2186
+ },
811
2187
  transition: { duration: 0.4, ease: [0.2, 0, 0, 1] },
812
2188
  strokeLinecap: "round"
813
2189
  }
814
- ) : null,
815
- isDeterminate && (isWavy ? /* @__PURE__ */ jsx(
816
- ActivePathElem,
2190
+ )),
2191
+ /* @__PURE__ */ jsx(
2192
+ "path",
817
2193
  {
2194
+ ref: determinateWavyActivePathRef,
818
2195
  d: wavyActivePath != null ? wavyActivePath : "",
819
2196
  fill: "none",
820
2197
  stroke: activeColor,
821
2198
  strokeWidth: trackHeight,
822
- strokeLinecap: "round",
823
- initial: { pathLength: 0 },
824
- animate: { pathLength: clampedValue / 100 },
825
- transition: {
826
- duration: 0.4,
827
- ease: [0.2, 0, 0, 1]
828
- }
2199
+ strokeLinecap: "round"
829
2200
  }
830
- ) : /* @__PURE__ */ jsx(
2201
+ )
2202
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2203
+ /* @__PURE__ */ jsx(
2204
+ m.circle,
2205
+ {
2206
+ cx: center,
2207
+ cy: center,
2208
+ r: radius,
2209
+ fill: "none",
2210
+ stroke: bgTrackColor,
2211
+ strokeWidth: trackHeight,
2212
+ initial: {
2213
+ pathLength: trackLength,
2214
+ pathOffset: trackOffset
2215
+ },
2216
+ animate: {
2217
+ pathLength: trackLength,
2218
+ pathOffset: trackOffset
2219
+ },
2220
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] },
2221
+ strokeLinecap: "round"
2222
+ }
2223
+ ),
2224
+ /* @__PURE__ */ jsx(
831
2225
  ActiveCircleElem,
832
2226
  {
833
2227
  cx: center,
@@ -844,8 +2238,8 @@ var CircularProgress = React18.forwardRef(
844
2238
  ease: [0.2, 0, 0, 1]
845
2239
  }
846
2240
  }
847
- ))
848
- ]
2241
+ )
2242
+ ] }) : null
849
2243
  }
850
2244
  ),
851
2245
  !isDeterminate && /* @__PURE__ */ jsx(
@@ -923,9 +2317,9 @@ var CircularProgress = React18.forwardRef(
923
2317
  );
924
2318
  CircularProgress.displayName = "CircularProgress";
925
2319
  function useContainerWidth() {
926
- const [width, setWidth] = React18.useState(0);
927
- const observerRef = React18.useRef(null);
928
- const ref = React18.useCallback((node) => {
2320
+ const [width, setWidth] = React23.useState(0);
2321
+ const observerRef = React23.useRef(null);
2322
+ const ref = React23.useCallback((node) => {
929
2323
  if (observerRef.current) {
930
2324
  observerRef.current.disconnect();
931
2325
  observerRef.current = null;
@@ -939,7 +2333,7 @@ function useContainerWidth() {
939
2333
  observerRef.current = obs;
940
2334
  }
941
2335
  }, []);
942
- React18.useEffect(() => {
2336
+ React23.useEffect(() => {
943
2337
  return () => {
944
2338
  if (observerRef.current) {
945
2339
  observerRef.current.disconnect();
@@ -949,7 +2343,7 @@ function useContainerWidth() {
949
2343
  return [ref, width];
950
2344
  }
951
2345
  function useMergedRef(...refs) {
952
- return React18.useCallback(
2346
+ return React23.useCallback(
953
2347
  (node) => {
954
2348
  for (const ref of refs) {
955
2349
  if (typeof ref === "function") {
@@ -963,7 +2357,7 @@ function useMergedRef(...refs) {
963
2357
  [refs]
964
2358
  );
965
2359
  }
966
- var FlatLinearTrack = React18.memo(function FlatLinearTrack2({
2360
+ var FlatLinearTrack = React23.memo(function FlatLinearTrack2({
967
2361
  trackHeight,
968
2362
  activeColor,
969
2363
  trackColor,
@@ -1039,7 +2433,7 @@ var FlatLinearTrack = React18.memo(function FlatLinearTrack2({
1039
2433
  }
1040
2434
  );
1041
2435
  });
1042
- var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
2436
+ var WavyLinearTrack = React23.memo(function WavyLinearTrack2({
1043
2437
  trackHeight,
1044
2438
  svgHeight,
1045
2439
  amplitude,
@@ -1058,13 +2452,13 @@ var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
1058
2452
  }) {
1059
2453
  const isDeterminate = typeof value === "number";
1060
2454
  const clampedValue = isDeterminate ? Math.max(0, Math.min(100, value)) : 100;
1061
- const titleId = React18.useId();
2455
+ const titleId = React23.useId();
1062
2456
  const [containerRef, width] = useContainerWidth();
1063
- const activePathRef = React18.useRef(null);
1064
- const trackPathRef = React18.useRef(null);
2457
+ const activePathRef = React23.useRef(null);
2458
+ const trackPathRef = React23.useRef(null);
1065
2459
  const amplitudeMV = useMotionValue(amplitude);
1066
2460
  const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 1);
1067
- React18.useEffect(() => {
2461
+ React23.useEffect(() => {
1068
2462
  if (isDeterminate) {
1069
2463
  const fraction = clampedValue / 100;
1070
2464
  let targetAmp = amplitude;
@@ -1252,7 +2646,7 @@ var WavyLinearTrack = React18.memo(function WavyLinearTrack2({
1252
2646
  }
1253
2647
  );
1254
2648
  });
1255
- var LinearProgress = React18.forwardRef(
2649
+ var LinearProgress = React23.forwardRef(
1256
2650
  (_a, ref) => {
1257
2651
  var _b = _a, {
1258
2652
  value,
@@ -1293,10 +2687,10 @@ var LinearProgress = React18.forwardRef(
1293
2687
  ]);
1294
2688
  const isDeterminate = value !== void 0;
1295
2689
  const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
1296
- const containerRef = React18.useRef(null);
2690
+ const containerRef = React23.useRef(null);
1297
2691
  const mergedRef = useMergedRef(ref, containerRef);
1298
- const [isRtl, setIsRtl] = React18.useState(false);
1299
- React18.useEffect(() => {
2692
+ const [isRtl, setIsRtl] = React23.useState(false);
2693
+ React23.useEffect(() => {
1300
2694
  if (containerRef.current) {
1301
2695
  const dir = getComputedStyle(containerRef.current).direction;
1302
2696
  setIsRtl(dir === "rtl");
@@ -1304,16 +2698,16 @@ var LinearProgress = React18.forwardRef(
1304
2698
  }, []);
1305
2699
  const resolvedTrackShape = trackShape != null ? trackShape : shape;
1306
2700
  const isWavy = shape === "wavy" || resolvedTrackShape === "wavy";
1307
- const effectiveAmplitude = React18.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
1308
- const svgHeight = React18.useMemo(
2701
+ const effectiveAmplitude = React23.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
2702
+ const svgHeight = React23.useMemo(
1309
2703
  () => isWavy ? trackHeight + effectiveAmplitude * 2 : trackHeight,
1310
2704
  [isWavy, trackHeight, effectiveAmplitude]
1311
2705
  );
1312
- const shouldShowStop = React18.useMemo(
2706
+ const shouldShowStop = React23.useMemo(
1313
2707
  () => isDeterminate && resolvedTrackShape === "flat" && showStopIndicator !== false,
1314
2708
  [isDeterminate, resolvedTrackShape, showStopIndicator]
1315
2709
  );
1316
- const stopSize = React18.useMemo(
2710
+ const stopSize = React23.useMemo(
1317
2711
  () => Math.max(2, trackHeight > 4 ? 4 : trackHeight / 2),
1318
2712
  [trackHeight]
1319
2713
  );
@@ -1388,7 +2782,7 @@ var LinearProgress = React18.forwardRef(
1388
2782
  }
1389
2783
  );
1390
2784
  LinearProgress.displayName = "LinearProgress";
1391
- var ProgressIndicator = React18.forwardRef((props, ref) => {
2785
+ var ProgressIndicator = React23.forwardRef((props, ref) => {
1392
2786
  if (props.variant === "circular") {
1393
2787
  return /* @__PURE__ */ jsx(CircularProgress, __spreadValues({ ref }, props));
1394
2788
  }
@@ -1642,7 +3036,7 @@ function AnimatedIconSlot({
1642
3036
  }
1643
3037
  );
1644
3038
  }
1645
- var ButtonComponent = React18.forwardRef(
3039
+ var ButtonComponent = React23.forwardRef(
1646
3040
  (_a, ref) => {
1647
3041
  var _b = _a, {
1648
3042
  className,
@@ -1708,9 +3102,9 @@ var ButtonComponent = React18.forwardRef(
1708
3102
  borderWidth: outlineWidth != null ? outlineWidth : colorStyle === "outlined" ? sizeTokens.outlineWidth : 0,
1709
3103
  borderStyle: colorStyle === "outlined" ? "solid" : void 0
1710
3104
  }, style);
1711
- const labelText = React18.useMemo(() => {
3105
+ const labelText = React23.useMemo(() => {
1712
3106
  if (asChild) {
1713
- const child = React18.Children.only(children);
3107
+ const child = React23.Children.only(children);
1714
3108
  return child.props.children;
1715
3109
  }
1716
3110
  return children;
@@ -1718,8 +3112,8 @@ var ButtonComponent = React18.forwardRef(
1718
3112
  const computedAriaLabel = ariaLabelProp || (typeof children === "string" ? children : void 0);
1719
3113
  const needsTouchTarget = size === "xs" || size === "sm";
1720
3114
  const motionRadius = useMotionValue(animateRadius);
1721
- const asChildRef = React18.useRef(null);
1722
- const mergedRef = React18.useCallback(
3115
+ const asChildRef = React23.useRef(null);
3116
+ const mergedRef = React23.useCallback(
1723
3117
  (node) => {
1724
3118
  asChildRef.current = node;
1725
3119
  if (typeof ref === "function") ref(node);
@@ -1728,14 +3122,14 @@ var ButtonComponent = React18.forwardRef(
1728
3122
  },
1729
3123
  [ref]
1730
3124
  );
1731
- React18.useEffect(() => {
3125
+ React23.useEffect(() => {
1732
3126
  if (!asChild) return;
1733
3127
  return motionRadius.on("change", (v) => {
1734
3128
  if (asChildRef.current)
1735
3129
  asChildRef.current.style.borderRadius = `${v}px`;
1736
3130
  });
1737
3131
  }, [motionRadius, asChild]);
1738
- React18.useEffect(() => {
3132
+ React23.useEffect(() => {
1739
3133
  if (!asChild) return;
1740
3134
  const controls = springAnimate(motionRadius, animateRadius);
1741
3135
  return () => controls.stop();
@@ -1743,14 +3137,14 @@ var ButtonComponent = React18.forwardRef(
1743
3137
  const { ripples, onPointerDown, removeRipple } = useRippleState({
1744
3138
  disabled: loading
1745
3139
  });
1746
- const handleClick = React18.useCallback(
3140
+ const handleClick = React23.useCallback(
1747
3141
  (e) => {
1748
3142
  if (loading) return e.preventDefault();
1749
3143
  onClick == null ? void 0 : onClick(e);
1750
3144
  },
1751
3145
  [loading, onClick]
1752
3146
  );
1753
- const handleKeyDown = React18.useCallback(
3147
+ const handleKeyDown = React23.useCallback(
1754
3148
  (e) => {
1755
3149
  if (loading) return;
1756
3150
  if (onClick && (e.key === "Enter" || e.key === " ")) {
@@ -1829,17 +3223,17 @@ var ButtonComponent = React18.forwardRef(
1829
3223
  isSelected && selectedIcon ? "selected-icon" : "icon"
1830
3224
  ) })
1831
3225
  ] });
1832
- const handleAsChildPointerDown = React18.useCallback(
3226
+ const handleAsChildPointerDown = React23.useCallback(
1833
3227
  (e) => {
1834
3228
  springAnimate(motionRadius, pressedRadius);
1835
3229
  onPointerDown == null ? void 0 : onPointerDown(e);
1836
3230
  },
1837
3231
  [motionRadius, pressedRadius, onPointerDown]
1838
3232
  );
1839
- const handleAsChildPointerUp = React18.useCallback(() => {
3233
+ const handleAsChildPointerUp = React23.useCallback(() => {
1840
3234
  springAnimate(motionRadius, animateRadius);
1841
3235
  }, [motionRadius, animateRadius]);
1842
- const handlePointerDown = React18.useCallback(
3236
+ const handlePointerDown = React23.useCallback(
1843
3237
  (e) => {
1844
3238
  onPointerDown(e);
1845
3239
  },
@@ -1849,7 +3243,7 @@ var ButtonComponent = React18.forwardRef(
1849
3243
  const strippedProps = __spreadValues({}, restProps);
1850
3244
  for (const key of MOTION_PROP_KEYS) delete strippedProps[key];
1851
3245
  const htmlProps = strippedProps;
1852
- const child = React18.Children.only(children);
3246
+ const child = React23.Children.only(children);
1853
3247
  return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(
1854
3248
  Slot,
1855
3249
  __spreadProps(__spreadValues({
@@ -1866,7 +3260,7 @@ var ButtonComponent = React18.forwardRef(
1866
3260
  }),
1867
3261
  className: buttonClassName
1868
3262
  }, htmlProps), {
1869
- children: React18.cloneElement(child, { children: innerContent })
3263
+ children: React23.cloneElement(child, { children: innerContent })
1870
3264
  })
1871
3265
  ) });
1872
3266
  }
@@ -1894,13 +3288,13 @@ var ButtonComponent = React18.forwardRef(
1894
3288
  }
1895
3289
  );
1896
3290
  ButtonComponent.displayName = "Button";
1897
- var Button = React18.memo(ButtonComponent);
3291
+ var Button = React23.memo(ButtonComponent);
1898
3292
  var VARIANT_FONT = {
1899
3293
  outlined: "'Material Symbols Outlined'",
1900
3294
  rounded: "'Material Symbols Rounded'",
1901
3295
  sharp: "'Material Symbols Sharp'"
1902
3296
  };
1903
- var IconComponent = React18.forwardRef(
3297
+ var IconComponent = React23.forwardRef(
1904
3298
  (_a, ref) => {
1905
3299
  var _b = _a, {
1906
3300
  name,
@@ -1966,8 +3360,8 @@ var IconComponent = React18.forwardRef(
1966
3360
  }
1967
3361
  );
1968
3362
  IconComponent.displayName = "Icon";
1969
- var Icon = React18.memo(IconComponent);
1970
- var ScrollArea = React18.forwardRef(
3363
+ var Icon = React23.memo(IconComponent);
3364
+ var ScrollArea = React23.forwardRef(
1971
3365
  (_a, ref) => {
1972
3366
  var _b = _a, {
1973
3367
  className,
@@ -1988,15 +3382,15 @@ var ScrollArea = React18.forwardRef(
1988
3382
  "viewportRef",
1989
3383
  "viewportProps"
1990
3384
  ]);
1991
- const [isTouchDevice, setIsTouchDevice] = React18.useState(false);
1992
- React18.useEffect(() => {
3385
+ const [isTouchDevice, setIsTouchDevice] = React23.useState(false);
3386
+ React23.useEffect(() => {
1993
3387
  if (typeof window !== "undefined") {
1994
3388
  setIsTouchDevice(
1995
3389
  "ontouchstart" in window || navigator.maxTouchPoints > 0
1996
3390
  );
1997
3391
  }
1998
3392
  }, []);
1999
- const resolvedType = React18.useMemo(() => {
3393
+ const resolvedType = React23.useMemo(() => {
2000
3394
  if (type === "hover" && isTouchDevice) {
2001
3395
  return "scroll";
2002
3396
  }
@@ -2047,7 +3441,7 @@ var ScrollArea = React18.forwardRef(
2047
3441
  }
2048
3442
  );
2049
3443
  ScrollArea.displayName = "ScrollArea";
2050
- var ScrollAreaScrollbar = React18.forwardRef((_a, ref) => {
3444
+ var ScrollAreaScrollbar = React23.forwardRef((_a, ref) => {
2051
3445
  var _b = _a, { className, orientation = "vertical" } = _b, props = __objRest(_b, ["className", "orientation"]);
2052
3446
  return /* @__PURE__ */ jsx(
2053
3447
  RadixScrollArea.Scrollbar,
@@ -2077,7 +3471,7 @@ var ScrollAreaScrollbar = React18.forwardRef((_a, ref) => {
2077
3471
  );
2078
3472
  });
2079
3473
  ScrollAreaScrollbar.displayName = RadixScrollArea.Scrollbar.displayName;
2080
- var ScrollAreaCorner = React18.forwardRef((_a, ref) => {
3474
+ var ScrollAreaCorner = React23.forwardRef((_a, ref) => {
2081
3475
  var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
2082
3476
  return /* @__PURE__ */ jsx(
2083
3477
  RadixScrollArea.Corner,
@@ -2273,7 +3667,7 @@ function buildWavePath(startX, endX, amplitude = 2, wavelength = 32, yCenter = 4
2273
3667
  }
2274
3668
  return d;
2275
3669
  }
2276
- var DividerImpl = React18.forwardRef(
3670
+ var DividerImpl = React23.forwardRef(
2277
3671
  (_a, ref) => {
2278
3672
  var _b = _a, {
2279
3673
  variant = "full-bleed",
@@ -2282,7 +3676,7 @@ var DividerImpl = React18.forwardRef(
2282
3676
  insetStart = "standard",
2283
3677
  waveConfig,
2284
3678
  decorative = false,
2285
- animate: animate3 = true,
3679
+ animate: animate4 = true,
2286
3680
  className,
2287
3681
  style
2288
3682
  } = _b, props = __objRest(_b, [
@@ -2298,7 +3692,7 @@ var DividerImpl = React18.forwardRef(
2298
3692
  ]);
2299
3693
  var _a2, _b2, _c;
2300
3694
  const reducedMotion = useReducedMotion();
2301
- const shouldAnimate = animate3 && !reducedMotion;
3695
+ const shouldAnimate = animate4 && !reducedMotion;
2302
3696
  const effectiveShape = shape === "wavy" && orientation === "vertical" ? "flat" : shape;
2303
3697
  if (shape === "wavy" && orientation === "vertical") {
2304
3698
  console.warn(
@@ -2393,9 +3787,9 @@ var DividerImpl = React18.forwardRef(
2393
3787
  }
2394
3788
  );
2395
3789
  DividerImpl.displayName = "Divider";
2396
- var Divider = React18.memo(DividerImpl);
2397
- var ListContext = React18.createContext(null);
2398
- var useListContext = () => React18.useContext(ListContext);
3790
+ var Divider = React23.memo(DividerImpl);
3791
+ var ListContext = React23.createContext(null);
3792
+ var useListContext = () => React23.useContext(ListContext);
2399
3793
  var LIST_TOKENS = {
2400
3794
  oneLineHeight: 56,
2401
3795
  twoLineHeight: 72,
@@ -2460,9 +3854,9 @@ function resolveItemId(item) {
2460
3854
  return String(item);
2461
3855
  }
2462
3856
  function isListItem(child) {
2463
- return React18.isValidElement(child) && child.props != null && typeof child.props === "object" && "value" in child.props;
3857
+ return React23.isValidElement(child) && child.props != null && typeof child.props === "object" && "value" in child.props;
2464
3858
  }
2465
- var ListImpl = React18.forwardRef(
3859
+ var ListImpl = React23.forwardRef(
2466
3860
  (_a, ref) => {
2467
3861
  var _b = _a, {
2468
3862
  className,
@@ -2493,12 +3887,12 @@ var ListImpl = React18.forwardRef(
2493
3887
  "innerRadius",
2494
3888
  "children"
2495
3889
  ]);
2496
- const listRef = React18.useRef(null);
2497
- const [draggedOrder, setDraggedOrder] = React18.useState(
3890
+ const listRef = React23.useRef(null);
3891
+ const [draggedOrder, setDraggedOrder] = React23.useState(
2498
3892
  null
2499
3893
  );
2500
- React18.useImperativeHandle(ref, () => listRef.current);
2501
- const [selectedState, setSelectedState] = React18.useState(
3894
+ React23.useImperativeHandle(ref, () => listRef.current);
3895
+ const [selectedState, setSelectedState] = React23.useState(
2502
3896
  () => {
2503
3897
  var _a2;
2504
3898
  const initialValue = (_a2 = value != null ? value : defaultValue) != null ? _a2 : [];
@@ -2508,13 +3902,13 @@ var ListImpl = React18.forwardRef(
2508
3902
  }
2509
3903
  );
2510
3904
  const isControlled = value !== void 0;
2511
- const selectedValues = React18.useMemo(() => {
3905
+ const selectedValues = React23.useMemo(() => {
2512
3906
  if (isControlled) {
2513
3907
  return new Set(Array.isArray(value) ? value : value ? [value] : []);
2514
3908
  }
2515
3909
  return selectedState;
2516
3910
  }, [isControlled, value, selectedState]);
2517
- const onItemChange = React18.useCallback(
3911
+ const onItemChange = React23.useCallback(
2518
3912
  (itemValue, selected) => {
2519
3913
  const nextSet = new Set(selectedValues);
2520
3914
  if (selectionMode === "single-select") {
@@ -2546,11 +3940,11 @@ var ListImpl = React18.forwardRef(
2546
3940
  coordinateGetter: sortableKeyboardCoordinates
2547
3941
  })
2548
3942
  );
2549
- const itemIds = React18.useMemo(
3943
+ const itemIds = React23.useMemo(
2550
3944
  () => items ? items.map(resolveItemId) : [],
2551
3945
  [items]
2552
3946
  );
2553
- const currentOrder = React18.useMemo(
3947
+ const currentOrder = React23.useMemo(
2554
3948
  () => draggedOrder || itemIds,
2555
3949
  [draggedOrder, itemIds]
2556
3950
  );
@@ -2610,20 +4004,20 @@ var ListImpl = React18.forwardRef(
2610
4004
  }
2611
4005
  (_a2 = focusableItems[nextIndex]) == null ? void 0 : _a2.focus();
2612
4006
  };
2613
- const childrenArray = React18.Children.toArray(children);
4007
+ const childrenArray = React23.Children.toArray(children);
2614
4008
  const listItemCount = childrenArray.filter(isListItem).length;
2615
4009
  let currentListItemIndex = 0;
2616
- const processedChildren = React18.Children.map(children, (child) => {
4010
+ const processedChildren = React23.Children.map(children, (child) => {
2617
4011
  if (!isListItem(child)) return child;
2618
4012
  const childValue = child.props.value;
2619
4013
  const index = reorderable && currentOrder.length > 0 ? currentOrder.indexOf(String(childValue)) : currentListItemIndex;
2620
4014
  currentListItemIndex++;
2621
- return React18.cloneElement(
4015
+ return React23.cloneElement(
2622
4016
  child,
2623
4017
  { _listIndex: index }
2624
4018
  );
2625
4019
  });
2626
- const contextValue = React18.useMemo(
4020
+ const contextValue = React23.useMemo(
2627
4021
  () => ({
2628
4022
  selectionMode,
2629
4023
  variant,
@@ -2647,7 +4041,7 @@ var ListImpl = React18.forwardRef(
2647
4041
  innerRadius
2648
4042
  ]
2649
4043
  );
2650
- const dndId = React18.useId();
4044
+ const dndId = React23.useId();
2651
4045
  const isListbox = selectionMode === "single-select" || selectionMode === "multi-select";
2652
4046
  const role = isListbox ? "listbox" : "list";
2653
4047
  const ariaMultiselectable = selectionMode === "multi-select" ? true : void 0;
@@ -2694,13 +4088,13 @@ var ListImpl = React18.forwardRef(
2694
4088
  }
2695
4089
  );
2696
4090
  ListImpl.displayName = "List";
2697
- var List = React18.memo(ListImpl);
4091
+ var List = React23.memo(ListImpl);
2698
4092
  var INSET_CLASSES = {
2699
4093
  icon: "pl-[56px]",
2700
4094
  avatar: "pl-[72px]",
2701
4095
  custom: "pl-4"
2702
4096
  };
2703
- var ListDividerImpl = React18.forwardRef(
4097
+ var ListDividerImpl = React23.forwardRef(
2704
4098
  (_a, ref) => {
2705
4099
  var _b = _a, { className, inset = false, insetType = "avatar" } = _b, props = __objRest(_b, ["className", "inset", "insetType"]);
2706
4100
  const insetClass = inset ? INSET_CLASSES[insetType] : "";
@@ -2725,7 +4119,7 @@ var ListDividerImpl = React18.forwardRef(
2725
4119
  }
2726
4120
  );
2727
4121
  ListDividerImpl.displayName = "ListDivider";
2728
- var ListDivider = React18.memo(ListDividerImpl);
4122
+ var ListDivider = React23.memo(ListDividerImpl);
2729
4123
  var MD3_STANDARD = [0.2, 0, 0, 1];
2730
4124
  var MD3_FAST_EFFECTS = [0.3, 0, 1, 1];
2731
4125
  var CHECKMARK_PATH = "M 4.5 9.5 L 7.5 12.5 L 13.5 5.5";
@@ -2739,7 +4133,7 @@ var NEXT_STATE = {
2739
4133
  checked: "indeterminate",
2740
4134
  indeterminate: "unchecked"
2741
4135
  };
2742
- var CheckboxVisual = React18.memo(function CheckboxVisual2({
4136
+ var CheckboxVisual = React23.memo(function CheckboxVisual2({
2743
4137
  isSelected,
2744
4138
  isIndeterminate,
2745
4139
  containerBg,
@@ -2810,7 +4204,7 @@ var CheckboxVisual = React18.memo(function CheckboxVisual2({
2810
4204
  );
2811
4205
  });
2812
4206
  function useMergedRef2(externalRef, internalRef) {
2813
- return React18.useCallback(
4207
+ return React23.useCallback(
2814
4208
  (node) => {
2815
4209
  internalRef.current = node;
2816
4210
  if (!externalRef) return;
@@ -2823,7 +4217,7 @@ function useMergedRef2(externalRef, internalRef) {
2823
4217
  [externalRef, internalRef]
2824
4218
  );
2825
4219
  }
2826
- var CheckboxComponent = React18.forwardRef(
4220
+ var CheckboxComponent = React23.forwardRef(
2827
4221
  ({
2828
4222
  checked,
2829
4223
  defaultChecked = false,
@@ -2845,20 +4239,20 @@ var CheckboxComponent = React18.forwardRef(
2845
4239
  }, ref) => {
2846
4240
  var _a;
2847
4241
  const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
2848
- const generatedId = React18.useId();
4242
+ const generatedId = React23.useId();
2849
4243
  const inputId = idProp != null ? idProp : label ? `checkbox-${generatedId}` : void 0;
2850
- const [internalState, setInternalState] = React18.useState(
4244
+ const [internalState, setInternalState] = React23.useState(
2851
4245
  () => defaultChecked ? "checked" : "unchecked"
2852
4246
  );
2853
4247
  const isControlled = stateProp !== void 0 || checked !== void 0;
2854
4248
  const baseState = isControlled ? resolveState(checked, false, stateProp) : internalState;
2855
4249
  const effectiveState = indeterminate ? "indeterminate" : baseState;
2856
- const [ripples, setRipples] = React18.useState([]);
2857
- const removeRipple = React18.useCallback(
4250
+ const [ripples, setRipples] = React23.useState([]);
4251
+ const removeRipple = React23.useCallback(
2858
4252
  (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
2859
4253
  []
2860
4254
  );
2861
- const onPointerDown = React18.useCallback(
4255
+ const onPointerDown = React23.useCallback(
2862
4256
  (e) => {
2863
4257
  if (disabled) return;
2864
4258
  const rect = e.currentTarget.getBoundingClientRect();
@@ -2872,7 +4266,7 @@ var CheckboxComponent = React18.forwardRef(
2872
4266
  },
2873
4267
  [disabled]
2874
4268
  );
2875
- const handleChange = React18.useCallback(
4269
+ const handleChange = React23.useCallback(
2876
4270
  (e) => {
2877
4271
  if (disabled) return;
2878
4272
  if (stateProp !== void 0) {
@@ -2898,9 +4292,9 @@ var CheckboxComponent = React18.forwardRef(
2898
4292
  onCheckedChange
2899
4293
  ]
2900
4294
  );
2901
- const inputRef = React18.useRef(null);
4295
+ const inputRef = React23.useRef(null);
2902
4296
  const mergedRef = useMergedRef2(ref, inputRef);
2903
- React18.useEffect(() => {
4297
+ React23.useEffect(() => {
2904
4298
  if (inputRef.current) {
2905
4299
  inputRef.current.indeterminate = effectiveState === "indeterminate";
2906
4300
  }
@@ -3025,19 +4419,19 @@ var CheckboxComponent = React18.forwardRef(
3025
4419
  }
3026
4420
  );
3027
4421
  CheckboxComponent.displayName = "Checkbox";
3028
- var Checkbox = React18.memo(CheckboxComponent);
3029
- var TriStateCheckboxComponent = React18.forwardRef((_a, ref) => {
4422
+ var Checkbox = React23.memo(CheckboxComponent);
4423
+ var TriStateCheckboxComponent = React23.forwardRef((_a, ref) => {
3030
4424
  var _b = _a, { state, onStateChange } = _b, rest = __objRest(_b, ["state", "onStateChange"]);
3031
4425
  return /* @__PURE__ */ jsx(Checkbox, __spreadValues({ ref, state, onStateChange }, rest));
3032
4426
  });
3033
4427
  TriStateCheckboxComponent.displayName = "TriStateCheckbox";
3034
- React18.memo(TriStateCheckboxComponent);
4428
+ React23.memo(TriStateCheckboxComponent);
3035
4429
  var MD3_FAST_EFFECTS2 = [0.3, 0, 1, 1];
3036
- var RadioGroupContext = React18.createContext(
4430
+ var RadioGroupContext = React23.createContext(
3037
4431
  null
3038
4432
  );
3039
4433
  function useMergedRef3(externalRef, internalRef) {
3040
- return React18.useCallback(
4434
+ return React23.useCallback(
3041
4435
  (node) => {
3042
4436
  internalRef.current = node;
3043
4437
  if (!externalRef) return;
@@ -3050,7 +4444,7 @@ function useMergedRef3(externalRef, internalRef) {
3050
4444
  [externalRef, internalRef]
3051
4445
  );
3052
4446
  }
3053
- var RadioVisual = React18.memo(function RadioVisual2({
4447
+ var RadioVisual = React23.memo(function RadioVisual2({
3054
4448
  isSelected,
3055
4449
  disabled,
3056
4450
  error,
@@ -3103,7 +4497,7 @@ var RadioVisual = React18.memo(function RadioVisual2({
3103
4497
  }
3104
4498
  );
3105
4499
  });
3106
- var RadioButtonComponent = React18.forwardRef(
4500
+ var RadioButtonComponent = React23.forwardRef(
3107
4501
  ({
3108
4502
  selected,
3109
4503
  defaultSelected = false,
@@ -3122,23 +4516,23 @@ var RadioButtonComponent = React18.forwardRef(
3122
4516
  required: requiredProp
3123
4517
  }, ref) => {
3124
4518
  var _a, _b;
3125
- const group = React18.useContext(RadioGroupContext);
4519
+ const group = React23.useContext(RadioGroupContext);
3126
4520
  const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
3127
- const generatedId = React18.useId();
4521
+ const generatedId = React23.useId();
3128
4522
  const inputId = idProp != null ? idProp : label ? `radio-${generatedId}` : void 0;
3129
4523
  const name = (_b = group == null ? void 0 : group.name) != null ? _b : nameProp;
3130
4524
  const disabled = (group == null ? void 0 : group.disabled) || disabledProp;
3131
4525
  const error = (group == null ? void 0 : group.error) || errorProp || color === "error";
3132
4526
  const required = (group == null ? void 0 : group.required) || requiredProp;
3133
- const [internalSelected, setInternalSelected] = React18.useState(defaultSelected);
4527
+ const [internalSelected, setInternalSelected] = React23.useState(defaultSelected);
3134
4528
  const isControlled = selected !== void 0;
3135
4529
  const isSelected = group ? group.selectedValue === value : isControlled ? selected != null ? selected : false : internalSelected;
3136
- const [ripples, setRipples] = React18.useState([]);
3137
- const removeRipple = React18.useCallback(
4530
+ const [ripples, setRipples] = React23.useState([]);
4531
+ const removeRipple = React23.useCallback(
3138
4532
  (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
3139
4533
  []
3140
4534
  );
3141
- const onPointerDown = React18.useCallback(
4535
+ const onPointerDown = React23.useCallback(
3142
4536
  (e) => {
3143
4537
  if (disabled) return;
3144
4538
  const rect = e.currentTarget.getBoundingClientRect();
@@ -3152,12 +4546,12 @@ var RadioButtonComponent = React18.forwardRef(
3152
4546
  },
3153
4547
  [disabled]
3154
4548
  );
3155
- const [isHovered, setIsHovered] = React18.useState(false);
3156
- const onPointerEnter = React18.useCallback(() => {
4549
+ const [isHovered, setIsHovered] = React23.useState(false);
4550
+ const onPointerEnter = React23.useCallback(() => {
3157
4551
  if (!disabled) setIsHovered(true);
3158
4552
  }, [disabled]);
3159
- const onPointerLeave = React18.useCallback(() => setIsHovered(false), []);
3160
- const handleChange = React18.useCallback(
4553
+ const onPointerLeave = React23.useCallback(() => setIsHovered(false), []);
4554
+ const handleChange = React23.useCallback(
3161
4555
  (_e) => {
3162
4556
  if (disabled || onClick === null) return;
3163
4557
  if (group) {
@@ -3171,7 +4565,7 @@ var RadioButtonComponent = React18.forwardRef(
3171
4565
  },
3172
4566
  [disabled, onClick, group, value, isControlled]
3173
4567
  );
3174
- const inputRef = React18.useRef(null);
4568
+ const inputRef = React23.useRef(null);
3175
4569
  const mergedRef = useMergedRef3(ref, inputRef);
3176
4570
  const stateLayerBg = error ? "before:bg-m3-error" : "before:bg-m3-primary";
3177
4571
  const stateLayerClass = cn(
@@ -3282,8 +4676,8 @@ var RadioButtonComponent = React18.forwardRef(
3282
4676
  }
3283
4677
  );
3284
4678
  RadioButtonComponent.displayName = "RadioButton";
3285
- var RadioButton = React18.memo(RadioButtonComponent);
3286
- var RadioGroupComponent = React18.forwardRef(
4679
+ var RadioButton = React23.memo(RadioButtonComponent);
4680
+ var RadioGroupComponent = React23.forwardRef(
3287
4681
  ({
3288
4682
  name,
3289
4683
  value: valueProp,
@@ -3298,19 +4692,19 @@ var RadioGroupComponent = React18.forwardRef(
3298
4692
  children,
3299
4693
  className
3300
4694
  }, ref) => {
3301
- const [internalValue, setInternalValue] = React18.useState(defaultValue);
4695
+ const [internalValue, setInternalValue] = React23.useState(defaultValue);
3302
4696
  const isControlled = valueProp !== void 0;
3303
4697
  const selectedValue = isControlled ? valueProp : internalValue;
3304
- const handleValueChange = React18.useCallback(
4698
+ const handleValueChange = React23.useCallback(
3305
4699
  (val) => {
3306
4700
  if (!isControlled) setInternalValue(val);
3307
4701
  onValueChange == null ? void 0 : onValueChange(val);
3308
4702
  },
3309
4703
  [isControlled, onValueChange]
3310
4704
  );
3311
- const groupRef = React18.useRef(null);
4705
+ const groupRef = React23.useRef(null);
3312
4706
  const mergedRef = useMergedRef3(ref, groupRef);
3313
- const onKeyDown = React18.useCallback(
4707
+ const onKeyDown = React23.useCallback(
3314
4708
  (e) => {
3315
4709
  var _a, _b;
3316
4710
  if (disabled) return;
@@ -3334,7 +4728,7 @@ var RadioGroupComponent = React18.forwardRef(
3334
4728
  },
3335
4729
  [disabled, handleValueChange]
3336
4730
  );
3337
- const contextValue = React18.useMemo(
4731
+ const contextValue = React23.useMemo(
3338
4732
  () => ({
3339
4733
  name,
3340
4734
  selectedValue,
@@ -3369,7 +4763,7 @@ var RadioGroupComponent = React18.forwardRef(
3369
4763
  }
3370
4764
  );
3371
4765
  RadioGroupComponent.displayName = "RadioGroup";
3372
- React18.memo(RadioGroupComponent);
4766
+ React23.memo(RadioGroupComponent);
3373
4767
 
3374
4768
  // src/ui/switch/switch.tokens.ts
3375
4769
  var SwitchTokens = {
@@ -3447,7 +4841,7 @@ function isIconVisible(thumbContent, icons, showOnlySelectedIcon, checked) {
3447
4841
  if (icons) return true;
3448
4842
  return showOnlySelectedIcon && checked;
3449
4843
  }
3450
- var SwitchVisual = React18.memo(function SwitchVisual2({
4844
+ var SwitchVisual = React23.memo(function SwitchVisual2({
3451
4845
  checked,
3452
4846
  disabled,
3453
4847
  isPressed,
@@ -3567,7 +4961,7 @@ var SwitchVisual = React18.memo(function SwitchVisual2({
3567
4961
  }
3568
4962
  );
3569
4963
  });
3570
- var SwitchComponent = React18.forwardRef(
4964
+ var SwitchComponent = React23.forwardRef(
3571
4965
  ({
3572
4966
  checked,
3573
4967
  onCheckedChange,
@@ -3585,16 +4979,16 @@ var SwitchComponent = React18.forwardRef(
3585
4979
  }, ref) => {
3586
4980
  var _a;
3587
4981
  const prefersReduced = (_a = useReducedMotion()) != null ? _a : false;
3588
- const [isPressed, setIsPressed] = React18.useState(false);
3589
- const [isHovered, setIsHovered] = React18.useState(false);
3590
- const [isFocused, setIsFocused] = React18.useState(false);
3591
- const [ripples, setRipples] = React18.useState([]);
3592
- const generatedId = React18.useId();
4982
+ const [isPressed, setIsPressed] = React23.useState(false);
4983
+ const [isHovered, setIsHovered] = React23.useState(false);
4984
+ const [isFocused, setIsFocused] = React23.useState(false);
4985
+ const [ripples, setRipples] = React23.useState([]);
4986
+ const generatedId = React23.useId();
3593
4987
  const switchId = label ? `switch-${generatedId}` : void 0;
3594
- const handleClick = React18.useCallback(() => {
4988
+ const handleClick = React23.useCallback(() => {
3595
4989
  if (!disabled) onCheckedChange(!checked);
3596
4990
  }, [disabled, checked, onCheckedChange]);
3597
- const handleKeyDown = React18.useCallback(
4991
+ const handleKeyDown = React23.useCallback(
3598
4992
  (e) => {
3599
4993
  if (disabled) return;
3600
4994
  if (e.key === " " || e.key === "Enter") {
@@ -3604,7 +4998,7 @@ var SwitchComponent = React18.forwardRef(
3604
4998
  },
3605
4999
  [disabled, checked, onCheckedChange]
3606
5000
  );
3607
- const handlePointerDown = React18.useCallback(
5001
+ const handlePointerDown = React23.useCallback(
3608
5002
  (e) => {
3609
5003
  if (disabled) return;
3610
5004
  setIsPressed(true);
@@ -3619,19 +5013,19 @@ var SwitchComponent = React18.forwardRef(
3619
5013
  },
3620
5014
  [disabled]
3621
5015
  );
3622
- const handlePointerUp = React18.useCallback(() => {
5016
+ const handlePointerUp = React23.useCallback(() => {
3623
5017
  setIsPressed(false);
3624
5018
  }, []);
3625
- const handlePointerEnter = React18.useCallback(() => {
5019
+ const handlePointerEnter = React23.useCallback(() => {
3626
5020
  if (!disabled) setIsHovered(true);
3627
5021
  }, [disabled]);
3628
- const handlePointerLeave = React18.useCallback(() => {
5022
+ const handlePointerLeave = React23.useCallback(() => {
3629
5023
  setIsHovered(false);
3630
5024
  setIsPressed(false);
3631
5025
  }, []);
3632
- const handleFocus = React18.useCallback(() => setIsFocused(true), []);
3633
- const handleBlur = React18.useCallback(() => setIsFocused(false), []);
3634
- const removeRipple = React18.useCallback(
5026
+ const handleFocus = React23.useCallback(() => setIsFocused(true), []);
5027
+ const handleBlur = React23.useCallback(() => setIsFocused(false), []);
5028
+ const removeRipple = React23.useCallback(
3635
5029
  (id) => setRipples((prev) => prev.filter((r) => r.id !== id)),
3636
5030
  []
3637
5031
  );
@@ -3657,7 +5051,7 @@ var SwitchComponent = React18.forwardRef(
3657
5051
  onFocus: handleFocus,
3658
5052
  onBlur: handleBlur,
3659
5053
  className: cn(
3660
- "relative inline-flex items-center justify-center cursor-pointer select-none",
5054
+ "relative inline-flex items-center justify-center cursor-pointer select-none shrink-0",
3661
5055
  // Touch target: 48×48 minimum (pad around 32px track)
3662
5056
  "min-w-12 min-h-12",
3663
5057
  // Focus ring — MD3 FocusIndicatorColor = secondary
@@ -3667,7 +5061,7 @@ var SwitchComponent = React18.forwardRef(
3667
5061
  disabled && "pointer-events-none cursor-not-allowed",
3668
5062
  !label && className
3669
5063
  ),
3670
- children: /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-full", children: [
5064
+ children: /* @__PURE__ */ jsxs("div", { className: "relative overflow-hidden rounded-full shrink-0", children: [
3671
5065
  /* @__PURE__ */ jsx(
3672
5066
  SwitchVisual,
3673
5067
  {
@@ -3716,7 +5110,7 @@ var SwitchComponent = React18.forwardRef(
3716
5110
  }
3717
5111
  );
3718
5112
  SwitchComponent.displayName = "Switch";
3719
- var Switch = React18.memo(SwitchComponent);
5113
+ var Switch = React23.memo(SwitchComponent);
3720
5114
 
3721
5115
  // src/ui/lists/list-utils.ts
3722
5116
  function getListItemHeight(hasOverline, supportingTextLines) {
@@ -3856,7 +5250,7 @@ function renderSwitchTrailing({
3856
5250
  trailingClass
3857
5251
  }) {
3858
5252
  const isSelectingMode = selectionMode === "single-select" || selectionMode === "multi-select";
3859
- const switchElement = React18.isValidElement(trailingContent) ? (() => {
5253
+ const switchElement = React23.isValidElement(trailingContent) ? (() => {
3860
5254
  const trailingProps = trailingContent.props;
3861
5255
  const checkedValue = !isSelectingMode && trailingProps.checked !== void 0 ? trailingProps.checked : isSelected;
3862
5256
  const disabledValue = trailingProps.disabled !== void 0 ? disabled || trailingProps.disabled : disabled;
@@ -3867,7 +5261,7 @@ function renderSwitchTrailing({
3867
5261
  onItemChange(value, checked);
3868
5262
  }
3869
5263
  };
3870
- return React18.cloneElement(
5264
+ return React23.cloneElement(
3871
5265
  trailingContent,
3872
5266
  { checked: checkedValue, disabled: disabledValue, onCheckedChange }
3873
5267
  );
@@ -3892,7 +5286,7 @@ function renderSwitchTrailing({
3892
5286
  )
3893
5287
  );
3894
5288
  }
3895
- var ListItemImpl = React18.forwardRef(
5289
+ var ListItemImpl = React23.forwardRef(
3896
5290
  (_a, ref) => {
3897
5291
  var _b = _a, {
3898
5292
  className,
@@ -3948,9 +5342,9 @@ var ListItemImpl = React18.forwardRef(
3948
5342
  });
3949
5343
  const reorderable = (_e = context == null ? void 0 : context.reorderable) != null ? _e : false;
3950
5344
  const isSelected = selected !== void 0 ? selected : (_f = context == null ? void 0 : context.selectedValues.has(value)) != null ? _f : false;
3951
- const [isHovered, setIsHovered] = React18.useState(false);
3952
- const [isFocused, setIsFocused] = React18.useState(false);
3953
- const [isPressed, setIsPressed] = React18.useState(false);
5345
+ const [isHovered, setIsHovered] = React23.useState(false);
5346
+ const [isFocused, setIsFocused] = React23.useState(false);
5347
+ const [isPressed, setIsPressed] = React23.useState(false);
3954
5348
  const { ripples, onPointerDown, removeRipple } = useRippleState({
3955
5349
  disabled
3956
5350
  });
@@ -3962,8 +5356,8 @@ var ListItemImpl = React18.forwardRef(
3962
5356
  transition,
3963
5357
  isDragging
3964
5358
  } = useSortable({ id: value, disabled: !reorderable });
3965
- const itemRef = React18.useRef(null);
3966
- const setRefs = React18.useCallback(
5359
+ const itemRef = React23.useRef(null);
5360
+ const setRefs = React23.useCallback(
3967
5361
  (node) => {
3968
5362
  itemRef.current = node;
3969
5363
  setNodeRef(node);
@@ -4416,7 +5810,7 @@ var ListItemImpl = React18.forwardRef(
4416
5810
  }
4417
5811
  );
4418
5812
  ListItemImpl.displayName = "ListItem";
4419
- var ListItem = React18.memo(ListItemImpl);
5813
+ var ListItem = React23.memo(ListItemImpl);
4420
5814
  var typographyVariants = cva("m-0 p-0 text-m3-on-surface", {
4421
5815
  variants: {
4422
5816
  variant: {
@@ -4442,10 +5836,10 @@ var typographyVariants = cva("m-0 p-0 text-m3-on-surface", {
4442
5836
  variant: "body-md"
4443
5837
  }
4444
5838
  });
4445
- var Text = React18.forwardRef(
5839
+ var Text = React23.forwardRef(
4446
5840
  (_a, ref) => {
4447
5841
  var _b = _a, { className, variant, as: Component, color, weight, style } = _b, props = __objRest(_b, ["className", "variant", "as", "color", "weight", "style"]);
4448
- const defaultComponent = React18.useMemo(() => {
5842
+ const defaultComponent = React23.useMemo(() => {
4449
5843
  const v = variant ? String(variant).toLowerCase() : "";
4450
5844
  if (v.startsWith("display") || v.startsWith("headline")) return "h1";
4451
5845
  if (v.startsWith("title")) return "h2";
@@ -5264,6 +6658,6 @@ function TypographyProvider({
5264
6658
  return /* @__PURE__ */ jsx(TypographyContext.Provider, { value, children });
5265
6659
  }
5266
6660
 
5267
- export { Card, CodeBlock, DEFAULT_FONT_VARIATION_AXES, Divider, LIST_TOKENS, List, ListContext, ListDivider, ListItem, MD3_EXPRESSIVE_FONT_VARIATION, ScrollArea, ScrollAreaScrollbar, TableOfContents, Text, TypeScaleTokens, Typography, TypographyContext, TypographyKeyTokens, TypographyProvider, TypographyTokens, buildWavePath, getExpressiveShape, getListItemHeight, serializeFontVariationAxes, shouldTopAlign, typographyVariants, useListContext, useTypography };
6661
+ export { Card, CardContent, CardFooter, CardHeader, CardMedia, Carousel, CarouselGrid, CarouselItem, CarouselScrollClient, CarouselTokens, CodeBlock, DEFAULT_FONT_VARIATION_AXES, Divider, LIST_TOKENS, List, ListContext, ListDivider, ListItem, MD3_EXPRESSIVE_FONT_VARIATION, SHADOW, ScrollArea, ScrollAreaScrollbar, TableOfContents, Text, TypeScaleTokens, Typography, TypographyContext, TypographyKeyTokens, TypographyProvider, TypographyTokens, VARIANT_ELEVATION, buildWavePath, cardVariants, getExpressiveShape, getListItemHeight, resolveElevationShadow, serializeFontVariationAxes, shouldTopAlign, typographyVariants, useCardElevation, useCarouselA11y, useCarouselKeylines, useListContext, useTypography };
5268
6662
  //# sourceMappingURL=layout.mjs.map
5269
6663
  //# sourceMappingURL=layout.mjs.map