@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,169 @@
1
+ import * as react from 'react';
2
+ import { HTMLAttributes, ElementType, ReactNode, CSSProperties } from 'react';
3
+ export { A as AppShell, a as AppShellProps, N as NavItem, b as NavSection, S as Sidebar, c as SidebarProps } from './sidebar-D-PafAXw.js';
4
+
5
+ /**
6
+ * Layout primitives.
7
+ *
8
+ * These exist because every application rebuilds them, badly. The rebuilt versions hardcode gaps in
9
+ * pixels, so they don't respond to a density setting; they use margins, so they collapse
10
+ * unpredictably; and they don't handle the RTL case.
11
+ *
12
+ * Everything here takes a **token key**, not a raw value: `gap={4}` means `--ansh-space-4`, so a
13
+ * layout is guaranteed to sit on the spacing scale. Passing an arbitrary string is still possible
14
+ * for the genuine one-off, but the type nudges toward the scale first.
15
+ */
16
+ /** A key into the spacing scale, or a raw CSS length for the rare exception. */
17
+ type SpaceToken = 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 12 | 16 | 20 | 24 | (string & {});
18
+ interface BaseProps extends HTMLAttributes<HTMLElement> {
19
+ as?: ElementType;
20
+ children?: ReactNode;
21
+ }
22
+ interface StackProps extends BaseProps {
23
+ /** Default `'vertical'` — the direction that needs a helper more often. */
24
+ direction?: 'horizontal' | 'vertical';
25
+ gap?: SpaceToken;
26
+ align?: CSSProperties['alignItems'];
27
+ justify?: CSSProperties['justifyContent'];
28
+ wrap?: boolean;
29
+ /** Grow to fill the cross axis. */
30
+ stretch?: boolean;
31
+ /** Insert a hairline divider between children. */
32
+ divide?: boolean;
33
+ }
34
+ /**
35
+ * One-dimensional flex layout.
36
+ *
37
+ * ```tsx
38
+ * <Stack direction="horizontal" gap={3} align="center">
39
+ * <Avatar src={user.avatar} name={user.name} />
40
+ * <Stack gap={0.5}>
41
+ * <strong>{user.name}</strong>
42
+ * <Text tone="secondary">{user.email}</Text>
43
+ * </Stack>
44
+ * </Stack>
45
+ * ```
46
+ */
47
+ declare const Stack: react.ForwardRefExoticComponent<StackProps & react.RefAttributes<HTMLElement>>;
48
+ /** Horizontal `Stack`, for readability at call sites. */
49
+ declare const HStack: react.ForwardRefExoticComponent<StackProps & react.RefAttributes<HTMLElement>>;
50
+ /** Vertical `Stack`, for symmetry with `HStack`. */
51
+ declare const VStack: react.ForwardRefExoticComponent<StackProps & react.RefAttributes<HTMLElement>>;
52
+ interface GridProps extends BaseProps {
53
+ /** Fixed column count, or `'auto'` for a responsive `auto-fill` track. */
54
+ columns?: number | 'auto';
55
+ /** Minimum column width when `columns="auto"`. Default `'16rem'`. */
56
+ minColumnWidth?: string;
57
+ gap?: SpaceToken;
58
+ /** Row gap, when it should differ from the column gap. */
59
+ rowGap?: SpaceToken;
60
+ align?: CSSProperties['alignItems'];
61
+ }
62
+ /**
63
+ * Two-dimensional layout.
64
+ *
65
+ * `columns="auto"` uses `repeat(auto-fill, minmax(min(N, 100%), 1fr))`. The inner `min()` is what
66
+ * stops the grid overflowing on a phone: without it, a 16rem minimum on a 15rem-wide viewport
67
+ * produces a track wider than the screen and a horizontal scrollbar.
68
+ */
69
+ declare const Grid: react.ForwardRefExoticComponent<GridProps & react.RefAttributes<HTMLElement>>;
70
+ interface GridItemProps extends BaseProps {
71
+ /** Columns to span. `'full'` spans the whole row. */
72
+ span?: number | 'full';
73
+ rowSpan?: number;
74
+ }
75
+ declare const GridItem: react.ForwardRefExoticComponent<GridItemProps & react.RefAttributes<HTMLElement>>;
76
+ interface ContainerProps extends BaseProps {
77
+ /** Max content width. Default `'lg'` (72rem). */
78
+ size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';
79
+ /** Horizontal padding. Default `6`. */
80
+ padding?: SpaceToken;
81
+ }
82
+ /** Centred, width-constrained page content. */
83
+ declare const Container: react.ForwardRefExoticComponent<ContainerProps & react.RefAttributes<HTMLElement>>;
84
+ interface DividerProps extends Omit<BaseProps, 'children'> {
85
+ orientation?: 'horizontal' | 'vertical';
86
+ /** Optional label rendered in the middle of the rule. */
87
+ label?: ReactNode;
88
+ }
89
+ /**
90
+ * A rule.
91
+ *
92
+ * With a label it becomes a labelled separator — the "or continue with" divider on a sign-in form.
93
+ * `role="separator"` is set only when there's no label; with one, it's a heading-like element and
94
+ * announcing it as a separator loses the text.
95
+ */
96
+ declare const Divider: react.ForwardRefExoticComponent<DividerProps & react.RefAttributes<HTMLDivElement>>;
97
+ interface SpacerProps {
98
+ size?: SpaceToken;
99
+ /** Grow to absorb free space in a flex container. */
100
+ grow?: boolean;
101
+ }
102
+ /** Explicit empty space. `grow` pushes siblings apart in a flex row. */
103
+ declare function Spacer({ size, grow }: SpacerProps): react.JSX.Element;
104
+ /** Centre a child on both axes. */
105
+ declare const Center: react.ForwardRefExoticComponent<BaseProps & react.RefAttributes<HTMLElement>>;
106
+ interface AspectRatioProps extends BaseProps {
107
+ /** Width ÷ height. `16 / 9` reads better than `1.777`. Default `16 / 9`. */
108
+ ratio?: number;
109
+ }
110
+ /**
111
+ * Reserve space at a fixed aspect ratio.
112
+ *
113
+ * Uses the `aspect-ratio` property rather than the padding-top hack. The reserved space is what
114
+ * matters: an image that loads without it shifts everything below, which is a Cumulative Layout
115
+ * Shift penalty and the most common cause of a failing Core Web Vitals score.
116
+ */
117
+ declare const AspectRatio: react.ForwardRefExoticComponent<AspectRatioProps & react.RefAttributes<HTMLElement>>;
118
+ interface ScrollAreaProps extends BaseProps {
119
+ /** Max height before scrolling starts. */
120
+ maxHeight?: string;
121
+ axis?: 'y' | 'x' | 'both';
122
+ /** Fade the content at the scrollable edges. Default `true`. */
123
+ fade?: boolean;
124
+ }
125
+ /**
126
+ * A scroll container with styled scrollbars and edge fades.
127
+ *
128
+ * The native scrollbar is kept — a JavaScript-rendered one breaks keyboard scrolling, mobile
129
+ * momentum, and the OS "scroll bar is always visible" accessibility setting. It is only *styled*,
130
+ * via `scrollbar-width`/`scrollbar-color` with a `::-webkit-scrollbar` fallback.
131
+ *
132
+ * The edge fade is a mask that appears only when there is more content in that direction. It is
133
+ * driven by `animation-timeline: scroll()` where supported, so it costs nothing on the main thread
134
+ * and degrades to no fade where it isn't.
135
+ */
136
+ declare const ScrollArea: react.ForwardRefExoticComponent<ScrollAreaProps & react.RefAttributes<HTMLElement>>;
137
+
138
+ interface ResizableProps {
139
+ /** Exactly two children: the two panes. */
140
+ children: [ReactNode, ReactNode];
141
+ direction?: 'horizontal' | 'vertical';
142
+ /** First pane's size as a percentage, `0`–`100`. Default `50`. */
143
+ defaultSize?: number;
144
+ size?: number;
145
+ onSizeChange?: (size: number) => void;
146
+ /** Clamp, as percentages. Defaults `10` and `90`. */
147
+ minSize?: number;
148
+ maxSize?: number;
149
+ /** Snap points in percent, e.g. `[25, 50, 75]`. Within 3% the handle snaps. */
150
+ snapPoints?: readonly number[];
151
+ className?: string;
152
+ /** Accessible name for the handle — "Resize sidebar", not "Resize". */
153
+ label?: string;
154
+ }
155
+ /**
156
+ * A two-pane split with a draggable divider.
157
+ *
158
+ * The layout every IDE, mail client and admin console needs, and the one most often shipped as
159
+ * mouse-only. The handle here is a real `role="separator"` with `aria-valuenow`, and arrow keys
160
+ * move it in 2% steps — WAI-ARIA calls this a window splitter and it is a documented pattern, not
161
+ * an invention.
162
+ *
163
+ * Sizes are percentages rather than pixels so the split survives a window resize proportionally.
164
+ * Dragging writes to a CSS custom property directly, bypassing React: a re-render per pointer move
165
+ * makes the drag feel heavy on a complex page, and the value is only committed to state on release.
166
+ */
167
+ declare function Resizable({ children, direction, defaultSize, size, onSizeChange, minSize, maxSize, snapPoints, className, label, }: ResizableProps): react.JSX.Element;
168
+
169
+ export { AspectRatio, type AspectRatioProps, Center, Container, type ContainerProps, Divider, type DividerProps, Grid, GridItem, type GridItemProps, type GridProps, HStack, Resizable, type ResizableProps, ScrollArea, type ScrollAreaProps, type SpaceToken, Spacer, type SpacerProps, Stack, type StackProps, VStack };
package/dist/layout.js ADDED
@@ -0,0 +1,7 @@
1
+ 'use client';
2
+ export { AspectRatio, Center, Container, Divider, Grid, GridItem, HStack, Resizable, ScrollArea, Spacer, Stack, VStack } from './chunk-EGG4CP7C.js';
3
+ export { AppShell, Sidebar } from './chunk-5CFQFMP5.js';
4
+ import './chunk-LXCIXR5T.js';
5
+ import './chunk-H34OXXJU.js';
6
+ //# sourceMappingURL=layout.js.map
7
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"layout.js"}
@@ -0,0 +1,395 @@
1
+ import * as react from 'react';
2
+ import { ReactNode, CSSProperties, ElementType, ForwardRefExoticComponent, ComponentPropsWithoutRef, RefAttributes } from 'react';
3
+ import * as _ansh_ui_core from '@ansh-ui/core';
4
+ import { EasingInput, SpringOptions, springs, StaggerFrom, resolvePalette, BaseBehaviourOptions, BehaviourDefinition, ReducedMotionMode } from '@ansh-ui/core';
5
+ import './use-observers-B9qtimrk.js';
6
+
7
+ /**
8
+ * Declarative motion.
9
+ *
10
+ * A deliberately **small** subset of what a full motion library does: transform properties and
11
+ * opacity, animated from `initial` to `animate`, plus hover and press states and an exit animation
12
+ * when paired with `AnimatePresence`.
13
+ *
14
+ * That scope is a decision, not a gap. Layout animation (FLIP), shared-element transitions and
15
+ * variant propagation each need machinery an order of magnitude larger than this file, and a
16
+ * half-implementation of them is worse than none — it works in the demo and fails on the real page.
17
+ * For those, use a dedicated library; for the 90% case of "fade this in, slide that up, spring the
18
+ * card on hover", this costs a fraction of the bundle.
19
+ *
20
+ * Values are written straight to the element's `style` from the ticker's write phase. React never
21
+ * re-renders during an animation.
22
+ */
23
+ interface MotionValues {
24
+ opacity?: number;
25
+ x?: number;
26
+ y?: number;
27
+ scale?: number;
28
+ scaleX?: number;
29
+ scaleY?: number;
30
+ rotate?: number;
31
+ /** Blur radius in px. */
32
+ blur?: number;
33
+ }
34
+ interface MotionTransition {
35
+ /** Seconds. Ignored when `spring` is set. Default `0.4`. */
36
+ duration?: number;
37
+ /** Seconds to wait. Default `0`. */
38
+ delay?: number;
39
+ easing?: EasingInput;
40
+ /** Use a spring instead of a tween. `true` uses the `smooth` preset. */
41
+ spring?: boolean | SpringOptions | keyof typeof springs;
42
+ }
43
+ type MotionElementProps = {
44
+ as?: ElementType;
45
+ /** Starting values. Applied before the first paint. */
46
+ initial?: MotionValues;
47
+ /** Target values. Changing these animates to the new target. */
48
+ animate?: MotionValues;
49
+ /** Values to animate to when removed by `AnimatePresence`. */
50
+ exit?: MotionValues;
51
+ transition?: MotionTransition;
52
+ whileHover?: MotionValues;
53
+ whileTap?: MotionValues;
54
+ /** Animate to `animate` only once scrolled into view. */
55
+ whileInView?: boolean;
56
+ /** Fraction visible before `whileInView` triggers. Default `0.2`. */
57
+ inViewAmount?: number;
58
+ className?: string;
59
+ style?: CSSProperties;
60
+ children?: ReactNode;
61
+ };
62
+ /**
63
+ * An animated element.
64
+ *
65
+ * ```tsx
66
+ * <Motion initial={{ opacity: 0, y: 24 }} animate={{ opacity: 1, y: 0 }} whileInView>
67
+ * <Card />
68
+ * </Motion>
69
+ * ```
70
+ */
71
+ declare function Motion({ as: Component, initial, animate: target, exit: _exit, transition, whileHover, whileTap, whileInView, inViewAmount, className, style, children, ...rest }: MotionElementProps & Record<string, unknown>): react.JSX.Element;
72
+ interface AnimatePresenceProps {
73
+ children: ReactNode;
74
+ /** Seconds to keep a removed child mounted. Default `0.35`. */
75
+ exitDuration?: number;
76
+ }
77
+ /**
78
+ * Keep removed children mounted long enough to animate out.
79
+ *
80
+ * React unmounts immediately when a child disappears from the tree, so an exit animation never gets
81
+ * a chance to run. This holds departing children in its own state, plays their `exit` values, then
82
+ * drops them.
83
+ *
84
+ * Children **must** have stable `key`s — that is how removals are detected at all. Without keys,
85
+ * React reuses element positions and this sees no removal to animate.
86
+ */
87
+ declare function AnimatePresence({ children, exitDuration }: AnimatePresenceProps): react.JSX.Element;
88
+ interface DraggableProps {
89
+ /** Constrain movement. */
90
+ axis?: 'x' | 'y' | 'both';
91
+ /** Bounds relative to the starting position, in px. */
92
+ bounds?: {
93
+ left?: number;
94
+ right?: number;
95
+ top?: number;
96
+ bottom?: number;
97
+ };
98
+ /** Spring back to the origin on release. */
99
+ snapBack?: boolean;
100
+ /** Carry momentum after release. Default `true` when not snapping back. */
101
+ momentum?: boolean;
102
+ onDragStart?: () => void;
103
+ onDragEnd?: (offset: {
104
+ x: number;
105
+ y: number;
106
+ }) => void;
107
+ className?: string;
108
+ style?: CSSProperties;
109
+ children: ReactNode;
110
+ }
111
+ /**
112
+ * A draggable surface with inertia.
113
+ *
114
+ * The momentum on release is what separates a drag that feels physical from one that stops dead.
115
+ * Velocity is measured over the last few pointer samples rather than the last two — a single pair
116
+ * of events is dominated by whatever jitter the final sample had, which produces a flick in the
117
+ * wrong direction often enough to be noticeable.
118
+ */
119
+ declare function Draggable({ axis, bounds, snapBack, momentum, onDragStart, onDragEnd, className, style, children, }: DraggableProps): react.JSX.Element;
120
+
121
+ interface GradientTextProps {
122
+ children: string;
123
+ /** Any number of colours, or a built-in palette name. */
124
+ colors?: readonly string[] | Parameters<typeof resolvePalette>[0];
125
+ /** Gradient angle in degrees. Default `100`. */
126
+ angle?: number;
127
+ /** Seconds for one full cycle. `0` holds a static gradient. Default `0` (static). */
128
+ duration?: number;
129
+ /** Interpolated stops handed to CSS. More is smoother. Default `16`. */
130
+ stops?: number;
131
+ as?: ElementType;
132
+ className?: string;
133
+ style?: React.CSSProperties;
134
+ }
135
+ /**
136
+ * Text filled with a perceptual gradient.
137
+ *
138
+ * Uses `background-clip: text`, and the stops are generated through the OKLab interpolator rather
139
+ * than handed to CSS as two endpoints. That is the whole point: a CSS
140
+ * `linear-gradient(#0275f4, #9f0550)` passes through a desaturated grey-brown at its midpoint,
141
+ * which on text — where the gradient crosses a narrow band — is exactly where the eye lands.
142
+ *
143
+ * Animation is a CSS `background-position` shift rather than a JS loop, because for a single
144
+ * property with no interaction the browser's own compositor is strictly better than anything we
145
+ * could do on the main thread.
146
+ */
147
+ declare function GradientText({ children, colors, angle, duration, stops, as: Component, className, style, }: GradientTextProps): react.JSX.Element;
148
+ interface AnimatedTextProps {
149
+ children: string;
150
+ /** Split granularity. Default `'chars'`. */
151
+ by?: 'chars' | 'words';
152
+ /** Seconds per unit's animation. Default `0.6`. */
153
+ duration?: number;
154
+ /** Seconds between units. Default `0.03`. */
155
+ each?: number;
156
+ /** Where the reveal wave begins. Default `'first'`. */
157
+ from?: StaggerFrom;
158
+ easing?: EasingInput;
159
+ /** Distance each unit travels into place, in pixels. Default `18`. */
160
+ distance?: number;
161
+ /** Starting blur in pixels — the "focus in" look. Default `0`. */
162
+ blur?: number;
163
+ /** Starting rotation in degrees. Default `0`. */
164
+ rotate?: number;
165
+ /** Clip each unit so it rises from behind a mask. Default `false`. */
166
+ mask?: boolean;
167
+ /** Wait until scrolled into view. Default `true`. */
168
+ whenInView?: boolean;
169
+ /** Replay every time it re-enters the viewport. Default `false`. */
170
+ repeat?: boolean;
171
+ /** Seconds to wait before starting. Default `0`. */
172
+ delay?: number;
173
+ as?: ElementType;
174
+ className?: string;
175
+ style?: React.CSSProperties;
176
+ onComplete?: () => void;
177
+ }
178
+ /**
179
+ * Text that reveals unit by unit.
180
+ *
181
+ * The split happens in React (so the markup is server-rendered and present in the HTML source for
182
+ * SEO and for no-JS readers) while the animation runs on the shared ticker (so a page full of these
183
+ * shares one clock and cannot drift).
184
+ *
185
+ * Under `prefers-reduced-motion` the text renders in its final state immediately — no hidden
186
+ * frame, no fade.
187
+ */
188
+ declare function AnimatedText({ children, by, duration, each, from, easing, distance, blur, rotate, mask, whenInView, repeat, delay, as: Component, className, style, onComplete, }: AnimatedTextProps): react.JSX.Element;
189
+
190
+ /**
191
+ * Turn a {@link BehaviourDefinition} into a React component.
192
+ *
193
+ * The DOM counterpart of {@link import('./create-effect-component').createEffectComponent}. The
194
+ * difference in the API is deliberate and small: a behaviour component renders its children
195
+ * *directly* rather than wrapping them in a positioned layer, because a behaviour manipulates the
196
+ * host element itself and inserting a wrapper would break the author's layout.
197
+ *
198
+ * ```tsx
199
+ * export const MagneticButton = createBehaviourComponent(magnetic, 'MagneticButton', 'button')
200
+ * ```
201
+ */
202
+ interface BehaviourComponentBaseProps {
203
+ as?: ElementType;
204
+ className?: string;
205
+ style?: React.CSSProperties;
206
+ children?: ReactNode;
207
+ }
208
+ type BehaviourComponentProps<Options extends BaseBehaviourOptions> = Options & BehaviourComponentBaseProps & Omit<ComponentPropsWithoutRef<'div'>, keyof Options | 'style' | 'className' | 'children'> &
209
+ /**
210
+ * Attributes that only make sense on the elements `as` is actually used with.
211
+ *
212
+ * `as="a"` without this is a type error on `href`, which makes the prop useless for the case it
213
+ * exists for — turning a magnetic button into a link. Full polymorphic typing (`as` as a generic
214
+ * that rewrites the whole prop set) is the textbook answer and it collapses inference for every
215
+ * behaviour option in the intersection, producing error messages nobody can read. Naming the two
216
+ * element types `as` is realistically pointed at is the trade that keeps both working.
217
+ */
218
+ Partial<Pick<ComponentPropsWithoutRef<'a'>, 'href' | 'target' | 'rel' | 'download'>> & Partial<Pick<ComponentPropsWithoutRef<'button'>, 'type' | 'disabled' | 'form' | 'name' | 'value'>>;
219
+ /** The type of a component produced by {@link createBehaviourComponent}. */
220
+ type BehaviourComponent<Options extends BaseBehaviourOptions, El extends HTMLElement = HTMLElement> = ForwardRefExoticComponent<BehaviourComponentProps<Options> & RefAttributes<El>>;
221
+ declare function createBehaviourComponent<Options extends BaseBehaviourOptions, El extends HTMLElement = HTMLElement>(definition: BehaviourDefinition<Options, El>, displayName?: string, defaultElement?: ElementType): BehaviourComponent<Options, El>;
222
+ /**
223
+ * Attach a behaviour to an element you already have a ref to.
224
+ *
225
+ * The hook form, for when a component's own element must carry the behaviour rather than being
226
+ * wrapped — which is most of the time when integrating with an existing design system.
227
+ *
228
+ * ```tsx
229
+ * const ref = useRef<HTMLButtonElement>(null)
230
+ * useBehaviour(ref, magnetic, { strength: 16 })
231
+ * ```
232
+ */
233
+ declare function useBehaviour<Options extends BaseBehaviourOptions, El extends HTMLElement>(ref: React.RefObject<El | null>, definition: BehaviourDefinition<Options, El>, options?: Partial<Options>): void;
234
+
235
+ interface MotionConfigValue {
236
+ reducedMotion: ReducedMotionMode;
237
+ /** Global playback rate. `0.5` is slow motion across every animation on the page. */
238
+ timeScale: number;
239
+ /** Pin adaptive quality, or `null` to let the frame budget decide. */
240
+ quality: number | null;
241
+ }
242
+ interface MotionConfigProps extends Partial<MotionConfigValue> {
243
+ /**
244
+ * Pause every animation while the document is hidden. Default `true`.
245
+ *
246
+ * Leave this on. Animating a background tab burns battery and spins fans for output nobody can
247
+ * see, and it is the most common performance complaint about animation-heavy sites.
248
+ */
249
+ pauseWhenHidden?: boolean;
250
+ /** Also pause when the window loses focus. Default `false` — a visible unfocused window still
251
+ * expects to animate. */
252
+ pauseWhenBlurred?: boolean;
253
+ /** Reduce quality on low battery where the platform exposes it. Default `true`. */
254
+ respectBattery?: boolean;
255
+ children?: ReactNode;
256
+ }
257
+ /**
258
+ * Application-level motion configuration.
259
+ *
260
+ * Optional — every component works without it. Mount it once at the root when you need
261
+ * app-wide control:
262
+ *
263
+ * ```tsx
264
+ * <MotionConfig reducedMotion={userPrefersCalm ? 'always' : 'auto'}>
265
+ * <App />
266
+ * </MotionConfig>
267
+ * ```
268
+ *
269
+ * `reducedMotion="always"` is genuinely useful in production, as the backing for an in-app
270
+ * "reduce motion" setting — many users who want calmer interfaces have never found the OS toggle.
271
+ */
272
+ declare function MotionConfig({ reducedMotion, timeScale, quality, pauseWhenHidden, pauseWhenBlurred, respectBattery, children, }: MotionConfigProps): react.JSX.Element;
273
+ /** Read the nearest {@link MotionConfig}. Returns sensible defaults with no provider present. */
274
+ declare function useMotionConfig(): MotionConfigValue;
275
+ type ThemeSetting = 'light' | 'dark' | 'system';
276
+ interface ThemeContextValue {
277
+ /** What was requested, including `'system'`. */
278
+ theme: ThemeSetting;
279
+ /** What is actually rendering. `'system'` is resolved to one or the other. */
280
+ resolved: 'light' | 'dark';
281
+ setTheme: (theme: ThemeSetting) => void;
282
+ }
283
+ interface ThemeProviderProps {
284
+ /** Initial setting. Default `'system'`. */
285
+ defaultTheme?: ThemeSetting;
286
+ /** Persist the choice under this `localStorage` key. Pass `null` to disable. Default `'ansh-theme'`. */
287
+ storageKey?: string | null;
288
+ children?: ReactNode;
289
+ }
290
+ /**
291
+ * Theme control over the `@ansh-ui/tokens` stylesheet.
292
+ *
293
+ * Sets `data-theme` on `<html>`, which the token stylesheet already understands. Two details that
294
+ * are easy to get wrong and are handled here:
295
+ *
296
+ * **`'system'` removes the attribute rather than writing a resolved value.** The token stylesheet
297
+ * guards its `prefers-color-scheme` rule with `:root:not([data-theme])`, so removing the attribute
298
+ * hands control back to the OS — and, importantly, means the theme keeps following the OS if the
299
+ * user changes it while the page is open.
300
+ *
301
+ * **The initial render always reports `'light'`.** Reading `localStorage` during render would be a
302
+ * hydration mismatch, since the server has no access to it. The stored value is applied in an
303
+ * effect. To avoid a flash of the wrong theme, ship the small inline script from
304
+ * {@link themeScript} in your document `<head>` — that is the only way to set the attribute before
305
+ * first paint, and it is what every correct implementation does.
306
+ */
307
+ declare function ThemeProvider({ defaultTheme, storageKey, children, }: ThemeProviderProps): react.JSX.Element;
308
+ declare function useTheme(): ThemeContextValue;
309
+ /**
310
+ * The blocking script that prevents a theme flash.
311
+ *
312
+ * Inject this in `<head>`, before any stylesheet. It reads the stored preference and sets
313
+ * `data-theme` synchronously, before the browser paints — which is the only point at which it can
314
+ * be done without a visible flash. It is deliberately tiny and dependency-free.
315
+ *
316
+ * ```tsx
317
+ * // Next.js app/layout.tsx
318
+ * <head>
319
+ * <script dangerouslySetInnerHTML={{ __html: themeScript() }} />
320
+ * </head>
321
+ * ```
322
+ */
323
+ declare function themeScript(storageKey?: string): string;
324
+
325
+ /**
326
+ * DOM behaviour components.
327
+ *
328
+ * Unlike the canvas backgrounds these render their children directly — no wrapper, no positioned
329
+ * layer — because a behaviour manipulates the host element and inserting a wrapper would break the
330
+ * author's layout.
331
+ */
332
+ /**
333
+ * An element that leans toward the pointer, spring-driven.
334
+ *
335
+ * Renders a `<button>` by default so it is keyboard-focusable and announced correctly. Pass
336
+ * `as="a"` or `as="div"` when it isn't a button — but if it *acts* like a button, leave it.
337
+ *
338
+ * ```tsx
339
+ * <MagneticButton strength={16} scale={1.04} onClick={submit}>
340
+ * Get started
341
+ * </MagneticButton>
342
+ * ```
343
+ */
344
+ declare const MagneticButton: BehaviourComponent<_ansh_ui_core.MagneticOptions, HTMLElement>;
345
+ /**
346
+ * A card that rotates in 3D toward the pointer, with a moving specular highlight.
347
+ *
348
+ * The `perspective()` is baked into the transform as its first function, so no parent wrapper is
349
+ * needed — which is the usual reason tilt implementations come out looking sheared rather than 3D.
350
+ */
351
+ declare const TiltCard: BehaviourComponent<_ansh_ui_core.TiltOptions, HTMLElement>;
352
+ /**
353
+ * A wave that expands from the point of contact.
354
+ *
355
+ * Also fires on Enter and Space, so keyboard activation gets the same feedback as a click. The
356
+ * ripple layer inherits the host's `border-radius`, so a pill button clips its ripple to a pill
357
+ * with no extra configuration.
358
+ */
359
+ declare const Ripple: BehaviourComponent<_ansh_ui_core.RippleOptions, HTMLElement>;
360
+ /**
361
+ * Seamless infinite scrolling content.
362
+ *
363
+ * Speed is in **pixels per second**, not a duration, so adding an item to a logo strip doesn't
364
+ * change how fast it scrolls. Content is duplicated as many times as needed to cover the
365
+ * container, and clones are `aria-hidden` so a screen reader reads the list once.
366
+ *
367
+ * ```tsx
368
+ * <Marquee speed={40} fadeEdges={64} pauseOnHover>
369
+ * {logos.map((logo) => <img key={logo.id} src={logo.src} alt={logo.name} />)}
370
+ * </Marquee>
371
+ * ```
372
+ */
373
+ declare const Marquee: BehaviourComponent<_ansh_ui_core.MarqueeOptions, HTMLElement>;
374
+ /**
375
+ * Reveal content as it enters the viewport.
376
+ *
377
+ * The hidden starting state is applied **in JavaScript**, not CSS. If the script never runs, the
378
+ * content is simply visible — degraded but readable. A CSS-hidden initial state means content that
379
+ * is permanently invisible when JavaScript fails, which has shipped to production on a lot of
380
+ * marketing sites.
381
+ *
382
+ * Pass `children=".selector"` to stagger descendants instead of revealing the host as one block.
383
+ */
384
+ declare const ScrollReveal: BehaviourComponent<_ansh_ui_core.ScrollRevealOptions, HTMLElement>;
385
+ /**
386
+ * Move an element at a different rate from the scroll.
387
+ *
388
+ * All measurement happens in the ticker's `read` phase, so fifty parallax elements cost one layout
389
+ * read per frame between them rather than one per scroll event each. Disabled outright under
390
+ * `prefers-reduced-motion` — parallax is the canonical vestibular trigger, and a slow parallax is
391
+ * still parallax.
392
+ */
393
+ declare const Parallax: BehaviourComponent<_ansh_ui_core.ParallaxOptions, HTMLElement>;
394
+
395
+ export { AnimatePresence as A, type BehaviourComponent as B, Draggable as D, GradientText as G, MagneticButton as M, Parallax as P, Ripple as R, ScrollReveal as S, type ThemeContextValue as T, type AnimatePresenceProps as a, AnimatedText as b, type AnimatedTextProps as c, type BehaviourComponentBaseProps as d, type BehaviourComponentProps as e, type DraggableProps as f, type GradientTextProps as g, Marquee as h, Motion as i, MotionConfig as j, type MotionConfigProps as k, type MotionConfigValue as l, type MotionTransition as m, type MotionValues as n, ThemeProvider as o, type ThemeProviderProps as p, type ThemeSetting as q, TiltCard as r, createBehaviourComponent as s, themeScript as t, useBehaviour as u, useMotionConfig as v, useTheme as w };