pnpm dlx dreamy add modalexport default function BasicModal() {
const { isOpen, onClose, onOpen } = useControllable();
return (
<>
<Button variant={"primary"} onClick={onOpen}>
Open Modal
</Button>
<Modal.Root isOpen={isOpen} onClose={onClose}>
<Modal.Overlay />
<Modal.Content>
<Modal.Header>Modal Header</Modal.Header>
<Modal.CloseButton />
<Modal.Body>Modal Body</Modal.Body>
<Modal.Footer>
<Button onClick={onClose}>Close</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
);
}export function SizeModals() {
const sizes = [
"sm",
"md",
"lg",
"xl",
"2xl",
"3xl",
"4xl",
"5xl",
"6xl",
"7xl",
"8xl"
] as const;
const ModalSize = useCallback(({ size }: { size: (typeof sizes)[number] }) => {
const { isOpen, onClose, onOpen } = useControllable();
return (
<>
<Button variant={"primary"} onClick={onOpen}>
Open {size} Modal
</Button>
<Modal.Root isOpen={isOpen} onClose={onClose} size={size}>
<Modal.Overlay />
<Modal.Content>
<Modal.Header>{size} Modal</Modal.Header>
<Modal.CloseButton />
<Modal.Body>This is a {size} modal!</Modal.Body>
<Modal.Footer>
<Button onClick={onClose}>Close</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
);
}, []);
return (
<Flex wrapped gap={2}>
{sizes.map((size) => (
<ModalSize size={size} key={"modal-size-" + size} />
))}
</Flex>
);
}- inside: The modal body will scroll inside the modal.
export default function ScrollBehaviorModal() {
const { isOpen, onClose, onOpen } = useControllable();
return (
<>
<Button variant={"primary"} onClick={onOpen}>
Open Modal
</Button>
<Modal.Root isOpen={isOpen} onClose={onClose} scrollBehavior={"inside"}>
<Modal.Overlay />
<Modal.Content>
<Modal.Header>Modal Header</Modal.Header>
<Modal.CloseButton />
<Modal.Body>Modal Body</Modal.Body>
<Modal.Footer>
<Button onClick={onClose}>Close</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
);
}- outside: The modal body will scroll outside the modal. If your content is long and it bugs the modal position, ensure to set the
placement="top"prop.
export function ScrollableOutsideModal() {
const { isOpen, onClose, onOpen } = useControllable();
return (
<>
<Button variant={"primary"} onClick={onOpen}>
Open Modal
</Button>
<Modal.Root
isOpen={isOpen}
onClose={onClose}
scrollBehavior="outside"
placement="top"
size={"lg"}
>
<Modal.Overlay />
<Modal.Content>
<Modal.Header>Modal Header</Modal.Header>
<Modal.CloseButton />
<Modal.Body>
{[...Array(10)].map((_, i) => (
<LoremIpsum key={`ipsum-${i}`} p={1} />
))}
</Modal.Body>
<Modal.Footer>
<Button onClick={onClose}>Close</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
);
}Sometimes you might want to place the modal on the top to avoid layout shifts.
export function PlacementModal() {
const { isOpen, onClose, onOpen } = useControllable();
return (
<>
<Button variant={"primary"} onClick={onOpen}>
Open Modal
</Button>
<Modal.Root isOpen={isOpen} onClose={onClose} placement={"top"}>
<Modal.Overlay />
<Modal.Content>
<Modal.Header>Modal Header</Modal.Header>
<Modal.CloseButton />
<Modal.Body>Modal Body</Modal.Body>
<Modal.Footer>
<Button onClick={onClose}>Close</Button>
</Modal.Footer>
</Modal.Content>
</Modal.Root>
</>
);
}