@tangle-network/ui 11.16.7 → 11.16.9
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
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @tangle-network/ui
|
|
2
2
|
|
|
3
|
+
## 11.16.9
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 272704e: On a phone, terminal output keeps its own lines and scrolls sideways inside the block, so listing columns stay aligned and hashes and URLs are not split mid-token. A closed command shows at most two lines at every width.
|
|
8
|
+
|
|
9
|
+
## 11.16.8
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- c8ab512: A terminal command whose tool reported an error with nothing recorded about the command shows its "tool reported error" badge in the warning tone and sans type, so it reads as a status rather than metadata. Red stays reserved for a nonzero exit, a timeout or a signal.
|
|
14
|
+
|
|
3
15
|
## 11.16.7
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
|
@@ -19,6 +19,10 @@ export interface CommandPreviewProps {
|
|
|
19
19
|
* dark terminal. It scopes the dark token set onto itself with
|
|
20
20
|
* `data-theme="dark"`, so stderr, the badges and the muted prompt keep the
|
|
21
21
|
* contrast they were designed with on a dark ground, in a light console too.
|
|
22
|
+
*
|
|
23
|
+
* On a phone the output keeps its own lines and scrolls sideways inside the
|
|
24
|
+
* block: wrapped output breaks the columns of a listing and splits hashes
|
|
25
|
+
* and URLs mid-token. The command still wraps between its tokens.
|
|
22
26
|
*/
|
|
23
27
|
export declare const CommandPreview: import("react").MemoExoticComponent<({ part, defaultExpanded, className }: CommandPreviewProps) => import("react").JSX.Element>;
|
|
24
28
|
//#endregion
|
|
@@ -103,7 +103,7 @@ function parseStructured(text) {
|
|
|
103
103
|
/** Exit status as a badge. Red only where the command itself is known to have
|
|
104
104
|
* failed: a nonzero exit, a timeout, or a signal. A tool that reported an
|
|
105
105
|
* error with nothing recorded about the command (no exit code, or exit 0
|
|
106
|
-
* from a runner that failed afterwards) gets
|
|
106
|
+
* from a runner that failed afterwards) gets an amber badge; its error text
|
|
107
107
|
* prints below. A clean run stays quiet green. */
|
|
108
108
|
function ExitBadge({ output, status }) {
|
|
109
109
|
if (status === "running" || status === "pending") return /* @__PURE__ */ jsxs("span", {
|
|
@@ -127,14 +127,14 @@ function ExitBadge({ output, status }) {
|
|
|
127
127
|
tone = "danger";
|
|
128
128
|
} else if (status === "error") {
|
|
129
129
|
label = exitCode === 0 ? "exit 0 · tool reported error" : "tool reported error";
|
|
130
|
-
tone = "
|
|
130
|
+
tone = "warning";
|
|
131
131
|
} else {
|
|
132
132
|
label = exitCode === 0 ? "exit 0" : null;
|
|
133
133
|
tone = "success";
|
|
134
134
|
}
|
|
135
135
|
if (label === null) return null;
|
|
136
136
|
return /* @__PURE__ */ jsx("span", {
|
|
137
|
-
className: cn("inline-flex shrink-0 items-center rounded-full border px-1.5 py-px text-[11px] font-medium tabular-nums", tone === "danger" && "border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]", tone === "success" && "border-transparent bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]", tone === "
|
|
137
|
+
className: cn("inline-flex shrink-0 items-center rounded-full border px-1.5 py-px font-sans text-[11px] font-medium tabular-nums", tone === "danger" && "border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]", tone === "success" && "border-transparent bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]", tone === "warning" && "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]"),
|
|
138
138
|
children: label
|
|
139
139
|
});
|
|
140
140
|
}
|
|
@@ -162,6 +162,10 @@ function CommandText({ command, all }) {
|
|
|
162
162
|
* dark terminal. It scopes the dark token set onto itself with
|
|
163
163
|
* `data-theme="dark"`, so stderr, the badges and the muted prompt keep the
|
|
164
164
|
* contrast they were designed with on a dark ground, in a light console too.
|
|
165
|
+
*
|
|
166
|
+
* On a phone the output keeps its own lines and scrolls sideways inside the
|
|
167
|
+
* block: wrapped output breaks the columns of a listing and splits hashes
|
|
168
|
+
* and URLs mid-token. The command still wraps between its tokens.
|
|
165
169
|
*/
|
|
166
170
|
const CommandPreview = memo(({ part, defaultExpanded = false, className }) => {
|
|
167
171
|
const [expanded, setExpanded] = useState(defaultExpanded);
|
|
@@ -179,7 +183,7 @@ const CommandPreview = memo(({ part, defaultExpanded = false, className }) => {
|
|
|
179
183
|
children: "$"
|
|
180
184
|
}),
|
|
181
185
|
/* @__PURE__ */ jsx("code", {
|
|
182
|
-
className: cn("min-w-0 flex-1 whitespace-pre-wrap [overflow-wrap:anywhere]", expanded ? "" : "
|
|
186
|
+
className: cn("min-w-0 flex-1 whitespace-pre-wrap [overflow-wrap:anywhere]", expanded ? "" : "max-h-8 overflow-hidden"),
|
|
183
187
|
children: /* @__PURE__ */ jsx(CommandText, {
|
|
184
188
|
command,
|
|
185
189
|
all: expanded
|
|
@@ -222,21 +226,21 @@ const CommandPreview = memo(({ part, defaultExpanded = false, className }) => {
|
|
|
222
226
|
tabIndex: 0,
|
|
223
227
|
role: "region",
|
|
224
228
|
"aria-label": "stdout",
|
|
225
|
-
className: cn("max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] px-3 py-2 leading-relaxed", focusRing),
|
|
229
|
+
className: cn("max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] max-sm:whitespace-pre max-sm:[overflow-wrap:normal] px-3 py-2 leading-relaxed", focusRing),
|
|
226
230
|
children: output.stdout
|
|
227
231
|
}) : null,
|
|
228
232
|
output.stderr ? /* @__PURE__ */ jsx("pre", {
|
|
229
233
|
tabIndex: 0,
|
|
230
234
|
role: "region",
|
|
231
235
|
"aria-label": "stderr",
|
|
232
|
-
className: cn("max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] border-t border-white/10 px-3 py-2 leading-relaxed text-[var(--surface-danger-text)]", focusRing),
|
|
236
|
+
className: cn("max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] max-sm:whitespace-pre max-sm:[overflow-wrap:normal] border-t border-white/10 px-3 py-2 leading-relaxed text-[var(--surface-danger-text)]", focusRing),
|
|
233
237
|
children: output.stderr
|
|
234
238
|
}) : null,
|
|
235
239
|
errorText ? /* @__PURE__ */ jsx("pre", {
|
|
236
240
|
tabIndex: 0,
|
|
237
241
|
role: "region",
|
|
238
242
|
"aria-label": "error",
|
|
239
|
-
className: cn("max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] border-t border-white/10 px-3 py-2 leading-relaxed text-[var(--surface-danger-text)]", focusRing),
|
|
243
|
+
className: cn("max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] max-sm:whitespace-pre max-sm:[overflow-wrap:normal] border-t border-white/10 px-3 py-2 leading-relaxed text-[var(--surface-danger-text)]", focusRing),
|
|
240
244
|
children: errorText
|
|
241
245
|
}) : null
|
|
242
246
|
]
|
package/package.json
CHANGED
|
@@ -13,10 +13,10 @@ function part(state: Partial<ToolPart["state"]>): ToolPart {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
describe("CommandPreview", () => {
|
|
16
|
-
it("shows
|
|
16
|
+
it("shows an amber badge, not a red exit, when a tool errored without an exit code", () => {
|
|
17
17
|
render(<CommandPreview part={part({ status: "error", output: "warning: x" })} />);
|
|
18
18
|
const badge = screen.getByText("tool reported error");
|
|
19
|
-
expect(badge.className).toContain("surface-
|
|
19
|
+
expect(badge.className).toContain("surface-warning");
|
|
20
20
|
expect(badge.className).not.toContain("surface-danger");
|
|
21
21
|
expect(screen.queryByText("error")).toBeNull();
|
|
22
22
|
});
|
|
@@ -52,13 +52,13 @@ describe("CommandPreview", () => {
|
|
|
52
52
|
expect(screen.getByText("timed out").className).toContain("surface-danger");
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
it("keeps a runner error after a clean exit
|
|
55
|
+
it("keeps a runner error after a clean exit amber, not red", () => {
|
|
56
56
|
render(
|
|
57
57
|
<CommandPreview
|
|
58
58
|
part={part({ status: "error", output: { stdout: "ok", stderr: "", exitCode: 0 } })}
|
|
59
59
|
/>,
|
|
60
60
|
);
|
|
61
|
-
expect(screen.getByText("exit 0 · tool reported error").className).toContain("surface-
|
|
61
|
+
expect(screen.getByText("exit 0 · tool reported error").className).toContain("surface-warning");
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
it("is a quiet row until opened, then a dark terminal", () => {
|
|
@@ -128,7 +128,7 @@ function parseStructured(text: string): CommandOutput | undefined {
|
|
|
128
128
|
/** Exit status as a badge. Red only where the command itself is known to have
|
|
129
129
|
* failed: a nonzero exit, a timeout, or a signal. A tool that reported an
|
|
130
130
|
* error with nothing recorded about the command (no exit code, or exit 0
|
|
131
|
-
* from a runner that failed afterwards) gets
|
|
131
|
+
* from a runner that failed afterwards) gets an amber badge; its error text
|
|
132
132
|
* prints below. A clean run stays quiet green. */
|
|
133
133
|
function ExitBadge({
|
|
134
134
|
output,
|
|
@@ -147,7 +147,7 @@ function ExitBadge({
|
|
|
147
147
|
}
|
|
148
148
|
const { exitCode, timedOut, signal } = output;
|
|
149
149
|
let label: string | null;
|
|
150
|
-
let tone: "danger" | "success" | "
|
|
150
|
+
let tone: "danger" | "success" | "warning";
|
|
151
151
|
if (timedOut) {
|
|
152
152
|
label = "timed out";
|
|
153
153
|
tone = "danger";
|
|
@@ -161,7 +161,7 @@ function ExitBadge({
|
|
|
161
161
|
// Say what is known: the tool reported an error. Nothing recorded says
|
|
162
162
|
// the command itself failed.
|
|
163
163
|
label = exitCode === 0 ? "exit 0 · tool reported error" : "tool reported error";
|
|
164
|
-
tone = "
|
|
164
|
+
tone = "warning";
|
|
165
165
|
} else {
|
|
166
166
|
label = exitCode === 0 ? "exit 0" : null;
|
|
167
167
|
tone = "success";
|
|
@@ -171,13 +171,15 @@ function ExitBadge({
|
|
|
171
171
|
<span
|
|
172
172
|
className={cn(
|
|
173
173
|
// Every badge has a border, so mixed rows keep one height.
|
|
174
|
-
"inline-flex shrink-0 items-center rounded-full border px-1.5 py-px text-[11px] font-medium tabular-nums",
|
|
174
|
+
"inline-flex shrink-0 items-center rounded-full border px-1.5 py-px font-sans text-[11px] font-medium tabular-nums",
|
|
175
175
|
tone === "danger" &&
|
|
176
176
|
"border-transparent bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
|
|
177
177
|
tone === "success" &&
|
|
178
178
|
"border-transparent bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
// A reported error with nothing recorded about the command deserves
|
|
180
|
+
// attention, but it is not a failed command: amber, not red.
|
|
181
|
+
tone === "warning" &&
|
|
182
|
+
"border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]",
|
|
181
183
|
)}
|
|
182
184
|
>
|
|
183
185
|
{label}
|
|
@@ -225,6 +227,10 @@ function CommandText({ command, all }: { command: string; all: boolean }) {
|
|
|
225
227
|
* dark terminal. It scopes the dark token set onto itself with
|
|
226
228
|
* `data-theme="dark"`, so stderr, the badges and the muted prompt keep the
|
|
227
229
|
* contrast they were designed with on a dark ground, in a light console too.
|
|
230
|
+
*
|
|
231
|
+
* On a phone the output keeps its own lines and scrolls sideways inside the
|
|
232
|
+
* block: wrapped output breaks the columns of a listing and splits hashes
|
|
233
|
+
* and URLs mid-token. The command still wraps between its tokens.
|
|
228
234
|
*/
|
|
229
235
|
export const CommandPreview = memo(
|
|
230
236
|
({ part, defaultExpanded = false, className }: CommandPreviewProps) => {
|
|
@@ -256,7 +262,10 @@ export const CommandPreview = memo(
|
|
|
256
262
|
<code
|
|
257
263
|
className={cn(
|
|
258
264
|
"min-w-0 flex-1 whitespace-pre-wrap [overflow-wrap:anywhere]",
|
|
259
|
-
|
|
265
|
+
// Closed, two lines of the command. A height cap, not
|
|
266
|
+
// line-clamp: each token is an inline box, which line-clamp
|
|
267
|
+
// does not count, so a phone showed three lines and more.
|
|
268
|
+
expanded ? "" : "max-h-8 overflow-hidden",
|
|
260
269
|
)}
|
|
261
270
|
>
|
|
262
271
|
<CommandText command={command} all={expanded} />
|
|
@@ -317,7 +326,7 @@ export const CommandPreview = memo(
|
|
|
317
326
|
role="region"
|
|
318
327
|
aria-label="stdout"
|
|
319
328
|
className={cn(
|
|
320
|
-
"max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] px-3 py-2 leading-relaxed",
|
|
329
|
+
"max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] max-sm:whitespace-pre max-sm:[overflow-wrap:normal] px-3 py-2 leading-relaxed",
|
|
321
330
|
focusRing,
|
|
322
331
|
)}
|
|
323
332
|
>
|
|
@@ -330,7 +339,7 @@ export const CommandPreview = memo(
|
|
|
330
339
|
role="region"
|
|
331
340
|
aria-label="stderr"
|
|
332
341
|
className={cn(
|
|
333
|
-
"max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] border-t border-white/10 px-3 py-2 leading-relaxed text-[var(--surface-danger-text)]",
|
|
342
|
+
"max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] max-sm:whitespace-pre max-sm:[overflow-wrap:normal] border-t border-white/10 px-3 py-2 leading-relaxed text-[var(--surface-danger-text)]",
|
|
334
343
|
focusRing,
|
|
335
344
|
)}
|
|
336
345
|
>
|
|
@@ -343,7 +352,7 @@ export const CommandPreview = memo(
|
|
|
343
352
|
role="region"
|
|
344
353
|
aria-label="error"
|
|
345
354
|
className={cn(
|
|
346
|
-
"max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] border-t border-white/10 px-3 py-2 leading-relaxed text-[var(--surface-danger-text)]",
|
|
355
|
+
"max-h-80 overflow-auto whitespace-pre-wrap [overflow-wrap:anywhere] max-sm:whitespace-pre max-sm:[overflow-wrap:normal] border-t border-white/10 px-3 py-2 leading-relaxed text-[var(--surface-danger-text)]",
|
|
347
356
|
focusRing,
|
|
348
357
|
)}
|
|
349
358
|
>
|