@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
@@ -0,0 +1,718 @@
1
+ 'use strict';
2
+
3
+ var chunk6VRF7X5C_cjs = require('./chunk-6VRF7X5C.cjs');
4
+ var chunkSFU5EPSN_cjs = require('./chunk-SFU5EPSN.cjs');
5
+ var react = require('react');
6
+ var core = require('@ansh-ui/core');
7
+ var jsxRuntime = require('react/jsx-runtime');
8
+ var tokens = require('@ansh-ui/tokens');
9
+
10
+ function createBehaviourComponent(definition, displayName, defaultElement = "div") {
11
+ const optionKeys = new Set(Object.keys(definition.defaults));
12
+ function Render(props, forwardedRef) {
13
+ const { as: Component2 = defaultElement, className, style, children, ...rest } = props;
14
+ const hostRef = react.useRef(null);
15
+ const handleRef = react.useRef(null);
16
+ const mergedRef = chunk6VRF7X5C_cjs.useMergedRef(hostRef, forwardedRef);
17
+ const options = {};
18
+ const domProps = {};
19
+ for (const [key, value] of Object.entries(rest)) {
20
+ if (optionKeys.has(key)) options[key] = value;
21
+ else domProps[key] = value;
22
+ }
23
+ const optionsKey = stableKey(options);
24
+ const optionsRef = react.useRef(options);
25
+ optionsRef.current = options;
26
+ react.useEffect(() => {
27
+ const host = hostRef.current;
28
+ if (!host) return;
29
+ const handle = core.mountBehaviour(definition, host, optionsRef.current);
30
+ handleRef.current = handle;
31
+ return () => {
32
+ handle.destroy();
33
+ handleRef.current = null;
34
+ };
35
+ }, []);
36
+ react.useEffect(() => {
37
+ handleRef.current?.update(optionsRef.current);
38
+ }, [optionsKey]);
39
+ return /* @__PURE__ */ jsxRuntime.jsx(Component2, { ref: mergedRef, className, style, ...domProps, children });
40
+ }
41
+ const Component = react.forwardRef(Render);
42
+ Component.displayName = displayName ?? `Ansh(${definition.name})`;
43
+ return Component;
44
+ }
45
+ function stableKey(options) {
46
+ const keys = Object.keys(options).sort();
47
+ const parts = [];
48
+ for (const key of keys) {
49
+ const value = options[key];
50
+ if (typeof value === "function") parts.push(`${key}:fn`);
51
+ else if (value === void 0) continue;
52
+ else parts.push(`${key}:${JSON.stringify(value)}`);
53
+ }
54
+ return parts.join("|");
55
+ }
56
+ function useBehaviour(ref, definition, options) {
57
+ const handleRef = react.useRef(null);
58
+ const optionsRef = react.useRef(options ?? {});
59
+ optionsRef.current = options ?? {};
60
+ const optionsKey = stableKey(optionsRef.current);
61
+ react.useEffect(() => {
62
+ const element = ref.current;
63
+ if (!element) return;
64
+ const handle = core.mountBehaviour(definition, element, optionsRef.current);
65
+ handleRef.current = handle;
66
+ return () => {
67
+ handle.destroy();
68
+ handleRef.current = null;
69
+ };
70
+ }, [definition, ref]);
71
+ react.useEffect(() => {
72
+ handleRef.current?.update(optionsRef.current);
73
+ }, [optionsKey]);
74
+ }
75
+ var MagneticButton = createBehaviourComponent(core.magnetic, "MagneticButton", "button");
76
+ var TiltCard = createBehaviourComponent(core.tilt, "TiltCard", "div");
77
+ var Ripple = createBehaviourComponent(core.ripple, "Ripple", "div");
78
+ var Marquee = createBehaviourComponent(core.marquee, "Marquee", "div");
79
+ var ScrollReveal = createBehaviourComponent(core.scrollReveal, "ScrollReveal", "div");
80
+ var Parallax = createBehaviourComponent(core.parallax, "Parallax", "div");
81
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? react.useLayoutEffect : react.useEffect;
82
+ var VISUALLY_HIDDEN = {
83
+ position: "absolute",
84
+ width: 1,
85
+ height: 1,
86
+ padding: 0,
87
+ margin: -1,
88
+ overflow: "hidden",
89
+ clipPath: "inset(50%)",
90
+ whiteSpace: "nowrap",
91
+ borderWidth: 0
92
+ };
93
+ function GradientText({
94
+ children,
95
+ colors,
96
+ angle = 100,
97
+ duration = 0,
98
+ stops = 16,
99
+ as: Component = "span",
100
+ className,
101
+ style
102
+ }) {
103
+ const gradientCss = react.useMemo(() => {
104
+ const palette = core.resolvePalette(colors);
105
+ const looped = duration > 0 ? [...palette, ...palette] : palette;
106
+ return core.createGradient(looped, { space: "oklab" }).toCss(`${angle}deg`, stops);
107
+ }, [colors, angle, duration, stops]);
108
+ const animated = duration > 0 && !core.prefersReducedMotion();
109
+ return /* @__PURE__ */ jsxRuntime.jsxs(
110
+ Component,
111
+ {
112
+ className,
113
+ style: {
114
+ backgroundImage: gradientCss,
115
+ backgroundSize: animated ? "200% 100%" : "100% 100%",
116
+ backgroundClip: "text",
117
+ WebkitBackgroundClip: "text",
118
+ color: "transparent",
119
+ // A fallback for the rare engine without background-clip support: the first colour still
120
+ // renders as solid text rather than the content vanishing entirely.
121
+ WebkitTextFillColor: "transparent",
122
+ display: "inline-block",
123
+ ...animated ? {
124
+ animation: `ansh-gradient-shift ${duration}s linear infinite`
125
+ } : {},
126
+ ...style
127
+ },
128
+ children: [
129
+ children,
130
+ animated ? /* @__PURE__ */ jsxRuntime.jsx(GradientKeyframes, {}) : null
131
+ ]
132
+ }
133
+ );
134
+ }
135
+ function GradientKeyframes() {
136
+ return /* @__PURE__ */ jsxRuntime.jsx(
137
+ "style",
138
+ {
139
+ dangerouslySetInnerHTML: {
140
+ __html: "@keyframes ansh-gradient-shift{from{background-position:0% 50%}to{background-position:200% 50%}}"
141
+ }
142
+ }
143
+ );
144
+ }
145
+ function AnimatedText({
146
+ children,
147
+ by = "chars",
148
+ duration = 0.6,
149
+ each = 0.03,
150
+ from = "first",
151
+ easing = "cinematic",
152
+ distance = 18,
153
+ blur = 0,
154
+ rotate = 0,
155
+ mask = false,
156
+ whenInView = true,
157
+ repeat = false,
158
+ delay = 0,
159
+ as: Component = "span",
160
+ className,
161
+ style,
162
+ onComplete
163
+ }) {
164
+ const hostRef = react.useRef(null);
165
+ const unitRefs = react.useRef([]);
166
+ const onCompleteRef = react.useRef(onComplete);
167
+ onCompleteRef.current = onComplete;
168
+ const units = react.useMemo(() => {
169
+ if (by === "words") {
170
+ return children.split(/(\s+)/).filter((token) => token.length > 0).map((token) => ({ text: token, space: /^\s+$/.test(token) }));
171
+ }
172
+ const graphemes = typeof Intl !== "undefined" && "Segmenter" in Intl ? Array.from(
173
+ new Intl.Segmenter(void 0, { granularity: "grapheme" }).segment(children),
174
+ (s) => s.segment
175
+ ) : Array.from(children);
176
+ return graphemes.map((character) => ({ text: character, space: /^\s$/.test(character) }));
177
+ }, [children, by]);
178
+ const animatedCount = react.useMemo(() => units.filter((u) => !u.space).length, [units]);
179
+ useIsomorphicLayoutEffect(() => {
180
+ const host = hostRef.current;
181
+ if (!host) return;
182
+ if (core.prefersReducedMotion()) {
183
+ onCompleteRef.current?.();
184
+ return;
185
+ }
186
+ const ease = core.resolveEasing(easing);
187
+ const delayFor = core.stagger(animatedCount, { each, from });
188
+ const ticker = core.getTicker();
189
+ const targets = [];
190
+ let animationIndex = 0;
191
+ units.forEach((unit, i) => {
192
+ if (unit.space) return;
193
+ const node = unitRefs.current[i];
194
+ if (node) targets.push({ node, delay: delay + delayFor(animationIndex) });
195
+ animationIndex++;
196
+ });
197
+ const apply = (node, progress) => {
198
+ const eased = ease(progress);
199
+ const inverse = 1 - eased;
200
+ node.style.opacity = String(eased);
201
+ const parts = [`translate3d(0, ${(distance * inverse).toFixed(2)}px, 0)`];
202
+ if (rotate !== 0) parts.push(`rotate(${(rotate * inverse).toFixed(2)}deg)`);
203
+ node.style.transform = parts.join(" ");
204
+ if (blur > 0) {
205
+ const amount = blur * inverse;
206
+ node.style.filter = amount > 0.05 ? `blur(${amount.toFixed(2)}px)` : "";
207
+ }
208
+ };
209
+ const reset = () => {
210
+ for (const { node } of targets) apply(node, 0);
211
+ };
212
+ const settle = (node) => {
213
+ node.style.opacity = "";
214
+ node.style.transform = "";
215
+ node.style.filter = "";
216
+ node.style.willChange = "";
217
+ };
218
+ let elapsed = 0;
219
+ let running = false;
220
+ let stopTicker = null;
221
+ const start = () => {
222
+ if (running) return;
223
+ running = true;
224
+ elapsed = 0;
225
+ for (const { node } of targets) node.style.willChange = "opacity, transform";
226
+ reset();
227
+ stopTicker = ticker.add(
228
+ ({ delta }) => {
229
+ elapsed += delta;
230
+ let allDone = true;
231
+ for (const target of targets) {
232
+ const local = elapsed - target.delay;
233
+ if (local < 0) {
234
+ allDone = false;
235
+ continue;
236
+ }
237
+ const progress = duration <= 0 ? 1 : local / duration;
238
+ if (progress >= 1) {
239
+ settle(target.node);
240
+ continue;
241
+ }
242
+ apply(target.node, progress);
243
+ allDone = false;
244
+ }
245
+ if (allDone) {
246
+ stopTicker?.();
247
+ stopTicker = null;
248
+ running = false;
249
+ onCompleteRef.current?.();
250
+ }
251
+ },
252
+ { phase: "write", name: "AnimatedText" }
253
+ );
254
+ };
255
+ if (!whenInView) {
256
+ reset();
257
+ start();
258
+ return () => {
259
+ stopTicker?.();
260
+ for (const { node } of targets) settle(node);
261
+ };
262
+ }
263
+ reset();
264
+ const stopObserver = core.observeIntersection(
265
+ host,
266
+ (entry) => {
267
+ if (entry.isIntersecting) {
268
+ start();
269
+ } else if (repeat) {
270
+ stopTicker?.();
271
+ stopTicker = null;
272
+ running = false;
273
+ reset();
274
+ }
275
+ },
276
+ { threshold: 0.2, rootMargin: "0px 0px -8% 0px" }
277
+ );
278
+ return () => {
279
+ stopObserver();
280
+ stopTicker?.();
281
+ for (const { node } of targets) settle(node);
282
+ };
283
+ }, [
284
+ units,
285
+ animatedCount,
286
+ duration,
287
+ each,
288
+ from,
289
+ easing,
290
+ distance,
291
+ blur,
292
+ rotate,
293
+ whenInView,
294
+ repeat,
295
+ delay
296
+ ]);
297
+ return /* @__PURE__ */ jsxRuntime.jsxs(Component, { ref: hostRef, className, style: { display: "inline-block", ...style }, children: [
298
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: VISUALLY_HIDDEN, children }),
299
+ /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: units.map(
300
+ (unit, i) => unit.space ? (
301
+ // Whitespace as a plain text node so it collapses and wraps like real text.
302
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: unit.text }, i)
303
+ ) : mask ? /* @__PURE__ */ jsxRuntime.jsx(
304
+ "span",
305
+ {
306
+ style: { display: "inline-block", overflow: "hidden", verticalAlign: "top" },
307
+ children: /* @__PURE__ */ jsxRuntime.jsx(
308
+ "span",
309
+ {
310
+ ref: (node) => {
311
+ unitRefs.current[i] = node;
312
+ },
313
+ style: { display: "inline-block" },
314
+ children: unit.text
315
+ }
316
+ )
317
+ },
318
+ i
319
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
320
+ "span",
321
+ {
322
+ ref: (node) => {
323
+ unitRefs.current[i] = node;
324
+ },
325
+ style: { display: "inline-block" },
326
+ children: unit.text
327
+ },
328
+ i
329
+ )
330
+ ) })
331
+ ] });
332
+ }
333
+ var MotionConfigContext = react.createContext({
334
+ reducedMotion: "auto",
335
+ timeScale: 1,
336
+ quality: null
337
+ });
338
+ function MotionConfig({
339
+ reducedMotion = "auto",
340
+ timeScale = 1,
341
+ quality = null,
342
+ pauseWhenHidden = true,
343
+ pauseWhenBlurred = false,
344
+ respectBattery = true,
345
+ children
346
+ }) {
347
+ react.useEffect(() => {
348
+ core.setReducedMotionMode(reducedMotion);
349
+ }, [reducedMotion]);
350
+ react.useEffect(() => {
351
+ core.getTicker().timeScale = timeScale;
352
+ }, [timeScale]);
353
+ react.useEffect(() => {
354
+ if (quality !== null) core.getTicker().lockQuality(quality);
355
+ }, [quality]);
356
+ react.useEffect(
357
+ () => core.attachLifecycle(core.getTicker(), {
358
+ pauseWhenHidden,
359
+ pauseWhenBlurred,
360
+ respectBattery
361
+ }),
362
+ [pauseWhenHidden, pauseWhenBlurred, respectBattery]
363
+ );
364
+ const value = react.useMemo(
365
+ () => ({ reducedMotion, timeScale, quality }),
366
+ [reducedMotion, timeScale, quality]
367
+ );
368
+ return /* @__PURE__ */ jsxRuntime.jsx(MotionConfigContext.Provider, { value, children });
369
+ }
370
+ function useMotionConfig() {
371
+ return react.useContext(MotionConfigContext);
372
+ }
373
+ var ThemeContext = react.createContext({
374
+ theme: "system",
375
+ resolved: "light",
376
+ setTheme: () => {
377
+ }
378
+ });
379
+ function ThemeProvider({
380
+ defaultTheme = "system",
381
+ storageKey = "ansh-theme",
382
+ children
383
+ }) {
384
+ const [theme, setThemeState] = react.useState(defaultTheme);
385
+ const [resolved, setResolved] = react.useState("light");
386
+ react.useEffect(() => {
387
+ if (!storageKey) return;
388
+ try {
389
+ const stored = localStorage.getItem(storageKey);
390
+ if (stored === "light" || stored === "dark" || stored === "system") {
391
+ setThemeState(stored);
392
+ }
393
+ } catch {
394
+ }
395
+ }, [storageKey]);
396
+ react.useEffect(() => {
397
+ tokens.applyTheme(theme);
398
+ setResolved(tokens.resolveTheme());
399
+ if (storageKey) {
400
+ try {
401
+ localStorage.setItem(storageKey, theme);
402
+ } catch {
403
+ }
404
+ }
405
+ }, [theme, storageKey]);
406
+ react.useEffect(() => {
407
+ if (theme !== "system" || typeof matchMedia !== "function") return;
408
+ const query = matchMedia("(prefers-color-scheme: dark)");
409
+ const onChange = () => setResolved(query.matches ? "dark" : "light");
410
+ query.addEventListener("change", onChange);
411
+ return () => query.removeEventListener("change", onChange);
412
+ }, [theme]);
413
+ const value = react.useMemo(() => ({ theme, resolved, setTheme: setThemeState }), [theme, resolved]);
414
+ return /* @__PURE__ */ jsxRuntime.jsx(ThemeContext.Provider, { value, children });
415
+ }
416
+ function useTheme() {
417
+ return react.useContext(ThemeContext);
418
+ }
419
+ function themeScript(storageKey = "ansh-theme") {
420
+ return `(function(){try{var t=localStorage.getItem(${JSON.stringify(storageKey)});if(t==='light'||t==='dark'){document.documentElement.setAttribute('data-theme',t)}}catch(e){}})()`;
421
+ }
422
+ var DEFAULTS = {
423
+ opacity: 1,
424
+ x: 0,
425
+ y: 0,
426
+ scale: 1,
427
+ scaleX: 1,
428
+ scaleY: 1,
429
+ rotate: 0,
430
+ blur: 0
431
+ };
432
+ function applyValues(node, values) {
433
+ const transform = `translate3d(${values.x}px, ${values.y}px, 0) scale(${values.scale * values.scaleX}, ${values.scale * values.scaleY}) rotate(${values.rotate}deg)`;
434
+ node.style.transform = transform;
435
+ node.style.opacity = String(values.opacity);
436
+ node.style.filter = values.blur > 0 ? `blur(${values.blur}px)` : "";
437
+ }
438
+ function resolve(values, base) {
439
+ return { ...base, ...values };
440
+ }
441
+ function Motion({
442
+ as: Component = "div",
443
+ initial,
444
+ animate: target,
445
+ // Destructured but unused here: `AnimatePresence` reads `exit` off the element's props when the
446
+ // child is removed and swaps it into `animate`. Pulling it out of `rest` stops it reaching the
447
+ // DOM as an unknown attribute.
448
+ exit: _exit,
449
+ transition,
450
+ whileHover,
451
+ whileTap,
452
+ whileInView = false,
453
+ inViewAmount = 0.2,
454
+ className,
455
+ style,
456
+ children,
457
+ ...rest
458
+ }) {
459
+ const nodeRef = react.useRef(null);
460
+ const currentRef = react.useRef(resolve(initial, DEFAULTS));
461
+ const controlsRef = react.useRef(null);
462
+ const [inView, setInView] = react.useState(!whileInView);
463
+ react.useLayoutEffect(() => {
464
+ if (nodeRef.current) applyValues(nodeRef.current, currentRef.current);
465
+ }, []);
466
+ const runTo = react.useCallback(
467
+ (next, options) => {
468
+ const node = nodeRef.current;
469
+ if (!node) return;
470
+ controlsRef.current?.stop();
471
+ const from = { ...currentRef.current };
472
+ const springOption = options?.spring ?? transition?.spring;
473
+ const animationOptions = {
474
+ ...options?.delay ?? transition?.delay !== void 0 ? { delay: options?.delay ?? transition?.delay ?? 0 } : null,
475
+ ...springOption ? {
476
+ spring: springOption === true ? core.springs.default : typeof springOption === "string" ? core.springs[springOption] : springOption
477
+ } : {
478
+ duration: options?.duration ?? transition?.duration ?? 0.4,
479
+ ...options?.easing ?? transition?.easing ? { easing: options?.easing ?? transition?.easing } : null
480
+ },
481
+ onUpdate: (t) => {
482
+ const frame = {};
483
+ for (const key of Object.keys(DEFAULTS)) {
484
+ frame[key] = from[key] + (next[key] - from[key]) * t;
485
+ }
486
+ currentRef.current = frame;
487
+ applyValues(node, frame);
488
+ },
489
+ onComplete: () => {
490
+ currentRef.current = next;
491
+ applyValues(node, next);
492
+ }
493
+ };
494
+ controlsRef.current = core.animate(0, 1, animationOptions);
495
+ },
496
+ [transition]
497
+ );
498
+ const targetKey = JSON.stringify(target ?? null);
499
+ react.useEffect(() => {
500
+ if (!inView) return;
501
+ runTo(resolve(target, DEFAULTS));
502
+ }, [targetKey, inView, runTo]);
503
+ react.useEffect(() => {
504
+ if (!whileInView) return;
505
+ const node = nodeRef.current;
506
+ if (!node || typeof IntersectionObserver === "undefined") {
507
+ setInView(true);
508
+ return;
509
+ }
510
+ const observer = new IntersectionObserver(
511
+ ([entry]) => {
512
+ if (entry?.isIntersecting) {
513
+ setInView(true);
514
+ observer.disconnect();
515
+ }
516
+ },
517
+ { threshold: inViewAmount }
518
+ );
519
+ observer.observe(node);
520
+ return () => observer.disconnect();
521
+ }, [whileInView, inViewAmount]);
522
+ react.useEffect(() => () => controlsRef.current?.stop(), []);
523
+ const interaction = {};
524
+ if (whileHover) {
525
+ interaction.onMouseEnter = () => runTo(resolve({ ...target, ...whileHover }, DEFAULTS));
526
+ interaction.onMouseLeave = () => runTo(resolve(target, DEFAULTS));
527
+ }
528
+ if (whileTap) {
529
+ interaction.onPointerDown = () => runTo(resolve({ ...target, ...whileTap }, DEFAULTS), { duration: 0.12 });
530
+ interaction.onPointerUp = () => runTo(resolve({ ...target, ...whileHover }, DEFAULTS));
531
+ }
532
+ return /* @__PURE__ */ jsxRuntime.jsx(
533
+ Component,
534
+ {
535
+ ref: nodeRef,
536
+ className,
537
+ style: { willChange: "transform, opacity", ...style },
538
+ ...interaction,
539
+ ...rest,
540
+ children
541
+ }
542
+ );
543
+ }
544
+ function AnimatePresence({ children, exitDuration = 0.35 }) {
545
+ const currentChildren = react.Children.toArray(children).filter(react.isValidElement);
546
+ const [rendered, setRendered] = react.useState(currentChildren);
547
+ const timersRef = react.useRef(/* @__PURE__ */ new Map());
548
+ const keys = currentChildren.map((child) => String(child.key));
549
+ const keysSignature = keys.join("|");
550
+ react.useEffect(() => {
551
+ const currentKeys2 = new Set(keys);
552
+ const departing = rendered.filter((child) => !currentKeys2.has(String(child.key)));
553
+ if (departing.length === 0) {
554
+ setRendered(currentChildren);
555
+ return;
556
+ }
557
+ setRendered([...currentChildren, ...departing]);
558
+ const delay = core.prefersReducedMotion() ? 0 : exitDuration * 1e3;
559
+ for (const child of departing) {
560
+ const key = String(child.key);
561
+ clearTimeout(timersRef.current.get(key));
562
+ timersRef.current.set(
563
+ key,
564
+ setTimeout(() => {
565
+ setRendered((previous) => previous.filter((entry) => String(entry.key) !== key));
566
+ timersRef.current.delete(key);
567
+ }, delay)
568
+ );
569
+ }
570
+ }, [keysSignature, exitDuration]);
571
+ react.useEffect(() => {
572
+ const timers = timersRef.current;
573
+ return () => {
574
+ for (const timer of timers.values()) clearTimeout(timer);
575
+ timers.clear();
576
+ };
577
+ }, []);
578
+ const currentKeys = new Set(keys);
579
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: rendered.map((child) => {
580
+ const leaving = !currentKeys.has(String(child.key));
581
+ if (!leaving) return child;
582
+ const props = child.props;
583
+ return react.cloneElement(child, {
584
+ animate: props.exit ?? { opacity: 0, scale: 0.96 },
585
+ transition: { duration: exitDuration, ...props.transition }
586
+ });
587
+ }) });
588
+ }
589
+ function Draggable({
590
+ axis = "both",
591
+ bounds,
592
+ snapBack = false,
593
+ momentum,
594
+ onDragStart,
595
+ onDragEnd,
596
+ className,
597
+ style,
598
+ children
599
+ }) {
600
+ const nodeRef = react.useRef(null);
601
+ const offsetRef = react.useRef({ x: 0, y: 0 });
602
+ const [dragging, setDragging] = react.useState(false);
603
+ const useMomentum = momentum ?? !snapBack;
604
+ const clamp = react.useCallback(
605
+ (value) => ({
606
+ x: Math.min(Math.max(value.x, bounds?.left ?? -Infinity), bounds?.right ?? Infinity),
607
+ y: Math.min(Math.max(value.y, bounds?.top ?? -Infinity), bounds?.bottom ?? Infinity)
608
+ }),
609
+ [bounds]
610
+ );
611
+ const write = (value) => {
612
+ if (nodeRef.current) {
613
+ nodeRef.current.style.transform = `translate3d(${value.x}px, ${value.y}px, 0)`;
614
+ }
615
+ };
616
+ const onPointerDown = (event) => {
617
+ event.currentTarget.setPointerCapture(event.pointerId);
618
+ setDragging(true);
619
+ onDragStart?.();
620
+ const start = { x: event.clientX, y: event.clientY };
621
+ const origin = { ...offsetRef.current };
622
+ const samples = [];
623
+ const onMove = (moveEvent) => {
624
+ const next = clamp({
625
+ x: axis === "y" ? origin.x : origin.x + (moveEvent.clientX - start.x),
626
+ y: axis === "x" ? origin.y : origin.y + (moveEvent.clientY - start.y)
627
+ });
628
+ offsetRef.current = next;
629
+ write(next);
630
+ samples.push({ x: next.x, y: next.y, t: performance.now() });
631
+ if (samples.length > 5) samples.shift();
632
+ };
633
+ const onUp = () => {
634
+ setDragging(false);
635
+ window.removeEventListener("pointermove", onMove);
636
+ window.removeEventListener("pointerup", onUp);
637
+ window.removeEventListener("pointercancel", onUp);
638
+ if (snapBack) {
639
+ core.animate(0, 1, {
640
+ spring: core.springs.subtle,
641
+ onUpdate: (t) => {
642
+ const value = { x: offsetRef.current.x * (1 - t), y: offsetRef.current.y * (1 - t) };
643
+ write(value);
644
+ },
645
+ onComplete: () => {
646
+ offsetRef.current = { x: 0, y: 0 };
647
+ write(offsetRef.current);
648
+ onDragEnd?.(offsetRef.current);
649
+ }
650
+ });
651
+ return;
652
+ }
653
+ if (useMomentum && samples.length >= 2) {
654
+ const first = samples[0];
655
+ const last = samples[samples.length - 1];
656
+ const elapsed = Math.max(1, last.t - first.t);
657
+ let velocity = {
658
+ x: (last.x - first.x) / elapsed * 1e3,
659
+ y: (last.y - first.y) / elapsed * 1e3
660
+ };
661
+ const decay = 0.95;
662
+ const stop = core.getTicker().add(
663
+ ({ delta }) => {
664
+ const factor = Math.pow(decay, delta * 60);
665
+ velocity = { x: velocity.x * factor, y: velocity.y * factor };
666
+ const next = clamp({
667
+ x: offsetRef.current.x + velocity.x * delta,
668
+ y: offsetRef.current.y + velocity.y * delta
669
+ });
670
+ offsetRef.current = next;
671
+ write(next);
672
+ if (Math.hypot(velocity.x, velocity.y) < 8) {
673
+ stop();
674
+ onDragEnd?.(offsetRef.current);
675
+ }
676
+ },
677
+ { phase: "write", name: "Draggable" }
678
+ );
679
+ return;
680
+ }
681
+ onDragEnd?.(offsetRef.current);
682
+ };
683
+ window.addEventListener("pointermove", onMove);
684
+ window.addEventListener("pointerup", onUp);
685
+ window.addEventListener("pointercancel", onUp);
686
+ };
687
+ return /* @__PURE__ */ jsxRuntime.jsx(
688
+ "div",
689
+ {
690
+ ref: nodeRef,
691
+ className: chunkSFU5EPSN_cjs.cx("ansh-draggable", dragging && "ansh-draggable--active", className),
692
+ style: { touchAction: axis === "x" ? "pan-y" : axis === "y" ? "pan-x" : "none", ...style },
693
+ onPointerDown,
694
+ children
695
+ }
696
+ );
697
+ }
698
+
699
+ exports.AnimatePresence = AnimatePresence;
700
+ exports.AnimatedText = AnimatedText;
701
+ exports.Draggable = Draggable;
702
+ exports.GradientText = GradientText;
703
+ exports.MagneticButton = MagneticButton;
704
+ exports.Marquee = Marquee;
705
+ exports.Motion = Motion;
706
+ exports.MotionConfig = MotionConfig;
707
+ exports.Parallax = Parallax;
708
+ exports.Ripple = Ripple;
709
+ exports.ScrollReveal = ScrollReveal;
710
+ exports.ThemeProvider = ThemeProvider;
711
+ exports.TiltCard = TiltCard;
712
+ exports.createBehaviourComponent = createBehaviourComponent;
713
+ exports.themeScript = themeScript;
714
+ exports.useBehaviour = useBehaviour;
715
+ exports.useMotionConfig = useMotionConfig;
716
+ exports.useTheme = useTheme;
717
+ //# sourceMappingURL=chunk-AVPEA5PB.cjs.map
718
+ //# sourceMappingURL=chunk-AVPEA5PB.cjs.map