@streamsai/ui 0.0.0-stage → 0.1.1

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 (206) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +57 -2
  3. package/dist/components/ui/agent-avatar.d.ts +50 -0
  4. package/dist/components/ui/agent-avatar.js +38 -0
  5. package/dist/components/ui/alert-dialog.d.ts +12 -0
  6. package/dist/components/ui/alert-dialog.js +37 -0
  7. package/dist/components/ui/alert.d.ts +10 -0
  8. package/dist/components/ui/alert.js +28 -0
  9. package/dist/components/ui/assets/loader.json.js +1 -0
  10. package/dist/components/ui/avatar-frame.d.ts +11 -0
  11. package/dist/components/ui/avatar-frame.js +20 -0
  12. package/dist/components/ui/avatar.d.ts +23 -0
  13. package/dist/components/ui/avatar.js +54 -0
  14. package/dist/components/ui/badge.d.ts +7 -0
  15. package/dist/components/ui/badge.js +36 -0
  16. package/dist/components/ui/bar-list.d.ts +40 -0
  17. package/dist/components/ui/bar-list.js +37 -0
  18. package/dist/components/ui/breadcrumb.d.ts +8 -0
  19. package/dist/components/ui/breadcrumb.js +21 -0
  20. package/dist/components/ui/button-group.d.ts +10 -0
  21. package/dist/components/ui/button-group.js +41 -0
  22. package/dist/components/ui/button.d.ts +9 -0
  23. package/dist/components/ui/button.js +39 -0
  24. package/dist/components/ui/card.d.ts +9 -0
  25. package/dist/components/ui/card.js +25 -0
  26. package/dist/components/ui/checkbox.d.ts +3 -0
  27. package/dist/components/ui/checkbox.js +16 -0
  28. package/dist/components/ui/chip.d.ts +13 -0
  29. package/dist/components/ui/chip.js +22 -0
  30. package/dist/components/ui/clickable.d.ts +27 -0
  31. package/dist/components/ui/clickable.js +54 -0
  32. package/dist/components/ui/code-block.d.ts +68 -0
  33. package/dist/components/ui/code-block.js +112 -0
  34. package/dist/components/ui/code-view.d.ts +21 -0
  35. package/dist/components/ui/code-view.js +20 -0
  36. package/dist/components/ui/collapsible.d.ts +6 -0
  37. package/dist/components/ui/collapsible.js +18 -0
  38. package/dist/components/ui/combobox.d.ts +14 -0
  39. package/dist/components/ui/combobox.js +37 -0
  40. package/dist/components/ui/command.d.ts +15 -0
  41. package/dist/components/ui/command.js +34 -0
  42. package/dist/components/ui/context-menu.d.ts +21 -0
  43. package/dist/components/ui/context-menu.js +60 -0
  44. package/dist/components/ui/counter.d.ts +11 -0
  45. package/dist/components/ui/counter.js +20 -0
  46. package/dist/components/ui/dialog.d.ts +17 -0
  47. package/dist/components/ui/dialog.js +41 -0
  48. package/dist/components/ui/disabled-reason.d.ts +22 -0
  49. package/dist/components/ui/disabled-reason.js +16 -0
  50. package/dist/components/ui/dropdown-menu.d.ts +33 -0
  51. package/dist/components/ui/dropdown-menu.js +58 -0
  52. package/dist/components/ui/editable-text.d.ts +95 -0
  53. package/dist/components/ui/editable-text.js +191 -0
  54. package/dist/components/ui/heading.d.ts +24 -0
  55. package/dist/components/ui/heading.js +92 -0
  56. package/dist/components/ui/hover-card.d.ts +9 -0
  57. package/dist/components/ui/hover-card.js +16 -0
  58. package/dist/components/ui/icon-button.d.ts +23 -0
  59. package/dist/components/ui/icon-button.js +32 -0
  60. package/dist/components/ui/input.d.ts +3 -0
  61. package/dist/components/ui/input.js +8 -0
  62. package/dist/components/ui/kbd.d.ts +12 -0
  63. package/dist/components/ui/kbd.js +12 -0
  64. package/dist/components/ui/label.d.ts +3 -0
  65. package/dist/components/ui/label.js +7 -0
  66. package/dist/components/ui/loader.d.ts +19 -0
  67. package/dist/components/ui/loader.js +157 -0
  68. package/dist/components/ui/message-toolbar.d.ts +20 -0
  69. package/dist/components/ui/message-toolbar.js +17 -0
  70. package/dist/components/ui/modal.d.ts +30 -0
  71. package/dist/components/ui/modal.js +41 -0
  72. package/dist/components/ui/nav-item.d.ts +25 -0
  73. package/dist/components/ui/nav-item.js +66 -0
  74. package/dist/components/ui/panel-section.d.ts +22 -0
  75. package/dist/components/ui/panel-section.js +26 -0
  76. package/dist/components/ui/popover.d.ts +14 -0
  77. package/dist/components/ui/popover.js +30 -0
  78. package/dist/components/ui/progress.d.ts +5 -0
  79. package/dist/components/ui/progress.js +16 -0
  80. package/dist/components/ui/provider-badge.d.ts +22 -0
  81. package/dist/components/ui/provider-badge.js +38 -0
  82. package/dist/components/ui/radio-group.d.ts +5 -0
  83. package/dist/components/ui/radio-group.js +21 -0
  84. package/dist/components/ui/reply-summary.d.ts +16 -0
  85. package/dist/components/ui/reply-summary.js +8 -0
  86. package/dist/components/ui/resizable.d.ts +8 -0
  87. package/dist/components/ui/resizable.js +15 -0
  88. package/dist/components/ui/rich-text-editor.d.ts +447 -0
  89. package/dist/components/ui/rich-text-editor.js +2419 -0
  90. package/dist/components/ui/running-indicator.d.ts +17 -0
  91. package/dist/components/ui/running-indicator.js +34 -0
  92. package/dist/components/ui/sandboxed-frame.d.ts +29 -0
  93. package/dist/components/ui/sandboxed-frame.js +77 -0
  94. package/dist/components/ui/scroll-area.d.ts +14 -0
  95. package/dist/components/ui/scroll-area.js +17 -0
  96. package/dist/components/ui/section-header.d.ts +12 -0
  97. package/dist/components/ui/section-header.js +12 -0
  98. package/dist/components/ui/select.d.ts +15 -0
  99. package/dist/components/ui/select.js +40 -0
  100. package/dist/components/ui/separator.d.ts +3 -0
  101. package/dist/components/ui/separator.js +13 -0
  102. package/dist/components/ui/sheet.d.ts +23 -0
  103. package/dist/components/ui/sheet.js +48 -0
  104. package/dist/components/ui/shimmer-text.d.ts +26 -0
  105. package/dist/components/ui/shimmer-text.js +32 -0
  106. package/dist/components/ui/sidebar.d.ts +63 -0
  107. package/dist/components/ui/sidebar.js +283 -0
  108. package/dist/components/ui/skeleton.d.ts +14 -0
  109. package/dist/components/ui/skeleton.js +12 -0
  110. package/dist/components/ui/sonner.d.ts +4 -0
  111. package/dist/components/ui/sonner.js +14 -0
  112. package/dist/components/ui/spark-bars.d.ts +29 -0
  113. package/dist/components/ui/spark-bars.js +24 -0
  114. package/dist/components/ui/spinner.d.ts +16 -0
  115. package/dist/components/ui/spinner.js +26 -0
  116. package/dist/components/ui/stacked-bar.d.ts +37 -0
  117. package/dist/components/ui/stacked-bar.js +56 -0
  118. package/dist/components/ui/status-dot.d.ts +16 -0
  119. package/dist/components/ui/status-dot.js +32 -0
  120. package/dist/components/ui/switch.d.ts +5 -0
  121. package/dist/components/ui/switch.js +13 -0
  122. package/dist/components/ui/tabs.d.ts +14 -0
  123. package/dist/components/ui/tabs.js +55 -0
  124. package/dist/components/ui/text.d.ts +27 -0
  125. package/dist/components/ui/text.js +100 -0
  126. package/dist/components/ui/textarea.d.ts +3 -0
  127. package/dist/components/ui/textarea.js +7 -0
  128. package/dist/components/ui/theme-toggle.d.ts +21 -0
  129. package/dist/components/ui/theme-toggle.js +17 -0
  130. package/dist/components/ui/toggle-group.d.ts +6 -0
  131. package/dist/components/ui/toggle-group.js +12 -0
  132. package/dist/components/ui/tooltip.d.ts +11 -0
  133. package/dist/components/ui/tooltip.js +21 -0
  134. package/dist/components/ui/trace.d.ts +24 -0
  135. package/dist/components/ui/trace.js +57 -0
  136. package/dist/components/ui/trend-line.d.ts +93 -0
  137. package/dist/components/ui/trend-line.js +215 -0
  138. package/dist/components/ui/truncate.d.ts +30 -0
  139. package/dist/components/ui/truncate.js +54 -0
  140. package/dist/components/ui/viewer-shell.d.ts +55 -0
  141. package/dist/components/ui/viewer-shell.js +15 -0
  142. package/dist/components/ui/virtual-list.d.ts +91 -0
  143. package/dist/components/ui/virtual-list.js +406 -0
  144. package/dist/components/ui/visually-hidden.d.ts +15 -0
  145. package/dist/components/ui/visually-hidden.js +19 -0
  146. package/dist/direction/index.d.ts +19 -0
  147. package/dist/direction/index.js +32 -0
  148. package/dist/hooks/use-code-highlighting.d.ts +22 -0
  149. package/dist/hooks/use-code-highlighting.js +47 -0
  150. package/dist/hooks/use-is-truncated.d.ts +7 -0
  151. package/dist/hooks/use-is-truncated.js +23 -0
  152. package/dist/hooks/use-mobile.d.ts +2 -0
  153. package/dist/hooks/use-mobile.js +15 -0
  154. package/dist/icons/custom.d.ts +29 -0
  155. package/dist/icons/custom.js +48 -0
  156. package/dist/icons/index.d.ts +49 -0
  157. package/dist/icons/index.js +50 -0
  158. package/dist/icons/provider-logos.d.ts +17 -0
  159. package/dist/icons/provider-logos.js +28 -0
  160. package/dist/icons/providers.d.ts +9 -0
  161. package/dist/icons/providers.js +51 -0
  162. package/dist/index.d.ts +102 -0
  163. package/dist/index.js +124 -0
  164. package/dist/lib/code-highlighter.d.ts +9 -0
  165. package/dist/lib/code-highlighter.js +65 -0
  166. package/dist/lib/code-language.d.ts +13 -0
  167. package/dist/lib/code-language.js +103 -0
  168. package/dist/lib/code-tokens.d.ts +9 -0
  169. package/dist/lib/code-tokens.js +27 -0
  170. package/dist/lib/copy-text.d.ts +6 -0
  171. package/dist/lib/copy-text.js +46 -0
  172. package/dist/lib/home-tile.d.ts +12 -0
  173. package/dist/lib/home-tile.js +45 -0
  174. package/dist/lib/reveal-mask.d.ts +9 -0
  175. package/dist/lib/reveal-mask.js +16 -0
  176. package/dist/lib/text-direction.d.ts +28 -0
  177. package/dist/lib/text-direction.js +119 -0
  178. package/dist/lib/utils.d.ts +11 -0
  179. package/dist/lib/utils.js +30 -0
  180. package/dist/motion/components.d.ts +184 -0
  181. package/dist/motion/components.js +211 -0
  182. package/dist/motion/config.d.ts +849 -0
  183. package/dist/motion/config.js +429 -0
  184. package/dist/motion/index.d.ts +8 -0
  185. package/dist/motion/index.js +8 -0
  186. package/dist/motion/modal-presence.d.ts +5 -0
  187. package/dist/motion/modal-presence.js +27 -0
  188. package/dist/motion/popup.d.ts +77 -0
  189. package/dist/motion/popup.js +103 -0
  190. package/dist/platform/index.d.ts +29 -0
  191. package/dist/platform/index.js +63 -0
  192. package/dist/styles/base.css +319 -0
  193. package/dist/styles/fonts/Figtree-Variable.woff2 +0 -0
  194. package/dist/styles/fonts/OFL.txt +93 -0
  195. package/dist/styles/fonts/Poppins-Medium.woff2 +0 -0
  196. package/dist/styles/fonts/Poppins-Regular.woff2 +0 -0
  197. package/dist/styles/fonts/Poppins-SemiBold.woff2 +0 -0
  198. package/dist/styles/fonts.css +28 -0
  199. package/dist/styles/globals.css +8 -0
  200. package/dist/styles/mcp-host.css +76 -0
  201. package/dist/styles/tokens.css +387 -0
  202. package/dist/styles/tokens.d.mts +57 -0
  203. package/dist/styles/tokens.mjs +59 -0
  204. package/dist/theme/index.d.ts +28 -0
  205. package/dist/theme/index.js +65 -0
  206. package/package.json +136 -3
@@ -0,0 +1,11 @@
1
+ import type { CnFunction } from 'cn';
2
+ /**
3
+ * Class merger for `@streamsai/ui`.
4
+ *
5
+ * Extends the default `cn` tables so our custom type-scale utilities
6
+ * (`text-body-*`, `text-body-15`, `text-compact`, `text-h3`, `text-message`) count as font sizes, not colors.
7
+ * Without that, merging `text-primary-foreground` with `text-body-3` drops the
8
+ * color — primary `Button size="sm"` labels then inherit near-black body text
9
+ * on a blue background.
10
+ */
11
+ export declare const cn: CnFunction;
@@ -0,0 +1,30 @@
1
+ import { createCn } from 'cn/config';
2
+ /**
3
+ * Class merger for `@streamsai/ui`.
4
+ *
5
+ * Extends the default `cn` tables so our custom type-scale utilities
6
+ * (`text-body-*`, `text-body-15`, `text-compact`, `text-h3`, `text-message`) count as font sizes, not colors.
7
+ * Without that, merging `text-primary-foreground` with `text-body-3` drops the
8
+ * color — primary `Button size="sm"` labels then inherit near-black body text
9
+ * on a blue background.
10
+ */
11
+ export const cn = createCn({
12
+ extend: {
13
+ classGroups: {
14
+ 'font-size': [
15
+ {
16
+ text: [
17
+ 'body-1',
18
+ 'body-2',
19
+ 'body-3',
20
+ 'body-15',
21
+ 'compact',
22
+ 'h3',
23
+ 'message',
24
+ 'message-jumbo',
25
+ ],
26
+ },
27
+ ],
28
+ },
29
+ },
30
+ });
@@ -0,0 +1,184 @@
1
+ import type { AnimatePresenceProps, HTMLMotionProps, Transition } from 'motion/react';
2
+ import type { Key, PropsWithChildren, ReactNode } from 'react';
3
+ /**
4
+ * Mounted once at the app root (and in both Storybooks). Honours the OS reduced-motion setting
5
+ * for every `motion` element below it (transforms are dropped, opacity still fades) and makes
6
+ * `transitions.base` the default for any element that does not name its own.
7
+ */
8
+ declare function MotionProvider({ children }: {
9
+ children: ReactNode;
10
+ }): import("react").JSX.Element;
11
+ /**
12
+ * Makes every JS animation finish instantly. Call it from test setup and from Storybook when a
13
+ * browser test runner drives it, so assertions (and axe) never catch an element mid-fade.
14
+ */
15
+ declare function disableMotion(): void;
16
+ /** Test helper: lets JS animations run for real again, for a test of what happens mid-animation. */
17
+ declare function enableMotion(): void;
18
+ /**
19
+ * Test helper: keep instant animations (`skipAnimations`) but retain exiting children so presence
20
+ * exit targets can be asserted. Pair with `disablePresenceExits` in `afterEach`.
21
+ */
22
+ declare function enablePresenceExits(): void;
23
+ /** Restores the default `disableMotion` presence shortcut after `enablePresenceExits`. */
24
+ declare function disablePresenceExits(): void;
25
+ /**
26
+ * `motion`'s `AnimatePresence`, except that under `disableMotion` it steps aside: leaving children
27
+ * unmount in the same render instead of a frame later, so a test can assert an indicator is gone
28
+ * straight after the state change. Everything in the repo uses this one, never motion's directly.
29
+ */
30
+ declare function AnimatePresence(props: PropsWithChildren<AnimatePresenceProps>): import("react").JSX.Element;
31
+ type DivMotionProps = Omit<HTMLMotionProps<'div'>, 'initial' | 'animate' | 'exit'>;
32
+ interface PageTransitionProps extends DivMotionProps {
33
+ /** Changes whenever the content is a different page (route path, stream id, session id). */
34
+ transitionKey: Key;
35
+ /** Show the content without the entrance, when something else already moves the page. */
36
+ still?: boolean;
37
+ }
38
+ /**
39
+ * Route and pane content arriving: a fade and a short rise each time `transitionKey` changes. It is
40
+ * enter-only on purpose. The old page is gone the moment the router swaps it, so the new one
41
+ * shows at once and never waits on an exit.
42
+ */
43
+ declare function PageTransition({ transitionKey, still, className, ...props }: PageTransitionProps): import("react").JSX.Element;
44
+ interface CollapseProps extends DivMotionProps {
45
+ open: boolean;
46
+ /** Skip the animation on first render, so content that starts open does not grow in on mount. */
47
+ initialOpen?: boolean;
48
+ /**
49
+ * `'x'` animates width instead, for a side panel beside flexible content. Give the child a fixed
50
+ * width so it slides in whole rather than reflowing on every frame.
51
+ */
52
+ axis?: 'y' | 'x';
53
+ }
54
+ /**
55
+ * Height (or width) 0 ↔ auto disclosure. Content unmounts when closed.
56
+ *
57
+ * Opening waits for the frame after the content first paints. Mounting a heavy panel can take a
58
+ * long frame, and an animation whose clock started before it would show up already most of the
59
+ * way open; starting after it keeps every frame of the reveal on screen.
60
+ */
61
+ declare function Collapse({ open, initialOpen, axis, className, style, ...props }: CollapseProps): import("react").JSX.Element;
62
+ /**
63
+ * The OS reduced-motion preference, following live changes. (`motion`'s `useReducedMotion` reads
64
+ * it once and does not re-render when it flips.) For components that must stop animating the
65
+ * moment the person asks, such as a height already on its way.
66
+ */
67
+ declare function usePrefersReducedMotion(): boolean;
68
+ interface AutoHeightProps extends Omit<HTMLMotionProps<'div'>, 'initial' | 'animate' | 'exit' | 'transition' | 'children'> {
69
+ children?: ReactNode;
70
+ /** `resize.step` for a whole step changing, `resize.reveal` (default) for small reveals. */
71
+ transition?: Transition;
72
+ /** Class for the measured inner block (the children's own layout, such as `flex flex-col gap-3`). */
73
+ innerClassName?: string;
74
+ }
75
+ /**
76
+ * A block that grows and shrinks to its content instead of jumping: a form step with a different
77
+ * number of lines, an error appearing, a list expanding. The inner block is measured with a
78
+ * ResizeObserver and the outer one animates an explicit pixel height with `resize.reveal`.
79
+ * It clips only while moving, so a focus ring is not cut off at rest. The tree is the same with or
80
+ * without reduced motion; under it the height changes in zero time.
81
+ */
82
+ declare function AutoHeight({ innerClassName, children, transition, style, ...props }: AutoHeightProps): import("react").JSX.Element;
83
+ type SwapPresetName = 'swap' | 'wheelUp' | 'wheelDown';
84
+ interface SwapProps extends DivMotionProps {
85
+ /** The state being shown. A new key crossfades the old content out and the new content in. */
86
+ swapKey: Key;
87
+ /** Render as an inline element (text and icon swaps inside a button). */
88
+ inline?: boolean;
89
+ /**
90
+ * Motion preset for the swap. Default `swap` (blur-scale crossfade). `wheelUp` / `wheelDown`
91
+ * are odometer rolls — clip the parent with `overflow-hidden` so travel stays in the box.
92
+ */
93
+ preset?: SwapPresetName;
94
+ }
95
+ /**
96
+ * Dynamic variants keyed by the latest `custom` preset. AnimatePresence's `custom` is what the
97
+ * exiting child reads, so a wheelUp → wheelDown change exits upward (`-100%`), not with the
98
+ * mount-time `wheelUp` exit.
99
+ */
100
+ declare const swapVariants: {
101
+ initial: (preset: SwapPresetName) => {
102
+ readonly opacity: 0;
103
+ readonly scale: 0.98;
104
+ readonly filter: "blur(2px)";
105
+ } | {
106
+ readonly y: "-100%";
107
+ readonly opacity: 0;
108
+ } | {
109
+ readonly y: "100%";
110
+ readonly opacity: 0;
111
+ };
112
+ animate: (preset: SwapPresetName) => {
113
+ readonly opacity: 1;
114
+ readonly scale: 1;
115
+ readonly filter: "blur(0px)";
116
+ readonly transition: {
117
+ readonly duration: 0.12;
118
+ readonly ease: [number, number, number, number];
119
+ };
120
+ readonly transitionEnd: {
121
+ readonly filter: "none";
122
+ };
123
+ } | {
124
+ readonly y: 0;
125
+ readonly opacity: 1;
126
+ readonly transition: {
127
+ readonly duration: 0.12;
128
+ readonly ease: [number, number, number, number];
129
+ };
130
+ } | {
131
+ readonly y: 0;
132
+ readonly opacity: 1;
133
+ readonly transition: {
134
+ readonly duration: 0.12;
135
+ readonly ease: [number, number, number, number];
136
+ };
137
+ };
138
+ exit: (preset: SwapPresetName) => {
139
+ readonly opacity: 0;
140
+ readonly scale: 0.98;
141
+ readonly filter: "blur(2px)";
142
+ readonly transition: {
143
+ readonly duration: 0.12;
144
+ readonly ease: [number, number, number, number];
145
+ };
146
+ } | {
147
+ readonly y: "100%";
148
+ readonly opacity: 0;
149
+ readonly transition: {
150
+ readonly duration: 0.1;
151
+ readonly ease: [number, number, number, number];
152
+ };
153
+ } | {
154
+ readonly y: "-100%";
155
+ readonly opacity: 0;
156
+ readonly transition: {
157
+ readonly duration: 0.1;
158
+ readonly ease: [number, number, number, number];
159
+ };
160
+ };
161
+ };
162
+ /**
163
+ * One piece of content replacing another in the same spot: Copy → Copied, an icon changing, a
164
+ * status label flipping, or a counter rolling. The two overlap briefly (`popLayout`), so the
165
+ * surrounding layout does not jump while they swap.
166
+ */
167
+ declare function Swap({ swapKey, inline, preset, className, ...props }: SwapProps): import("react").JSX.Element;
168
+ interface StaggerItemProps extends DivMotionProps {
169
+ /** Position in the group; later items start a beat later, capped by `stagger.max`. */
170
+ index: number;
171
+ /** `rise` for rows, `lift` for cards, `pop` for chips, `scaleIn` for tiles that grow in place. */
172
+ preset?: 'rise' | 'lift' | 'pop' | 'fade' | 'scaleIn';
173
+ /** Seconds between peers; `stagger.offset` for a Sense peer group. */
174
+ step?: number;
175
+ /** `li` for a row in a list. */
176
+ as?: 'div' | 'li';
177
+ }
178
+ /**
179
+ * A card, row or widget in a group that should cascade in on first render (settings cards,
180
+ * analytics widgets, catalog tiles). The cascade is capped, so a long list is never slow to show.
181
+ */
182
+ declare function StaggerItem({ index, preset, step, as, ...props }: StaggerItemProps): import("react").JSX.Element;
183
+ export { MotionProvider, disableMotion, enableMotion, enablePresenceExits, disablePresenceExits, AnimatePresence, PageTransition, Collapse, AutoHeight, usePrefersReducedMotion, Swap, swapVariants, StaggerItem, };
184
+ export type { PageTransitionProps, CollapseProps, AutoHeightProps, SwapProps, SwapPresetName, StaggerItemProps, };
@@ -0,0 +1,211 @@
1
+ import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { AnimatePresence as MotionAnimatePresence, MotionConfig, MotionGlobalConfig, PresenceContext, animate, motion, useIsPresent, useMotionValue, } from 'motion/react';
3
+ import { useCallback, useContext, useEffect, useLayoutEffect, useRef, useState, useSyncExternalStore, } from 'react';
4
+ import { presets, resize, staggerDelay, transitions } from './config.js';
5
+ /**
6
+ * Mounted once at the app root (and in both Storybooks). Honours the OS reduced-motion setting
7
+ * for every `motion` element below it (transforms are dropped, opacity still fades) and makes
8
+ * `transitions.base` the default for any element that does not name its own.
9
+ */
10
+ function MotionProvider({ children }) {
11
+ return (_jsx(MotionConfig, { reducedMotion: "user", transition: transitions.base, children: children }));
12
+ }
13
+ /**
14
+ * Makes every JS animation finish instantly. Call it from test setup and from Storybook when a
15
+ * browser test runner drives it, so assertions (and axe) never catch an element mid-fade.
16
+ */
17
+ function disableMotion() {
18
+ MotionGlobalConfig.skipAnimations = true;
19
+ exitsDisabled = true;
20
+ }
21
+ /** Test helper: lets JS animations run for real again, for a test of what happens mid-animation. */
22
+ function enableMotion() {
23
+ MotionGlobalConfig.skipAnimations = false;
24
+ exitsDisabled = false;
25
+ }
26
+ /**
27
+ * Test helper: keep instant animations (`skipAnimations`) but retain exiting children so presence
28
+ * exit targets can be asserted. Pair with `disablePresenceExits` in `afterEach`.
29
+ */
30
+ function enablePresenceExits() {
31
+ exitsDisabled = false;
32
+ }
33
+ /** Restores the default `disableMotion` presence shortcut after `enablePresenceExits`. */
34
+ function disablePresenceExits() {
35
+ exitsDisabled = true;
36
+ }
37
+ /** Set once, before the first render, by `disableMotion`; flipped only by the test helpers above. */
38
+ let exitsDisabled = false;
39
+ /**
40
+ * `motion`'s `AnimatePresence`, except that under `disableMotion` it steps aside: leaving children
41
+ * unmount in the same render instead of a frame later, so a test can assert an indicator is gone
42
+ * straight after the state change. Everything in the repo uses this one, never motion's directly.
43
+ */
44
+ function AnimatePresence(props) {
45
+ if (exitsDisabled)
46
+ return _jsx(_Fragment, { children: props.children });
47
+ return _jsx(MotionAnimatePresence, { ...props });
48
+ }
49
+ /**
50
+ * Route and pane content arriving: a fade and a short rise each time `transitionKey` changes. It is
51
+ * enter-only on purpose. The old page is gone the moment the router swaps it, so the new one
52
+ * shows at once and never waits on an exit.
53
+ */
54
+ function PageTransition({ transitionKey, still = false, className, ...props }) {
55
+ return (_jsx(motion.div, { initial: still ? false : presets.rise.initial, animate: presets.rise.animate, className: className, ...props }, transitionKey));
56
+ }
57
+ /**
58
+ * Height (or width) 0 ↔ auto disclosure. Content unmounts when closed.
59
+ *
60
+ * Opening waits for the frame after the content first paints. Mounting a heavy panel can take a
61
+ * long frame, and an animation whose clock started before it would show up already most of the
62
+ * way open; starting after it keeps every frame of the reveal on screen.
63
+ */
64
+ function Collapse({ open, initialOpen = true, axis = 'y', className, style, ...props }) {
65
+ return (_jsx(AnimatePresence, { initial: !initialOpen, children: open ? (_jsx(CollapseBody, { axis: axis, className: className, style: style, ...props }, "collapse")) : null }));
66
+ }
67
+ function CollapseBody({ axis, style, onAnimationStart, onAnimationComplete, ...props }) {
68
+ const preset = axis === 'x' ? presets.collapseX : presets.collapse;
69
+ // `initial: false` from the presence means this is the first render of content that starts open
70
+ // (`initialOpen`): it appears as it is. Anything opened after that grows in.
71
+ const skipEntrance = useContext(PresenceContext)?.initial === false;
72
+ const [painted, setPainted] = useState(skipEntrance || exitsDisabled);
73
+ // The body clips only while its edge moves. Open and at rest it does not, so a focus ring, a
74
+ // shadow or a negative margin on the content is not cut off at the body's edge.
75
+ const [settled, setSettled] = useState(painted);
76
+ const present = useIsPresent();
77
+ useEffect(() => {
78
+ if (painted)
79
+ return;
80
+ // Two frames: the first still runs before the mount's own layout and paint.
81
+ let frame = requestAnimationFrame(() => {
82
+ frame = requestAnimationFrame(() => setPainted(true));
83
+ });
84
+ return () => cancelAnimationFrame(frame);
85
+ }, [painted]);
86
+ return (_jsx(motion.div, { initial: preset.initial, animate: painted ? preset.animate : preset.initial, exit: preset.exit, style: { overflow: settled ? undefined : 'hidden', ...style }, onAnimationStart: (definition) => {
87
+ setSettled(false);
88
+ onAnimationStart?.(definition);
89
+ }, onAnimationComplete: (definition) => {
90
+ setSettled(painted && present);
91
+ onAnimationComplete?.(definition);
92
+ }, ...props }));
93
+ }
94
+ const REDUCED_MOTION_QUERY = '(prefers-reduced-motion: reduce)';
95
+ function subscribeReducedMotion(notify) {
96
+ if (typeof window.matchMedia !== 'function')
97
+ return () => { };
98
+ const query = window.matchMedia(REDUCED_MOTION_QUERY);
99
+ query.addEventListener('change', notify);
100
+ return () => query.removeEventListener('change', notify);
101
+ }
102
+ const reducedMotionNow = () => typeof window.matchMedia === 'function' && window.matchMedia(REDUCED_MOTION_QUERY).matches;
103
+ /**
104
+ * The OS reduced-motion preference, following live changes. (`motion`'s `useReducedMotion` reads
105
+ * it once and does not re-render when it flips.) For components that must stop animating the
106
+ * moment the person asks, such as a height already on its way.
107
+ */
108
+ function usePrefersReducedMotion() {
109
+ return useSyncExternalStore(subscribeReducedMotion, reducedMotionNow, () => false);
110
+ }
111
+ /**
112
+ * A block that grows and shrinks to its content instead of jumping: a form step with a different
113
+ * number of lines, an error appearing, a list expanding. The inner block is measured with a
114
+ * ResizeObserver and the outer one animates an explicit pixel height with `resize.reveal`.
115
+ * It clips only while moving, so a focus ring is not cut off at rest. The tree is the same with or
116
+ * without reduced motion; under it the height changes in zero time.
117
+ */
118
+ function AutoHeight({ innerClassName, children, transition = resize.reveal, style, ...props }) {
119
+ const reduced = usePrefersReducedMotion();
120
+ const innerRef = useRef(null);
121
+ const height = useMotionValue('auto');
122
+ const control = useRef(null);
123
+ const measured = useRef(false);
124
+ const [moving, setMoving] = useState(false);
125
+ // The latest options, so the observer (set up once) never goes stale.
126
+ const options = useRef({ reduced, transition });
127
+ useLayoutEffect(() => {
128
+ options.current = { reduced, transition };
129
+ });
130
+ const measure = useCallback(() => {
131
+ const node = innerRef.current;
132
+ if (!node)
133
+ return;
134
+ const next = Math.ceil(node.getBoundingClientRect().height);
135
+ control.current?.stop();
136
+ // The first measure replaces `auto`, which cannot be animated, so it is set as it is.
137
+ if (!measured.current || options.current.reduced) {
138
+ measured.current = true;
139
+ height.set(next);
140
+ setMoving(false);
141
+ return;
142
+ }
143
+ if (height.get() === next) {
144
+ // Back where it was before the animation got going: nothing left to wait for.
145
+ setMoving(false);
146
+ return;
147
+ }
148
+ setMoving(true);
149
+ control.current = animate(height, next, {
150
+ ...options.current.transition,
151
+ onComplete: () => setMoving(false),
152
+ });
153
+ }, [height]);
154
+ // Asking for less motion mid-animation settles the height where it is going, at once.
155
+ useLayoutEffect(() => {
156
+ if (reduced)
157
+ measure();
158
+ }, [reduced, measure]);
159
+ useLayoutEffect(() => {
160
+ measure();
161
+ const node = innerRef.current;
162
+ if (!node || typeof ResizeObserver === 'undefined')
163
+ return;
164
+ const observer = new ResizeObserver(measure);
165
+ observer.observe(node);
166
+ return () => {
167
+ observer.disconnect();
168
+ control.current?.stop();
169
+ };
170
+ }, [measure]);
171
+ return (_jsx(motion.div, { style: { height, overflow: moving ? 'hidden' : undefined, ...style }, ...props, children: _jsx("div", { ref: innerRef, className: innerClassName, children: children }) }));
172
+ }
173
+ /**
174
+ * Dynamic variants keyed by the latest `custom` preset. AnimatePresence's `custom` is what the
175
+ * exiting child reads, so a wheelUp → wheelDown change exits upward (`-100%`), not with the
176
+ * mount-time `wheelUp` exit.
177
+ */
178
+ const swapVariants = {
179
+ initial: (preset) => presets[preset].initial,
180
+ animate: (preset) => presets[preset].animate,
181
+ exit: (preset) => presets[preset].exit,
182
+ };
183
+ /**
184
+ * One piece of content replacing another in the same spot: Copy → Copied, an icon changing, a
185
+ * status label flipping, or a counter rolling. The two overlap briefly (`popLayout`), so the
186
+ * surrounding layout does not jump while they swap.
187
+ */
188
+ function Swap({ swapKey, inline = false, preset = 'swap', className, ...props }) {
189
+ // `custom` on AnimatePresence is the exit direction for the outgoing keyed child.
190
+ return (_jsx(AnimatePresence, { mode: "popLayout", initial: false, custom: preset, children: inline ? (_jsx(motion.span, { custom: preset, variants: swapVariants, initial: "initial", animate: "animate", exit: "exit", className: className, ...props }, swapKey)) : (_jsx(motion.div, { custom: preset, variants: swapVariants, initial: "initial", animate: "animate", exit: "exit", className: className, ...props }, swapKey)) }));
191
+ }
192
+ /** Adds `delay` to a transition and to each per-value transition inside it, which ignore the top level. */
193
+ const withDelay = (transition, delay) => Object.fromEntries([
194
+ ...Object.entries(transition).map(([key, value]) => value && typeof value === 'object' && !Array.isArray(value)
195
+ ? [key, { ...value, delay: (value.delay ?? 0) + delay }]
196
+ : [key, value]),
197
+ ['delay', delay],
198
+ ]);
199
+ /**
200
+ * A card, row or widget in a group that should cascade in on first render (settings cards,
201
+ * analytics widgets, catalog tiles). The cascade is capped, so a long list is never slow to show.
202
+ */
203
+ function StaggerItem({ index, preset = 'rise', step, as = 'div', ...props }) {
204
+ const { initial, animate, exit } = presets[preset];
205
+ const Element = as === 'li' ? motion.li : motion.div;
206
+ return (_jsx(Element, { initial: initial, animate: {
207
+ ...animate,
208
+ transition: withDelay(animate.transition, staggerDelay(index, step)),
209
+ }, exit: exit, ...props }));
210
+ }
211
+ export { MotionProvider, disableMotion, enableMotion, enablePresenceExits, disablePresenceExits, AnimatePresence, PageTransition, Collapse, AutoHeight, usePrefersReducedMotion, Swap, swapVariants, StaggerItem, };