Variants belong in cva

Reusable variants go in cva(); one-off sizes go in className.

From shadcn (Vercel plugin): Extending Components; Avatar has no size prop.

Pick a variant, get classes

Pick a variant and size; cva resolves the classes.

variant
size
<Button>Preview

Avatar has no size prop

Try a size prop, then a className.

size propIgnored
40 × 40px
<Avatar>
classNameResizes
48 × 48px
<Avatar className="h-12 w-12">
<Avatar size="lg" />          // no such prop
<Avatar className="h-12 w-12"> // one-off size

Add a variant you own

Name it, pick a tone, then add it to cva.

New variantDraft

ui/button.tsxYou own it

Why it matters, pros and cons

Why it matters

You own the copied component, so its cva() table is yours to extend.

Pros

  • Change once, every call site follows.
  • Typos fail to compile via VariantProps.
  • className still covers the one-off.

Cons

  • Every variant is API surface to maintain.
  • Re-adding the component from the CLI overwrites edits.
  • className sizes drift once a size becomes a rule.