@mcp-b/react-components 0.5.0 → 0.5.2

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.
@@ -243,7 +243,7 @@ function WorkspaceExplorer({ workspace, className, title = "Workspace", actions,
243
243
  children: [showFileView ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Button, {
244
244
  variant: "ghost",
245
245
  color: "neutral",
246
- size: "sm",
246
+ size: "xs",
247
247
  onClick: () => setView("tree"),
248
248
  "aria-label": "Back to files",
249
249
  children: /* @__PURE__ */ jsx(ArrowLeftIcon, { "aria-hidden": "true" })
@@ -262,7 +262,7 @@ function WorkspaceExplorer({ workspace, className, title = "Workspace", actions,
262
262
  children: [actions, /* @__PURE__ */ jsx(Button, {
263
263
  variant: "ghost",
264
264
  color: "neutral",
265
- size: "sm",
265
+ size: "xs",
266
266
  onClick: refresh,
267
267
  disabled: isLoading,
268
268
  "aria-label": "Refresh workspace",
@@ -82,9 +82,15 @@
82
82
  counter-reset: line;
83
83
  }
84
84
 
85
+ /* The plain fallback emits .line spans with no newline text nodes, so it
86
+ needs block to break lines. Shiki output keeps its "\n" nodes — block
87
+ there gives every newline its own empty line box (double-spaced code). */
88
+ .code-block__content--numbered:is(pre) > code .line {
89
+ display: block;
90
+ }
91
+
85
92
  .code-block__content--numbered:is(pre) > code .line,
86
93
  .code-block__content--numbered pre code .line {
87
- display: block;
88
94
  counter-increment: line;
89
95
  }
90
96
 
@@ -55,6 +55,8 @@
55
55
  @import "./tooltip.css" layer(components);
56
56
 
57
57
  /* AI Chat & Code Components */
58
+ @import "streamdown/styles.css" layer(components);
59
+ @import "./streamdown.css" layer(components);
58
60
  @import "./artifact.css" layer(components);
59
61
  @import "./browser-live-view.css" layer(components);
60
62
  @import "./browser-replay.css" layer(components);
@@ -57,6 +57,11 @@
57
57
  overflow: auto;
58
58
  }
59
59
 
60
+ .message__response {
61
+ min-inline-size: 0;
62
+ max-inline-size: 100%;
63
+ }
64
+
60
65
  .message__attachment {
61
66
  display: inline-flex;
62
67
  align-items: center;
@@ -0,0 +1,381 @@
1
+ /*
2
+ * Streamdown renders Tailwind utility class names we don't compile; its
3
+ * stable `data-streamdown` attributes are the supported styling hook for
4
+ * non-Tailwind consumers. This sheet restyles that output with our tokens.
5
+ * Note: table-fullscreen and link-safety-modal portal to <body>, so nothing
6
+ * here may assume a .message__response ancestor.
7
+ */
8
+
9
+ /* ---- Inline elements ---- */
10
+
11
+ /* Streamdown emits <span data-streamdown="strong">, not <strong> — without
12
+ this rule bold text renders as plain text. */
13
+ [data-streamdown="strong"] {
14
+ font-weight: var(--sigvelo-font-weight-semibold);
15
+ }
16
+
17
+ [data-streamdown="link"] {
18
+ color: var(--sigvelo-color-primary-text);
19
+ font-weight: var(--sigvelo-font-weight-semibold);
20
+ text-decoration: underline;
21
+ overflow-wrap: anywhere;
22
+ }
23
+
24
+ /* Links render as <button> when link safety is enabled. */
25
+ button[data-streamdown="link"] {
26
+ appearance: none;
27
+ border: 0;
28
+ padding: 0;
29
+ background: transparent;
30
+ cursor: pointer;
31
+ font: inherit;
32
+ text-align: start;
33
+ }
34
+
35
+ [data-streamdown="inline-code"] {
36
+ padding-block: 0.0625rem;
37
+ padding-inline: 0.25rem;
38
+ border-radius: var(--sigvelo-radius-xs);
39
+ background-color: var(--sigvelo-color-neutral-bg-subtle);
40
+ font-family: var(--sigvelo-font-mono);
41
+ font-size: 0.875em;
42
+ }
43
+
44
+ [data-streamdown="superscript"],
45
+ [data-streamdown="subscript"] {
46
+ font-size: 0.75em;
47
+ }
48
+
49
+ /* ---- Block typography ---- */
50
+
51
+ /* Chat-scale headings: markdown headings inside a message shouldn't shout. */
52
+ [data-streamdown="heading-1"],
53
+ [data-streamdown="heading-2"],
54
+ [data-streamdown="heading-3"],
55
+ [data-streamdown="heading-4"],
56
+ [data-streamdown="heading-5"],
57
+ [data-streamdown="heading-6"] {
58
+ margin-block: 0.75rem 0.375rem;
59
+ font-size: 1.125em;
60
+ font-weight: var(--sigvelo-font-weight-semibold);
61
+ line-height: 1.25;
62
+ }
63
+
64
+ [data-streamdown="heading-1"],
65
+ [data-streamdown="heading-2"] {
66
+ font-size: 1.25em;
67
+ }
68
+
69
+ [data-streamdown="blockquote"] {
70
+ margin-block: 0.5rem;
71
+ padding-inline-start: 0.75rem;
72
+ border-inline-start: 2px solid var(--sigvelo-color-neutral-border-subtle);
73
+ color: var(--sigvelo-color-text-muted);
74
+ }
75
+
76
+ [data-streamdown="ordered-list"],
77
+ [data-streamdown="unordered-list"] {
78
+ margin-block: 0.25rem;
79
+ padding-inline-start: 1.25rem;
80
+ }
81
+
82
+ [data-streamdown="ordered-list"] {
83
+ list-style: decimal;
84
+ }
85
+
86
+ [data-streamdown="unordered-list"] {
87
+ list-style: disc;
88
+ }
89
+
90
+ [data-streamdown="list-item"] {
91
+ padding-block: 0.125rem;
92
+ }
93
+
94
+ [data-streamdown="list-item"] > p {
95
+ display: inline;
96
+ }
97
+
98
+ [data-streamdown="horizontal-rule"] {
99
+ margin-block: 1rem;
100
+ border: 0;
101
+ border-block-start: 1px solid var(--sigvelo-color-neutral-border-subtle);
102
+ }
103
+
104
+ [data-streamdown="image-wrapper"] {
105
+ display: inline-block;
106
+ margin-block: 0.5rem;
107
+ }
108
+
109
+ [data-streamdown="image"] {
110
+ max-width: 100%;
111
+ border-radius: var(--sigvelo-radius-md);
112
+ }
113
+
114
+ [data-streamdown="image-fallback"] {
115
+ font-size: var(--sigvelo-text-xs);
116
+ font-style: italic;
117
+ color: var(--sigvelo-color-text-muted);
118
+ }
119
+
120
+ /* ---- Shared chrome: action buttons ---- */
121
+
122
+ :is(
123
+ [data-streamdown="code-block-actions"],
124
+ [data-streamdown="mermaid-block-actions"],
125
+ [data-streamdown="table-wrapper"],
126
+ [data-streamdown="table-fullscreen"]
127
+ )
128
+ button {
129
+ appearance: none;
130
+ display: inline-flex;
131
+ align-items: center;
132
+ justify-content: center;
133
+ padding: 0.25rem;
134
+ border: 0;
135
+ border-radius: var(--sigvelo-radius-sm);
136
+ background: transparent;
137
+ color: var(--sigvelo-color-text-muted);
138
+ cursor: pointer;
139
+ transition: color 120ms ease;
140
+ }
141
+
142
+ :is(
143
+ [data-streamdown="code-block-actions"],
144
+ [data-streamdown="mermaid-block-actions"],
145
+ [data-streamdown="table-wrapper"],
146
+ [data-streamdown="table-fullscreen"]
147
+ )
148
+ button:hover {
149
+ color: var(--sigvelo-color-text);
150
+ }
151
+
152
+ :is(
153
+ [data-streamdown="code-block-actions"],
154
+ [data-streamdown="mermaid-block-actions"],
155
+ [data-streamdown="table-wrapper"]
156
+ )
157
+ button:disabled {
158
+ cursor: not-allowed;
159
+ opacity: 0.5;
160
+ }
161
+
162
+ /* ---- Code blocks (and mermaid, same shell) ---- */
163
+
164
+ /* Fill-based containment: no perimeter border, matching .code-block. */
165
+ [data-streamdown="code-block"],
166
+ [data-streamdown="mermaid-block"] {
167
+ display: flex;
168
+ flex-direction: column;
169
+ gap: 0.25rem;
170
+ width: 100%;
171
+ margin-block: 0.5rem;
172
+ padding: 0.375rem;
173
+ border-radius: var(--sigvelo-radius-lg);
174
+ background-color: var(--sigvelo-color-neutral-bg-subtle);
175
+ }
176
+
177
+ [data-streamdown="code-block-header"] {
178
+ display: flex;
179
+ align-items: center;
180
+ min-height: 1.5rem;
181
+ padding-inline: 0.5rem;
182
+ font-family: var(--sigvelo-font-mono);
183
+ font-size: var(--sigvelo-text-xs);
184
+ text-transform: lowercase;
185
+ color: var(--sigvelo-color-text-muted);
186
+ }
187
+
188
+ /* Streamdown wraps the action bar in an anonymous sticky div that overlays
189
+ the header row (header 1.5rem + gap 0.25rem). */
190
+ :is([data-streamdown="code-block"], [data-streamdown="mermaid-block"])
191
+ > div:has(> [data-streamdown$="-block-actions"]) {
192
+ position: sticky;
193
+ top: 0.25rem;
194
+ z-index: 1;
195
+ display: flex;
196
+ align-items: center;
197
+ justify-content: flex-end;
198
+ height: 1.5rem;
199
+ margin-block-start: -1.75rem;
200
+ pointer-events: none;
201
+ }
202
+
203
+ [data-streamdown="code-block-actions"],
204
+ [data-streamdown="mermaid-block-actions"] {
205
+ display: flex;
206
+ flex-shrink: 0;
207
+ align-items: center;
208
+ gap: 0.25rem;
209
+ pointer-events: auto;
210
+ border-radius: var(--sigvelo-radius-md);
211
+ background-color: var(--sigvelo-color-neutral-bg-subtle);
212
+ }
213
+
214
+ [data-streamdown="code-block-body"] {
215
+ overflow-x: auto;
216
+ border-radius: var(--sigvelo-radius-md);
217
+ }
218
+
219
+ [data-streamdown="code-block-body"] pre {
220
+ margin: 0;
221
+ padding-block: 0.5rem;
222
+ padding-inline: 0.5rem;
223
+ background-color: transparent;
224
+ font-family: var(--sigvelo-font-mono);
225
+ font-size: 0.8125rem;
226
+ line-height: 1.55;
227
+ }
228
+
229
+ /* The code plugin emits one <span class="block"> per line with no newline
230
+ text nodes — without this, highlighted code collapses onto one line. */
231
+ [data-streamdown="code-block-body"] code > span {
232
+ display: block;
233
+ }
234
+
235
+ [data-streamdown="mermaid"] {
236
+ width: 100%;
237
+ }
238
+
239
+ /* ---- Tables ---- */
240
+
241
+ [data-streamdown="table-wrapper"] {
242
+ display: flex;
243
+ flex-direction: column;
244
+ gap: 0.25rem;
245
+ margin-block: 0.5rem;
246
+ min-inline-size: 0;
247
+ max-inline-size: 100%;
248
+ }
249
+
250
+ /* Anonymous action row above the table. */
251
+ [data-streamdown="table-wrapper"] > div:not(:has([data-streamdown="table"])) {
252
+ display: flex;
253
+ align-items: center;
254
+ justify-content: flex-end;
255
+ gap: 0.25rem;
256
+ }
257
+
258
+ /* Anonymous scroll container around the table. */
259
+ [data-streamdown="table-wrapper"] > div:has(> [data-streamdown="table"]) {
260
+ overflow-x: auto;
261
+ max-inline-size: 100%;
262
+ }
263
+
264
+ [data-streamdown="table"] {
265
+ width: 100%;
266
+ border-collapse: collapse;
267
+ font-size: var(--sigvelo-text-sm);
268
+ }
269
+
270
+ [data-streamdown="table-header-cell"],
271
+ [data-streamdown="table-cell"] {
272
+ padding-block: 0.25rem;
273
+ padding-inline: 0.5rem;
274
+ border-block-end: 1px solid var(--sigvelo-color-neutral-border-subtle);
275
+ text-align: start;
276
+ vertical-align: top;
277
+ overflow-wrap: anywhere;
278
+ }
279
+
280
+ [data-streamdown="table-header-cell"] {
281
+ font-weight: var(--sigvelo-font-weight-semibold);
282
+ white-space: nowrap;
283
+ }
284
+
285
+ /* Fullscreen table view portals to <body>; its single child wraps a
286
+ toolbar row and a scrollable table area. */
287
+ [data-streamdown="table-fullscreen"] {
288
+ position: fixed;
289
+ inset: 0;
290
+ z-index: 50;
291
+ background-color: var(--sigvelo-color-surface);
292
+ }
293
+
294
+ [data-streamdown="table-fullscreen"] > div {
295
+ display: flex;
296
+ flex-direction: column;
297
+ height: 100%;
298
+ }
299
+
300
+ [data-streamdown="table-fullscreen"] > div > div:first-child {
301
+ display: flex;
302
+ align-items: center;
303
+ justify-content: flex-end;
304
+ gap: 0.25rem;
305
+ padding: 0.75rem;
306
+ }
307
+
308
+ [data-streamdown="table-fullscreen"] > div > div:last-child {
309
+ flex: 1;
310
+ overflow: auto;
311
+ padding-block: 0 1rem;
312
+ padding-inline: 1rem;
313
+ }
314
+
315
+ [data-streamdown="table-fullscreen"] thead {
316
+ position: sticky;
317
+ top: 0;
318
+ z-index: 1;
319
+ background-color: var(--sigvelo-color-surface);
320
+ }
321
+
322
+ /* ---- Copy/download format dropdowns ----
323
+ * The menus have no data attributes — only literal `relative`/`absolute`
324
+ * class names — so scope tightly to streamdown containers. */
325
+
326
+ :is(
327
+ [data-streamdown="table-wrapper"],
328
+ [data-streamdown="table-fullscreen"],
329
+ [data-streamdown="mermaid-block-actions"]
330
+ )
331
+ .relative {
332
+ position: relative;
333
+ display: inline-flex;
334
+ }
335
+
336
+ :is(
337
+ [data-streamdown="table-wrapper"],
338
+ [data-streamdown="table-fullscreen"],
339
+ [data-streamdown="mermaid-block-actions"]
340
+ )
341
+ .absolute {
342
+ position: absolute;
343
+ top: 100%;
344
+ right: 0;
345
+ z-index: 20;
346
+ display: flex;
347
+ flex-direction: column;
348
+ min-width: 7.5rem;
349
+ margin-block-start: 0.25rem;
350
+ overflow: hidden;
351
+ border-radius: var(--sigvelo-radius-md);
352
+ border: 1px solid var(--sigvelo-color-neutral-border-subtle);
353
+ background-color: var(--sigvelo-color-surface);
354
+ box-shadow: var(--sigvelo-shadow-md);
355
+ }
356
+
357
+ :is(
358
+ [data-streamdown="table-wrapper"],
359
+ [data-streamdown="table-fullscreen"],
360
+ [data-streamdown="mermaid-block-actions"]
361
+ )
362
+ .absolute
363
+ > button {
364
+ justify-content: flex-start;
365
+ width: 100%;
366
+ padding-block: 0.375rem;
367
+ padding-inline: 0.75rem;
368
+ border-radius: 0;
369
+ font-size: var(--sigvelo-text-sm);
370
+ color: var(--sigvelo-color-text);
371
+ }
372
+
373
+ :is(
374
+ [data-streamdown="table-wrapper"],
375
+ [data-streamdown="table-fullscreen"],
376
+ [data-streamdown="mermaid-block-actions"]
377
+ )
378
+ .absolute
379
+ > button:hover {
380
+ background-color: var(--sigvelo-color-neutral-bg-subtle);
381
+ }
@@ -7,11 +7,13 @@
7
7
  color: var(--sigvelo-color-text);
8
8
  }
9
9
 
10
+ /* Compact masthead, sized to the pre-design-system nanites workbench. */
10
11
  .workspace-explorer__header {
11
12
  display: flex;
12
13
  align-items: center;
13
14
  gap: 0.5rem;
14
- padding: 0.5rem 0.75rem;
15
+ min-height: 2.5rem;
16
+ padding: 0.25rem 0.625rem;
15
17
  border-block-end: var(--sigvelo-border-style) var(--sigvelo-border-width)
16
18
  var(--sigvelo-color-neutral-border-subtle);
17
19
  }
@@ -47,10 +49,10 @@
47
49
  .workspace-explorer__body {
48
50
  display: flex;
49
51
  flex-direction: column;
50
- gap: 0.5rem;
52
+ gap: 0.375rem;
51
53
  min-height: 0;
52
54
  flex: 1;
53
- padding: 0.5rem 0.75rem;
55
+ padding: 0.375rem 0.625rem;
54
56
  overflow: auto;
55
57
  }
56
58
 
@@ -58,6 +60,7 @@
58
60
  display: flex;
59
61
  align-items: center;
60
62
  gap: 0.375rem;
63
+ min-height: 2rem;
61
64
  padding-inline: 0.5rem;
62
65
  color: var(--sigvelo-color-text-muted);
63
66
  border: var(--sigvelo-border-style) var(--sigvelo-border-width)
@@ -72,12 +75,12 @@
72
75
  .workspace-explorer__filter input {
73
76
  flex: 1;
74
77
  min-width: 0;
75
- padding-block: 0.375rem;
78
+ padding-block: 0.25rem;
76
79
  border: none;
77
80
  background: transparent;
78
81
  color: var(--sigvelo-color-text);
79
82
  font-family: inherit;
80
- font-size: 0.8125rem;
83
+ font-size: 0.75rem;
81
84
  outline: none;
82
85
  }
83
86
 
@@ -87,6 +90,20 @@
87
90
  padding-block: 0;
88
91
  }
89
92
 
93
+ /* Rows hug their label — hover reads as a pill around the name, not a
94
+ full-width bar (carried over from the original nanites workbench). */
95
+ .workspace-explorer__tree .file-tree__node {
96
+ inline-size: fit-content;
97
+ max-inline-size: 100%;
98
+ gap: 0.5rem;
99
+ padding-block: 0.3125rem;
100
+ border-radius: var(--sigvelo-radius-md);
101
+ }
102
+
103
+ .workspace-explorer__tree .file-tree__name {
104
+ line-height: 1.4;
105
+ }
106
+
90
107
  .workspace-explorer__empty {
91
108
  display: flex;
92
109
  flex: 1;
@@ -98,11 +115,22 @@
98
115
  text-align: center;
99
116
  }
100
117
 
118
+ /* File preview fills the pane flush — no card-in-pane inset. */
101
119
  .workspace-explorer__file {
102
120
  display: flex;
103
121
  flex-direction: column;
104
122
  min-height: 0;
105
123
  flex: 1;
106
124
  overflow: auto;
107
- padding: 0.5rem 0.75rem;
125
+ }
126
+
127
+ .workspace-explorer__code {
128
+ flex: 1;
129
+ border-radius: 0;
130
+ }
131
+
132
+ /* File contents read at gutter scale, like the original workbench preview. */
133
+ .workspace-explorer__code :is(.code-block__content, .code-block__content pre) {
134
+ font-size: 0.75rem;
135
+ line-height: 1.6;
108
136
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcp-b/react-components",
3
- "version": "0.5.0",
3
+ "version": "0.5.2",
4
4
  "description": "MCP-B React components built on Base UI and shared design tokens, including Cloudflare Think chat primitives.",
5
5
  "homepage": "https://design-system.sigvelo.com",
6
6
  "bugs": {
@@ -49,7 +49,7 @@
49
49
  "anser": "^2.3.5",
50
50
  "shiki": "^3.23.0",
51
51
  "streamdown": "^2.5.0",
52
- "@mcp-b/design-tokens": "0.5.0"
52
+ "@mcp-b/design-tokens": "0.5.2"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@ai-sdk/react": "^3.0.194",