RadCN
Overlaysreadycomponentready

Dialog

A modal dialog primitive with trigger, content, title, description, footer, and dismiss controls.

Importimport { Dialog, DialogContent, DialogTrigger } from 'radcn/dialog'
Preview

Live package example

Render the upstream edit-profile Dialog and share-link Dialog examples with native form, labelled inputs, read-only link input, and explicit close actions.

Demo and Close Button

Render the upstream edit-profile Dialog and share-link Dialog examples with native form, labelled inputs, read-only link input, and explicit close actions.

Preview
import {
  Dialog,
  DialogClose,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogOverlay,
  DialogPortal,
  DialogTitle,
  DialogTrigger,
} from 'radcn/dialog'
import { Input } from 'radcn/input'
import { Label } from 'radcn/label'

export function DialogPreview() {
  return (
    <>
      <Dialog defaultOpen={true} id="profile-dialog">
        <DialogTrigger class="radcn-button radcn-button--outline">
          Open Dialog
        </DialogTrigger>
        <DialogPortal>
          <DialogOverlay />
          <DialogContent class="radcn-docs-dialog-demo-content" style="width:min(100%,425px);">
            <form method="post">
              <DialogHeader>
                <DialogTitle>Edit profile</DialogTitle>
                <DialogDescription>
                  Make changes to your profile here. Click save when you're done.
                </DialogDescription>
              </DialogHeader>
              <div style="display:grid;gap:1rem;">
                <Label for="name-1">Name</Label>
                <Input id="name-1" name="name" value="Pedro Duarte" />
                <Label for="username-1">Username</Label>
                <Input id="username-1" name="username" value="@peduarte" />
              </div>
              <DialogFooter>
                <DialogClose class="radcn-button radcn-button--outline">Cancel</DialogClose>
                <button class="radcn-button radcn-button--default" type="submit">
                  Save changes
                </button>
              </DialogFooter>
            </form>
          </DialogContent>
        </DialogPortal>
      </Dialog>

      <Dialog defaultOpen={true} id="share-dialog">
        <DialogTrigger class="radcn-button radcn-button--outline">Share</DialogTrigger>
        <DialogPortal>
          <DialogOverlay />
          <DialogContent class="radcn-docs-dialog-close-button-content" style="width:min(100%,448px);">
          <DialogHeader>
            <DialogTitle>Share link</DialogTitle>
            <DialogDescription>
              Anyone who has this link will be able to view this.
            </DialogDescription>
          </DialogHeader>
            <Label class="sr-only" for="share-link">Link</Label>
            <Input
              id="share-link"
              readOnly
              value="https://ui.shadcn.com/docs/installation"
            />
          <DialogFooter class="radcn-docs-dialog-footer-start" style="justify-content:flex-start;">
            <DialogClose class="radcn-button radcn-button--secondary">Close</DialogClose>
          </DialogFooter>
        </DialogContent>
      </DialogPortal>
    </Dialog>
    </>
  )
}

Installation

Intended future install command. RadCN is private and not published to npm yet, so this snippet documents the target user-facing API rather than something external consumers can run today.

pnpm add radcn # intended future package
import { Dialog, DialogContent, DialogTrigger } from 'radcn/dialog'

Theming

RadCN tokens read the resolved theme from the document. Store the user's preference separately, then resolve system preferences to a concrete light or dark theme before setting package tokens.

<html data-radcn-theme-mode="system" data-radcn-theme="dark">
  ...
</html>

Accessibility

  • Enhanced dialogs assign dialog roles, aria-labelledby, aria-describedby, focus movement, Escape handling, and scroll locking.
  • Titles and descriptions are separate parts so accessible relationships can be created when enhanced.
  • Dismiss buttons are native buttons and remain visible in the server-rendered markup.

Customization

  • Overlay, content, header, footer, title, description, trigger, and close parts all expose RadCN classes and data hooks.
  • Use CSS variables and part classes to tune surface, shadow, radius, and spacing without replacing the primitive.
  • DialogTrigger and DialogClose are native buttons, so shadcn asChild Button composition maps to Button classes or app-owned styling on the Dialog part.
  • Input, Label, Button, native form shells, sr-only labels, read-only fields, and share-link presentation remain composed surfaces outside Dialog.

Remix 3 Notes

  • RadCN separates server markup from browser enhancement through enhanceDialog instead of depending on React state.
  • React open/onOpenChange, Radix DialogPrimitive, className, data-slot, cn, Tailwind utilities, XIcon, and lucide-react are upstream implementation details rather than RadCN Dialog dependencies.
  • DialogFooter showCloseButton is an upstream convenience API that the active examples do not use; RadCN composes explicit DialogClose actions in the footer.
  • The share-link example displays a read-only URL only. RadCN does not add copy-to-clipboard behavior for this row.
  • The docs preview keeps hidden dialog content inspectable so users can review styling; isolated fixture tests prove runtime focus and dismissal behavior.
  • Vendor source remains read-only evidence and is not imported by RadCN.