import { createContext, useCallback, useContext, useRef, useState } from "react"; import Icon from "./components/Icon"; /** * Rückfragen innerhalb der Anwendung statt über den Browser. * * `window.confirm` reißt den Benutzer aus der Oberfläche, zeigt den Hostnamen * und lässt sich weder gestalten noch beschriften. Der Dialog hier sieht aus wie * der Rest der Anwendung, kann eine Aktion benennen ("Löschen" statt "OK") und * gefährliche Schritte rot hervorheben. * * Aufruf bleibt so einfach wie vorher: * * const confirm = useConfirm(); * if (!(await confirm({ title: "Gruppe löschen?", message: "…" }))) return; * * Mit `prompt: true` wird daraus eine Eingabe; aufgeloest wird dann der * eingetippte Text (oder `null` beim Abbrechen). Auch dafuer gilt der Grund von * oben: `window.prompt` sieht aus wie der Browser, nicht wie diese Anwendung. * * const name = await confirm({ title: "Name?", prompt: true, defaultValue: "…" }); */ const ConfirmContext = createContext(async () => false); export function ConfirmProvider({ children }) { const [frage, setFrage] = useState(null); const [eingabe, setEingabe] = useState(""); // Die Zusage des offenen Dialogs, damit `await confirm(...)` funktioniert. const antwort = useRef(null); const confirm = useCallback((optionen) => { const gestellt = typeof optionen === "string" ? { message: optionen } : optionen; setFrage(gestellt); setEingabe(gestellt.defaultValue ?? ""); return new Promise((resolve) => { antwort.current = resolve; }); }, []); function schliessen(ergebnis) { setFrage(null); antwort.current?.(ergebnis); antwort.current = null; } /** Bei einer Eingabe zaehlt der Text, sonst wie bisher true/false. */ function bestaetigen() { if (!frage?.prompt) { schliessen(true); return; } const text = eingabe.trim(); if (!text) return; // Leer bestaetigen ergibt keinen Sinn schliessen(text); } return ( {children} {frage && (
e.target === e.currentTarget && schliessen(frage.prompt ? null : false)}>

{frage.title || "Bitte bestätigen"}

{frage.message &&

{frage.message}

} {frage.prompt && (
{/* eslint-disable-next-line jsx-a11y/no-autofocus */} setEingabe(e.target.value)} onKeyDown={(e) => { if (e.key === "Enter") bestaetigen(); if (e.key === "Escape") schliessen(null); }} />
)}
)}
); } export function useConfirm() { return useContext(ConfirmContext); }