@setsquare/ui 0.1.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 (312) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +49 -0
  4. package/README.md +313 -0
  5. package/dist/index.d.ts +129 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +78 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/lib/cn.d.ts +4 -0
  10. package/dist/lib/cn.d.ts.map +1 -0
  11. package/dist/lib/cn.js +59 -0
  12. package/dist/lib/cn.js.map +1 -0
  13. package/dist/lib/tokens.d.ts +5 -0
  14. package/dist/lib/tokens.d.ts.map +1 -0
  15. package/dist/lib/tokens.js +22 -0
  16. package/dist/lib/tokens.js.map +1 -0
  17. package/dist/lib/use-element-width.d.ts +4 -0
  18. package/dist/lib/use-element-width.d.ts.map +1 -0
  19. package/dist/lib/use-element-width.js +17 -0
  20. package/dist/lib/use-element-width.js.map +1 -0
  21. package/dist/lint/index.d.ts +41 -0
  22. package/dist/lint/index.d.ts.map +1 -0
  23. package/dist/lint/index.js +648 -0
  24. package/dist/lint/index.js.map +1 -0
  25. package/dist/shell/app-header.d.ts +13 -0
  26. package/dist/shell/app-header.d.ts.map +1 -0
  27. package/dist/shell/app-header.js +11 -0
  28. package/dist/shell/app-header.js.map +1 -0
  29. package/dist/shell/dashboard-shell.d.ts +67 -0
  30. package/dist/shell/dashboard-shell.d.ts.map +1 -0
  31. package/dist/shell/dashboard-shell.js +168 -0
  32. package/dist/shell/dashboard-shell.js.map +1 -0
  33. package/dist/shell/page-header.d.ts +19 -0
  34. package/dist/shell/page-header.d.ts.map +1 -0
  35. package/dist/shell/page-header.js +11 -0
  36. package/dist/shell/page-header.js.map +1 -0
  37. package/dist/shell/right-panel.d.ts +25 -0
  38. package/dist/shell/right-panel.d.ts.map +1 -0
  39. package/dist/shell/right-panel.js +37 -0
  40. package/dist/shell/right-panel.js.map +1 -0
  41. package/dist/shell/sidebar.d.ts +68 -0
  42. package/dist/shell/sidebar.d.ts.map +1 -0
  43. package/dist/shell/sidebar.js +68 -0
  44. package/dist/shell/sidebar.js.map +1 -0
  45. package/dist/shell/site-footer.d.ts +28 -0
  46. package/dist/shell/site-footer.d.ts.map +1 -0
  47. package/dist/shell/site-footer.js +15 -0
  48. package/dist/shell/site-footer.js.map +1 -0
  49. package/dist/shell/site-header-padding.d.ts +7 -0
  50. package/dist/shell/site-header-padding.d.ts.map +1 -0
  51. package/dist/shell/site-header-padding.js +27 -0
  52. package/dist/shell/site-header-padding.js.map +1 -0
  53. package/dist/shell/site-header.d.ts +23 -0
  54. package/dist/shell/site-header.d.ts.map +1 -0
  55. package/dist/shell/site-header.js +13 -0
  56. package/dist/shell/site-header.js.map +1 -0
  57. package/dist/shell/site-menu.d.ts +27 -0
  58. package/dist/shell/site-menu.d.ts.map +1 -0
  59. package/dist/shell/site-menu.js +56 -0
  60. package/dist/shell/site-menu.js.map +1 -0
  61. package/dist/shell/site-nav-link.d.ts +24 -0
  62. package/dist/shell/site-nav-link.d.ts.map +1 -0
  63. package/dist/shell/site-nav-link.js +35 -0
  64. package/dist/shell/site-nav-link.js.map +1 -0
  65. package/dist/shell/site-nav.d.ts +12 -0
  66. package/dist/shell/site-nav.d.ts.map +1 -0
  67. package/dist/shell/site-nav.js +9 -0
  68. package/dist/shell/site-nav.js.map +1 -0
  69. package/dist/shell/site-path.d.ts +8 -0
  70. package/dist/shell/site-path.d.ts.map +1 -0
  71. package/dist/shell/site-path.js +11 -0
  72. package/dist/shell/site-path.js.map +1 -0
  73. package/dist/shell/site-shell.d.ts +25 -0
  74. package/dist/shell/site-shell.d.ts.map +1 -0
  75. package/dist/shell/site-shell.js +17 -0
  76. package/dist/shell/site-shell.js.map +1 -0
  77. package/dist/styles/styles.css +10 -0
  78. package/dist/styles/theme.css +579 -0
  79. package/dist/styles/tokens.css +295 -0
  80. package/dist/testing/index.d.ts +321 -0
  81. package/dist/testing/index.d.ts.map +1 -0
  82. package/dist/testing/index.js +1175 -0
  83. package/dist/testing/index.js.map +1 -0
  84. package/dist/tokens.json +982 -0
  85. package/dist/ui/alert.d.ts +35 -0
  86. package/dist/ui/alert.d.ts.map +1 -0
  87. package/dist/ui/alert.js +65 -0
  88. package/dist/ui/alert.js.map +1 -0
  89. package/dist/ui/avatar.d.ts +16 -0
  90. package/dist/ui/avatar.d.ts.map +1 -0
  91. package/dist/ui/avatar.js +13 -0
  92. package/dist/ui/avatar.js.map +1 -0
  93. package/dist/ui/badge.d.ts +13 -0
  94. package/dist/ui/badge.d.ts.map +1 -0
  95. package/dist/ui/badge.js +24 -0
  96. package/dist/ui/badge.js.map +1 -0
  97. package/dist/ui/breadcrumbs.d.ts +13 -0
  98. package/dist/ui/breadcrumbs.d.ts.map +1 -0
  99. package/dist/ui/breadcrumbs.js +12 -0
  100. package/dist/ui/breadcrumbs.js.map +1 -0
  101. package/dist/ui/button-styles.d.ts +24 -0
  102. package/dist/ui/button-styles.d.ts.map +1 -0
  103. package/dist/ui/button-styles.js +50 -0
  104. package/dist/ui/button-styles.js.map +1 -0
  105. package/dist/ui/button.d.ts +27 -0
  106. package/dist/ui/button.d.ts.map +1 -0
  107. package/dist/ui/button.js +30 -0
  108. package/dist/ui/button.js.map +1 -0
  109. package/dist/ui/calendar.d.ts +19 -0
  110. package/dist/ui/calendar.d.ts.map +1 -0
  111. package/dist/ui/calendar.js +52 -0
  112. package/dist/ui/calendar.js.map +1 -0
  113. package/dist/ui/card.d.ts +30 -0
  114. package/dist/ui/card.d.ts.map +1 -0
  115. package/dist/ui/card.js +18 -0
  116. package/dist/ui/card.js.map +1 -0
  117. package/dist/ui/checkbox.d.ts +36 -0
  118. package/dist/ui/checkbox.d.ts.map +1 -0
  119. package/dist/ui/checkbox.js +38 -0
  120. package/dist/ui/checkbox.js.map +1 -0
  121. package/dist/ui/code-block.d.ts +20 -0
  122. package/dist/ui/code-block.d.ts.map +1 -0
  123. package/dist/ui/code-block.js +22 -0
  124. package/dist/ui/code-block.js.map +1 -0
  125. package/dist/ui/combo-box.d.ts +17 -0
  126. package/dist/ui/combo-box.d.ts.map +1 -0
  127. package/dist/ui/combo-box.js +14 -0
  128. package/dist/ui/combo-box.js.map +1 -0
  129. package/dist/ui/copy-button.d.ts +14 -0
  130. package/dist/ui/copy-button.d.ts.map +1 -0
  131. package/dist/ui/copy-button.js +36 -0
  132. package/dist/ui/copy-button.js.map +1 -0
  133. package/dist/ui/date-field.d.ts +38 -0
  134. package/dist/ui/date-field.d.ts.map +1 -0
  135. package/dist/ui/date-field.js +78 -0
  136. package/dist/ui/date-field.js.map +1 -0
  137. package/dist/ui/dialog.d.ts +41 -0
  138. package/dist/ui/dialog.d.ts.map +1 -0
  139. package/dist/ui/dialog.js +69 -0
  140. package/dist/ui/dialog.js.map +1 -0
  141. package/dist/ui/disclosure.d.ts +18 -0
  142. package/dist/ui/disclosure.d.ts.map +1 -0
  143. package/dist/ui/disclosure.js +15 -0
  144. package/dist/ui/disclosure.js.map +1 -0
  145. package/dist/ui/empty-state.d.ts +17 -0
  146. package/dist/ui/empty-state.d.ts.map +1 -0
  147. package/dist/ui/empty-state.js +9 -0
  148. package/dist/ui/empty-state.js.map +1 -0
  149. package/dist/ui/error-state.d.ts +45 -0
  150. package/dist/ui/error-state.d.ts.map +1 -0
  151. package/dist/ui/error-state.js +88 -0
  152. package/dist/ui/error-state.js.map +1 -0
  153. package/dist/ui/field.d.ts +46 -0
  154. package/dist/ui/field.d.ts.map +1 -0
  155. package/dist/ui/field.js +79 -0
  156. package/dist/ui/field.js.map +1 -0
  157. package/dist/ui/file-upload.d.ts +54 -0
  158. package/dist/ui/file-upload.d.ts.map +1 -0
  159. package/dist/ui/file-upload.js +170 -0
  160. package/dist/ui/file-upload.js.map +1 -0
  161. package/dist/ui/form.d.ts +56 -0
  162. package/dist/ui/form.d.ts.map +1 -0
  163. package/dist/ui/form.js +137 -0
  164. package/dist/ui/form.js.map +1 -0
  165. package/dist/ui/grid-list.d.ts +24 -0
  166. package/dist/ui/grid-list.d.ts.map +1 -0
  167. package/dist/ui/grid-list.js +21 -0
  168. package/dist/ui/grid-list.js.map +1 -0
  169. package/dist/ui/hero.d.ts +36 -0
  170. package/dist/ui/hero.d.ts.map +1 -0
  171. package/dist/ui/hero.js +19 -0
  172. package/dist/ui/hero.js.map +1 -0
  173. package/dist/ui/icon-button.d.ts +18 -0
  174. package/dist/ui/icon-button.d.ts.map +1 -0
  175. package/dist/ui/icon-button.js +13 -0
  176. package/dist/ui/icon-button.js.map +1 -0
  177. package/dist/ui/icon.d.ts +20 -0
  178. package/dist/ui/icon.d.ts.map +1 -0
  179. package/dist/ui/icon.js +26 -0
  180. package/dist/ui/icon.js.map +1 -0
  181. package/dist/ui/kbd.d.ts +7 -0
  182. package/dist/ui/kbd.d.ts.map +1 -0
  183. package/dist/ui/kbd.js +7 -0
  184. package/dist/ui/kbd.js.map +1 -0
  185. package/dist/ui/link-card.d.ts +23 -0
  186. package/dist/ui/link-card.d.ts.map +1 -0
  187. package/dist/ui/link-card.js +19 -0
  188. package/dist/ui/link-card.js.map +1 -0
  189. package/dist/ui/list-box.d.ts +17 -0
  190. package/dist/ui/list-box.d.ts.map +1 -0
  191. package/dist/ui/list-box.js +18 -0
  192. package/dist/ui/list-box.js.map +1 -0
  193. package/dist/ui/menu.d.ts +31 -0
  194. package/dist/ui/menu.d.ts.map +1 -0
  195. package/dist/ui/menu.js +40 -0
  196. package/dist/ui/menu.js.map +1 -0
  197. package/dist/ui/number-field.d.ts +19 -0
  198. package/dist/ui/number-field.d.ts.map +1 -0
  199. package/dist/ui/number-field.js +19 -0
  200. package/dist/ui/number-field.js.map +1 -0
  201. package/dist/ui/prose.d.ts +12 -0
  202. package/dist/ui/prose.d.ts.map +1 -0
  203. package/dist/ui/prose.js +11 -0
  204. package/dist/ui/prose.js.map +1 -0
  205. package/dist/ui/radio-group.d.ts +20 -0
  206. package/dist/ui/radio-group.d.ts.map +1 -0
  207. package/dist/ui/radio-group.js +16 -0
  208. package/dist/ui/radio-group.js.map +1 -0
  209. package/dist/ui/scroll-region.d.ts +18 -0
  210. package/dist/ui/scroll-region.d.ts.map +1 -0
  211. package/dist/ui/scroll-region.js +29 -0
  212. package/dist/ui/scroll-region.js.map +1 -0
  213. package/dist/ui/search-field.d.ts +12 -0
  214. package/dist/ui/search-field.d.ts.map +1 -0
  215. package/dist/ui/search-field.js +12 -0
  216. package/dist/ui/search-field.js.map +1 -0
  217. package/dist/ui/search.d.ts +43 -0
  218. package/dist/ui/search.d.ts.map +1 -0
  219. package/dist/ui/search.js +45 -0
  220. package/dist/ui/search.js.map +1 -0
  221. package/dist/ui/section.d.ts +50 -0
  222. package/dist/ui/section.d.ts.map +1 -0
  223. package/dist/ui/section.js +25 -0
  224. package/dist/ui/section.js.map +1 -0
  225. package/dist/ui/segmented-control.d.ts +18 -0
  226. package/dist/ui/segmented-control.d.ts.map +1 -0
  227. package/dist/ui/segmented-control.js +17 -0
  228. package/dist/ui/segmented-control.js.map +1 -0
  229. package/dist/ui/select.d.ts +18 -0
  230. package/dist/ui/select.d.ts.map +1 -0
  231. package/dist/ui/select.js +13 -0
  232. package/dist/ui/select.js.map +1 -0
  233. package/dist/ui/selection-bar.d.ts +28 -0
  234. package/dist/ui/selection-bar.d.ts.map +1 -0
  235. package/dist/ui/selection-bar.js +35 -0
  236. package/dist/ui/selection-bar.js.map +1 -0
  237. package/dist/ui/sheet.d.ts +21 -0
  238. package/dist/ui/sheet.d.ts.map +1 -0
  239. package/dist/ui/sheet.js +16 -0
  240. package/dist/ui/sheet.js.map +1 -0
  241. package/dist/ui/skeleton.d.ts +31 -0
  242. package/dist/ui/skeleton.d.ts.map +1 -0
  243. package/dist/ui/skeleton.js +38 -0
  244. package/dist/ui/skeleton.js.map +1 -0
  245. package/dist/ui/slider.d.ts +31 -0
  246. package/dist/ui/slider.d.ts.map +1 -0
  247. package/dist/ui/slider.js +33 -0
  248. package/dist/ui/slider.js.map +1 -0
  249. package/dist/ui/spinner.d.ts +27 -0
  250. package/dist/ui/spinner.d.ts.map +1 -0
  251. package/dist/ui/spinner.js +21 -0
  252. package/dist/ui/spinner.js.map +1 -0
  253. package/dist/ui/split.d.ts +14 -0
  254. package/dist/ui/split.d.ts.map +1 -0
  255. package/dist/ui/split.js +11 -0
  256. package/dist/ui/split.js.map +1 -0
  257. package/dist/ui/stat-list.d.ts +25 -0
  258. package/dist/ui/stat-list.d.ts.map +1 -0
  259. package/dist/ui/stat-list.js +14 -0
  260. package/dist/ui/stat-list.js.map +1 -0
  261. package/dist/ui/steps.d.ts +23 -0
  262. package/dist/ui/steps.d.ts.map +1 -0
  263. package/dist/ui/steps.js +16 -0
  264. package/dist/ui/steps.js.map +1 -0
  265. package/dist/ui/switch.d.ts +13 -0
  266. package/dist/ui/switch.d.ts.map +1 -0
  267. package/dist/ui/switch.js +12 -0
  268. package/dist/ui/switch.js.map +1 -0
  269. package/dist/ui/table.d.ts +25 -0
  270. package/dist/ui/table.d.ts.map +1 -0
  271. package/dist/ui/table.js +29 -0
  272. package/dist/ui/table.js.map +1 -0
  273. package/dist/ui/tag.d.ts +14 -0
  274. package/dist/ui/tag.d.ts.map +1 -0
  275. package/dist/ui/tag.js +11 -0
  276. package/dist/ui/tag.js.map +1 -0
  277. package/dist/ui/text-field.d.ts +27 -0
  278. package/dist/ui/text-field.d.ts.map +1 -0
  279. package/dist/ui/text-field.js +17 -0
  280. package/dist/ui/text-field.js.map +1 -0
  281. package/dist/ui/text-link.d.ts +17 -0
  282. package/dist/ui/text-link.d.ts.map +1 -0
  283. package/dist/ui/text-link.js +15 -0
  284. package/dist/ui/text-link.js.map +1 -0
  285. package/dist/ui/theme-switcher.d.ts +26 -0
  286. package/dist/ui/theme-switcher.d.ts.map +1 -0
  287. package/dist/ui/theme-switcher.js +32 -0
  288. package/dist/ui/theme-switcher.js.map +1 -0
  289. package/dist/ui/theme.d.ts +54 -0
  290. package/dist/ui/theme.d.ts.map +1 -0
  291. package/dist/ui/theme.js +135 -0
  292. package/dist/ui/theme.js.map +1 -0
  293. package/dist/ui/toast.d.ts +34 -0
  294. package/dist/ui/toast.d.ts.map +1 -0
  295. package/dist/ui/toast.js +69 -0
  296. package/dist/ui/toast.js.map +1 -0
  297. package/dist/ui/tooltip.d.ts +10 -0
  298. package/dist/ui/tooltip.d.ts.map +1 -0
  299. package/dist/ui/tooltip.js +10 -0
  300. package/dist/ui/tooltip.js.map +1 -0
  301. package/package.json +123 -0
  302. package/templates/next/error.tsx +32 -0
  303. package/templates/next/loading.tsx +19 -0
  304. package/templates/next/not-found.tsx +18 -0
  305. package/templates/next/page-transition.tsx +33 -0
  306. package/templates/next/portal-layout.tsx +70 -0
  307. package/templates/next/prefetch-on-intent.ts +31 -0
  308. package/templates/next/root-layout.tsx +16 -0
  309. package/templates/next/site-layout.tsx +58 -0
  310. package/templates/next/site-nav.ts +16 -0
  311. package/templates/next/site-not-found.tsx +21 -0
  312. package/templates/next/site-router.tsx +17 -0
@@ -0,0 +1,137 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useId, useLayoutEffect, useRef, useState, } from 'react';
4
+ import { Form as RACForm } from 'react-aria-components';
5
+ import { CircleAlert, CircleCheck } from 'lucide-react';
6
+ import { cn } from '../lib/cn.js';
7
+ import { NecessityContext } from './field.js';
8
+ /**
9
+ * Every problem in one place at the top of the form, each a link that moves focus to its field
10
+ * (WCAG 3.3.1, 3.3.3). The messages match the ones beside the fields, word for word.
11
+ */
12
+ export function ErrorSummary({ errors, title = 'There is a problem', autoFocus, className, }) {
13
+ const ref = useRef(null);
14
+ const headingId = useId();
15
+ const key = errors.map((e) => e.id + e.message).join('|');
16
+ // `key` is deliberate: a new set of errors (a second failed submit) moves focus to the summary again.
17
+ /* oxlint-disable react/exhaustive-effect-dependencies */
18
+ useEffect(() => {
19
+ if (autoFocus && errors.length)
20
+ ref.current?.focus();
21
+ }, [autoFocus, key, errors.length]);
22
+ /* oxlint-enable react/exhaustive-effect-dependencies */
23
+ if (!errors.length)
24
+ return null;
25
+ return (_jsxs("div", { ref: ref, tabIndex: -1, role: "group", "aria-labelledby": headingId, className: cn('rounded-lg border-2 border-destructive bg-destructive-subtle p-4 text-foreground outline-none focus-visible:focus-ring', className), children: [_jsxs("h2", { id: headingId, className: "flex items-center gap-2 text-subheading", children: [_jsx(CircleAlert, { "aria-hidden": "true", className: "size-5 shrink-0 text-destructive" }), title] }), _jsx("ul", { className: "mt-2 flex flex-col gap-1 pl-7 text-sm", children: errors.map((e) => (_jsx("li", { children: _jsx("a", { href: `#${e.id}`, onClick: (ev) => {
26
+ const el = document.getElementById(e.id);
27
+ if (!el)
28
+ return;
29
+ ev.preventDefault();
30
+ el.focus();
31
+ el.scrollIntoView({ block: 'center' });
32
+ }, className: "inline-flex min-h-target items-center rounded-sm font-semibold text-destructive underline decoration-1 underline-offset-3 outline-none focus-visible:focus-ring", children: e.message }) }, e.id + e.message))) })] }));
33
+ }
34
+ function fieldTarget(el) {
35
+ const root = el.closest('[data-rac]');
36
+ // Hidden selects behind a React Aria Select point focus at the visible trigger.
37
+ const hidden = el.getAttribute('aria-hidden') === 'true' || el.tabIndex === -1 || el.tagName === 'SELECT';
38
+ const visible = hidden
39
+ ? root?.querySelector('button[id], input[id]:not([type=hidden]):not([tabindex="-1"])')
40
+ : null;
41
+ return { root, target: visible ?? el };
42
+ }
43
+ /** The message a field is showing — what the summary must repeat word for word. */
44
+ function shownMessage(root, fallback) {
45
+ const text = root
46
+ ?.querySelector('[data-field-error-text]')
47
+ ?.textContent?.replace(/^Error:\s*/, '')
48
+ .trim();
49
+ return text || fallback;
50
+ }
51
+ function collectErrors(form) {
52
+ const seen = new Set();
53
+ const out = [];
54
+ for (const el of Array.from(form.elements)) {
55
+ if (!el.willValidate || el.validity.valid)
56
+ continue;
57
+ // Radio groups and checkbox groups: one entry, pointing at the first control.
58
+ const key = el.name || el.id;
59
+ if (!key || seen.has(key))
60
+ continue;
61
+ seen.add(key);
62
+ const { root, target } = fieldTarget(el);
63
+ if (!target.id)
64
+ continue;
65
+ out.push({ id: target.id, message: shownMessage(root, el.validationMessage) });
66
+ }
67
+ return out;
68
+ }
69
+ /**
70
+ * React Aria Form, validated natively on submit: invalid fields show their message and the first gets focus;
71
+ * the ErrorSummary lists them all. Server errors (`validationErrors`, keyed by field name) show the same way,
72
+ * and the summary takes focus because no field has it.
73
+ */
74
+ export function Form({ necessityIndicator = 'required', errorSummary = true, validationErrors, onSubmit, className, children, ...props }) {
75
+ const ref = useRef(null);
76
+ const [errors, setErrors] = useState([]);
77
+ const [fromServer, setFromServer] = useState(false);
78
+ useEffect(() => {
79
+ const form = ref.current;
80
+ if (!form)
81
+ return;
82
+ let frame = 0;
83
+ const onInvalid = () => {
84
+ cancelAnimationFrame(frame);
85
+ frame = requestAnimationFrame(() => {
86
+ frame = requestAnimationFrame(() => {
87
+ setFromServer(false);
88
+ setErrors(collectErrors(form));
89
+ });
90
+ });
91
+ };
92
+ form.addEventListener('invalid', onInvalid, true);
93
+ return () => form.removeEventListener('invalid', onInvalid, true);
94
+ }, []);
95
+ // Server errors: after they render, read the messages back from the fields.
96
+ useLayoutEffect(() => {
97
+ const form = ref.current;
98
+ if (!form || !validationErrors || !Object.keys(validationErrors).length)
99
+ return;
100
+ const frame = requestAnimationFrame(() => {
101
+ const items = [];
102
+ for (const [name, msg] of Object.entries(validationErrors)) {
103
+ const el = form.elements.namedItem(name);
104
+ const node = el instanceof RadioNodeList ? el[0] : el;
105
+ if (!node)
106
+ continue;
107
+ const { target } = fieldTarget(node);
108
+ if (target.id)
109
+ items.push({ id: target.id, message: Array.isArray(msg) ? msg.join(' ') : String(msg) });
110
+ }
111
+ setFromServer(true);
112
+ setErrors(items);
113
+ });
114
+ return () => cancelAnimationFrame(frame);
115
+ }, [validationErrors]);
116
+ return (_jsx(NecessityContext.Provider, { value: necessityIndicator, children: _jsxs(RACForm, { ref: ref, ...props, validationErrors: validationErrors, onSubmit: (e) => {
117
+ setErrors([]);
118
+ onSubmit?.(e);
119
+ }, className: cn('flex flex-col gap-(--field-gap)', className), children: [errorSummary && _jsx(ErrorSummary, { errors: errors, autoFocus: fromServer }), children] }) }));
120
+ }
121
+ /** A titled group of related fields: heading and hint on the left at wide sizes, fields on the right. */
122
+ export function FormSection({ title, description, children, className }) {
123
+ const id = useId();
124
+ return (_jsxs("div", { role: "group", "aria-labelledby": id, className: cn('grid gap-4 border-t border-border pt-6 first:border-t-0 first:pt-0 @min-[48rem]/main:grid-cols-[minmax(12rem,1fr)_2fr] @min-[48rem]/main:gap-8', className), children: [_jsxs("div", { children: [_jsx("h2", { id: id, className: "text-subheading", children: title }), description && (_jsx("p", { className: "mt-1 max-w-(--measure) text-[13px] leading-5 text-muted-foreground", children: description }))] }), _jsx("div", { className: "flex min-w-0 flex-col gap-(--field-gap)", children: children })] }));
125
+ }
126
+ /** The form's buttons: the primary action first in reading order at the end of the row, cancel beside it. */
127
+ export function FormActions({ children, className }) {
128
+ return (_jsx("div", { className: cn('flex flex-wrap items-center justify-end gap-(--control-gap) border-t border-border pt-4', className), children: children }));
129
+ }
130
+ /**
131
+ * A polite live region for results that don't move focus: "Saved", "3 results" (WCAG 4.1.3).
132
+ * Render it once, empty, and change its text.
133
+ */
134
+ export function StatusMessage({ children, tone = 'success', className, }) {
135
+ return (_jsx("p", { role: "status", className: cn('flex min-h-5 items-center gap-1.5 text-[13px] leading-5 font-semibold', tone === 'success' ? 'text-success' : 'text-muted-foreground', className), children: children ? (_jsxs(_Fragment, { children: [tone === 'success' && _jsx(CircleCheck, { "aria-hidden": "true", className: "size-4 shrink-0" }), children] })) : null }));
136
+ }
137
+ //# sourceMappingURL=form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"form.js","sourceRoot":"","sources":["../../src/ui/form.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type GridListItemProps as RACGridListItemProps, type GridListProps as RACGridListProps } from 'react-aria-components';
3
+ export interface GridListProps<T extends object> extends Omit<RACGridListProps<T>, 'className'> {
4
+ /** Required: what the list holds ("Members"). */
5
+ 'aria-label': string;
6
+ className?: string;
7
+ }
8
+ /**
9
+ * A list of items people act on — members, files, integrations — where each row can hold its own buttons.
10
+ * Arrow keys move between rows, Tab reaches the buttons in a row. With `selectionMode="multiple"` every row
11
+ * gets a SelectionCheckbox; Space or a click on the row toggles it. The list is `relative` because it scrolls.
12
+ */
13
+ export declare function GridList<T extends object>({ className, ...props }: GridListProps<T>): import("react").JSX.Element;
14
+ export interface GridListItemProps extends Omit<RACGridListItemProps, 'className' | 'children'> {
15
+ children: ReactNode;
16
+ /** Second line: a role, a size, a status in words. */
17
+ description?: ReactNode;
18
+ /** Buttons for this row only. Name them with the row ("Remove Priya Shah"). */
19
+ actions?: ReactNode;
20
+ className?: string;
21
+ }
22
+ /** Selected: brand-subtle, the 3px sidebar-primary marker and a ticked box — the same signals as a table row. */
23
+ export declare function GridListItem({ children, description, actions, className, ...props }: GridListItemProps): import("react").JSX.Element;
24
+ //# sourceMappingURL=grid-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-list.d.ts","sourceRoot":"","sources":["../../src/ui/grid-list.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAGL,KAAK,iBAAiB,IAAI,oBAAoB,EAC9C,KAAK,aAAa,IAAI,gBAAgB,EACvC,MAAM,uBAAuB,CAAC;AAI/B,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC;IAC7F,iDAAiD;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,aAAa,CAAC,CAAC,CAAC,+BAUnF;AAED,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,oBAAoB,EAAE,WAAW,GAAG,UAAU,CAAC;IAC7F,QAAQ,EAAE,SAAS,CAAC;IACpB,sDAAsD;IACtD,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iHAAiH;AACjH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,WAAW,EACX,OAAO,EACP,SAAS,EACT,GAAG,KAAK,EACT,EAAE,iBAAiB,+BA6BnB"}
@@ -0,0 +1,21 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { GridList as RACGridList, GridListItem as RACGridListItem, } from 'react-aria-components';
4
+ import { cn } from '../lib/cn.js';
5
+ import { SelectionCheckbox } from './checkbox.js';
6
+ /**
7
+ * A list of items people act on — members, files, integrations — where each row can hold its own buttons.
8
+ * Arrow keys move between rows, Tab reaches the buttons in a row. With `selectionMode="multiple"` every row
9
+ * gets a SelectionCheckbox; Space or a click on the row toggles it. The list is `relative` because it scrolls.
10
+ */
11
+ export function GridList({ className, ...props }) {
12
+ return (_jsx(RACGridList, { ...props, className: cn('relative flex max-h-[inherit] flex-col overflow-auto rounded-lg border border-border bg-card text-sm outline-none data-focus-visible:focus-ring', className) }));
13
+ }
14
+ /** Selected: brand-subtle, the 3px sidebar-primary marker and a ticked box — the same signals as a table row. */
15
+ export function GridListItem({ children, description, actions, className, ...props }) {
16
+ const textValue = props.textValue ?? (typeof children === 'string' ? children : undefined);
17
+ return (_jsx(RACGridListItem, { ...props, textValue: textValue, className: cn(
18
+ // React Aria sets data-hovered only on a row that can be selected or has an action: the pointer then.
19
+ 'group/item relative flex min-h-[calc(var(--control-height)+12px)] cursor-default items-center gap-3 border-b border-border px-3 py-1.5 outline-none last:border-b-0', 'data-hovered:cursor-pointer data-disabled:cursor-not-allowed data-hovered:bg-accent data-selected:bg-brand-subtle data-selected:shadow-[inset_3px_0_0_var(--sidebar-primary)] data-focus-visible:focus-ring-inset data-disabled:opacity-60', className), children: ({ selectionMode, selectionBehavior }) => (_jsxs(_Fragment, { children: [selectionMode !== 'none' && selectionBehavior === 'toggle' && (_jsx(SelectionCheckbox, { className: "-ml-1" })), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "leading-5 font-medium text-foreground", children: children }), description && (_jsx("span", { className: "text-[13px] leading-5 text-muted-foreground", children: description }))] }), actions && _jsx("span", { className: "flex shrink-0 items-center gap-1", children: actions })] })) }));
20
+ }
21
+ //# sourceMappingURL=grid-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid-list.js","sourceRoot":"","sources":["../../src/ui/grid-list.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EACL,QAAQ,IAAI,WAAW,EACvB,YAAY,IAAI,eAAe,GAGhC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAQlD;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAmB,EAAE,SAAS,EAAE,GAAG,KAAK,EAAoB;IAClF,OAAO,CACL,KAAC,WAAW,OACN,KAAK,EACT,SAAS,EAAE,EAAE,CACX,iJAAiJ,EACjJ,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC;AAWD,iHAAiH;AACjH,MAAM,UAAU,YAAY,CAAC,EAC3B,QAAQ,EACR,WAAW,EACX,OAAO,EACP,SAAS,EACT,GAAG,KAAK,EACU;IAClB,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3F,OAAO,CACL,KAAC,eAAe,OACV,KAAK,EACT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,EAAE;QACX,sGAAsG;QACtG,qKAAqK,EACrK,4OAA4O,EAC5O,SAAS,CACV,YAEA,CAAC,EAAE,aAAa,EAAE,iBAAiB,EAAE,EAAE,EAAE,CAAC,CACzC,8BACG,aAAa,KAAK,MAAM,IAAI,iBAAiB,KAAK,QAAQ,IAAI,CAC7D,KAAC,iBAAiB,IAAC,SAAS,EAAC,OAAO,GAAG,CACxC,EACD,gBAAM,SAAS,EAAC,8BAA8B,aAC5C,eAAM,SAAS,EAAC,uCAAuC,YAAE,QAAQ,GAAQ,EACxE,WAAW,IAAI,CACd,eAAM,SAAS,EAAC,6CAA6C,YAAE,WAAW,GAAQ,CACnF,IACI,EACN,OAAO,IAAI,eAAM,SAAS,EAAC,kCAAkC,YAAE,OAAO,GAAQ,IAC9E,CACJ,GACe,CACnB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface HeroProps {
3
+ /** The h1. Mark a phrase in it with HeroHighlight. */
4
+ title: ReactNode;
5
+ eyebrow?: ReactNode;
6
+ /** A sentence or two under the title, inside `--measure`. */
7
+ intro?: ReactNode;
8
+ /** One or two LinkButtons at `visualSize="lg"`: at most one primary. */
9
+ actions?: ReactNode;
10
+ /** Beside the text from where both fit, above it never: a code sample, figures, a picture. */
11
+ aside?: ReactNode;
12
+ /**
13
+ * Under the text, across the container: a screenshot, a video. Anything that moves by itself for more than
14
+ * five seconds needs a visible pause control (the README's motion rule).
15
+ */
16
+ media?: ReactNode;
17
+ /** The title's id, to name the page's main by it. */
18
+ titleId?: string;
19
+ /** `h1` (default). `h2` or `h3` only to show a hero inside another page, as the docs do. */
20
+ titleAs?: 'h1' | 'h2' | 'h3';
21
+ className?: string;
22
+ }
23
+ /**
24
+ * The first band of a landing page: eyebrow, title, intro and calls to action, with an optional aside beside
25
+ * them and media under them. Stacks to one column where the two columns don't fit. Server-safe.
26
+ */
27
+ export declare function Hero({ title, eyebrow, intro, actions, aside, media, titleId, titleAs: Title, className, }: HeroProps): import("react").JSX.Element;
28
+ /**
29
+ * A phrase in the hero's title set apart by colour: `brand` (default) or `muted`. Both meet text contrast on
30
+ * the page's ground in all four themes, and the words still read without it.
31
+ */
32
+ export declare function HeroHighlight({ children, tone, }: {
33
+ children: ReactNode;
34
+ tone?: 'brand' | 'muted';
35
+ }): import("react").JSX.Element;
36
+ //# sourceMappingURL=hero.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hero.d.ts","sourceRoot":"","sources":["../../src/ui/hero.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,WAAW,SAAS;IACxB,sDAAsD;IACtD,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,wEAAwE;IACxE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,8FAA8F;IAC9F,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4FAA4F;IAC5F,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,EACnB,KAAK,EACL,OAAO,EACP,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,EAAE,KAAY,EACrB,SAAS,GACV,EAAE,SAAS,+BA0BX;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,IAAc,GACf,EAAE;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CAC1B,+BAIA"}
@@ -0,0 +1,19 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../lib/cn.js';
3
+ import { Eyebrow } from './section.js';
4
+ /**
5
+ * The first band of a landing page: eyebrow, title, intro and calls to action, with an optional aside beside
6
+ * them and media under them. Stacks to one column where the two columns don't fit. Server-safe.
7
+ */
8
+ export function Hero({ title, eyebrow, intro, actions, aside, media, titleId, titleAs: Title = 'h1', className, }) {
9
+ const text = (_jsxs("div", { className: "min-w-0", children: [eyebrow && _jsx(Eyebrow, { className: "mb-4", children: eyebrow }), _jsx(Title, { id: titleId, className: "max-w-[20ch] text-display", children: title }), intro && _jsx("p", { className: "mt-6 max-w-(--measure) text-lead text-muted-foreground", children: intro }), actions && _jsx("div", { className: "mt-8 flex flex-wrap gap-(--control-gap)", children: actions })] }));
10
+ return (_jsx("section", { className: cn('section-band', className), children: _jsxs("div", { className: "site-container", children: [aside ? (_jsxs("div", { className: "split", children: [text, _jsx("div", { className: "min-w-0", children: aside })] })) : (text), media && _jsx("div", { className: "mt-12 min-w-0", children: media })] }) }));
11
+ }
12
+ /**
13
+ * A phrase in the hero's title set apart by colour: `brand` (default) or `muted`. Both meet text contrast on
14
+ * the page's ground in all four themes, and the words still read without it.
15
+ */
16
+ export function HeroHighlight({ children, tone = 'brand', }) {
17
+ return (_jsx("span", { className: tone === 'brand' ? 'text-brand' : 'text-muted-foreground', children: children }));
18
+ }
19
+ //# sourceMappingURL=hero.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hero.js","sourceRoot":"","sources":["../../src/ui/hero.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAwBvC;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,EACnB,KAAK,EACL,OAAO,EACP,KAAK,EACL,OAAO,EACP,KAAK,EACL,KAAK,EACL,OAAO,EACP,OAAO,EAAE,KAAK,GAAG,IAAI,EACrB,SAAS,GACC;IACV,MAAM,IAAI,GAAG,CACX,eAAK,SAAS,EAAC,SAAS,aACrB,OAAO,IAAI,KAAC,OAAO,IAAC,SAAS,EAAC,MAAM,YAAE,OAAO,GAAW,EACzD,KAAC,KAAK,IAAC,EAAE,EAAE,OAAO,EAAE,SAAS,EAAC,2BAA2B,YACtD,KAAK,GACA,EACP,KAAK,IAAI,YAAG,SAAS,EAAC,wDAAwD,YAAE,KAAK,GAAK,EAC1F,OAAO,IAAI,cAAK,SAAS,EAAC,yCAAyC,YAAE,OAAO,GAAO,IAChF,CACP,CAAC;IACF,OAAO,CACL,kBAAS,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC,YAC/C,eAAK,SAAS,EAAC,gBAAgB,aAC5B,KAAK,CAAC,CAAC,CAAC,CACP,eAAK,SAAS,EAAC,OAAO,aACnB,IAAI,EACL,cAAK,SAAS,EAAC,SAAS,YAAE,KAAK,GAAO,IAClC,CACP,CAAC,CAAC,CAAC,CACF,IAAI,CACL,EACA,KAAK,IAAI,cAAK,SAAS,EAAC,eAAe,YAAE,KAAK,GAAO,IAClD,GACE,CACX,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,QAAQ,EACR,IAAI,GAAG,OAAO,GAIf;IACC,OAAO,CACL,eAAM,SAAS,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,uBAAuB,YAAG,QAAQ,GAAQ,CAC9F,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type ButtonProps } from './button.js';
2
+ import { type IconProp } from './icon.js';
3
+ export type { IconComponent, IconProp } from './icon.js';
4
+ export interface IconButtonProps extends Omit<ButtonProps, 'children' | 'visualSize'> {
5
+ /** Accessible name, also shown as the tooltip. Include any count: "Notifications, 3 unread". */
6
+ label: string;
7
+ icon: IconProp;
8
+ /** Painted size: 36px or 28px. The target is at least --target-min either way (44px at AAA). */
9
+ visualSize?: 'icon' | 'icon-sm';
10
+ /** Visual count bubble (aria-hidden — put the number in `label`). */
11
+ count?: number;
12
+ /** false hides the tooltip; a string replaces its text. */
13
+ tooltip?: boolean | string;
14
+ tooltipPlacement?: 'top' | 'bottom' | 'left' | 'right';
15
+ }
16
+ /** Icon-only button that always carries an accessible name and a tooltip. */
17
+ export declare const IconButton: import("react").ForwardRefExoticComponent<IconButtonProps & import("react").RefAttributes<HTMLButtonElement>>;
18
+ //# sourceMappingURL=icon-button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon-button.d.ts","sourceRoot":"","sources":["../../src/ui/icon-button.tsx"],"names":[],"mappings":"AACA,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAGtD,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEzD,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,WAAW,EAAE,UAAU,GAAG,YAAY,CAAC;IACnF,gGAAgG;IAChG,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,gGAAgG;IAChG,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,OAAO,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;CACxD;AAED,6EAA6E;AAC7E,eAAO,MAAM,UAAU,+GAoCrB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { forwardRef } from 'react';
3
+ import { Button } from './button.js';
4
+ import { renderIcon } from './icon.js';
5
+ import { Tooltip, TooltipTrigger } from './tooltip.js';
6
+ /** Icon-only button that always carries an accessible name and a tooltip. */
7
+ export const IconButton = forwardRef(function IconButton({ label, icon, visualSize = 'icon', variant = 'ghost', count, tooltip = true, tooltipPlacement = 'bottom', ...props }, ref) {
8
+ const button = (_jsxs(Button, { ref: ref, variant: variant, visualSize: visualSize, "aria-label": label, ...props, children: [renderIcon(icon), count ? (_jsx("span", { "aria-hidden": "true", className: "absolute top-0.5 right-0.5 min-w-[18px] rounded-full bg-destructive px-[5px] text-center text-[11px] leading-[18px] font-bold text-destructive-foreground ring-2 ring-background", children: count > 99 ? '99+' : count })) : null] }));
9
+ if (!tooltip)
10
+ return button;
11
+ return (_jsxs(TooltipTrigger, { delay: 500, children: [button, _jsx(Tooltip, { placement: tooltipPlacement, children: typeof tooltip === 'string' ? tooltip : label })] }));
12
+ });
13
+ //# sourceMappingURL=icon-button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon-button.js","sourceRoot":"","sources":["../../src/ui/icon-button.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,MAAM,EAAoB,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAiBvD,6EAA6E;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,UAAU,CAAqC,SAAS,UAAU,CAC1F,EACE,KAAK,EACL,IAAI,EACJ,UAAU,GAAG,MAAM,EACnB,OAAO,GAAG,OAAO,EACjB,KAAK,EACL,OAAO,GAAG,IAAI,EACd,gBAAgB,GAAG,QAAQ,EAC3B,GAAG,KAAK,EACT,EACD,GAAG;IAEH,MAAM,MAAM,GAAG,CACb,MAAC,MAAM,IAAC,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,gBAAc,KAAK,KAAM,KAAK,aACrF,UAAU,CAAC,IAAI,CAAC,EAEhB,KAAK,CAAC,CAAC,CAAC,CACP,8BACc,MAAM,EAClB,SAAS,EAAC,kLAAkL,YAE3L,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GACtB,CACR,CAAC,CAAC,CAAC,IAAI,IACD,CACV,CAAC;IACF,IAAI,CAAC,OAAO;QAAE,OAAO,MAAM,CAAC;IAC5B,OAAO,CACL,MAAC,cAAc,IAAC,KAAK,EAAE,GAAG,aACvB,MAAM,EACP,KAAC,OAAO,IAAC,SAAS,EAAE,gBAAgB,YACjC,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GACtC,IACK,CAClB,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { type ComponentType, type ReactElement, type SVGProps } from 'react';
2
+ export type IconComponent = ComponentType<SVGProps<SVGSVGElement> & {
3
+ className?: string;
4
+ }>;
5
+ /**
6
+ * An icon as a component (`Folder`) or as an element (`<Folder />`). A server component that passes an icon to
7
+ * a client component has to pass the element: a component is a function, and can't cross that boundary.
8
+ */
9
+ export type IconProp = IconComponent | ReactElement<SVGProps<SVGSVGElement>>;
10
+ /**
11
+ * An icon given either way, hidden from assistive tech (its label is the control's). `className` is the
12
+ * component's default; an element's own classes come after it, so the caller's size or colour wins.
13
+ *
14
+ * An element a server component passes to a client component can arrive as a lazy reference, not an element
15
+ * (React defers some of what it sends), so it can't be cloned. It is rendered inside a span that carries
16
+ * `aria-hidden` and the default classes; the svg fills the span through a rule with no specificity, so a
17
+ * class on the element itself still wins.
18
+ */
19
+ export declare function renderIcon(icon: IconProp, className?: string): ReactElement;
20
+ //# sourceMappingURL=icon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon.d.ts","sourceRoot":"","sources":["../../src/ui/icon.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,YAAY,EAEjB,KAAK,QAAQ,EACd,MAAM,OAAO,CAAC;AAGf,MAAM,MAAM,aAAa,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC5F;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAM7E;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,YAAY,CAoB3E"}
@@ -0,0 +1,26 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cloneElement, isValidElement, } from 'react';
3
+ import { cn } from '../lib/cn.js';
4
+ const LAZY = Symbol.for('react.lazy');
5
+ const isLazy = (x) => typeof x === 'object' && x !== null && x.$$typeof === LAZY;
6
+ /**
7
+ * An icon given either way, hidden from assistive tech (its label is the control's). `className` is the
8
+ * component's default; an element's own classes come after it, so the caller's size or colour wins.
9
+ *
10
+ * An element a server component passes to a client component can arrive as a lazy reference, not an element
11
+ * (React defers some of what it sends), so it can't be cloned. It is rendered inside a span that carries
12
+ * `aria-hidden` and the default classes; the svg fills the span through a rule with no specificity, so a
13
+ * class on the element itself still wins.
14
+ */
15
+ export function renderIcon(icon, className) {
16
+ if (isValidElement(icon))
17
+ return cloneElement(icon, {
18
+ 'aria-hidden': true,
19
+ className: cn(className, icon.props.className),
20
+ });
21
+ if (isLazy(icon))
22
+ return (_jsx("span", { "aria-hidden": "true", className: cn('inline-flex shrink-0 items-center justify-center [:where(&>svg)]:size-full', className), children: icon }));
23
+ const Icon = icon;
24
+ return _jsx(Icon, { "aria-hidden": "true", className: className });
25
+ }
26
+ //# sourceMappingURL=icon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"icon.js","sourceRoot":"","sources":["../../src/ui/icon.tsx"],"names":[],"mappings":";AAAA,OAAO,EACL,YAAY,EACZ,cAAc,GAKf,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AASlC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;AACtC,MAAM,MAAM,GAAG,CAAC,CAAU,EAAkB,EAAE,CAC5C,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAK,CAA2B,CAAC,QAAQ,KAAK,IAAI,CAAC;AAExF;;;;;;;;GAQG;AACH,MAAM,UAAU,UAAU,CAAC,IAAc,EAAE,SAAkB;IAC3D,IAAI,cAAc,CAA0B,IAAI,CAAC;QAC/C,OAAO,YAAY,CAAC,IAAI,EAAE;YACxB,aAAa,EAAE,IAAI;YACnB,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;SAC/C,CAAC,CAAC;IACL,IAAI,MAAM,CAAC,IAAI,CAAC;QACd,OAAO,CACL,8BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CACX,4EAA4E,EAC5E,SAAS,CACV,YAEA,IAAI,GACA,CACR,CAAC;IACJ,MAAM,IAAI,GAAG,IAAqB,CAAC;IACnC,OAAO,KAAC,IAAI,mBAAa,MAAM,EAAC,SAAS,EAAE,SAAS,GAAI,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { ReactNode } from 'react';
2
+ /** Keyboard hint. Decorative by default: say the shortcut in words where it matters. */
3
+ export declare function Kbd({ children, className }: {
4
+ children: ReactNode;
5
+ className?: string;
6
+ }): import("react").JSX.Element;
7
+ //# sourceMappingURL=kbd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kbd.d.ts","sourceRoot":"","sources":["../../src/ui/kbd.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,wFAAwF;AACxF,wBAAgB,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAYvF"}
package/dist/ui/kbd.js ADDED
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from '../lib/cn.js';
3
+ /** Keyboard hint. Decorative by default: say the shortcut in words where it matters. */
4
+ export function Kbd({ children, className }) {
5
+ return (_jsx("kbd", { "aria-hidden": "true", className: cn('inline-flex h-[22px] items-center rounded-sm border border-border bg-muted px-1.5 font-mono text-xs leading-5 text-muted-foreground', className), children: children }));
6
+ }
7
+ //# sourceMappingURL=kbd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kbd.js","sourceRoot":"","sources":["../../src/ui/kbd.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC,wFAAwF;AACxF,MAAM,UAAU,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,EAA+C;IACtF,OAAO,CACL,6BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CACX,qIAAqI,EACrI,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type LinkProps as RACLinkProps } from 'react-aria-components';
3
+ import { type IconProp } from './icon.js';
4
+ export interface LinkCardProps extends Omit<RACLinkProps, 'className' | 'children'> {
5
+ href: string;
6
+ /** The heading, which names the link. */
7
+ title: ReactNode;
8
+ headingLevel?: 2 | 3 | 4;
9
+ /** Muted text under the title; the link's description. */
10
+ description?: ReactNode;
11
+ icon?: IconProp;
12
+ /** Layer 1, the target: the whole card. */
13
+ className?: string;
14
+ /** Layer 2, the painted card. */
15
+ visualClassName?: string;
16
+ }
17
+ /**
18
+ * A card that is one link: the whole card is the `<a>`, named by its heading and described by its text. It
19
+ * holds no other control, since a link can't contain one. Three layers: the link is the target, the card is
20
+ * the paint (hover, focus ring), the text is the content. No overlay stretches a link over a card.
21
+ */
22
+ export declare function LinkCard({ href, title, headingLevel, description, icon, className, visualClassName, ...props }: LinkCardProps): import("react").JSX.Element;
23
+ //# sourceMappingURL=link-card.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-card.d.ts","sourceRoot":"","sources":["../../src/ui/link-card.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAmB,KAAK,SAAS,IAAI,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGxF,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,YAAY,EAAE,WAAW,GAAG,UAAU,CAAC;IACjF,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,KAAK,EAAE,SAAS,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,YAAgB,EAChB,WAAW,EACX,IAAI,EACJ,SAAS,EACT,eAAe,EACf,GAAG,KAAK,EACT,EAAE,aAAa,+BAyCf"}
@@ -0,0 +1,19 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from 'react';
4
+ import { Link as RACLink } from 'react-aria-components';
5
+ import { ArrowRight } from 'lucide-react';
6
+ import { cn } from '../lib/cn.js';
7
+ import { renderIcon } from './icon.js';
8
+ /**
9
+ * A card that is one link: the whole card is the `<a>`, named by its heading and described by its text. It
10
+ * holds no other control, since a link can't contain one. Three layers: the link is the target, the card is
11
+ * the paint (hover, focus ring), the text is the content. No overlay stretches a link over a card.
12
+ */
13
+ export function LinkCard({ href, title, headingLevel = 3, description, icon, className, visualClassName, ...props }) {
14
+ const titleId = useId();
15
+ const descriptionId = useId();
16
+ const Heading = `h${headingLevel}`;
17
+ return (_jsx(RACLink, { ...props, href: href, "aria-labelledby": titleId, "aria-describedby": description ? descriptionId : undefined, className: cn('group/link-card relative flex min-h-target min-w-target cursor-pointer text-foreground no-underline outline-none', className), children: _jsxs("div", { className: cn('card-surface flex w-full flex-col gap-2 group-data-hovered/link-card:bg-accent group-data-focus-visible/link-card:focus-ring', visualClassName), children: [icon && (_jsx("span", { className: "mb-2 inline-flex size-10 items-center justify-center rounded-md bg-brand-subtle text-brand", children: renderIcon(icon, 'size-5') })), _jsxs(Heading, { id: titleId, className: "flex items-start gap-2 text-subheading group-data-hovered/link-card:underline", children: [_jsx("span", { className: "min-w-0", children: title }), _jsx(ArrowRight, { "aria-hidden": "true", className: "mt-1 size-4 shrink-0" })] }), description && (_jsx("p", { id: descriptionId, className: "text-body text-muted-foreground", children: description }))] }) }));
18
+ }
19
+ //# sourceMappingURL=link-card.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"link-card.js","sourceRoot":"","sources":["../../src/ui/link-card.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,KAAK,EAAkB,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,IAAI,IAAI,OAAO,EAAkC,MAAM,uBAAuB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAgBtD;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,YAAY,GAAG,CAAC,EAChB,WAAW,EACX,IAAI,EACJ,SAAS,EACT,eAAe,EACf,GAAG,KAAK,EACM;IACd,MAAM,OAAO,GAAG,KAAK,EAAE,CAAC;IACxB,MAAM,aAAa,GAAG,KAAK,EAAE,CAAC;IAC9B,MAAM,OAAO,GAAG,IAAI,YAAY,EAAwB,CAAC;IACzD,OAAO,CACL,KAAC,OAAO,OACF,KAAK,EACT,IAAI,EAAE,IAAI,qBACO,OAAO,sBACN,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,EACzD,SAAS,EAAE,EAAE,CACX,kHAAkH,EAClH,SAAS,CACV,YAED,eACE,SAAS,EAAE,EAAE,CACX,8HAA8H,EAC9H,eAAe,CAChB,aAEA,IAAI,IAAI,CACP,eAAM,SAAS,EAAC,4FAA4F,YACzG,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,GACtB,CACR,EACD,MAAC,OAAO,IACN,EAAE,EAAE,OAAO,EACX,SAAS,EAAC,+EAA+E,aAEzF,eAAM,SAAS,EAAC,SAAS,YAAE,KAAK,GAAQ,EACxC,KAAC,UAAU,mBAAa,MAAM,EAAC,SAAS,EAAC,sBAAsB,GAAG,IAC1D,EACT,WAAW,IAAI,CACd,YAAG,EAAE,EAAE,aAAa,EAAE,SAAS,EAAC,iCAAiC,YAC9D,WAAW,GACV,CACL,IACG,GACE,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type ListBoxItemProps, type ListBoxProps } from 'react-aria-components';
3
+ export declare function ListBox<T extends object>({ className, ...props }: Omit<ListBoxProps<T>, 'className'> & {
4
+ className?: string;
5
+ }): import("react").JSX.Element;
6
+ export interface OptionProps extends Omit<ListBoxItemProps, 'className' | 'children'> {
7
+ children: ReactNode;
8
+ description?: string;
9
+ className?: string;
10
+ }
11
+ /** One choice in a Select or ComboBox. Selected: a check and weight 600, not colour alone. */
12
+ export declare function Option({ children, description, className, ...props }: OptionProps): import("react").JSX.Element;
13
+ export declare function OptionSection<T extends object>({ title, children, }: {
14
+ title: string;
15
+ children: ReactNode;
16
+ }): import("react").JSX.Element;
17
+ //# sourceMappingURL=list-box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-box.d.ts","sourceRoot":"","sources":["../../src/ui/list-box.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAKL,KAAK,gBAAgB,EACrB,KAAK,YAAY,EAClB,MAAM,uBAAuB,CAAC;AAK/B,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,EACxC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAU7D;AAED,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,UAAU,CAAC;IACnF,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,8FAA8F;AAC9F,wBAAgB,MAAM,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,+BA4BjF;AAED,wBAAgB,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,EAC9C,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;CACrB,+BASA"}
@@ -0,0 +1,18 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Header, ListBox as RACListBox, ListBoxItem as RACListBoxItem, ListBoxSection as RACListBoxSection, } from 'react-aria-components';
4
+ import { Check } from 'lucide-react';
5
+ import { cn } from '../lib/cn.js';
6
+ import { rowTarget } from './menu.js';
7
+ export function ListBox({ className, ...props }) {
8
+ return (_jsx(RACListBox, { ...props, className: cn('relative max-h-[inherit] overflow-auto p-1 outline-none data-focus-visible:focus-ring-inset', className) }));
9
+ }
10
+ /** One choice in a Select or ComboBox. Selected: a check and weight 600, not colour alone. */
11
+ export function Option({ children, description, className, ...props }) {
12
+ const textValue = props.textValue ?? (typeof children === 'string' ? children : undefined);
13
+ return (_jsx(RACListBoxItem, { ...props, textValue: textValue, className: cn('group/option', rowTarget, className), children: ({ isSelected }) => (_jsxs("span", { className: cn('flex min-h-nav-item w-full min-w-0 items-center gap-3 rounded-md px-3 py-1.5', 'group-data-focused/option:bg-accent group-data-focus-visible/option:focus-ring-inset group-data-selected/option:font-semibold'), children: [_jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "truncate", children: children }), description && (_jsx("span", { className: "truncate text-[13px] font-normal text-muted-foreground", children: description }))] }), isSelected && _jsx(Check, { "aria-hidden": "true", className: "size-4 shrink-0 text-brand" })] })) }));
14
+ }
15
+ export function OptionSection({ title, children, }) {
16
+ return (_jsxs(RACListBoxSection, { className: "not-first:mt-1 not-first:border-t not-first:border-border not-first:pt-1", children: [_jsx(Header, { className: "px-3 pt-1.5 pb-1 text-[13px] leading-5 font-semibold text-muted-foreground", children: title }), children] }));
17
+ }
18
+ //# sourceMappingURL=list-box.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-box.js","sourceRoot":"","sources":["../../src/ui/list-box.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EACL,MAAM,EACN,OAAO,IAAI,UAAU,EACrB,WAAW,IAAI,cAAc,EAC7B,cAAc,IAAI,iBAAiB,GAGpC,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,UAAU,OAAO,CAAmB,EACxC,SAAS,EACT,GAAG,KAAK,EACoD;IAC5D,OAAO,CACL,KAAC,UAAU,OACL,KAAK,EACT,SAAS,EAAE,EAAE,CACX,6FAA6F,EAC7F,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC;AAQD,8FAA8F;AAC9F,MAAM,UAAU,MAAM,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,EAAe;IAChF,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3F,OAAO,CACL,KAAC,cAAc,OACT,KAAK,EACT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,SAAS,EAAE,SAAS,CAAC,YAElD,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CACnB,gBACE,SAAS,EAAE,EAAE,CACX,8EAA8E,EAC9E,+HAA+H,CAChI,aAED,gBAAM,SAAS,EAAC,8BAA8B,aAC5C,eAAM,SAAS,EAAC,UAAU,YAAE,QAAQ,GAAQ,EAC3C,WAAW,IAAI,CACd,eAAM,SAAS,EAAC,wDAAwD,YACrE,WAAW,GACP,CACR,IACI,EACN,UAAU,IAAI,KAAC,KAAK,mBAAa,MAAM,EAAC,SAAS,EAAC,4BAA4B,GAAG,IAC7E,CACR,GACc,CAClB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAmB,EAC9C,KAAK,EACL,QAAQ,GAIT;IACC,OAAO,CACL,MAAC,iBAAiB,IAAI,SAAS,EAAC,0EAA0E,aACxG,KAAC,MAAM,IAAC,SAAS,EAAC,4EAA4E,YAC3F,KAAK,GACC,EACR,QAAQ,IACS,CACrB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { ReactNode } from 'react';
2
+ import { MenuTrigger, type MenuItemProps as RACMenuItemProps, type MenuProps as RACMenuProps, type PopoverProps as RACPopoverProps } from 'react-aria-components';
3
+ import { type IconProp } from './icon.js';
4
+ export interface PopoverProps extends Omit<RACPopoverProps, 'className'> {
5
+ className?: string;
6
+ }
7
+ /** Floating surface for menus and listboxes: popover ground, border and shadow-lg. */
8
+ export declare function Popover({ className, offset, ...props }: PopoverProps): import("react").JSX.Element;
9
+ export declare function Menu<T extends object>({ className, ...props }: Omit<RACMenuProps<T>, 'className'> & {
10
+ className?: string;
11
+ }): import("react").JSX.Element;
12
+ /** Layer 1 of a row. Name the group after the component (`group/item`, `group/option`). */
13
+ export declare const rowTarget = "flex min-h-target cursor-pointer items-center text-sm text-popover-foreground no-underline outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50";
14
+ /** Layer 2 of a row, for a row whose group is `group/item`. */
15
+ export declare const itemVisual = "flex min-h-nav-item w-full min-w-0 items-center gap-3 rounded-md px-3 py-1.5 group-data-focused/item:bg-accent group-data-focus-visible/item:focus-ring-inset";
16
+ export interface MenuItemProps extends Omit<RACMenuItemProps, 'className' | 'children'> {
17
+ icon?: IconProp;
18
+ description?: string;
19
+ children: ReactNode;
20
+ className?: string;
21
+ }
22
+ /** A row in a menu. Keyboard focus draws the inset ring on the highlight as well as the hover ground. */
23
+ export declare function MenuItem({ icon, description, children, className, ...props }: MenuItemProps): import("react").JSX.Element;
24
+ export declare function MenuSection<T extends object>({ title, children, className, }: {
25
+ title?: string;
26
+ children: ReactNode;
27
+ className?: string;
28
+ }): import("react").JSX.Element;
29
+ export declare function MenuSeparator(): import("react").JSX.Element;
30
+ export { MenuTrigger };
31
+ //# sourceMappingURL=menu.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.d.ts","sourceRoot":"","sources":["../../src/ui/menu.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAKL,WAAW,EAGX,KAAK,aAAa,IAAI,gBAAgB,EACtC,KAAK,SAAS,IAAI,YAAY,EAC9B,KAAK,YAAY,IAAI,eAAe,EACrC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,eAAe,EAAE,WAAW,CAAC;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,sFAAsF;AACtF,wBAAgB,OAAO,CAAC,EAAE,SAAS,EAAE,MAAU,EAAE,GAAG,KAAK,EAAE,EAAE,YAAY,+BAaxE;AAED,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,EACrC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAW7D;AAOD,2FAA2F;AAC3F,eAAO,MAAM,SAAS,sKAC+I,CAAC;AACtK,+DAA+D;AAC/D,eAAO,MAAM,UAAU,kKAC0I,CAAC;AAElK,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,gBAAgB,EAAE,WAAW,GAAG,UAAU,CAAC;IACrF,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yGAAyG;AACzG,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,aAAa,+BAwB3F;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,EAC5C,KAAK,EACL,QAAQ,EACR,SAAS,GACV,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAgBA;AAED,wBAAgB,aAAa,gCAE5B;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
@@ -0,0 +1,40 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Header, Menu as RACMenu, MenuItem as RACMenuItem, MenuSection as RACMenuSection, MenuTrigger, Popover as RACPopover, Separator, } from 'react-aria-components';
4
+ import { Check } from 'lucide-react';
5
+ import { cn } from '../lib/cn.js';
6
+ import { renderIcon } from './icon.js';
7
+ /** Floating surface for menus and listboxes: popover ground, border and shadow-lg. */
8
+ export function Popover({ className, offset = 6, ...props }) {
9
+ return (_jsx(RACPopover, { offset: offset, ...props, className: cn(
10
+ // React Aria positions the popover inline (style="position: absolute"), which the lint rule can't see.
11
+ // oxlint-disable-next-line setsquare-ui/positioned-scroll-container
12
+ 'z-(--z-popover) min-w-(--trigger-width) overflow-auto rounded-lg border border-border bg-popover text-popover-foreground shadow-(--shadow-lg) outline-none', className) }));
13
+ }
14
+ export function Menu({ className, ...props }) {
15
+ return (_jsx(RACMenu, { ...props, className: cn(
16
+ // The menu itself holds focus when opened by pointer, until an arrow key moves to an item.
17
+ 'relative max-h-[inherit] min-w-56 overflow-auto p-1 outline-none data-focus-visible:focus-ring-inset', className) }));
18
+ }
19
+ /*
20
+ * Rows in menus, lists and search results, in three layers: the row element is the target (Layer 1, the
21
+ * full width and at least --target-min tall); the highlight inside it is painted at --nav-item-height
22
+ * (Layer 2), with the focus ring; the icon and text are Layer 3. At AAA a 36px highlight sits in a 44px row.
23
+ */
24
+ /** Layer 1 of a row. Name the group after the component (`group/item`, `group/option`). */
25
+ export const rowTarget = 'flex min-h-target cursor-pointer items-center text-sm text-popover-foreground no-underline outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50';
26
+ /** Layer 2 of a row, for a row whose group is `group/item`. */
27
+ export const itemVisual = 'flex min-h-nav-item w-full min-w-0 items-center gap-3 rounded-md px-3 py-1.5 group-data-focused/item:bg-accent group-data-focus-visible/item:focus-ring-inset';
28
+ /** A row in a menu. Keyboard focus draws the inset ring on the highlight as well as the hover ground. */
29
+ export function MenuItem({ icon, description, children, className, ...props }) {
30
+ const textValue = props.textValue ?? (typeof children === 'string' ? children : undefined);
31
+ return (_jsx(RACMenuItem, { ...props, textValue: textValue, className: cn('group/item', rowTarget, className), children: ({ isSelected, selectionMode }) => (_jsxs("span", { className: itemVisual, children: [icon && renderIcon(icon, 'size-5 shrink-0 text-muted-foreground'), _jsxs("span", { className: "flex min-w-0 flex-1 flex-col", children: [_jsx("span", { className: "truncate", children: children }), description && (_jsx("span", { className: "truncate text-[13px] text-muted-foreground", children: description }))] }), selectionMode !== 'none' && isSelected && (_jsx(Check, { "aria-hidden": "true", className: "size-4 shrink-0 text-brand" }))] })) }));
32
+ }
33
+ export function MenuSection({ title, children, className, }) {
34
+ return (_jsxs(RACMenuSection, { className: cn('not-first:mt-1 not-first:border-t not-first:border-border not-first:pt-1', className), children: [title && (_jsx(Header, { className: "px-3 pt-1.5 pb-1 text-[13px] leading-5 font-semibold text-muted-foreground", children: title })), children] }));
35
+ }
36
+ export function MenuSeparator() {
37
+ return _jsx(Separator, { className: "mx-1 my-1 h-px bg-border" });
38
+ }
39
+ export { MenuTrigger };
40
+ //# sourceMappingURL=menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"menu.js","sourceRoot":"","sources":["../../src/ui/menu.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EACL,MAAM,EACN,IAAI,IAAI,OAAO,EACf,QAAQ,IAAI,WAAW,EACvB,WAAW,IAAI,cAAc,EAC7B,WAAW,EACX,OAAO,IAAI,UAAU,EACrB,SAAS,GAIV,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAMtD,sFAAsF;AACtF,MAAM,UAAU,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,GAAG,CAAC,EAAE,GAAG,KAAK,EAAgB;IACvE,OAAO,CACL,KAAC,UAAU,IACT,MAAM,EAAE,MAAM,KACV,KAAK,EACT,SAAS,EAAE,EAAE;QACX,uGAAuG;QACvG,oEAAoE;QACpE,4JAA4J,EAC5J,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,IAAI,CAAmB,EACrC,SAAS,EACT,GAAG,KAAK,EACoD;IAC5D,OAAO,CACL,KAAC,OAAO,OACF,KAAK,EACT,SAAS,EAAE,EAAE;QACX,2FAA2F;QAC3F,sGAAsG,EACtG,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,2FAA2F;AAC3F,MAAM,CAAC,MAAM,SAAS,GACpB,mKAAmK,CAAC;AACtK,+DAA+D;AAC/D,MAAM,CAAC,MAAM,UAAU,GACrB,+JAA+J,CAAC;AASlK,yGAAyG;AACzG,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAiB;IAC1F,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC3F,OAAO,CACL,KAAC,WAAW,OACN,KAAK,EACT,SAAS,EAAE,SAAS,EACpB,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC,YAEhD,CAAC,EAAE,UAAU,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAClC,gBAAM,SAAS,EAAE,UAAU,aACxB,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,uCAAuC,CAAC,EAClE,gBAAM,SAAS,EAAC,8BAA8B,aAC5C,eAAM,SAAS,EAAC,UAAU,YAAE,QAAQ,GAAQ,EAC3C,WAAW,IAAI,CACd,eAAM,SAAS,EAAC,4CAA4C,YAAE,WAAW,GAAQ,CAClF,IACI,EACN,aAAa,KAAK,MAAM,IAAI,UAAU,IAAI,CACzC,KAAC,KAAK,mBAAa,MAAM,EAAC,SAAS,EAAC,4BAA4B,GAAG,CACpE,IACI,CACR,GACW,CACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAmB,EAC5C,KAAK,EACL,QAAQ,EACR,SAAS,GAKV;IACC,OAAO,CACL,MAAC,cAAc,IACb,SAAS,EAAE,EAAE,CACX,0EAA0E,EAC1E,SAAS,CACV,aAEA,KAAK,IAAI,CACR,KAAC,MAAM,IAAC,SAAS,EAAC,4EAA4E,YAC3F,KAAK,GACC,CACV,EACA,QAAQ,IACM,CAClB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,KAAC,SAAS,IAAC,SAAS,EAAC,0BAA0B,GAAG,CAAC;AAC5D,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}