@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,35 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useRef } from 'react';
4
+ import { cn } from '../lib/cn.js';
5
+ import { focusAfter } from '../lib/tokens.js';
6
+ import { Button } from './button.js';
7
+ /**
8
+ * The count and bulk actions for a multi-select Table or GridList. The count is a live region that is always
9
+ * in the page, so each change is announced ("3 projects selected") without moving focus.
10
+ *
11
+ * Buttons that take themselves away hand focus on: after "Select all", to "Clear selection"; after "Clear
12
+ * selection", to "Select all" if there is one, otherwise to the next focusable thing after the bar — so put the
13
+ * bar directly above its table or list.
14
+ */
15
+ export function SelectionBar({ count, total, noun, onClear, onSelectAll, children, className, }) {
16
+ const ref = useRef(null);
17
+ const clearRef = useRef(null);
18
+ const selectAllRef = useRef(null);
19
+ const n = count === 'all' ? (total ?? 0) : count;
20
+ const all = count === 'all' || (total != null && n === total && n > 0);
21
+ const text = n === 0
22
+ ? ''
23
+ : all
24
+ ? `All ${total ?? n} ${noun[1]} selected`
25
+ : `${n} ${n === 1 ? noun[0] : noun[1]} selected`;
26
+ const showSelectAll = !!onSelectAll && !all && (total ?? 0) > 0;
27
+ return (_jsxs("div", { ref: ref, className: cn('flex flex-wrap items-center gap-x-4 gap-y-2', (n > 0 || showSelectAll) && 'min-h-control-target', className), children: [_jsx("p", { role: "status", className: cn('text-sm leading-5 font-semibold text-foreground', n === 0 && 'sr-only'), children: text }), (n > 0 || showSelectAll) && (_jsxs("div", { role: "group", "aria-label": "Selection", className: "flex flex-wrap items-center gap-2", children: [n > 0 && children, showSelectAll && (_jsxs(Button, { ref: selectAllRef, variant: "ghost", visualSize: "sm", onPress: () => {
28
+ onSelectAll();
29
+ requestAnimationFrame(() => clearRef.current?.focus());
30
+ }, children: ["Select all ", total, " ", noun[1]] })), n > 0 && (_jsx(Button, { ref: clearRef, variant: "ghost", visualSize: "sm", onPress: () => {
31
+ onClear();
32
+ requestAnimationFrame(() => selectAllRef.current ? selectAllRef.current.focus() : focusAfter(ref.current));
33
+ }, children: "Clear selection" }))] }))] }));
34
+ }
35
+ //# sourceMappingURL=selection-bar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-bar.js","sourceRoot":"","sources":["../../src/ui/selection-bar.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface SheetProps {
3
+ isOpen: boolean;
4
+ onOpenChange: (open: boolean) => void;
5
+ side?: 'left' | 'right';
6
+ /** Visible heading; also names the dialog. */
7
+ title?: string;
8
+ /** Name the dialog without a visible heading (the mobile navigation). */
9
+ 'aria-label'?: string;
10
+ /** Extra actions beside the close button. */
11
+ headerActions?: ReactNode;
12
+ children: ReactNode;
13
+ footer?: ReactNode;
14
+ className?: string;
15
+ }
16
+ /**
17
+ * A modal panel from the edge: focus is trapped inside, Escape and the backdrop close it,
18
+ * focus returns to what opened it. Slides by --motion-distance, so AAA themes fade only.
19
+ */
20
+ export declare function Sheet({ isOpen, onOpenChange, side, title, headerActions, children, footer, className, ...rest }: SheetProps): import("react").JSX.Element;
21
+ //# sourceMappingURL=sheet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.d.ts","sourceRoot":"","sources":["../../src/ui/sheet.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMvC,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACxB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EACpB,MAAM,EACN,YAAY,EACZ,IAAc,EACd,KAAK,EACL,aAAa,EACb,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACR,EAAE,UAAU,+BA+CZ"}
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Dialog, Heading, Modal, ModalOverlay } from 'react-aria-components';
4
+ import { X } from 'lucide-react';
5
+ import { cn } from '../lib/cn.js';
6
+ import { IconButton } from './icon-button.js';
7
+ /**
8
+ * A modal panel from the edge: focus is trapped inside, Escape and the backdrop close it,
9
+ * focus returns to what opened it. Slides by --motion-distance, so AAA themes fade only.
10
+ */
11
+ export function Sheet({ isOpen, onOpenChange, side = 'right', title, headerActions, children, footer, className, ...rest }) {
12
+ return (_jsx(ModalOverlay, { isOpen: isOpen, onOpenChange: onOpenChange, isDismissable: true, "data-overlay": true, className: "fixed inset-0 z-(--z-sheet) bg-overlay", children: _jsx(Modal, { "data-sheet": side, className: cn('fixed inset-y-0 flex max-w-[calc(100%-3rem)] flex-col bg-background text-foreground shadow-(--shadow-lg) outline-none', side === 'right'
13
+ ? 'right-0 w-panel border-l border-border'
14
+ : 'left-0 w-sidebar border-r border-sidebar-border bg-sidebar', className), children: _jsxs(Dialog, { "aria-label": title ? undefined : rest['aria-label'], className: "flex h-full min-h-0 flex-col outline-none", children: [title ? (_jsxs("div", { className: "flex min-h-[calc(var(--control-height)+1rem)] items-center justify-between gap-2 border-b border-border py-2 pr-2 pl-4", children: [_jsx(Heading, { slot: "title", className: "text-subheading", children: title }), _jsxs("div", { className: "flex items-center gap-1", children: [headerActions, _jsx(IconButton, { label: "Close", icon: X, visualSize: "icon-sm", slot: "close", tooltip: false, className: "justify-end" })] })] })) : null, children, footer] }) }) }));
15
+ }
16
+ //# sourceMappingURL=sheet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sheet.js","sourceRoot":"","sources":["../../src/ui/sheet.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAiB9C;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAC,EACpB,MAAM,EACN,YAAY,EACZ,IAAI,GAAG,OAAO,EACd,KAAK,EACL,aAAa,EACb,QAAQ,EACR,MAAM,EACN,SAAS,EACT,GAAG,IAAI,EACI;IACX,OAAO,CACL,KAAC,YAAY,IACX,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,YAAY,EAC1B,aAAa,8BAEb,SAAS,EAAC,wCAAwC,YAElD,KAAC,KAAK,kBACQ,IAAI,EAChB,SAAS,EAAE,EAAE,CACX,uHAAuH,EACvH,IAAI,KAAK,OAAO;gBACd,CAAC,CAAC,wCAAwC;gBAC1C,CAAC,CAAC,4DAA4D,EAChE,SAAS,CACV,YAED,MAAC,MAAM,kBACO,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAClD,SAAS,EAAC,2CAA2C,aAEpD,KAAK,CAAC,CAAC,CAAC,CACP,eAAK,SAAS,EAAC,wHAAwH,aACrI,KAAC,OAAO,IAAC,IAAI,EAAC,OAAO,EAAC,SAAS,EAAC,iBAAiB,YAC9C,KAAK,GACE,EACV,eAAK,SAAS,EAAC,yBAAyB,aACrC,aAAa,EACd,KAAC,UAAU,IACT,KAAK,EAAC,OAAO,EACb,IAAI,EAAE,CAAC,EACP,UAAU,EAAC,SAAS,EACpB,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,KAAK,EACd,SAAS,EAAC,aAAa,GACvB,IACE,IACF,CACP,CAAC,CAAC,CAAC,IAAI,EACP,QAAQ,EACR,MAAM,IACA,GACH,GACK,CAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { type ReactNode } from 'react';
2
+ /** A placeholder block. Decorative: the surrounding LoadingState says what is loading. Pulses (opacity), never shimmers across. */
3
+ export declare function Skeleton({ className }: {
4
+ className?: string;
5
+ }): import("react").JSX.Element;
6
+ export declare function SkeletonText({ lines, className }: {
7
+ lines?: number;
8
+ className?: string;
9
+ }): import("react").JSX.Element;
10
+ /** Table-shaped placeholder: header row and `rows` body rows at the real row height. */
11
+ export declare function TableSkeleton({ rows, columns, className, }: {
12
+ rows?: number;
13
+ columns?: number;
14
+ className?: string;
15
+ }): import("react").JSX.Element;
16
+ export interface LoadingStateProps {
17
+ /** Announced once, politely: "Loading projects". */
18
+ label: string;
19
+ /** The skeleton to show — shaped like the content that is coming. */
20
+ children: ReactNode;
21
+ /** ms before the skeleton appears. Default --duration-loading-delay, so fast loads never flash it. */
22
+ delay?: number;
23
+ className?: string;
24
+ }
25
+ /**
26
+ * Wraps a skeleton: marks the region busy, announces the label through a polite status,
27
+ * and shows the skeleton only after a short delay. Replace it with the content (and, if it
28
+ * helps, a StatusMessage such as "12 projects") when loading finishes.
29
+ */
30
+ export declare function LoadingState({ label, children, delay, className }: LoadingStateProps): import("react").JSX.Element;
31
+ //# sourceMappingURL=skeleton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton.d.ts","sourceRoot":"","sources":["../../src/ui/skeleton.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAI5D,mIAAmI;AACnI,wBAAgB,QAAQ,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAU7D;AAED,wBAAgB,YAAY,CAAC,EAAE,KAAS,EAAE,SAAS,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAQ5F;AAED,wFAAwF;AACxF,wBAAgB,aAAa,CAAC,EAC5B,IAAQ,EACR,OAAW,EACX,SAAS,GACV,EAAE;IACD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,+BAwBA;AAED,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,QAAQ,EAAE,SAAS,CAAC;IACpB,sGAAsG;IACtG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,iBAAiB,+BAqBpF"}
@@ -0,0 +1,38 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import { cn } from '../lib/cn.js';
5
+ import { readMs } from '../lib/tokens.js';
6
+ /** A placeholder block. Decorative: the surrounding LoadingState says what is loading. Pulses (opacity), never shimmers across. */
7
+ export function Skeleton({ className }) {
8
+ return (_jsx("span", { "aria-hidden": "true", className: cn('block rounded-md bg-accent animate-pulse motion-reduce:animate-none', className) }));
9
+ }
10
+ export function SkeletonText({ lines = 3, className }) {
11
+ return (_jsx("span", { "aria-hidden": "true", className: cn('flex flex-col gap-2', className), children: Array.from({ length: lines }, (_, i) => (_jsx(Skeleton, { className: cn('h-3.5', i === lines - 1 ? 'w-2/3' : 'w-full') }, i))) }));
12
+ }
13
+ /** Table-shaped placeholder: header row and `rows` body rows at the real row height. */
14
+ export function TableSkeleton({ rows = 6, columns = 4, className, }) {
15
+ const widths = ['w-40', 'w-20', 'w-28', 'w-24', 'w-16'];
16
+ return (_jsxs("div", { "aria-hidden": "true", className: cn('overflow-hidden rounded-lg border border-border bg-card', className), children: [_jsx("div", { className: "flex h-control-target items-center gap-6 border-b border-border bg-muted px-3", children: Array.from({ length: columns }, (_, c) => (_jsx(Skeleton, { className: cn('h-3', widths[c % widths.length]) }, c))) }), Array.from({ length: rows }, (_row, r) => (_jsx("div", { className: "flex h-[calc(var(--control-height)+12px)] items-center gap-6 border-b border-border px-3 last:border-b-0", children: Array.from({ length: columns }, (_cell, c) => (_jsx(Skeleton, { className: cn('h-3.5', widths[(c + r) % widths.length]) }, c))) }, r)))] }));
17
+ }
18
+ /**
19
+ * Wraps a skeleton: marks the region busy, announces the label through a polite status,
20
+ * and shows the skeleton only after a short delay. Replace it with the content (and, if it
21
+ * helps, a StatusMessage such as "12 projects") when loading finishes.
22
+ */
23
+ export function LoadingState({ label, children, delay, className }) {
24
+ const [visible, setVisible] = useState(delay === 0);
25
+ const [announce, setAnnounce] = useState('');
26
+ useEffect(() => {
27
+ const wait = delay ?? readMs('--duration-loading-delay', 400);
28
+ const show = setTimeout(() => setVisible(true), wait);
29
+ // Live regions announce changes, not their first content: fill it in after mount.
30
+ const say = setTimeout(() => setAnnounce(label), 50);
31
+ return () => {
32
+ clearTimeout(show);
33
+ clearTimeout(say);
34
+ };
35
+ }, [delay, label]);
36
+ return (_jsxs("div", { "aria-busy": "true", className: className, children: [_jsx("span", { role: "status", className: "sr-only", children: announce }), visible && _jsx("div", { "aria-hidden": "true", children: children })] }));
37
+ }
38
+ //# sourceMappingURL=skeleton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skeleton.js","sourceRoot":"","sources":["../../src/ui/skeleton.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { type ReactNode } from 'react';
2
+ import { type SliderProps as RACSliderProps } from 'react-aria-components';
3
+ import { type FieldWidth } from './field.js';
4
+ interface SliderBaseProps {
5
+ label: string;
6
+ /** What the value controls, and anything that limits it. Read with each thumb. */
7
+ description?: ReactNode;
8
+ /** Show the minimum and maximum under the track. Default true. */
9
+ showRange?: boolean;
10
+ width?: FieldWidth;
11
+ className?: string;
12
+ }
13
+ export interface SliderProps extends SliderBaseProps, Omit<RACSliderProps<number>, 'className' | 'children'> {
14
+ }
15
+ export interface RangeSliderProps extends SliderBaseProps, Omit<RACSliderProps<number[]>, 'className' | 'children'> {
16
+ /** Names for the two thumbs, read before their values. Default ["Minimum", "Maximum"]. */
17
+ thumbLabels?: [string, string];
18
+ }
19
+ /**
20
+ * Choose a value from a continuous range where the exact number matters less than its position — volume,
21
+ * a threshold, a budget. For an exact number people will type, use a NumberField.
22
+ *
23
+ * Operable without dragging: press anywhere on the track to move the nearest thumb, or use the arrow keys,
24
+ * Page Up/Down and Home/End. The track is --target-min tall, and each thumb's target is at least
25
+ * --target-min square, though the visible thumb is --choice-size.
26
+ */
27
+ export declare function Slider(props: SliderProps): import("react").JSX.Element;
28
+ /** Choose a minimum and a maximum on one track. Each thumb has its own name ("Minimum", "Maximum"). */
29
+ export declare function RangeSlider({ thumbLabels, ...props }: RangeSliderProps): import("react").JSX.Element;
30
+ export {};
31
+ //# sourceMappingURL=slider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slider.d.ts","sourceRoot":"","sources":["../../src/ui/slider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAML,KAAK,WAAW,IAAI,cAAc,EACnC,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAuC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAElF,UAAU,eAAe;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,kEAAkE;IAClE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WACf,SAAQ,eAAe,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC;CAAG;AAEpF,MAAM,WAAW,gBACf,SAAQ,eAAe,EAAE,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC,EAAE,WAAW,GAAG,UAAU,CAAC;IACjF,0FAA0F;IAC1F,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,WAAW,+BAExC;AAED,uGAAuG;AACvG,wBAAgB,WAAW,CAAC,EAAE,WAAoC,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,+BAE/F"}
@@ -0,0 +1,33 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useId } from 'react';
4
+ import { Slider as RACSlider, SliderFill, SliderOutput, SliderThumb, SliderTrack, } from 'react-aria-components';
5
+ import { cn } from '../lib/cn.js';
6
+ import { FieldLabel, fieldStack, fieldWidths } from './field.js';
7
+ /**
8
+ * Choose a value from a continuous range where the exact number matters less than its position — volume,
9
+ * a threshold, a budget. For an exact number people will type, use a NumberField.
10
+ *
11
+ * Operable without dragging: press anywhere on the track to move the nearest thumb, or use the arrow keys,
12
+ * Page Up/Down and Home/End. The track is --target-min tall, and each thumb's target is at least
13
+ * --target-min square, though the visible thumb is --choice-size.
14
+ */
15
+ export function Slider(props) {
16
+ return _jsx(SliderRoot, { ...props });
17
+ }
18
+ /** Choose a minimum and a maximum on one track. Each thumb has its own name ("Minimum", "Maximum"). */
19
+ export function RangeSlider({ thumbLabels = ['Minimum', 'Maximum'], ...props }) {
20
+ return _jsx(SliderRoot, { ...props, thumbLabels: thumbLabels });
21
+ }
22
+ function SliderRoot({ label, description, showRange = true, width = 'md', className, thumbLabels, ...props }) {
23
+ const descriptionId = useId();
24
+ const minValue = props.minValue ?? 0;
25
+ const maxValue = props.maxValue ?? 100;
26
+ const format = new Intl.NumberFormat(undefined, props.formatOptions);
27
+ return (_jsxs(RACSlider, { ...props, className: cn(fieldStack, fieldWidths[width], className), children: [_jsxs("div", { className: "flex items-baseline justify-between gap-4", children: [_jsx(FieldLabel, { children: label }), _jsx(SliderOutput, { className: "text-sm leading-5 font-semibold text-foreground tabular-nums", children: ({ state }) => state.values.map((_, i) => state.getThumbValueLabel(i)).join(' – ') })] }), description && (_jsx("p", { id: descriptionId, className: "max-w-(--measure) text-[13px] leading-5 text-muted-foreground", children: description })), _jsx(SliderTrack, { className: "group/track relative h-(--target-min) w-full cursor-pointer data-disabled:cursor-not-allowed data-disabled:opacity-60", children: ({ state }) => (_jsxs(_Fragment, { children: [_jsx("div", { "aria-hidden": "true", className: "absolute inset-x-0 top-1/2 h-1.5 -translate-y-1/2 rounded-full bg-input aaa:h-2", children: _jsx(SliderFill, { className: "rounded-full bg-primary" }) }), state.values.map((_, i) => (_jsx(SliderThumb, { index: i, "aria-label": thumbLabels?.[i], "aria-describedby": description ? descriptionId : undefined, className: cn(
28
+ // Layer 1: the thumb element is the target, at least --target-min square, centred on the
29
+ // value. Transparent; React Aria positions it and puts the real input inside it.
30
+ // The thumb is dragged, not pressed: grab, and grabbing while it moves.
31
+ 'group/thumb top-1/2 grid size-target cursor-grab place-items-center outline-none data-disabled:cursor-not-allowed data-dragging:cursor-grabbing'), children: _jsx("span", { "aria-hidden": "true", className: cn('size-choice rounded-full border-2 border-primary bg-background shadow-(--shadow-sm)', 'group-data-hovered/thumb:bg-accent group-data-dragging/thumb:bg-accent group-data-focus-visible/thumb:focus-ring group-data-disabled/thumb:border-muted-foreground') }) }, i)))] })) }), showRange && (_jsxs("div", { "aria-hidden": "true", className: "-mt-1 flex justify-between text-[13px] leading-5 text-muted-foreground tabular-nums", children: [_jsx("span", { children: format.format(minValue) }), _jsx("span", { children: format.format(maxValue) })] }))] }));
32
+ }
33
+ //# sourceMappingURL=slider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slider.js","sourceRoot":"","sources":["../../src/ui/slider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type ProgressBarProps as RACProgressBarProps } from 'react-aria-components';
3
+ /**
4
+ * The spinning arc. Decorative — pair it with text or use <Spinner>, which is a labelled progressbar.
5
+ * Turns once per --duration-spin; at AAA and under reduced motion it pulses (opacity) instead of turning.
6
+ */
7
+ export declare function SpinnerIcon({ className }: {
8
+ className?: string;
9
+ }): import("react").JSX.Element;
10
+ export interface SpinnerProps {
11
+ /** What is loading: "Loading projects". Always required — it is the accessible name. */
12
+ label: string;
13
+ /** Show the label beside the arc (default hidden, read by assistive tech). */
14
+ showLabel?: boolean;
15
+ size?: 'sm' | 'md' | 'lg';
16
+ className?: string;
17
+ }
18
+ /** An indeterminate progressbar: for waits you cannot measure. Show it only after --duration-loading-delay. */
19
+ export declare function Spinner({ label, showLabel, size, className }: SpinnerProps): import("react").JSX.Element;
20
+ export interface ProgressBarProps extends Omit<RACProgressBarProps, 'className' | 'children'> {
21
+ label: string;
22
+ description?: ReactNode;
23
+ className?: string;
24
+ }
25
+ /** Measured progress — uploads, exports, imports. The value is shown as text as well as the bar. */
26
+ export declare function ProgressBar({ label, description, className, ...props }: ProgressBarProps): import("react").JSX.Element;
27
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/ui/spinner.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,gBAAgB,IAAI,mBAAmB,EAC7C,MAAM,uBAAuB,CAAC;AAG/B;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BA6BhE;AAED,MAAM,WAAW,YAAY;IAC3B,wFAAwF;IACxF,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,+GAA+G;AAC/G,wBAAgB,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAW,EAAE,SAAS,EAAE,EAAE,YAAY,+BAWjF;AAED,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,WAAW,GAAG,UAAU,CAAC;IAC3F,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,oGAAoG;AACpG,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,gBAAgB,+BA8BxF"}
@@ -0,0 +1,21 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Label, ProgressBar as RACProgressBar, Text, } from 'react-aria-components';
4
+ import { cn } from '../lib/cn.js';
5
+ /**
6
+ * The spinning arc. Decorative — pair it with text or use <Spinner>, which is a labelled progressbar.
7
+ * Turns once per --duration-spin; at AAA and under reduced motion it pulses (opacity) instead of turning.
8
+ */
9
+ export function SpinnerIcon({ className }) {
10
+ return (_jsxs("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", "data-spinner": true, className: cn('size-5 shrink-0 animate-spin [animation-duration:var(--duration-spin)] motion-reduce:animate-pulse aaa:animate-pulse', className), children: [_jsx("circle", { cx: "12", cy: "12", r: "9", fill: "none", stroke: "currentColor", strokeOpacity: "0.25", strokeWidth: "3" }), _jsx("path", { d: "M21 12a9 9 0 0 0-9-9", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round" })] }));
11
+ }
12
+ const spinnerSizes = { sm: 'size-4', md: 'size-5', lg: 'size-8' };
13
+ /** An indeterminate progressbar: for waits you cannot measure. Show it only after --duration-loading-delay. */
14
+ export function Spinner({ label, showLabel, size = 'md', className }) {
15
+ return (_jsxs(RACProgressBar, { isIndeterminate: true, "aria-label": showLabel ? undefined : label, className: cn('inline-flex items-center gap-2 text-sm text-muted-foreground', className), children: [_jsx(SpinnerIcon, { className: cn(spinnerSizes[size], 'text-brand') }), showLabel && _jsx(Label, { children: label })] }));
16
+ }
17
+ /** Measured progress — uploads, exports, imports. The value is shown as text as well as the bar. */
18
+ export function ProgressBar({ label, description, className, ...props }) {
19
+ return (_jsx(RACProgressBar, { ...props, className: cn('flex w-full max-w-[28rem] flex-col gap-1.5', className), children: ({ percentage, valueText, isIndeterminate }) => (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-baseline justify-between gap-4 text-sm", children: [_jsx(Label, { className: "font-semibold", children: label }), _jsx("span", { className: "text-muted-foreground tabular-nums", children: valueText })] }), _jsx("div", { className: "h-2 overflow-hidden rounded-full border border-input bg-muted aaa:h-3", children: _jsx("div", { className: cn('h-full rounded-full bg-primary transition-[width] duration-(--duration-fast) motion-reduce:transition-none', isIndeterminate && 'w-1/3 animate-pulse'), style: isIndeterminate ? undefined : { width: `${percentage ?? 0}%` } }) }), description && (_jsx(Text, { slot: "description", className: "text-[13px] leading-5 text-muted-foreground", children: description }))] })) }));
20
+ }
21
+ //# sourceMappingURL=spinner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/ui/spinner.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EACL,KAAK,EACL,WAAW,IAAI,cAAc,EAC7B,IAAI,GAEL,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAElC;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,EAAE,SAAS,EAA0B;IAC/D,OAAO,CACL,eACE,OAAO,EAAC,WAAW,iBACP,MAAM,wBAElB,SAAS,EAAE,EAAE,CACX,sHAAsH,EACtH,SAAS,CACV,aAED,iBACE,EAAE,EAAC,IAAI,EACP,EAAE,EAAC,IAAI,EACP,CAAC,EAAC,GAAG,EACL,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,aAAa,EAAC,MAAM,EACpB,WAAW,EAAC,GAAG,GACf,EACF,eACE,CAAC,EAAC,sBAAsB,EACxB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,aAAa,EAAC,OAAO,GACrB,IACE,CACP,CAAC;AACJ,CAAC;AAWD,MAAM,YAAY,GAAG,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC;AAElE,+GAA+G;AAC/G,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,GAAG,IAAI,EAAE,SAAS,EAAgB;IAChF,OAAO,CACL,MAAC,cAAc,IACb,eAAe,sBACH,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,EACzC,SAAS,EAAE,EAAE,CAAC,8DAA8D,EAAE,SAAS,CAAC,aAExF,KAAC,WAAW,IAAC,SAAS,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY,CAAC,GAAI,EAC/D,SAAS,IAAI,KAAC,KAAK,cAAE,KAAK,GAAS,IACrB,CAClB,CAAC;AACJ,CAAC;AAQD,oGAAoG;AACpG,MAAM,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,EAAoB;IACvF,OAAO,CACL,KAAC,cAAc,OACT,KAAK,EACT,SAAS,EAAE,EAAE,CAAC,4CAA4C,EAAE,SAAS,CAAC,YAErE,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,EAAE,EAAE,CAAC,CAC/C,8BACE,eAAK,SAAS,EAAC,mDAAmD,aAChE,KAAC,KAAK,IAAC,SAAS,EAAC,eAAe,YAAE,KAAK,GAAS,EAChD,eAAM,SAAS,EAAC,oCAAoC,YAAE,SAAS,GAAQ,IACnE,EACN,cAAK,SAAS,EAAC,uEAAuE,YACpF,cACE,SAAS,EAAE,EAAE,CACX,4GAA4G,EAC5G,eAAe,IAAI,qBAAqB,CACzC,EACD,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,UAAU,IAAI,CAAC,GAAG,EAAE,GACrE,GACE,EACL,WAAW,IAAI,CACd,KAAC,IAAI,IAAC,IAAI,EAAC,aAAa,EAAC,SAAS,EAAC,6CAA6C,YAC7E,WAAW,GACP,CACR,IACA,CACJ,GACc,CAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export interface SplitProps extends HTMLAttributes<HTMLDivElement> {
3
+ /** Two things, text and media, in the order they're read: the first is on the left, and on top when stacked. */
4
+ children: ReactNode;
5
+ /** `center` (default) or `start`, for text much taller than the media. */
6
+ align?: 'center' | 'start';
7
+ }
8
+ /**
9
+ * Text beside media, as two equal columns from where each fits at 22rem, one above the other below that. The
10
+ * columns can shrink below their content, so a code sample in one scrolls inside it, not the page. The order
11
+ * on screen is the order in the page; nothing is swapped visually. Server-safe.
12
+ */
13
+ export declare function Split({ children, align, className, ...props }: SplitProps): import("react").JSX.Element;
14
+ //# sourceMappingURL=split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../src/ui/split.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAC,cAAc,CAAC;IAChE,gHAAgH;IAChH,QAAQ,EAAE,SAAS,CAAC;IACpB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAgB,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAMpF"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from '../lib/cn.js';
3
+ /**
4
+ * Text beside media, as two equal columns from where each fits at 22rem, one above the other below that. The
5
+ * columns can shrink below their content, so a code sample in one scrolls inside it, not the page. The order
6
+ * on screen is the order in the page; nothing is swapped visually. Server-safe.
7
+ */
8
+ export function Split({ children, align = 'center', className, ...props }) {
9
+ return (_jsx("div", { ...props, className: cn('split', align === 'start' && 'items-start', className), children: children }));
10
+ }
11
+ //# sourceMappingURL=split.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../src/ui/split.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AASlC;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAc;IACnF,OAAO,CACL,iBAAS,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,KAAK,OAAO,IAAI,aAAa,EAAE,SAAS,CAAC,YAClF,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface StatListProps {
3
+ /** Stat elements. */
4
+ children: ReactNode;
5
+ className?: string;
6
+ }
7
+ /** Figures, as many to a row as fit at 10rem: a description list. Server-safe. */
8
+ export declare function StatList({ children, className }: StatListProps): import("react").JSX.Element;
9
+ export interface StatProps {
10
+ /** What it counts: "Routes matched". */
11
+ label: ReactNode;
12
+ /** The figure: "38". */
13
+ value: ReactNode;
14
+ /**
15
+ * Where the figure comes from: a sentence, a TextLink, or both. Required: a figure is only stated with its
16
+ * source.
17
+ */
18
+ source: ReactNode;
19
+ }
20
+ /**
21
+ * One figure: shown figure first, then what it counts, then its source. A screen reader reads what it counts,
22
+ * the figure, then the source. Server-safe.
23
+ */
24
+ export declare function Stat({ label, value, source }: StatProps): import("react").JSX.Element;
25
+ //# sourceMappingURL=stat-list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stat-list.d.ts","sourceRoot":"","sources":["../../src/ui/stat-list.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,aAAa,+BAE9D;AAED,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,KAAK,EAAE,SAAS,CAAC;IACjB,wBAAwB;IACxB,KAAK,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,MAAM,EAAE,SAAS,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,SAAS,+BAQvD"}
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../lib/cn.js';
3
+ /** Figures, as many to a row as fit at 10rem: a description list. Server-safe. */
4
+ export function StatList({ children, className }) {
5
+ return _jsx("dl", { className: cn('stat-list', className), children: children });
6
+ }
7
+ /**
8
+ * One figure: shown figure first, then what it counts, then its source. A screen reader reads what it counts,
9
+ * the figure, then the source. Server-safe.
10
+ */
11
+ export function Stat({ label, value, source }) {
12
+ return (_jsxs("div", { children: [_jsx("dt", { children: label }), _jsx("dd", { children: value }), _jsx("dd", { children: source })] }));
13
+ }
14
+ //# sourceMappingURL=stat-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stat-list.js","sourceRoot":"","sources":["../../src/ui/stat-list.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC,kFAAkF;AAClF,MAAM,UAAU,QAAQ,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAiB;IAC7D,OAAO,aAAI,SAAS,EAAE,EAAE,CAAC,WAAW,EAAE,SAAS,CAAC,YAAG,QAAQ,GAAM,CAAC;AACpE,CAAC;AAcD;;;GAGG;AACH,MAAM,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAa;IACtD,OAAO,CACL,0BACE,uBAAK,KAAK,GAAM,EAChB,uBAAK,KAAK,GAAM,EAChB,uBAAK,MAAM,GAAM,IACb,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { ReactNode } from 'react';
2
+ export interface StepsProps {
3
+ /** Step elements, in order. */
4
+ children: ReactNode;
5
+ className?: string;
6
+ }
7
+ /**
8
+ * Numbered steps: an ordered list, as many to a row as fit at 14rem. The number is generated content, so a
9
+ * screen reader reads it with the step. `role="list"` keeps it a list in Safari, where Tailwind's reset takes
10
+ * the markers off. Server-safe.
11
+ */
12
+ export declare function Steps({ children, className }: StepsProps): import("react").JSX.Element;
13
+ export interface StepProps {
14
+ title: ReactNode;
15
+ /** 3 (default) under a section's h2. */
16
+ headingLevel?: 2 | 3 | 4;
17
+ /** What happens in this step. */
18
+ children?: ReactNode;
19
+ className?: string;
20
+ }
21
+ /** One step: its title and what happens. Server-safe. */
22
+ export declare function Step({ title, headingLevel, children, className }: StepProps): import("react").JSX.Element;
23
+ //# sourceMappingURL=steps.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../src/ui/steps.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvC,MAAM,WAAW,UAAU;IACzB,+BAA+B;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,UAAU,+BAOxD;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,SAAS,CAAC;IACjB,wCAAwC;IACxC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,yDAAyD;AACzD,wBAAgB,IAAI,CAAC,EAAE,KAAK,EAAE,YAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,SAAS,+BAQ/E"}
@@ -0,0 +1,16 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../lib/cn.js';
3
+ /**
4
+ * Numbered steps: an ordered list, as many to a row as fit at 14rem. The number is generated content, so a
5
+ * screen reader reads it with the step. `role="list"` keeps it a list in Safari, where Tailwind's reset takes
6
+ * the markers off. Server-safe.
7
+ */
8
+ export function Steps({ children, className }) {
9
+ return (_jsx("ol", { role: "list", className: cn('steps', className), children: children }));
10
+ }
11
+ /** One step: its title and what happens. Server-safe. */
12
+ export function Step({ title, headingLevel = 3, children, className }) {
13
+ const Heading = `h${headingLevel}`;
14
+ return (_jsxs("li", { className: className, children: [_jsx(Heading, { className: "text-subheading", children: title }), children && _jsx("div", { className: "mt-2 text-body text-muted-foreground", children: children })] }));
15
+ }
16
+ //# sourceMappingURL=steps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"steps.js","sourceRoot":"","sources":["../../src/ui/steps.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAc;IACvD,OAAO,CAEL,aAAI,IAAI,EAAC,MAAM,EAAC,SAAS,EAAE,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,YAC9C,QAAQ,GACN,CACN,CAAC;AACJ,CAAC;AAWD,yDAAyD;AACzD,MAAM,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,GAAG,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAa;IAC9E,MAAM,OAAO,GAAG,IAAI,YAAY,EAAwB,CAAC;IACzD,OAAO,CACL,cAAI,SAAS,EAAE,SAAS,aACtB,KAAC,OAAO,IAAC,SAAS,EAAC,iBAAiB,YAAE,KAAK,GAAW,EACrD,QAAQ,IAAI,cAAK,SAAS,EAAC,sCAAsC,YAAE,QAAQ,GAAO,IAChF,CACN,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type SwitchProps as RACSwitchProps } from 'react-aria-components';
3
+ export interface SwitchProps extends Omit<RACSwitchProps, 'className' | 'children'> {
4
+ children: ReactNode;
5
+ description?: ReactNode;
6
+ className?: string;
7
+ }
8
+ /**
9
+ * On/off that takes effect immediately — confirm the change with a status message. Inside a form that is
10
+ * submitted later, use a Checkbox. On: the thumb moves right and the track fills, never colour alone.
11
+ */
12
+ export declare function Switch({ children, description, className, ...props }: SwitchProps): import("react").JSX.Element;
13
+ //# sourceMappingURL=switch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch.d.ts","sourceRoot":"","sources":["../../src/ui/switch.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAuB,KAAK,WAAW,IAAI,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGhG,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,UAAU,CAAC;IACjF,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,WAAW,+BA+BjF"}
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Switch as RACSwitch } from 'react-aria-components';
4
+ import { cn } from '../lib/cn.js';
5
+ /**
6
+ * On/off that takes effect immediately — confirm the change with a status message. Inside a form that is
7
+ * submitted later, use a Checkbox. On: the thumb moves right and the track fills, never colour alone.
8
+ */
9
+ export function Switch({ children, description, className, ...props }) {
10
+ return (_jsxs(RACSwitch, { ...props, className: cn('group/choice relative flex min-h-target cursor-pointer items-start gap-3 py-[calc((var(--target-min)-var(--choice-size))/2)] text-sm leading-5 text-foreground outline-none data-disabled:cursor-not-allowed data-disabled:opacity-60 data-readonly:cursor-default', className), children: [_jsx("span", { "aria-hidden": "true", className: cn('relative mt-[calc((20px-var(--choice-size))/2)] h-choice w-[calc(var(--choice-size)*1.8)] shrink-0 rounded-full border border-input bg-muted transition-colors duration-(--duration-fast)', 'group-data-focus-visible/choice:focus-ring group-data-selected/choice:border-primary group-data-selected/choice:bg-primary'), children: _jsx("span", { className: cn('absolute top-1/2 left-[2px] size-[calc(var(--choice-size)-6px)] -translate-y-1/2 rounded-full bg-muted-foreground', 'transition-[left] duration-(--duration-fast) motion-reduce:transition-none aaa:transition-none', 'group-data-selected/choice:left-[calc(100%-var(--choice-size)+4px)] group-data-selected/choice:bg-primary-foreground') }) }), _jsxs("span", { className: "flex min-w-0 flex-col", children: [_jsx("span", { children: children }), description && _jsx("span", { className: "text-[13px] text-muted-foreground", children: description })] })] }));
11
+ }
12
+ //# sourceMappingURL=switch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"switch.js","sourceRoot":"","sources":["../../src/ui/switch.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,MAAM,IAAI,SAAS,EAAsC,MAAM,uBAAuB,CAAC;AAChG,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,EAAe;IAChF,OAAO,CAEL,MAAC,SAAS,OACJ,KAAK,EACT,SAAS,EAAE,EAAE,CACX,oQAAoQ,EACpQ,SAAS,CACV,aAED,8BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CACX,2LAA2L,EAC3L,4HAA4H,CAC7H,YAED,eACE,SAAS,EAAE,EAAE,CACX,mHAAmH,EACnH,gGAAgG,EAChG,sHAAsH,CACvH,GACD,GACG,EACP,gBAAM,SAAS,EAAC,uBAAuB,aACrC,yBAAO,QAAQ,GAAQ,EACtB,WAAW,IAAI,eAAM,SAAS,EAAC,mCAAmC,YAAE,WAAW,GAAQ,IACnF,IACG,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type CellProps, type ColumnProps, type RowProps, type TableBodyProps, type TableHeaderProps, type TableProps as RACTableProps } from 'react-aria-components';
3
+ export interface TableProps extends Omit<RACTableProps, 'className'> {
4
+ /** Required: what the table lists ("Projects"). */
5
+ 'aria-label': string;
6
+ className?: string;
7
+ }
8
+ /**
9
+ * React Aria Table (the grid pattern): arrow keys move between rows and cells, Space or click selects.
10
+ * Scrolls sideways inside its own container when it cannot reflow (1.4.10 allows this for data tables).
11
+ */
12
+ export declare function Table({ className, ...props }: TableProps): import("react").JSX.Element;
13
+ export declare function TableHeader<T extends object>(props: Omit<TableHeaderProps<T>, 'className'>): import("react").JSX.Element;
14
+ export declare function Column({ className, ...props }: Omit<ColumnProps, 'className'> & {
15
+ className?: string;
16
+ }): import("react").JSX.Element;
17
+ export declare function TableBody<T extends object>(props: Omit<TableBodyProps<T>, 'className'>): import("react").JSX.Element;
18
+ export declare function Row<T extends object>({ className, ...props }: Omit<RowProps<T>, 'className'> & {
19
+ className?: string;
20
+ }): import("react").JSX.Element;
21
+ export declare function Cell({ className, children, ...props }: Omit<CellProps, 'className' | 'children'> & {
22
+ className?: string;
23
+ children?: ReactNode;
24
+ }): import("react").JSX.Element;
25
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/ui/table.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAOL,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,UAAU,IAAI,aAAa,EACjC,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC;IAClE,mDAAmD;IACnD,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAQxD;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,+BAE1F;AAED,wBAAgB,MAAM,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAUzD;AAED,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,+BAEtF;AAED,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,EACpC,SAAS,EACT,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAWzD;AAED,wBAAgB,IAAI,CAAC,EACnB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;CAAE,+BAa1F"}
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { Cell as RACCell, Column as RACColumn, Row as RACRow, Table as RACTable, TableBody as RACTableBody, TableHeader as RACTableHeader, } from 'react-aria-components';
4
+ import { cn } from '../lib/cn.js';
5
+ /**
6
+ * React Aria Table (the grid pattern): arrow keys move between rows and cells, Space or click selects.
7
+ * Scrolls sideways inside its own container when it cannot reflow (1.4.10 allows this for data tables).
8
+ */
9
+ export function Table({ className, ...props }) {
10
+ return (_jsx("div", { className: cn('relative overflow-x-auto rounded-lg border border-border bg-card', className), children: _jsx(RACTable, { ...props, className: "w-full border-separate border-spacing-0 text-sm" }) }));
11
+ }
12
+ export function TableHeader(props) {
13
+ return _jsx(RACTableHeader, { ...props });
14
+ }
15
+ export function Column({ className, ...props }) {
16
+ return (_jsx(RACColumn, { ...props, className: cn('h-control-target border-b border-border bg-muted px-3 text-left text-[13px] font-semibold whitespace-nowrap text-muted-foreground outline-none data-allows-sorting:cursor-pointer data-focus-visible:focus-ring-inset', className) }));
17
+ }
18
+ export function TableBody(props) {
19
+ return _jsx(RACTableBody, { ...props });
20
+ }
21
+ export function Row({ className, ...props }) {
22
+ return (_jsx(RACRow, { ...props, className: cn(
23
+ // React Aria sets data-hovered only on a row that can be selected or has an action: the pointer then.
24
+ 'group/row cursor-default outline-none data-disabled:cursor-not-allowed data-hovered:cursor-pointer data-hovered:bg-accent data-selected:bg-brand-subtle data-focus-visible:focus-ring-inset', className) }));
25
+ }
26
+ export function Cell({ className, children, ...props }) {
27
+ return (_jsx(RACCell, { ...props, className: cn('h-[calc(var(--control-height)+12px)] border-b border-border px-3 whitespace-nowrap outline-none group-last/row:border-b-0 data-focus-visible:focus-ring-inset', 'first:group-data-selected/row:shadow-[inset_3px_0_0_var(--sidebar-primary)]', className), children: children }));
28
+ }
29
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../src/ui/table.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EACL,IAAI,IAAI,OAAO,EACf,MAAM,IAAI,SAAS,EACnB,GAAG,IAAI,MAAM,EACb,KAAK,IAAI,QAAQ,EACjB,SAAS,IAAI,YAAY,EACzB,WAAW,IAAI,cAAc,GAO9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC;;;GAGG;AACH,MAAM,UAAU,KAAK,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAc;IACvD,OAAO,CACL,cACE,SAAS,EAAE,EAAE,CAAC,kEAAkE,EAAE,SAAS,CAAC,YAE5F,KAAC,QAAQ,OAAK,KAAK,EAAE,SAAS,EAAC,iDAAiD,GAAG,GAC/E,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAmB,KAA6C;IACzF,OAAO,KAAC,cAAc,OAAK,KAAK,GAAI,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,EACrB,SAAS,EACT,GAAG,KAAK,EACgD;IACxD,OAAO,CACL,KAAC,SAAS,OACJ,KAAK,EACT,SAAS,EAAE,EAAE,CACX,uNAAuN,EACvN,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAmB,KAA2C;IACrF,OAAO,KAAC,YAAY,OAAK,KAAK,GAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,GAAG,CAAmB,EACpC,SAAS,EACT,GAAG,KAAK,EACgD;IACxD,OAAO,CACL,KAAC,MAAM,OACD,KAAK,EACT,SAAS,EAAE,EAAE;QACX,sGAAsG;QACtG,6LAA6L,EAC7L,SAAS,CACV,GACD,CACH,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,EACnB,SAAS,EACT,QAAQ,EACR,GAAG,KAAK,EACiF;IACzF,OAAO,CACL,KAAC,OAAO,OACF,KAAK,EACT,SAAS,EAAE,EAAE,CACX,+JAA+J,EAC/J,6EAA6E,EAC7E,SAAS,CACV,YAEA,QAAQ,GACD,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type IconProp } from './icon.js';
3
+ export interface TagProps {
4
+ children: ReactNode;
5
+ /** Decorative, before the words. */
6
+ icon?: IconProp;
7
+ className?: string;
8
+ }
9
+ /**
10
+ * A short label in a pill: "Open source", "Beta". Not a status, which says how something is doing: that is
11
+ * StatusBadge. Server-safe.
12
+ */
13
+ export declare function Tag({ children, icon, className }: TagProps): import("react").JSX.Element;
14
+ //# sourceMappingURL=tag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tag.d.ts","sourceRoot":"","sources":["../../src/ui/tag.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEtD,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,SAAS,CAAC;IACpB,oCAAoC;IACpC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,QAAQ,+BAO1D"}
package/dist/ui/tag.js ADDED
@@ -0,0 +1,11 @@
1
+ import { jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { cn } from '../lib/cn.js';
3
+ import { renderIcon } from './icon.js';
4
+ /**
5
+ * A short label in a pill: "Open source", "Beta". Not a status, which says how something is doing: that is
6
+ * StatusBadge. Server-safe.
7
+ */
8
+ export function Tag({ children, icon, className }) {
9
+ return (_jsxs("span", { className: cn('tag', className), children: [icon && renderIcon(icon, 'size-3.5'), children] }));
10
+ }
11
+ //# sourceMappingURL=tag.js.map