Skip to content

Dialog ​

A fully accessible, headless Dialog (modal) component for React. Composed of multiple subcomponents for flexible usage.

Features ​

  • Accessible (focus trap, keyboard navigation, ARIA attributes)
  • Headless (no styles, fully customizable)
  • Composable API (Dialog, DialogOverlay, DialogContent, DialogTitle, DialogActions)
  • Context-powered hooks

Installation ​

bash
npm install react-headless-ui-kit

Usage ​

tsx
import {
  Dialog,
  DialogOverlay,
  DialogContent,
  DialogTitle,
  DialogActions,
  useDialog,
} from "react-headless-ui-kit";

function ExampleDialog() {
  const [open, setOpen] = useState(false);

  return (
    <>
      <button onClick={() => setOpen(true)}>Open dialog</button>
      <Dialog open={open} onClose={() => setOpen(false)}>
        <DialogOverlay
          style={{
            position: "fixed",
            inset: 0,
            background: "rgba(0,0,0,0.5)",
            display: "grid",
            placeItems: "center",
          }}
        >
          <DialogContent
            style={{
              background: "white",
              padding: "1rem",
              borderRadius: 8,
              maxWidth: 400,
              width: "100%",
            }}
          >
            <DialogTitle>Dialog Title</DialogTitle>
            <DialogContent>
              Dialog body content goes here.
            </DialogContent>
            <DialogActions
              style={{ marginTop: 16, display: "flex", gap: 8 }}
            >
              <button onClick={() => setOpen(false)}>Close</button>
            </DialogActions>
          </DialogContent>
        </DialogOverlay>
      </Dialog>
    </>
  );
}

API Reference ​

<Dialog /> ​

PropTypeDescription
openbooleanWhether the dialog is open
onClose() => voidCallback to close the dialog
childrenReactNodeDialog content
containerElement | nullPortal target (default: body)

<DialogOverlay /> ​

Wraps the dialog content and handles click outside to close.

PropTypeDescription
childrenReactNodeOverlay content

<DialogContent /> ​

Main dialog content container. Handles focus management and ARIA attributes.

PropTypeDescription
childrenReactNodeDialog content

<DialogTitle /> ​

Dialog title, linked via aria-labelledby.

PropTypeDescription
childrenReactNodeTitle text

<DialogActions /> ​

Container for dialog action buttons.

PropTypeDescription
childrenReactNodeAction buttons

useDialog() ​

Hook to access dialog context values inside subcomponents.

Return valueDescription
onCloseClose callback
onOpenOpen callback
openDialog open state
titleIdARIA title id
descriptionIdARIA description id

Accessibility ​

  • Focus is trapped inside the dialog when open.
  • Pressing Escape closes the dialog.
  • ARIA attributes are set for screen readers.

Customization ​

All components are unstyled. Use your own styles via className or style props.