diff --git a/packages/cli/src/ui/components/SessionBrowser.tsx b/packages/cli/src/ui/components/SessionBrowser.tsx index 9e2843c570..0fc80a1d4e 100644 --- a/packages/cli/src/ui/components/SessionBrowser.tsx +++ b/packages/cli/src/ui/components/SessionBrowser.tsx @@ -116,38 +116,9 @@ const Kbd = ({ name, shortcut }: { name: string; shortcut: string }) => ( ); -/** - * Loading state component displayed while sessions are being loaded. - */ -const SessionBrowserLoading = (): React.JSX.Element => ( - - Loading sessions… - -); - -/** - * Error state component displayed when session loading fails. - */ -const SessionBrowserError = ({ - state, -}: { - state: SessionBrowserState; -}): React.JSX.Element => ( - - Error: {state.error} - Press q to exit - -); - -/** - * Empty state component displayed when no sessions are found. - */ -const SessionBrowserEmpty = (): React.JSX.Element => ( - - No auto-saved conversations found. - Press q to exit - -); +import { SessionBrowserLoading } from './SessionBrowser/SessionBrowserLoading.js'; +import { SessionBrowserError } from './SessionBrowser/SessionBrowserError.js'; +import { SessionBrowserEmpty } from './SessionBrowser/SessionBrowserEmpty.js'; import { sortSessions, filterSessions } from './SessionBrowser/utils.js'; diff --git a/packages/cli/src/ui/components/SessionBrowser/SessionBrowserEmpty.tsx b/packages/cli/src/ui/components/SessionBrowser/SessionBrowserEmpty.tsx new file mode 100644 index 0000000000..31c9544cd8 --- /dev/null +++ b/packages/cli/src/ui/components/SessionBrowser/SessionBrowserEmpty.tsx @@ -0,0 +1,19 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import type React from 'react'; +import { Box, Text } from 'ink'; +import { Colors } from '../../colors.js'; + +/** + * Empty state component displayed when no sessions are found. + */ +export const SessionBrowserEmpty = (): React.JSX.Element => ( + + No auto-saved conversations found. + Press q to exit + +); diff --git a/packages/cli/src/ui/components/SessionBrowser/SessionBrowserError.tsx b/packages/cli/src/ui/components/SessionBrowser/SessionBrowserError.tsx new file mode 100644 index 0000000000..cf46fb8954 --- /dev/null +++ b/packages/cli/src/ui/components/SessionBrowser/SessionBrowserError.tsx @@ -0,0 +1,24 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import type React from 'react'; +import { Box, Text } from 'ink'; +import { Colors } from '../../colors.js'; +import type { SessionBrowserState } from '../SessionBrowser.js'; + +/** + * Error state component displayed when session loading fails. + */ +export const SessionBrowserError = ({ + state, +}: { + state: SessionBrowserState; +}): React.JSX.Element => ( + + Error: {state.error} + Press q to exit + +); diff --git a/packages/cli/src/ui/components/SessionBrowser/SessionBrowserLoading.tsx b/packages/cli/src/ui/components/SessionBrowser/SessionBrowserLoading.tsx new file mode 100644 index 0000000000..e0c372eca2 --- /dev/null +++ b/packages/cli/src/ui/components/SessionBrowser/SessionBrowserLoading.tsx @@ -0,0 +1,18 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import type React from 'react'; +import { Box, Text } from 'ink'; +import { Colors } from '../../colors.js'; + +/** + * Loading state component displayed while sessions are being loaded. + */ +export const SessionBrowserLoading = (): React.JSX.Element => ( + + Loading sessions… + +); diff --git a/packages/cli/src/ui/components/SessionBrowser/SessionBrowserStates.test.tsx b/packages/cli/src/ui/components/SessionBrowser/SessionBrowserStates.test.tsx new file mode 100644 index 0000000000..2b816a8211 --- /dev/null +++ b/packages/cli/src/ui/components/SessionBrowser/SessionBrowserStates.test.tsx @@ -0,0 +1,35 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { render } from '../../../test-utils/render.js'; +import { describe, it, expect } from 'vitest'; +import { SessionBrowserLoading } from './SessionBrowserLoading.js'; +import { SessionBrowserError } from './SessionBrowserError.js'; +import { SessionBrowserEmpty } from './SessionBrowserEmpty.js'; +import type { SessionBrowserState } from '../SessionBrowser.js'; + +describe('SessionBrowser UI States', () => { + it('SessionBrowserLoading renders correctly', async () => { + const { lastFrame, waitUntilReady } = render(); + await waitUntilReady(); + expect(lastFrame()).toMatchSnapshot(); + }); + + it('SessionBrowserError renders correctly', async () => { + const mockState = { error: 'Test error message' } as SessionBrowserState; + const { lastFrame, waitUntilReady } = render( + , + ); + await waitUntilReady(); + expect(lastFrame()).toMatchSnapshot(); + }); + + it('SessionBrowserEmpty renders correctly', async () => { + const { lastFrame, waitUntilReady } = render(); + await waitUntilReady(); + expect(lastFrame()).toMatchSnapshot(); + }); +}); diff --git a/packages/cli/src/ui/components/SessionBrowser/__snapshots__/SessionBrowserStates.test.tsx.snap b/packages/cli/src/ui/components/SessionBrowser/__snapshots__/SessionBrowserStates.test.tsx.snap new file mode 100644 index 0000000000..e5939219cb --- /dev/null +++ b/packages/cli/src/ui/components/SessionBrowser/__snapshots__/SessionBrowserStates.test.tsx.snap @@ -0,0 +1,18 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`SessionBrowser UI States > SessionBrowserEmpty renders correctly 1`] = ` +" No auto-saved conversations found. + Press q to exit +" +`; + +exports[`SessionBrowser UI States > SessionBrowserError renders correctly 1`] = ` +" Error: Test error message + Press q to exit +" +`; + +exports[`SessionBrowser UI States > SessionBrowserLoading renders correctly 1`] = ` +" Loading sessions… +" +`;