@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,636 @@
1
+ "use client";
2
+ import { c as _c } from "react/compiler-runtime";
3
+ /**
4
+ * Arc's Tabs (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): its segmented list on Arc's tokens, a
5
+ * highlight that glides between triggers with Arc's morph spring, a list that scrolls sideways and keeps the active
6
+ * tab in view, and panels that slide in from the side of the chosen tab while their height morphs from the previous
7
+ * panel. Radix keeps the roles, keyboard navigation and controlled or uncontrolled value.
8
+ */
9
+ import { createContext, useContext, useLayoutEffect, useRef, useState } from "react";
10
+ import { Slot, Tabs as TabsPrimitive } from "radix-ui";
11
+ import { AnimatePresence, animate, motion, useIsPresent } from "motion/react";
12
+ import { TABS_DIRECTION, TABS_PANEL_HEIGHT_TOLERANCE_PX, TABS_PANEL_OFFSET_PX, TABS_PANEL_REDUCED_EXIT_DURATION_S, TABS_REVEAL_MARGIN_PX } from "../constants/tabs.js";
13
+ import { usePrefersReducedMotion } from "../hooks/use-prefers-reduced-motion.js";
14
+ import { cn } from "../lib/utils.js";
15
+ import { ARC_DURATION, ARC_EASE, ARC_SPRING_SMOOTH } from "../motion/arc-tokens.js";
16
+ import { GlideSlot } from "../motion/glide-slot.js";
17
+ import { useAttachedElement } from "../motion/use-attached-element.js";
18
+ import { jsx as _jsx } from "react/jsx-runtime";
19
+ const TabsMotionContext = createContext(null);
20
+ /** Returns the elements of a slot that belong to this Tabs instance, never to a nested one. */
21
+ function getOwnElements(root, selector) {
22
+ return Array.from(root.querySelectorAll(selector)).filter((element) => element.closest("[data-slot=\"tabs\"]") === root);
23
+ }
24
+ /**
25
+ * Reads which way the selection travels from the order of this instance's triggers.
26
+ * @param root - The tabs root, or null before it is attached.
27
+ * @param fromValue - Value of the previously active tab.
28
+ * @param toValue - Value of the newly active tab.
29
+ * @returns The travel direction, or null when either tab is not rendered.
30
+ */
31
+ function getTravelDirection(root, fromValue, toValue) {
32
+ if (!root) return null;
33
+ const order = getOwnElements(root, "[data-slot=\"tabs-trigger\"]").map((trigger) => trigger.getAttribute("data-value"));
34
+ const fromIndex = order.indexOf(fromValue);
35
+ const toIndex = order.indexOf(toValue);
36
+ if (fromIndex < 0 || toIndex < 0 || fromIndex === toIndex) return null;
37
+ return toIndex > fromIndex ? TABS_DIRECTION.forward : TABS_DIRECTION.backward;
38
+ }
39
+ /**
40
+ * Groups a tab list with its panels. Accepts Radix's `value`/`defaultValue`/`onValueChange` contract unchanged.
41
+ * @param props - Radix root props, including `orientation` and `ref`.
42
+ * @returns The tabs root.
43
+ */
44
+ function Tabs(t0) {
45
+ const $ = _c(28);
46
+ let className;
47
+ let defaultValue;
48
+ let onValueChange;
49
+ let props;
50
+ let ref;
51
+ let t1;
52
+ let value;
53
+ if ($[0] !== t0) {
54
+ ({className, orientation: t1, value, defaultValue, onValueChange, ref, ...props} = t0);
55
+ $[0] = t0;
56
+ $[1] = className;
57
+ $[2] = defaultValue;
58
+ $[3] = onValueChange;
59
+ $[4] = props;
60
+ $[5] = ref;
61
+ $[6] = t1;
62
+ $[7] = value;
63
+ } else {
64
+ className = $[1];
65
+ defaultValue = $[2];
66
+ onValueChange = $[3];
67
+ props = $[4];
68
+ ref = $[5];
69
+ t1 = $[6];
70
+ value = $[7];
71
+ }
72
+ const orientation = t1 === undefined ? "horizontal" : t1;
73
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue ?? "");
74
+ const [direction, setDirection] = useState(TABS_DIRECTION.forward);
75
+ const [root, attachRoot] = useAttachedElement(ref);
76
+ const panelHeightRef = useRef(null);
77
+ const leavingRectRef = useRef(null);
78
+ const activeValue = value ?? uncontrolledValue;
79
+ const [renderedValue, setRenderedValue] = useState(activeValue);
80
+ if (renderedValue !== activeValue) {
81
+ setRenderedValue(activeValue);
82
+ const travelDirection = getTravelDirection(root, renderedValue, activeValue);
83
+ if (travelDirection !== null) {
84
+ setDirection(travelDirection);
85
+ }
86
+ }
87
+ let t2;
88
+ if ($[8] !== onValueChange || $[9] !== root || $[10] !== value) {
89
+ t2 = function handleValueChange(nextValue) {
90
+ const activePanel = root ? getOwnElements(root, "[data-slot=\"tabs-content\"][data-state=\"active\"]")[0] : undefined;
91
+ leavingRectRef.current = activePanel ? {
92
+ value: nextValue,
93
+ rect: activePanel.getBoundingClientRect()
94
+ } : null;
95
+ if (value === undefined) {
96
+ setUncontrolledValue(nextValue);
97
+ }
98
+ onValueChange?.(nextValue);
99
+ };
100
+ $[8] = onValueChange;
101
+ $[9] = root;
102
+ $[10] = value;
103
+ $[11] = t2;
104
+ } else {
105
+ t2 = $[11];
106
+ }
107
+ const handleValueChange = t2;
108
+ let t3;
109
+ if ($[12] !== activeValue || $[13] !== direction || $[14] !== orientation) {
110
+ t3 = {
111
+ activeValue,
112
+ direction,
113
+ orientation,
114
+ panelHeightRef,
115
+ leavingRectRef
116
+ };
117
+ $[12] = activeValue;
118
+ $[13] = direction;
119
+ $[14] = orientation;
120
+ $[15] = t3;
121
+ } else {
122
+ t3 = $[15];
123
+ }
124
+ let t4;
125
+ if ($[16] !== className) {
126
+ t4 = cn("group/tabs relative flex gap-(--space-4) data-horizontal:flex-col", className);
127
+ $[16] = className;
128
+ $[17] = t4;
129
+ } else {
130
+ t4 = $[17];
131
+ }
132
+ let t5;
133
+ if ($[18] !== activeValue || $[19] !== attachRoot || $[20] !== handleValueChange || $[21] !== orientation || $[22] !== props || $[23] !== t4) {
134
+ t5 = /* @__PURE__ */ _jsx(TabsPrimitive.Root, {
135
+ ref: attachRoot,
136
+ "data-slot": "tabs",
137
+ "data-orientation": orientation,
138
+ orientation,
139
+ className: t4,
140
+ ...props,
141
+ value: activeValue,
142
+ onValueChange: handleValueChange
143
+ });
144
+ $[18] = activeValue;
145
+ $[19] = attachRoot;
146
+ $[20] = handleValueChange;
147
+ $[21] = orientation;
148
+ $[22] = props;
149
+ $[23] = t4;
150
+ $[24] = t5;
151
+ } else {
152
+ t5 = $[24];
153
+ }
154
+ let t6;
155
+ if ($[25] !== t3 || $[26] !== t5) {
156
+ t6 = /* @__PURE__ */ _jsx(TabsMotionContext.Provider, {
157
+ value: t3,
158
+ children: t5
159
+ });
160
+ $[25] = t3;
161
+ $[26] = t5;
162
+ $[27] = t6;
163
+ } else {
164
+ t6 = $[27];
165
+ }
166
+ return t6;
167
+ }
168
+ /**
169
+ * Arc's segmented list: a muted track whose active trigger is a raised surface. Horizontal lists scroll sideways
170
+ * without a visible scrollbar.
171
+ */
172
+ const tabsListClassName = "group/tabs-list inline-flex w-fit max-w-full min-w-0 items-center gap-(--space-1) rounded-(--radius-control) border border-border bg-surface-muted p-(--space-1) text-text-muted group-data-horizontal/tabs:overflow-x-auto group-data-horizontal/tabs:[scrollbar-width:none] group-data-horizontal/tabs:[&::-webkit-scrollbar]:hidden group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col";
173
+ /**
174
+ * Scrolls a horizontally overflowing list just enough to show the trigger, never the page around it. The target is an
175
+ * absolute offset, so a second call while a smooth scroll is still running (focus and selection both reveal the
176
+ * trigger on the same key press) aims at the same place instead of adding its delta to a moving position.
177
+ * @param list - The scrolling tab list.
178
+ * @param trigger - The trigger to reveal.
179
+ * @param reduceMotion - True jumps instead of scrolling smoothly.
180
+ */
181
+ function revealTrigger(list, trigger, reduceMotion) {
182
+ if (!trigger || list.scrollWidth <= list.clientWidth || typeof list.scrollTo !== "function") return;
183
+ const frame = list.getBoundingClientRect();
184
+ const item = trigger.getBoundingClientRect();
185
+ const itemStart = item.left - frame.left + list.scrollLeft;
186
+ const itemEnd = itemStart + item.width;
187
+ const visibleStart = list.scrollLeft;
188
+ const visibleEnd = visibleStart + list.clientWidth;
189
+ const target = itemStart < visibleStart + TABS_REVEAL_MARGIN_PX ? itemStart - TABS_REVEAL_MARGIN_PX : itemEnd > visibleEnd - TABS_REVEAL_MARGIN_PX ? itemEnd - list.clientWidth + TABS_REVEAL_MARGIN_PX : visibleStart;
190
+ if (target !== visibleStart) list.scrollTo({
191
+ left: target,
192
+ behavior: reduceMotion ? "instant" : "smooth"
193
+ });
194
+ }
195
+ /**
196
+ * Holds the triggers. The active highlight glides to the newly selected trigger and the list scrolls to keep the
197
+ * active or focused trigger visible.
198
+ * @param props - Radix list props, including `aria-label`, `loop` and `ref`.
199
+ * @returns The tab list.
200
+ */
201
+ function TabsList(t0) {
202
+ const $ = _c(28);
203
+ let className;
204
+ let onFocusCapture;
205
+ let props;
206
+ let ref;
207
+ if ($[0] !== t0) {
208
+ ({className, ref, onFocusCapture, ...props} = t0);
209
+ $[0] = t0;
210
+ $[1] = className;
211
+ $[2] = onFocusCapture;
212
+ $[3] = props;
213
+ $[4] = ref;
214
+ } else {
215
+ className = $[1];
216
+ onFocusCapture = $[2];
217
+ props = $[3];
218
+ ref = $[4];
219
+ }
220
+ const motionState = useContext(TabsMotionContext);
221
+ const reduceMotion = usePrefersReducedMotion();
222
+ const [list, attachList] = useAttachedElement(ref);
223
+ const activeValue = motionState?.activeValue;
224
+ let t1;
225
+ if ($[5] !== list || $[6] !== motionState?.orientation || $[7] !== reduceMotion) {
226
+ t1 = () => {
227
+ if (!list || motionState?.orientation === "vertical") {
228
+ return;
229
+ }
230
+ const revealActiveTrigger = () => revealTrigger(list, list.querySelector("[data-slot=\"tabs-trigger\"][data-state=\"active\"]"), reduceMotion);
231
+ revealActiveTrigger();
232
+ const observer = new ResizeObserver(revealActiveTrigger);
233
+ for (const trigger of list.querySelectorAll("[data-slot=\"tabs-trigger\"]")) {
234
+ observer.observe(trigger);
235
+ }
236
+ return () => observer.disconnect();
237
+ };
238
+ $[5] = list;
239
+ $[6] = motionState?.orientation;
240
+ $[7] = reduceMotion;
241
+ $[8] = t1;
242
+ } else {
243
+ t1 = $[8];
244
+ }
245
+ const t2 = motionState?.orientation;
246
+ let t3;
247
+ if ($[9] !== activeValue || $[10] !== list || $[11] !== reduceMotion || $[12] !== t2) {
248
+ t3 = [
249
+ list,
250
+ activeValue,
251
+ t2,
252
+ reduceMotion
253
+ ];
254
+ $[9] = activeValue;
255
+ $[10] = list;
256
+ $[11] = reduceMotion;
257
+ $[12] = t2;
258
+ $[13] = t3;
259
+ } else {
260
+ t3 = $[13];
261
+ }
262
+ useLayoutEffect(t1, t3);
263
+ let t4;
264
+ if ($[14] !== list || $[15] !== motionState?.orientation || $[16] !== onFocusCapture || $[17] !== reduceMotion) {
265
+ t4 = function handleFocusCapture(event) {
266
+ onFocusCapture?.(event);
267
+ if (!list || motionState?.orientation === "vertical") {
268
+ return;
269
+ }
270
+ if (event.target instanceof HTMLElement && event.target.getAttribute("role") === "tab") {
271
+ revealTrigger(list, event.target, reduceMotion);
272
+ }
273
+ };
274
+ $[14] = list;
275
+ $[15] = motionState?.orientation;
276
+ $[16] = onFocusCapture;
277
+ $[17] = reduceMotion;
278
+ $[18] = t4;
279
+ } else {
280
+ t4 = $[18];
281
+ }
282
+ const handleFocusCapture = t4;
283
+ let t5;
284
+ if ($[19] !== className) {
285
+ t5 = cn(tabsListClassName, className);
286
+ $[19] = className;
287
+ $[20] = t5;
288
+ } else {
289
+ t5 = $[20];
290
+ }
291
+ let t6;
292
+ if ($[21] !== handleFocusCapture || $[22] !== props || $[23] !== t5) {
293
+ t6 = /* @__PURE__ */ _jsx(TabsPrimitive.List, {
294
+ "data-slot": "tabs-list",
295
+ className: t5,
296
+ onFocusCapture: handleFocusCapture,
297
+ ...props
298
+ });
299
+ $[21] = handleFocusCapture;
300
+ $[22] = props;
301
+ $[23] = t5;
302
+ $[24] = t6;
303
+ } else {
304
+ t6 = $[24];
305
+ }
306
+ let t7;
307
+ if ($[25] !== attachList || $[26] !== t6) {
308
+ t7 = /* @__PURE__ */ _jsx(GlideSlot, {
309
+ preset: "tabs",
310
+ ref: attachList,
311
+ children: t6
312
+ });
313
+ $[25] = attachList;
314
+ $[26] = t6;
315
+ $[27] = t7;
316
+ } else {
317
+ t7 = $[27];
318
+ }
319
+ return t7;
320
+ }
321
+ /**
322
+ * Selects a panel. Arc's trigger: muted label, accent label once active, hover only on fine pointers and the
323
+ * shared keyboard focus outline.
324
+ * @param props - Radix trigger props, including `value`.
325
+ * @returns The tab.
326
+ */
327
+ function TabsTrigger(t0) {
328
+ const $ = _c(10);
329
+ let className;
330
+ let props;
331
+ let value;
332
+ if ($[0] !== t0) {
333
+ ({className, value, ...props} = t0);
334
+ $[0] = t0;
335
+ $[1] = className;
336
+ $[2] = props;
337
+ $[3] = value;
338
+ } else {
339
+ className = $[1];
340
+ props = $[2];
341
+ value = $[3];
342
+ }
343
+ let t1;
344
+ if ($[4] !== className) {
345
+ t1 = cn("relative inline-flex min-h-(--control-height-sm) min-w-[5.5rem] flex-[1_0_auto] cursor-pointer items-center justify-center gap-1.5 rounded-[calc(var(--radius-control)-3px)] border border-transparent bg-transparent px-(--space-3) font-sans text-sm font-medium whitespace-nowrap text-text-muted [-webkit-tap-highlight-color:transparent] transition-[color,background-color,border-color,box-shadow] duration-(--duration-fast) ease-(--ease-standard) select-none motion-reduce:transition-none hover-fine:text-foreground active:text-foreground disabled:cursor-not-allowed disabled:opacity-50 data-active:text-(--accent-strong) group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", "data-active:border-border data-active:bg-surface data-active:shadow-(--shadow-resting)", className);
346
+ $[4] = className;
347
+ $[5] = t1;
348
+ } else {
349
+ t1 = $[5];
350
+ }
351
+ let t2;
352
+ if ($[6] !== props || $[7] !== t1 || $[8] !== value) {
353
+ t2 = /* @__PURE__ */ _jsx(TabsPrimitive.Trigger, {
354
+ "data-slot": "tabs-trigger",
355
+ "data-value": value,
356
+ value,
357
+ className: t1,
358
+ ...props
359
+ });
360
+ $[6] = props;
361
+ $[7] = t1;
362
+ $[8] = value;
363
+ $[9] = t2;
364
+ } else {
365
+ t2 = $[9];
366
+ }
367
+ return t2;
368
+ }
369
+ /** Panel classes: Arc's body text rhythm and a rounded keyboard focus outline. */
370
+ const tabsContentClassName = "flex-1 text-sm leading-(--leading-body) [--focus-outline-offset:3px] focus-visible:rounded-(--radius-control) data-[state=inactive]:pointer-events-none";
371
+ /** Places a slide offset on the axis the list runs along. */
372
+ function slideOffset({ orientation }, distance) {
373
+ return orientation === "vertical" ? {
374
+ x: 0,
375
+ y: distance
376
+ } : {
377
+ x: distance,
378
+ y: 0
379
+ };
380
+ }
381
+ /** Arc's panel motion: slides in from the side of the chosen tab and leaves quickly the opposite way. */
382
+ const panelVariants = {
383
+ enter: (custom) => ({
384
+ opacity: 0,
385
+ ...slideOffset(custom, custom.direction * TABS_PANEL_OFFSET_PX.enter)
386
+ }),
387
+ center: {
388
+ opacity: 1,
389
+ x: 0,
390
+ y: 0,
391
+ transition: {
392
+ opacity: {
393
+ duration: ARC_DURATION.standard,
394
+ ease: [...ARC_EASE.enter]
395
+ },
396
+ x: ARC_SPRING_SMOOTH,
397
+ y: ARC_SPRING_SMOOTH
398
+ }
399
+ },
400
+ exit: (custom) => ({
401
+ opacity: 0,
402
+ ...slideOffset(custom, custom.direction * -TABS_PANEL_OFFSET_PX.exit),
403
+ transition: {
404
+ duration: ARC_DURATION.instant,
405
+ ease: [...ARC_EASE.standard]
406
+ }
407
+ })
408
+ };
409
+ /** Reduced motion: a short crossfade in place. Keys match `panelVariants`, so server and client styles agree. */
410
+ const reducedPanelVariants = {
411
+ enter: {
412
+ opacity: 0,
413
+ x: 0,
414
+ y: 0
415
+ },
416
+ center: {
417
+ opacity: 1,
418
+ x: 0,
419
+ y: 0,
420
+ transition: { duration: ARC_DURATION.instant }
421
+ },
422
+ exit: {
423
+ opacity: 0,
424
+ x: 0,
425
+ y: 0,
426
+ transition: { duration: TABS_PANEL_REDUCED_EXIT_DURATION_S }
427
+ }
428
+ };
429
+ /** Inline properties the height morph overrides on the panel and restores when it settles. */
430
+ const MORPH_STYLE_PROPERTIES = [
431
+ "height",
432
+ "overflow",
433
+ "flex",
434
+ "min-height"
435
+ ];
436
+ /** Animates the consumer's own element when `TabsContent` is used with `asChild`. */
437
+ const MotionPanelSlot = motion.create(Slot.Root);
438
+ /**
439
+ * The animated element behind an active panel. While present it morphs from the previous panel's height to its
440
+ * own; once leaving it stays pinned where it was, inert and hidden from assistive technology, until it fades out.
441
+ */
442
+ function TabsPanel({ motionState, reduceMotion, asChild, ref, ...props }) {
443
+ const isPresent = useIsPresent();
444
+ const [panel, attachPanel] = useAttachedElement(ref);
445
+ const { panelHeightRef, leavingRectRef, direction, orientation } = motionState;
446
+ const activeValue = useContext(TabsMotionContext)?.activeValue ?? motionState.activeValue;
447
+ const PanelElement = asChild ? MotionPanelSlot : motion.div;
448
+ useLayoutEffect(() => {
449
+ if (!panel) return;
450
+ if (!isPresent) {
451
+ const leaving = leavingRectRef.current;
452
+ const before = leaving?.value === activeValue ? leaving.rect : null;
453
+ const now = panel.getBoundingClientRect();
454
+ if (before) panel.style.translate = `${before.left - now.left}px ${before.top - now.top}px`;
455
+ return;
456
+ }
457
+ panel.style.translate = "";
458
+ const fromHeight = panelHeightRef.current;
459
+ const toHeight = panel.offsetHeight;
460
+ let controls;
461
+ const inlineStyle = MORPH_STYLE_PROPERTIES.map((property) => ({
462
+ property,
463
+ value: panel.style.getPropertyValue(property),
464
+ priority: panel.style.getPropertyPriority(property)
465
+ }));
466
+ const release = () => {
467
+ for (const { property, value, priority } of inlineStyle) panel.style.setProperty(property, value, priority);
468
+ };
469
+ if (fromHeight !== null && Math.abs(fromHeight - toHeight) > TABS_PANEL_HEIGHT_TOLERANCE_PX && !reduceMotion) {
470
+ panel.style.flex = "none";
471
+ panel.style.minHeight = "0";
472
+ if (toHeight > fromHeight) panel.style.overflow = "clip";
473
+ panel.style.height = `${fromHeight}px`;
474
+ controls = animate(panel, { height: [fromHeight, toHeight] }, {
475
+ ...ARC_SPRING_SMOOTH,
476
+ onComplete: release
477
+ });
478
+ }
479
+ panelHeightRef.current = controls && fromHeight !== null ? fromHeight : toHeight;
480
+ const observer = new ResizeObserver(() => {
481
+ panelHeightRef.current = panel.offsetHeight;
482
+ });
483
+ observer.observe(panel);
484
+ return () => {
485
+ observer.disconnect();
486
+ controls?.stop();
487
+ release();
488
+ };
489
+ }, [
490
+ panel,
491
+ isPresent,
492
+ reduceMotion,
493
+ panelHeightRef,
494
+ leavingRectRef,
495
+ activeValue
496
+ ]);
497
+ return /* @__PURE__ */ _jsx(PanelElement, {
498
+ ref: attachPanel,
499
+ ...props,
500
+ custom: {
501
+ direction,
502
+ orientation
503
+ },
504
+ variants: reduceMotion ? reducedPanelVariants : panelVariants,
505
+ initial: "enter",
506
+ animate: "center",
507
+ exit: "exit",
508
+ inert: !isPresent || undefined,
509
+ "aria-hidden": !isPresent || undefined
510
+ });
511
+ }
512
+ /**
513
+ * Content of one tab. Inside `Tabs` it animates between panels; with `forceMount` it stays mounted and switches
514
+ * without motion, as Radix renders it. With `asChild` the consumer's element is the panel in both cases.
515
+ * @param props - Radix content props, including `value` and `forceMount`.
516
+ * @returns The tab panel, or nothing while another tab is active.
517
+ */
518
+ function TabsContent(t0) {
519
+ const $ = _c(31);
520
+ let asChild;
521
+ let children;
522
+ let className;
523
+ let forceMount;
524
+ let props;
525
+ let value;
526
+ if ($[0] !== t0) {
527
+ ({className, value, forceMount, asChild, children, ...props} = t0);
528
+ $[0] = t0;
529
+ $[1] = asChild;
530
+ $[2] = children;
531
+ $[3] = className;
532
+ $[4] = forceMount;
533
+ $[5] = props;
534
+ $[6] = value;
535
+ } else {
536
+ asChild = $[1];
537
+ children = $[2];
538
+ className = $[3];
539
+ forceMount = $[4];
540
+ props = $[5];
541
+ value = $[6];
542
+ }
543
+ const motionState = useContext(TabsMotionContext);
544
+ const reduceMotion = usePrefersReducedMotion();
545
+ let t1;
546
+ if ($[7] !== className) {
547
+ t1 = cn(tabsContentClassName, className);
548
+ $[7] = className;
549
+ $[8] = t1;
550
+ } else {
551
+ t1 = $[8];
552
+ }
553
+ const classes = t1;
554
+ if (forceMount || !motionState) {
555
+ let t2;
556
+ if ($[9] !== asChild || $[10] !== children || $[11] !== classes || $[12] !== forceMount || $[13] !== props || $[14] !== value) {
557
+ t2 = /* @__PURE__ */ _jsx(TabsPrimitive.Content, {
558
+ "data-slot": "tabs-content",
559
+ value,
560
+ forceMount,
561
+ asChild,
562
+ className: classes,
563
+ ...props,
564
+ children
565
+ });
566
+ $[9] = asChild;
567
+ $[10] = children;
568
+ $[11] = classes;
569
+ $[12] = forceMount;
570
+ $[13] = props;
571
+ $[14] = value;
572
+ $[15] = t2;
573
+ } else {
574
+ t2 = $[15];
575
+ }
576
+ return t2;
577
+ }
578
+ const isSelected = motionState.activeValue === value;
579
+ let t2;
580
+ if ($[16] !== motionState.direction || $[17] !== motionState.orientation) {
581
+ t2 = {
582
+ direction: motionState.direction,
583
+ orientation: motionState.orientation
584
+ };
585
+ $[16] = motionState.direction;
586
+ $[17] = motionState.orientation;
587
+ $[18] = t2;
588
+ } else {
589
+ t2 = $[18];
590
+ }
591
+ const t3 = t2;
592
+ let t4;
593
+ if ($[19] !== asChild || $[20] !== children || $[21] !== classes || $[22] !== isSelected || $[23] !== motionState || $[24] !== props || $[25] !== reduceMotion || $[26] !== value) {
594
+ t4 = isSelected && /* @__PURE__ */ _jsx(TabsPrimitive.Content, {
595
+ "data-slot": "tabs-content",
596
+ ...props,
597
+ value,
598
+ forceMount: true,
599
+ asChild: true,
600
+ children: /* @__PURE__ */ _jsx(TabsPanel, {
601
+ className: classes,
602
+ motionState,
603
+ reduceMotion,
604
+ asChild,
605
+ children
606
+ })
607
+ }, value);
608
+ $[19] = asChild;
609
+ $[20] = children;
610
+ $[21] = classes;
611
+ $[22] = isSelected;
612
+ $[23] = motionState;
613
+ $[24] = props;
614
+ $[25] = reduceMotion;
615
+ $[26] = value;
616
+ $[27] = t4;
617
+ } else {
618
+ t4 = $[27];
619
+ }
620
+ let t5;
621
+ if ($[28] !== t3 || $[29] !== t4) {
622
+ t5 = /* @__PURE__ */ _jsx(AnimatePresence, {
623
+ initial: false,
624
+ mode: "popLayout",
625
+ custom: t3,
626
+ children: t4
627
+ });
628
+ $[28] = t3;
629
+ $[29] = t4;
630
+ $[30] = t5;
631
+ } else {
632
+ t5 = $[30];
633
+ }
634
+ return t5;
635
+ }
636
+ export { Tabs, TabsList, TabsTrigger, TabsContent };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Arc's Textarea (https://uiarc.dev, MIT License, see THIRD_PARTY_NOTICES.md): a multi-line field on Arc's tokens with
3
+ * a 110px minimum height and a vertical resize handle. With a `label`, `description` or `error` it renders Arc's
4
+ * labelled field, where a live count in the description rolls its digits; without them it renders the bare control.
5
+ */
6
+ import type { ComponentProps } from "react";
7
+ import type { FieldCopyProps } from "./field.js";
8
+ export type TextareaProps = ComponentProps<"textarea"> & FieldCopyProps;
9
+ /**
10
+ * Free-form multi-line text, controlled or uncontrolled like a native textarea.
11
+ * @param textareaProps - Optional field copy plus every native textarea attribute, including `ref`, `rows` and `maxLength`.
12
+ * @returns The labelled field when `label`, `description` or `error` is passed (even as `undefined`), otherwise the
13
+ * bare control.
14
+ */
15
+ declare function Textarea(textareaProps: TextareaProps): import("react").JSX.Element;
16
+ export { Textarea };