Files
2026-05-27 23:47:53 +01:00

3.0 KiB

Sheet Variants (cva config)

Purpose

sheetOverlayVariants, sheetContentVariants, sheetHeaderVariants, sheetFooterVariants, sheetTitleVariants, sheetDescriptionVariants, and sheetCloseButtonVariants are the cva configurations powering every <Sheet> slot. They are split from sheet.tsx into their own module so an ejected source copy under npx shadcn@latest add @suaveplan/sheet keeps the cva configurations in a dedicated file. Theme overrides flow through useThemedVariants("Sheet<Slot>").

The content cva is the only slot with a variant axis (side); all other slots are layout-only so consumers can compose freely.

Features

  • Overlay: fixed inset-0 bg-black/80 with fade animations driven by Radix's data-state.
  • Content: four sides (top, right, bottom, left) with matching slide-in/slide-out animations and edge anchoring.
  • start-0 / end-0 (logical properties) on left/right so RTL flips automatically.
  • Header / footer / title / description: layout-only utilities matching the shadcn upstream sheet recipe.
  • Close button: pinned at end-4 top-4 (logical), focus-ring + opacity hover.
  • motion-reduce:animate-none motion-reduce:transition-none on the content so the slide collapses under reduced-motion.

Usage: Basic Example

import { sheetContentVariants, sheetTitleVariants } from "@suaveplan/react-ui";

const contentClassName = sheetContentVariants({ side: "right" });
const titleClassName = sheetTitleVariants();

Usage: Advanced Example

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

export function CustomSidePanel() {
    return (
        <div
            role="dialog"
            aria-modal="true"
            className={cn(
                sheetContentVariants({ side: "left" }),
                "border-l-4 border-primary"
            )}
        >
            …
        </div>
    );
}

API Reference

sheetOverlayVariants(): string

Returns the overlay backdrop classes; takes no arguments.

sheetContentVariants(props?: { side?: "top" | "right" | "bottom" | "left" }): string

Returns the panel classes. Omitted side falls back to defaultVariants.side = "right".

sheetHeaderVariants(): string / sheetFooterVariants(): string / sheetTitleVariants(): string / sheetDescriptionVariants(): string / sheetCloseButtonVariants(): string

Each returns a single class string. None take arguments.

Implementation Notes

  • The left and right side classes use logical properties (start-0 / end-0 and border-s / border-e) so the panel anchors correctly in both LTR and RTL — RTL automatically flips start ↔ end via the CSS spec.
  • The chassis NEVER assigns a numeric z-index. Radix's portal hosts the content above all page content via DOM placement.
  • The slide-in/out class names (slide-in-from-top, slide-out-to-right, …) require the consumer's Tailwind setup to load tailwindcss-animate — the chassis ships this via @suaveplan/react-ui/styles/global.css.