@ansh-ui/react 0.2.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 (111) hide show
  1. package/LICENSE +21 -0
  2. package/dist/chunk-5CFQFMP5.js +178 -0
  3. package/dist/chunk-5CFQFMP5.js.map +1 -0
  4. package/dist/chunk-6VRF7X5C.cjs +164 -0
  5. package/dist/chunk-6VRF7X5C.cjs.map +1 -0
  6. package/dist/chunk-AVPEA5PB.cjs +718 -0
  7. package/dist/chunk-AVPEA5PB.cjs.map +1 -0
  8. package/dist/chunk-C32LKF23.cjs +198 -0
  9. package/dist/chunk-C32LKF23.cjs.map +1 -0
  10. package/dist/chunk-C5JG6TMM.cjs +1200 -0
  11. package/dist/chunk-C5JG6TMM.cjs.map +1 -0
  12. package/dist/chunk-DATBU46V.cjs +614 -0
  13. package/dist/chunk-DATBU46V.cjs.map +1 -0
  14. package/dist/chunk-EGG4CP7C.js +320 -0
  15. package/dist/chunk-EGG4CP7C.js.map +1 -0
  16. package/dist/chunk-H34OXXJU.js +55 -0
  17. package/dist/chunk-H34OXXJU.js.map +1 -0
  18. package/dist/chunk-HO2YSF5O.js +187 -0
  19. package/dist/chunk-HO2YSF5O.js.map +1 -0
  20. package/dist/chunk-HPGCILO4.js +760 -0
  21. package/dist/chunk-HPGCILO4.js.map +1 -0
  22. package/dist/chunk-IBXLC5IE.js +154 -0
  23. package/dist/chunk-IBXLC5IE.js.map +1 -0
  24. package/dist/chunk-LDCZQP3R.js +1185 -0
  25. package/dist/chunk-LDCZQP3R.js.map +1 -0
  26. package/dist/chunk-LXCIXR5T.js +27 -0
  27. package/dist/chunk-LXCIXR5T.js.map +1 -0
  28. package/dist/chunk-O2PX54KX.js +94 -0
  29. package/dist/chunk-O2PX54KX.js.map +1 -0
  30. package/dist/chunk-OHBWBXLO.cjs +101 -0
  31. package/dist/chunk-OHBWBXLO.cjs.map +1 -0
  32. package/dist/chunk-OJN5JBNP.cjs +776 -0
  33. package/dist/chunk-OJN5JBNP.cjs.map +1 -0
  34. package/dist/chunk-OLTS6G5M.js +606 -0
  35. package/dist/chunk-OLTS6G5M.js.map +1 -0
  36. package/dist/chunk-PO5DU3FU.cjs +29 -0
  37. package/dist/chunk-PO5DU3FU.cjs.map +1 -0
  38. package/dist/chunk-QO3E7TJS.js +2940 -0
  39. package/dist/chunk-QO3E7TJS.js.map +1 -0
  40. package/dist/chunk-RHTLNSVW.cjs +2976 -0
  41. package/dist/chunk-RHTLNSVW.cjs.map +1 -0
  42. package/dist/chunk-SFU5EPSN.cjs +61 -0
  43. package/dist/chunk-SFU5EPSN.cjs.map +1 -0
  44. package/dist/chunk-T4AK2KLM.js +699 -0
  45. package/dist/chunk-T4AK2KLM.js.map +1 -0
  46. package/dist/chunk-WGYNCSTP.cjs +333 -0
  47. package/dist/chunk-WGYNCSTP.cjs.map +1 -0
  48. package/dist/chunk-XEP6P7E6.js +279 -0
  49. package/dist/chunk-XEP6P7E6.js.map +1 -0
  50. package/dist/chunk-XMXECSQO.cjs +286 -0
  51. package/dist/chunk-XMXECSQO.cjs.map +1 -0
  52. package/dist/chunk-ZWAFLHC2.cjs +181 -0
  53. package/dist/chunk-ZWAFLHC2.cjs.map +1 -0
  54. package/dist/data.cjs +71 -0
  55. package/dist/data.cjs.map +1 -0
  56. package/dist/data.d.cts +316 -0
  57. package/dist/data.d.ts +316 -0
  58. package/dist/data.js +6 -0
  59. package/dist/data.js.map +1 -0
  60. package/dist/form.cjs +153 -0
  61. package/dist/form.cjs.map +1 -0
  62. package/dist/form.d.cts +660 -0
  63. package/dist/form.d.ts +660 -0
  64. package/dist/form.js +8 -0
  65. package/dist/form.js.map +1 -0
  66. package/dist/index.cjs +1641 -0
  67. package/dist/index.cjs.map +1 -0
  68. package/dist/index.d.cts +552 -0
  69. package/dist/index.d.ts +552 -0
  70. package/dist/index.js +956 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/layout.cjs +68 -0
  73. package/dist/layout.cjs.map +1 -0
  74. package/dist/layout.d.cts +169 -0
  75. package/dist/layout.d.ts +169 -0
  76. package/dist/layout.js +7 -0
  77. package/dist/layout.js.map +1 -0
  78. package/dist/motion-CQmCq6_k.d.ts +395 -0
  79. package/dist/motion-CSX4g2N8.d.cts +395 -0
  80. package/dist/motion.cjs +79 -0
  81. package/dist/motion.cjs.map +1 -0
  82. package/dist/motion.d.cts +4 -0
  83. package/dist/motion.d.ts +4 -0
  84. package/dist/motion.js +6 -0
  85. package/dist/motion.js.map +1 -0
  86. package/dist/navigation.cjs +48 -0
  87. package/dist/navigation.cjs.map +1 -0
  88. package/dist/navigation.d.cts +210 -0
  89. package/dist/navigation.d.ts +210 -0
  90. package/dist/navigation.js +7 -0
  91. package/dist/navigation.js.map +1 -0
  92. package/dist/overlay.cjs +69 -0
  93. package/dist/overlay.cjs.map +1 -0
  94. package/dist/overlay.d.cts +330 -0
  95. package/dist/overlay.d.ts +330 -0
  96. package/dist/overlay.js +8 -0
  97. package/dist/overlay.js.map +1 -0
  98. package/dist/position-DVScKcaa.d.cts +66 -0
  99. package/dist/position-DVScKcaa.d.ts +66 -0
  100. package/dist/primitives.cjs +162 -0
  101. package/dist/primitives.cjs.map +1 -0
  102. package/dist/primitives.d.cts +294 -0
  103. package/dist/primitives.d.ts +294 -0
  104. package/dist/primitives.js +9 -0
  105. package/dist/primitives.js.map +1 -0
  106. package/dist/sidebar-D-PafAXw.d.cts +71 -0
  107. package/dist/sidebar-D-PafAXw.d.ts +71 -0
  108. package/dist/styles.css +5575 -0
  109. package/dist/use-observers-B9qtimrk.d.cts +99 -0
  110. package/dist/use-observers-B9qtimrk.d.ts +99 -0
  111. package/package.json +92 -0
package/dist/index.js ADDED
@@ -0,0 +1,956 @@
1
+ 'use client';
2
+ export { useAnimate, useIsMounted, useMotionStyle, useMotionValue, useMotionValueState, useSpringValue } from './chunk-O2PX54KX.js';
3
+ export { AspectRatio, Center, Container, Divider, Grid, GridItem, HStack, Resizable, ScrollArea, Spacer, Stack, VStack } from './chunk-EGG4CP7C.js';
4
+ export { Calendar, Checkbox, ChoiceCard, ColorPicker, Combobox, DatePicker, DateRangePicker, Dropzone, Field, Fieldset, Input, NumberInput, OptionList, PinInput, Radio, RadioGroup, RangeSlider, Rating, Select, Slider, Switch, TagsInput, Textarea, VisuallyHidden, addDays, addMonths, filterOptions, firstEnabled, isSameDay, scoreOption, startOfDay, stepActive, useFieldContext, useFieldControl, useTypeahead } from './chunk-QO3E7TJS.js';
5
+ export { AlertDialog, CommandPalette, ContextMenu, Dialog, DialogFooter, Drawer, DropdownMenu, HoverCard, Popover, PopoverContent, PopoverTrigger, Tooltip, TooltipProvider, useCommandShortcut } from './chunk-LDCZQP3R.js';
6
+ export { Presence, Slot, getTabbable, slotted, useAutoFocus, useFocusRestore, useFocusTrap, usePresence, useRovingFocus } from './chunk-HO2YSF5O.js';
7
+ export { Portal, computePosition, useAnchoredPosition, useDismiss, useScrollLock } from './chunk-XEP6P7E6.js';
8
+ export { Avatar, AvatarGroup, Badge, CircularProgress, CodeBlock, DataTable, DescriptionList, EmptyState, Kbd, Meter, Pagination, Progress, Stat, Table, Timeline } from './chunk-HPGCILO4.js';
9
+ export { Accordion, Breadcrumbs, Collapsible, DisclosureList, NavigationMenu, Stepper, Tabs } from './chunk-OLTS6G5M.js';
10
+ export { AppShell, Sidebar } from './chunk-5CFQFMP5.js';
11
+ export { useControllableState } from './chunk-LXCIXR5T.js';
12
+ import { useBehaviour } from './chunk-T4AK2KLM.js';
13
+ export { AnimatePresence, AnimatedText, Draggable, GradientText, MagneticButton, Marquee, Motion, MotionConfig, Parallax, Ripple, ScrollReveal, ThemeProvider, TiltCard, createBehaviourComponent, themeScript, useBehaviour, useMotionConfig, useTheme } from './chunk-T4AK2KLM.js';
14
+ import { useMergedRef, useInView } from './chunk-IBXLC5IE.js';
15
+ export { useElementSize, useFrameBudget, useInView, useMergedRef, usePointer, useReducedMotion, useScrollProgress, useTicker, useWindowScroll } from './chunk-IBXLC5IE.js';
16
+ import { cx } from './chunk-H34OXXJU.js';
17
+ export { composeEventHandlers, cx, mergeProps, mergeRefs } from './chunk-H34OXXJU.js';
18
+ import { forwardRef, useRef, useEffect, createContext, useMemo, useState, useCallback, useContext, useId } from 'react';
19
+ import { magnetic, ripple, getTicker, mountEffect, aurora, meshGradient, animatedGradient, particleField, constellation, meteors, rain, snow, fireflies, waves, blob, noiseLayer, spotlight, prefersReducedMotion } from '@ansh-ui/core';
20
+ export { MotionValue, animate, checkContrast, createGradient, createNoise, createScale, createTimeline, cubicBezier, easings, ensureContrast, generatePalette, getRegistry, getTicker, mixColors, motionValue, palettes, parseColor, pickReadable, prefersReducedMotion, registerEasing, setReducedMotionMode, signature as signatureEasings, springs, stagger, toHex, toOklchString } from '@ansh-ui/core';
21
+ import { jsx, jsxs } from 'react/jsx-runtime';
22
+
23
+ var HOST_STYLE = {
24
+ position: "relative",
25
+ isolation: "isolate",
26
+ overflow: "hidden"
27
+ };
28
+ var CONTENT_STYLE = {
29
+ position: "relative",
30
+ zIndex: 1
31
+ };
32
+ function createEffectComponent(definition, displayName) {
33
+ const optionKeys = new Set(Object.keys(definition.defaults));
34
+ function Render(props, forwardedRef) {
35
+ const { as: Component2 = "div", className, style, children, ...rest } = props;
36
+ const hostRef = useRef(null);
37
+ const handleRef = useRef(null);
38
+ const mergedRef = useMergedRef(hostRef, forwardedRef);
39
+ const options = {};
40
+ const domProps = {};
41
+ for (const [key, value] of Object.entries(rest)) {
42
+ if (optionKeys.has(key)) options[key] = value;
43
+ else domProps[key] = value;
44
+ }
45
+ const optionsKey = stableKey(options);
46
+ const optionsRef = useRef(options);
47
+ optionsRef.current = options;
48
+ useEffect(() => {
49
+ const host = hostRef.current;
50
+ if (!host) return;
51
+ const handle = mountEffect(definition, host, optionsRef.current);
52
+ handleRef.current = handle;
53
+ return () => {
54
+ handle.destroy();
55
+ handleRef.current = null;
56
+ };
57
+ }, []);
58
+ useEffect(() => {
59
+ handleRef.current?.update(optionsRef.current);
60
+ }, [optionsKey]);
61
+ return /* @__PURE__ */ jsx(
62
+ Component2,
63
+ {
64
+ ref: mergedRef,
65
+ className,
66
+ style: { ...HOST_STYLE, ...style },
67
+ ...domProps,
68
+ children: children != null ? /* @__PURE__ */ jsx("div", { style: CONTENT_STYLE, children }) : null
69
+ }
70
+ );
71
+ }
72
+ const Component = forwardRef(Render);
73
+ Component.displayName = displayName ?? `Ansh(${definition.name})`;
74
+ return Component;
75
+ }
76
+ function stableKey(options) {
77
+ const keys = Object.keys(options).sort();
78
+ const parts = [];
79
+ for (const key of keys) {
80
+ const value = options[key];
81
+ if (typeof value === "function") {
82
+ parts.push(`${key}:fn`);
83
+ } else if (value === void 0) {
84
+ continue;
85
+ } else {
86
+ parts.push(`${key}:${JSON.stringify(value)}`);
87
+ }
88
+ }
89
+ return parts.join("|");
90
+ }
91
+ var AuroraBackground = createEffectComponent(aurora, "AuroraBackground");
92
+ var MeshGradient = createEffectComponent(meshGradient, "MeshGradient");
93
+ var AnimatedGradient = createEffectComponent(animatedGradient, "AnimatedGradient");
94
+ var ParticleField = createEffectComponent(particleField, "ParticleField");
95
+ var Constellation = createEffectComponent(constellation, "Constellation");
96
+ var MeteorShower = createEffectComponent(meteors, "MeteorShower");
97
+ var Rain = createEffectComponent(rain, "Rain");
98
+ var Snow = createEffectComponent(snow, "Snow");
99
+ var Fireflies = createEffectComponent(fireflies, "Fireflies");
100
+ var Waves = createEffectComponent(waves, "Waves");
101
+ var LiquidBlob = createEffectComponent(blob, "LiquidBlob");
102
+ var NoiseLayer = createEffectComponent(noiseLayer, "NoiseLayer");
103
+ var Spotlight = createEffectComponent(spotlight, "Spotlight");
104
+ var Button = forwardRef(function Button2({
105
+ variant = "solid",
106
+ size = "md",
107
+ as: Component = "button",
108
+ magneticStrength = 0,
109
+ ripple: ripple$1 = false,
110
+ glowColors,
111
+ duration,
112
+ className,
113
+ style,
114
+ children,
115
+ ...rest
116
+ }, forwardedRef) {
117
+ const localRef = useRef(null);
118
+ const mergedRef = useMergedRef(localRef, forwardedRef);
119
+ useBehaviour(localRef, magnetic, {
120
+ strength: magneticStrength,
121
+ disabled: magneticStrength <= 0,
122
+ scale: magneticStrength > 0 ? 1.03 : 1
123
+ });
124
+ useBehaviour(localRef, ripple, { disabled: !ripple$1 });
125
+ const classes = [
126
+ "ansh-btn",
127
+ `ansh-btn--${variant}`,
128
+ size !== "md" && `ansh-btn--${size}`,
129
+ "ansh-focusable",
130
+ className
131
+ ].filter(Boolean).join(" ");
132
+ const cssVars = {};
133
+ if (glowColors) {
134
+ cssVars["--ansh-glow-from"] = glowColors[0];
135
+ cssVars["--ansh-glow-via"] = glowColors[1];
136
+ cssVars["--ansh-glow-to"] = glowColors[0];
137
+ }
138
+ if (duration !== void 0) {
139
+ cssVars["--ansh-glow-duration"] = `${duration}s`;
140
+ cssVars["--ansh-shimmer-duration"] = `${duration}s`;
141
+ }
142
+ return /* @__PURE__ */ jsx(Component, { ref: mergedRef, className: classes, style: { ...cssVars, ...style }, ...rest, children });
143
+ });
144
+ var IconButton = forwardRef(function IconButton2({ label, className, ...rest }, ref) {
145
+ return /* @__PURE__ */ jsx(
146
+ Button,
147
+ {
148
+ ref,
149
+ "aria-label": label,
150
+ className: ["ansh-btn--icon", className].filter(Boolean).join(" "),
151
+ style: { padding: "var(--ansh-space-3)", aspectRatio: "1" },
152
+ ...rest
153
+ }
154
+ );
155
+ });
156
+ var SpotlightCard = forwardRef(function SpotlightCard2({ as: Component = "div", color, size, className, children, ...rest }, forwardedRef) {
157
+ const localRef = useRef(null);
158
+ const mergedRef = useMergedRef(localRef, forwardedRef);
159
+ useEffect(() => {
160
+ const node = localRef.current;
161
+ if (!node) return;
162
+ const onMove = (event) => {
163
+ const rect = node.getBoundingClientRect();
164
+ node.style.setProperty("--ansh-spot-x", `${event.clientX - rect.left}px`);
165
+ node.style.setProperty("--ansh-spot-y", `${event.clientY - rect.top}px`);
166
+ };
167
+ const onEnter = () => node.style.setProperty("--ansh-spot-opacity", "1");
168
+ const onLeave = () => node.style.setProperty("--ansh-spot-opacity", "0");
169
+ node.addEventListener("pointermove", onMove, { passive: true });
170
+ node.addEventListener("pointerenter", onEnter, { passive: true });
171
+ node.addEventListener("pointerleave", onLeave, { passive: true });
172
+ return () => {
173
+ node.removeEventListener("pointermove", onMove);
174
+ node.removeEventListener("pointerenter", onEnter);
175
+ node.removeEventListener("pointerleave", onLeave);
176
+ };
177
+ }, []);
178
+ const cssVars = {};
179
+ if (color) cssVars["--ansh-spot-color"] = color;
180
+ if (size) cssVars["--ansh-spot-size"] = `${size}px`;
181
+ return /* @__PURE__ */ jsx(
182
+ Component,
183
+ {
184
+ ref: mergedRef,
185
+ className: ["ansh-card", "ansh-card--spotlight", className].filter(Boolean).join(" "),
186
+ style: cssVars,
187
+ ...rest,
188
+ children
189
+ }
190
+ );
191
+ });
192
+ var GlowCard = forwardRef(function GlowCard2({ as: Component = "div", colors, duration, className, style, children, ...rest }, ref) {
193
+ const cssVars = {};
194
+ if (colors) {
195
+ cssVars["--ansh-glow-from"] = colors[0];
196
+ cssVars["--ansh-glow-via"] = colors[1];
197
+ cssVars["--ansh-glow-to"] = colors[0];
198
+ }
199
+ if (duration !== void 0) cssVars["--ansh-glow-duration"] = `${duration}s`;
200
+ return /* @__PURE__ */ jsx(
201
+ Component,
202
+ {
203
+ ref,
204
+ className: ["ansh-card", "ansh-card--glow", className].filter(Boolean).join(" "),
205
+ style: { ...cssVars, ...style },
206
+ ...rest,
207
+ children
208
+ }
209
+ );
210
+ });
211
+ var TiltCard3D = forwardRef(function TiltCard3D2({ as: Component = "div", max = 12, className, style, children, ...rest }, forwardedRef) {
212
+ const localRef = useRef(null);
213
+ const mergedRef = useMergedRef(localRef, forwardedRef);
214
+ useEffect(() => {
215
+ const node = localRef.current;
216
+ if (!node) return;
217
+ let pending = null;
218
+ const onMove = (event) => {
219
+ const rect = node.getBoundingClientRect();
220
+ pending = {
221
+ nx: (event.clientX - rect.left) / rect.width - 0.5,
222
+ ny: (event.clientY - rect.top) / rect.height - 0.5
223
+ };
224
+ };
225
+ const onLeave = () => {
226
+ pending = { nx: 0, ny: 0 };
227
+ };
228
+ node.addEventListener("pointermove", onMove, { passive: true });
229
+ node.addEventListener("pointerleave", onLeave, { passive: true });
230
+ const stop = getTicker().add(
231
+ () => {
232
+ if (!pending) return;
233
+ const { nx, ny } = pending;
234
+ node.style.transform = `perspective(800px) rotateX(${(-ny * max).toFixed(2)}deg) rotateY(${(nx * max).toFixed(2)}deg)`;
235
+ },
236
+ { phase: "write", name: "TiltCard3D" }
237
+ );
238
+ return () => {
239
+ node.removeEventListener("pointermove", onMove);
240
+ node.removeEventListener("pointerleave", onLeave);
241
+ stop();
242
+ };
243
+ }, [max]);
244
+ return /* @__PURE__ */ jsx(
245
+ Component,
246
+ {
247
+ ref: mergedRef,
248
+ className: ["ansh-card", className].filter(Boolean).join(" "),
249
+ style: { transition: "transform 400ms ease-out", ...style },
250
+ ...rest,
251
+ children
252
+ }
253
+ );
254
+ });
255
+ function BentoGrid({ columns = 3, className, style, children, ...rest }) {
256
+ return /* @__PURE__ */ jsx(
257
+ "div",
258
+ {
259
+ className: ["ansh-bento", className].filter(Boolean).join(" "),
260
+ style: { ["--ansh-bento-cols"]: columns, ...style },
261
+ ...rest,
262
+ children
263
+ }
264
+ );
265
+ }
266
+ function BentoItem({
267
+ span = 1,
268
+ rowSpan = 1,
269
+ className,
270
+ style,
271
+ children,
272
+ ...rest
273
+ }) {
274
+ return /* @__PURE__ */ jsx(
275
+ "div",
276
+ {
277
+ className: ["ansh-bento__item", "ansh-card", className].filter(Boolean).join(" "),
278
+ style: { ["--ansh-span"]: span, ["--ansh-row-span"]: rowSpan, ...style },
279
+ ...rest,
280
+ children
281
+ }
282
+ );
283
+ }
284
+ function Dock({
285
+ items,
286
+ size = 48,
287
+ magnification = 80,
288
+ distance = 140,
289
+ className,
290
+ ...rest
291
+ }) {
292
+ const dockRef = useRef(null);
293
+ const itemRefs = useRef([]);
294
+ useEffect(() => {
295
+ const dock = dockRef.current;
296
+ if (!dock) return;
297
+ let pointerX = null;
298
+ const sizes = items.map(() => size);
299
+ const onMove = (event) => {
300
+ pointerX = event.clientX;
301
+ };
302
+ const onLeave = () => {
303
+ pointerX = null;
304
+ };
305
+ dock.addEventListener("pointermove", onMove, { passive: true });
306
+ dock.addEventListener("pointerleave", onLeave, { passive: true });
307
+ const stop = getTicker().add(
308
+ ({ delta }) => {
309
+ const retain = Math.pow(1e-4, delta);
310
+ for (let i = 0; i < itemRefs.current.length; i++) {
311
+ const node = itemRefs.current[i];
312
+ if (!node) continue;
313
+ let target = size;
314
+ if (pointerX !== null) {
315
+ const rect = node.getBoundingClientRect();
316
+ const centre = rect.left + rect.width / 2;
317
+ const gap = Math.abs(pointerX - centre);
318
+ if (gap < distance) {
319
+ const falloff = (Math.cos(gap / distance * Math.PI) + 1) / 2;
320
+ target = size + (magnification - size) * falloff;
321
+ }
322
+ }
323
+ sizes[i] = target + (sizes[i] - target) * retain;
324
+ if (Math.abs(sizes[i] - target) < 0.1) sizes[i] = target;
325
+ node.style.width = `${sizes[i].toFixed(1)}px`;
326
+ node.style.height = `${sizes[i].toFixed(1)}px`;
327
+ }
328
+ },
329
+ { phase: "write", name: "Dock" }
330
+ );
331
+ return () => {
332
+ dock.removeEventListener("pointermove", onMove);
333
+ dock.removeEventListener("pointerleave", onLeave);
334
+ stop();
335
+ };
336
+ }, [items, size, magnification, distance]);
337
+ return /* @__PURE__ */ jsx(
338
+ "div",
339
+ {
340
+ ref: dockRef,
341
+ className: ["ansh-dock", className].filter(Boolean).join(" "),
342
+ role: "toolbar",
343
+ "aria-label": "Dock",
344
+ ...rest,
345
+ children: items.map((item, index) => {
346
+ const Tag = item.href ? "a" : "button";
347
+ return /* @__PURE__ */ jsxs(
348
+ Tag,
349
+ {
350
+ ref: (node) => {
351
+ itemRefs.current[index] = node;
352
+ },
353
+ className: "ansh-dock__item ansh-focusable",
354
+ style: { ["--ansh-dock-size"]: `${size}px` },
355
+ "aria-label": item.label,
356
+ onClick: item.onClick,
357
+ ...item.href ? { href: item.href } : { type: "button" },
358
+ children: [
359
+ item.icon,
360
+ /* @__PURE__ */ jsx("span", { className: "ansh-dock__label", "aria-hidden": "true", children: item.label })
361
+ ]
362
+ },
363
+ item.label
364
+ );
365
+ })
366
+ }
367
+ );
368
+ }
369
+ function Typewriter({
370
+ words,
371
+ speed = 24,
372
+ deleteSpeed = 40,
373
+ pause = 1.6,
374
+ loop,
375
+ caret = true,
376
+ className,
377
+ ...rest
378
+ }) {
379
+ const list = useMemo(() => typeof words === "string" ? [words] : words, [words]);
380
+ const shouldLoop = loop ?? list.length > 1;
381
+ const [visible, setVisible] = useState("");
382
+ const reduced = prefersReducedMotion();
383
+ useEffect(() => {
384
+ if (reduced || list.length === 0) return;
385
+ let wordIndex = 0;
386
+ let charCount = 0;
387
+ let phase = "typing";
388
+ let timer = 0;
389
+ const stop = getTicker().add(
390
+ ({ delta }) => {
391
+ timer += delta;
392
+ const current = list[wordIndex] ?? "";
393
+ switch (phase) {
394
+ case "typing": {
395
+ const target = Math.min(current.length, Math.floor(timer * speed));
396
+ if (target !== charCount) {
397
+ charCount = target;
398
+ setVisible(current.slice(0, charCount));
399
+ }
400
+ if (charCount >= current.length) {
401
+ phase = "holding";
402
+ timer = 0;
403
+ }
404
+ break;
405
+ }
406
+ case "holding": {
407
+ if (timer >= pause) {
408
+ if (!shouldLoop && list.length === 1) {
409
+ stop();
410
+ return;
411
+ }
412
+ phase = "deleting";
413
+ timer = 0;
414
+ }
415
+ break;
416
+ }
417
+ case "deleting": {
418
+ const target = Math.max(0, current.length - Math.floor(timer * deleteSpeed));
419
+ if (target !== charCount) {
420
+ charCount = target;
421
+ setVisible(current.slice(0, charCount));
422
+ }
423
+ if (charCount === 0) {
424
+ wordIndex = (wordIndex + 1) % list.length;
425
+ if (wordIndex === 0 && !shouldLoop) {
426
+ stop();
427
+ return;
428
+ }
429
+ phase = "typing";
430
+ timer = 0;
431
+ }
432
+ break;
433
+ }
434
+ }
435
+ },
436
+ { phase: "compute", name: "Typewriter" }
437
+ );
438
+ return stop;
439
+ }, [list, speed, deleteSpeed, pause, shouldLoop, reduced]);
440
+ return /* @__PURE__ */ jsxs("span", { className, ...rest, children: [
441
+ /* @__PURE__ */ jsx(
442
+ "span",
443
+ {
444
+ style: {
445
+ position: "absolute",
446
+ width: 1,
447
+ height: 1,
448
+ overflow: "hidden",
449
+ clipPath: "inset(50%)",
450
+ whiteSpace: "nowrap"
451
+ },
452
+ children: list.join(", ")
453
+ }
454
+ ),
455
+ /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", children: [
456
+ reduced ? list[0] : visible,
457
+ caret && !reduced ? /* @__PURE__ */ jsx("span", { className: "ansh-caret" }) : null
458
+ ] })
459
+ ] });
460
+ }
461
+ function ShinyText({ duration, className, style, children, ...rest }) {
462
+ return /* @__PURE__ */ jsx(
463
+ "span",
464
+ {
465
+ className: ["ansh-shiny", className].filter(Boolean).join(" "),
466
+ style: {
467
+ ...duration !== void 0 ? { ["--ansh-shiny-duration"]: `${duration}s` } : {},
468
+ ...style
469
+ },
470
+ ...rest,
471
+ children
472
+ }
473
+ );
474
+ }
475
+ function NumberTicker({
476
+ value,
477
+ duration = 1.4,
478
+ decimals = 0,
479
+ prefix = "",
480
+ suffix = "",
481
+ whenInView = true,
482
+ className,
483
+ ...rest
484
+ }) {
485
+ const [ref, inView] = useInView({ threshold: 0.3, once: true });
486
+ const displayRef = useRef(null);
487
+ const formatter = useRef(
488
+ new Intl.NumberFormat(void 0, {
489
+ minimumFractionDigits: decimals,
490
+ maximumFractionDigits: decimals
491
+ })
492
+ );
493
+ useEffect(() => {
494
+ formatter.current = new Intl.NumberFormat(void 0, {
495
+ minimumFractionDigits: decimals,
496
+ maximumFractionDigits: decimals
497
+ });
498
+ }, [decimals]);
499
+ useEffect(() => {
500
+ const node = displayRef.current;
501
+ if (!node) return;
502
+ const write = (n) => {
503
+ node.textContent = `${prefix}${formatter.current.format(n)}${suffix}`;
504
+ };
505
+ if (prefersReducedMotion()) {
506
+ write(value);
507
+ return;
508
+ }
509
+ if (whenInView && !inView) {
510
+ write(0);
511
+ return;
512
+ }
513
+ let elapsed = 0;
514
+ const stop = getTicker().add(
515
+ ({ delta }) => {
516
+ elapsed += delta;
517
+ const t = duration <= 0 ? 1 : Math.min(1, elapsed / duration);
518
+ const eased = t >= 1 ? 1 : 1 - Math.pow(2, -10 * t);
519
+ write(value * eased);
520
+ if (t >= 1) {
521
+ write(value);
522
+ stop();
523
+ }
524
+ },
525
+ { phase: "write", name: "NumberTicker" }
526
+ );
527
+ return stop;
528
+ }, [value, duration, prefix, suffix, whenInView, inView]);
529
+ return /* @__PURE__ */ jsxs("span", { ref, className, ...rest, children: [
530
+ /* @__PURE__ */ jsxs(
531
+ "span",
532
+ {
533
+ style: {
534
+ position: "absolute",
535
+ width: 1,
536
+ height: 1,
537
+ overflow: "hidden",
538
+ clipPath: "inset(50%)"
539
+ },
540
+ children: [
541
+ prefix,
542
+ value,
543
+ suffix
544
+ ]
545
+ }
546
+ ),
547
+ /* @__PURE__ */ jsx("span", { ref: displayRef, "aria-hidden": "true" })
548
+ ] });
549
+ }
550
+ function Spinner({
551
+ size = 24,
552
+ thickness = 3,
553
+ label = "Loading",
554
+ className,
555
+ style,
556
+ ...rest
557
+ }) {
558
+ return /* @__PURE__ */ jsx(
559
+ "span",
560
+ {
561
+ className: ["ansh-spinner", className].filter(Boolean).join(" "),
562
+ style: {
563
+ ["--ansh-size"]: `${size}px`,
564
+ ["--ansh-thickness"]: `${thickness}px`,
565
+ ...style
566
+ },
567
+ ...label ? { role: "status", "aria-label": label } : { "aria-hidden": "true" },
568
+ ...rest
569
+ }
570
+ );
571
+ }
572
+ function LoadingDots({ size = 8, label = "Loading", className, style, ...rest }) {
573
+ return /* @__PURE__ */ jsxs(
574
+ "span",
575
+ {
576
+ className: ["ansh-dots", className].filter(Boolean).join(" "),
577
+ style: { ["--ansh-size"]: `${size}px`, ...style },
578
+ ...label ? { role: "status", "aria-label": label } : { "aria-hidden": "true" },
579
+ ...rest,
580
+ children: [
581
+ /* @__PURE__ */ jsx("span", {}),
582
+ /* @__PURE__ */ jsx("span", {}),
583
+ /* @__PURE__ */ jsx("span", {})
584
+ ]
585
+ }
586
+ );
587
+ }
588
+ function Skeleton({
589
+ width = "100%",
590
+ height = "1em",
591
+ circle = false,
592
+ className,
593
+ style,
594
+ ...rest
595
+ }) {
596
+ return /* @__PURE__ */ jsx(
597
+ "div",
598
+ {
599
+ className: ["ansh-skeleton", className].filter(Boolean).join(" "),
600
+ "aria-hidden": "true",
601
+ style: {
602
+ width,
603
+ height,
604
+ ...circle ? { borderRadius: "50%", aspectRatio: "1" } : {},
605
+ ...style
606
+ },
607
+ ...rest
608
+ }
609
+ );
610
+ }
611
+ var ToastContext = createContext(null);
612
+ function ToastProvider({ children }) {
613
+ const [toasts, setToasts] = useState([]);
614
+ const [closing, setClosing] = useState(/* @__PURE__ */ new Set());
615
+ const timers = useRef(/* @__PURE__ */ new Map());
616
+ const dismiss = useCallback((id) => {
617
+ setClosing((prev) => new Set(prev).add(id));
618
+ const timer = setTimeout(() => {
619
+ setToasts((prev) => prev.filter((t) => t.id !== id));
620
+ setClosing((prev) => {
621
+ const next = new Set(prev);
622
+ next.delete(id);
623
+ return next;
624
+ });
625
+ }, 200);
626
+ timers.current.set(`${id}-exit`, timer);
627
+ }, []);
628
+ const toast = useCallback(
629
+ (input) => {
630
+ const id = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
631
+ const next = { id, duration: 4500, variant: "info", ...input };
632
+ setToasts((prev) => [...prev, next]);
633
+ if (next.duration && next.duration > 0) {
634
+ timers.current.set(
635
+ id,
636
+ setTimeout(() => dismiss(id), next.duration)
637
+ );
638
+ }
639
+ return id;
640
+ },
641
+ [dismiss]
642
+ );
643
+ useEffect(() => {
644
+ const map = timers.current;
645
+ return () => {
646
+ for (const timer of map.values()) clearTimeout(timer);
647
+ map.clear();
648
+ };
649
+ }, []);
650
+ const value = useMemo(() => ({ toast, dismiss }), [toast, dismiss]);
651
+ return /* @__PURE__ */ jsxs(ToastContext.Provider, { value, children: [
652
+ children,
653
+ /* @__PURE__ */ jsx(
654
+ "div",
655
+ {
656
+ className: "ansh-toaster",
657
+ role: "region",
658
+ "aria-live": "polite",
659
+ "aria-label": "Notifications",
660
+ children: toasts.map((t) => /* @__PURE__ */ jsxs(
661
+ "div",
662
+ {
663
+ className: `ansh-toast ansh-toast--${t.variant ?? "info"}`,
664
+ "data-state": closing.has(t.id) ? "closing" : "open",
665
+ children: [
666
+ /* @__PURE__ */ jsx("span", { className: "ansh-toast__dot", "aria-hidden": "true" }),
667
+ /* @__PURE__ */ jsxs("div", { style: { display: "grid", gap: 2 }, children: [
668
+ t.title ? /* @__PURE__ */ jsx("div", { className: "ansh-toast__title", children: t.title }) : null,
669
+ /* @__PURE__ */ jsx("div", { className: "ansh-toast__body", children: t.message })
670
+ ] }),
671
+ /* @__PURE__ */ jsx(
672
+ "button",
673
+ {
674
+ type: "button",
675
+ onClick: () => dismiss(t.id),
676
+ "aria-label": "Dismiss notification",
677
+ className: "ansh-focusable",
678
+ style: {
679
+ marginLeft: "auto",
680
+ background: "none",
681
+ border: 0,
682
+ color: "inherit",
683
+ cursor: "pointer",
684
+ opacity: 0.6,
685
+ padding: 4
686
+ },
687
+ children: "\u2715"
688
+ }
689
+ )
690
+ ]
691
+ },
692
+ t.id
693
+ ))
694
+ }
695
+ )
696
+ ] });
697
+ }
698
+ function useToast() {
699
+ const context = useContext(ToastContext);
700
+ if (!context) {
701
+ throw new Error("[ansh] useToast() must be used inside a <ToastProvider>.");
702
+ }
703
+ return context;
704
+ }
705
+ function PricingTable({ plans, className }) {
706
+ return /* @__PURE__ */ jsx("div", { className: ["ansh-pricing", className].filter(Boolean).join(" "), children: plans.map((plan) => /* @__PURE__ */ jsxs(
707
+ "div",
708
+ {
709
+ className: [
710
+ "ansh-card",
711
+ "ansh-plan",
712
+ plan.featured && "ansh-plan--featured",
713
+ plan.featured && "ansh-card--glow"
714
+ ].filter(Boolean).join(" "),
715
+ children: [
716
+ plan.featured ? /* @__PURE__ */ jsx("span", { className: "ansh-plan__badge", children: plan.badge ?? "Most popular" }) : null,
717
+ /* @__PURE__ */ jsxs("div", { children: [
718
+ /* @__PURE__ */ jsx("div", { className: "ansh-plan__name", children: plan.name }),
719
+ /* @__PURE__ */ jsxs("div", { className: "ansh-plan__price", children: [
720
+ /* @__PURE__ */ jsx("span", { children: plan.price }),
721
+ plan.period ? /* @__PURE__ */ jsx("span", { className: "ansh-plan__period", children: plan.period }) : null
722
+ ] })
723
+ ] }),
724
+ plan.description ? /* @__PURE__ */ jsx(
725
+ "p",
726
+ {
727
+ style: {
728
+ margin: 0,
729
+ fontSize: "var(--ansh-text-sm)",
730
+ color: "var(--ansh-content-secondary)"
731
+ },
732
+ children: plan.description
733
+ }
734
+ ) : null,
735
+ /* @__PURE__ */ jsx("ul", { className: "ansh-plan__features", children: plan.features.map((feature) => /* @__PURE__ */ jsxs("li", { children: [
736
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", style: { color: "var(--ansh-state-success)" }, children: "\u2713" }),
737
+ /* @__PURE__ */ jsx("span", { children: feature })
738
+ ] }, feature)) }),
739
+ plan.cta ? /* @__PURE__ */ jsx(
740
+ Button,
741
+ {
742
+ as: plan.cta.href ? "a" : "button",
743
+ ...plan.cta.href ? { href: plan.cta.href } : {},
744
+ onClick: plan.cta.onClick,
745
+ variant: plan.cta.variant ?? (plan.featured ? "shimmer" : "ghost"),
746
+ style: { marginTop: "auto", width: "100%" },
747
+ children: plan.cta.label
748
+ }
749
+ ) : null
750
+ ]
751
+ },
752
+ plan.name
753
+ )) });
754
+ }
755
+ function FAQAccordion({
756
+ items,
757
+ multiple = false,
758
+ defaultOpen,
759
+ className
760
+ }) {
761
+ const [open, setOpen] = useState(
762
+ () => new Set(defaultOpen === void 0 ? [] : [defaultOpen])
763
+ );
764
+ const baseId = useId();
765
+ const toggle = (index) => {
766
+ setOpen((prev) => {
767
+ const next = new Set(multiple ? prev : []);
768
+ if (prev.has(index)) next.delete(index);
769
+ else next.add(index);
770
+ return next;
771
+ });
772
+ };
773
+ return /* @__PURE__ */ jsx("div", { className: ["ansh-accordion", className].filter(Boolean).join(" "), children: items.map((item, index) => {
774
+ const isOpen = open.has(index);
775
+ const triggerId = `${baseId}-trigger-${index}`;
776
+ const panelId = `${baseId}-panel-${index}`;
777
+ return /* @__PURE__ */ jsxs("div", { className: "ansh-accordion__item", children: [
778
+ /* @__PURE__ */ jsx("h3", { style: { margin: 0 }, children: /* @__PURE__ */ jsxs(
779
+ "button",
780
+ {
781
+ id: triggerId,
782
+ type: "button",
783
+ className: "ansh-accordion__trigger ansh-focusable",
784
+ "aria-expanded": isOpen,
785
+ "aria-controls": panelId,
786
+ onClick: () => toggle(index),
787
+ children: [
788
+ /* @__PURE__ */ jsx("span", { children: item.question }),
789
+ /* @__PURE__ */ jsx("span", { className: "ansh-accordion__icon", "aria-hidden": "true", children: "+" })
790
+ ]
791
+ }
792
+ ) }),
793
+ /* @__PURE__ */ jsx(
794
+ "div",
795
+ {
796
+ id: panelId,
797
+ role: "region",
798
+ "aria-labelledby": triggerId,
799
+ className: "ansh-accordion__panel",
800
+ "data-open": isOpen,
801
+ ...isOpen ? {} : { inert: true },
802
+ children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("div", { className: "ansh-accordion__body", children: item.answer }) })
803
+ }
804
+ )
805
+ ] }, item.question);
806
+ }) });
807
+ }
808
+ var ICONS = {
809
+ info: /* @__PURE__ */ jsxs(
810
+ "svg",
811
+ {
812
+ viewBox: "0 0 20 20",
813
+ width: "18",
814
+ height: "18",
815
+ fill: "none",
816
+ stroke: "currentColor",
817
+ strokeWidth: "1.6",
818
+ children: [
819
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "7.5" }),
820
+ /* @__PURE__ */ jsx("path", { d: "M10 9v4.5", strokeLinecap: "round" }),
821
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "6.5", r: "0.9", fill: "currentColor", stroke: "none" })
822
+ ]
823
+ }
824
+ ),
825
+ success: /* @__PURE__ */ jsxs(
826
+ "svg",
827
+ {
828
+ viewBox: "0 0 20 20",
829
+ width: "18",
830
+ height: "18",
831
+ fill: "none",
832
+ stroke: "currentColor",
833
+ strokeWidth: "1.6",
834
+ children: [
835
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "7.5" }),
836
+ /* @__PURE__ */ jsx("path", { d: "M6.5 10.3l2.4 2.4 4.6-5.2", strokeLinecap: "round", strokeLinejoin: "round" })
837
+ ]
838
+ }
839
+ ),
840
+ warning: /* @__PURE__ */ jsxs(
841
+ "svg",
842
+ {
843
+ viewBox: "0 0 20 20",
844
+ width: "18",
845
+ height: "18",
846
+ fill: "none",
847
+ stroke: "currentColor",
848
+ strokeWidth: "1.6",
849
+ children: [
850
+ /* @__PURE__ */ jsx(
851
+ "path",
852
+ {
853
+ d: "M8.6 3.2L1.9 14.6a1.6 1.6 0 001.4 2.4h13.4a1.6 1.6 0 001.4-2.4L11.4 3.2a1.6 1.6 0 00-2.8 0z",
854
+ strokeLinejoin: "round"
855
+ }
856
+ ),
857
+ /* @__PURE__ */ jsx("path", { d: "M10 7.5v3.5", strokeLinecap: "round" }),
858
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "13.6", r: "0.9", fill: "currentColor", stroke: "none" })
859
+ ]
860
+ }
861
+ ),
862
+ danger: /* @__PURE__ */ jsxs(
863
+ "svg",
864
+ {
865
+ viewBox: "0 0 20 20",
866
+ width: "18",
867
+ height: "18",
868
+ fill: "none",
869
+ stroke: "currentColor",
870
+ strokeWidth: "1.6",
871
+ children: [
872
+ /* @__PURE__ */ jsx("circle", { cx: "10", cy: "10", r: "7.5" }),
873
+ /* @__PURE__ */ jsx("path", { d: "M7.5 7.5l5 5M12.5 7.5l-5 5", strokeLinecap: "round" })
874
+ ]
875
+ }
876
+ ),
877
+ neutral: null
878
+ };
879
+ function Alert({
880
+ tone = "info",
881
+ title,
882
+ children,
883
+ icon,
884
+ dismissible = false,
885
+ onDismiss,
886
+ actions,
887
+ variant = "soft",
888
+ className
889
+ }) {
890
+ const [visible, setVisible] = useState(true);
891
+ if (!visible) return null;
892
+ const urgent = tone === "danger" || tone === "warning";
893
+ const resolvedIcon = icon === void 0 ? ICONS[tone] : icon;
894
+ return /* @__PURE__ */ jsxs(
895
+ "div",
896
+ {
897
+ className: cx("ansh-alert", `ansh-alert--${tone}`, `ansh-alert--${variant}`, className),
898
+ role: urgent ? "alert" : "status",
899
+ "aria-live": urgent ? "assertive" : "polite",
900
+ children: [
901
+ resolvedIcon ? /* @__PURE__ */ jsx("span", { className: "ansh-alert__icon", "aria-hidden": "true", children: resolvedIcon }) : null,
902
+ /* @__PURE__ */ jsxs("div", { className: "ansh-alert__body", children: [
903
+ title ? /* @__PURE__ */ jsx("p", { className: "ansh-alert__title", children: title }) : null,
904
+ children ? /* @__PURE__ */ jsx("div", { className: "ansh-alert__message", children }) : null,
905
+ actions ? /* @__PURE__ */ jsx("div", { className: "ansh-alert__actions", children: actions }) : null
906
+ ] }),
907
+ dismissible ? /* @__PURE__ */ jsx(
908
+ "button",
909
+ {
910
+ type: "button",
911
+ className: "ansh-alert__close ansh-focusable",
912
+ "aria-label": "Dismiss message",
913
+ onClick: () => {
914
+ setVisible(false);
915
+ onDismiss?.();
916
+ },
917
+ children: /* @__PURE__ */ jsx("svg", { viewBox: "0 0 16 16", width: "12", height: "12", "aria-hidden": "true", children: /* @__PURE__ */ jsx(
918
+ "path",
919
+ {
920
+ d: "M4 4l8 8M12 4l-8 8",
921
+ stroke: "currentColor",
922
+ strokeWidth: "1.75",
923
+ strokeLinecap: "round",
924
+ fill: "none"
925
+ }
926
+ ) })
927
+ }
928
+ ) : null
929
+ ]
930
+ }
931
+ );
932
+ }
933
+ function Banner({ sticky = false, className, ...rest }) {
934
+ return /* @__PURE__ */ jsx(
935
+ Alert,
936
+ {
937
+ variant: "solid",
938
+ className: cx("ansh-banner", sticky && "ansh-banner--sticky", className),
939
+ ...rest
940
+ }
941
+ );
942
+ }
943
+ function Callout({ label, tone = "info", icon, className, children }) {
944
+ return /* @__PURE__ */ jsxs("aside", { className: cx("ansh-callout", `ansh-callout--${tone}`, className), children: [
945
+ /* @__PURE__ */ jsx("span", { className: "ansh-callout__icon", "aria-hidden": "true", children: icon ?? ICONS[tone] }),
946
+ /* @__PURE__ */ jsxs("div", { className: "ansh-callout__body", children: [
947
+ label ? /* @__PURE__ */ jsx("p", { className: "ansh-callout__label", children: label }) : null,
948
+ /* @__PURE__ */ jsx("div", { className: "ansh-callout__content", children })
949
+ ] })
950
+ ] });
951
+ }
952
+ var VERSION = "0.1.0";
953
+
954
+ export { Alert, AnimatedGradient, AuroraBackground, Banner, BentoGrid, BentoItem, Button, Callout, Constellation, Dock, FAQAccordion, Fireflies, GlowCard, IconButton, LiquidBlob, LoadingDots, MeshGradient, MeteorShower, NoiseLayer, NumberTicker, ParticleField, PricingTable, Rain, ShinyText, Skeleton, Snow, Spinner, Spotlight, SpotlightCard, TiltCard3D, ToastProvider, Typewriter, VERSION, Waves, createEffectComponent, useToast };
955
+ //# sourceMappingURL=index.js.map
956
+ //# sourceMappingURL=index.js.map