Skip to main content
Version: 1.0.3

Modals

The Modals component provides an accessible, animated dialog for displaying important content, confirmations, or flows that require user attention. It includes a dimmed overlay, structured header/body/footer slots, keyboard support, and configurable color schemes.

Installation

ignix add component modal

Usage

import { Modal } from '@ignix-ui/modal';

Basic usage

import { Button } from '@ignix-ui/button';

function BasicModalExample() {
const [isOpen, setIsOpen] = useState(false);

return (
<>
<Button onClick={() => setIsOpen(true)}>Open modal</Button>
<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Confirm action"
>
<p>Are you sure you want to proceed?</p>
</Modal>
</>
);
}

Composable (nested) usage

import { useState, useCallback } from 'react';
import { AnimatePresence } from 'framer-motion';
import {
ModalOverlay,
ModalContent,
ModalHeader,
ModalBody,
ModalFooter,
Modal,
} from '@ignix-ui/modal';
import { Button } from '@ignix-ui/button';
import { cn } from './utils/cn';
import { Info } from 'lucide-react';

// Type for Modal's static colorSchemeConfig (for TypeScript)
type ModalWithColorConfig = typeof Modal & {
colorSchemeConfig: Record<
string,
{
backdrop: string;
content: string;
header: string;
body: string;
footer: string;
closeButton: string;
cancelButton: string;
confirmButton: string;
}
>;
};

function ComposableModalExample() {
const [isOpen, setIsOpen] = useState(false);
const close = useCallback(() => setIsOpen(false), []);

const colorScheme = 'primary';
const scheme = (Modal as ModalWithColorConfig).colorSchemeConfig[colorScheme];

const backdropClassName = cn(scheme.backdrop);
const contentClassName = cn(scheme.content);
const headerClassName = cn(scheme.header);
const bodyClassName = cn('border-l-4', scheme.body);
const footerClassName = cn(scheme.footer);

return (
<>
<Button onClick={() => setIsOpen(true)}>Open modal</Button>
<AnimatePresence>
{isOpen && (
<ModalOverlay
closeOnOverlayClick
onRequestClose={close}
backdropClassName={backdropClassName}
>
<ModalContent size="md" className={contentClassName}>
<ModalHeader
title="Confirm action"
icon={<Info className="h-5 w-5 text-primary" />}
iconClassName="bg-primary/10 border-primary/30"
showCloseButton
onClose={close}
className={headerClassName}
closeButtonClassName={scheme.closeButton}
/>
<ModalBody className={bodyClassName}>
<p className="mb-2">Are you sure you want to proceed? This cannot be undone.</p>
<p className="text-sm text-muted-foreground">Press Esc or click outside to close.</p>
</ModalBody>
<ModalFooter
confirmText="Confirm"
cancelText="Cancel"
onConfirm={() => close()}
onCancel={close}
className={footerClassName}
cancelButtonClassName={scheme.cancelButton}
confirmButtonClassName={scheme.confirmButton}
/>
</ModalContent>
</ModalOverlay>
)}
</AnimatePresence>
</>
);
}

Color schemes

<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Success"
colorScheme="success"
>
<p>Your changes have been saved successfully.</p>
</Modal>

<Modal
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Delete item?"
colorScheme="destructive"
>
<p>This action cannot be undone. Are you sure?</p>
</Modal>

Props

PropTypeDefaultDescription
isOpenbooleanfalseWhether the modal is visible.
onClose() => voidCallback fired when the modal should close (overlay click, Esc, footer buttons, close icon, etc.).
onConfirm() => voidundefinedCalled when the confirm button is clicked.
onCancel() => voidundefinedCalled when the cancel button is clicked.
titleReact.ReactNodeundefinedHeader title text or node.
childrenReact.ReactNodeundefinedModal body content.
confirmTextstring"Confirm"Label for the confirm button.
cancelTextstring"Cancel"Label for the cancel button.
showFooterbooleantrueWhether to render the footer with action buttons.
showCloseButtonbooleantrueWhether to show the close (X) button in the header.
closeOnOverlayClickbooleantrueWhether clicking on the overlay closes the modal.
closeOnEscapebooleantrueWhether pressing the Escape key closes the modal.
size'sm' | 'md' | 'lg' | 'xl' | 'full'"md"Size variant of the modal.
colorScheme'primary' | 'accent' | 'success' | 'warning' | 'destructive' | 'info'"primary"Built-in color scheme controlling header, borders, and button styles.
colorOverrides{ overlay?, backdrop?, content?, header?, body?, footer?, closeButton?, cancelButton?, confirmButton? }undefinedFine-grained Tailwind class overrides for different visual areas.
classNamestringundefinedAdditional classes for the modal content container.
overlayClassNamestringundefinedAdditional classes for the overlay wrapper.
headerClassNamestringundefinedAdditional classes for the header.
bodyClassNamestringundefinedAdditional classes for the body.
footerClassNamestringundefinedAdditional classes for the footer.
headerIconReact.ReactNodeundefinedOptional icon rendered to the left of the title in the header.
headerIconClassNamestringundefinedAdditional classes for the header icon wrapper.