diff --git a/packages/cli/src/ui/components/shared/EnumSelector.test.tsx b/packages/cli/src/ui/components/shared/EnumSelector.test.tsx deleted file mode 100644 index be2df513f97..00000000000 --- a/packages/cli/src/ui/components/shared/EnumSelector.test.tsx +++ /dev/null @@ -1,152 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { renderWithProviders } from '../../../test-utils/render.js'; -import { EnumSelector } from './EnumSelector.js'; -import type { SettingEnumOption } from '../../../config/settingsSchema.js'; -import { describe, it, expect } from 'vitest'; - -const LANGUAGE_OPTIONS: readonly SettingEnumOption[] = [ - { label: 'English', value: 'en' }, - { label: '中文 (简体)', value: 'zh' }, - { label: 'Español', value: 'es' }, - { label: 'Français', value: 'fr' }, -]; - -const NUMERIC_OPTIONS: readonly SettingEnumOption[] = [ - { label: 'Low', value: 1 }, - { label: 'Medium', value: 2 }, - { label: 'High', value: 3 }, -]; - -describe('', () => { - it('renders with string options and matches snapshot', () => { - const { lastFrame } = renderWithProviders( - {}} - />, - ); - expect(lastFrame()).toMatchSnapshot(); - }); - - it('renders with numeric options and matches snapshot', () => { - const { lastFrame } = renderWithProviders( - {}} - />, - ); - expect(lastFrame()).toMatchSnapshot(); - }); - - it('renders inactive state and matches snapshot', () => { - const { lastFrame } = renderWithProviders( - {}} - />, - ); - expect(lastFrame()).toMatchSnapshot(); - }); - - it('renders with single option and matches snapshot', () => { - const singleOption: readonly SettingEnumOption[] = [ - { label: 'Only Option', value: 'only' }, - ]; - const { lastFrame } = renderWithProviders( - {}} - />, - ); - expect(lastFrame()).toMatchSnapshot(); - }); - - it('renders nothing when no options are provided', () => { - const { lastFrame } = renderWithProviders( - {}} - />, - ); - expect(lastFrame()).toBe(''); - }); - - it('handles currentValue not found in options', () => { - const { lastFrame } = renderWithProviders( - {}} - />, - ); - // Should default to first option - expect(lastFrame()).toContain('English'); - }); - - it('updates when currentValue changes externally', () => { - const { rerender, lastFrame } = renderWithProviders( - {}} - />, - ); - expect(lastFrame()).toContain('English'); - - rerender( - {}} - />, - ); - expect(lastFrame()).toContain('中文 (简体)'); - }); - - it('shows navigation arrows when multiple options available', () => { - const { lastFrame } = renderWithProviders( - {}} - />, - ); - expect(lastFrame()).toContain('←'); - expect(lastFrame()).toContain('→'); - }); - - it('hides navigation arrows when single option available', () => { - const singleOption: readonly SettingEnumOption[] = [ - { label: 'Only Option', value: 'only' }, - ]; - const { lastFrame } = renderWithProviders( - {}} - />, - ); - expect(lastFrame()).not.toContain('←'); - expect(lastFrame()).not.toContain('→'); - }); -}); diff --git a/packages/cli/src/ui/components/shared/EnumSelector.tsx b/packages/cli/src/ui/components/shared/EnumSelector.tsx deleted file mode 100644 index a86efd8ff13..00000000000 --- a/packages/cli/src/ui/components/shared/EnumSelector.tsx +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { useState, useEffect } from 'react'; -import type React from 'react'; -import { Box, Text } from 'ink'; -import { Colors } from '../../colors.js'; -import type { SettingEnumOption } from '../../../config/settingsSchema.js'; - -interface EnumSelectorProps { - options: readonly SettingEnumOption[]; - currentValue: string | number; - isActive: boolean; - onValueChange: (value: string | number) => void; -} - -/** - * A left-right scrolling selector for enum values - */ -export function EnumSelector({ - options, - currentValue, - isActive, - onValueChange: _onValueChange, -}: EnumSelectorProps): React.JSX.Element { - const [currentIndex, setCurrentIndex] = useState(() => { - // Guard against empty options array - if (!options || options.length === 0) { - return 0; - } - const index = options.findIndex((option) => option.value === currentValue); - return index >= 0 ? index : 0; - }); - - // Update index when currentValue changes externally - useEffect(() => { - // Guard against empty options array - if (!options || options.length === 0) { - return; - } - const index = options.findIndex((option) => option.value === currentValue); - // Always update index, defaulting to 0 if value not found - setCurrentIndex(index >= 0 ? index : 0); - }, [currentValue, options]); - - // Guard against empty options array - if (!options || options.length === 0) { - return ; - } - - // Left/right navigation is handled by parent component - // This component is purely for display - // onValueChange is kept for interface compatibility but not used internally - - const currentOption = options[currentIndex] || options[0]; - const canScrollLeft = options.length > 1; - const canScrollRight = options.length > 1; - - return ( - - - {canScrollLeft ? '←' : ' '} - - - - {currentOption.label} - - - - {canScrollRight ? '→' : ' '} - - - ); -} - -// Export the interface for external use -export type { EnumSelectorProps }; diff --git a/packages/cli/src/ui/components/shared/__snapshots__/EnumSelector.test.tsx.snap b/packages/cli/src/ui/components/shared/__snapshots__/EnumSelector.test.tsx.snap deleted file mode 100644 index 9949aba5e47..00000000000 --- a/packages/cli/src/ui/components/shared/__snapshots__/EnumSelector.test.tsx.snap +++ /dev/null @@ -1,9 +0,0 @@ -// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html - -exports[` > renders inactive state and matches snapshot 1`] = `"← 中文 (简体) →"`; - -exports[` > renders with numeric options and matches snapshot 1`] = `"← Medium →"`; - -exports[` > renders with single option and matches snapshot 1`] = `" Only Option"`; - -exports[` > renders with string options and matches snapshot 1`] = `"← English →"`;