Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions packages/cli/src/ui/components/AskUserDialog.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1581,4 +1581,71 @@ describe('AskUserDialog', () => {
expect(frame).toContain('1. Option 1');
});
});

it('indents multi-line descriptions correctly', async () => {
const questions: Question[] = [
{
question: 'Single choice?',
header: 'Indent Test',
type: QuestionType.CHOICE,
options: [
{
label: 'Option 1',
description:
'This is a very long description that is expected to wrap onto multiple lines in a narrow terminal. We want to ensure that all lines are correctly indented.',
},
],
multiSelect: false,
},
];

const { lastFrame, waitUntilReady } = await renderWithProviders(
<AskUserDialog
questions={questions}
onSubmit={vi.fn()}
onCancel={vi.fn()}
width={40} // Narrow width to force wrapping
/>,
{ width: 40 },
);

await waitFor(async () => {
await waitUntilReady();
// Snapshot will capture the visual alignment
expect(lastFrame()).toMatchSnapshot();
});
});

it('indents multi-line descriptions correctly in multi-select mode', async () => {
const questions: Question[] = [
{
question: 'Multi-select?',
header: 'Indent Test',
type: QuestionType.CHOICE,
options: [
{
label: 'Option 1',
description:
'This is a very long description that is expected to wrap onto multiple lines in a narrow terminal. We want to ensure that all lines are correctly indented even with checkboxes.',
},
],
multiSelect: true,
},
];

const { lastFrame, waitUntilReady } = await renderWithProviders(
<AskUserDialog
questions={questions}
onSubmit={vi.fn()}
onCancel={vi.fn()}
width={40} // Narrow width to force wrapping
/>,
{ width: 40 },
);

await waitFor(async () => {
await waitUntilReady();
expect(lastFrame()).toMatchSnapshot();
});
});
});
16 changes: 9 additions & 7 deletions packages/cli/src/ui/components/AskUserDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1004,13 +1004,15 @@ const ChoiceQuestionView: React.FC<ChoiceQuestionViewProps> = ({
)}
</Box>
{optionItem.description && (
<Text color={theme.text.secondary} wrap="wrap">
{' '}
<RenderInline
text={optionItem.description}
defaultColor={theme.text.secondary}
/>
</Text>
// Padding aligns with option label: 4 for multi-select (checkbox + space), 1 for single-select
<Box paddingLeft={showCheck ? 4 : 1}>
<Text color={theme.text.secondary} wrap="wrap">
<RenderInline
text={optionItem.description}
defaultColor={theme.text.secondary}
/>
</Text>
</Box>
)}
</Box>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,42 @@ Enter to select · ↑/↓ to navigate · Esc to cancel
"
`;

exports[`AskUserDialog > indents multi-line descriptions correctly 1`] = `
"Single choice?

● 1. Option 1
This is a very long description
that is expected to wrap onto
multiple lines in a narrow
terminal. We want to ensure that
all lines are correctly indented.
2. Enter a custom value

Enter to select · ↑/↓ to navigate · Esc
to cancel
"
`;

exports[`AskUserDialog > indents multi-line descriptions correctly in multi-select mode 1`] = `
"Multi-select?
(Select all that apply)

● 1. [ ] Option 1
This is a very long description
that is expected to wrap onto
multiple lines in a narrow
terminal. We want to ensure
that all lines are correctly
indented even with checkboxes.
2. [ ] Enter a custom value
Done
Finish selection

Enter to select · ↑/↓ to navigate · Esc
to cancel
"
`;

exports[`AskUserDialog > renders question and options 1`] = `
"Which authentication method should we use?

Expand Down Expand Up @@ -188,7 +224,7 @@ exports[`AskUserDialog > verifies "All of the above" visual state with snapshot
1. [x] TypeScript
2. [x] ESLint
● 3. [x] All of the above
Select all options
Select all options
4. [ ] Enter a custom value
Done
Finish selection
Expand Down
Loading