Recipes

Copy-paste Tailwind Variants recipes for common UI patterns like buttons, alerts, and badges.

Button

import { tv, type VariantProps } from 'tailwind-variants';export const button = tv({  base: [    'inline-flex cursor-pointer items-center justify-center gap-2 select-none',    'rounded-lg font-medium transition-colors',    'disabled:cursor-not-allowed disabled:opacity-50'  ],  variants: {    variant: {      primary: 'bg-zinc-900 text-white hover:bg-zinc-800',      secondary: 'border border-zinc-300 bg-zinc-50 text-zinc-900 hover:bg-zinc-100',      tertiary: 'text-zinc-700 hover:bg-zinc-200/70 hover:text-zinc-950'    },    size: {      sm: 'h-8 px-3 text-sm',      md: 'h-10 px-4 text-sm',      lg: 'h-12 px-6 text-base'    }  },  compoundVariants: [    { variant: 'primary', size: 'lg', class: 'shadow-lg shadow-zinc-900/15' },    { variant: 'secondary', size: 'lg', class: 'shadow-sm' }  ],  defaultVariants: {    variant: 'primary',    size: 'md'  }});export type ButtonVariants = VariantProps<typeof button>;

Alert (with slots)

import { tv, type VariantProps } from 'tailwind-variants';export const alert = tv({  slots: {    base: 'flex gap-3 rounded-lg p-4 border',    icon: 'size-5 shrink-0 mt-0.5',    content: 'flex-1 min-w-0',    title: 'font-semibold leading-snug',    description: 'text-sm mt-1 opacity-90'  },  variants: {    color: {      default: {        base: 'bg-zinc-50 border-zinc-200 text-zinc-900',        icon: 'text-zinc-500'      },      success: {        base: 'bg-green-50 border-green-200 text-green-900',        icon: 'text-green-600'      },      warning: {        base: 'bg-amber-50 border-amber-200 text-amber-900',        icon: 'text-amber-600'      },      danger: {        base: 'bg-red-50 border-red-200 text-red-900',        icon: 'text-red-600'      }    }  },  defaultVariants: {    color: 'default'  }});export type AlertVariants = VariantProps<typeof alert>;

Badge

import { tv, type VariantProps } from 'tailwind-variants';export const badge = tv({  base: 'inline-flex select-none items-center rounded-full font-medium',  variants: {    variant: {      solid: '',      soft: '',      outline: 'border bg-transparent'    },    color: {      default: '',      primary: '',      success: '',      danger: ''    },    size: {      sm: 'px-2 py-0.5 text-xs',      md: 'px-2.5 py-0.5 text-sm'    }  },  compoundVariants: [    { variant: 'solid', color: 'default', class: 'bg-zinc-900 text-white' },    { variant: 'solid', color: 'primary', class: 'bg-blue-600 text-white' },    { variant: 'solid', color: 'success', class: 'bg-green-600 text-white' },    { variant: 'solid', color: 'danger', class: 'bg-red-600 text-white' },    { variant: 'soft', color: 'default', class: 'bg-zinc-100 text-zinc-700' },    { variant: 'soft', color: 'primary', class: 'bg-blue-100 text-blue-700' },    { variant: 'outline', color: 'default', class: 'border-zinc-300 text-zinc-700' },    { variant: 'outline', color: 'primary', class: 'border-blue-300 text-blue-700' }  ],  defaultVariants: {    variant: 'soft',    color: 'default',    size: 'sm'  }});export type BadgeVariants = VariantProps<typeof badge>;

On this page