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 React Aria.

Installation

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

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

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

Usage

import {
  DialogTrigger,
  Dialog,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogBody,
  DialogFooter,
  DialogClose,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
const paragraph =
  "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.";
<DialogTrigger>
  <Button variant="tertiary">Open Dialog</Button>
  <Dialog
    height="auto"
    width="md"
    showCloseButton
    isDismissable
  >
    <DialogHeader>
      <DialogTitle>Dialog Title</DialogTitle>
      <DialogDescription>Review your changes.</DialogDescription>
    </DialogHeader>
    <DialogBody padding>
      <p>{paragraph}</p>
    </DialogBody>
    <DialogFooter align="end">
      <DialogClose>Cancel</DialogClose>
      <Button slot="close">Save changes</Button>
    </DialogFooter>
  </Dialog>
</DialogTrigger>;

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 isOpen and onOpenChange on the outer DialogTrigger.

Examples

Default

import {
  DialogTrigger,
  Dialog,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogBody,
  DialogFooter,
  DialogClose,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
const paragraph =
  "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.";
function Example({ scrollable = false }: { scrollable?: boolean }) {
  return (
    <DialogTrigger>
      <Button variant="tertiary">Open Dialog</Button>
      <Dialog height="auto">
        <DialogHeader>
          <DialogTitle>Dialog Title</DialogTitle>
          <DialogDescription>
            Make changes to your profile here.
          </DialogDescription>
        </DialogHeader>

        <DialogBody className="grid gap-4">
          {scrollable ? (
            Array.from({ length: 6 }, (_, index) => (
              <p key={index}>{paragraph}</p>
            ))
          ) : (
            <p>Your changes can be reviewed before saving.</p>
          )}
        </DialogBody>
        <DialogFooter>
          <DialogClose variant="tertiary">Cancel</DialogClose>
          <Button slot="close">Save changes</Button>
        </DialogFooter>
      </Dialog>
    </DialogTrigger>
  );
}
<Example />;

Scrollable

import {
  DialogTrigger,
  Dialog,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogBody,
  DialogFooter,
  DialogClose,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
const paragraph =
  "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.";
function Example({ scrollable = false }: { scrollable?: boolean }) {
  return (
    <DialogTrigger>
      <Button variant="tertiary">Open Dialog</Button>
      <Dialog height="auto">
        <DialogHeader>
          <DialogTitle>Dialog Title</DialogTitle>
          <DialogDescription>
            Make changes to your profile here.
          </DialogDescription>
        </DialogHeader>

        <DialogBody className="grid gap-4">
          {scrollable ? (
            Array.from({ length: 6 }, (_, index) => (
              <p key={index}>{paragraph}</p>
            ))
          ) : (
            <p>Your changes can be reviewed before saving.</p>
          )}
        </DialogBody>
        <DialogFooter>
          <DialogClose variant="tertiary">Cancel</DialogClose>
          <Button slot="close">Save changes</Button>
        </DialogFooter>
      </Dialog>
    </DialogTrigger>
  );
}
<Example scrollable />;

API reference

Frontfriend-owned props. Native HTML and inherited primitive props remain documented by React Aria.

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.