/** * ConfirmDialog component for TUI. * Displays a confirmation dialog with [Y] Apply / [N] Cancel / [E] Edit options. * Supports inline editing when user selects Edit. */ import { Box, Text, useInput } from "ink" import React, { useCallback, useState } from "react" import type { ConfirmChoice } from "../../shared/types/index.js" import { DiffView, type DiffViewProps } from "./DiffView.js" import { EditableContent } from "./EditableContent.js" export interface ConfirmDialogProps { message: string diff?: DiffViewProps onSelect: (choice: ConfirmChoice, editedContent?: string[]) => void editableContent?: string[] syntaxHighlight?: boolean } type DialogMode = "confirm" | "edit" function ChoiceButton({ hotkey, label, isSelected, }: { hotkey: string label: string isSelected: boolean }): React.JSX.Element { return ( [{hotkey}] {label} ) } export function ConfirmDialog({ message, diff, onSelect, editableContent, syntaxHighlight = false, }: ConfirmDialogProps): React.JSX.Element { const [mode, setMode] = useState("confirm") const [selected, setSelected] = useState(null) const linesToEdit = editableContent ?? diff?.newLines ?? [] const canEdit = linesToEdit.length > 0 const handleEditSubmit = useCallback( (editedLines: string[]) => { setSelected("apply") onSelect("apply", editedLines) }, [onSelect], ) const handleEditCancel = useCallback(() => { setMode("confirm") setSelected(null) }, []) useInput( (input, key) => { if (mode === "edit") { return } const lowerInput = input.toLowerCase() if (lowerInput === "y") { setSelected("apply") onSelect("apply") } else if (lowerInput === "n") { setSelected("cancel") onSelect("cancel") } else if (lowerInput === "e" && canEdit) { setSelected("edit") setMode("edit") } else if (key.escape) { setSelected("cancel") onSelect("cancel") } }, { isActive: mode === "confirm" }, ) if (mode === "edit") { return ( ) } return ( ⚠ {message} {diff && ( )} {canEdit ? ( ) : ( [E] Edit (disabled) )} ) }