@xynogen/pix-pretty 1.7.4 → 1.7.5
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/package.json +1 -1
- package/src/gate-overlay.test.ts +17 -0
- package/src/gate-overlay.ts +13 -5
package/package.json
CHANGED
package/src/gate-overlay.test.ts
CHANGED
|
@@ -117,6 +117,23 @@ describe("showOverlay — confirm mode", () => {
|
|
|
117
117
|
expect(joined).toContain("MY TITLE");
|
|
118
118
|
expect(joined).toContain("body-line-x");
|
|
119
119
|
});
|
|
120
|
+
|
|
121
|
+
test("wraps a long body command instead of truncating it", async () => {
|
|
122
|
+
// A command far wider than any modal width — must survive in full, wrapped.
|
|
123
|
+
const longCmd = `echo ${"pix-gate-installed-or-linked ".repeat(8)}done`;
|
|
124
|
+
let captured: string[] = [];
|
|
125
|
+
await showOverlay(
|
|
126
|
+
makeUI((comp) => {
|
|
127
|
+
captured = comp.render(80);
|
|
128
|
+
comp.handleInput(ENTER);
|
|
129
|
+
}),
|
|
130
|
+
{ mode: "confirm", title: "T", body: [longCmd], timeoutMs: 0 },
|
|
131
|
+
);
|
|
132
|
+
// Every whitespace-delimited token of the command appears somewhere in the
|
|
133
|
+
// frame — nothing was dropped by truncation.
|
|
134
|
+
const joined = captured.join("\n");
|
|
135
|
+
for (const tok of longCmd.split(" ")) expect(joined).toContain(tok);
|
|
136
|
+
});
|
|
120
137
|
});
|
|
121
138
|
|
|
122
139
|
describe("showOverlay — sudo mode", () => {
|
package/src/gate-overlay.ts
CHANGED
|
@@ -14,7 +14,12 @@
|
|
|
14
14
|
* - Single source of truth for the overlay look across pix-gate and pix-sudo.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
Input,
|
|
19
|
+
type SelectItem,
|
|
20
|
+
SelectList,
|
|
21
|
+
wrapTextWithAnsi,
|
|
22
|
+
} from "@earendil-works/pi-tui";
|
|
18
23
|
import { frameLines, modalWidth, selectListTheme } from "./modal-frame.js";
|
|
19
24
|
|
|
20
25
|
// ── Types ─────────────────────────────────────────────────────────────────────
|
|
@@ -139,12 +144,15 @@ function buildLines(opts: {
|
|
|
139
144
|
const inner = width - 4; // CHROME = 2 border + 2 padding
|
|
140
145
|
const lines: string[] = [];
|
|
141
146
|
|
|
142
|
-
// Title
|
|
143
|
-
|
|
147
|
+
// Title — wrap so a long reason/command isn't truncated by the frame.
|
|
148
|
+
for (const t of wrapTextWithAnsi(config.title, inner)) {
|
|
149
|
+
lines.push(theme.fg(accent, theme.bold(t)));
|
|
150
|
+
}
|
|
144
151
|
|
|
145
|
-
// Body
|
|
152
|
+
// Body — wrap each line so long commands wrap instead of getting cut off.
|
|
146
153
|
for (const line of config.body ?? []) {
|
|
147
|
-
|
|
154
|
+
const wrapped = line === "" ? [""] : wrapTextWithAnsi(line, inner);
|
|
155
|
+
for (const w of wrapped) lines.push(theme.fg("text", w));
|
|
148
156
|
}
|
|
149
157
|
|
|
150
158
|
// Divider after title/body
|