Skip to content

Commit 6ae8f55

Browse files
authored
fix(init): preserve welcome banner alignment (#1255)
## Summary The `sentry init` welcome screen centered every block-art row independently. Because the top row is narrower than the rest, the arch shifted to the right relative to the wordmark. Center the banner using its widest row so the artwork keeps its authored indentation while the responsive variants remain unchanged. Add an Ink regression test that verifies every row position and the centered banner origin. ## Test plan - [x] `pnpm run lint` - [x] `pnpm vitest run test/lib/init/ui/ink-app.snapshot.test.tsx --coverage.enabled=false` - [x] `pnpm run typecheck` - [x] `git diff --check`
1 parent 9fa96f6 commit 6ae8f55

2 files changed

Lines changed: 32 additions & 1 deletion

File tree

src/lib/init/ui/ink-app.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,13 +625,15 @@ function IntroScreen({
625625
bannerRows.length === 0 || bannerLinesWidth(bannerRows) <= bodyWidth
626626
? bannerRows
627627
: bannerLinesForWidth(bodyWidth);
628+
// Center the banner as one unit; centering rows separately shifts shorter rows.
629+
const bannerWidth = bannerLinesWidth(banner);
628630

629631
return (
630632
<Box alignItems="center" flexDirection="column" width={bodyWidth}>
631633
<Box
632-
alignItems="center"
633634
flexDirection="column"
634635
marginBottom={welcomePrompt ? 2 : 1}
636+
width={bannerWidth}
635637
>
636638
{banner.map((row, i) => (
637639
// biome-ignore lint/suspicious/noArrayIndexKey: positional banner rows

test/lib/init/ui/ink-app.snapshot.test.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ import { setTimeout as sleep } from "node:timers/promises";
1414
import { render } from "ink";
1515
import { createElement } from "react";
1616
import { describe, expect, test } from "vitest";
17+
import {
18+
bannerLinesWidth,
19+
FULL_BANNER_LINES,
20+
} from "../../../../src/lib/banner.js";
1721
import {
1822
App,
1923
formatFeedbackBanner,
@@ -307,6 +311,31 @@ describe("Ink App snapshot", () => {
307311
expect(hasForcedWhiteForeground(withoutFeedbackBanner(frame))).toBe(false);
308312
});
309313

314+
test("welcome banner preserves row alignment while centering the art", async () => {
315+
const store = new WizardStore({ bannerRows: FULL_BANNER_LINES });
316+
setWelcomePrompt(store);
317+
318+
const terminalColumns = 120;
319+
const frame = stripAnsi(
320+
(await renderApp(store, terminalColumns)).allOutput()
321+
);
322+
const lines = frame.split(LINE_SPLIT_RE);
323+
const bannerOrigin = Math.floor(
324+
(terminalColumns - bannerLinesWidth(FULL_BANNER_LINES)) / 2
325+
);
326+
327+
for (const { content } of FULL_BANNER_LINES) {
328+
const visibleContent = content.trimStart();
329+
const leadingSpaces = content.length - visibleContent.length;
330+
const renderedRow = lines.find((line) => line.includes(visibleContent));
331+
332+
expect(renderedRow).toBeDefined();
333+
expect(renderedRow?.indexOf(visibleContent)).toBe(
334+
bannerOrigin + leadingSpaces
335+
);
336+
}
337+
});
338+
310339
test("intro banner shrinks to fit narrow terminals (never wraps)", async () => {
311340
// A banner wider than the narrow terminal; distinctive marker so we can tell
312341
// whether it was rendered verbatim or replaced by a fitting variant.

0 commit comments

Comments
 (0)