@nanisoft/prism-ui 0.10.1 → 0.13.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 (334) hide show
  1. package/LICENSE +21 -21
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/blocks/app-shell-01/app-shell.js +4 -4
  4. package/dist/blocks/app-shell-01/index.d.ts +2 -2
  5. package/dist/blocks/app-shell-01/index.js +1 -1
  6. package/dist/blocks/auth-form-01/auth-form.d.ts +11 -1
  7. package/dist/blocks/auth-form-01/auth-form.d.ts.map +1 -1
  8. package/dist/blocks/auth-form-01/auth-form.js +11 -8
  9. package/dist/blocks/auth-form-01/index.d.ts +2 -2
  10. package/dist/blocks/auth-form-01/index.js +1 -1
  11. package/dist/blocks/cta-01/cta.d.ts +26 -21
  12. package/dist/blocks/cta-01/cta.d.ts.map +1 -1
  13. package/dist/blocks/cta-01/cta.js +2 -2
  14. package/dist/blocks/cta-01/index.d.ts +2 -2
  15. package/dist/blocks/cta-01/index.js +1 -1
  16. package/dist/blocks/data-table-01/data-table.js +7 -7
  17. package/dist/blocks/data-table-01/index.d.ts +2 -2
  18. package/dist/blocks/data-table-01/index.js +1 -1
  19. package/dist/blocks/empty-state-01/empty-state.d.ts +143 -0
  20. package/dist/blocks/empty-state-01/empty-state.d.ts.map +1 -0
  21. package/dist/blocks/empty-state-01/empty-state.js +104 -0
  22. package/dist/blocks/empty-state-01/index.d.ts +3 -0
  23. package/dist/blocks/empty-state-01/index.d.ts.map +1 -0
  24. package/dist/blocks/empty-state-01/index.js +1 -0
  25. package/dist/blocks/feature-grid-01/feature-grid.d.ts +28 -1
  26. package/dist/blocks/feature-grid-01/feature-grid.d.ts.map +1 -1
  27. package/dist/blocks/feature-grid-01/feature-grid.js +34 -3
  28. package/dist/blocks/feature-grid-01/index.d.ts +2 -2
  29. package/dist/blocks/feature-grid-01/index.js +1 -1
  30. package/dist/blocks/hero-01/hero.d.ts +49 -17
  31. package/dist/blocks/hero-01/hero.d.ts.map +1 -1
  32. package/dist/blocks/hero-01/hero.js +14 -9
  33. package/dist/blocks/hero-01/index.d.ts +2 -1
  34. package/dist/blocks/hero-01/index.d.ts.map +1 -1
  35. package/dist/blocks/hero-01/index.js +1 -1
  36. package/dist/blocks/index.d.ts +20 -20
  37. package/dist/blocks/index.js +19 -19
  38. package/dist/blocks/instrument-panel-01/index.d.ts +2 -2
  39. package/dist/blocks/instrument-panel-01/index.js +1 -1
  40. package/dist/blocks/instrument-panel-01/instrument-panel.js +1 -1
  41. package/dist/blocks/logo-strip-01/index.d.ts +2 -2
  42. package/dist/blocks/logo-strip-01/index.js +1 -1
  43. package/dist/blocks/logo-strip-01/logo-strip.d.ts +1 -1
  44. package/dist/blocks/logo-strip-01/logo-strip.js +2 -2
  45. package/dist/blocks/note-grid-01/index.d.ts +2 -2
  46. package/dist/blocks/note-grid-01/index.js +1 -1
  47. package/dist/blocks/note-grid-01/note-grid.d.ts +1 -1
  48. package/dist/blocks/note-grid-01/note-grid.js +1 -1
  49. package/dist/blocks/page-header-01/index.d.ts +2 -2
  50. package/dist/blocks/page-header-01/index.js +1 -1
  51. package/dist/blocks/page-header-01/page-header.d.ts +1 -1
  52. package/dist/blocks/page-header-01/page-header.js +4 -4
  53. package/dist/blocks/pricing-01/index.d.ts +1 -1
  54. package/dist/blocks/pricing-01/index.js +1 -1
  55. package/dist/blocks/pricing-01/pricing.d.ts +8 -1
  56. package/dist/blocks/pricing-01/pricing.d.ts.map +1 -1
  57. package/dist/blocks/pricing-01/pricing.js +15 -5
  58. package/dist/blocks/process-flow-01/index.d.ts +3 -0
  59. package/dist/blocks/process-flow-01/index.d.ts.map +1 -0
  60. package/dist/blocks/process-flow-01/index.js +1 -0
  61. package/dist/blocks/process-flow-01/process-flow.d.ts +118 -0
  62. package/dist/blocks/process-flow-01/process-flow.d.ts.map +1 -0
  63. package/dist/blocks/process-flow-01/process-flow.js +71 -0
  64. package/dist/blocks/process-rail-01/index.d.ts +2 -2
  65. package/dist/blocks/process-rail-01/index.js +1 -1
  66. package/dist/blocks/process-rail-01/process-rail.d.ts +1 -1
  67. package/dist/blocks/process-rail-01/process-rail.js +2 -2
  68. package/dist/blocks/product-grid-01/index.d.ts +2 -2
  69. package/dist/blocks/product-grid-01/index.js +1 -1
  70. package/dist/blocks/product-grid-01/product-grid.d.ts +37 -5
  71. package/dist/blocks/product-grid-01/product-grid.d.ts.map +1 -1
  72. package/dist/blocks/product-grid-01/product-grid.js +20 -6
  73. package/dist/blocks/run-console-01/index.d.ts +3 -0
  74. package/dist/blocks/run-console-01/index.d.ts.map +1 -0
  75. package/dist/blocks/run-console-01/index.js +1 -0
  76. package/dist/blocks/run-console-01/run-console.d.ts +111 -0
  77. package/dist/blocks/run-console-01/run-console.d.ts.map +1 -0
  78. package/dist/blocks/run-console-01/run-console.js +48 -0
  79. package/dist/blocks/settings-panel-01/index.d.ts +2 -2
  80. package/dist/blocks/settings-panel-01/index.js +1 -1
  81. package/dist/blocks/settings-panel-01/settings-panel.d.ts +11 -1
  82. package/dist/blocks/settings-panel-01/settings-panel.d.ts.map +1 -1
  83. package/dist/blocks/settings-panel-01/settings-panel.js +15 -10
  84. package/dist/blocks/site-footer/index.d.ts +2 -2
  85. package/dist/blocks/site-footer/index.js +1 -1
  86. package/dist/blocks/site-footer/site-footer.d.ts +1 -1
  87. package/dist/blocks/site-footer/site-footer.js +2 -2
  88. package/dist/blocks/site-header/index.d.ts +2 -2
  89. package/dist/blocks/site-header/index.js +1 -1
  90. package/dist/blocks/site-header/site-header.d.ts +2 -2
  91. package/dist/blocks/site-header/site-header.js +3 -3
  92. package/dist/blocks/site-navbar/index.d.ts +3 -0
  93. package/dist/blocks/site-navbar/index.d.ts.map +1 -0
  94. package/dist/blocks/site-navbar/index.js +1 -0
  95. package/dist/blocks/site-navbar/mobile-nav.d.ts +48 -0
  96. package/dist/blocks/site-navbar/mobile-nav.d.ts.map +1 -0
  97. package/dist/blocks/site-navbar/mobile-nav.js +35 -0
  98. package/dist/blocks/site-navbar/mode-toggle.d.ts +39 -0
  99. package/dist/blocks/site-navbar/mode-toggle.d.ts.map +1 -0
  100. package/dist/blocks/site-navbar/mode-toggle.js +39 -0
  101. package/dist/blocks/site-navbar/navbar-controls.d.ts +79 -0
  102. package/dist/blocks/site-navbar/navbar-controls.d.ts.map +1 -0
  103. package/dist/blocks/site-navbar/navbar-controls.js +40 -0
  104. package/dist/blocks/site-navbar/search-entry.d.ts +29 -0
  105. package/dist/blocks/site-navbar/search-entry.d.ts.map +1 -0
  106. package/dist/blocks/site-navbar/search-entry.js +52 -0
  107. package/dist/blocks/site-navbar/site-navbar.d.ts +212 -0
  108. package/dist/blocks/site-navbar/site-navbar.d.ts.map +1 -0
  109. package/dist/blocks/site-navbar/site-navbar.js +61 -0
  110. package/dist/blocks/site-navbar/sites-menu.d.ts +40 -0
  111. package/dist/blocks/site-navbar/sites-menu.d.ts.map +1 -0
  112. package/dist/blocks/site-navbar/sites-menu.js +48 -0
  113. package/dist/blocks/site-navbar/theme-menu.d.ts +47 -0
  114. package/dist/blocks/site-navbar/theme-menu.d.ts.map +1 -0
  115. package/dist/blocks/site-navbar/theme-menu.js +55 -0
  116. package/dist/blocks/stack-grid-01/index.d.ts +2 -2
  117. package/dist/blocks/stack-grid-01/index.js +1 -1
  118. package/dist/blocks/stack-grid-01/stack-grid.d.ts +42 -11
  119. package/dist/blocks/stack-grid-01/stack-grid.d.ts.map +1 -1
  120. package/dist/blocks/stack-grid-01/stack-grid.js +15 -7
  121. package/dist/blocks/stats-01/index.d.ts +9 -1
  122. package/dist/blocks/stats-01/index.d.ts.map +1 -1
  123. package/dist/blocks/stats-01/index.js +8 -1
  124. package/dist/blocks/stats-01/stats.d.ts +1 -1
  125. package/dist/blocks/stats-01/stats.js +2 -2
  126. package/dist/blocks/status-ledger-01/index.d.ts +2 -2
  127. package/dist/blocks/status-ledger-01/index.js +1 -1
  128. package/dist/blocks/status-ledger-01/status-ledger.d.ts +1 -1
  129. package/dist/blocks/status-ledger-01/status-ledger.js +2 -2
  130. package/dist/catalog.d.ts +1 -1
  131. package/dist/catalog.d.ts.map +1 -1
  132. package/dist/catalog.js +473 -1
  133. package/dist/components/index.d.ts +104 -66
  134. package/dist/components/index.d.ts.map +1 -1
  135. package/dist/components/index.js +74 -40
  136. package/dist/components/ui/accordion.js +1 -1
  137. package/dist/components/ui/alert-dialog.d.ts +119 -0
  138. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  139. package/dist/components/ui/alert-dialog.js +82 -0
  140. package/dist/components/ui/alert.js +1 -1
  141. package/dist/components/ui/aspect-ratio.d.ts +60 -0
  142. package/dist/components/ui/aspect-ratio.d.ts.map +1 -0
  143. package/dist/components/ui/aspect-ratio.js +61 -0
  144. package/dist/components/ui/avatar.js +1 -1
  145. package/dist/components/ui/badge.js +1 -1
  146. package/dist/components/ui/breadcrumb.js +1 -1
  147. package/dist/components/ui/button-group.d.ts +68 -0
  148. package/dist/components/ui/button-group.d.ts.map +1 -0
  149. package/dist/components/ui/button-group.js +54 -0
  150. package/dist/components/ui/button.js +1 -1
  151. package/dist/components/ui/calendar.d.ts +158 -0
  152. package/dist/components/ui/calendar.d.ts.map +1 -0
  153. package/dist/components/ui/calendar.js +216 -0
  154. package/dist/components/ui/card.d.ts +18 -6
  155. package/dist/components/ui/card.d.ts.map +1 -1
  156. package/dist/components/ui/card.js +23 -8
  157. package/dist/components/ui/carousel.d.ts +118 -0
  158. package/dist/components/ui/carousel.d.ts.map +1 -0
  159. package/dist/components/ui/carousel.js +152 -0
  160. package/dist/components/ui/chart-frame.d.ts +216 -0
  161. package/dist/components/ui/chart-frame.d.ts.map +1 -0
  162. package/dist/components/ui/chart-frame.js +286 -0
  163. package/dist/components/ui/checkbox.js +1 -1
  164. package/dist/components/ui/collapsible.d.ts +97 -0
  165. package/dist/components/ui/collapsible.d.ts.map +1 -0
  166. package/dist/components/ui/collapsible.js +54 -0
  167. package/dist/components/ui/combobox.d.ts +141 -0
  168. package/dist/components/ui/combobox.d.ts.map +1 -0
  169. package/dist/components/ui/combobox.js +243 -0
  170. package/dist/components/ui/command-palette.d.ts +106 -0
  171. package/dist/components/ui/command-palette.d.ts.map +1 -0
  172. package/dist/components/ui/command-palette.js +176 -0
  173. package/dist/components/ui/command.d.ts +82 -0
  174. package/dist/components/ui/command.d.ts.map +1 -0
  175. package/dist/components/ui/command.js +37 -0
  176. package/dist/components/ui/context-menu.d.ts +151 -0
  177. package/dist/components/ui/context-menu.d.ts.map +1 -0
  178. package/dist/components/ui/context-menu.js +97 -0
  179. package/dist/components/ui/cta-link.js +1 -1
  180. package/dist/components/ui/date-picker.d.ts +111 -0
  181. package/dist/components/ui/date-picker.d.ts.map +1 -0
  182. package/dist/components/ui/date-picker.js +74 -0
  183. package/dist/components/ui/diagram.d.ts +84 -15
  184. package/dist/components/ui/diagram.d.ts.map +1 -1
  185. package/dist/components/ui/diagram.js +77 -7
  186. package/dist/components/ui/dialog.js +1 -1
  187. package/dist/components/ui/diff.d.ts +105 -0
  188. package/dist/components/ui/diff.d.ts.map +1 -0
  189. package/dist/components/ui/diff.js +113 -0
  190. package/dist/components/ui/dropdown-menu.d.ts +18 -0
  191. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  192. package/dist/components/ui/dropdown-menu.js +1 -1
  193. package/dist/components/ui/fact-list.js +1 -1
  194. package/dist/components/ui/field.js +1 -1
  195. package/dist/components/ui/form.d.ts +151 -0
  196. package/dist/components/ui/form.d.ts.map +1 -0
  197. package/dist/components/ui/form.js +73 -0
  198. package/dist/components/ui/hover-card.d.ts +105 -0
  199. package/dist/components/ui/hover-card.d.ts.map +1 -0
  200. package/dist/components/ui/hover-card.js +49 -0
  201. package/dist/components/ui/input-group.d.ts +99 -0
  202. package/dist/components/ui/input-group.d.ts.map +1 -0
  203. package/dist/components/ui/input-group.js +83 -0
  204. package/dist/components/ui/input.js +1 -1
  205. package/dist/components/ui/item.d.ts +113 -0
  206. package/dist/components/ui/item.d.ts.map +1 -0
  207. package/dist/components/ui/item.js +61 -0
  208. package/dist/components/ui/kbd.js +1 -1
  209. package/dist/components/ui/label.d.ts +58 -0
  210. package/dist/components/ui/label.d.ts.map +1 -0
  211. package/dist/components/ui/label.js +29 -0
  212. package/dist/components/ui/live-region.d.ts +9 -0
  213. package/dist/components/ui/live-region.d.ts.map +1 -1
  214. package/dist/components/ui/live-region.js +10 -2
  215. package/dist/components/ui/mark.js +1 -1
  216. package/dist/components/ui/menubar.d.ts +197 -0
  217. package/dist/components/ui/menubar.d.ts.map +1 -0
  218. package/dist/components/ui/menubar.js +109 -0
  219. package/dist/components/ui/meter.d.ts +121 -0
  220. package/dist/components/ui/meter.d.ts.map +1 -0
  221. package/dist/components/ui/meter.js +82 -0
  222. package/dist/components/ui/native-select.d.ts +72 -0
  223. package/dist/components/ui/native-select.d.ts.map +1 -0
  224. package/dist/components/ui/native-select.js +55 -0
  225. package/dist/components/ui/navigation-menu.d.ts +186 -0
  226. package/dist/components/ui/navigation-menu.d.ts.map +1 -0
  227. package/dist/components/ui/navigation-menu.js +94 -0
  228. package/dist/components/ui/number-field.d.ts +111 -0
  229. package/dist/components/ui/number-field.d.ts.map +1 -0
  230. package/dist/components/ui/number-field.js +84 -0
  231. package/dist/components/ui/one-time-code.d.ts +127 -0
  232. package/dist/components/ui/one-time-code.d.ts.map +1 -0
  233. package/dist/components/ui/one-time-code.js +57 -0
  234. package/dist/components/ui/pagination.js +1 -1
  235. package/dist/components/ui/popover.js +1 -1
  236. package/dist/components/ui/product-mark.d.ts +1 -1
  237. package/dist/components/ui/product-mark.js +1 -1
  238. package/dist/components/ui/product-switcher.d.ts +1 -1
  239. package/dist/components/ui/product-switcher.js +2 -2
  240. package/dist/components/ui/progress.js +1 -1
  241. package/dist/components/ui/prose.js +1 -1
  242. package/dist/components/ui/pulse-graph.js +1 -1
  243. package/dist/components/ui/pulse-series.js +1 -1
  244. package/dist/components/ui/radio-group.js +1 -1
  245. package/dist/components/ui/resizable.d.ts +129 -0
  246. package/dist/components/ui/resizable.d.ts.map +1 -0
  247. package/dist/components/ui/resizable.js +205 -0
  248. package/dist/components/ui/scroll-area.d.ts +97 -0
  249. package/dist/components/ui/scroll-area.d.ts.map +1 -0
  250. package/dist/components/ui/scroll-area.js +68 -0
  251. package/dist/components/ui/search-dialog.d.ts +139 -0
  252. package/dist/components/ui/search-dialog.d.ts.map +1 -0
  253. package/dist/components/ui/search-dialog.js +178 -0
  254. package/dist/components/ui/section.d.ts +26 -0
  255. package/dist/components/ui/section.d.ts.map +1 -1
  256. package/dist/components/ui/section.js +32 -1
  257. package/dist/components/ui/select.js +1 -1
  258. package/dist/components/ui/separator.js +1 -1
  259. package/dist/components/ui/sheet.d.ts +103 -0
  260. package/dist/components/ui/sheet.d.ts.map +1 -0
  261. package/dist/components/ui/sheet.js +58 -0
  262. package/dist/components/ui/sidebar.d.ts +228 -0
  263. package/dist/components/ui/sidebar.d.ts.map +1 -0
  264. package/dist/components/ui/sidebar.js +172 -0
  265. package/dist/components/ui/signal-field.js +1 -1
  266. package/dist/components/ui/skeleton.js +1 -1
  267. package/dist/components/ui/slider.js +1 -1
  268. package/dist/components/ui/spinner.d.ts +79 -0
  269. package/dist/components/ui/spinner.d.ts.map +1 -0
  270. package/dist/components/ui/spinner.js +79 -0
  271. package/dist/components/ui/switch.js +1 -1
  272. package/dist/components/ui/table-sort.d.ts +97 -0
  273. package/dist/components/ui/table-sort.d.ts.map +1 -0
  274. package/dist/components/ui/table-sort.js +102 -0
  275. package/dist/components/ui/table.js +1 -1
  276. package/dist/components/ui/tabs.js +1 -1
  277. package/dist/components/ui/textarea.js +1 -1
  278. package/dist/components/ui/timeline.d.ts +106 -0
  279. package/dist/components/ui/timeline.d.ts.map +1 -0
  280. package/dist/components/ui/timeline.js +111 -0
  281. package/dist/components/ui/toast.d.ts +219 -0
  282. package/dist/components/ui/toast.d.ts.map +1 -0
  283. package/dist/components/ui/toast.js +270 -0
  284. package/dist/components/ui/toggle-group.d.ts +118 -0
  285. package/dist/components/ui/toggle-group.d.ts.map +1 -0
  286. package/dist/components/ui/toggle-group.js +194 -0
  287. package/dist/components/ui/toggle.d.ts +73 -0
  288. package/dist/components/ui/toggle.d.ts.map +1 -0
  289. package/dist/components/ui/toggle.js +44 -0
  290. package/dist/components/ui/tooltip.js +1 -1
  291. package/dist/components/ui/tree.js +1 -1
  292. package/dist/components/ui/typography.js +1 -1
  293. package/dist/fonts/Inter-OFL.txt +93 -93
  294. package/dist/index.d.ts +72 -70
  295. package/dist/index.d.ts.map +1 -1
  296. package/dist/index.js +61 -60
  297. package/dist/lib/rank.d.ts +69 -0
  298. package/dist/lib/rank.d.ts.map +1 -0
  299. package/dist/lib/rank.js +77 -0
  300. package/dist/live/index.d.ts +22 -0
  301. package/dist/live/index.d.ts.map +1 -0
  302. package/dist/live/index.js +20 -0
  303. package/dist/live/run-stream-01/index.d.ts +3 -0
  304. package/dist/live/run-stream-01/index.d.ts.map +1 -0
  305. package/dist/live/run-stream-01/index.js +1 -0
  306. package/dist/live/run-stream-01/run-stream.d.ts +125 -0
  307. package/dist/live/run-stream-01/run-stream.d.ts.map +1 -0
  308. package/dist/live/run-stream-01/run-stream.js +111 -0
  309. package/dist/pages/auth-page/index.d.ts +15 -2
  310. package/dist/pages/auth-page/index.d.ts.map +1 -1
  311. package/dist/pages/auth-page/index.js +8 -4
  312. package/dist/pages/blog-post-page/index.js +5 -5
  313. package/dist/pages/dashboard-page/index.d.ts +4 -4
  314. package/dist/pages/dashboard-page/index.js +4 -4
  315. package/dist/pages/docs-shell/docs-shell.d.ts +37 -4
  316. package/dist/pages/docs-shell/docs-shell.d.ts.map +1 -1
  317. package/dist/pages/docs-shell/docs-shell.js +107 -16
  318. package/dist/pages/docs-shell/index.d.ts +2 -2
  319. package/dist/pages/docs-shell/index.js +1 -1
  320. package/dist/pages/index.d.ts +14 -14
  321. package/dist/pages/index.js +7 -7
  322. package/dist/pages/marketing-page/index.d.ts +6 -6
  323. package/dist/pages/marketing-page/index.js +5 -5
  324. package/dist/pages/not-found-page/index.js +4 -4
  325. package/dist/pages/settings-page/index.d.ts +3 -3
  326. package/dist/pages/settings-page/index.js +4 -4
  327. package/dist/provider/index.d.ts +4 -4
  328. package/dist/provider/index.js +2 -2
  329. package/dist/provider/provider.d.ts +1 -1
  330. package/dist/provider/provider.js +1 -1
  331. package/dist/provider/theme-script.d.ts +1 -1
  332. package/dist/provider/theme-script.js +1 -1
  333. package/dist/styles.css +689 -0
  334. package/package.json +9 -1
@@ -0,0 +1,127 @@
1
+ /** How the code is drawn in groups, for a code the reader sees written in groups. */
2
+ export interface OneTimeCodeGrouping {
3
+ /** The zero-based indices of the segments a separator is drawn after. */
4
+ readonly after: readonly number[];
5
+ /** What the separator is. The caller's, because it is read by a person. */
6
+ readonly separator: React.ReactNode;
7
+ }
8
+ /** The props the One time code accepts. */
9
+ export interface OneTimeCodeProps {
10
+ /**
11
+ * The accessible name of the code.
12
+ *
13
+ * Required. A row of six single-character fields with no name is six anonymous
14
+ * fields, and a reader cannot say out loud which one they are in.
15
+ */
16
+ label: string;
17
+ /** How many characters the code has. */
18
+ length: number;
19
+ /**
20
+ * The characters the code may contain.
21
+ *
22
+ * The caller's decision because it is theirs: a numeric code, an alphabet-only
23
+ * recovery code and an alphanumeric one-time token are three different things
24
+ * and a verification service decides which. A character outside the set is
25
+ * refused as it is typed or pasted rather than accepted and refused later, so
26
+ * the field never holds a value the server will reject.
27
+ */
28
+ characters?: 'numeric' | 'alpha' | 'alphanumeric' | 'none';
29
+ /**
30
+ * A normaliser, run after the character set has been applied.
31
+ *
32
+ * For the rules the closed set cannot express: folding a pasted code to lower
33
+ * case, stripping a leading country code. It must be idempotent, because the
34
+ * field normalises again on every edit and again on the way out of one.
35
+ */
36
+ normalize?: (value: string) => string;
37
+ /**
38
+ * The accessible name of one segment, receiving its zero-based index.
39
+ *
40
+ * Without it every segment is named by the field's own label, which is enough to
41
+ * satisfy the form but not to tell a reader which of the six they are in. This
42
+ * Component does not know the reader's words for a position, so it asks.
43
+ */
44
+ segmentLabel?: (index: number) => string;
45
+ /** How the code is drawn in groups, when it is read in groups. */
46
+ grouping?: OneTimeCodeGrouping;
47
+ /** The code, when the field is controlled. */
48
+ value?: string;
49
+ /** The code the field starts with, for an uncontrolled field. */
50
+ defaultValue?: string;
51
+ /** Called with the code as it changes. */
52
+ onValueChange?: (value: string) => void;
53
+ /** Called once every segment is filled, including by a paste that fills them all. */
54
+ onComplete?: (value: string) => void;
55
+ /**
56
+ * Called with the text the reader attempted when part of it was refused.
57
+ *
58
+ * The attempted text, not a verdict. Whether a refused character deserves a word
59
+ * to the reader is the caller's decision, and this Component ships no sentence
60
+ * into a consumer's product.
61
+ */
62
+ onInvalid?: (attempted: string) => void;
63
+ /** Whether the field submits its form as soon as the code is complete. */
64
+ autoSubmit?: boolean;
65
+ /** Whether the characters are hidden as they are typed. */
66
+ mask?: boolean;
67
+ /** Whether the field ignores interaction. */
68
+ disabled?: boolean;
69
+ /** Whether a code must be entered before the form submits. */
70
+ required?: boolean;
71
+ /** Whether the reader may see the code but not change it. */
72
+ readOnly?: boolean;
73
+ /** The form field name. The code is submitted under it. */
74
+ name?: string;
75
+ /** Identifies the form that owns the hidden input. */
76
+ form?: string;
77
+ /** The first segment's id. The rest derive from it. */
78
+ id?: string;
79
+ /** Layout only. */
80
+ className?: string;
81
+ }
82
+ /**
83
+ * A verification code entered one segment at a time.
84
+ *
85
+ * **A paste of the whole code lands in every segment.** A reader who has the code
86
+ * on their clipboard has already done the hard part, and a field that accepted one
87
+ * character per paste would make them retype it one box at a time, which is what
88
+ * they are on their phone to avoid. So a paste into the first segment is
89
+ * distributed across the ones after it and `onComplete` fires once, from the paste,
90
+ * rather than after six keystrokes.
91
+ *
92
+ * **A refused character is refused, not stored.** Whitespace is dropped and
93
+ * anything outside `characters` is refused, whether it was typed or pasted, so
94
+ * "123 456" pastes as `123456` and `12345a6` pastes as `123456`. The alternative,
95
+ * accepting the text and rejecting it at the server, gives the reader a field
96
+ * that looks right and a form that does not submit.
97
+ *
98
+ * **The code is one value, not six.** The segments are six views of one string of
99
+ * `length` characters, so Backspace removes a character from the string and the
100
+ * characters after it close up: on `123456`, Backspace in the third segment leaves
101
+ * `12456`. Six boxes that each had to be emptied by hand would need a rule for
102
+ * what Backspace on an empty box means, and every version of that rule is wrong
103
+ * for somebody. The rule that does nothing traps a reader who is correcting a
104
+ * digit; the rule that clears the box before deletes a character they did not ask
105
+ * to delete.
106
+ *
107
+ * **The character set, the normaliser and the words are all the caller's.** Which
108
+ * characters a code may contain is decided by the service that issued it, folding
109
+ * case is a rule only the caller knows, and every segment's accessible name is a
110
+ * phrase. Nothing here is a table of words or a regular expression.
111
+ *
112
+ * **The first segment is named by a real `<label>`, and it is hidden.** Base UI
113
+ * strips `aria-label` from that one segment on purpose: it is the segment the
114
+ * platform autofills, and the label element is what names the autofill prompt as
115
+ * well as the field. This Component renders that label visually hidden, because a
116
+ * label above a row of six boxes is the caller's to place. Pass `id` and put your
117
+ * own `Label` on the first segment, and this one steps aside.
118
+ *
119
+ * **One Tab stop for the whole code.** A reader reaches the first segment and the
120
+ * rest follow as they type, so the code is one stop in a form rather than six, and
121
+ * the segments are a named group rather than six fields in a row. It is built on
122
+ * Base UI's OTP field, which owns the segmentation, the clamping to `length` and
123
+ * the autofill hint the platform needs for a one-time code.
124
+ */
125
+ declare function OneTimeCode({ label, length, characters, normalize, segmentLabel, grouping, value, defaultValue, onValueChange, onComplete, onInvalid, autoSubmit, mask, disabled, required, readOnly, name, form, id, className, }: OneTimeCodeProps): import("react").JSX.Element;
126
+ export { OneTimeCode };
127
+ //# sourceMappingURL=one-time-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"one-time-code.d.ts","sourceRoot":"","sources":["../../../src/components/ui/one-time-code.tsx"],"names":[],"mappings":"AAOA,qFAAqF;AACrF,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAA;CACpC;AAED,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAA;IACd;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,cAAc,GAAG,MAAM,CAAA;IAC1D;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACrC;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IACxC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,mBAAmB,CAAA;IAC9B,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,0CAA0C;IAC1C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,qFAAqF;IACrF,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,0EAA0E;IAC1E,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6CAA6C;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uDAAuD;IACvD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,mBAAmB;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,iBAAS,WAAW,CAAC,EACnB,KAAK,EACL,MAAM,EACN,UAAsB,EACtB,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,KAAK,EACL,YAAY,EACZ,aAAa,EACb,UAAU,EACV,SAAS,EACT,UAAkB,EAClB,IAAY,EACZ,QAAgB,EAChB,QAAgB,EAChB,QAAgB,EAChB,IAAI,EACJ,IAAI,EACJ,EAAE,EACF,SAAS,GACV,EAAE,gBAAgB,+BA0ElB;AAED,OAAO,EAAE,WAAW,EAAE,CAAA"}
@@ -0,0 +1,57 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { OTPField as OTPFieldPrimitive } from '@base-ui/react/otp-field';
4
+ import { Fragment, useId } from 'react';
5
+ import { cn } from '../../lib/utils.js';
6
+ /**
7
+ * A verification code entered one segment at a time.
8
+ *
9
+ * **A paste of the whole code lands in every segment.** A reader who has the code
10
+ * on their clipboard has already done the hard part, and a field that accepted one
11
+ * character per paste would make them retype it one box at a time, which is what
12
+ * they are on their phone to avoid. So a paste into the first segment is
13
+ * distributed across the ones after it and `onComplete` fires once, from the paste,
14
+ * rather than after six keystrokes.
15
+ *
16
+ * **A refused character is refused, not stored.** Whitespace is dropped and
17
+ * anything outside `characters` is refused, whether it was typed or pasted, so
18
+ * "123 456" pastes as `123456` and `12345a6` pastes as `123456`. The alternative,
19
+ * accepting the text and rejecting it at the server, gives the reader a field
20
+ * that looks right and a form that does not submit.
21
+ *
22
+ * **The code is one value, not six.** The segments are six views of one string of
23
+ * `length` characters, so Backspace removes a character from the string and the
24
+ * characters after it close up: on `123456`, Backspace in the third segment leaves
25
+ * `12456`. Six boxes that each had to be emptied by hand would need a rule for
26
+ * what Backspace on an empty box means, and every version of that rule is wrong
27
+ * for somebody. The rule that does nothing traps a reader who is correcting a
28
+ * digit; the rule that clears the box before deletes a character they did not ask
29
+ * to delete.
30
+ *
31
+ * **The character set, the normaliser and the words are all the caller's.** Which
32
+ * characters a code may contain is decided by the service that issued it, folding
33
+ * case is a rule only the caller knows, and every segment's accessible name is a
34
+ * phrase. Nothing here is a table of words or a regular expression.
35
+ *
36
+ * **The first segment is named by a real `<label>`, and it is hidden.** Base UI
37
+ * strips `aria-label` from that one segment on purpose: it is the segment the
38
+ * platform autofills, and the label element is what names the autofill prompt as
39
+ * well as the field. This Component renders that label visually hidden, because a
40
+ * label above a row of six boxes is the caller's to place. Pass `id` and put your
41
+ * own `Label` on the first segment, and this one steps aside.
42
+ *
43
+ * **One Tab stop for the whole code.** A reader reaches the first segment and the
44
+ * rest follow as they type, so the code is one stop in a form rather than six, and
45
+ * the segments are a named group rather than six fields in a row. It is built on
46
+ * Base UI's OTP field, which owns the segmentation, the clamping to `length` and
47
+ * the autofill hint the platform needs for a one-time code.
48
+ */
49
+ function OneTimeCode({ label, length, characters = 'numeric', normalize, segmentLabel, grouping, value, defaultValue, onValueChange, onComplete, onInvalid, autoSubmit = false, mask = false, disabled = false, required = false, readOnly = false, name, form, id, className, }) {
50
+ const generated = useId();
51
+ const firstId = id ?? generated;
52
+ const boundary = (index) => grouping?.after.includes(index) === true;
53
+ return (_jsxs(OTPFieldPrimitive.Root, { "data-slot": "one-time-code", className: cn('flex items-center justify-center gap-2', className), length: length, validationType: characters, ...(normalize === undefined ? null : { normalizeValue: normalize }), ...(value === undefined ? {} : { value }), ...(defaultValue === undefined ? {} : { defaultValue }), onValueChange: (next) => onValueChange?.(next), onValueComplete: (next) => onComplete?.(next), onValueInvalid: (attempted) => onInvalid?.(attempted), autoSubmit: autoSubmit, mask: mask, disabled: disabled, required: required, readOnly: readOnly, name: name, ...(form === undefined ? null : { form }), id: firstId, "aria-label": label, children: [id === undefined ? (_jsx("label", { htmlFor: firstId, className: "sr-only", children: label })) : null, Array.from({ length }, (_, index) => (_jsxs(Fragment, { children: [_jsx(OTPFieldPrimitive.Input, { "data-slot": "one-time-code-input", ...(index === 0
54
+ ? null
55
+ : { 'aria-label': segmentLabel === undefined ? label : segmentLabel(index) }), className: cn('border-input bg-background text-foreground h-11 w-9 rounded-md border text-center text-base tabular-nums outline-none', 'transition-[color,box-shadow] duration-fast ease-out', 'focus-visible:border-ring focus-visible:ring-ring focus-visible:ring-[3px]', 'disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50', 'pointer-coarse:size-11') }), boundary(index) ? (_jsx("span", { "data-slot": "one-time-code-separator", "aria-hidden": "true", className: "text-muted-foreground shrink-0 text-base", children: grouping?.separator })) : null] }, index)))] }));
56
+ }
57
+ export { OneTimeCode };
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { ChevronLeft, ChevronRight, MoreHorizontal } from 'lucide-react';
3
- import { cn } from '../../lib/utils';
3
+ import { cn } from '../../lib/utils.js';
4
4
  /**
5
5
  * The control that moves between pages of a paged collection.
6
6
  *
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Popover as PopoverPrimitive } from '@base-ui/react/popover';
4
- import { cn } from '../../lib/utils';
4
+ import { cn } from '../../lib/utils.js';
5
5
  /**
6
6
  * A floating surface opened by a trigger.
7
7
  *
@@ -1,4 +1,4 @@
1
- import type { PackId } from '../../theming';
1
+ import type { PackId } from '../../theming/index.js';
2
2
  /**
3
3
  * The three sizes a product mark is drawn at: the mark's diameter and the name
4
4
  * beside it, taken together so the two parts of the mark stay in proportion.
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from '../../lib/utils';
2
+ import { cn } from '../../lib/utils.js';
3
3
  /**
4
4
  * The full spectrum, as the five series tokens and nothing else.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  import type { ComponentProps } from 'react';
2
- import { type ProductMarkProps, type ProductMarkSize } from './product-mark';
2
+ import { type ProductMarkProps, type ProductMarkSize } from './product-mark.js';
3
3
  /**
4
4
  * One product in the set a switcher moves between.
5
5
  *
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { ProductMark } from './product-mark';
3
- import { cn } from '../../lib/utils';
2
+ import { ProductMark } from './product-mark.js';
3
+ import { cn } from '../../lib/utils.js';
4
4
  /**
5
5
  * A switch between the members of a set of products.
6
6
  *
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Progress as ProgressPrimitive } from '@base-ui/react/progress';
4
- import { cn } from '../../lib/utils';
4
+ import { cn } from '../../lib/utils.js';
5
5
  /**
6
6
  * A bar that reports how far a task has progressed.
7
7
  *
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import { cn } from '../../lib/utils';
2
+ import { cn } from '../../lib/utils.js';
3
3
  /**
4
4
  * The size a run of prose is set at.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from '../../lib/utils';
2
+ import { cn } from '../../lib/utils.js';
3
3
  /**
4
4
  * The canvas the graph draws into, in its own user units.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { cn } from '../../lib/utils';
2
+ import { cn } from '../../lib/utils.js';
3
3
  /**
4
4
  * The canvas the series draws into, in its own user units.
5
5
  *
@@ -3,7 +3,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
3
3
  import { Radio as RadioPrimitive } from '@base-ui/react/radio';
4
4
  import { RadioGroup as RadioGroupPrimitive } from '@base-ui/react/radio-group';
5
5
  import { CircleIcon } from 'lucide-react';
6
- import { cn } from '../../lib/utils';
6
+ import { cn } from '../../lib/utils.js';
7
7
  /**
8
8
  * A set of radio items where exactly one may be chosen.
9
9
  *
@@ -0,0 +1,129 @@
1
+ import { type ComponentProps, type ReactNode } from 'react';
2
+ /**
3
+ * The divider's position, as a percentage along the group's main axis.
4
+ *
5
+ * A percentage rather than a pixel count because the group is a proportion of
6
+ * whatever the page gives it, and a divider measured in pixels is wrong the
7
+ * moment the window is resized or the group is put in a narrower column. A
8
+ * percentage is wrong for one case and that case is a pane whose content must
9
+ * not reflow, and a caller who needs one is measuring their content rather than
10
+ * asking for a split.
11
+ */
12
+ type Position = number;
13
+ /** How the panes are laid out, and therefore which pair of arrows moves a divider. */
14
+ type ResizableOrientation = 'horizontal' | 'vertical';
15
+ /** The props the Resizable group accepts. */
16
+ export interface ResizableProps extends Omit<ComponentProps<'div'>, 'onChange'> {
17
+ /**
18
+ * The accessible name of the group.
19
+ *
20
+ * Required rather than defaulted, because a resizable is announced as two
21
+ * panes with a divider between them, and two unnamed panes side by side are a
22
+ * page where a reader is told "region" twice and cannot tell which is which.
23
+ */
24
+ label: string;
25
+ /** Whether the panes sit side by side or stacked. @defaultValue horizontal */
26
+ orientation?: ResizableOrientation;
27
+ /**
28
+ * The divider's starting position, as a percentage along the main axis.
29
+ * @defaultValue 50
30
+ */
31
+ defaultPosition?: Position;
32
+ /**
33
+ * The controlled divider position, as a percentage along the main axis.
34
+ *
35
+ * The position is a prop and a callback rather than something the group keeps
36
+ * to itself, and that is the decision this Component makes: **a split is
37
+ * worth remembering, and this Component will not remember it for you.** A
38
+ * reader who drags a sidebar to where their work fits and comes back to a
39
+ * reset split has been told the preference did not count, and the honest fix is
40
+ * the caller reading this and persisting it, because a design system cannot
41
+ * know a reader's storage, cannot know which of a reader's panes this one is,
42
+ * and cannot know whether a second reader of the same account wants the same
43
+ * number. Pass the stored value back as `position` and this is a controlled
44
+ * group with no storage of its own anywhere.
45
+ */
46
+ position?: Position;
47
+ /** Called when the divider moves, with the new position. */
48
+ onPositionChange?: (position: Position) => void;
49
+ /** Whether the divider ignores user interaction. @defaultValue false */
50
+ disabled?: boolean;
51
+ /** The panes and the divider between them. */
52
+ children?: ReactNode;
53
+ }
54
+ /** The props ResizablePanel accepts. */
55
+ export interface ResizablePanelProps extends ComponentProps<'div'> {
56
+ /** The pane's share of the group, as a percentage. @defaultValue 50 */
57
+ size?: Position;
58
+ }
59
+ /**
60
+ * Two panes with a divider between them that both a pointer and a keyboard move.
61
+ *
62
+ * **The divider is the Component, and everything about it is a decision a
63
+ * consumer would otherwise make badly.** It is an ARIA separator that is
64
+ * focusable, so the split is operable without a pointer at all, and it reports
65
+ * `aria-valuenow` as the position along the split, so a reader is told where the
66
+ * divider is rather than only being able to feel it. Arrow keys move it by a
67
+ * small step, Home takes it to one end and End to the other, and both are
68
+ * clamped, so a reader who holds the key stops at the end rather than pushing a
69
+ * pane to nothing and being unable to get it back.
70
+ *
71
+ * **It remembers nothing across a reload, and that is deliberate.** The position
72
+ * is a prop and a callback, so a caller who wants a reader's split to survive a
73
+ * reload persists it and passes it back, and a design system that wrote to a
74
+ * reader's storage unasked would be making a claim about the product it does not
75
+ * know. The failure this prevents is a sidebar that silently resets, which is the
76
+ * same class of defect as a control that forgets a setting the reader chose and
77
+ * nobody can explain.
78
+ *
79
+ * **A divider has a name and it is the caller's word.** There is no default,
80
+ * because a default would be the same word on every divider on every page and
81
+ * would be true of none of them.
82
+ *
83
+ * This is the one Component here that is not composed on a Base UI primitive,
84
+ * because Base UI 1.8.0 ships none: the package has no `Resizable` in it, so the
85
+ * separator role, the focusable-divider keyboard model and the drag are authored
86
+ * here rather than wrapped. Every other overlay in this batch is composed, and a
87
+ * hand-rolled focus trap or portal would be a second and worse answer; a divider
88
+ * is none of those five things.
89
+ */
90
+ declare function Resizable({ className, label, orientation, defaultPosition, position: positionProp, onPositionChange, disabled, ...props }: ResizableProps): import("react").JSX.Element;
91
+ /**
92
+ * One pane of the split.
93
+ *
94
+ * `size` is a prop rather than something computed from the content, because a
95
+ * pane whose width depends on what is in it is how a split ends up reporting a
96
+ * different position after a reload than before one, and the divider is measured
97
+ * against a box the reader cannot predict.
98
+ */
99
+ declare function ResizablePanel({ className, size, style, ...props }: ResizablePanelProps): import("react").JSX.Element;
100
+ /**
101
+ * The divider, and the whole of the Component's behaviour.
102
+ *
103
+ * A focusable ARIA separator with a value, so the split is operable and
104
+ * announced: `role="separator"`, `aria-valuenow` for the position, and
105
+ * `aria-orientation` for the axis, which is what tells a reader whether the left
106
+ * and right arrows or the up and down ones are the ones to press.
107
+ */
108
+ declare function ResizableHandle({ className, label, onKeyDown, ...props }: ResizableHandleProps): import("react").JSX.Element;
109
+ /**
110
+ * The props ResizableHandle accepts.
111
+ *
112
+ * The `label` is required for the same reason the group's is, and it is a prop
113
+ * rather than a default because there is no honest default: a divider named
114
+ * "Resize" in a page with a file tree, a preview and a comment thread tells a
115
+ * reader nothing about which one they are holding, and the words that would
116
+ * tell them are the words for that product's panes.
117
+ */
118
+ export interface ResizableHandleProps extends Omit<ComponentProps<'div'>, 'onChange'> {
119
+ /**
120
+ * The accessible name of this divider.
121
+ *
122
+ * Required. A divider with no name is announced as "separator", and a page
123
+ * with three of them is a page where a screen reader user cannot tell which
124
+ * one they are about to move.
125
+ */
126
+ label: string;
127
+ }
128
+ export { Resizable, ResizablePanel, ResizableHandle };
129
+ //# sourceMappingURL=resizable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resizable.d.ts","sourceRoot":"","sources":["../../../src/components/ui/resizable.tsx"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,cAAc,EAGnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAA;AAId;;;;;;;;;GASG;AACH,KAAK,QAAQ,GAAG,MAAM,CAAA;AAEtB,sFAAsF;AACtF,KAAK,oBAAoB,GAAG,YAAY,GAAG,UAAU,CAAA;AAgDrD,6CAA6C;AAC7C,MAAM,WAAW,cAAe,SAAQ,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IAC7E;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,8EAA8E;IAC9E,WAAW,CAAC,EAAE,oBAAoB,CAAA;IAClC;;;OAGG;IACH,eAAe,CAAC,EAAE,QAAQ,CAAA;IAC1B;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,4DAA4D;IAC5D,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAA;IAC/C,wEAAwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,wCAAwC;AACxC,MAAM,WAAW,mBAAoB,SAAQ,cAAc,CAAC,KAAK,CAAC;IAChE,uEAAuE;IACvE,IAAI,CAAC,EAAE,QAAQ,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,iBAAS,SAAS,CAAC,EACjB,SAAS,EACT,KAAK,EACL,WAA0B,EAC1B,eAAoB,EACpB,QAAQ,EAAE,YAAY,EACtB,gBAAgB,EAChB,QAAgB,EAChB,GAAG,KAAK,EACT,EAAE,cAAc,+BA0FhB;AAED;;;;;;;GAOG;AACH,iBAAS,cAAc,CAAC,EAAE,SAAS,EAAE,IAAS,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE,mBAAmB,+BAoBrF;AAED;;;;;;;GAOG;AACH,iBAAS,eAAe,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,KAAK,EAAE,EAAE,oBAAoB,+BA8FvF;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC;IACnF;;;;;;OAMG;IACH,KAAK,EAAE,MAAM,CAAA;CACd;AAED,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,eAAe,EAAE,CAAA"}
@@ -0,0 +1,205 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useCallback, useContext, useMemo, useRef, useState, } from 'react';
4
+ import { cn } from '../../lib/utils.js';
5
+ /** The window the divider may travel in, as a percentage of the group. */
6
+ const MIN = 10;
7
+ const MAX = 90;
8
+ /** How far one arrow-key press moves the divider, as a percentage of the group. */
9
+ const STEP = 5;
10
+ const ResizableContext = createContext(null);
11
+ /**
12
+ * The group context, which a pane and a divider are both children of.
13
+ *
14
+ * The part name is a machine value and lowercase on purpose: it reaches a
15
+ * developer in a console and never a reader, and the gate that refuses shipped
16
+ * copy cannot tell a part's own name from a sentence. The diagnostic is the
17
+ * house's own shape, an error thrown when a caller has composed a part outside
18
+ * the group it belongs to, and the useful half of it is what to do about it.
19
+ */
20
+ function useResizableContext(part) {
21
+ const context = useContext(ResizableContext);
22
+ if (context === null) {
23
+ throw new Error(`Resizable: the ${part} must be rendered inside a Resizable, because the split is owned by the group and neither part can know it on its own.`);
24
+ }
25
+ return context;
26
+ }
27
+ /**
28
+ * Two panes with a divider between them that both a pointer and a keyboard move.
29
+ *
30
+ * **The divider is the Component, and everything about it is a decision a
31
+ * consumer would otherwise make badly.** It is an ARIA separator that is
32
+ * focusable, so the split is operable without a pointer at all, and it reports
33
+ * `aria-valuenow` as the position along the split, so a reader is told where the
34
+ * divider is rather than only being able to feel it. Arrow keys move it by a
35
+ * small step, Home takes it to one end and End to the other, and both are
36
+ * clamped, so a reader who holds the key stops at the end rather than pushing a
37
+ * pane to nothing and being unable to get it back.
38
+ *
39
+ * **It remembers nothing across a reload, and that is deliberate.** The position
40
+ * is a prop and a callback, so a caller who wants a reader's split to survive a
41
+ * reload persists it and passes it back, and a design system that wrote to a
42
+ * reader's storage unasked would be making a claim about the product it does not
43
+ * know. The failure this prevents is a sidebar that silently resets, which is the
44
+ * same class of defect as a control that forgets a setting the reader chose and
45
+ * nobody can explain.
46
+ *
47
+ * **A divider has a name and it is the caller's word.** There is no default,
48
+ * because a default would be the same word on every divider on every page and
49
+ * would be true of none of them.
50
+ *
51
+ * This is the one Component here that is not composed on a Base UI primitive,
52
+ * because Base UI 1.8.0 ships none: the package has no `Resizable` in it, so the
53
+ * separator role, the focusable-divider keyboard model and the drag are authored
54
+ * here rather than wrapped. Every other overlay in this batch is composed, and a
55
+ * hand-rolled focus trap or portal would be a second and worse answer; a divider
56
+ * is none of those five things.
57
+ */
58
+ function Resizable({ className, label, orientation = 'horizontal', defaultPosition = 50, position: positionProp, onPositionChange, disabled = false, ...props }) {
59
+ const [internal, setInternal] = useState(defaultPosition);
60
+ const [dragging, setDragging] = useState(false);
61
+ const group = useRef(null);
62
+ const { ref: callerRef, ...rest } = props;
63
+ // Both refs, rather than mine and then the caller's. The drag measures the
64
+ // pointer against this element's box, so a caller who forwarded a ref and
65
+ // silently replaced ours would get a divider the keyboard moves and the pointer
66
+ // does not, which is a split that only half works.
67
+ const setGroup = useCallback((element) => {
68
+ group.current = element;
69
+ if (typeof callerRef === 'function')
70
+ callerRef(element);
71
+ else if (callerRef !== null && callerRef !== undefined)
72
+ callerRef.current = element;
73
+ }, [callerRef]);
74
+ const controlled = positionProp !== undefined;
75
+ const position = controlled ? positionProp : internal;
76
+ /**
77
+ * The position every move is measured from, kept in a ref rather than read
78
+ * from the rendered value.
79
+ *
80
+ * This is the whole of the keyboard model and it is not a style choice. A
81
+ * reader who holds ArrowRight produces four key events before React has
82
+ * re-rendered, and a move that read the rendered position each time would see
83
+ * the same number four times and travel one step instead of four. The divider
84
+ * would then feel broken to exactly the reader using it the way it is meant to
85
+ * be used, and a drag would run behind the pointer.
86
+ */
87
+ const latest = useRef(position);
88
+ latest.current = position;
89
+ const moveTo = useCallback((next) => {
90
+ if (disabled)
91
+ return;
92
+ const clamped = Math.min(MAX, Math.max(MIN, next));
93
+ latest.current = clamped;
94
+ if (!controlled)
95
+ setInternal(clamped);
96
+ onPositionChange?.(clamped);
97
+ }, [controlled, disabled, onPositionChange]);
98
+ const moveBy = useCallback((delta) => {
99
+ if (disabled)
100
+ return;
101
+ moveTo(latest.current + delta);
102
+ }, [disabled, moveTo]);
103
+ const value = useMemo(() => ({
104
+ orientation,
105
+ position,
106
+ moveTo,
107
+ moveBy,
108
+ min: MIN,
109
+ max: MAX,
110
+ disabled,
111
+ dragging,
112
+ setDragging,
113
+ groupElement: () => group.current,
114
+ }), [orientation, position, moveTo, moveBy, disabled, dragging]);
115
+ return (_jsx(ResizableContext.Provider, { value: value, children: _jsx("div", { "data-slot": "resizable", role: "group", "aria-label": label, "data-orientation": orientation, "data-dragging": dragging ? 'true' : undefined, ref: setGroup, className: cn('flex h-full w-full', orientation === 'vertical' ? 'flex-col' : 'flex-row', 'data-[dragging]:select-none', className), ...rest }) }));
116
+ }
117
+ /**
118
+ * One pane of the split.
119
+ *
120
+ * `size` is a prop rather than something computed from the content, because a
121
+ * pane whose width depends on what is in it is how a split ends up reporting a
122
+ * different position after a reload than before one, and the divider is measured
123
+ * against a box the reader cannot predict.
124
+ */
125
+ function ResizablePanel({ className, size = 50, style, ...props }) {
126
+ const { orientation, disabled } = useResizableContext('panel');
127
+ return (_jsx("div", { "data-slot": "resizable-panel", "data-orientation": orientation, "data-disabled": disabled ? 'true' : undefined, style: {
128
+ flexBasis: `${size}%`,
129
+ flexGrow: 0,
130
+ flexShrink: 0,
131
+ minWidth: 0,
132
+ minHeight: 0,
133
+ ...style,
134
+ }, className: cn('overflow-hidden', className), ...props }));
135
+ }
136
+ /**
137
+ * The divider, and the whole of the Component's behaviour.
138
+ *
139
+ * A focusable ARIA separator with a value, so the split is operable and
140
+ * announced: `role="separator"`, `aria-valuenow` for the position, and
141
+ * `aria-orientation` for the axis, which is what tells a reader whether the left
142
+ * and right arrows or the up and down ones are the ones to press.
143
+ */
144
+ function ResizableHandle({ className, label, onKeyDown, ...props }) {
145
+ const { orientation, position, moveTo, moveBy, min, max, disabled, dragging, setDragging, groupElement, } = useResizableContext('divider');
146
+ const last = useRef(null);
147
+ const onPointerDown = (event) => {
148
+ if (disabled || event.button !== 0)
149
+ return;
150
+ event.currentTarget.setPointerCapture(event.pointerId);
151
+ // The pointer's own coordinate, and not the divider's, because a drag is a
152
+ // distance travelled and the first event is a press rather than a move.
153
+ last.current = orientation === 'horizontal' ? event.clientX : event.clientY;
154
+ setDragging(true);
155
+ };
156
+ const onPointerMove = (event) => {
157
+ if (last.current === null)
158
+ return;
159
+ const box = groupElement()?.getBoundingClientRect();
160
+ if (box === undefined)
161
+ return;
162
+ // Measured along the group's own axis, so a horizontal split follows the x
163
+ // and a vertical one follows the y, and a caller that passes the wrong
164
+ // `orientation` cannot get a divider that tracks the wrong coordinate.
165
+ const here = orientation === 'horizontal' ? event.clientX : event.clientY;
166
+ const delta = here - last.current;
167
+ const travel = orientation === 'horizontal' ? box.width : box.height;
168
+ if (travel === 0)
169
+ return;
170
+ moveBy((delta / travel) * 100);
171
+ last.current = here;
172
+ };
173
+ const endDrag = (event) => {
174
+ if (last.current === null)
175
+ return;
176
+ event.currentTarget.releasePointerCapture(event.pointerId);
177
+ last.current = null;
178
+ setDragging(false);
179
+ };
180
+ const onKey = (event) => {
181
+ if (disabled)
182
+ return;
183
+ const decrease = orientation === 'horizontal' ? 'ArrowLeft' : 'ArrowUp';
184
+ const increase = orientation === 'horizontal' ? 'ArrowRight' : 'ArrowDown';
185
+ if (event.key === decrease)
186
+ moveBy(-STEP);
187
+ else if (event.key === increase)
188
+ moveBy(STEP);
189
+ else if (event.key === 'Home')
190
+ moveTo(min);
191
+ else if (event.key === 'End')
192
+ moveTo(max);
193
+ else
194
+ return;
195
+ // Only the keys this Component owns are prevented, so a reader who binds
196
+ // something else to the divider still gets it.
197
+ event.preventDefault();
198
+ event.stopPropagation();
199
+ };
200
+ return (_jsx("div", { "data-slot": "resizable-handle", role: "separator", "aria-label": label, "aria-orientation": orientation, "aria-valuenow": Math.round(position), "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled ? 'true' : undefined, tabIndex: disabled ? -1 : 0, "data-orientation": orientation, "data-dragging": dragging ? 'true' : undefined, onPointerDown: onPointerDown, onPointerMove: onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag, onKeyDown: (event) => {
201
+ onKey(event);
202
+ onKeyDown?.(event);
203
+ }, className: cn('bg-border relative shrink-0 touch-none outline-none', orientation === 'vertical' ? 'h-px w-full cursor-row-resize' : 'h-full w-px cursor-col-resize', 'transition-colors duration-fast ease-out', 'hover:bg-ring focus-visible:bg-ring data-[dragging]:bg-ring', 'focus-visible:ring-ring focus-visible:ring-[3px]', 'data-[disabled]:pointer-events-none data-[disabled]:opacity-50', className), ...props }));
204
+ }
205
+ export { Resizable, ResizablePanel, ResizableHandle };