mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-02-01 22:48:03 +00:00
fix(ui): prevent content leak in MaxSizedBox bottom overflow
When using overflowDirection="bottom", content was bleeding through after the "... last N lines hidden ..." indicator. This was caused by the inner overflow Box not having a constrained height. Add maxHeight constraint to inner overflow Box when overflowing.
This commit is contained in:
@@ -4,10 +4,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { render } from '../../../test-utils/render.js';
|
||||
import { render, renderWithProviders } from '../../../test-utils/render.js';
|
||||
import { waitFor } from '../../../test-utils/async.js';
|
||||
import { OverflowProvider } from '../../contexts/OverflowContext.js';
|
||||
import { MaxSizedBox } from './MaxSizedBox.js';
|
||||
import { MarkdownDisplay } from '../../utils/MarkdownDisplay.js';
|
||||
import { Box, Text } from 'ink';
|
||||
import { describe, it, expect } from 'vitest';
|
||||
|
||||
@@ -226,4 +227,31 @@ describe('<MaxSizedBox />', () => {
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('does not leak content after hidden indicator with bottom overflow', async () => {
|
||||
const markdownContent = Array.from(
|
||||
{ length: 20 },
|
||||
(_, i) => `- Step ${i + 1}: Do something important`,
|
||||
).join('\n');
|
||||
const { lastFrame } = renderWithProviders(
|
||||
<MaxSizedBox maxWidth={80} maxHeight={5} overflowDirection="bottom">
|
||||
<MarkdownDisplay
|
||||
text={`## Plan\n\n${markdownContent}`}
|
||||
isPending={false}
|
||||
terminalWidth={76}
|
||||
/>
|
||||
</MaxSizedBox>,
|
||||
{ width: 80 },
|
||||
);
|
||||
|
||||
await waitFor(() => expect(lastFrame()).toContain('... last'));
|
||||
|
||||
const frame = lastFrame()!;
|
||||
const lines = frame.split('\n');
|
||||
const lastLine = lines[lines.length - 1];
|
||||
|
||||
// The last line should only contain the hidden indicator, no leaked content
|
||||
expect(lastLine).toMatch(/^\.\.\. last \d+ lines? hidden \.\.\.$/);
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -120,7 +120,12 @@ export const MaxSizedBox: React.FC<MaxSizedBoxProps> = ({
|
||||
hidden ...
|
||||
</Text>
|
||||
)}
|
||||
<Box flexDirection="column" overflow="hidden" flexGrow={1}>
|
||||
<Box
|
||||
flexDirection="column"
|
||||
overflow="hidden"
|
||||
flexGrow={1}
|
||||
maxHeight={isOverflowing ? visibleContentHeight : undefined}
|
||||
>
|
||||
<Box
|
||||
flexDirection="column"
|
||||
ref={onRefChange}
|
||||
|
||||
@@ -31,6 +31,14 @@ Line 29
|
||||
Line 30"
|
||||
`;
|
||||
|
||||
exports[`<MaxSizedBox /> > does not leak content after hidden indicator with bottom overflow 1`] = `
|
||||
"Plan
|
||||
|
||||
- Step 1: Do something important
|
||||
- Step 2: Do something important
|
||||
... last 18 lines hidden ..."
|
||||
`;
|
||||
|
||||
exports[`<MaxSizedBox /> > does not truncate when maxHeight is undefined 1`] = `
|
||||
"Line 1
|
||||
Line 2"
|
||||
|
||||
Reference in New Issue
Block a user