feat(ui): use Tab to switch focus between shell and input (#14332)

This commit is contained in:
Jacob Richman
2026-01-12 15:30:12 -08:00
committed by GitHub
parent 2e8c6cfdbb
commit ca6786a28b
11 changed files with 180 additions and 114 deletions
@@ -2418,6 +2418,84 @@ describe('InputPrompt', () => {
});
});
describe('Tab focus toggle', () => {
it.each([
{
name: 'should toggle focus in on Tab when no suggestions or ghost text',
showSuggestions: false,
ghostText: '',
suggestions: [],
expectedFocusToggle: true,
},
{
name: 'should accept ghost text and NOT toggle focus on Tab',
showSuggestions: false,
ghostText: 'ghost text',
suggestions: [],
expectedFocusToggle: false,
expectedAcceptCall: true,
},
{
name: 'should NOT toggle focus on Tab when suggestions are present',
showSuggestions: true,
ghostText: '',
suggestions: [{ label: 'test', value: 'test' }],
expectedFocusToggle: false,
},
])(
'$name',
async ({
showSuggestions,
ghostText,
suggestions,
expectedFocusToggle,
expectedAcceptCall,
}) => {
const mockAccept = vi.fn();
mockedUseCommandCompletion.mockReturnValue({
...mockCommandCompletion,
showSuggestions,
suggestions,
promptCompletion: {
text: ghostText,
accept: mockAccept,
clear: vi.fn(),
isLoading: false,
isActive: ghostText !== '',
markSelected: vi.fn(),
},
});
const { stdin, unmount } = renderWithProviders(
<InputPrompt {...props} />,
{
uiActions,
uiState: { activePtyId: 1 },
},
);
await act(async () => {
stdin.write('\t');
});
await waitFor(() => {
if (expectedFocusToggle) {
expect(uiActions.setEmbeddedShellFocused).toHaveBeenCalledWith(
true,
);
} else {
expect(uiActions.setEmbeddedShellFocused).not.toHaveBeenCalled();
}
if (expectedAcceptCall) {
expect(mockAccept).toHaveBeenCalled();
}
});
unmount();
},
);
});
describe('mouse interaction', () => {
it.each([
{