Files
suaveplan/packages/ui/react/react-ui/src/components/dropdown-menu/dropdown-menu.variants.md
2026-05-27 23:47:53 +01:00

3.5 KiB

DropdownMenu Variants (cva config)

Purpose

dropdownMenuContentVariants, dropdownMenuItemVariants, dropdownMenuLabelVariants, dropdownMenuSeparatorVariants, dropdownMenuShortcutVariants, dropdownMenuCheckboxItemVariants, dropdownMenuRadioItemVariants, and dropdownMenuSubTriggerVariants are the cva (class-variance-authority) configurations powering every <DropdownMenu> slot. They are split from dropdown-menu.tsx into their own module so an ejected source copy under npx shadcn@latest add @suaveplan/dropdown-menu keeps the cva configurations in a dedicated file. Theme overrides flow through useThemedVariants("DropdownMenu<Slot>").

The Item / Label / SubTrigger cvas all carry an inset axis so consumers can align rows whether or not they include checkbox / radio indicators. The content cva carries the open/close animations keyed off Radix's data-state and data-side attributes.

Features

  • Content: min-w-[8rem] floating surface with side-aware slide-in animations and motion-reduce:animate-none.
  • Item: focus-bg lift via focus:bg-accent, disabled opacity, optional ps-8 inset gutter.
  • Label: semibold heading text, optional inset gutter.
  • Separator: -mx-1 my-1 h-px bg-border divider.
  • Shortcut: ms-auto text-xs tracking-widest text-muted-foreground row terminator.
  • Checkbox / Radio item: ps-8 pe-2 to leave space for the start-aligned indicator.
  • SubTrigger: open-state lifts background to data-[state=open]:bg-accent.

Usage: Basic Example

import {
    dropdownMenuContentVariants,
    dropdownMenuItemVariants,
} from "@suaveplan/react-ui";

const contentClassName = dropdownMenuContentVariants();
const itemClassName = dropdownMenuItemVariants({ inset: true });

Usage: Advanced Example

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

export function WideContent({
    children,
    className,
}: {
    children: React.ReactNode;
    className?: string;
}) {
    return (
        <div
            className={cn(
                dropdownMenuContentVariants(),
                "min-w-[16rem]",
                className
            )}
        >
            {children}
        </div>
    );
}

API Reference

dropdownMenuContentVariants(): string

Returns the floating surface class string. No arguments.

dropdownMenuItemVariants(props?: { inset?: boolean }): string

Returns the item class string. Defaults to { inset: false }.

dropdownMenuLabelVariants(props?: { inset?: boolean }): string

Returns the label class string. Defaults to { inset: false }.

dropdownMenuSeparatorVariants(): string

Returns the separator class string. No arguments.

dropdownMenuShortcutVariants(): string

Returns the shortcut class string. No arguments.

dropdownMenuCheckboxItemVariants(): string

Returns the checkbox item class string. No arguments.

dropdownMenuRadioItemVariants(): string

Returns the radio item class string. No arguments.

dropdownMenuSubTriggerVariants(props?: { inset?: boolean }): string

Returns the sub-trigger class string. Defaults to { inset: false }.

Implementation Notes

  • Per the shadcn skill rule, no numeric z-index is assigned anywhere — Radix portals handle stacking.
  • The check / dot indicators sit at start-2 (logical property) so they flip correctly in RTL.
  • motion-reduce:animate-none collapses the open/close animation for prefers-reduced-motion: reduce.
  • The Sub-trigger chevron carries ms-auto so the icon flips to the leading edge in RTL via the logical-margin property.