@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,140 @@
1
+ {
2
+ "name": "Tree",
3
+ "slug": "tree",
4
+ "group": "chrome",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "A hierarchical outline: a rig, a scene graph, a folder of shows.\n\nHand-built rather than wrapped, because the pattern's whole cost is in three\ndetails no primitive here provides together:\n\n- **Roving tabindex.** The tree is one tab stop; the arrow keys move inside\n it. Eighty rows must never mean eighty presses of Tab.\n- **A flat DOM.** Rows carry `aria-level` / `aria-posinset` / `aria-setsize`\n instead of nesting `role=\"group\"` wrappers, which is both valid ARIA and the\n shape a virtualizer needs when the outline grows past a screenful.\n- **The gutter.** `└ ├ │` in the mono grid, `aria-hidden` — structure you can\n see at a glance without indentation alone having to carry it.\n\nSelection is a tint (`accent-soft` ground, accent ink), never a solid fill —\nthe same ruling as the sidebar item and the active tab.",
9
+ "props": [
10
+ {
11
+ "name": "items",
12
+ "type": "readonly TreeItem[]",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "The roots, in display order."
16
+ },
17
+ {
18
+ "name": "expanded",
19
+ "type": "readonly string[]",
20
+ "required": false,
21
+ "defaultValue": null,
22
+ "description": "Expanded ids when controlled. Pass with `onExpandedChange`."
23
+ },
24
+ {
25
+ "name": "defaultExpanded",
26
+ "type": "readonly string[]",
27
+ "required": false,
28
+ "defaultValue": null,
29
+ "description": "Initially expanded ids when uncontrolled."
30
+ },
31
+ {
32
+ "name": "onExpandedChange",
33
+ "type": "((expanded: string[]) => void)",
34
+ "required": false,
35
+ "defaultValue": null,
36
+ "description": "Called with the whole next expanded set whenever a row is folded or unfolded."
37
+ },
38
+ {
39
+ "name": "selected",
40
+ "type": "string | null",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "Selected id when controlled. Pass with `onSelect`."
44
+ },
45
+ {
46
+ "name": "defaultSelected",
47
+ "type": "string | null",
48
+ "required": false,
49
+ "defaultValue": "null",
50
+ "description": "Initially selected id when uncontrolled."
51
+ },
52
+ {
53
+ "name": "onSelect",
54
+ "type": "((id: string) => void)",
55
+ "required": false,
56
+ "defaultValue": null,
57
+ "description": "Called with the id of the row the user selected."
58
+ },
59
+ {
60
+ "name": "renderRow",
61
+ "type": "((row: TreeRow) => ReactNode)",
62
+ "required": false,
63
+ "defaultValue": null,
64
+ "description": "Replace the *body* of a row — the icon, label and badge.\n\nThe row element itself, its ARIA, its tab index and its indent gutter stay\nwith the component on purpose: those are the parts a call site cannot get\nwrong without breaking keyboard navigation for everyone."
65
+ },
66
+ {
67
+ "name": "rowControls",
68
+ "type": "((item: TreeItem, row: TreeRow) => ReactNode)",
69
+ "required": false,
70
+ "defaultValue": null,
71
+ "description": "Controls hung off the right of each row, revealed on hover or focus.\n\nThis is where the three-state visibility idiom goes — see\n{@link TreeVisibilityToggle} — along with focus, rename and delete\naffordances. Anything essential belongs in the row body or a context menu\ninstead: hover-revealed controls are invisible on touch."
72
+ },
73
+ {
74
+ "name": "guides",
75
+ "type": "boolean",
76
+ "required": false,
77
+ "defaultValue": "true",
78
+ "description": "Draw the box-drawing indent gutter. Defaults to `true`."
79
+ },
80
+ {
81
+ "name": "aria-label",
82
+ "type": "string",
83
+ "required": false,
84
+ "defaultValue": null,
85
+ "description": "Accessible name for the tree. Required in practice — name what it lists."
86
+ }
87
+ ],
88
+ "typeReferences": [
89
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"onSelect\">"
90
+ ],
91
+ "subcomponents": [],
92
+ "parts": [],
93
+ "variants": {},
94
+ "defaultVariants": {},
95
+ "tokensUsed": [
96
+ "--cue-accent",
97
+ "--cue-accent-soft",
98
+ "--cue-control-sm",
99
+ "--cue-fg",
100
+ "--cue-fg-muted",
101
+ "--cue-fg-subtle",
102
+ "--cue-font-mono",
103
+ "--cue-icon-md",
104
+ "--cue-icon-sm",
105
+ "--cue-info",
106
+ "--cue-radius-control",
107
+ "--cue-space-1",
108
+ "--cue-space-2",
109
+ "--cue-space-4",
110
+ "--cue-surface-2",
111
+ "--cue-text-ui",
112
+ "--cue-warn"
113
+ ],
114
+ "summary": "A hierarchical outline: a rig, a scene graph, a folder of shows.",
115
+ "examples": [
116
+ {
117
+ "title": "Usage",
118
+ "code": "<Tree\n aria-label=\"Rig\"\n items={rig}\n selected={selected}\n onSelect={setSelected}\n rowControls={(item) => (\n <TreeVisibilityToggle value={visibility[item.id]} onValueChange={set(item.id)} />\n )}\n/>",
119
+ "language": "tsx"
120
+ }
121
+ ],
122
+ "status": "todo-docs",
123
+ "url": "/docs/components/tree",
124
+ "mdUrl": "/docs/components/tree.md",
125
+ "jsonUrl": "/r/components/tree.json",
126
+ "specimens": [
127
+ {
128
+ "title": "Tree",
129
+ "group": "chrome",
130
+ "components": [
131
+ "Tree",
132
+ "TreeVisibilityToggle"
133
+ ],
134
+ "code": "<Panel className=\"w-full max-w-[30rem] p-(--cue-space-2)\">\n <Tree\n items={TREE_ITEMS}\n expanded={expanded}\n onExpandedChange={setExpanded}\n selected={selected}\n onSelect={setSelected}\n rowControls={(item) => (\n <TreeVisibilityToggle\n value={visibility[item.id] ?? \"visible\"}\n onValueChange={(next) =>\n setVisibility((current) => ({ ...current, [item.id]: next }))\n }\n />\n )}\n />\n</Panel>",
135
+ "note": "Roving tabindex, `└` indent guides, a hover-revealed control slot and the three-state visibility toggle.",
136
+ "interaction": "arrow keys move and expand, Enter selects; the row controls appear on hover and stay put for keyboard users."
137
+ }
138
+ ],
139
+ "todo": true
140
+ }
@@ -0,0 +1,113 @@
1
+ {
2
+ "name": "TwoStepButton",
3
+ "slug": "two-step-button",
4
+ "group": "instruments",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "Arm, then confirm: a destructive action that takes two deliberate presses.\n\nThe most-reused interaction in the portfolio (fifteen call sites, three\nhand-rolled implementations) and the right shape for a destructive action\nthat is *routine* — deleting a cue, clearing a patch. A modal\n`AlertDialog` is the right shape for a rare and expensive one; putting a\ndialog in front of an action people take twenty times an hour just teaches\nthem to dismiss dialogs.\n\nFour ways out, because an armed button left lying around is a trap: Cancel,\nEscape, moving focus away, and a timeout. Focus lands on **Cancel** when the\npair arms, never on the destructive half — the same ruling as a destructive\ndialog's default button, and it means a stuck Enter key cannot walk through\nboth steps.",
9
+ "props": [
10
+ {
11
+ "name": "onConfirm",
12
+ "type": "() => void",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "Fired once, when the *second* press lands."
16
+ },
17
+ {
18
+ "name": "children",
19
+ "type": "ReactNode",
20
+ "required": true,
21
+ "defaultValue": null,
22
+ "description": "The idle label — name the action, not the button (\"Delete rig\", not \"Delete\")."
23
+ },
24
+ {
25
+ "name": "confirmLabel",
26
+ "type": "ReactNode",
27
+ "required": false,
28
+ "defaultValue": "Confirm",
29
+ "description": "Label on the armed half. Defaults to `\"Confirm\"`."
30
+ },
31
+ {
32
+ "name": "cancelLabel",
33
+ "type": "ReactNode",
34
+ "required": false,
35
+ "defaultValue": "Cancel",
36
+ "description": "Label on the escape hatch. Defaults to `\"Cancel\"`."
37
+ },
38
+ {
39
+ "name": "tone",
40
+ "type": "\"danger\" | \"warn\"",
41
+ "required": false,
42
+ "defaultValue": "danger",
43
+ "description": "How severe this is. Defaults to `\"danger\"`."
44
+ },
45
+ {
46
+ "name": "timeout",
47
+ "type": "number",
48
+ "required": false,
49
+ "defaultValue": "4000",
50
+ "description": "ms before an untouched armed state disarms itself. `0` disables. Defaults to `4000`."
51
+ },
52
+ {
53
+ "name": "onArmedChange",
54
+ "type": "((armed: boolean) => void)",
55
+ "required": false,
56
+ "defaultValue": null,
57
+ "description": "Called with the new armed state on every arm and disarm."
58
+ },
59
+ {
60
+ "name": "render",
61
+ "type": "RenderProp<Record<string, unknown>>",
62
+ "required": false,
63
+ "defaultValue": null,
64
+ "description": "Replace the rendered element (Base UI render prop). Accepts an element —\n`render={<a href=\"/x\" />}` — or a function returning one. When set, the\ndefault `type=\"button\"` is dropped so non-button elements stay valid."
65
+ },
66
+ {
67
+ "name": "icon",
68
+ "type": "ElementType<any, keyof IntrinsicElements>",
69
+ "required": false,
70
+ "defaultValue": null,
71
+ "description": "Optional leading icon component (e.g. a lucide icon). Rendered\n`aria-hidden` and sized to the density icon token, so it tracks the density\nlevel without the caller passing a pixel size."
72
+ }
73
+ ],
74
+ "typeReferences": [
75
+ "Omit<ButtonProps, \"onClick\" | \"variant\" | \"onConfirm\" | \"children\">"
76
+ ],
77
+ "subcomponents": [],
78
+ "parts": [],
79
+ "variants": {},
80
+ "defaultVariants": {},
81
+ "tokensUsed": [
82
+ "--cue-danger",
83
+ "--cue-danger-fg",
84
+ "--cue-space-2",
85
+ "--cue-warn",
86
+ "--cue-warn-fg"
87
+ ],
88
+ "summary": "Arm, then confirm: a destructive action that takes two deliberate presses.",
89
+ "examples": [
90
+ {
91
+ "title": "Usage",
92
+ "code": "<TwoStepButton onConfirm={() => deleteRig(id)}>Delete rig</TwoStepButton>\n<TwoStepButton tone=\"warn\" timeout={0} confirmLabel=\"Reset it\" onConfirm={reset}>\n Reset patch\n</TwoStepButton>",
93
+ "language": "tsx"
94
+ }
95
+ ],
96
+ "status": "todo-docs",
97
+ "url": "/docs/components/two-step-button",
98
+ "mdUrl": "/docs/components/two-step-button.md",
99
+ "jsonUrl": "/r/components/two-step-button.json",
100
+ "specimens": [
101
+ {
102
+ "title": "TwoStepButton",
103
+ "group": "instruments",
104
+ "components": [
105
+ "TwoStepButton"
106
+ ],
107
+ "code": "<Specimens>\n <Specimen label=\"danger\">\n <TwoStepButton\n tone=\"danger\"\n onConfirm={() => setConfirmed((count) => count + 1)}\n confirmLabel={COPY.destructive.action}\n >\n {COPY.destructive.action}\n </TwoStepButton>\n </Specimen>\n <Specimen label=\"warn\">\n <TwoStepButton tone=\"warn\" onConfirm={() => setConfirmed((count) => count + 1)}>\n Reset patch\n </TwoStepButton>\n </Specimen>\n <Specimen label=\"short timeout\">\n <TwoStepButton timeout={2000} onConfirm={() => setConfirmed((count) => count + 1)}>\n Unpatch all\n </TwoStepButton>\n </Specimen>\n <Specimen label=\"disabled\">\n <TwoStepButton disabled onConfirm={() => {}}>\n Unpatch all\n </TwoStepButton>\n </Specimen>\n <Specimen label=\"confirmed\">\n <Chip tone={confirmed === 0 ? \"neutral\" : \"ok\"}>{confirmed} confirmed</Chip>\n </Specimen>\n</Specimens>",
108
+ "note": "Arm, then confirm. The portfolio's most-reused interaction, unified from three upstream implementations.",
109
+ "interaction": "Escape, blur and the timeout all disarm; the armed state shows a visible Cancel next to a tone-solid confirm."
110
+ }
111
+ ],
112
+ "todo": true
113
+ }
@@ -0,0 +1,127 @@
1
+ {
2
+ "name": "UniverseGrid",
3
+ "slug": "universe-grid",
4
+ "group": "dmx",
5
+ "importPath": "@cueplusplus/ui/dmx",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "A universe as 512 slots of occupancy: who holds what, and where two fixtures\nwere given the same address.\n\nPorted from stagetool's patching panel, which is the only audited product with\na real patch model behind it. What it draws is deliberately not a table:\n\n- **Position is the address.** A block's left edge *is* channel `start`, so the\n shape of a patch — the gaps, the drift, the fixture that starts at 497 —\n reads without anyone counting.\n- **A one-channel fixture is still visible.** Blocks have a two-pixel floor,\n which is the whole reason the bar can honestly claim to show everything\n patched.\n- **A conflict is drawn twice.** Both offending blocks get a danger ring *and*\n the contested slots get a band, because \"these two overlap\" and \"here is\n where\" are two different questions.\n\nAccessibility follows the `GroupBar` rule: colour is never the only channel.\nWithout `onSelect` the bar is one `role=\"img\"` whose name spells the whole\npatch out; with it, each block becomes a named button and the bar becomes a\ngroup.",
9
+ "props": [
10
+ {
11
+ "name": "allocations",
12
+ "type": "readonly DmxAllocation[]",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "The patch. Order is display order; overlaps are found, not assumed away."
16
+ },
17
+ {
18
+ "name": "label",
19
+ "type": "string",
20
+ "required": false,
21
+ "defaultValue": null,
22
+ "description": "Which universe this is. Names the graphic; also the group label when selectable."
23
+ },
24
+ {
25
+ "name": "slots",
26
+ "type": "number",
27
+ "required": false,
28
+ "defaultValue": "512",
29
+ "description": "Frame length. Defaults to a full universe of 512."
30
+ },
31
+ {
32
+ "name": "height",
33
+ "type": "number",
34
+ "required": false,
35
+ "defaultValue": "18",
36
+ "description": "Bar height in px at the 16px root, emitted as `rem`. Defaults to `18`."
37
+ },
38
+ {
39
+ "name": "ruler",
40
+ "type": "boolean",
41
+ "required": false,
42
+ "defaultValue": "true",
43
+ "description": "Draw the address ruler. Defaults to `true`."
44
+ },
45
+ {
46
+ "name": "legend",
47
+ "type": "boolean",
48
+ "required": false,
49
+ "defaultValue": "true",
50
+ "description": "Draw the legend row. Defaults to `true`."
51
+ },
52
+ {
53
+ "name": "legendMax",
54
+ "type": "number",
55
+ "required": false,
56
+ "defaultValue": "6",
57
+ "description": "Legend entries before the tail collapses. Defaults to `6`."
58
+ },
59
+ {
60
+ "name": "onSelect",
61
+ "type": "((allocation: DmxAllocation) => void)",
62
+ "required": false,
63
+ "defaultValue": null,
64
+ "description": "Make the blocks buttons. Without it they are decoration inside one\n`role=\"img\"`, which is what keeps a 40-fixture patch from becoming 40 tab\nstops."
65
+ },
66
+ {
67
+ "name": "emptyLabel",
68
+ "type": "string",
69
+ "required": false,
70
+ "defaultValue": "No patch assignments",
71
+ "description": "What to say when nothing is patched. Defaults to `\"No patch assignments\"`."
72
+ }
73
+ ],
74
+ "typeReferences": [
75
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\" | \"onSelect\">"
76
+ ],
77
+ "subcomponents": [],
78
+ "parts": [],
79
+ "variants": {},
80
+ "defaultVariants": {},
81
+ "tokensUsed": [
82
+ "--cue-accent",
83
+ "--cue-border",
84
+ "--cue-busy",
85
+ "--cue-danger",
86
+ "--cue-danger-soft",
87
+ "--cue-data-ground",
88
+ "--cue-fg-muted",
89
+ "--cue-fg-subtle",
90
+ "--cue-font-mono",
91
+ "--cue-info",
92
+ "--cue-ok",
93
+ "--cue-radius-control",
94
+ "--cue-space-2",
95
+ "--cue-space-4",
96
+ "--cue-space-5",
97
+ "--cue-sunken",
98
+ "--cue-text-label",
99
+ "--cue-text-micro",
100
+ "--cue-warn"
101
+ ],
102
+ "summary": "A universe as 512 slots of occupancy: who holds what, and where two fixtures were given the same address.",
103
+ "examples": [
104
+ {
105
+ "title": "Usage",
106
+ "code": "<UniverseGrid\n label=\"Universe 1\"\n allocations={[\n { label: \"wash\", start: 1, size: 24, tone: \"accent\" },\n { label: \"movers\", start: 129, size: 32, tone: \"info\" },\n ]}\n/>",
107
+ "language": "tsx"
108
+ }
109
+ ],
110
+ "status": "todo-docs",
111
+ "url": "/docs/components/universe-grid",
112
+ "mdUrl": "/docs/components/universe-grid.md",
113
+ "jsonUrl": "/r/components/universe-grid.json",
114
+ "specimens": [
115
+ {
116
+ "title": "UniverseGrid",
117
+ "group": "dmx",
118
+ "components": [
119
+ "UniverseGrid"
120
+ ],
121
+ "code": "<div className=\"flex w-full flex-col gap-(--cue-space-5)\">\n <UniverseGrid allocations={ALLOCATIONS} label=\"Universe 1 patch\" />\n <UniverseGrid\n allocations={[\n { label: \"Front truss\", start: 1, size: 48, tone: \"accent\" },\n { label: \"Movers\", start: 40, size: 32, tone: \"info\" },\n ]}\n label=\"Universe 2 patch, with a conflict\"\n />\n <UniverseGrid allocations={[]} label=\"Universe 3 patch\" emptyLabel={COPY.empty.title} />\n <UniverseGrid\n allocations={ALLOCATIONS}\n ruler={false}\n legend={false}\n height={10}\n label=\"Universe 1 patch, bare\"\n />\n</div>",
122
+ "note": "512 slots of occupancy: minimum 2px slivers so a two-channel fixture is still visible, a conflict ring where two allocations overlap, a tick ruler at 1/64/…/512 and a legend that folds to `+N more`.",
123
+ "interaction": "each block is a button; the accessible name spells the whole patch out, so the picture is not the only channel."
124
+ }
125
+ ],
126
+ "todo": true
127
+ }
@@ -0,0 +1,124 @@
1
+ {
2
+ "name": "UsageChart",
3
+ "slug": "usage-chart",
4
+ "group": "instruments",
5
+ "importPath": "@cueplusplus/ui",
6
+ "peerDependencies": [],
7
+ "clientOnly": true,
8
+ "description": "A quota trace: where you sit against the ceiling, over time.\n\nDependency-free inline SVG — a charting library is a large price for one\nline and five gridlines, and none of them draws the three things that make\nthis chart honest:\n\n1. **The y axis is always 0–100.** A quota chart auto-scaled to its own range\n makes a flat 3% look identical to a flat 95%. The ceiling is the reading,\n so the ceiling is always drawn.\n2. **Gaps are gaps.** When the sweep does not run, the line breaks. Joining\n across a hole invents data — and worse, invents a *smooth* trend across\n exactly the window nothing is known about. The area fill stops at the\n break for the same reason.\n3. **Out-of-range values are clamped, not plotted.** Upstream numbers are\n reverse-engineered and can be anything; 140% should read as a flat line on\n the ceiling, not as a path drawn over the axis labels.",
9
+ "props": [
10
+ {
11
+ "name": "points",
12
+ "type": "readonly UsageChartPoint[]",
13
+ "required": true,
14
+ "defaultValue": null,
15
+ "description": "The series. Sorted and cleaned internally; order in is not order out."
16
+ },
17
+ {
18
+ "name": "tone",
19
+ "type": "\"accent\" | \"danger\" | \"busy\" | \"ok\" | \"warn\" | \"info\"",
20
+ "required": false,
21
+ "defaultValue": "accent",
22
+ "description": "Stroke tone. Defaults to `\"accent\"`."
23
+ },
24
+ {
25
+ "name": "height",
26
+ "type": "number",
27
+ "required": false,
28
+ "defaultValue": "120",
29
+ "description": "Plot height in px at the 16px root. Defaults to `120`."
30
+ },
31
+ {
32
+ "name": "gapMs",
33
+ "type": "number",
34
+ "required": false,
35
+ "defaultValue": "15 * 60 * 1000",
36
+ "description": "Break the line when consecutive samples are further apart than this, in ms."
37
+ },
38
+ {
39
+ "name": "threshold",
40
+ "type": "number",
41
+ "required": false,
42
+ "defaultValue": null,
43
+ "description": "Draw a dashed rule at this percentage — where throttling starts, say."
44
+ },
45
+ {
46
+ "name": "label",
47
+ "type": "string",
48
+ "required": false,
49
+ "defaultValue": null,
50
+ "description": "The accessible name. Name the series; the shape is not self-describing."
51
+ },
52
+ {
53
+ "name": "emptyLabel",
54
+ "type": "string",
55
+ "required": false,
56
+ "defaultValue": "No data yet",
57
+ "description": "What to say when there is nothing to plot. Defaults to `\"No data yet\"`."
58
+ },
59
+ {
60
+ "name": "formatTimestamp",
61
+ "type": "((t: number) => string)",
62
+ "required": false,
63
+ "defaultValue": null,
64
+ "description": "Format a sample's timestamp for the tooltip. Defaults to a short local date-time."
65
+ },
66
+ {
67
+ "name": "formatValue",
68
+ "type": "((v: number) => string)",
69
+ "required": false,
70
+ "defaultValue": "(value) => `${Math.round(value)}%`",
71
+ "description": "Format a sample's value for the tooltip. Defaults to `\"87%\"`."
72
+ }
73
+ ],
74
+ "typeReferences": [
75
+ "Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\">"
76
+ ],
77
+ "subcomponents": [],
78
+ "parts": [],
79
+ "variants": {},
80
+ "defaultVariants": {},
81
+ "tokensUsed": [
82
+ "--cue-accent",
83
+ "--cue-border",
84
+ "--cue-border-overlay",
85
+ "--cue-busy",
86
+ "--cue-danger",
87
+ "--cue-fg",
88
+ "--cue-fg-subtle",
89
+ "--cue-font-mono",
90
+ "--cue-info",
91
+ "--cue-ok",
92
+ "--cue-radius-control",
93
+ "--cue-space-1",
94
+ "--cue-space-3",
95
+ "--cue-surface-2",
96
+ "--cue-text-label",
97
+ "--cue-warn"
98
+ ],
99
+ "summary": "A quota trace: where you sit against the ceiling, over time.",
100
+ "examples": [
101
+ {
102
+ "title": "Usage",
103
+ "code": "<UsageChart label=\"API requests\" points={series} threshold={80} tone=\"warn\" />",
104
+ "language": "tsx"
105
+ }
106
+ ],
107
+ "status": "todo-docs",
108
+ "url": "/docs/components/usage-chart",
109
+ "mdUrl": "/docs/components/usage-chart.md",
110
+ "jsonUrl": "/r/components/usage-chart.json",
111
+ "specimens": [
112
+ {
113
+ "title": "UsageChart",
114
+ "group": "instruments",
115
+ "components": [
116
+ "UsageChart"
117
+ ],
118
+ "code": "<div className=\"grid w-full gap-(--cue-space-5) lg:grid-cols-2\">\n <UsageChart points={USAGE} gapMs={2 * MINUTE} threshold={80} label=\"Output level\" />\n <UsageChart points={[]} label=\"No samples\" emptyLabel={COPY.empty.title} />\n</div>",
119
+ "note": "A dependency-free SVG chart pinned to 0–100, with gap-aware path segmentation: a hole in the data is a hole in the line, not a straight edge across it.",
120
+ "interaction": "hover draws a crosshair at the nearest point and a tooltip chip; the whole chart carries a text summary for readers who get no hover."
121
+ }
122
+ ],
123
+ "todo": true
124
+ }