Files
skills/docs/ui/react/react-ui/src/components/dialog/dialog.variants.md
2026-05-29 08:20:56 +01:00

3.4 KiB

Dialog Variants (cva config)

Purpose

dialogOverlayVariants, dialogContentVariants, dialogHeaderVariants, dialogFooterVariants, dialogTitleVariants, dialogDescriptionVariants, and dialogCloseButtonVariants are the cva (class-variance-authority) configurations powering every <Dialog> slot. They are split from dialog.tsx into their own module so an ejected source copy under npx shadcn@latest add @suaveplan/dialog keeps the cva configurations in a dedicated file. Theme overrides flow through useThemedVariants("Dialog<Slot>").

The overlay and content cva carry the open/close animation classes; the structural slots (header/footer/title/description) carry layout-only classes so consumers can compose visually rich variations without escaping the cva surface.

Features

  • Overlay: fixed inset-0 bg-black/80 with data-[state=open]:animate-in data-[state=closed]:animate-out keyed off Radix's data-state attribute.
  • Content: centred panel via translate-x-[-50%] translate-y-[-50%], four sizes (sm → max-w-sm, default → max-w-lg, lg → max-w-2xl, xl → max-w-4xl), shadow, sm-rounded.
  • Header: flex column, text-center sm:text-start so RTL locales align correctly on small screens.
  • Footer: flex column-reverse stacking on small screens, flex row with end-justify above sm.
  • Title: large semibold heading; tracking tightened.
  • Description: muted-foreground text-sm.
  • Close button: pinned at end-4 top-4 (logical property — flips automatically in RTL); focus:ring-2, disabled:pointer-events-none, motion-reduce:transition-none.
  • NEVER carries a numeric z-index (Radix portals handle stacking).

Usage: Basic Example

import {
    dialogContentVariants,
    dialogTitleVariants,
} from "@suaveplan/react-ui";

const contentClassName = dialogContentVariants({ size: "lg" });
const titleClassName = dialogTitleVariants();

Usage: Advanced Example

import { dialogContentVariants, cn } from "@suaveplan/react-ui";

export function CustomPanel() {
    return (
        <div
            role="dialog"
            aria-modal="true"
            className={cn(
                dialogContentVariants({ size: "xl" }),
                "border-2 border-primary"
            )}
        >
            …
        </div>
    );
}

API Reference

dialogOverlayVariants(): string

Returns the overlay backdrop classes; takes no arguments.

dialogContentVariants(props?: { size?: "sm" | "default" | "lg" | "xl" }): string

Returns the panel classes. Omitted size falls back to defaultVariants.size = "default".

dialogHeaderVariants(): string / dialogFooterVariants(): string / dialogTitleVariants(): string / dialogDescriptionVariants(): string / dialogCloseButtonVariants(): string

Each returns a single class string suitable for use inside cn(...) chains. None take arguments — the layout slots are not parameterised by design.

Implementation Notes

  • The cva uses motion-reduce:animate-none on the overlay AND content so the entire open/close transition collapses for prefers-reduced-motion: reduce. Consumers can layer their own additional motion-reduce overrides via cn(...) if they want a more elaborate fall-back.
  • Per the shadcn skill rule, the cva NEVER assigns a numeric z-index. Radix's <Portal> mounts the overlay + content into the document body so stacking is implicit.
  • The close-button cva uses logical properties (end-4) rather than right-4 so RTL flips for free.