@cueplusplus/ui 0.1.0 → 0.3.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 (246) hide show
  1. package/CHANGELOG.md +705 -0
  2. package/dist/brand/_chassis.d.ts +54 -0
  3. package/dist/brand/_chassis.js +81 -0
  4. package/dist/brand/_geometry.js +41 -0
  5. package/dist/brand/cue-logotype.d.ts +29 -0
  6. package/dist/brand/cue-logotype.js +60 -0
  7. package/dist/brand/cue-mark.d.ts +30 -0
  8. package/dist/brand/cue-mark.js +61 -0
  9. package/dist/brand/index.d.ts +5 -0
  10. package/dist/brand/plussie.d.ts +67 -0
  11. package/dist/brand/plussie.js +125 -0
  12. package/dist/chat/agent-pile.js +1 -1
  13. package/dist/chat/ask-box.js +2 -2
  14. package/dist/chat/delegation-card.js +1 -1
  15. package/dist/chat/message.js +2 -2
  16. package/dist/chrome/_edge-scroller.d.ts +45 -0
  17. package/dist/chrome/_edge-scroller.js +149 -0
  18. package/dist/chrome/_glyphs.js +19 -1
  19. package/dist/chrome/_tabs-scroll.d.ts +13 -8
  20. package/dist/chrome/_tabs-scroll.js +13 -8
  21. package/dist/chrome/app-bar.d.ts +103 -0
  22. package/dist/chrome/app-bar.js +175 -0
  23. package/dist/chrome/app-shell.d.ts +125 -0
  24. package/dist/chrome/app-shell.js +167 -0
  25. package/dist/chrome/footer.d.ts +75 -0
  26. package/dist/chrome/footer.js +68 -0
  27. package/dist/chrome/index.d.ts +5 -1
  28. package/dist/chrome/index.js +4 -1
  29. package/dist/chrome/navigation-menu.js +1 -1
  30. package/dist/chrome/page-shell.d.ts +1 -1
  31. package/dist/chrome/page-shell.js +15 -5
  32. package/dist/chrome/segmented-control.d.ts +19 -0
  33. package/dist/chrome/segmented-control.js +40 -21
  34. package/dist/chrome/tabs.js +21 -65
  35. package/dist/chrome/toolbar.d.ts +22 -0
  36. package/dist/chrome/toolbar.js +26 -5
  37. package/dist/configurator/_overrides.js +22 -8
  38. package/dist/configurator/configurator.js +1 -1
  39. package/dist/configurator/panel-sections.js +10 -4
  40. package/dist/dmx/channel-matrix.js +1 -1
  41. package/dist/forms/otp-field.js +1 -1
  42. package/dist/index.d.ts +18 -9
  43. package/dist/index.js +16 -10
  44. package/dist/instruments/data-table.js +1 -1
  45. package/dist/instruments/index.d.ts +2 -2
  46. package/dist/instruments/index.js +2 -2
  47. package/dist/instruments/table.d.ts +14 -1
  48. package/dist/instruments/table.js +20 -1
  49. package/dist/layout/carousel.js +1 -1
  50. package/dist/layout/container.d.ts +1 -1
  51. package/dist/layout/container.js +6 -3
  52. package/dist/layout/index.d.ts +3 -3
  53. package/dist/layout/index.js +3 -3
  54. package/dist/layout/pagination.js +1 -1
  55. package/dist/layout/sidebar.d.ts +23 -3
  56. package/dist/layout/sidebar.js +18 -7
  57. package/dist/midi/spectrum-visualizer.js +1 -1
  58. package/dist/midi/timeline-ruler.js +1 -1
  59. package/dist/overlays/command-palette.js +1 -1
  60. package/dist/overlays/dialog.js +1 -1
  61. package/dist/overlays/dropdown-menu.js +2 -2
  62. package/dist/overlays/hover-card.js +1 -1
  63. package/dist/overlays/index.js +1 -1
  64. package/dist/overlays/popover.js +1 -1
  65. package/dist/overlays/sheet.js +1 -1
  66. package/dist/overlays/toast.js +1 -1
  67. package/dist/primitives/chip.d.ts +1 -1
  68. package/dist/primitives/index.d.ts +1 -1
  69. package/dist/primitives/index.js +1 -1
  70. package/dist/primitives/status-dot.d.ts +7 -0
  71. package/dist/primitives/status-dot.js +8 -1
  72. package/dist/styles.css +58 -2
  73. package/dist/system/density.d.ts +4 -1
  74. package/dist/system/density.js +12 -4
  75. package/dist/system/index.d.ts +4 -4
  76. package/dist/system/portal.d.ts +5 -5
  77. package/dist/system/portal.js +30 -11
  78. package/dist/system/prepaint.d.ts +34 -9
  79. package/dist/system/prepaint.js +48 -25
  80. package/dist/system/theme-provider.d.ts +48 -11
  81. package/dist/system/theme-provider.js +109 -35
  82. package/dist/system/use-density.d.ts +3 -3
  83. package/dist/system/use-density.js +16 -6
  84. package/dist/system/use-theme.d.ts +4 -2
  85. package/dist/system/use-theme.js +4 -2
  86. package/dist/theming/_presets.js +133 -5
  87. package/dist/theming/create-theme.d.ts +2 -2
  88. package/dist/theming/create-theme.js +37 -19
  89. package/dist/theming/serialize.d.ts +1 -1
  90. package/dist/theming/serialize.js +25 -1
  91. package/manifest/components/accordion.json +154 -0
  92. package/manifest/components/agent-pile.json +116 -0
  93. package/manifest/components/alert-dialog.json +190 -0
  94. package/manifest/components/app-bar.json +244 -0
  95. package/manifest/components/app-shell.json +291 -0
  96. package/manifest/components/app-window-frame.json +102 -0
  97. package/manifest/components/ask-box.json +209 -0
  98. package/manifest/components/autocomplete.json +197 -0
  99. package/manifest/components/avatar-group.json +72 -0
  100. package/manifest/components/avatar.json +95 -0
  101. package/manifest/components/breadcrumb.json +74 -0
  102. package/manifest/components/button-group.json +74 -0
  103. package/manifest/components/button.json +125 -0
  104. package/manifest/components/calendar.json +65 -0
  105. package/manifest/components/card.json +140 -0
  106. package/manifest/components/carousel.json +200 -0
  107. package/manifest/components/channel-matrix.json +173 -0
  108. package/manifest/components/chart-container.json +111 -0
  109. package/manifest/components/chart-ramp.json +72 -0
  110. package/manifest/components/chart-swatch.json +65 -0
  111. package/manifest/components/chart-tooltip-content.json +114 -0
  112. package/manifest/components/checkbox-group.json +68 -0
  113. package/manifest/components/checkbox.json +93 -0
  114. package/manifest/components/chip.json +132 -0
  115. package/manifest/components/collapsible.json +120 -0
  116. package/manifest/components/color-area.json +59 -0
  117. package/manifest/components/color-field.json +79 -0
  118. package/manifest/components/color-picker.json +175 -0
  119. package/manifest/components/color-slider.json +75 -0
  120. package/manifest/components/color-swatch.json +68 -0
  121. package/manifest/components/colors-section.json +66 -0
  122. package/manifest/components/combobox.json +198 -0
  123. package/manifest/components/command-palette.json +177 -0
  124. package/manifest/components/composer.json +176 -0
  125. package/manifest/components/container.json +60 -0
  126. package/manifest/components/context-menu.json +121 -0
  127. package/manifest/components/copy-button.json +93 -0
  128. package/manifest/components/cue-logotype.json +96 -0
  129. package/manifest/components/cue-mark.json +97 -0
  130. package/manifest/components/cue-portal-frame.json +55 -0
  131. package/manifest/components/data-table-pagination.json +83 -0
  132. package/manifest/components/data-table-toolbar.json +104 -0
  133. package/manifest/components/date-field.json +80 -0
  134. package/manifest/components/date-picker.json +191 -0
  135. package/manifest/components/date-range-picker.json +191 -0
  136. package/manifest/components/delegation-card.json +144 -0
  137. package/manifest/components/density.json +58 -0
  138. package/manifest/components/description-list.json +84 -0
  139. package/manifest/components/dialog.json +198 -0
  140. package/manifest/components/disclosure.json +109 -0
  141. package/manifest/components/dmx-bar.json +94 -0
  142. package/manifest/components/dmx-strip.json +101 -0
  143. package/manifest/components/drawer.json +179 -0
  144. package/manifest/components/dropdown-menu.json +229 -0
  145. package/manifest/components/empty-state.json +90 -0
  146. package/manifest/components/env-var-input.json +150 -0
  147. package/manifest/components/export-dialog.json +84 -0
  148. package/manifest/components/eyebrow.json +56 -0
  149. package/manifest/components/field-description.json +63 -0
  150. package/manifest/components/field-error.json +77 -0
  151. package/manifest/components/field-label.json +63 -0
  152. package/manifest/components/field.json +79 -0
  153. package/manifest/components/file-upload.json +159 -0
  154. package/manifest/components/flow-background.json +50 -0
  155. package/manifest/components/flow-controls.json +50 -0
  156. package/manifest/components/footer.json +112 -0
  157. package/manifest/components/grid.json +81 -0
  158. package/manifest/components/group-bar.json +102 -0
  159. package/manifest/components/hover-card.json +151 -0
  160. package/manifest/components/icon-button.json +88 -0
  161. package/manifest/components/info-tip.json +98 -0
  162. package/manifest/components/input-group.json +91 -0
  163. package/manifest/components/input.json +89 -0
  164. package/manifest/components/item.json +129 -0
  165. package/manifest/components/kbd.json +52 -0
  166. package/manifest/components/link.json +81 -0
  167. package/manifest/components/log-viewer.json +139 -0
  168. package/manifest/components/menubar.json +157 -0
  169. package/manifest/components/message-list.json +100 -0
  170. package/manifest/components/message.json +116 -0
  171. package/manifest/components/meter.json +114 -0
  172. package/manifest/components/multi-select.json +190 -0
  173. package/manifest/components/musical-time-input.json +113 -0
  174. package/manifest/components/navigation-menu.json +226 -0
  175. package/manifest/components/node-card.json +109 -0
  176. package/manifest/components/node-handle.json +69 -0
  177. package/manifest/components/number-field.json +107 -0
  178. package/manifest/components/otp-field.json +128 -0
  179. package/manifest/components/page-shell.json +96 -0
  180. package/manifest/components/pagination.json +92 -0
  181. package/manifest/components/panel-header.json +77 -0
  182. package/manifest/components/panel.json +71 -0
  183. package/manifest/components/password-input.json +119 -0
  184. package/manifest/components/piano-keyboard.json +120 -0
  185. package/manifest/components/plussie.json +111 -0
  186. package/manifest/components/popover.json +193 -0
  187. package/manifest/components/preset-section.json +73 -0
  188. package/manifest/components/progress.json +95 -0
  189. package/manifest/components/radio-group.json +73 -0
  190. package/manifest/components/radio.json +80 -0
  191. package/manifest/components/rating.json +141 -0
  192. package/manifest/components/resizable.json +88 -0
  193. package/manifest/components/row.json +109 -0
  194. package/manifest/components/scroll-area.json +91 -0
  195. package/manifest/components/scrollable-tabs-list.json +83 -0
  196. package/manifest/components/scrub-input.json +200 -0
  197. package/manifest/components/seam-cell.json +75 -0
  198. package/manifest/components/seam-grid.json +75 -0
  199. package/manifest/components/seam-list.json +56 -0
  200. package/manifest/components/search-input.json +134 -0
  201. package/manifest/components/section-header.json +112 -0
  202. package/manifest/components/segmented-control.json +138 -0
  203. package/manifest/components/select.json +194 -0
  204. package/manifest/components/separator.json +53 -0
  205. package/manifest/components/shape-section.json +66 -0
  206. package/manifest/components/sheet.json +186 -0
  207. package/manifest/components/sidebar.json +198 -0
  208. package/manifest/components/signal-edge.json +56 -0
  209. package/manifest/components/skeleton.json +46 -0
  210. package/manifest/components/slider.json +89 -0
  211. package/manifest/components/sparkline.json +76 -0
  212. package/manifest/components/spectrum-visualizer.json +115 -0
  213. package/manifest/components/spinner.json +61 -0
  214. package/manifest/components/stack.json +96 -0
  215. package/manifest/components/stat.json +87 -0
  216. package/manifest/components/status-bar.json +58 -0
  217. package/manifest/components/status-dot.json +78 -0
  218. package/manifest/components/stepper.json +89 -0
  219. package/manifest/components/switch.json +87 -0
  220. package/manifest/components/table-scroll-region.json +69 -0
  221. package/manifest/components/table.json +155 -0
  222. package/manifest/components/tabs.json +145 -0
  223. package/manifest/components/tags-input.json +190 -0
  224. package/manifest/components/terminal-frame.json +119 -0
  225. package/manifest/components/textarea.json +76 -0
  226. package/manifest/components/theme-configurator.json +124 -0
  227. package/manifest/components/theme-provider.json +134 -0
  228. package/manifest/components/threshold-rail.json +160 -0
  229. package/manifest/components/time-field.json +80 -0
  230. package/manifest/components/timeline-ruler.json +139 -0
  231. package/manifest/components/timeline.json +115 -0
  232. package/manifest/components/title-bar.json +82 -0
  233. package/manifest/components/toast.json +130 -0
  234. package/manifest/components/toggle-group.json +106 -0
  235. package/manifest/components/toggle.json +109 -0
  236. package/manifest/components/token-editor.json +90 -0
  237. package/manifest/components/toolbar.json +163 -0
  238. package/manifest/components/tooltip.json +164 -0
  239. package/manifest/components/tree-visibility-toggle.json +84 -0
  240. package/manifest/components/tree.json +140 -0
  241. package/manifest/components/two-step-button.json +113 -0
  242. package/manifest/components/universe-grid.json +127 -0
  243. package/manifest/components/usage-chart.json +124 -0
  244. package/manifest/manifest.json +2142 -0
  245. package/manifest/tokens.json +138 -0
  246. package/package.json +13 -5
@@ -0,0 +1,198 @@
1
+ {
2
+ "name": "Combobox",
3
+ "slug": "combobox",
4
+ "group": "forms",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "A {@link Select } you can type into: one value out of a known, filterable set.\n\nThe line between this and {@link Autocomplete } is worth holding: a combobox's\nvalue is always one of `items` — the text is a *filter*, and anything not in\nthe list cannot be chosen. An autocomplete's value is whatever the user typed\nand the list is only a suggestion. Pick the one whose contract matches what\nhappens to the value downstream.\n\nThe public API is string-valued like `Select`'s, even though Base UI's item\nvalues are the option objects: a caller stores `\"wash\"`, not an object it has\nto keep referentially stable across renders.\n\nThe popup is portalled through {@link useCuePortalProps}, so it carries the\ncaller's `data-theme` / `data-density` / `data-mode` even though it mounts at\nthe end of `<body>`.",
9
+ "props": [
10
+ {
11
+ "name": "items",
12
+ "type": "readonly ComboboxOption[]",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "The rows, in display order. Base UI filters them against what is typed."
16
+ },
17
+ {
18
+ "name": "value",
19
+ "type": "string | null",
20
+ "required": false,
21
+ "defaultValue": null,
22
+ "description": "Selected value. Use with `onValueChange` for a controlled combobox."
23
+ },
24
+ {
25
+ "name": "defaultValue",
26
+ "type": "string | null",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Initially selected value for an uncontrolled combobox."
30
+ },
31
+ {
32
+ "name": "onValueChange",
33
+ "type": "((value: string | null) => void)",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Called with the newly selected value (`null` when cleared)."
37
+ },
38
+ {
39
+ "name": "placeholder",
40
+ "type": "string",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "Shown while the input is empty."
44
+ },
45
+ {
46
+ "name": "emptyMessage",
47
+ "type": "ReactNode",
48
+ "required": false,
49
+ "defaultValue": "No matches",
50
+ "description": "Shown in place of the list when the query matches nothing."
51
+ },
52
+ {
53
+ "name": "size",
54
+ "type": "\"sm\" | \"md\" | \"lg\"",
55
+ "required": false,
56
+ "defaultValue": null,
57
+ "description": "Rung of the control ladder. Defaults to `\"md\"`."
58
+ },
59
+ {
60
+ "name": "autoHighlight",
61
+ "type": "boolean",
62
+ "required": false,
63
+ "defaultValue": "true",
64
+ "description": "Highlight the first match automatically so Enter picks it."
65
+ },
66
+ {
67
+ "name": "disabled",
68
+ "type": "boolean",
69
+ "required": false,
70
+ "defaultValue": null,
71
+ "description": "Prevent opening and grey the field out."
72
+ },
73
+ {
74
+ "name": "required",
75
+ "type": "boolean",
76
+ "required": false,
77
+ "defaultValue": null,
78
+ "description": "Require a value before the owning form submits."
79
+ },
80
+ {
81
+ "name": "name",
82
+ "type": "string",
83
+ "required": false,
84
+ "defaultValue": null,
85
+ "description": "Name for the hidden input, when the combobox is part of a form."
86
+ },
87
+ {
88
+ "name": "id",
89
+ "type": "string",
90
+ "required": false,
91
+ "defaultValue": null,
92
+ "description": "Id forwarded to the text input."
93
+ },
94
+ {
95
+ "name": "aria-label",
96
+ "type": "string",
97
+ "required": false,
98
+ "defaultValue": null,
99
+ "description": "Accessible name for the input, when no {@link FieldLabel } names it."
100
+ },
101
+ {
102
+ "name": "aria-labelledby",
103
+ "type": "string",
104
+ "required": false,
105
+ "defaultValue": null,
106
+ "description": "Id of the element naming the input."
107
+ },
108
+ {
109
+ "name": "clearLabel",
110
+ "type": "string",
111
+ "required": false,
112
+ "defaultValue": "Clear selection",
113
+ "description": "Accessible name for the clear button. Defaults to `\"Clear selection\"`."
114
+ },
115
+ {
116
+ "name": "className",
117
+ "type": "string",
118
+ "required": false,
119
+ "defaultValue": null,
120
+ "description": "Extra classes for the field."
121
+ },
122
+ {
123
+ "name": "popupClassName",
124
+ "type": "string",
125
+ "required": false,
126
+ "defaultValue": null,
127
+ "description": "Extra classes for the popup surface."
128
+ },
129
+ {
130
+ "name": "sideOffset",
131
+ "type": "number",
132
+ "required": false,
133
+ "defaultValue": "4",
134
+ "description": "Distance in px between the field and the popup. Defaults to `4`."
135
+ }
136
+ ],
137
+ "typeReferences": [],
138
+ "subcomponents": [],
139
+ "parts": [],
140
+ "variants": {},
141
+ "defaultVariants": {},
142
+ "tokensUsed": [
143
+ "--cue-accent",
144
+ "--cue-accent-soft",
145
+ "--cue-border",
146
+ "--cue-border-overlay",
147
+ "--cue-chip-h",
148
+ "--cue-control-lg",
149
+ "--cue-control-md",
150
+ "--cue-control-sm",
151
+ "--cue-danger",
152
+ "--cue-fg",
153
+ "--cue-fg-muted",
154
+ "--cue-fg-subtle",
155
+ "--cue-font-mono",
156
+ "--cue-icon-md",
157
+ "--cue-icon-sm",
158
+ "--cue-radius-control",
159
+ "--cue-radius-overlay",
160
+ "--cue-scrim",
161
+ "--cue-space-1",
162
+ "--cue-space-2",
163
+ "--cue-space-3",
164
+ "--cue-space-4",
165
+ "--cue-space-5",
166
+ "--cue-sunken",
167
+ "--cue-surface-2",
168
+ "--cue-text-body",
169
+ "--cue-text-emphasis",
170
+ "--cue-text-label",
171
+ "--cue-text-ui"
172
+ ],
173
+ "summary": "A {@link Select } you can type into: one value out of a known, filterable set.",
174
+ "examples": [
175
+ {
176
+ "title": "Usage",
177
+ "code": "<Combobox aria-label=\"Fixture\" items={fixtures} value={fixture} onValueChange={setFixture} />",
178
+ "language": "tsx"
179
+ }
180
+ ],
181
+ "status": "todo-docs",
182
+ "url": "/docs/components/combobox",
183
+ "mdUrl": "/docs/components/combobox.md",
184
+ "jsonUrl": "/r/components/combobox.json",
185
+ "specimens": [
186
+ {
187
+ "title": "Combobox",
188
+ "group": "forms",
189
+ "components": [
190
+ "Combobox"
191
+ ],
192
+ "code": "<div className=\"grid w-full gap-(--cue-space-5) lg:grid-cols-3\">\n <Combobox\n aria-label=\"Fixture type\"\n items={FIXTURE_OPTIONS}\n defaultValue=\"s4\"\n placeholder=\"Fixture type\"\n />\n <Combobox\n aria-label=\"Fixture type, empty\"\n items={FIXTURE_OPTIONS}\n placeholder=\"Fixture type\"\n emptyMessage={COPY.empty.title}\n />\n <Combobox\n aria-label=\"Fixture type, disabled\"\n items={FIXTURE_OPTIONS}\n defaultValue=\"par64\"\n disabled\n />\n</div>",
193
+ "note": "A filtered list with a committed value. An item can be disabled; the empty message is a real string, not a blank popup.",
194
+ "interaction": "arrow keys move the highlight, Enter commits, Escape reverts to the committed value."
195
+ }
196
+ ],
197
+ "todo": true
198
+ }
@@ -0,0 +1,177 @@
1
+ {
2
+ "name": "CommandPalette",
3
+ "slug": "command-palette",
4
+ "group": "overlays",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The ⌘K surface: type a few letters, run a command.\n\nA Base UI `Combobox` living inside a Base UI `Dialog`, which is what buys the\ntwo halves nobody hand-rolls correctly. The dialog gives a real focus trap,\nfocus restoration and outside-press dismissal; the combobox gives\n`role=\"listbox\"`, `aria-activedescendant` tracking the highlighted row, and\narrow/Home/End/Enter navigation that a screen reader announces — the gap in\nevery home-grown palette, snuffle's included, where the list is a `div` of\nbuttons and the input never says which one Enter would run.\n\nMatching is debounced (see {@link CommandPaletteProps.debounceMs}) while the\nfield is not, and the first surviving command is highlighted automatically, so\n\"type three letters, press Enter\" always does the obvious thing.\n\nThe whole thing is portalled through the system's portal contract, so a\npalette opened from an ultra-compact island renders at that density.",
9
+ "props": [
10
+ {
11
+ "name": "items",
12
+ "type": "readonly CommandPaletteItem[]",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "Every command the palette can run, in the order they should appear."
16
+ },
17
+ {
18
+ "name": "onSelect",
19
+ "type": "(item: CommandPaletteItem) => void",
20
+ "required": true,
21
+ "defaultValue": null,
22
+ "description": "Called with the command the user ran. The palette closes itself afterwards."
23
+ },
24
+ {
25
+ "name": "open",
26
+ "type": "boolean",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Open state when controlled. Pass with `onOpenChange`."
30
+ },
31
+ {
32
+ "name": "defaultOpen",
33
+ "type": "boolean",
34
+ "required": false,
35
+ "defaultValue": "false",
36
+ "description": "Initial open state when uncontrolled. Defaults to `false`."
37
+ },
38
+ {
39
+ "name": "onOpenChange",
40
+ "type": "((open: boolean) => void)",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "Called whenever the palette wants to open or close."
44
+ },
45
+ {
46
+ "name": "placeholder",
47
+ "type": "string",
48
+ "required": false,
49
+ "defaultValue": "Type a command",
50
+ "description": "Shown while the query is empty. Defaults to `\"Type a command\"`."
51
+ },
52
+ {
53
+ "name": "emptyMessage",
54
+ "type": "ReactNode",
55
+ "required": false,
56
+ "defaultValue": "No commands match",
57
+ "description": "Shown in place of the list when nothing matches. Defaults to `\"No commands match\"`."
58
+ },
59
+ {
60
+ "name": "label",
61
+ "type": "string",
62
+ "required": false,
63
+ "defaultValue": "Command palette",
64
+ "description": "Accessible name for the dialog and the input. Defaults to `\"Command palette\"`."
65
+ },
66
+ {
67
+ "name": "footer",
68
+ "type": "ReactNode",
69
+ "required": false,
70
+ "defaultValue": "(\n <>\n <span>↑↓ navigate</span>\n <span>⏎ run</span>\n <span>esc close</span>\n </>\n)",
71
+ "description": "The hint strip along the foot. Pass `null` to drop it."
72
+ },
73
+ {
74
+ "name": "debounceMs",
75
+ "type": "number",
76
+ "required": false,
77
+ "defaultValue": "200",
78
+ "description": "Quiet period in ms before the query is re-matched. Defaults to `200`.\n\nThe field itself never waits — only the matching does — so typing stays at\none frame per keystroke however long the command list is."
79
+ },
80
+ {
81
+ "name": "filter",
82
+ "type": "((items: readonly CommandPaletteItem[], query: string) => CommandPaletteItem[])",
83
+ "required": false,
84
+ "defaultValue": "defaultFilter",
85
+ "description": "Replace the matcher. Defaults to a case-insensitive substring match over\n`label` and `keywords`. Return the surviving commands in display order."
86
+ },
87
+ {
88
+ "name": "className",
89
+ "type": "string",
90
+ "required": false,
91
+ "defaultValue": null,
92
+ "description": "Extra classes for the palette surface."
93
+ },
94
+ {
95
+ "name": "backdropClassName",
96
+ "type": "string",
97
+ "required": false,
98
+ "defaultValue": null,
99
+ "description": "Extra classes for the scrim behind it."
100
+ }
101
+ ],
102
+ "typeReferences": [],
103
+ "subcomponents": [],
104
+ "parts": [],
105
+ "variants": {},
106
+ "defaultVariants": {},
107
+ "tokensUsed": [
108
+ "--cue-accent-soft",
109
+ "--cue-border",
110
+ "--cue-border-overlay",
111
+ "--cue-control-lg",
112
+ "--cue-control-md",
113
+ "--cue-control-sm",
114
+ "--cue-fg",
115
+ "--cue-fg-muted",
116
+ "--cue-fg-subtle",
117
+ "--cue-font-mono",
118
+ "--cue-icon-md",
119
+ "--cue-icon-sm",
120
+ "--cue-radius-control",
121
+ "--cue-radius-overlay",
122
+ "--cue-scrim",
123
+ "--cue-space-1",
124
+ "--cue-space-2",
125
+ "--cue-space-3",
126
+ "--cue-space-4",
127
+ "--cue-sunken",
128
+ "--cue-surface-1",
129
+ "--cue-surface-2",
130
+ "--cue-text-body",
131
+ "--cue-text-emphasis",
132
+ "--cue-text-label",
133
+ "--cue-text-micro",
134
+ "--cue-text-ui"
135
+ ],
136
+ "summary": "The keyboard entry point: type, filter, run.",
137
+ "examples": [
138
+ {
139
+ "title": "Wired to a shortcut",
140
+ "code": "<CommandPalette\n open={open}\n onOpenChange={setOpen}\n items={[\n { id: \"blackout\", label: \"Blackout\", group: \"Transport\", keywords: [\"panic\"] },\n { id: \"patch\", label: \"Open patch\", group: \"Navigate\" },\n ]}\n onSelect={(item) => run(item.id)}\n/>",
141
+ "language": "tsx"
142
+ },
143
+ {
144
+ "title": "Usage",
145
+ "code": "<CommandPalette\n open={open}\n onOpenChange={setOpen}\n items={[\n { id: \"go\", label: \"Go\", group: \"Playback\", hint: <Kbd>⏎</Kbd> },\n { id: \"patch\", label: \"Patch fixture\", group: \"Patch\", keywords: [\"dmx\", \"address\"] },\n ]}\n onSelect={(command) => run(command.id)}\n/>",
146
+ "language": "tsx"
147
+ }
148
+ ],
149
+ "status": "stable",
150
+ "url": "/docs/components/command-palette",
151
+ "mdUrl": "/docs/components/command-palette.md",
152
+ "jsonUrl": "/r/components/command-palette.json",
153
+ "whenToUse": [
154
+ "An app with more commands than a toolbar can hold.",
155
+ "Giving power users one shortcut that reaches everything, usually Cmd/Ctrl-K."
156
+ ],
157
+ "whenNotToUse": [
158
+ "Choosing a value in a form. Use `Combobox`.",
159
+ "As the only route to a command. Everything in the palette should also be reachable in the UI."
160
+ ],
161
+ "commonMistakes": [
162
+ "Re-sorting `items` per keystroke. Commands keep the order they are given, and groups keep the order they first appear in.",
163
+ "Debouncing the field itself. Only the matching waits; the input stays at one frame per keystroke."
164
+ ],
165
+ "specimens": [
166
+ {
167
+ "title": "CommandPalette",
168
+ "group": "overlays",
169
+ "components": [
170
+ "CommandPalette"
171
+ ],
172
+ "code": "<Specimens>\n <Specimen label=\"trigger\">\n <Button onClick={() => setPaletteOpen(true)}>\n Open palette <Kbd>⌘K</Kbd>\n </Button>\n </Specimen>\n <Specimen label=\"last command\">\n <Chip tone={lastCommand === null ? \"neutral\" : \"accent\"}>{lastCommand ?? \"none\"}</Chip>\n </Specimen>\n</Specimens>\n<CommandPalette\n items={PALETTE_ITEMS}\n open={paletteOpen}\n onOpenChange={setPaletteOpen}\n onSelect={(item) => setLastCommand(item.label)}\n placeholder=\"Run a command\"\n emptyMessage={COPY.empty.title}\n footer={\n <span className=\"flex items-center gap-(--cue-space-2)\">\n <Kbd>↑</Kbd>\n <Kbd>↓</Kbd> to move\n <Kbd>↵</Kbd> to run\n </span>\n }\n/>",
173
+ "note": "A combobox inside a dialog: grouped items, a 200 ms debounce, full arrow-key navigation and `aria-activedescendant` on the input.",
174
+ "interaction": "the whole list is reachable from the keyboard without ever moving DOM focus off the field."
175
+ }
176
+ ]
177
+ }
@@ -0,0 +1,176 @@
1
+ {
2
+ "name": "Composer",
3
+ "slug": "composer",
4
+ "group": "chat",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "The thing you type into: an auto-growing textarea, a send affordance, and\nslots for everything a host wants to hang off them.\n\nThree decisions worth stating:\n\n- **It grows, it does not scroll.** A one-line box that hides the second half\n of what you wrote is the most-complained-about part of every chat UI. The\n box starts at the tall control rung and grows to `maxRows` before it gives\n up and scrolls.\n- **The submit gesture is a setting.** Enter-to-send is right for a chat lane\n and wrong for a prompt editor where every draft is three paragraphs, so\n both are first-class and the *other* key always inserts a newline.\n- **Stop is never disabled.** While a run is in flight the composer is\n `disabled`, but the button that ends the run cannot inherit that — a stop\n you cannot press is not a stop.\n\nThe ref lands on the textarea rather than the form: focusing the composer is\nthe thing hosts actually reach for.",
9
+ "props": [
10
+ {
11
+ "name": "onSend",
12
+ "type": "(value: string) => void",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "Fired with the trimmed draft. Never fired with an empty string."
16
+ },
17
+ {
18
+ "name": "value",
19
+ "type": "string",
20
+ "required": false,
21
+ "defaultValue": null,
22
+ "description": "Draft when the host owns it. Pass with `onValueChange`."
23
+ },
24
+ {
25
+ "name": "defaultValue",
26
+ "type": "string",
27
+ "required": false,
28
+ "defaultValue": "",
29
+ "description": "Initial draft when uncontrolled."
30
+ },
31
+ {
32
+ "name": "onValueChange",
33
+ "type": "((value: string) => void)",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Called on every keystroke with the new draft."
37
+ },
38
+ {
39
+ "name": "placeholder",
40
+ "type": "string",
41
+ "required": false,
42
+ "defaultValue": "Message",
43
+ "description": "Placeholder for the empty box. Defaults to `\"Message\"`."
44
+ },
45
+ {
46
+ "name": "disabled",
47
+ "type": "boolean",
48
+ "required": false,
49
+ "defaultValue": "false",
50
+ "description": "Block sending — a closed thread, a failed connection."
51
+ },
52
+ {
53
+ "name": "busy",
54
+ "type": "boolean",
55
+ "required": false,
56
+ "defaultValue": "false",
57
+ "description": "A run is in flight. With `onStop`, swaps Send for Stop."
58
+ },
59
+ {
60
+ "name": "onStop",
61
+ "type": "(() => void)",
62
+ "required": false,
63
+ "defaultValue": null,
64
+ "description": "Abort the in-flight run. Renders the Stop button while `busy`."
65
+ },
66
+ {
67
+ "name": "submitKey",
68
+ "type": "\"enter\" | \"mod+enter\"",
69
+ "required": false,
70
+ "defaultValue": "enter",
71
+ "description": "Which gesture submits. Defaults to `\"enter\"`."
72
+ },
73
+ {
74
+ "name": "maxRows",
75
+ "type": "number",
76
+ "required": false,
77
+ "defaultValue": "8",
78
+ "description": "Rows the box may grow to before it scrolls. Defaults to `8`."
79
+ },
80
+ {
81
+ "name": "sendLabel",
82
+ "type": "ReactNode",
83
+ "required": false,
84
+ "defaultValue": "Send",
85
+ "description": "Label on the send button. Defaults to `\"Send\"`."
86
+ },
87
+ {
88
+ "name": "stopLabel",
89
+ "type": "ReactNode",
90
+ "required": false,
91
+ "defaultValue": "Stop",
92
+ "description": "Label on the stop button. Defaults to `\"Stop\"`."
93
+ },
94
+ {
95
+ "name": "attachments",
96
+ "type": "ReactNode",
97
+ "required": false,
98
+ "defaultValue": null,
99
+ "description": "Tray above the input — attachment chips, a reply-to quote."
100
+ },
101
+ {
102
+ "name": "toolbar",
103
+ "type": "ReactNode",
104
+ "required": false,
105
+ "defaultValue": null,
106
+ "description": "Controls beside the send button — an attach button, a model picker."
107
+ },
108
+ {
109
+ "name": "hint",
110
+ "type": "ReactNode",
111
+ "required": false,
112
+ "defaultValue": null,
113
+ "description": "Quiet strip under the input — a keyboard hint, a character count."
114
+ },
115
+ {
116
+ "name": "aria-label",
117
+ "type": "string",
118
+ "required": false,
119
+ "defaultValue": "Message",
120
+ "description": "Accessible name for the input. Defaults to `\"Message\"`."
121
+ }
122
+ ],
123
+ "typeReferences": [
124
+ "Omit<React.ComponentPropsWithoutRef<\"form\">, \"onSubmit\" | \"onChange\">"
125
+ ],
126
+ "subcomponents": [],
127
+ "parts": [],
128
+ "variants": {},
129
+ "defaultVariants": {},
130
+ "tokensUsed": [
131
+ "--cue-accent",
132
+ "--cue-border",
133
+ "--cue-control-lg",
134
+ "--cue-control-md",
135
+ "--cue-control-sm",
136
+ "--cue-danger",
137
+ "--cue-fg",
138
+ "--cue-fg-subtle",
139
+ "--cue-font-mono",
140
+ "--cue-radius-control",
141
+ "--cue-space-2",
142
+ "--cue-space-3",
143
+ "--cue-space-4",
144
+ "--cue-space-5",
145
+ "--cue-sunken",
146
+ "--cue-text-body",
147
+ "--cue-text-label",
148
+ "--cue-text-micro",
149
+ "--cue-text-ui"
150
+ ],
151
+ "summary": "The thing you type into: an auto-growing textarea, a send affordance, and slots for everything a host wants to hang off them.",
152
+ "examples": [
153
+ {
154
+ "title": "Usage",
155
+ "code": "<Composer onSend={send} />\n<Composer submitKey=\"mod+enter\" busy={running} onStop={abort} onSend={send} />",
156
+ "language": "tsx"
157
+ }
158
+ ],
159
+ "status": "todo-docs",
160
+ "url": "/docs/components/composer",
161
+ "mdUrl": "/docs/components/composer.md",
162
+ "jsonUrl": "/r/components/composer.json",
163
+ "specimens": [
164
+ {
165
+ "title": "Composer",
166
+ "group": "chat",
167
+ "components": [
168
+ "Composer"
169
+ ],
170
+ "code": "<div className=\"flex w-full max-w-[42rem] flex-col gap-(--cue-space-5)\">\n <Composer\n value={draft}\n onValueChange={setDraft}\n onSend={(value) => {\n setSent(value);\n setDraft(\"\");\n }}\n placeholder=\"Ask the swarm\"\n hint={<span>Enter sends. Shift+Enter starts a line.</span>}\n />\n <Composer\n onSend={() => {}}\n submitKey=\"mod+enter\"\n busy\n onStop={() => {}}\n defaultValue=\"Patching universe 2\"\n hint=\"Busy: the send control becomes Stop.\"\n />\n <Composer onSend={() => {}} disabled placeholder=\"Disabled\" />\n {sent === null ? null : <Chip tone=\"accent\">sent: {sent}</Chip>}\n</div>",
171
+ "note": "An auto-growing textarea at the large control height, with an attachment slot, a toolbar slot and a Stop that reports rather than decides.",
172
+ "interaction": "Enter sends by default, mod+Enter when configured the other way; Shift+Enter always inserts a newline."
173
+ }
174
+ ],
175
+ "todo": true
176
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "Container",
3
+ "slug": "container",
4
+ "group": "layout",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": false,
8
+ "description": "A centred column with the standard gutters and nothing else.\n\n`PageShell` is this plus a page header; reach for `Container` when the page\nalready has its own heading (a route that opens with a `TitleBar`, a section\ninside a shell) and all you need is the measure.\n\nStatic markup — no `\"use client\"`.",
9
+ "props": [
10
+ {
11
+ "name": "width",
12
+ "type": "\"narrow\" | \"wide\" | \"broad\" | \"full\"",
13
+ "required": false,
14
+ "defaultValue": "narrow",
15
+ "description": "Which measure the column takes. Defaults to `\"narrow\"`."
16
+ },
17
+ {
18
+ "name": "padded",
19
+ "type": "boolean",
20
+ "required": false,
21
+ "defaultValue": "true",
22
+ "description": "Draw the standard side gutters. Defaults to `true`."
23
+ }
24
+ ],
25
+ "typeReferences": [
26
+ "React.ComponentPropsWithoutRef<\"div\">"
27
+ ],
28
+ "subcomponents": [],
29
+ "parts": [],
30
+ "variants": {},
31
+ "defaultVariants": {},
32
+ "tokensUsed": [
33
+ "--cue-space-6"
34
+ ],
35
+ "summary": "A centred column with the standard gutters and nothing else.",
36
+ "examples": [
37
+ {
38
+ "title": "Usage",
39
+ "code": "<Container width=\"wide\"><Table /></Container>\n<Container width=\"full\" padded={false}><Canvas /></Container>",
40
+ "language": "tsx"
41
+ }
42
+ ],
43
+ "status": "todo-docs",
44
+ "url": "/docs/components/container",
45
+ "mdUrl": "/docs/components/container.md",
46
+ "jsonUrl": "/r/components/container.json",
47
+ "specimens": [
48
+ {
49
+ "title": "Container",
50
+ "group": "layout",
51
+ "components": [
52
+ "Container"
53
+ ],
54
+ "code": "<div className=\"flex w-full flex-col gap-(--cue-space-3)\">\n {([\"narrow\", \"wide\", \"full\"] as const).map((width) => (\n <Container\n key={width}\n width={width}\n className=\"rounded-(--radius-control) border border-dashed border-border py-(--cue-space-3) text-center font-mono text-(length:--cue-text-label) text-fg-subtle\"\n >\n {width}\n </Container>\n ))}\n</div>",
55
+ "note": "Three measures. The one place a max-width is allowed to be hardcoded, because a measure is typographic, not thematic.",
56
+ "interaction": "none."
57
+ }
58
+ ],
59
+ "todo": true
60
+ }