TypeScript
css-variants is built with TypeScript and provides complete type inference out of the box.
Type Inference
Section titled “Type Inference”Variant types are automatically inferred from your configuration:
import { cv } from 'css-variants'
const button = cv({ variants: { color: { primary: 'bg-blue-600', secondary: 'bg-gray-200', danger: 'bg-red-600', }, size: { sm: 'text-sm', md: 'text-base', lg: 'text-lg', }, },})
// TypeScript knows the valid optionsbutton({ color: 'primary' }) // ✓ Validbutton({ color: 'invalid' }) // ✗ Error: Type '"invalid"' is not assignablebutton({ size: 'xl' }) // ✗ Error: Type '"xl"' is not assignableExtracting Variant Types
Section titled “Extracting Variant Types”Use Parameters to extract the props type from a variant function:
const button = cv({ variants: { color: { primary: '...', secondary: '...' }, size: { sm: '...', md: '...', lg: '...' }, },})
// Extract the variant props typetype ButtonVariants = Parameters<typeof button>[0]// => {// color?: 'primary' | 'secondary'// size?: 'sm' | 'md' | 'lg'// className?: ClassValue// }Component Props
Section titled “Component Props”Combine variant props with HTML element props:
import { cv } from 'css-variants'
const buttonVariants = cv({ base: 'rounded font-medium', variants: { color: { primary: 'bg-blue-600 text-white', secondary: 'bg-gray-200 text-gray-900', }, size: { sm: 'px-3 py-1.5 text-sm', md: 'px-4 py-2 text-base', lg: 'px-6 py-3 text-lg', }, },})
type ButtonVariants = Parameters<typeof buttonVariants>[0]
// Combine with HTML button propstype ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & ButtonVariants
export function Button({ color, size, className, children, ...props}: ButtonProps) { return ( <button className={buttonVariants({ color, size, className })} {...props} > {children} </button> )}With Required Variants
Section titled “With Required Variants”Make specific variants required:
type ButtonVariants = Parameters<typeof buttonVariants>[0]
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & Omit<ButtonVariants, 'color'> & Required<Pick<ButtonVariants, 'color'>>
// Now color is required<Button color="primary">Click me</Button> // ✓<Button>Click me</Button> // ✗ Error: Property 'color' is missingSlot Variant Types
Section titled “Slot Variant Types”For slot variants, you can extract both props and slot names:
import { scv } from 'css-variants'
const card = scv({ slots: ['root', 'header', 'title', 'content', 'footer'], base: { root: 'rounded-lg border', header: 'p-4 border-b', title: 'text-lg font-semibold', content: 'p-4', footer: 'p-4 border-t', }, variants: { variant: { default: { root: 'border-gray-200' }, primary: { root: 'border-blue-200' }, }, },})
// Extract variant propstype CardVariants = Parameters<typeof card>[0]// => {// variant?: 'default' | 'primary'// classNames?: { root?: ClassValue, header?: ClassValue, ... }// }
// Extract slot namestype CardSlots = keyof ReturnType<typeof card>// => 'root' | 'header' | 'title' | 'content' | 'footer'Boolean Variants
Section titled “Boolean Variants”Boolean variants accept actual boolean values despite using string keys:
const checkbox = cv({ variants: { checked: { true: 'bg-blue-600', // String key false: 'bg-white', // String key }, disabled: { true: 'opacity-50', false: '', }, },})
// TypeScript accepts booleanscheckbox({ checked: true, disabled: false }) // ✓ Validcheckbox({ checked: 'true' }) // ✗ Error: Type 'string' is not assignable to type 'boolean'Type Utilities
Section titled “Type Utilities”NonNullable Variants
Section titled “NonNullable Variants”type ButtonVariants = Parameters<typeof button>[0]type RequiredVariants = NonNullable<ButtonVariants>Variant Keys
Section titled “Variant Keys”const button = cv({ variants: { color: { primary: '...', secondary: '...' }, size: { sm: '...', md: '...', lg: '...' }, },})
type VariantConfig = Parameters<typeof button>[0]type ColorOptions = NonNullable<VariantConfig>['color']// => 'primary' | 'secondary' | undefined
type SizeOptions = NonNullable<VariantConfig>['size']// => 'sm' | 'md' | 'lg' | undefinedIDE Support
Section titled “IDE Support”css-variants provides excellent IDE support:
- Autocomplete for variant names and values
- Type checking for invalid variants
- Hover documentation showing available options
- Go to definition for variant configurations
Make sure your tsconfig.json has strict mode enabled for the best experience:
{ "compilerOptions": { "strict": true, "strictNullChecks": true }}