feat: add double-click to expand/collapse large paste placeholders (#17471)

This commit is contained in:
Jack Wotherspoon
2026-01-26 21:59:09 -05:00
committed by GitHub
parent 5cf06503c8
commit a79051d9f8
11 changed files with 1024 additions and 61 deletions
@@ -9,7 +9,7 @@ import {
createMockSettings,
} from '../../test-utils/render.js';
import { waitFor } from '../../test-utils/async.js';
import { act } from 'react';
import { act, useState } from 'react';
import type { InputPromptProps } from './InputPrompt.js';
import { InputPrompt } from './InputPrompt.js';
import type { TextBuffer } from './shared/text-buffer.js';
@@ -2900,6 +2900,93 @@ describe('InputPrompt', () => {
unmount();
});
it('should toggle paste expansion on double-click', async () => {
const id = '[Pasted Text: 10 lines]';
const largeText =
'line1\nline2\nline3\nline4\nline5\nline6\nline7\nline8\nline9\nline10';
const baseProps = props;
const TestWrapper = () => {
const [isExpanded, setIsExpanded] = useState(false);
const currentLines = isExpanded ? largeText.split('\n') : [id];
const currentText = isExpanded ? largeText : id;
const buffer = {
...baseProps.buffer,
text: currentText,
lines: currentLines,
viewportVisualLines: currentLines,
allVisualLines: currentLines,
pastedContent: { [id]: largeText },
transformationsByLine: isExpanded
? currentLines.map(() => [])
: [
[
{
logStart: 0,
logEnd: id.length,
logicalText: id,
collapsedText: id,
type: 'paste',
id,
},
],
],
visualScrollRow: 0,
visualToLogicalMap: currentLines.map(
(_, i) => [i, 0] as [number, number],
),
visualToTransformedMap: currentLines.map(() => 0),
getLogicalPositionFromVisual: vi.fn().mockReturnValue({
row: 0,
col: 2,
}),
togglePasteExpansion: vi.fn().mockImplementation(() => {
setIsExpanded(!isExpanded);
}),
getExpandedPasteAtLine: vi
.fn()
.mockReturnValue(isExpanded ? id : null),
};
return <InputPrompt {...baseProps} buffer={buffer as TextBuffer} />;
};
const { stdin, stdout, unmount, simulateClick } = renderWithProviders(
<TestWrapper />,
{
mouseEventsEnabled: true,
useAlternateBuffer: true,
uiActions,
},
);
// 1. Verify initial placeholder
await waitFor(() => {
expect(stdout.lastFrame()).toMatchSnapshot();
});
// Simulate double-click to expand
await simulateClick(stdin, 5, 2);
await simulateClick(stdin, 5, 2);
// 2. Verify expanded content is visible
await waitFor(() => {
expect(stdout.lastFrame()).toMatchSnapshot();
});
// Simulate double-click to collapse
await simulateClick(stdin, 5, 2);
await simulateClick(stdin, 5, 2);
// 3. Verify placeholder is restored
await waitFor(() => {
expect(stdout.lastFrame()).toMatchSnapshot();
});
unmount();
});
it('should move cursor on mouse click with plain borders', async () => {
props.config.getUseBackgroundColor = () => false;
props.buffer.text = 'hello world';