@cueplusplus/ui 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/dist/charts/_token.js +39 -0
  2. package/dist/charts/container.d.ts +58 -0
  3. package/dist/charts/container.js +77 -0
  4. package/dist/charts/index.d.ts +5 -0
  5. package/dist/charts/index.js +5 -0
  6. package/dist/charts/ramps.d.ts +140 -0
  7. package/dist/charts/ramps.js +615 -0
  8. package/dist/charts/theme.d.ts +112 -0
  9. package/dist/charts/theme.js +165 -0
  10. package/dist/charts/tones.d.ts +111 -0
  11. package/dist/charts/tones.js +127 -0
  12. package/dist/chat/_glyphs.js +55 -0
  13. package/dist/chat/agent-color.d.ts +84 -0
  14. package/dist/chat/agent-color.js +101 -0
  15. package/dist/chat/agent-pile.d.ts +55 -0
  16. package/dist/chat/agent-pile.js +121 -0
  17. package/dist/chat/ask-box.d.ts +88 -0
  18. package/dist/chat/ask-box.js +341 -0
  19. package/dist/chat/composer.d.ts +66 -0
  20. package/dist/chat/composer.js +144 -0
  21. package/dist/chat/delegation-card.d.ts +60 -0
  22. package/dist/chat/delegation-card.js +129 -0
  23. package/dist/chat/index.d.ts +8 -0
  24. package/dist/chat/index.js +8 -0
  25. package/dist/chat/message-list.d.ts +39 -0
  26. package/dist/chat/message-list.js +105 -0
  27. package/dist/chat/message.d.ts +47 -0
  28. package/dist/chat/message.js +108 -0
  29. package/dist/chrome/_glyphs.js +101 -0
  30. package/dist/chrome/_tabs-scroll.d.ts +62 -0
  31. package/dist/chrome/_tabs-scroll.js +68 -0
  32. package/dist/chrome/_tree.d.ts +75 -0
  33. package/dist/chrome/_tree.js +49 -0
  34. package/dist/chrome/empty-state.d.ts +37 -0
  35. package/dist/chrome/empty-state.js +57 -0
  36. package/dist/chrome/eyebrow.d.ts +29 -0
  37. package/dist/chrome/eyebrow.js +36 -0
  38. package/dist/chrome/index.d.ts +17 -0
  39. package/dist/chrome/index.js +17 -0
  40. package/dist/chrome/navigation-menu.d.ts +80 -0
  41. package/dist/chrome/navigation-menu.js +121 -0
  42. package/dist/chrome/page-shell.d.ts +38 -0
  43. package/dist/chrome/page-shell.js +66 -0
  44. package/dist/chrome/panel.d.ts +55 -0
  45. package/dist/chrome/panel.js +67 -0
  46. package/dist/chrome/row.d.ts +82 -0
  47. package/dist/chrome/row.js +106 -0
  48. package/dist/chrome/scroll-area.d.ts +39 -0
  49. package/dist/chrome/scroll-area.js +70 -0
  50. package/dist/chrome/section-header.d.ts +42 -0
  51. package/dist/chrome/section-header.js +79 -0
  52. package/dist/chrome/segmented-control.d.ts +58 -0
  53. package/dist/chrome/segmented-control.js +76 -0
  54. package/dist/chrome/status-bar.d.ts +46 -0
  55. package/dist/chrome/status-bar.js +56 -0
  56. package/dist/chrome/tabs.d.ts +80 -0
  57. package/dist/chrome/tabs.js +176 -0
  58. package/dist/chrome/title-bar.d.ts +37 -0
  59. package/dist/chrome/title-bar.js +45 -0
  60. package/dist/chrome/toolbar.d.ts +46 -0
  61. package/dist/chrome/toolbar.js +62 -0
  62. package/dist/chrome/tree.d.ts +98 -0
  63. package/dist/chrome/tree.js +248 -0
  64. package/dist/color/_checker.js +14 -0
  65. package/dist/color/_convert.d.ts +52 -0
  66. package/dist/color/_convert.js +66 -0
  67. package/dist/color/_glyphs.js +28 -0
  68. package/dist/color/_thumb.js +15 -0
  69. package/dist/color/_value.js +28 -0
  70. package/dist/color/color-area.d.ts +27 -0
  71. package/dist/color/color-area.js +40 -0
  72. package/dist/color/color-field.d.ts +32 -0
  73. package/dist/color/color-field.js +43 -0
  74. package/dist/color/color-picker.d.ts +71 -0
  75. package/dist/color/color-picker.js +178 -0
  76. package/dist/color/color-slider.d.ts +31 -0
  77. package/dist/color/color-slider.js +51 -0
  78. package/dist/color/color-swatch.d.ts +32 -0
  79. package/dist/color/color-swatch.js +44 -0
  80. package/dist/color/index.d.ts +7 -0
  81. package/dist/color/index.js +7 -0
  82. package/dist/configurator/_export.d.ts +78 -0
  83. package/dist/configurator/_export.js +261 -0
  84. package/dist/configurator/_glyphs.js +92 -0
  85. package/dist/configurator/_overrides.d.ts +247 -0
  86. package/dist/configurator/_overrides.js +514 -0
  87. package/dist/configurator/configurator.d.ts +71 -0
  88. package/dist/configurator/configurator.js +279 -0
  89. package/dist/configurator/export-dialog.d.ts +30 -0
  90. package/dist/configurator/export-dialog.js +121 -0
  91. package/dist/configurator/index.d.ts +8 -0
  92. package/dist/configurator/index.js +8 -0
  93. package/dist/configurator/panel-sections.d.ts +86 -0
  94. package/dist/configurator/panel-sections.js +316 -0
  95. package/dist/configurator/token-editor.d.ts +74 -0
  96. package/dist/configurator/token-editor.js +149 -0
  97. package/dist/configurator/use-zoom.d.ts +87 -0
  98. package/dist/configurator/use-zoom.js +113 -0
  99. package/dist/date/_glyphs.js +34 -0
  100. package/dist/date/_segments.js +55 -0
  101. package/dist/date/_trigger.js +31 -0
  102. package/dist/date/calendar.d.ts +25 -0
  103. package/dist/date/calendar.js +125 -0
  104. package/dist/date/date-field.d.ts +34 -0
  105. package/dist/date/date-field.js +41 -0
  106. package/dist/date/date-picker.d.ts +69 -0
  107. package/dist/date/date-picker.js +89 -0
  108. package/dist/date/date-range-picker.d.ts +65 -0
  109. package/dist/date/date-range-picker.js +92 -0
  110. package/dist/date/index.d.ts +6 -0
  111. package/dist/date/index.js +6 -0
  112. package/dist/date/time-field.d.ts +29 -0
  113. package/dist/date/time-field.js +36 -0
  114. package/dist/dmx/_ramp.d.ts +77 -0
  115. package/dist/dmx/_ramp.js +169 -0
  116. package/dist/dmx/_readout.js +53 -0
  117. package/dist/dmx/_universe.d.ts +105 -0
  118. package/dist/dmx/_universe.js +112 -0
  119. package/dist/dmx/channel-matrix.d.ts +81 -0
  120. package/dist/dmx/channel-matrix.js +285 -0
  121. package/dist/dmx/dmx-bar.d.ts +50 -0
  122. package/dist/dmx/dmx-bar.js +107 -0
  123. package/dist/dmx/dmx-strip.d.ts +41 -0
  124. package/dist/dmx/dmx-strip.js +196 -0
  125. package/dist/dmx/index.d.ts +7 -0
  126. package/dist/dmx/index.js +7 -0
  127. package/dist/dmx/universe-grid.d.ts +61 -0
  128. package/dist/dmx/universe-grid.js +182 -0
  129. package/dist/flow/_frame.d.ts +52 -0
  130. package/dist/flow/_frame.js +38 -0
  131. package/dist/flow/controls.d.ts +41 -0
  132. package/dist/flow/controls.js +53 -0
  133. package/dist/flow/flow.css +121 -0
  134. package/dist/flow/handles.d.ts +40 -0
  135. package/dist/flow/handles.js +61 -0
  136. package/dist/flow/index.d.ts +7 -0
  137. package/dist/flow/index.js +7 -0
  138. package/dist/flow/node-card.d.ts +71 -0
  139. package/dist/flow/node-card.js +102 -0
  140. package/dist/flow/signal-edge.d.ts +60 -0
  141. package/dist/flow/signal-edge.js +108 -0
  142. package/dist/flow/use-flow-theme.d.ts +69 -0
  143. package/dist/flow/use-flow-theme.js +109 -0
  144. package/dist/forms/_chassis.d.ts +64 -0
  145. package/dist/forms/_chassis.js +59 -0
  146. package/dist/forms/_glyphs.js +143 -0
  147. package/dist/forms/_listbox.js +55 -0
  148. package/dist/forms/autocomplete.d.ts +61 -0
  149. package/dist/forms/autocomplete.js +88 -0
  150. package/dist/forms/button-group.d.ts +47 -0
  151. package/dist/forms/button-group.js +52 -0
  152. package/dist/forms/checkbox.d.ts +51 -0
  153. package/dist/forms/checkbox.js +98 -0
  154. package/dist/forms/combobox.d.ts +73 -0
  155. package/dist/forms/combobox.js +108 -0
  156. package/dist/forms/env-var-input.d.ts +74 -0
  157. package/dist/forms/env-var-input.js +116 -0
  158. package/dist/forms/field.d.ts +89 -0
  159. package/dist/forms/field.js +102 -0
  160. package/dist/forms/file-upload.d.ts +113 -0
  161. package/dist/forms/file-upload.js +232 -0
  162. package/dist/forms/index.d.ts +26 -0
  163. package/dist/forms/index.js +26 -0
  164. package/dist/forms/input-group.d.ts +31 -0
  165. package/dist/forms/input-group.js +54 -0
  166. package/dist/forms/input.d.ts +33 -0
  167. package/dist/forms/input.js +36 -0
  168. package/dist/forms/multi-select.d.ts +62 -0
  169. package/dist/forms/multi-select.js +107 -0
  170. package/dist/forms/number-field.d.ts +38 -0
  171. package/dist/forms/number-field.js +64 -0
  172. package/dist/forms/otp-field.d.ts +54 -0
  173. package/dist/forms/otp-field.js +59 -0
  174. package/dist/forms/password-input.d.ts +46 -0
  175. package/dist/forms/password-input.js +62 -0
  176. package/dist/forms/radio-group.d.ts +50 -0
  177. package/dist/forms/radio-group.js +64 -0
  178. package/dist/forms/rating.d.ts +69 -0
  179. package/dist/forms/rating.js +103 -0
  180. package/dist/forms/scrub-input.d.ts +81 -0
  181. package/dist/forms/scrub-input.js +249 -0
  182. package/dist/forms/search-input.d.ts +54 -0
  183. package/dist/forms/search-input.js +112 -0
  184. package/dist/forms/select.d.ts +75 -0
  185. package/dist/forms/select.js +91 -0
  186. package/dist/forms/slider.d.ts +44 -0
  187. package/dist/forms/slider.js +65 -0
  188. package/dist/forms/switch.d.ts +36 -0
  189. package/dist/forms/switch.js +71 -0
  190. package/dist/forms/tags-input.d.ts +69 -0
  191. package/dist/forms/tags-input.js +148 -0
  192. package/dist/forms/textarea.d.ts +27 -0
  193. package/dist/forms/textarea.js +37 -0
  194. package/dist/forms/toggle-group.d.ts +41 -0
  195. package/dist/forms/toggle-group.js +56 -0
  196. package/dist/forms/toggle.d.ts +41 -0
  197. package/dist/forms/toggle.js +100 -0
  198. package/dist/index.d.ts +112 -0
  199. package/dist/index.js +104 -0
  200. package/dist/instruments/_ansi.js +116 -0
  201. package/dist/instruments/_glyphs.js +90 -0
  202. package/dist/instruments/_motion.js +56 -0
  203. package/dist/instruments/_rem.js +21 -0
  204. package/dist/instruments/app-window-frame.d.ts +48 -0
  205. package/dist/instruments/app-window-frame.js +76 -0
  206. package/dist/instruments/copy-button.d.ts +41 -0
  207. package/dist/instruments/copy-button.js +112 -0
  208. package/dist/instruments/data-table.d.ts +168 -0
  209. package/dist/instruments/data-table.js +212 -0
  210. package/dist/instruments/group-bar.d.ts +63 -0
  211. package/dist/instruments/group-bar.js +122 -0
  212. package/dist/instruments/index.d.ts +13 -0
  213. package/dist/instruments/index.js +13 -0
  214. package/dist/instruments/log-viewer.d.ts +74 -0
  215. package/dist/instruments/log-viewer.js +215 -0
  216. package/dist/instruments/meter.d.ts +77 -0
  217. package/dist/instruments/meter.js +96 -0
  218. package/dist/instruments/progress.d.ts +45 -0
  219. package/dist/instruments/progress.js +61 -0
  220. package/dist/instruments/seam-grid.d.ts +66 -0
  221. package/dist/instruments/seam-grid.js +78 -0
  222. package/dist/instruments/sparkline.d.ts +39 -0
  223. package/dist/instruments/sparkline.js +85 -0
  224. package/dist/instruments/stat.d.ts +35 -0
  225. package/dist/instruments/stat.js +59 -0
  226. package/dist/instruments/table.d.ts +51 -0
  227. package/dist/instruments/table.js +92 -0
  228. package/dist/instruments/terminal-frame.d.ts +89 -0
  229. package/dist/instruments/terminal-frame.js +256 -0
  230. package/dist/instruments/two-step-button.d.ts +47 -0
  231. package/dist/instruments/two-step-button.js +147 -0
  232. package/dist/instruments/usage-chart.d.ts +55 -0
  233. package/dist/instruments/usage-chart.js +235 -0
  234. package/dist/layout/_collapse.js +46 -0
  235. package/dist/layout/_glyphs.js +45 -0
  236. package/dist/layout/accordion.d.ts +52 -0
  237. package/dist/layout/accordion.js +81 -0
  238. package/dist/layout/breadcrumb.d.ts +35 -0
  239. package/dist/layout/breadcrumb.js +67 -0
  240. package/dist/layout/card.d.ts +51 -0
  241. package/dist/layout/card.js +76 -0
  242. package/dist/layout/carousel.d.ts +96 -0
  243. package/dist/layout/carousel.js +211 -0
  244. package/dist/layout/collapsible.d.ts +74 -0
  245. package/dist/layout/collapsible.js +126 -0
  246. package/dist/layout/container.d.ts +27 -0
  247. package/dist/layout/container.js +40 -0
  248. package/dist/layout/description-list.d.ts +24 -0
  249. package/dist/layout/description-list.js +37 -0
  250. package/dist/layout/grid.d.ts +40 -0
  251. package/dist/layout/grid.js +48 -0
  252. package/dist/layout/index.d.ts +15 -0
  253. package/dist/layout/index.js +15 -0
  254. package/dist/layout/item.d.ts +65 -0
  255. package/dist/layout/item.js +100 -0
  256. package/dist/layout/link.d.ts +48 -0
  257. package/dist/layout/link.js +63 -0
  258. package/dist/layout/pagination.d.ts +54 -0
  259. package/dist/layout/pagination.js +121 -0
  260. package/dist/layout/resizable.d.ts +38 -0
  261. package/dist/layout/resizable.js +68 -0
  262. package/dist/layout/sidebar.d.ts +67 -0
  263. package/dist/layout/sidebar.js +129 -0
  264. package/dist/layout/stack.d.ts +46 -0
  265. package/dist/layout/stack.js +62 -0
  266. package/dist/layout/stepper.d.ts +49 -0
  267. package/dist/layout/stepper.js +81 -0
  268. package/dist/layout/timeline.d.ts +43 -0
  269. package/dist/layout/timeline.js +63 -0
  270. package/dist/lib/aria-class.js +24 -0
  271. package/dist/lib/cn.js +18 -0
  272. package/dist/lib/compose.js +38 -0
  273. package/dist/lib/cva.d.ts +18 -0
  274. package/dist/lib/cva.js +65 -0
  275. package/dist/midi/_notes.d.ts +101 -0
  276. package/dist/midi/_notes.js +183 -0
  277. package/dist/midi/_ruler.d.ts +100 -0
  278. package/dist/midi/_ruler.js +105 -0
  279. package/dist/midi/_time.d.ts +107 -0
  280. package/dist/midi/_time.js +130 -0
  281. package/dist/midi/index.d.ts +9 -0
  282. package/dist/midi/index.js +9 -0
  283. package/dist/midi/musical-time-input.d.ts +48 -0
  284. package/dist/midi/musical-time-input.js +154 -0
  285. package/dist/midi/piano-keyboard.d.ts +50 -0
  286. package/dist/midi/piano-keyboard.js +193 -0
  287. package/dist/midi/spectrum-visualizer.d.ts +65 -0
  288. package/dist/midi/spectrum-visualizer.js +213 -0
  289. package/dist/midi/threshold-rail.d.ts +72 -0
  290. package/dist/midi/threshold-rail.js +214 -0
  291. package/dist/midi/timeline-ruler.d.ts +83 -0
  292. package/dist/midi/timeline-ruler.js +152 -0
  293. package/dist/overlays/_debounce.js +34 -0
  294. package/dist/overlays/_glyphs.js +59 -0
  295. package/dist/overlays/_surface.d.ts +70 -0
  296. package/dist/overlays/_surface.js +70 -0
  297. package/dist/overlays/_wheel.js +42 -0
  298. package/dist/overlays/alert-dialog.d.ts +67 -0
  299. package/dist/overlays/alert-dialog.js +117 -0
  300. package/dist/overlays/command-palette.d.ts +93 -0
  301. package/dist/overlays/command-palette.js +193 -0
  302. package/dist/overlays/context-menu.d.ts +64 -0
  303. package/dist/overlays/context-menu.js +78 -0
  304. package/dist/overlays/dialog.d.ts +72 -0
  305. package/dist/overlays/dialog.js +124 -0
  306. package/dist/overlays/drawer.d.ts +75 -0
  307. package/dist/overlays/drawer.js +151 -0
  308. package/dist/overlays/dropdown-menu.d.ts +79 -0
  309. package/dist/overlays/dropdown-menu.js +156 -0
  310. package/dist/overlays/hover-card.d.ts +58 -0
  311. package/dist/overlays/hover-card.js +91 -0
  312. package/dist/overlays/index.d.ts +15 -0
  313. package/dist/overlays/index.js +15 -0
  314. package/dist/overlays/info-tip.d.ts +41 -0
  315. package/dist/overlays/info-tip.js +45 -0
  316. package/dist/overlays/menubar.d.ts +72 -0
  317. package/dist/overlays/menubar.js +100 -0
  318. package/dist/overlays/popover.d.ts +66 -0
  319. package/dist/overlays/popover.js +114 -0
  320. package/dist/overlays/sheet.d.ts +78 -0
  321. package/dist/overlays/sheet.js +131 -0
  322. package/dist/overlays/toast.d.ts +106 -0
  323. package/dist/overlays/toast.js +146 -0
  324. package/dist/overlays/tooltip.d.ts +57 -0
  325. package/dist/overlays/tooltip.js +95 -0
  326. package/dist/primitives/avatar.d.ts +51 -0
  327. package/dist/primitives/avatar.js +93 -0
  328. package/dist/primitives/button.d.ts +46 -0
  329. package/dist/primitives/button.js +94 -0
  330. package/dist/primitives/chip.d.ts +47 -0
  331. package/dist/primitives/chip.js +152 -0
  332. package/dist/primitives/icon-button.d.ts +41 -0
  333. package/dist/primitives/icon-button.js +59 -0
  334. package/dist/primitives/index.d.ts +10 -0
  335. package/dist/primitives/index.js +10 -0
  336. package/dist/primitives/kbd.d.ts +17 -0
  337. package/dist/primitives/kbd.js +24 -0
  338. package/dist/primitives/separator.d.ts +25 -0
  339. package/dist/primitives/separator.js +30 -0
  340. package/dist/primitives/skeleton.d.ts +20 -0
  341. package/dist/primitives/skeleton.js +27 -0
  342. package/dist/primitives/spinner.d.ts +26 -0
  343. package/dist/primitives/spinner.js +31 -0
  344. package/dist/primitives/status-dot.d.ts +44 -0
  345. package/dist/primitives/status-dot.js +50 -0
  346. package/dist/styles.css +19 -0
  347. package/dist/system/density.d.ts +33 -0
  348. package/dist/system/density.js +49 -0
  349. package/dist/system/index.d.ts +8 -0
  350. package/dist/system/index.js +7 -0
  351. package/dist/system/portal.d.ts +51 -0
  352. package/dist/system/portal.js +122 -0
  353. package/dist/system/prepaint.d.ts +38 -0
  354. package/dist/system/prepaint.js +37 -0
  355. package/dist/system/theme-provider.d.ts +72 -0
  356. package/dist/system/theme-provider.js +252 -0
  357. package/dist/system/use-density.d.ts +33 -0
  358. package/dist/system/use-density.js +84 -0
  359. package/dist/system/use-isomorphic-layout-effect.js +15 -0
  360. package/dist/system/use-theme.d.ts +19 -0
  361. package/dist/system/use-theme.js +25 -0
  362. package/dist/theming/_presets.d.ts +11 -0
  363. package/dist/theming/_presets.js +487 -0
  364. package/dist/theming/contrast.d.ts +110 -0
  365. package/dist/theming/contrast.js +167 -0
  366. package/dist/theming/create-theme.d.ts +165 -0
  367. package/dist/theming/create-theme.js +442 -0
  368. package/dist/theming/index.d.ts +5 -0
  369. package/dist/theming/index.js +5 -0
  370. package/dist/theming/serialize.d.ts +145 -0
  371. package/dist/theming/serialize.js +165 -0
  372. package/package.json +216 -0
@@ -0,0 +1,37 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import * as React from "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/layout/description-list.tsx
5
+ const LAYOUTS = {
6
+ inline: "grid grid-cols-[max-content_minmax(0,1fr)] gap-x-(--cue-space-5) gap-y-(--cue-space-2)",
7
+ stacked: "flex flex-col gap-(--cue-space-3)"
8
+ };
9
+ /** The `<dl>` family: {@link DescriptionListRoot}, `Term` and `Detail`. */
10
+ const DescriptionList = {
11
+ Root: React.forwardRef(function DescriptionListRoot({ className, layout = "inline", ...elementProps }, ref) {
12
+ return /* @__PURE__ */ jsx("dl", {
13
+ ref,
14
+ "data-slot": "description-list",
15
+ className: cn(LAYOUTS[layout], className),
16
+ ...elementProps
17
+ });
18
+ }),
19
+ Term: React.forwardRef(function DescriptionListTerm({ className, ...elementProps }, ref) {
20
+ return /* @__PURE__ */ jsx("dt", {
21
+ ref,
22
+ "data-slot": "description-list-term",
23
+ className: cn("font-mono text-(length:--cue-text-label) tracking-[0.15em] text-fg-subtle uppercase", className),
24
+ ...elementProps
25
+ });
26
+ }),
27
+ Detail: React.forwardRef(function DescriptionListDetail({ className, ...elementProps }, ref) {
28
+ return /* @__PURE__ */ jsx("dd", {
29
+ ref,
30
+ "data-slot": "description-list-detail",
31
+ className: cn("m-0 font-mono text-(length:--cue-text-ui) text-fg", className),
32
+ ...elementProps
33
+ });
34
+ })
35
+ };
36
+ //#endregion
37
+ export { DescriptionList };
@@ -0,0 +1,40 @@
1
+ import { SpaceStep, StackAlign, StackJustify } from "./stack.js";
2
+ import * as React from "react";
3
+ //#region src/layout/grid.d.ts
4
+ /** How many equal columns to lay out. */
5
+ type GridColumns = 1 | 2 | 3 | 4 | 5 | 6;
6
+ interface GridProps extends React.ComponentPropsWithoutRef<"div"> {
7
+ /** How many equal columns. Defaults to `1`. Ignored when `minItemWidth` is set. */
8
+ cols?: GridColumns;
9
+ /** Which rung of the density space ladder to spend between cells. Defaults to `4`. */
10
+ gap?: SpaceStep;
11
+ /**
12
+ * Fill the row with as many columns of at least this width as fit, instead of
13
+ * a fixed count. Any CSS length (`"12rem"`, `"200px"`).
14
+ *
15
+ * Prefer this over a column count wherever the content has a natural minimum
16
+ * measure — it is responsive without a single breakpoint.
17
+ */
18
+ minItemWidth?: string;
19
+ /** Cross-axis alignment of the cells. */
20
+ align?: StackAlign;
21
+ /** Main-axis distribution of the tracks. */
22
+ justify?: StackJustify;
23
+ }
24
+ /**
25
+ * Two-dimensional layout: equal columns, or as many as fit.
26
+ *
27
+ * Same bargain as `Stack` — the gap is a rung of the density ladder rather than
28
+ * a hand-picked pixel value, so a card grid tightens with the rest of the
29
+ * console when the user asks for ultra-compact.
30
+ *
31
+ * Static markup — no `"use client"`.
32
+ *
33
+ * @example
34
+ * <Grid cols={3} gap={5}>{cards}</Grid>
35
+ * @example
36
+ * <Grid minItemWidth="14rem" gap={4}>{cards}</Grid>
37
+ */
38
+ declare const Grid: React.ForwardRefExoticComponent<GridProps & React.RefAttributes<HTMLDivElement>>;
39
+ //#endregion
40
+ export { Grid, GridColumns, GridProps };
@@ -0,0 +1,48 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import { ALIGN_CLASSES, GAP_CLASSES, JUSTIFY_CLASSES } from "./stack.js";
3
+ import * as React from "react";
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/layout/grid.tsx
6
+ /** Static class per count — Tailwind scans source text, not computed strings. */
7
+ const COLUMN_CLASSES = {
8
+ 1: "grid-cols-1",
9
+ 2: "grid-cols-2",
10
+ 3: "grid-cols-3",
11
+ 4: "grid-cols-4",
12
+ 5: "grid-cols-5",
13
+ 6: "grid-cols-6"
14
+ };
15
+ /**
16
+ * The auto-filling track. The measure travels as a custom property rather than
17
+ * as an arbitrary value, so the track definition is one static class the
18
+ * scanner always sees instead of a fresh one per call site.
19
+ */
20
+ const AUTO_FILL_CLASS = "grid-cols-[repeat(auto-fill,minmax(var(--cue-grid-min),1fr))]";
21
+ /**
22
+ * Two-dimensional layout: equal columns, or as many as fit.
23
+ *
24
+ * Same bargain as `Stack` — the gap is a rung of the density ladder rather than
25
+ * a hand-picked pixel value, so a card grid tightens with the rest of the
26
+ * console when the user asks for ultra-compact.
27
+ *
28
+ * Static markup — no `"use client"`.
29
+ *
30
+ * @example
31
+ * <Grid cols={3} gap={5}>{cards}</Grid>
32
+ * @example
33
+ * <Grid minItemWidth="14rem" gap={4}>{cards}</Grid>
34
+ */
35
+ const Grid = React.forwardRef(function Grid({ className, cols = 1, gap = 4, minItemWidth, align, justify, style, ...elementProps }, ref) {
36
+ return /* @__PURE__ */ jsx("div", {
37
+ ref,
38
+ "data-slot": "grid",
39
+ className: cn("grid", minItemWidth === void 0 ? COLUMN_CLASSES[cols] : AUTO_FILL_CLASS, GAP_CLASSES[gap], align === void 0 ? null : ALIGN_CLASSES[align], justify === void 0 ? null : JUSTIFY_CLASSES[justify], className),
40
+ style: minItemWidth === void 0 ? style : {
41
+ "--cue-grid-min": minItemWidth,
42
+ ...style
43
+ },
44
+ ...elementProps
45
+ });
46
+ });
47
+ //#endregion
48
+ export { Grid };
@@ -0,0 +1,15 @@
1
+ import { Accordion, AccordionHeaderProps, AccordionItemProps, AccordionPanelProps, AccordionRootProps, AccordionTriggerProps } from "./accordion.js";
2
+ import { Breadcrumb, BreadcrumbItem, BreadcrumbProps } from "./breadcrumb.js";
3
+ import { Card, CardContentProps, CardDescriptionProps, CardFooterProps, CardHeaderProps, CardRootProps, CardTitleProps } from "./card.js";
4
+ import { Collapsible, CollapsiblePanelProps, CollapsibleRootProps, CollapsibleTriggerProps, Disclosure, DisclosureProps } from "./collapsible.js";
5
+ import { Container, ContainerProps, ContainerWidth } from "./container.js";
6
+ import { DescriptionList, DescriptionListDetailProps, DescriptionListLayout, DescriptionListRootProps, DescriptionListTermProps } from "./description-list.js";
7
+ import { SpaceStep, Stack, StackAlign, StackJustify, StackProps } from "./stack.js";
8
+ import { Grid, GridColumns, GridProps } from "./grid.js";
9
+ import { Item, ItemProps, itemVariants } from "./item.js";
10
+ import { Link, LinkProps, linkVariants } from "./link.js";
11
+ import { Pagination, PaginationEntry, PaginationProps, paginationRange } from "./pagination.js";
12
+ import { Sidebar, SidebarItemProps, SidebarRailProps, SidebarRootProps, SidebarSectionProps, useSidebar } from "./sidebar.js";
13
+ import { Stepper, StepperProps, StepperState, StepperStep } from "./stepper.js";
14
+ import { Timeline, TimelineContentProps, TimelineItemProps, TimelineMarkerProps, TimelineRootProps } from "./timeline.js";
15
+ export { Accordion, type AccordionHeaderProps, type AccordionItemProps, type AccordionPanelProps, type AccordionRootProps, type AccordionTriggerProps, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Card, type CardContentProps, type CardDescriptionProps, type CardFooterProps, type CardHeaderProps, type CardRootProps, type CardTitleProps, Collapsible, type CollapsiblePanelProps, type CollapsibleRootProps, type CollapsibleTriggerProps, Container, type ContainerProps, type ContainerWidth, DescriptionList, type DescriptionListDetailProps, type DescriptionListLayout, type DescriptionListRootProps, type DescriptionListTermProps, Disclosure, type DisclosureProps, Grid, type GridColumns, type GridProps, Item, type ItemProps, Link, type LinkProps, Pagination, type PaginationEntry, type PaginationProps, Sidebar, type SidebarItemProps, type SidebarRailProps, type SidebarRootProps, type SidebarSectionProps, type SpaceStep, Stack, type StackAlign, type StackJustify, type StackProps, Stepper, type StepperProps, type StepperState, type StepperStep, Timeline, type TimelineContentProps, type TimelineItemProps, type TimelineMarkerProps, type TimelineRootProps, itemVariants, linkVariants, paginationRange, useSidebar };
@@ -0,0 +1,15 @@
1
+ import { Accordion } from "./accordion.js";
2
+ import { Breadcrumb } from "./breadcrumb.js";
3
+ import { Card } from "./card.js";
4
+ import { Collapsible, Disclosure } from "./collapsible.js";
5
+ import { Container } from "./container.js";
6
+ import { DescriptionList } from "./description-list.js";
7
+ import { Stack } from "./stack.js";
8
+ import { Grid } from "./grid.js";
9
+ import { Item, itemVariants } from "./item.js";
10
+ import { Link, linkVariants } from "./link.js";
11
+ import { Pagination, paginationRange } from "./pagination.js";
12
+ import { Sidebar, useSidebar } from "./sidebar.js";
13
+ import { Stepper } from "./stepper.js";
14
+ import { Timeline } from "./timeline.js";
15
+ export { Accordion, Breadcrumb, Card, Collapsible, Container, DescriptionList, Disclosure, Grid, Item, Link, Pagination, Sidebar, Stack, Stepper, Timeline, itemVariants, linkVariants, paginationRange, useSidebar };
@@ -0,0 +1,65 @@
1
+ import { ClassProp, VariantProps } from "../lib/cva.js";
2
+ import * as React from "react";
3
+ //#region src/layout/item.d.ts
4
+ /**
5
+ * The media-object recipe: an optional leading glyph, two lines of text and a
6
+ * trailing slot, on the row padding rung.
7
+ *
8
+ * Framing and hover feedback are split across `variants` for the same reason as
9
+ * `chipVariants`: emitting a fill from one variant and cancelling it from
10
+ * another would leave two competing background utilities in the class string
11
+ * and lean on `tailwind-merge` to pick a winner.
12
+ *
13
+ * @example
14
+ * <div className={itemVariants({ variant: "outline" })} />
15
+ */
16
+ declare const itemVariants: (props?: ({
17
+ variant?: "outline" | "plain" | "soft" | null | undefined;
18
+ interactive?: boolean | null | undefined;
19
+ } & ClassProp) | undefined) => string;
20
+ interface ItemProps extends Omit<React.HTMLAttributes<HTMLElement>, "title">, VariantProps<typeof itemVariants> {
21
+ /** Leading slot: an icon, an avatar, a status dot. */
22
+ media?: React.ReactNode;
23
+ /** The item's name — one line, truncated rather than wrapped. */
24
+ title?: React.ReactNode;
25
+ /** One supporting line under the title, a rung smaller and muted. */
26
+ description?: React.ReactNode;
27
+ /**
28
+ * Trailing slot: a value, a chip, a control.
29
+ *
30
+ * Do not combine with `interactive` — the whole item is then a `<button>`,
31
+ * and a button may not contain another one. Put the controls beside the item
32
+ * instead, or drop `interactive` and make the title itself the link.
33
+ */
34
+ actions?: React.ReactNode;
35
+ /** Which framing to paint. Defaults to `"plain"`. */
36
+ variant?: "plain" | "outline" | "soft";
37
+ /**
38
+ * Render as a `<button>` with hover feedback and a focus ring instead of a
39
+ * static `<div>`. Use for items that select, open or toggle something.
40
+ */
41
+ interactive?: boolean;
42
+ /** Disable the interactive form. Ignored when `interactive` is not set. */
43
+ disabled?: boolean;
44
+ /** Extra content between the text column and the action slot. */
45
+ children?: React.ReactNode;
46
+ }
47
+ /**
48
+ * One thing in a list, with room for a glyph, a name, a line of detail and a
49
+ * control — the shape a settings entry, a search hit and a device row all want.
50
+ *
51
+ * Where `Row` is a line of a hairline table, `Item` is a self-contained object
52
+ * that can stand alone, sit in a `Stack` or fill a `Grid` cell. It is a real
53
+ * `<button>` when interactive rather than a `<div>` with an `onClick`, so
54
+ * keyboard users get it for free.
55
+ *
56
+ * Static markup — no `"use client"`.
57
+ *
58
+ * @example
59
+ * <Item media={<StatusDot tone="ok" />} title="Node 12" description="10.0.0.12" />
60
+ * @example
61
+ * <Item interactive variant="outline" title="Front truss" onClick={open} />
62
+ */
63
+ declare const Item: React.ForwardRefExoticComponent<ItemProps & React.RefAttributes<HTMLElement>>;
64
+ //#endregion
65
+ export { Item, ItemProps, itemVariants };
@@ -0,0 +1,100 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import { cva } from "../lib/cva.js";
3
+ import * as React from "react";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ //#region src/layout/item.tsx
6
+ /**
7
+ * The media-object recipe: an optional leading glyph, two lines of text and a
8
+ * trailing slot, on the row padding rung.
9
+ *
10
+ * Framing and hover feedback are split across `variants` for the same reason as
11
+ * `chipVariants`: emitting a fill from one variant and cancelling it from
12
+ * another would leave two competing background utilities in the class string
13
+ * and lean on `tailwind-merge` to pick a winner.
14
+ *
15
+ * @example
16
+ * <div className={itemVariants({ variant: "outline" })} />
17
+ */
18
+ const itemVariants = cva("flex w-full items-center gap-(--cue-space-4) rounded-(--radius-control) px-(--cue-pad-row-x) py-(--cue-pad-row-y) text-left font-mono text-(length:--cue-text-ui) text-fg", {
19
+ variants: {
20
+ variant: {
21
+ plain: "",
22
+ outline: "border border-border",
23
+ soft: "bg-surface-2"
24
+ },
25
+ interactive: {
26
+ true: "cursor-pointer transition-colors duration-150 outline-none hover:bg-surface-2 focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent disabled:pointer-events-none disabled:opacity-40",
27
+ false: ""
28
+ }
29
+ },
30
+ defaultVariants: {
31
+ variant: "plain",
32
+ interactive: false
33
+ }
34
+ });
35
+ /**
36
+ * One thing in a list, with room for a glyph, a name, a line of detail and a
37
+ * control — the shape a settings entry, a search hit and a device row all want.
38
+ *
39
+ * Where `Row` is a line of a hairline table, `Item` is a self-contained object
40
+ * that can stand alone, sit in a `Stack` or fill a `Grid` cell. It is a real
41
+ * `<button>` when interactive rather than a `<div>` with an `onClick`, so
42
+ * keyboard users get it for free.
43
+ *
44
+ * Static markup — no `"use client"`.
45
+ *
46
+ * @example
47
+ * <Item media={<StatusDot tone="ok" />} title="Node 12" description="10.0.0.12" />
48
+ * @example
49
+ * <Item interactive variant="outline" title="Front truss" onClick={open} />
50
+ */
51
+ const Item = React.forwardRef(function Item({ className, media, title, description, actions, variant, interactive = false, disabled, children, ...elementProps }, ref) {
52
+ const classes = cn(itemVariants({
53
+ variant,
54
+ interactive
55
+ }), className);
56
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
57
+ media === void 0 ? null : /* @__PURE__ */ jsx("span", {
58
+ "data-slot": "item-media",
59
+ className: "flex shrink-0 items-center text-fg-muted",
60
+ children: media
61
+ }),
62
+ title === void 0 && description === void 0 ? null : /* @__PURE__ */ jsxs("span", {
63
+ "data-slot": "item-text",
64
+ className: "flex min-w-0 flex-1 flex-col gap-(--cue-space-1)",
65
+ children: [title === void 0 ? null : /* @__PURE__ */ jsx("span", {
66
+ "data-slot": "item-title",
67
+ className: "truncate text-fg",
68
+ children: title
69
+ }), description === void 0 ? null : /* @__PURE__ */ jsx("span", {
70
+ "data-slot": "item-description",
71
+ className: "truncate text-(length:--cue-text-label) text-fg-muted",
72
+ children: description
73
+ })]
74
+ }),
75
+ children,
76
+ actions === void 0 ? null : /* @__PURE__ */ jsx("span", {
77
+ "data-slot": "item-actions",
78
+ className: "flex shrink-0 items-center gap-(--cue-space-2)",
79
+ children: actions
80
+ })
81
+ ] });
82
+ if (interactive) return /* @__PURE__ */ jsx("button", {
83
+ ref,
84
+ type: "button",
85
+ disabled,
86
+ "data-slot": "item",
87
+ className: classes,
88
+ ...elementProps,
89
+ children: content
90
+ });
91
+ return /* @__PURE__ */ jsx("div", {
92
+ ref,
93
+ "data-slot": "item",
94
+ className: classes,
95
+ ...elementProps,
96
+ children: content
97
+ });
98
+ });
99
+ //#endregion
100
+ export { Item, itemVariants };
@@ -0,0 +1,48 @@
1
+ import { ClassProp, VariantProps } from "../lib/cva.js";
2
+ import * as React from "react";
3
+ import { useRender } from "@base-ui/react/use-render";
4
+ //#region src/layout/link.d.ts
5
+ /**
6
+ * The link recipe.
7
+ *
8
+ * The house rule is that a link is **not** underlined: in a console, body copy
9
+ * is rare and links are mostly labels inside dense furniture, where a rule
10
+ * under every one of them turns a panel into a page of hyperlinks. Colour on
11
+ * hover carries the affordance instead. The `underline` variant exists for the
12
+ * one place the rule is right — links inside a paragraph of prose, where colour
13
+ * alone would fail WCAG 1.4.1 — and it offsets the rule by 4px so descenders
14
+ * are not struck through.
15
+ *
16
+ * @example
17
+ * <a className={linkVariants({ variant: "underline" })} href="/docs">Docs</a>
18
+ */
19
+ declare const linkVariants: (props?: ({
20
+ variant?: "plain" | "underline" | null | undefined;
21
+ } & ClassProp) | undefined) => string;
22
+ interface LinkProps extends React.ComponentPropsWithoutRef<"a">, VariantProps<typeof linkVariants> {
23
+ /**
24
+ * Open in a new tab, mark the anchor `rel="noreferrer noopener"` and append a
25
+ * `↗`. The glyph is not decoration: a link that replaces the user's context
26
+ * without warning is a WCAG 3.2.5 failure, and the arrow is the warning.
27
+ */
28
+ external?: boolean;
29
+ /**
30
+ * Replace the rendered element (Base UI render prop). Accepts an element —
31
+ * `render={<NextLink href="/x" />}` — or a function returning one. This is
32
+ * how the design system composes with a router without depending on one.
33
+ */
34
+ render?: useRender.RenderProp;
35
+ }
36
+ /**
37
+ * A text link: accent on hover, no rule unless you ask for one.
38
+ *
39
+ * @example
40
+ * <Link href="/patch">Patch</Link>
41
+ * @example
42
+ * <Link href="https://base-ui.com" external variant="underline">Base UI</Link>
43
+ * @example
44
+ * <Link render={<NextLink href="/cues" />}>Cues</Link>
45
+ */
46
+ declare const Link: React.ForwardRefExoticComponent<LinkProps & React.RefAttributes<HTMLAnchorElement>>;
47
+ //#endregion
48
+ export { Link, LinkProps, linkVariants };
@@ -0,0 +1,63 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { cva } from "../lib/cva.js";
4
+ import * as React from "react";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+ import { useRender } from "@base-ui/react/use-render";
7
+ //#region src/layout/link.tsx
8
+ /**
9
+ * The link recipe.
10
+ *
11
+ * The house rule is that a link is **not** underlined: in a console, body copy
12
+ * is rare and links are mostly labels inside dense furniture, where a rule
13
+ * under every one of them turns a panel into a page of hyperlinks. Colour on
14
+ * hover carries the affordance instead. The `underline` variant exists for the
15
+ * one place the rule is right — links inside a paragraph of prose, where colour
16
+ * alone would fail WCAG 1.4.1 — and it offsets the rule by 4px so descenders
17
+ * are not struck through.
18
+ *
19
+ * @example
20
+ * <a className={linkVariants({ variant: "underline" })} href="/docs">Docs</a>
21
+ */
22
+ const linkVariants = cva("cursor-pointer rounded-(--radius-control) font-mono text-fg transition-colors duration-150 outline-none hover:text-accent focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-accent", {
23
+ variants: { variant: {
24
+ plain: "no-underline",
25
+ underline: "underline decoration-border underline-offset-4 hover:decoration-accent"
26
+ } },
27
+ defaultVariants: { variant: "plain" }
28
+ });
29
+ /**
30
+ * A text link: accent on hover, no rule unless you ask for one.
31
+ *
32
+ * @example
33
+ * <Link href="/patch">Patch</Link>
34
+ * @example
35
+ * <Link href="https://base-ui.com" external variant="underline">Base UI</Link>
36
+ * @example
37
+ * <Link render={<NextLink href="/cues" />}>Cues</Link>
38
+ */
39
+ const Link = React.forwardRef(function Link({ className, variant, external = false, render, children, ...elementProps }, ref) {
40
+ const externalProps = external ? {
41
+ target: "_blank",
42
+ rel: elementProps.rel ?? "noreferrer noopener"
43
+ } : null;
44
+ return useRender({
45
+ render,
46
+ ref,
47
+ defaultTagName: "a",
48
+ props: {
49
+ ...elementProps,
50
+ ...externalProps,
51
+ "data-slot": "link",
52
+ className: cn(linkVariants({ variant }), external ? "inline-flex items-center gap-(--cue-space-1)" : null, className),
53
+ children: /* @__PURE__ */ jsxs(Fragment, { children: [children, external ? /* @__PURE__ */ jsx("span", {
54
+ "data-slot": "link-external-glyph",
55
+ "aria-hidden": "true",
56
+ className: "shrink-0 text-(length:--cue-text-micro) leading-none select-none",
57
+ children: "↗"
58
+ }) : null] })
59
+ }
60
+ });
61
+ });
62
+ //#endregion
63
+ export { Link, linkVariants };
@@ -0,0 +1,54 @@
1
+ import * as React from "react";
2
+ //#region src/layout/pagination.d.ts
3
+ /** A page number, or the ellipsis standing in for a run of hidden pages. */
4
+ type PaginationEntry = number | "gap";
5
+ /**
6
+ * Which page buttons to draw for a given position in a run of pages.
7
+ *
8
+ * Exported and pure so the layout rule can be unit-tested on its own — the
9
+ * awkward cases (a window that runs off either end, a gap standing in for one
10
+ * page) are arithmetic, not rendering, and every pager that gets them wrong
11
+ * gets them wrong here.
12
+ *
13
+ * The window keeps a constant width as it travels: near either end the missing
14
+ * siblings are spent on the near side instead, so the control does not change
15
+ * size as the user pages through. A gap that would hide exactly one page is
16
+ * replaced by that page, because an ellipsis costs the same room as the number
17
+ * it is hiding.
18
+ *
19
+ * @param page The current page, 1-based.
20
+ * @param pageCount How many pages there are in total.
21
+ * @param siblingCount How many pages to show either side of the current one.
22
+ * @returns Page numbers and `"gap"` markers, in display order.
23
+ * @example
24
+ * paginationRange(10, 20) // [1, "gap", 9, 10, 11, "gap", 20]
25
+ */
26
+ declare function paginationRange(page: number, pageCount: number, siblingCount?: number): PaginationEntry[];
27
+ interface PaginationProps extends Omit<React.ComponentPropsWithoutRef<"nav">, "onChange" | "children"> {
28
+ /** The current page, 1-based. */
29
+ page: number;
30
+ /** How many pages there are in total. */
31
+ pageCount: number;
32
+ /** Called with the page a control asked for. Always within `1..pageCount`. */
33
+ onPageChange: (page: number) => void;
34
+ /** How many pages to show either side of the current one. Defaults to `1`. */
35
+ siblingCount?: number;
36
+ /** The nav's accessible name. Defaults to `"Pagination"`. */
37
+ label?: string;
38
+ }
39
+ /**
40
+ * The pager: previous, a window of page numbers, next.
41
+ *
42
+ * Renders nothing at all when there is a single page — a control offering no
43
+ * choice is chrome that says "there is more here" when there is not.
44
+ *
45
+ * Every page number is a real button with a spoken name ("Page 3"), because the
46
+ * bare numeral is meaningless read aloud out of context; the ellipses are
47
+ * `aria-hidden` for the same reason breadcrumb separators are.
48
+ *
49
+ * @example
50
+ * <Pagination page={page} pageCount={12} onPageChange={setPage} />
51
+ */
52
+ declare const Pagination: React.ForwardRefExoticComponent<PaginationProps & React.RefAttributes<HTMLElement>>;
53
+ //#endregion
54
+ export { Pagination, PaginationEntry, PaginationProps, paginationRange };
@@ -0,0 +1,121 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { ChevronLeftGlyph, ChevronRightGlyph } from "./_glyphs.js";
4
+ import { IconButton } from "../primitives/icon-button.js";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/layout/pagination.tsx
8
+ /**
9
+ * Which page buttons to draw for a given position in a run of pages.
10
+ *
11
+ * Exported and pure so the layout rule can be unit-tested on its own — the
12
+ * awkward cases (a window that runs off either end, a gap standing in for one
13
+ * page) are arithmetic, not rendering, and every pager that gets them wrong
14
+ * gets them wrong here.
15
+ *
16
+ * The window keeps a constant width as it travels: near either end the missing
17
+ * siblings are spent on the near side instead, so the control does not change
18
+ * size as the user pages through. A gap that would hide exactly one page is
19
+ * replaced by that page, because an ellipsis costs the same room as the number
20
+ * it is hiding.
21
+ *
22
+ * @param page The current page, 1-based.
23
+ * @param pageCount How many pages there are in total.
24
+ * @param siblingCount How many pages to show either side of the current one.
25
+ * @returns Page numbers and `"gap"` markers, in display order.
26
+ * @example
27
+ * paginationRange(10, 20) // [1, "gap", 9, 10, 11, "gap", 20]
28
+ */
29
+ function paginationRange(page, pageCount, siblingCount = 1) {
30
+ if (pageCount < 1) return [];
31
+ const run = (from, to) => Array.from({ length: Math.max(to - from + 1, 0) }, (_, index) => from + index);
32
+ if (pageCount <= siblingCount * 2 + 5) return run(1, pageCount);
33
+ const left = Math.max(page - siblingCount, 1);
34
+ const right = Math.min(page + siblingCount, pageCount);
35
+ const gapLeft = left > 2;
36
+ const gapRight = right < pageCount - 1;
37
+ const edgeRun = siblingCount * 2 + 3;
38
+ const entries = gapLeft ? gapRight ? [
39
+ 1,
40
+ "gap",
41
+ ...run(left, right),
42
+ "gap",
43
+ pageCount
44
+ ] : [
45
+ 1,
46
+ "gap",
47
+ ...run(pageCount - edgeRun + 1, pageCount)
48
+ ] : [
49
+ ...run(1, edgeRun),
50
+ "gap",
51
+ pageCount
52
+ ];
53
+ return entries.map((entry, index) => {
54
+ if (entry !== "gap") return entry;
55
+ const before = entries[index - 1];
56
+ const after = entries[index + 1];
57
+ return typeof before === "number" && typeof after === "number" && after - before === 2 ? before + 1 : entry;
58
+ });
59
+ }
60
+ /**
61
+ * One page button: a square on the short rung of the control ladder, tinted
62
+ * with `accent-soft` when it is the page you are on — never a solid accent
63
+ * fill, which at console density reads as a second, louder button.
64
+ */
65
+ const PAGE_BUTTON_CLASSES = "inline-flex h-control-sm min-w-control-sm cursor-pointer items-center justify-center rounded-(--radius-control) border-0 bg-transparent px-(--cue-space-2) font-mono text-(length:--cue-text-ui) tabular-nums text-fg-muted transition-colors duration-150 outline-none select-none hover:bg-surface-2 hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-1 focus-visible:outline-accent";
66
+ /**
67
+ * The pager: previous, a window of page numbers, next.
68
+ *
69
+ * Renders nothing at all when there is a single page — a control offering no
70
+ * choice is chrome that says "there is more here" when there is not.
71
+ *
72
+ * Every page number is a real button with a spoken name ("Page 3"), because the
73
+ * bare numeral is meaningless read aloud out of context; the ellipses are
74
+ * `aria-hidden` for the same reason breadcrumb separators are.
75
+ *
76
+ * @example
77
+ * <Pagination page={page} pageCount={12} onPageChange={setPage} />
78
+ */
79
+ const Pagination = React.forwardRef(function Pagination({ className, page, pageCount, onPageChange, siblingCount = 1, label = "Pagination", ...elementProps }, ref) {
80
+ if (pageCount <= 1) return null;
81
+ const entries = paginationRange(page, pageCount, siblingCount);
82
+ return /* @__PURE__ */ jsxs("nav", {
83
+ ref,
84
+ "data-slot": "pagination",
85
+ "aria-label": label,
86
+ className: cn("flex items-center gap-(--cue-space-1)", className),
87
+ ...elementProps,
88
+ children: [
89
+ /* @__PURE__ */ jsx(IconButton, {
90
+ "aria-label": "Previous page",
91
+ icon: ChevronLeftGlyph,
92
+ size: "sm",
93
+ disabled: page <= 1,
94
+ onClick: () => onPageChange(page - 1)
95
+ }),
96
+ entries.map((entry, index) => entry === "gap" ? /* @__PURE__ */ jsx("span", {
97
+ "data-slot": "pagination-gap",
98
+ "aria-hidden": "true",
99
+ className: "inline-flex h-control-sm items-center justify-center px-(--cue-space-1) font-mono text-(length:--cue-text-ui) text-fg-subtle select-none",
100
+ children: "…"
101
+ }, `gap-${index}`) : /* @__PURE__ */ jsx("button", {
102
+ type: "button",
103
+ "data-slot": "pagination-page",
104
+ "aria-label": `Page ${entry}`,
105
+ "aria-current": entry === page ? "page" : void 0,
106
+ onClick: () => onPageChange(entry),
107
+ className: cn(PAGE_BUTTON_CLASSES, entry === page ? "bg-accent-soft text-accent" : null),
108
+ children: entry
109
+ }, entry)),
110
+ /* @__PURE__ */ jsx(IconButton, {
111
+ "aria-label": "Next page",
112
+ icon: ChevronRightGlyph,
113
+ size: "sm",
114
+ disabled: page >= pageCount,
115
+ onClick: () => onPageChange(page + 1)
116
+ })
117
+ ]
118
+ });
119
+ });
120
+ //#endregion
121
+ export { Pagination, paginationRange };
@@ -0,0 +1,38 @@
1
+ import * as React from "react";
2
+ import { Group, Panel, Separator } from "react-resizable-panels";
3
+ //#region src/layout/resizable.d.ts
4
+ /** Which way the panels are laid out. */
5
+ type ResizableOrientation = "horizontal" | "vertical";
6
+ interface ResizableGroupProps extends React.ComponentProps<typeof Group> {}
7
+ interface ResizablePanelProps extends React.ComponentProps<typeof Panel> {}
8
+ interface ResizableHandleProps extends React.ComponentProps<typeof Separator> {
9
+ /**
10
+ * Draw a short grip line down the middle of the handle.
11
+ *
12
+ * A 4px strip that only colours on hover is easy to miss on first sight; the
13
+ * grip is the standing hint that the seam is draggable, for the price of one
14
+ * hairline.
15
+ */
16
+ withGrip?: boolean;
17
+ }
18
+ /**
19
+ * Split panes the user can drag, on `react-resizable-panels`.
20
+ *
21
+ * `react-resizable-panels` is an **optional peer**: import this from
22
+ * `@cueplusplus/ui/layout/resizable`, never from the core barrel, so an app
23
+ * with no split view never installs one.
24
+ *
25
+ * @example
26
+ * <Resizable.Group orientation="horizontal">
27
+ * <Resizable.Panel id="tree" defaultSize={25} minSize={15}>…</Resizable.Panel>
28
+ * <Resizable.Handle withGrip />
29
+ * <Resizable.Panel id="editor">…</Resizable.Panel>
30
+ * </Resizable.Group>
31
+ */
32
+ declare const Resizable: {
33
+ Group: React.ForwardRefExoticComponent<ResizableGroupProps & React.RefAttributes<HTMLDivElement>>;
34
+ Panel: React.ForwardRefExoticComponent<ResizablePanelProps & React.RefAttributes<HTMLDivElement>>;
35
+ Handle: React.ForwardRefExoticComponent<ResizableHandleProps & React.RefAttributes<HTMLDivElement>>;
36
+ };
37
+ //#endregion
38
+ export { Resizable, ResizableGroupProps, ResizableHandleProps, ResizableOrientation, ResizablePanelProps };