@astra-kit/ui 0.0.0-stage → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +330 -2
  4. package/THIRD_PARTY_NOTICES.md +31 -0
  5. package/assets/fonts/geist-LICENSE.txt +93 -0
  6. package/assets/fonts/geist-latin-variable.woff2 +0 -0
  7. package/assets/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
  8. package/assets/fonts/ibm-plex-mono-latin-500.woff2 +0 -0
  9. package/assets/fonts/ibmplexmono-LICENSE.txt +93 -0
  10. package/assets/fonts/inter-LICENSE.txt +93 -0
  11. package/assets/fonts/inter-latin-variable.woff2 +0 -0
  12. package/dist/adapters/unpic-image.d.ts +3 -0
  13. package/dist/adapters/unpic-image.js +98 -0
  14. package/dist/components/account-menu.d.ts +67 -0
  15. package/dist/components/account-menu.js +440 -0
  16. package/dist/components/action-button.d.ts +25 -0
  17. package/dist/components/action-button.js +264 -0
  18. package/dist/components/alert.d.ts +31 -0
  19. package/dist/components/alert.js +503 -0
  20. package/dist/components/animated-collapse.d.ts +19 -0
  21. package/dist/components/animated-collapse.js +170 -0
  22. package/dist/components/animated-count.d.ts +13 -0
  23. package/dist/components/animated-count.js +105 -0
  24. package/dist/components/animated-list-item.d.ts +25 -0
  25. package/dist/components/animated-list-item.js +134 -0
  26. package/dist/components/animated-theme-toggler.d.ts +12 -0
  27. package/dist/components/animated-theme-toggler.js +200 -0
  28. package/dist/components/avatar.d.ts +65 -0
  29. package/dist/components/avatar.js +463 -0
  30. package/dist/components/badge.d.ts +21 -0
  31. package/dist/components/badge.js +297 -0
  32. package/dist/components/button-interaction.d.ts +23 -0
  33. package/dist/components/button-interaction.js +22 -0
  34. package/dist/components/button-label.d.ts +8 -0
  35. package/dist/components/button-label.js +203 -0
  36. package/dist/components/button.d.ts +23 -0
  37. package/dist/components/button.js +145 -0
  38. package/dist/components/calendar.d.ts +47 -0
  39. package/dist/components/calendar.js +155 -0
  40. package/dist/components/card.d.ts +38 -0
  41. package/dist/components/card.js +904 -0
  42. package/dist/components/carousel.d.ts +71 -0
  43. package/dist/components/carousel.js +585 -0
  44. package/dist/components/checkbox.d.ts +15 -0
  45. package/dist/components/checkbox.js +324 -0
  46. package/dist/components/control-button.d.ts +16 -0
  47. package/dist/components/control-button.js +215 -0
  48. package/dist/components/data-table.d.ts +118 -0
  49. package/dist/components/data-table.js +895 -0
  50. package/dist/components/dialog-surface.d.ts +49 -0
  51. package/dist/components/dialog-surface.js +220 -0
  52. package/dist/components/dialog.d.ts +92 -0
  53. package/dist/components/dialog.js +320 -0
  54. package/dist/components/dropdown-menu.d.ts +58 -0
  55. package/dist/components/dropdown-menu.js +135 -0
  56. package/dist/components/field.d.ts +53 -0
  57. package/dist/components/field.js +710 -0
  58. package/dist/components/file-upload.d.ts +88 -0
  59. package/dist/components/file-upload.js +776 -0
  60. package/dist/components/filter-presets-bar.d.ts +73 -0
  61. package/dist/components/filter-presets-bar.js +510 -0
  62. package/dist/components/filter-query-bar.d.ts +21 -0
  63. package/dist/components/filter-query-bar.js +881 -0
  64. package/dist/components/filter-query-grammar.d.ts +188 -0
  65. package/dist/components/filter-query-grammar.js +875 -0
  66. package/dist/components/form.d.ts +29 -0
  67. package/dist/components/form.js +330 -0
  68. package/dist/components/highlighter.d.ts +15 -0
  69. package/dist/components/highlighter.js +152 -0
  70. package/dist/components/hover-card.d.ts +50 -0
  71. package/dist/components/hover-card.js +80 -0
  72. package/dist/components/input-group.d.ts +16 -0
  73. package/dist/components/input-group.js +277 -0
  74. package/dist/components/input.d.ts +17 -0
  75. package/dist/components/input.js +120 -0
  76. package/dist/components/label.d.ts +4 -0
  77. package/dist/components/label.js +43 -0
  78. package/dist/components/link.d.ts +9 -0
  79. package/dist/components/link.js +43 -0
  80. package/dist/components/morph-text.d.ts +14 -0
  81. package/dist/components/morph-text.js +210 -0
  82. package/dist/components/pagination.d.ts +59 -0
  83. package/dist/components/pagination.js +190 -0
  84. package/dist/components/popover.d.ts +17 -0
  85. package/dist/components/popover.js +40 -0
  86. package/dist/components/presence-swap.d.ts +22 -0
  87. package/dist/components/presence-swap.js +209 -0
  88. package/dist/components/primitives/alert-dialog.d.ts +68 -0
  89. package/dist/components/primitives/alert-dialog.js +629 -0
  90. package/dist/components/primitives/avatar.d.ts +46 -0
  91. package/dist/components/primitives/avatar.js +265 -0
  92. package/dist/components/primitives/calendar.d.ts +37 -0
  93. package/dist/components/primitives/calendar.js +1250 -0
  94. package/dist/components/primitives/carousel.d.ts +106 -0
  95. package/dist/components/primitives/carousel.js +928 -0
  96. package/dist/components/primitives/dialog.d.ts +62 -0
  97. package/dist/components/primitives/dialog.js +490 -0
  98. package/dist/components/primitives/dropdown-menu-items.d.ts +59 -0
  99. package/dist/components/primitives/dropdown-menu-items.js +265 -0
  100. package/dist/components/primitives/dropdown-menu.d.ts +64 -0
  101. package/dist/components/primitives/dropdown-menu.js +560 -0
  102. package/dist/components/primitives/hover-card.d.ts +50 -0
  103. package/dist/components/primitives/hover-card.js +507 -0
  104. package/dist/components/primitives/pagination.d.ts +65 -0
  105. package/dist/components/primitives/pagination.js +373 -0
  106. package/dist/components/primitives/popover.d.ts +22 -0
  107. package/dist/components/primitives/popover.js +213 -0
  108. package/dist/components/primitives/select.d.ts +37 -0
  109. package/dist/components/primitives/select.js +428 -0
  110. package/dist/components/primitives/tooltip.d.ts +30 -0
  111. package/dist/components/primitives/tooltip.js +277 -0
  112. package/dist/components/progress-ring.d.ts +20 -0
  113. package/dist/components/progress-ring.js +53 -0
  114. package/dist/components/radio-group.d.ts +34 -0
  115. package/dist/components/radio-group.js +392 -0
  116. package/dist/components/reaction-button.d.ts +30 -0
  117. package/dist/components/reaction-button.js +189 -0
  118. package/dist/components/rich-link-editor.d.ts +25 -0
  119. package/dist/components/rich-link-editor.js +320 -0
  120. package/dist/components/rich-markdown-content.d.ts +10 -0
  121. package/dist/components/rich-markdown-content.js +56 -0
  122. package/dist/components/rich-text-content.d.ts +19 -0
  123. package/dist/components/rich-text-content.js +26 -0
  124. package/dist/components/select.d.ts +55 -0
  125. package/dist/components/select.js +188 -0
  126. package/dist/components/separator.d.ts +3 -0
  127. package/dist/components/separator.js +48 -0
  128. package/dist/components/sheet.d.ts +19 -0
  129. package/dist/components/sheet.js +420 -0
  130. package/dist/components/sidebar-panel-context.d.ts +17 -0
  131. package/dist/components/sidebar-panel-context.js +14 -0
  132. package/dist/components/sidebar.d.ts +195 -0
  133. package/dist/components/sidebar.js +2041 -0
  134. package/dist/components/skeleton.d.ts +23 -0
  135. package/dist/components/skeleton.js +334 -0
  136. package/dist/components/split-button.d.ts +36 -0
  137. package/dist/components/split-button.js +306 -0
  138. package/dist/components/svgs/whatsappIcon.d.ts +3 -0
  139. package/dist/components/svgs/whatsappIcon.js +14 -0
  140. package/dist/components/switch.d.ts +13 -0
  141. package/dist/components/switch.js +444 -0
  142. package/dist/components/table.d.ts +10 -0
  143. package/dist/components/table.js +298 -0
  144. package/dist/components/tabs.d.ts +36 -0
  145. package/dist/components/tabs.js +636 -0
  146. package/dist/components/textarea.d.ts +16 -0
  147. package/dist/components/textarea.js +111 -0
  148. package/dist/components/themed-toaster.d.ts +7 -0
  149. package/dist/components/themed-toaster.js +86 -0
  150. package/dist/components/toaster.d.ts +12 -0
  151. package/dist/components/toaster.js +62 -0
  152. package/dist/components/tooltip.d.ts +43 -0
  153. package/dist/components/tooltip.js +65 -0
  154. package/dist/components/typing-animation.d.ts +34 -0
  155. package/dist/components/typing-animation.js +389 -0
  156. package/dist/constants/action-button.d.ts +20 -0
  157. package/dist/constants/action-button.js +17 -0
  158. package/dist/constants/alert.d.ts +16 -0
  159. package/dist/constants/alert.js +13 -0
  160. package/dist/constants/avatar.d.ts +38 -0
  161. package/dist/constants/avatar.js +32 -0
  162. package/dist/constants/badge.d.ts +6 -0
  163. package/dist/constants/badge.js +6 -0
  164. package/dist/constants/button.d.ts +16 -0
  165. package/dist/constants/button.js +16 -0
  166. package/dist/constants/calendar.d.ts +36 -0
  167. package/dist/constants/calendar.js +34 -0
  168. package/dist/constants/card.d.ts +23 -0
  169. package/dist/constants/card.js +20 -0
  170. package/dist/constants/carousel.d.ts +55 -0
  171. package/dist/constants/carousel.js +74 -0
  172. package/dist/constants/checkbox.d.ts +17 -0
  173. package/dist/constants/checkbox.js +17 -0
  174. package/dist/constants/dialog.d.ts +11 -0
  175. package/dist/constants/dialog.js +10 -0
  176. package/dist/constants/dropdown-menu.d.ts +17 -0
  177. package/dist/constants/dropdown-menu.js +48 -0
  178. package/dist/constants/field.d.ts +24 -0
  179. package/dist/constants/field.js +24 -0
  180. package/dist/constants/hover-card.d.ts +37 -0
  181. package/dist/constants/hover-card.js +85 -0
  182. package/dist/constants/morph-text.d.ts +13 -0
  183. package/dist/constants/morph-text.js +13 -0
  184. package/dist/constants/motion.d.ts +12 -0
  185. package/dist/constants/motion.js +12 -0
  186. package/dist/constants/pagination.d.ts +20 -0
  187. package/dist/constants/pagination.js +20 -0
  188. package/dist/constants/popover.d.ts +7 -0
  189. package/dist/constants/popover.js +33 -0
  190. package/dist/constants/radio-group.d.ts +10 -0
  191. package/dist/constants/radio-group.js +10 -0
  192. package/dist/constants/select.d.ts +7 -0
  193. package/dist/constants/select.js +34 -0
  194. package/dist/constants/sidebar.d.ts +9 -0
  195. package/dist/constants/sidebar.js +17 -0
  196. package/dist/constants/skeleton.d.ts +17 -0
  197. package/dist/constants/skeleton.js +17 -0
  198. package/dist/constants/split-button.d.ts +7 -0
  199. package/dist/constants/split-button.js +5 -0
  200. package/dist/constants/switch.d.ts +33 -0
  201. package/dist/constants/switch.js +41 -0
  202. package/dist/constants/tabs.d.ts +17 -0
  203. package/dist/constants/tabs.js +17 -0
  204. package/dist/constants/toast.d.ts +3 -0
  205. package/dist/constants/toast.js +3 -0
  206. package/dist/constants/tooltip.d.ts +13 -0
  207. package/dist/constants/tooltip.js +52 -0
  208. package/dist/hooks/use-horizontal-swipe.d.ts +23 -0
  209. package/dist/hooks/use-horizontal-swipe.js +80 -0
  210. package/dist/hooks/use-is-hydrated.d.ts +6 -0
  211. package/dist/hooks/use-is-hydrated.js +20 -0
  212. package/dist/hooks/use-mobile.d.ts +1 -0
  213. package/dist/hooks/use-mobile.js +19 -0
  214. package/dist/hooks/use-prefers-reduced-motion.d.ts +2 -0
  215. package/dist/hooks/use-prefers-reduced-motion.js +27 -0
  216. package/dist/hooks/use-rich-link-editor.d.ts +55 -0
  217. package/dist/hooks/use-rich-link-editor.js +515 -0
  218. package/dist/hooks/use-sidebar-persistence.d.ts +6 -0
  219. package/dist/hooks/use-sidebar-persistence.js +52 -0
  220. package/dist/hooks/use-today.d.ts +7 -0
  221. package/dist/hooks/use-today.js +50 -0
  222. package/dist/hooks/use-viewer-time-zone.d.ts +6 -0
  223. package/dist/hooks/use-viewer-time-zone.js +20 -0
  224. package/dist/hooks.d.ts +11 -0
  225. package/dist/hooks.js +11 -0
  226. package/dist/index.d.ts +71 -0
  227. package/dist/index.js +69 -0
  228. package/dist/lib/browser-clipboard.d.ts +13 -0
  229. package/dist/lib/browser-clipboard.js +48 -0
  230. package/dist/lib/column-filter-value.d.ts +12 -0
  231. package/dist/lib/column-filter-value.js +52 -0
  232. package/dist/lib/file-acceptance.d.ts +43 -0
  233. package/dist/lib/file-acceptance.js +107 -0
  234. package/dist/lib/format-file-size.d.ts +16 -0
  235. package/dist/lib/format-file-size.js +34 -0
  236. package/dist/lib/fuzzy-search.d.ts +17 -0
  237. package/dist/lib/fuzzy-search.js +183 -0
  238. package/dist/lib/horizontal-swipe.d.ts +23 -0
  239. package/dist/lib/horizontal-swipe.js +29 -0
  240. package/dist/lib/image-dimensions.d.ts +2 -0
  241. package/dist/lib/image-dimensions.js +7 -0
  242. package/dist/lib/name-initials.d.ts +7 -0
  243. package/dist/lib/name-initials.js +11 -0
  244. package/dist/lib/rich-text/link-markdown-constants.d.ts +147 -0
  245. package/dist/lib/rich-text/link-markdown-constants.js +458 -0
  246. package/dist/lib/rich-text/link-markdown-types.d.ts +53 -0
  247. package/dist/lib/rich-text/link-markdown-types.js +1 -0
  248. package/dist/lib/rich-text/link-markdown.d.ts +193 -0
  249. package/dist/lib/rich-text/link-markdown.js +592 -0
  250. package/dist/lib/rich-text/rich-markdown.d.ts +41 -0
  251. package/dist/lib/rich-text/rich-markdown.js +105 -0
  252. package/dist/lib/rich-text/rich-text-editor-dom.d.ts +26 -0
  253. package/dist/lib/rich-text/rich-text-editor-dom.js +79 -0
  254. package/dist/lib/toast-layer.d.ts +24 -0
  255. package/dist/lib/toast-layer.js +76 -0
  256. package/dist/lib/utils.d.ts +2 -0
  257. package/dist/lib/utils.js +2 -0
  258. package/dist/lib/year-month-filter.d.ts +16 -0
  259. package/dist/lib/year-month-filter.js +46 -0
  260. package/dist/motion/arc-floating-slot.d.ts +40 -0
  261. package/dist/motion/arc-floating-slot.js +177 -0
  262. package/dist/motion/arc-press.d.ts +6 -0
  263. package/dist/motion/arc-press.js +59 -0
  264. package/dist/motion/arc-swap.d.ts +22 -0
  265. package/dist/motion/arc-swap.js +49 -0
  266. package/dist/motion/arc-tokens.d.ts +53 -0
  267. package/dist/motion/arc-tokens.js +73 -0
  268. package/dist/motion/glide-indicator.d.ts +69 -0
  269. package/dist/motion/glide-indicator.js +309 -0
  270. package/dist/motion/glide-slot.d.ts +9 -0
  271. package/dist/motion/glide-slot.js +71 -0
  272. package/dist/motion/motion-slot.d.ts +12 -0
  273. package/dist/motion/motion-slot.js +376 -0
  274. package/dist/motion/overlay-warmth.d.ts +24 -0
  275. package/dist/motion/overlay-warmth.js +70 -0
  276. package/dist/motion/presence.d.ts +40 -0
  277. package/dist/motion/presence.js +101 -0
  278. package/dist/motion/surface-keyframes.d.ts +24 -0
  279. package/dist/motion/surface-keyframes.js +141 -0
  280. package/dist/motion/tokens.d.ts +81 -0
  281. package/dist/motion/tokens.js +67 -0
  282. package/dist/motion/use-attached-element.d.ts +7 -0
  283. package/dist/motion/use-attached-element.js +22 -0
  284. package/dist/motion/use-morph-width.d.ts +13 -0
  285. package/dist/motion/use-morph-width.js +59 -0
  286. package/dist/next.d.ts +14 -0
  287. package/dist/next.js +79 -0
  288. package/dist/providers/astra-ui-provider.d.ts +27 -0
  289. package/dist/providers/astra-ui-provider.js +100 -0
  290. package/dist/providers/native-provider.d.ts +4 -0
  291. package/dist/providers/native-provider.js +45 -0
  292. package/dist/sonner.d.ts +7 -0
  293. package/dist/sonner.js +8 -0
  294. package/dist/styles.css +2 -0
  295. package/dist/tanstack.d.ts +11 -0
  296. package/dist/tanstack.js +50 -0
  297. package/dist/theme.d.ts +3 -0
  298. package/dist/theme.js +1 -0
  299. package/dist/types/data-table.d.ts +27 -0
  300. package/dist/types/data-table.js +1 -0
  301. package/fonts.css +5 -0
  302. package/package.json +450 -4
  303. package/styles.css +4 -0
  304. package/theme.css +248 -0
@@ -0,0 +1,503 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Arc's Alert (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): a persistent message that helps people
5
+ * recover or continue, on Arc's surface with a resting shadow. A `tone` tints and picks its icon, which morphs in
6
+ * place when the tone changes, and a new title or string detail rises in over the old one. `onDismiss` adds a dismiss
7
+ * button and `open` collapses the alert's height while it fades, so the content below closes the gap.
8
+ */
9
+ import { useRef, useState } from "react";
10
+ import { AnimatePresence, motion, useIsPresent } from "motion/react";
11
+ import { Check, CircleX, Info, TriangleAlert, X } from "lucide-react";
12
+ import { ALERT_DISMISS_LABEL, ALERT_DISMISS_LABEL_SEPARATOR, ALERT_TEXT_OFFSET_EM, ALERT_TONE_ROLE } from "../constants/alert.js";
13
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
14
+ import { cn } from "../lib/utils.js";
15
+ import { ARC_BLUR, ARC_DURATION, ARC_EASE, ARC_SPRING_SMOOTH } from "../motion/arc-tokens.js";
16
+ import { ARC_ICON_ENTER, ARC_ICON_EXIT, ARC_ICON_TRANSITION, ARC_REDUCED_EXIT, ARC_REDUCED_TRANSITION, ARC_SWAP_EXIT_TRANSITION, ARC_SWAP_REST } from "../motion/arc-swap.js";
17
+ import { useAttachedElement } from "../motion/use-attached-element.js";
18
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
19
+ /** The icon each tone shows unless `icon` replaces it. */
20
+ const TONE_ICON = {
21
+ info: Info,
22
+ success: Check,
23
+ warning: TriangleAlert,
24
+ danger: CircleX
25
+ };
26
+ /** Colour of the icon for each tone. */
27
+ const TONE_ICON_CLASS_NAME = {
28
+ info: "text-(--accent)",
29
+ success: "text-success",
30
+ warning: "text-warning",
31
+ danger: "text-danger"
32
+ };
33
+ const reducedEnter = { opacity: 0 };
34
+ /** A new title or detail rises out of a soft blur; the old one lifts away faster. */
35
+ const textEnter = {
36
+ opacity: 0,
37
+ y: `${ALERT_TEXT_OFFSET_EM}em`,
38
+ filter: `blur(${ARC_BLUR.soft}px)`
39
+ };
40
+ const textExit = {
41
+ opacity: 0,
42
+ y: `${-ALERT_TEXT_OFFSET_EM}em`,
43
+ filter: `blur(${ARC_BLUR.subtle}px)`,
44
+ transition: ARC_SWAP_EXIT_TRANSITION
45
+ };
46
+ const textTransition = {
47
+ duration: ARC_DURATION.standard,
48
+ ease: [...ARC_EASE.enter]
49
+ };
50
+ const presenceTransition = {
51
+ height: ARC_SPRING_SMOOTH,
52
+ opacity: {
53
+ duration: ARC_DURATION.standard,
54
+ ease: [...ARC_EASE.enter]
55
+ }
56
+ };
57
+ /** The alert itself collapses, so its padding, border and margins close along with the height. */
58
+ const collapsedBox = {
59
+ height: 0,
60
+ paddingTop: 0,
61
+ paddingBottom: 0,
62
+ borderTopWidth: 0,
63
+ borderBottomWidth: 0,
64
+ marginTop: 0,
65
+ marginBottom: 0
66
+ };
67
+ const presenceExit = {
68
+ ...collapsedBox,
69
+ opacity: 0,
70
+ transition: {
71
+ default: ARC_SPRING_SMOOTH,
72
+ opacity: ARC_SWAP_EXIT_TRANSITION
73
+ }
74
+ };
75
+ const reducedPresenceExit = {
76
+ ...collapsedBox,
77
+ opacity: 0,
78
+ transition: { duration: 0 }
79
+ };
80
+ /** Entrance target; once it settles, the alert hands height and opacity back to the consumer's classes and style. */
81
+ const presenceEnter = {
82
+ height: "auto",
83
+ opacity: 1
84
+ };
85
+ /**
86
+ * Converts a consumer style value into the inline string React would write.
87
+ * @param value - The consumer's style value, if any.
88
+ * @param unit - Unit appended to numbers, as React does for lengths.
89
+ * @returns The inline value, or an empty string to fall back to the stylesheet.
90
+ */
91
+ function toInlineStyleValue(value, unit = "") {
92
+ if (value === undefined) return "";
93
+ return typeof value === "number" ? `${value}${unit}` : value;
94
+ }
95
+ /** Outgoing copies are hidden from assistive technology while they fade, so the live region reads only the current one. */
96
+ function AlertSwap(props) {
97
+ const $ = _c(3);
98
+ const isPresent = useIsPresent();
99
+ const t0 = isPresent ? props["aria-hidden"] : true;
100
+ let t1;
101
+ if ($[0] !== props || $[1] !== t0) {
102
+ t1 = /* @__PURE__ */ _jsx(motion.span, {
103
+ ...props,
104
+ "aria-hidden": t0
105
+ });
106
+ $[0] = props;
107
+ $[1] = t0;
108
+ $[2] = t1;
109
+ } else {
110
+ t1 = $[2];
111
+ }
112
+ return t1;
113
+ }
114
+ /** A line of copy that rises in over the previous one when it changes. */
115
+ function AlertText(t0) {
116
+ const $ = _c(5);
117
+ const { text, reduceMotion } = t0;
118
+ const t1 = reduceMotion ? reducedEnter : textEnter;
119
+ const t2 = reduceMotion ? ARC_REDUCED_EXIT : textExit;
120
+ const t3 = reduceMotion ? ARC_REDUCED_TRANSITION : textTransition;
121
+ let t4;
122
+ if ($[0] !== t1 || $[1] !== t2 || $[2] !== t3 || $[3] !== text) {
123
+ t4 = /* @__PURE__ */ _jsx(AnimatePresence, {
124
+ mode: "popLayout",
125
+ initial: false,
126
+ children: /* @__PURE__ */ _jsx(AlertSwap, {
127
+ className: "relative block",
128
+ initial: t1,
129
+ animate: ARC_SWAP_REST,
130
+ exit: t2,
131
+ transition: t3,
132
+ children: text
133
+ }, text)
134
+ });
135
+ $[0] = t1;
136
+ $[1] = t2;
137
+ $[2] = t3;
138
+ $[3] = text;
139
+ $[4] = t4;
140
+ } else {
141
+ t4 = $[4];
142
+ }
143
+ return t4;
144
+ }
145
+ /** The tone icon: a new tone morphs its icon in place. */
146
+ function AlertIcon(t0) {
147
+ const $ = _c(11);
148
+ const { icon, iconKey, tone, reduceMotion } = t0;
149
+ const t1 = TONE_ICON_CLASS_NAME[tone];
150
+ let t2;
151
+ if ($[0] !== t1) {
152
+ t2 = cn("relative mt-px grid size-[18px] flex-none place-items-center [&_svg]:block [&_svg:not([class*='size-'])]:size-[18px]", t1);
153
+ $[0] = t1;
154
+ $[1] = t2;
155
+ } else {
156
+ t2 = $[1];
157
+ }
158
+ const t3 = reduceMotion ? reducedEnter : ARC_ICON_ENTER;
159
+ const t4 = reduceMotion ? ARC_REDUCED_EXIT : ARC_ICON_EXIT;
160
+ const t5 = reduceMotion ? ARC_REDUCED_TRANSITION : ARC_ICON_TRANSITION;
161
+ let t6;
162
+ if ($[2] !== icon || $[3] !== iconKey || $[4] !== t3 || $[5] !== t4 || $[6] !== t5) {
163
+ t6 = /* @__PURE__ */ _jsx(AnimatePresence, {
164
+ mode: "popLayout",
165
+ initial: false,
166
+ children: /* @__PURE__ */ _jsx(AlertSwap, {
167
+ className: "relative grid place-items-center",
168
+ initial: t3,
169
+ animate: ARC_SWAP_REST,
170
+ exit: t4,
171
+ transition: t5,
172
+ children: icon
173
+ }, iconKey)
174
+ });
175
+ $[2] = icon;
176
+ $[3] = iconKey;
177
+ $[4] = t3;
178
+ $[5] = t4;
179
+ $[6] = t5;
180
+ $[7] = t6;
181
+ } else {
182
+ t6 = $[7];
183
+ }
184
+ let t7;
185
+ if ($[8] !== t2 || $[9] !== t6) {
186
+ t7 = /* @__PURE__ */ _jsx("span", {
187
+ "data-slot": "alert-icon",
188
+ "aria-hidden": "true",
189
+ className: t2,
190
+ children: t6
191
+ });
192
+ $[8] = t2;
193
+ $[9] = t6;
194
+ $[10] = t7;
195
+ } else {
196
+ t7 = $[10];
197
+ }
198
+ return t7;
199
+ }
200
+ /** Arc's alert surface: icon, copy column, optional action and dismiss button in one row. */
201
+ const alertClassName = "group/alert relative flex w-full min-w-0 items-start gap-(--space-3) rounded-(--radius-control) border border-border bg-surface p-(--space-4) text-left text-sm text-foreground shadow-(--shadow-resting)";
202
+ /** The alert surface itself. */
203
+ function AlertBox(t0) {
204
+ const $ = _c(60);
205
+ let action;
206
+ let children;
207
+ let className;
208
+ let dismissLabel;
209
+ let icon;
210
+ let onDismiss;
211
+ let presence;
212
+ let props;
213
+ let reduceMotion;
214
+ let t1;
215
+ let title;
216
+ if ($[0] !== t0) {
217
+ ({className, title, tone: t1, icon, action, onDismiss, dismissLabel, reduceMotion, presence, children, ...props} = t0);
218
+ $[0] = t0;
219
+ $[1] = action;
220
+ $[2] = children;
221
+ $[3] = className;
222
+ $[4] = dismissLabel;
223
+ $[5] = icon;
224
+ $[6] = onDismiss;
225
+ $[7] = presence;
226
+ $[8] = props;
227
+ $[9] = reduceMotion;
228
+ $[10] = t1;
229
+ $[11] = title;
230
+ } else {
231
+ action = $[1];
232
+ children = $[2];
233
+ className = $[3];
234
+ dismissLabel = $[4];
235
+ icon = $[5];
236
+ onDismiss = $[6];
237
+ presence = $[7];
238
+ props = $[8];
239
+ reduceMotion = $[9];
240
+ t1 = $[10];
241
+ title = $[11];
242
+ }
243
+ const tone = t1 === undefined ? "info" : t1;
244
+ const isPresent = useIsPresent();
245
+ const ToneIcon = TONE_ICON[tone];
246
+ let t2;
247
+ if ($[12] !== ToneIcon || $[13] !== icon) {
248
+ t2 = icon === false ? null : icon ?? /* @__PURE__ */ _jsx(ToneIcon, { "aria-hidden": "true" });
249
+ $[12] = ToneIcon;
250
+ $[13] = icon;
251
+ $[14] = t2;
252
+ } else {
253
+ t2 = $[14];
254
+ }
255
+ const resolvedIcon = t2;
256
+ const details = typeof children === "string" || typeof children === "number" ? String(children) : null;
257
+ const hasDetails = children !== undefined && children !== null && children !== false && children !== "";
258
+ const t3 = ALERT_TONE_ROLE[tone];
259
+ let t4;
260
+ if ($[15] !== className) {
261
+ t4 = cn(alertClassName, className);
262
+ $[15] = className;
263
+ $[16] = t4;
264
+ } else {
265
+ t4 = $[16];
266
+ }
267
+ let t5;
268
+ if ($[17] !== props || $[18] !== t3 || $[19] !== t4 || $[20] !== tone) {
269
+ t5 = {
270
+ "data-slot": "alert",
271
+ "data-tone": tone,
272
+ role: t3,
273
+ className: t4,
274
+ ...props
275
+ };
276
+ $[17] = props;
277
+ $[18] = t3;
278
+ $[19] = t4;
279
+ $[20] = tone;
280
+ $[21] = t5;
281
+ } else {
282
+ t5 = $[21];
283
+ }
284
+ const rootProps = t5;
285
+ let t6;
286
+ if ($[22] !== icon || $[23] !== reduceMotion || $[24] !== resolvedIcon || $[25] !== tone) {
287
+ t6 = resolvedIcon ? /* @__PURE__ */ _jsx(AlertIcon, {
288
+ icon: resolvedIcon,
289
+ iconKey: icon ? "custom" : tone,
290
+ tone,
291
+ reduceMotion
292
+ }) : null;
293
+ $[22] = icon;
294
+ $[23] = reduceMotion;
295
+ $[24] = resolvedIcon;
296
+ $[25] = tone;
297
+ $[26] = t6;
298
+ } else {
299
+ t6 = $[26];
300
+ }
301
+ let t7;
302
+ if ($[27] !== reduceMotion || $[28] !== title) {
303
+ t7 = /* @__PURE__ */ _jsx("strong", {
304
+ "data-slot": "alert-title",
305
+ className: "relative block text-sm font-medium",
306
+ children: /* @__PURE__ */ _jsx(AlertText, {
307
+ text: title,
308
+ reduceMotion
309
+ })
310
+ });
311
+ $[27] = reduceMotion;
312
+ $[28] = title;
313
+ $[29] = t7;
314
+ } else {
315
+ t7 = $[29];
316
+ }
317
+ let t8;
318
+ if ($[30] !== children || $[31] !== details || $[32] !== hasDetails || $[33] !== reduceMotion) {
319
+ t8 = hasDetails ? /* @__PURE__ */ _jsx("div", {
320
+ "data-slot": "alert-description",
321
+ className: "relative text-xs leading-(--leading-body) text-pretty text-text-secondary [&_a]:underline [&_a]:underline-offset-3 [&_a]:hover-fine:text-foreground [&_p:not(:last-child)]:mb-4",
322
+ children: details === null ? children : /* @__PURE__ */ _jsx(AlertText, {
323
+ text: details,
324
+ reduceMotion
325
+ })
326
+ }) : null;
327
+ $[30] = children;
328
+ $[31] = details;
329
+ $[32] = hasDetails;
330
+ $[33] = reduceMotion;
331
+ $[34] = t8;
332
+ } else {
333
+ t8 = $[34];
334
+ }
335
+ let t9;
336
+ if ($[35] !== t7 || $[36] !== t8) {
337
+ t9 = /* @__PURE__ */ _jsxs("div", {
338
+ "data-slot": "alert-copy",
339
+ className: "grid min-w-0 flex-[1_1_8rem] gap-(--space-1)",
340
+ children: [t7, t8]
341
+ });
342
+ $[35] = t7;
343
+ $[36] = t8;
344
+ $[37] = t9;
345
+ } else {
346
+ t9 = $[37];
347
+ }
348
+ let t10;
349
+ if ($[38] !== action) {
350
+ t10 = action ? /* @__PURE__ */ _jsx("div", {
351
+ "data-slot": "alert-action",
352
+ className: "flex flex-none flex-wrap items-center gap-(--space-2) self-start",
353
+ children: action
354
+ }) : null;
355
+ $[38] = action;
356
+ $[39] = t10;
357
+ } else {
358
+ t10 = $[39];
359
+ }
360
+ let t11;
361
+ if ($[40] !== t10 || $[41] !== t9) {
362
+ t11 = /* @__PURE__ */ _jsxs("div", {
363
+ className: "flex min-w-0 flex-1 flex-wrap items-start gap-(--space-3)",
364
+ children: [t9, t10]
365
+ });
366
+ $[40] = t10;
367
+ $[41] = t9;
368
+ $[42] = t11;
369
+ } else {
370
+ t11 = $[42];
371
+ }
372
+ let t12;
373
+ if ($[43] !== dismissLabel || $[44] !== onDismiss || $[45] !== title) {
374
+ t12 = onDismiss ? /* @__PURE__ */ _jsx("button", {
375
+ type: "button",
376
+ "data-slot": "alert-dismiss",
377
+ "aria-label": dismissLabel ?? `${ALERT_DISMISS_LABEL}${ALERT_DISMISS_LABEL_SEPARATOR}${title}`,
378
+ onClick: onDismiss,
379
+ className: "-my-[5px] -mr-1.5 grid size-7 flex-none cursor-pointer place-items-center rounded-(--radius-pill) border-0 bg-transparent text-text-muted [-webkit-tap-highlight-color:transparent] transition-[scale,background-color,color] duration-(--duration-fast) ease-(--ease-standard) hover-fine:bg-surface-muted hover-fine:text-foreground active:scale-[.96] motion-reduce:transition-none motion-reduce:active:scale-100",
380
+ children: /* @__PURE__ */ _jsx(X, {
381
+ className: "size-4",
382
+ strokeWidth: 1.75,
383
+ "aria-hidden": "true"
384
+ })
385
+ }) : null;
386
+ $[43] = dismissLabel;
387
+ $[44] = onDismiss;
388
+ $[45] = title;
389
+ $[46] = t12;
390
+ } else {
391
+ t12 = $[46];
392
+ }
393
+ let t13;
394
+ if ($[47] !== t11 || $[48] !== t12 || $[49] !== t6) {
395
+ t13 = /* @__PURE__ */ _jsxs(_Fragment, { children: [
396
+ t6,
397
+ t11,
398
+ t12
399
+ ] });
400
+ $[47] = t11;
401
+ $[48] = t12;
402
+ $[49] = t6;
403
+ $[50] = t13;
404
+ } else {
405
+ t13 = $[50];
406
+ }
407
+ const content = t13;
408
+ if (presence) {
409
+ const t14 = rootProps;
410
+ const t15 = isPresent ? rootProps["aria-hidden"] : true;
411
+ const t16 = !isPresent || rootProps.inert;
412
+ let t17;
413
+ if ($[51] !== content || $[52] !== presence || $[53] !== t14 || $[54] !== t15 || $[55] !== t16) {
414
+ t17 = /* @__PURE__ */ _jsx(motion.div, {
415
+ ...t14,
416
+ ...presence,
417
+ "aria-hidden": t15,
418
+ inert: t16,
419
+ children: content
420
+ });
421
+ $[51] = content;
422
+ $[52] = presence;
423
+ $[53] = t14;
424
+ $[54] = t15;
425
+ $[55] = t16;
426
+ $[56] = t17;
427
+ } else {
428
+ t17 = $[56];
429
+ }
430
+ return t17;
431
+ }
432
+ let t14;
433
+ if ($[57] !== content || $[58] !== rootProps) {
434
+ t14 = /* @__PURE__ */ _jsx("div", {
435
+ ...rootProps,
436
+ children: content
437
+ });
438
+ $[57] = content;
439
+ $[58] = rootProps;
440
+ $[59] = t14;
441
+ } else {
442
+ t14 = $[59];
443
+ }
444
+ return t14;
445
+ }
446
+ /**
447
+ * A persistent, in-flow message with a tone icon, a title and optional details, action and dismissal.
448
+ * @param props - Title, tone, details, presence and dismissal, extensions and native div attributes.
449
+ * @returns The alert; with `open` or `onDismiss` it collapses its own height when hidden.
450
+ */
451
+ function Alert({ open, onDismiss, ref: consumerRef, ...props }) {
452
+ const reduceMotion = usePrefersReducedMotion();
453
+ const [isDismissed, setIsDismissed] = useState(false);
454
+ const [presenceElement, attachPresence] = useAttachedElement(consumerRef);
455
+ const restingOverflow = useRef(undefined);
456
+ const clipPresence = () => {
457
+ if (!presenceElement) return;
458
+ restingOverflow.current ??= presenceElement.style.overflow;
459
+ presenceElement.style.overflow = "hidden";
460
+ };
461
+ const settlePresence = (definition) => {
462
+ if (!presenceElement) return;
463
+ if (restingOverflow.current !== undefined) presenceElement.style.overflow = restingOverflow.current;
464
+ restingOverflow.current = undefined;
465
+ if (definition === presenceEnter) {
466
+ presenceElement.style.height = toInlineStyleValue(props.style?.height, "px");
467
+ presenceElement.style.opacity = toInlineStyleValue(props.style?.opacity);
468
+ }
469
+ };
470
+ if (open === undefined && !onDismiss) {
471
+ return /* @__PURE__ */ _jsx(AlertBox, {
472
+ ...props,
473
+ ref: consumerRef,
474
+ reduceMotion
475
+ });
476
+ }
477
+ const isOpen = open ?? !isDismissed;
478
+ const dismiss = onDismiss && (() => open === undefined ? setIsDismissed(true) : onDismiss());
479
+ return /* @__PURE__ */ _jsx(AnimatePresence, {
480
+ initial: false,
481
+ onExitComplete: () => {
482
+ if (open === undefined) onDismiss?.();
483
+ },
484
+ children: isOpen ? /* @__PURE__ */ _jsx(AlertBox, {
485
+ ...props,
486
+ onDismiss: dismiss,
487
+ reduceMotion,
488
+ presence: {
489
+ ref: attachPresence,
490
+ initial: {
491
+ height: 0,
492
+ opacity: 0
493
+ },
494
+ animate: presenceEnter,
495
+ exit: reduceMotion ? reducedPresenceExit : presenceExit,
496
+ transition: reduceMotion ? { duration: 0 } : presenceTransition,
497
+ onAnimationStart: clipPresence,
498
+ onAnimationComplete: settlePresence
499
+ }
500
+ }, "alert") : null
501
+ });
502
+ }
503
+ export { Alert };
@@ -0,0 +1,19 @@
1
+ /** Expands and collapses a region by animating its height, then releases overflow. */
2
+ import { type ReactNode } from "react";
3
+ export interface AnimatedCollapseProps {
4
+ /** Whether the region is rendered and expanded. */
5
+ isOpen: boolean;
6
+ children: ReactNode;
7
+ className?: string;
8
+ id?: string;
9
+ /** Animate the very first render too; off by default so SSR output stays visible. */
10
+ animateOnMount?: boolean;
11
+ }
12
+ /**
13
+ * Renders `children` only while `isOpen`, animating height and opacity.
14
+ * Keep padding inside `children`: the animated wrapper collapses to zero height.
15
+ * Overflow is clipped only while animating, so focus rings and popovers are not cut once settled.
16
+ * @param props - Open state, content and optional wrapper attributes.
17
+ * @returns The animated region, or nothing when closed.
18
+ */
19
+ export declare function AnimatedCollapse({ isOpen, children, className, id, animateOnMount }: AnimatedCollapseProps): import("react").JSX.Element;
@@ -0,0 +1,170 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /** Expands and collapses a region by animating its height, then releases overflow. */
4
+ import { useState } from "react";
5
+ import { AnimatePresence, motion, useIsPresent } from "motion/react";
6
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
7
+ import { cn } from "../lib/utils.js";
8
+ import { MOTION_EASE, MOTION_EASE_STANDARD, MOTION_TIMING, SPRING_PANEL } from "../motion/tokens.js";
9
+ import { jsx as _jsx } from "react/jsx-runtime";
10
+ /** Arc's accordion: the height springs without overshoot while the content fades in. */
11
+ const COLLAPSE_TRANSITION = {
12
+ height: SPRING_PANEL,
13
+ opacity: {
14
+ duration: MOTION_TIMING.panel,
15
+ ease: MOTION_EASE
16
+ }
17
+ };
18
+ /** Arc's accordion closes on the same spring and fades out faster than it came in. */
19
+ const COLLAPSE_EXIT_TRANSITION = {
20
+ height: SPRING_PANEL,
21
+ opacity: {
22
+ duration: MOTION_TIMING.fast,
23
+ ease: MOTION_EASE_STANDARD
24
+ }
25
+ };
26
+ /** Reduced motion applies the height at once but keeps the short fade, so exits always settle. */
27
+ const REDUCED_MOTION_COLLAPSE_TRANSITION = {
28
+ height: { duration: 0 },
29
+ opacity: {
30
+ duration: MOTION_TIMING.panel,
31
+ ease: MOTION_EASE
32
+ }
33
+ };
34
+ /**
35
+ * The animated region. While it collapses out it turns inert and hidden from assistive
36
+ * technology, so stale controls cannot be clicked, focused or announced during the fade.
37
+ * @param props - Content, optional wrapper attributes and whether it mounts with an entrance.
38
+ * @returns The animated region.
39
+ */
40
+ function AnimatedCollapseRegion(t0) {
41
+ const $ = _c(17);
42
+ const { children, className, id, isEntering } = t0;
43
+ const [isSettled, setIsSettled] = useState(!isEntering);
44
+ const isPresent = useIsPresent();
45
+ const shouldReduceMotion = usePrefersReducedMotion();
46
+ const t1 = isPresent ? undefined : true;
47
+ const t2 = !isPresent || undefined;
48
+ const t3 = isSettled ? "overflow-visible" : "overflow-hidden";
49
+ let t4;
50
+ if ($[0] !== className || $[1] !== t3) {
51
+ t4 = cn(t3, className);
52
+ $[0] = className;
53
+ $[1] = t3;
54
+ $[2] = t4;
55
+ } else {
56
+ t4 = $[2];
57
+ }
58
+ let t5;
59
+ let t6;
60
+ if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
61
+ t5 = {
62
+ height: 0,
63
+ opacity: 0
64
+ };
65
+ t6 = {
66
+ height: "auto",
67
+ opacity: 1
68
+ };
69
+ $[3] = t5;
70
+ $[4] = t6;
71
+ } else {
72
+ t5 = $[3];
73
+ t6 = $[4];
74
+ }
75
+ const t7 = shouldReduceMotion ? REDUCED_MOTION_COLLAPSE_TRANSITION : COLLAPSE_EXIT_TRANSITION;
76
+ let t8;
77
+ if ($[5] !== t7) {
78
+ t8 = {
79
+ height: 0,
80
+ opacity: 0,
81
+ transition: t7
82
+ };
83
+ $[5] = t7;
84
+ $[6] = t8;
85
+ } else {
86
+ t8 = $[6];
87
+ }
88
+ const t9 = shouldReduceMotion ? REDUCED_MOTION_COLLAPSE_TRANSITION : COLLAPSE_TRANSITION;
89
+ let t10;
90
+ let t11;
91
+ if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
92
+ t10 = () => setIsSettled(false);
93
+ t11 = () => setIsSettled(true);
94
+ $[7] = t10;
95
+ $[8] = t11;
96
+ } else {
97
+ t10 = $[7];
98
+ t11 = $[8];
99
+ }
100
+ let t12;
101
+ if ($[9] !== children || $[10] !== id || $[11] !== t1 || $[12] !== t2 || $[13] !== t4 || $[14] !== t8 || $[15] !== t9) {
102
+ t12 = /* @__PURE__ */ _jsx(motion.div, {
103
+ "data-slot": "animated-collapse",
104
+ id,
105
+ "aria-hidden": t1,
106
+ inert: t2,
107
+ className: t4,
108
+ initial: t5,
109
+ animate: t6,
110
+ exit: t8,
111
+ transition: t9,
112
+ onAnimationStart: t10,
113
+ onAnimationComplete: t11,
114
+ children
115
+ });
116
+ $[9] = children;
117
+ $[10] = id;
118
+ $[11] = t1;
119
+ $[12] = t2;
120
+ $[13] = t4;
121
+ $[14] = t8;
122
+ $[15] = t9;
123
+ $[16] = t12;
124
+ } else {
125
+ t12 = $[16];
126
+ }
127
+ return t12;
128
+ }
129
+ /**
130
+ * Renders `children` only while `isOpen`, animating height and opacity.
131
+ * Keep padding inside `children`: the animated wrapper collapses to zero height.
132
+ * Overflow is clipped only while animating, so focus rings and popovers are not cut once settled.
133
+ * @param props - Open state, content and optional wrapper attributes.
134
+ * @returns The animated region, or nothing when closed.
135
+ */
136
+ export function AnimatedCollapse(t0) {
137
+ const $ = _c(9);
138
+ const { isOpen, children, className, id, animateOnMount: t1 } = t0;
139
+ const animateOnMount = t1 === undefined ? false : t1;
140
+ let t2;
141
+ if ($[0] !== animateOnMount || $[1] !== children || $[2] !== className || $[3] !== id || $[4] !== isOpen) {
142
+ t2 = isOpen ? /* @__PURE__ */ _jsx(AnimatedCollapseRegion, {
143
+ className,
144
+ id,
145
+ isEntering: animateOnMount,
146
+ children
147
+ }, "animated-collapse") : null;
148
+ $[0] = animateOnMount;
149
+ $[1] = children;
150
+ $[2] = className;
151
+ $[3] = id;
152
+ $[4] = isOpen;
153
+ $[5] = t2;
154
+ } else {
155
+ t2 = $[5];
156
+ }
157
+ let t3;
158
+ if ($[6] !== animateOnMount || $[7] !== t2) {
159
+ t3 = /* @__PURE__ */ _jsx(AnimatePresence, {
160
+ initial: animateOnMount,
161
+ children: t2
162
+ });
163
+ $[6] = animateOnMount;
164
+ $[7] = t2;
165
+ $[8] = t3;
166
+ } else {
167
+ t3 = $[8];
168
+ }
169
+ return t3;
170
+ }
@@ -0,0 +1,13 @@
1
+ export interface AnimatedCountProps {
2
+ value: number;
3
+ /** Optional formatter, for example a locale-aware number format. */
4
+ format?: (value: number) => string;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Renders `value` and animates each change: increments roll up, decrements roll down.
9
+ * With reduced motion the new value replaces the previous one without travel.
10
+ * @param props - Current value, optional formatter and class name.
11
+ * @returns The animated number.
12
+ */
13
+ export declare function AnimatedCount({ value, format, className }: AnimatedCountProps): import("react").JSX.Element;