ConfirmDialog

free

ConfirmDialog wraps Dialog with a status icon, title, message, and cancel/confirm button pair for destructive or informational confirmations.

react-icons
Preview
Dark
import { useState } from 'react';
import Button from '@/components/ui/Button';
import ConfirmDialog from '@/components/composites/ConfirmDialog';

export default function UsageDemo() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>
        Delete item
      </Button>
      <ConfirmDialog
        isOpen={open}
        type="danger"
        title="Delete this item?"
        onConfirm={() => setOpen(false)}
        onCancel={() => setOpen(false)}
        confirmText="Delete"
      >
        This action cannot be undone. The item will be permanently removed.
      </ConfirmDialog>
    </>
  );
}

Installation

Add this component with the NateUI CLI.

npx nateui@latest add ConfirmDialog

Examples

Status Types

Preview
Dark
import { useState } from 'react';
import Button from '@/components/ui/Button';
import ConfirmDialog from '@/components/composites/ConfirmDialog';

type DialogState = {
  open: boolean;
  type: 'info' | 'success' | 'warning' | 'danger';
};

export default function StatusTypesDemo() {
  const [state, setState] = useState<DialogState>({
    open: false,
    type: 'info',
  });

  const types = ['info', 'success', 'warning', 'danger'] as const;

  return (
    <>
      <div className="flex flex-wrap gap-2">
        {types.map((t) => (
          <Button
            key={t}
            variant={t === 'danger' ? 'solid' : 'default'}
            destructive={t === 'danger'}
            onClick={() => setState({ open: true, type: t })}
          >
            {t.charAt(0).toUpperCase() + t.slice(1)}
          </Button>
        ))}
      </div>
      <ConfirmDialog
        isOpen={state.open}
        type={state.type}
        title={`${state.type.charAt(0).toUpperCase() + state.type.slice(1)} confirmation`}
        onConfirm={() => setState((s) => ({ ...s, open: false }))}
        onCancel={() => setState((s) => ({ ...s, open: false }))}
        confirmText="Continue"
      >
        This is a {state.type}-type confirmation dialog with a matching
        status icon and color.
      </ConfirmDialog>
    </>
  );
}

Custom Buttons

Preview
Dark
import { useState } from 'react';
import Button from '@/components/ui/Button';
import ConfirmDialog from '@/components/composites/ConfirmDialog';

export default function CustomButtonsDemo() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <Button onClick={() => setOpen(true)}>
        Archive project
      </Button>
      <ConfirmDialog
        isOpen={open}
        type="warning"
        title="Archive this project?"
        confirmText="Archive"
        cancelText="Keep working"
        confirmButtonProps={{ destructive: true }}
        onConfirm={() => setOpen(false)}
        onCancel={() => setOpen(false)}
      >
        The project will be moved to archives. Team members will lose access
        until it is restored.
      </ConfirmDialog>
    </>
  );
}

Controlled

Preview
Dark
import { useState } from 'react';
import Button from '@/components/ui/Button';
import ConfirmDialog from '@/components/composites/ConfirmDialog';

export default function ControlledDemo() {
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);

  const handleConfirm = () => {
    setLoading(true);
    setTimeout(() => {
      setLoading(false);
      setOpen(false);
    }, 1000);
  };

  return (
    <>
      <Button onClick={() => setOpen(true)}>
        Submit order
      </Button>
      <ConfirmDialog
        isOpen={open}
        type="info"
        title="Confirm order"
        confirmText={loading ? 'Processing...' : 'Submit'}
        confirmButtonProps={{ loading }}
        onConfirm={handleConfirm}
        onCancel={() => !loading && setOpen(false)}
      >
        Please review your order before submitting. This will charge your
        account immediately.
      </ConfirmDialog>
    </>
  );
}

API

PropDescriptionTypeDefault
isOpenControls whether the dialog is visible.boolean
typeStatus variant that determines the icon and color.'info' | 'success' | 'warning' | 'danger''info'
titleDialog heading text.ReactNode | string
childrenMessage body rendered below the title.ReactNode
confirmTextLabel for the confirm button.ReactNode | string'Confirm'
cancelTextLabel for the cancel button.ReactNode | string'Cancel'
onConfirmCalled when the confirm button is clicked.() => void
onCancelCalled when the cancel button is clicked.() => void
confirmButtonPropsProps forwarded to the confirm Button.ButtonProps
cancelButtonPropsProps forwarded to the cancel Button.ButtonProps
closableShow a close button in the dialog header.booleanfalse
sizeWidth of the dialog.'sm' | 'md' | 'lg''md'