Skip to main content

Overview

Edit profile
Update your display name and bio.
Ahmad Dani
🗑
Delete account?
All your data will be permanently deleted.
Modal renders a centered overlay panel over a dimmed backdrop. Use it for confirmations, form flows, detail views, and any interaction that requires the user’s full attention.
For simple yes/no confirmations, consider a compact AlertDialog. Use Drawer or Sheet for side-panel interactions that don’t block the full screen.

Installation

npm install @araf-ds/core

Usage

import {
  Modal,
  ModalContent,
  ModalDescription,
  ModalFooter,
  ModalHeader,
  ModalTitle,
  ModalTrigger,
} from "@araf-ds/core"

export default function Example() {
  const [open, setOpen] = useState(false)
  return (
    <Modal open={open} onOpenChange={setOpen}>
      <ModalTrigger asChild>
        <Button>Edit profile</Button>
      </ModalTrigger>
      <ModalContent>
        <ModalHeader>
          <ModalTitle>Edit profile</ModalTitle>
          <ModalDescription>Update your display name and bio.</ModalDescription>
        </ModalHeader>
        <div className="px-6 py-4">
          <Input label="Display name" defaultValue="Ahmad Dani" />
        </div>
        <ModalFooter>
          <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
          <Button>Save changes</Button>
        </ModalFooter>
      </ModalContent>
    </Modal>
  )
}

Variants

Default Modal

Standard dialog for forms or informational content.
Edit profile
Update your display name and bio.
Ahmad Dani
<Modal open={open} onOpenChange={setOpen}>
  <ModalContent>
    <ModalHeader>
      <ModalTitle>Edit profile</ModalTitle>
      <ModalDescription>Update your display name and bio.</ModalDescription>
    </ModalHeader>
    <div className="px-6 py-4">
      <Input label="Display name" defaultValue="Ahmad Dani" />
    </div>
    <ModalFooter>
      <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
      <Button>Save changes</Button>
    </ModalFooter>
  </ModalContent>
</Modal>

Warning Modal

Unpublish page?
This page will no longer be visible to users.
<Modal open={open} onOpenChange={setOpen}>
  <ModalContent iconVariant="warning" icon={<AlertTriangleIcon />}>
    <ModalHeader>
      <ModalTitle>Unpublish page?</ModalTitle>
      <ModalDescription>This page will no longer be visible to users.</ModalDescription>
    </ModalHeader>
    <ModalFooter>
      <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
      <Button variant="warning">Unpublish</Button>
    </ModalFooter>
  </ModalContent>
</Modal>

Destructive Modal

Delete account?
All your data will be permanently deleted. This cannot be undone.
<Modal open={open} onOpenChange={setOpen}>
  <ModalContent iconVariant="destructive" icon={<TrashIcon />}>
    <ModalHeader>
      <ModalTitle>Delete account?</ModalTitle>
      <ModalDescription>All your data will be permanently deleted. This cannot be undone.</ModalDescription>
    </ModalHeader>
    <ModalFooter>
      <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
      <Button variant="destructive">Delete account</Button>
    </ModalFooter>
  </ModalContent>
</Modal>
Always require a second confirmation step before executing destructive actions in a Modal.

API Reference

open
boolean
Controls the open state.
onOpenChange
(open: boolean) => void
Callback fired when the open state changes.
defaultOpen
boolean
default:"false"
Uncontrolled default open state.

ModalContent

size
string
default:"md"
Dialog width. Values: sm · md · lg · xl · full
icon
ReactNode
Icon shown in the header area alongside the title.
iconVariant
string
default:"default"
Icon container background. Values: default · warning · destructive
className
string
Additional Tailwind classes for custom overrides.

ModalFooter

align
string
default:"end"
Button alignment inside the footer. Values: start · end · between

Accessibility

  • Modal uses role="dialog" with aria-modal="true"
  • Focus is trapped inside the modal while open
  • Pressing Escape closes the modal
  • Focus returns to the trigger element when the modal closes
  • ModalTitle is linked via aria-labelledby
  • ModalDescription is linked via aria-describedby

Do’s & Don’ts

Do

  • Use Modal for actions that require the user’s complete attention
  • Keep modals focused on a single task
  • Always provide a clear Cancel/Close action
  • Use destructive iconVariant for irreversible actions

Don't

  • Don’t use Modal for non-critical information — use Toast or Alert
  • Don’t nest modals inside other modals
  • Don’t make modals too large — keep content scannable
  • Don’t auto-close a modal after a destructive action without confirmation