xiod-ui 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 (224) hide show
  1. package/LICENSE +73 -0
  2. package/README.md +167 -0
  3. package/dist/components/accordion.d.ts +9 -0
  4. package/dist/components/accordion.js +46 -0
  5. package/dist/components/agent-steps.d.ts +47 -0
  6. package/dist/components/agent-steps.js +223 -0
  7. package/dist/components/alert-dialog.d.ts +21 -0
  8. package/dist/components/alert-dialog.js +74 -0
  9. package/dist/components/alert.d.ts +12 -0
  10. package/dist/components/alert.js +45 -0
  11. package/dist/components/aspect-ratio.d.ts +9 -0
  12. package/dist/components/aspect-ratio.js +22 -0
  13. package/dist/components/autocomplete.d.ts +35 -0
  14. package/dist/components/autocomplete.js +160 -0
  15. package/dist/components/avatar.d.ts +17 -0
  16. package/dist/components/avatar.js +65 -0
  17. package/dist/components/badge.d.ts +15 -0
  18. package/dist/components/badge.js +46 -0
  19. package/dist/components/breadcrumb.d.ts +12 -0
  20. package/dist/components/breadcrumb.js +75 -0
  21. package/dist/components/button-group.d.ts +14 -0
  22. package/dist/components/button-group.js +45 -0
  23. package/dist/components/button-split.d.ts +19 -0
  24. package/dist/components/button-split.js +73 -0
  25. package/dist/components/button.d.ts +15 -0
  26. package/dist/components/button.js +54 -0
  27. package/dist/components/calendar.d.ts +63 -0
  28. package/dist/components/calendar.js +425 -0
  29. package/dist/components/card.d.ts +17 -0
  30. package/dist/components/card.js +139 -0
  31. package/dist/components/carousel.d.ts +59 -0
  32. package/dist/components/carousel.js +503 -0
  33. package/dist/components/checkbox.d.ts +16 -0
  34. package/dist/components/checkbox.js +86 -0
  35. package/dist/components/circular-progress.d.ts +28 -0
  36. package/dist/components/circular-progress.js +127 -0
  37. package/dist/components/collapsible.d.ts +8 -0
  38. package/dist/components/collapsible.js +27 -0
  39. package/dist/components/color-picker.d.ts +159 -0
  40. package/dist/components/color-picker.js +1589 -0
  41. package/dist/components/combobox.d.ts +46 -0
  42. package/dist/components/combobox.js +237 -0
  43. package/dist/components/command.d.ts +22 -0
  44. package/dist/components/command.js +129 -0
  45. package/dist/components/context-menu.d.ts +38 -0
  46. package/dist/components/context-menu.js +164 -0
  47. package/dist/components/copy-to-clipboard.d.ts +32 -0
  48. package/dist/components/copy-to-clipboard.js +83 -0
  49. package/dist/components/corner-badge.d.ts +22 -0
  50. package/dist/components/corner-badge.js +84 -0
  51. package/dist/components/dashboard-grid.d.ts +83 -0
  52. package/dist/components/dashboard-grid.js +486 -0
  53. package/dist/components/date-picker.d.ts +29 -0
  54. package/dist/components/date-picker.js +261 -0
  55. package/dist/components/dialog.d.ts +26 -0
  56. package/dist/components/dialog.js +97 -0
  57. package/dist/components/dot-matrix.d.ts +32 -0
  58. package/dist/components/dot-matrix.js +707 -0
  59. package/dist/components/draggable.d.ts +42 -0
  60. package/dist/components/draggable.js +346 -0
  61. package/dist/components/drawer.d.ts +66 -0
  62. package/dist/components/drawer.js +304 -0
  63. package/dist/components/empty.d.ts +14 -0
  64. package/dist/components/empty.js +75 -0
  65. package/dist/components/field.d.ts +12 -0
  66. package/dist/components/field.js +44 -0
  67. package/dist/components/fieldset.d.ts +7 -0
  68. package/dist/components/fieldset.js +21 -0
  69. package/dist/components/file-upload.d.ts +61 -0
  70. package/dist/components/file-upload.js +482 -0
  71. package/dist/components/form.d.ts +6 -0
  72. package/dist/components/form.js +14 -0
  73. package/dist/components/frame.d.ts +10 -0
  74. package/dist/components/frame.js +47 -0
  75. package/dist/components/gauge.d.ts +27 -0
  76. package/dist/components/gauge.js +74 -0
  77. package/dist/components/grid.d.ts +26 -0
  78. package/dist/components/grid.js +204 -0
  79. package/dist/components/group.d.ts +19 -0
  80. package/dist/components/group.js +45 -0
  81. package/dist/components/input-group.d.ts +15 -0
  82. package/dist/components/input-group.js +61 -0
  83. package/dist/components/input-otp.d.ts +24 -0
  84. package/dist/components/input-otp.js +50 -0
  85. package/dist/components/input-payment.d.ts +131 -0
  86. package/dist/components/input-payment.js +1140 -0
  87. package/dist/components/input-phone.d.ts +70 -0
  88. package/dist/components/input-phone.js +657 -0
  89. package/dist/components/input-sensitive.d.ts +12 -0
  90. package/dist/components/input-sensitive.js +169 -0
  91. package/dist/components/input.d.ts +13 -0
  92. package/dist/components/input.js +26 -0
  93. package/dist/components/kbd.d.ts +6 -0
  94. package/dist/components/kbd.js +19 -0
  95. package/dist/components/kinetic-click.d.ts +48 -0
  96. package/dist/components/kinetic-click.js +1184 -0
  97. package/dist/components/label.d.ts +6 -0
  98. package/dist/components/label.js +18 -0
  99. package/dist/components/list-box.d.ts +20 -0
  100. package/dist/components/list-box.js +148 -0
  101. package/dist/components/loader.d.ts +13 -0
  102. package/dist/components/loader.js +430 -0
  103. package/dist/components/marker.d.ts +15 -0
  104. package/dist/components/marker.js +59 -0
  105. package/dist/components/menu.d.ts +42 -0
  106. package/dist/components/menu.js +186 -0
  107. package/dist/components/menubar.d.ts +40 -0
  108. package/dist/components/menubar.js +107 -0
  109. package/dist/components/message.d.ts +33 -0
  110. package/dist/components/message.js +112 -0
  111. package/dist/components/meter.d.ts +10 -0
  112. package/dist/components/meter.js +42 -0
  113. package/dist/components/morphic-toast.d.ts +61 -0
  114. package/dist/components/morphic-toast.js +916 -0
  115. package/dist/components/navigation-menu.d.ts +26 -0
  116. package/dist/components/navigation-menu.js +116 -0
  117. package/dist/components/number-field.d.ts +15 -0
  118. package/dist/components/number-field.js +86 -0
  119. package/dist/components/option-picker.d.ts +18 -0
  120. package/dist/components/option-picker.js +89 -0
  121. package/dist/components/orb.d.ts +38 -0
  122. package/dist/components/orb.js +1413 -0
  123. package/dist/components/pagination.d.ts +25 -0
  124. package/dist/components/pagination.js +147 -0
  125. package/dist/components/popover.d.ts +22 -0
  126. package/dist/components/popover.js +79 -0
  127. package/dist/components/preview-card.d.ts +16 -0
  128. package/dist/components/preview-card.js +60 -0
  129. package/dist/components/progress.d.ts +21 -0
  130. package/dist/components/progress.js +139 -0
  131. package/dist/components/radio.d.ts +16 -0
  132. package/dist/components/radio.js +68 -0
  133. package/dist/components/resizable.d.ts +58 -0
  134. package/dist/components/resizable.js +964 -0
  135. package/dist/components/ruler-picker.d.ts +27 -0
  136. package/dist/components/ruler-picker.js +253 -0
  137. package/dist/components/scroll-area.d.ts +13 -0
  138. package/dist/components/scroll-area.js +34 -0
  139. package/dist/components/scroll-bar.d.ts +13 -0
  140. package/dist/components/scroll-bar.js +47 -0
  141. package/dist/components/select.d.ts +29 -0
  142. package/dist/components/select.js +140 -0
  143. package/dist/components/separator.d.ts +6 -0
  144. package/dist/components/separator.js +15 -0
  145. package/dist/components/sidebar.d.ts +65 -0
  146. package/dist/components/sidebar.js +408 -0
  147. package/dist/components/skeleton.d.ts +5 -0
  148. package/dist/components/skeleton.js +12 -0
  149. package/dist/components/slider.d.ts +12 -0
  150. package/dist/components/slider.js +96 -0
  151. package/dist/components/sortable.d.ts +44 -0
  152. package/dist/components/sortable.js +327 -0
  153. package/dist/components/switch.d.ts +15 -0
  154. package/dist/components/switch.js +63 -0
  155. package/dist/components/table.d.ts +12 -0
  156. package/dist/components/table.js +65 -0
  157. package/dist/components/tabs.d.ts +12 -0
  158. package/dist/components/tabs.js +39 -0
  159. package/dist/components/text.d.ts +14 -0
  160. package/dist/components/text.js +69 -0
  161. package/dist/components/textarea.d.ts +9 -0
  162. package/dist/components/textarea.js +20 -0
  163. package/dist/components/theme-provider.d.ts +52 -0
  164. package/dist/components/theme-provider.js +148 -0
  165. package/dist/components/timeline.d.ts +34 -0
  166. package/dist/components/timeline.js +147 -0
  167. package/dist/components/toast.d.ts +17 -0
  168. package/dist/components/toast.js +161 -0
  169. package/dist/components/toggle-group.d.ts +14 -0
  170. package/dist/components/toggle-group.js +53 -0
  171. package/dist/components/toggle.d.ts +11 -0
  172. package/dist/components/toggle.js +36 -0
  173. package/dist/components/toolbar.d.ts +11 -0
  174. package/dist/components/toolbar.js +49 -0
  175. package/dist/components/tooltip.d.ts +17 -0
  176. package/dist/components/tooltip.js +56 -0
  177. package/dist/components/waveform.d.ts +61 -0
  178. package/dist/components/waveform.js +500 -0
  179. package/dist/components/wheel-picker.d.ts +44 -0
  180. package/dist/components/wheel-picker.js +771 -0
  181. package/dist/hooks/use-copy-to-clipboard.d.ts +9 -0
  182. package/dist/hooks/use-copy-to-clipboard.js +36 -0
  183. package/dist/hooks/use-media-query.d.ts +21 -0
  184. package/dist/hooks/use-media-query.js +58 -0
  185. package/dist/styles.css +202 -0
  186. package/dist/themes/afterglow.css +89 -0
  187. package/dist/themes/afterglow.scoped.css +90 -0
  188. package/dist/themes/blacklight.css +89 -0
  189. package/dist/themes/blacklight.scoped.css +90 -0
  190. package/dist/themes/cathode.css +89 -0
  191. package/dist/themes/cathode.scoped.css +90 -0
  192. package/dist/themes/cel.css +89 -0
  193. package/dist/themes/cel.scoped.css +90 -0
  194. package/dist/themes/cinder.css +89 -0
  195. package/dist/themes/cinder.scoped.css +90 -0
  196. package/dist/themes/clay.css +89 -0
  197. package/dist/themes/clay.scoped.css +90 -0
  198. package/dist/themes/cobalt.css +89 -0
  199. package/dist/themes/cobalt.scoped.css +90 -0
  200. package/dist/themes/crimson.css +89 -0
  201. package/dist/themes/crimson.scoped.css +90 -0
  202. package/dist/themes/ion.css +89 -0
  203. package/dist/themes/ion.scoped.css +90 -0
  204. package/dist/themes/iris.css +89 -0
  205. package/dist/themes/iris.scoped.css +90 -0
  206. package/dist/themes/lagoon.css +89 -0
  207. package/dist/themes/lagoon.scoped.css +90 -0
  208. package/dist/themes/mochi.css +89 -0
  209. package/dist/themes/mochi.scoped.css +90 -0
  210. package/dist/themes/riso.css +89 -0
  211. package/dist/themes/riso.scoped.css +90 -0
  212. package/dist/themes/roast.css +89 -0
  213. package/dist/themes/roast.scoped.css +90 -0
  214. package/dist/themes/sage.css +89 -0
  215. package/dist/themes/sage.scoped.css +90 -0
  216. package/dist/themes/sepia.css +89 -0
  217. package/dist/themes/sepia.scoped.css +90 -0
  218. package/dist/themes/sorbet.css +89 -0
  219. package/dist/themes/sorbet.scoped.css +90 -0
  220. package/dist/themes/taffy.css +89 -0
  221. package/dist/themes/taffy.scoped.css +90 -0
  222. package/dist/themes/toxin.css +89 -0
  223. package/dist/themes/toxin.scoped.css +90 -0
  224. package/package.json +140 -0
@@ -0,0 +1,916 @@
1
+ "use client";
2
+ import { cn } from "cn";
3
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
+ import { memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
5
+ import { Cancel } from "xiod-icons/icons/Cancel";
6
+ import { Check } from "xiod-icons/icons/Check";
7
+ import { AlertCircle } from "xiod-icons/icons/AlertCircle";
8
+ import { InformationCircle } from "xiod-icons/icons/InformationCircle";
9
+ import { LoadingSpinner } from "xiod-icons/icons/LoadingSpinner";
10
+ import { ArrowRight } from "xiod-icons/icons/ArrowRight";
11
+ //#region src/components/morphic-toast.tsx
12
+ const HEIGHT = 40;
13
+ const WIDTH = 350;
14
+ const DEFAULT_ROUNDNESS = 16;
15
+ const DEFAULT_TOAST_DURATION = 6e3;
16
+ const EXIT_DURATION = 600;
17
+ const AUTO_EXPAND_DELAY = 150;
18
+ const AUTO_COLLAPSE_DELAY = 4e3;
19
+ const BLUR_RATIO = .5;
20
+ const PILL_PADDING = 10;
21
+ const MIN_EXPAND_RATIO = 2.25;
22
+ const SWAP_COLLAPSE_MS = 200;
23
+ const HEADER_EXIT_MS = 420;
24
+ const pillAlign = (pos) => pos.includes("right") ? "right" : pos.includes("center") ? "center" : "left";
25
+ const expandDir = (pos) => pos.startsWith("top") ? "bottom" : "top";
26
+ const STATE_ICON = {
27
+ success: /* @__PURE__ */ jsx(Check, { className: "size-3.5" }),
28
+ loading: /* @__PURE__ */ jsx(LoadingSpinner, {
29
+ className: "size-3.5 animate-spin",
30
+ "aria-hidden": "true"
31
+ }),
32
+ error: /* @__PURE__ */ jsx(Cancel, { className: "size-3.5" }),
33
+ warning: /* @__PURE__ */ jsx(AlertCircle, { className: "size-3.5" }),
34
+ info: /* @__PURE__ */ jsx(InformationCircle, { className: "size-3.5" }),
35
+ action: /* @__PURE__ */ jsx(ArrowRight, { className: "size-3.5" })
36
+ };
37
+ const store = {
38
+ toasts: [],
39
+ listeners: /* @__PURE__ */ new Set(),
40
+ position: "top-right",
41
+ options: void 0,
42
+ emit() {
43
+ for (const fn of this.listeners) fn(this.toasts);
44
+ },
45
+ update(fn) {
46
+ this.toasts = fn(this.toasts);
47
+ this.emit();
48
+ }
49
+ };
50
+ let idCounter = 0;
51
+ const generateId = () => `${++idCounter}-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
52
+ const timeoutKey = (t) => `${t.id}:${t.instanceId}`;
53
+ const dismissToast = (id) => {
54
+ const item = store.toasts.find((t) => t.id === id);
55
+ if (!item || item.exiting) return;
56
+ store.update((prev) => prev.map((t) => t.id === id ? {
57
+ ...t,
58
+ exiting: true
59
+ } : t));
60
+ setTimeout(() => store.update((prev) => prev.filter((t) => t.id !== id)), EXIT_DURATION);
61
+ };
62
+ const resolveAutopilot = (opts, duration) => {
63
+ if (opts.autopilot === false || !duration || duration <= 0) return {};
64
+ const cfg = typeof opts.autopilot === "object" ? opts.autopilot : void 0;
65
+ const clamp = (v) => Math.min(duration, Math.max(0, v));
66
+ return {
67
+ expandDelayMs: clamp(cfg?.expand ?? AUTO_EXPAND_DELAY),
68
+ collapseDelayMs: clamp(cfg?.collapse ?? AUTO_COLLAPSE_DELAY)
69
+ };
70
+ };
71
+ const mergeOptions = (options) => ({
72
+ ...store.options,
73
+ ...options,
74
+ styles: {
75
+ ...store.options?.styles,
76
+ ...options.styles
77
+ }
78
+ });
79
+ const buildMorphicToastItem = (merged, id, fallbackPosition) => {
80
+ const duration = merged.duration ?? DEFAULT_TOAST_DURATION;
81
+ const auto = resolveAutopilot(merged, duration);
82
+ return {
83
+ ...merged,
84
+ id,
85
+ instanceId: generateId(),
86
+ position: merged.position ?? fallbackPosition ?? store.position,
87
+ autoExpandDelayMs: auto.expandDelayMs,
88
+ autoCollapseDelayMs: auto.collapseDelayMs
89
+ };
90
+ };
91
+ const createToast = (options) => {
92
+ const live = store.toasts.filter((t) => !t.exiting);
93
+ const merged = mergeOptions(options);
94
+ const id = merged.id ?? "morphic-default";
95
+ const prev = live.find((t) => t.id === id);
96
+ const item = buildMorphicToastItem(merged, id, prev?.position);
97
+ if (prev) store.update((p) => p.map((t) => t.id === id ? item : t));
98
+ else store.update((p) => [...p.filter((t) => t.id !== id), item]);
99
+ return {
100
+ id,
101
+ duration: merged.duration ?? DEFAULT_TOAST_DURATION
102
+ };
103
+ };
104
+ const updateToast = (id, options) => {
105
+ const existing = store.toasts.find((t) => t.id === id);
106
+ if (!existing) return;
107
+ const item = buildMorphicToastItem(mergeOptions(options), id, existing.position);
108
+ store.update((prev) => prev.map((t) => t.id === id ? item : t));
109
+ };
110
+ const morphicToast = {
111
+ show: (opts) => createToast({
112
+ ...opts,
113
+ state: opts.type
114
+ }).id,
115
+ success: (opts) => createToast({
116
+ ...opts,
117
+ state: "success"
118
+ }).id,
119
+ error: (opts) => createToast({
120
+ ...opts,
121
+ state: "error"
122
+ }).id,
123
+ warning: (opts) => createToast({
124
+ ...opts,
125
+ state: "warning"
126
+ }).id,
127
+ info: (opts) => createToast({
128
+ ...opts,
129
+ state: "info"
130
+ }).id,
131
+ action: (opts) => createToast({
132
+ ...opts,
133
+ state: "action"
134
+ }).id,
135
+ promise: (promise, opts) => {
136
+ const { id } = createToast({
137
+ ...opts.loading,
138
+ state: "loading",
139
+ duration: null,
140
+ position: opts.position
141
+ });
142
+ const p = typeof promise === "function" ? promise() : promise;
143
+ (async () => {
144
+ try {
145
+ const data = await p;
146
+ if (opts.action) {
147
+ const actionOpts = typeof opts.action === "function" ? opts.action(data) : opts.action;
148
+ updateToast(id, {
149
+ ...actionOpts,
150
+ state: "action",
151
+ id
152
+ });
153
+ } else {
154
+ const successOpts = typeof opts.success === "function" ? opts.success(data) : opts.success;
155
+ updateToast(id, {
156
+ ...successOpts,
157
+ state: "success",
158
+ id
159
+ });
160
+ }
161
+ } catch (error) {
162
+ const errorOpts = typeof opts.error === "function" ? opts.error(error) : opts.error;
163
+ updateToast(id, {
164
+ ...errorOpts,
165
+ state: "error",
166
+ id
167
+ });
168
+ }
169
+ })();
170
+ return p;
171
+ },
172
+ dismiss: dismissToast,
173
+ clear: (position) => store.update((prev) => position ? prev.filter((t) => t.position !== position) : [])
174
+ };
175
+ const GooeyDefs = memo(function GooeyDefs({ filterId, blur }) {
176
+ return /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("filter", {
177
+ id: filterId,
178
+ x: "-20%",
179
+ y: "-20%",
180
+ width: "140%",
181
+ height: "140%",
182
+ colorInterpolationFilters: "sRGB",
183
+ children: [
184
+ /* @__PURE__ */ jsx("feGaussianBlur", {
185
+ in: "SourceGraphic",
186
+ stdDeviation: blur,
187
+ result: "blur"
188
+ }),
189
+ /* @__PURE__ */ jsx("feColorMatrix", {
190
+ in: "blur",
191
+ mode: "matrix",
192
+ values: "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 20 -10",
193
+ result: "goo"
194
+ }),
195
+ /* @__PURE__ */ jsx("feComposite", {
196
+ in: "SourceGraphic",
197
+ in2: "goo",
198
+ operator: "atop"
199
+ })
200
+ ]
201
+ }) });
202
+ });
203
+ const MorphicToast = memo(function MorphicToast({ id, fill, state = "success", title = state, description, position = "left", expand = "bottom", className, icon, styles, button, roundness, exiting = false, autoExpandDelayMs, autoCollapseDelayMs, canExpand, refreshKey, onMouseEnter, onMouseLeave, onDismiss, ...props }) {
204
+ const next = useMemo(() => ({
205
+ title,
206
+ description,
207
+ state,
208
+ icon,
209
+ styles,
210
+ button,
211
+ fill
212
+ }), [
213
+ title,
214
+ description,
215
+ state,
216
+ icon,
217
+ styles,
218
+ button,
219
+ fill
220
+ ]);
221
+ const [view, setView] = useState(next);
222
+ const [applied, setApplied] = useState(refreshKey);
223
+ const [isExpanded, setIsExpanded] = useState(false);
224
+ const [ready, setReady] = useState(false);
225
+ const [pillWidth, setPillWidth] = useState(0);
226
+ const [contentHeight, setContentHeight] = useState(0);
227
+ const hasDesc = Boolean(view.description) || Boolean(view.button);
228
+ const isLoading = view.state === "loading";
229
+ const open = hasDesc && isExpanded && !isLoading;
230
+ const allowExpand = isLoading ? false : canExpand;
231
+ const headerKey = `${view.state}-${view.title}`;
232
+ const filterId = `morphic-gooey-${id}`;
233
+ const resolvedRoundness = Math.max(0, roundness ?? DEFAULT_ROUNDNESS);
234
+ const blur = resolvedRoundness * BLUR_RATIO;
235
+ const headerRef = useRef(null);
236
+ const contentRef = useRef(null);
237
+ const headerExitRef = useRef(null);
238
+ const autoExpandRef = useRef(null);
239
+ const autoCollapseRef = useRef(null);
240
+ const swapTimerRef = useRef(null);
241
+ const lastRefreshKeyRef = useRef(refreshKey);
242
+ const pendingRef = useRef(null);
243
+ const [headerLayer, setHeaderLayer] = useState({
244
+ current: {
245
+ key: headerKey,
246
+ view
247
+ },
248
+ prev: null
249
+ });
250
+ const innerRef = useRef(null);
251
+ const headerPadRef = useRef(null);
252
+ const pillRoRef = useRef(null);
253
+ const pillRafRef = useRef(0);
254
+ const pillObservedRef = useRef(null);
255
+ useLayoutEffect(() => {
256
+ const el = innerRef.current;
257
+ const header = headerRef.current;
258
+ if (!el || !header) return;
259
+ if (headerPadRef.current === null) {
260
+ const cs = getComputedStyle(header);
261
+ headerPadRef.current = parseFloat(cs.paddingLeft) + parseFloat(cs.paddingRight);
262
+ }
263
+ const px = headerPadRef.current;
264
+ const measure = () => {
265
+ const w = el.scrollWidth + px + PILL_PADDING;
266
+ if (w > PILL_PADDING) setPillWidth((prev) => prev === w ? prev : w);
267
+ };
268
+ measure();
269
+ if (!pillRoRef.current) pillRoRef.current = new ResizeObserver(() => {
270
+ cancelAnimationFrame(pillRafRef.current);
271
+ pillRafRef.current = requestAnimationFrame(() => {
272
+ const inner = innerRef.current;
273
+ const pad = headerPadRef.current ?? 0;
274
+ if (!inner) return;
275
+ const w = inner.scrollWidth + pad + PILL_PADDING;
276
+ if (w > PILL_PADDING) setPillWidth((prev) => prev === w ? prev : w);
277
+ });
278
+ });
279
+ if (pillObservedRef.current !== el) {
280
+ if (pillObservedRef.current) pillRoRef.current.unobserve(pillObservedRef.current);
281
+ pillRoRef.current.observe(el);
282
+ pillObservedRef.current = el;
283
+ }
284
+ }, []);
285
+ useEffect(() => {
286
+ return () => {
287
+ cancelAnimationFrame(pillRafRef.current);
288
+ pillRoRef.current?.disconnect();
289
+ };
290
+ }, []);
291
+ useLayoutEffect(() => {
292
+ if (!hasDesc) {
293
+ setContentHeight(0);
294
+ return;
295
+ }
296
+ const el = contentRef.current;
297
+ if (!el) return;
298
+ const measure = () => {
299
+ const h = el.scrollHeight;
300
+ setContentHeight((prev) => prev === h ? prev : h);
301
+ };
302
+ measure();
303
+ let rafId = 0;
304
+ const ro = new ResizeObserver(() => {
305
+ cancelAnimationFrame(rafId);
306
+ rafId = requestAnimationFrame(measure);
307
+ });
308
+ ro.observe(el);
309
+ return () => {
310
+ cancelAnimationFrame(rafId);
311
+ ro.disconnect();
312
+ };
313
+ }, [hasDesc]);
314
+ useEffect(() => {
315
+ const raf = requestAnimationFrame(() => setReady(true));
316
+ return () => cancelAnimationFrame(raf);
317
+ }, []);
318
+ useLayoutEffect(() => {
319
+ setHeaderLayer((currentLayer) => {
320
+ if (currentLayer.current.key === headerKey) {
321
+ if (currentLayer.current.view === view) return currentLayer;
322
+ return {
323
+ ...currentLayer,
324
+ current: {
325
+ key: headerKey,
326
+ view
327
+ }
328
+ };
329
+ }
330
+ return {
331
+ prev: currentLayer.current,
332
+ current: {
333
+ key: headerKey,
334
+ view
335
+ }
336
+ };
337
+ });
338
+ }, [headerKey, view]);
339
+ useEffect(() => {
340
+ if (!headerLayer.prev) return;
341
+ if (headerExitRef.current) clearTimeout(headerExitRef.current);
342
+ headerExitRef.current = window.setTimeout(() => {
343
+ headerExitRef.current = null;
344
+ setHeaderLayer((currentLayer) => ({
345
+ ...currentLayer,
346
+ prev: null
347
+ }));
348
+ }, HEADER_EXIT_MS);
349
+ return () => {
350
+ if (headerExitRef.current) {
351
+ clearTimeout(headerExitRef.current);
352
+ headerExitRef.current = null;
353
+ }
354
+ };
355
+ }, [headerLayer.prev]);
356
+ useEffect(() => {
357
+ setView((prev) => prev.fill === fill ? prev : {
358
+ ...prev,
359
+ fill
360
+ });
361
+ }, [fill]);
362
+ useEffect(() => {
363
+ if (refreshKey === void 0) {
364
+ setView(next);
365
+ setApplied(void 0);
366
+ pendingRef.current = null;
367
+ lastRefreshKeyRef.current = refreshKey;
368
+ return;
369
+ }
370
+ if (lastRefreshKeyRef.current === refreshKey) return;
371
+ lastRefreshKeyRef.current = refreshKey;
372
+ if (swapTimerRef.current) {
373
+ clearTimeout(swapTimerRef.current);
374
+ swapTimerRef.current = null;
375
+ }
376
+ if (open) {
377
+ pendingRef.current = {
378
+ key: refreshKey,
379
+ payload: next
380
+ };
381
+ setIsExpanded(false);
382
+ swapTimerRef.current = window.setTimeout(() => {
383
+ swapTimerRef.current = null;
384
+ const pending = pendingRef.current;
385
+ if (!pending) return;
386
+ setView(pending.payload);
387
+ setApplied(pending.key);
388
+ pendingRef.current = null;
389
+ }, SWAP_COLLAPSE_MS);
390
+ } else {
391
+ pendingRef.current = null;
392
+ setView(next);
393
+ setApplied(refreshKey);
394
+ }
395
+ }, [
396
+ open,
397
+ refreshKey,
398
+ next
399
+ ]);
400
+ useEffect(() => {
401
+ if (!hasDesc) return;
402
+ if (autoExpandRef.current) clearTimeout(autoExpandRef.current);
403
+ if (autoCollapseRef.current) clearTimeout(autoCollapseRef.current);
404
+ if (exiting || !allowExpand) {
405
+ setIsExpanded(false);
406
+ return;
407
+ }
408
+ if (autoExpandDelayMs == null && autoCollapseDelayMs == null) return;
409
+ const expandDelay = autoExpandDelayMs ?? 0;
410
+ const collapseDelay = autoCollapseDelayMs ?? 0;
411
+ if (expandDelay > 0) autoExpandRef.current = window.setTimeout(() => setIsExpanded(true), expandDelay);
412
+ else setIsExpanded(true);
413
+ if (collapseDelay > 0) autoCollapseRef.current = window.setTimeout(() => setIsExpanded(false), collapseDelay);
414
+ return () => {
415
+ if (autoExpandRef.current) clearTimeout(autoExpandRef.current);
416
+ if (autoCollapseRef.current) clearTimeout(autoCollapseRef.current);
417
+ };
418
+ }, [
419
+ autoCollapseDelayMs,
420
+ autoExpandDelayMs,
421
+ hasDesc,
422
+ allowExpand,
423
+ exiting,
424
+ applied
425
+ ]);
426
+ const minExpanded = HEIGHT * MIN_EXPAND_RATIO;
427
+ const rawExpanded = hasDesc ? Math.max(minExpanded, HEIGHT + contentHeight) : minExpanded;
428
+ const frozenExpandedRef = useRef(rawExpanded);
429
+ if (open) frozenExpandedRef.current = rawExpanded;
430
+ const expanded = open ? rawExpanded : frozenExpandedRef.current;
431
+ const svgHeight = hasDesc ? Math.max(expanded, minExpanded) : HEIGHT;
432
+ const expandedContent = Math.max(0, expanded - HEIGHT);
433
+ const resolvedPillWidth = Math.max(pillWidth || HEIGHT, HEIGHT);
434
+ const pillHeight = HEIGHT + blur * 3;
435
+ const pillX = position === "right" ? WIDTH - resolvedPillWidth : position === "center" ? (WIDTH - resolvedPillWidth) / 2 : 0;
436
+ const viewBox = `0 0 ${WIDTH} ${svgHeight}`;
437
+ const canvasStyle = useMemo(() => ({ filter: `url(#${filterId})` }), [filterId]);
438
+ const rootStyle = useMemo(() => ({
439
+ "--_h": `${open ? expanded : HEIGHT}px`,
440
+ "--_pw": `${resolvedPillWidth}px`,
441
+ "--_px": `${pillX}px`,
442
+ "--_ht": `translateY(${open ? expand === "bottom" ? 3 : -3 : 0}px) scale(${open ? .98 : 1})`,
443
+ "--_co": `${open ? 1 : 0}`
444
+ }), [
445
+ open,
446
+ expanded,
447
+ resolvedPillWidth,
448
+ pillX,
449
+ expand
450
+ ]);
451
+ const handleEnter = useCallback((e) => {
452
+ onMouseEnter?.(e);
453
+ if (hasDesc) setIsExpanded(true);
454
+ }, [hasDesc, onMouseEnter]);
455
+ const handleLeave = useCallback((e) => {
456
+ onMouseLeave?.(e);
457
+ setIsExpanded(false);
458
+ }, [onMouseLeave]);
459
+ const handleTransitionEnd = useCallback((e) => {
460
+ if (e.propertyName !== "height" && e.propertyName !== "transform") return;
461
+ if (open) return;
462
+ const pending = pendingRef.current;
463
+ if (!pending) return;
464
+ if (swapTimerRef.current) {
465
+ clearTimeout(swapTimerRef.current);
466
+ swapTimerRef.current = null;
467
+ }
468
+ setView(pending.payload);
469
+ setApplied(pending.key);
470
+ pendingRef.current = null;
471
+ }, [open]);
472
+ const SWIPE_DISMISS = 30;
473
+ const SWIPE_MAX = 20;
474
+ const containerRef = useRef(null);
475
+ const pointerStartRef = useRef(null);
476
+ const onDismissRef = useRef(onDismiss);
477
+ onDismissRef.current = onDismiss;
478
+ const swipeHandlersRef = useRef(null);
479
+ if (!swipeHandlersRef.current) {
480
+ const handlers = {
481
+ onMove: (e) => {
482
+ const el = containerRef.current;
483
+ if (pointerStartRef.current === null || !el) return;
484
+ const dy = e.clientY - pointerStartRef.current;
485
+ const clamped = Math.min(Math.abs(dy), SWIPE_MAX) * (dy > 0 ? 1 : -1);
486
+ el.style.transform = `translateY(${clamped}px)`;
487
+ },
488
+ onUp: (e) => {
489
+ const el = containerRef.current;
490
+ if (pointerStartRef.current === null || !el) return;
491
+ const dy = e.clientY - pointerStartRef.current;
492
+ pointerStartRef.current = null;
493
+ el.style.transform = "";
494
+ el.removeEventListener("pointermove", handlers.onMove);
495
+ el.removeEventListener("pointerup", handlers.onUp);
496
+ if (Math.abs(dy) > SWIPE_DISMISS) onDismissRef.current?.();
497
+ }
498
+ };
499
+ swipeHandlersRef.current = handlers;
500
+ }
501
+ const handleButtonClick = useCallback((e) => {
502
+ e.preventDefault();
503
+ e.stopPropagation();
504
+ view.button?.onClick();
505
+ }, [view.button]);
506
+ const handlePointerDown = useCallback((e) => {
507
+ if (exiting || !onDismiss) return;
508
+ if (e.target.closest("[data-morphic-button]")) return;
509
+ pointerStartRef.current = e.clientY;
510
+ e.currentTarget.setPointerCapture(e.pointerId);
511
+ const el = containerRef.current;
512
+ const h = swipeHandlersRef.current;
513
+ if (el && h) {
514
+ el.addEventListener("pointermove", h.onMove, { passive: true });
515
+ el.addEventListener("pointerup", h.onUp, { passive: true });
516
+ }
517
+ }, [exiting, onDismiss]);
518
+ return /* @__PURE__ */ jsxs("div", {
519
+ ref: containerRef,
520
+ role: "status",
521
+ "data-morphic-toast": true,
522
+ "data-slot": "morphic-toast",
523
+ ...props,
524
+ "data-ready": ready,
525
+ "data-expanded": open,
526
+ "data-exiting": exiting,
527
+ "data-edge": expand,
528
+ "data-position": position,
529
+ "data-state": view.state,
530
+ className: cn("relative pointer-events-auto w-[350px] overflow-visible transition-[opacity,height] duration-600 will-change-transform text-zinc-900 dark:text-white drop-shadow-[0_8px_16px_rgba(0,0,0,0.06)] dark:drop-shadow-[0_8px_16px_rgba(0,0,0,0.35)] [&_svg:not([class*='size-'])]:size-4.5 sm:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0", exiting && "opacity-0 scale-95 pointer-events-none", className),
531
+ style: {
532
+ ...rootStyle,
533
+ height: open ? expanded : HEIGHT,
534
+ transition: ready ? `transform 396ms var(--morphic-spring-easing), opacity 396ms var(--morphic-spring-easing), height 600ms var(--morphic-spring-easing)` : "none"
535
+ },
536
+ onMouseEnter: handleEnter,
537
+ onMouseLeave: handleLeave,
538
+ onTransitionEnd: handleTransitionEnd,
539
+ onPointerDown: handlePointerDown,
540
+ children: [
541
+ /* @__PURE__ */ jsx("div", {
542
+ "data-morphic-canvas": true,
543
+ "data-edge": expand,
544
+ className: cn("absolute left-0 right-0 pointer-events-none overflow-visible", expand === "top" ? "bottom-0 scale-y-[-1]" : "top-0"),
545
+ style: canvasStyle,
546
+ children: /* @__PURE__ */ jsxs("svg", {
547
+ "data-morphic-svg": true,
548
+ width: WIDTH,
549
+ height: svgHeight,
550
+ viewBox,
551
+ className: "overflow-visible",
552
+ children: [
553
+ /* @__PURE__ */ jsx("title", { children: "Morphic Notification" }),
554
+ /* @__PURE__ */ jsx(GooeyDefs, {
555
+ filterId,
556
+ blur
557
+ }),
558
+ /* @__PURE__ */ jsx("rect", {
559
+ "data-morphic-pill": true,
560
+ className: "fill-white dark:fill-zinc-900",
561
+ style: {
562
+ x: pillX,
563
+ y: 0,
564
+ width: resolvedPillWidth,
565
+ height: open ? pillHeight : HEIGHT,
566
+ rx: resolvedRoundness,
567
+ ry: resolvedRoundness,
568
+ fill,
569
+ transition: ready ? `x var(--morphic-duration) var(--morphic-spring-easing), width var(--morphic-duration) var(--morphic-spring-easing), height var(--morphic-duration) var(--morphic-spring-easing)` : "none"
570
+ }
571
+ }),
572
+ /* @__PURE__ */ jsx("rect", {
573
+ "data-morphic-body": true,
574
+ y: HEIGHT,
575
+ width: WIDTH,
576
+ className: "fill-white dark:fill-zinc-900",
577
+ style: {
578
+ height: open ? expandedContent : 0,
579
+ opacity: open ? 1 : 0,
580
+ rx: resolvedRoundness,
581
+ ry: resolvedRoundness,
582
+ fill,
583
+ transition: `height var(--morphic-duration) ${open ? "var(--morphic-spring-easing)" : "ease-in"}, opacity var(--morphic-duration) ${open ? "var(--morphic-spring-easing)" : "ease-in"}`
584
+ }
585
+ })
586
+ ]
587
+ })
588
+ }),
589
+ /* @__PURE__ */ jsx("div", {
590
+ ref: headerRef,
591
+ "data-morphic-header": true,
592
+ "data-edge": expand,
593
+ className: cn("absolute z-20 flex items-center px-4 h-10 overflow-hidden select-none left-(--_px,0px) max-w-(--_pw,350px)", expand === "top" ? "bottom-0" : "top-0"),
594
+ style: {
595
+ transform: "var(--_ht)",
596
+ transition: ready ? `transform var(--morphic-duration) var(--morphic-spring-easing), left var(--morphic-duration) var(--morphic-spring-easing), max-width var(--morphic-duration) var(--morphic-spring-easing)` : "none"
597
+ },
598
+ children: /* @__PURE__ */ jsxs("div", {
599
+ className: "relative inline-flex items-center h-full",
600
+ children: [/* @__PURE__ */ jsxs("div", {
601
+ ref: innerRef,
602
+ "data-morphic-header-inner": true,
603
+ "data-layer": "current",
604
+ className: "flex items-center gap-2.5 whitespace-nowrap",
605
+ style: { animation: ready ? "morphic-header-enter var(--morphic-duration) var(--morphic-spring-easing) both" : "none" },
606
+ children: [/* @__PURE__ */ jsx("div", {
607
+ "data-morphic-badge": true,
608
+ "data-state": headerLayer.current.view.state,
609
+ className: cn("flex h-6 w-6 shrink-0 items-center justify-center rounded-full p-0.5 box-border", headerLayer.current.view.styles?.badge),
610
+ children: headerLayer.current.view.icon ?? STATE_ICON[headerLayer.current.view.state]
611
+ }), /* @__PURE__ */ jsx("span", {
612
+ "data-morphic-title": true,
613
+ "data-state": headerLayer.current.view.state,
614
+ className: cn("text-[13px] leading-4 font-medium capitalize", headerLayer.current.view.styles?.title),
615
+ children: headerLayer.current.view.title
616
+ })]
617
+ }, headerLayer.current.key), headerLayer.prev && /* @__PURE__ */ jsxs("div", {
618
+ "data-morphic-header-inner": true,
619
+ "data-layer": "prev",
620
+ "data-exiting": "true",
621
+ className: "absolute left-0 top-0 z-0 pointer-events-none flex items-center gap-2.5 whitespace-nowrap",
622
+ style: { animation: "morphic-header-exit calc(var(--morphic-duration) * 0.7) ease forwards" },
623
+ children: [/* @__PURE__ */ jsx("div", {
624
+ "data-morphic-badge": true,
625
+ "data-state": headerLayer.prev.view.state,
626
+ className: cn("flex h-6 w-6 shrink-0 items-center justify-center rounded-full p-0.5 box-border", headerLayer.prev.view.styles?.badge),
627
+ children: headerLayer.prev.view.icon ?? STATE_ICON[headerLayer.prev.view.state]
628
+ }), /* @__PURE__ */ jsx("span", {
629
+ "data-morphic-title": true,
630
+ "data-state": headerLayer.prev.view.state,
631
+ className: cn("text-[13px] leading-4 font-medium capitalize", headerLayer.prev.view.styles?.title),
632
+ children: headerLayer.prev.view.title
633
+ })]
634
+ }, headerLayer.prev.key)]
635
+ })
636
+ }),
637
+ hasDesc && /* @__PURE__ */ jsx("div", {
638
+ "data-morphic-content": true,
639
+ "data-edge": expand,
640
+ "data-visible": open,
641
+ className: cn("absolute left-0 z-10 w-full pointer-events-none opacity-0 select-none", expand === "top" ? "top-0" : "top-10", open && "pointer-events-auto opacity-100 select-text"),
642
+ style: { transition: ready ? open ? `opacity calc(var(--morphic-duration) * 0.6) ease calc(var(--morphic-duration) * 0.3)` : `opacity calc(var(--morphic-duration) * 0.08) ease calc(var(--morphic-duration) * 0.04)` : "none" },
643
+ children: /* @__PURE__ */ jsxs("div", {
644
+ ref: contentRef,
645
+ "data-morphic-description": true,
646
+ className: cn("w-full text-left p-4 text-[13.5px] leading-5 text-zinc-900/60 dark:text-white/60", view.styles?.description),
647
+ children: [view.description, view.button && /* @__PURE__ */ jsx("button", {
648
+ type: "button",
649
+ "data-morphic-button": true,
650
+ "data-state": view.state,
651
+ className: cn("relative inline-flex items-center justify-center h-7 px-3 mt-3 rounded-full text-xs font-medium cursor-pointer transition-colors duration-150 border-0 outline-none select-none text-zinc-900 bg-zinc-900/10 hover:bg-zinc-900/20 dark:text-white dark:bg-white/10 dark:hover:bg-white/20 pointer-coarse:after:absolute pointer-coarse:after:size-full pointer-coarse:after:min-h-11 pointer-coarse:after:min-w-11", view.styles?.button),
652
+ onClick: handleButtonClick,
653
+ children: view.button.title
654
+ })]
655
+ })
656
+ })
657
+ ]
658
+ });
659
+ });
660
+ function MorphicToaster({ children, position = "top-right", offset, options, className, style, ...props }) {
661
+ const [toasts, setToasts] = useState(store.toasts);
662
+ const [activeId, setActiveId] = useState();
663
+ const hoverRef = useRef(false);
664
+ const timersRef = useRef(/* @__PURE__ */ new Map());
665
+ const listRef = useRef(toasts);
666
+ const latestRef = useRef(void 0);
667
+ const handlersCache = useRef(/* @__PURE__ */ new Map());
668
+ useEffect(() => {
669
+ store.position = position;
670
+ store.options = options;
671
+ }, [position, options]);
672
+ const clearAllTimers = useCallback(() => {
673
+ for (const t of timersRef.current.values()) clearTimeout(t);
674
+ timersRef.current.clear();
675
+ }, []);
676
+ const schedule = useCallback((items) => {
677
+ if (hoverRef.current) return;
678
+ for (const item of items) {
679
+ if (item.exiting) continue;
680
+ const key = timeoutKey(item);
681
+ if (timersRef.current.has(key)) continue;
682
+ if (item.duration === null) continue;
683
+ const dur = item.duration ?? DEFAULT_TOAST_DURATION;
684
+ if (dur <= 0) continue;
685
+ timersRef.current.set(key, window.setTimeout(() => dismissToast(item.id), dur));
686
+ }
687
+ }, []);
688
+ useEffect(() => {
689
+ const listener = (next) => setToasts(next);
690
+ store.listeners.add(listener);
691
+ return () => {
692
+ store.listeners.delete(listener);
693
+ clearAllTimers();
694
+ };
695
+ }, [clearAllTimers]);
696
+ useEffect(() => {
697
+ listRef.current = toasts;
698
+ const toastKeys = new Set(toasts.map(timeoutKey));
699
+ const toastIds = new Set(toasts.map((t) => t.id));
700
+ for (const [key, timer] of timersRef.current) if (!toastKeys.has(key)) {
701
+ clearTimeout(timer);
702
+ timersRef.current.delete(key);
703
+ }
704
+ for (const id of handlersCache.current.keys()) if (!toastIds.has(id)) handlersCache.current.delete(id);
705
+ schedule(toasts);
706
+ }, [toasts, schedule]);
707
+ const handleMouseEnterRef = useRef(null);
708
+ const handleMouseLeaveRef = useRef(null);
709
+ handleMouseEnterRef.current = useCallback(() => {
710
+ if (hoverRef.current) return;
711
+ hoverRef.current = true;
712
+ clearAllTimers();
713
+ }, [clearAllTimers]);
714
+ handleMouseLeaveRef.current = useCallback(() => {
715
+ if (!hoverRef.current) return;
716
+ hoverRef.current = false;
717
+ schedule(listRef.current);
718
+ }, [schedule]);
719
+ const latest = useMemo(() => {
720
+ for (let i = toasts.length - 1; i >= 0; i--) if (!toasts[i].exiting) return toasts[i].id;
721
+ }, [toasts]);
722
+ useEffect(() => {
723
+ latestRef.current = latest;
724
+ setActiveId(latest);
725
+ }, [latest]);
726
+ const getHandlers = useCallback((toastId) => {
727
+ let cached = handlersCache.current.get(toastId);
728
+ if (cached) return cached;
729
+ cached = {
730
+ enter: (e) => {
731
+ setActiveId((prev) => prev === toastId ? prev : toastId);
732
+ handleMouseEnterRef.current?.(e);
733
+ },
734
+ leave: (e) => {
735
+ setActiveId((prev) => prev === latestRef.current ? prev : latestRef.current);
736
+ handleMouseLeaveRef.current?.(e);
737
+ },
738
+ dismiss: () => dismissToast(toastId)
739
+ };
740
+ handlersCache.current.set(toastId, cached);
741
+ return cached;
742
+ }, []);
743
+ const getViewportStyle = useCallback((pos) => {
744
+ if (offset === void 0) return void 0;
745
+ const o = typeof offset === "object" ? offset : {
746
+ top: offset,
747
+ right: offset,
748
+ bottom: offset,
749
+ left: offset
750
+ };
751
+ const s = {};
752
+ const px = (v) => typeof v === "number" ? `${v}px` : v;
753
+ if (pos.startsWith("top") && o.top) s.top = px(o.top);
754
+ if (pos.startsWith("bottom") && o.bottom) s.bottom = px(o.bottom);
755
+ if (pos.endsWith("left") && o.left) s.left = px(o.left);
756
+ if (pos.endsWith("right") && o.right) s.right = px(o.right);
757
+ return s;
758
+ }, [offset]);
759
+ const activePositions = useMemo(() => {
760
+ const map = /* @__PURE__ */ new Map();
761
+ for (const t of toasts) {
762
+ const pos = t.position ?? position;
763
+ const arr = map.get(pos);
764
+ if (arr) arr.push(t);
765
+ else map.set(pos, [t]);
766
+ }
767
+ return map;
768
+ }, [toasts, position]);
769
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
770
+ /* @__PURE__ */ jsx("style", { dangerouslySetInnerHTML: { __html: `
771
+ :root {
772
+ --morphic-duration: 600ms;
773
+ --morphic-spring-easing: linear(0, 0.002 0.6%, 0.007 1.2%, 0.015 1.8%, 0.026 2.4%, 0.041 3.1%, 0.06 3.8%, 0.108 5.3%, 0.157 6.6%, 0.214 8%, 0.467 13.7%, 0.577 16.3%, 0.631 17.7%, 0.682 19.1%, 0.73 20.5%, 0.771 21.8%, 0.808 23.1%, 0.844 24.5%, 0.874 25.8%, 0.903 27.2%, 0.928 28.6%, 0.952 30.1%, 0.972 31.6%, 0.988 33.1%, 1.01 35.7%, 1.025 38.5%, 1.034 41.6%, 1.038 45%, 1.035 50.1%, 1.012 64.2%, 1.003 73%, 0.999 83.7%, 1);
774
+ --morphic-state-success: oklch(0.723 0.219 142.136);
775
+ --morphic-state-loading: oklch(0.556 0 0);
776
+ --morphic-state-error: oklch(0.637 0.237 25.331);
777
+ --morphic-state-warning: oklch(0.795 0.184 86.047);
778
+ --morphic-state-info: oklch(0.685 0.169 237.323);
779
+ --morphic-state-action: oklch(0.623 0.214 259.815);
780
+ }
781
+ @keyframes morphic-header-enter {
782
+ from { opacity: 0; filter: blur(6px); }
783
+ to { opacity: 1; filter: blur(0px); }
784
+ }
785
+ @keyframes morphic-header-exit {
786
+ from { opacity: 1; filter: blur(0px); }
787
+ to { opacity: 0; filter: blur(6px); }
788
+ }
789
+ [data-morphic-toast] [data-morphic-badge],
790
+ [data-morphic-toast] [data-morphic-title] {
791
+ --_c: var(--morphic-state-success);
792
+ }
793
+ [data-morphic-toast] [data-morphic-badge][data-state="loading"],
794
+ [data-morphic-toast] [data-morphic-title][data-state="loading"] {
795
+ --_c: var(--morphic-state-loading);
796
+ }
797
+ [data-morphic-toast] [data-morphic-badge][data-state="error"],
798
+ [data-morphic-toast] [data-morphic-title][data-state="error"] {
799
+ --_c: var(--morphic-state-error);
800
+ }
801
+ [data-morphic-toast] [data-morphic-badge][data-state="warning"],
802
+ [data-morphic-toast] [data-morphic-title][data-state="warning"] {
803
+ --_c: var(--morphic-state-warning);
804
+ }
805
+ [data-morphic-toast] [data-morphic-badge][data-state="info"],
806
+ [data-morphic-toast] [data-morphic-title][data-state="info"] {
807
+ --_c: var(--morphic-state-info);
808
+ }
809
+ [data-morphic-toast] [data-morphic-badge][data-state="action"],
810
+ [data-morphic-toast] [data-morphic-title][data-state="action"] {
811
+ --_c: var(--morphic-state-action);
812
+ }
813
+
814
+ [data-morphic-toast] [data-morphic-badge] {
815
+ color: var(--_c) !important;
816
+ background-color: color-mix(in oklch, var(--_c) 15%, transparent) !important;
817
+ }
818
+ [data-morphic-toast] [data-morphic-title] {
819
+ color: var(--_c) !important;
820
+ }
821
+
822
+ [data-morphic-button][data-state] {
823
+ --_c: var(--morphic-state-success);
824
+ }
825
+ [data-morphic-button][data-state="loading"] {
826
+ --_c: var(--morphic-state-loading);
827
+ }
828
+ [data-morphic-button][data-state="error"] {
829
+ --_c: var(--morphic-state-error);
830
+ }
831
+ [data-morphic-button][data-state="warning"] {
832
+ --_c: var(--morphic-state-warning);
833
+ }
834
+ [data-morphic-button][data-state="info"] {
835
+ --_c: var(--morphic-state-info);
836
+ }
837
+ [data-morphic-button][data-state="action"] {
838
+ --_c: var(--morphic-state-action);
839
+ }
840
+
841
+ [data-morphic-toast] [data-morphic-button] {
842
+ color: var(--_c) !important;
843
+ background-color: color-mix(in oklch, var(--_c) 15%, transparent) !important;
844
+ }
845
+ [data-morphic-toast] [data-morphic-button]:hover {
846
+ background-color: color-mix(in oklch, var(--_c) 25%, transparent) !important;
847
+ }
848
+ [data-morphic-toast] [data-morphic-button][data-state="action"] {
849
+ color: #ffffff !important;
850
+ background-color: var(--_c) !important;
851
+ }
852
+ [data-morphic-toast] [data-morphic-button][data-state="action"]:hover {
853
+ background-color: color-mix(in oklch, var(--_c) 85%, #000000) !important;
854
+ }
855
+
856
+ [data-morphic-viewport][data-position^="top"] [data-morphic-toast]:not([data-ready="true"]) {
857
+ margin-bottom: calc(-1 * (${HEIGHT}px + 0.75rem));
858
+ transform: translateY(-6px) scale(0.95);
859
+ }
860
+ [data-morphic-viewport][data-position^="bottom"] [data-morphic-toast]:not([data-ready="true"]) {
861
+ margin-top: calc(-1 * (${HEIGHT}px + 0.75rem));
862
+ transform: translateY(6px) scale(0.95);
863
+ }
864
+ [data-morphic-viewport][data-position^="top"] [data-morphic-toast][data-ready="true"][data-exiting="true"] {
865
+ transform: translateY(-6px) scale(0.95);
866
+ }
867
+ [data-morphic-viewport][data-position^="bottom"] [data-morphic-toast][data-ready="true"][data-exiting="true"] {
868
+ transform: translateY(6px) scale(0.95);
869
+ }
870
+ ` } }),
871
+ children,
872
+ Array.from(activePositions, ([pos, items]) => {
873
+ const pill = pillAlign(pos);
874
+ const expand = expandDir(pos);
875
+ return /* @__PURE__ */ jsx("section", {
876
+ "data-morphic-viewport": true,
877
+ "data-slot": "morphic-toaster-viewport",
878
+ "data-position": pos,
879
+ "aria-live": "polite",
880
+ className: cn("fixed z-50 flex flex-col gap-3 p-3 pointer-events-none max-w-[calc(100vw-1.5rem)]", pos.startsWith("top") ? "top-0 flex-col-reverse" : "bottom-0 flex-col", pos.endsWith("left") ? "left-0 items-start" : pos.endsWith("right") ? "right-0 items-end" : "left-1/2 -translate-x-1/2 items-center", className),
881
+ style: {
882
+ ...getViewportStyle(pos),
883
+ ...style
884
+ },
885
+ ...props,
886
+ children: items.map((item) => {
887
+ const h = getHandlers(item.id);
888
+ return /* @__PURE__ */ jsx(MorphicToast, {
889
+ id: item.id,
890
+ state: item.state,
891
+ title: item.title,
892
+ description: item.description,
893
+ position: pill,
894
+ expand,
895
+ icon: item.icon,
896
+ fill: item.fill,
897
+ styles: item.styles,
898
+ button: item.button,
899
+ roundness: item.roundness,
900
+ exiting: item.exiting,
901
+ autoExpandDelayMs: item.autoExpandDelayMs,
902
+ autoCollapseDelayMs: item.autoCollapseDelayMs,
903
+ refreshKey: item.instanceId,
904
+ canExpand: activeId === void 0 || activeId === item.id,
905
+ onMouseEnter: h.enter,
906
+ onMouseLeave: h.leave,
907
+ onDismiss: h.dismiss,
908
+ className: item.className
909
+ }, item.id);
910
+ })
911
+ }, pos);
912
+ })
913
+ ] });
914
+ }
915
+ //#endregion
916
+ export { MorphicToaster, morphicToast };