@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,19 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type NumberFieldProps as RACNumberFieldProps } from 'react-aria-components';
3
+ import { type FieldWidth } from './field.js';
4
+ export interface NumberFieldProps extends Omit<RACNumberFieldProps, 'className' | 'children' | 'validate'> {
5
+ label: string;
6
+ description?: ReactNode;
7
+ errorMessage?: string;
8
+ requiredMessage?: string;
9
+ validate?: (value: number) => string | string[] | true | null | undefined;
10
+ width?: FieldWidth;
11
+ className?: string;
12
+ }
13
+ /**
14
+ * A number with − and + steppers. Each stepper is its own target (Layer 1, at least --target-min) around a
15
+ * 28px painted button that stays 4px from the box's edge at every level. Arrow keys and typing work too;
16
+ * min and max clamp on blur.
17
+ */
18
+ export declare function NumberField({ label, description, errorMessage, requiredMessage, validate, width, className, ...props }: NumberFieldProps): import("react").JSX.Element;
19
+ //# sourceMappingURL=number-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-field.d.ts","sourceRoot":"","sources":["../../src/ui/number-field.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,gBAAgB,IAAI,mBAAmB,EAC7C,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAUL,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAC5C,mBAAmB,EACnB,WAAW,GAAG,UAAU,GAAG,UAAU,CACtC;IACC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1E,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,KAAY,EACZ,SAAS,EACT,GAAG,KAAK,EACT,EAAE,gBAAgB,+BA+ClB"}
@@ -0,0 +1,19 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Group, Input, NumberField as RACNumberField, } from 'react-aria-components';
4
+ import { Minus, Plus } from 'lucide-react';
5
+ import { cn } from '../lib/cn.js';
6
+ import { Button } from './button.js';
7
+ import { FieldDescription, FieldError, FieldLabel, fieldBox, fieldInput, fieldStack, fieldWidths, lcFirst, withRequired, } from './field.js';
8
+ /**
9
+ * A number with − and + steppers. Each stepper is its own target (Layer 1, at least --target-min) around a
10
+ * 28px painted button that stays 4px from the box's edge at every level. Arrow keys and typing work too;
11
+ * min and max clamp on blur.
12
+ */
13
+ export function NumberField({ label, description, errorMessage, requiredMessage, validate, width = 'sm', className, ...props }) {
14
+ return (_jsxs(RACNumberField, { ...props, validate: withRequired(props.isRequired, requiredMessage ?? `Enter ${lcFirst(label)}`, (v) => v == null || Number.isNaN(v), validate), className: cn(fieldStack, fieldWidths[width],
15
+ // Two stepper targets plus room for five digits. At AAA the targets are 44px, so a narrow field
16
+ // grows past its width rather than squeezing the number (min-width wins over max-width).
17
+ 'min-w-[calc(2*max(var(--target-min),var(--control-height-sm))+5ch+1.5rem)]', className), children: [_jsx(FieldLabel, { isRequired: props.isRequired, children: label }), description && _jsx(FieldDescription, { children: description }), _jsx(FieldError, { requiredMessage: requiredMessage ?? `Enter ${lcFirst(label)}`, children: errorMessage }), _jsxs(Group, { className: fieldBox, children: [_jsx(Button, { slot: "decrement", variant: "ghost", visualSize: "icon-sm", className: "ms-1 justify-start", visualClassName: "[&_svg]:size-4", children: _jsx(Minus, { "aria-hidden": "true" }) }), _jsx(Input, { className: cn(fieldInput, 'px-2 text-center tabular-nums') }), _jsx(Button, { slot: "increment", variant: "ghost", visualSize: "icon-sm", className: "me-1 justify-end", visualClassName: "[&_svg]:size-4", children: _jsx(Plus, { "aria-hidden": "true" }) })] })] }));
18
+ }
19
+ //# sourceMappingURL=number-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"number-field.js","sourceRoot":"","sources":["../../src/ui/number-field.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EACL,KAAK,EACL,KAAK,EACL,WAAW,IAAI,cAAc,GAE9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,WAAW,EACX,OAAO,EACP,YAAY,GAEb,MAAM,YAAY,CAAC;AAepB;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,KAAK,GAAG,IAAI,EACZ,SAAS,EACT,GAAG,KAAK,EACS;IACjB,OAAO,CACL,MAAC,cAAc,OACT,KAAK,EACT,QAAQ,EAAE,YAAY,CACpB,KAAK,CAAC,UAAU,EAChB,eAAe,IAAI,SAAS,OAAO,CAAC,KAAK,CAAC,EAAE,EAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EACnC,QAAQ,CACT,EACD,SAAS,EAAE,EAAE,CACX,UAAU,EACV,WAAW,CAAC,KAAK,CAAC;QAClB,gGAAgG;QAChG,yFAAyF;QACzF,4EAA4E,EAC5E,SAAS,CACV,aAED,KAAC,UAAU,IAAC,UAAU,EAAE,KAAK,CAAC,UAAU,YAAG,KAAK,GAAc,EAC7D,WAAW,IAAI,KAAC,gBAAgB,cAAE,WAAW,GAAoB,EAClE,KAAC,UAAU,IAAC,eAAe,EAAE,eAAe,IAAI,SAAS,OAAO,CAAC,KAAK,CAAC,EAAE,YACtE,YAAY,GACF,EACb,MAAC,KAAK,IAAC,SAAS,EAAE,QAAQ,aACxB,KAAC,MAAM,IACL,IAAI,EAAC,WAAW,EAChB,OAAO,EAAC,OAAO,EACf,UAAU,EAAC,SAAS,EACpB,SAAS,EAAC,oBAAoB,EAC9B,eAAe,EAAC,gBAAgB,YAEhC,KAAC,KAAK,mBAAa,MAAM,GAAG,GACrB,EACT,KAAC,KAAK,IAAC,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,+BAA+B,CAAC,GAAI,EACrE,KAAC,MAAM,IACL,IAAI,EAAC,WAAW,EAChB,OAAO,EAAC,OAAO,EACf,UAAU,EAAC,SAAS,EACpB,SAAS,EAAC,kBAAkB,EAC5B,eAAe,EAAC,gBAAgB,YAEhC,KAAC,IAAI,mBAAa,MAAM,GAAG,GACpB,IACH,IACO,CAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { HTMLAttributes, ReactNode } from 'react';
2
+ export interface ProseProps extends HTMLAttributes<HTMLDivElement> {
3
+ /** Headings, paragraphs, lists, inline code and TextLinks. */
4
+ children: ReactNode;
5
+ }
6
+ /**
7
+ * Long text, such as a privacy notice or a guide: inside `--measure`, with `--paragraph-gap` between blocks
8
+ * (both larger at AAA), spaced headings, and lists with their markers back. Links in it are TextLinks, or plain
9
+ * `<a href>`, which the base styles underline. Server-safe.
10
+ */
11
+ export declare function Prose({ children, className, ...props }: ProseProps): import("react").JSX.Element;
12
+ //# sourceMappingURL=prose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prose.d.ts","sourceRoot":"","sources":["../../src/ui/prose.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGvD,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAC,cAAc,CAAC;IAChE,8DAA8D;IAC9D,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAMlE"}
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { cn } from '../lib/cn.js';
3
+ /**
4
+ * Long text, such as a privacy notice or a guide: inside `--measure`, with `--paragraph-gap` between blocks
5
+ * (both larger at AAA), spaced headings, and lists with their markers back. Links in it are TextLinks, or plain
6
+ * `<a href>`, which the base styles underline. Server-safe.
7
+ */
8
+ export function Prose({ children, className, ...props }) {
9
+ return (_jsx("div", { ...props, className: cn('site-prose', className), children: children }));
10
+ }
11
+ //# sourceMappingURL=prose.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prose.js","sourceRoot":"","sources":["../../src/ui/prose.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAOlC;;;;GAIG;AACH,MAAM,UAAU,KAAK,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,EAAc;IACjE,OAAO,CACL,iBAAS,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,YAAY,EAAE,SAAS,CAAC,YACnD,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type RadioGroupProps as RACRadioGroupProps, type RadioProps as RACRadioProps } from 'react-aria-components';
3
+ export interface RadioGroupProps extends Omit<RACRadioGroupProps, 'className' | 'children' | 'validate'> {
4
+ label: string;
5
+ description?: ReactNode;
6
+ errorMessage?: string;
7
+ requiredMessage?: string;
8
+ children: ReactNode;
9
+ className?: string;
10
+ }
11
+ /** Choose exactly one of a few options that people should compare side by side. Arrow keys move and select. */
12
+ export declare function RadioGroup({ label, description, errorMessage, requiredMessage, children, className, orientation, ...props }: RadioGroupProps): import("react").JSX.Element;
13
+ export interface RadioProps extends Omit<RACRadioProps, 'className' | 'children'> {
14
+ children: ReactNode;
15
+ description?: ReactNode;
16
+ className?: string;
17
+ }
18
+ /** Selected: a thick ring in `primary` — a change of shape, not only colour. */
19
+ export declare function Radio({ children, description, className, ...props }: RadioProps): import("react").JSX.Element;
20
+ //# sourceMappingURL=radio-group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group.d.ts","sourceRoot":"","sources":["../../src/ui/radio-group.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAGL,KAAK,eAAe,IAAI,kBAAkB,EAC1C,KAAK,UAAU,IAAI,aAAa,EACjC,MAAM,uBAAuB,CAAC;AAW/B,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,kBAAkB,EAClB,WAAW,GAAG,UAAU,GAAG,UAAU,CACtC;IACC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,+GAA+G;AAC/G,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,SAAS,EACT,WAAwB,EACxB,GAAG,KAAK,EACT,EAAE,eAAe,+BAiCjB;AAED,MAAM,WAAW,UAAW,SAAQ,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,UAAU,CAAC;IAC/E,QAAQ,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,gFAAgF;AAChF,wBAAgB,KAAK,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,UAAU,+BAyB/E"}
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Radio as RACRadio, RadioGroup as RACRadioGroup, } from 'react-aria-components';
4
+ import { cn } from '../lib/cn.js';
5
+ import { FieldDescription, FieldError, FieldLabel, fieldStack, lcFirst, withRequired, } from './field.js';
6
+ /** Choose exactly one of a few options that people should compare side by side. Arrow keys move and select. */
7
+ export function RadioGroup({ label, description, errorMessage, requiredMessage, children, className, orientation = 'vertical', ...props }) {
8
+ return (_jsxs(RACRadioGroup, { ...props, orientation: orientation, validate: props.isRequired
9
+ ? withRequired(true, requiredMessage ?? `Choose ${lcFirst(label)}`, (v) => !v)
10
+ : undefined, className: cn(fieldStack, className), children: [_jsx(FieldLabel, { elementType: "span", isRequired: props.isRequired, children: label }), description && _jsx(FieldDescription, { children: description }), _jsx(FieldError, { requiredMessage: requiredMessage ?? `Choose ${lcFirst(label)}`, children: errorMessage }), _jsx("div", { className: cn('flex', orientation === 'horizontal' ? 'flex-row flex-wrap gap-x-6' : 'flex-col'), children: children })] }));
11
+ }
12
+ /** Selected: a thick ring in `primary` — a change of shape, not only colour. */
13
+ export function Radio({ children, description, className, ...props }) {
14
+ return (_jsxs(RACRadio, { ...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('mt-[calc((20px-var(--choice-size))/2)] size-choice shrink-0 rounded-full border border-input bg-background', 'group-data-focus-visible/choice:focus-ring group-data-hovered/choice:border-foreground', 'group-data-selected/choice:border-[calc(var(--choice-size)*0.3)] group-data-selected/choice:border-primary', 'group-data-invalid/choice:border-destructive') }), _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 })] })] }));
15
+ }
16
+ //# sourceMappingURL=radio-group.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"radio-group.js","sourceRoot":"","sources":["../../src/ui/radio-group.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EACL,KAAK,IAAI,QAAQ,EACjB,UAAU,IAAI,aAAa,GAG5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,OAAO,EACP,YAAY,GACb,MAAM,YAAY,CAAC;AAcpB,+GAA+G;AAC/G,MAAM,UAAU,UAAU,CAAC,EACzB,KAAK,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,SAAS,EACT,WAAW,GAAG,UAAU,EACxB,GAAG,KAAK,EACQ;IAChB,OAAO,CACL,MAAC,aAAa,OACR,KAAK,EACT,WAAW,EAAE,WAAW,EACxB,QAAQ,EACN,KAAK,CAAC,UAAU;YACd,CAAC,CAAC,YAAY,CACV,IAAI,EACJ,eAAe,IAAI,UAAU,OAAO,CAAC,KAAK,CAAC,EAAE,EAC7C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CACV;YACH,CAAC,CAAC,SAAS,EAEf,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,SAAS,CAAC,aAEpC,KAAC,UAAU,IAAC,WAAW,EAAC,MAAM,EAAC,UAAU,EAAE,KAAK,CAAC,UAAU,YACxD,KAAK,GACK,EACZ,WAAW,IAAI,KAAC,gBAAgB,cAAE,WAAW,GAAoB,EAClE,KAAC,UAAU,IAAC,eAAe,EAAE,eAAe,IAAI,UAAU,OAAO,CAAC,KAAK,CAAC,EAAE,YACvE,YAAY,GACF,EACb,cACE,SAAS,EAAE,EAAE,CACX,MAAM,EACN,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,UAAU,CACzE,YAEA,QAAQ,GACL,IACQ,CACjB,CAAC;AACJ,CAAC;AAQD,gFAAgF;AAChF,MAAM,UAAU,KAAK,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,KAAK,EAAc;IAC9E,OAAO,CAEL,MAAC,QAAQ,OACH,KAAK,EACT,SAAS,EAAE,EAAE,CACX,oQAAoQ,EACpQ,SAAS,CACV,aAED,8BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CACX,4GAA4G,EAC5G,wFAAwF,EACxF,4GAA4G,EAC5G,8CAA8C,CAC/C,GACD,EACF,gBAAM,SAAS,EAAC,uBAAuB,aACrC,yBAAO,QAAQ,GAAQ,EACtB,WAAW,IAAI,eAAM,SAAS,EAAC,mCAAmC,YAAE,WAAW,GAAQ,IACnF,IACE,CACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface ScrollRegionProps {
3
+ /**
4
+ * Required: what scrolls ("Token pairs", "app/layout.tsx"). It names the region while it scrolls, so it has
5
+ * to differ from every other region on the page — two with one name are landmarks nobody can tell apart.
6
+ */
7
+ label: string;
8
+ children: ReactNode;
9
+ className?: string;
10
+ }
11
+ /**
12
+ * Content that scrolls sideways inside its own box instead of the page: a plain table, code, a wide figure.
13
+ * Only while it scrolls is it a tab stop, so a keyboard can scroll it, and a named region, so the stop says
14
+ * what it is. Content that fits is left alone. `relative`, like every scroller here, so hidden text inside is
15
+ * placed against it. A `Table` doesn't need this: its rows and cells take focus, which scrolls them in.
16
+ */
17
+ export declare function ScrollRegion({ label, children, className }: ScrollRegionProps): import("react").JSX.Element;
18
+ //# sourceMappingURL=scroll-region.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-region.d.ts","sourceRoot":"","sources":["../../src/ui/scroll-region.tsx"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGpE,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE,iBAAiB,+BA4B7E"}
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from 'react';
4
+ import { cn } from '../lib/cn.js';
5
+ /**
6
+ * Content that scrolls sideways inside its own box instead of the page: a plain table, code, a wide figure.
7
+ * Only while it scrolls is it a tab stop, so a keyboard can scroll it, and a named region, so the stop says
8
+ * what it is. Content that fits is left alone. `relative`, like every scroller here, so hidden text inside is
9
+ * placed against it. A `Table` doesn't need this: its rows and cells take focus, which scrolls them in.
10
+ */
11
+ export function ScrollRegion({ label, children, className }) {
12
+ const ref = useRef(null);
13
+ const [scrolls, setScrolls] = useState(false);
14
+ useEffect(() => {
15
+ const el = ref.current;
16
+ if (!el)
17
+ return;
18
+ const measure = () => setScrolls(el.scrollWidth > el.clientWidth + 1);
19
+ measure();
20
+ const observer = new ResizeObserver(measure);
21
+ observer.observe(el);
22
+ // The content can grow without the box resizing.
23
+ for (const child of el.children)
24
+ observer.observe(child);
25
+ return () => observer.disconnect();
26
+ }, []);
27
+ return (_jsx("div", { ref: ref, tabIndex: scrolls ? 0 : undefined, role: scrolls ? 'region' : undefined, "aria-label": scrolls ? label : undefined, className: cn('relative overflow-x-auto rounded-sm outline-none focus-visible:focus-ring-inset', className), children: children }));
28
+ }
29
+ //# sourceMappingURL=scroll-region.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll-region.js","sourceRoot":"","sources":["../../src/ui/scroll-region.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AACpE,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAYlC;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAqB;IAC5E,MAAM,GAAG,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IACzC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,GAAG,CAAC,OAAO,CAAC;QACvB,IAAI,CAAC,EAAE;YAAE,OAAO;QAChB,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,WAAW,GAAG,EAAE,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QACtE,OAAO,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC;QAC7C,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACrB,iDAAiD;QACjD,KAAK,MAAM,KAAK,IAAI,EAAE,CAAC,QAAQ;YAAE,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACzD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC;IACrC,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,CACL,cACE,GAAG,EAAE,GAAG,EACR,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EACjC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,gBACxB,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EACvC,SAAS,EAAE,EAAE,CACX,iFAAiF,EACjF,SAAS,CACV,YAEA,QAAQ,GACL,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type SearchFieldProps as RACSearchFieldProps } from 'react-aria-components';
2
+ import { type FieldWidth } from './field.js';
3
+ export interface SearchFieldProps extends Omit<RACSearchFieldProps, 'className' | 'children'> {
4
+ /** Visible label, or pass aria-label for a toolbar filter whose purpose is obvious from context. */
5
+ label?: string;
6
+ placeholder?: string;
7
+ width?: FieldWidth;
8
+ className?: string;
9
+ }
10
+ /** Filter the content on this page (the header's AppSearch searches everything). Escape or the clear button empties it. */
11
+ export declare function SearchField({ label, placeholder, width, className, ...props }: SearchFieldProps): import("react").JSX.Element;
12
+ //# sourceMappingURL=search-field.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-field.d.ts","sourceRoot":"","sources":["../../src/ui/search-field.tsx"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,gBAAgB,IAAI,mBAAmB,EAC7C,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,gBAAiB,SAAQ,IAAI,CAAC,mBAAmB,EAAE,WAAW,GAAG,UAAU,CAAC;IAC3F,oGAAoG;IACpG,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2HAA2H;AAC3H,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,KAAY,EACZ,SAAS,EACT,GAAG,KAAK,EACT,EAAE,gBAAgB,+BAyBlB"}
@@ -0,0 +1,12 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Input, SearchField as RACSearchField, } from 'react-aria-components';
4
+ import { Search, X } from 'lucide-react';
5
+ import { cn } from '../lib/cn.js';
6
+ import { Button } from './button.js';
7
+ import { FieldLabel, fieldBox, fieldInput, fieldStack, fieldWidths, } from './field.js';
8
+ /** Filter the content on this page (the header's AppSearch searches everything). Escape or the clear button empties it. */
9
+ export function SearchField({ label, placeholder, width = 'sm', className, ...props }) {
10
+ return (_jsxs(RACSearchField, { ...props, className: cn(fieldStack, fieldWidths[width], className), children: [label && _jsx(FieldLabel, { children: label }), _jsxs("div", { className: fieldBox, children: [_jsx(Search, { "aria-hidden": "true", className: "pointer-events-none absolute top-1/2 left-2.5 size-5 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { placeholder: placeholder, className: cn(fieldInput, 'pl-10 [&::-webkit-search-cancel-button]:hidden') }), _jsx(Button, { variant: "ghost", visualSize: "icon-sm", className: "me-1 justify-end group-data-empty/field:hidden", visualClassName: "text-muted-foreground group-data-hovered/button:text-foreground [&_svg]:size-4", children: _jsx(X, { "aria-hidden": "true" }) })] })] }));
11
+ }
12
+ //# sourceMappingURL=search-field.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-field.js","sourceRoot":"","sources":["../../src/ui/search-field.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EACL,KAAK,EACL,WAAW,IAAI,cAAc,GAE9B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EACL,UAAU,EACV,QAAQ,EACR,UAAU,EACV,UAAU,EACV,WAAW,GAEZ,MAAM,YAAY,CAAC;AAUpB,2HAA2H;AAC3H,MAAM,UAAU,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,KAAK,GAAG,IAAI,EACZ,SAAS,EACT,GAAG,KAAK,EACS;IACjB,OAAO,CACL,MAAC,cAAc,OAAK,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,aAChF,KAAK,IAAI,KAAC,UAAU,cAAE,KAAK,GAAc,EAC1C,eAAK,SAAS,EAAE,QAAQ,aACtB,KAAC,MAAM,mBACO,MAAM,EAClB,SAAS,EAAC,6FAA6F,GACvG,EACF,KAAC,KAAK,IACJ,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,gDAAgD,CAAC,GAC3E,EAEF,KAAC,MAAM,IACL,OAAO,EAAC,OAAO,EACf,UAAU,EAAC,SAAS,EACpB,SAAS,EAAC,gDAAgD,EAC1D,eAAe,EAAC,gFAAgF,YAEhG,KAAC,CAAC,mBAAa,MAAM,GAAG,GACjB,IACL,IACS,CAClB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { type Key } from 'react-aria-components';
2
+ import { type IconProp } from './icon.js';
3
+ export interface SearchItem {
4
+ id: string;
5
+ label: string;
6
+ description?: string;
7
+ icon?: IconProp;
8
+ href?: string;
9
+ }
10
+ export interface SearchSection {
11
+ id: string;
12
+ title: string;
13
+ items: SearchItem[];
14
+ }
15
+ export interface CommandSearchProps {
16
+ isOpen: boolean;
17
+ onOpenChange: (open: boolean) => void;
18
+ sections: SearchSection[];
19
+ onAction?: (id: Key) => void;
20
+ placeholder?: string;
21
+ }
22
+ /** The search dialog: type to filter, arrow keys to move, Enter to go, Escape to close. */
23
+ export declare function CommandSearch({ isOpen, onOpenChange, sections, onAction, placeholder, }: CommandSearchProps): import("react").JSX.Element;
24
+ export interface SearchTriggerProps {
25
+ onPress: () => void;
26
+ placeholder?: string;
27
+ /** Icon-only, for narrow headers. */
28
+ compact?: boolean;
29
+ className?: string;
30
+ }
31
+ /** Opens the search dialog. Looks like a field; is a button, named "Search", with the shortcut announced. */
32
+ export declare function SearchTrigger({ onPress, placeholder, compact, className, }: SearchTriggerProps): import("react").JSX.Element;
33
+ export interface AppSearchProps {
34
+ sections: SearchSection[];
35
+ onAction?: (id: Key) => void;
36
+ compact?: boolean;
37
+ defaultOpen?: boolean;
38
+ placeholder?: string;
39
+ className?: string;
40
+ }
41
+ /** Trigger + dialog + the ⌘K / Ctrl+K shortcut, wired together. */
42
+ export declare function AppSearch({ sections, onAction, compact, defaultOpen, placeholder, className, }: AppSearchProps): import("react").JSX.Element;
43
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/ui/search.tsx"],"names":[],"mappings":"AAGA,OAAO,EAcL,KAAK,GAAG,EACT,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAItD,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AACD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,2FAA2F;AAC3F,wBAAgB,aAAa,CAAC,EAC5B,MAAM,EACN,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,WAAoD,GACrD,EAAE,kBAAkB,+BAmFpB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qCAAqC;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,6GAA6G;AAC7G,wBAAgB,aAAa,CAAC,EAC5B,OAAO,EACP,WAAsB,EACtB,OAAO,EACP,SAAS,GACV,EAAE,kBAAkB,+BA8BpB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,mEAAmE;AACnE,wBAAgB,SAAS,CAAC,EACxB,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,WAAmB,EACnB,WAAW,EACX,SAAS,GACV,EAAE,cAAc,+BAwBhB"}
@@ -0,0 +1,45 @@
1
+ 'use client';
2
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import { Autocomplete, Button as RACButton, Collection, Dialog, Header, Input, Menu, MenuItem, MenuSection, Modal, ModalOverlay, SearchField, useFilter, } from 'react-aria-components';
5
+ import { Search, SearchX } from 'lucide-react';
6
+ import { cn } from '../lib/cn.js';
7
+ import { fieldBox, fieldInput } from './field.js';
8
+ import { IconButton } from './icon-button.js';
9
+ import { renderIcon } from './icon.js';
10
+ import { Kbd } from './kbd.js';
11
+ import { itemVisual, rowTarget } from './menu.js';
12
+ /** The search dialog: type to filter, arrow keys to move, Enter to go, Escape to close. */
13
+ export function CommandSearch({ isOpen, onOpenChange, sections, onAction, placeholder = 'Search projects, people and settings', }) {
14
+ const { contains } = useFilter({ sensitivity: 'base' });
15
+ return (_jsx(ModalOverlay, { isOpen: isOpen, onOpenChange: onOpenChange, isDismissable: true, "data-overlay": true, className: "fixed inset-0 z-(--z-popover) flex items-start justify-center bg-overlay px-4 pt-[12vh]", children: _jsx(Modal, { "data-sheet": "top", className: "w-full max-w-[40rem] overflow-hidden rounded-xl border border-border bg-popover text-popover-foreground shadow-(--shadow-lg) outline-none", children: _jsx(Dialog, { "aria-label": "Search", className: "flex max-h-[70vh] flex-col outline-none", children: _jsxs(Autocomplete, { filter: contains, children: [_jsx(SearchField, { "aria-label": "Search", autoFocus: true, className: "border-b border-border p-3", children: _jsxs("div", { className: fieldBox, children: [_jsx(Search, { "aria-hidden": "true", className: "pointer-events-none absolute top-1/2 left-2.5 size-5 -translate-y-1/2 text-muted-foreground" }), _jsx(Input, { placeholder: placeholder, className: cn(fieldInput, 'pr-14 pl-10 [&::-webkit-search-cancel-button]:hidden') }), _jsx(Kbd, { className: "pointer-events-none absolute top-1/2 right-2 -translate-y-1/2", children: "Esc" })] }) }), _jsx(Menu, { items: sections, onAction: (id) => {
16
+ onAction?.(id);
17
+ onOpenChange(false);
18
+ }, renderEmptyState: () => (_jsxs("div", { className: "flex flex-col items-center gap-2 px-4 py-10 text-center text-sm text-muted-foreground", children: [_jsx(SearchX, { "aria-hidden": "true", className: "size-6" }), "No results. Try a project name, a person or a setting."] })), className: "relative min-h-0 flex-1 overflow-auto p-2 outline-none", children: (section) => (_jsxs(MenuSection, { id: section.id, className: "not-first:mt-2", children: [_jsx(Header, { className: "px-3 pt-1 pb-1 text-[13px] leading-5 font-semibold text-muted-foreground", children: section.title }), _jsx(Collection, { items: section.items, children: (item) => (_jsx(MenuItem, { id: item.id, href: item.href, textValue: item.label, className: cn('group/item', rowTarget), children: _jsxs("span", { className: itemVisual, children: [item.icon &&
19
+ renderIcon(item.icon, 'size-5 shrink-0 text-muted-foreground'), _jsxs("span", { className: "flex min-w-0 flex-col", children: [_jsx("span", { className: "truncate font-medium", children: item.label }), item.description && (_jsx("span", { className: "truncate text-[13px] text-muted-foreground", children: item.description }))] })] }) })) })] })) })] }) }) }) }));
20
+ }
21
+ /** Opens the search dialog. Looks like a field; is a button, named "Search", with the shortcut announced. */
22
+ export function SearchTrigger({ onPress, placeholder = 'Search', compact, className, }) {
23
+ if (compact) {
24
+ return (_jsx(IconButton, { label: "Search", icon: Search, onPress: onPress, "aria-haspopup": "dialog", "aria-keyshortcuts": "Meta+K Control+K" }));
25
+ }
26
+ return (_jsxs(RACButton, { onPress: onPress, "aria-label": "Search", "aria-haspopup": "dialog", "aria-keyshortcuts": "Meta+K Control+K", className: cn(
27
+ // Looks like a field, so it is built like one: the button is the target, the box is painted behind it.
28
+ 'field-paint flex h-control-target w-64 min-w-0 cursor-pointer items-center gap-2 pr-2 pl-2.5 text-left text-sm text-muted-foreground outline-none', 'data-hovered:before:bg-accent data-focus-visible:before:focus-ring', className), children: [_jsx(Search, { "aria-hidden": "true", className: "size-5 shrink-0" }), _jsx("span", { className: "min-w-0 flex-1 truncate", children: placeholder }), _jsx(Kbd, { children: "\u2318K" })] }));
29
+ }
30
+ /** Trigger + dialog + the ⌘K / Ctrl+K shortcut, wired together. */
31
+ export function AppSearch({ sections, onAction, compact, defaultOpen = false, placeholder, className, }) {
32
+ const [isOpen, setOpen] = useState(defaultOpen);
33
+ useEffect(() => {
34
+ const onKey = (e) => {
35
+ if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {
36
+ e.preventDefault();
37
+ setOpen(true);
38
+ }
39
+ };
40
+ document.addEventListener('keydown', onKey);
41
+ return () => document.removeEventListener('keydown', onKey);
42
+ }, []);
43
+ return (_jsxs(_Fragment, { children: [_jsx(SearchTrigger, { onPress: () => setOpen(true), compact: compact, className: className }), _jsx(CommandSearch, { isOpen: isOpen, onOpenChange: setOpen, sections: sections, onAction: onAction, placeholder: placeholder })] }));
44
+ }
45
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/ui/search.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import { type HTMLAttributes, type ReactNode } from 'react';
2
+ export interface ContainerProps extends HTMLAttributes<HTMLDivElement> {
3
+ children: ReactNode;
4
+ /** `narrow`: `--site-max-narrow` (768px), for long text or a form. Default `--site-max` (1180px). */
5
+ width?: 'default' | 'narrow';
6
+ }
7
+ /** The content width of a public page, centred, with `--site-gutter` either side. Server-safe. */
8
+ export declare function Container({ children, width, className, ...props }: ContainerProps): import("react").JSX.Element;
9
+ /** A short label above a heading, in sentence case. Server-safe. */
10
+ export declare function Eyebrow({ children, className }: {
11
+ children: ReactNode;
12
+ className?: string;
13
+ }): import("react").JSX.Element;
14
+ export interface SectionHeaderProps {
15
+ title: ReactNode;
16
+ eyebrow?: ReactNode;
17
+ /** A sentence or two under the heading, inside `--measure`. */
18
+ intro?: ReactNode;
19
+ /** The heading's id, for a Section named by it or a link to it. */
20
+ id?: string;
21
+ /** 2 (default) for a section of the page, 3 for one inside another. */
22
+ headingLevel?: 2 | 3;
23
+ className?: string;
24
+ }
25
+ /** A section's eyebrow, heading and intro, with the space before its content. Server-safe. */
26
+ export declare function SectionHeader({ title, eyebrow, intro, id, headingLevel, className, }: SectionHeaderProps): import("react").JSX.Element;
27
+ export interface SectionProps extends Omit<HTMLAttributes<HTMLElement>, 'title'> {
28
+ /** The heading: every section has one. */
29
+ title: ReactNode;
30
+ eyebrow?: ReactNode;
31
+ intro?: ReactNode;
32
+ children?: ReactNode;
33
+ headingLevel?: 2 | 3;
34
+ /** The heading's id, to name something else by it (a form) or link to it. Default: generated. */
35
+ headingId?: string;
36
+ /**
37
+ * Name the section by its heading, so it is a region landmark. Off by default: a named section is listed
38
+ * with the landmarks, and naming every section fills that list. Use it for the few a reader jumps to.
39
+ */
40
+ landmark?: boolean;
41
+ /** The alternate ground, `card`, with a border above and below. */
42
+ raised?: boolean;
43
+ /** Less space above and below (`--section-y-tight`). */
44
+ tight?: boolean;
45
+ /** The content width: `narrow` for long text or a form. */
46
+ width?: 'default' | 'narrow';
47
+ }
48
+ /** One full-width band of a public page: its header, then its content, in a Container. Server-safe. */
49
+ export declare function Section({ title, eyebrow, intro, children, headingLevel, headingId, landmark, raised, tight, width, className, ...props }: SectionProps): import("react").JSX.Element;
50
+ //# sourceMappingURL=section.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section.d.ts","sourceRoot":"","sources":["../../src/ui/section.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGnE,MAAM,WAAW,cAAe,SAAQ,cAAc,CAAC,cAAc,CAAC;IACpE,QAAQ,EAAE,SAAS,CAAC;IACpB,qGAAqG;IACrG,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC9B;AAED,kGAAkG;AAClG,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,KAAiB,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,cAAc,+BAS7F;AAED,oEAAoE;AACpE,wBAAgB,OAAO,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAE3F;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,+DAA+D;IAC/D,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,mEAAmE;IACnE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,8FAA8F;AAC9F,wBAAgB,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,EACP,KAAK,EACL,EAAE,EACF,YAAgB,EAChB,SAAS,GACV,EAAE,kBAAkB,+BAWpB;AAED,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC9E,0CAA0C;IAC1C,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACrB,iGAAiG;IACjG,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wDAAwD;IACxD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,2DAA2D;IAC3D,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;CAC9B;AAED,uGAAuG;AACvG,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,YAAgB,EAChB,SAAS,EACT,QAAgB,EAChB,MAAc,EACd,KAAa,EACb,KAAiB,EACjB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,YAAY,+BA0Bd"}
@@ -0,0 +1,25 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useId } from 'react';
3
+ import { cn } from '../lib/cn.js';
4
+ /** The content width of a public page, centred, with `--site-gutter` either side. Server-safe. */
5
+ export function Container({ children, width = 'default', className, ...props }) {
6
+ return (_jsx("div", { ...props, className: cn(width === 'narrow' ? 'site-container-narrow' : 'site-container', className), children: children }));
7
+ }
8
+ /** A short label above a heading, in sentence case. Server-safe. */
9
+ export function Eyebrow({ children, className }) {
10
+ return _jsx("p", { className: cn('eyebrow', className), children: children });
11
+ }
12
+ /** A section's eyebrow, heading and intro, with the space before its content. Server-safe. */
13
+ export function SectionHeader({ title, eyebrow, intro, id, headingLevel = 2, className, }) {
14
+ const Heading = headingLevel === 3 ? 'h3' : 'h2';
15
+ return (_jsxs("div", { className: cn('section-head', className), children: [eyebrow && _jsx(Eyebrow, { children: eyebrow }), _jsx(Heading, { id: id, className: "text-display-section", children: title }), intro && _jsx("p", { className: "text-lead text-muted-foreground", children: intro })] }));
16
+ }
17
+ /** One full-width band of a public page: its header, then its content, in a Container. Server-safe. */
18
+ export function Section({ title, eyebrow, intro, children, headingLevel = 2, headingId, landmark = false, raised = false, tight = false, width = 'default', className, ...props }) {
19
+ const generatedId = useId();
20
+ const id = headingId ?? generatedId;
21
+ return (_jsx("section", { ...props, "aria-labelledby": landmark ? id : undefined, className: cn(tight ? 'section-band-tight' : 'section-band',
22
+ // section-band-raised's ground, so it combines with the tight spacing.
23
+ raised && 'border-y border-border bg-card', className), children: _jsxs(Container, { width: width, children: [_jsx(SectionHeader, { id: id, title: title, eyebrow: eyebrow, intro: intro, headingLevel: headingLevel }), children] }) }));
24
+ }
25
+ //# sourceMappingURL=section.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section.js","sourceRoot":"","sources":["../../src/ui/section.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,KAAK,EAAuC,MAAM,OAAO,CAAC;AACnE,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAQlC,kGAAkG;AAClG,MAAM,UAAU,SAAS,CAAC,EAAE,QAAQ,EAAE,KAAK,GAAG,SAAS,EAAE,SAAS,EAAE,GAAG,KAAK,EAAkB;IAC5F,OAAO,CACL,iBACM,KAAK,EACT,SAAS,EAAE,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,gBAAgB,EAAE,SAAS,CAAC,YAExF,QAAQ,GACL,CACP,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,OAAO,CAAC,EAAE,QAAQ,EAAE,SAAS,EAA+C;IAC1F,OAAO,YAAG,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,YAAG,QAAQ,GAAK,CAAC;AAChE,CAAC;AAcD,8FAA8F;AAC9F,MAAM,UAAU,aAAa,CAAC,EAC5B,KAAK,EACL,OAAO,EACP,KAAK,EACL,EAAE,EACF,YAAY,GAAG,CAAC,EAChB,SAAS,GACU;IACnB,MAAM,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IACjD,OAAO,CACL,eAAK,SAAS,EAAE,EAAE,CAAC,cAAc,EAAE,SAAS,CAAC,aAC1C,OAAO,IAAI,KAAC,OAAO,cAAE,OAAO,GAAW,EACxC,KAAC,OAAO,IAAC,EAAE,EAAE,EAAE,EAAE,SAAS,EAAC,sBAAsB,YAC9C,KAAK,GACE,EACT,KAAK,IAAI,YAAG,SAAS,EAAC,iCAAiC,YAAE,KAAK,GAAK,IAChE,CACP,CAAC;AACJ,CAAC;AAwBD,uGAAuG;AACvG,MAAM,UAAU,OAAO,CAAC,EACtB,KAAK,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,YAAY,GAAG,CAAC,EAChB,SAAS,EACT,QAAQ,GAAG,KAAK,EAChB,MAAM,GAAG,KAAK,EACd,KAAK,GAAG,KAAK,EACb,KAAK,GAAG,SAAS,EACjB,SAAS,EACT,GAAG,KAAK,EACK;IACb,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,SAAS,IAAI,WAAW,CAAC;IACpC,OAAO,CACL,qBACM,KAAK,qBACQ,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAC1C,SAAS,EAAE,EAAE,CACX,KAAK,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,cAAc;QAC7C,uEAAuE;QACvE,MAAM,IAAI,gCAAgC,EAC1C,SAAS,CACV,YAED,MAAC,SAAS,IAAC,KAAK,EAAE,KAAK,aACrB,KAAC,aAAa,IACZ,EAAE,EAAE,EAAE,EACN,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,YAAY,GAC1B,EACD,QAAQ,IACC,GACJ,CACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { type ToggleButtonGroupProps, type ToggleButtonProps } from 'react-aria-components';
2
+ export interface SegmentedControlProps extends Omit<ToggleButtonGroupProps, 'className' | 'selectionMode'> {
3
+ /** Name the group: "Show projects". */
4
+ 'aria-label': string;
5
+ className?: string;
6
+ }
7
+ /** One of a few mutually exclusive views of the same content. Selected = border, ground and weight, never colour alone. */
8
+ export declare function SegmentedControl({ className, ...props }: SegmentedControlProps): import("react").JSX.Element;
9
+ /**
10
+ * A segment in three layers. The toggle button is the target (Layer 1): at least --target-min square. The
11
+ * painted segment inside it (Layer 2) is 4px shorter than the bar. At AAA the target is taller than the bar,
12
+ * so a negative block margin lets it reach past the bar's edges instead of making the bar taller.
13
+ */
14
+ export declare function Segment({ className, visualClassName, children, ...props }: Omit<ToggleButtonProps, 'className'> & {
15
+ className?: string;
16
+ visualClassName?: string;
17
+ }): import("react").JSX.Element;
18
+ //# sourceMappingURL=segmented-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmented-control.d.ts","sourceRoot":"","sources":["../../src/ui/segmented-control.tsx"],"names":[],"mappings":"AAEA,OAAO,EAIL,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAG/B,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,sBAAsB,EACtB,WAAW,GAAG,eAAe,CAC9B;IACC,uCAAuC;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2HAA2H;AAC3H,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,qBAAqB,+BAS9E;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,EACtB,SAAS,EACT,eAAe,EACf,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,+BAwBzF"}
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { composeRenderProps, ToggleButton, ToggleButtonGroup, } from 'react-aria-components';
4
+ import { cn } from '../lib/cn.js';
5
+ /** One of a few mutually exclusive views of the same content. Selected = border, ground and weight, never colour alone. */
6
+ export function SegmentedControl({ className, ...props }) {
7
+ return (_jsx(ToggleButtonGroup, { selectionMode: "single", disallowEmptySelection: true, ...props, className: cn('inline-flex gap-0.5 rounded-lg bg-muted p-0.5', className) }));
8
+ }
9
+ /**
10
+ * A segment in three layers. The toggle button is the target (Layer 1): at least --target-min square. The
11
+ * painted segment inside it (Layer 2) is 4px shorter than the bar. At AAA the target is taller than the bar,
12
+ * so a negative block margin lets it reach past the bar's edges instead of making the bar taller.
13
+ */
14
+ export function Segment({ className, visualClassName, children, ...props }) {
15
+ return (_jsx(ToggleButton, { ...props, className: cn('group/segment relative inline-flex min-h-target min-w-target cursor-pointer items-center justify-center outline-none data-disabled:cursor-not-allowed', 'my-[min(0px,calc((var(--control-height)-4px-var(--target-min))/2))]', className), children: composeRenderProps(children, (kids) => (_jsx("span", { className: cn('inline-flex h-[calc(var(--control-height)-4px)] w-full items-center justify-center rounded-md border border-transparent px-(--control-pad-x) text-sm font-medium whitespace-nowrap text-muted-foreground', 'group-data-hovered/segment:text-foreground group-data-focus-visible/segment:focus-ring', 'group-data-selected/segment:border-input group-data-selected/segment:bg-background group-data-selected/segment:font-bold group-data-selected/segment:text-foreground', visualClassName), children: kids }))) }));
16
+ }
17
+ //# sourceMappingURL=segmented-control.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmented-control.js","sourceRoot":"","sources":["../../src/ui/segmented-control.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,GAGlB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAWlC,2HAA2H;AAC3H,MAAM,UAAU,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,KAAK,EAAyB;IAC7E,OAAO,CACL,KAAC,iBAAiB,IAChB,aAAa,EAAC,QAAQ,EACtB,sBAAsB,WAClB,KAAK,EACT,SAAS,EAAE,EAAE,CAAC,+CAA+C,EAAE,SAAS,CAAC,GACzE,CACH,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,EACtB,SAAS,EACT,eAAe,EACf,QAAQ,EACR,GAAG,KAAK,EACgF;IACxF,OAAO,CACL,KAAC,YAAY,OACP,KAAK,EACT,SAAS,EAAE,EAAE,CACX,uJAAuJ,EACvJ,qEAAqE,EACrE,SAAS,CACV,YAEA,kBAAkB,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CACtC,eACE,SAAS,EAAE,EAAE,CACX,0MAA0M,EAC1M,wFAAwF,EACxF,sKAAsK,EACtK,eAAe,CAChB,YAEA,IAAI,GACA,CACR,CAAC,GACW,CAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from 'react';
2
+ import { type Key, type SelectProps as RACSelectProps } from 'react-aria-components';
3
+ import { type FieldWidth } from './field.js';
4
+ export interface SelectProps<T extends object> extends Omit<RACSelectProps<T>, 'className' | 'children' | 'validate'> {
5
+ label: string;
6
+ description?: ReactNode;
7
+ errorMessage?: string;
8
+ /** Default "Choose <label>". */
9
+ requiredMessage?: string;
10
+ validate?: (value: Key | null) => string | string[] | true | null | undefined;
11
+ items?: Iterable<T>;
12
+ children: ReactNode | ((item: T) => ReactNode);
13
+ width?: FieldWidth;
14
+ className?: string;
15
+ }
16
+ /** Choose one of a known, short list (about 5–15). Longer or searchable lists are a ComboBox. */
17
+ export declare function Select<T extends object>({ label, description, errorMessage, requiredMessage, validate, items, children, width, placeholder, className, ...props }: SelectProps<T>): import("react").JSX.Element;
18
+ //# sourceMappingURL=select.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../src/ui/select.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAIL,KAAK,GAAG,EACR,KAAK,WAAW,IAAI,cAAc,EACnC,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAQL,KAAK,UAAU,EAChB,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,WAAW,CAAC,CAAC,SAAS,MAAM,CAAE,SAAQ,IAAI,CACzD,cAAc,CAAC,CAAC,CAAC,EACjB,WAAW,GAAG,UAAU,GAAG,UAAU,CACtC;IACC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,GAAG,IAAI,KAAK,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IAC9E,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpB,QAAQ,EAAE,SAAS,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC;IAC/C,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,iGAAiG;AACjG,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,EACvC,KAAK,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,KAAY,EACZ,WAAuB,EACvB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,WAAW,CAAC,CAAC,CAAC,+BAmChB"}
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Button, Select as RACSelect, SelectValue, } from 'react-aria-components';
4
+ import { ChevronDown } from 'lucide-react';
5
+ import { cn } from '../lib/cn.js';
6
+ import { FieldDescription, FieldError, FieldLabel, fieldStack, fieldWidths, lcFirst, withRequired, } from './field.js';
7
+ import { ListBox } from './list-box.js';
8
+ import { Popover } from './menu.js';
9
+ /** Choose one of a known, short list (about 5–15). Longer or searchable lists are a ComboBox. */
10
+ export function Select({ label, description, errorMessage, requiredMessage, validate, items, children, width = 'md', placeholder = 'Choose…', className, ...props }) {
11
+ return (_jsxs(RACSelect, { ...props, placeholder: placeholder, validate: withRequired(props.isRequired, requiredMessage ?? `Choose ${lcFirst(label)}`, (v) => v == null, validate), className: cn(fieldStack, fieldWidths[width], className), children: [_jsx(FieldLabel, { isRequired: props.isRequired, children: label }), description && _jsx(FieldDescription, { children: description }), _jsx(FieldError, { requiredMessage: requiredMessage ?? `Choose ${lcFirst(label)}`, children: errorMessage }), _jsxs(Button, { className: cn('field-paint flex h-control-target w-full min-w-0 cursor-pointer items-center gap-2 px-(--control-pad-x) text-left text-sm text-foreground outline-none data-disabled:cursor-not-allowed', 'data-focus-visible:before:focus-ring data-pressed:before:bg-accent group-data-invalid/field:before:border-destructive group-data-invalid/field:before:shadow-[inset_0_0_0_1px_var(--destructive)] data-disabled:opacity-60'), children: [_jsx(SelectValue, { className: "min-w-0 flex-1 truncate data-placeholder:text-muted-foreground" }), _jsx(ChevronDown, { "aria-hidden": "true", className: "size-4 shrink-0 text-muted-foreground" })] }), _jsx(Popover, { placement: "bottom start", className: "max-h-80", children: _jsx(ListBox, { items: items, children: children }) })] }));
12
+ }
13
+ //# sourceMappingURL=select.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../../src/ui/select.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EACL,MAAM,EACN,MAAM,IAAI,SAAS,EACnB,WAAW,GAGZ,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EACL,gBAAgB,EAChB,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,OAAO,EACP,YAAY,GAEb,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC,iGAAiG;AACjG,MAAM,UAAU,MAAM,CAAmB,EACvC,KAAK,EACL,WAAW,EACX,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,KAAK,GAAG,IAAI,EACZ,WAAW,GAAG,SAAS,EACvB,SAAS,EACT,GAAG,KAAK,EACO;IACf,OAAO,CACL,MAAC,SAAS,OACH,KAA2B,EAChC,WAAW,EAAE,WAAW,EACxB,QAAQ,EACN,YAAY,CACV,KAAK,CAAC,UAAU,EAChB,eAAe,IAAI,UAAU,OAAO,CAAC,KAAK,CAAC,EAAE,EAC7C,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,EAChB,QAAQ,CACA,EAEZ,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,aAExD,KAAC,UAAU,IAAC,UAAU,EAAE,KAAK,CAAC,UAAU,YAAG,KAAK,GAAc,EAC7D,WAAW,IAAI,KAAC,gBAAgB,cAAE,WAAW,GAAoB,EAClE,KAAC,UAAU,IAAC,eAAe,EAAE,eAAe,IAAI,UAAU,OAAO,CAAC,KAAK,CAAC,EAAE,YACvE,YAAY,GACF,EAEb,MAAC,MAAM,IACL,SAAS,EAAE,EAAE,CACX,yLAAyL,EACzL,4NAA4N,CAC7N,aAED,KAAC,WAAW,IAAC,SAAS,EAAC,gEAAgE,GAAG,EAC1F,KAAC,WAAW,mBAAa,MAAM,EAAC,SAAS,EAAC,uCAAuC,GAAG,IAC7E,EACT,KAAC,OAAO,IAAC,SAAS,EAAC,cAAc,EAAC,SAAS,EAAC,UAAU,YACpD,KAAC,OAAO,IAAC,KAAK,EAAE,KAAK,YAAG,QAAiB,GAAW,GAC5C,IACA,CACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,28 @@
1
+ import { type ReactNode } from 'react';
2
+ export interface SelectionBarProps {
3
+ /** How many are selected. "all" when the whole collection is selected (React Aria's `'all'`). */
4
+ count: number | 'all';
5
+ /** Items in the collection, for "All 12 projects selected" and "Select all 12 projects". */
6
+ total?: number;
7
+ /** Singular and plural nouns: ['project', 'projects']. */
8
+ noun: [string, string];
9
+ onClear: () => void;
10
+ /**
11
+ * Shows "Select all <total> <nouns>" while not everything is selected. A GridList has no header checkbox,
12
+ * so give it this; a Table's header checkbox already does the job.
13
+ */
14
+ onSelectAll?: () => void;
15
+ /** Actions for the selection, shown while something is selected. */
16
+ children?: ReactNode;
17
+ className?: string;
18
+ }
19
+ /**
20
+ * The count and bulk actions for a multi-select Table or GridList. The count is a live region that is always
21
+ * in the page, so each change is announced ("3 projects selected") without moving focus.
22
+ *
23
+ * Buttons that take themselves away hand focus on: after "Select all", to "Clear selection"; after "Clear
24
+ * selection", to "Select all" if there is one, otherwise to the next focusable thing after the bar — so put the
25
+ * bar directly above its table or list.
26
+ */
27
+ export declare function SelectionBar({ count, total, noun, onClear, onSelectAll, children, className, }: SelectionBarProps): import("react").JSX.Element;
28
+ //# sourceMappingURL=selection-bar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-bar.d.ts","sourceRoot":"","sources":["../../src/ui/selection-bar.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAK/C,MAAM,WAAW,iBAAiB;IAChC,iGAAiG;IACjG,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC;IACtB,4FAA4F;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,oEAAoE;IACpE,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,EAC3B,KAAK,EACL,KAAK,EACL,IAAI,EACJ,OAAO,EACP,WAAW,EACX,QAAQ,EACR,SAAS,GACV,EAAE,iBAAiB,+BA+DnB"}