@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,235 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { toRem } from "./_rem.js";
4
+ import * as React from "react";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+ //#region src/instruments/usage-chart.tsx
7
+ const TONE_CLASSES = {
8
+ accent: "text-accent",
9
+ ok: "text-ok",
10
+ busy: "text-busy",
11
+ warn: "text-warn",
12
+ danger: "text-danger",
13
+ info: "text-info"
14
+ };
15
+ /**
16
+ * Fixed viewBox width. The SVG stretches to its container, so the internal
17
+ * width can be a constant and the path maths stays integer-friendly.
18
+ */
19
+ const VIEW_WIDTH = 600;
20
+ /** Room for the axis labels, in viewBox units, without a layout pass. */
21
+ const PAD = {
22
+ top: 6,
23
+ right: 4,
24
+ bottom: 14,
25
+ left: 22
26
+ };
27
+ /** The horizontal rules. 0 and 100 are the ceiling and the floor; the rest are guides. */
28
+ const GRID_LINES = [
29
+ 0,
30
+ 25,
31
+ 50,
32
+ 75,
33
+ 100
34
+ ];
35
+ /** Default plot height in px at the 16px root. */
36
+ const DEFAULT_HEIGHT_PX = 120;
37
+ /** Default hole width before the line breaks: one missed quarter-hourly sweep. */
38
+ const DEFAULT_GAP_MS = 9e5;
39
+ /** Axis label size, in viewBox units — not a token, because the viewBox is not in rem. */
40
+ const AXIS_FONT_SIZE = 8;
41
+ /** Sorted, finite samples split into runs no wider than `gapMs`. */
42
+ function segment(points, gapMs) {
43
+ const clean = points.filter((point) => Number.isFinite(point.t) && Number.isFinite(point.v) && point.t >= 0).sort((a, b) => a.t - b.t);
44
+ if (clean.length === 0) return [];
45
+ const runs = [];
46
+ let run = [clean[0]];
47
+ for (let index = 1; index < clean.length; index += 1) {
48
+ const point = clean[index];
49
+ const previous = clean[index - 1];
50
+ if (point.t - previous.t > gapMs) {
51
+ runs.push(run);
52
+ run = [];
53
+ }
54
+ run.push(point);
55
+ }
56
+ runs.push(run);
57
+ return runs;
58
+ }
59
+ /**
60
+ * A quota trace: where you sit against the ceiling, over time.
61
+ *
62
+ * Dependency-free inline SVG — a charting library is a large price for one
63
+ * line and five gridlines, and none of them draws the three things that make
64
+ * this chart honest:
65
+ *
66
+ * 1. **The y axis is always 0–100.** A quota chart auto-scaled to its own range
67
+ * makes a flat 3% look identical to a flat 95%. The ceiling is the reading,
68
+ * so the ceiling is always drawn.
69
+ * 2. **Gaps are gaps.** When the sweep does not run, the line breaks. Joining
70
+ * across a hole invents data — and worse, invents a *smooth* trend across
71
+ * exactly the window nothing is known about. The area fill stops at the
72
+ * break for the same reason.
73
+ * 3. **Out-of-range values are clamped, not plotted.** Upstream numbers are
74
+ * reverse-engineered and can be anything; 140% should read as a flat line on
75
+ * the ceiling, not as a path drawn over the axis labels.
76
+ *
77
+ * @example
78
+ * <UsageChart label="API requests" points={series} threshold={80} tone="warn" />
79
+ */
80
+ const UsageChart = React.forwardRef(function UsageChart({ className, points, tone = "accent", height = DEFAULT_HEIGHT_PX, gapMs = DEFAULT_GAP_MS, threshold, label, emptyLabel = "No data yet", formatTimestamp, formatValue = (value) => `${Math.round(value)}%`, ...elementProps }, ref) {
81
+ const gradientId = React.useId();
82
+ const [hover, setHover] = React.useState(null);
83
+ const segments = React.useMemo(() => segment(points, gapMs), [points, gapMs]);
84
+ const plotWidth = VIEW_WIDTH - PAD.left - PAD.right;
85
+ const plotHeight = height - PAD.top - PAD.bottom;
86
+ const floor = PAD.top + plotHeight;
87
+ const all = React.useMemo(() => segments.flat(), [segments]);
88
+ const first = all[0];
89
+ const last = all[all.length - 1];
90
+ const start = first?.t ?? 0;
91
+ const span = Math.max(1, (last?.t ?? start + 1) - start);
92
+ const round = (value) => Math.round(value * 100) / 100;
93
+ const x = (t) => round(PAD.left + (t - start) / span * plotWidth);
94
+ const y = (value) => round(PAD.top + (1 - Math.min(100, Math.max(0, value)) / 100) * plotHeight);
95
+ if (segments.length === 0) return /* @__PURE__ */ jsx("div", {
96
+ ref,
97
+ "data-slot": "usage-chart",
98
+ "data-empty": "true",
99
+ className: cn("flex items-center justify-center font-mono text-(length:--cue-text-label) text-fg-subtle", className),
100
+ style: { height: toRem(height) },
101
+ ...elementProps,
102
+ children: emptyLabel
103
+ });
104
+ const linePath = (run) => run.map((point, index) => `${index === 0 ? "M" : "L"}${x(point.t).toFixed(1)},${y(point.v).toFixed(1)}`).join(" ");
105
+ const areaPath = (run) => `${linePath(run)} L${x(run[run.length - 1].t).toFixed(1)},${floor.toFixed(1)} L${x(run[0].t).toFixed(1)},${floor.toFixed(1)} Z`;
106
+ const onMove = (event) => {
107
+ const box = event.currentTarget.getBoundingClientRect();
108
+ if (box.width === 0) return;
109
+ const viewX = (event.clientX - box.left) / box.width * VIEW_WIDTH;
110
+ const t = start + (viewX - PAD.left) / plotWidth * span;
111
+ let nearest = all[0];
112
+ for (const point of all) if (Math.abs(point.t - t) < Math.abs(nearest.t - t)) nearest = point;
113
+ setHover({
114
+ x: viewX,
115
+ point: nearest
116
+ });
117
+ };
118
+ return /* @__PURE__ */ jsxs("div", {
119
+ ref,
120
+ "data-slot": "usage-chart",
121
+ className: cn("relative min-w-0", className),
122
+ ...elementProps,
123
+ children: [/* @__PURE__ */ jsxs("svg", {
124
+ role: "img",
125
+ "aria-label": label ?? "Usage over time",
126
+ "data-tone": tone,
127
+ viewBox: `0 0 ${VIEW_WIDTH} ${height}`,
128
+ preserveAspectRatio: "none",
129
+ className: cn("block w-full", TONE_CLASSES[tone]),
130
+ style: { height: toRem(height) },
131
+ onMouseMove: onMove,
132
+ onMouseLeave: () => setHover(null),
133
+ children: [
134
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("linearGradient", {
135
+ id: gradientId,
136
+ x1: "0",
137
+ y1: "0",
138
+ x2: "0",
139
+ y2: "1",
140
+ children: [/* @__PURE__ */ jsx("stop", {
141
+ offset: "0%",
142
+ stopColor: "currentColor",
143
+ stopOpacity: "0.22"
144
+ }), /* @__PURE__ */ jsx("stop", {
145
+ offset: "100%",
146
+ stopColor: "currentColor",
147
+ stopOpacity: "0"
148
+ })]
149
+ }) }),
150
+ /* @__PURE__ */ jsx("g", {
151
+ className: "text-border",
152
+ children: GRID_LINES.map((value) => /* @__PURE__ */ jsx("line", {
153
+ "data-slot": "usage-chart-grid",
154
+ x1: PAD.left,
155
+ x2: VIEW_WIDTH - PAD.right,
156
+ y1: y(value),
157
+ y2: y(value),
158
+ stroke: "currentColor",
159
+ strokeWidth: "0.5",
160
+ opacity: value === 0 || value === 100 ? .9 : .45
161
+ }, value))
162
+ }),
163
+ /* @__PURE__ */ jsx("g", {
164
+ className: "fill-fg-subtle font-mono",
165
+ children: GRID_LINES.map((value) => /* @__PURE__ */ jsx("text", {
166
+ "data-slot": "usage-chart-axis",
167
+ x: PAD.left - 4,
168
+ y: y(value) + 3,
169
+ textAnchor: "end",
170
+ fontSize: AXIS_FONT_SIZE,
171
+ children: value
172
+ }, value))
173
+ }),
174
+ threshold === void 0 ? null : /* @__PURE__ */ jsx("line", {
175
+ "data-slot": "usage-chart-threshold",
176
+ className: "text-danger",
177
+ x1: PAD.left,
178
+ x2: VIEW_WIDTH - PAD.right,
179
+ y1: y(threshold),
180
+ y2: y(threshold),
181
+ stroke: "currentColor",
182
+ strokeWidth: "0.75",
183
+ strokeDasharray: "3 3",
184
+ opacity: "0.7"
185
+ }),
186
+ segments.map((run, index) => /* @__PURE__ */ jsxs("g", { children: [run.length > 1 ? /* @__PURE__ */ jsx("path", {
187
+ "data-slot": "usage-chart-area",
188
+ d: areaPath(run),
189
+ fill: `url(#${gradientId})`
190
+ }) : null, /* @__PURE__ */ jsx("path", {
191
+ "data-slot": "usage-chart-line",
192
+ d: linePath(run),
193
+ fill: "none",
194
+ stroke: "currentColor",
195
+ strokeWidth: "1.25",
196
+ strokeLinejoin: "round",
197
+ strokeLinecap: "round",
198
+ vectorEffect: "non-scaling-stroke"
199
+ })] }, index)),
200
+ hover === null ? null : /* @__PURE__ */ jsxs("g", {
201
+ pointerEvents: "none",
202
+ children: [/* @__PURE__ */ jsx("line", {
203
+ "data-slot": "usage-chart-crosshair",
204
+ className: "text-fg",
205
+ x1: x(hover.point.t),
206
+ x2: x(hover.point.t),
207
+ y1: PAD.top,
208
+ y2: floor,
209
+ stroke: "currentColor",
210
+ strokeWidth: "0.5",
211
+ opacity: "0.5"
212
+ }), /* @__PURE__ */ jsx("circle", {
213
+ "data-slot": "usage-chart-marker",
214
+ cx: x(hover.point.t),
215
+ cy: y(hover.point.v),
216
+ r: "2.5",
217
+ fill: "currentColor"
218
+ })]
219
+ })
220
+ ]
221
+ }), hover === null ? null : /* @__PURE__ */ jsx("div", {
222
+ "data-slot": "usage-chart-tooltip",
223
+ className: "pointer-events-none absolute top-0 -translate-x-1/2 rounded-(--radius-control) border border-border-overlay bg-surface-2 px-(--cue-space-3) py-(--cue-space-1) font-mono text-(length:--cue-text-label) tabular-nums text-fg",
224
+ style: { left: `${Math.min(88, Math.max(2, hover.x / VIEW_WIDTH * 100))}%` },
225
+ children: `${formatValue(hover.point.v)} · ${formatTimestamp === void 0 ? new Date(hover.point.t).toLocaleString(void 0, {
226
+ month: "short",
227
+ day: "numeric",
228
+ hour: "2-digit",
229
+ minute: "2-digit"
230
+ }) : formatTimestamp(hover.point.t)}`
231
+ })]
232
+ });
233
+ });
234
+ //#endregion
235
+ export { UsageChart };
@@ -0,0 +1,46 @@
1
+ //#region src/layout/_collapse.ts
2
+ /**
3
+ * The one disclosure recipe, shared by `Accordion` and `Collapsible`.
4
+ *
5
+ * Both wrap a Base UI primitive that speaks the same state vocabulary
6
+ * (`data-panel-open` on the trigger, a measured `--*-panel-height` on the
7
+ * panel), so the skin is written once here rather than twice — a change to how
8
+ * a section opens is then a one-line change, and the tests can assert the same
9
+ * recipe on both.
10
+ *
11
+ * @internal Not part of the public API.
12
+ */
13
+ /**
14
+ * The summary row: one rung of the density control ladder, mono, padded to the
15
+ * same gutters as a `Row` so a stack of sections lines up with a stack of rows.
16
+ *
17
+ * `focus-visible:outline-solid` re-declares the outline style the sibling
18
+ * `outline-none` switched off — see the note on `buttonChassis`. The ring is
19
+ * inset (`-outline-offset-2`) because sections live inside `overflow-hidden`
20
+ * panels, where an outset ring on the first row would be clipped by the rim.
21
+ */
22
+ const collapseTriggerClasses = "group/collapse flex h-control-md w-full cursor-pointer items-center gap-(--cue-space-3) px-(--cue-pad-row-x) text-left font-mono text-(length:--cue-text-ui) text-fg-muted transition-colors duration-150 outline-none select-none hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-2 focus-visible:outline-accent data-[panel-open]:text-fg data-[disabled]:pointer-events-none data-[disabled]:opacity-40";
23
+ /** The label between the summary row's gutters — truncates, never wraps. */
24
+ const collapseLabelClasses = "min-w-0 flex-1 truncate";
25
+ /**
26
+ * The caret at the end of a summary row. Rotation is driven off the trigger's
27
+ * own `data-panel-open`, so nothing in React has to know the section is open.
28
+ */
29
+ const collapseCaretClasses = "size-icon-sm shrink-0 text-fg-subtle transition-transform duration-150 ease-out group-data-[panel-open]/collapse:rotate-90 motion-reduce:transition-none";
30
+ /**
31
+ * Enter/exit for a panel, animated from the height Base UI measures for us.
32
+ *
33
+ * The animating element carries no padding on purpose: padding is part of the
34
+ * box's height, so it would be counted into the `0 → measured` transition and
35
+ * make the panel jump at both ends. The body lives one element in — see
36
+ * {@link collapsePanelBodyClasses}.
37
+ */
38
+ const PANEL_MOTION = "overflow-hidden transition-[height] duration-150 ease-out motion-reduce:transition-none data-[starting-style]:h-0 data-[ending-style]:h-0";
39
+ /** {@link PANEL_MOTION} against the accordion's measured height. */
40
+ const accordionPanelClasses = `${PANEL_MOTION} h-(--accordion-panel-height)`;
41
+ /** {@link PANEL_MOTION} against the collapsible's measured height. */
42
+ const collapsiblePanelClasses = `${PANEL_MOTION} h-(--collapsible-panel-height)`;
43
+ /** The padded body inside a panel: aligned to the summary row's gutters. */
44
+ const collapsePanelBodyClasses = "px-(--cue-pad-row-x) pt-(--cue-space-1) pb-(--cue-space-4) font-mono text-(length:--cue-text-ui) leading-relaxed text-fg-muted";
45
+ //#endregion
46
+ export { accordionPanelClasses, collapseCaretClasses, collapseLabelClasses, collapsePanelBodyClasses, collapseTriggerClasses, collapsiblePanelClasses };
@@ -0,0 +1,45 @@
1
+ import "react";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/layout/_glyphs.tsx
4
+ /**
5
+ * Shared layout glyphs.
6
+ *
7
+ * Drawn inline rather than pulled from `lucide-react` for the same reason as
8
+ * `chrome/_glyphs.tsx` and `overlays/_glyphs.tsx`: a caret on an accordion row
9
+ * and a chevron on a pager should not put an icon dependency on the render path
10
+ * of every page, and hand-set strokes stay hairline-thin at the 8–12px sizes
11
+ * console density asks for. `currentColor` everywhere — the tone comes from the
12
+ * parent.
13
+ *
14
+ * @internal Not part of the public API.
15
+ */
16
+ /** A right-pointing chevron. Rotate it 90° to point down. */
17
+ function ChevronRightGlyph(props) {
18
+ return /* @__PURE__ */ jsx("svg", {
19
+ viewBox: "0 0 16 16",
20
+ fill: "none",
21
+ stroke: "currentColor",
22
+ strokeWidth: "2",
23
+ strokeLinecap: "round",
24
+ strokeLinejoin: "round",
25
+ "aria-hidden": "true",
26
+ ...props,
27
+ children: /* @__PURE__ */ jsx("path", { d: "m6 3 5 5-5 5" })
28
+ });
29
+ }
30
+ /** A left-pointing chevron. */
31
+ function ChevronLeftGlyph(props) {
32
+ return /* @__PURE__ */ jsx("svg", {
33
+ viewBox: "0 0 16 16",
34
+ fill: "none",
35
+ stroke: "currentColor",
36
+ strokeWidth: "2",
37
+ strokeLinecap: "round",
38
+ strokeLinejoin: "round",
39
+ "aria-hidden": "true",
40
+ ...props,
41
+ children: /* @__PURE__ */ jsx("path", { d: "m10 3-5 5 5 5" })
42
+ });
43
+ }
44
+ //#endregion
45
+ export { ChevronLeftGlyph, ChevronRightGlyph };
@@ -0,0 +1,52 @@
1
+ import * as React from "react";
2
+ import { Accordion } from "@base-ui/react/accordion";
3
+ //#region src/layout/accordion.d.ts
4
+ interface AccordionRootProps extends Omit<Accordion.Root.Props, "className"> {
5
+ /** Extra classes for the accordion frame. */
6
+ className?: string;
7
+ }
8
+ interface AccordionItemProps extends Omit<Accordion.Item.Props, "className"> {
9
+ /** Extra classes for the section. */
10
+ className?: string;
11
+ }
12
+ interface AccordionHeaderProps extends Omit<Accordion.Header.Props, "className"> {
13
+ /** Extra classes for the heading. */
14
+ className?: string;
15
+ }
16
+ interface AccordionTriggerProps extends Omit<Accordion.Trigger.Props, "className"> {
17
+ /** Extra classes for the summary row. */
18
+ className?: string;
19
+ }
20
+ interface AccordionPanelProps extends Omit<Accordion.Panel.Props, "className"> {
21
+ /** Extra classes for the animating box. Padding belongs on `bodyClassName`. */
22
+ className?: string;
23
+ /** Extra classes for the padded body inside it. */
24
+ bodyClassName?: string;
25
+ }
26
+ /**
27
+ * A stack of sections, one (or several) open at a time.
28
+ *
29
+ * Wraps Base UI's `Accordion`, so the disclosure ARIA, keyboard handling and
30
+ * open-state bookkeeping are the primitive's. This layer adds the console skin:
31
+ * hairline separation, mono summary rows on the control ladder, and a height
32
+ * transition that respects `prefers-reduced-motion`.
33
+ *
34
+ * @example
35
+ * <Accordion.Root>
36
+ * <Accordion.Item value="routing">
37
+ * <Accordion.Header><Accordion.Trigger>routing</Accordion.Trigger></Accordion.Header>
38
+ * <Accordion.Panel>…</Accordion.Panel>
39
+ * </Accordion.Item>
40
+ * </Accordion.Root>
41
+ * @example
42
+ * <Accordion.Root multiple defaultValue={["routing"]}>…</Accordion.Root>
43
+ */
44
+ declare const Accordion$1: {
45
+ Root: React.ForwardRefExoticComponent<Omit<AccordionRootProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
46
+ Item: React.ForwardRefExoticComponent<Omit<AccordionItemProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
47
+ Header: React.ForwardRefExoticComponent<Omit<AccordionHeaderProps, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
48
+ Trigger: React.ForwardRefExoticComponent<Omit<AccordionTriggerProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
49
+ Panel: React.ForwardRefExoticComponent<Omit<AccordionPanelProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
50
+ };
51
+ //#endregion
52
+ export { Accordion$1 as Accordion, AccordionHeaderProps, AccordionItemProps, AccordionPanelProps, AccordionRootProps, AccordionTriggerProps };
@@ -0,0 +1,81 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { accordionPanelClasses, collapseCaretClasses, collapseLabelClasses, collapsePanelBodyClasses, collapseTriggerClasses } from "./_collapse.js";
4
+ import { ChevronRightGlyph } from "./_glyphs.js";
5
+ import * as React from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Accordion } from "@base-ui/react/accordion";
8
+ /**
9
+ * A stack of sections, one (or several) open at a time.
10
+ *
11
+ * Wraps Base UI's `Accordion`, so the disclosure ARIA, keyboard handling and
12
+ * open-state bookkeeping are the primitive's. This layer adds the console skin:
13
+ * hairline separation, mono summary rows on the control ladder, and a height
14
+ * transition that respects `prefers-reduced-motion`.
15
+ *
16
+ * @example
17
+ * <Accordion.Root>
18
+ * <Accordion.Item value="routing">
19
+ * <Accordion.Header><Accordion.Trigger>routing</Accordion.Trigger></Accordion.Header>
20
+ * <Accordion.Panel>…</Accordion.Panel>
21
+ * </Accordion.Item>
22
+ * </Accordion.Root>
23
+ * @example
24
+ * <Accordion.Root multiple defaultValue={["routing"]}>…</Accordion.Root>
25
+ */
26
+ const Accordion$1 = {
27
+ Root: React.forwardRef(function AccordionRoot({ className, ...elementProps }, ref) {
28
+ return /* @__PURE__ */ jsx(Accordion.Root, {
29
+ ref,
30
+ "data-slot": "accordion",
31
+ className: cn("flex min-w-0 flex-col", className),
32
+ ...elementProps
33
+ });
34
+ }),
35
+ Item: React.forwardRef(function AccordionItem({ className, ...elementProps }, ref) {
36
+ return /* @__PURE__ */ jsx(Accordion.Item, {
37
+ ref,
38
+ "data-slot": "accordion-item",
39
+ className: cn("border-t border-border first:border-t-0", className),
40
+ ...elementProps
41
+ });
42
+ }),
43
+ Header: React.forwardRef(function AccordionHeader({ className, ...elementProps }, ref) {
44
+ return /* @__PURE__ */ jsx(Accordion.Header, {
45
+ ref,
46
+ "data-slot": "accordion-header",
47
+ className: cn("m-0 flex", className),
48
+ ...elementProps
49
+ });
50
+ }),
51
+ Trigger: React.forwardRef(function AccordionTrigger({ className, children, ...elementProps }, ref) {
52
+ return /* @__PURE__ */ jsxs(Accordion.Trigger, {
53
+ ref,
54
+ "data-slot": "accordion-trigger",
55
+ className: cn(collapseTriggerClasses, className),
56
+ ...elementProps,
57
+ children: [/* @__PURE__ */ jsx("span", {
58
+ className: collapseLabelClasses,
59
+ children
60
+ }), /* @__PURE__ */ jsx(ChevronRightGlyph, {
61
+ "data-slot": "accordion-caret",
62
+ className: collapseCaretClasses
63
+ })]
64
+ });
65
+ }),
66
+ Panel: React.forwardRef(function AccordionPanel({ className, bodyClassName, children, ...elementProps }, ref) {
67
+ return /* @__PURE__ */ jsx(Accordion.Panel, {
68
+ ref,
69
+ "data-slot": "accordion-panel",
70
+ className: cn(accordionPanelClasses, className),
71
+ ...elementProps,
72
+ children: /* @__PURE__ */ jsx("div", {
73
+ "data-slot": "accordion-panel-body",
74
+ className: cn(collapsePanelBodyClasses, bodyClassName),
75
+ children
76
+ })
77
+ });
78
+ })
79
+ };
80
+ //#endregion
81
+ export { Accordion$1 as Accordion };
@@ -0,0 +1,35 @@
1
+ import * as React from "react";
2
+ //#region src/layout/breadcrumb.d.ts
3
+ /** One crumb in the trail. */
4
+ interface BreadcrumbItem {
5
+ /** What the crumb says. */
6
+ label: React.ReactNode;
7
+ /** Where it goes. Renders an `<a>`. */
8
+ href?: string;
9
+ /** What it does. Renders a `<button>` when there is no `href`. */
10
+ onClick?: React.MouseEventHandler<HTMLElement>;
11
+ }
12
+ interface BreadcrumbProps extends Omit<React.ComponentPropsWithoutRef<"nav">, "children"> {
13
+ /** The trail, root first. The last entry is the current page. */
14
+ items: readonly BreadcrumbItem[];
15
+ /** What sits between crumbs. Defaults to `"/"`. */
16
+ separator?: React.ReactNode;
17
+ /** The nav's accessible name. Defaults to `"Breadcrumb"`. */
18
+ label?: string;
19
+ }
20
+ /**
21
+ * Where you are, and how to get back.
22
+ *
23
+ * The last crumb is never a link: it is the page you are on, marked
24
+ * `aria-current="page"` and set in full-strength ink so the trail has one
25
+ * visible end. Separators are `aria-hidden` — a screen reader announcing
26
+ * "console slash patch slash universe 1" is reading punctuation, not structure.
27
+ *
28
+ * Static markup — no `"use client"`.
29
+ *
30
+ * @example
31
+ * <Breadcrumb items={[{ label: "Console", href: "/" }, { label: "Patch" }]} />
32
+ */
33
+ declare const Breadcrumb: React.ForwardRefExoticComponent<BreadcrumbProps & React.RefAttributes<HTMLElement>>;
34
+ //#endregion
35
+ export { Breadcrumb, BreadcrumbItem, BreadcrumbProps };
@@ -0,0 +1,67 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import * as React from "react";
3
+ import { jsx, jsxs } from "react/jsx-runtime";
4
+ //#region src/layout/breadcrumb.tsx
5
+ /**
6
+ * A crumb that goes somewhere. Muted until hovered, never underlined — the
7
+ * trail is navigation furniture and should not read as body-copy links.
8
+ */
9
+ const CRUMB_LINK_CLASSES = "cursor-pointer rounded-(--radius-control) border-0 bg-transparent p-0 font-mono text-(length:--cue-text-label) text-fg-muted no-underline 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";
10
+ /**
11
+ * Where you are, and how to get back.
12
+ *
13
+ * The last crumb is never a link: it is the page you are on, marked
14
+ * `aria-current="page"` and set in full-strength ink so the trail has one
15
+ * visible end. Separators are `aria-hidden` — a screen reader announcing
16
+ * "console slash patch slash universe 1" is reading punctuation, not structure.
17
+ *
18
+ * Static markup — no `"use client"`.
19
+ *
20
+ * @example
21
+ * <Breadcrumb items={[{ label: "Console", href: "/" }, { label: "Patch" }]} />
22
+ */
23
+ const Breadcrumb = React.forwardRef(function Breadcrumb({ className, items, separator = "/", label = "Breadcrumb", ...elementProps }, ref) {
24
+ return /* @__PURE__ */ jsx("nav", {
25
+ ref,
26
+ "data-slot": "breadcrumb",
27
+ "aria-label": label,
28
+ className: cn("min-w-0", className),
29
+ ...elementProps,
30
+ children: /* @__PURE__ */ jsx("ol", {
31
+ className: "m-0 flex list-none flex-wrap items-center gap-(--cue-space-2) p-0 font-mono text-(length:--cue-text-label) text-fg-muted",
32
+ children: items.map((item, index) => {
33
+ const last = index === items.length - 1;
34
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [index === 0 ? null : /* @__PURE__ */ jsx("li", {
35
+ "data-slot": "breadcrumb-separator",
36
+ "aria-hidden": "true",
37
+ className: "text-fg-subtle select-none",
38
+ children: separator
39
+ }), /* @__PURE__ */ jsx("li", {
40
+ "data-slot": "breadcrumb-item",
41
+ className: "min-w-0",
42
+ children: last ? /* @__PURE__ */ jsx("span", {
43
+ "data-slot": "breadcrumb-current",
44
+ "aria-current": "page",
45
+ className: "truncate text-fg",
46
+ children: item.label
47
+ }) : item.href !== void 0 ? /* @__PURE__ */ jsx("a", {
48
+ href: item.href,
49
+ onClick: item.onClick,
50
+ className: CRUMB_LINK_CLASSES,
51
+ children: item.label
52
+ }) : item.onClick !== void 0 ? /* @__PURE__ */ jsx("button", {
53
+ type: "button",
54
+ onClick: item.onClick,
55
+ className: CRUMB_LINK_CLASSES,
56
+ children: item.label
57
+ }) : /* @__PURE__ */ jsx("span", {
58
+ className: "truncate",
59
+ children: item.label
60
+ })
61
+ })] }, index);
62
+ })
63
+ })
64
+ });
65
+ });
66
+ //#endregion
67
+ export { Breadcrumb };
@@ -0,0 +1,51 @@
1
+ import * as React from "react";
2
+ //#region src/layout/card.d.ts
3
+ interface CardRootProps extends React.ComponentPropsWithoutRef<"div"> {
4
+ /**
5
+ * Separate the card's sections with hairline seams instead of whitespace.
6
+ *
7
+ * The card is then filled with the border colour and its sections sit `1px`
8
+ * apart, each painting its own opaque ground — the same idiom as `SeamList`,
9
+ * where the gap *is* the rule and can never double up with a border.
10
+ */
11
+ seam?: boolean;
12
+ }
13
+ interface CardHeaderProps extends React.ComponentPropsWithoutRef<"div"> {
14
+ /**
15
+ * Right-hand slot: the controls that act on the whole card (a menu, a status
16
+ * chip, a count).
17
+ */
18
+ actions?: React.ReactNode;
19
+ /** The leading cluster — normally a {@link CardTitle} and a description. */
20
+ children?: React.ReactNode;
21
+ }
22
+ /** Props for {@link CardTitle}: the native `<h3>` surface plus `className`. */
23
+ type CardTitleProps = React.ComponentPropsWithoutRef<"h3">;
24
+ /** Props for {@link CardDescription}: the native `<p>` surface plus `className`. */
25
+ type CardDescriptionProps = React.ComponentPropsWithoutRef<"p">;
26
+ /** Props for {@link CardContent}: the native `<div>` surface plus `className`. */
27
+ type CardContentProps = React.ComponentPropsWithoutRef<"div">;
28
+ /** Props for {@link CardFooter}: the native `<div>` surface plus `className`. */
29
+ type CardFooterProps = React.ComponentPropsWithoutRef<"div">;
30
+ /**
31
+ * A padded container for one thing: a summary, a setting group, a preview.
32
+ *
33
+ * Every section paints its own `surface-1` ground, which is what lets the root
34
+ * switch to the seam idiom without any of the parts knowing.
35
+ *
36
+ * @example
37
+ * <Card.Root seam>
38
+ * <Card.Header><Card.Title>Failover</Card.Title></Card.Header>
39
+ * <Card.Content>…</Card.Content>
40
+ * </Card.Root>
41
+ */
42
+ declare const Card: {
43
+ Root: React.ForwardRefExoticComponent<CardRootProps & React.RefAttributes<HTMLDivElement>>;
44
+ Header: React.ForwardRefExoticComponent<CardHeaderProps & React.RefAttributes<HTMLDivElement>>;
45
+ Title: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, "ref"> & React.RefAttributes<HTMLHeadingElement>>;
46
+ Description: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, "ref"> & React.RefAttributes<HTMLParagraphElement>>;
47
+ Content: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
48
+ Footer: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
49
+ };
50
+ //#endregion
51
+ export { Card, CardContentProps, CardDescriptionProps, CardFooterProps, CardHeaderProps, CardRootProps, CardTitleProps };