@workerdeck/ui 0.12.0 → 0.15.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 (32) hide show
  1. package/README.md +19 -0
  2. package/build/{SessionPanel-NQ8ksCfj.mjs → SessionPanel-DI1NO4l8.mjs} +223 -163
  3. package/build/SessionPanel-DI1NO4l8.mjs.map +1 -0
  4. package/build/{SessionPanel-Dy9lQrOV.d.mts → SessionPanel-J2U8v88q.d.mts} +86 -8
  5. package/build/index.d.mts +118 -7
  6. package/build/index.mjs +355 -169
  7. package/build/index.mjs.map +1 -1
  8. package/build/workspace.d.mts +13 -1
  9. package/build/workspace.mjs +7 -2
  10. package/build/workspace.mjs.map +1 -1
  11. package/package.json +4 -4
  12. package/src/components/agent/Composer.tsx +112 -37
  13. package/src/components/agent/EngineIcon.tsx +97 -0
  14. package/src/components/agent/Loader.tsx +4 -1
  15. package/src/components/agent/Message.tsx +12 -5
  16. package/src/components/agent/QuestionPrompt.tsx +1 -1
  17. package/src/components/agent/SessionBrowser.tsx +266 -138
  18. package/src/components/agent/SessionPanel.tsx +149 -48
  19. package/src/components/agent/SessionWorkspace.tsx +17 -0
  20. package/src/components/agent/StatusBar.tsx +58 -12
  21. package/src/components/agent/Transcript.tsx +2 -3
  22. package/src/components/agent/line-prompt.tsx +2 -2
  23. package/src/components/agent/transcript-variant.tsx +14 -0
  24. package/src/components/ui/Badge.tsx +6 -1
  25. package/src/components/ui/Empty.tsx +56 -0
  26. package/src/components/ui/Menu.tsx +1 -1
  27. package/src/components/ui/Select.tsx +1 -1
  28. package/src/components/ui/Splitter.tsx +14 -0
  29. package/src/components/ui/Tooltip.tsx +1 -1
  30. package/src/index.ts +11 -1
  31. package/src/styles/theme.css +77 -15
  32. package/build/SessionPanel-NQ8ksCfj.mjs.map +0 -1
@@ -20,6 +20,12 @@ export interface SplitterProps {
20
20
  max: number
21
21
  /** Keyboard step. */
22
22
  step?: number
23
+ /**
24
+ * Size to snap back to on a double-click — the convention every pane divider
25
+ * that can be dragged is expected to honour. Omit and a double-click does
26
+ * nothing, which is the honest behaviour when there is no default to mean.
27
+ */
28
+ defaultValue?: number
23
29
  /** Set when dragging the splitter *away* from the origin should shrink the
24
30
  * controlled pane — i.e. the pane is on the right or the bottom. */
25
31
  inverted?: boolean
@@ -52,6 +58,7 @@ export function Splitter({
52
58
  min,
53
59
  max,
54
60
  step = 16,
61
+ defaultValue,
55
62
  inverted,
56
63
  'aria-label': label,
57
64
  className,
@@ -84,6 +91,12 @@ export function Splitter({
84
91
  }
85
92
  }
86
93
 
94
+ // The second click of a double-click has already started a drag, so the reset
95
+ // has to land after `endDrag` — which it does: dblclick fires after pointerup.
96
+ const onDoubleClick = () => {
97
+ if (defaultValue !== undefined) onValueChange(clamp(defaultValue))
98
+ }
99
+
87
100
  const onKeyDown = (event: ReactKeyboardEvent<HTMLDivElement>) => {
88
101
  // The arrows that move *along* this splitter's axis of travel; the other
89
102
  // pair is left to the page, which is what a separator should do with them.
@@ -112,6 +125,7 @@ export function Splitter({
112
125
  onPointerMove={onPointerMove}
113
126
  onPointerUp={endDrag}
114
127
  onPointerCancel={endDrag}
128
+ onDoubleClick={onDoubleClick}
115
129
  onKeyDown={onKeyDown}
116
130
  className={cn(
117
131
  // A 1px line that reads as a border, with a larger invisible grab area
@@ -8,7 +8,7 @@ export const TooltipContent: FunctionComponent<
8
8
  TooltipPrimitive.Popup.Props & Pick<TooltipPrimitive.Positioner.Props, 'side' | 'sideOffset'>
9
9
  > = ({ className, side = 'top', sideOffset = 6, ...props }) => (
10
10
  <TooltipPrimitive.Portal>
11
- <TooltipPrimitive.Positioner side={side} sideOffset={sideOffset} className='isolate z-60'>
11
+ <TooltipPrimitive.Positioner side={side} sideOffset={sideOffset} className='isolate z-90'>
12
12
  <TooltipPrimitive.Popup
13
13
  data-slot='tooltip-content'
14
14
  className={cn(
package/src/index.ts CHANGED
@@ -42,6 +42,7 @@ export { CopyButton, type CopyButtonProps } from './components/ui/CopyButton.tsx
42
42
  export { Spinner } from './components/ui/Spinner.tsx'
43
43
  export { CodeBlock, type CodeBlockProps } from './components/ui/CodeBlock.tsx'
44
44
  export { Splitter, type SplitterProps } from './components/ui/Splitter.tsx'
45
+ export { Empty, EmptyKey } from './components/ui/Empty.tsx'
45
46
  export { ProgressRing, type ProgressRingProps } from './components/ui/ProgressRing.tsx'
46
47
  // Prompt input (vendored just-marketing/prompt-area, themed to these tokens)
47
48
  export {
@@ -88,6 +89,7 @@ export {
88
89
  useTranscriptDensity,
89
90
  useTranscriptVariant,
90
91
  type TranscriptDensity,
92
+ type TranscriptFont,
91
93
  type TranscriptVariant,
92
94
  } from './components/agent/transcript-variant.tsx'
93
95
  export { Response, type ResponseProps } from './components/agent/Response.tsx'
@@ -136,7 +138,15 @@ export {
136
138
  type SessionListItemProps,
137
139
  type SessionListProps,
138
140
  } from './components/agent/SessionList.tsx'
139
- export { SessionBrowser, type SessionBrowserProps } from './components/agent/SessionBrowser.tsx'
141
+ export {
142
+ SessionBrowser,
143
+ rowShapeClass,
144
+ type SessionBrowserProps,
145
+ } from './components/agent/SessionBrowser.tsx'
146
+ export { SessionStatusIcon } from './components/agent/SessionBrowser.tsx'
147
+ // Lifted out of the VS Code sidebar once the dashboard grew a collapsed rail
148
+ // that needs the same glyph — two copies of a trademark set is one too many.
149
+ export { EngineIcon } from './components/agent/EngineIcon.tsx'
140
150
  export {
141
151
  SessionEmptyState,
142
152
  type SessionEmptyStateProps,
@@ -24,6 +24,15 @@
24
24
  --bg-code: #f5f5f5;
25
25
  --bg-elevated: #ffffffcc;
26
26
 
27
+ /* A list row's hover and selected fills. **Alpha, not a flat colour**, because
28
+ a row sits on whatever its host paints — `bg-sidebar` in the dashboard,
29
+ `--vscode-sideBar-background` in the extension — and a flat value tuned for
30
+ one of those is invisible on the others. `--bg-surface-hover` was exactly
31
+ that mistake: on the dark sidebar (#131313) it lands on #141414, one step
32
+ of 255 away, so the hover state did not exist. */
33
+ --row-hover: rgb(0 0 0 / 0.05);
34
+ --row-active: rgb(0 0 0 / 0.08);
35
+
27
36
  /* ---------- Borders ---------- */
28
37
  --border: #ebebeb;
29
38
  --border-light: #e0e0e0;
@@ -36,12 +45,19 @@
36
45
  --fg-4: #a1a1a1;
37
46
  --fg-disabled: #c9c9c9;
38
47
 
39
- /* ---------- Accent = the inverse of the canvas ---------- */
40
- --accent: #171717;
41
- --accent-hover: #000000;
42
- --accent-dim: #737373;
43
- --accent-bg: #f2f2f2;
44
- --accent-ring: #17171733;
48
+ /* ---------- Accent ----------
49
+ * VS Code blue (`#0078d4`) — the product's primary. It is the *same* hue in
50
+ * both themes rather than the inverse of the canvas: a primary that flips
51
+ * from near-black to near-white is a contrast device, not a brand colour, and
52
+ * WorkerDeck now shares an editor's visual language.
53
+ *
54
+ * Not to be confused with the brand's live green (`docs/assets/BRAND.md`),
55
+ * which stays what it is — a *signal*, not a primary. */
56
+ --accent: #0078d4;
57
+ --accent-hover: #106ebe;
58
+ --accent-dim: #6ca9d8;
59
+ --accent-bg: #eff6fc;
60
+ --accent-ring: #0078d433;
45
61
 
46
62
  /* ---------- Semantic ---------- */
47
63
  --success: #0f7b4f;
@@ -72,7 +88,9 @@
72
88
  --accent-tint: var(--accent-bg);
73
89
  --accent-fg: #ffffff;
74
90
  --warn: var(--warning);
75
- --ring: var(--fg-1);
91
+ /* Focus ring is the accent, as in an editor — the comment below already said
92
+ * "accent-derived"; before the blue it was indistinguishable from fg-1. */
93
+ --ring: var(--accent);
76
94
  }
77
95
 
78
96
  [data-theme='dark'] {
@@ -83,6 +101,9 @@
83
101
  --bg-code: #141414;
84
102
  --bg-elevated: #0a0a0acc;
85
103
 
104
+ --row-hover: rgb(255 255 255 / 0.06);
105
+ --row-active: rgb(255 255 255 / 0.10);
106
+
86
107
  /* ---------- Borders ---------- */
87
108
  --border: #1f1f1f;
88
109
  --border-light: #292929;
@@ -95,12 +116,16 @@
95
116
  --fg-4: #6e6e6e;
96
117
  --fg-disabled: #454545;
97
118
 
98
- /* ---------- Accent = the inverse of the canvas ---------- */
99
- --accent: #ededed;
100
- --accent-hover: #ffffff;
101
- --accent-dim: #8f8f8f;
102
- --accent-bg: #1f1f1f;
103
- --accent-ring: #ffffff3d;
119
+ /* ---------- Accent ----------
120
+ * The same blue as light. `--accent` stays `#0078d4` because it is a *fill*
121
+ * carrying white text (4.6:1) — the brighter `#3794ff` would drop that to
122
+ * 2.9:1. The bright one is the hover and the ring, where nothing sits on top
123
+ * of it and the extra lift is what a dark canvas needs. */
124
+ --accent: #0078d4;
125
+ --accent-hover: #3794ff;
126
+ --accent-dim: #4a7ba0;
127
+ --accent-bg: #12283c;
128
+ --accent-ring: #3794ff4d;
104
129
 
105
130
  /* ---------- Semantic ---------- */
106
131
  --success: #3ecf8e;
@@ -131,9 +156,12 @@
131
156
  --text: var(--fg-1);
132
157
  --text-muted: var(--fg-3);
133
158
  --accent-tint: var(--accent-bg);
134
- --accent-fg: #0a0a0a;
159
+ /* White on the blue fill in both themes — the accent no longer inverts. */
160
+ --accent-fg: #ffffff;
135
161
  --warn: var(--warning);
136
- --ring: var(--fg-1);
162
+ /* Focus ring is the accent, as in an editor — the comment below already said
163
+ * "accent-derived"; before the blue it was indistinguishable from fg-1. */
164
+ --ring: var(--accent);
137
165
  }
138
166
 
139
167
  /* Theme-independent tokens — type tracking, easing, fonts.
@@ -168,6 +196,38 @@
168
196
  --radius: var(--radius-md);
169
197
  }
170
198
 
199
+ /*
200
+ * The agent panel's typeface, from `SessionPanel`'s `transcriptFont` prop.
201
+ *
202
+ * `mono` repoints the **sans** token at the mono stack for that subtree, so the
203
+ * transcript and its composer render monospace and read as part of the terminal
204
+ * rather than as a web app beside one. The mono token itself is left alone: code
205
+ * was already mono, and pointing both at the same stack is what makes the two
206
+ * indistinguishable — which is the point.
207
+ *
208
+ * A subtree rule rather than `:root`, and deliberately: this is the *agent
209
+ * panel's* preference, not the app's. A host's sidebar, dialogs and lists keep
210
+ * their UI font, and nothing outside the panel can pick this up by accident.
211
+ * (VS Code's webview does the same thing one level up, at `html[data-font]`,
212
+ * because there the panel *is* the document.)
213
+ */
214
+ [data-agent-font='mono'] {
215
+ --cw-font-sans: var(--cw-font-mono);
216
+ /* Tailwind's `font-sans` utility reads `--font-sans`, whose `:root` value is
217
+ `var(--cw-font-sans)` — and a `var()` inside a custom property is resolved
218
+ against the element that DECLARED it, not the one that inherits it. So
219
+ repointing `--cw-font-sans` here leaves `--font-sans` still holding the sans
220
+ stack it computed at `:root`. Both have to move. */
221
+ --font-sans: var(--cw-font-mono);
222
+ /* And the actual property, because the ambient typeface is not a token lookup
223
+ at all: `body { font-family: var(--cw-font-sans) }` computed once at `body`,
224
+ and every descendant inherits that *resolved* stack. Nothing under here
225
+ re-reads the token, so the subtree has to be told directly.
226
+ (VS Code's webview gets away with tokens alone only because its override
227
+ sits on `html` — the same element `:root` declares them on.) */
228
+ font-family: var(--cw-font-mono);
229
+ }
230
+
171
231
  /* Drive dark: off the same <html data-theme> the tokens swap on. */
172
232
  @custom-variant dark (&:where([data-theme='dark'], [data-theme='dark'] *));
173
233
 
@@ -188,6 +248,8 @@
188
248
  --color-ring: var(--ring);
189
249
 
190
250
  --color-surface-hover: var(--bg-surface-hover);
251
+ --color-row-hover: var(--row-hover);
252
+ --color-row-active: var(--row-active);
191
253
  /* Named code-bg (not code) so it can't shadow the --text-code font-size token:
192
254
  with a --color-code defined, `text-code` would resolve to the color namespace
193
255
  and paint text in the code *background* color — invisible in both themes. */