Skip to content
All Taste components

Overlays

Confirm dialog

Asks before something that can't be undone, and says exactly what will be lost.

destructive · what gets removed · cancel first

Delete Kaveri Foods?

This removes the customer and everything linked to them. It can't be undone.

  • Invoices 14
  • Unpaid balance ₹1,26,000
"use client";
import { useEffect, useRef } from "react";
import { AlertTriangle } from "lucide-react";

/** Native <dialog> with role="alertdialog"; Cancel gets focus first so Enter never deletes by accident. */
export function ConfirmDialog({ open, title, body, confirmLabel, onConfirm, onCancel }: {
  open: boolean;
  title: string;
  body: React.ReactNode;
  confirmLabel: string;
  onConfirm: () => void;
  onCancel: () => void;
}) {
  const ref = useRef<HTMLDialogElement>(null);
  const cancelRef = useRef<HTMLButtonElement>(null);

  useEffect(() => {
    const d = ref.current;
    if (!d) return;
    if (open && !d.open) { d.showModal(); cancelRef.current?.focus(); }
    if (!open && d.open) d.close();
  }, [open]);

  return (
    <dialog
      ref={ref}
      role="alertdialog"
      aria-labelledby="confirm-title"
      aria-describedby="confirm-body"
      onClose={onCancel}
      className="w-[calc(100%-32px)] max-w-[380px] rounded-lg border border-border bg-bg p-0 text-fg shadow-2xl backdrop:bg-neutral-950/45"
    >
      <div className="flex gap-3.5 p-5">
        <span className="grid size-10 shrink-0 place-items-center rounded-full bg-danger-soft text-danger">
          <AlertTriangle className="size-5" aria-hidden />
        </span>
        <div className="grid min-w-0 gap-1">
          <h2 id="confirm-title" className="text-base font-semibold tracking-tight">{title}</h2>
          <div id="confirm-body" className="text-[13.5px] text-fg-muted">{body}</div>
        </div>
      </div>
      <div className="flex flex-wrap justify-end gap-2 border-t border-border bg-surface px-5 py-3">
        <button ref={cancelRef} type="button" onClick={onCancel}
          className="h-9 rounded border border-border-strong bg-bg px-3.5 text-sm font-medium text-fg hover:bg-surface">
          Cancel
        </button>
        <button type="button" onClick={onConfirm}
          className="h-9 rounded bg-danger px-3.5 text-sm font-medium text-bg hover:opacity-90">
          {confirmLabel}
        </button>
      </div>
    </dialog>
  );
}

The code uses the Taste Tailwind preset. Make yours on the Taste page with Export my system.