@rinzai/zen 0.11.0 → 0.14.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 (289) hide show
  1. package/README.md +37 -7
  2. package/dist/accordion/index.d.ts +41 -0
  3. package/dist/accordion/index.d.ts.map +1 -0
  4. package/dist/accordion/index.js +81 -0
  5. package/dist/animated-number/index.d.ts +3 -2
  6. package/dist/animated-number/index.d.ts.map +1 -1
  7. package/dist/animated-number/index.js +40 -38
  8. package/dist/avatar/index.d.ts +7 -2
  9. package/dist/avatar/index.d.ts.map +1 -1
  10. package/dist/avatar/index.js +17 -11
  11. package/dist/backdrop/index.d.ts +4 -4
  12. package/dist/backdrop/index.d.ts.map +1 -1
  13. package/dist/backdrop/index.js +41 -39
  14. package/dist/badge/index.d.ts +4 -2
  15. package/dist/badge/index.d.ts.map +1 -1
  16. package/dist/badge/index.js +20 -11
  17. package/dist/base.css +4 -0
  18. package/dist/breadcrumbs/index.d.ts +1 -1
  19. package/dist/breadcrumbs/index.d.ts.map +1 -1
  20. package/dist/breadcrumbs/index.js +25 -24
  21. package/dist/button/index.d.ts +3 -3
  22. package/dist/button/index.d.ts.map +1 -1
  23. package/dist/button/index.js +16 -11
  24. package/dist/button-group/index.d.ts +13 -0
  25. package/dist/button-group/index.d.ts.map +1 -0
  26. package/dist/button-group/index.js +14 -0
  27. package/dist/calendar/index.d.ts +15 -8
  28. package/dist/calendar/index.d.ts.map +1 -1
  29. package/dist/calendar/index.js +97 -91
  30. package/dist/calendar-heatmap/index.d.ts +7 -5
  31. package/dist/calendar-heatmap/index.d.ts.map +1 -1
  32. package/dist/calendar-heatmap/index.js +32 -30
  33. package/dist/canvas/geometry.js +0 -1
  34. package/dist/canvas/index.d.ts +6 -6
  35. package/dist/canvas/index.d.ts.map +1 -1
  36. package/dist/canvas/index.js +135 -133
  37. package/dist/carousel/index.d.ts +27 -0
  38. package/dist/carousel/index.d.ts.map +1 -0
  39. package/dist/carousel/index.js +162 -0
  40. package/dist/chart/index.d.ts +5 -4
  41. package/dist/chart/index.d.ts.map +1 -1
  42. package/dist/chart/index.js +137 -135
  43. package/dist/chart/palette.js +0 -1
  44. package/dist/checkbox/index.d.ts +3 -3
  45. package/dist/checkbox/index.d.ts.map +1 -1
  46. package/dist/checkbox/index.js +33 -30
  47. package/dist/chip/index.js +1 -1
  48. package/dist/code-block/index.d.ts.map +1 -1
  49. package/dist/code-block/index.js +27 -25
  50. package/dist/code-input/index.d.ts.map +1 -1
  51. package/dist/code-input/index.js +30 -24
  52. package/dist/collapse/index.d.ts +4 -3
  53. package/dist/collapse/index.d.ts.map +1 -1
  54. package/dist/collapse/index.js +42 -39
  55. package/dist/color-picker/index.d.ts +14 -7
  56. package/dist/color-picker/index.d.ts.map +1 -1
  57. package/dist/color-picker/index.js +139 -128
  58. package/dist/combobox/index.d.ts +14 -6
  59. package/dist/combobox/index.d.ts.map +1 -1
  60. package/dist/combobox/index.js +158 -146
  61. package/dist/command-palette/index.d.ts +4 -3
  62. package/dist/command-palette/index.d.ts.map +1 -1
  63. package/dist/command-palette/index.js +60 -57
  64. package/dist/confirm-dialog/index.d.ts +6 -7
  65. package/dist/confirm-dialog/index.d.ts.map +1 -1
  66. package/dist/confirm-dialog/index.js +20 -16
  67. package/dist/date-picker/index.d.ts +23 -14
  68. package/dist/date-picker/index.d.ts.map +1 -1
  69. package/dist/date-picker/index.js +109 -93
  70. package/dist/dialog/index.d.ts +3 -4
  71. package/dist/dialog/index.d.ts.map +1 -1
  72. package/dist/dialog/index.js +58 -55
  73. package/dist/disclosure/index.d.ts +8 -0
  74. package/dist/disclosure/index.d.ts.map +1 -1
  75. package/dist/disclosure/index.js +31 -32
  76. package/dist/editable-cell/index.d.ts +4 -5
  77. package/dist/editable-cell/index.d.ts.map +1 -1
  78. package/dist/editable-cell/index.js +23 -22
  79. package/dist/field/index.d.ts +8 -8
  80. package/dist/field/index.d.ts.map +1 -1
  81. package/dist/field/index.js +20 -18
  82. package/dist/filter-bar/index.d.ts +2 -2
  83. package/dist/filter-bar/index.d.ts.map +1 -1
  84. package/dist/filter-bar/index.js +38 -36
  85. package/dist/header/index.d.ts +1 -1
  86. package/dist/header/index.d.ts.map +1 -1
  87. package/dist/header/index.js +13 -11
  88. package/dist/hover-card/index.d.ts +32 -0
  89. package/dist/hover-card/index.d.ts.map +1 -0
  90. package/dist/hover-card/index.js +84 -0
  91. package/dist/icon-picker/index.d.ts +16 -5
  92. package/dist/icon-picker/index.d.ts.map +1 -1
  93. package/dist/icon-picker/index.js +42 -47
  94. package/dist/icons/micro/plus.d.ts +3 -0
  95. package/dist/icons/micro/plus.d.ts.map +1 -0
  96. package/dist/icons/micro/plus.js +17 -0
  97. package/dist/index.d.ts +37 -24
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/input/index.d.ts +5 -1
  100. package/dist/input/index.d.ts.map +1 -1
  101. package/dist/input/index.js +9 -9
  102. package/dist/input-group/index.d.ts +4 -1
  103. package/dist/input-group/index.d.ts.map +1 -1
  104. package/dist/input-group/index.js +14 -14
  105. package/dist/keypad/index.d.ts +9 -7
  106. package/dist/keypad/index.d.ts.map +1 -1
  107. package/dist/keypad/index.js +22 -19
  108. package/dist/lib.js +112 -97
  109. package/dist/load-more/index.d.ts +4 -2
  110. package/dist/load-more/index.d.ts.map +1 -1
  111. package/dist/load-more/index.js +26 -23
  112. package/dist/locale-provider/index.d.ts +23 -0
  113. package/dist/locale-provider/index.d.ts.map +1 -0
  114. package/dist/locale-provider/index.js +35 -0
  115. package/dist/menu/index.d.ts +62 -9
  116. package/dist/menu/index.d.ts.map +1 -1
  117. package/dist/menu/index.js +371 -128
  118. package/dist/meter/index.d.ts +2 -2
  119. package/dist/meter/index.d.ts.map +1 -1
  120. package/dist/meter/index.js +4 -4
  121. package/dist/money-input/index.d.ts +20 -10
  122. package/dist/money-input/index.d.ts.map +1 -1
  123. package/dist/money-input/index.js +199 -190
  124. package/dist/month-picker/index.d.ts +17 -10
  125. package/dist/month-picker/index.d.ts.map +1 -1
  126. package/dist/month-picker/index.js +97 -86
  127. package/dist/navigation-menu/index.d.ts +42 -0
  128. package/dist/navigation-menu/index.d.ts.map +1 -0
  129. package/dist/navigation-menu/index.js +144 -0
  130. package/dist/number-field/index.d.ts +50 -0
  131. package/dist/number-field/index.d.ts.map +1 -0
  132. package/dist/number-field/index.js +133 -0
  133. package/dist/page-header/index.d.ts +4 -3
  134. package/dist/page-header/index.d.ts.map +1 -1
  135. package/dist/page-header/index.js +2 -1
  136. package/dist/pagination/index.d.ts +1 -1
  137. package/dist/pagination/index.d.ts.map +1 -1
  138. package/dist/pagination/index.js +35 -33
  139. package/dist/progress-ring/index.d.ts +4 -3
  140. package/dist/progress-ring/index.d.ts.map +1 -1
  141. package/dist/progress-ring/index.js +11 -10
  142. package/dist/radio-cards/index.d.ts +9 -5
  143. package/dist/radio-cards/index.d.ts.map +1 -1
  144. package/dist/radio-cards/index.js +26 -24
  145. package/dist/radio-group/index.d.ts +9 -8
  146. package/dist/radio-group/index.d.ts.map +1 -1
  147. package/dist/radio-group/index.js +35 -34
  148. package/dist/range-slider/index.d.ts +10 -4
  149. package/dist/range-slider/index.d.ts.map +1 -1
  150. package/dist/range-slider/index.js +43 -31
  151. package/dist/repeat-picker/index.d.ts +13 -6
  152. package/dist/repeat-picker/index.d.ts.map +1 -1
  153. package/dist/repeat-picker/index.js +73 -61
  154. package/dist/resizable/index.d.ts +29 -0
  155. package/dist/resizable/index.d.ts.map +1 -0
  156. package/dist/resizable/index.js +135 -0
  157. package/dist/segmented/index.d.ts +8 -5
  158. package/dist/segmented/index.d.ts.map +1 -1
  159. package/dist/segmented/index.js +36 -34
  160. package/dist/select/index.d.ts +9 -3
  161. package/dist/select/index.d.ts.map +1 -1
  162. package/dist/select/index.js +99 -96
  163. package/dist/separator/index.d.ts +14 -0
  164. package/dist/separator/index.d.ts.map +1 -0
  165. package/dist/separator/index.js +15 -0
  166. package/dist/side-nav/index.js +1 -1
  167. package/dist/skeleton/index.d.ts +4 -4
  168. package/dist/skeleton/index.d.ts.map +1 -1
  169. package/dist/skeleton/index.js +4 -3
  170. package/dist/slider/index.d.ts +6 -3
  171. package/dist/slider/index.d.ts.map +1 -1
  172. package/dist/slider/index.js +29 -23
  173. package/dist/sortable/index.d.ts +10 -20
  174. package/dist/sortable/index.d.ts.map +1 -1
  175. package/dist/sortable/index.js +72 -134
  176. package/dist/sortable/shared.d.ts +56 -0
  177. package/dist/sortable/shared.d.ts.map +1 -0
  178. package/dist/sortable/shared.js +104 -0
  179. package/dist/sortable/tree-model.d.ts +46 -0
  180. package/dist/sortable/tree-model.d.ts.map +1 -0
  181. package/dist/sortable/tree-model.js +87 -0
  182. package/dist/sortable/tree.d.ts +31 -0
  183. package/dist/sortable/tree.d.ts.map +1 -0
  184. package/dist/sortable/tree.js +150 -0
  185. package/dist/sparkline/index.d.ts +1 -1
  186. package/dist/sparkline/index.d.ts.map +1 -1
  187. package/dist/sparkline/index.js +26 -25
  188. package/dist/spinner/index.d.ts +4 -3
  189. package/dist/spinner/index.d.ts.map +1 -1
  190. package/dist/spinner/index.js +2 -1
  191. package/dist/status-pill/index.d.ts.map +1 -1
  192. package/dist/status-pill/index.js +1 -1
  193. package/dist/stepper/index.d.ts +1 -1
  194. package/dist/stepper/index.d.ts.map +1 -1
  195. package/dist/stepper/index.js +31 -30
  196. package/dist/tab-bar/index.js +1 -1
  197. package/dist/table/index.d.ts +5 -5
  198. package/dist/table/index.d.ts.map +1 -1
  199. package/dist/table/index.js +66 -64
  200. package/dist/table/selection.d.ts +2 -2
  201. package/dist/table/selection.d.ts.map +1 -1
  202. package/dist/table/selection.js +41 -38
  203. package/dist/table/swipe.d.ts +1 -1
  204. package/dist/table/swipe.d.ts.map +1 -1
  205. package/dist/table/swipe.js +1 -1
  206. package/dist/table-of-contents/index.d.ts +4 -2
  207. package/dist/table-of-contents/index.d.ts.map +1 -1
  208. package/dist/table-of-contents/index.js +27 -25
  209. package/dist/tabs/index.d.ts.map +1 -1
  210. package/dist/tabs/index.js +90 -88
  211. package/dist/tag-input/index.d.ts +3 -1
  212. package/dist/tag-input/index.d.ts.map +1 -1
  213. package/dist/tag-input/index.js +61 -52
  214. package/dist/theme-toggle/index.d.ts +9 -8
  215. package/dist/theme-toggle/index.d.ts.map +1 -1
  216. package/dist/theme-toggle/index.js +30 -28
  217. package/dist/theme.css +90 -12
  218. package/dist/time-field/index.d.ts +31 -0
  219. package/dist/time-field/index.d.ts.map +1 -0
  220. package/dist/time-field/index.js +175 -0
  221. package/dist/timeline/index.js +1 -1
  222. package/dist/toast/index.d.ts +1 -1
  223. package/dist/toast/index.d.ts.map +1 -1
  224. package/dist/toast/index.js +127 -125
  225. package/dist/toggle/index.d.ts +2 -2
  226. package/dist/toggle/index.d.ts.map +1 -1
  227. package/dist/toggle/index.js +8 -6
  228. package/dist/toggle-group/index.d.ts +35 -0
  229. package/dist/toggle-group/index.d.ts.map +1 -0
  230. package/dist/toggle-group/index.js +53 -0
  231. package/dist/toolbar/index.d.ts +19 -0
  232. package/dist/toolbar/index.d.ts.map +1 -0
  233. package/dist/toolbar/index.js +36 -0
  234. package/dist/tooltip/index.d.ts.map +1 -1
  235. package/dist/tooltip/index.js +40 -74
  236. package/dist/tree/index.d.ts.map +1 -1
  237. package/dist/tree/index.js +105 -102
  238. package/dist/trend/index.d.ts +2 -2
  239. package/dist/trend/index.d.ts.map +1 -1
  240. package/dist/trend/index.js +20 -19
  241. package/dist/utils/color.js +0 -1
  242. package/dist/utils/cva.js +0 -1
  243. package/dist/utils/cx.js +0 -1
  244. package/dist/utils/date.d.ts +6 -0
  245. package/dist/utils/date.d.ts.map +1 -1
  246. package/dist/utils/date.js +1 -2
  247. package/dist/utils/direction.d.ts +7 -0
  248. package/dist/utils/direction.d.ts.map +1 -0
  249. package/dist/utils/direction.js +6 -0
  250. package/dist/utils/form-value.d.ts +15 -0
  251. package/dist/utils/form-value.d.ts.map +1 -0
  252. package/dist/utils/form-value.js +29 -0
  253. package/dist/utils/fx.js +0 -1
  254. package/dist/utils/merge.js +0 -1
  255. package/dist/utils/messages.d.ts +137 -0
  256. package/dist/utils/messages.d.ts.map +1 -0
  257. package/dist/utils/messages.js +133 -0
  258. package/dist/utils/money.js +0 -1
  259. package/dist/utils/month.js +0 -1
  260. package/dist/utils/motion.js +0 -1
  261. package/dist/utils/refs.d.ts +6 -0
  262. package/dist/utils/refs.d.ts.map +1 -0
  263. package/dist/utils/refs.js +13 -0
  264. package/dist/utils/repeat.d.ts +3 -1
  265. package/dist/utils/repeat.d.ts.map +1 -1
  266. package/dist/utils/repeat.js +28 -25
  267. package/dist/utils/roving.d.ts +17 -0
  268. package/dist/utils/roving.d.ts.map +1 -0
  269. package/dist/utils/roving.js +35 -0
  270. package/dist/utils/section-link.js +0 -1
  271. package/dist/utils/slot.d.ts.map +1 -1
  272. package/dist/utils/slot.js +7 -11
  273. package/dist/utils/status-icons.js +7 -7
  274. package/dist/utils/styles.d.ts +9 -2
  275. package/dist/utils/styles.d.ts.map +1 -1
  276. package/dist/utils/styles.js +6 -3
  277. package/dist/utils/theme-wave.js +0 -1
  278. package/dist/utils/theme.js +0 -1
  279. package/dist/utils/useAnchoredPopup.d.ts +7 -4
  280. package/dist/utils/useAnchoredPopup.d.ts.map +1 -1
  281. package/dist/utils/useAnchoredPopup.js +18 -11
  282. package/dist/utils/useControllable.d.ts +9 -0
  283. package/dist/utils/useControllable.d.ts.map +1 -0
  284. package/dist/utils/useControllable.js +15 -0
  285. package/dist/utils/useHoverPopup.d.ts +39 -0
  286. package/dist/utils/useHoverPopup.d.ts.map +1 -0
  287. package/dist/utils/useHoverPopup.js +64 -0
  288. package/dist/zen.css +1 -1
  289. package/package.json +1 -1
package/README.md CHANGED
@@ -40,13 +40,16 @@ The look is set in [Geist](https://vercel.com/font); load it however you like.
40
40
  ## Usage
41
41
 
42
42
  ```tsx
43
- import { Backdrop, Button, Card } from '@rinzai/zen';
43
+ import { Backdrop, Button, Card, CardHeader, CardTitle } from '@rinzai/zen';
44
44
 
45
45
  export default function App() {
46
46
  return (
47
47
  <>
48
48
  <Backdrop />
49
- <Card title="Budget">
49
+ <Card>
50
+ <CardHeader>
51
+ <CardTitle>Budget</CardTitle>
52
+ </CardHeader>
50
53
  <Button>Save changes</Button>
51
54
  </Card>
52
55
  </>
@@ -56,14 +59,31 @@ export default function App() {
56
59
 
57
60
  ## What's inside
58
61
 
59
- - **Surfaces:** Card, Inset, Alert, Stat, Dialog (and sheets from an edge), ConfirmDialog, Popover, Tooltip, Toast (a stacked deck), Disclosure, Backdrop (aurora, contours or dots, and a pointer light)
60
- - **Inputs:** Button, Input, TextArea, InputGroup, MoneyInput (with currency conversion), Select, Combobox, Calendar, DatePicker, DateRangePicker, MonthPicker, ColorPicker, Checkbox, RadioGroup, RadioCards, Segmented, Slider, Toggle, Chip, Field
61
- - **Data:** Chart (areas, lines, bars) and DonutChart in plain SVG, composable Table with sticky edges and sorting, tree rows, editable cells, virtual rows, Meter, ProgressRing, AnimatedNumber, Badge, StatusPill (a live save status), Skeleton, Spinner, Canvas (items placed freely, with snapping)
62
- - **Navigation:** Header, Pills, Tabs, TabBar, SideNav, TableOfContents, Menu
62
+ - **Surfaces:** Card, Inset, Alert, Stat, Dialog (and sheets from an edge), ConfirmDialog, Popover, Tooltip, HoverCard, Toast (a stacked deck), Disclosure, Accordion, Separator, Resizable panels, Carousel, Backdrop (aurora, contours or dots, and a pointer light)
63
+ - **Inputs:** Button, ButtonGroup, Toggle, ToggleGroup, Toolbar, Input, TextArea, InputGroup, NumberField, TimeField, MoneyInput (with currency conversion), Select, Combobox, Calendar, DatePicker, DateRangePicker, MonthPicker, ColorPicker, Checkbox, RadioGroup, RadioCards, Segmented, Slider, Chip, Field
64
+ - **Data:** Chart (areas, lines, bars) and DonutChart in plain SVG, composable Table with sticky edges, sorting and rows reordered by drag and drop, tree rows, editable cells, virtual rows, SortableList and SortableTree, Meter, ProgressRing, AnimatedNumber, Badge, StatusPill (a live save status), Skeleton, Spinner, Canvas (items placed freely, with snapping)
65
+ - **Navigation:** Header, NavigationMenu, Pills, Tabs, TabBar, SideNav, TableOfContents, Menu (with submenus, checkbox and radio items, and context menus), Menubar
63
66
  - **Theming:** dark and light, OKLCH tokens, and a theme generator (presets or any hue) that keeps contrast readable
67
+ - **Languages:** LocaleProvider for the locale and every word, and right-to-left layout
64
68
  - **Hooks and utilities:** `themeWave` (the theme spreads from the switch like a drop falling into water: ripples, glints and a rainbow edge, drawn on the GPU; `prepareThemeWave` readies it when the pointer reaches your own switch), `useAnchoredPopup`, `useVirtualList`, `useTree`, `useSort`, `useCopyToClipboard`, money, currency, month and date helpers, `hexToOklch` and `oklchToHex`, `cx` (Tailwind-aware class merging), `cva`
65
69
 
66
- Every component takes `className`, and a class you pass always overrides the component's default.
70
+ Every component takes `className`, and a class you pass always overrides the component's default. Other props (`id`, `aria-*`, `data-*`, handlers) and `ref` reach its element, and parts that render a link or button take `asChild` to use your own (a router's Link, say).
71
+
72
+ ## Values and forms
73
+
74
+ Controls report changes with `onValueChange` (`onCheckedChange` for Checkbox and Toggle). Pass `value` to control one, or `defaultValue` to let it keep its own. Give a control a `name` and it's submitted with its form, the custom ones (Combobox, the date pickers, MoneyInput, ColorPicker, TagInput…) included, and goes back to its first value when the form is reset.
75
+
76
+ ## Languages and right to left
77
+
78
+ ```tsx
79
+ import { LocaleProvider } from '@rinzai/zen';
80
+
81
+ <LocaleProvider locale="fr-FR" messages={{ clear: 'Effacer', noResults: 'Aucun résultat' }}>
82
+ <App />
83
+ </LocaleProvider>;
84
+ ```
85
+
86
+ The locale formats dates, numbers and money, and sets the week's first day. `messages` replaces any of the words Zen shows or announces (`ENGLISH` lists them all); the rest stay English. With `dir="rtl"` on the page or any element above, layout, arrow keys and chevrons mirror.
67
87
 
68
88
  ## Theming
69
89
 
@@ -84,6 +104,16 @@ import { applyPreset, applyTheme, DEFAULT_THEME } from '@rinzai/zen';
84
104
  applyTheme(applyPreset(DEFAULT_THEME, 'ocean'));
85
105
  ```
86
106
 
107
+ ## Overlays
108
+
109
+ For a page composited over something else, such as an OBS browser source, which never gets a pointer:
110
+
111
+ ```html
112
+ <html data-zen-glow="ambient" data-zen-page="transparent"></html>
113
+ ```
114
+
115
+ `data-zen-glow="ambient"` sends the edge light round each glowing border by itself (on any element, it does so for what's inside). `data-zen-page="transparent"` paints nothing behind the content; it needs the base stylesheet.
116
+
87
117
  ## Browser support
88
118
 
89
119
  Chrome and Edge 114+, Safari 17+ and Firefox 128+: the versions with the native Popover API that popups, menus and toasts are built on, and with what Tailwind v4 needs.
@@ -0,0 +1,41 @@
1
+ import { ComponentProps, ReactNode } from 'react';
2
+ /**
3
+ * Sections under headings that open one at a time (or several, with
4
+ * `multiple`), e.g. questions and answers. Each AccordionItem is a Disclosure:
5
+ * an AccordionTrigger and an AccordionContent that grows open and folds shut.
6
+ * ↑↓ move between the headings, Home and End jump to the first and last.
7
+ */
8
+ export default function Accordion(props: AccordionProps): import('react').JSX.Element;
9
+ /** One section: an AccordionTrigger and its AccordionContent. */
10
+ export declare function AccordionItem({ value, className, ...rest }: AccordionItemProps): import('react').JSX.Element;
11
+ /** The heading and its button: your label, and a chevron that turns over while open. */
12
+ export declare function AccordionTrigger({ level, className, onClick, children, ...rest }: AccordionTriggerProps): import('react').JSX.Element;
13
+ /** What the trigger shows and hides; only in the page while open (or folding shut). */
14
+ export declare function AccordionContent({ className, ...rest }: ComponentProps<'div'>): import('react').JSX.Element;
15
+ interface AccordionBaseProps extends Omit<ComponentProps<'div'>, 'defaultValue'> {
16
+ children?: ReactNode;
17
+ }
18
+ export type AccordionProps = AccordionBaseProps & ({
19
+ /** One section open at a time (the default); opening one closes the other. */
20
+ multiple?: false;
21
+ /** The open section's value, or null for none, when you keep it. */
22
+ value?: string | null;
23
+ defaultValue?: string | null;
24
+ onValueChange?: (value: string | null) => void;
25
+ } | {
26
+ /** Any number open at once. */
27
+ multiple: true;
28
+ value?: readonly string[];
29
+ defaultValue?: readonly string[];
30
+ onValueChange?: (value: readonly string[]) => void;
31
+ });
32
+ export interface AccordionItemProps extends ComponentProps<'div'> {
33
+ /** Names the section in the Accordion's value. */
34
+ value: string;
35
+ }
36
+ export interface AccordionTriggerProps extends ComponentProps<'button'> {
37
+ /** The heading level it sits in, to fit the page's outline. Default 3. */
38
+ level?: 2 | 3 | 4 | 5 | 6;
39
+ }
40
+ export {};
41
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/accordion/index.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAgC,SAAS,EAAc,MAAM,OAAO,CAAC;AAe5F;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,KAAK,EAAE,cAAc,+BAwCtD;AAED,iEAAiE;AACjE,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,kBAAkB,+BAQ9E;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,EAAE,KAAS,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,qBAAqB,+BAwB3G;AAED,uFAAuF;AACvF,wBAAgB,gBAAgB,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,cAAc,CAAC,KAAK,CAAC,+BAE7E;AAED,UAAU,kBAAmB,SAAQ,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,cAAc,CAAC;IAC5E,QAAQ,CAAC,EAAE,SAAS,CAAC;CACxB;AAED,MAAM,MAAM,cAAc,GAAG,kBAAkB,GAC3C,CACM;IACI,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,KAAK,CAAC;IACjB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CAClD,GACD;IACI,+BAA+B;IAC/B,QAAQ,EAAE,IAAI,CAAC;IACf,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;CACtD,CACN,CAAC;AAEN,MAAM,WAAW,kBAAmB,SAAQ,cAAc,CAAC,KAAK,CAAC;IAC7D,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAsB,SAAQ,cAAc,CAAC,QAAQ,CAAC;IACnE,0EAA0E;IAC1E,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;CAC7B"}
@@ -0,0 +1,81 @@
1
+ "use client";
2
+ import { cx as e } from "../utils/cx.js";
3
+ import { useControllable as t } from "../utils/useControllable.js";
4
+ import { FieldChevron as n } from "../utils/field-chevron.js";
5
+ import r, { DisclosureContent as i, useDisclosure as a } from "../disclosure/index.js";
6
+ import { createContext as o, useContext as s } from "react";
7
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
8
+ //#region packages/accordion/index.tsx
9
+ var u = o(null);
10
+ function d(e) {
11
+ let t = s(u);
12
+ if (!t) throw Error(`<${e}> must be inside <Accordion>`);
13
+ return t;
14
+ }
15
+ function f(n) {
16
+ let { multiple: r, value: i, defaultValue: a, onValueChange: o, className: s, onKeyDown: l, ...d } = n, [f, p] = t(i, a ?? (r ? [] : null), o), m = typeof f == "string" ? [f] : f ?? [], h = {
17
+ isOpen: (e) => m.includes(e),
18
+ setOpen: (e, t) => {
19
+ p(r ? t ? [...m, e] : m.filter((t) => t !== e) : t ? e : null);
20
+ }
21
+ }, g = (e) => {
22
+ l?.(e);
23
+ let t = e.currentTarget, n = [...t.querySelectorAll(".zen__accordion-trigger:not(:disabled)")].filter((e) => e.closest(".zen__accordion") === t), r = n.indexOf(e.target);
24
+ if (r === -1) return;
25
+ let i = {
26
+ ArrowDown: r + 1,
27
+ ArrowUp: r - 1,
28
+ Home: 0,
29
+ End: n.length - 1
30
+ }[e.key];
31
+ i !== void 0 && (e.preventDefault(), n[(i + n.length) % n.length].focus());
32
+ };
33
+ return /* @__PURE__ */ c(u.Provider, {
34
+ value: h,
35
+ children: /* @__PURE__ */ c("div", {
36
+ ...d,
37
+ onKeyDown: g,
38
+ className: e("zen__accordion divide-tint/[0.07] flex flex-col divide-y", s)
39
+ })
40
+ });
41
+ }
42
+ function p({ value: t, className: n, ...i }) {
43
+ let a = d("AccordionItem"), o = a.isOpen(t);
44
+ return /* @__PURE__ */ c(r, {
45
+ open: o,
46
+ onOpenChange: (e) => a.setOpen(t, e),
47
+ children: /* @__PURE__ */ c("div", {
48
+ "data-open": o || void 0,
49
+ className: e("zen__accordion-item", n),
50
+ ...i
51
+ })
52
+ });
53
+ }
54
+ function m({ level: t = 3, className: r, onClick: i, children: o, ...s }) {
55
+ let { open: u, setOpen: d, contentId: f } = a("AccordionTrigger"), p = `h${t}`;
56
+ return /* @__PURE__ */ c(p, {
57
+ className: "m-0! font-[inherit] text-[length:inherit]",
58
+ children: /* @__PURE__ */ l("button", {
59
+ type: "button",
60
+ "aria-expanded": u,
61
+ "aria-controls": u ? f : void 0,
62
+ onClick: (e) => {
63
+ i?.(e), e.defaultPrevented || d(!u);
64
+ },
65
+ className: e("zen__accordion-trigger group text-muted-foreground hover:text-foreground aria-expanded:text-foreground focus-ring flex w-full cursor-pointer items-center justify-between gap-3 rounded-md py-3.5 text-start text-sm font-medium transition-colors duration-200 disabled:cursor-not-allowed disabled:opacity-50", r),
66
+ ...s,
67
+ children: [o, /* @__PURE__ */ c(n, {
68
+ open: u,
69
+ className: "ease-out-soft text-inherit"
70
+ })]
71
+ })
72
+ });
73
+ }
74
+ function h({ className: t, ...n }) {
75
+ return /* @__PURE__ */ c(i, {
76
+ className: e("text-muted-foreground pt-0 pb-4 text-sm", t),
77
+ ...n
78
+ });
79
+ }
80
+ //#endregion
81
+ export { h as AccordionContent, p as AccordionItem, m as AccordionTrigger, f as default };
@@ -8,10 +8,11 @@ import { Money } from '../utils/money';
8
8
  */
9
9
  export default function AnimatedNumber({ value, format, duration, fromZero, roll, className, }: AnimatedNumberProps): import('react').JSX.Element;
10
10
  /** An amount of money (minor units) that counts to each new value. */
11
- export declare function AnimatedMoney({ value, currency, locale, showDecimals, ...rest }: Omit<AnimatedNumberProps, 'format' | 'value'> & {
11
+ export declare function AnimatedMoney({ value, currency, locale: localeProp, showDecimals, ...rest }: Omit<AnimatedNumberProps, 'format' | 'value'> & {
12
12
  value: Money;
13
13
  currency: string;
14
- locale: string;
14
+ /** Defaults to the LocaleProvider's. */
15
+ locale?: string;
15
16
  showDecimals?: boolean;
16
17
  }): import('react').JSX.Element;
17
18
  export interface AnimatedNumberProps {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/animated-number/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAO3D;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACnC,KAAK,EACL,MAAe,EACf,QAAc,EACd,QAAe,EACf,IAAY,EACZ,SAAS,GACZ,EAAE,mBAAmB,+BAiDrB;AAoBD,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,MAAM,EACN,YAAoB,EACpB,GAAG,IAAI,EACV,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG;IAC/C,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B,+BAIA;AAED,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/animated-number/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAe,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAO3D;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACnC,KAAK,EACL,MAAe,EACf,QAAc,EACd,QAAe,EACf,IAAY,EACZ,SAAS,GACZ,EAAE,mBAAmB,+BAiDrB;AAoBD,sEAAsE;AACtE,wBAAgB,aAAa,CAAC,EAC1B,KAAK,EACL,QAAQ,EACR,MAAM,EAAE,UAAU,EAClB,YAAoB,EACpB,GAAG,IAAI,EACV,EAAE,IAAI,CAAC,mBAAmB,EAAE,QAAQ,GAAG,OAAO,CAAC,GAAG;IAC/C,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;CAC1B,+BAKA;AAED,MAAM,WAAW,mBAAmB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -1,55 +1,56 @@
1
1
  "use client";
2
2
  import { cx as e } from "../utils/cx.js";
3
- import { formatMoney as t } from "../utils/money.js";
4
- import { reducedMotion as n } from "../utils/motion.js";
5
- import { useEffect as r, useLayoutEffect as i, useRef as a, useState as o } from "react";
6
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
3
+ import { useLocale as t } from "../locale-provider/index.js";
4
+ import { formatMoney as n } from "../utils/money.js";
5
+ import { reducedMotion as r } from "../utils/motion.js";
6
+ import { useEffect as i, useLayoutEffect as a, useRef as o, useState as s } from "react";
7
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
7
8
  //#region packages/animated-number/index.tsx
8
- var l = typeof window > "u" ? r : i, u = (e) => 1 - (1 - e) ** 3;
9
- function d({ value: t, format: i = String, duration: d = 650, fromZero: f = !0, roll: m = !1, className: h }) {
10
- let [g, _] = o(f ? 0 : t), v = a(f ? 0 : t), [y, b] = o(!f);
11
- if (r(() => {
12
- if (!m || y) return;
9
+ var u = typeof window > "u" ? i : a, d = (e) => 1 - (1 - e) ** 3;
10
+ function f({ value: t, format: n = String, duration: a = 650, fromZero: f = !0, roll: p = !1, className: h }) {
11
+ let [g, _] = s(f ? 0 : t), v = o(f ? 0 : t), [y, b] = s(!f);
12
+ if (i(() => {
13
+ if (!p || y) return;
13
14
  let e = requestAnimationFrame(() => b(!0));
14
15
  return () => cancelAnimationFrame(e);
15
- }, [m, y]), l(() => {
16
- if (m) return;
17
- if (n() || d <= 0) {
16
+ }, [p, y]), u(() => {
17
+ if (p) return;
18
+ if (r() || a <= 0) {
18
19
  v.current = t, _(t);
19
20
  return;
20
21
  }
21
- let e = v.current, r = performance.now(), i = requestAnimationFrame(function n(a) {
22
- let o = Math.min(1, (a - r) / d), s = Math.round(e + (t - e) * u(o));
23
- v.current = s, _(s), o < 1 && (i = requestAnimationFrame(n));
22
+ let e = v.current, n = performance.now(), i = requestAnimationFrame(function r(o) {
23
+ let s = Math.min(1, (o - n) / a), c = Math.round(e + (t - e) * d(s));
24
+ v.current = c, _(c), s < 1 && (i = requestAnimationFrame(r));
24
25
  });
25
26
  return () => cancelAnimationFrame(i);
26
27
  }, [
27
28
  t,
28
- d,
29
- m
30
- ]), m) {
31
- let n = i(t);
32
- return /* @__PURE__ */ c("span", {
29
+ a,
30
+ p
31
+ ]), p) {
32
+ let r = n(t);
33
+ return /* @__PURE__ */ l("span", {
33
34
  className: e("zen__animated-number inline-flex items-start tabular-nums", h),
34
- children: [/* @__PURE__ */ s("span", {
35
+ children: [/* @__PURE__ */ c("span", {
35
36
  className: "sr-only",
36
- children: n
37
- }), /* @__PURE__ */ s("span", {
37
+ children: r
38
+ }), /* @__PURE__ */ c("span", {
38
39
  "aria-hidden": !0,
39
40
  className: "inline-flex items-start",
40
- children: n.split("").map((e, t) => /\d/.test(e) ? /* @__PURE__ */ s(p, {
41
+ children: r.split("").map((e, t) => /\d/.test(e) ? /* @__PURE__ */ c(m, {
41
42
  digit: y ? Number(e) : 0,
42
- duration: d
43
- }, n.length - t) : /* @__PURE__ */ s("span", { children: e }, n.length - t))
43
+ duration: a
44
+ }, r.length - t) : /* @__PURE__ */ c("span", { children: e }, r.length - t))
44
45
  })]
45
46
  });
46
47
  }
47
- return /* @__PURE__ */ s("span", {
48
+ return /* @__PURE__ */ c("span", {
48
49
  className: e("zen__animated-number tabular-nums", h),
49
- children: i(g)
50
+ children: n(g)
50
51
  });
51
52
  }
52
- var f = [
53
+ var p = [
53
54
  0,
54
55
  1,
55
56
  2,
@@ -61,25 +62,26 @@ var f = [
61
62
  8,
62
63
  9
63
64
  ];
64
- function p({ digit: e, duration: t }) {
65
- return /* @__PURE__ */ s("span", {
65
+ function m({ digit: e, duration: t }) {
66
+ return /* @__PURE__ */ c("span", {
66
67
  className: "inline-block h-[1lh] overflow-hidden",
67
- children: /* @__PURE__ */ s("span", {
68
+ children: /* @__PURE__ */ c("span", {
68
69
  className: "zen__digit ease-out-soft flex flex-col transition-[translate]",
69
70
  style: {
70
71
  translate: `0 ${-e * 10}%`,
71
72
  transitionDuration: `${t}ms`
72
73
  },
73
- children: f.map((e) => /* @__PURE__ */ s("span", { children: e }, e))
74
+ children: p.map((e) => /* @__PURE__ */ c("span", { children: e }, e))
74
75
  })
75
76
  });
76
77
  }
77
- function m({ value: e, currency: n, locale: r, showDecimals: i = !1, ...a }) {
78
- return /* @__PURE__ */ s(d, {
78
+ function h({ value: e, currency: r, locale: i, showDecimals: a = !1, ...o }) {
79
+ let s = t(i);
80
+ return /* @__PURE__ */ c(f, {
79
81
  value: e,
80
- format: (e) => t(e, n, r, { showDecimals: i }),
81
- ...a
82
+ format: (e) => n(e, r, s, { showDecimals: a }),
83
+ ...o
82
84
  });
83
85
  }
84
86
  //#endregion
85
- export { m as AnimatedMoney, d as default };
87
+ export { h as AnimatedMoney, f as default };
@@ -1,9 +1,13 @@
1
+ import { ComponentProps } from 'react';
1
2
  /**
2
3
  * Round profile picture; without an image, the name's initial on the glowing
3
4
  * accent. Decorative (hidden from screen readers) unless you give it `alt`.
4
5
  */
5
- export default function Avatar({ src, name, alt, className }: AvatarProps): import('react').JSX.Element;
6
+ export default function Avatar({ src, name, alt, className, ...rest }: AvatarProps): import('react').JSX.Element;
7
+ /** `reason` says what went wrong, so you can say it in your own words; `message` says it in English. */
6
8
  export declare class ImageCropError extends Error {
9
+ readonly reason: 'not-an-image' | 'too-large' | 'unreadable';
10
+ constructor(reason: 'not-an-image' | 'too-large' | 'unreadable', message: string);
7
11
  }
8
12
  /**
9
13
  * Crops an image file to a centred square and resizes it in the browser (to
@@ -11,7 +15,8 @@ export declare class ImageCropError extends Error {
11
15
  * Handy for profile pictures you store yourself.
12
16
  */
13
17
  export declare function cropImageToSquare(file: Blob, size?: number, quality?: number): Promise<string>;
14
- export interface AvatarProps {
18
+ /** Other props (data-*, an id, a title) go on the avatar's outer element. */
19
+ export interface AvatarProps extends Omit<ComponentProps<'span'>, 'children'> {
15
20
  /** Image URL (or data URL); without it, or if it fails to load, the initial is shown. */
16
21
  src?: string | null;
17
22
  /** Name or email, for the initial. */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/avatar/index.tsx"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,WAAW,+BA+BxE;AAED,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAM,EAAE,OAAO,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAkB/F;AAED,MAAM,WAAW,WAAW;IACxB,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/avatar/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAY,MAAM,OAAO,CAAC;AAEjD;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,WAAW,+BAgCjF;AAED,wGAAwG;AACxG,qBAAa,cAAe,SAAQ,KAAK;IAEjC,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,GAAG,YAAY;gBAAnD,MAAM,EAAE,cAAc,GAAG,WAAW,GAAG,YAAY,EAC5D,OAAO,EAAE,MAAM;CAItB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAM,EAAE,OAAO,SAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAkB/F;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAY,SAAQ,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IACzE,yFAAyF;IACzF,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -3,34 +3,40 @@ import { cx as e } from "../utils/cx.js";
3
3
  import { useState as t } from "react";
4
4
  import { jsx as n, jsxs as r } from "react/jsx-runtime";
5
5
  //#region packages/avatar/index.tsx
6
- function i({ src: i, name: a, alt: o, className: s }) {
7
- let c = (a.trim()[0] ?? "?").toUpperCase(), [l, u] = t(null), d = i && i !== l ? i : null;
6
+ function i({ src: i, name: a, alt: o, className: s, ...c }) {
7
+ let l = (a.trim()[0] ?? "?").toUpperCase(), [u, d] = t(null), f = i && i !== u ? i : null;
8
8
  return /* @__PURE__ */ r("span", {
9
9
  role: o ? "img" : void 0,
10
10
  "aria-label": o,
11
11
  "aria-hidden": !o || void 0,
12
+ ...c,
12
13
  className: e("zen__avatar relative inline-grid shrink-0 place-items-center overflow-hidden rounded-full font-semibold select-none", "size-9 text-sm", "text-primary-foreground bg-[radial-gradient(circle_at_30%_25%,oklch(var(--glow)/0.9),oklch(var(--primary)/0.55))]", "shadow-[0_0_0_1px_oklch(var(--tint)/0.12),0_0_18px_-6px_oklch(var(--glow)/calc(0.9*var(--glow-strength)))]", s),
13
14
  children: [/* @__PURE__ */ n("span", {
14
- className: d ? "invisible" : void 0,
15
- children: c
16
- }), d && /* @__PURE__ */ n("img", {
17
- src: d,
15
+ className: f ? "invisible" : void 0,
16
+ children: l
17
+ }), f && /* @__PURE__ */ n("img", {
18
+ src: f,
18
19
  alt: "",
19
- onError: () => u(d),
20
+ onError: () => d(f),
20
21
  className: "absolute inset-0 size-full object-cover",
21
22
  draggable: !1
22
23
  })]
23
24
  });
24
25
  }
25
- var a = class extends Error {};
26
+ var a = class extends Error {
27
+ reason;
28
+ constructor(e, t) {
29
+ super(t), this.reason = e;
30
+ }
31
+ };
26
32
  async function o(e, t = 160, n = .85) {
27
- if (!e.type.startsWith("image/")) throw new a("Choose an image file.");
28
- if (e.size > 20971520) throw new a("That image is too large (over 20 MB).");
33
+ if (!e.type.startsWith("image/")) throw new a("not-an-image", "Choose an image file.");
34
+ if (e.size > 20971520) throw new a("too-large", "That image is too large (over 20 MB).");
29
35
  let r;
30
36
  try {
31
37
  r = await createImageBitmap(e);
32
38
  } catch {
33
- throw new a("That image couldn't be read.");
39
+ throw new a("unreadable", "That image couldn't be read.");
34
40
  }
35
41
  let i = Math.min(r.width, r.height), o = document.createElement("canvas");
36
42
  o.width = o.height = t;
@@ -1,18 +1,18 @@
1
- import { CSSProperties } from 'react';
1
+ import { ComponentProps } from 'react';
2
2
  /**
3
3
  * Fixed page background: slow aurora glows over a faint pattern (topographic
4
4
  * contours or a dot grid), with a light that follows the pointer. It also
5
5
  * lights `.glow-edge` and `.glow-border` borders (cards, outline buttons,
6
6
  * dialogs, fields) near the pointer. Render once, behind everything.
7
7
  */
8
- export default function Backdrop({ pattern, topoSrc, className, style }: BackdropProps): import('react').JSX.Element;
9
- export interface BackdropProps {
8
+ export default function Backdrop({ pattern, topoSrc, className, style, ref: refProp, ...rest }: BackdropProps): import('react').JSX.Element;
9
+ /** Other props (data-*, an id) go on the backdrop layer. */
10
+ export interface BackdropProps extends Omit<ComponentProps<'div'>, 'children'> {
10
11
  /** Background pattern. Defaults to contours when `topoSrc` is given, dots otherwise. */
11
12
  pattern?: 'contours' | 'dots';
12
13
  /** URL of a contour-line image (strokes on transparent), used as a mask. */
13
14
  topoSrc?: string;
14
15
  /** Classes for the backdrop layer (e.g. a view-transition-name). */
15
16
  className?: string;
16
- style?: CSSProperties;
17
17
  }
18
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/backdrop/index.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAqB,MAAM,OAAO,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,aAAa,+BA2NrF;AAED,MAAM,WAAW,aAAa;IAC1B,wFAAwF;IACxF,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACzB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/backdrop/index.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAoC,MAAM,OAAO,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,CAAC,OAAO,UAAU,QAAQ,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,aAAa,+BA6N5G;AAED,4DAA4D;AAC5D,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC1E,wFAAwF;IACxF,OAAO,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IAC9B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB"}
@@ -1,48 +1,49 @@
1
1
  "use client";
2
2
  import { cx as e } from "../utils/cx.js";
3
3
  import { applyGraphicsMode as t } from "../utils/graphics.js";
4
- import { useEffect as n, useRef as r } from "react";
5
- import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
4
+ import { useMergedRefs as n } from "../utils/refs.js";
5
+ import { useEffect as r, useRef as i } from "react";
6
+ import { Fragment as a, jsx as o, jsxs as s } from "react/jsx-runtime";
6
7
  //#region packages/backdrop/index.tsx
7
- function s({ pattern: s, topoSrc: c, className: l, style: u }) {
8
- let d = s ?? (c ? "contours" : "dots"), f = r(null);
9
- return n(() => {
10
- let e = document.documentElement, n = f.current, r = 0, i = -9999, a = -9999, o = /* @__PURE__ */ new WeakSet(), s = !0, c = /* @__PURE__ */ new WeakMap(), [l, u] = typeof CSS < "u" && CSS.supports?.("width", "attr(x type(<length>))") ? ["data-zen-gx", "data-zen-gy"] : ["--gx", "--gy"], d = (e, t, n) => t.startsWith("data-") ? e.setAttribute(t, n) : e.style.setProperty(t, n), p = (e, t, n, r = l, i = u) => {
8
+ function c({ pattern: c, topoSrc: l, className: u, style: d, ref: f, ...p }) {
9
+ let m = c ?? (l ? "contours" : "dots"), h = i(null), g = n(h, f);
10
+ return r(() => {
11
+ let e = document.documentElement, n = h.current, r = 0, i = -9999, a = -9999, o = /* @__PURE__ */ new WeakSet(), s = !0, c = /* @__PURE__ */ new WeakMap(), [l, u] = typeof CSS < "u" && CSS.supports?.("width", "attr(x type(<length>))") ? ["data-zen-gx", "data-zen-gy"] : ["--gx", "--gy"], d = (e, t, n) => t.startsWith("data-") ? e.setAttribute(t, n) : e.style.setProperty(t, n), f = (e, t, n, r = l, i = u) => {
11
12
  let a = t + " " + n;
12
13
  c.get(e) !== a && (c.set(e, a), d(e, r, t), d(e, i, n));
13
- }, m = () => {
14
+ }, p = () => {
14
15
  r = 0;
15
16
  let e = Array.from(document.querySelectorAll(".glow-edge, .glow-border")), t = e.map((e) => e.getBoundingClientRect()), c = n?.getBoundingClientRect();
16
17
  if (n && c) {
17
18
  let e = s ? "out" : "in";
18
19
  n.dataset.pointer !== e && (n.dataset.pointer = e);
19
20
  let t = n.querySelector(".zen-light");
20
- t && !s && p(t, `${Math.round(i - c.left)}px`, `${Math.round(a - c.top)}px`, "left", "top");
21
+ t && !s && f(t, `${Math.round(i - c.left)}px`, `${Math.round(a - c.top)}px`, "left", "top");
21
22
  }
22
23
  e.forEach((e, n) => {
23
24
  let r = t[n];
24
- i > r.left - 400 && i < r.right + 400 && a > r.top - 400 && a < r.bottom + 400 ? (p(e, `${Math.round(i - r.left)}px`, `${Math.round(a - r.top)}px`), o.delete(e)) : o.has(e) || (p(e, "-9999px", "-9999px"), o.add(e));
25
+ i > r.left - 400 && i < r.right + 400 && a > r.top - 400 && a < r.bottom + 400 ? (f(e, `${Math.round(i - r.left)}px`, `${Math.round(a - r.top)}px`), o.delete(e)) : o.has(e) || (f(e, "-9999px", "-9999px"), o.add(e));
25
26
  });
26
- }, h = () => {
27
- r ||= requestAnimationFrame(m);
27
+ }, m = () => {
28
+ r ||= requestAnimationFrame(p);
28
29
  }, g = (e) => {
29
- i = e.clientX, a = e.clientY, s = !1, h();
30
+ i = e.clientX, a = e.clientY, s = !1, m();
30
31
  }, _ = () => {
31
- i = a = -9999, s = !0, h();
32
+ i = a = -9999, s = !0, m();
32
33
  };
33
34
  if (window.matchMedia?.("(hover: none), (pointer: coarse)").matches || t() === "lite") return;
34
35
  window.addEventListener("pointermove", g, { passive: !0 }), e.addEventListener("pointerleave", _);
35
36
  let v = 0, y = () => {
36
- clearTimeout(v), v = window.setTimeout(h, 120);
37
+ clearTimeout(v), v = window.setTimeout(m, 120);
37
38
  };
38
39
  return window.addEventListener("scroll", y, {
39
40
  passive: !0,
40
41
  capture: !0
41
- }), window.addEventListener("resize", h, { passive: !0 }), () => {
42
- window.removeEventListener("pointermove", g), e.removeEventListener("pointerleave", _), window.removeEventListener("scroll", y, { capture: !0 }), clearTimeout(v), window.removeEventListener("resize", h), cancelAnimationFrame(r);
42
+ }), window.addEventListener("resize", m, { passive: !0 }), () => {
43
+ window.removeEventListener("pointermove", g), e.removeEventListener("pointerleave", _), window.removeEventListener("scroll", y, { capture: !0 }), clearTimeout(v), window.removeEventListener("resize", m), cancelAnimationFrame(r);
43
44
  };
44
- }, []), n(() => {
45
- let e = f.current?.querySelector(".zen-aurora");
45
+ }, []), r(() => {
46
+ let e = h.current?.querySelector(".zen-aurora");
46
47
  if (!e?.getAnimations) return;
47
48
  let t = performance.now(), n = () => {
48
49
  let n = performance.now(), r = e.getAnimations().filter((e) => e.effect?.getTiming().iterations === Infinity).map((e) => [e, e.playState === "paused" ? Number(e.currentTime ?? 0) : null]);
@@ -52,11 +53,11 @@ function s({ pattern: s, topoSrc: c, className: l, style: u }) {
52
53
  n();
53
54
  let r = window.setInterval(n, 1e3 / 6);
54
55
  return () => clearInterval(r);
55
- }, []), n(() => {
56
- let e = f.current;
57
- if (!c || !e || typeof document > "u") return;
56
+ }, []), r(() => {
57
+ let e = h.current;
58
+ if (!l || !e || typeof document > "u") return;
58
59
  let t = "", n = !1, r = 0, i = new Image();
59
- i.src = c;
60
+ i.src = l;
60
61
  let a = async () => {
61
62
  try {
62
63
  await i.decode();
@@ -77,33 +78,34 @@ function s({ pattern: s, topoSrc: c, className: l, style: u }) {
77
78
  clearTimeout(r), r = window.setTimeout(a, 200);
78
79
  });
79
80
  return o?.observe(e), () => {
80
- n = !0, clearTimeout(r), o?.disconnect(), t && URL.revokeObjectURL(t), e.style.setProperty("--zen-topo", `url("${c}")`);
81
+ n = !0, clearTimeout(r), o?.disconnect(), t && URL.revokeObjectURL(t), e.style.setProperty("--zen-topo", `url("${l}")`);
81
82
  };
82
- }, [c]), /* @__PURE__ */ o("div", {
83
- ref: f,
84
- className: e("zen-backdrop", l),
85
- "data-pattern": d,
83
+ }, [l]), /* @__PURE__ */ s("div", {
84
+ ...p,
85
+ ref: g,
86
+ className: e("zen-backdrop", u),
87
+ "data-pattern": m,
86
88
  "aria-hidden": !0,
87
89
  style: {
88
- ...c && { "--zen-topo": `url("${c}")` },
89
- ...u
90
+ ...l && { "--zen-topo": `url("${l}")` },
91
+ ...d
90
92
  },
91
93
  children: [
92
- /* @__PURE__ */ a("div", { className: "zen-aurora" }),
93
- d === "contours" ? /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a("div", { className: "zen-topo" }), /* @__PURE__ */ a("div", {
94
+ /* @__PURE__ */ o("div", { className: "zen-aurora" }),
95
+ m === "contours" ? /* @__PURE__ */ s(a, { children: [/* @__PURE__ */ o("div", { className: "zen-topo" }), /* @__PURE__ */ o("div", {
94
96
  className: "zen-topo zen-topo--lit",
95
- children: /* @__PURE__ */ a("div", { className: "zen-light" })
96
- })] }) : /* @__PURE__ */ o(i, { children: [
97
- /* @__PURE__ */ a("div", { className: "zen-dots" }),
98
- /* @__PURE__ */ a("div", { className: "zen-dots zen-dots--ambient" }),
99
- /* @__PURE__ */ a("div", {
97
+ children: /* @__PURE__ */ o("div", { className: "zen-light" })
98
+ })] }) : /* @__PURE__ */ s(a, { children: [
99
+ /* @__PURE__ */ o("div", { className: "zen-dots" }),
100
+ /* @__PURE__ */ o("div", { className: "zen-dots zen-dots--ambient" }),
101
+ /* @__PURE__ */ o("div", {
100
102
  className: "zen-dots zen-dots--lit",
101
- children: /* @__PURE__ */ a("div", { className: "zen-light" })
103
+ children: /* @__PURE__ */ o("div", { className: "zen-light" })
102
104
  })
103
105
  ] }),
104
- /* @__PURE__ */ a("div", { className: "zen-vignette" })
106
+ /* @__PURE__ */ o("div", { className: "zen-vignette" })
105
107
  ]
106
108
  });
107
109
  }
108
110
  //#endregion
109
- export { s as default };
111
+ export { c as default };
@@ -1,8 +1,10 @@
1
1
  import { VariantProps } from '../utils/cva';
2
2
  import { ComponentProps } from 'react';
3
- export default function Badge({ variant, className, ...rest }: BadgeProps): import('react').JSX.Element;
3
+ /** A small label for status, counts and tags; `tone="negative"` for bad news. */
4
+ export default function Badge({ variant, tone, className, ...rest }: BadgeProps): import('react').JSX.Element;
4
5
  declare const badgeVariants: (props?: ({
5
- variant?: "outline" | "default" | "destructive" | "secondary" | null | undefined;
6
+ variant?: "outline" | "default" | "secondary" | null | undefined;
7
+ tone?: "default" | "negative" | null | undefined;
6
8
  } & ({
7
9
  class: import('../utils/cx').ClassValue;
8
10
  className?: never;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/badge/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAO,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEvC,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,UAAU,+BAExE;AACD,QAAA,MAAM,aAAa;;;;;;;;;;;0BAgBlB,CAAC;AACF,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,aAAa,CAAC;CAAG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../packages/badge/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAO,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAEvC,iFAAiF;AACjF,MAAM,CAAC,OAAO,UAAU,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,IAAI,EAAE,EAAE,UAAU,+BAE9E;AACD,QAAA,MAAM,aAAa;;;;;;;;;;;;0BAoBlB,CAAC;AACF,MAAM,WAAW,UAAW,SAAQ,cAAc,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC,OAAO,aAAa,CAAC;CAAG"}