/**
* 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)
)}
)
}