Vesyl UI

Dialog

A modal overlay that interrupts the flow to confirm an action or collect a small amount of input. Built on base-ui Dialog — focus trapping, scroll locking, Escape-to-close, and ARIA wiring come for free.

Compose the parts: Dialog (root, owns the open state), DialogTrigger (the element that opens it), and DialogContent (the popup — it renders the backdrop, the centered panel, and a corner close button). Inside the content, lay out DialogHeader (DialogTitle + DialogDescription) and DialogFooter (the actions). DialogClose dismisses the dialog from anywhere inside it. For destructive confirmations, reach for AlertDialog instead — it forces an explicit choice and traps Escape.

Basic

A trigger plus a content panel with a title, description, and a footer. Following the VESYL dialog convention, the cancel action sits on the left and the primary (here destructive) action on the right. Wrap each part’s underlying element with render so a Button becomes the trigger and the close actions.

With a form

Dialogs are a natural home for short forms. Put the fields between the header and footer; the panel grows to fit, and DialogContent lays its children out as a gap-6 grid so sections stay evenly spaced.

Wider content

DialogContent caps at sm:max-w-md by default. Override the width with a className (e.g. sm:max-w-2xl) when the body is a list, table, or multi-column layout that needs the room.

Hiding the close button

Pass showCloseButton={false} to DialogContent to drop the corner ✕ — useful for flows that should only exit through a footer action. DialogFooter has a matching showCloseButton that appends a ready-made outline “Close” button so you don’t have to wire one up.

Controlled

Dialog is uncontrolled by default — DialogTrigger and DialogClose toggle it for you. To drive it yourself (open it from a menu item, close it only after a mutation resolves), pass open and onOpenChange. The exported DialogProps type captures that pair for component props.

import { type DialogProps } from "@vesyl/ui-next";

function DeleteBoxDialog({ box, open, onOpenChange }: DialogProps & { box: Box }) {
  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent>{/* … */}</DialogContent>
    </Dialog>
  );
}

Reference

Dialog

Root container; owns the open state. Extends base-ui Dialog.Root props.

PropTypeDefaultDescription
defaultOpenbooleanfalseInitial open state (uncontrolled)
openbooleanOpen state (controlled)
onOpenChange(open: boolean) => voidFires when the open state should change
modalbooleantrueTrap focus and block interaction behind it

DialogTrigger

The element that opens the dialog. Extends base-ui Dialog.Trigger props.

PropTypeDefaultDescription
renderReact.ReactElementRender as another element, e.g. render={<Button />}

DialogContent

The popup. Renders the backdrop, the centered panel, and (by default) a corner close button. Extends base-ui Dialog.Popup props.

PropTypeDefaultDescription
showCloseButtonbooleantrueRender the ✕ button in the top-right corner
showBackdropbooleantrueRender the dimming overlay; set false for dialogs nested in a Sheet
classNamestringMerged onto the panel — override the sm:max-w-md width cap here

DialogHeader

Stacks the title and description with a small gap. Plain div.

PropTypeDefaultDescription
classNamestringMerged onto the div

DialogTitle

The accessible heading, wired to the dialog via ARIA. Extends base-ui Dialog.Title props.

PropTypeDefaultDescription
classNamestringMerged onto the title

DialogDescription

Supporting copy under the title, wired to the dialog via ARIA. Links inside it are auto-underlined. Extends base-ui Dialog.Description props.

PropTypeDefaultDescription
classNamestringMerged onto the description

DialogFooter

Lays out actions — stacked on mobile, right-aligned in a row on sm+. Plain div.

PropTypeDefaultDescription
showCloseButtonbooleanfalseAppend a ready-made outline “Close” button that dismisses
classNamestringMerged onto the div

DialogClose

Dismisses the dialog when activated. Extends base-ui Dialog.Close props.

PropTypeDefaultDescription
renderReact.ReactElementRender as another element, e.g. render={<Button />}

DialogProps

Exported helper type for controlled-dialog component props.

FieldTypeDescription
openbooleanControlled open state
onOpenChange(open: boolean) => voidCalled when the open state should change