Quick Start
Get up and running with Shadcn Modal Manager in minutes
1. Set Up the Provider
Wrap your application with ModalProvider:
import { ModalProvider } from "shadcn-modal-manager";
function App() {
return (
<ModalProvider>
<YourApp />
</ModalProvider>
);
}2. Create a Modal
Use ModalManager.create to define a modal component. The modal receives props via the data option when opened:
import { ModalManager, useModal, shadcnUiDialog, shadcnUiDialogContent } from "shadcn-modal-manager";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
interface EditUserModalProps {
userId: string;
userName: string;
}
export const EditUserModal = ModalManager.create<EditUserModalProps>(
({ userId, userName }) => {
const modal = useModal();
const handleSave = async (e: React.FormEvent) => {
e.preventDefault();
await saveUser(userId);
modal.close({ saved: true });
};
return (
<Dialog {...shadcnUiDialog(modal)}>
<DialogContent {...shadcnUiDialogContent(modal)}>
<DialogHeader>
<DialogTitle>Edit {userName}</DialogTitle>
</DialogHeader>
<form onSubmit={handleSave} className="space-y-4">
{/* form fields */}
<div className="p-4 border rounded">Form Content</div>
<DialogFooter>
<Button type="button" variant="outline" onClick={modal.dismiss}>
Cancel
</Button>
<Button type="submit">Save</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
);
}
);3. Open the Modal
Use ModalManager.open() to show the modal from anywhere in your app:
import { ModalManager } from "shadcn-modal-manager";
import { EditUserModal } from "./edit-user-modal";
function UserList() {
const handleEdit = async (user) => {
const modalRef = ModalManager.open(EditUserModal, {
data: { userId: user.id, userName: user.name }
});
const result = await modalRef.afterClosed();
if (result?.saved) {
refetch();
}
};
return (
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name}
<button onClick={() => handleEdit(user)}>Edit</button>
</li>
))}
</ul>
);
}Key Concepts
Modal Handler
Inside a modal, useModal() returns a handler with:
State:
modalId- The modal's unique identifierdata- Data passed viaModalManager.open()isOpen- Whether the modal is openkeepMounted- Whether to keep mounted after close
Controls:
open(data?)- Open this modal (useful for nested modals)close(result?)- Close with a result valuedismiss()- Close without a resultremove()- Force remove from the store
Animation:
onAnimationEnd()- Call when exit animation completes
Adapters
Adapters translate the modal handler into props for your UI library:
// The adapter handles onOpenChange, animation callbacks, etc.
<Dialog {...shadcnUiDialog(modal)}>
<DialogContent {...shadcnUiDialogContent(modal)}>
{/* content */}
</DialogContent>
</Dialog>Promise-based Control
ModalManager.open() returns a ModalRef with promise methods:
const ref = ModalManager.open(MyModal, { data: { ... } });
// Wait for the modal to finish opening animation
await ref.afterOpened();
// Wait for the modal to close and get the result
const result = await ref.afterClosed();