@cueplusplus/ui 0.20.0 → 0.21.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.
- package/CHANGELOG.md +134 -0
- package/dist/brand/particle-logo.js +11 -3
- package/dist/chat/agent-pile.js +2 -2
- package/dist/chrome/_status-bar.js +1 -1
- package/dist/chrome/app-shell.js +1 -1
- package/dist/chrome/navigation-menu.js +3 -3
- package/dist/chrome/row.js +1 -1
- package/dist/chrome/scroll-area.js +1 -1
- package/dist/chrome/section-header.js +1 -1
- package/dist/chrome/segmented-control.js +1 -1
- package/dist/chrome/tabs.js +1 -1
- package/dist/chrome/toolbar.js +1 -1
- package/dist/chrome/tree.js +3 -3
- package/dist/date/calendar.js +3 -3
- package/dist/dmx/channel-matrix.js +1 -1
- package/dist/dmx/universe-grid.js +1 -1
- package/dist/elements/agent-handoff.js +3 -3
- package/dist/elements/agent-plan.js +1 -1
- package/dist/elements/agent-status.js +1 -1
- package/dist/elements/agent-surface.d.ts +9 -6
- package/dist/elements/agent-surface.js +3 -2
- package/dist/elements/approval-card.d.ts +29 -3
- package/dist/elements/approval-card.js +18 -8
- package/dist/elements/artifact-card.js +2 -2
- package/dist/elements/canvas-split.js +3 -3
- package/dist/elements/chart.js +1 -1
- package/dist/elements/chat-panel.js +2 -2
- package/dist/elements/checkpoint-history.js +1 -1
- package/dist/elements/code-diff.js +1 -1
- package/dist/elements/code-runner.js +1 -1
- package/dist/elements/composer.d.ts +8 -2
- package/dist/elements/composer.js +20 -12
- package/dist/elements/computer-use.js +2 -2
- package/dist/elements/confidence-marker.js +1 -1
- package/dist/elements/connection-state.js +2 -2
- package/dist/elements/context-breakdown.js +1 -1
- package/dist/elements/context-usage.js +1 -1
- package/dist/elements/conversation-search.js +2 -2
- package/dist/elements/cost-meter.js +1 -1
- package/dist/elements/data-table.js +1 -1
- package/dist/elements/diagram.js +1 -1
- package/dist/elements/draft-restore.js +2 -2
- package/dist/elements/edit-message.js +1 -1
- package/dist/elements/elements.css +134 -0
- package/dist/elements/elicitation-form.d.ts +8 -1
- package/dist/elements/elicitation-form.js +24 -16
- package/dist/elements/empty-state.js +3 -3
- package/dist/elements/error-state.js +2 -2
- package/dist/elements/event-feed.d.ts +88 -0
- package/dist/elements/event-feed.js +190 -0
- package/dist/elements/feedback-dialog.js +2 -2
- package/dist/elements/file-tree.js +1 -1
- package/dist/elements/flow-graph.js +2 -2
- package/dist/elements/generative.css +13 -0
- package/dist/elements/generative.d.ts +8 -6
- package/dist/elements/generative.js +4 -3
- package/dist/elements/image-generation.js +2 -2
- package/dist/elements/index.d.ts +7 -3
- package/dist/elements/index.js +5 -2
- package/dist/elements/inline-citation.js +1 -1
- package/dist/elements/job-progress.js +1 -1
- package/dist/elements/launcher-bubble.js +3 -3
- package/dist/elements/loading-state.js +1 -1
- package/dist/elements/map-answer.js +1 -1
- package/dist/elements/math-block.js +1 -1
- package/dist/elements/mcp-server-panel.js +3 -3
- package/dist/elements/memory-chips.js +1 -1
- package/dist/elements/message-attachment.js +3 -3
- package/dist/elements/message-branches.js +1 -1
- package/dist/elements/message-pair.js +2 -2
- package/dist/elements/message-queue.js +1 -1
- package/dist/elements/message-timing.js +1 -1
- package/dist/elements/mobile-composer.js +1 -1
- package/dist/elements/model-picker.js +1 -1
- package/dist/elements/number-ticker.js +1 -1
- package/dist/elements/onboarding.js +3 -3
- package/dist/elements/permission-grant.js +3 -3
- package/dist/elements/prompt-library.js +1 -1
- package/dist/elements/question-card.d.ts +50 -0
- package/dist/elements/question-card.js +117 -0
- package/dist/elements/queue-dock.js +1 -1
- package/dist/elements/quota-banner.js +1 -1
- package/dist/elements/quote-reply.js +3 -3
- package/dist/elements/read-aloud.js +2 -2
- package/dist/elements/reasoning-effort.js +2 -2
- package/dist/elements/reasoning-panel.js +3 -3
- package/dist/elements/recommendation-card.js +2 -2
- package/dist/elements/regenerate-menu.js +1 -1
- package/dist/elements/request-delivery.js +31 -0
- package/dist/elements/research-report.js +1 -1
- package/dist/elements/retrieval-chunks.js +3 -3
- package/dist/elements/revert-dock.js +1 -1
- package/dist/elements/reviewable-diff.js +4 -4
- package/dist/elements/schedule-card.js +2 -2
- package/dist/elements/score-breakdown.js +2 -2
- package/dist/elements/scroll-anchor.js +2 -2
- package/dist/elements/settings-panel.js +3 -3
- package/dist/elements/sources.js +1 -1
- package/dist/elements/spec-sheet.js +1 -1
- package/dist/elements/stopped-run.js +2 -2
- package/dist/elements/streaming-text.js +2 -2
- package/dist/elements/subagent-list.js +4 -4
- package/dist/elements/suggestions.js +1 -1
- package/dist/elements/surfaces.d.ts +6 -6
- package/dist/elements/surfaces.js +7 -7
- package/dist/elements/tail-status.js +1 -1
- package/dist/elements/terminal-block.js +1 -1
- package/dist/elements/thinking-indicator.js +1 -1
- package/dist/elements/timeline.js +1 -1
- package/dist/elements/todo-list.js +1 -1
- package/dist/elements/tool-call.d.ts +18 -2
- package/dist/elements/tool-call.js +20 -11
- package/dist/elements/tool-error.js +2 -2
- package/dist/elements/tool-group.d.ts +11 -3
- package/dist/elements/tool-group.js +62 -38
- package/dist/elements/tool-state.d.ts +13 -0
- package/dist/elements/tool-state.js +44 -0
- package/dist/elements/tool-timeline.js +2 -2
- package/dist/elements/trace-waterfall.js +2 -2
- package/dist/elements/unsupported-request-card.d.ts +31 -0
- package/dist/elements/unsupported-request-card.js +80 -0
- package/dist/elements/vocabulary.d.ts +50 -1
- package/dist/elements/vocabulary.js +50 -1
- package/dist/elements/voice-conversation.js +5 -5
- package/dist/elements/web-preview.js +1 -1
- package/dist/elements/web-search.js +2 -2
- package/dist/elements/work-collapse.js +1 -1
- package/dist/forms/file-upload.js +1 -1
- package/dist/forms/rating.js +1 -1
- package/dist/forms/select.js +1 -1
- package/dist/forms/switch.js +2 -2
- package/dist/forms/toggle.js +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/instruments/_ledger-disclosure.js +1 -1
- package/dist/instruments/data-tree.js +1 -1
- package/dist/instruments/meter.js +1 -1
- package/dist/instruments/seam-grid.js +1 -1
- package/dist/layout/_collapse.js +3 -3
- package/dist/layout/bento.js +1 -1
- package/dist/layout/breadcrumb.js +1 -1
- package/dist/layout/carousel.js +1 -1
- package/dist/layout/collapsible.js +1 -1
- package/dist/layout/index.d.ts +3 -1
- package/dist/layout/index.js +3 -1
- package/dist/layout/item.js +1 -1
- package/dist/layout/link.js +1 -1
- package/dist/layout/pagination.js +1 -1
- package/dist/layout/pane-seam.d.ts +75 -0
- package/dist/layout/pane-seam.js +127 -0
- package/dist/layout/resizable.d.ts +2 -1
- package/dist/layout/resizable.js +3 -2
- package/dist/layout/reveal.js +10 -4
- package/dist/layout/sidebar.js +3 -3
- package/dist/layout/split-pane.d.ts +74 -0
- package/dist/layout/split-pane.js +135 -0
- package/dist/layout/stepper.js +1 -1
- package/dist/lib/auto-grow.js +42 -0
- package/dist/overlays/_surface.d.ts +4 -4
- package/dist/overlays/_surface.js +4 -4
- package/dist/overlays/drawer.js +1 -1
- package/dist/overlays/menubar.js +1 -1
- package/dist/overlays/sheet.js +1 -1
- package/dist/overlays/toast.js +1 -1
- package/dist/primitives/button.js +1 -1
- package/dist/primitives/chip.d.ts +1 -1
- package/dist/styles.css +12 -0
- package/dist/system/agent-skin.d.ts +11 -5
- package/dist/system/frame-clock.js +1 -0
- package/dist/system/theme-registry.d.ts +1 -1
- package/dist/system/theme-registry.js +1 -1
- package/manifest/components/agent-surface.json +5 -4
- package/manifest/components/approval-card.json +45 -7
- package/manifest/components/composer-input.json +16 -2
- package/manifest/components/elicitation-form.json +16 -1
- package/manifest/components/event-feed.json +171 -0
- package/manifest/components/event-row.json +116 -0
- package/manifest/components/generative-ui.json +4 -3
- package/manifest/components/pane-seam.json +171 -0
- package/manifest/components/question-card.json +157 -0
- package/manifest/components/resizable.json +1 -1
- package/manifest/components/reveal.json +3 -1
- package/manifest/components/split-pane.json +224 -0
- package/manifest/components/tool-call.json +46 -2
- package/manifest/components/tool-group.json +15 -3
- package/manifest/components/unsupported-request-card.json +117 -0
- package/manifest/fixtures.json +16 -0
- package/manifest/manifest.json +91 -13
- package/manifest/tokens.json +9 -2
- package/package.json +8 -6
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"lucide-react"
|
|
8
8
|
],
|
|
9
9
|
"clientOnly": true,
|
|
10
|
-
"description": "The text field. Enter
|
|
10
|
+
"description": "The text field: a textarea that grows with what it holds, to a cap. Enter sends and\nShift+Enter breaks the line, both guarded against IME composition so accepting a\ncandidate does not send the message.",
|
|
11
11
|
"props": [
|
|
12
12
|
{
|
|
13
13
|
"name": "onSubmit",
|
|
@@ -19,10 +19,24 @@
|
|
|
19
19
|
"kind": "callback",
|
|
20
20
|
"fixture": "callback.log"
|
|
21
21
|
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"name": "size",
|
|
25
|
+
"type": "\"sm\" | \"md\"",
|
|
26
|
+
"required": false,
|
|
27
|
+
"defaultValue": "md",
|
|
28
|
+
"description": "`md` (the default) or `sm`: the smaller rung, a 36px floor with body type, for a\ncompact console.",
|
|
29
|
+
"control": {
|
|
30
|
+
"kind": "enum",
|
|
31
|
+
"members": [
|
|
32
|
+
"sm",
|
|
33
|
+
"md"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
22
36
|
}
|
|
23
37
|
],
|
|
24
38
|
"typeReferences": [
|
|
25
|
-
"Omit<ComponentProps<\"
|
|
39
|
+
"Omit<ComponentProps<\"textarea\">, \"onSubmit\"> & {\n /**\n * Called on Enter, guarded against IME composition so accepting a candidate does not\n * send.\n */\n onSubmit?: () => void;\n /**\n * `md` (the default) or `sm`: the smaller rung, a 36px floor with body type, for a\n * compact console.\n */\n size?: \"sm\" | \"md\";\n}"
|
|
26
40
|
],
|
|
27
41
|
"subcomponents": [],
|
|
28
42
|
"parts": [],
|
|
@@ -76,10 +76,25 @@
|
|
|
76
76
|
"kind": "callback",
|
|
77
77
|
"fixture": "callback.log"
|
|
78
78
|
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"name": "delivery",
|
|
82
|
+
"type": "\"failed\" | \"sending\" | \"sent\"",
|
|
83
|
+
"required": false,
|
|
84
|
+
"defaultValue": null,
|
|
85
|
+
"description": "Where the answer has got to: `sending`, `sent` or `failed`. While it is on its way\nand once it has arrived, the form offers nothing to press. `failed` offers Decline\nand Send again. An outcome `state` wins over it.",
|
|
86
|
+
"control": {
|
|
87
|
+
"kind": "enum",
|
|
88
|
+
"members": [
|
|
89
|
+
"failed",
|
|
90
|
+
"sending",
|
|
91
|
+
"sent"
|
|
92
|
+
]
|
|
93
|
+
}
|
|
79
94
|
}
|
|
80
95
|
],
|
|
81
96
|
"typeReferences": [
|
|
82
|
-
"Omit<\n ComponentProps<\"div\">,\n | \"children\"\n | \"server\"\n | \"message\"\n | \"fields\"\n | \"state\"\n | \"onAccept\"\n | \"onDecline\"\n> & {\n /** Which server paused to ask. */\n server: string;\n /** Why the input is needed, in the server's words. */\n message: string;\n /** The schema the server sent, already resolved to display values. */\n fields: readonly ElicitationField[];\n /** Swaps the action row for the outcome once the user answers. */\n state: ElicitationState;\n /** Called when the filled form is sent back. */\n onAccept?: () => void;\n /** Called when the request is refused. */\n onDecline?: () => void;\n}"
|
|
97
|
+
"Omit<\n ComponentProps<\"div\">,\n | \"children\"\n | \"server\"\n | \"message\"\n | \"fields\"\n | \"state\"\n | \"onAccept\"\n | \"onDecline\"\n | \"delivery\"\n> & {\n /** Which server paused to ask. */\n server: string;\n /** Why the input is needed, in the server's words. */\n message: string;\n /** The schema the server sent, already resolved to display values. */\n fields: readonly ElicitationField[];\n /** Swaps the action row for the outcome once the user answers. */\n state: ElicitationState;\n /** Called when the filled form is sent back. */\n onAccept?: () => void;\n /** Called when the request is refused. */\n onDecline?: () => void;\n /**\n * Where the answer has got to: `sending`, `sent` or `failed`. While it is on its way\n * and once it has arrived, the form offers nothing to press. `failed` offers Decline\n * and Send again. An outcome `state` wins over it.\n */\n delivery?: RequestDelivery;\n}"
|
|
83
98
|
],
|
|
84
99
|
"subcomponents": [],
|
|
85
100
|
"parts": [],
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "EventFeed",
|
|
3
|
+
"slug": "event-feed",
|
|
4
|
+
"group": "elements",
|
|
5
|
+
"importPath": "@cueplusplus/ui/elements",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "A filterable activity feed: timestamped, typed records with a one-line\npreview, and a selection the detail pane follows (#103).\n\nThe chips are built from the kinds present, in the order each first\nappears, each with its count, so a feed never offers a filter that keeps\nnothing. The rows are a listbox: j and k, or the arrows, move the selection\nthrough the rows the filter keeps, and Home and End jump to the ends. The\nselection follows the keyboard, so the detail beside it follows too.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "label",
|
|
12
|
+
"type": "string",
|
|
13
|
+
"required": true,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "The feed's accessible name: `Run events`.",
|
|
16
|
+
"control": {
|
|
17
|
+
"kind": "string"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "events",
|
|
22
|
+
"type": "readonly FeedEvent[]",
|
|
23
|
+
"required": true,
|
|
24
|
+
"defaultValue": null,
|
|
25
|
+
"description": "The records, oldest first or newest first: the feed keeps the order given.",
|
|
26
|
+
"control": {
|
|
27
|
+
"kind": "array",
|
|
28
|
+
"fixture": "agents.feed"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "filter",
|
|
33
|
+
"type": "string",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": null,
|
|
36
|
+
"description": "The kind the feed keeps, or `all`, when the caller holds it.",
|
|
37
|
+
"control": {
|
|
38
|
+
"kind": "string"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"name": "defaultFilter",
|
|
43
|
+
"type": "string",
|
|
44
|
+
"required": false,
|
|
45
|
+
"defaultValue": "all",
|
|
46
|
+
"description": "The kind to start on when nothing controls it. Defaults to `all`.",
|
|
47
|
+
"control": {
|
|
48
|
+
"kind": "string"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "onFilterChange",
|
|
53
|
+
"type": "((filter: string) => void)",
|
|
54
|
+
"required": false,
|
|
55
|
+
"defaultValue": null,
|
|
56
|
+
"description": "Called with the kind, or `all`, when a chip is pressed.",
|
|
57
|
+
"control": {
|
|
58
|
+
"kind": "callback",
|
|
59
|
+
"fixture": "callback.log"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "selectedId",
|
|
64
|
+
"type": "string | null",
|
|
65
|
+
"required": false,
|
|
66
|
+
"defaultValue": "null",
|
|
67
|
+
"description": "The selected event's `id`, or `null` for none.",
|
|
68
|
+
"control": {
|
|
69
|
+
"kind": "string",
|
|
70
|
+
"nullable": true
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "onSelect",
|
|
75
|
+
"type": "((id: string) => void)",
|
|
76
|
+
"required": false,
|
|
77
|
+
"defaultValue": null,
|
|
78
|
+
"description": "Called with an event's `id` when a row is clicked or the keyboard moves to it.",
|
|
79
|
+
"control": {
|
|
80
|
+
"kind": "callback",
|
|
81
|
+
"fixture": "callback.log"
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
"name": "formatTime",
|
|
86
|
+
"type": "((timestamp: string | number | Date) => string)",
|
|
87
|
+
"required": false,
|
|
88
|
+
"defaultValue": null,
|
|
89
|
+
"description": "Formats the time column. Defaults to a time of day for a `Date` or a number.",
|
|
90
|
+
"control": {
|
|
91
|
+
"kind": "callback",
|
|
92
|
+
"fixture": "callback.log"
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "labels",
|
|
97
|
+
"type": "Partial<EventFeedLabels>",
|
|
98
|
+
"required": false,
|
|
99
|
+
"defaultValue": null,
|
|
100
|
+
"description": "Replace any of the feed's own copy.",
|
|
101
|
+
"control": {
|
|
102
|
+
"kind": "opaque"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"typeReferences": [
|
|
107
|
+
"Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\" | \"onSelect\">"
|
|
108
|
+
],
|
|
109
|
+
"subcomponents": [],
|
|
110
|
+
"parts": [],
|
|
111
|
+
"variants": {},
|
|
112
|
+
"defaultVariants": {},
|
|
113
|
+
"tokensUsed": [
|
|
114
|
+
"--cue-accent",
|
|
115
|
+
"--cue-border",
|
|
116
|
+
"--cue-danger",
|
|
117
|
+
"--cue-fg",
|
|
118
|
+
"--cue-fg-muted",
|
|
119
|
+
"--cue-fg-subtle",
|
|
120
|
+
"--cue-focus",
|
|
121
|
+
"--cue-focus-ring",
|
|
122
|
+
"--cue-ok",
|
|
123
|
+
"--cue-radius-control",
|
|
124
|
+
"--cue-space-1",
|
|
125
|
+
"--cue-space-2",
|
|
126
|
+
"--cue-space-3",
|
|
127
|
+
"--cue-stream",
|
|
128
|
+
"--cue-style-focus-width",
|
|
129
|
+
"--cue-surface-2",
|
|
130
|
+
"--cue-text-label",
|
|
131
|
+
"--cue-text-ui",
|
|
132
|
+
"--cue-warn"
|
|
133
|
+
],
|
|
134
|
+
"summary": "A filterable activity feed: typed, timestamped records with a one-line preview and a selection.",
|
|
135
|
+
"examples": [
|
|
136
|
+
{
|
|
137
|
+
"title": "Usage",
|
|
138
|
+
"code": "const [selected, setSelected] = React.useState<string | null>(null);\n\n<EventFeed\n label=\"Run events\"\n events={events}\n selectedId={selected}\n onSelect={setSelected}\n/>",
|
|
139
|
+
"language": "tsx"
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"status": "stable",
|
|
143
|
+
"url": "/docs/components/event-feed",
|
|
144
|
+
"mdUrl": "/docs/components/event-feed.md",
|
|
145
|
+
"jsonUrl": "/r/components/event-feed.json",
|
|
146
|
+
"whenToUse": [
|
|
147
|
+
"Inspecting a run beside its transcript: tool calls, permission asks, compactions, errors.",
|
|
148
|
+
"Any stream of typed records outside agents: MCP logs, device heartbeats, billing events, CI steps."
|
|
149
|
+
],
|
|
150
|
+
"whenNotToUse": [
|
|
151
|
+
"The conversation itself. Tool calls in the transcript are `ToolGroup`'s; this is the list beside it.",
|
|
152
|
+
"Raw log lines with ANSI colour. `LogViewer`, from `@cueplusplus/ui/instruments/log-viewer`, reads those."
|
|
153
|
+
],
|
|
154
|
+
"commonMistakes": [
|
|
155
|
+
"Drawing the detail inside the feed. The feed reports a selection; put the detail in `SplitPane`'s `detail` slot.",
|
|
156
|
+
"Kinds that are sentences. Each kind becomes a chip, so keep them to a word: `tool`, `permission`, `error`.",
|
|
157
|
+
"Formatting time strings and also passing `formatTime`. A string timestamp is drawn as given; pass a `Date` or a number to have it formatted."
|
|
158
|
+
],
|
|
159
|
+
"specimens": [
|
|
160
|
+
{
|
|
161
|
+
"title": "EventFeed",
|
|
162
|
+
"group": "elements",
|
|
163
|
+
"components": [
|
|
164
|
+
"EventFeed"
|
|
165
|
+
],
|
|
166
|
+
"code": "<div className=\"w-full max-w-md\">\n <EventFeed\n label=\"Patch run events\"\n events={RUN_EVENTS}\n selectedId={runEvent}\n onSelect={setRunEvent}\n />\n</div>",
|
|
167
|
+
"note": "The inspector beside a transcript: typed records, each a time, a toned dot, a kind, a title and a one-line preview. The chips are built from the kinds present, each with its count, so no chip keeps nothing. The detail is the host's: in a console it goes in SplitPane's detail slot.",
|
|
168
|
+
"interaction": "press a chip to keep one kind. Tab into the list, then j and k, or the arrows, move the selection through the rows the filter keeps, and Home and End jump to the ends."
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "EventRow",
|
|
3
|
+
"slug": "event-row",
|
|
4
|
+
"group": "elements",
|
|
5
|
+
"importPath": "@cueplusplus/ui/elements",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "One event, as a feed row: time, a toned dot, kind, title, and a one-line\npreview under the title. Exported for a list of the caller's own.\n\nInside an {@link EventFeed} it is an `option` of the feed's listbox. Drawn\nalone it claims no role, and in a listbox of the caller's it takes\n`role=\"option\"` from its props; either way `aria-selected` follows `selected`\nonly when the row is an option.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "event",
|
|
12
|
+
"type": "FeedEvent",
|
|
13
|
+
"required": true,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "The record this row draws.",
|
|
16
|
+
"control": {
|
|
17
|
+
"kind": "opaque",
|
|
18
|
+
"fixture": "agents.feed-event"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"name": "selected",
|
|
23
|
+
"type": "boolean",
|
|
24
|
+
"required": false,
|
|
25
|
+
"defaultValue": "false",
|
|
26
|
+
"description": "Whether this row is the selected one.",
|
|
27
|
+
"control": {
|
|
28
|
+
"kind": "boolean"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "onSelect",
|
|
33
|
+
"type": "((id: string) => void)",
|
|
34
|
+
"required": false,
|
|
35
|
+
"defaultValue": null,
|
|
36
|
+
"description": "Called with the event's `id` when the row is clicked.",
|
|
37
|
+
"control": {
|
|
38
|
+
"kind": "callback",
|
|
39
|
+
"fixture": "callback.log"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"name": "formatTime",
|
|
44
|
+
"type": "((timestamp: string | number | Date) => string)",
|
|
45
|
+
"required": false,
|
|
46
|
+
"defaultValue": "formatTimestamp",
|
|
47
|
+
"description": "Formats the time column. Defaults to a time of day for a `Date` or a number.",
|
|
48
|
+
"control": {
|
|
49
|
+
"kind": "callback",
|
|
50
|
+
"fixture": "callback.log"
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"typeReferences": [
|
|
55
|
+
"Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\" | \"onSelect\">"
|
|
56
|
+
],
|
|
57
|
+
"subcomponents": [],
|
|
58
|
+
"parts": [],
|
|
59
|
+
"variants": {},
|
|
60
|
+
"defaultVariants": {},
|
|
61
|
+
"tokensUsed": [
|
|
62
|
+
"--cue-accent",
|
|
63
|
+
"--cue-border",
|
|
64
|
+
"--cue-danger",
|
|
65
|
+
"--cue-fg",
|
|
66
|
+
"--cue-fg-muted",
|
|
67
|
+
"--cue-fg-subtle",
|
|
68
|
+
"--cue-focus",
|
|
69
|
+
"--cue-focus-ring",
|
|
70
|
+
"--cue-ok",
|
|
71
|
+
"--cue-radius-control",
|
|
72
|
+
"--cue-space-1",
|
|
73
|
+
"--cue-space-2",
|
|
74
|
+
"--cue-space-3",
|
|
75
|
+
"--cue-stream",
|
|
76
|
+
"--cue-style-focus-width",
|
|
77
|
+
"--cue-surface-2",
|
|
78
|
+
"--cue-text-label",
|
|
79
|
+
"--cue-text-ui",
|
|
80
|
+
"--cue-warn"
|
|
81
|
+
],
|
|
82
|
+
"summary": "One event as an activity feed draws it, for a list of your own.",
|
|
83
|
+
"examples": [
|
|
84
|
+
{
|
|
85
|
+
"title": "Usage",
|
|
86
|
+
"code": "<div role=\"listbox\" aria-label=\"Recent\">\n <EventRow role=\"option\" event={event} selected={event.id === id} onSelect={setId} />\n</div>",
|
|
87
|
+
"language": "tsx"
|
|
88
|
+
}
|
|
89
|
+
],
|
|
90
|
+
"status": "stable",
|
|
91
|
+
"url": "/docs/components/event-row",
|
|
92
|
+
"mdUrl": "/docs/components/event-row.md",
|
|
93
|
+
"jsonUrl": "/r/components/event-row.json",
|
|
94
|
+
"whenToUse": [
|
|
95
|
+
"A custom list of typed records that should look like `EventFeed`'s rows: grouped by run, virtualised, or interleaved with headings."
|
|
96
|
+
],
|
|
97
|
+
"whenNotToUse": [
|
|
98
|
+
"A plain filterable feed. `EventFeed` draws these rows with chips and a keyboard already."
|
|
99
|
+
],
|
|
100
|
+
"commonMistakes": [
|
|
101
|
+
"Rows in a listbox of your own without `role=\"option\"`. Outside an `EventFeed` a row claims no role, so pass it, and the row then says whether it is selected.",
|
|
102
|
+
"Expecting the row to move the selection from the keyboard. `EventFeed` owns that; a list of your own must too."
|
|
103
|
+
],
|
|
104
|
+
"specimens": [
|
|
105
|
+
{
|
|
106
|
+
"title": "EventRow",
|
|
107
|
+
"group": "elements",
|
|
108
|
+
"components": [
|
|
109
|
+
"EventRow"
|
|
110
|
+
],
|
|
111
|
+
"code": "<div role=\"listbox\" aria-label=\"Two run events\" className=\"flex w-full max-w-md flex-col\">\n <EventRow role=\"option\" event={RUN_EVENTS[0]} onSelect={setRunEvent} />\n <EventRow role=\"option\" event={RUN_EVENTS[3]} selected onSelect={setRunEvent} />\n</div>",
|
|
112
|
+
"note": "One event as the feed draws it, for a list of your own: the time, the toned dot, the kind, the title and its preview. The second row is the selected one.",
|
|
113
|
+
"interaction": "click a row: it reports its id through onSelect. Inside an EventFeed the feed owns the keyboard."
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"importPath": "@cueplusplus/ui/elements/generative",
|
|
6
6
|
"peerDependencies": [],
|
|
7
7
|
"clientOnly": true,
|
|
8
|
-
"description": "The vocabulary a model composes at runtime.\n\nEvery other component in this library is handed props by a programmer, and a\nwrong one costs a type error at the call site. This one is handed a tree by a\nlanguage model over a network, so its whole contract is what it does with\ninput nobody checked. A model emits JSON — 27 intrinsic names, nested — and\n`GenerativeUI` turns it into elements. There is no compile step between the\ntwo and there cannot be one.\n\nThat reverses the usual priorities. The interesting question is not what a\ncorrect spec renders as, it is what an incorrect one does, and the answer is\nthree-fold and never an exception:\n\n- a `$type` from a newer catalogue draws an in-place notice and its siblings\n still render;\n- a spec that is not a component tree at all draws a legible error state,\n never a blank box that looks like a message still streaming;\n- a tree nested deeper than {@link GENERATIVE_MAX_DEPTH} stops and says so,\n rather than exhausting the stack and taking the console with it.\n\nThe root is a plain `<div data-slot=\"generative-ui\" data-aui=\"root\">` and it\nis always there: an unreadable spec draws the error state *inside* it rather\nthan instead of it, so a caller's layout, `className` and ref hold whatever\nthe model sent.\n\n## Why it is not Tailwind\n\nThe stylesheet is plain `[data-aui]` CSS, and the tree it draws carries no\n`class` attribute anywhere. That is upstream's arrangement and it is worth\nkeeping precisely: a widget a model composed has to draw inside whatever\nconsole it was sent to, and a console is very often somebody else's app with\nno utility framework, no shadcn and no design system of its own. The\nconsequence runs all the way down — the icons are hand-drawn rather than\n`lucide-react`, the chart is 300 lines of SVG rather than `recharts`, and\n`./elements/generative` declares no optional peer at all. There is no package\nin the tree whose absence turns a weather card into a stack trace.\n\n```tsx\nimport { GenerativeUI } from \"@cueplusplus/ui/elements/generative\";\nimport \"@cueplusplus/ui/elements/generative.css\";\n```\n\n##
|
|
8
|
+
"description": "The vocabulary a model composes at runtime.\n\nEvery other component in this library is handed props by a programmer, and a\nwrong one costs a type error at the call site. This one is handed a tree by a\nlanguage model over a network, so its whole contract is what it does with\ninput nobody checked. A model emits JSON — 27 intrinsic names, nested — and\n`GenerativeUI` turns it into elements. There is no compile step between the\ntwo and there cannot be one.\n\nThat reverses the usual priorities. The interesting question is not what a\ncorrect spec renders as, it is what an incorrect one does, and the answer is\nthree-fold and never an exception:\n\n- a `$type` from a newer catalogue draws an in-place notice and its siblings\n still render;\n- a spec that is not a component tree at all draws a legible error state,\n never a blank box that looks like a message still streaming;\n- a tree nested deeper than {@link GENERATIVE_MAX_DEPTH} stops and says so,\n rather than exhausting the stack and taking the console with it.\n\nThe root is a plain `<div data-slot=\"generative-ui\" data-aui=\"root\">` and it\nis always there: an unreadable spec draws the error state *inside* it rather\nthan instead of it, so a caller's layout, `className` and ref hold whatever\nthe model sent.\n\n## Why it is not Tailwind\n\nThe stylesheet is plain `[data-aui]` CSS, and the tree it draws carries no\n`class` attribute anywhere. That is upstream's arrangement and it is worth\nkeeping precisely: a widget a model composed has to draw inside whatever\nconsole it was sent to, and a console is very often somebody else's app with\nno utility framework, no shadcn and no design system of its own. The\nconsequence runs all the way down — the icons are hand-drawn rather than\n`lucide-react`, the chart is 300 lines of SVG rather than `recharts`, and\n`./elements/generative` declares no optional peer at all. There is no package\nin the tree whose absence turns a weather card into a stack trace.\n\n```tsx\nimport { GenerativeUI } from \"@cueplusplus/ui/elements/generative\";\nimport \"@cueplusplus/ui/elements/generative.css\";\n```\n\n## Skins\n\n`skin` and `fidelity` are the same two axes {@link AgentSurface } publishes,\nand for the same reason: the vocabulary has cue's values by default,\nCursor's under `skin=\"cursor\"`, and assistant-ui's under `skin=\"aui\"`, which\nis upstream's own\n`data-aui-theme=\"elements\"` layer — a 20px card, a borderless 12px field, a\npill button. Pass them here when the tree is its own island; leave them off\ninside an `AgentSurface`, which has already stamped the subtree and whose\nvalues inherit through CSS with nothing threaded.",
|
|
9
9
|
"props": [
|
|
10
10
|
{
|
|
11
11
|
"name": "spec",
|
|
@@ -62,13 +62,14 @@
|
|
|
62
62
|
},
|
|
63
63
|
{
|
|
64
64
|
"name": "skin",
|
|
65
|
-
"type": "\"cue\" | \"aui\"",
|
|
65
|
+
"type": "\"cursor\" | \"cue\" | \"aui\"",
|
|
66
66
|
"required": false,
|
|
67
67
|
"defaultValue": null,
|
|
68
|
-
"description": "Which value-set paints this tree: `cue` (the default)
|
|
68
|
+
"description": "Which value-set paints this tree: `cue` (the default), `aui`, which\ninstalls assistant-ui's own surface language, or `cursor`, Cursor's\nagent-pane values. Leave it off inside an {@link AgentSurface }, which has\nstamped the subtree already.",
|
|
69
69
|
"control": {
|
|
70
70
|
"kind": "enum",
|
|
71
71
|
"members": [
|
|
72
|
+
"cursor",
|
|
72
73
|
"cue",
|
|
73
74
|
"aui"
|
|
74
75
|
]
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "PaneSeam",
|
|
3
|
+
"slug": "pane-seam",
|
|
4
|
+
"group": "layout",
|
|
5
|
+
"importPath": "@cueplusplus/ui",
|
|
6
|
+
"peerDependencies": [],
|
|
7
|
+
"clientOnly": true,
|
|
8
|
+
"description": "One accessible seam that resizes one pane, with no dependency (cue-ui-55).\n\n`Resizable` divides a frame between panel groups on `react-resizable-panels`,\nan optional peer. Most consoles need one thing less: a side pane whose edge a\nreader can drag, and move from the keyboard. This is that edge, and nothing\nelse. It owns a number, not a layout: apply `value` to the pane's width (or\nheight) and the seam supplies the rest.\n\nThe rest is the part a hand-written separator forgets. It is a focusable\n`role=\"separator\"` that says its size and its bounds (`aria-valuenow`,\n`-valuemin`, `-valuemax`), so the width is spoken as well as draggable. The\narrows move it by `step`, Shift by `largeStep`, and Home and End jump to the\nbounds. Every value is clamped, so the pane can never squeeze its neighbour\nout of use.",
|
|
9
|
+
"props": [
|
|
10
|
+
{
|
|
11
|
+
"name": "label",
|
|
12
|
+
"type": "string",
|
|
13
|
+
"required": true,
|
|
14
|
+
"defaultValue": null,
|
|
15
|
+
"description": "The name a screen reader lists the seam by: `Resize the inspector`. Required,\nbecause a separator nobody can name is one a keyboard user cannot find.",
|
|
16
|
+
"control": {
|
|
17
|
+
"kind": "string"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "value",
|
|
22
|
+
"type": "number",
|
|
23
|
+
"required": false,
|
|
24
|
+
"defaultValue": null,
|
|
25
|
+
"description": "The pane's size in pixels, when the caller holds it.",
|
|
26
|
+
"control": {
|
|
27
|
+
"kind": "number"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "defaultValue",
|
|
32
|
+
"type": "number",
|
|
33
|
+
"required": false,
|
|
34
|
+
"defaultValue": null,
|
|
35
|
+
"description": "The size to start from when nothing controls it. Defaults to `min`.",
|
|
36
|
+
"control": {
|
|
37
|
+
"kind": "number"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "onValueChange",
|
|
42
|
+
"type": "((value: number) => void)",
|
|
43
|
+
"required": false,
|
|
44
|
+
"defaultValue": null,
|
|
45
|
+
"description": "Called with every new size, already clamped to `min` and `max`.",
|
|
46
|
+
"control": {
|
|
47
|
+
"kind": "callback",
|
|
48
|
+
"fixture": "callback.log"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"name": "min",
|
|
53
|
+
"type": "number",
|
|
54
|
+
"required": true,
|
|
55
|
+
"defaultValue": null,
|
|
56
|
+
"description": "The smallest the pane may become, in pixels.",
|
|
57
|
+
"control": {
|
|
58
|
+
"kind": "number"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "max",
|
|
63
|
+
"type": "number",
|
|
64
|
+
"required": true,
|
|
65
|
+
"defaultValue": null,
|
|
66
|
+
"description": "The largest the pane may become, in pixels.",
|
|
67
|
+
"control": {
|
|
68
|
+
"kind": "number"
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "step",
|
|
73
|
+
"type": "number",
|
|
74
|
+
"required": false,
|
|
75
|
+
"defaultValue": "16",
|
|
76
|
+
"description": "How far one arrow press moves the seam, in pixels. Defaults to 16.",
|
|
77
|
+
"control": {
|
|
78
|
+
"kind": "number"
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "largeStep",
|
|
83
|
+
"type": "number",
|
|
84
|
+
"required": false,
|
|
85
|
+
"defaultValue": "64",
|
|
86
|
+
"description": "How far Shift with an arrow moves it, in pixels. Defaults to 64.",
|
|
87
|
+
"control": {
|
|
88
|
+
"kind": "number"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"name": "orientation",
|
|
93
|
+
"type": "\"horizontal\" | \"vertical\"",
|
|
94
|
+
"required": false,
|
|
95
|
+
"defaultValue": "vertical",
|
|
96
|
+
"description": "`vertical`, the default, divides side-by-side panes and resizes a width;\n`horizontal` divides stacked panes and resizes a height.",
|
|
97
|
+
"control": {
|
|
98
|
+
"kind": "enum",
|
|
99
|
+
"members": [
|
|
100
|
+
"horizontal",
|
|
101
|
+
"vertical"
|
|
102
|
+
]
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"name": "edge",
|
|
107
|
+
"type": "\"end\" | \"start\"",
|
|
108
|
+
"required": false,
|
|
109
|
+
"defaultValue": "start",
|
|
110
|
+
"description": "Where the pane sits: `start`, the default, before the seam (left, or top),\nor `end`, after it. Moving the seam away from the pane grows it. A vertical\nseam reads the document's direction, so `start` is the right-hand pane\nunder `dir=\"rtl\"`.",
|
|
111
|
+
"control": {
|
|
112
|
+
"kind": "enum",
|
|
113
|
+
"members": [
|
|
114
|
+
"end",
|
|
115
|
+
"start"
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
],
|
|
120
|
+
"typeReferences": [
|
|
121
|
+
"Omit<React.ComponentPropsWithoutRef<\"div\">, \"children\" | \"defaultValue\" | \"onChange\">"
|
|
122
|
+
],
|
|
123
|
+
"subcomponents": [],
|
|
124
|
+
"parts": [],
|
|
125
|
+
"variants": {},
|
|
126
|
+
"defaultVariants": {},
|
|
127
|
+
"tokensUsed": [
|
|
128
|
+
"--cue-accent",
|
|
129
|
+
"--cue-border",
|
|
130
|
+
"--cue-focus",
|
|
131
|
+
"--cue-focus-ring",
|
|
132
|
+
"--cue-style-focus-width"
|
|
133
|
+
],
|
|
134
|
+
"summary": "One accessible seam that resizes one pane, with no dependency.",
|
|
135
|
+
"examples": [
|
|
136
|
+
{
|
|
137
|
+
"title": "Usage",
|
|
138
|
+
"code": "const [width, setWidth] = React.useState(320);\nconst inspector = { width };\n\n<div className=\"flex\">\n <main className=\"min-w-0 flex-1\">…</main>\n <PaneSeam\n label=\"Resize the inspector\"\n edge=\"end\"\n min={240}\n max={640}\n value={width}\n onValueChange={setWidth}\n />\n <aside style={inspector}>…</aside>\n</div>",
|
|
139
|
+
"language": "tsx"
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"status": "stable",
|
|
143
|
+
"url": "/docs/components/pane-seam",
|
|
144
|
+
"mdUrl": "/docs/components/pane-seam.md",
|
|
145
|
+
"jsonUrl": "/r/components/pane-seam.json",
|
|
146
|
+
"whenToUse": [
|
|
147
|
+
"A side pane whose edge a reader can drag and move from the keyboard: an inspector, a file tree, a thread beside a canvas.",
|
|
148
|
+
"Keeping the layout yours. The seam reports a size and you apply it, so it fits any flex or grid frame."
|
|
149
|
+
],
|
|
150
|
+
"whenNotToUse": [
|
|
151
|
+
"Several panels that divide one frame by percentage. Use `Resizable`, from `@cueplusplus/ui/layout/resizable`.",
|
|
152
|
+
"A list beside a detail that should stack when narrow. `SplitPane` builds that on this seam."
|
|
153
|
+
],
|
|
154
|
+
"commonMistakes": [
|
|
155
|
+
"Rendering the seam and not applying its `value`. It moves nothing by itself; put the value on the pane's width or height.",
|
|
156
|
+
"Setting `edge` for the wrong side. `edge=\"end\"` is a pane after the seam, which grows as the seam moves toward the start.",
|
|
157
|
+
"A `label` that names the seam rather than the pane. A screen reader lists it by name, so say what it resizes: `Resize the inspector`."
|
|
158
|
+
],
|
|
159
|
+
"specimens": [
|
|
160
|
+
{
|
|
161
|
+
"title": "PaneSeam",
|
|
162
|
+
"group": "layout",
|
|
163
|
+
"components": [
|
|
164
|
+
"PaneSeam"
|
|
165
|
+
],
|
|
166
|
+
"code": "<div className=\"flex h-[9rem] w-full max-w-[36rem] overflow-hidden rounded-(--radius-surface) border border-border\">\n <div className=\"flex min-w-0 flex-1 items-center justify-center font-mono text-(length:--cue-text-ui) text-fg-muted\">\n Patch\n </div>\n <PaneSeam\n label=\"Resize the inspector\"\n edge=\"end\"\n min={160}\n max={360}\n value={inspector}\n onValueChange={setInspector}\n />\n <div\n className=\"flex shrink-0 items-center justify-center font-mono text-(length:--cue-text-ui) text-fg-muted\"\n style={{ width: inspector }}\n >\n Inspector · {inspector}px\n </div>\n</div>",
|
|
167
|
+
"note": "One seam that resizes one pane, with no dependency. It owns a number, not a layout: the inspector below takes the seam's value as its width, and the seam clamps it so the patch list always keeps its room.",
|
|
168
|
+
"interaction": "drag the seam, or tab to it: the arrows move it 16px, Shift+arrow 64px, and Home and End jump to the inspector's narrowest and widest. A screen reader hears the width and its bounds."
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|