({
existingApiKey,
apiKeyOrOAuthToken,
onApiKeyChange,
onSubmit,
onToggleUseExistingKey,
onCreateOAuthToken,
selectedOption = existingApiKey ? 'existing' : onCreateOAuthToken ? 'oauth' : 'new',
onSelectOption,
}: ApiKeyStepProps)
| 17 | } |
| 18 | |
| 19 | export function ApiKeyStep({ |
| 20 | existingApiKey, |
| 21 | apiKeyOrOAuthToken, |
| 22 | onApiKeyChange, |
| 23 | onSubmit, |
| 24 | onToggleUseExistingKey, |
| 25 | onCreateOAuthToken, |
| 26 | selectedOption = existingApiKey ? 'existing' : onCreateOAuthToken ? 'oauth' : 'new', |
| 27 | onSelectOption, |
| 28 | }: ApiKeyStepProps) { |
| 29 | const [cursorOffset, setCursorOffset] = useState(0); |
| 30 | const terminalSize = useTerminalSize(); |
| 31 | const [theme] = useTheme(); |
| 32 | |
| 33 | const handlePrevious = useCallback(() => { |
| 34 | if (selectedOption === 'new' && onCreateOAuthToken) { |
| 35 | // From 'new' go up to 'oauth' |
| 36 | onSelectOption?.('oauth'); |
| 37 | } else if (selectedOption === 'oauth' && existingApiKey) { |
| 38 | // From 'oauth' go up to 'existing' (only if it exists) |
| 39 | onSelectOption?.('existing'); |
| 40 | onToggleUseExistingKey(true); |
| 41 | } |
| 42 | }, [selectedOption, onCreateOAuthToken, existingApiKey, onSelectOption, onToggleUseExistingKey]); |
| 43 | |
| 44 | const handleNext = useCallback(() => { |
| 45 | if (selectedOption === 'existing') { |
| 46 | // From 'existing' go down to 'oauth' (if available) or 'new' |
| 47 | onSelectOption?.(onCreateOAuthToken ? 'oauth' : 'new'); |
| 48 | onToggleUseExistingKey(false); |
| 49 | } else if (selectedOption === 'oauth') { |
| 50 | // From 'oauth' go down to 'new' |
| 51 | onSelectOption?.('new'); |
| 52 | } |
| 53 | }, [selectedOption, onCreateOAuthToken, onSelectOption, onToggleUseExistingKey]); |
| 54 | |
| 55 | const handleConfirm = useCallback(() => { |
| 56 | if (selectedOption === 'oauth' && onCreateOAuthToken) { |
| 57 | onCreateOAuthToken(); |
| 58 | } else { |
| 59 | onSubmit(); |
| 60 | } |
| 61 | }, [selectedOption, onCreateOAuthToken, onSubmit]); |
| 62 | |
| 63 | // When the text input is visible, omit confirm:yes so bare 'y' passes |
| 64 | // through to the input instead of submitting. TextInput's onSubmit handles |
| 65 | // Enter. Keep the Confirmation context (not Settings) to avoid j/k bindings. |
| 66 | const isTextInputVisible = selectedOption === 'new'; |
| 67 | useKeybindings( |
| 68 | { |
| 69 | 'confirm:previous': handlePrevious, |
| 70 | 'confirm:next': handleNext, |
| 71 | 'confirm:yes': handleConfirm, |
| 72 | }, |
| 73 | { context: 'Confirmation', isActive: !isTextInputVisible }, |
| 74 | ); |
| 75 | useKeybindings( |
| 76 | { |
nothing calls this directly
no test coverage detected