Variants
Creating Variants
To kick things off, let’s build a “basic” button
component, using cva
to handle our variant’s classes
import { cva } from "cva";
const button = cva({ base: "rounded border font-semibold", // **or** // base: ["font-semibold", "border", "rounded"], variants: { intent: { primary: "border-transparent bg-blue-500 text-white hover:bg-blue-600", // **or** // primary: [ // "bg-blue-500", // "text-white", // "border-transparent", // "hover:bg-blue-600", // ], secondary: "border-gray-400 bg-white text-gray-800 hover:bg-gray-100", }, size: { small: "px-2 py-1 text-sm", medium: "px-4 py-2 text-base", }, }, compoundVariants: [ { intent: "primary", size: "medium", class: "uppercase", // **or** if you're a React.js user, `className` may feel more consistent: // className: "uppercase" }, ], defaultVariants: { intent: "primary", size: "medium", },});
button();// => "font-semibold border rounded bg-blue-500 text-white border-transparent hover:bg-blue-600 text-base py-2 px-4 uppercase"
button({ intent: "secondary", size: "small" });// => "font-semibold border rounded bg-white text-gray-800 border-gray-400 hover:bg-gray-100 text-sm py-1 px-2"
Compound Variants
Variants that apply when multiple other variant conditions are met.
import { cva } from "cva";
const button = cva({ base: "…", variants: { intent: { primary: "…", secondary: "…" }, size: { small: "…", medium: "…" }, }, compoundVariants: [ // Applied via: // `button({ intent: "primary", size: "medium" })` { intent: "primary", size: "medium", class: "…", }, ],});
Targeting Multiple Variant Conditions
import { cva } from "cva";
const button = cva({ base: "…", variants: { intent: { primary: "…", secondary: "…" }, size: { small: "…", medium: "…" }, }, compoundVariants: [ // Applied via: // `button({ intent: "primary", size: "medium" })` // or // `button({ intent: "secondary", size: "medium" })` { intent: ["primary", "secondary"], size: "medium", class: "…", }, ],});
Disabling Variants
Want to disable a variant completely? Provide an option with a value of null
.
If you’re stuck on naming, we recommend setting an explicit "unset"
option (similar to the CSS keyword).
import { cva } from "cva";
const button = cva({ base: "button", variants: { intent: { unset: null, primary: "button--primary", secondary: "button--secondary", }, },});
button({ intent: "unset" });// => "button"