Installation
pnpm i cva@beta
npm i cva@beta
yarn add cva@beta
bun add cva@beta
Tailwind CSS
If you’re a Tailwind user, here are some additional (optional) steps to get the most out of cva
:
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
.vscode/settings.json
:.vscode/settings.json {"tailwindCSS.experimental.classRegex": [["cva\\(((?:[^()]|\\([^()]*\\))*)\\)", "[\"'`]?([^\"'`]+)[\"'`]?"],["cx\\(((?:[^()]|\\([^()]*\\))*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]]}
Add the following to your .zed/settings.json
:
{ "lsp": { "tailwindcss-language-server": { "settings": { "experimental": { "classRegex": [ ["cva\\(((?:[^()]|\\([^()]*\\))*)\\)", "[\"'`]?([^\"'`]+)[\"'`]?"], ["cx\\(((?:[^()]|\\([^()]*\\))*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"] ] } } } }}
-
Add the following configuration:
require 'lspconfig'.tailwindcss.setup({settings = {tailwindCSS = {experimental = {classRegex = {{ "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
{"experimental": {"classRegex": [["cva\\(((?:[^()]|\\([^()]*\\))*)\\)", "[\"'`]?([^\"'`]+)[\"'`]?"],["cx\\(((?:[^()]|\\([^()]*\\))*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]]}}
Handling Style Conflicts
If you want to merge Tailwind CSS classes without conflicts, you may wish to roll-your-own cva
with the tailwind-merge
package:
Example with tailwind-merge
import { defineConfig } from "cva";import { twMerge } from "tailwind-merge";
export const { cva, cx, compose } = defineConfig({ hooks: { onComplete: (className) => twMerge(className), },});
import { cx, cva } from "../cva.config";
export const button = cva({ // 1. `twMerge` strips out `bg-gray-200`… base: "font-semibold bg-gray-200 border rounded", variants: { intent: { // 2. …as variant `bg-*` values take precedence primary: "bg-blue-500 text-white border-transparent hover:bg-blue-600", secondary: "bg-white text-gray-800 border-gray-400 hover:bg-gray-100", }, } defaultVariants: { intent: "primary", },});
button();// => "font-semibold border rounded bg-blue-500 text-white border-transparent hover:bg-blue-600 text-base py-2 px-4 uppercase"
cx("bg-gray-200", "bg-blue-500");// => "bg-blue-500"