Installation
pnpm i class-variance-authoritynpm i class-variance-authorityyarn add class-variance-authoritybun add class-variance-authoritydeno add class-variance-authorityDo I really have to write such a long package name?
Unfortunately, for a little bit longer, yes. Originally, the plan was to publish the package as cva, but this name was taken and marked as a “placeholder”.
On 2022/02/16, GitHub transferred NPM ownership of cva to Joe Bell. This shorter name will be used from v1 onwards.
In the meantime, you can always alias the package for your convenience…
-
Alias the package with
npm installTerminal window npm i cva@npm:class-variance-authority -
Then import like so:
import { cva } from "cva";// …
Tailwind CSS
Section titled “Tailwind CSS”If you’re a Tailwind user, here are some additional (optional) steps to get the most out of cva:
IntelliSense
Section titled “IntelliSense”You can enable autocompletion inside cva using the steps below:
-
Install the “Tailwind CSS IntelliSense” Visual Studio Code extension
-
Add the following to your
settings.json:
{ "tailwindCSS.classFunctions": ["cva", "cx"]}Add the following to your .zed/settings.json:
{ "lsp": { "tailwindcss-language-server": { "settings": { "classFunctions": ["cva", "cx"], } } }}-
Add the following configuration:
require 'lspconfig'.tailwindcss.setup({ settings = { tailwindCSS = { classFunctions = { "cva", "cx" }, }, },})-
Check the version. Available for WebStorm 2023.1 and later
-
Open the settings. Go to Languages and Frameworks | Style Sheets | Tailwind CSS
-
Add the following to your tailwind configuration
{ "classFunctions": ["cva", "cx"]}Handling Style Conflicts
Section titled “Handling Style Conflicts”Although cva’s API is designed to help you avoid styling conflicts, there’s still a small margin of error.
If you’re keen to lift that burden altogether, check out the wonderful tailwind-merge package.
For bulletproof components, wrap your cva component with twMerge.
Example with tailwind-merge
import { cva, type VariantProps } from "class-variance-authority";import { twMerge } from "tailwind-merge";
const buttonVariants = cva(["your", "base", "classes"], { variants: { intent: { primary: ["your", "primary", "classes"], }, }, defaultVariants: { intent: "primary", },});
export interface ButtonVariants extends VariantProps<typeof buttonVariants> {}
export const button = (variants: ButtonVariants) => twMerge(buttonVariants(variants));