Skip to content

Composing Components

Any number of cva components can be shallow merged into a single component via the compose method:

// components/card.ts
import { cva, compose } from "cva";

const box = cva({
  base: "box box-border",
  variants: {
    margin: { 0: "m-0", 2: "m-2", 4: "m-4", 8: "m-8" },
    padding: { 0: "p-0", 2: "p-2", 4: "p-4", 8: "p-8" },
  },
  defaultVariants: {
    margin: 0,
    padding: 0,
  },
});

const root = cva({
  base: "card border-solid border-slate-300 rounded",
  variants: {
    shadow: {
      md: "drop-shadow-md",
      lg: "drop-shadow-lg",
      xl: "drop-shadow-xl",
    },
  },
});

export interface CardProps extends VariantProps<typeof card> {}
export const card = compose(box, root);

card({ margin: 2, shadow: "md" });
// => "box box-border m-2 card border-solid border-slate-300 rounded drop-shadow-md"
card({ margin: 2, shadow: "md", class: "adhoc-class" });
// => "box box-border m-2 card border-solid border-slate-300 rounded drop-shadow-md adhoc-class"