@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,109 @@
1
+ "use client";
2
+ import { ThemeContext } from "../system/theme-provider.js";
3
+ import { FLOW_NODE_FRAME_PROPERTY, flowFrameColor } from "./_frame.js";
4
+ import { SignalEdge } from "./signal-edge.js";
5
+ import * as React from "react";
6
+ //#region src/flow/use-flow-theme.ts
7
+ /**
8
+ * React Flow paints its own chrome — edges, handles, controls, the minimap, the
9
+ * selection box — from a documented set of `--xy-*` custom properties, each one
10
+ * consulted before the library's built-in default. Mapping that set onto this
11
+ * system's tokens is the whole theme: no wrapper components, no props threaded
12
+ * through a graph, and a theme, mode or density switch that costs nothing
13
+ * because every value is a *reference*, re-resolved by the browser.
14
+ *
15
+ * The map is published two ways, and they are checked against each other
16
+ * (`test/flow/flow-css.test.ts`):
17
+ *
18
+ * - as this object, to spread on the canvas: `<ReactFlow style={theme.style}>`;
19
+ * - as the `.react-flow` block of `flow.css`, for apps that would rather import
20
+ * a stylesheet than thread a prop.
21
+ *
22
+ * Either is enough. Both is harmless.
23
+ */
24
+ const FLOW_THEME_VARIABLES = Object.freeze({
25
+ "--xy-background-color": "var(--cue-bg)",
26
+ "--xy-background-pattern-color": "var(--cue-surface-2)",
27
+ "--xy-edge-stroke": "var(--cue-border-strong)",
28
+ "--xy-edge-stroke-width": "1.5",
29
+ "--xy-edge-stroke-selected": "var(--cue-fg)",
30
+ "--xy-connectionline-stroke": "var(--cue-accent)",
31
+ "--xy-connectionline-stroke-width": "1.5",
32
+ "--xy-edge-label-background-color": "var(--cue-surface-2)",
33
+ "--xy-edge-label-color": "var(--cue-fg)",
34
+ "--xy-handle-background-color": "var(--cue-accent)",
35
+ "--xy-handle-border-color": "var(--cue-bg)",
36
+ "--xy-node-background-color": "var(--cue-surface-1)",
37
+ "--xy-node-border": "1px solid var(--cue-border)",
38
+ "--xy-node-border-radius": "var(--cue-radius-surface)",
39
+ "--xy-node-color": "var(--cue-fg)",
40
+ "--xy-node-group-background-color": "var(--cue-surface-2)",
41
+ "--xy-node-boxshadow-hover": "0 0 0 1px var(--cue-border-strong)",
42
+ "--xy-node-boxshadow-selected": "0 0 0 1px var(--cue-fg)",
43
+ "--xy-controls-button-background-color": "var(--cue-surface-2)",
44
+ "--xy-controls-button-background-color-hover": "var(--cue-surface-3)",
45
+ "--xy-controls-button-color": "var(--cue-fg-muted)",
46
+ "--xy-controls-button-color-hover": "var(--cue-accent)",
47
+ "--xy-controls-button-border-color": "var(--cue-border)",
48
+ "--xy-controls-box-shadow": "0 8px 24px rgba(0, 0, 0, 0.4)",
49
+ "--xy-minimap-background-color": "var(--cue-surface-1)",
50
+ "--xy-minimap-mask-background-color": "color-mix(in oklch, var(--cue-bg) 70%, transparent)",
51
+ "--xy-minimap-mask-stroke-color": "var(--cue-border)",
52
+ "--xy-minimap-node-background-color": "var(--cue-surface-3)",
53
+ "--xy-minimap-node-stroke-color": "var(--cue-border)",
54
+ "--xy-selection-background-color": "var(--cue-accent-soft)",
55
+ "--xy-selection-border": "1px dashed var(--cue-accent)",
56
+ "--xy-resize-background-color": "var(--cue-accent)",
57
+ "--xy-attribution-background-color": "color-mix(in oklch, var(--cue-bg) 70%, transparent)"
58
+ });
59
+ /** Frame colour per node kind, ready to put on a React Flow node's `style`. */
60
+ const NODE_STYLES = Object.freeze({
61
+ input: { [FLOW_NODE_FRAME_PROPERTY]: flowFrameColor("input") },
62
+ output: { [FLOW_NODE_FRAME_PROPERTY]: flowFrameColor("output") },
63
+ processing: { [FLOW_NODE_FRAME_PROPERTY]: flowFrameColor("processing") }
64
+ });
65
+ /**
66
+ * `edgeTypes` for `<ReactFlow>`.
67
+ *
68
+ * A module constant, not a fresh object: React Flow re-registers every edge when
69
+ * this changes identity, and warns in the console about exactly this mistake.
70
+ */
71
+ const EDGE_TYPES = Object.freeze({ signal: SignalEdge });
72
+ /** `defaultEdgeOptions`: every edge is a signal edge unless it says otherwise. */
73
+ const DEFAULT_EDGE_OPTIONS = Object.freeze({
74
+ type: "signal",
75
+ interactionWidth: 16
76
+ });
77
+ /**
78
+ * Everything a `<ReactFlow>` needs to look like it belongs to this system.
79
+ *
80
+ * @example
81
+ * const theme = useFlowTheme();
82
+ * <ReactFlow
83
+ * nodes={nodes}
84
+ * edges={edges}
85
+ * nodeTypes={nodeTypes}
86
+ * edgeTypes={theme.edgeTypes}
87
+ * defaultEdgeOptions={theme.defaultEdgeOptions}
88
+ * colorMode={theme.colorMode}
89
+ * style={theme.style}
90
+ * >
91
+ * <FlowBackground />
92
+ * <FlowControls />
93
+ * </ReactFlow>
94
+ * @example
95
+ * // Colour a whole class of nodes at once — the cards inherit the frame.
96
+ * const nodes = inputs.map((input) => ({ ...input, style: theme.nodeStyles.input }));
97
+ */
98
+ function useFlowTheme() {
99
+ const colorMode = React.useContext(ThemeContext)?.resolvedMode ?? "dark";
100
+ return React.useMemo(() => ({
101
+ colorMode,
102
+ style: FLOW_THEME_VARIABLES,
103
+ edgeTypes: EDGE_TYPES,
104
+ defaultEdgeOptions: DEFAULT_EDGE_OPTIONS,
105
+ nodeStyles: NODE_STYLES
106
+ }), [colorMode]);
107
+ }
108
+ //#endregion
109
+ export { FLOW_THEME_VARIABLES, useFlowTheme };
@@ -0,0 +1,64 @@
1
+ import { ClassProp, VariantProps } from "../lib/cva.js";
2
+ //#region src/forms/_chassis.d.ts
3
+ /**
4
+ * The rung of the density control ladder a form control sits on.
5
+ *
6
+ * Named `FormControlSize` rather than `ControlSize` because
7
+ * `@cueplusplus/ui/system` already exports a `ControlSize` for
8
+ * `useControlHeight`, and the root barrel re-exports both.
9
+ */
10
+ type FormControlSize = "sm" | "md" | "lg";
11
+ /**
12
+ * Everything the recessed control chassis paints except the box itself.
13
+ *
14
+ * Split out from the size rung so controls that own their own geometry — a
15
+ * `<textarea>` that must grow, a `NumberField.Group` that packs two buttons and
16
+ * an input into one rim — can reuse the surface without fighting a height or a
17
+ * horizontal padding they do not want.
18
+ *
19
+ * Inputs are **recessed**: `bg-sunken` sets them *into* the panel rather than
20
+ * raising them off it, which is the portfolio-wide convention for anything the
21
+ * user types into.
22
+ *
23
+ * `focus-visible:outline-solid` re-declares the outline style the sibling
24
+ * `outline-none` switched off — see the note on `buttonChassis`.
25
+ */
26
+ declare const controlSurface = "w-full rounded-(--radius-control) border border-border bg-sunken font-mono text-fg placeholder:text-fg-subtle outline-none focus:border-accent focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent disabled:opacity-40 data-[disabled]:opacity-40 data-[invalid]:border-danger";
27
+ /**
28
+ * The full recessed-control recipe, one variant per rung of the control ladder.
29
+ *
30
+ * Height, horizontal padding and text size move together — a control that is
31
+ * one rung shorter also needs to be one rung tighter and one rung smaller, or
32
+ * the glyphs collide with the rim.
33
+ *
34
+ * @example
35
+ * <input className={cn(controlVariants({ size: "sm" }), className)} />
36
+ */
37
+ declare const controlVariants: (props?: ({
38
+ size?: "sm" | "md" | "lg" | null | undefined;
39
+ } & ClassProp) | undefined) => string;
40
+ /** `size` prop shape shared by every control that rides the chassis. */
41
+ type ControlVariantProps = VariantProps<typeof controlVariants>;
42
+ /**
43
+ * The chassis at its default `md` rung — the exact class list the spec pins for
44
+ * a plain form control. Kept as a derived constant, never a second copy, so the
45
+ * recipe cannot drift from {@link controlVariants}.
46
+ */
47
+ declare const controlClasses: string;
48
+ /**
49
+ * Ink for a control nested inside something that already paints the rim (an
50
+ * `InputGroup`, a `NumberField.Group`).
51
+ *
52
+ * Strips the box entirely — no border, no fill, no padding, no height — and
53
+ * inherits the font size from the wrapper so the two never disagree about which
54
+ * density rung they are on.
55
+ */
56
+ declare const bareControlClasses = "min-w-0 flex-1 border-0 bg-transparent p-0 font-mono text-[length:inherit] text-fg placeholder:text-fg-subtle outline-none disabled:opacity-40";
57
+ /**
58
+ * Focus feedback for a wrapper that owns the rim on behalf of an inner control.
59
+ * A `<div>` never matches `:focus-visible`, so the group has to watch its
60
+ * descendants instead.
61
+ */
62
+ declare const controlGroupFocusClasses = "focus-within:border-accent focus-within:outline-2 focus-within:outline-solid focus-within:outline-offset-1 focus-within:outline-accent";
63
+ //#endregion
64
+ export { ControlVariantProps, FormControlSize, bareControlClasses, controlClasses, controlGroupFocusClasses, controlSurface, controlVariants };
@@ -0,0 +1,59 @@
1
+ import { cva } from "../lib/cva.js";
2
+ //#region src/forms/_chassis.ts
3
+ /**
4
+ * Everything the recessed control chassis paints except the box itself.
5
+ *
6
+ * Split out from the size rung so controls that own their own geometry — a
7
+ * `<textarea>` that must grow, a `NumberField.Group` that packs two buttons and
8
+ * an input into one rim — can reuse the surface without fighting a height or a
9
+ * horizontal padding they do not want.
10
+ *
11
+ * Inputs are **recessed**: `bg-sunken` sets them *into* the panel rather than
12
+ * raising them off it, which is the portfolio-wide convention for anything the
13
+ * user types into.
14
+ *
15
+ * `focus-visible:outline-solid` re-declares the outline style the sibling
16
+ * `outline-none` switched off — see the note on `buttonChassis`.
17
+ */
18
+ const controlSurface = "w-full rounded-(--radius-control) border border-border bg-sunken font-mono text-fg placeholder:text-fg-subtle outline-none focus:border-accent focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent disabled:opacity-40 data-[disabled]:opacity-40 data-[invalid]:border-danger";
19
+ /**
20
+ * The full recessed-control recipe, one variant per rung of the control ladder.
21
+ *
22
+ * Height, horizontal padding and text size move together — a control that is
23
+ * one rung shorter also needs to be one rung tighter and one rung smaller, or
24
+ * the glyphs collide with the rim.
25
+ *
26
+ * @example
27
+ * <input className={cn(controlVariants({ size: "sm" }), className)} />
28
+ */
29
+ const controlVariants = cva(controlSurface, {
30
+ variants: { size: {
31
+ sm: "h-control-sm px-(--cue-space-3) text-(length:--cue-text-label)",
32
+ md: "h-control-md px-(--cue-space-4) text-(length:--cue-text-ui)",
33
+ lg: "h-control-lg px-(--cue-space-5) text-(length:--cue-text-body)"
34
+ } },
35
+ defaultVariants: { size: "md" }
36
+ });
37
+ /**
38
+ * The chassis at its default `md` rung — the exact class list the spec pins for
39
+ * a plain form control. Kept as a derived constant, never a second copy, so the
40
+ * recipe cannot drift from {@link controlVariants}.
41
+ */
42
+ const controlClasses = controlVariants();
43
+ /**
44
+ * Ink for a control nested inside something that already paints the rim (an
45
+ * `InputGroup`, a `NumberField.Group`).
46
+ *
47
+ * Strips the box entirely — no border, no fill, no padding, no height — and
48
+ * inherits the font size from the wrapper so the two never disagree about which
49
+ * density rung they are on.
50
+ */
51
+ const bareControlClasses = "min-w-0 flex-1 border-0 bg-transparent p-0 font-mono text-[length:inherit] text-fg placeholder:text-fg-subtle outline-none disabled:opacity-40";
52
+ /**
53
+ * Focus feedback for a wrapper that owns the rim on behalf of an inner control.
54
+ * A `<div>` never matches `:focus-visible`, so the group has to watch its
55
+ * descendants instead.
56
+ */
57
+ const controlGroupFocusClasses = "focus-within:border-accent focus-within:outline-2 focus-within:outline-solid focus-within:outline-offset-1 focus-within:outline-accent";
58
+ //#endregion
59
+ export { bareControlClasses, controlClasses, controlGroupFocusClasses, controlSurface, controlVariants };
@@ -0,0 +1,143 @@
1
+ import "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ //#region src/forms/_glyphs.tsx
4
+ /**
5
+ * Shared form glyphs.
6
+ *
7
+ * Drawn inline rather than pulled from `lucide-react`, for the same reason as
8
+ * `chrome/_glyphs.tsx`, `layout/_glyphs.tsx` and `overlays/_glyphs.tsx`: a caret
9
+ * on a combobox and a tick on a chosen row should not put an icon dependency on
10
+ * the render path of every form, and hand-set strokes stay hairline-thin at the
11
+ * 8–12px sizes console density asks for. `currentColor` everywhere — the tone
12
+ * comes from the parent.
13
+ *
14
+ * @internal Not part of the public API.
15
+ */
16
+ /** A caret pair — one glyph that says "this opens downward and closes upward". */
17
+ function CaretGlyph(props) {
18
+ return /* @__PURE__ */ jsx("svg", {
19
+ viewBox: "0 0 16 16",
20
+ fill: "currentColor",
21
+ "aria-hidden": "true",
22
+ ...props,
23
+ children: /* @__PURE__ */ jsx("path", { d: "M11 10H5l3 3.5zm0-4H5l3-3.5z" })
24
+ });
25
+ }
26
+ /** The tick marking a chosen row. */
27
+ function TickGlyph(props) {
28
+ return /* @__PURE__ */ jsx("svg", {
29
+ viewBox: "0 0 16 16",
30
+ fill: "none",
31
+ stroke: "currentColor",
32
+ strokeWidth: "2.5",
33
+ strokeLinecap: "round",
34
+ strokeLinejoin: "round",
35
+ "aria-hidden": "true",
36
+ ...props,
37
+ children: /* @__PURE__ */ jsx("path", { d: "m3 8.5 3.5 3.5L13 4.5" })
38
+ });
39
+ }
40
+ /** A cross, not an "x" glyph, so it stays square at 8px. Clears and removes. */
41
+ function CrossGlyph(props) {
42
+ return /* @__PURE__ */ jsx("svg", {
43
+ viewBox: "0 0 16 16",
44
+ fill: "none",
45
+ stroke: "currentColor",
46
+ strokeWidth: "1.75",
47
+ strokeLinecap: "round",
48
+ "aria-hidden": "true",
49
+ ...props,
50
+ children: /* @__PURE__ */ jsx("path", { d: "m4 4 8 8M12 4l-8 8" })
51
+ });
52
+ }
53
+ /** A magnifier at hairline weight, sized to the density icon token by the caller. */
54
+ function SearchGlyph(props) {
55
+ return /* @__PURE__ */ jsxs("svg", {
56
+ viewBox: "0 0 16 16",
57
+ fill: "none",
58
+ stroke: "currentColor",
59
+ strokeWidth: "1.75",
60
+ strokeLinecap: "round",
61
+ "aria-hidden": "true",
62
+ ...props,
63
+ children: [/* @__PURE__ */ jsx("circle", {
64
+ cx: "7",
65
+ cy: "7",
66
+ r: "4.5"
67
+ }), /* @__PURE__ */ jsx("path", { d: "m10.5 10.5 3 3" })]
68
+ });
69
+ }
70
+ /** An open eye: the value is currently legible. */
71
+ function EyeGlyph(props) {
72
+ return /* @__PURE__ */ jsxs("svg", {
73
+ viewBox: "0 0 16 16",
74
+ fill: "none",
75
+ stroke: "currentColor",
76
+ strokeWidth: "1.5",
77
+ strokeLinecap: "round",
78
+ strokeLinejoin: "round",
79
+ "aria-hidden": "true",
80
+ ...props,
81
+ children: [/* @__PURE__ */ jsx("path", { d: "M1.5 8S4 3.5 8 3.5 14.5 8 14.5 8 12 12.5 8 12.5 1.5 8 1.5 8Z" }), /* @__PURE__ */ jsx("circle", {
82
+ cx: "8",
83
+ cy: "8",
84
+ r: "2"
85
+ })]
86
+ });
87
+ }
88
+ /** The same eye with a stroke through it: the value is masked. */
89
+ function EyeOffGlyph(props) {
90
+ return /* @__PURE__ */ jsxs("svg", {
91
+ viewBox: "0 0 16 16",
92
+ fill: "none",
93
+ stroke: "currentColor",
94
+ strokeWidth: "1.5",
95
+ strokeLinecap: "round",
96
+ strokeLinejoin: "round",
97
+ "aria-hidden": "true",
98
+ ...props,
99
+ children: [
100
+ /* @__PURE__ */ jsx("path", { d: "M6.2 4A6.5 6.5 0 0 1 8 3.5C12 3.5 14.5 8 14.5 8a12 12 0 0 1-2.3 2.7M9.8 12a6.5 6.5 0 0 1-1.8.5C4 12.5 1.5 8 1.5 8A12 12 0 0 1 4.4 4.8" }),
101
+ /* @__PURE__ */ jsx("path", { d: "M6.6 6.6a2 2 0 0 0 2.8 2.8" }),
102
+ /* @__PURE__ */ jsx("path", { d: "m2.5 2.5 11 11" })
103
+ ]
104
+ });
105
+ }
106
+ /**
107
+ * A filled five-point star, the rating mark. Solid rather than outlined: at 12px
108
+ * an outlined star is a smudge, and the difference between "on" and "off" has to
109
+ * survive a glance.
110
+ */
111
+ function StarGlyph(props) {
112
+ return /* @__PURE__ */ jsx("svg", {
113
+ viewBox: "0 0 16 16",
114
+ fill: "currentColor",
115
+ "aria-hidden": "true",
116
+ ...props,
117
+ children: /* @__PURE__ */ jsx("path", { d: "m8 1.6 1.9 4 4.4.6-3.2 3.1.8 4.3L8 11.6l-3.9 2 .8-4.3L1.7 6.2l4.4-.6z" })
118
+ });
119
+ }
120
+ /**
121
+ * `{x}` — the mathematician's variable, the mark on an environment-variable
122
+ * reference. Reads as "a name that stands for something else", which is exactly
123
+ * what `env(NAME)` is.
124
+ */
125
+ function VariableGlyph(props) {
126
+ return /* @__PURE__ */ jsxs("svg", {
127
+ viewBox: "0 0 16 16",
128
+ fill: "none",
129
+ stroke: "currentColor",
130
+ strokeWidth: "1.5",
131
+ strokeLinecap: "round",
132
+ strokeLinejoin: "round",
133
+ "aria-hidden": "true",
134
+ ...props,
135
+ children: [
136
+ /* @__PURE__ */ jsx("path", { d: "M5.5 2.5A2.5 2.5 0 0 0 4 4.8v1.4L2.5 8 4 9.8v1.4a2.5 2.5 0 0 0 1.5 2.3" }),
137
+ /* @__PURE__ */ jsx("path", { d: "M10.5 2.5A2.5 2.5 0 0 1 12 4.8v1.4L13.5 8 12 9.8v1.4a2.5 2.5 0 0 1-1.5 2.3" }),
138
+ /* @__PURE__ */ jsx("path", { d: "m6.8 6.4 2.4 3.2m0-3.2-2.4 3.2" })
139
+ ]
140
+ });
141
+ }
142
+ //#endregion
143
+ export { CaretGlyph, CrossGlyph, EyeGlyph, EyeOffGlyph, SearchGlyph, StarGlyph, TickGlyph, VariableGlyph };
@@ -0,0 +1,55 @@
1
+ import { overlayPopupTransitionClasses, overlayPositionerClasses, overlaySurfaceClasses } from "../overlays/_surface.js";
2
+ //#region src/forms/_listbox.ts
3
+ /**
4
+ * The shared skin of every filterable list in this group — `Combobox`,
5
+ * `Autocomplete`, `MultiSelect`, `TagsInput`.
6
+ *
7
+ * All four are the same shape: a control-chassis input that opens a portalled
8
+ * listbox. Encoding the surface once is what keeps them from drifting apart, and
9
+ * it borrows the overlay language from `overlays/_surface.ts` rather than
10
+ * restating it, so "what a floating surface looks like" stays a single decision.
11
+ *
12
+ * @internal Not part of the public API.
13
+ */
14
+ /** The positioner: a layout box owning the stacking context, nothing painted. */
15
+ const listboxPositionerClasses = overlayPositionerClasses;
16
+ /**
17
+ * The popup: overlay surface, anchored to the trigger's width, capped at the
18
+ * space the positioner reports so a long list scrolls instead of overflowing the
19
+ * viewport.
20
+ */
21
+ const listboxPopupClasses = `${overlaySurfaceClasses} ${overlayPopupTransitionClasses} w-(--anchor-width) max-w-(--available-width) overflow-hidden py-(--cue-space-1) outline-none`;
22
+ /** The scroll container inside the popup. */
23
+ const listboxListClasses = "max-h-[min(var(--available-height),18rem)] overflow-y-auto overscroll-contain outline-none";
24
+ /**
25
+ * One row. `data-highlighted` — not `:hover` — carries the tint, so keyboard
26
+ * navigation and the pointer agree on which row is active, and the tint is
27
+ * `accent-soft` rather than a solid fill (the luma defect ruling).
28
+ */
29
+ const listboxItemClasses = "flex h-control-sm cursor-default items-center gap-(--cue-space-2) px-(--cue-space-3) font-mono text-(length:--cue-text-ui) text-fg-muted outline-none select-none data-[highlighted]:bg-accent-soft data-[highlighted]:text-fg data-[selected]:text-accent data-[disabled]:pointer-events-none data-[disabled]:opacity-40";
30
+ /** The "nothing matched" line: same rhythm as a row, but muted and unreachable. */
31
+ const listboxEmptyClasses = "flex h-control-sm items-center px-(--cue-space-3) font-mono text-(length:--cue-text-ui) text-fg-subtle select-none";
32
+ /** The tick gutter, always reserved so labels never jog sideways. */
33
+ const listboxIndicatorClasses = "flex size-icon-sm shrink-0 items-center justify-center";
34
+ /**
35
+ * A multi-value control grows with its chips, so it takes the chassis' fill,
36
+ * rim and radius but sets its own vertical rhythm — a fixed `h-control-*` would
37
+ * clip the second row of chips.
38
+ */
39
+ const chipFieldClasses = "flex w-full cursor-text flex-wrap items-center gap-(--cue-space-1) py-(--cue-space-1)";
40
+ /**
41
+ * A value chip inside the field: the `h-chip` token and the tinted-neutral
42
+ * colours of `chipVariants`, but *not* that recipe.
43
+ *
44
+ * `Chip` is uppercase and wide-tracked because it labels a *state* — `ONLINE`,
45
+ * `FAULT`. A chip here holds user data (a truss name, a tag), and uppercasing
46
+ * user data throws away information the user typed on purpose. Same shape, same
47
+ * palette, ordinary casing.
48
+ */
49
+ const valueChipClasses = "group/chip inline-flex h-chip max-w-full min-w-0 cursor-default items-center gap-(--cue-space-1) rounded-(--radius-control) border border-border bg-surface-2 py-0 pr-(--cue-space-1) pl-(--cue-space-2) font-mono text-(length:--cue-text-label) leading-none text-fg-muted outline-none select-none data-[highlighted]:border-accent/60 data-[highlighted]:text-fg focus-within:border-accent/60 focus-within:text-fg";
50
+ /** The chip's remove affordance. */
51
+ const chipRemoveClasses = "flex size-icon-sm shrink-0 cursor-pointer items-center justify-center rounded-(--radius-control) border-0 bg-transparent p-0 text-fg-subtle outline-none transition-colors hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent";
52
+ /** The trailing caret / clear affordance beside a filterable input. */
53
+ const listboxAdornmentClasses = "flex shrink-0 cursor-pointer items-center justify-center rounded-(--radius-control) border-0 bg-transparent p-0 text-fg-subtle outline-none transition-colors hover:text-fg focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent";
54
+ //#endregion
55
+ export { chipFieldClasses, chipRemoveClasses, listboxAdornmentClasses, listboxEmptyClasses, listboxIndicatorClasses, listboxItemClasses, listboxListClasses, listboxPopupClasses, listboxPositionerClasses, valueChipClasses };
@@ -0,0 +1,61 @@
1
+ import { FormControlSize } from "./_chassis.js";
2
+ import * as React from "react";
3
+ //#region src/forms/autocomplete.d.ts
4
+ interface AutocompleteProps {
5
+ /** The suggestions, filtered against what is typed. */
6
+ items: readonly string[];
7
+ /** Current text. Use with `onValueChange` for a controlled field. */
8
+ value?: string;
9
+ /** Initial text for an uncontrolled field. */
10
+ defaultValue?: string;
11
+ /** Fired on every keystroke and when a suggestion is picked. */
12
+ onValueChange?: (value: string) => void;
13
+ /** Shown while the field is empty. */
14
+ placeholder?: string;
15
+ /** Shown in place of the list when the query matches nothing. */
16
+ emptyMessage?: React.ReactNode;
17
+ /** Rung of the control ladder. Defaults to `"md"`. */
18
+ size?: FormControlSize;
19
+ /** Highlight the first match automatically so Enter accepts it. */
20
+ autoHighlight?: boolean;
21
+ /** Prevent opening and grey the field out. */
22
+ disabled?: boolean;
23
+ /** Require text before the owning form submits. */
24
+ required?: boolean;
25
+ /** Name for the input, when the field is part of a form. */
26
+ name?: string;
27
+ /** Id forwarded to the input. */
28
+ id?: string;
29
+ /** Accessible name for the input, when no {@link FieldLabel} names it. */
30
+ "aria-label"?: string;
31
+ /** Id of the element naming the input. */
32
+ "aria-labelledby"?: string;
33
+ /** Accessible name for the clear button. Defaults to `"Clear"`. */
34
+ clearLabel?: string;
35
+ /** Extra classes for the field. */
36
+ className?: string;
37
+ /** Extra classes for the popup surface. */
38
+ popupClassName?: string;
39
+ /** Distance in px between the field and the popup. Defaults to `4`. */
40
+ sideOffset?: number;
41
+ }
42
+ /**
43
+ * A text field that suggests as you type — and accepts what you typed anyway.
44
+ *
45
+ * The counterpart to {@link Combobox}: there the list *is* the set of legal
46
+ * values, here it is only a shortcut. Anything the user types survives blur, so
47
+ * this is the right control for a name, a search term or a host — anywhere the
48
+ * suggestions are a convenience rather than a constraint.
49
+ *
50
+ * Suggestions are plain strings for the same reason: an autocomplete has no
51
+ * separate value/label axis, because the label *is* the value.
52
+ *
53
+ * The popup is portalled through {@link useCuePortalProps}, so it carries the
54
+ * caller's `data-theme` / `data-density` / `data-mode`.
55
+ *
56
+ * @example
57
+ * <Autocomplete aria-label="Cue name" items={recentCues} onValueChange={setName} />
58
+ */
59
+ declare const Autocomplete: React.ForwardRefExoticComponent<AutocompleteProps & React.RefAttributes<HTMLInputElement>>;
60
+ //#endregion
61
+ export { Autocomplete, AutocompleteProps };
@@ -0,0 +1,88 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { bareControlClasses, controlGroupFocusClasses, controlVariants } from "./_chassis.js";
4
+ import { useCuePortalProps } from "../system/portal.js";
5
+ import { CrossGlyph } from "./_glyphs.js";
6
+ import { listboxAdornmentClasses, listboxEmptyClasses, listboxItemClasses, listboxListClasses, listboxPopupClasses, listboxPositionerClasses } from "./_listbox.js";
7
+ import * as React from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { Autocomplete } from "@base-ui/react/autocomplete";
10
+ //#region src/forms/autocomplete.tsx
11
+ /**
12
+ * A text field that suggests as you type — and accepts what you typed anyway.
13
+ *
14
+ * The counterpart to {@link Combobox}: there the list *is* the set of legal
15
+ * values, here it is only a shortcut. Anything the user types survives blur, so
16
+ * this is the right control for a name, a search term or a host — anywhere the
17
+ * suggestions are a convenience rather than a constraint.
18
+ *
19
+ * Suggestions are plain strings for the same reason: an autocomplete has no
20
+ * separate value/label axis, because the label *is* the value.
21
+ *
22
+ * The popup is portalled through {@link useCuePortalProps}, so it carries the
23
+ * caller's `data-theme` / `data-density` / `data-mode`.
24
+ *
25
+ * @example
26
+ * <Autocomplete aria-label="Cue name" items={recentCues} onValueChange={setName} />
27
+ */
28
+ const Autocomplete$1 = React.forwardRef(function Autocomplete$2({ items, value, defaultValue, onValueChange, placeholder, emptyMessage = "No matches", size, autoHighlight = false, disabled, required, name, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, clearLabel = "Clear", className, popupClassName, sideOffset = 4 }, ref) {
29
+ const portalProps = useCuePortalProps();
30
+ const handleValueChange = React.useCallback((next) => {
31
+ onValueChange?.(next);
32
+ }, [onValueChange]);
33
+ return /* @__PURE__ */ jsxs(Autocomplete.Root, {
34
+ items,
35
+ value,
36
+ defaultValue,
37
+ onValueChange: onValueChange === void 0 ? void 0 : handleValueChange,
38
+ autoHighlight,
39
+ disabled,
40
+ required,
41
+ name,
42
+ children: [/* @__PURE__ */ jsxs(Autocomplete.InputGroup, {
43
+ "data-slot": "autocomplete-group",
44
+ className: cn(controlVariants({ size }), "flex items-center gap-(--cue-space-2)", controlGroupFocusClasses, className),
45
+ children: [/* @__PURE__ */ jsx(Autocomplete.Input, {
46
+ ref,
47
+ id,
48
+ "data-slot": "autocomplete-input",
49
+ placeholder,
50
+ "aria-label": ariaLabel,
51
+ "aria-labelledby": ariaLabelledBy,
52
+ className: cn(bareControlClasses, "truncate")
53
+ }), /* @__PURE__ */ jsx(Autocomplete.Clear, {
54
+ "aria-label": clearLabel,
55
+ "data-slot": "autocomplete-clear",
56
+ className: listboxAdornmentClasses,
57
+ children: /* @__PURE__ */ jsx(CrossGlyph, { className: "size-icon-sm" })
58
+ })]
59
+ }), /* @__PURE__ */ jsx(Autocomplete.Portal, {
60
+ ...portalProps,
61
+ children: /* @__PURE__ */ jsx(Autocomplete.Positioner, {
62
+ className: listboxPositionerClasses,
63
+ sideOffset,
64
+ children: /* @__PURE__ */ jsxs(Autocomplete.Popup, {
65
+ "data-slot": "autocomplete-popup",
66
+ className: cn(listboxPopupClasses, popupClassName),
67
+ children: [/* @__PURE__ */ jsx(Autocomplete.Empty, {
68
+ className: listboxEmptyClasses,
69
+ children: emptyMessage
70
+ }), /* @__PURE__ */ jsx(Autocomplete.List, {
71
+ className: listboxListClasses,
72
+ children: (item) => /* @__PURE__ */ jsx(Autocomplete.Item, {
73
+ value: item,
74
+ "data-slot": "autocomplete-item",
75
+ className: listboxItemClasses,
76
+ children: /* @__PURE__ */ jsx("span", {
77
+ className: "truncate",
78
+ children: item
79
+ })
80
+ }, item)
81
+ })]
82
+ })
83
+ })
84
+ })]
85
+ });
86
+ });
87
+ //#endregion
88
+ export { Autocomplete$1 as Autocomplete };
@@ -0,0 +1,47 @@
1
+ import * as React from "react";
2
+ //#region src/forms/button-group.d.ts
3
+ /** Which way a {@link ButtonGroup} runs. */
4
+ type ButtonGroupOrientation = "horizontal" | "vertical";
5
+ interface ButtonGroupProps extends React.ComponentPropsWithoutRef<"div"> {
6
+ /** Which way the children run. Defaults to `"horizontal"`. */
7
+ orientation?: ButtonGroupOrientation;
8
+ /**
9
+ * Join the children into one control (shared rims, outer corners only).
10
+ * Defaults to `true`; pass `false` for a merely-adjacent row of buttons that
11
+ * should still be announced as one group.
12
+ */
13
+ attached?: boolean;
14
+ /**
15
+ * Accessible name for the cluster. A group of buttons with no name is a group
16
+ * of buttons; with one it is "Blend mode".
17
+ */
18
+ "aria-label"?: string;
19
+ /** The buttons — {@link Button}, {@link IconButton} or anything button-shaped. */
20
+ children: React.ReactNode;
21
+ }
22
+ /**
23
+ * Several related actions drawn as one control.
24
+ *
25
+ * Purely presentational: it owns no state and imposes no roving focus, because
26
+ * its members are *actions*, each independently reachable by Tab. When the
27
+ * members represent a **choice** rather than actions, use {@link ToggleGroup}
28
+ * (several or none) or `SegmentedControl` (exactly one) — those carry the
29
+ * pressed-state ARIA a group of plain buttons must not fake.
30
+ *
31
+ * The children keep their own variants, so a `secondary`/`primary` pair reads as
32
+ * "and here is the one you probably want" without any extra API.
33
+ *
34
+ * @example
35
+ * <ButtonGroup aria-label="Blend mode">
36
+ * <Button>HTP</Button>
37
+ * <Button variant="primary">LTP</Button>
38
+ * </ButtonGroup>
39
+ * @example
40
+ * <ButtonGroup aria-label="Zoom" orientation="vertical">
41
+ * <IconButton aria-label="Zoom in" icon={Plus} variant="outline" />
42
+ * <IconButton aria-label="Zoom out" icon={Minus} variant="outline" />
43
+ * </ButtonGroup>
44
+ */
45
+ declare const ButtonGroup: React.ForwardRefExoticComponent<ButtonGroupProps & React.RefAttributes<HTMLDivElement>>;
46
+ //#endregion
47
+ export { ButtonGroup, ButtonGroupOrientation, ButtonGroupProps };