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