import React, { useState } from "react"; import { Box, Text, useInput } from "ink"; import { useTerminalTheme } from "../hooks/useTerminalTheme"; export type TConfirmationSeverity = "low" | "high"; export function ConfirmationPanel(props: { message: string; detail?: string; severity?: TConfirmationSeverity; /** For "high" severity destructive git/data operations: require typing this exact word (e.g. "DELETE"). */ typedConfirmationWord?: string; initial?: boolean; onSubmit: (confirmed: boolean) => void; onCancel: () => void; }) { const theme = useTerminalTheme(); const [typedValue, setTypedValue] = useState(""); const severity = props.severity ?? "low"; const requiresTyped = severity === "high" && Boolean(props.typedConfirmationWord); useInput((input, key) => { if (key.escape) { props.onCancel(); return; } if (requiresTyped) { if (key.return) { props.onSubmit(typedValue.trim() === props.typedConfirmationWord); return; } if (key.backspace || key.delete) { setTypedValue((current) => current.slice(0, -1)); return; } if (!key.ctrl && !key.meta && input) { setTypedValue((current) => current + input); } return; } if (input.toLowerCase() === "y" || key.return) { props.onSubmit(input.toLowerCase() === "n" ? false : true); return; } if (input.toLowerCase() === "n") { props.onSubmit(false); } }); return ( {props.message} {props.detail ? {props.detail} : null} {requiresTyped ? ( Type {props.typedConfirmationWord} to confirm: {typedValue} ) : ( (Y/n) )} ); }