@bug-on/m3-expressive 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/README.md +110 -0
  3. package/dist/assets/fonts/GoogleSansFlex-VariableFont.woff2 +0 -0
  4. package/dist/assets/fonts/MaterialSymbolsOutlined-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  5. package/dist/assets/fonts/MaterialSymbolsRounded-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  6. package/dist/assets/fonts/MaterialSymbolsSharp-VariableFont_FILL,GRAD,opsz,wght.ttf +0 -0
  7. package/dist/assets/loading-indicator.svg +19 -0
  8. package/dist/assets/material-symbols-cdn.css +65 -0
  9. package/dist/assets/material-symbols-self-hosted.css +94 -0
  10. package/dist/buttons.d.mts +180 -0
  11. package/dist/buttons.d.ts +180 -0
  12. package/dist/buttons.js +4282 -0
  13. package/dist/buttons.js.map +1 -0
  14. package/dist/buttons.mjs +4227 -0
  15. package/dist/buttons.mjs.map +1 -0
  16. package/dist/core.d.mts +422 -0
  17. package/dist/core.d.ts +422 -0
  18. package/dist/core.js +2581 -0
  19. package/dist/core.js.map +1 -0
  20. package/dist/core.mjs +2547 -0
  21. package/dist/core.mjs.map +1 -0
  22. package/dist/feedback.d.mts +600 -0
  23. package/dist/feedback.d.ts +600 -0
  24. package/dist/feedback.js +2357 -0
  25. package/dist/feedback.js.map +1 -0
  26. package/dist/feedback.mjs +2321 -0
  27. package/dist/feedback.mjs.map +1 -0
  28. package/dist/forms.d.mts +40 -0
  29. package/dist/forms.d.ts +40 -0
  30. package/dist/forms.js +4263 -0
  31. package/dist/forms.js.map +1 -0
  32. package/dist/forms.mjs +4228 -0
  33. package/dist/forms.mjs.map +1 -0
  34. package/dist/icon-button-D-gs0gfj.d.mts +136 -0
  35. package/dist/icon-button-D-gs0gfj.d.ts +136 -0
  36. package/dist/index.css +309 -0
  37. package/dist/index.css.d.ts +2 -0
  38. package/dist/index.d.mts +24 -0
  39. package/dist/index.d.ts +24 -0
  40. package/dist/index.js +23972 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/index.mjs +23668 -0
  43. package/dist/index.mjs.map +1 -0
  44. package/dist/layout.d.mts +610 -0
  45. package/dist/layout.d.ts +610 -0
  46. package/dist/layout.js +5091 -0
  47. package/dist/layout.js.map +1 -0
  48. package/dist/layout.mjs +5042 -0
  49. package/dist/layout.mjs.map +1 -0
  50. package/dist/material-symbols-cdn.css +65 -0
  51. package/dist/material-symbols-cdn.css.d.ts +2 -0
  52. package/dist/material-symbols-self-hosted.css +94 -0
  53. package/dist/material-symbols-self-hosted.css.d.ts +2 -0
  54. package/dist/md3-DFhj-NZj.d.mts +17 -0
  55. package/dist/md3-DFhj-NZj.d.ts +17 -0
  56. package/dist/navigation.d.mts +2766 -0
  57. package/dist/navigation.d.ts +2766 -0
  58. package/dist/navigation.js +6684 -0
  59. package/dist/navigation.js.map +1 -0
  60. package/dist/navigation.mjs +6573 -0
  61. package/dist/navigation.mjs.map +1 -0
  62. package/dist/overlays.d.mts +161 -0
  63. package/dist/overlays.d.ts +161 -0
  64. package/dist/overlays.js +3298 -0
  65. package/dist/overlays.js.map +1 -0
  66. package/dist/overlays.mjs +3244 -0
  67. package/dist/overlays.mjs.map +1 -0
  68. package/dist/pickers.d.mts +1074 -0
  69. package/dist/pickers.d.ts +1074 -0
  70. package/dist/pickers.js +4240 -0
  71. package/dist/pickers.js.map +1 -0
  72. package/dist/pickers.mjs +4200 -0
  73. package/dist/pickers.mjs.map +1 -0
  74. package/dist/plugin.d.mts +1 -0
  75. package/dist/plugin.d.ts +1 -0
  76. package/dist/plugin.js +13 -0
  77. package/dist/plugin.js.map +1 -0
  78. package/dist/plugin.mjs +3 -0
  79. package/dist/plugin.mjs.map +1 -0
  80. package/dist/scroll-area-CVS6HyLl.d.mts +33 -0
  81. package/dist/scroll-area-CVS6HyLl.d.ts +33 -0
  82. package/dist/shapes.d.mts +1119 -0
  83. package/dist/shapes.d.ts +1119 -0
  84. package/dist/shapes.js +2941 -0
  85. package/dist/shapes.js.map +1 -0
  86. package/dist/shapes.mjs +2889 -0
  87. package/dist/shapes.mjs.map +1 -0
  88. package/dist/side-sheet-modal-BY6VCC8p.d.mts +553 -0
  89. package/dist/side-sheet-modal-CglP6KYA.d.ts +553 -0
  90. package/dist/split-button-trailing-uncheckable-C5CLCIKP.d.ts +731 -0
  91. package/dist/split-button-trailing-uncheckable-MXj_kyNt.d.mts +731 -0
  92. package/dist/text-field-eAIpz9z1.d.mts +1038 -0
  93. package/dist/text-field-eAIpz9z1.d.ts +1038 -0
  94. package/dist/typography-339RV6v7.d.mts +486 -0
  95. package/dist/typography-339RV6v7.d.ts +486 -0
  96. package/dist/typography.css +22 -0
  97. package/dist/typography.css.d.ts +2 -0
  98. package/package.json +207 -0
@@ -0,0 +1,3244 @@
1
+ "use client";
2
+ import * as RadixDialog from '@radix-ui/react-dialog';
3
+ import { m, LazyMotion, domMax, useMotionValue, animate, useAnimationFrame, AnimatePresence, useReducedMotion, useTransform } from 'motion/react';
4
+ import * as React6 from 'react';
5
+ import { useState, useRef, useCallback, useMemo, useEffect, useLayoutEffect } from 'react';
6
+ import { clsx } from 'clsx';
7
+ import { twMerge } from 'tailwind-merge';
8
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
9
+ import * as RadixScrollArea from '@radix-ui/react-scroll-area';
10
+ import { createPortal } from 'react-dom';
11
+
12
+ var __defProp = Object.defineProperty;
13
+ var __defProps = Object.defineProperties;
14
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
15
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
16
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
17
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
18
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
19
+ var __spreadValues = (a, b) => {
20
+ for (var prop in b || (b = {}))
21
+ if (__hasOwnProp.call(b, prop))
22
+ __defNormalProp(a, prop, b[prop]);
23
+ if (__getOwnPropSymbols)
24
+ for (var prop of __getOwnPropSymbols(b)) {
25
+ if (__propIsEnum.call(b, prop))
26
+ __defNormalProp(a, prop, b[prop]);
27
+ }
28
+ return a;
29
+ };
30
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
31
+ var __objRest = (source, exclude) => {
32
+ var target = {};
33
+ for (var prop in source)
34
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
35
+ target[prop] = source[prop];
36
+ if (source != null && __getOwnPropSymbols)
37
+ for (var prop of __getOwnPropSymbols(source)) {
38
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
39
+ target[prop] = source[prop];
40
+ }
41
+ return target;
42
+ };
43
+ function cn(...inputs) {
44
+ return twMerge(clsx(inputs));
45
+ }
46
+ 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";
47
+ var SHAPE_KEY_SPLINES = [
48
+ "0.5 0.2 0 0.8",
49
+ "0.5 0.2 0 0.8",
50
+ "0.5 0.2 0 0.8",
51
+ "0.5 0.2 0 0.8",
52
+ "0.5 0.2 0 0.8",
53
+ "0.5 0.2 0 0.8",
54
+ "0.5 0.2 0 0.8",
55
+ "0.5 0.2 0 0.8",
56
+ "0.5 0.2 0 0.8",
57
+ "0.5 0.2 0 0.8",
58
+ "0.5 0.2 0 0.8",
59
+ "0.5 0.2 0 0.8",
60
+ "0.5 0.2 0 0.8"
61
+ ].join("; ");
62
+ var SHAPE_VALUES = [
63
+ "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",
64
+ "M20.3 8.6 21.1 8 22 7.6 23 7.3 23 7.3 24 7.2 25 7.3 25.9 7.5 26.8 8 27.6 8.6 28.4 9.1 28.4 9.1 29.3 9.6 30.3 9.8 31.3 9.9 32.3 10 33.3 10.2 34.2 10.6 34.2 10.6 35 11.2 35.7 11.9 36.3 12.7 36.7 13.6 36.9 14.6 37.2 15.5 37.2 15.5 37.6 16.5 38.2 17.3 38.9 18 39.6 18.7 40.2 19.5 40.6 20.4 40.6 20.4 40.9 21.3 41 22.3 40.9 23.3 40.6 24.3 40.2 25.2 39.8 26.1 39.8 26.1 39.5 27 39.4 28 39.5 29 39.6 30 39.5 31 39.3 32 39.3 32 38.9 32.9 38.3 33.7 37.6 34.4 36.8 35 35.9 35.4 35 35.8 35 35.8 34.1 36.3 33.4 37 32.9 37.9 32.3 38.7 31.6 39.4 30.8 40 30.8 40 29.9 40.4 28.9 40.7 27.9 40.8 27 40.7 26 40.4 25 40.1 25 40.1 24 40 23 40.1 22.1 40.4 21.1 40.7 20.1 40.8 19.1 40.7 19.1 40.7 18.2 40.5 17.3 40 16.4 39.5 15.7 38.8 15.2 37.9 14.6 37.1 14.6 37.1 13.9 36.4 13.1 35.8 12.2 35.4 11.3 35 10.5 34.4 9.7 33.8 9.7 33.8 9.1 32.9 8.7 32 8.5 31.1 8.4 30.1 8.5 29.1 8.6 28.1 8.6 28.1 8.5 27.1 8.3 26.1 7.8 25.2 7.4 24.3 7.1 23.4 7 22.4 7 22.4 7.1 21.4 7.3 20.4 7.8 19.5 8.3 18.7 9.1 18 9.8 17.3 9.8 17.3 10.4 16.5 10.8 15.6 11 14.6 11.3 13.7 11.7 12.8 12.2 11.9 12.2 11.9 12.9 11.2 13.8 10.7 14.7 10.2 15.6 10 16.6 9.9 17.6 9.8 17.6 9.8 18.6 9.6 19.5 9.2Z",
65
+ "M18.6 9.6 19.5 9.2 20.3 8.6 21.1 8 22 7.6 23 7.3 24 7.2 25 7.3 25.9 7.5 26.8 8 27.6 8.6 28.4 9.1 29.3 9.6 30.3 9.8 31.3 9.9 32.3 10 33.3 10.2 34.2 10.6 35 11.2 35.7 11.9 36.3 12.7 36.7 13.6 36.9 14.6 37.2 15.5 37.6 16.4 38.2 17.3 38.9 18 39.6 18.7 40.2 19.5 40.6 20.4 40.9 21.3 41 22.3 40.9 23.3 40.6 24.3 40.2 25.2 39.8 26.1 39.5 27 39.4 28 39.5 29 39.6 30 39.5 31 39.3 32 38.9 32.9 38.3 33.7 37.6 34.4 36.8 35 35.9 35.4 35 35.8 34.1 36.3 33.4 37 32.9 37.9 32.3 38.7 31.6 39.4 30.8 40 29.9 40.4 28.9 40.7 27.9 40.8 27 40.7 26 40.4 25 40.1 24 40 23 40.1 22.1 40.4 21.1 40.7 20.1 40.8 19.1 40.7 18.2 40.5 17.3 40 16.4 39.5 15.7 38.8 15.2 37.9 14.6 37.1 13.9 36.4 13.1 35.8 12.2 35.4 11.3 35 10.5 34.4 9.7 33.8 9.1 32.9 8.7 32 8.5 31.1 8.4 30.1 8.5 29.1 8.6 28.1 8.5 27.1 8.3 26.1 7.8 25.2 7.4 24.3 7.1 23.4 7 22.4 7.1 21.4 7.3 20.4 7.8 19.5 8.3 18.7 9.1 18 9.8 17.3 10.4 16.5 10.8 15.6 11 14.6 11.3 13.7 11.7 12.8 12.2 11.9 12.9 11.2 13.8 10.7 14.7 10.2 15.6 10 16.6 9.9 17.6 9.8Z",
66
+ "M18.6 9.9 19.5 9.4 20.3 8.8 21.1 8.2 22 7.8 23 7.6 23.9 7.5 24.9 7.6 25.9 7.8 26.8 8.2 27.6 8.7 28.5 9.3 29.3 9.9 30.1 10.5 30.9 11 31.7 11.6 32.5 12.2 33.3 12.8 33.7 13.1 34.1 13.3 34.9 13.9 35.7 14.5 36.6 15 37.4 15.6 38.2 16.2 39 16.8 39.7 17.5 40.2 18.3 40.7 19.2 40.9 20.1 41 21.1 40.9 22.1 40.7 23.1 40.3 24 40 24.9 39.7 25.9 39.4 26.8 39 27.8 38.7 28.7 38.4 29.6 38.1 30.6 37.8 31.5 37.5 32.5 37.2 33.4 36.9 34.4 36.6 35.3 36.2 36.2 35.7 37.1 35 37.8 34.3 38.4 33.4 38.9 32.5 39.3 31.5 39.5 30.5 39.5 30 39.5 29.5 39.5 28.5 39.5 27.5 39.5 26.5 39.5 25.5 39.4 24.5 39.4 23.6 39.4 22.6 39.4 21.6 39.5 20.6 39.5 19.6 39.5 18.6 39.5 17.6 39.5 16.6 39.5 15.6 39.3 14.7 39 13.8 38.5 13.1 37.9 12.4 37.2 11.9 36.3 11.5 35.4 11.2 34.5 10.9 33.5 10.6 32.6 10.3 31.6 10 30.7 9.7 29.7 9.3 28.8 9 27.9 8.7 26.9 8.4 26 8 25 7.7 24.1 7.4 23.2 7.1 22.2 7.1 21.7 7 21.2 7.1 20.2 7.3 19.3 7.7 18.4 8.3 17.5 8.9 16.8 9.7 16.2 10.5 15.6 11.4 15.1 12.2 14.5 13 14 13.8 13.4 14.6 12.8 15.4 12.3 16.2 11.7 17 11.1 17.8 10.5Z",
67
+ "M15.4 12.3 16.2 11.7 17 11.1 17.8 10.5 18.6 9.9 19.5 9.4 20.3 8.8 21.1 8.3 22 7.8 23 7.6 23.9 7.5 24.9 7.6 25.9 7.8 26.8 8.2 27.6 8.7 28.5 9.3 29.3 9.9 30.1 10.5 30.9 11 31.7 11.6 32.5 12.2 33.3 12.8 34.1 13.3 34.9 13.9 35.7 14.5 36.6 15 37.4 15.6 38.2 16.2 39 16.8 39.7 17.5 40.2 18.3 40.7 19.2 40.9 20.1 41 21.1 40.9 22.1 40.7 23.1 40.3 24 40 24.9 39.7 25.9 39.4 26.8 39 27.8 38.7 28.7 38.4 29.6 38.1 30.6 37.8 31.5 37.5 32.5 37.2 33.4 36.9 34.4 36.6 35.3 36.2 36.2 35.7 37.1 35 37.8 34.3 38.4 33.4 38.9 32.5 39.3 31.5 39.4 30.5 39.5 29.5 39.5 28.5 39.5 27.5 39.5 26.5 39.5 25.5 39.4 24.5 39.4 23.6 39.4 22.6 39.4 21.6 39.5 20.6 39.5 19.6 39.5 18.6 39.5 17.6 39.5 16.6 39.5 15.6 39.3 14.7 39 13.8 38.5 13.1 37.9 12.4 37.2 11.9 36.3 11.5 35.4 11.2 34.5 10.9 33.5 10.6 32.6 10.3 31.6 10 30.7 9.7 29.7 9.3 28.8 9 27.9 8.7 26.9 8.4 26 8 25 7.7 24.1 7.4 23.2 7.1 22.2 7 21.2 7.1 20.2 7.3 19.3 7.7 18.4 8.3 17.5 8.9 16.8 9.7 16.2 10.5 15.6 11.4 15.1 12.2 14.5 13 14 13.8 13.4 14.6 12.8Z",
68
+ "M17 12.8 17.7 12.1 18.5 11.5 19.3 10.9 20.1 10.5 20.2 10.4 21.1 10 22 9.7 23 9.4 24 9.2 25 9 26 9 27 9 27.6 9.1 28 9.1 28.9 9.3 29.9 9.6 30.9 9.9 31.8 10.3 32.6 10.8 33.5 11.3 34.3 11.9 34.6 12.2 35 12.6 35.7 13.3 36.4 14.1 36.9 14.9 37.4 15.8 37.9 16.6 38.3 17.6 38.6 18.5 38.6 18.7 38.8 19.5 38.9 20.5 39 21.5 39 22.5 38.9 23.5 38.7 24.5 38.5 25.4 38.2 26.3 38.2 26.4 37.8 27.3 37.4 28.2 36.8 29.1 36.2 29.9 35.6 30.6 34.9 31.3 34.2 32 33.8 32.5 33.5 32.8 32.8 33.5 32.1 34.2 31.4 34.9 30.7 35.6 29.9 36.2 29.1 36.8 28.2 37.3 27.9 37.5 27.4 37.8 26.4 38.2 25.5 38.5 24.5 38.7 23.5 38.9 22.5 39 21.5 39 20.5 38.9 20.4 38.9 19.5 38.8 18.6 38.6 17.6 38.3 16.7 37.9 15.8 37.5 14.9 37 14.1 36.4 13.4 35.8 13.3 35.8 12.6 35.1 12 34.3 11.3 33.5 10.8 32.7 10.3 31.8 9.9 30.9 9.6 30 9.4 29.3 9.3 29 9.1 28 9 27 9 26 9 25 9.2 24 9.4 23 9.6 22.1 9.8 21.7 10 21.1 10.4 20.2 10.9 19.4 11.4 18.5 12.1 17.8 12.7 17 13.4 16.3 14.2 15.6 14.2 15.5 14.9 14.9 15.6 14.2 16.3 13.5Z",
69
+ "M33.5 11.3 34.3 11.9 35 12.6 35.3 12.8 35.7 13.3 36.4 14.1 36.9 14.9 37.4 15.8 37.9 16.6 38.3 17.6 38.3 17.7 38.6 18.5 38.8 19.5 38.9 20.5 39 21.5 39 22.5 38.9 23.5 38.9 23.5 38.7 24.5 38.5 25.4 38.2 26.4 37.8 27.3 37.4 28.2 36.9 28.9 36.8 29.1 36.2 29.9 35.6 30.6 34.9 31.3 34.2 32 33.5 32.8 33.1 33.2 32.8 33.5 32.1 34.2 31.4 34.9 30.7 35.6 29.9 36.2 29.1 36.8 28.7 37 28.2 37.3 27.4 37.8 26.4 38.2 25.5 38.5 24.5 38.7 23.5 38.9 23.3 38.9 22.5 39 21.5 39 20.5 38.9 19.5 38.8 18.6 38.6 17.6 38.3 17.6 38.3 16.7 37.9 15.8 37.5 14.9 37 14.1 36.4 13.3 35.8 12.7 35.2 12.6 35.1 12 34.3 11.3 33.5 10.8 32.7 10.3 31.8 9.9 30.9 9.7 30.3 9.6 29.9 9.3 29 9.1 28 9 27 9 26 9 25 9.1 24.5 9.2 24 9.4 23 9.6 22.1 10 21.1 10.4 20.2 10.9 19.4 11.1 19.1 11.5 18.5 12.1 17.7 12.7 17 13.5 16.3 14.2 15.6 14.9 14.9 14.9 14.8 15.6 14.2 16.3 13.5 17 12.8 17.7 12.1 18.5 11.5 19.3 11 19.3 10.9 20.2 10.4 21.1 10 22 9.7 23 9.4 24 9.2 24.7 9.1 25 9 26 9 27 9 28 9.1 28.9 9.3 29.9 9.6 30.4 9.7 30.9 9.9 31.8 10.3 32.6 10.8Z",
70
+ "M33.2 11.1 34.2 11.2 35.1 11.4 36 11.9 36.6 12.7 36.8 13.7 36.9 14.7 36.9 15.7 37 16.7 37.1 17.7 37.3 18.6 37.9 19.4 38.5 20.2 39.2 20.9 39.8 21.7 40.5 22.4 40.9 23.3 41 24.3 40.7 25.2 40.1 26 39.4 26.8 38.8 27.5 38.1 28.3 37.5 29.1 37.1 30 37 31 37 31.9 36.9 32.9 36.8 33.9 36.7 34.9 36.2 35.8 35.5 36.4 34.5 36.8 33.6 36.8 32.6 36.9 31.6 37 30.6 37.1 29.6 37.2 28.8 37.7 28 38.4 27.3 39 26.5 39.7 25.8 40.3 24.9 40.8 23.9 41 23 40.8 22.1 40.2 21.4 39.6 20.6 38.9 19.9 38.3 19.1 37.6 18.3 37.2 17.3 37 16.3 37 15.3 36.9 14.3 36.8 13.3 36.7 12.4 36.4 11.7 35.7 11.3 34.8 11.2 33.8 11.1 32.8 11 31.8 11 30.8 10.9 29.9 10.4 29 9.8 28.2 9.1 27.5 8.5 26.7 7.8 26 7.3 25.1 7 24.2 7.1 23.2 7.6 22.3 8.2 21.6 8.9 20.8 9.5 20.1 10.2 19.3 10.7 18.5 10.9 17.5 11 16.6 11.1 15.6 11.1 14.6 11.2 13.6 11.5 12.6 12.1 11.9 13 11.4 13.9 11.2 14.9 11.1 15.9 11 16.9 11 17.9 10.9 18.8 10.6 19.6 10 20.4 9.3 21.1 8.6 21.9 8 22.6 7.4 23.6 7 24.6 7.1 25.5 7.5 26.2 8.1 27 8.7 27.7 9.4 28.5 10 29.3 10.6 30.2 10.9 31.2 11 32.2 11.1Z",
71
+ "M27.7 9.4 28.5 10 29.3 10.6 30.2 10.9 31.2 11 32.2 11.1 33.2 11.1 34.2 11.2 35.1 11.4 36 11.9 36.6 12.7 36.8 13.7 36.9 14.7 36.9 15.7 37 16.7 37.1 17.7 37.3 18.6 37.9 19.4 38.5 20.2 39.2 20.9 39.8 21.7 40.5 22.4 40.9 23.3 41 24.3 40.7 25.2 40.1 26 39.4 26.8 38.8 27.5 38.1 28.3 37.5 29.1 37.1 30 37 31 37 31.9 36.9 32.9 36.8 33.9 36.7 34.9 36.2 35.8 35.5 36.4 34.5 36.8 33.6 36.9 32.6 36.9 31.6 37 30.6 37.1 29.6 37.2 28.8 37.7 28 38.4 27.3 39 26.5 39.7 25.8 40.3 24.9 40.8 23.9 41 23 40.8 22.1 40.2 21.4 39.6 20.6 38.9 19.9 38.3 19.1 37.6 18.3 37.2 17.3 37 16.3 37 15.3 36.9 14.3 36.8 13.3 36.7 12.4 36.4 11.7 35.7 11.3 34.8 11.2 33.8 11.1 32.8 11 31.8 11 30.8 10.9 29.9 10.4 29 9.8 28.2 9.1 27.5 8.5 26.7 7.8 26 7.3 25.1 7 24.2 7.1 23.2 7.6 22.3 8.2 21.6 8.9 20.8 9.5 20.1 10.2 19.3 10.7 18.5 10.9 17.5 11 16.5 11.1 15.6 11.1 14.6 11.2 13.6 11.5 12.6 12.1 11.9 13 11.4 13.9 11.2 14.9 11.1 15.9 11 16.9 11 17.9 10.9 18.8 10.6 19.6 10 20.4 9.3 21.1 8.6 21.9 8 22.6 7.4 23.6 7 24.6 7.1 25.5 7.5 26.2 8.1 27 8.7Z",
72
+ "M27.9 10.6 28.8 10.3 29.8 10.1 30.8 10 31.8 10.1 32.7 10.3 33.7 10.6 34.6 11.1 34.8 11.3 35.4 11.7 36.1 12.4 36.7 13.1 37.2 14 37.6 14.9 37.9 15.9 38 16.9 38 17.9 37.8 18.8 37.5 19.8 37.1 20.7 36.8 21.6 36.5 22.6 36.4 23.6 36.4 24.4 36.4 24.6 36.5 25.5 36.8 26.5 37.2 27.4 37.6 28.3 37.8 29.3 38 30.3 38 31.3 37.8 32.3 37.6 33.2 37.2 34.1 36.6 35 36 35.7 35.3 36.4 34.4 37 34.1 37.2 33.6 37.4 32.6 37.8 31.6 37.9 30.6 38 29.7 37.9 28.7 37.7 27.8 37.3 26.8 36.9 25.9 36.6 24.9 36.4 23.9 36.4 22.9 36.4 22 36.6 21 37 20.1 37.4 20.1 37.4 19.2 37.7 18.2 37.9 17.2 38 16.2 37.9 15.3 37.7 14.3 37.4 13.4 36.9 12.6 36.3 11.9 35.6 11.3 34.9 10.8 34 10.4 33.1 10.1 32.1 10 31.1 10 30.6 10 30.1 10.2 29.2 10.5 28.2 10.9 27.3 11.2 26.4 11.5 25.4 11.6 24.4 11.6 23.4 11.5 22.5 11.2 21.5 10.8 20.6 10.4 19.7 10.2 18.7 10 17.7 10 16.7 10 16.6 10.2 15.7 10.4 14.8 10.8 13.9 11.4 13 12 12.3 12.7 11.6 13.6 11 14.4 10.6 15.4 10.2 16.4 10.1 17.4 10 18.3 10.1 19.3 10.3 20.2 10.7 20.9 11 21.2 11.1 22.1 11.4 23.1 11.6 24.1 11.6 25.1 11.6 26 11.4 27 11Z",
73
+ "M36 35.7 35.3 36.4 34.4 37 33.6 37.4 32.6 37.8 31.6 37.9 30.6 38 29.7 37.9 28.7 37.7 27.8 37.3 26.8 36.9 25.9 36.6 24.9 36.4 23.9 36.4 22.9 36.4 22 36.6 21 37 20.1 37.4 19.2 37.7 18.2 37.9 17.2 38 16.2 37.9 15.3 37.7 14.3 37.4 13.4 36.9 12.6 36.3 11.9 35.6 11.3 34.9 10.8 34 10.4 33.1 10.1 32.1 10 31.1 10 30.2 10.2 29.2 10.5 28.2 10.9 27.3 11.2 26.4 11.5 25.4 11.6 24.4 11.6 23.4 11.5 22.5 11.2 21.5 10.8 20.6 10.4 19.7 10.2 18.7 10 17.7 10 16.7 10.2 15.7 10.4 14.8 10.8 13.9 11.4 13 12 12.3 12.7 11.6 13.6 11 14.4 10.6 15.4 10.2 16.4 10.1 17.4 10 18.3 10.1 19.3 10.3 20.2 10.7 21.2 11.1 22.1 11.4 23.1 11.6 24.1 11.6 25.1 11.6 26 11.4 27 11 27.9 10.6 28.8 10.3 29.8 10.1 30.8 10 31.8 10.1 32.7 10.3 33.7 10.6 34.6 11.1 35.4 11.7 36.1 12.4 36.7 13.1 37.2 14 37.6 14.9 37.9 15.9 38 16.9 38 17.8 37.8 18.8 37.5 19.8 37.1 20.7 36.8 21.6 36.5 22.6 36.4 23.6 36.4 24.6 36.5 25.5 36.8 26.5 37.2 27.4 37.6 28.3 37.8 29.3 38 30.3 38 31.3 37.8 32.3 37.6 33.2 37.2 34.1 36.6 35Z",
74
+ "M32.1 32.1 31.4 32.8 30.7 33.5 29.9 34.1 29.1 34.7 28.3 35.3 27.6 35.8 27.5 35.8 26.6 36.4 25.8 36.8 24.9 37.3 24 37.7 23.1 38 22.1 38.3 21.2 38.6 20.2 38.8 19.2 38.9 18.2 39 17.2 39 16.6 38.9 16.3 38.9 15.3 38.7 14.3 38.4 13.4 38 12.5 37.5 11.7 36.9 11.1 36.3 10.5 35.5 10 34.6 9.6 33.7 9.3 32.7 9.1 31.7 9.1 31.4 9 30.8 9 29.8 9.1 28.8 9.2 27.8 9.4 26.8 9.7 25.9 10 24.9 10.3 24 10.7 23.1 11.2 22.2 11.6 21.4 12.2 20.5 12.2 20.4 12.7 19.7 13.3 18.9 13.9 18.1 14.5 17.3 15.2 16.6 15.9 15.9 16.6 15.2 17.3 14.5 18.1 13.9 18.9 13.3 19.7 12.7 20.4 12.2 20.5 12.2 21.4 11.6 22.2 11.2 23.1 10.7 24 10.3 24.9 10 25.9 9.7 26.8 9.4 27.8 9.2 28.8 9.1 29.8 9 30.8 9 31.4 9.1 31.7 9.1 32.7 9.3 33.7 9.6 34.6 10 35.5 10.5 36.3 11.1 36.9 11.7 37.5 12.5 38 13.4 38.4 14.3 38.7 15.3 38.9 16.3 38.9 16.6 39 17.2 39 18.2 38.9 19.2 38.8 20.2 38.6 21.2 38.3 22.1 38 23.1 37.7 24 37.3 24.9 36.8 25.8 36.4 26.6 35.8 27.5 35.8 27.6 35.3 28.3 34.7 29.1 34.1 29.9 33.5 30.7 32.8 31.4Z",
75
+ "M24.3 10.2 24.9 10 25.9 9.7 26.8 9.4 27.1 9.4 27.8 9.2 28.8 9.1 29.8 9 29.9 9 30.8 9 31.7 9.1 32.7 9.3 32.8 9.3 33.7 9.6 34.6 10 35.5 10.5 35.5 10.5 36.3 11.1 36.9 11.7 37.5 12.5 37.5 12.5 38 13.4 38.4 14.3 38.7 15.2 38.7 15.3 38.9 16.3 39 17.2 39 18.1 39 18.2 38.9 19.2 38.8 20.2 38.6 20.9 38.6 21.2 38.3 22.1 38 23.1 37.8 23.7 37.7 24 37.3 24.9 36.8 25.8 36.5 26.4 36.4 26.6 35.8 27.5 35.3 28.3 35 28.8 34.7 29.1 34.1 29.9 33.5 30.7 33.1 31.1 32.8 31.4 32.1 32.1 31.4 32.8 31.1 33.1 30.7 33.5 29.9 34.1 29.1 34.7 28.8 35 28.3 35.3 27.5 35.8 26.6 36.4 26.4 36.5 25.8 36.8 24.9 37.3 24 37.7 23.7 37.8 23.1 38 22.1 38.3 21.2 38.6 20.9 38.6 20.2 38.8 19.2 38.9 18.2 39 18.1 39 17.2 39 16.3 38.9 15.3 38.7 15.2 38.7 14.3 38.4 13.4 38 12.5 37.5 12.5 37.5 11.7 36.9 11.1 36.3 10.5 35.5 10.5 35.5 10 34.6 9.6 33.7 9.3 32.8 9.3 32.7 9.1 31.7 9 30.8 9 29.9 9 29.8 9.1 28.8 9.2 27.8 9.4 27.1 9.4 26.8 9.7 25.9 10 24.9 10.2 24.3 10.3 24 10.7 23.1 11.2 22.2 11.5 21.6 11.6 21.4 12.2 20.5 12.7 19.7 13 19.2 13.3 18.9 13.9 18.1 14.5 17.3 14.9 16.9 15.2 16.6 15.9 15.9 16.6 15.2 16.9 14.9 17.3 14.5 18.1 13.9 18.9 13.3 19.2 13 19.7 12.7 20.5 12.2 21.4 11.6 21.6 11.5 22.2 11.2 23.1 10.7 24 10.3Z",
76
+ "M22.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 37.9 17.3 38.9 17.5 39.8 17.9 40.4 18.7 40.5 19.7 40 20.5 39.3 21.3 38.7 22 38.1 22.8 37.6 23.7 37.7 24.6 38.3 25.4 38.9 26.2 39.6 27 40.2 27.7 40.5 28.6 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.8 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.6 9.1 21.8 8.4 21 7.8 20.3 7.5 19.4 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.2 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.1 20.9 10.4 21.4 9.5 21.9 8.7Z"
77
+ ].join(";");
78
+ var ROTATE_KEY_TIMES = "0; 0.14; 0.29; 0.43; 0.57; 0.71; 0.86; 1";
79
+ var ROTATE_KEY_SPLINES = [
80
+ "0.5 0.2 0 0.8",
81
+ "0.5 0.2 0 0.8",
82
+ "0.5 0.2 0 0.8",
83
+ "0.5 0.2 0 0.8",
84
+ "0.5 0.2 0 0.8",
85
+ "0.5 0.2 0 0.8",
86
+ "0.5 0.2 0 0.8"
87
+ ].join("; ");
88
+ 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";
89
+ 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";
90
+ 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";
91
+ var IndeterminateSvg = React6.memo(function IndeterminateSvg2({
92
+ size
93
+ }) {
94
+ const [ready, setReady] = React6.useState(false);
95
+ React6.useEffect(() => {
96
+ const raf = requestAnimationFrame(() => setReady(true));
97
+ return () => cancelAnimationFrame(raf);
98
+ }, []);
99
+ return /* @__PURE__ */ jsx(
100
+ "svg",
101
+ {
102
+ viewBox: "4 4 40 40",
103
+ width: size,
104
+ height: size,
105
+ fill: "currentColor",
106
+ xmlns: "http://www.w3.org/2000/svg",
107
+ "aria-hidden": "true",
108
+ focusable: "false",
109
+ children: /* @__PURE__ */ jsx("path", { d: SHAPE_VALUES.split(";")[0], children: ready && /* @__PURE__ */ jsxs(Fragment, { children: [
110
+ /* @__PURE__ */ jsx(
111
+ "animate",
112
+ {
113
+ attributeName: "d",
114
+ dur: "5s",
115
+ repeatCount: "indefinite",
116
+ calcMode: "spline",
117
+ keySplines: SHAPE_KEY_SPLINES,
118
+ keyTimes: SHAPE_KEY_TIMES,
119
+ values: SHAPE_VALUES
120
+ }
121
+ ),
122
+ /* @__PURE__ */ jsx(
123
+ "animateTransform",
124
+ {
125
+ attributeName: "transform",
126
+ attributeType: "XML",
127
+ type: "rotate",
128
+ dur: "5s",
129
+ repeatCount: "indefinite",
130
+ calcMode: "spline",
131
+ keySplines: ROTATE_KEY_SPLINES,
132
+ keyTimes: ROTATE_KEY_TIMES,
133
+ values: ROTATE_VALUES
134
+ }
135
+ )
136
+ ] }) })
137
+ }
138
+ );
139
+ });
140
+ var DeterminateSvg = React6.memo(function DeterminateSvg2({
141
+ size,
142
+ progress
143
+ }) {
144
+ const p = Math.min(1, Math.max(0, progress));
145
+ const rotation = -180 * p;
146
+ const pathD = p < 0.5 ? DETERMINATE_CIRCLE : DETERMINATE_SOFT_BURST;
147
+ return /* @__PURE__ */ jsx(
148
+ "svg",
149
+ {
150
+ viewBox: "4 4 40 40",
151
+ width: size,
152
+ height: size,
153
+ fill: "currentColor",
154
+ xmlns: "http://www.w3.org/2000/svg",
155
+ "aria-hidden": "true",
156
+ focusable: "false",
157
+ style: {
158
+ transform: `rotate(${rotation}deg)`,
159
+ transition: "transform 0.3s ease"
160
+ },
161
+ children: /* @__PURE__ */ jsx("path", { d: pathD, style: { transition: "d 0.3s ease" } })
162
+ }
163
+ );
164
+ });
165
+ var LoadingIndicator = React6.forwardRef(
166
+ (_a, ref) => {
167
+ var _b = _a, {
168
+ variant = "uncontained",
169
+ size = 48,
170
+ progress,
171
+ color,
172
+ className,
173
+ "aria-label": ariaLabel,
174
+ style
175
+ } = _b, restProps = __objRest(_b, [
176
+ "variant",
177
+ "size",
178
+ "progress",
179
+ "color",
180
+ "className",
181
+ "aria-label",
182
+ "style"
183
+ ]);
184
+ const isContained = variant === "contained";
185
+ const isDeterminate = progress !== void 0;
186
+ const clampedSize = Math.min(240, Math.max(24, size));
187
+ const scaleFactor = clampedSize / 48;
188
+ const containerSize = isContained ? 38 * scaleFactor : void 0;
189
+ const indicatorSize = isContained ? 24 * scaleFactor : clampedSize;
190
+ const activeColor = isContained ? color != null ? color : "var(--md-sys-color-indicator-contained-active)" : color != null ? color : "var(--md-sys-color-indicator-active)";
191
+ const ariaNow = isDeterminate ? Math.round(Math.min(1, Math.max(0, progress)) * 100) : void 0;
192
+ return /* @__PURE__ */ jsx(
193
+ "div",
194
+ __spreadProps(__spreadValues({
195
+ ref,
196
+ role: "progressbar",
197
+ "aria-label": ariaLabel,
198
+ "aria-valuemin": 0,
199
+ "aria-valuemax": 100,
200
+ "aria-valuenow": ariaNow,
201
+ className: cn(
202
+ "inline-flex items-center justify-center shrink-0",
203
+ className
204
+ ),
205
+ style: __spreadValues({
206
+ width: clampedSize,
207
+ height: clampedSize,
208
+ color: activeColor
209
+ }, style)
210
+ }, restProps), {
211
+ children: isContained ? /* @__PURE__ */ jsx(
212
+ "div",
213
+ {
214
+ className: "flex items-center justify-center rounded-full",
215
+ style: {
216
+ width: containerSize,
217
+ height: containerSize,
218
+ backgroundColor: "var(--md-sys-color-indicator-contained-container)"
219
+ },
220
+ children: isDeterminate ? /* @__PURE__ */ jsx(DeterminateSvg, { size: indicatorSize, progress }) : /* @__PURE__ */ jsx(IndeterminateSvg, { size: indicatorSize })
221
+ }
222
+ ) : isDeterminate ? /* @__PURE__ */ jsx(DeterminateSvg, { size: indicatorSize, progress }) : /* @__PURE__ */ jsx(IndeterminateSvg, { size: indicatorSize })
223
+ })
224
+ );
225
+ }
226
+ );
227
+ LoadingIndicator.displayName = "LoadingIndicator";
228
+
229
+ // src/ui/progress-indicator/utils.ts
230
+ function easeInOutCubic(x) {
231
+ return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;
232
+ }
233
+ function generateWavyCircularPath(center, radius, amplitude, wavelength) {
234
+ const circumference = 2 * Math.PI * radius;
235
+ const numWaves = Math.max(
236
+ 3,
237
+ Math.round(circumference / Math.max(1, wavelength))
238
+ );
239
+ const steps = numWaves * 4;
240
+ const dt = 2 * Math.PI / steps;
241
+ const rAt = (t) => radius + amplitude * Math.sin(numWaves * t);
242
+ const drAt = (t) => amplitude * numWaves * Math.cos(numWaves * t);
243
+ const xAt = (t) => center + rAt(t) * Math.cos(t);
244
+ const yAt = (t) => center + rAt(t) * Math.sin(t);
245
+ const dxAt = (t) => drAt(t) * Math.cos(t) - rAt(t) * Math.sin(t);
246
+ const dyAt = (t) => drAt(t) * Math.sin(t) + rAt(t) * Math.cos(t);
247
+ let d = "";
248
+ const tStart = 0;
249
+ for (let i = 0; i < steps; i++) {
250
+ const t0 = tStart + i * dt;
251
+ const t1 = tStart + (i + 1) * dt;
252
+ const scale = dt / 3;
253
+ const cp1x = xAt(t0) + scale * dxAt(t0);
254
+ const cp1y = yAt(t0) + scale * dyAt(t0);
255
+ const cp2x = xAt(t1) - scale * dxAt(t1);
256
+ const cp2y = yAt(t1) - scale * dyAt(t1);
257
+ if (i === 0) d += `M ${xAt(t0).toFixed(2)} ${yAt(t0).toFixed(2)}`;
258
+ d += ` C ${cp1x.toFixed(2)} ${cp1y.toFixed(2)}, ${cp2x.toFixed(2)} ${cp2y.toFixed(2)}, ${xAt(t1).toFixed(2)} ${yAt(t1).toFixed(2)}`;
259
+ }
260
+ d += " Z";
261
+ return d;
262
+ }
263
+ function getSinePath(startX, endX, phase, wl, amp) {
264
+ if (startX >= endX) return "";
265
+ let d = "";
266
+ const step = amp === 0 ? Math.max(10, endX - startX) : 1;
267
+ const yStart = Math.sin((startX + phase) / wl * 2 * Math.PI) * amp;
268
+ d += `M ${startX.toFixed(2)} ${yStart.toFixed(2)}`;
269
+ let nextX = Math.ceil(startX / step) * step;
270
+ if (nextX === startX) nextX += step;
271
+ while (nextX < endX) {
272
+ const y = Math.sin((nextX + phase) / wl * 2 * Math.PI) * amp;
273
+ d += ` L ${nextX.toFixed(2)} ${y.toFixed(2)}`;
274
+ nextX += step;
275
+ }
276
+ const yEnd = Math.sin((endX + phase) / wl * 2 * Math.PI) * amp;
277
+ d += ` L ${endX.toFixed(2)} ${yEnd.toFixed(2)}`;
278
+ return d;
279
+ }
280
+ var CircularProgress = React6.forwardRef(
281
+ (_a, ref) => {
282
+ var _b = _a, {
283
+ value,
284
+ size = 48,
285
+ trackHeight = 4,
286
+ shape = "flat",
287
+ amplitude,
288
+ wavelength,
289
+ gapSize = 4,
290
+ crawlerSpeed = 1,
291
+ color,
292
+ trackColor,
293
+ className,
294
+ "aria-label": ariaLabel
295
+ } = _b, restProps = __objRest(_b, [
296
+ "value",
297
+ "size",
298
+ "trackHeight",
299
+ "shape",
300
+ "amplitude",
301
+ "wavelength",
302
+ "gapSize",
303
+ "crawlerSpeed",
304
+ "color",
305
+ "trackColor",
306
+ "className",
307
+ "aria-label"
308
+ ]);
309
+ const isDeterminate = value !== void 0;
310
+ const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
311
+ const radius = (size - trackHeight) / 2;
312
+ const center = size / 2;
313
+ const activeColor = color || "var(--md-sys-color-indicator-active)";
314
+ const bgTrackColor = trackColor || "var(--md-sys-color-indicator-track)";
315
+ const isWavy = shape === "wavy";
316
+ const BASELINE_SIZE = 48;
317
+ const scaleFactor = size / BASELINE_SIZE;
318
+ const effectiveAmplitude = React6.useMemo(
319
+ () => amplitude != null ? amplitude : 1.6 * scaleFactor,
320
+ [amplitude, scaleFactor]
321
+ );
322
+ const effectiveWavelength = React6.useMemo(
323
+ () => wavelength != null ? wavelength : 15 * scaleFactor,
324
+ [wavelength, scaleFactor]
325
+ );
326
+ const wavyActivePath = React6.useMemo(
327
+ () => isWavy ? generateWavyCircularPath(
328
+ center,
329
+ radius,
330
+ effectiveAmplitude,
331
+ effectiveWavelength
332
+ ) : null,
333
+ [isWavy, center, radius, effectiveAmplitude, effectiveWavelength]
334
+ );
335
+ const circumference = React6.useMemo(() => 2 * Math.PI * radius, [radius]);
336
+ const gapForTrack = React6.useMemo(
337
+ () => (gapSize + trackHeight) / circumference,
338
+ [gapSize, trackHeight, circumference]
339
+ );
340
+ const activeAngularFraction = isDeterminate ? clampedValue / 100 : 0;
341
+ const trackOffset = isDeterminate ? activeAngularFraction + gapForTrack : 0;
342
+ const trackLength = isDeterminate ? Math.max(1e-3, 1 - activeAngularFraction - 2 * gapForTrack) : 1;
343
+ const ActiveCircleElem = m.circle;
344
+ const ActivePathElem = m.path;
345
+ return /* @__PURE__ */ jsx(
346
+ "div",
347
+ __spreadProps(__spreadValues({
348
+ ref,
349
+ role: "progressbar",
350
+ "aria-label": ariaLabel,
351
+ "aria-valuenow": isDeterminate ? clampedValue : void 0,
352
+ "aria-valuemin": 0,
353
+ "aria-valuemax": 100,
354
+ className: cn(
355
+ "relative inline-flex items-center justify-center shrink-0",
356
+ className
357
+ ),
358
+ style: { width: size, height: size }
359
+ }, restProps), {
360
+ children: /* @__PURE__ */ jsxs(LazyMotion, { features: domMax, strict: true, children: [
361
+ /* @__PURE__ */ jsxs(
362
+ "svg",
363
+ {
364
+ width: size,
365
+ height: size,
366
+ viewBox: `0 0 ${size} ${size}`,
367
+ "aria-hidden": "true",
368
+ style: { transform: "rotate(-90deg)", overflow: "visible" },
369
+ children: [
370
+ isDeterminate ? /* @__PURE__ */ jsx(
371
+ m.circle,
372
+ {
373
+ cx: center,
374
+ cy: center,
375
+ r: radius,
376
+ fill: "none",
377
+ stroke: bgTrackColor,
378
+ strokeWidth: trackHeight,
379
+ initial: { pathLength: trackLength, pathOffset: trackOffset },
380
+ animate: { pathLength: trackLength, pathOffset: trackOffset },
381
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] },
382
+ strokeLinecap: "round"
383
+ }
384
+ ) : null,
385
+ isDeterminate && (isWavy ? /* @__PURE__ */ jsx(
386
+ ActivePathElem,
387
+ {
388
+ d: wavyActivePath != null ? wavyActivePath : "",
389
+ fill: "none",
390
+ stroke: activeColor,
391
+ strokeWidth: trackHeight,
392
+ strokeLinecap: "round",
393
+ initial: { pathLength: 0 },
394
+ animate: { pathLength: clampedValue / 100 },
395
+ transition: {
396
+ duration: 0.4,
397
+ ease: [0.2, 0, 0, 1]
398
+ }
399
+ }
400
+ ) : /* @__PURE__ */ jsx(
401
+ ActiveCircleElem,
402
+ {
403
+ cx: center,
404
+ cy: center,
405
+ r: radius,
406
+ fill: "none",
407
+ stroke: activeColor,
408
+ strokeWidth: trackHeight,
409
+ strokeLinecap: "round",
410
+ initial: { pathLength: 0 },
411
+ animate: { pathLength: clampedValue / 100 },
412
+ transition: {
413
+ duration: 0.4,
414
+ ease: [0.2, 0, 0, 1]
415
+ }
416
+ }
417
+ ))
418
+ ]
419
+ }
420
+ ),
421
+ !isDeterminate && /* @__PURE__ */ jsxs(
422
+ m.svg,
423
+ {
424
+ width: size,
425
+ height: size,
426
+ viewBox: `0 0 ${size} ${size}`,
427
+ "aria-hidden": "true",
428
+ style: {
429
+ position: "absolute",
430
+ inset: 0,
431
+ overflow: "visible",
432
+ rotate: "-90deg",
433
+ transformOrigin: "center"
434
+ },
435
+ animate: { rotate: ["-90deg", "270deg"] },
436
+ transition: {
437
+ rotate: {
438
+ duration: 2 / Math.max(0.1, crawlerSpeed),
439
+ repeat: Number.POSITIVE_INFINITY,
440
+ ease: "linear"
441
+ }
442
+ },
443
+ children: [
444
+ /* @__PURE__ */ jsx(
445
+ m.circle,
446
+ {
447
+ cx: center,
448
+ cy: center,
449
+ r: radius,
450
+ fill: "none",
451
+ stroke: bgTrackColor,
452
+ strokeWidth: trackHeight,
453
+ strokeLinecap: "round",
454
+ style: { originX: "50%", originY: "50%" },
455
+ animate: {
456
+ pathLength: [
457
+ Math.max(1e-3, 1 - 0.1 - 2 * gapForTrack),
458
+ Math.max(1e-3, 1 - 0.75 - 2 * gapForTrack),
459
+ Math.max(1e-3, 1 - 0.1 - 2 * gapForTrack)
460
+ ],
461
+ rotate: [
462
+ `${(0.1 + gapForTrack) * 360}deg`,
463
+ `${(1 + gapForTrack) * 360}deg`,
464
+ `${(1.1 + gapForTrack) * 360}deg`
465
+ ]
466
+ },
467
+ transition: {
468
+ duration: 2 / Math.max(0.1, crawlerSpeed),
469
+ repeat: Number.POSITIVE_INFINITY,
470
+ ease: [0.4, 0, 0.2, 1]
471
+ }
472
+ }
473
+ ),
474
+ isWavy ? /* @__PURE__ */ jsx(
475
+ ActivePathElem,
476
+ {
477
+ d: wavyActivePath != null ? wavyActivePath : "",
478
+ fill: "none",
479
+ stroke: activeColor,
480
+ strokeWidth: trackHeight,
481
+ strokeLinecap: "round",
482
+ style: { originX: "50%", originY: "50%" },
483
+ animate: {
484
+ pathLength: [0.1, 0.75, 0.1],
485
+ rotate: ["0deg", "90deg", "360deg"]
486
+ },
487
+ transition: {
488
+ duration: 2 / Math.max(0.1, crawlerSpeed),
489
+ repeat: Number.POSITIVE_INFINITY,
490
+ ease: [0.4, 0, 0.2, 1]
491
+ }
492
+ }
493
+ ) : /* @__PURE__ */ jsx(
494
+ ActiveCircleElem,
495
+ {
496
+ cx: center,
497
+ cy: center,
498
+ r: radius,
499
+ fill: "none",
500
+ stroke: activeColor,
501
+ strokeWidth: trackHeight,
502
+ strokeLinecap: "round",
503
+ style: { originX: "50%", originY: "50%" },
504
+ animate: {
505
+ pathLength: [0.1, 0.75, 0.1],
506
+ rotate: ["0deg", "90deg", "360deg"]
507
+ },
508
+ transition: {
509
+ duration: 2 / Math.max(0.1, crawlerSpeed),
510
+ repeat: Number.POSITIVE_INFINITY,
511
+ ease: [0.4, 0, 0.2, 1]
512
+ }
513
+ }
514
+ )
515
+ ]
516
+ }
517
+ )
518
+ ] })
519
+ })
520
+ );
521
+ }
522
+ );
523
+ CircularProgress.displayName = "CircularProgress";
524
+ function useContainerWidth() {
525
+ const [width, setWidth] = React6.useState(0);
526
+ const observerRef = React6.useRef(null);
527
+ const ref = React6.useCallback((node) => {
528
+ if (observerRef.current) {
529
+ observerRef.current.disconnect();
530
+ observerRef.current = null;
531
+ }
532
+ if (node) {
533
+ const obs = new ResizeObserver((entries) => {
534
+ const contentRect = entries[0].contentRect;
535
+ setWidth(contentRect.width);
536
+ });
537
+ obs.observe(node);
538
+ observerRef.current = obs;
539
+ }
540
+ }, []);
541
+ React6.useEffect(() => {
542
+ return () => {
543
+ if (observerRef.current) {
544
+ observerRef.current.disconnect();
545
+ }
546
+ };
547
+ }, []);
548
+ return [ref, width];
549
+ }
550
+ function useMergedRef(...refs) {
551
+ return React6.useCallback(
552
+ (node) => {
553
+ for (const ref of refs) {
554
+ if (typeof ref === "function") {
555
+ ref(node);
556
+ } else if (ref && typeof ref === "object") {
557
+ ref.current = node;
558
+ }
559
+ }
560
+ },
561
+ // eslint-disable-next-line react-hooks/exhaustive-deps
562
+ [refs]
563
+ );
564
+ }
565
+ var FlatLinearTrack = React6.memo(function FlatLinearTrack2({
566
+ trackHeight,
567
+ activeColor,
568
+ trackColor,
569
+ value,
570
+ isRtl,
571
+ gapSize,
572
+ crawlerSpeed
573
+ }) {
574
+ const isDeterminate = value !== void 0;
575
+ const radius = trackHeight / 2;
576
+ const minActiveWidth = trackHeight;
577
+ return /* @__PURE__ */ jsx(
578
+ "div",
579
+ {
580
+ className: "relative w-full overflow-hidden",
581
+ style: { height: trackHeight, borderRadius: radius },
582
+ children: isDeterminate ? /* @__PURE__ */ jsxs(Fragment, { children: [
583
+ /* @__PURE__ */ jsx(
584
+ m.div,
585
+ {
586
+ className: "absolute inset-y-0",
587
+ style: {
588
+ backgroundColor: trackColor,
589
+ borderRadius: radius,
590
+ width: "100%"
591
+ },
592
+ initial: {
593
+ [isRtl ? "right" : "left"]: `calc(max(${minActiveWidth}px, 0%) + ${gapSize}px)`
594
+ },
595
+ animate: {
596
+ [isRtl ? "right" : "left"]: `calc(max(${minActiveWidth}px, ${value}%) + ${gapSize}px)`
597
+ },
598
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] }
599
+ }
600
+ ),
601
+ /* @__PURE__ */ jsx(
602
+ m.div,
603
+ {
604
+ className: "absolute inset-y-0",
605
+ style: __spreadValues({
606
+ backgroundColor: activeColor,
607
+ borderRadius: radius,
608
+ minWidth: minActiveWidth
609
+ }, isRtl ? { right: 0 } : { left: 0 }),
610
+ initial: { width: `${minActiveWidth}px` },
611
+ animate: { width: `${value}%` },
612
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] }
613
+ }
614
+ )
615
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
616
+ /* @__PURE__ */ jsx(
617
+ "div",
618
+ {
619
+ className: "absolute inset-0",
620
+ style: { backgroundColor: trackColor, borderRadius: radius }
621
+ }
622
+ ),
623
+ /* @__PURE__ */ jsx(
624
+ m.div,
625
+ {
626
+ className: "absolute inset-y-0",
627
+ style: { backgroundColor: activeColor, borderRadius: radius },
628
+ initial: { left: "-40%", width: "40%" },
629
+ animate: { left: ["-40%", "100%"], width: ["40%", "20%", "40%"] },
630
+ transition: {
631
+ duration: 2 / Math.max(0.1, crawlerSpeed),
632
+ repeat: Number.POSITIVE_INFINITY,
633
+ ease: "easeInOut"
634
+ }
635
+ }
636
+ )
637
+ ] })
638
+ }
639
+ );
640
+ });
641
+ var WavyLinearTrack = React6.memo(function WavyLinearTrack2({
642
+ trackHeight,
643
+ svgHeight,
644
+ amplitude,
645
+ wavelength,
646
+ indeterminateWavelength,
647
+ activeColor,
648
+ trackColor,
649
+ value,
650
+ isRtl,
651
+ gapSize,
652
+ waveSpeed,
653
+ crawlerSpeed,
654
+ determinateAnimation,
655
+ indeterminateAnimation,
656
+ trackShape
657
+ }) {
658
+ const isDeterminate = typeof value === "number";
659
+ const clampedValue = isDeterminate ? Math.max(0, Math.min(100, value)) : 100;
660
+ const titleId = React6.useId();
661
+ const [containerRef, width] = useContainerWidth();
662
+ const activePathRef = React6.useRef(null);
663
+ const trackPathRef = React6.useRef(null);
664
+ const amplitudeMV = useMotionValue(amplitude);
665
+ const fractionMV = useMotionValue(isDeterminate ? clampedValue / 100 : 1);
666
+ React6.useEffect(() => {
667
+ if (isDeterminate) {
668
+ const fraction = clampedValue / 100;
669
+ let targetAmp = amplitude;
670
+ if (determinateAnimation === "md3") {
671
+ targetAmp = fraction <= 0.1 || fraction >= 0.95 ? 0 : amplitude;
672
+ }
673
+ animate(amplitudeMV, targetAmp, {
674
+ type: "spring",
675
+ bounce: 0,
676
+ duration: 0.5
677
+ });
678
+ animate(fractionMV, fraction, { duration: 0.4, ease: [0.2, 0, 0, 1] });
679
+ }
680
+ }, [
681
+ clampedValue,
682
+ isDeterminate,
683
+ amplitude,
684
+ amplitudeMV,
685
+ fractionMV,
686
+ determinateAnimation
687
+ ]);
688
+ const activeWavelength = Math.max(
689
+ 1,
690
+ isDeterminate ? wavelength : indeterminateWavelength
691
+ );
692
+ const trackAmp = trackShape === "wavy" ? amplitude : 0;
693
+ useAnimationFrame((time) => {
694
+ if (width === 0) return;
695
+ const currentAmp = amplitudeMV.get();
696
+ const phase = time / 1e3 * waveSpeed * activeWavelength;
697
+ const capWidth = trackHeight / 2;
698
+ let activePathD = "";
699
+ let trackD = "";
700
+ const totalGap = gapSize + trackHeight;
701
+ if (isDeterminate) {
702
+ const fraction = fractionMV.get();
703
+ const barHead = fraction * width;
704
+ const adjHead = Math.max(capWidth, Math.min(width - capWidth, barHead));
705
+ const adjTail = capWidth;
706
+ if (fraction > 0 && adjHead - adjTail > 0.1) {
707
+ activePathD = getSinePath(
708
+ adjTail,
709
+ adjHead,
710
+ phase,
711
+ activeWavelength,
712
+ currentAmp
713
+ );
714
+ } else if (fraction === 0) {
715
+ activePathD = `M ${capWidth} 0 L ${capWidth + 0.01} 0`;
716
+ }
717
+ const trackStart = adjHead + totalGap;
718
+ if (trackStart < width - capWidth) {
719
+ trackD = getSinePath(
720
+ trackStart,
721
+ width - capWidth,
722
+ phase,
723
+ activeWavelength,
724
+ trackAmp
725
+ );
726
+ }
727
+ } else {
728
+ const safeCrawlerSpeed = Math.max(0.1, crawlerSpeed);
729
+ const activeLines = [];
730
+ if (indeterminateAnimation === "continuous") {
731
+ const cycle = 2e3 / safeCrawlerSpeed;
732
+ const fraction = time % cycle / cycle;
733
+ activeLines.push({
734
+ tail: easeInOutCubic(Math.max(0, fraction * 1.5 - 0.5)),
735
+ head: easeInOutCubic(Math.min(1, fraction * 1.5))
736
+ });
737
+ } else {
738
+ const cycle = 1750 / safeCrawlerSpeed;
739
+ const t = time % cycle * safeCrawlerSpeed;
740
+ const l1H = easeInOutCubic(Math.max(0, Math.min(1, t / 1e3)));
741
+ const l1T = easeInOutCubic(Math.max(0, Math.min(1, (t - 250) / 1e3)));
742
+ const l2H = easeInOutCubic(Math.max(0, Math.min(1, (t - 650) / 850)));
743
+ const l2T = easeInOutCubic(Math.max(0, Math.min(1, (t - 900) / 850)));
744
+ activeLines.push({ tail: l1T, head: l1H });
745
+ activeLines.push({ tail: l2T, head: l2H });
746
+ }
747
+ const segments = activeLines.map((line) => {
748
+ const barTail = line.tail * width;
749
+ const barHead = line.head * width;
750
+ const adjTail = Math.max(
751
+ capWidth,
752
+ Math.min(width - capWidth, barTail)
753
+ );
754
+ const adjHead = Math.max(
755
+ capWidth,
756
+ Math.min(width - capWidth, barHead)
757
+ );
758
+ return { adjTail, adjHead };
759
+ }).filter((seg) => seg.adjHead - seg.adjTail > 0.1);
760
+ activePathD = segments.map(
761
+ (seg) => getSinePath(
762
+ seg.adjTail,
763
+ seg.adjHead,
764
+ phase,
765
+ activeWavelength,
766
+ currentAmp
767
+ )
768
+ ).join(" ");
769
+ let currentTrackX = capWidth;
770
+ for (const seg of segments) {
771
+ const trackEnd = seg.adjTail - totalGap;
772
+ if (trackEnd > currentTrackX) {
773
+ trackD += `${getSinePath(currentTrackX, trackEnd, phase, activeWavelength, trackAmp)} `;
774
+ }
775
+ currentTrackX = Math.max(currentTrackX, seg.adjHead + totalGap);
776
+ }
777
+ if (currentTrackX < width - capWidth) {
778
+ trackD += getSinePath(
779
+ currentTrackX,
780
+ width - capWidth,
781
+ phase,
782
+ activeWavelength,
783
+ trackAmp
784
+ );
785
+ }
786
+ }
787
+ if (activePathRef.current)
788
+ activePathRef.current.setAttribute("d", activePathD);
789
+ if (trackPathRef.current)
790
+ trackPathRef.current.setAttribute("d", trackD.trim());
791
+ });
792
+ return /* @__PURE__ */ jsx(
793
+ "div",
794
+ {
795
+ ref: containerRef,
796
+ className: "relative w-full overflow-hidden",
797
+ style: { height: svgHeight },
798
+ children: width > 0 && /* @__PURE__ */ jsxs(
799
+ "svg",
800
+ {
801
+ className: "absolute inset-0 w-full h-full",
802
+ style: {
803
+ overflow: "visible",
804
+ transform: isRtl ? "scaleX(-1)" : void 0
805
+ },
806
+ "aria-labelledby": titleId,
807
+ children: [
808
+ /* @__PURE__ */ jsx("title", { id: titleId, children: isDeterminate ? `Progress: ${clampedValue}%` : "Indeterminate loading progress" }),
809
+ /* @__PURE__ */ jsxs("g", { transform: `translate(0, ${svgHeight / 2})`, children: [
810
+ /* @__PURE__ */ jsx(
811
+ "path",
812
+ {
813
+ ref: trackPathRef,
814
+ fill: "none",
815
+ stroke: trackColor,
816
+ strokeWidth: trackHeight,
817
+ strokeLinecap: "round"
818
+ }
819
+ ),
820
+ /* @__PURE__ */ jsx(
821
+ "path",
822
+ {
823
+ ref: activePathRef,
824
+ fill: "none",
825
+ stroke: activeColor,
826
+ strokeWidth: trackHeight,
827
+ strokeLinecap: "round"
828
+ }
829
+ )
830
+ ] })
831
+ ]
832
+ }
833
+ )
834
+ }
835
+ );
836
+ });
837
+ var LinearProgress = React6.forwardRef(
838
+ (_a, ref) => {
839
+ var _b = _a, {
840
+ value,
841
+ shape = "flat",
842
+ trackShape,
843
+ trackHeight = 4,
844
+ amplitude,
845
+ wavelength = 40,
846
+ indeterminateWavelength = 20,
847
+ waveSpeed = 1,
848
+ crawlerSpeed = 1,
849
+ determinateAnimation = "md3",
850
+ indeterminateAnimation = "continuous",
851
+ gapSize = 4,
852
+ showStopIndicator = "auto",
853
+ color,
854
+ trackColor,
855
+ className,
856
+ "aria-label": ariaLabel
857
+ } = _b, restProps = __objRest(_b, [
858
+ "value",
859
+ "shape",
860
+ "trackShape",
861
+ "trackHeight",
862
+ "amplitude",
863
+ "wavelength",
864
+ "indeterminateWavelength",
865
+ "waveSpeed",
866
+ "crawlerSpeed",
867
+ "determinateAnimation",
868
+ "indeterminateAnimation",
869
+ "gapSize",
870
+ "showStopIndicator",
871
+ "color",
872
+ "trackColor",
873
+ "className",
874
+ "aria-label"
875
+ ]);
876
+ const isDeterminate = value !== void 0;
877
+ const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
878
+ const containerRef = React6.useRef(null);
879
+ const mergedRef = useMergedRef(ref, containerRef);
880
+ const [isRtl, setIsRtl] = React6.useState(false);
881
+ React6.useEffect(() => {
882
+ if (containerRef.current) {
883
+ const dir = getComputedStyle(containerRef.current).direction;
884
+ setIsRtl(dir === "rtl");
885
+ }
886
+ }, []);
887
+ const isWavy = shape === "wavy";
888
+ const resolvedTrackShape = trackShape != null ? trackShape : shape;
889
+ const effectiveAmplitude = React6.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
890
+ const svgHeight = React6.useMemo(
891
+ () => isWavy ? trackHeight + effectiveAmplitude * 2 : trackHeight,
892
+ [isWavy, trackHeight, effectiveAmplitude]
893
+ );
894
+ const shouldShowStop = React6.useMemo(
895
+ () => isDeterminate && resolvedTrackShape === "flat" && (showStopIndicator === true || showStopIndicator === "auto" && isDeterminate),
896
+ [isDeterminate, resolvedTrackShape, showStopIndicator]
897
+ );
898
+ const stopSize = React6.useMemo(
899
+ () => Math.max(2, trackHeight > 4 ? 4 : trackHeight / 2),
900
+ [trackHeight]
901
+ );
902
+ const stopOffset = (trackHeight - stopSize) / 2;
903
+ const activeColor = color || "var(--md-sys-color-indicator-active)";
904
+ const bgTrackColor = trackColor || "var(--md-sys-color-indicator-track)";
905
+ return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsxs(
906
+ "div",
907
+ __spreadProps(__spreadValues({
908
+ ref: mergedRef,
909
+ role: "progressbar",
910
+ "aria-label": ariaLabel,
911
+ "aria-valuenow": isDeterminate ? clampedValue : void 0,
912
+ "aria-valuemin": 0,
913
+ "aria-valuemax": 100,
914
+ className: cn(
915
+ "relative flex w-full flex-col justify-center",
916
+ className
917
+ ),
918
+ style: { height: svgHeight }
919
+ }, restProps), {
920
+ children: [
921
+ isWavy ? /* @__PURE__ */ jsx(
922
+ WavyLinearTrack,
923
+ {
924
+ trackHeight,
925
+ svgHeight,
926
+ amplitude: effectiveAmplitude,
927
+ wavelength,
928
+ indeterminateWavelength,
929
+ activeColor,
930
+ trackColor: bgTrackColor,
931
+ value: isDeterminate ? clampedValue : void 0,
932
+ isRtl,
933
+ gapSize,
934
+ waveSpeed,
935
+ crawlerSpeed,
936
+ determinateAnimation,
937
+ indeterminateAnimation,
938
+ trackShape: resolvedTrackShape
939
+ }
940
+ ) : /* @__PURE__ */ jsx(
941
+ FlatLinearTrack,
942
+ {
943
+ trackHeight,
944
+ activeColor,
945
+ trackColor: bgTrackColor,
946
+ value: isDeterminate ? clampedValue : void 0,
947
+ isRtl,
948
+ gapSize,
949
+ crawlerSpeed
950
+ }
951
+ ),
952
+ shouldShowStop && /* @__PURE__ */ jsx(
953
+ "div",
954
+ {
955
+ "aria-hidden": "true",
956
+ className: "absolute rounded-full",
957
+ style: __spreadValues({
958
+ width: stopSize,
959
+ height: stopSize,
960
+ backgroundColor: "var(--md-sys-color-indicator-stop)",
961
+ top: svgHeight / 2 - stopSize / 2
962
+ }, isRtl ? { left: stopOffset } : { right: stopOffset })
963
+ }
964
+ )
965
+ ]
966
+ })
967
+ ) });
968
+ }
969
+ );
970
+ LinearProgress.displayName = "LinearProgress";
971
+ var ProgressIndicator = React6.forwardRef((props, ref) => {
972
+ if (props.variant === "circular") {
973
+ return /* @__PURE__ */ jsx(CircularProgress, __spreadValues({ ref }, props));
974
+ }
975
+ return /* @__PURE__ */ jsx(LinearProgress, __spreadValues({ ref }, props));
976
+ });
977
+ ProgressIndicator.displayName = "ProgressIndicator";
978
+ var RippleItem = React6.memo(function RippleItem2({
979
+ ripple,
980
+ onDone
981
+ }) {
982
+ return /* @__PURE__ */ jsx(
983
+ m.span,
984
+ {
985
+ "aria-hidden": "true",
986
+ style: {
987
+ position: "absolute",
988
+ left: ripple.x - ripple.size / 2,
989
+ top: ripple.y - ripple.size / 2,
990
+ width: ripple.size,
991
+ height: ripple.size,
992
+ borderRadius: "50%",
993
+ backgroundColor: "currentColor",
994
+ pointerEvents: "none",
995
+ transformOrigin: "center"
996
+ },
997
+ initial: { scale: 0, opacity: 0.12 },
998
+ animate: { scale: 1, opacity: 0 },
999
+ exit: { opacity: 0 },
1000
+ transition: {
1001
+ scale: { duration: 0.5, ease: [0.2, 0, 0, 1] },
1002
+ opacity: { duration: 0.4, ease: "easeOut", delay: 0.1 }
1003
+ },
1004
+ onAnimationComplete: () => onDone(ripple.id)
1005
+ },
1006
+ ripple.id
1007
+ );
1008
+ });
1009
+ function Ripple({
1010
+ ripples,
1011
+ onRippleDone,
1012
+ disabled = false,
1013
+ respectSystemMotion = true
1014
+ }) {
1015
+ const prefersReduced = useReducedMotion();
1016
+ if (disabled) return null;
1017
+ if (respectSystemMotion && prefersReduced) return null;
1018
+ return /* @__PURE__ */ jsx(AnimatePresence, { children: ripples.map((r) => /* @__PURE__ */ jsx(RippleItem, { ripple: r, onDone: onRippleDone }, r.id)) });
1019
+ }
1020
+ function useRippleState(options = {}) {
1021
+ const { disabled = false } = options;
1022
+ const [ripples, setRipples] = React6.useState([]);
1023
+ const onPointerDown = React6.useCallback(
1024
+ (e) => {
1025
+ if (disabled) return;
1026
+ const rect = e.currentTarget.getBoundingClientRect();
1027
+ const x = e.clientX - rect.left;
1028
+ const y = e.clientY - rect.top;
1029
+ const rippleSize = Math.hypot(rect.width, rect.height) * 2;
1030
+ setRipples((prev) => [
1031
+ ...prev,
1032
+ { id: Date.now(), x, y, size: rippleSize }
1033
+ ]);
1034
+ },
1035
+ [disabled]
1036
+ );
1037
+ const removeRipple = React6.useCallback((id) => {
1038
+ setRipples((prev) => prev.filter((r) => r.id !== id));
1039
+ }, []);
1040
+ return { ripples, onPointerDown, removeRipple };
1041
+ }
1042
+
1043
+ // src/ui/shared/motion-tokens.ts
1044
+ var DEFAULT_SPATIAL_SPRING = {
1045
+ type: "spring",
1046
+ stiffness: 380,
1047
+ damping: 31.19
1048
+ };
1049
+ var FAST_EFFECTS_SPRING = {
1050
+ type: "spring",
1051
+ stiffness: 3800,
1052
+ damping: 123.29
1053
+ };
1054
+ var DEFAULT_EFFECTS_SPRING = {
1055
+ type: "spring",
1056
+ stiffness: 1600,
1057
+ damping: 80
1058
+ };
1059
+ var CSS_CURVES = {
1060
+ expressive: {
1061
+ fast: {
1062
+ spatial: {
1063
+ curve: "cubic-bezier(0.42, 1.67, 0.21, 0.90)",
1064
+ durationMs: 350
1065
+ },
1066
+ effects: {
1067
+ curve: "cubic-bezier(0.31, 0.94, 0.34, 1.00)",
1068
+ durationMs: 150
1069
+ }
1070
+ },
1071
+ default: {
1072
+ spatial: {
1073
+ curve: "cubic-bezier(0.38, 1.21, 0.22, 1.00)",
1074
+ durationMs: 500
1075
+ },
1076
+ effects: {
1077
+ curve: "cubic-bezier(0.34, 0.80, 0.34, 1.00)",
1078
+ durationMs: 200
1079
+ }
1080
+ },
1081
+ slow: {
1082
+ spatial: {
1083
+ curve: "cubic-bezier(0.39, 1.29, 0.35, 0.98)",
1084
+ durationMs: 650
1085
+ },
1086
+ effects: {
1087
+ curve: "cubic-bezier(0.34, 0.88, 0.34, 1.00)",
1088
+ durationMs: 300
1089
+ }
1090
+ }
1091
+ },
1092
+ standard: {
1093
+ fast: {
1094
+ spatial: {
1095
+ curve: "cubic-bezier(0.27, 1.06, 0.18, 1.00)",
1096
+ durationMs: 350
1097
+ },
1098
+ effects: {
1099
+ curve: "cubic-bezier(0.31, 0.94, 0.34, 1.00)",
1100
+ durationMs: 150
1101
+ }
1102
+ },
1103
+ default: {
1104
+ spatial: {
1105
+ curve: "cubic-bezier(0.27, 1.06, 0.18, 1.00)",
1106
+ durationMs: 500
1107
+ },
1108
+ effects: {
1109
+ curve: "cubic-bezier(0.34, 0.80, 0.34, 1.00)",
1110
+ durationMs: 200
1111
+ }
1112
+ },
1113
+ slow: {
1114
+ spatial: {
1115
+ curve: "cubic-bezier(0.27, 1.06, 0.18, 1.00)",
1116
+ durationMs: 750
1117
+ },
1118
+ effects: {
1119
+ curve: "cubic-bezier(0.34, 0.88, 0.34, 1.00)",
1120
+ durationMs: 300
1121
+ }
1122
+ }
1123
+ }
1124
+ };
1125
+ function getMotionTransitionCSS(speed, type, scheme = "expressive") {
1126
+ const { curve, durationMs } = CSS_CURVES[scheme][speed][type];
1127
+ return `${durationMs}ms ${curve}`;
1128
+ }
1129
+
1130
+ // src/ui/shared/constants.ts
1131
+ var SPRING_TRANSITION_FAST = FAST_EFFECTS_SPRING;
1132
+ var SPRING_TRANSITION = DEFAULT_EFFECTS_SPRING;
1133
+ var ICON_SPAN_VARIANTS = {
1134
+ initial: { scale: 0.01 },
1135
+ animate: { scale: 1 },
1136
+ exit: { scale: 0.01 }
1137
+ };
1138
+ function TouchTarget() {
1139
+ return /* @__PURE__ */ jsx(
1140
+ "span",
1141
+ {
1142
+ "aria-hidden": "true",
1143
+ className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 min-w-12 min-h-12 cursor-pointer pointer-events-none"
1144
+ }
1145
+ );
1146
+ }
1147
+ var SIZE_STYLES = {
1148
+ xs: "h-8 w-8",
1149
+ sm: "h-10 w-10",
1150
+ md: "h-14 w-14",
1151
+ lg: "h-24 w-24",
1152
+ xl: "h-[8.5rem] w-[8.5rem]"
1153
+ };
1154
+ var SIZE_ICON = {
1155
+ xs: { cls: "size-5", px: 20 },
1156
+ sm: { cls: "size-6", px: 24 },
1157
+ md: { cls: "size-6", px: 24 },
1158
+ lg: { cls: "size-8", px: 32 },
1159
+ xl: { cls: "size-10", px: 40 }
1160
+ };
1161
+ var RADIUS_MAP = {
1162
+ xs: {
1163
+ round: 16,
1164
+ square: 12,
1165
+ pressed: 8,
1166
+ selectedRound: 12,
1167
+ selectedSquare: 16
1168
+ },
1169
+ sm: {
1170
+ round: 20,
1171
+ square: 12,
1172
+ pressed: 8,
1173
+ selectedRound: 12,
1174
+ selectedSquare: 20
1175
+ },
1176
+ md: {
1177
+ round: 28,
1178
+ square: 16,
1179
+ pressed: 12,
1180
+ selectedRound: 16,
1181
+ selectedSquare: 28
1182
+ },
1183
+ lg: {
1184
+ round: 48,
1185
+ square: 28,
1186
+ pressed: 16,
1187
+ selectedRound: 28,
1188
+ selectedSquare: 48
1189
+ },
1190
+ xl: {
1191
+ round: 68,
1192
+ square: 28,
1193
+ pressed: 16,
1194
+ selectedRound: 28,
1195
+ selectedSquare: 68
1196
+ }
1197
+ };
1198
+ var SIZE_OUTLINE_WIDTH = {
1199
+ xs: "border",
1200
+ sm: "border",
1201
+ md: "border",
1202
+ lg: "border-2",
1203
+ xl: "border-[3px]"
1204
+ };
1205
+ var colorStyles = {
1206
+ standard: {
1207
+ default: "text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
1208
+ selected: "text-m3-primary hover:bg-m3-primary/8 active:bg-m3-primary/12"
1209
+ },
1210
+ filled: {
1211
+ default: "bg-m3-surface-container text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
1212
+ selected: "bg-m3-primary text-m3-on-primary hover:brightness-95 active:brightness-90"
1213
+ },
1214
+ tonal: {
1215
+ default: "bg-m3-secondary-container text-m3-on-secondary-container hover:bg-m3-on-secondary-container/8 active:bg-m3-on-secondary-container/12",
1216
+ selected: "bg-m3-secondary text-m3-on-secondary hover:brightness-95 active:brightness-90"
1217
+ },
1218
+ outlined: {
1219
+ default: "border-m3-outline-variant text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
1220
+ selected: "bg-m3-inverse-surface text-m3-inverse-on-surface border-transparent hover:brightness-95 active:brightness-90"
1221
+ }
1222
+ };
1223
+ var baseIconButtonClasses = [
1224
+ "relative shrink-0 inline-flex items-center justify-center",
1225
+ "select-none cursor-pointer",
1226
+ "transition-[background-color,color,border-color,box-shadow,opacity,filter] duration-200",
1227
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2",
1228
+ "disabled:pointer-events-none disabled:opacity-[0.38]"
1229
+ ];
1230
+ function resolveAnimateRadius(radiusConfig, shape, isToggle, isSelected) {
1231
+ if (isToggle && isSelected) {
1232
+ return shape === "round" ? radiusConfig.selectedRound : radiusConfig.selectedSquare;
1233
+ }
1234
+ return shape === "round" ? radiusConfig.round : radiusConfig.square;
1235
+ }
1236
+ function resolveDisabledBgClass(colorStyle) {
1237
+ if (colorStyle === "filled" || colorStyle === "tonal") {
1238
+ return "disabled:bg-m3-on-surface/12 disabled:text-m3-on-surface/[0.38]";
1239
+ }
1240
+ if (colorStyle === "outlined") {
1241
+ return "disabled:text-m3-on-surface/[0.38] disabled:border-m3-on-surface/[0.12]";
1242
+ }
1243
+ return "disabled:text-m3-on-surface/[0.38]";
1244
+ }
1245
+ var IconButtonComponent = React6.forwardRef(
1246
+ (_a, ref) => {
1247
+ var _b = _a, {
1248
+ className,
1249
+ style,
1250
+ variant = "default",
1251
+ colorStyle = "standard",
1252
+ size = "sm",
1253
+ shape = "round",
1254
+ selected,
1255
+ loading = false,
1256
+ loadingVariant = "loading-indicator",
1257
+ iconSize,
1258
+ children,
1259
+ onClick,
1260
+ onKeyDown,
1261
+ "aria-label": ariaLabel
1262
+ } = _b, restProps = __objRest(_b, [
1263
+ "className",
1264
+ "style",
1265
+ "variant",
1266
+ "colorStyle",
1267
+ "size",
1268
+ "shape",
1269
+ "selected",
1270
+ "loading",
1271
+ "loadingVariant",
1272
+ "iconSize",
1273
+ "children",
1274
+ "onClick",
1275
+ "onKeyDown",
1276
+ "aria-label"
1277
+ ]);
1278
+ var _a2, _b2;
1279
+ const isToggle = variant === "toggle";
1280
+ const isSelected = isToggle && !!selected;
1281
+ const resolvedColorClass = React6.useMemo(
1282
+ () => isSelected ? colorStyles[colorStyle].selected : colorStyles[colorStyle].default,
1283
+ [isSelected, colorStyle]
1284
+ );
1285
+ const outlineWidthClass = React6.useMemo(
1286
+ () => {
1287
+ var _a3;
1288
+ return colorStyle === "outlined" && !isSelected ? (_a3 = SIZE_OUTLINE_WIDTH[size]) != null ? _a3 : "border" : "";
1289
+ },
1290
+ [colorStyle, isSelected, size]
1291
+ );
1292
+ const disabledBgClass = React6.useMemo(
1293
+ () => resolveDisabledBgClass(colorStyle),
1294
+ [colorStyle]
1295
+ );
1296
+ const radiusConfig = (_a2 = RADIUS_MAP[size]) != null ? _a2 : RADIUS_MAP.sm;
1297
+ const animateRadius = resolveAnimateRadius(
1298
+ radiusConfig,
1299
+ shape,
1300
+ isToggle,
1301
+ isSelected
1302
+ );
1303
+ const pressedRadius = radiusConfig.pressed;
1304
+ const sizeIcon = (_b2 = SIZE_ICON[size]) != null ? _b2 : SIZE_ICON.sm;
1305
+ const iconClass = sizeIcon.cls;
1306
+ const defaultIconPx = sizeIcon.px;
1307
+ const iconPx = iconSize != null ? iconSize : defaultIconPx;
1308
+ const isCustomSize = iconSize != null && iconSize !== "inherit";
1309
+ const needsTouchTarget = size === "xs" || size === "sm";
1310
+ const { ripples, onPointerDown, removeRipple } = useRippleState({
1311
+ disabled: loading
1312
+ });
1313
+ const handleClick = React6.useCallback(
1314
+ (e) => {
1315
+ if (loading) {
1316
+ e.preventDefault();
1317
+ return;
1318
+ }
1319
+ onClick == null ? void 0 : onClick(e);
1320
+ },
1321
+ [loading, onClick]
1322
+ );
1323
+ const handleKeyDown = React6.useCallback(
1324
+ (e) => {
1325
+ if (loading) return;
1326
+ if ((e.key === "Enter" || e.key === " ") && onClick) {
1327
+ e.preventDefault();
1328
+ e.currentTarget.click();
1329
+ }
1330
+ onKeyDown == null ? void 0 : onKeyDown(e);
1331
+ },
1332
+ [loading, onClick, onKeyDown]
1333
+ );
1334
+ return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsxs(
1335
+ m.button,
1336
+ __spreadProps(__spreadValues({
1337
+ ref,
1338
+ type: "button",
1339
+ "aria-pressed": isToggle ? isSelected : void 0,
1340
+ "aria-label": ariaLabel,
1341
+ "aria-busy": loading || void 0,
1342
+ "aria-disabled": loading || restProps.disabled,
1343
+ onClick: handleClick,
1344
+ onPointerDown,
1345
+ onKeyDown: handleKeyDown,
1346
+ style,
1347
+ animate: { borderRadius: animateRadius },
1348
+ whileTap: { borderRadius: pressedRadius },
1349
+ transition: { borderRadius: SPRING_TRANSITION_FAST },
1350
+ className: cn(
1351
+ baseIconButtonClasses,
1352
+ resolvedColorClass,
1353
+ outlineWidthClass,
1354
+ disabledBgClass,
1355
+ "overflow-hidden",
1356
+ SIZE_STYLES[size],
1357
+ loading && "pointer-events-none opacity-75 cursor-not-allowed",
1358
+ className
1359
+ )
1360
+ }, restProps), {
1361
+ children: [
1362
+ needsTouchTarget && /* @__PURE__ */ jsx(TouchTarget, {}),
1363
+ /* @__PURE__ */ jsx(Ripple, { ripples, onRippleDone: removeRipple }),
1364
+ /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", initial: false, children: loading ? /* @__PURE__ */ jsx(
1365
+ m.span,
1366
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
1367
+ transition: SPRING_TRANSITION,
1368
+ className: cn(
1369
+ "flex items-center justify-center shrink-0",
1370
+ iconSize != null ? void 0 : iconClass
1371
+ ),
1372
+ style: isCustomSize ? { width: `${iconSize}px`, height: `${iconSize}px` } : void 0,
1373
+ children: loadingVariant === "loading-indicator" ? /* @__PURE__ */ jsx(
1374
+ LoadingIndicator,
1375
+ {
1376
+ size: typeof iconPx === "number" ? iconPx : defaultIconPx,
1377
+ color: "currentColor",
1378
+ "aria-label": "Loading"
1379
+ }
1380
+ ) : /* @__PURE__ */ jsx(
1381
+ ProgressIndicator,
1382
+ {
1383
+ variant: "circular",
1384
+ size: typeof iconPx === "number" ? iconPx : defaultIconPx,
1385
+ color: "currentColor",
1386
+ trackColor: "transparent",
1387
+ "aria-label": "Loading"
1388
+ }
1389
+ )
1390
+ }),
1391
+ "loading"
1392
+ ) : /* @__PURE__ */ jsx(
1393
+ m.span,
1394
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
1395
+ transition: SPRING_TRANSITION,
1396
+ "aria-hidden": "true",
1397
+ className: cn(
1398
+ "flex items-center justify-center shrink-0 [&_svg]:w-full [&_svg]:h-full [&_.md-icon]:text-[length:inherit]!",
1399
+ iconSize != null ? void 0 : iconClass
1400
+ ),
1401
+ style: {
1402
+ fontSize: typeof iconPx === "number" ? `${iconPx}px` : iconPx,
1403
+ width: isCustomSize ? `${iconSize}px` : void 0,
1404
+ height: isCustomSize ? `${iconSize}px` : void 0
1405
+ },
1406
+ children
1407
+ }),
1408
+ "content"
1409
+ ) })
1410
+ ]
1411
+ })
1412
+ ) });
1413
+ }
1414
+ );
1415
+ IconButtonComponent.displayName = "IconButton";
1416
+ var IconButton = React6.memo(IconButtonComponent);
1417
+ var VARIANT_FONT = {
1418
+ outlined: "'Material Symbols Outlined'",
1419
+ rounded: "'Material Symbols Rounded'",
1420
+ sharp: "'Material Symbols Sharp'"
1421
+ };
1422
+ var IconComponent = React6.forwardRef(
1423
+ (_a, ref) => {
1424
+ var _b = _a, {
1425
+ name,
1426
+ variant = "outlined",
1427
+ fill = 0,
1428
+ weight = 400,
1429
+ grade = 0,
1430
+ opticalSize = 24,
1431
+ size,
1432
+ animateFill = false,
1433
+ className,
1434
+ style
1435
+ } = _b, restProps = __objRest(_b, [
1436
+ "name",
1437
+ "variant",
1438
+ "fill",
1439
+ "weight",
1440
+ "grade",
1441
+ "opticalSize",
1442
+ "size",
1443
+ "animateFill",
1444
+ "className",
1445
+ "style"
1446
+ ]);
1447
+ const fontVariationSettings = `'FILL' ${fill}, 'wght' ${weight}, 'GRAD' ${grade}, 'opsz' ${opticalSize}`;
1448
+ const computedStyle = __spreadValues({
1449
+ fontFamily: VARIANT_FONT[variant],
1450
+ fontSize: size === "inherit" ? "inherit" : size != null ? `${size}px` : `${opticalSize}px`,
1451
+ fontVariationSettings
1452
+ }, style);
1453
+ if (animateFill) {
1454
+ return /* @__PURE__ */ jsx(LazyMotion, { features: domMax, strict: true, children: /* @__PURE__ */ jsx(
1455
+ m.span,
1456
+ __spreadProps(__spreadValues({
1457
+ ref,
1458
+ className: cn(
1459
+ "md-icon inline-flex items-center justify-center shrink-0 select-none",
1460
+ className
1461
+ ),
1462
+ "aria-hidden": "true",
1463
+ animate: { fontVariationSettings },
1464
+ transition: SPRING_TRANSITION_FAST,
1465
+ style: computedStyle
1466
+ }, restProps), {
1467
+ children: name
1468
+ })
1469
+ ) });
1470
+ }
1471
+ return /* @__PURE__ */ jsx(
1472
+ "span",
1473
+ __spreadProps(__spreadValues({
1474
+ ref,
1475
+ className: cn(
1476
+ "md-icon inline-flex items-center justify-center shrink-0 select-none",
1477
+ className
1478
+ ),
1479
+ "aria-hidden": "true",
1480
+ style: computedStyle
1481
+ }, restProps), {
1482
+ children: name
1483
+ })
1484
+ );
1485
+ }
1486
+ );
1487
+ IconComponent.displayName = "Icon";
1488
+ var Icon = React6.memo(IconComponent);
1489
+ var ScrollArea = React6.forwardRef(
1490
+ (_a, ref) => {
1491
+ var _b = _a, {
1492
+ className,
1493
+ viewportClassName,
1494
+ children,
1495
+ type = "hover",
1496
+ orientation = "vertical",
1497
+ scrollHideDelay = 600,
1498
+ viewportRef,
1499
+ viewportProps
1500
+ } = _b, props = __objRest(_b, [
1501
+ "className",
1502
+ "viewportClassName",
1503
+ "children",
1504
+ "type",
1505
+ "orientation",
1506
+ "scrollHideDelay",
1507
+ "viewportRef",
1508
+ "viewportProps"
1509
+ ]);
1510
+ const [isTouchDevice, setIsTouchDevice] = React6.useState(false);
1511
+ React6.useEffect(() => {
1512
+ if (typeof window !== "undefined") {
1513
+ setIsTouchDevice(
1514
+ "ontouchstart" in window || navigator.maxTouchPoints > 0
1515
+ );
1516
+ }
1517
+ }, []);
1518
+ const resolvedType = React6.useMemo(() => {
1519
+ if (type === "hover" && isTouchDevice) {
1520
+ return "scroll";
1521
+ }
1522
+ return type;
1523
+ }, [type, isTouchDevice]);
1524
+ const radixType = resolvedType === "none" ? "always" : resolvedType;
1525
+ return /* @__PURE__ */ jsxs(
1526
+ RadixScrollArea.Root,
1527
+ __spreadProps(__spreadValues({
1528
+ ref,
1529
+ type: radixType,
1530
+ scrollHideDelay,
1531
+ className: cn("relative overflow-hidden flex flex-col", className)
1532
+ }, props), {
1533
+ children: [
1534
+ /* @__PURE__ */ jsx(
1535
+ RadixScrollArea.Viewport,
1536
+ __spreadProps(__spreadValues({
1537
+ ref: viewportRef
1538
+ }, viewportProps), {
1539
+ className: cn(
1540
+ "h-full w-full flex-1 min-h-0 min-w-0 rounded-[inherit]",
1541
+ "outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-1",
1542
+ viewportClassName,
1543
+ viewportProps == null ? void 0 : viewportProps.className
1544
+ ),
1545
+ children
1546
+ })
1547
+ ),
1548
+ (orientation === "vertical" || orientation === "both") && /* @__PURE__ */ jsx(
1549
+ ScrollAreaScrollbar,
1550
+ {
1551
+ orientation: "vertical",
1552
+ className: resolvedType === "none" ? "hidden" : void 0
1553
+ }
1554
+ ),
1555
+ (orientation === "horizontal" || orientation === "both") && /* @__PURE__ */ jsx(
1556
+ ScrollAreaScrollbar,
1557
+ {
1558
+ orientation: "horizontal",
1559
+ className: resolvedType === "none" ? "hidden" : void 0
1560
+ }
1561
+ ),
1562
+ /* @__PURE__ */ jsx(RadixScrollArea.Corner, { className: "bg-m3-surface-container" })
1563
+ ]
1564
+ })
1565
+ );
1566
+ }
1567
+ );
1568
+ ScrollArea.displayName = "ScrollArea";
1569
+ var ScrollAreaScrollbar = React6.forwardRef((_a, ref) => {
1570
+ var _b = _a, { className, orientation = "vertical" } = _b, props = __objRest(_b, ["className", "orientation"]);
1571
+ return /* @__PURE__ */ jsx(
1572
+ RadixScrollArea.Scrollbar,
1573
+ __spreadProps(__spreadValues({
1574
+ ref,
1575
+ orientation,
1576
+ className: cn(
1577
+ "flex touch-none select-none transition-all duration-300 ease-in-out",
1578
+ "absolute z-50",
1579
+ orientation === "vertical" && "right-0 top-0 bottom-0 w-2.5 border-l border-l-transparent p-px",
1580
+ orientation === "horizontal" && "bottom-0 left-0 right-0 h-2.5 flex-col border-t border-t-transparent p-px",
1581
+ "data-[state=hidden]:opacity-0 data-[state=visible]:opacity-100",
1582
+ className
1583
+ )
1584
+ }, props), {
1585
+ children: /* @__PURE__ */ jsx(
1586
+ RadixScrollArea.Thumb,
1587
+ {
1588
+ className: cn(
1589
+ "relative flex-1 rounded-full bg-m3-on-surface/25 transition-colors duration-200",
1590
+ "hover:bg-m3-on-surface/40 active:bg-m3-on-surface/55",
1591
+ "before:absolute before:left-1/2 before:top-1/2 before:min-h-11 before:min-w-11 before:-translate-x-1/2 before:-translate-y-1/2"
1592
+ )
1593
+ }
1594
+ )
1595
+ })
1596
+ );
1597
+ });
1598
+ ScrollAreaScrollbar.displayName = RadixScrollArea.Scrollbar.displayName;
1599
+ var ScrollAreaCorner = React6.forwardRef((_a, ref) => {
1600
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1601
+ return /* @__PURE__ */ jsx(
1602
+ RadixScrollArea.Corner,
1603
+ __spreadValues({
1604
+ ref,
1605
+ className: cn("bg-m3-surface-container", className)
1606
+ }, props)
1607
+ );
1608
+ });
1609
+ ScrollAreaCorner.displayName = "ScrollAreaCorner";
1610
+ var MD3_SPRING = DEFAULT_SPATIAL_SPRING;
1611
+ var MD3_OVERLAY_ANIM = {
1612
+ initial: { opacity: 0 },
1613
+ animate: {
1614
+ opacity: 1,
1615
+ transition: { duration: 0.2, ease: "easeOut" }
1616
+ },
1617
+ exit: { opacity: 0, transition: { duration: 0.15, ease: "easeIn" } }
1618
+ };
1619
+ var MD3_CONTENT_ANIM = {
1620
+ initial: { opacity: 0, scale: 0.85, y: 24 },
1621
+ animate: { opacity: 1, scale: 1, y: 0, transition: MD3_SPRING },
1622
+ exit: {
1623
+ opacity: 0,
1624
+ scale: 0.95,
1625
+ y: 8,
1626
+ transition: { duration: 0.15, ease: "easeIn" }
1627
+ }
1628
+ };
1629
+ var MD3_FULLSCREEN_ANIM = {
1630
+ initial: { y: "100%" },
1631
+ animate: { y: 0, transition: MD3_SPRING },
1632
+ exit: { y: "100%", transition: { duration: 0.2, ease: "easeIn" } }
1633
+ };
1634
+ var Dialog = ({ open, onOpenChange, children }) => /* @__PURE__ */ jsx(RadixDialog.Root, { open, onOpenChange, children });
1635
+ Dialog.displayName = "Dialog";
1636
+ var DialogTrigger = RadixDialog.Trigger;
1637
+ DialogTrigger.displayName = "DialogTrigger";
1638
+ var DialogPortal = ({
1639
+ open,
1640
+ children
1641
+ }) => /* @__PURE__ */ jsx(RadixDialog.Portal, { forceMount: true, children: /* @__PURE__ */ jsx(AnimatePresence, { children: open ? React6.Children.toArray(children) : null }) });
1642
+ DialogPortal.displayName = "DialogPortal";
1643
+ var DialogOverlay = React6.forwardRef((_a, ref) => {
1644
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1645
+ return /* @__PURE__ */ jsx(RadixDialog.Overlay, __spreadProps(__spreadValues({ ref, asChild: true }, props), { children: /* @__PURE__ */ jsx(
1646
+ m.div,
1647
+ __spreadValues({
1648
+ className: cn("fixed inset-0 z-50 bg-black/32", className),
1649
+ "aria-hidden": "true"
1650
+ }, MD3_OVERLAY_ANIM)
1651
+ ) }));
1652
+ });
1653
+ DialogOverlay.displayName = "DialogOverlay";
1654
+ var DialogContent = React6.forwardRef((_a, ref) => {
1655
+ var _b = _a, { className, children, hideCloseButton = false } = _b, props = __objRest(_b, ["className", "children", "hideCloseButton"]);
1656
+ return /* @__PURE__ */ jsx(
1657
+ RadixDialog.Content,
1658
+ __spreadProps(__spreadValues({
1659
+ ref,
1660
+ asChild: true,
1661
+ "aria-describedby": void 0
1662
+ }, props), {
1663
+ children: /* @__PURE__ */ jsxs(
1664
+ m.div,
1665
+ __spreadProps(__spreadValues({
1666
+ className: cn(
1667
+ "fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2",
1668
+ "w-[calc(100%-2rem)] max-w-140",
1669
+ "rounded-[28px] bg-m3-surface-container-high p-6",
1670
+ "shadow-lg outline-none focus-visible:ring-2 focus-visible:ring-m3-primary",
1671
+ className
1672
+ ),
1673
+ role: "dialog"
1674
+ }, MD3_CONTENT_ANIM), {
1675
+ children: [
1676
+ children,
1677
+ !hideCloseButton && /* @__PURE__ */ jsx(RadixDialog.Close, { asChild: true, "aria-label": "Close dialog", children: /* @__PURE__ */ jsx(
1678
+ IconButton,
1679
+ {
1680
+ size: "sm",
1681
+ colorStyle: "filled",
1682
+ className: "absolute right-4 top-4",
1683
+ "aria-label": "Close",
1684
+ children: /* @__PURE__ */ jsx(Icon, { name: "close", "aria-hidden": "true" })
1685
+ }
1686
+ ) })
1687
+ ]
1688
+ })
1689
+ )
1690
+ })
1691
+ );
1692
+ });
1693
+ DialogContent.displayName = "DialogContent";
1694
+ var DialogIcon = React6.forwardRef((_a, ref) => {
1695
+ var _b = _a, { className, children } = _b, props = __objRest(_b, ["className", "children"]);
1696
+ return /* @__PURE__ */ jsx(
1697
+ "div",
1698
+ __spreadProps(__spreadValues({
1699
+ ref,
1700
+ className: cn("flex justify-center mb-4 text-m3-secondary", className),
1701
+ "aria-hidden": "true"
1702
+ }, props), {
1703
+ children
1704
+ })
1705
+ );
1706
+ });
1707
+ DialogIcon.displayName = "DialogIcon";
1708
+ var DialogHeader = (_a) => {
1709
+ var _b = _a, {
1710
+ className
1711
+ } = _b, props = __objRest(_b, [
1712
+ "className"
1713
+ ]);
1714
+ return /* @__PURE__ */ jsx("div", __spreadValues({ className: cn("flex flex-col gap-2 mb-4", className) }, props));
1715
+ };
1716
+ DialogHeader.displayName = "DialogHeader";
1717
+ var DialogTitle = React6.forwardRef((_a, ref) => {
1718
+ var _b = _a, { className, asChild } = _b, props = __objRest(_b, ["className", "asChild"]);
1719
+ return /* @__PURE__ */ jsx(
1720
+ RadixDialog.Title,
1721
+ __spreadValues({
1722
+ ref,
1723
+ asChild,
1724
+ className: cn(
1725
+ "text-[24px] leading-8 font-normal text-m3-on-surface tracking-[0em]",
1726
+ className
1727
+ )
1728
+ }, props)
1729
+ );
1730
+ });
1731
+ DialogTitle.displayName = "DialogTitle";
1732
+ var DialogDescription = React6.forwardRef((_a, ref) => {
1733
+ var _b = _a, { className, asChild } = _b, props = __objRest(_b, ["className", "asChild"]);
1734
+ return /* @__PURE__ */ jsx(
1735
+ RadixDialog.Description,
1736
+ __spreadValues({
1737
+ ref,
1738
+ asChild,
1739
+ className: cn("text-sm text-m3-on-surface-variant leading-5", className)
1740
+ }, props)
1741
+ );
1742
+ });
1743
+ DialogDescription.displayName = "DialogDescription";
1744
+ var DialogBody = React6.forwardRef((_a, ref) => {
1745
+ var _b = _a, { className, children, dir } = _b, props = __objRest(_b, ["className", "children", "dir"]);
1746
+ return /* @__PURE__ */ jsx(
1747
+ ScrollArea,
1748
+ __spreadProps(__spreadValues({
1749
+ ref,
1750
+ type: "hover",
1751
+ dir,
1752
+ className: cn("max-h-[calc(85dvh-200px)] -mx-6", className),
1753
+ viewportClassName: "px-6"
1754
+ }, props), {
1755
+ children
1756
+ })
1757
+ );
1758
+ });
1759
+ DialogBody.displayName = "DialogBody";
1760
+ var DialogFooter = (_a) => {
1761
+ var _b = _a, {
1762
+ className
1763
+ } = _b, props = __objRest(_b, [
1764
+ "className"
1765
+ ]);
1766
+ return /* @__PURE__ */ jsx(
1767
+ "div",
1768
+ __spreadValues({
1769
+ className: cn("flex flex-row justify-end gap-2 mt-6", className)
1770
+ }, props)
1771
+ );
1772
+ };
1773
+ DialogFooter.displayName = "DialogFooter";
1774
+ var DialogClose = RadixDialog.Close;
1775
+ var DialogFullScreenContent = React6.forwardRef(
1776
+ (_a, ref) => {
1777
+ var _b = _a, {
1778
+ className,
1779
+ children,
1780
+ title,
1781
+ actionLabel,
1782
+ onAction,
1783
+ showDivider
1784
+ } = _b, props = __objRest(_b, [
1785
+ "className",
1786
+ "children",
1787
+ "title",
1788
+ "actionLabel",
1789
+ "onAction",
1790
+ "showDivider"
1791
+ ]);
1792
+ return /* @__PURE__ */ jsx(
1793
+ RadixDialog.Content,
1794
+ __spreadProps(__spreadValues({
1795
+ ref,
1796
+ asChild: true,
1797
+ "aria-describedby": void 0
1798
+ }, props), {
1799
+ children: /* @__PURE__ */ jsxs(
1800
+ m.div,
1801
+ __spreadProps(__spreadValues({
1802
+ className: cn(
1803
+ "fixed inset-0 z-50 w-full h-full bg-m3-surface flex flex-col",
1804
+ "outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-m3-primary",
1805
+ className
1806
+ ),
1807
+ role: "dialog"
1808
+ }, MD3_FULLSCREEN_ANIM), {
1809
+ children: [
1810
+ /* @__PURE__ */ jsxs("div", { className: "flex shrink-0 items-center px-4 h-14 gap-2 bg-m3-surface", children: [
1811
+ /* @__PURE__ */ jsx(RadixDialog.Close, { asChild: true, "aria-label": "Close dialog", children: /* @__PURE__ */ jsx(IconButton, { size: "sm", colorStyle: "filled", "aria-label": "Close", children: /* @__PURE__ */ jsx(Icon, { name: "close", "aria-hidden": "true" }) }) }),
1812
+ title && /* @__PURE__ */ jsx(DialogTitle, { className: "flex-1 text-[22px] leading-7 font-medium truncate pr-2", children: title }),
1813
+ actionLabel && onAction && /* @__PURE__ */ jsx(
1814
+ "button",
1815
+ {
1816
+ type: "button",
1817
+ onClick: onAction,
1818
+ className: "text-sm font-medium text-m3-primary px-3 py-2 rounded-full hover:bg-m3-primary/8 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary transition-colors whitespace-nowrap",
1819
+ children: actionLabel
1820
+ }
1821
+ )
1822
+ ] }),
1823
+ showDivider && /* @__PURE__ */ jsx("hr", { className: "border-m3-outline-variant w-full shrink-0 m-0" }),
1824
+ /* @__PURE__ */ jsx(
1825
+ ScrollArea,
1826
+ {
1827
+ type: "hover",
1828
+ className: "flex-1 w-full",
1829
+ viewportClassName: "p-6",
1830
+ children
1831
+ }
1832
+ )
1833
+ ]
1834
+ })
1835
+ )
1836
+ })
1837
+ );
1838
+ }
1839
+ );
1840
+ DialogFullScreenContent.displayName = "DialogFullScreenContent";
1841
+ var MD3_DRAWER_SPRING = DEFAULT_SPATIAL_SPRING;
1842
+ var MD3_DRAWER_ANIM = {
1843
+ initial: { y: "100%", opacity: 0.6 },
1844
+ animate: {
1845
+ y: 0,
1846
+ opacity: 1,
1847
+ transition: MD3_DRAWER_SPRING
1848
+ },
1849
+ exit: {
1850
+ y: "100%",
1851
+ opacity: 0,
1852
+ transition: { duration: 0.22, ease: "easeIn" }
1853
+ }
1854
+ };
1855
+ var MD3_SCRIM_ANIM = {
1856
+ initial: { opacity: 0 },
1857
+ animate: {
1858
+ opacity: 1,
1859
+ transition: { duration: 0.2, ease: "easeOut" }
1860
+ },
1861
+ exit: { opacity: 0, transition: { duration: 0.18, ease: "easeIn" } }
1862
+ };
1863
+ var Drawer = ({ open, onOpenChange, children }) => /* @__PURE__ */ jsx(RadixDialog.Root, { open, onOpenChange, children });
1864
+ Drawer.displayName = "Drawer";
1865
+ var DrawerTrigger = RadixDialog.Trigger;
1866
+ DrawerTrigger.displayName = "DrawerTrigger";
1867
+ var DrawerClose = RadixDialog.Close;
1868
+ var DrawerPortal = ({
1869
+ open,
1870
+ children
1871
+ }) => /* @__PURE__ */ jsx(RadixDialog.Portal, { forceMount: true, children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: open && children }) });
1872
+ var DrawerOverlay = React6.forwardRef((_a, ref) => {
1873
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1874
+ return /* @__PURE__ */ jsx(RadixDialog.Overlay, __spreadProps(__spreadValues({ ref, asChild: true }, props), { children: /* @__PURE__ */ jsx(
1875
+ m.div,
1876
+ __spreadValues({
1877
+ "aria-hidden": "true",
1878
+ className: cn("fixed inset-0 z-50 bg-black/40", className)
1879
+ }, MD3_SCRIM_ANIM)
1880
+ ) }));
1881
+ });
1882
+ DrawerOverlay.displayName = "DrawerOverlay";
1883
+ var DrawerContent = React6.forwardRef(
1884
+ (_a, ref) => {
1885
+ var _b = _a, {
1886
+ className,
1887
+ children,
1888
+ maxHeight = "90vh",
1889
+ hideHandle = false,
1890
+ hideCloseButton = false,
1891
+ style
1892
+ } = _b, props = __objRest(_b, [
1893
+ "className",
1894
+ "children",
1895
+ "maxHeight",
1896
+ "hideHandle",
1897
+ "hideCloseButton",
1898
+ "style"
1899
+ ]);
1900
+ return /* @__PURE__ */ jsx(RadixDialog.Content, __spreadProps(__spreadValues({ ref, asChild: true }, props), { children: /* @__PURE__ */ jsxs(
1901
+ m.div,
1902
+ __spreadProps(__spreadValues({
1903
+ className: cn(
1904
+ // MD3 Bottom Sheet shape: chỉ bo góc trên
1905
+ "fixed bottom-0 left-0 right-0 z-50",
1906
+ "rounded-t-[28px] bg-m3-surface-container-low",
1907
+ "flex flex-col overflow-hidden",
1908
+ "outline-none",
1909
+ // focus-visible ring — a11y
1910
+ "focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-inset",
1911
+ className
1912
+ ),
1913
+ style: __spreadValues({ maxHeight }, style)
1914
+ }, MD3_DRAWER_ANIM), {
1915
+ children: [
1916
+ !hideHandle && /* @__PURE__ */ jsx(
1917
+ "div",
1918
+ {
1919
+ "aria-hidden": "true",
1920
+ className: "mx-auto mt-3 h-1 w-9 rounded-full bg-m3-on-surface-variant/40 shrink-0"
1921
+ }
1922
+ ),
1923
+ !hideCloseButton && /* @__PURE__ */ jsx(
1924
+ RadixDialog.Close,
1925
+ {
1926
+ className: cn(
1927
+ "absolute right-4 top-3 rounded-full p-2",
1928
+ "text-m3-on-surface-variant",
1929
+ "hover:bg-m3-on-surface/8",
1930
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary",
1931
+ "transition-colors duration-200"
1932
+ ),
1933
+ "aria-label": "\u0110\xF3ng b\u1EA3ng \u0111i\u1EC1u khi\u1EC3n",
1934
+ children: /* @__PURE__ */ jsx(Icon, { name: "close", size: 20, "aria-hidden": "true" })
1935
+ }
1936
+ ),
1937
+ /* @__PURE__ */ jsx("div", { className: "flex-1 overflow-y-auto overscroll-contain p-6", children })
1938
+ ]
1939
+ })
1940
+ ) }));
1941
+ }
1942
+ );
1943
+ DrawerContent.displayName = "DrawerContent";
1944
+ var DrawerHeader = (_a) => {
1945
+ var _b = _a, {
1946
+ className
1947
+ } = _b, props = __objRest(_b, [
1948
+ "className"
1949
+ ]);
1950
+ return /* @__PURE__ */ jsx("div", __spreadValues({ className: cn("flex flex-col gap-1 mb-4", className) }, props));
1951
+ };
1952
+ DrawerHeader.displayName = "DrawerHeader";
1953
+ var DrawerFooter = (_a) => {
1954
+ var _b = _a, {
1955
+ className
1956
+ } = _b, props = __objRest(_b, [
1957
+ "className"
1958
+ ]);
1959
+ return /* @__PURE__ */ jsx("div", __spreadValues({ className: cn("flex flex-col gap-2 mt-4", className) }, props));
1960
+ };
1961
+ DrawerFooter.displayName = "DrawerFooter";
1962
+ var DrawerTitle = React6.forwardRef((_a, ref) => {
1963
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1964
+ return /* @__PURE__ */ jsx(
1965
+ RadixDialog.Title,
1966
+ __spreadValues({
1967
+ ref,
1968
+ className: cn(
1969
+ "text-[22px] leading-7 font-medium text-m3-on-surface",
1970
+ className
1971
+ )
1972
+ }, props)
1973
+ );
1974
+ });
1975
+ DrawerTitle.displayName = "DrawerTitle";
1976
+ var DrawerDescription = React6.forwardRef((_a, ref) => {
1977
+ var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
1978
+ return /* @__PURE__ */ jsx(
1979
+ RadixDialog.Description,
1980
+ __spreadValues({
1981
+ ref,
1982
+ className: cn("text-sm text-m3-on-surface-variant leading-5", className)
1983
+ }, props)
1984
+ );
1985
+ });
1986
+ DrawerDescription.displayName = "DrawerDescription";
1987
+ var INDICATOR = "h-1 w-8 rounded-full bg-m3-on-surface-variant/40";
1988
+ var DragHandle = React6.forwardRef(
1989
+ ({ className, onCycle, "aria-label": ariaLabel }, ref) => {
1990
+ const isInteractive = Boolean(onCycle);
1991
+ if (isInteractive) {
1992
+ return /* @__PURE__ */ jsx(
1993
+ "button",
1994
+ {
1995
+ ref,
1996
+ type: "button",
1997
+ "aria-label": ariaLabel != null ? ariaLabel : "Adjust sheet height",
1998
+ className: cn(
1999
+ "flex items-center justify-center w-full pt-[30px] pb-[22px] shrink-0",
2000
+ "cursor-pointer bg-transparent border-0",
2001
+ "rounded-sm outline-none focus-visible:ring-[3px] focus-visible:ring-m3-on-surface-variant focus-visible:ring-offset-2",
2002
+ className
2003
+ ),
2004
+ onClick: onCycle,
2005
+ "data-testid": "sheet-drag-handle",
2006
+ children: /* @__PURE__ */ jsx("div", { className: INDICATOR })
2007
+ }
2008
+ );
2009
+ }
2010
+ return /* @__PURE__ */ jsx(
2011
+ "div",
2012
+ {
2013
+ ref,
2014
+ "aria-hidden": true,
2015
+ className: cn(
2016
+ "flex items-center justify-center w-full pt-[30px] pb-[22px] shrink-0",
2017
+ className
2018
+ ),
2019
+ "data-testid": "sheet-drag-handle",
2020
+ children: /* @__PURE__ */ jsx("div", { className: INDICATOR })
2021
+ }
2022
+ );
2023
+ }
2024
+ );
2025
+ DragHandle.displayName = "DragHandle";
2026
+
2027
+ // src/ui/sheets/shared/utils.ts
2028
+ function resolveDividers(divider) {
2029
+ var _a, _b;
2030
+ if (divider === false) return { header: false, footer: false };
2031
+ if (divider === void 0 || divider === true) {
2032
+ return { header: true, footer: true };
2033
+ }
2034
+ return { header: (_a = divider.header) != null ? _a : true, footer: (_b = divider.footer) != null ? _b : true };
2035
+ }
2036
+ function buildSideSheetAnim(edge) {
2037
+ const exitX = edge === "end" ? "100%" : "-100%";
2038
+ return {
2039
+ initial: { x: exitX, opacity: 0.6 },
2040
+ animate: { x: 0, opacity: 1, transition: DEFAULT_SPATIAL_SPRING },
2041
+ exit: {
2042
+ x: exitX,
2043
+ opacity: 0,
2044
+ transition: { duration: 0.22, ease: "easeIn" }
2045
+ }
2046
+ };
2047
+ }
2048
+ var DEFAULT_SHEET_BG = "bg-m3-surface-container-low";
2049
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
2050
+ var DISMISS_THRESHOLD = 0.4;
2051
+ var DISMISS_VELOCITY_THRESHOLD = 600;
2052
+ var DEFAULT_SAFE_AREA_OFFSET = 56;
2053
+ var BOUNDARY_DAMPENING_ZONE = 80;
2054
+ var parseSnapPoint = (snap, viewportHeight, naturalHeight, safeAreaOffset, parsedMaxHeight, hasUserSnapPoints) => {
2055
+ const absoluteMaxHeight = viewportHeight - safeAreaOffset;
2056
+ const capHeight = hasUserSnapPoints ? absoluteMaxHeight : Math.min(absoluteMaxHeight, parsedMaxHeight);
2057
+ if (typeof snap === "number") return Math.min(snap, capHeight);
2058
+ if (snap === "full") return capHeight;
2059
+ if (snap === "fit" || snap === "max-content")
2060
+ return Math.min(
2061
+ naturalHeight,
2062
+ Math.min(absoluteMaxHeight, parsedMaxHeight)
2063
+ );
2064
+ if (snap === "partiallyExpanded")
2065
+ return Math.min(Math.floor(viewportHeight * 0.5), capHeight);
2066
+ if (typeof snap === "string") {
2067
+ if (snap.endsWith("%")) {
2068
+ return Math.min(parseFloat(snap) / 100 * viewportHeight, capHeight);
2069
+ }
2070
+ if (snap.endsWith("px")) {
2071
+ return Math.min(parseFloat(snap), capHeight);
2072
+ }
2073
+ if (snap.endsWith("dvh") || snap.endsWith("vh")) {
2074
+ return Math.min(parseFloat(snap) / 100 * viewportHeight, capHeight);
2075
+ }
2076
+ }
2077
+ return Math.min(naturalHeight, capHeight);
2078
+ };
2079
+ var measureSafeAreaOffset = () => {
2080
+ if (typeof document === "undefined") return DEFAULT_SAFE_AREA_OFFSET;
2081
+ const el = document.createElement("div");
2082
+ el.style.cssText = "position:absolute;top:0;height:max(56px,env(safe-area-inset-top,0px));visibility:hidden;pointer-events:none";
2083
+ document.body.appendChild(el);
2084
+ const height = el.offsetHeight;
2085
+ document.body.removeChild(el);
2086
+ return height;
2087
+ };
2088
+ function useBottomSheet({
2089
+ isOpen,
2090
+ onClose,
2091
+ snapPoints,
2092
+ defaultSnapPoint,
2093
+ onSnapChange,
2094
+ gesturesEnabled = true,
2095
+ isModal = false,
2096
+ maxHeight
2097
+ }) {
2098
+ const [scopeNode, setScopeNode] = useState(null);
2099
+ const scopeNodeRef = useRef(null);
2100
+ const scope = useCallback((node) => {
2101
+ scopeNodeRef.current = node;
2102
+ setScopeNode(node);
2103
+ }, []);
2104
+ Object.defineProperty(scope, "current", {
2105
+ get: () => scopeNodeRef.current,
2106
+ set: (v) => {
2107
+ scopeNodeRef.current = v;
2108
+ },
2109
+ configurable: true
2110
+ });
2111
+ const y = useMotionValue(
2112
+ typeof window !== "undefined" ? window.visualViewport ? window.visualViewport.height : window.innerHeight : 800
2113
+ );
2114
+ const [dimensions, setDimensions] = useState({
2115
+ viewportHeight: typeof window !== "undefined" ? window.visualViewport ? window.visualViewport.height : window.innerHeight : 800,
2116
+ naturalHeight: 0,
2117
+ safeAreaOffset: DEFAULT_SAFE_AREA_OFFSET
2118
+ });
2119
+ const hasMeasuredAfterOpen = useRef(false);
2120
+ const measureDimensions = useCallback(() => {
2121
+ const node = scopeNodeRef.current;
2122
+ if (!node) return;
2123
+ const viewportHeight2 = window.visualViewport ? window.visualViewport.height : window.innerHeight;
2124
+ const safeAreaOffset2 = measureSafeAreaOffset();
2125
+ const viewport = node.querySelector("[data-radix-scroll-area-viewport]");
2126
+ let naturalHeight2 = node.scrollHeight;
2127
+ if (viewport) {
2128
+ let nonScrollableHeight = 0;
2129
+ for (let i = 0; i < node.children.length; i++) {
2130
+ const child = node.children[i];
2131
+ if (!child.contains(viewport) && child !== viewport) {
2132
+ nonScrollableHeight += child.offsetHeight;
2133
+ }
2134
+ }
2135
+ naturalHeight2 = nonScrollableHeight + viewport.scrollHeight;
2136
+ }
2137
+ if (naturalHeight2 > 0) hasMeasuredAfterOpen.current = true;
2138
+ setDimensions((prev) => {
2139
+ if (prev.viewportHeight === viewportHeight2 && prev.naturalHeight === naturalHeight2 && prev.safeAreaOffset === safeAreaOffset2) {
2140
+ return prev;
2141
+ }
2142
+ return { viewportHeight: viewportHeight2, naturalHeight: naturalHeight2, safeAreaOffset: safeAreaOffset2 };
2143
+ });
2144
+ }, []);
2145
+ useIsomorphicLayoutEffect(() => {
2146
+ if (!isOpen || !scopeNode) return;
2147
+ measureDimensions();
2148
+ const observer = new ResizeObserver(measureDimensions);
2149
+ const viewport = scopeNode.querySelector(
2150
+ "[data-radix-scroll-area-viewport]"
2151
+ );
2152
+ if (viewport) {
2153
+ observer.observe(viewport);
2154
+ if (viewport.firstElementChild)
2155
+ observer.observe(viewport.firstElementChild);
2156
+ } else {
2157
+ observer.observe(scopeNode);
2158
+ }
2159
+ window.addEventListener("resize", measureDimensions);
2160
+ return () => {
2161
+ observer.disconnect();
2162
+ window.removeEventListener("resize", measureDimensions);
2163
+ };
2164
+ }, [isOpen, scopeNode, measureDimensions]);
2165
+ useIsomorphicLayoutEffect(() => {
2166
+ const vv = window.visualViewport;
2167
+ if (!isOpen || !vv) return;
2168
+ const handleResize = () => {
2169
+ document.documentElement.style.setProperty(
2170
+ "--sheet-vh",
2171
+ `${vv.height}px`
2172
+ );
2173
+ measureDimensions();
2174
+ };
2175
+ vv.addEventListener("resize", handleResize);
2176
+ handleResize();
2177
+ return () => vv.removeEventListener("resize", handleResize);
2178
+ }, [isOpen, measureDimensions]);
2179
+ const { viewportHeight, naturalHeight, safeAreaOffset } = dimensions;
2180
+ const parsedMaxHeight = useMemo(() => {
2181
+ if (!maxHeight) return viewportHeight - safeAreaOffset;
2182
+ if (maxHeight.endsWith("px")) return parseFloat(maxHeight);
2183
+ if (maxHeight.endsWith("dvh") || maxHeight.endsWith("vh")) {
2184
+ return parseFloat(maxHeight) / 100 * viewportHeight;
2185
+ }
2186
+ if (maxHeight.endsWith("%")) {
2187
+ return parseFloat(maxHeight) / 100 * viewportHeight;
2188
+ }
2189
+ return parseFloat(maxHeight) || viewportHeight - safeAreaOffset;
2190
+ }, [maxHeight, viewportHeight, safeAreaOffset]);
2191
+ const snaps = useMemo(() => {
2192
+ if (snapPoints) return snapPoints;
2193
+ if (isModal) return ["partiallyExpanded", "full"];
2194
+ return ["fit"];
2195
+ }, [snapPoints, isModal]);
2196
+ const allowsViewportSnapExpansion = snapPoints !== void 0 || snaps.length > 1;
2197
+ const snapHeights = useMemo(
2198
+ () => snaps.map(
2199
+ (snap) => parseSnapPoint(
2200
+ snap,
2201
+ viewportHeight,
2202
+ naturalHeight,
2203
+ safeAreaOffset,
2204
+ parsedMaxHeight,
2205
+ allowsViewportSnapExpansion
2206
+ )
2207
+ ),
2208
+ [
2209
+ snaps,
2210
+ viewportHeight,
2211
+ naturalHeight,
2212
+ safeAreaOffset,
2213
+ parsedMaxHeight,
2214
+ allowsViewportSnapExpansion
2215
+ ]
2216
+ );
2217
+ const maxSheetHeight = useMemo(
2218
+ () => viewportHeight - safeAreaOffset,
2219
+ [viewportHeight, safeAreaOffset]
2220
+ );
2221
+ const snapYValues = useMemo(
2222
+ () => snapHeights.map((h) => Math.max(0, maxSheetHeight - h)),
2223
+ [snapHeights, maxSheetHeight]
2224
+ );
2225
+ const sortedSnaps = useMemo(() => {
2226
+ const combined = snaps.map((point, idx) => ({
2227
+ point,
2228
+ height: snapHeights[idx],
2229
+ y: snapYValues[idx]
2230
+ }));
2231
+ return combined.sort((a, b) => b.y - a.y);
2232
+ }, [snaps, snapHeights, snapYValues]);
2233
+ const [activeSnapIndex, setActiveSnapIndex] = useState(0);
2234
+ const activeSnapPoint = useMemo(
2235
+ () => {
2236
+ var _a, _b;
2237
+ return (_b = (_a = sortedSnaps[activeSnapIndex]) == null ? void 0 : _a.point) != null ? _b : "fit";
2238
+ },
2239
+ [sortedSnaps, activeSnapIndex]
2240
+ );
2241
+ const isContentScrollable = useMemo(
2242
+ () => sortedSnaps.length <= 1 || activeSnapIndex === sortedSnaps.length - 1,
2243
+ [sortedSnaps, activeSnapIndex]
2244
+ );
2245
+ const lowestSnapY = useMemo(() => {
2246
+ var _a, _b;
2247
+ return (_b = (_a = sortedSnaps[0]) == null ? void 0 : _a.y) != null ? _b : 300;
2248
+ }, [sortedSnaps]);
2249
+ const scrimOpacity = useTransform(y, [lowestSnapY, maxSheetHeight], [1, 0]);
2250
+ const defaultSnap = useMemo(
2251
+ () => {
2252
+ var _a;
2253
+ return (_a = defaultSnapPoint != null ? defaultSnapPoint : snaps[0]) != null ? _a : "fit";
2254
+ },
2255
+ [defaultSnapPoint, snaps]
2256
+ );
2257
+ const prevIsOpen = useRef(isOpen);
2258
+ useIsomorphicLayoutEffect(() => {
2259
+ if (isOpen && !prevIsOpen.current) {
2260
+ y.set(viewportHeight);
2261
+ hasMeasuredAfterOpen.current = false;
2262
+ const defaultIdx = sortedSnaps.findIndex((s) => s.point === defaultSnap);
2263
+ setActiveSnapIndex(defaultIdx !== -1 ? defaultIdx : 0);
2264
+ } else if (!isOpen && prevIsOpen.current) {
2265
+ setDimensions((prev) => __spreadProps(__spreadValues({}, prev), { naturalHeight: 0 }));
2266
+ void animate(y, viewportHeight, {
2267
+ type: "tween",
2268
+ duration: 0.22,
2269
+ ease: "easeIn"
2270
+ });
2271
+ }
2272
+ prevIsOpen.current = isOpen;
2273
+ }, [isOpen, y, viewportHeight, sortedSnaps, defaultSnap]);
2274
+ useEffect(() => {
2275
+ var _a;
2276
+ if (!isOpen || sortedSnaps.length === 0 || naturalHeight === 0) return;
2277
+ if (!hasMeasuredAfterOpen.current) return;
2278
+ const targetY = (_a = sortedSnaps[activeSnapIndex]) == null ? void 0 : _a.y;
2279
+ if (targetY === void 0) return;
2280
+ void animate(y, targetY, { type: "spring", stiffness: 300, damping: 30 });
2281
+ }, [isOpen, sortedSnaps, activeSnapIndex, y, naturalHeight]);
2282
+ const snapTo = useCallback(
2283
+ (snapPoint) => {
2284
+ const idx = sortedSnaps.findIndex((s) => s.point === snapPoint);
2285
+ if (idx === -1) return;
2286
+ setActiveSnapIndex(idx);
2287
+ void animate(y, sortedSnaps[idx].y, {
2288
+ type: "spring",
2289
+ stiffness: 300,
2290
+ damping: 30
2291
+ });
2292
+ onSnapChange == null ? void 0 : onSnapChange(snapPoint);
2293
+ },
2294
+ [sortedSnaps, y, onSnapChange]
2295
+ );
2296
+ const cycleSnapPoint = useCallback(() => {
2297
+ const nextIdx = activeSnapIndex + 1;
2298
+ if (nextIdx >= sortedSnaps.length) {
2299
+ onClose();
2300
+ } else {
2301
+ setActiveSnapIndex(nextIdx);
2302
+ void animate(y, sortedSnaps[nextIdx].y, {
2303
+ type: "spring",
2304
+ stiffness: 300,
2305
+ damping: 30
2306
+ });
2307
+ onSnapChange == null ? void 0 : onSnapChange(sortedSnaps[nextIdx].point);
2308
+ }
2309
+ }, [activeSnapIndex, sortedSnaps, y, onClose, onSnapChange]);
2310
+ const dragConstraints = useMemo(
2311
+ () => {
2312
+ var _a, _b;
2313
+ return {
2314
+ top: Math.max(0, (_b = (_a = sortedSnaps[sortedSnaps.length - 1]) == null ? void 0 : _a.y) != null ? _b : 0),
2315
+ bottom: viewportHeight
2316
+ };
2317
+ },
2318
+ [sortedSnaps, viewportHeight]
2319
+ );
2320
+ useEffect(() => {
2321
+ if (!isOpen || !gesturesEnabled || !scopeNode) return;
2322
+ const node = scopeNode;
2323
+ const viewport = node.querySelector(
2324
+ "[data-radix-scroll-area-viewport]"
2325
+ );
2326
+ let startY = 0;
2327
+ let initialSheetY = 0;
2328
+ let isDragging = false;
2329
+ let lastY = 0;
2330
+ let lastTime = 0;
2331
+ let velocity = 0;
2332
+ let activeInput = null;
2333
+ let dragStartTarget = null;
2334
+ let lastTouchTime = 0;
2335
+ let preventNextClick = false;
2336
+ const MOUSE_DRAG_THRESHOLD = 5;
2337
+ const updateVelocity = (currentY) => {
2338
+ const currentTime = performance.now();
2339
+ const deltaTime = currentTime - lastTime;
2340
+ if (deltaTime > 0) {
2341
+ velocity = (currentY - lastY) / deltaTime * 1e3;
2342
+ }
2343
+ lastY = currentY;
2344
+ lastTime = currentTime;
2345
+ };
2346
+ const tryStartDrag = (deltaY) => {
2347
+ if (viewport == null ? void 0 : viewport.contains(dragStartTarget)) {
2348
+ const isAtHighestSnap = activeSnapIndex === sortedSnaps.length - 1;
2349
+ if (!isAtHighestSnap) {
2350
+ isDragging = true;
2351
+ return true;
2352
+ }
2353
+ const scrollTop = viewport.scrollTop;
2354
+ const isPullingDown = deltaY > 0;
2355
+ if (!isDragging) {
2356
+ if (scrollTop <= 0 && isPullingDown) {
2357
+ isDragging = true;
2358
+ return true;
2359
+ }
2360
+ return false;
2361
+ }
2362
+ return true;
2363
+ }
2364
+ isDragging = true;
2365
+ return true;
2366
+ };
2367
+ const applyDragPosition = (deltaY) => {
2368
+ let nextY = initialSheetY + deltaY;
2369
+ if (nextY < dragConstraints.top) {
2370
+ const overdrag = dragConstraints.top - nextY;
2371
+ nextY = dragConstraints.top - overdrag * 0.15;
2372
+ }
2373
+ y.set(nextY);
2374
+ };
2375
+ const finalizeDrag = () => {
2376
+ var _a, _b;
2377
+ if (!isDragging) return;
2378
+ preventNextClick = true;
2379
+ isDragging = false;
2380
+ const currentY = y.get();
2381
+ const lowestSnap = sortedSnaps[0];
2382
+ const lowestY = (_a = lowestSnap == null ? void 0 : lowestSnap.y) != null ? _a : viewportHeight;
2383
+ const lowestHeight = (_b = lowestSnap == null ? void 0 : lowestSnap.height) != null ? _b : 200;
2384
+ let finalVelocity = velocity;
2385
+ if (finalVelocity > 0) {
2386
+ const distanceToFloor = Math.max(0, currentY - lowestY);
2387
+ if (distanceToFloor < BOUNDARY_DAMPENING_ZONE) {
2388
+ const factor = distanceToFloor / BOUNDARY_DAMPENING_ZONE;
2389
+ finalVelocity *= factor * factor;
2390
+ if (velocity >= DISMISS_VELOCITY_THRESHOLD) {
2391
+ finalVelocity = Math.max(
2392
+ finalVelocity,
2393
+ DISMISS_VELOCITY_THRESHOLD * 0.1
2394
+ );
2395
+ }
2396
+ }
2397
+ }
2398
+ const dragOffset = Math.max(0, currentY - lowestY);
2399
+ const shouldDismiss = finalVelocity > DISMISS_VELOCITY_THRESHOLD || dragOffset > lowestHeight * DISMISS_THRESHOLD;
2400
+ if (shouldDismiss) {
2401
+ onClose();
2402
+ return;
2403
+ }
2404
+ let closestIdx = 0;
2405
+ let minDiff = Infinity;
2406
+ for (let i = 0; i < sortedSnaps.length; i++) {
2407
+ const diff = Math.abs(sortedSnaps[i].y - currentY);
2408
+ if (diff < minDiff) {
2409
+ minDiff = diff;
2410
+ closestIdx = i;
2411
+ }
2412
+ }
2413
+ setActiveSnapIndex(closestIdx);
2414
+ void animate(y, sortedSnaps[closestIdx].y, {
2415
+ type: "spring",
2416
+ stiffness: 380,
2417
+ damping: 31.19
2418
+ });
2419
+ onSnapChange == null ? void 0 : onSnapChange(sortedSnaps[closestIdx].point);
2420
+ };
2421
+ const onTouchStart = (e) => {
2422
+ lastTouchTime = Date.now();
2423
+ activeInput = "touch";
2424
+ dragStartTarget = e.target;
2425
+ startY = e.touches[0].clientY;
2426
+ initialSheetY = y.get();
2427
+ isDragging = false;
2428
+ lastY = startY;
2429
+ lastTime = performance.now();
2430
+ velocity = 0;
2431
+ };
2432
+ const onTouchMove = (e) => {
2433
+ if (!e.touches[0] || activeInput !== "touch") return;
2434
+ const currentY = e.touches[0].clientY;
2435
+ const deltaY = currentY - startY;
2436
+ updateVelocity(currentY);
2437
+ if (tryStartDrag(deltaY)) {
2438
+ e.preventDefault();
2439
+ applyDragPosition(deltaY);
2440
+ }
2441
+ };
2442
+ const onTouchEnd = () => {
2443
+ if (activeInput !== "touch") return;
2444
+ activeInput = null;
2445
+ finalizeDrag();
2446
+ dragStartTarget = null;
2447
+ };
2448
+ const onMouseDown = (e) => {
2449
+ if (e.button !== 0) return;
2450
+ if (Date.now() - lastTouchTime < 500) return;
2451
+ activeInput = "mouse";
2452
+ dragStartTarget = e.target;
2453
+ startY = e.clientY;
2454
+ initialSheetY = y.get();
2455
+ isDragging = false;
2456
+ lastY = startY;
2457
+ lastTime = performance.now();
2458
+ velocity = 0;
2459
+ };
2460
+ const onMouseMove = (e) => {
2461
+ if (activeInput !== "mouse") return;
2462
+ const currentY = e.clientY;
2463
+ const deltaY = currentY - startY;
2464
+ if (!isDragging && Math.abs(deltaY) < MOUSE_DRAG_THRESHOLD) return;
2465
+ updateVelocity(currentY);
2466
+ if (tryStartDrag(deltaY)) {
2467
+ e.preventDefault();
2468
+ document.body.style.userSelect = "none";
2469
+ applyDragPosition(deltaY);
2470
+ }
2471
+ };
2472
+ const onMouseUp = () => {
2473
+ if (activeInput !== "mouse") return;
2474
+ activeInput = null;
2475
+ document.body.style.userSelect = "";
2476
+ finalizeDrag();
2477
+ dragStartTarget = null;
2478
+ };
2479
+ const onClickCapture = (e) => {
2480
+ if (preventNextClick) {
2481
+ e.stopPropagation();
2482
+ preventNextClick = false;
2483
+ }
2484
+ };
2485
+ node.addEventListener("touchstart", onTouchStart, { passive: true });
2486
+ node.addEventListener("touchmove", onTouchMove, { passive: false });
2487
+ node.addEventListener("touchend", onTouchEnd);
2488
+ node.addEventListener("touchcancel", onTouchEnd);
2489
+ node.addEventListener("mousedown", onMouseDown);
2490
+ document.addEventListener("mousemove", onMouseMove);
2491
+ document.addEventListener("mouseup", onMouseUp);
2492
+ node.addEventListener("click", onClickCapture, true);
2493
+ return () => {
2494
+ node.removeEventListener("touchstart", onTouchStart);
2495
+ node.removeEventListener("touchmove", onTouchMove);
2496
+ node.removeEventListener("touchend", onTouchEnd);
2497
+ node.removeEventListener("touchcancel", onTouchEnd);
2498
+ node.removeEventListener("mousedown", onMouseDown);
2499
+ document.removeEventListener("mousemove", onMouseMove);
2500
+ document.removeEventListener("mouseup", onMouseUp);
2501
+ node.removeEventListener("click", onClickCapture, true);
2502
+ document.body.style.userSelect = "";
2503
+ };
2504
+ }, [
2505
+ isOpen,
2506
+ gesturesEnabled,
2507
+ sortedSnaps,
2508
+ activeSnapIndex,
2509
+ y,
2510
+ dragConstraints.top,
2511
+ viewportHeight,
2512
+ onClose,
2513
+ onSnapChange,
2514
+ scopeNode
2515
+ ]);
2516
+ return {
2517
+ scope,
2518
+ y,
2519
+ scrimOpacity,
2520
+ activeSnapPoint,
2521
+ isContentScrollable,
2522
+ snapTo,
2523
+ cycleSnapPoint,
2524
+ dragConstraints
2525
+ };
2526
+ }
2527
+ var SHEET_ANIM = {
2528
+ initial: { opacity: 0.6 },
2529
+ animate: { opacity: 1, transition: DEFAULT_SPATIAL_SPRING },
2530
+ exit: {
2531
+ opacity: 0,
2532
+ transition: { duration: 0.22, ease: "easeIn" }
2533
+ }
2534
+ };
2535
+ var ABSOLUTE_MAX_HEIGHT = "calc(100dvh - max(56px, env(safe-area-inset-top, 0px)))";
2536
+ function resolveMaxHeight(maxHeight, snapPoints) {
2537
+ if (maxHeight === "90dvh" && snapPoints && snapPoints.length > 0)
2538
+ return ABSOLUTE_MAX_HEIGHT;
2539
+ return maxHeight;
2540
+ }
2541
+ var BottomSheet = React6.forwardRef(
2542
+ ({
2543
+ isOpen,
2544
+ onClose,
2545
+ children,
2546
+ className,
2547
+ maxHeight = "90dvh",
2548
+ hideHandle = false,
2549
+ portal = true,
2550
+ "aria-labelledby": ariaLabelledBy,
2551
+ "aria-label": ariaLabel,
2552
+ header,
2553
+ footer,
2554
+ divider,
2555
+ scrollAreaProps,
2556
+ snapPoints,
2557
+ defaultSnapPoint,
2558
+ onSnapChange,
2559
+ gesturesEnabled = true,
2560
+ containerColor,
2561
+ sheetMaxWidth
2562
+ }, ref) => {
2563
+ var _a;
2564
+ const { scope, y, isContentScrollable, snapTo, cycleSnapPoint } = useBottomSheet({
2565
+ isOpen,
2566
+ onClose,
2567
+ snapPoints,
2568
+ defaultSnapPoint,
2569
+ onSnapChange,
2570
+ gesturesEnabled,
2571
+ isModal: false,
2572
+ maxHeight: resolveMaxHeight(maxHeight, snapPoints)
2573
+ });
2574
+ React6.useEffect(() => {
2575
+ const node = scope.current;
2576
+ if (node) {
2577
+ node.snapTo = snapTo;
2578
+ }
2579
+ }, [snapTo, scope]);
2580
+ const [mounted, setMounted] = React6.useState(false);
2581
+ React6.useEffect(() => {
2582
+ setMounted(true);
2583
+ }, []);
2584
+ const resolvedDividers = React6.useMemo(
2585
+ () => resolveDividers(divider),
2586
+ [divider]
2587
+ );
2588
+ const resolvedSheetMaxWidth = React6.useMemo(() => {
2589
+ if (sheetMaxWidth === void 0)
2590
+ return "var(--m3-bottom-sheet-max-width, 640px)";
2591
+ if (typeof sheetMaxWidth === "number") return `${sheetMaxWidth}px`;
2592
+ return sheetMaxWidth;
2593
+ }, [sheetMaxWidth]);
2594
+ const mergedRef = React6.useCallback(
2595
+ (node) => {
2596
+ scope(node);
2597
+ if (typeof ref === "function") ref(node);
2598
+ else if (ref) ref.current = node;
2599
+ },
2600
+ [scope, ref]
2601
+ );
2602
+ const content = /* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxs(
2603
+ m.div,
2604
+ __spreadProps(__spreadValues({
2605
+ ref: mergedRef,
2606
+ role: "dialog",
2607
+ "aria-modal": "false",
2608
+ "aria-label": ariaLabel,
2609
+ "aria-labelledby": ariaLabelledBy,
2610
+ tabIndex: -1,
2611
+ className: cn(
2612
+ "fixed bottom-0 z-50",
2613
+ "left-0 right-0 mx-auto",
2614
+ "rounded-t-[28px]",
2615
+ !containerColor && DEFAULT_SHEET_BG,
2616
+ "flex flex-col overflow-hidden",
2617
+ "outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-inset",
2618
+ className
2619
+ ),
2620
+ style: {
2621
+ backgroundColor: containerColor,
2622
+ // Container must span the full available viewport height so that
2623
+ // snap points above the default maxHeight (e.g. "full", "70%")
2624
+ // can reveal their content via the y (translateY) offset mechanism.
2625
+ height: "var(--sheet-vh, 100dvh)",
2626
+ maxHeight: ABSOLUTE_MAX_HEIGHT,
2627
+ maxWidth: resolvedSheetMaxWidth,
2628
+ y
2629
+ }
2630
+ }, SHEET_ANIM), {
2631
+ children: [
2632
+ !hideHandle && /* @__PURE__ */ jsx(DragHandle, { onCycle: cycleSnapPoint }),
2633
+ header && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-6 pb-4", children: header }),
2634
+ header && resolvedDividers.header && /* @__PURE__ */ jsx("hr", { className: "border-t border-m3-outline-variant w-full shrink-0 m-0" }),
2635
+ /* @__PURE__ */ jsx(
2636
+ ScrollArea,
2637
+ __spreadProps(__spreadValues({
2638
+ type: "hover"
2639
+ }, scrollAreaProps), {
2640
+ className: cn(
2641
+ "flex-1 min-h-0 min-w-0",
2642
+ scrollAreaProps == null ? void 0 : scrollAreaProps.className
2643
+ ),
2644
+ viewportClassName: cn(
2645
+ "px-6 pb-6 overscroll-contain",
2646
+ header ? "pt-4" : "",
2647
+ scrollAreaProps == null ? void 0 : scrollAreaProps.viewportClassName
2648
+ ),
2649
+ viewportProps: __spreadProps(__spreadValues({}, scrollAreaProps == null ? void 0 : scrollAreaProps.viewportProps), {
2650
+ style: __spreadProps(__spreadValues({}, (_a = scrollAreaProps == null ? void 0 : scrollAreaProps.viewportProps) == null ? void 0 : _a.style), {
2651
+ overflowY: isContentScrollable ? "auto" : "hidden"
2652
+ })
2653
+ }),
2654
+ children
2655
+ })
2656
+ ),
2657
+ footer && resolvedDividers.footer && /* @__PURE__ */ jsx("hr", { className: "border-t border-m3-outline-variant w-full shrink-0 m-0" }),
2658
+ footer && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-6 pt-4 pb-6", children: footer })
2659
+ ]
2660
+ })
2661
+ ) });
2662
+ if (portal) {
2663
+ if (!mounted) return null;
2664
+ return createPortal(content, document.body);
2665
+ }
2666
+ return content;
2667
+ }
2668
+ );
2669
+ BottomSheet.displayName = "BottomSheet";
2670
+ var SCRIM_ANIM = {
2671
+ initial: { opacity: 0 },
2672
+ animate: {
2673
+ opacity: 1,
2674
+ transition: { duration: 0.2, ease: "easeOut" }
2675
+ },
2676
+ exit: { opacity: 0, transition: { duration: 0.18, ease: "easeIn" } }
2677
+ };
2678
+ var Scrim = React6.forwardRef(
2679
+ ({ onClick, className, style }, ref) => /* @__PURE__ */ jsx(
2680
+ m.div,
2681
+ __spreadValues({
2682
+ ref,
2683
+ "aria-hidden": "true",
2684
+ className: cn("fixed inset-0 z-40 bg-black/40", className),
2685
+ onClick,
2686
+ style
2687
+ }, SCRIM_ANIM)
2688
+ )
2689
+ );
2690
+ Scrim.displayName = "Scrim";
2691
+ var SHEET_ANIM2 = {
2692
+ initial: { opacity: 0.6 },
2693
+ animate: { opacity: 1, transition: DEFAULT_SPATIAL_SPRING },
2694
+ exit: {
2695
+ opacity: 0,
2696
+ transition: { duration: 0.22, ease: "easeIn" }
2697
+ }
2698
+ };
2699
+ var ABSOLUTE_MAX_HEIGHT2 = "calc(100dvh - max(56px, env(safe-area-inset-top, 0px)))";
2700
+ function resolveMaxHeight2(maxHeight, snapPoints) {
2701
+ if (maxHeight === "90dvh" && snapPoints && snapPoints.length > 0)
2702
+ return ABSOLUTE_MAX_HEIGHT2;
2703
+ return maxHeight;
2704
+ }
2705
+ function resolveSheetMaxWidth(value) {
2706
+ if (value === void 0) return "var(--m3-bottom-sheet-max-width, 640px)";
2707
+ if (typeof value === "number") return `${value}px`;
2708
+ return value;
2709
+ }
2710
+ var BottomSheetModal = React6.forwardRef(
2711
+ ({
2712
+ isOpen,
2713
+ onClose,
2714
+ children,
2715
+ className,
2716
+ maxHeight = "90dvh",
2717
+ hideHandle = false,
2718
+ "aria-labelledby": ariaLabelledBy,
2719
+ "aria-label": ariaLabel,
2720
+ header,
2721
+ footer,
2722
+ divider,
2723
+ scrollAreaProps,
2724
+ snapPoints,
2725
+ defaultSnapPoint,
2726
+ onSnapChange,
2727
+ gesturesEnabled = true,
2728
+ containerColor,
2729
+ sheetMaxWidth
2730
+ }, ref) => {
2731
+ var _a;
2732
+ const {
2733
+ scope,
2734
+ y,
2735
+ scrimOpacity,
2736
+ isContentScrollable,
2737
+ snapTo,
2738
+ cycleSnapPoint
2739
+ } = useBottomSheet({
2740
+ isOpen,
2741
+ onClose,
2742
+ snapPoints,
2743
+ defaultSnapPoint,
2744
+ onSnapChange,
2745
+ gesturesEnabled,
2746
+ isModal: true,
2747
+ maxHeight: resolveMaxHeight2(maxHeight, snapPoints)
2748
+ });
2749
+ React6.useEffect(() => {
2750
+ const node = scope.current;
2751
+ if (node) {
2752
+ node.snapTo = snapTo;
2753
+ }
2754
+ }, [snapTo, scope]);
2755
+ const resolvedDividers = React6.useMemo(
2756
+ () => resolveDividers(divider),
2757
+ [divider]
2758
+ );
2759
+ const resolvedSheetMaxWidth = React6.useMemo(
2760
+ () => resolveSheetMaxWidth(sheetMaxWidth),
2761
+ [sheetMaxWidth]
2762
+ );
2763
+ const mergedRef = React6.useCallback(
2764
+ (node) => {
2765
+ scope(node);
2766
+ if (typeof ref === "function") ref(node);
2767
+ else if (ref) ref.current = node;
2768
+ },
2769
+ [scope, ref]
2770
+ );
2771
+ return /* @__PURE__ */ jsx(
2772
+ RadixDialog.Root,
2773
+ {
2774
+ open: isOpen,
2775
+ onOpenChange: (open) => !open && onClose(),
2776
+ children: /* @__PURE__ */ jsx(RadixDialog.Portal, { forceMount: true, children: /* @__PURE__ */ jsxs(AnimatePresence, { children: [
2777
+ isOpen && /* @__PURE__ */ jsx(RadixDialog.Overlay, { asChild: true, forceMount: true, children: /* @__PURE__ */ jsx(Scrim, { onClick: onClose, style: { opacity: scrimOpacity } }) }, "scrim"),
2778
+ isOpen && /* @__PURE__ */ jsx(
2779
+ RadixDialog.Content,
2780
+ {
2781
+ asChild: true,
2782
+ forceMount: true,
2783
+ "aria-describedby": void 0,
2784
+ "aria-labelledby": ariaLabelledBy,
2785
+ "aria-label": ariaLabel,
2786
+ children: /* @__PURE__ */ jsxs(
2787
+ m.div,
2788
+ __spreadProps(__spreadValues({
2789
+ ref: mergedRef,
2790
+ className: cn(
2791
+ // Positioning: fixed at bottom, centered with max-width
2792
+ "fixed bottom-0 z-50",
2793
+ "left-0 right-0 mx-auto",
2794
+ // Visual style
2795
+ "rounded-t-[28px]",
2796
+ !containerColor && DEFAULT_SHEET_BG,
2797
+ "flex flex-col overflow-hidden",
2798
+ "outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-inset",
2799
+ className
2800
+ ),
2801
+ style: {
2802
+ backgroundColor: containerColor,
2803
+ height: "var(--sheet-vh, 100dvh)",
2804
+ // Container must span the full available viewport height so that
2805
+ // snap points above the default maxHeight (e.g. "full", "70%")
2806
+ // can reveal their content via the y (translateY) offset mechanism.
2807
+ maxHeight: ABSOLUTE_MAX_HEIGHT2,
2808
+ maxWidth: resolvedSheetMaxWidth,
2809
+ y
2810
+ }
2811
+ }, SHEET_ANIM2), {
2812
+ children: [
2813
+ /* @__PURE__ */ jsx(RadixDialog.Title, { className: "sr-only", children: ariaLabel || "Bottom Sheet" }),
2814
+ !hideHandle && /* @__PURE__ */ jsx(DragHandle, { onCycle: cycleSnapPoint }),
2815
+ header && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-6 pb-4", children: header }),
2816
+ header && resolvedDividers.header && /* @__PURE__ */ jsx("hr", { className: "border-t border-m3-outline-variant w-full shrink-0 m-0" }),
2817
+ /* @__PURE__ */ jsx(
2818
+ ScrollArea,
2819
+ __spreadProps(__spreadValues({
2820
+ type: "hover"
2821
+ }, scrollAreaProps), {
2822
+ className: cn(
2823
+ "flex-1 min-h-0 min-w-0",
2824
+ scrollAreaProps == null ? void 0 : scrollAreaProps.className
2825
+ ),
2826
+ viewportClassName: cn(
2827
+ "px-6 pb-6 overscroll-contain",
2828
+ header ? "pt-4" : "",
2829
+ scrollAreaProps == null ? void 0 : scrollAreaProps.viewportClassName
2830
+ ),
2831
+ viewportProps: __spreadProps(__spreadValues({}, scrollAreaProps == null ? void 0 : scrollAreaProps.viewportProps), {
2832
+ style: __spreadProps(__spreadValues({}, (_a = scrollAreaProps == null ? void 0 : scrollAreaProps.viewportProps) == null ? void 0 : _a.style), {
2833
+ overflowY: isContentScrollable ? "auto" : "hidden"
2834
+ })
2835
+ }),
2836
+ children
2837
+ })
2838
+ ),
2839
+ footer && resolvedDividers.footer && /* @__PURE__ */ jsx("hr", { className: "border-t border-m3-outline-variant w-full shrink-0 m-0" }),
2840
+ footer && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-6 pt-4 pb-6", children: footer })
2841
+ ]
2842
+ })
2843
+ )
2844
+ },
2845
+ "content"
2846
+ )
2847
+ ] }) })
2848
+ }
2849
+ );
2850
+ }
2851
+ );
2852
+ BottomSheetModal.displayName = "BottomSheetModal";
2853
+ var DISMISS_VELOCITY_THRESHOLD2 = 500;
2854
+ var BOUNDARY_DAMPENING_ZONE2 = 80;
2855
+ var SPRING = { type: "spring", stiffness: 300, damping: 30 };
2856
+ function useBottomSheetScaffold({
2857
+ peekHeight = 56,
2858
+ swipeEnabled = true,
2859
+ onStateChange,
2860
+ initialState = "partiallyExpanded"
2861
+ } = {}) {
2862
+ const [containerHeight, setContainerHeight] = useState(
2863
+ typeof window !== "undefined" ? window.innerHeight : 800
2864
+ );
2865
+ const containerNodeRef = useRef(null);
2866
+ const containerRef = useCallback((node) => {
2867
+ containerNodeRef.current = node;
2868
+ if (node) {
2869
+ setContainerHeight(node.offsetHeight || window.innerHeight);
2870
+ }
2871
+ }, []);
2872
+ useEffect(() => {
2873
+ const node = containerNodeRef.current;
2874
+ if (!node) return;
2875
+ const observer = new ResizeObserver(() => {
2876
+ setContainerHeight(node.offsetHeight);
2877
+ });
2878
+ observer.observe(node);
2879
+ return () => observer.disconnect();
2880
+ }, []);
2881
+ const expandedY = 0;
2882
+ const partialY = containerHeight - peekHeight;
2883
+ const y = useMotionValue(initialState === "expanded" ? expandedY : partialY);
2884
+ const [sheetState, setSheetState] = useState(
2885
+ initialState
2886
+ );
2887
+ const [isScrollDisablingDrag, setIsScrollDisablingDrag] = useState(false);
2888
+ const isDragEnabled = swipeEnabled && !isScrollDisablingDrag;
2889
+ const dragConstraints = useMemo(
2890
+ () => ({ top: 0, bottom: partialY }),
2891
+ [partialY]
2892
+ );
2893
+ useEffect(() => {
2894
+ const targetY = sheetState === "expanded" ? 0 : partialY;
2895
+ void animate(y, targetY, SPRING);
2896
+ }, [partialY, sheetState, y]);
2897
+ const expand = useCallback(() => {
2898
+ setSheetState("expanded");
2899
+ void animate(y, 0, SPRING);
2900
+ onStateChange == null ? void 0 : onStateChange("expanded");
2901
+ }, [y, onStateChange]);
2902
+ const partialExpand = useCallback(() => {
2903
+ setSheetState("partiallyExpanded");
2904
+ void animate(y, partialY, SPRING);
2905
+ onStateChange == null ? void 0 : onStateChange("partiallyExpanded");
2906
+ }, [y, partialY, onStateChange]);
2907
+ const toggle = useCallback(() => {
2908
+ if (sheetState === "expanded") partialExpand();
2909
+ else expand();
2910
+ }, [sheetState, expand, partialExpand]);
2911
+ const handleDragEnd = useCallback(
2912
+ (_event, info) => {
2913
+ const rawY = y.get();
2914
+ let velocity = info.velocity.y;
2915
+ if (velocity > 0) {
2916
+ const distanceToFloor = Math.max(0, partialY - rawY);
2917
+ if (distanceToFloor < BOUNDARY_DAMPENING_ZONE2) {
2918
+ const factor = distanceToFloor / BOUNDARY_DAMPENING_ZONE2;
2919
+ velocity *= factor * factor;
2920
+ }
2921
+ }
2922
+ if (velocity > DISMISS_VELOCITY_THRESHOLD2) {
2923
+ partialExpand();
2924
+ return;
2925
+ }
2926
+ if (velocity < -DISMISS_VELOCITY_THRESHOLD2) {
2927
+ expand();
2928
+ return;
2929
+ }
2930
+ const midpoint = partialY / 2;
2931
+ if (rawY < midpoint) expand();
2932
+ else partialExpand();
2933
+ },
2934
+ [y, partialY, expand, partialExpand]
2935
+ );
2936
+ const handleContentScroll = useCallback(
2937
+ (e) => {
2938
+ if (sheetState !== "expanded") {
2939
+ e.currentTarget.scrollTop = 0;
2940
+ setIsScrollDisablingDrag(false);
2941
+ return;
2942
+ }
2943
+ setIsScrollDisablingDrag(e.currentTarget.scrollTop > 0);
2944
+ },
2945
+ [sheetState]
2946
+ );
2947
+ const contentPaddingBottom = `${peekHeight}px`;
2948
+ return {
2949
+ sheetState,
2950
+ y,
2951
+ expand,
2952
+ partialExpand,
2953
+ toggle,
2954
+ isDragEnabled,
2955
+ dragConstraints,
2956
+ handleDragEnd,
2957
+ handleContentScroll,
2958
+ contentPaddingBottom,
2959
+ containerRef
2960
+ };
2961
+ }
2962
+ var BottomSheetScaffold = React6.forwardRef(
2963
+ ({
2964
+ sheetContent,
2965
+ children,
2966
+ sheetPeekHeight = 56,
2967
+ sheetMaxWidth,
2968
+ sheetDragHandle,
2969
+ sheetSwipeEnabled = true,
2970
+ topBar,
2971
+ sheetContainerColor,
2972
+ onSheetStateChange,
2973
+ initialSheetState = "partiallyExpanded",
2974
+ className
2975
+ }, ref) => {
2976
+ const {
2977
+ y,
2978
+ toggle,
2979
+ isDragEnabled,
2980
+ dragConstraints,
2981
+ handleDragEnd,
2982
+ handleContentScroll,
2983
+ contentPaddingBottom,
2984
+ containerRef
2985
+ } = useBottomSheetScaffold({
2986
+ peekHeight: sheetPeekHeight,
2987
+ swipeEnabled: sheetSwipeEnabled,
2988
+ onStateChange: onSheetStateChange,
2989
+ initialState: initialSheetState
2990
+ });
2991
+ const resolvedSheetMaxWidth = React6.useMemo(() => {
2992
+ if (sheetMaxWidth === void 0)
2993
+ return "var(--m3-bottom-sheet-max-width, 640px)";
2994
+ if (typeof sheetMaxWidth === "number") return `${sheetMaxWidth}px`;
2995
+ return sheetMaxWidth;
2996
+ }, [sheetMaxWidth]);
2997
+ const mergedRef = React6.useCallback(
2998
+ (node) => {
2999
+ containerRef(node);
3000
+ if (typeof ref === "function") ref(node);
3001
+ else if (ref) ref.current = node;
3002
+ },
3003
+ [containerRef, ref]
3004
+ );
3005
+ const resolvedDragHandle = React6.useMemo(() => {
3006
+ if (sheetDragHandle === null) return null;
3007
+ if (sheetDragHandle !== void 0) return sheetDragHandle;
3008
+ return /* @__PURE__ */ jsx(DragHandle, { onCycle: toggle });
3009
+ }, [sheetDragHandle, toggle]);
3010
+ return /* @__PURE__ */ jsxs(
3011
+ "div",
3012
+ {
3013
+ ref: mergedRef,
3014
+ className: cn(
3015
+ "relative flex flex-col h-full w-full overflow-hidden",
3016
+ className
3017
+ ),
3018
+ children: [
3019
+ topBar && /* @__PURE__ */ jsx("div", { className: "shrink-0 z-10", children: topBar }),
3020
+ /* @__PURE__ */ jsx("div", { className: "relative flex-1 min-h-0 overflow-y-auto", children: children(contentPaddingBottom) }),
3021
+ /* @__PURE__ */ jsxs(
3022
+ m.div,
3023
+ {
3024
+ className: cn(
3025
+ "absolute bottom-0 left-0 right-0 mx-auto",
3026
+ "rounded-t-[28px] flex flex-col overflow-hidden",
3027
+ !sheetContainerColor && DEFAULT_SHEET_BG,
3028
+ // MD3 elevation-1 for standard sheet
3029
+ "elevation-1"
3030
+ ),
3031
+ style: {
3032
+ backgroundColor: sheetContainerColor,
3033
+ maxWidth: resolvedSheetMaxWidth,
3034
+ y,
3035
+ // Sheet panel is always tall enough to fill from top to bottom
3036
+ height: "100%",
3037
+ transformOrigin: "center bottom"
3038
+ },
3039
+ drag: isDragEnabled ? "y" : false,
3040
+ dragConstraints,
3041
+ dragElastic: { top: 0.1, bottom: 0 },
3042
+ onDragEnd: handleDragEnd,
3043
+ transition: DEFAULT_SPATIAL_SPRING,
3044
+ children: [
3045
+ resolvedDragHandle,
3046
+ /* @__PURE__ */ jsx(
3047
+ ScrollArea,
3048
+ {
3049
+ type: "hover",
3050
+ className: "flex-1 min-h-0 min-w-0",
3051
+ viewportClassName: "px-6 pb-6",
3052
+ viewportProps: {
3053
+ onScroll: handleContentScroll
3054
+ },
3055
+ children: sheetContent
3056
+ }
3057
+ )
3058
+ ]
3059
+ }
3060
+ )
3061
+ ]
3062
+ }
3063
+ );
3064
+ }
3065
+ );
3066
+ BottomSheetScaffold.displayName = "BottomSheetScaffold";
3067
+ var COPLANAR_TRANSITION = `margin ${getMotionTransitionCSS("default", "spatial")}`;
3068
+ var SideSheet = React6.forwardRef(
3069
+ ({
3070
+ isOpen,
3071
+ children,
3072
+ className,
3073
+ edge = "end",
3074
+ width = "360px",
3075
+ coplanarSiblingRef,
3076
+ portal = true,
3077
+ "aria-labelledby": ariaLabelledBy,
3078
+ "aria-label": ariaLabel,
3079
+ header,
3080
+ footer,
3081
+ divider,
3082
+ scrollAreaProps
3083
+ }, ref) => {
3084
+ const sheetAnim = React6.useMemo(() => buildSideSheetAnim(edge), [edge]);
3085
+ const [mounted, setMounted] = React6.useState(false);
3086
+ React6.useEffect(() => {
3087
+ setMounted(true);
3088
+ }, []);
3089
+ const resolvedDividers = React6.useMemo(
3090
+ () => resolveDividers(divider),
3091
+ [divider]
3092
+ );
3093
+ React6.useEffect(() => {
3094
+ const sibling = coplanarSiblingRef == null ? void 0 : coplanarSiblingRef.current;
3095
+ if (!sibling) return;
3096
+ sibling.style.transition = COPLANAR_TRANSITION;
3097
+ const marginProp = edge === "end" ? "marginRight" : "marginLeft";
3098
+ sibling.style[marginProp] = isOpen ? width : "";
3099
+ return () => {
3100
+ sibling.style.marginRight = "";
3101
+ sibling.style.marginLeft = "";
3102
+ sibling.style.transition = "";
3103
+ };
3104
+ }, [isOpen, edge, width, coplanarSiblingRef]);
3105
+ const content = /* @__PURE__ */ jsx(AnimatePresence, { children: isOpen && /* @__PURE__ */ jsxs(
3106
+ m.aside,
3107
+ __spreadProps(__spreadValues({
3108
+ ref,
3109
+ role: "complementary",
3110
+ "aria-label": ariaLabel,
3111
+ "aria-labelledby": ariaLabelledBy,
3112
+ tabIndex: -1,
3113
+ className: cn(
3114
+ "fixed top-0 bottom-0 z-40",
3115
+ edge === "end" ? "right-0" : "left-0",
3116
+ "bg-m3-surface-container-low",
3117
+ "flex flex-col overflow-hidden",
3118
+ edge === "end" ? "border-l border-m3-outline-variant" : "border-r border-m3-outline-variant",
3119
+ "outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-inset",
3120
+ className
3121
+ ),
3122
+ style: { width }
3123
+ }, sheetAnim), {
3124
+ children: [
3125
+ header && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-6 py-4", children: header }),
3126
+ header && resolvedDividers.header && /* @__PURE__ */ jsx("hr", { className: "border-t border-m3-outline-variant w-full shrink-0 m-0" }),
3127
+ /* @__PURE__ */ jsx(
3128
+ ScrollArea,
3129
+ __spreadProps(__spreadValues({
3130
+ type: "hover"
3131
+ }, scrollAreaProps), {
3132
+ className: cn(
3133
+ "flex-1 min-h-0 min-w-0",
3134
+ scrollAreaProps == null ? void 0 : scrollAreaProps.className
3135
+ ),
3136
+ viewportClassName: cn(
3137
+ "overscroll-contain",
3138
+ scrollAreaProps == null ? void 0 : scrollAreaProps.viewportClassName
3139
+ ),
3140
+ viewportProps: scrollAreaProps == null ? void 0 : scrollAreaProps.viewportProps,
3141
+ children
3142
+ })
3143
+ ),
3144
+ footer && resolvedDividers.footer && /* @__PURE__ */ jsx("hr", { className: "border-t border-m3-outline-variant w-full shrink-0 m-0" }),
3145
+ footer && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-6 py-4", children: footer })
3146
+ ]
3147
+ })
3148
+ ) });
3149
+ if (portal) {
3150
+ if (!mounted) return null;
3151
+ return createPortal(content, document.body);
3152
+ }
3153
+ return content;
3154
+ }
3155
+ );
3156
+ SideSheet.displayName = "SideSheet";
3157
+ var SideSheetModal = React6.forwardRef(
3158
+ ({
3159
+ isOpen,
3160
+ onClose,
3161
+ children,
3162
+ className,
3163
+ edge = "end",
3164
+ width = "360px",
3165
+ "aria-labelledby": ariaLabelledBy,
3166
+ "aria-label": ariaLabel,
3167
+ header,
3168
+ footer,
3169
+ divider,
3170
+ scrollAreaProps
3171
+ }, ref) => {
3172
+ const sheetAnim = React6.useMemo(() => buildSideSheetAnim(edge), [edge]);
3173
+ const resolvedDividers = React6.useMemo(
3174
+ () => resolveDividers(divider),
3175
+ [divider]
3176
+ );
3177
+ return /* @__PURE__ */ jsx(
3178
+ RadixDialog.Root,
3179
+ {
3180
+ open: isOpen,
3181
+ onOpenChange: (open) => !open && onClose(),
3182
+ children: /* @__PURE__ */ jsx(RadixDialog.Portal, { forceMount: true, children: /* @__PURE__ */ jsx(AnimatePresence, { mode: "wait", children: isOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
3183
+ /* @__PURE__ */ jsx(RadixDialog.Overlay, { asChild: true, children: /* @__PURE__ */ jsx(Scrim, { onClick: onClose }) }),
3184
+ /* @__PURE__ */ jsx(
3185
+ RadixDialog.Content,
3186
+ {
3187
+ asChild: true,
3188
+ "aria-describedby": void 0,
3189
+ "aria-labelledby": ariaLabelledBy,
3190
+ "aria-label": ariaLabel,
3191
+ onEscapeKeyDown: onClose,
3192
+ children: /* @__PURE__ */ jsxs(
3193
+ m.div,
3194
+ __spreadProps(__spreadValues({
3195
+ ref,
3196
+ className: cn(
3197
+ "fixed top-0 bottom-0 z-50",
3198
+ edge === "end" ? "right-0" : "left-0",
3199
+ "bg-m3-surface-container-low",
3200
+ "flex flex-col overflow-hidden",
3201
+ edge === "end" ? "border-l border-m3-outline-variant rounded-l-m3-xl" : "border-r border-m3-outline-variant rounded-r-m3-xl",
3202
+ "outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-inset",
3203
+ className
3204
+ ),
3205
+ style: { width }
3206
+ }, sheetAnim), {
3207
+ children: [
3208
+ /* @__PURE__ */ jsx(RadixDialog.Title, { className: "sr-only", children: ariaLabel || "Side Sheet" }),
3209
+ header && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-6 py-4", children: header }),
3210
+ header && resolvedDividers.header && /* @__PURE__ */ jsx("hr", { className: "border-t border-m3-outline-variant w-full shrink-0 m-0" }),
3211
+ /* @__PURE__ */ jsx(
3212
+ ScrollArea,
3213
+ __spreadProps(__spreadValues({
3214
+ type: "hover"
3215
+ }, scrollAreaProps), {
3216
+ className: cn(
3217
+ "flex-1 min-h-0 min-w-0",
3218
+ scrollAreaProps == null ? void 0 : scrollAreaProps.className
3219
+ ),
3220
+ viewportClassName: cn(
3221
+ "overscroll-contain",
3222
+ scrollAreaProps == null ? void 0 : scrollAreaProps.viewportClassName
3223
+ ),
3224
+ viewportProps: scrollAreaProps == null ? void 0 : scrollAreaProps.viewportProps,
3225
+ children
3226
+ })
3227
+ ),
3228
+ footer && resolvedDividers.footer && /* @__PURE__ */ jsx("hr", { className: "border-t border-m3-outline-variant w-full shrink-0 m-0" }),
3229
+ footer && /* @__PURE__ */ jsx("div", { className: "shrink-0 px-6 py-4", children: footer })
3230
+ ]
3231
+ })
3232
+ )
3233
+ }
3234
+ )
3235
+ ] }) }) })
3236
+ }
3237
+ );
3238
+ }
3239
+ );
3240
+ SideSheetModal.displayName = "SideSheetModal";
3241
+
3242
+ export { BottomSheet, BottomSheetModal, BottomSheetScaffold, Dialog, DialogBody, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogFullScreenContent, DialogHeader, DialogIcon, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DragHandle, Drawer, DrawerClose, DrawerContent, DrawerDescription, DrawerFooter, DrawerHeader, DrawerOverlay, DrawerPortal, DrawerTitle, DrawerTrigger, Scrim, SideSheet, SideSheetModal, useBottomSheet, useBottomSheetScaffold };
3243
+ //# sourceMappingURL=overlays.mjs.map
3244
+ //# sourceMappingURL=overlays.mjs.map