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 Reka UI.

Installation

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

pnpm exec frontfriend download dialog -f vue --primitive reka

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

Usage

<script setup lang="ts">
import { Dialog } from "@/components/ui/dialog";
import { DialogTrigger } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { DialogContent } from "@/components/ui/dialog";
import { DialogHeader } from "@/components/ui/dialog";
import { DialogTitle } from "@/components/ui/dialog";
import { DialogDescription } from "@/components/ui/dialog";
import { DialogBody } from "@/components/ui/dialog";
import { DialogFooter } from "@/components/ui/dialog";
import { DialogClose } from "@/components/ui/dialog";
import * as UI from "@/components/ui/dialog";

const Component = UI.Dialog;

const args = {
  "padding": true,
  "closeIcon": true,
  "closeOnOutside": true,
  "height": "auto",
  "width": "md",
  "align": "end",
} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown> & {
    height?: "auto" | "full";
    width?: "xs" | "sm" | "md" | "lg" | "3xl" | "5xl" | "full" | "fit";
    align?: "start" | "end" | "justify" | "stretch";
  };
</script>

<template>
  <Dialog
    ><DialogTrigger as-child><Button>Open Dialog</Button></DialogTrigger
    ><DialogContent
      :close-on-outside="args.closeOnOutside"
      :show-close-button="args.closeIcon"
      :height="args.height"
      :width="args.width"
      ><DialogHeader
        ><DialogTitle>Dialog Title</DialogTitle
        ><DialogDescription
          >Review your changes.</DialogDescription
        ></DialogHeader
      ><DialogBody :padding="args.padding">Review your changes.</DialogBody
      ><DialogFooter :align="args.align"
        ><DialogClose>Cancel</DialogClose></DialogFooter
      ></DialogContent
    ></Dialog
  >
</template>

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

Use v-model:open on Dialog.

Examples

Default

<script setup lang="ts">
import { Dialog } from "@/components/ui/dialog";
import { DialogTrigger } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { DialogContent } from "@/components/ui/dialog";
import { DialogHeader } from "@/components/ui/dialog";
import { DialogTitle } from "@/components/ui/dialog";
import { DialogDescription } from "@/components/ui/dialog";
import { DialogBody } from "@/components/ui/dialog";
import { DialogFooter } from "@/components/ui/dialog";
import * as UI from "@/components/ui/dialog";

const Component = UI.Dialog;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Dialog
    ><DialogTrigger as-child
      ><Button variant="outline">Edit Profile</Button></DialogTrigger
    ><DialogContent
      ><DialogHeader
        ><DialogTitle>Edit profile</DialogTitle
        ><DialogDescription
          >Make changes to your profile here. Click save when you're
          done.</DialogDescription
        ></DialogHeader
      ><DialogBody class="grid gap-4"
        ><p>Dialog content goes here.</p></DialogBody
      ><DialogFooter
        ><Button type="submit">Save changes</Button></DialogFooter
      ></DialogContent
    ></Dialog
  >
</template>

Scrollable

<script setup lang="ts">
import { Dialog } from "@/components/ui/dialog";
import { DialogTrigger } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { DialogScrollContent } from "@/components/ui/dialog";
import { DialogHeader } from "@/components/ui/dialog";
import { DialogTitle } from "@/components/ui/dialog";
import { DialogDescription } from "@/components/ui/dialog";
import { DialogBody } from "@/components/ui/dialog";
import { DialogFooter } from "@/components/ui/dialog";
import * as UI from "@/components/ui/dialog";

const Component = UI.Dialog;

const args = {

} satisfies Partial<
  InstanceType<typeof Component> extends { $props: infer Props } ? Props : {}
> &
  Record<string, unknown>;
</script>

<template>
  <Dialog
    ><DialogTrigger as-child
      ><Button variant="outline">Open Scrollable</Button></DialogTrigger
    ><DialogScrollContent class="max-w-md"
      ><DialogHeader
        ><DialogTitle>Terms of Service</DialogTitle
        ><DialogDescription
          >Please read the following before continuing.</DialogDescription
        ></DialogHeader
      ><DialogBody class="grid gap-4"
        ><p v-for="i in 8" :key="i">
          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.
        </p></DialogBody
      ><DialogFooter
        ><Button type="submit">Accept</Button></DialogFooter
      ></DialogScrollContent
    ></Dialog
  >
</template>

API reference

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

Dialog

Prop Type Default Description
overlay boolean —

DialogBody

Prop Type Default Description
class HTMLAttributes["class"] —
noPadding boolean —

DialogDescription

Prop Type Default Description
class HTMLAttributes["class"] —

DialogFooter

Prop Type Default Description
align "end" | "justify" | "start" | "stretch" —
class HTMLAttributes["class"] —
showCloseButton boolean —

DialogHeader

Prop Type Default Description
class HTMLAttributes["class"] —
closeIcon boolean —

DialogTitle

Prop Type Default Description
class HTMLAttributes["class"] —

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