Meet Frontfriend.Your brand. Your rules. Your agents, connected.Explore what’s new

Dialog

A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.

Interactive preview

Rendered from the shared Frontfriend stories with React Base, the same preview Studio shows. Styling comes from your Design System; the code below is native to Radix UI.

Installation

Complete project setup first. Your configuration must select react/radix and include your Design System ID.

pnpm exec frontfriend download dialog -f react --primitive radix

Review dependencies reported by the downloader and keep your source changes in version control.

Usage

import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogBody,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
function DialogDemo({
  align,
  padding = true,
  closeIcon,
  height,
  width,
  overlay,
  closeOnOutside,
}: {
  align?: "end" | "justify" | "start" | "stretch";
  padding?: boolean;
  closeIcon?: boolean;
  width?: "xs" | "sm" | "md" | "lg" | "3xl" | "5xl" | "full" | "fit";
  height?: "full" | "auto";
  overlay?: boolean;
  closeOnOutside?: boolean;
}) {
  return (
    <Dialog overlay={overlay}>
      <DialogTrigger asChild>
        <Button variant="tertiary">Open Dialog</Button>
      </DialogTrigger>
      <DialogContent
        height={height}
        width={width}
        closeOnOutside={closeOnOutside}
      >
        <DialogHeader closeIcon={closeIcon}>
          <DialogTitle>Dialog Title</DialogTitle>
          <DialogDescription>
            Make changes to your profile here. Click save when you're done.
          </DialogDescription>
        </DialogHeader>
        <DialogBody padding={padding} className="grid gap-4">
          <p>
            Velit mollit eu amet ullamco ad. Est do enim sunt officia id ullamco
            consectetur tempor eiusmod sit. Fugiat eiusmod veniam velit fugiat
            ipsum Lorem id eiusmod tempor est. Ex in Lorem occaecat magna
            eiusmod eiusmod dolor nisi voluptate incididunt eiusmod deserunt
            cupidatat cillum. Ad Lorem laboris aute commodo ullamco ipsum enim
            id incididunt dolor. Irure ut non aliqua fugiat mollit voluptate
            aliquip aliqua voluptate consectetur quis fugiat. Eu pariatur
            incididunt adipisicing elit sint fugiat dolore mollit.
          </p>
        </DialogBody>
        <DialogFooter align={align}>
          <Button type="submit" variant="tertiary" className="ml-0">
            Cancel
          </Button>
          <Button type="submit">Save changes</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
<DialogDemo align="end" padding closeIcon overlay closeOnOutside height="auto" />;

Controlled dialogs

Control the open state through the selected target’s native API, as the examples show. Close only after a successful asynchronous action, and preserve the user’s input when validation fails.

Keep the title and description in the dialog composition. A complex form may need explicit initial focus and an associated error summary; test it in your application.

Accessibility

  • Include an accessible title and a useful description.
  • Check initial focus, focus containment and focus restoration.
  • Test Escape and outside dismissal in the real product context.
  • Use an alert dialog for decisions that require explicit acknowledgement; do not silently change a dialog’s role.

Controlled state

Control open and onOpenChange on Dialog.

Examples

Default

import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogBody,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
function DialogDemo({
  align,
  padding = true,
  closeIcon,
  height,
  width,
  overlay,
  closeOnOutside,
}: {
  align?: "end" | "justify" | "start" | "stretch";
  padding?: boolean;
  closeIcon?: boolean;
  width?: "xs" | "sm" | "md" | "lg" | "3xl" | "5xl" | "full" | "fit";
  height?: "full" | "auto";
  overlay?: boolean;
  closeOnOutside?: boolean;
}) {
  return (
    <Dialog overlay={overlay}>
      <DialogTrigger asChild>
        <Button variant="tertiary">Open Dialog</Button>
      </DialogTrigger>
      <DialogContent
        height={height}
        width={width}
        closeOnOutside={closeOnOutside}
      >
        <DialogHeader closeIcon={closeIcon}>
          <DialogTitle>Dialog Title</DialogTitle>
          <DialogDescription>
            Make changes to your profile here. Click save when you're done.
          </DialogDescription>
        </DialogHeader>
        <DialogBody padding={padding} className="grid gap-4">
          <p>
            Velit mollit eu amet ullamco ad. Est do enim sunt officia id ullamco
            consectetur tempor eiusmod sit. Fugiat eiusmod veniam velit fugiat
            ipsum Lorem id eiusmod tempor est. Ex in Lorem occaecat magna
            eiusmod eiusmod dolor nisi voluptate incididunt eiusmod deserunt
            cupidatat cillum. Ad Lorem laboris aute commodo ullamco ipsum enim
            id incididunt dolor. Irure ut non aliqua fugiat mollit voluptate
            aliquip aliqua voluptate consectetur quis fugiat. Eu pariatur
            incididunt adipisicing elit sint fugiat dolore mollit.
          </p>
        </DialogBody>
        <DialogFooter align={align}>
          <Button type="submit" variant="tertiary" className="ml-0">
            Cancel
          </Button>
          <Button type="submit">Save changes</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
<DialogDemo align="end" padding closeIcon overlay closeOnOutside height="auto" />;

Scrollable

import {
  Dialog,
  DialogTrigger,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogBody,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
function DialogScrollableDemo({
  align,
  padding = true,
  closeIcon,
  height,
  width,
  overlay,
  closeOnOutside,
}: {
  align?: "end" | "justify" | "start" | "stretch";
  padding?: boolean;
  closeIcon?: boolean;
  width?: "xs" | "sm" | "md" | "lg" | "3xl" | "5xl" | "full" | "fit";
  height?: "full" | "auto";
  overlay?: boolean;
  closeOnOutside?: boolean;
}) {
  return (
    <Dialog overlay={overlay}>
      <DialogTrigger asChild>
        <Button variant="tertiary">Open Dialog</Button>
      </DialogTrigger>
      <DialogContent
        height={height}
        width={width}
        closeOnOutside={closeOnOutside}
      >
        <DialogHeader closeIcon={closeIcon}>
          <DialogTitle>Dialog Title</DialogTitle>
          <DialogDescription>
            Make changes to your profile here. Click save when you're done.
          </DialogDescription>
        </DialogHeader>
        <DialogBody padding={padding} className="grid gap-4">
          <p>
            Velit mollit eu amet ullamco ad. Est do enim sunt officia id ullamco
            consectetur tempor eiusmod sit. Fugiat eiusmod veniam velit fugiat
            ipsum Lorem id eiusmod tempor est. Ex in Lorem occaecat magna
            eiusmod eiusmod dolor nisi voluptate incididunt eiusmod deserunt
            cupidatat cillum. Ad Lorem laboris aute commodo ullamco ipsum enim
            id incididunt dolor. Irure ut non aliqua fugiat mollit voluptate
            aliquip aliqua voluptate consectetur quis fugiat. Eu pariatur
            incididunt adipisicing elit sint fugiat dolore mollit.
          </p>
          <p>
            Velit mollit eu amet ullamco ad. Est do enim sunt officia id ullamco
            consectetur tempor eiusmod sit. Fugiat eiusmod veniam velit fugiat
            ipsum Lorem id eiusmod tempor est. Ex in Lorem occaecat magna
            eiusmod eiusmod dolor nisi voluptate incididunt eiusmod deserunt
            cupidatat cillum. Ad Lorem laboris aute commodo ullamco ipsum enim
            id incididunt dolor. Irure ut non aliqua fugiat mollit voluptate
            aliquip aliqua voluptate consectetur quis fugiat. Eu pariatur
            incididunt adipisicing elit sint fugiat dolore mollit.
          </p>
          <p>
            Velit mollit eu amet ullamco ad. Est do enim sunt officia id ullamco
            consectetur tempor eiusmod sit. Fugiat eiusmod veniam velit fugiat
            ipsum Lorem id eiusmod tempor est. Ex in Lorem occaecat magna
            eiusmod eiusmod dolor nisi voluptate incididunt eiusmod deserunt
            cupidatat cillum. Ad Lorem laboris aute commodo ullamco ipsum enim
            id incididunt dolor. Irure ut non aliqua fugiat mollit voluptate
            aliquip aliqua voluptate consectetur quis fugiat. Eu pariatur
            incididunt adipisicing elit sint fugiat dolore mollit.
          </p>
          <p>
            Velit mollit eu amet ullamco ad. Est do enim sunt officia id ullamco
            consectetur tempor eiusmod sit. Fugiat eiusmod veniam velit fugiat
            ipsum Lorem id eiusmod tempor est. Ex in Lorem occaecat magna
            eiusmod eiusmod dolor nisi voluptate incididunt eiusmod deserunt
            cupidatat cillum. Ad Lorem laboris aute commodo ullamco ipsum enim
            id incididunt dolor. Irure ut non aliqua fugiat mollit voluptate
            aliquip aliqua voluptate consectetur quis fugiat. Eu pariatur
            incididunt adipisicing elit sint fugiat dolore mollit.
          </p>
        </DialogBody>
        <DialogFooter align={align}>
          <Button type="submit" variant="tertiary" className="ml-0">
            Cancel
          </Button>
          <Button type="submit">Save changes</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
<DialogScrollableDemo align="end" padding closeIcon />;

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by Radix UI.

Dialog

Prop Type Default Description
overlay boolean true

DialogBody

Prop Type Default Description
padding boolean true

DialogFooter

Prop Type Default Description
align "end" | "justify" | "start" | "stretch" "end"
showCloseButton boolean false

DialogHeader

Prop Type Default Description
closeIcon boolean false

Configuration determines the actual classes and available styling hooks. See Theming & component configuration before introducing a repeated local override.