Skip to content
DesignOSby h4rithd
ui / overlay

Dialog

A native modal dialog with backdrop dismissal and structured regions.

PREVIEW READY
LIVE PREVIEWDARK / LIGHT COMPATIBLE
INSTALL / SOURCE REGISTRY

Add Dialog to your project

The command adds the component source and its DesignOS base dependency.

$pnpm dlx shadcn@latest add https://designos.h4rithd.com/r/dialog.json
registry/default/ui/dialog.tsx
"use client"

import * as React from "react"
import { X } from "lucide-react"
import { clsx as cn } from "clsx"
import "@/components/designos/designos.css"

export type DialogProps = { trigger: React.ReactNode; title: React.ReactNode; description?: React.ReactNode; children: React.ReactNode; footer?: React.ReactNode; className?: string }

export function Dialog({ trigger, title, description, children, footer, className }: DialogProps) {
  const ref = React.useRef<HTMLDialogElement>(null)
  const titleId = React.useId()
  const descriptionId = React.useId()
  const close = () => ref.current?.close()
  return <>
    <button type="button" className="dos-button dos-button--secondary" onClick={() => ref.current?.showModal()}>{trigger}</button>
    <dialog ref={ref} className={cn("dos-dialog", className)} aria-labelledby={titleId} aria-describedby={description ? descriptionId : undefined} onClick={(event) => { if (event.target === ref.current) close() }}>
      <header className="dos-dialog__header"><div><h2 id={titleId} className="dos-card__title">{title}</h2>{description && <p id={descriptionId} className="dos-card__description">{description}</p>}</div><button className="dos-icon-button dos-button--ghost" aria-label="Close dialog" onClick={close}><X aria-hidden="true" /></button></header>
      <div className="dos-dialog__body">{children}</div>
      {footer && <footer className="dos-dialog__footer">{footer}</footer>}
    </dialog>
  </>
}

Component contract

  • Source-owned after installation
  • Dark and light theme variables
  • Keyboard and visible-focus behavior
  • Reduced-motion fallback
  • Responsive from 320px upward
  • IBM Plex Sans + JetBrains Mono hierarchy