Skip to Content

Dialog

A compound component for modal dialogs. Built on the native <dialog> element — showModal() provides a native focus trap, Escape key handling, and ::backdrop support.

Usage

import { Dialog, DialogClose, DialogContent, DialogTrigger } from '@froglet/ui' // Uncontrolled <Dialog> <DialogTrigger> <button type="button">Open dialog</button> </DialogTrigger> <DialogContent aria-label="Example dialog"> <p>Dialog content goes here.</p> <DialogClose>Close</DialogClose> </DialogContent> </Dialog> // Controlled const [open, setOpen] = useState(false) <Dialog open={open} onOpenChange={setOpen}> <DialogTrigger> <button type="button">Open</button> </DialogTrigger> <DialogContent aria-label="Controlled dialog"> <p>Content.</p> <DialogClose>Close</DialogClose> </DialogContent> </Dialog>

Props

Dialog

PropTypeDefaultDescription
defaultOpenbooleanfalseUncontrolled initial open state.
openbooleanControlled open state.
onOpenChange(open: boolean) => voidCalled when open state changes.
childrenReactNodeDialogTrigger and DialogContent.

Dialog renders no DOM element — it is a context provider only.

DialogTrigger

PropTypeDescription
childrenReactElementA single element whose onClick is augmented to open the dialog.

Uses cloneElement — pass any focusable element (<button>, <Button>). No DOM wrapper is added.

DialogContent

Extends HTMLAttributes<HTMLDialogElement>.

PropTypeDescription
classNamestringAdditional CSS classes. Use to apply a token block.
refReact.Ref<HTMLDialogElement>Forwarded to the underlying <dialog>.

Pass aria-label or aria-labelledby directly on DialogContent.

DialogClose

Extends ButtonHTMLAttributes<HTMLButtonElement>.

PropTypeDescription
classNamestringAdditional CSS classes. Use to apply a token block.
refReact.Ref<HTMLButtonElement>Forwarded to the underlying <button>.

CSS Custom Properties

TokenDefaultDescription
--dialog-padding1.5remPanel internal spacing.
--dialog-max-width32remMaximum panel width.
--dialog-background-colorCanvasPanel background.
--dialog-colorCanvasTextPanel text color.
--dialog-border-width0Panel border width.
--dialog-border-stylesolidPanel border style.
--dialog-border-colorPanel border color. No border when unset.
--dialog-border-radius0Panel corner rounding.
--dialog-backdrop-colorrgb(0 0 0 / 0.5)Backdrop overlay color.
--dialog-close-padding0.5rem 1remClose button padding.
--dialog-close-border-width1pxClose border width.
--dialog-close-border-colorcurrentColorClose border color.
--dialog-close-border-radius0Close button corner rounding.
--dialog-outline-width-focus2pxFocus ring width.
--dialog-outline-color-focuscurrentColorFocus ring color.
--dialog-outline-offset-focus2pxFocus ring offset.

Accessibility

  • DialogContent renders a native <dialog> with role="dialog" automatically.
  • showModal() creates a native focus trap — keyboard focus is locked inside the dialog while open.
  • Pressing Escape fires a native close event, which this component handles by calling setOpen(false).
  • Provide aria-label or aria-labelledby on DialogContent to label the dialog for screen readers.
Last updated on