@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,2357 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('motion/react');
5
+ var React12 = require('react');
6
+ var clsx = require('clsx');
7
+ var tailwindMerge = require('tailwind-merge');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+ var reactSlot = require('@radix-ui/react-slot');
10
+ var reactDom = require('react-dom');
11
+
12
+ function _interopNamespace(e) {
13
+ if (e && e.__esModule) return e;
14
+ var n = Object.create(null);
15
+ if (e) {
16
+ Object.keys(e).forEach(function (k) {
17
+ if (k !== 'default') {
18
+ var d = Object.getOwnPropertyDescriptor(e, k);
19
+ Object.defineProperty(n, k, d.get ? d : {
20
+ enumerable: true,
21
+ get: function () { return e[k]; }
22
+ });
23
+ }
24
+ });
25
+ }
26
+ n.default = e;
27
+ return Object.freeze(n);
28
+ }
29
+
30
+ var React12__namespace = /*#__PURE__*/_interopNamespace(React12);
31
+
32
+ var __defProp = Object.defineProperty;
33
+ var __defProps = Object.defineProperties;
34
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
35
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
36
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
37
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
38
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
39
+ var __spreadValues = (a, b) => {
40
+ for (var prop in b || (b = {}))
41
+ if (__hasOwnProp.call(b, prop))
42
+ __defNormalProp(a, prop, b[prop]);
43
+ if (__getOwnPropSymbols)
44
+ for (var prop of __getOwnPropSymbols(b)) {
45
+ if (__propIsEnum.call(b, prop))
46
+ __defNormalProp(a, prop, b[prop]);
47
+ }
48
+ return a;
49
+ };
50
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
51
+ var __objRest = (source, exclude) => {
52
+ var target = {};
53
+ for (var prop in source)
54
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
55
+ target[prop] = source[prop];
56
+ if (source != null && __getOwnPropSymbols)
57
+ for (var prop of __getOwnPropSymbols(source)) {
58
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
59
+ target[prop] = source[prop];
60
+ }
61
+ return target;
62
+ };
63
+ function cn(...inputs) {
64
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
65
+ }
66
+
67
+ // src/ui/shared/motion-tokens.ts
68
+ var FAST_SPATIAL_SPRING = {
69
+ type: "spring",
70
+ stiffness: 800,
71
+ damping: 33.94
72
+ };
73
+ var DEFAULT_SPATIAL_SPRING = {
74
+ type: "spring",
75
+ stiffness: 380,
76
+ damping: 31.19
77
+ };
78
+ var FAST_EFFECTS_SPRING = {
79
+ type: "spring",
80
+ stiffness: 3800,
81
+ damping: 123.29
82
+ };
83
+ var DEFAULT_EFFECTS_SPRING = {
84
+ type: "spring",
85
+ stiffness: 1600,
86
+ damping: 80
87
+ };
88
+ function formatBadgeLabel(children, max) {
89
+ if (typeof children === "number") {
90
+ return max !== void 0 && children > max ? `${max}+` : String(children);
91
+ }
92
+ if (typeof children === "string") {
93
+ if (max !== void 0) {
94
+ const asNum = Number(children);
95
+ if (!Number.isNaN(asNum) && asNum > max) return `${max}+`;
96
+ }
97
+ return children.length > 4 ? children.slice(0, 4) : children;
98
+ }
99
+ return "";
100
+ }
101
+ function detectBadgeHasContent(badge) {
102
+ return React12__namespace.isValidElement(badge) && badge.props.children != null;
103
+ }
104
+ var BadgeImpl = React12__namespace.forwardRef(
105
+ (_a, ref) => {
106
+ var _b = _a, {
107
+ children,
108
+ max,
109
+ containerColor,
110
+ contentColor,
111
+ className,
112
+ style,
113
+ "aria-label": ariaLabel
114
+ } = _b, props = __objRest(_b, [
115
+ "children",
116
+ "max",
117
+ "containerColor",
118
+ "contentColor",
119
+ "className",
120
+ "style",
121
+ "aria-label"
122
+ ]);
123
+ const hasContent = children != null;
124
+ const label = hasContent ? formatBadgeLabel(children, max) : "";
125
+ const reducedMotion = react.useReducedMotion();
126
+ const isDecorative = !hasContent && !ariaLabel;
127
+ const springTransition = reducedMotion ? { duration: 0 } : FAST_SPATIAL_SPRING;
128
+ const colorStyle = __spreadValues(__spreadValues(__spreadValues({}, containerColor && { backgroundColor: containerColor }), contentColor && { color: contentColor }), style);
129
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
130
+ react.m.span,
131
+ __spreadProps(__spreadValues({
132
+ ref,
133
+ role: isDecorative ? void 0 : "status",
134
+ "aria-hidden": isDecorative ? "true" : void 0,
135
+ "aria-label": hasContent ? ariaLabel != null ? ariaLabel : label : ariaLabel,
136
+ initial: { scale: 0, opacity: 0 },
137
+ animate: { scale: 1, opacity: 1 },
138
+ exit: { scale: 0, opacity: 0 },
139
+ transition: springTransition,
140
+ className: cn(
141
+ "rounded-full ring-[1.5px] ring-m3-surface",
142
+ !containerColor && "bg-m3-error",
143
+ hasContent ? cn(
144
+ "inline-flex items-center justify-center",
145
+ "min-w-4 h-4 px-1 text-[11px] font-medium leading-none",
146
+ !contentColor && "text-m3-on-error"
147
+ ) : "inline-block w-1.5 h-1.5",
148
+ className
149
+ ),
150
+ style: colorStyle
151
+ }, props), {
152
+ children: hasContent && label
153
+ })
154
+ ) });
155
+ }
156
+ );
157
+ BadgeImpl.displayName = "Badge";
158
+ var Badge = React12__namespace.memo(BadgeImpl);
159
+ function BadgedBox({
160
+ badge,
161
+ children,
162
+ className,
163
+ badgeSize
164
+ }) {
165
+ const isLarge = badgeSize ? badgeSize === "large" : detectBadgeHasContent(badge);
166
+ const badgePositionClass = isLarge ? "translate-x-[35%] -translate-y-[35%]" : "translate-x-[50%] -translate-y-[50%]";
167
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: cn("relative inline-flex", className), children: [
168
+ children,
169
+ /* @__PURE__ */ jsxRuntime.jsx(
170
+ "span",
171
+ {
172
+ className: cn("absolute right-0 top-0", badgePositionClass),
173
+ "aria-hidden": "true",
174
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: badge })
175
+ }
176
+ )
177
+ ] });
178
+ }
179
+ 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";
180
+ var SHAPE_KEY_SPLINES = [
181
+ "0.5 0.2 0 0.8",
182
+ "0.5 0.2 0 0.8",
183
+ "0.5 0.2 0 0.8",
184
+ "0.5 0.2 0 0.8",
185
+ "0.5 0.2 0 0.8",
186
+ "0.5 0.2 0 0.8",
187
+ "0.5 0.2 0 0.8",
188
+ "0.5 0.2 0 0.8",
189
+ "0.5 0.2 0 0.8",
190
+ "0.5 0.2 0 0.8",
191
+ "0.5 0.2 0 0.8",
192
+ "0.5 0.2 0 0.8",
193
+ "0.5 0.2 0 0.8"
194
+ ].join("; ");
195
+ var SHAPE_VALUES = [
196
+ "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",
197
+ "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",
198
+ "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",
199
+ "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",
200
+ "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",
201
+ "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",
202
+ "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",
203
+ "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",
204
+ "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",
205
+ "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",
206
+ "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",
207
+ "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",
208
+ "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",
209
+ "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"
210
+ ].join(";");
211
+ var ROTATE_KEY_TIMES = "0; 0.14; 0.29; 0.43; 0.57; 0.71; 0.86; 1";
212
+ var ROTATE_KEY_SPLINES = [
213
+ "0.5 0.2 0 0.8",
214
+ "0.5 0.2 0 0.8",
215
+ "0.5 0.2 0 0.8",
216
+ "0.5 0.2 0 0.8",
217
+ "0.5 0.2 0 0.8",
218
+ "0.5 0.2 0 0.8",
219
+ "0.5 0.2 0 0.8"
220
+ ].join("; ");
221
+ 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";
222
+ 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";
223
+ 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";
224
+ var IndeterminateSvg = React12__namespace.memo(function IndeterminateSvg2({
225
+ size
226
+ }) {
227
+ const [ready, setReady] = React12__namespace.useState(false);
228
+ React12__namespace.useEffect(() => {
229
+ const raf = requestAnimationFrame(() => setReady(true));
230
+ return () => cancelAnimationFrame(raf);
231
+ }, []);
232
+ return /* @__PURE__ */ jsxRuntime.jsx(
233
+ "svg",
234
+ {
235
+ viewBox: "4 4 40 40",
236
+ width: size,
237
+ height: size,
238
+ fill: "currentColor",
239
+ xmlns: "http://www.w3.org/2000/svg",
240
+ "aria-hidden": "true",
241
+ focusable: "false",
242
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: SHAPE_VALUES.split(";")[0], children: ready && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
243
+ /* @__PURE__ */ jsxRuntime.jsx(
244
+ "animate",
245
+ {
246
+ attributeName: "d",
247
+ dur: "5s",
248
+ repeatCount: "indefinite",
249
+ calcMode: "spline",
250
+ keySplines: SHAPE_KEY_SPLINES,
251
+ keyTimes: SHAPE_KEY_TIMES,
252
+ values: SHAPE_VALUES
253
+ }
254
+ ),
255
+ /* @__PURE__ */ jsxRuntime.jsx(
256
+ "animateTransform",
257
+ {
258
+ attributeName: "transform",
259
+ attributeType: "XML",
260
+ type: "rotate",
261
+ dur: "5s",
262
+ repeatCount: "indefinite",
263
+ calcMode: "spline",
264
+ keySplines: ROTATE_KEY_SPLINES,
265
+ keyTimes: ROTATE_KEY_TIMES,
266
+ values: ROTATE_VALUES
267
+ }
268
+ )
269
+ ] }) })
270
+ }
271
+ );
272
+ });
273
+ var DeterminateSvg = React12__namespace.memo(function DeterminateSvg2({
274
+ size,
275
+ progress
276
+ }) {
277
+ const p = Math.min(1, Math.max(0, progress));
278
+ const rotation = -180 * p;
279
+ const pathD = p < 0.5 ? DETERMINATE_CIRCLE : DETERMINATE_SOFT_BURST;
280
+ return /* @__PURE__ */ jsxRuntime.jsx(
281
+ "svg",
282
+ {
283
+ viewBox: "4 4 40 40",
284
+ width: size,
285
+ height: size,
286
+ fill: "currentColor",
287
+ xmlns: "http://www.w3.org/2000/svg",
288
+ "aria-hidden": "true",
289
+ focusable: "false",
290
+ style: {
291
+ transform: `rotate(${rotation}deg)`,
292
+ transition: "transform 0.3s ease"
293
+ },
294
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: pathD, style: { transition: "d 0.3s ease" } })
295
+ }
296
+ );
297
+ });
298
+ var LoadingIndicator = React12__namespace.forwardRef(
299
+ (_a, ref) => {
300
+ var _b = _a, {
301
+ variant = "uncontained",
302
+ size = 48,
303
+ progress,
304
+ color,
305
+ className,
306
+ "aria-label": ariaLabel,
307
+ style
308
+ } = _b, restProps = __objRest(_b, [
309
+ "variant",
310
+ "size",
311
+ "progress",
312
+ "color",
313
+ "className",
314
+ "aria-label",
315
+ "style"
316
+ ]);
317
+ const isContained = variant === "contained";
318
+ const isDeterminate = progress !== void 0;
319
+ const clampedSize = Math.min(240, Math.max(24, size));
320
+ const scaleFactor = clampedSize / 48;
321
+ const containerSize = isContained ? 38 * scaleFactor : void 0;
322
+ const indicatorSize = isContained ? 24 * scaleFactor : clampedSize;
323
+ const activeColor = isContained ? color != null ? color : "var(--md-sys-color-indicator-contained-active)" : color != null ? color : "var(--md-sys-color-indicator-active)";
324
+ const ariaNow = isDeterminate ? Math.round(Math.min(1, Math.max(0, progress)) * 100) : void 0;
325
+ return /* @__PURE__ */ jsxRuntime.jsx(
326
+ "div",
327
+ __spreadProps(__spreadValues({
328
+ ref,
329
+ role: "progressbar",
330
+ "aria-label": ariaLabel,
331
+ "aria-valuemin": 0,
332
+ "aria-valuemax": 100,
333
+ "aria-valuenow": ariaNow,
334
+ className: cn(
335
+ "inline-flex items-center justify-center shrink-0",
336
+ className
337
+ ),
338
+ style: __spreadValues({
339
+ width: clampedSize,
340
+ height: clampedSize,
341
+ color: activeColor
342
+ }, style)
343
+ }, restProps), {
344
+ children: isContained ? /* @__PURE__ */ jsxRuntime.jsx(
345
+ "div",
346
+ {
347
+ className: "flex items-center justify-center rounded-full",
348
+ style: {
349
+ width: containerSize,
350
+ height: containerSize,
351
+ backgroundColor: "var(--md-sys-color-indicator-contained-container)"
352
+ },
353
+ children: isDeterminate ? /* @__PURE__ */ jsxRuntime.jsx(DeterminateSvg, { size: indicatorSize, progress }) : /* @__PURE__ */ jsxRuntime.jsx(IndeterminateSvg, { size: indicatorSize })
354
+ }
355
+ ) : isDeterminate ? /* @__PURE__ */ jsxRuntime.jsx(DeterminateSvg, { size: indicatorSize, progress }) : /* @__PURE__ */ jsxRuntime.jsx(IndeterminateSvg, { size: indicatorSize })
356
+ })
357
+ );
358
+ }
359
+ );
360
+ LoadingIndicator.displayName = "LoadingIndicator";
361
+
362
+ // src/ui/progress-indicator/utils.ts
363
+ function easeInOutCubic(x) {
364
+ return x < 0.5 ? 4 * x * x * x : 1 - (-2 * x + 2) ** 3 / 2;
365
+ }
366
+ function generateWavyCircularPath(center, radius, amplitude, wavelength) {
367
+ const circumference = 2 * Math.PI * radius;
368
+ const numWaves = Math.max(
369
+ 3,
370
+ Math.round(circumference / Math.max(1, wavelength))
371
+ );
372
+ const steps = numWaves * 4;
373
+ const dt = 2 * Math.PI / steps;
374
+ const rAt = (t) => radius + amplitude * Math.sin(numWaves * t);
375
+ const drAt = (t) => amplitude * numWaves * Math.cos(numWaves * t);
376
+ const xAt = (t) => center + rAt(t) * Math.cos(t);
377
+ const yAt = (t) => center + rAt(t) * Math.sin(t);
378
+ const dxAt = (t) => drAt(t) * Math.cos(t) - rAt(t) * Math.sin(t);
379
+ const dyAt = (t) => drAt(t) * Math.sin(t) + rAt(t) * Math.cos(t);
380
+ let d = "";
381
+ const tStart = 0;
382
+ for (let i = 0; i < steps; i++) {
383
+ const t0 = tStart + i * dt;
384
+ const t1 = tStart + (i + 1) * dt;
385
+ const scale = dt / 3;
386
+ const cp1x = xAt(t0) + scale * dxAt(t0);
387
+ const cp1y = yAt(t0) + scale * dyAt(t0);
388
+ const cp2x = xAt(t1) - scale * dxAt(t1);
389
+ const cp2y = yAt(t1) - scale * dyAt(t1);
390
+ if (i === 0) d += `M ${xAt(t0).toFixed(2)} ${yAt(t0).toFixed(2)}`;
391
+ d += ` C ${cp1x.toFixed(2)} ${cp1y.toFixed(2)}, ${cp2x.toFixed(2)} ${cp2y.toFixed(2)}, ${xAt(t1).toFixed(2)} ${yAt(t1).toFixed(2)}`;
392
+ }
393
+ d += " Z";
394
+ return d;
395
+ }
396
+ function getSinePath(startX, endX, phase, wl, amp) {
397
+ if (startX >= endX) return "";
398
+ let d = "";
399
+ const step = amp === 0 ? Math.max(10, endX - startX) : 1;
400
+ const yStart = Math.sin((startX + phase) / wl * 2 * Math.PI) * amp;
401
+ d += `M ${startX.toFixed(2)} ${yStart.toFixed(2)}`;
402
+ let nextX = Math.ceil(startX / step) * step;
403
+ if (nextX === startX) nextX += step;
404
+ while (nextX < endX) {
405
+ const y = Math.sin((nextX + phase) / wl * 2 * Math.PI) * amp;
406
+ d += ` L ${nextX.toFixed(2)} ${y.toFixed(2)}`;
407
+ nextX += step;
408
+ }
409
+ const yEnd = Math.sin((endX + phase) / wl * 2 * Math.PI) * amp;
410
+ d += ` L ${endX.toFixed(2)} ${yEnd.toFixed(2)}`;
411
+ return d;
412
+ }
413
+ var CircularProgress = React12__namespace.forwardRef(
414
+ (_a, ref) => {
415
+ var _b = _a, {
416
+ value,
417
+ size = 48,
418
+ trackHeight = 4,
419
+ shape = "flat",
420
+ amplitude,
421
+ wavelength,
422
+ gapSize = 4,
423
+ crawlerSpeed = 1,
424
+ color,
425
+ trackColor,
426
+ className,
427
+ "aria-label": ariaLabel
428
+ } = _b, restProps = __objRest(_b, [
429
+ "value",
430
+ "size",
431
+ "trackHeight",
432
+ "shape",
433
+ "amplitude",
434
+ "wavelength",
435
+ "gapSize",
436
+ "crawlerSpeed",
437
+ "color",
438
+ "trackColor",
439
+ "className",
440
+ "aria-label"
441
+ ]);
442
+ const isDeterminate = value !== void 0;
443
+ const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
444
+ const radius = (size - trackHeight) / 2;
445
+ const center = size / 2;
446
+ const activeColor = color || "var(--md-sys-color-indicator-active)";
447
+ const bgTrackColor = trackColor || "var(--md-sys-color-indicator-track)";
448
+ const isWavy = shape === "wavy";
449
+ const BASELINE_SIZE = 48;
450
+ const scaleFactor = size / BASELINE_SIZE;
451
+ const effectiveAmplitude = React12__namespace.useMemo(
452
+ () => amplitude != null ? amplitude : 1.6 * scaleFactor,
453
+ [amplitude, scaleFactor]
454
+ );
455
+ const effectiveWavelength = React12__namespace.useMemo(
456
+ () => wavelength != null ? wavelength : 15 * scaleFactor,
457
+ [wavelength, scaleFactor]
458
+ );
459
+ const wavyActivePath = React12__namespace.useMemo(
460
+ () => isWavy ? generateWavyCircularPath(
461
+ center,
462
+ radius,
463
+ effectiveAmplitude,
464
+ effectiveWavelength
465
+ ) : null,
466
+ [isWavy, center, radius, effectiveAmplitude, effectiveWavelength]
467
+ );
468
+ const circumference = React12__namespace.useMemo(() => 2 * Math.PI * radius, [radius]);
469
+ const gapForTrack = React12__namespace.useMemo(
470
+ () => (gapSize + trackHeight) / circumference,
471
+ [gapSize, trackHeight, circumference]
472
+ );
473
+ const activeAngularFraction = isDeterminate ? clampedValue / 100 : 0;
474
+ const trackOffset = isDeterminate ? activeAngularFraction + gapForTrack : 0;
475
+ const trackLength = isDeterminate ? Math.max(1e-3, 1 - activeAngularFraction - 2 * gapForTrack) : 1;
476
+ const ActiveCircleElem = react.m.circle;
477
+ const ActivePathElem = react.m.path;
478
+ return /* @__PURE__ */ jsxRuntime.jsx(
479
+ "div",
480
+ __spreadProps(__spreadValues({
481
+ ref,
482
+ role: "progressbar",
483
+ "aria-label": ariaLabel,
484
+ "aria-valuenow": isDeterminate ? clampedValue : void 0,
485
+ "aria-valuemin": 0,
486
+ "aria-valuemax": 100,
487
+ className: cn(
488
+ "relative inline-flex items-center justify-center shrink-0",
489
+ className
490
+ ),
491
+ style: { width: size, height: size }
492
+ }, restProps), {
493
+ children: /* @__PURE__ */ jsxRuntime.jsxs(react.LazyMotion, { features: react.domMax, strict: true, children: [
494
+ /* @__PURE__ */ jsxRuntime.jsxs(
495
+ "svg",
496
+ {
497
+ width: size,
498
+ height: size,
499
+ viewBox: `0 0 ${size} ${size}`,
500
+ "aria-hidden": "true",
501
+ style: { transform: "rotate(-90deg)", overflow: "visible" },
502
+ children: [
503
+ isDeterminate ? /* @__PURE__ */ jsxRuntime.jsx(
504
+ react.m.circle,
505
+ {
506
+ cx: center,
507
+ cy: center,
508
+ r: radius,
509
+ fill: "none",
510
+ stroke: bgTrackColor,
511
+ strokeWidth: trackHeight,
512
+ initial: { pathLength: trackLength, pathOffset: trackOffset },
513
+ animate: { pathLength: trackLength, pathOffset: trackOffset },
514
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] },
515
+ strokeLinecap: "round"
516
+ }
517
+ ) : null,
518
+ isDeterminate && (isWavy ? /* @__PURE__ */ jsxRuntime.jsx(
519
+ ActivePathElem,
520
+ {
521
+ d: wavyActivePath != null ? wavyActivePath : "",
522
+ fill: "none",
523
+ stroke: activeColor,
524
+ strokeWidth: trackHeight,
525
+ strokeLinecap: "round",
526
+ initial: { pathLength: 0 },
527
+ animate: { pathLength: clampedValue / 100 },
528
+ transition: {
529
+ duration: 0.4,
530
+ ease: [0.2, 0, 0, 1]
531
+ }
532
+ }
533
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
534
+ ActiveCircleElem,
535
+ {
536
+ cx: center,
537
+ cy: center,
538
+ r: radius,
539
+ fill: "none",
540
+ stroke: activeColor,
541
+ strokeWidth: trackHeight,
542
+ strokeLinecap: "round",
543
+ initial: { pathLength: 0 },
544
+ animate: { pathLength: clampedValue / 100 },
545
+ transition: {
546
+ duration: 0.4,
547
+ ease: [0.2, 0, 0, 1]
548
+ }
549
+ }
550
+ ))
551
+ ]
552
+ }
553
+ ),
554
+ !isDeterminate && /* @__PURE__ */ jsxRuntime.jsxs(
555
+ react.m.svg,
556
+ {
557
+ width: size,
558
+ height: size,
559
+ viewBox: `0 0 ${size} ${size}`,
560
+ "aria-hidden": "true",
561
+ style: {
562
+ position: "absolute",
563
+ inset: 0,
564
+ overflow: "visible",
565
+ rotate: "-90deg",
566
+ transformOrigin: "center"
567
+ },
568
+ animate: { rotate: ["-90deg", "270deg"] },
569
+ transition: {
570
+ rotate: {
571
+ duration: 2 / Math.max(0.1, crawlerSpeed),
572
+ repeat: Number.POSITIVE_INFINITY,
573
+ ease: "linear"
574
+ }
575
+ },
576
+ children: [
577
+ /* @__PURE__ */ jsxRuntime.jsx(
578
+ react.m.circle,
579
+ {
580
+ cx: center,
581
+ cy: center,
582
+ r: radius,
583
+ fill: "none",
584
+ stroke: bgTrackColor,
585
+ strokeWidth: trackHeight,
586
+ strokeLinecap: "round",
587
+ style: { originX: "50%", originY: "50%" },
588
+ animate: {
589
+ pathLength: [
590
+ Math.max(1e-3, 1 - 0.1 - 2 * gapForTrack),
591
+ Math.max(1e-3, 1 - 0.75 - 2 * gapForTrack),
592
+ Math.max(1e-3, 1 - 0.1 - 2 * gapForTrack)
593
+ ],
594
+ rotate: [
595
+ `${(0.1 + gapForTrack) * 360}deg`,
596
+ `${(1 + gapForTrack) * 360}deg`,
597
+ `${(1.1 + gapForTrack) * 360}deg`
598
+ ]
599
+ },
600
+ transition: {
601
+ duration: 2 / Math.max(0.1, crawlerSpeed),
602
+ repeat: Number.POSITIVE_INFINITY,
603
+ ease: [0.4, 0, 0.2, 1]
604
+ }
605
+ }
606
+ ),
607
+ isWavy ? /* @__PURE__ */ jsxRuntime.jsx(
608
+ ActivePathElem,
609
+ {
610
+ d: wavyActivePath != null ? wavyActivePath : "",
611
+ fill: "none",
612
+ stroke: activeColor,
613
+ strokeWidth: trackHeight,
614
+ strokeLinecap: "round",
615
+ style: { originX: "50%", originY: "50%" },
616
+ animate: {
617
+ pathLength: [0.1, 0.75, 0.1],
618
+ rotate: ["0deg", "90deg", "360deg"]
619
+ },
620
+ transition: {
621
+ duration: 2 / Math.max(0.1, crawlerSpeed),
622
+ repeat: Number.POSITIVE_INFINITY,
623
+ ease: [0.4, 0, 0.2, 1]
624
+ }
625
+ }
626
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
627
+ ActiveCircleElem,
628
+ {
629
+ cx: center,
630
+ cy: center,
631
+ r: radius,
632
+ fill: "none",
633
+ stroke: activeColor,
634
+ strokeWidth: trackHeight,
635
+ strokeLinecap: "round",
636
+ style: { originX: "50%", originY: "50%" },
637
+ animate: {
638
+ pathLength: [0.1, 0.75, 0.1],
639
+ rotate: ["0deg", "90deg", "360deg"]
640
+ },
641
+ transition: {
642
+ duration: 2 / Math.max(0.1, crawlerSpeed),
643
+ repeat: Number.POSITIVE_INFINITY,
644
+ ease: [0.4, 0, 0.2, 1]
645
+ }
646
+ }
647
+ )
648
+ ]
649
+ }
650
+ )
651
+ ] })
652
+ })
653
+ );
654
+ }
655
+ );
656
+ CircularProgress.displayName = "CircularProgress";
657
+ function useContainerWidth() {
658
+ const [width, setWidth] = React12__namespace.useState(0);
659
+ const observerRef = React12__namespace.useRef(null);
660
+ const ref = React12__namespace.useCallback((node) => {
661
+ if (observerRef.current) {
662
+ observerRef.current.disconnect();
663
+ observerRef.current = null;
664
+ }
665
+ if (node) {
666
+ const obs = new ResizeObserver((entries) => {
667
+ const contentRect = entries[0].contentRect;
668
+ setWidth(contentRect.width);
669
+ });
670
+ obs.observe(node);
671
+ observerRef.current = obs;
672
+ }
673
+ }, []);
674
+ React12__namespace.useEffect(() => {
675
+ return () => {
676
+ if (observerRef.current) {
677
+ observerRef.current.disconnect();
678
+ }
679
+ };
680
+ }, []);
681
+ return [ref, width];
682
+ }
683
+ function useMergedRef(...refs) {
684
+ return React12__namespace.useCallback(
685
+ (node) => {
686
+ for (const ref of refs) {
687
+ if (typeof ref === "function") {
688
+ ref(node);
689
+ } else if (ref && typeof ref === "object") {
690
+ ref.current = node;
691
+ }
692
+ }
693
+ },
694
+ // eslint-disable-next-line react-hooks/exhaustive-deps
695
+ [refs]
696
+ );
697
+ }
698
+ var FlatLinearTrack = React12__namespace.memo(function FlatLinearTrack2({
699
+ trackHeight,
700
+ activeColor,
701
+ trackColor,
702
+ value,
703
+ isRtl,
704
+ gapSize,
705
+ crawlerSpeed
706
+ }) {
707
+ const isDeterminate = value !== void 0;
708
+ const radius = trackHeight / 2;
709
+ const minActiveWidth = trackHeight;
710
+ return /* @__PURE__ */ jsxRuntime.jsx(
711
+ "div",
712
+ {
713
+ className: "relative w-full overflow-hidden",
714
+ style: { height: trackHeight, borderRadius: radius },
715
+ children: isDeterminate ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
716
+ /* @__PURE__ */ jsxRuntime.jsx(
717
+ react.m.div,
718
+ {
719
+ className: "absolute inset-y-0",
720
+ style: {
721
+ backgroundColor: trackColor,
722
+ borderRadius: radius,
723
+ width: "100%"
724
+ },
725
+ initial: {
726
+ [isRtl ? "right" : "left"]: `calc(max(${minActiveWidth}px, 0%) + ${gapSize}px)`
727
+ },
728
+ animate: {
729
+ [isRtl ? "right" : "left"]: `calc(max(${minActiveWidth}px, ${value}%) + ${gapSize}px)`
730
+ },
731
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] }
732
+ }
733
+ ),
734
+ /* @__PURE__ */ jsxRuntime.jsx(
735
+ react.m.div,
736
+ {
737
+ className: "absolute inset-y-0",
738
+ style: __spreadValues({
739
+ backgroundColor: activeColor,
740
+ borderRadius: radius,
741
+ minWidth: minActiveWidth
742
+ }, isRtl ? { right: 0 } : { left: 0 }),
743
+ initial: { width: `${minActiveWidth}px` },
744
+ animate: { width: `${value}%` },
745
+ transition: { duration: 0.4, ease: [0.2, 0, 0, 1] }
746
+ }
747
+ )
748
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
749
+ /* @__PURE__ */ jsxRuntime.jsx(
750
+ "div",
751
+ {
752
+ className: "absolute inset-0",
753
+ style: { backgroundColor: trackColor, borderRadius: radius }
754
+ }
755
+ ),
756
+ /* @__PURE__ */ jsxRuntime.jsx(
757
+ react.m.div,
758
+ {
759
+ className: "absolute inset-y-0",
760
+ style: { backgroundColor: activeColor, borderRadius: radius },
761
+ initial: { left: "-40%", width: "40%" },
762
+ animate: { left: ["-40%", "100%"], width: ["40%", "20%", "40%"] },
763
+ transition: {
764
+ duration: 2 / Math.max(0.1, crawlerSpeed),
765
+ repeat: Number.POSITIVE_INFINITY,
766
+ ease: "easeInOut"
767
+ }
768
+ }
769
+ )
770
+ ] })
771
+ }
772
+ );
773
+ });
774
+ var WavyLinearTrack = React12__namespace.memo(function WavyLinearTrack2({
775
+ trackHeight,
776
+ svgHeight,
777
+ amplitude,
778
+ wavelength,
779
+ indeterminateWavelength,
780
+ activeColor,
781
+ trackColor,
782
+ value,
783
+ isRtl,
784
+ gapSize,
785
+ waveSpeed,
786
+ crawlerSpeed,
787
+ determinateAnimation,
788
+ indeterminateAnimation,
789
+ trackShape
790
+ }) {
791
+ const isDeterminate = typeof value === "number";
792
+ const clampedValue = isDeterminate ? Math.max(0, Math.min(100, value)) : 100;
793
+ const titleId = React12__namespace.useId();
794
+ const [containerRef, width] = useContainerWidth();
795
+ const activePathRef = React12__namespace.useRef(null);
796
+ const trackPathRef = React12__namespace.useRef(null);
797
+ const amplitudeMV = react.useMotionValue(amplitude);
798
+ const fractionMV = react.useMotionValue(isDeterminate ? clampedValue / 100 : 1);
799
+ React12__namespace.useEffect(() => {
800
+ if (isDeterminate) {
801
+ const fraction = clampedValue / 100;
802
+ let targetAmp = amplitude;
803
+ if (determinateAnimation === "md3") {
804
+ targetAmp = fraction <= 0.1 || fraction >= 0.95 ? 0 : amplitude;
805
+ }
806
+ react.animate(amplitudeMV, targetAmp, {
807
+ type: "spring",
808
+ bounce: 0,
809
+ duration: 0.5
810
+ });
811
+ react.animate(fractionMV, fraction, { duration: 0.4, ease: [0.2, 0, 0, 1] });
812
+ }
813
+ }, [
814
+ clampedValue,
815
+ isDeterminate,
816
+ amplitude,
817
+ amplitudeMV,
818
+ fractionMV,
819
+ determinateAnimation
820
+ ]);
821
+ const activeWavelength = Math.max(
822
+ 1,
823
+ isDeterminate ? wavelength : indeterminateWavelength
824
+ );
825
+ const trackAmp = trackShape === "wavy" ? amplitude : 0;
826
+ react.useAnimationFrame((time) => {
827
+ if (width === 0) return;
828
+ const currentAmp = amplitudeMV.get();
829
+ const phase = time / 1e3 * waveSpeed * activeWavelength;
830
+ const capWidth = trackHeight / 2;
831
+ let activePathD = "";
832
+ let trackD = "";
833
+ const totalGap = gapSize + trackHeight;
834
+ if (isDeterminate) {
835
+ const fraction = fractionMV.get();
836
+ const barHead = fraction * width;
837
+ const adjHead = Math.max(capWidth, Math.min(width - capWidth, barHead));
838
+ const adjTail = capWidth;
839
+ if (fraction > 0 && adjHead - adjTail > 0.1) {
840
+ activePathD = getSinePath(
841
+ adjTail,
842
+ adjHead,
843
+ phase,
844
+ activeWavelength,
845
+ currentAmp
846
+ );
847
+ } else if (fraction === 0) {
848
+ activePathD = `M ${capWidth} 0 L ${capWidth + 0.01} 0`;
849
+ }
850
+ const trackStart = adjHead + totalGap;
851
+ if (trackStart < width - capWidth) {
852
+ trackD = getSinePath(
853
+ trackStart,
854
+ width - capWidth,
855
+ phase,
856
+ activeWavelength,
857
+ trackAmp
858
+ );
859
+ }
860
+ } else {
861
+ const safeCrawlerSpeed = Math.max(0.1, crawlerSpeed);
862
+ const activeLines = [];
863
+ if (indeterminateAnimation === "continuous") {
864
+ const cycle = 2e3 / safeCrawlerSpeed;
865
+ const fraction = time % cycle / cycle;
866
+ activeLines.push({
867
+ tail: easeInOutCubic(Math.max(0, fraction * 1.5 - 0.5)),
868
+ head: easeInOutCubic(Math.min(1, fraction * 1.5))
869
+ });
870
+ } else {
871
+ const cycle = 1750 / safeCrawlerSpeed;
872
+ const t = time % cycle * safeCrawlerSpeed;
873
+ const l1H = easeInOutCubic(Math.max(0, Math.min(1, t / 1e3)));
874
+ const l1T = easeInOutCubic(Math.max(0, Math.min(1, (t - 250) / 1e3)));
875
+ const l2H = easeInOutCubic(Math.max(0, Math.min(1, (t - 650) / 850)));
876
+ const l2T = easeInOutCubic(Math.max(0, Math.min(1, (t - 900) / 850)));
877
+ activeLines.push({ tail: l1T, head: l1H });
878
+ activeLines.push({ tail: l2T, head: l2H });
879
+ }
880
+ const segments = activeLines.map((line) => {
881
+ const barTail = line.tail * width;
882
+ const barHead = line.head * width;
883
+ const adjTail = Math.max(
884
+ capWidth,
885
+ Math.min(width - capWidth, barTail)
886
+ );
887
+ const adjHead = Math.max(
888
+ capWidth,
889
+ Math.min(width - capWidth, barHead)
890
+ );
891
+ return { adjTail, adjHead };
892
+ }).filter((seg) => seg.adjHead - seg.adjTail > 0.1);
893
+ activePathD = segments.map(
894
+ (seg) => getSinePath(
895
+ seg.adjTail,
896
+ seg.adjHead,
897
+ phase,
898
+ activeWavelength,
899
+ currentAmp
900
+ )
901
+ ).join(" ");
902
+ let currentTrackX = capWidth;
903
+ for (const seg of segments) {
904
+ const trackEnd = seg.adjTail - totalGap;
905
+ if (trackEnd > currentTrackX) {
906
+ trackD += `${getSinePath(currentTrackX, trackEnd, phase, activeWavelength, trackAmp)} `;
907
+ }
908
+ currentTrackX = Math.max(currentTrackX, seg.adjHead + totalGap);
909
+ }
910
+ if (currentTrackX < width - capWidth) {
911
+ trackD += getSinePath(
912
+ currentTrackX,
913
+ width - capWidth,
914
+ phase,
915
+ activeWavelength,
916
+ trackAmp
917
+ );
918
+ }
919
+ }
920
+ if (activePathRef.current)
921
+ activePathRef.current.setAttribute("d", activePathD);
922
+ if (trackPathRef.current)
923
+ trackPathRef.current.setAttribute("d", trackD.trim());
924
+ });
925
+ return /* @__PURE__ */ jsxRuntime.jsx(
926
+ "div",
927
+ {
928
+ ref: containerRef,
929
+ className: "relative w-full overflow-hidden",
930
+ style: { height: svgHeight },
931
+ children: width > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
932
+ "svg",
933
+ {
934
+ className: "absolute inset-0 w-full h-full",
935
+ style: {
936
+ overflow: "visible",
937
+ transform: isRtl ? "scaleX(-1)" : void 0
938
+ },
939
+ "aria-labelledby": titleId,
940
+ children: [
941
+ /* @__PURE__ */ jsxRuntime.jsx("title", { id: titleId, children: isDeterminate ? `Progress: ${clampedValue}%` : "Indeterminate loading progress" }),
942
+ /* @__PURE__ */ jsxRuntime.jsxs("g", { transform: `translate(0, ${svgHeight / 2})`, children: [
943
+ /* @__PURE__ */ jsxRuntime.jsx(
944
+ "path",
945
+ {
946
+ ref: trackPathRef,
947
+ fill: "none",
948
+ stroke: trackColor,
949
+ strokeWidth: trackHeight,
950
+ strokeLinecap: "round"
951
+ }
952
+ ),
953
+ /* @__PURE__ */ jsxRuntime.jsx(
954
+ "path",
955
+ {
956
+ ref: activePathRef,
957
+ fill: "none",
958
+ stroke: activeColor,
959
+ strokeWidth: trackHeight,
960
+ strokeLinecap: "round"
961
+ }
962
+ )
963
+ ] })
964
+ ]
965
+ }
966
+ )
967
+ }
968
+ );
969
+ });
970
+ var LinearProgress = React12__namespace.forwardRef(
971
+ (_a, ref) => {
972
+ var _b = _a, {
973
+ value,
974
+ shape = "flat",
975
+ trackShape,
976
+ trackHeight = 4,
977
+ amplitude,
978
+ wavelength = 40,
979
+ indeterminateWavelength = 20,
980
+ waveSpeed = 1,
981
+ crawlerSpeed = 1,
982
+ determinateAnimation = "md3",
983
+ indeterminateAnimation = "continuous",
984
+ gapSize = 4,
985
+ showStopIndicator = "auto",
986
+ color,
987
+ trackColor,
988
+ className,
989
+ "aria-label": ariaLabel
990
+ } = _b, restProps = __objRest(_b, [
991
+ "value",
992
+ "shape",
993
+ "trackShape",
994
+ "trackHeight",
995
+ "amplitude",
996
+ "wavelength",
997
+ "indeterminateWavelength",
998
+ "waveSpeed",
999
+ "crawlerSpeed",
1000
+ "determinateAnimation",
1001
+ "indeterminateAnimation",
1002
+ "gapSize",
1003
+ "showStopIndicator",
1004
+ "color",
1005
+ "trackColor",
1006
+ "className",
1007
+ "aria-label"
1008
+ ]);
1009
+ const isDeterminate = value !== void 0;
1010
+ const clampedValue = isDeterminate ? Math.min(100, Math.max(0, value)) : 0;
1011
+ const containerRef = React12__namespace.useRef(null);
1012
+ const mergedRef = useMergedRef(ref, containerRef);
1013
+ const [isRtl, setIsRtl] = React12__namespace.useState(false);
1014
+ React12__namespace.useEffect(() => {
1015
+ if (containerRef.current) {
1016
+ const dir = getComputedStyle(containerRef.current).direction;
1017
+ setIsRtl(dir === "rtl");
1018
+ }
1019
+ }, []);
1020
+ const isWavy = shape === "wavy";
1021
+ const resolvedTrackShape = trackShape != null ? trackShape : shape;
1022
+ const effectiveAmplitude = React12__namespace.useMemo(() => amplitude != null ? amplitude : 3, [amplitude]);
1023
+ const svgHeight = React12__namespace.useMemo(
1024
+ () => isWavy ? trackHeight + effectiveAmplitude * 2 : trackHeight,
1025
+ [isWavy, trackHeight, effectiveAmplitude]
1026
+ );
1027
+ const shouldShowStop = React12__namespace.useMemo(
1028
+ () => isDeterminate && resolvedTrackShape === "flat" && (showStopIndicator === true || showStopIndicator === "auto" && isDeterminate),
1029
+ [isDeterminate, resolvedTrackShape, showStopIndicator]
1030
+ );
1031
+ const stopSize = React12__namespace.useMemo(
1032
+ () => Math.max(2, trackHeight > 4 ? 4 : trackHeight / 2),
1033
+ [trackHeight]
1034
+ );
1035
+ const stopOffset = (trackHeight - stopSize) / 2;
1036
+ const activeColor = color || "var(--md-sys-color-indicator-active)";
1037
+ const bgTrackColor = trackColor || "var(--md-sys-color-indicator-track)";
1038
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1039
+ "div",
1040
+ __spreadProps(__spreadValues({
1041
+ ref: mergedRef,
1042
+ role: "progressbar",
1043
+ "aria-label": ariaLabel,
1044
+ "aria-valuenow": isDeterminate ? clampedValue : void 0,
1045
+ "aria-valuemin": 0,
1046
+ "aria-valuemax": 100,
1047
+ className: cn(
1048
+ "relative flex w-full flex-col justify-center",
1049
+ className
1050
+ ),
1051
+ style: { height: svgHeight }
1052
+ }, restProps), {
1053
+ children: [
1054
+ isWavy ? /* @__PURE__ */ jsxRuntime.jsx(
1055
+ WavyLinearTrack,
1056
+ {
1057
+ trackHeight,
1058
+ svgHeight,
1059
+ amplitude: effectiveAmplitude,
1060
+ wavelength,
1061
+ indeterminateWavelength,
1062
+ activeColor,
1063
+ trackColor: bgTrackColor,
1064
+ value: isDeterminate ? clampedValue : void 0,
1065
+ isRtl,
1066
+ gapSize,
1067
+ waveSpeed,
1068
+ crawlerSpeed,
1069
+ determinateAnimation,
1070
+ indeterminateAnimation,
1071
+ trackShape: resolvedTrackShape
1072
+ }
1073
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1074
+ FlatLinearTrack,
1075
+ {
1076
+ trackHeight,
1077
+ activeColor,
1078
+ trackColor: bgTrackColor,
1079
+ value: isDeterminate ? clampedValue : void 0,
1080
+ isRtl,
1081
+ gapSize,
1082
+ crawlerSpeed
1083
+ }
1084
+ ),
1085
+ shouldShowStop && /* @__PURE__ */ jsxRuntime.jsx(
1086
+ "div",
1087
+ {
1088
+ "aria-hidden": "true",
1089
+ className: "absolute rounded-full",
1090
+ style: __spreadValues({
1091
+ width: stopSize,
1092
+ height: stopSize,
1093
+ backgroundColor: "var(--md-sys-color-indicator-stop)",
1094
+ top: svgHeight / 2 - stopSize / 2
1095
+ }, isRtl ? { left: stopOffset } : { right: stopOffset })
1096
+ }
1097
+ )
1098
+ ]
1099
+ })
1100
+ ) });
1101
+ }
1102
+ );
1103
+ LinearProgress.displayName = "LinearProgress";
1104
+ var ProgressIndicator = React12__namespace.forwardRef((props, ref) => {
1105
+ if (props.variant === "circular") {
1106
+ return /* @__PURE__ */ jsxRuntime.jsx(CircularProgress, __spreadValues({ ref }, props));
1107
+ }
1108
+ return /* @__PURE__ */ jsxRuntime.jsx(LinearProgress, __spreadValues({ ref }, props));
1109
+ });
1110
+ ProgressIndicator.displayName = "ProgressIndicator";
1111
+ var RippleItem = React12__namespace.memo(function RippleItem2({
1112
+ ripple,
1113
+ onDone
1114
+ }) {
1115
+ return /* @__PURE__ */ jsxRuntime.jsx(
1116
+ react.m.span,
1117
+ {
1118
+ "aria-hidden": "true",
1119
+ style: {
1120
+ position: "absolute",
1121
+ left: ripple.x - ripple.size / 2,
1122
+ top: ripple.y - ripple.size / 2,
1123
+ width: ripple.size,
1124
+ height: ripple.size,
1125
+ borderRadius: "50%",
1126
+ backgroundColor: "currentColor",
1127
+ pointerEvents: "none",
1128
+ transformOrigin: "center"
1129
+ },
1130
+ initial: { scale: 0, opacity: 0.12 },
1131
+ animate: { scale: 1, opacity: 0 },
1132
+ exit: { opacity: 0 },
1133
+ transition: {
1134
+ scale: { duration: 0.5, ease: [0.2, 0, 0, 1] },
1135
+ opacity: { duration: 0.4, ease: "easeOut", delay: 0.1 }
1136
+ },
1137
+ onAnimationComplete: () => onDone(ripple.id)
1138
+ },
1139
+ ripple.id
1140
+ );
1141
+ });
1142
+ function Ripple({
1143
+ ripples,
1144
+ onRippleDone,
1145
+ disabled = false,
1146
+ respectSystemMotion = true
1147
+ }) {
1148
+ const prefersReduced = react.useReducedMotion();
1149
+ if (disabled) return null;
1150
+ if (respectSystemMotion && prefersReduced) return null;
1151
+ return /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { children: ripples.map((r) => /* @__PURE__ */ jsxRuntime.jsx(RippleItem, { ripple: r, onDone: onRippleDone }, r.id)) });
1152
+ }
1153
+ function useRippleState(options = {}) {
1154
+ const { disabled = false } = options;
1155
+ const [ripples, setRipples] = React12__namespace.useState([]);
1156
+ const onPointerDown = React12__namespace.useCallback(
1157
+ (e) => {
1158
+ if (disabled) return;
1159
+ const rect = e.currentTarget.getBoundingClientRect();
1160
+ const x = e.clientX - rect.left;
1161
+ const y = e.clientY - rect.top;
1162
+ const rippleSize = Math.hypot(rect.width, rect.height) * 2;
1163
+ setRipples((prev) => [
1164
+ ...prev,
1165
+ { id: Date.now(), x, y, size: rippleSize }
1166
+ ]);
1167
+ },
1168
+ [disabled]
1169
+ );
1170
+ const removeRipple = React12__namespace.useCallback((id) => {
1171
+ setRipples((prev) => prev.filter((r) => r.id !== id));
1172
+ }, []);
1173
+ return { ripples, onPointerDown, removeRipple };
1174
+ }
1175
+
1176
+ // src/ui/shared/constants.ts
1177
+ var SPRING_TRANSITION_FAST = FAST_EFFECTS_SPRING;
1178
+ var SPRING_TRANSITION = DEFAULT_EFFECTS_SPRING;
1179
+ var ICON_SPAN_VARIANTS = {
1180
+ initial: { scale: 0.01 },
1181
+ animate: { scale: 1 },
1182
+ exit: { scale: 0.01 }
1183
+ };
1184
+ function TouchTarget() {
1185
+ return /* @__PURE__ */ jsxRuntime.jsx(
1186
+ "span",
1187
+ {
1188
+ "aria-hidden": "true",
1189
+ 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"
1190
+ }
1191
+ );
1192
+ }
1193
+ var SIZE_STYLES = {
1194
+ xs: "h-8 w-8",
1195
+ sm: "h-10 w-10",
1196
+ md: "h-14 w-14",
1197
+ lg: "h-24 w-24",
1198
+ xl: "h-[8.5rem] w-[8.5rem]"
1199
+ };
1200
+ var SIZE_ICON = {
1201
+ xs: { cls: "size-5", px: 20 },
1202
+ sm: { cls: "size-6", px: 24 },
1203
+ md: { cls: "size-6", px: 24 },
1204
+ lg: { cls: "size-8", px: 32 },
1205
+ xl: { cls: "size-10", px: 40 }
1206
+ };
1207
+ var RADIUS_MAP = {
1208
+ xs: {
1209
+ round: 16,
1210
+ square: 12,
1211
+ pressed: 8,
1212
+ selectedRound: 12,
1213
+ selectedSquare: 16
1214
+ },
1215
+ sm: {
1216
+ round: 20,
1217
+ square: 12,
1218
+ pressed: 8,
1219
+ selectedRound: 12,
1220
+ selectedSquare: 20
1221
+ },
1222
+ md: {
1223
+ round: 28,
1224
+ square: 16,
1225
+ pressed: 12,
1226
+ selectedRound: 16,
1227
+ selectedSquare: 28
1228
+ },
1229
+ lg: {
1230
+ round: 48,
1231
+ square: 28,
1232
+ pressed: 16,
1233
+ selectedRound: 28,
1234
+ selectedSquare: 48
1235
+ },
1236
+ xl: {
1237
+ round: 68,
1238
+ square: 28,
1239
+ pressed: 16,
1240
+ selectedRound: 28,
1241
+ selectedSquare: 68
1242
+ }
1243
+ };
1244
+ var SIZE_OUTLINE_WIDTH = {
1245
+ xs: "border",
1246
+ sm: "border",
1247
+ md: "border",
1248
+ lg: "border-2",
1249
+ xl: "border-[3px]"
1250
+ };
1251
+ var colorStyles = {
1252
+ standard: {
1253
+ default: "text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
1254
+ selected: "text-m3-primary hover:bg-m3-primary/8 active:bg-m3-primary/12"
1255
+ },
1256
+ filled: {
1257
+ default: "bg-m3-surface-container text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
1258
+ selected: "bg-m3-primary text-m3-on-primary hover:brightness-95 active:brightness-90"
1259
+ },
1260
+ tonal: {
1261
+ default: "bg-m3-secondary-container text-m3-on-secondary-container hover:bg-m3-on-secondary-container/8 active:bg-m3-on-secondary-container/12",
1262
+ selected: "bg-m3-secondary text-m3-on-secondary hover:brightness-95 active:brightness-90"
1263
+ },
1264
+ outlined: {
1265
+ default: "border-m3-outline-variant text-m3-on-surface-variant hover:bg-m3-on-surface-variant/8 active:bg-m3-on-surface-variant/12",
1266
+ selected: "bg-m3-inverse-surface text-m3-inverse-on-surface border-transparent hover:brightness-95 active:brightness-90"
1267
+ }
1268
+ };
1269
+ var baseIconButtonClasses = [
1270
+ "relative shrink-0 inline-flex items-center justify-center",
1271
+ "select-none cursor-pointer",
1272
+ "transition-[background-color,color,border-color,box-shadow,opacity,filter] duration-200",
1273
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-m3-primary focus-visible:ring-offset-2",
1274
+ "disabled:pointer-events-none disabled:opacity-[0.38]"
1275
+ ];
1276
+ function resolveAnimateRadius(radiusConfig, shape, isToggle, isSelected) {
1277
+ if (isToggle && isSelected) {
1278
+ return shape === "round" ? radiusConfig.selectedRound : radiusConfig.selectedSquare;
1279
+ }
1280
+ return shape === "round" ? radiusConfig.round : radiusConfig.square;
1281
+ }
1282
+ function resolveDisabledBgClass(colorStyle) {
1283
+ if (colorStyle === "filled" || colorStyle === "tonal") {
1284
+ return "disabled:bg-m3-on-surface/12 disabled:text-m3-on-surface/[0.38]";
1285
+ }
1286
+ if (colorStyle === "outlined") {
1287
+ return "disabled:text-m3-on-surface/[0.38] disabled:border-m3-on-surface/[0.12]";
1288
+ }
1289
+ return "disabled:text-m3-on-surface/[0.38]";
1290
+ }
1291
+ var IconButtonComponent = React12__namespace.forwardRef(
1292
+ (_a, ref) => {
1293
+ var _b = _a, {
1294
+ className,
1295
+ style,
1296
+ variant = "default",
1297
+ colorStyle = "standard",
1298
+ size = "sm",
1299
+ shape = "round",
1300
+ selected,
1301
+ loading = false,
1302
+ loadingVariant = "loading-indicator",
1303
+ iconSize,
1304
+ children,
1305
+ onClick,
1306
+ onKeyDown,
1307
+ "aria-label": ariaLabel
1308
+ } = _b, restProps = __objRest(_b, [
1309
+ "className",
1310
+ "style",
1311
+ "variant",
1312
+ "colorStyle",
1313
+ "size",
1314
+ "shape",
1315
+ "selected",
1316
+ "loading",
1317
+ "loadingVariant",
1318
+ "iconSize",
1319
+ "children",
1320
+ "onClick",
1321
+ "onKeyDown",
1322
+ "aria-label"
1323
+ ]);
1324
+ var _a2, _b2;
1325
+ const isToggle = variant === "toggle";
1326
+ const isSelected = isToggle && !!selected;
1327
+ const resolvedColorClass = React12__namespace.useMemo(
1328
+ () => isSelected ? colorStyles[colorStyle].selected : colorStyles[colorStyle].default,
1329
+ [isSelected, colorStyle]
1330
+ );
1331
+ const outlineWidthClass = React12__namespace.useMemo(
1332
+ () => {
1333
+ var _a3;
1334
+ return colorStyle === "outlined" && !isSelected ? (_a3 = SIZE_OUTLINE_WIDTH[size]) != null ? _a3 : "border" : "";
1335
+ },
1336
+ [colorStyle, isSelected, size]
1337
+ );
1338
+ const disabledBgClass = React12__namespace.useMemo(
1339
+ () => resolveDisabledBgClass(colorStyle),
1340
+ [colorStyle]
1341
+ );
1342
+ const radiusConfig = (_a2 = RADIUS_MAP[size]) != null ? _a2 : RADIUS_MAP.sm;
1343
+ const animateRadius = resolveAnimateRadius(
1344
+ radiusConfig,
1345
+ shape,
1346
+ isToggle,
1347
+ isSelected
1348
+ );
1349
+ const pressedRadius = radiusConfig.pressed;
1350
+ const sizeIcon = (_b2 = SIZE_ICON[size]) != null ? _b2 : SIZE_ICON.sm;
1351
+ const iconClass = sizeIcon.cls;
1352
+ const defaultIconPx = sizeIcon.px;
1353
+ const iconPx = iconSize != null ? iconSize : defaultIconPx;
1354
+ const isCustomSize = iconSize != null && iconSize !== "inherit";
1355
+ const needsTouchTarget = size === "xs" || size === "sm";
1356
+ const { ripples, onPointerDown, removeRipple } = useRippleState({
1357
+ disabled: loading
1358
+ });
1359
+ const handleClick = React12__namespace.useCallback(
1360
+ (e) => {
1361
+ if (loading) {
1362
+ e.preventDefault();
1363
+ return;
1364
+ }
1365
+ onClick == null ? void 0 : onClick(e);
1366
+ },
1367
+ [loading, onClick]
1368
+ );
1369
+ const handleKeyDown = React12__namespace.useCallback(
1370
+ (e) => {
1371
+ if (loading) return;
1372
+ if ((e.key === "Enter" || e.key === " ") && onClick) {
1373
+ e.preventDefault();
1374
+ e.currentTarget.click();
1375
+ }
1376
+ onKeyDown == null ? void 0 : onKeyDown(e);
1377
+ },
1378
+ [loading, onClick, onKeyDown]
1379
+ );
1380
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsxs(
1381
+ react.m.button,
1382
+ __spreadProps(__spreadValues({
1383
+ ref,
1384
+ type: "button",
1385
+ "aria-pressed": isToggle ? isSelected : void 0,
1386
+ "aria-label": ariaLabel,
1387
+ "aria-busy": loading || void 0,
1388
+ "aria-disabled": loading || restProps.disabled,
1389
+ onClick: handleClick,
1390
+ onPointerDown,
1391
+ onKeyDown: handleKeyDown,
1392
+ style,
1393
+ animate: { borderRadius: animateRadius },
1394
+ whileTap: { borderRadius: pressedRadius },
1395
+ transition: { borderRadius: SPRING_TRANSITION_FAST },
1396
+ className: cn(
1397
+ baseIconButtonClasses,
1398
+ resolvedColorClass,
1399
+ outlineWidthClass,
1400
+ disabledBgClass,
1401
+ "overflow-hidden",
1402
+ SIZE_STYLES[size],
1403
+ loading && "pointer-events-none opacity-75 cursor-not-allowed",
1404
+ className
1405
+ )
1406
+ }, restProps), {
1407
+ children: [
1408
+ needsTouchTarget && /* @__PURE__ */ jsxRuntime.jsx(TouchTarget, {}),
1409
+ /* @__PURE__ */ jsxRuntime.jsx(Ripple, { ripples, onRippleDone: removeRipple }),
1410
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", initial: false, children: loading ? /* @__PURE__ */ jsxRuntime.jsx(
1411
+ react.m.span,
1412
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
1413
+ transition: SPRING_TRANSITION,
1414
+ className: cn(
1415
+ "flex items-center justify-center shrink-0",
1416
+ iconSize != null ? void 0 : iconClass
1417
+ ),
1418
+ style: isCustomSize ? { width: `${iconSize}px`, height: `${iconSize}px` } : void 0,
1419
+ children: loadingVariant === "loading-indicator" ? /* @__PURE__ */ jsxRuntime.jsx(
1420
+ LoadingIndicator,
1421
+ {
1422
+ size: typeof iconPx === "number" ? iconPx : defaultIconPx,
1423
+ color: "currentColor",
1424
+ "aria-label": "Loading"
1425
+ }
1426
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1427
+ ProgressIndicator,
1428
+ {
1429
+ variant: "circular",
1430
+ size: typeof iconPx === "number" ? iconPx : defaultIconPx,
1431
+ color: "currentColor",
1432
+ trackColor: "transparent",
1433
+ "aria-label": "Loading"
1434
+ }
1435
+ )
1436
+ }),
1437
+ "loading"
1438
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1439
+ react.m.span,
1440
+ __spreadProps(__spreadValues({}, ICON_SPAN_VARIANTS), {
1441
+ transition: SPRING_TRANSITION,
1442
+ "aria-hidden": "true",
1443
+ className: cn(
1444
+ "flex items-center justify-center shrink-0 [&_svg]:w-full [&_svg]:h-full [&_.md-icon]:text-[length:inherit]!",
1445
+ iconSize != null ? void 0 : iconClass
1446
+ ),
1447
+ style: {
1448
+ fontSize: typeof iconPx === "number" ? `${iconPx}px` : iconPx,
1449
+ width: isCustomSize ? `${iconSize}px` : void 0,
1450
+ height: isCustomSize ? `${iconSize}px` : void 0
1451
+ },
1452
+ children
1453
+ }),
1454
+ "content"
1455
+ ) })
1456
+ ]
1457
+ })
1458
+ ) });
1459
+ }
1460
+ );
1461
+ IconButtonComponent.displayName = "IconButton";
1462
+ var IconButton = React12__namespace.memo(IconButtonComponent);
1463
+ var VARIANT_FONT = {
1464
+ outlined: "'Material Symbols Outlined'",
1465
+ rounded: "'Material Symbols Rounded'",
1466
+ sharp: "'Material Symbols Sharp'"
1467
+ };
1468
+ var IconComponent = React12__namespace.forwardRef(
1469
+ (_a, ref) => {
1470
+ var _b = _a, {
1471
+ name,
1472
+ variant = "outlined",
1473
+ fill = 0,
1474
+ weight = 400,
1475
+ grade = 0,
1476
+ opticalSize = 24,
1477
+ size,
1478
+ animateFill = false,
1479
+ className,
1480
+ style
1481
+ } = _b, restProps = __objRest(_b, [
1482
+ "name",
1483
+ "variant",
1484
+ "fill",
1485
+ "weight",
1486
+ "grade",
1487
+ "opticalSize",
1488
+ "size",
1489
+ "animateFill",
1490
+ "className",
1491
+ "style"
1492
+ ]);
1493
+ const fontVariationSettings = `'FILL' ${fill}, 'wght' ${weight}, 'GRAD' ${grade}, 'opsz' ${opticalSize}`;
1494
+ const computedStyle = __spreadValues({
1495
+ fontFamily: VARIANT_FONT[variant],
1496
+ fontSize: size === "inherit" ? "inherit" : size != null ? `${size}px` : `${opticalSize}px`,
1497
+ fontVariationSettings
1498
+ }, style);
1499
+ if (animateFill) {
1500
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1501
+ react.m.span,
1502
+ __spreadProps(__spreadValues({
1503
+ ref,
1504
+ className: cn(
1505
+ "md-icon inline-flex items-center justify-center shrink-0 select-none",
1506
+ className
1507
+ ),
1508
+ "aria-hidden": "true",
1509
+ animate: { fontVariationSettings },
1510
+ transition: SPRING_TRANSITION_FAST,
1511
+ style: computedStyle
1512
+ }, restProps), {
1513
+ children: name
1514
+ })
1515
+ ) });
1516
+ }
1517
+ return /* @__PURE__ */ jsxRuntime.jsx(
1518
+ "span",
1519
+ __spreadProps(__spreadValues({
1520
+ ref,
1521
+ className: cn(
1522
+ "md-icon inline-flex items-center justify-center shrink-0 select-none",
1523
+ className
1524
+ ),
1525
+ "aria-hidden": "true",
1526
+ style: computedStyle
1527
+ }, restProps), {
1528
+ children: name
1529
+ })
1530
+ );
1531
+ }
1532
+ );
1533
+ IconComponent.displayName = "Icon";
1534
+ var Icon = React12__namespace.memo(IconComponent);
1535
+ var DURATION_MAP = {
1536
+ short: 4e3,
1537
+ long: 7e3
1538
+ };
1539
+ var RESULT = {
1540
+ ACTION: "action-performed",
1541
+ DISMISSED: "dismissed"
1542
+ };
1543
+ var SNACKBAR_SPRING = DEFAULT_SPATIAL_SPRING;
1544
+ var SNACKBAR_ANIM = {
1545
+ initial: { opacity: 0, y: 56, scale: 0.9 },
1546
+ animate: {
1547
+ opacity: 1,
1548
+ y: 0,
1549
+ scale: 1,
1550
+ transition: SNACKBAR_SPRING
1551
+ },
1552
+ exit: {
1553
+ opacity: 0,
1554
+ y: 24,
1555
+ scale: 0.95,
1556
+ transition: { duration: 0.2, ease: "easeIn" }
1557
+ }
1558
+ };
1559
+ var REDUCED_MOTION_ANIM = {
1560
+ initial: { opacity: 0 },
1561
+ animate: { opacity: 1 },
1562
+ exit: { opacity: 0 }
1563
+ };
1564
+ function resolveDuration(duration) {
1565
+ if (duration === void 0) return DURATION_MAP.short;
1566
+ if (typeof duration === "number") return duration;
1567
+ return DURATION_MAP[duration];
1568
+ }
1569
+ function generateId() {
1570
+ return typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : Math.random().toString(36).slice(2);
1571
+ }
1572
+ function toSnackbarData(item) {
1573
+ return { id: generateId(), visuals: item.visuals, resolve: item.resolve };
1574
+ }
1575
+ function useSnackbarState() {
1576
+ const [current, setCurrent] = React12__namespace.useState(null);
1577
+ const queueRef = React12__namespace.useRef([]);
1578
+ const showSnackbar = React12__namespace.useCallback(
1579
+ (visuals) => {
1580
+ return new Promise((resolve) => {
1581
+ const item = { visuals, resolve };
1582
+ setCurrent((prev) => {
1583
+ if (prev === null) return toSnackbarData(item);
1584
+ queueRef.current.push(item);
1585
+ return prev;
1586
+ });
1587
+ });
1588
+ },
1589
+ []
1590
+ );
1591
+ const _dismiss = React12__namespace.useCallback((result) => {
1592
+ setCurrent((prev) => {
1593
+ if (prev) prev.resolve(result);
1594
+ const next = queueRef.current.shift();
1595
+ return next ? toSnackbarData(next) : null;
1596
+ });
1597
+ }, []);
1598
+ React12__namespace.useEffect(() => {
1599
+ return () => {
1600
+ for (const item of queueRef.current) {
1601
+ item.resolve(RESULT.DISMISSED);
1602
+ }
1603
+ queueRef.current = [];
1604
+ };
1605
+ }, []);
1606
+ return { current, showSnackbar, _dismiss };
1607
+ }
1608
+ var Snackbar = React12__namespace.memo(function Snackbar2({
1609
+ data,
1610
+ className
1611
+ }) {
1612
+ const { visuals, resolve } = data;
1613
+ const {
1614
+ message,
1615
+ actionLabel,
1616
+ withDismissAction = false,
1617
+ actionOnNewLine = false,
1618
+ duration
1619
+ } = visuals;
1620
+ const reducedMotion = react.useReducedMotion();
1621
+ const durationMs = resolveDuration(duration);
1622
+ React12__namespace.useEffect(() => {
1623
+ const timer = setTimeout(() => resolve(RESULT.DISMISSED), durationMs);
1624
+ return () => clearTimeout(timer);
1625
+ }, [resolve, durationMs]);
1626
+ const handleAction = React12__namespace.useCallback(
1627
+ () => resolve(RESULT.ACTION),
1628
+ [resolve]
1629
+ );
1630
+ const handleDismiss = React12__namespace.useCallback(
1631
+ () => resolve(RESULT.DISMISSED),
1632
+ [resolve]
1633
+ );
1634
+ const hasActions = actionLabel || withDismissAction;
1635
+ const anim = reducedMotion ? REDUCED_MOTION_ANIM : SNACKBAR_ANIM;
1636
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1637
+ react.m.div,
1638
+ __spreadProps(__spreadValues({
1639
+ role: "status",
1640
+ "aria-live": "polite",
1641
+ "aria-atomic": "true"
1642
+ }, anim), {
1643
+ className: cn(
1644
+ "flex items-center gap-2",
1645
+ "min-w-72 max-w-142 w-max",
1646
+ "rounded-sm px-4 py-3 shadow-md",
1647
+ "text-m3-inverse-on-surface bg-m3-inverse-surface",
1648
+ actionOnNewLine ? "flex-col items-start" : "flex-row",
1649
+ className,
1650
+ visuals.className
1651
+ ),
1652
+ children: [
1653
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-1 text-sm leading-5 font-normal", children: message }),
1654
+ hasActions && /* @__PURE__ */ jsxRuntime.jsxs(
1655
+ "div",
1656
+ {
1657
+ className: cn(
1658
+ "flex shrink-0 items-center gap-1",
1659
+ actionOnNewLine && "self-end"
1660
+ ),
1661
+ children: [
1662
+ actionLabel && /* @__PURE__ */ jsxRuntime.jsx(
1663
+ "button",
1664
+ {
1665
+ type: "button",
1666
+ onClick: handleAction,
1667
+ className: cn(
1668
+ "text-sm font-medium",
1669
+ "px-2 py-1 rounded-sm",
1670
+ "focus-visible:outline-none focus-visible:ring-2",
1671
+ "transition-colors whitespace-nowrap",
1672
+ "text-m3-inverse-primary"
1673
+ ),
1674
+ children: actionLabel
1675
+ }
1676
+ ),
1677
+ withDismissAction && /* @__PURE__ */ jsxRuntime.jsx(
1678
+ IconButton,
1679
+ {
1680
+ size: "sm",
1681
+ colorStyle: "filled",
1682
+ "aria-label": "Dismiss notification",
1683
+ onClick: handleDismiss,
1684
+ className: "text-m3-inverse-on-surface bg-m3-inverse-surface",
1685
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { name: "close", "aria-hidden": "true" })
1686
+ }
1687
+ )
1688
+ ]
1689
+ }
1690
+ )
1691
+ ]
1692
+ })
1693
+ );
1694
+ });
1695
+ Snackbar.displayName = "Snackbar";
1696
+ function SnackbarHost({ state, className }) {
1697
+ const { current, _dismiss } = state;
1698
+ const wrappedData = React12__namespace.useMemo(() => {
1699
+ if (!current) return null;
1700
+ return __spreadProps(__spreadValues({}, current), { resolve: _dismiss });
1701
+ }, [current, _dismiss]);
1702
+ return /* @__PURE__ */ jsxRuntime.jsx(react.LazyMotion, { features: react.domMax, strict: true, children: /* @__PURE__ */ jsxRuntime.jsx(
1703
+ "section",
1704
+ {
1705
+ "aria-label": "Snackbar notifications",
1706
+ className: cn(
1707
+ "fixed bottom-4 left-1/2 -translate-x-1/2 z-50",
1708
+ "flex flex-col items-center pointer-events-none",
1709
+ className
1710
+ ),
1711
+ children: /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: wrappedData && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-auto", children: /* @__PURE__ */ jsxRuntime.jsx(Snackbar, { data: wrappedData }) }, wrappedData.id) })
1712
+ }
1713
+ ) });
1714
+ }
1715
+ SnackbarHost.displayName = "SnackbarHost";
1716
+ var SnackbarContext = React12__namespace.createContext(
1717
+ null
1718
+ );
1719
+ function SnackbarProvider({ children }) {
1720
+ const state = useSnackbarState();
1721
+ const contextValue = React12__namespace.useMemo(
1722
+ () => ({ showSnackbar: state.showSnackbar }),
1723
+ [state.showSnackbar]
1724
+ );
1725
+ return /* @__PURE__ */ jsxRuntime.jsxs(SnackbarContext.Provider, { value: contextValue, children: [
1726
+ children,
1727
+ /* @__PURE__ */ jsxRuntime.jsx(SnackbarHost, { state })
1728
+ ] });
1729
+ }
1730
+ SnackbarProvider.displayName = "SnackbarProvider";
1731
+ function useSnackbar() {
1732
+ const ctx = React12__namespace.useContext(SnackbarContext);
1733
+ if (!ctx) {
1734
+ throw new Error("useSnackbar must be used within a <SnackbarProvider>.");
1735
+ }
1736
+ return ctx;
1737
+ }
1738
+
1739
+ // src/ui/tooltip/tooltip.tokens.ts
1740
+ var TooltipTokens = {
1741
+ PlainTooltip: {
1742
+ containerColor: "var(--md-sys-color-inverse-surface)",
1743
+ // #322F35 light / #E6E1E5 dark
1744
+ textColor: "var(--md-sys-color-inverse-on-surface)",
1745
+ // #F5EFF7 light / #322F35 dark
1746
+ shape: "rounded-[4px]",
1747
+ // CornerExtraSmall = 4dp
1748
+ font: "text-[12px] font-normal tracking-[0.4px] leading-[16px]",
1749
+ // BodySmall
1750
+ height: "min-h-6",
1751
+ // 24dp min height
1752
+ padding: "px-2 py-1",
1753
+ // 8dp all sides
1754
+ maxWidth: "max-w-50"
1755
+ },
1756
+ RichTooltip: {
1757
+ containerColor: "var(--md-sys-color-surface-container)",
1758
+ elevation: "shadow-md",
1759
+ // ElevationTokens.Level2 (approximate with shadow-md)
1760
+ shape: "rounded-[12px]",
1761
+ // CornerMedium = 12dp
1762
+ paddingTop: "pt-3",
1763
+ // 12dp
1764
+ paddingBottom: "pb-2",
1765
+ // 8dp
1766
+ paddingX: "px-4",
1767
+ // 16dp
1768
+ maxWidth: "max-w-80",
1769
+ subheadColor: "var(--md-sys-color-on-surface-variant)",
1770
+ subheadFont: "text-[14px] font-medium leading-[20px]",
1771
+ // TitleSmall
1772
+ bodyColor: "var(--md-sys-color-on-surface-variant)",
1773
+ bodyFont: "text-[14px] font-normal leading-[20px]",
1774
+ // BodyMedium
1775
+ actionColor: "var(--md-sys-color-primary)",
1776
+ actionFont: "text-[14px] font-medium leading-[20px]"
1777
+ // LabelLarge
1778
+ }
1779
+ };
1780
+ var CENTER_H = "left-1/2 -translate-x-1/2";
1781
+ var CENTER_V = "top-1/2 -translate-y-1/2 flex items-center justify-center";
1782
+ var POSITION_BY_SIDE = {
1783
+ top: (h) => `bottom-[calc(-1*${h}px)] ${CENTER_H}`,
1784
+ bottom: (h) => `top-[calc(-1*${h}px)] ${CENTER_H}`,
1785
+ left: (h) => `right-[calc(-1*${h}px)] ${CENTER_V}`,
1786
+ right: (h) => `left-[calc(-1*${h}px)] ${CENTER_V}`
1787
+ };
1788
+ var ROTATION = {
1789
+ top: "180deg",
1790
+ bottom: "0deg",
1791
+ left: "90deg",
1792
+ right: "-90deg"
1793
+ };
1794
+ function TooltipCaretShape({
1795
+ side,
1796
+ width = 16,
1797
+ height = 8,
1798
+ color,
1799
+ customPath,
1800
+ className = ""
1801
+ }) {
1802
+ const isHorizontal = side === "left" || side === "right";
1803
+ const path = customPath != null ? customPath : `M 0,${height} L ${width / 2},0 L ${width},${height} Z`;
1804
+ return /* @__PURE__ */ jsxRuntime.jsx(
1805
+ "div",
1806
+ {
1807
+ className: `absolute pointer-events-none z-[-1] ${POSITION_BY_SIDE[side](height)} ${className}`,
1808
+ style: {
1809
+ width: isHorizontal ? height : width,
1810
+ height: isHorizontal ? width : height,
1811
+ color
1812
+ },
1813
+ "aria-hidden": "true",
1814
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1815
+ "svg",
1816
+ {
1817
+ width,
1818
+ height,
1819
+ viewBox: `0 0 ${width} ${height}`,
1820
+ fill: "currentColor",
1821
+ xmlns: "http://www.w3.org/2000/svg",
1822
+ "aria-hidden": "true",
1823
+ style: {
1824
+ transform: `rotate(${ROTATION[side]})`,
1825
+ display: "block",
1826
+ transformOrigin: "center"
1827
+ },
1828
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: path })
1829
+ }
1830
+ )
1831
+ }
1832
+ );
1833
+ }
1834
+ var PlainTooltip = React12.forwardRef(
1835
+ (_a, ref) => {
1836
+ var _b = _a, {
1837
+ children,
1838
+ caret,
1839
+ className = "",
1840
+ maxWidth,
1841
+ containerColor,
1842
+ textColor
1843
+ } = _b, props = __objRest(_b, [
1844
+ "children",
1845
+ "caret",
1846
+ "className",
1847
+ "maxWidth",
1848
+ "containerColor",
1849
+ "textColor"
1850
+ ]);
1851
+ var _a2;
1852
+ const {
1853
+ containerColor: tokenContainer,
1854
+ textColor: tokenText,
1855
+ font,
1856
+ padding,
1857
+ shape,
1858
+ height,
1859
+ maxWidth: tokenMaxWidth
1860
+ } = TooltipTokens.PlainTooltip;
1861
+ const style = __spreadValues(__spreadProps(__spreadValues({}, props.style), {
1862
+ backgroundColor: containerColor != null ? containerColor : tokenContainer,
1863
+ color: textColor != null ? textColor : tokenText
1864
+ }), maxWidth && { maxWidth });
1865
+ const side = (_a2 = props["data-side"]) != null ? _a2 : "top";
1866
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1867
+ "div",
1868
+ __spreadProps(__spreadValues({
1869
+ ref,
1870
+ className: `relative inline-flex items-center box-border ${shape} ${font} ${padding} ${height} ${!maxWidth ? tokenMaxWidth : ""} ${className}`,
1871
+ style
1872
+ }, props), {
1873
+ children: [
1874
+ (caret == null ? void 0 : caret.enabled) && /* @__PURE__ */ jsxRuntime.jsx(
1875
+ TooltipCaretShape,
1876
+ {
1877
+ side,
1878
+ width: caret.width,
1879
+ height: caret.height,
1880
+ color: style.backgroundColor,
1881
+ customPath: caret.customPath
1882
+ }
1883
+ ),
1884
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-normal text-start wrap-break-word", children })
1885
+ ]
1886
+ })
1887
+ );
1888
+ }
1889
+ );
1890
+ PlainTooltip.displayName = "PlainTooltip";
1891
+ var RichTooltip = React12.forwardRef(
1892
+ (_a, ref) => {
1893
+ var _b = _a, {
1894
+ children,
1895
+ title,
1896
+ action,
1897
+ caret,
1898
+ className = "",
1899
+ maxWidth,
1900
+ colors = {}
1901
+ } = _b, props = __objRest(_b, [
1902
+ "children",
1903
+ "title",
1904
+ "action",
1905
+ "caret",
1906
+ "className",
1907
+ "maxWidth",
1908
+ "colors"
1909
+ ]);
1910
+ var _a2, _b2, _c, _d, _e;
1911
+ const {
1912
+ containerColor: tokenContainer,
1913
+ elevation,
1914
+ shape,
1915
+ paddingTop,
1916
+ paddingBottom,
1917
+ paddingX,
1918
+ maxWidth: tokenMaxWidth,
1919
+ subheadColor,
1920
+ subheadFont,
1921
+ bodyColor,
1922
+ bodyFont,
1923
+ actionColor,
1924
+ actionFont
1925
+ } = TooltipTokens.RichTooltip;
1926
+ const containerStyle = __spreadValues(__spreadProps(__spreadValues({}, props.style), {
1927
+ backgroundColor: (_a2 = colors.container) != null ? _a2 : tokenContainer
1928
+ }), maxWidth && { maxWidth });
1929
+ const side = (_b2 = props["data-side"]) != null ? _b2 : "top";
1930
+ const titleColor = (_c = colors.title) != null ? _c : subheadColor;
1931
+ const bodyColorResolved = (_d = colors.body) != null ? _d : bodyColor;
1932
+ const actionColorResolved = (_e = colors.action) != null ? _e : actionColor;
1933
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1934
+ "div",
1935
+ __spreadProps(__spreadValues({
1936
+ ref,
1937
+ className: `relative box-border flex flex-col ${shape} ${elevation} ${paddingTop} ${paddingBottom} ${paddingX} ${!maxWidth ? tokenMaxWidth : ""} ${className}`,
1938
+ style: containerStyle
1939
+ }, props), {
1940
+ children: [
1941
+ (caret == null ? void 0 : caret.enabled) && /* @__PURE__ */ jsxRuntime.jsx(
1942
+ TooltipCaretShape,
1943
+ {
1944
+ side,
1945
+ width: caret.width,
1946
+ height: caret.height,
1947
+ color: containerStyle.backgroundColor,
1948
+ customPath: caret.customPath
1949
+ }
1950
+ ),
1951
+ title && /* @__PURE__ */ jsxRuntime.jsx("div", { className: `mb-1 ${subheadFont}`, style: { color: titleColor }, children: title }),
1952
+ children && /* @__PURE__ */ jsxRuntime.jsx(
1953
+ "div",
1954
+ {
1955
+ className: `whitespace-normal text-start wrap-break-word ${bodyFont}`,
1956
+ style: { color: bodyColorResolved },
1957
+ children
1958
+ }
1959
+ ),
1960
+ action && /* @__PURE__ */ jsxRuntime.jsx(
1961
+ "div",
1962
+ {
1963
+ className: `mt-2 flex min-h-9 flex-wrap items-center gap-2 ${actionFont}`,
1964
+ style: { color: actionColorResolved },
1965
+ children: action
1966
+ }
1967
+ )
1968
+ ]
1969
+ })
1970
+ );
1971
+ }
1972
+ );
1973
+ RichTooltip.displayName = "RichTooltip";
1974
+ var VIEWPORT_PADDING = 8;
1975
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React12.useLayoutEffect : React12.useEffect;
1976
+ function resolveAutoPlacement(spaceTop, spaceBottom, spaceLeft, spaceRight, tooltipWidth, tooltipHeight, spacing) {
1977
+ if (spaceTop >= tooltipHeight + spacing) return "top";
1978
+ if (spaceBottom >= tooltipHeight + spacing) return "bottom";
1979
+ if (spaceLeft >= tooltipWidth + spacing) return "left";
1980
+ if (spaceRight >= tooltipWidth + spacing) return "right";
1981
+ return "top";
1982
+ }
1983
+ function resolveActualSide(targetPlacement, spaceTop, spaceBottom, spaceLeft, spaceRight, tooltipWidth, tooltipHeight, spacing) {
1984
+ const needsHeight = tooltipHeight + spacing;
1985
+ const needsWidth = tooltipWidth + spacing;
1986
+ if (targetPlacement === "top")
1987
+ return spaceTop < needsHeight && spaceBottom >= needsHeight ? "bottom" : "top";
1988
+ if (targetPlacement === "bottom")
1989
+ return spaceBottom < needsHeight && spaceTop >= needsHeight ? "top" : "bottom";
1990
+ if (targetPlacement === "left")
1991
+ return spaceLeft < needsWidth && spaceRight >= needsWidth ? "right" : "left";
1992
+ return spaceRight < needsWidth && spaceLeft >= needsWidth ? "left" : "right";
1993
+ }
1994
+ function calculateXY(side, anchorRect, tooltipWidth, tooltipHeight, spacing) {
1995
+ const anchorCenterX = anchorRect.left + anchorRect.width / 2;
1996
+ const anchorCenterY = anchorRect.top + anchorRect.height / 2;
1997
+ if (side === "top")
1998
+ return {
1999
+ top: anchorRect.top - tooltipHeight - spacing,
2000
+ left: anchorCenterX - tooltipWidth / 2
2001
+ };
2002
+ if (side === "bottom")
2003
+ return {
2004
+ top: anchorRect.bottom + spacing,
2005
+ left: anchorCenterX - tooltipWidth / 2
2006
+ };
2007
+ if (side === "left")
2008
+ return {
2009
+ top: anchorCenterY - tooltipHeight / 2,
2010
+ left: anchorRect.left - tooltipWidth - spacing
2011
+ };
2012
+ return {
2013
+ top: anchorCenterY - tooltipHeight / 2,
2014
+ left: anchorRect.right + spacing
2015
+ };
2016
+ }
2017
+ function clampToViewport(side, top, left, tooltipWidth, tooltipHeight) {
2018
+ const isVertical = side === "top" || side === "bottom";
2019
+ const viewportWidth = window.innerWidth;
2020
+ const viewportHeight = window.innerHeight;
2021
+ if (isVertical) {
2022
+ left = Math.max(
2023
+ VIEWPORT_PADDING,
2024
+ Math.min(left, viewportWidth - VIEWPORT_PADDING - tooltipWidth)
2025
+ );
2026
+ } else {
2027
+ top = Math.max(
2028
+ VIEWPORT_PADDING,
2029
+ Math.min(top, viewportHeight - VIEWPORT_PADDING - tooltipHeight)
2030
+ );
2031
+ }
2032
+ return { top, left };
2033
+ }
2034
+ function useTooltipPosition(anchorRef, tooltipRef, placement, spacing, isVisible) {
2035
+ const [position, setPosition] = React12.useState({
2036
+ top: -9999,
2037
+ left: -9999,
2038
+ actualSide: placement === "auto" ? "top" : placement
2039
+ });
2040
+ useIsomorphicLayoutEffect(() => {
2041
+ if (!isVisible || !anchorRef.current || !tooltipRef.current) return;
2042
+ const calculatePosition = () => {
2043
+ const anchorEl = anchorRef.current;
2044
+ const tooltipEl = tooltipRef.current;
2045
+ if (!anchorEl || !tooltipEl) return;
2046
+ const anchorRect = anchorEl.getBoundingClientRect();
2047
+ const tooltipRect = tooltipEl.getBoundingClientRect();
2048
+ const tooltipWidth = tooltipRect.width;
2049
+ const tooltipHeight = tooltipRect.height;
2050
+ const spaceTop = anchorRect.top;
2051
+ const spaceBottom = window.innerHeight - anchorRect.bottom;
2052
+ const spaceLeft = anchorRect.left;
2053
+ const spaceRight = window.innerWidth - anchorRect.right;
2054
+ const targetSide = placement === "auto" ? resolveAutoPlacement(
2055
+ spaceTop,
2056
+ spaceBottom,
2057
+ spaceLeft,
2058
+ spaceRight,
2059
+ tooltipWidth,
2060
+ tooltipHeight,
2061
+ spacing
2062
+ ) : placement;
2063
+ const actualSide = resolveActualSide(
2064
+ targetSide,
2065
+ spaceTop,
2066
+ spaceBottom,
2067
+ spaceLeft,
2068
+ spaceRight,
2069
+ tooltipWidth,
2070
+ tooltipHeight,
2071
+ spacing
2072
+ );
2073
+ const { top, left } = calculateXY(
2074
+ actualSide,
2075
+ anchorRect,
2076
+ tooltipWidth,
2077
+ tooltipHeight,
2078
+ spacing
2079
+ );
2080
+ const clamped = clampToViewport(
2081
+ actualSide,
2082
+ top,
2083
+ left,
2084
+ tooltipWidth,
2085
+ tooltipHeight
2086
+ );
2087
+ setPosition(__spreadProps(__spreadValues({}, clamped), { actualSide }));
2088
+ };
2089
+ calculatePosition();
2090
+ window.addEventListener("resize", calculatePosition);
2091
+ window.addEventListener("scroll", calculatePosition, true);
2092
+ const resizeObserver = new ResizeObserver(calculatePosition);
2093
+ if (anchorRef.current) resizeObserver.observe(anchorRef.current);
2094
+ if (tooltipRef.current) resizeObserver.observe(tooltipRef.current);
2095
+ return () => {
2096
+ window.removeEventListener("resize", calculatePosition);
2097
+ window.removeEventListener("scroll", calculatePosition, true);
2098
+ resizeObserver.disconnect();
2099
+ };
2100
+ }, [isVisible, placement, spacing, anchorRef, tooltipRef]);
2101
+ return position;
2102
+ }
2103
+ var activeTooltipDismissals = /* @__PURE__ */ new Set();
2104
+ function useTooltipState(config) {
2105
+ const {
2106
+ initialVisible = false,
2107
+ isPersistent = false,
2108
+ duration = 1500
2109
+ } = config != null ? config : {};
2110
+ const [isVisible, setIsVisible] = React12.useState(initialVisible);
2111
+ const dismiss = React12.useCallback(() => {
2112
+ setIsVisible(false);
2113
+ activeTooltipDismissals.delete(dismiss);
2114
+ }, []);
2115
+ const show = React12.useCallback(() => {
2116
+ for (const otherDismiss of activeTooltipDismissals) {
2117
+ if (otherDismiss !== dismiss) otherDismiss();
2118
+ }
2119
+ setIsVisible(true);
2120
+ activeTooltipDismissals.add(dismiss);
2121
+ }, [dismiss]);
2122
+ React12.useEffect(() => {
2123
+ if (!isVisible || isPersistent) return;
2124
+ const timeoutId = setTimeout(dismiss, duration);
2125
+ return () => clearTimeout(timeoutId);
2126
+ }, [isVisible, isPersistent, duration, dismiss]);
2127
+ React12.useEffect(() => {
2128
+ return () => {
2129
+ activeTooltipDismissals.delete(dismiss);
2130
+ };
2131
+ }, [dismiss]);
2132
+ return { isVisible, show, dismiss };
2133
+ }
2134
+ var TRANSFORM_ORIGIN = {
2135
+ top: "50% 100%",
2136
+ bottom: "50% 0%",
2137
+ left: "100% 50%",
2138
+ right: "0% 50%"
2139
+ };
2140
+ var MOTION_VARIANTS = {
2141
+ full: {
2142
+ hidden: { opacity: 0, scale: 0.8 },
2143
+ visible: {
2144
+ opacity: 1,
2145
+ scale: 1,
2146
+ transition: {
2147
+ opacity: { duration: 0.1, ease: "easeOut" },
2148
+ scale: { type: "spring", stiffness: 900, damping: 90, mass: 0.5 }
2149
+ }
2150
+ },
2151
+ exit: {
2152
+ opacity: 0,
2153
+ scale: 0.8,
2154
+ transition: {
2155
+ opacity: { duration: 0.075, ease: "easeIn" },
2156
+ scale: { duration: 0.1, ease: "easeIn" }
2157
+ }
2158
+ }
2159
+ },
2160
+ reduced: {
2161
+ hidden: { opacity: 0 },
2162
+ visible: { opacity: 1, transition: { duration: 0.15 } },
2163
+ exit: { opacity: 0, transition: { duration: 0.1 } }
2164
+ }
2165
+ };
2166
+ function clearTimeout2(ref) {
2167
+ if (ref.current !== null) window.clearTimeout(ref.current);
2168
+ }
2169
+ function TooltipBox({
2170
+ children,
2171
+ tooltip,
2172
+ placement = "top",
2173
+ trigger = ["hover", "focus"],
2174
+ state: controlledState,
2175
+ spacingFromAnchor = 4,
2176
+ disabled = false,
2177
+ className = "",
2178
+ showDelay = 400,
2179
+ hideDelay = 200,
2180
+ "aria-label": ariaLabel
2181
+ }) {
2182
+ const internalState = useTooltipState();
2183
+ const state = controlledState != null ? controlledState : internalState;
2184
+ const anchorRef = React12.useRef(null);
2185
+ const tooltipRef = React12.useRef(null);
2186
+ const hoverTimeoutRef = React12.useRef(null);
2187
+ const hideTimeoutRef = React12.useRef(null);
2188
+ const pressTimeoutRef = React12.useRef(null);
2189
+ const triggers = Array.isArray(trigger) ? trigger : [trigger];
2190
+ const [mounted, setMounted] = React12.useState(false);
2191
+ const [hasHoverSupport, setHasHoverSupport] = React12.useState(true);
2192
+ const [prefersReducedMotion, setPrefersReducedMotion] = React12.useState(false);
2193
+ React12.useEffect(() => {
2194
+ setMounted(true);
2195
+ setHasHoverSupport(!window.matchMedia("(hover: none)").matches);
2196
+ }, []);
2197
+ React12.useEffect(() => {
2198
+ const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
2199
+ setPrefersReducedMotion(mediaQuery.matches);
2200
+ const onChange = (e) => setPrefersReducedMotion(e.matches);
2201
+ mediaQuery.addEventListener("change", onChange);
2202
+ return () => mediaQuery.removeEventListener("change", onChange);
2203
+ }, []);
2204
+ const position = useTooltipPosition(
2205
+ anchorRef,
2206
+ tooltipRef,
2207
+ placement,
2208
+ spacingFromAnchor,
2209
+ state.isVisible
2210
+ );
2211
+ const canHover = !disabled && hasHoverSupport && triggers.includes("hover");
2212
+ const canClick = !disabled && triggers.includes("click");
2213
+ const handlePointerEnter = () => {
2214
+ if (!canHover) return;
2215
+ clearTimeout2(hoverTimeoutRef);
2216
+ clearTimeout2(hideTimeoutRef);
2217
+ hoverTimeoutRef.current = window.setTimeout(() => state.show(), showDelay);
2218
+ };
2219
+ const handlePointerLeave = () => {
2220
+ if (!canHover) return;
2221
+ clearTimeout2(hoverTimeoutRef);
2222
+ hideTimeoutRef.current = window.setTimeout(
2223
+ () => state.dismiss(),
2224
+ hideDelay
2225
+ );
2226
+ };
2227
+ const handleFocus = () => {
2228
+ if (disabled || !triggers.includes("focus")) return;
2229
+ state.show();
2230
+ };
2231
+ const handleBlur = (e) => {
2232
+ if (disabled) return;
2233
+ const focusMovedInside = tooltipRef.current && (e.relatedTarget === tooltipRef.current || tooltipRef.current.contains(e.relatedTarget));
2234
+ if (focusMovedInside) return;
2235
+ state.dismiss();
2236
+ };
2237
+ const handlePointerDown = (e) => {
2238
+ if (disabled || !triggers.includes("long-press") || e.pointerType === "mouse")
2239
+ return;
2240
+ clearTimeout2(pressTimeoutRef);
2241
+ pressTimeoutRef.current = window.setTimeout(() => state.show(), 500);
2242
+ };
2243
+ const handleClick = () => {
2244
+ if (!canClick) return;
2245
+ if (state.isVisible) state.dismiss();
2246
+ else state.show();
2247
+ };
2248
+ const handleKeyDown = (e) => {
2249
+ if (disabled || !canClick) return;
2250
+ if (e.key === "Enter" || e.key === " ") {
2251
+ e.preventDefault();
2252
+ handleClick();
2253
+ }
2254
+ };
2255
+ const handleContextMenu = (e) => {
2256
+ if (triggers.includes("long-press") && state.isVisible) e.preventDefault();
2257
+ };
2258
+ const handleTooltipPointerEnter = () => {
2259
+ if (!canHover) return;
2260
+ clearTimeout2(hideTimeoutRef);
2261
+ };
2262
+ const handleTooltipPointerLeave = () => {
2263
+ if (!canHover) return;
2264
+ hideTimeoutRef.current = window.setTimeout(
2265
+ () => state.dismiss(),
2266
+ hideDelay
2267
+ );
2268
+ };
2269
+ React12.useEffect(() => {
2270
+ if (!state.isVisible) return;
2271
+ const onKeyDown = (e) => {
2272
+ var _a;
2273
+ if (e.key === "Escape") {
2274
+ state.dismiss();
2275
+ (_a = anchorRef.current) == null ? void 0 : _a.focus();
2276
+ }
2277
+ };
2278
+ document.addEventListener("keydown", onKeyDown);
2279
+ return () => document.removeEventListener("keydown", onKeyDown);
2280
+ }, [state.isVisible, state]);
2281
+ const tooltipId = React12.useId();
2282
+ const tooltipWithProps = React12.cloneElement(
2283
+ tooltip,
2284
+ {
2285
+ "data-side": position.actualSide,
2286
+ id: tooltipId,
2287
+ role: "tooltip",
2288
+ onBlur: handleBlur
2289
+ }
2290
+ );
2291
+ const variants = prefersReducedMotion ? MOTION_VARIANTS.reduced : MOTION_VARIANTS.full;
2292
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2293
+ /* @__PURE__ */ jsxRuntime.jsx(
2294
+ reactSlot.Slot,
2295
+ {
2296
+ ref: anchorRef,
2297
+ className: `inline-flex ${className}`,
2298
+ onPointerEnter: handlePointerEnter,
2299
+ onPointerLeave: handlePointerLeave,
2300
+ onFocus: handleFocus,
2301
+ onBlur: handleBlur,
2302
+ onPointerDown: handlePointerDown,
2303
+ onPointerUp: () => clearTimeout2(pressTimeoutRef),
2304
+ onPointerCancel: () => clearTimeout2(pressTimeoutRef),
2305
+ onContextMenu: handleContextMenu,
2306
+ onClick: handleClick,
2307
+ onKeyDown: handleKeyDown,
2308
+ "aria-label": ariaLabel,
2309
+ "aria-describedby": state.isVisible ? tooltipId : void 0,
2310
+ children: React12__namespace.isValidElement(children) ? children : /* @__PURE__ */ jsxRuntime.jsx("span", { children })
2311
+ }
2312
+ ),
2313
+ mounted && reactDom.createPortal(
2314
+ /* @__PURE__ */ jsxRuntime.jsx(react.AnimatePresence, { mode: "wait", children: state.isVisible && !disabled && /* @__PURE__ */ jsxRuntime.jsx(
2315
+ react.m.div,
2316
+ {
2317
+ ref: tooltipRef,
2318
+ initial: "hidden",
2319
+ animate: "visible",
2320
+ exit: "exit",
2321
+ variants,
2322
+ onPointerEnter: handleTooltipPointerEnter,
2323
+ onPointerLeave: handleTooltipPointerLeave,
2324
+ style: {
2325
+ position: "fixed",
2326
+ top: position.top,
2327
+ left: position.left,
2328
+ transformOrigin: TRANSFORM_ORIGIN[position.actualSide],
2329
+ zIndex: 50,
2330
+ pointerEvents: "auto"
2331
+ },
2332
+ children: tooltipWithProps
2333
+ }
2334
+ ) }),
2335
+ document.body
2336
+ )
2337
+ ] });
2338
+ }
2339
+
2340
+ exports.Badge = Badge;
2341
+ exports.BadgedBox = BadgedBox;
2342
+ exports.LoadingIndicator = LoadingIndicator;
2343
+ exports.PlainTooltip = PlainTooltip;
2344
+ exports.ProgressIndicator = ProgressIndicator;
2345
+ exports.RichTooltip = RichTooltip;
2346
+ exports.Snackbar = Snackbar;
2347
+ exports.SnackbarHost = SnackbarHost;
2348
+ exports.SnackbarProvider = SnackbarProvider;
2349
+ exports.TooltipBox = TooltipBox;
2350
+ exports.TooltipCaretShape = TooltipCaretShape;
2351
+ exports.TooltipTokens = TooltipTokens;
2352
+ exports.useSnackbar = useSnackbar;
2353
+ exports.useSnackbarState = useSnackbarState;
2354
+ exports.useTooltipPosition = useTooltipPosition;
2355
+ exports.useTooltipState = useTooltipState;
2356
+ //# sourceMappingURL=feedback.js.map
2357
+ //# sourceMappingURL=feedback.js.map