@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,75 @@
1
+ import { FormControlSize } from "./_chassis.js";
2
+ import * as React from "react";
3
+ //#region src/forms/select.d.ts
4
+ /** One row in a {@link Select}. */
5
+ interface SelectOption {
6
+ /** Submitted value and identity of the row. */
7
+ value: string;
8
+ /** What the user reads, in the trigger as well as the list. */
9
+ label: React.ReactNode;
10
+ /** Grey the row out and skip it during keyboard navigation. */
11
+ disabled?: boolean;
12
+ }
13
+ interface SelectProps {
14
+ /** The rows, in display order. */
15
+ items: readonly SelectOption[];
16
+ /** Selected value. Use with `onValueChange` for a controlled select. */
17
+ value?: string | null;
18
+ /** Initially selected value for an uncontrolled select. */
19
+ defaultValue?: string | null;
20
+ /** Called with the newly selected value (`null` when cleared). */
21
+ onValueChange?: (value: string | null) => void;
22
+ /** Shown in the trigger while nothing is selected. */
23
+ placeholder?: React.ReactNode;
24
+ /** Rung of the control ladder for the trigger. Defaults to `"md"`. */
25
+ size?: FormControlSize;
26
+ /** Prevent opening and grey the trigger out. */
27
+ disabled?: boolean;
28
+ /** Require a value before the owning form submits. */
29
+ required?: boolean;
30
+ /** Name for the hidden input, when the select is part of a form. */
31
+ name?: string;
32
+ /** Id forwarded to the select's hidden input. */
33
+ id?: string;
34
+ /** Accessible name for the trigger, when no {@link FieldLabel} names it. */
35
+ "aria-label"?: string;
36
+ /** Id of the element naming the trigger. */
37
+ "aria-labelledby"?: string;
38
+ /**
39
+ * Lock interaction to the popup while it is open. Defaults to `true`, matching
40
+ * Base UI; set `false` inside a canvas or a drag surface that must keep
41
+ * receiving pointer events.
42
+ */
43
+ modal?: boolean;
44
+ /** Extra classes for the trigger. */
45
+ className?: string;
46
+ /** Extra classes for the popup surface. */
47
+ popupClassName?: string;
48
+ /** Distance in px between the trigger and the popup. Defaults to `4`. */
49
+ sideOffset?: number;
50
+ }
51
+ /**
52
+ * A dropdown for choosing one of a known set of values.
53
+ *
54
+ * The trigger rides the recessed control chassis so a select lines up with the
55
+ * {@link Input}s beside it; the popup wears the overlay surface
56
+ * (`surface-2` + `border-overlay` + the overlay radius) that every floating
57
+ * element in this system shares. Rows are one `control-sm` tall — the list is
58
+ * meant to show a dozen options without scrolling.
59
+ *
60
+ * The popup is portalled through {@link useCuePortalProps}, so it carries the
61
+ * caller's `data-theme` / `data-density` / `data-mode` even though it mounts at
62
+ * the end of `<body>`. Without that a select opened inside an ultra-compact
63
+ * island would render at the page's density.
64
+ *
65
+ * @example
66
+ * <Select
67
+ * aria-label="Blend mode"
68
+ * items={[{ value: "htp", label: "HTP" }, { value: "ltp", label: "LTP" }]}
69
+ * value={mode}
70
+ * onValueChange={setMode}
71
+ * />
72
+ */
73
+ declare const Select: React.ForwardRefExoticComponent<SelectProps & React.RefAttributes<HTMLButtonElement>>;
74
+ //#endregion
75
+ export { Select, SelectOption, SelectProps };
@@ -0,0 +1,91 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { controlVariants } from "./_chassis.js";
4
+ import { useCuePortalProps } from "../system/portal.js";
5
+ import { CaretGlyph, TickGlyph } from "./_glyphs.js";
6
+ import * as React from "react";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { Select } from "@base-ui/react/select";
9
+ //#region src/forms/select.tsx
10
+ /**
11
+ * A dropdown for choosing one of a known set of values.
12
+ *
13
+ * The trigger rides the recessed control chassis so a select lines up with the
14
+ * {@link Input}s beside it; the popup wears the overlay surface
15
+ * (`surface-2` + `border-overlay` + the overlay radius) that every floating
16
+ * element in this system shares. Rows are one `control-sm` tall — the list is
17
+ * meant to show a dozen options without scrolling.
18
+ *
19
+ * The popup is portalled through {@link useCuePortalProps}, so it carries the
20
+ * caller's `data-theme` / `data-density` / `data-mode` even though it mounts at
21
+ * the end of `<body>`. Without that a select opened inside an ultra-compact
22
+ * island would render at the page's density.
23
+ *
24
+ * @example
25
+ * <Select
26
+ * aria-label="Blend mode"
27
+ * items={[{ value: "htp", label: "HTP" }, { value: "ltp", label: "LTP" }]}
28
+ * value={mode}
29
+ * onValueChange={setMode}
30
+ * />
31
+ */
32
+ const Select$1 = React.forwardRef(function Select$2({ items, value, defaultValue, onValueChange, placeholder, size, disabled, required, name, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, modal, className, popupClassName, sideOffset = 4 }, ref) {
33
+ const portalProps = useCuePortalProps();
34
+ const handleValueChange = React.useCallback((next) => {
35
+ onValueChange?.(next ?? null);
36
+ }, [onValueChange]);
37
+ return /* @__PURE__ */ jsxs(Select.Root, {
38
+ items,
39
+ value,
40
+ defaultValue,
41
+ onValueChange: onValueChange === void 0 ? void 0 : handleValueChange,
42
+ disabled,
43
+ required,
44
+ name,
45
+ id,
46
+ modal,
47
+ children: [/* @__PURE__ */ jsxs(Select.Trigger, {
48
+ ref,
49
+ "data-slot": "select-trigger",
50
+ "aria-label": ariaLabel,
51
+ "aria-labelledby": ariaLabelledBy,
52
+ className: cn(controlVariants({ size }), "flex cursor-default items-center justify-between gap-(--cue-space-3) text-left", "hover:not-data-disabled:border-border-strong", className),
53
+ children: [/* @__PURE__ */ jsx(Select.Value, {
54
+ className: "truncate data-[placeholder]:text-fg-subtle",
55
+ placeholder
56
+ }), /* @__PURE__ */ jsx(Select.Icon, {
57
+ className: "flex shrink-0 items-center text-fg-subtle",
58
+ children: /* @__PURE__ */ jsx(CaretGlyph, { className: "size-icon-md" })
59
+ })]
60
+ }), /* @__PURE__ */ jsx(Select.Portal, {
61
+ ...portalProps,
62
+ children: /* @__PURE__ */ jsx(Select.Positioner, {
63
+ className: "z-50 outline-none",
64
+ sideOffset,
65
+ alignItemWithTrigger: false,
66
+ children: /* @__PURE__ */ jsx(Select.Popup, {
67
+ "data-slot": "select-popup",
68
+ className: cn("min-w-(--anchor-width) origin-(--transform-origin) overflow-hidden rounded-(--radius-overlay) border border-border-overlay bg-surface-2 py-(--cue-space-1) shadow-[0_8px_24px_rgba(0,0,0,0.4)] outline-none", "transition-[opacity,scale] duration-100 ease-out motion-reduce:transition-none", "data-[starting-style]:scale-[0.98] data-[starting-style]:opacity-0", "data-[ending-style]:scale-[0.98] data-[ending-style]:opacity-0", popupClassName),
69
+ children: /* @__PURE__ */ jsx(Select.List, {
70
+ className: "max-h-(--available-height) overflow-y-auto",
71
+ children: items.map((item) => /* @__PURE__ */ jsxs(Select.Item, {
72
+ value: item.value,
73
+ disabled: item.disabled,
74
+ "data-slot": "select-item",
75
+ className: "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",
76
+ children: [/* @__PURE__ */ jsx("span", {
77
+ className: "flex size-icon-sm shrink-0 items-center justify-center",
78
+ children: /* @__PURE__ */ jsx(Select.ItemIndicator, { children: /* @__PURE__ */ jsx(TickGlyph, { className: "size-icon-sm" }) })
79
+ }), /* @__PURE__ */ jsx(Select.ItemText, {
80
+ className: "truncate",
81
+ children: item.label
82
+ })]
83
+ }, item.value))
84
+ })
85
+ })
86
+ })
87
+ })]
88
+ });
89
+ });
90
+ //#endregion
91
+ export { Select$1 as Select };
@@ -0,0 +1,44 @@
1
+ import * as React from "react";
2
+ import { Slider } from "@base-ui/react/slider";
3
+ //#region src/forms/slider.d.ts
4
+ interface SliderProps extends Omit<Slider.Root.Props, "className" | "onValueCommitted"> {
5
+ /** Extra classes, merged over the root defaults. */
6
+ className?: string;
7
+ /**
8
+ * Fired once when a gesture *ends*: pointer-up after a drag, key-up after a
9
+ * step, or a track press. `onValueChange` fires on every intermediate value —
10
+ * a drag emits dozens — so an undo stack, a network write or a persisted
11
+ * setting must hang off this, not off `onValueChange`, or it will record every
12
+ * frame of the drag as a separate edit.
13
+ */
14
+ onCommit?: (value: number | number[]) => void;
15
+ /** Visible label above the track. */
16
+ label?: React.ReactNode;
17
+ /** Show the live formatted value opposite the label. */
18
+ showValue?: boolean;
19
+ /**
20
+ * Accessible name for the thumb. With several thumbs each is suffixed with its
21
+ * 1-based index, so a range slider announces "Window 1" and "Window 2".
22
+ */
23
+ "aria-label"?: string;
24
+ }
25
+ /**
26
+ * A continuous value control: one thumb, or several for a range.
27
+ *
28
+ * Drawn as a 2px rail rather than the chunky default — at console density a
29
+ * slider is a readout first and a grab target second, and the thumb supplies the
30
+ * affordance. The filled portion uses the theme accent so the slider agrees with
31
+ * every other "this much" indicator on screen.
32
+ *
33
+ * The important part of the API is {@link SliderProps.onCommit}: the
34
+ * change/commit split is what lets a host app coalesce a whole drag into one
35
+ * undo entry instead of hundreds.
36
+ *
37
+ * @example
38
+ * <Slider aria-label="Intensity" value={level} onValueChange={setLevel} onCommit={pushUndo} />
39
+ * @example
40
+ * <Slider label="Window" showValue defaultValue={[20, 60]} />
41
+ */
42
+ declare const Slider$1: React.ForwardRefExoticComponent<Omit<SliderProps, "ref"> & React.RefAttributes<HTMLDivElement>>;
43
+ //#endregion
44
+ export { Slider$1 as Slider, SliderProps };
@@ -0,0 +1,65 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import * as React from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { Slider } from "@base-ui/react/slider";
6
+ //#region src/forms/slider.tsx
7
+ /** How many thumbs the current value implies. */
8
+ function thumbCount(value, defaultValue) {
9
+ const source = value ?? defaultValue;
10
+ return Array.isArray(source) ? source.length : 1;
11
+ }
12
+ /**
13
+ * A continuous value control: one thumb, or several for a range.
14
+ *
15
+ * Drawn as a 2px rail rather than the chunky default — at console density a
16
+ * slider is a readout first and a grab target second, and the thumb supplies the
17
+ * affordance. The filled portion uses the theme accent so the slider agrees with
18
+ * every other "this much" indicator on screen.
19
+ *
20
+ * The important part of the API is {@link SliderProps.onCommit}: the
21
+ * change/commit split is what lets a host app coalesce a whole drag into one
22
+ * undo entry instead of hundreds.
23
+ *
24
+ * @example
25
+ * <Slider aria-label="Intensity" value={level} onValueChange={setLevel} onCommit={pushUndo} />
26
+ * @example
27
+ * <Slider label="Window" showValue defaultValue={[20, 60]} />
28
+ */
29
+ const Slider$1 = React.forwardRef(function Slider$2({ className, onCommit, label, showValue = false, "aria-label": ariaLabel, value, defaultValue, ...elementProps }, ref) {
30
+ const count = thumbCount(value, defaultValue);
31
+ const handleCommitted = React.useCallback((next) => {
32
+ onCommit?.(typeof next === "number" ? next : [...next]);
33
+ }, [onCommit]);
34
+ return /* @__PURE__ */ jsxs(Slider.Root, {
35
+ ref,
36
+ "data-slot": "slider",
37
+ value,
38
+ defaultValue,
39
+ onValueCommitted: onCommit === void 0 ? void 0 : handleCommitted,
40
+ className: cn("flex w-full flex-col gap-(--cue-space-2)", className),
41
+ ...elementProps,
42
+ children: [label === void 0 && !showValue ? null : /* @__PURE__ */ jsxs("div", {
43
+ className: "flex items-baseline justify-between gap-(--cue-space-3) font-mono text-(length:--cue-text-label) tracking-[0.1em] text-fg-muted uppercase",
44
+ children: [label === void 0 ? /* @__PURE__ */ jsx("span", {}) : /* @__PURE__ */ jsx(Slider.Label, { children: label }), showValue ? /* @__PURE__ */ jsx(Slider.Value, { className: "tabular-nums text-fg normal-case tracking-normal" }) : null]
45
+ }), /* @__PURE__ */ jsx(Slider.Control, {
46
+ "data-slot": "slider-control",
47
+ className: "flex h-control-sm w-full touch-none items-center select-none",
48
+ children: /* @__PURE__ */ jsxs(Slider.Track, {
49
+ "data-slot": "slider-track",
50
+ className: "relative h-0.5 w-full rounded-full bg-border select-none",
51
+ children: [/* @__PURE__ */ jsx(Slider.Indicator, {
52
+ "data-slot": "slider-indicator",
53
+ className: "h-full rounded-full bg-accent select-none"
54
+ }), Array.from({ length: count }, (_, index) => /* @__PURE__ */ jsx(Slider.Thumb, {
55
+ index,
56
+ "data-slot": "slider-thumb",
57
+ "aria-label": ariaLabel === void 0 ? void 0 : count > 1 ? `${ariaLabel} ${index + 1}` : ariaLabel,
58
+ className: "size-[0.5rem] rounded-full bg-accent outline-none focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-accent data-[disabled]:opacity-40"
59
+ }, index))]
60
+ })
61
+ })]
62
+ });
63
+ });
64
+ //#endregion
65
+ export { Slider$1 as Slider };
@@ -0,0 +1,36 @@
1
+ import * as React from "react";
2
+ import { Switch } from "@base-ui/react/switch";
3
+ //#region src/forms/switch.d.ts
4
+ interface SwitchProps extends Omit<Switch.Root.Props, "className"> {
5
+ /** Extra classes, merged over the track defaults. */
6
+ className?: string;
7
+ /**
8
+ * Inline label rendered beside the track and wrapped with it in a `<label>`,
9
+ * so the text is both the accessible name and part of the hit target.
10
+ */
11
+ label?: React.ReactNode;
12
+ /**
13
+ * Track size. Defaults to `"md"` (28×14). `sm` exists because a console packs
14
+ * switches into 20px rows where a stock 44px switch simply does not fit.
15
+ */
16
+ size?: "sm" | "md" | "lg";
17
+ }
18
+ /**
19
+ * A binary on/off control — `role="switch"`, not a checkbox.
20
+ *
21
+ * The distinction matters to assistive tech: a switch takes effect immediately,
22
+ * a checkbox is a value you submit later. Use this for "live" state (blackout,
23
+ * mute, follow) and {@link Checkbox} for form values.
24
+ *
25
+ * Ships in three sizes down to a 22×12 track, because a dense console cannot
26
+ * spare the height a stock switch demands. The thumb slides on a transform and
27
+ * stills entirely under `prefers-reduced-motion`.
28
+ *
29
+ * @example
30
+ * <Switch label="Blackout" checked={blackout} onCheckedChange={setBlackout} />
31
+ * @example
32
+ * <Switch aria-label="Mute channel" size="sm" />
33
+ */
34
+ declare const Switch$1: React.ForwardRefExoticComponent<Omit<SwitchProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
35
+ //#endregion
36
+ export { Switch$1 as Switch, SwitchProps };
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import * as React from "react";
4
+ import { jsx, jsxs } from "react/jsx-runtime";
5
+ import { Switch } from "@base-ui/react/switch";
6
+ //#region src/forms/switch.tsx
7
+ /**
8
+ * The three tracks, in rem so they follow browser zoom and the user's font size.
9
+ *
10
+ * Geometry (px at the 16px reference root): `sm` 22×12 with an 8px thumb, `md`
11
+ * 28×14 with 10px, `lg` 34×18 with 12px. The travel is
12
+ * `track − 2×border − 2×inset − thumb`, i.e. the thumb sits one hairline inside
13
+ * the rim at both ends.
14
+ */
15
+ const SWITCH_SIZES = {
16
+ sm: {
17
+ track: "w-[1.375rem] h-[0.75rem]",
18
+ thumb: "size-[0.5rem] data-[checked]:translate-x-[0.625rem]"
19
+ },
20
+ md: {
21
+ track: "w-[1.75rem] h-[0.875rem]",
22
+ thumb: "size-[0.625rem] data-[checked]:translate-x-[0.875rem]"
23
+ },
24
+ lg: {
25
+ track: "w-[2.125rem] h-[1.125rem]",
26
+ thumb: "size-[0.75rem] data-[checked]:translate-x-[1.125rem]"
27
+ }
28
+ };
29
+ /**
30
+ * A binary on/off control — `role="switch"`, not a checkbox.
31
+ *
32
+ * The distinction matters to assistive tech: a switch takes effect immediately,
33
+ * a checkbox is a value you submit later. Use this for "live" state (blackout,
34
+ * mute, follow) and {@link Checkbox} for form values.
35
+ *
36
+ * Ships in three sizes down to a 22×12 track, because a dense console cannot
37
+ * spare the height a stock switch demands. The thumb slides on a transform and
38
+ * stills entirely under `prefers-reduced-motion`.
39
+ *
40
+ * @example
41
+ * <Switch label="Blackout" checked={blackout} onCheckedChange={setBlackout} />
42
+ * @example
43
+ * <Switch aria-label="Mute channel" size="sm" />
44
+ */
45
+ const Switch$1 = React.forwardRef(function Switch$2({ className, label, size = "md", ...elementProps }, ref) {
46
+ const labelId = React.useId();
47
+ const hasLabel = label !== void 0;
48
+ const geometry = SWITCH_SIZES[size];
49
+ const control = /* @__PURE__ */ jsx(Switch.Root, {
50
+ ref,
51
+ "data-slot": "switch",
52
+ "aria-labelledby": hasLabel ? labelId : void 0,
53
+ className: cn("relative inline-flex shrink-0 items-center rounded-full border border-border bg-surface-3 p-0 outline-none transition-colors duration-150 motion-reduce:transition-none", geometry.track, "hover:border-border-strong", "data-[checked]:border-accent data-[checked]:bg-accent", "focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-1 focus-visible:outline-accent", "data-[disabled]:pointer-events-none data-[disabled]:opacity-40", "data-[invalid]:border-danger", className),
54
+ ...elementProps,
55
+ children: /* @__PURE__ */ jsx(Switch.Thumb, {
56
+ "data-slot": "switch-thumb",
57
+ className: cn("absolute top-1/2 left-px -translate-y-1/2 rounded-full bg-fg-muted transition-transform duration-150 motion-reduce:transition-none", geometry.thumb, "data-[checked]:bg-accent-fg")
58
+ })
59
+ });
60
+ if (!hasLabel) return control;
61
+ return /* @__PURE__ */ jsxs("label", {
62
+ "data-slot": "switch-label",
63
+ className: "inline-flex cursor-pointer items-center gap-(--cue-space-3) font-mono text-(length:--cue-text-ui) text-fg-muted select-none has-[[data-disabled]]:cursor-default has-[[data-disabled]]:opacity-40",
64
+ children: [control, /* @__PURE__ */ jsx("span", {
65
+ id: labelId,
66
+ children: label
67
+ })]
68
+ });
69
+ });
70
+ //#endregion
71
+ export { Switch$1 as Switch };
@@ -0,0 +1,69 @@
1
+ import { FormControlSize } from "./_chassis.js";
2
+ import * as React from "react";
3
+ //#region src/forms/tags-input.d.ts
4
+ interface TagsInputProps {
5
+ /** The tags. Use with `onValueChange` for a controlled field. */
6
+ value?: readonly string[];
7
+ /** Initial tags for an uncontrolled field. */
8
+ defaultValue?: readonly string[];
9
+ /** Called with the full list after every add or remove. */
10
+ onValueChange?: (value: string[]) => void;
11
+ /**
12
+ * Optional known tags, offered in a popup as the user types. Free-form entry
13
+ * works with or without them — a suggestion is a shortcut, never a constraint.
14
+ */
15
+ suggestions?: readonly string[];
16
+ /** Shown while there are no tags. */
17
+ placeholder?: string;
18
+ /** Rung of the control ladder. Defaults to `"md"`. */
19
+ size?: FormControlSize;
20
+ /**
21
+ * Extra keys that commit the pending tag, on top of Enter. Defaults to `[","]`
22
+ * — the separator every "type a list" field in the wild accepts.
23
+ */
24
+ separators?: readonly string[];
25
+ /** Refuse further tags past this many. */
26
+ max?: number;
27
+ /** Prevent entry and grey the field out. */
28
+ disabled?: boolean;
29
+ /** Name for the hidden input, when the field is part of a form. */
30
+ name?: string;
31
+ /** Id forwarded to the text input. */
32
+ id?: string;
33
+ /** Accessible name for the input, when no {@link FieldLabel} names it. */
34
+ "aria-label"?: string;
35
+ /** Id of the element naming the input. */
36
+ "aria-labelledby"?: string;
37
+ /**
38
+ * Accessible name for a tag's remove button. Defaults to
39
+ * ``(tag) => `Remove ${tag}` ``.
40
+ */
41
+ removeLabel?: (tag: string) => string;
42
+ /** Extra classes for the field. */
43
+ className?: string;
44
+ /** Extra classes for the popup surface. */
45
+ popupClassName?: string;
46
+ /** Distance in px between the field and the popup. Defaults to `4`. */
47
+ sideOffset?: number;
48
+ }
49
+ /**
50
+ * Free-form tags, each a removable chip.
51
+ *
52
+ * {@link MultiSelect} with the set opened up: Enter (or a separator key) commits
53
+ * whatever is in the box, so this is the control for labels, hostnames and
54
+ * anything else the product cannot enumerate in advance. Pass `suggestions` to
55
+ * offer the ones you *do* know.
56
+ *
57
+ * Three rules the hand-rolled version always misses, all enforced here: tags are
58
+ * trimmed, blanks are refused, and duplicates are refused silently rather than
59
+ * appended (a tag list is a set). Backspace in an empty input removes the last
60
+ * tag, courtesy of Base UI's chip handling.
61
+ *
62
+ * @example
63
+ * <TagsInput aria-label="Labels" value={labels} onValueChange={setLabels} />
64
+ * @example
65
+ * <TagsInput aria-label="Labels" suggestions={knownLabels} max={8} />
66
+ */
67
+ declare const TagsInput: React.ForwardRefExoticComponent<TagsInputProps & React.RefAttributes<HTMLInputElement>>;
68
+ //#endregion
69
+ export { TagsInput, TagsInputProps };
@@ -0,0 +1,148 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { bareControlClasses, controlGroupFocusClasses, controlSurface } from "./_chassis.js";
4
+ import { useCuePortalProps } from "../system/portal.js";
5
+ import { CrossGlyph } from "./_glyphs.js";
6
+ import { chipFieldClasses, chipRemoveClasses, listboxItemClasses, listboxListClasses, listboxPopupClasses, listboxPositionerClasses, valueChipClasses } from "./_listbox.js";
7
+ import * as React from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ import { Combobox } from "@base-ui/react/combobox";
10
+ //#region src/forms/tags-input.tsx
11
+ /** Horizontal padding and type size per rung; the height comes from the chips. */
12
+ const FIELD_SIZES = {
13
+ sm: "min-h-control-sm px-(--cue-space-2) text-(length:--cue-text-label)",
14
+ md: "min-h-control-md px-(--cue-space-3) text-(length:--cue-text-ui)",
15
+ lg: "min-h-control-lg px-(--cue-space-4) text-(length:--cue-text-body)"
16
+ };
17
+ /**
18
+ * Free-form tags, each a removable chip.
19
+ *
20
+ * {@link MultiSelect} with the set opened up: Enter (or a separator key) commits
21
+ * whatever is in the box, so this is the control for labels, hostnames and
22
+ * anything else the product cannot enumerate in advance. Pass `suggestions` to
23
+ * offer the ones you *do* know.
24
+ *
25
+ * Three rules the hand-rolled version always misses, all enforced here: tags are
26
+ * trimmed, blanks are refused, and duplicates are refused silently rather than
27
+ * appended (a tag list is a set). Backspace in an empty input removes the last
28
+ * tag, courtesy of Base UI's chip handling.
29
+ *
30
+ * @example
31
+ * <TagsInput aria-label="Labels" value={labels} onValueChange={setLabels} />
32
+ * @example
33
+ * <TagsInput aria-label="Labels" suggestions={knownLabels} max={8} />
34
+ */
35
+ const TagsInput = React.forwardRef(function TagsInput({ value, defaultValue, onValueChange, suggestions, placeholder, size = "md", separators = [","], max, disabled, name, id, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, removeLabel = (tag) => `Remove ${tag}`, className, popupClassName, sideOffset = 4 }, ref) {
36
+ const portalProps = useCuePortalProps();
37
+ const isControlled = value !== void 0;
38
+ const [uncontrolled, setUncontrolled] = React.useState(() => [...defaultValue ?? []]);
39
+ const tags = React.useMemo(() => isControlled ? [...value] : uncontrolled, [
40
+ isControlled,
41
+ uncontrolled,
42
+ value
43
+ ]);
44
+ const [query, setQuery] = React.useState("");
45
+ const highlighted = React.useRef(void 0);
46
+ const commit = React.useCallback((next) => {
47
+ if (!isControlled) setUncontrolled(next);
48
+ onValueChange?.(next);
49
+ }, [isControlled, onValueChange]);
50
+ const add = React.useCallback((raw) => {
51
+ const tag = raw.trim();
52
+ if (tag === "") return;
53
+ if (tags.includes(tag)) return;
54
+ if (max !== void 0 && tags.length >= max) return;
55
+ commit([...tags, tag]);
56
+ setQuery("");
57
+ }, [
58
+ commit,
59
+ max,
60
+ tags
61
+ ]);
62
+ const handleValueChange = React.useCallback((next) => {
63
+ const picked = next;
64
+ if (max !== void 0 && picked.length > max) return;
65
+ commit(picked);
66
+ setQuery("");
67
+ }, [commit, max]);
68
+ const handleKeyDown = React.useCallback((event) => {
69
+ if (event.defaultPrevented || disabled === true) return;
70
+ if (!(event.key === "Enter" || separators.includes(event.key)) || highlighted.current !== void 0) return;
71
+ if (query.trim() === "") {
72
+ if (event.key !== "Enter") event.preventDefault();
73
+ return;
74
+ }
75
+ event.preventDefault();
76
+ add(query);
77
+ }, [
78
+ add,
79
+ disabled,
80
+ query,
81
+ separators
82
+ ]);
83
+ return /* @__PURE__ */ jsxs(Combobox.Root, {
84
+ multiple: true,
85
+ items: suggestions ?? [],
86
+ value: tags,
87
+ onValueChange: handleValueChange,
88
+ inputValue: query,
89
+ onInputValueChange: setQuery,
90
+ onItemHighlighted: (item) => {
91
+ highlighted.current = item;
92
+ },
93
+ disabled,
94
+ name,
95
+ children: [/* @__PURE__ */ jsx(Combobox.InputGroup, {
96
+ "data-slot": "tags-input-group",
97
+ className: cn(controlSurface, FIELD_SIZES[size], controlGroupFocusClasses, className),
98
+ children: /* @__PURE__ */ jsx(Combobox.Chips, {
99
+ className: chipFieldClasses,
100
+ children: /* @__PURE__ */ jsx(Combobox.Value, { children: (selected) => /* @__PURE__ */ jsxs(React.Fragment, { children: [selected.map((tag) => /* @__PURE__ */ jsxs(Combobox.Chip, {
101
+ "data-slot": "tags-input-chip",
102
+ className: valueChipClasses,
103
+ children: [/* @__PURE__ */ jsx("span", {
104
+ className: "truncate",
105
+ children: tag
106
+ }), /* @__PURE__ */ jsx(Combobox.ChipRemove, {
107
+ "aria-label": removeLabel(tag),
108
+ className: chipRemoveClasses,
109
+ children: /* @__PURE__ */ jsx(CrossGlyph, { className: "size-icon-sm" })
110
+ })]
111
+ }, tag)), /* @__PURE__ */ jsx(Combobox.Input, {
112
+ ref,
113
+ id,
114
+ "data-slot": "tags-input-input",
115
+ placeholder: selected.length > 0 ? "" : placeholder,
116
+ "aria-label": ariaLabel,
117
+ "aria-labelledby": ariaLabelledBy,
118
+ onKeyDown: handleKeyDown,
119
+ className: cn(bareControlClasses, "h-control-sm w-auto min-w-[6ch]")
120
+ })] }) })
121
+ })
122
+ }), suggestions === void 0 ? null : /* @__PURE__ */ jsx(Combobox.Portal, {
123
+ ...portalProps,
124
+ children: /* @__PURE__ */ jsx(Combobox.Positioner, {
125
+ className: listboxPositionerClasses,
126
+ sideOffset,
127
+ children: /* @__PURE__ */ jsx(Combobox.Popup, {
128
+ "data-slot": "tags-input-popup",
129
+ className: cn(listboxPopupClasses, popupClassName),
130
+ children: /* @__PURE__ */ jsx(Combobox.List, {
131
+ className: listboxListClasses,
132
+ children: (item) => /* @__PURE__ */ jsx(Combobox.Item, {
133
+ value: item,
134
+ "data-slot": "tags-input-item",
135
+ className: listboxItemClasses,
136
+ children: /* @__PURE__ */ jsx("span", {
137
+ className: "truncate",
138
+ children: item
139
+ })
140
+ }, item)
141
+ })
142
+ })
143
+ })
144
+ })]
145
+ });
146
+ });
147
+ //#endregion
148
+ export { TagsInput };
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ //#region src/forms/textarea.d.ts
3
+ interface TextareaProps extends React.ComponentPropsWithoutRef<"textarea"> {
4
+ /** Extra classes, merged over the chassis. */
5
+ className?: string;
6
+ /** Visible rows before the box starts scrolling. Defaults to `3`. */
7
+ rows?: number;
8
+ }
9
+ /**
10
+ * The multi-line text control.
11
+ *
12
+ * Rendered through Base UI's `Field.Control`, so it joins a {@link Field} on the
13
+ * same terms as {@link Input} — label wiring, `aria-describedby`, `data-invalid`
14
+ * — while still being a real `<textarea>`.
15
+ *
16
+ * Wears the recessed chassis minus the fixed control height: a textarea's job is
17
+ * to be taller than one rung. Height comes from `rows`, and the user may drag it
18
+ * taller (`resize-y`) but never wider, which would break the panel grid.
19
+ *
20
+ * @example
21
+ * <Textarea placeholder="Notes for the operator" />
22
+ * @example
23
+ * <Field><FieldLabel>Cue notes</FieldLabel><Textarea rows={6} /></Field>
24
+ */
25
+ declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
26
+ //#endregion
27
+ export { Textarea, TextareaProps };
@@ -0,0 +1,37 @@
1
+ "use client";
2
+ import { cn } from "../lib/cn.js";
3
+ import { controlSurface } from "./_chassis.js";
4
+ import * as React from "react";
5
+ import { jsx } from "react/jsx-runtime";
6
+ import { Field } from "@base-ui/react/field";
7
+ //#region src/forms/textarea.tsx
8
+ /**
9
+ * The multi-line text control.
10
+ *
11
+ * Rendered through Base UI's `Field.Control`, so it joins a {@link Field} on the
12
+ * same terms as {@link Input} — label wiring, `aria-describedby`, `data-invalid`
13
+ * — while still being a real `<textarea>`.
14
+ *
15
+ * Wears the recessed chassis minus the fixed control height: a textarea's job is
16
+ * to be taller than one rung. Height comes from `rows`, and the user may drag it
17
+ * taller (`resize-y`) but never wider, which would break the panel grid.
18
+ *
19
+ * @example
20
+ * <Textarea placeholder="Notes for the operator" />
21
+ * @example
22
+ * <Field><FieldLabel>Cue notes</FieldLabel><Textarea rows={6} /></Field>
23
+ */
24
+ const Textarea = React.forwardRef(function Textarea({ className, rows = 3, ...elementProps }, ref) {
25
+ const controlProps = elementProps;
26
+ return /* @__PURE__ */ jsx(Field.Control, {
27
+ render: /* @__PURE__ */ jsx("textarea", {
28
+ ref,
29
+ rows
30
+ }),
31
+ "data-slot": "textarea",
32
+ className: cn(controlSurface, "resize-y px-(--cue-space-4) py-(--cue-space-3) text-(length:--cue-text-ui) leading-relaxed", className),
33
+ ...controlProps
34
+ });
35
+ });
36
+ //#endregion
37
+ export { Textarea };