MiHCM
overlay/@mihcm/ui·v0.21.0·stable

AlertDialog

Non-dismissable modal requiring a user response. No backdrop dismiss, no Escape close. Composable sub-components mirror Dialog.

Destructive confirmation

Delete account?

This action cannot be undone. All data will be permanently removed.

import {
  AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogFooter,
  AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel,
} from '@mihcm/ui/AlertDialog';
 
const [open, setOpen] = useState(false);
 
<>
  <Button variant="destructive" onClick={() => setOpen(true)}>
    Delete account
  </Button>
  <AlertDialog open={open} onOpenChange={setOpen}>
    <AlertDialogContent>
      <AlertDialogHeader>
        <AlertDialogTitle>Delete account?</AlertDialogTitle>
        <AlertDialogDescription>
          This action cannot be undone. All data will be permanently removed.
        </AlertDialogDescription>
      </AlertDialogHeader>
      <AlertDialogFooter>
        <AlertDialogCancel onClick={() => setOpen(false)}>Cancel</AlertDialogCancel>
        <AlertDialogAction variant="destructive" onClick={() => setOpen(false)}>
          Delete
        </AlertDialogAction>
      </AlertDialogFooter>
    </AlertDialogContent>
  </AlertDialog>
</>

Small size

Discard changes?

Your unsaved changes will be lost.

<AlertDialog open={open} onOpenChange={setOpen}>
  <AlertDialogContent size="sm">
    <AlertDialogHeader>
      <AlertDialogTitle>Discard changes?</AlertDialogTitle>
      <AlertDialogDescription>Your unsaved changes will be lost.</AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel onClick={() => setOpen(false)}>Keep editing</AlertDialogCancel>
      <AlertDialogAction onClick={() => setOpen(false)}>Discard</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Confirmation input — AlertDialogBody

Use the new AlertDialogBody slot when the alert needs a confirmation field, checkbox, or any extra explanation. The content panel adds an automatic 16px row gap between Header / Body / Footer, so nothing sits glued together.

Some designations have incomplete profiles

Employees in these designations will be excluded from scoring. Confirm before activating the cycle.

import {
  AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogBody, AlertDialogFooter,
  AlertDialogTitle, AlertDialogDescription, AlertDialogAction, AlertDialogCancel,
} from '@mihcm/ui/AlertDialog';
import { Input } from '@mihcm/ui/Input';
import { Label } from '@mihcm/ui/Label';
 
const [open, setOpen] = useState(false);
const [confirmText, setConfirmText] = useState('');
const canActivate = confirmText.trim() === 'ACTIVATE';
 
<AlertDialog open={open} onOpenChange={setOpen}>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Some designations have incomplete profiles</AlertDialogTitle>
      <AlertDialogDescription>
        Employees in these designations will be excluded from scoring. Confirm before activating the cycle.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogBody>
      <Label htmlFor="alert-confirm" className="sr-only">Type ACTIVATE to confirm</Label>
      <Input
        id="alert-confirm"
        value={confirmText}
        onChange={(e) => setConfirmText(e.currentTarget.value)}
        placeholder="ACTIVATE"
      />
    </AlertDialogBody>
    <AlertDialogFooter>
      <AlertDialogCancel onClick={() => setOpen(false)}>Cancel</AlertDialogCancel>
      <AlertDialogAction variant="destructive" disabled={!canActivate}>
        Activate cycle
      </AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>

Informational (non-destructive)

Session expiring

Your session will expire in 5 minutes. Save your work to avoid losing changes.

<AlertDialog open={open} onOpenChange={setOpen}>
  <AlertDialogContent>
    <AlertDialogHeader>
      <AlertDialogTitle>Session expiring</AlertDialogTitle>
      <AlertDialogDescription>
        Your session will expire in 5 minutes. Save your work to avoid losing changes.
      </AlertDialogDescription>
    </AlertDialogHeader>
    <AlertDialogFooter>
      <AlertDialogCancel onClick={() => setOpen(false)}>Dismiss</AlertDialogCancel>
      <AlertDialogAction onClick={handleExtendSession}>Extend session</AlertDialogAction>
    </AlertDialogFooter>
  </AlertDialogContent>
</AlertDialog>