@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,392 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Arc's RadioGroup (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md) on Radix's radio group: a fieldset
5
+ * whose legend names the choice and whose options render as Arc's rows. The mark dips on press, previews a faint dot
6
+ * while held, and the new dot springs in while the old one shrinks away; one highlight travels to the chosen row on
7
+ * the morph spring, so a change reads as a single physical move. Arrow keys take the same path.
8
+ */
9
+ import { createContext, useContext, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
10
+ import { RadioGroup as RadioGroupPrimitive } from "radix-ui";
11
+ import { animate, motion } from "motion/react";
12
+ import { RADIO_GROUP_DOT_HIDDEN_SCALE, RADIO_GROUP_OPTION_ID_SUFFIX, RADIO_GROUP_READY_ATTRIBUTE } from "../constants/radio-group.js";
13
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
14
+ import { cn } from "../lib/utils.js";
15
+ import { ARC_DURATION, ARC_SPRING_MORPH, ARC_SPRING_SNAPPY } from "../motion/arc-tokens.js";
16
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
17
+ /** Selector of the option row that holds the checked radio. */
18
+ const CHECKED_OPTION_SELECTOR = "[data-slot=\"radio-group-option\"]:has([data-slot=\"radio-group-item\"][data-state=\"checked\"])";
19
+ /** Selector of every option row, observed so the highlight follows rows that resize. */
20
+ const OPTION_SELECTOR = "[data-slot=\"radio-group-option\"]";
21
+ /** The value chosen in the enclosing group, read by each option to spring its dot in or out. */
22
+ const RadioGroupValueContext = createContext(undefined);
23
+ /**
24
+ * Sizes the highlight to the chosen row. A new choice glides on the morph spring; the first paint and resizes place it
25
+ * at once, and a group without a chosen row hides it.
26
+ * @param highlight - The travelling highlight element.
27
+ * @param row - The checked option row, if any.
28
+ * @param placedAt - Geometry the highlight was last placed at; updated in place.
29
+ * @param shouldGlide - Whether this change should travel instead of jumping.
30
+ */
31
+ function placeHighlight(highlight, row, placedAt, shouldGlide) {
32
+ const nextGeometry = row ? `${row.offsetLeft} ${row.offsetTop} ${row.offsetWidth} ${row.offsetHeight}` : "";
33
+ if (!highlight || nextGeometry === placedAt.current) return;
34
+ const wasVisible = placedAt.current !== "";
35
+ placedAt.current = nextGeometry;
36
+ if (!row) {
37
+ animate(highlight, { opacity: 0 }, { duration: 0 });
38
+ return;
39
+ }
40
+ const target = {
41
+ x: row.offsetLeft,
42
+ y: row.offsetTop,
43
+ width: row.offsetWidth,
44
+ height: row.offsetHeight,
45
+ opacity: 1
46
+ };
47
+ if (shouldGlide && wasVisible) {
48
+ animate(highlight, target, {
49
+ ...ARC_SPRING_MORPH,
50
+ opacity: { duration: 0 }
51
+ });
52
+ return;
53
+ }
54
+ Object.assign(highlight.style, {
55
+ transform: `translateX(${target.x}px) translateY(${target.y}px)`,
56
+ width: `${target.width}px`,
57
+ height: `${target.height}px`,
58
+ opacity: "1"
59
+ });
60
+ animate(highlight, target, { duration: 0 });
61
+ }
62
+ /**
63
+ * Arc's mark recipe: the faint preview dot and the press dip answer the whole row.
64
+ */
65
+ const radioGroupItemClassName = "peer group/radio-group-item relative z-2 grid aspect-square size-[17px] shrink-0 cursor-pointer place-items-center rounded-full border border-border-strong bg-transparent p-0 [-webkit-tap-highlight-color:transparent] [transition:border-color_var(--duration-fast)_var(--ease-standard),background-color_var(--duration-fast)_var(--ease-standard),scale_var(--duration-spring)_var(--ease-spring)] before:size-[7px] before:rounded-full before:bg-foreground before:opacity-0 before:transition-opacity before:duration-(--duration-instant) before:ease-(--ease-standard) before:[grid-area:1/1] before:content-[''] disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:border-(--control-on) data-[state=checked]:bg-(--control-on) aria-invalid:data-[state=unchecked]:border-danger hover-fine:data-[state=unchecked]:not-disabled:border-text-muted active:not-disabled:scale-[.88] active:not-disabled:[transition:border-color_var(--duration-fast)_var(--ease-standard),background-color_var(--duration-fast)_var(--ease-standard),scale_100ms_var(--ease-standard)] active:not-disabled:data-[state=unchecked]:before:opacity-[.22] group-active/radio-group-option:not-disabled:scale-[.88] group-active/radio-group-option:not-disabled:data-[state=unchecked]:before:opacity-[.22] motion-reduce:scale-100 motion-reduce:transition-none motion-reduce:before:transition-none";
66
+ /** Arc's option row: answers a press with color only, while the mark is what moves. */
67
+ const optionClassName = "group/radio-group-option relative flex cursor-pointer items-center gap-(--space-3) rounded-(--radius-control) border border-border p-(--space-3) [-webkit-tap-highlight-color:transparent] transition-[background-color,border-color] duration-(--duration-fast) ease-(--ease-standard) hover-fine:bg-surface-muted active:bg-surface-muted has-disabled:cursor-not-allowed has-disabled:opacity-50 [[data-slot=radio-group]:not([data-ready])_&]:has-data-[state=checked]:border-(--control-on) [[data-slot=radio-group]:not([data-ready])_&]:has-data-[state=checked]:bg-[color-mix(in_oklab,var(--control-on)_5%,transparent)] motion-reduce:transition-none";
68
+ /**
69
+ * One option row: the radio mark and its copy.
70
+ * @param option - The option to render.
71
+ * @returns The row, a label that activates its radio.
72
+ */
73
+ function RadioGroupOptionRow(t0) {
74
+ const $ = _c(26);
75
+ const { value, label, description, disabled } = t0;
76
+ const rowId = useId();
77
+ const labelId = `${rowId}-${RADIO_GROUP_OPTION_ID_SUFFIX.label}`;
78
+ const descriptionId = `${rowId}-${RADIO_GROUP_OPTION_ID_SUFFIX.description}`;
79
+ const reduceMotion = usePrefersReducedMotion();
80
+ const isChecked = useContext(RadioGroupValueContext) === value;
81
+ const t1 = description ? descriptionId : undefined;
82
+ let t2;
83
+ if ($[0] !== isChecked) {
84
+ t2 = isChecked ? {
85
+ scale: 1,
86
+ opacity: 1
87
+ } : {
88
+ scale: RADIO_GROUP_DOT_HIDDEN_SCALE,
89
+ opacity: 0
90
+ };
91
+ $[0] = isChecked;
92
+ $[1] = t2;
93
+ } else {
94
+ t2 = $[1];
95
+ }
96
+ let t3;
97
+ if ($[2] !== isChecked || $[3] !== reduceMotion) {
98
+ t3 = reduceMotion ? { duration: 0 } : {
99
+ ...ARC_SPRING_SNAPPY,
100
+ opacity: { duration: isChecked ? ARC_DURATION.fast : ARC_DURATION.instant }
101
+ };
102
+ $[2] = isChecked;
103
+ $[3] = reduceMotion;
104
+ $[4] = t3;
105
+ } else {
106
+ t3 = $[4];
107
+ }
108
+ let t4;
109
+ if ($[5] !== t2 || $[6] !== t3) {
110
+ t4 = /* @__PURE__ */ _jsx(RadioGroupPrimitive.Indicator, {
111
+ forceMount: true,
112
+ asChild: true,
113
+ children: /* @__PURE__ */ _jsx(motion.span, {
114
+ "data-slot": "radio-group-indicator",
115
+ className: "pointer-events-none block size-[7px] rounded-full bg-(--control-glyph) [grid-area:1/1]",
116
+ initial: false,
117
+ animate: t2,
118
+ transition: t3
119
+ })
120
+ });
121
+ $[5] = t2;
122
+ $[6] = t3;
123
+ $[7] = t4;
124
+ } else {
125
+ t4 = $[7];
126
+ }
127
+ let t5;
128
+ if ($[8] !== disabled || $[9] !== labelId || $[10] !== t1 || $[11] !== t4 || $[12] !== value) {
129
+ t5 = /* @__PURE__ */ _jsx(RadioGroupPrimitive.Item, {
130
+ "data-slot": "radio-group-item",
131
+ className: radioGroupItemClassName,
132
+ value,
133
+ disabled,
134
+ "aria-labelledby": labelId,
135
+ "aria-describedby": t1,
136
+ children: t4
137
+ });
138
+ $[8] = disabled;
139
+ $[9] = labelId;
140
+ $[10] = t1;
141
+ $[11] = t4;
142
+ $[12] = value;
143
+ $[13] = t5;
144
+ } else {
145
+ t5 = $[13];
146
+ }
147
+ let t6;
148
+ if ($[14] !== label || $[15] !== labelId) {
149
+ t6 = /* @__PURE__ */ _jsx("span", {
150
+ id: labelId,
151
+ "data-slot": "radio-group-option-label",
152
+ className: "block text-sm font-medium text-text-secondary transition-colors duration-(--duration-standard) ease-(--ease-standard) group-has-data-[state=checked]/radio-group-option:text-foreground motion-reduce:transition-none",
153
+ children: label
154
+ });
155
+ $[14] = label;
156
+ $[15] = labelId;
157
+ $[16] = t6;
158
+ } else {
159
+ t6 = $[16];
160
+ }
161
+ let t7;
162
+ if ($[17] !== description || $[18] !== descriptionId) {
163
+ t7 = description ? /* @__PURE__ */ _jsx("span", {
164
+ id: descriptionId,
165
+ "data-slot": "radio-group-option-description",
166
+ className: "mt-0.5 block text-xs text-text-muted",
167
+ children: description
168
+ }) : null;
169
+ $[17] = description;
170
+ $[18] = descriptionId;
171
+ $[19] = t7;
172
+ } else {
173
+ t7 = $[19];
174
+ }
175
+ let t8;
176
+ if ($[20] !== t6 || $[21] !== t7) {
177
+ t8 = /* @__PURE__ */ _jsxs("span", {
178
+ className: "relative z-2 min-w-0",
179
+ children: [t6, t7]
180
+ });
181
+ $[20] = t6;
182
+ $[21] = t7;
183
+ $[22] = t8;
184
+ } else {
185
+ t8 = $[22];
186
+ }
187
+ let t9;
188
+ if ($[23] !== t5 || $[24] !== t8) {
189
+ t9 = /* @__PURE__ */ _jsxs("label", {
190
+ "data-slot": "radio-group-option",
191
+ className: optionClassName,
192
+ onClick: _temp,
193
+ children: [t5, t8]
194
+ });
195
+ $[23] = t5;
196
+ $[24] = t8;
197
+ $[25] = t9;
198
+ } else {
199
+ t9 = $[25];
200
+ }
201
+ return t9;
202
+ }
203
+ function _temp(event) {
204
+ const radio = event.currentTarget.querySelector("[data-slot=\"radio-group-item\"]");
205
+ if (radio && !radio.disabled && event.target !== radio) {
206
+ radio.focus({ preventScroll: true });
207
+ }
208
+ }
209
+ /**
210
+ * A choice of one option from a visible set, controlled with `value` or uncontrolled with `defaultValue`.
211
+ * @param props - Legend, options, value, change handler, form name and classes.
212
+ * @returns The fieldset with its legend and option rows.
213
+ */
214
+ function RadioGroup(t0) {
215
+ const $ = _c(32);
216
+ const { label, options, value, defaultValue, onValueChange, name, className } = t0;
217
+ const reduceMotion = usePrefersReducedMotion();
218
+ const generatedId = useId();
219
+ const legendId = `${generatedId}-legend`;
220
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
221
+ const selectedValue = value ?? uncontrolledValue;
222
+ const groupRef = useRef(null);
223
+ const optionsRef = useRef(null);
224
+ const highlightRef = useRef(null);
225
+ const shownValue = useRef(null);
226
+ const placedAt = useRef("");
227
+ let t1;
228
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
229
+ t1 = () => optionsRef.current?.querySelector(CHECKED_OPTION_SELECTOR) ?? null;
230
+ $[0] = t1;
231
+ } else {
232
+ t1 = $[0];
233
+ }
234
+ const findCheckedRow = t1;
235
+ let t2;
236
+ let t3;
237
+ if ($[1] !== reduceMotion || $[2] !== selectedValue) {
238
+ t2 = () => {
239
+ const hasChanged = shownValue.current !== null && shownValue.current !== selectedValue;
240
+ placeHighlight(highlightRef.current, findCheckedRow(), placedAt, hasChanged && !reduceMotion);
241
+ shownValue.current = selectedValue;
242
+ groupRef.current?.setAttribute(RADIO_GROUP_READY_ATTRIBUTE, "");
243
+ };
244
+ t3 = [selectedValue, reduceMotion];
245
+ $[1] = reduceMotion;
246
+ $[2] = selectedValue;
247
+ $[3] = t2;
248
+ $[4] = t3;
249
+ } else {
250
+ t2 = $[3];
251
+ t3 = $[4];
252
+ }
253
+ useLayoutEffect(t2, t3);
254
+ let t4;
255
+ if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
256
+ t4 = () => {
257
+ const list = optionsRef.current;
258
+ if (!list || typeof ResizeObserver === "undefined") {
259
+ return;
260
+ }
261
+ const observer = new ResizeObserver(() => placeHighlight(highlightRef.current, findCheckedRow(), placedAt, false));
262
+ observer.observe(list);
263
+ list.querySelectorAll(OPTION_SELECTOR).forEach((row) => observer.observe(row));
264
+ return () => observer.disconnect();
265
+ };
266
+ $[5] = t4;
267
+ } else {
268
+ t4 = $[5];
269
+ }
270
+ useEffect(t4);
271
+ const t5 = name ?? generatedId;
272
+ let t6;
273
+ if ($[6] !== onValueChange || $[7] !== value) {
274
+ t6 = (nextValue) => {
275
+ if (value === undefined) {
276
+ setUncontrolledValue(nextValue);
277
+ }
278
+ onValueChange?.(nextValue);
279
+ };
280
+ $[6] = onValueChange;
281
+ $[7] = value;
282
+ $[8] = t6;
283
+ } else {
284
+ t6 = $[8];
285
+ }
286
+ let t7;
287
+ if ($[9] !== className) {
288
+ t7 = cn("m-0 grid min-w-0 border-0 p-0", className);
289
+ $[9] = className;
290
+ $[10] = t7;
291
+ } else {
292
+ t7 = $[10];
293
+ }
294
+ let t8;
295
+ if ($[11] !== label || $[12] !== legendId) {
296
+ t8 = /* @__PURE__ */ _jsx("legend", {
297
+ id: legendId,
298
+ "data-slot": "radio-group-label",
299
+ className: "mb-(--space-2) p-0 text-sm font-medium text-foreground",
300
+ children: label
301
+ });
302
+ $[11] = label;
303
+ $[12] = legendId;
304
+ $[13] = t8;
305
+ } else {
306
+ t8 = $[13];
307
+ }
308
+ let t9;
309
+ if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
310
+ t9 = /* @__PURE__ */ _jsx("span", {
311
+ ref: highlightRef,
312
+ "data-slot": "radio-group-highlight",
313
+ "aria-hidden": "true",
314
+ className: "pointer-events-none absolute top-0 left-0 z-1 box-border rounded-(--radius-control) border border-(--control-on) bg-[color-mix(in_oklab,var(--control-on)_5%,transparent)] opacity-0"
315
+ });
316
+ $[14] = t9;
317
+ } else {
318
+ t9 = $[14];
319
+ }
320
+ let t10;
321
+ if ($[15] !== options) {
322
+ t10 = options.map(_temp2);
323
+ $[15] = options;
324
+ $[16] = t10;
325
+ } else {
326
+ t10 = $[16];
327
+ }
328
+ let t11;
329
+ if ($[17] !== t10) {
330
+ t11 = /* @__PURE__ */ _jsxs("div", {
331
+ ref: optionsRef,
332
+ "data-slot": "radio-group-options",
333
+ className: "relative grid w-full gap-(--space-2)",
334
+ children: [t9, t10]
335
+ });
336
+ $[17] = t10;
337
+ $[18] = t11;
338
+ } else {
339
+ t11 = $[18];
340
+ }
341
+ let t12;
342
+ if ($[19] !== legendId || $[20] !== t11 || $[21] !== t7 || $[22] !== t8) {
343
+ t12 = /* @__PURE__ */ _jsxs("fieldset", {
344
+ ref: groupRef,
345
+ "data-slot": "radio-group",
346
+ "aria-labelledby": legendId,
347
+ className: t7,
348
+ children: [t8, t11]
349
+ });
350
+ $[19] = legendId;
351
+ $[20] = t11;
352
+ $[21] = t7;
353
+ $[22] = t8;
354
+ $[23] = t12;
355
+ } else {
356
+ t12 = $[23];
357
+ }
358
+ let t13;
359
+ if ($[24] !== selectedValue || $[25] !== t12 || $[26] !== t5 || $[27] !== t6) {
360
+ t13 = /* @__PURE__ */ _jsx(RadioGroupPrimitive.Root, {
361
+ asChild: true,
362
+ name: t5,
363
+ value: selectedValue,
364
+ onValueChange: t6,
365
+ children: t12
366
+ });
367
+ $[24] = selectedValue;
368
+ $[25] = t12;
369
+ $[26] = t5;
370
+ $[27] = t6;
371
+ $[28] = t13;
372
+ } else {
373
+ t13 = $[28];
374
+ }
375
+ let t14;
376
+ if ($[29] !== selectedValue || $[30] !== t13) {
377
+ t14 = /* @__PURE__ */ _jsx(RadioGroupValueContext.Provider, {
378
+ value: selectedValue,
379
+ children: t13
380
+ });
381
+ $[29] = selectedValue;
382
+ $[30] = t13;
383
+ $[31] = t14;
384
+ } else {
385
+ t14 = $[31];
386
+ }
387
+ return t14;
388
+ }
389
+ function _temp2(option) {
390
+ return /* @__PURE__ */ _jsx(RadioGroupOptionRow, { ...option }, option.value);
391
+ }
392
+ export { RadioGroup };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Toggle for likes and similar reactions: the icon gets Arc's kick (https://uiarc.dev, MIT License, see
3
+ * THIRD_PARTY_NOTICES.md) when the viewer reacts and the counter rolls in the direction of the change. The (optimistic) reaction state is owned by the caller.
4
+ */
5
+ import { type ComponentType, type MouseEvent, type SVGProps } from "react";
6
+ export interface ReactionButtonProps {
7
+ /** Accessible name, including the current count (for example "Me gusta 3"). */
8
+ ariaLabel: string;
9
+ isActive: boolean;
10
+ count: number;
11
+ onClick: (event: MouseEvent<HTMLButtonElement>) => void;
12
+ isDisabled?: boolean;
13
+ /** Icon of the reaction; it is filled with `activeColor` while active. */
14
+ icon?: ComponentType<SVGProps<SVGSVGElement>>;
15
+ /**
16
+ * CSS color of the active icon, such as `var(--primary)` or `currentColor` to follow the
17
+ * button text. Defaults to the destructive color, the usual tone of a like.
18
+ */
19
+ activeColor?: string;
20
+ /** Formats the visible count, for example with a locale-aware compact format. */
21
+ formatCount?: (count: number) => string;
22
+ className?: string;
23
+ }
24
+ /**
25
+ * Renders an outline toggle button exposing its state with `aria-pressed`. Server-rendered and already-active
26
+ * reactions never kick on load; only a change to active does, and not at all with reduced motion.
27
+ * @param props - Accessible name, state, count, click handler and optional icon.
28
+ * @returns The reaction button.
29
+ */
30
+ export declare function ReactionButton({ ariaLabel, isActive, count, onClick, isDisabled, icon: Icon, formatCount, activeColor, className, }: ReactionButtonProps): import("react").JSX.Element;
@@ -0,0 +1,189 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Toggle for likes and similar reactions: the icon gets Arc's kick (https://uiarc.dev, MIT License, see
5
+ * THIRD_PARTY_NOTICES.md) when the viewer reacts and the counter rolls in the direction of the change. The (optimistic) reaction state is owned by the caller.
6
+ */
7
+ import { useEffect, useRef } from "react";
8
+ import { HeartIcon } from "lucide-react";
9
+ import { animate, motion, useMotionValue } from "motion/react";
10
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
11
+ import { cn } from "../lib/utils.js";
12
+ import { AnimatedCount } from "./animated-count.js";
13
+ import { ControlButton } from "./control-button.js";
14
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
15
+ /**
16
+ * Arc's kick: an impulse rather than a keyframe. The icon starts at rest with velocity, overshoots and settles, and a
17
+ * quick second reaction adds to the running motion instead of restarting it.
18
+ */
19
+ const REACTION_KICK = {
20
+ type: "spring",
21
+ stiffness: 420,
22
+ damping: 17
23
+ };
24
+ /** Scale velocity, per second, the kick gives the icon. */
25
+ const REACTION_KICK_SCALE_VELOCITY = 11;
26
+ /** Rotation velocity, in degrees per second, the kick gives the icon. */
27
+ const REACTION_KICK_ROTATE_VELOCITY = -420;
28
+ /**
29
+ * Renders an outline toggle button exposing its state with `aria-pressed`. Server-rendered and already-active
30
+ * reactions never kick on load; only a change to active does, and not at all with reduced motion.
31
+ * @param props - Accessible name, state, count, click handler and optional icon.
32
+ * @returns The reaction button.
33
+ */
34
+ export function ReactionButton(t0) {
35
+ const $ = _c(32);
36
+ const { ariaLabel, isActive, count, onClick, isDisabled: t1, icon: t2, formatCount, activeColor, className } = t0;
37
+ const isDisabled = t1 === undefined ? false : t1;
38
+ const Icon = t2 === undefined ? HeartIcon : t2;
39
+ const shouldReduceMotion = usePrefersReducedMotion();
40
+ const scale = useMotionValue(1);
41
+ const rotate = useMotionValue(0);
42
+ const wasActive = useRef(isActive);
43
+ let t3;
44
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
45
+ t3 = [];
46
+ $[0] = t3;
47
+ } else {
48
+ t3 = $[0];
49
+ }
50
+ const kickControls = useRef(t3);
51
+ let t4;
52
+ let t5;
53
+ if ($[1] !== isActive || $[2] !== rotate || $[3] !== scale || $[4] !== shouldReduceMotion) {
54
+ t4 = () => {
55
+ const becameActive = isActive && !wasActive.current;
56
+ wasActive.current = isActive;
57
+ if (shouldReduceMotion) {
58
+ kickControls.current.forEach(_temp);
59
+ kickControls.current = [];
60
+ scale.jump(1);
61
+ rotate.jump(0);
62
+ return;
63
+ }
64
+ if (!becameActive) {
65
+ return;
66
+ }
67
+ kickControls.current = [animate(scale, 1, {
68
+ ...REACTION_KICK,
69
+ velocity: scale.getVelocity() + REACTION_KICK_SCALE_VELOCITY
70
+ }), animate(rotate, 0, {
71
+ ...REACTION_KICK,
72
+ velocity: rotate.getVelocity() + REACTION_KICK_ROTATE_VELOCITY
73
+ })];
74
+ };
75
+ t5 = [
76
+ isActive,
77
+ rotate,
78
+ scale,
79
+ shouldReduceMotion
80
+ ];
81
+ $[1] = isActive;
82
+ $[2] = rotate;
83
+ $[3] = scale;
84
+ $[4] = shouldReduceMotion;
85
+ $[5] = t4;
86
+ $[6] = t5;
87
+ } else {
88
+ t4 = $[5];
89
+ t5 = $[6];
90
+ }
91
+ useEffect(t4, t5);
92
+ let t6;
93
+ if ($[7] !== activeColor) {
94
+ t6 = activeColor ? { "--astra-reaction-active-color": activeColor } : undefined;
95
+ $[7] = activeColor;
96
+ $[8] = t6;
97
+ } else {
98
+ t6 = $[8];
99
+ }
100
+ const activeColorStyle = t6;
101
+ const t7 = isActive || undefined;
102
+ let t8;
103
+ if ($[9] !== className) {
104
+ t8 = cn("group/reaction", className);
105
+ $[9] = className;
106
+ $[10] = t8;
107
+ } else {
108
+ t8 = $[10];
109
+ }
110
+ let t9;
111
+ if ($[11] !== rotate || $[12] !== scale) {
112
+ t9 = {
113
+ scale,
114
+ rotate
115
+ };
116
+ $[11] = rotate;
117
+ $[12] = scale;
118
+ $[13] = t9;
119
+ } else {
120
+ t9 = $[13];
121
+ }
122
+ let t10;
123
+ if ($[14] !== Icon) {
124
+ t10 = /* @__PURE__ */ _jsx(Icon, { className: "size-4 transition-[fill,color] group-data-active/reaction:fill-current group-data-active/reaction:text-[var(--astra-reaction-active-color,var(--destructive))]" });
125
+ $[14] = Icon;
126
+ $[15] = t10;
127
+ } else {
128
+ t10 = $[15];
129
+ }
130
+ let t11;
131
+ if ($[16] !== t10 || $[17] !== t9) {
132
+ t11 = /* @__PURE__ */ _jsx(motion.span, {
133
+ "aria-hidden": true,
134
+ className: "inline-flex origin-center items-center justify-center",
135
+ style: t9,
136
+ children: t10
137
+ });
138
+ $[16] = t10;
139
+ $[17] = t9;
140
+ $[18] = t11;
141
+ } else {
142
+ t11 = $[18];
143
+ }
144
+ let t12;
145
+ if ($[19] !== count || $[20] !== formatCount) {
146
+ t12 = /* @__PURE__ */ _jsx(AnimatedCount, {
147
+ className: "min-w-[1ch]",
148
+ value: count,
149
+ format: formatCount
150
+ });
151
+ $[19] = count;
152
+ $[20] = formatCount;
153
+ $[21] = t12;
154
+ } else {
155
+ t12 = $[21];
156
+ }
157
+ let t13;
158
+ if ($[22] !== activeColorStyle || $[23] !== ariaLabel || $[24] !== isActive || $[25] !== isDisabled || $[26] !== onClick || $[27] !== t11 || $[28] !== t12 || $[29] !== t7 || $[30] !== t8) {
159
+ t13 = /* @__PURE__ */ _jsxs(ControlButton, {
160
+ "data-slot": "reaction-button",
161
+ "data-active": t7,
162
+ "aria-label": ariaLabel,
163
+ "aria-pressed": isActive,
164
+ className: t8,
165
+ disabled: isDisabled,
166
+ onClick,
167
+ style: activeColorStyle,
168
+ type: "button",
169
+ variant: "outline",
170
+ children: [t11, t12]
171
+ });
172
+ $[22] = activeColorStyle;
173
+ $[23] = ariaLabel;
174
+ $[24] = isActive;
175
+ $[25] = isDisabled;
176
+ $[26] = onClick;
177
+ $[27] = t11;
178
+ $[28] = t12;
179
+ $[29] = t7;
180
+ $[30] = t8;
181
+ $[31] = t13;
182
+ } else {
183
+ t13 = $[31];
184
+ }
185
+ return t13;
186
+ }
187
+ function _temp(controls) {
188
+ return controls.stop();
189
+ }
@@ -0,0 +1,25 @@
1
+ import type { RichLinkEditorController } from "../hooks/use-rich-link-editor.js";
2
+ /** Copy for the link popover. Every entry is optional and defaults to Spanish. */
3
+ export type RichLinkEditorCopy = {
4
+ editAction: string;
5
+ editCancel: string;
6
+ editSave: string;
7
+ popoverTextLabel: string;
8
+ popoverUrlLabel: string;
9
+ removeAction: string;
10
+ };
11
+ export type RichLinkEditorProps = {
12
+ ariaLabel: string;
13
+ copy?: Partial<RichLinkEditorCopy>;
14
+ editor: RichLinkEditorController;
15
+ placeholder: string;
16
+ ariaDescribedBy?: string;
17
+ isDisabled?: boolean;
18
+ isInvalid?: boolean;
19
+ };
20
+ /**
21
+ * `contentEditable` rich link editor: renders the controller's preview segments,
22
+ * turning each link into a popover that edits or removes it. All state lives in
23
+ * the `useRichLinkEditor` controller; this component is presentation only.
24
+ */
25
+ export declare function RichLinkEditor({ ariaDescribedBy, ariaLabel, copy: copyOverrides, editor, isDisabled, isInvalid, placeholder, }: RichLinkEditorProps): import("react").JSX.Element;