### Install Tailwind Variants with npm Source: https://www.tailwind-variants.org/docs/getting-started Install the tailwind-variants package using npm. ```bash npm install tailwind-variants ``` -------------------------------- ### Install Tailwind Variants with yarn Source: https://www.tailwind-variants.org/docs/getting-started Install the tailwind-variants package using yarn. ```bash yarn add tailwind-variants ``` -------------------------------- ### Install tailwind-merge with yarn Source: https://www.tailwind-variants.org/docs/getting-started Install the tailwind-merge package using yarn for conflict resolution. ```bash yarn add tailwind-merge ``` -------------------------------- ### Install Tailwind Variants with pnpm Source: https://www.tailwind-variants.org/docs/getting-started Install the tailwind-variants package using pnpm. ```bash pnpm add tailwind-variants ``` -------------------------------- ### Install tailwind-merge with pnpm Source: https://www.tailwind-variants.org/docs/getting-started Install the tailwind-merge package using pnpm for conflict resolution. ```bash pnpm add tailwind-merge ``` -------------------------------- ### Styling Multiple Slots with a Card Component Source: https://www.tailwind-variants.org/docs/introduction This example shows how to define and use multiple slots for a card component, allowing different parts of the card (base, avatar, description, etc.) to be styled independently. ```javascript import { tv } from 'tailwind-variants'; const card = tv({ slots: { base: 'md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-gray-900', avatar: 'w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto drop-shadow-lg', wrapper: 'flex-1 pt-6 md:p-8 text-center md:text-left space-y-4', description: 'text-md font-medium', infoWrapper: 'font-medium', name: 'text-sm text-sky-500 dark:text-sky-400', role: 'text-sm text-slate-700 dark:text-slate-500' } }); const { base, avatar, wrapper, description, infoWrapper, name, role } = card(); return (

“Tailwind variants allows you to reduce repeated code in your project and make it more readable. They fixed the headache of building a design system with TailwindCSS.”

Zoey Lang
Full-stack developer, HeroUI
); ``` -------------------------------- ### Install tailwind-merge with npm Source: https://www.tailwind-variants.org/docs/getting-started Install the tailwind-merge package using npm for conflict resolution. ```bash npm install tailwind-merge ``` -------------------------------- ### Install tailwind-merge for v3 Original Build Source: https://www.tailwind-variants.org/docs/migration If you use the default configuration with `twMerge: true` in v3, install `tailwind-merge` to enable conflict resolution. ```bash # npm npm install tailwind-merge # yarn yarn add tailwind-merge # pnpm pnpm add tailwind-merge ``` -------------------------------- ### Prettier Plugin Setup Source: https://www.tailwind-variants.org/docs/getting-started Configure prettier-plugin-tailwindcss to sort class names generated by the 'tv' function. ```javascript module.exports = { plugins: [require('prettier-plugin-tailwindcss')], tailwindFunctions: ['tv'] }; ``` -------------------------------- ### Define and Use TV Component Source: https://www.tailwind-variants.org/docs/api-reference Use `tv` to create a component with variants and slots. Call the returned function to get class names, or destructure slots for individual access. Access component properties like `base`, `slots`, `variants`, etc., directly from the returned object. ```javascript import { tv } from 'tailwind-variants' const element = tv(options, config) // call the element function to get the class names element({'...'}) // => string // call the element function with slots to get the class names const { slot1, slot2 } = element({...}) // => Record slot1({}) // => string // access to the returned object element.base // => string element.slots // => Record element.variants // => Record element.variantKeys // => string[] element.defaultVariants // => Record element.compoundVariants // => Array> element.compoundSlots // => Array> ``` -------------------------------- ### Overriding Button Color Variants Source: https://www.tailwind-variants.org/docs/introduction This example demonstrates how to override the default color variants of a button component using the `class` prop. The provided class will take precedence over the variant's classes. ```javascript import { tv } from 'tailwind-variants'; const button = tv({ base: 'font-semibold text-white py-1 px-3 rounded-full active:opacity-80', variants: { color: { primary: 'bg-blue-500 hover:bg-blue-700', secondary: 'bg-purple-500 hover:bg-purple-700', success: 'bg-green-500 hover:bg-green-700', error: 'bg-red-500 hover:bg-red-700' } } }); button({ color: 'secondary', class: 'bg-pink-500 hover:bg-pink-500' // overrides the color variant }); /** * Result: * font-semibold text-white py-1 px-3 rounded-full active:opacity-80 bg-pink-500 hover:bg-pink-500 */ ``` -------------------------------- ### Importing cn and cnBase in v3 Source: https://www.tailwind-variants.org/docs/migration Shows how to import `cn` and `cnBase` in v3 for both original and lite builds, highlighting `cn` as the recommended import. ```javascript // v2 import { cnBase } from 'tailwind-variants'; // v3 - Original build (with tailwind-merge) import { cn, cnBase } from 'tailwind-variants'; // v3 - Lite build (without tailwind-merge) import { cn, cnBase } from 'tailwind-variants/lite'; ``` -------------------------------- ### Create Custom TV Instance Source: https://www.tailwind-variants.org/docs/api-reference Use `createTV` to instantiate a `tv` function with a default configuration, such as enabling `twMerge` and providing a custom `twMergeConfig`. ```javascript import { createTV } from 'tailwind-variants'; const tv = createTV({ twMerge: true, twMergeConfig: { // custom config } }); ``` -------------------------------- ### Neovim IntelliSense Configuration Source: https://www.tailwind-variants.org/docs/getting-started Configure Neovim to enable autocompletion for 'tv' function calls using the Tailwind CSS Language Server. ```lua require('lspconfig').tailwindcss.setup({ settings = { tailwindCSS = { classFunctions = { "tv" }, }, }, }) ``` -------------------------------- ### createTV Source: https://www.tailwind-variants.org/docs/api-reference Creates a custom `tv` instance with a specified default configuration. This is useful for setting up a consistent theming or configuration across multiple `tv` definitions. ```APIDOC ## createTV ### Description The `createTV` function allows you to create a pre-configured instance of the `tv` function. This is ideal for establishing default settings, such as `twMerge` behavior or custom merge configurations, that will be applied to all `tv` calls made with this instance. ### Usage ```javascript import { createTV } from 'tailwind-variants'; const tv = createTV({ twMerge: true, twMergeConfig: { // custom config } }); ``` ``` -------------------------------- ### IntelliJ IntelliSense Configuration Source: https://www.tailwind-variants.org/docs/getting-started Configure IntelliJ settings via Languages & Frameworks to enable autocompletion for 'tv' function calls. ```json { "classFunctions": ["tv"] } ``` -------------------------------- ### Custom tv instance with createTV Source: https://www.tailwind-variants.org/docs/config Creates a reusable instance of the tv function with a specified configuration using createTV. This is ideal when different use cases require distinct configurations. ```javascript import { createTV } from 'tailwind-variants'; const tv = createTV({ twMerge: false // ... }); tv({ base: '' }); ``` -------------------------------- ### cn function conflict resolution change Source: https://www.tailwind-variants.org/docs/migration Starting v3.2.0, the `cn` function defaults to `twMerge: true`, automatically resolving conflicting Tailwind classes. Use `cx` if no resolution is desired. ```javascript cn('text-blue-500', 'text-red-500'); // => "text-blue-500 text-red-500" (both classes) ``` ```javascript cn('text-blue-500', 'text-red-500'); // => "text-red-500" (conflict resolved) ``` -------------------------------- ### Import from Original Build Source: https://www.tailwind-variants.org/docs/getting-started Import necessary functions from the default entry point of the original Tailwind Variants build. ```javascript import { tv, createTV, cn, cnMerge, cx } from 'tailwind-variants'; ``` -------------------------------- ### Advanced Custom tv wrapper Source: https://www.tailwind-variants.org/docs/config Creates a custom tv wrapper that extends the default configuration with custom merge configurations for theme values and class groups. This approach maintains type safety and allows overriding defaults. ```javascript // tv.ts import type { TV } from 'tailwind-variants'; import { tv as tvBase } from 'tailwind-variants'; const COMMON_UNITS = ['small', 'medium', 'large']; const twMergeConfig = { theme: { spacing: ['divider'], radius: COMMON_UNITS }, classGroups: { shadow: [{ shadow: COMMON_UNITS }], opacity: [{ opacity: ['disabled'] }], 'font-size': [{ text: ['tiny', ...COMMON_UNITS] }], 'border-w': [{ border: COMMON_UNITS }], 'bg-image': [ 'bg-stripe-gradient-default', 'bg-stripe-gradient-primary', 'bg-stripe-gradient-secondary', 'bg-stripe-gradient-success', 'bg-stripe-gradient-warning', 'bg-stripe-gradient-danger' ] } }; export const tv: TV = (options, config) => tvBase(options, { ...config, twMerge: config?.twMerge ?? true, twMergeConfig: { ...config?.twMergeConfig, theme: { ...config?.twMergeConfig?.theme, ...twMergeConfig.theme }, classGroups: { ...config?.twMergeConfig?.classGroups, ...twMergeConfig.classGroups } } }); ``` -------------------------------- ### Import Lite Build Source: https://www.tailwind-variants.org/docs/config Imports the tv function and utilities from 'tailwind-variants/lite'. This build excludes 'tailwind-merge' for a smaller bundle size and does not support twMerge or twMergeConfig options. ```javascript import { tv, createTV, cn, cnMerge, cx } from 'tailwind-variants/lite'; ``` -------------------------------- ### Component with Compound Slots and Variants Source: https://www.tailwind-variants.org/docs/slots Demonstrates creating a component with shared base styles for multiple slots and applying variants based on size. Useful for components with many slots needing consistent styling. ```javascript import { tv } from "tailwind-variants"; cosnt baseItem = [ "flex", "flex-wrap", "truncate", "box-border", "outline-none", "items-center", "justify-center", "bg-neutral-100", "hover:bg-neutral-200", "active:bg-neutral-300", "text-neutral-500", ] const pagination = tv({ slots: { base: "flex flex-wrap relative gap-1 max-w-fit", item: [...baseItem, 'data-[active="true"]:bg-blue-500 data-[active="true"]:text-white'], prev: baseItem, next: baseItem, }, variants: { size: { xs: { item: "w-7 h-7 text-xs", prev: "w-7 h-7 text-xs", next: "w-7 h-7 text-xs", }, sm: { item: "w-8 h-8 text-sm", prev: "w-8 h-8 text-sm", next: "w-8 h-8 text-sm", }, md: { item: "w-9 h-9 text-base", prev: "w-9 h-9 text-base", next: "w-9 h-9 text-base", }, }, }, defaultVariants: { size: "md", }, }); ``` -------------------------------- ### Import Original Build Source: https://www.tailwind-variants.org/docs/config Imports the main tv function and utilities from the 'tailwind-variants' package. This build includes 'tailwind-merge' for automatic conflict resolution. ```javascript import { tv, createTV, cn, cnMerge, cx } from 'tailwind-variants'; ``` -------------------------------- ### Basic cx Usage Source: https://www.tailwind-variants.org/docs/api-reference Demonstrates simple concatenation of class names using `cx`. It handles arrays and objects, and ignores falsy values. ```javascript // Usage - no conflict resolution // Simple concatenation cx('text-xl', 'font-bold'); // => 'text-xl font-bold' ``` ```javascript // Handles arrays and objects cx(['px-4', 'py-2'], { 'bg-blue-500': true, 'text-white': false }); // => 'px-4 py-2 bg-blue-500' ``` ```javascript // Ignores falsy values (except 0) cx('text-xl', false && 'font-bold', null, undefined); // => 'text-xl' ``` -------------------------------- ### cx with Multiple Classes Source: https://www.tailwind-variants.org/docs/api-reference Illustrates how `cx` handles multiple classes, including hover states and conditional classes within objects. ```javascript // Multiple classes cx('text-blue-500', 'text-red-500'); // => "text-blue-500 text-red-500" (both classes included) ``` ```javascript cx('text-blue-500', 'hover:text-blue-700'); // => "text-blue-500 hover:text-blue-700" ``` ```javascript cx(['text-blue-500', null, undefined, 'hover:text-blue-700']); // => "text-blue-500 hover:text-blue-700" ``` ```javascript cx('text-blue-500', { 'font-bold': true, italic: false }); // => "text-blue-500 font-bold" ``` -------------------------------- ### VSCode IntelliSense Configuration Source: https://www.tailwind-variants.org/docs/getting-started Configure VSCode settings to enable autocompletion for 'tv' function calls with the Tailwind CSS IntelliSense Extension. ```json { "tailwindCSS.classFunctions": ["tv"] } ``` -------------------------------- ### Reuse tv Instances Source: https://www.tailwind-variants.org/docs/faq Create tv instances once and reuse them to optimize performance. Avoid creating new instances within component render functions. ```javascript // Good - defined once const button = tv({ /* ... */ }); // Avoid - creates new instance each render function Component() { const button = tv({ /* ... */ }); } ``` -------------------------------- ### Compose Button Variants with Tailwind Variants Source: https://www.tailwind-variants.org/docs/examples Demonstrates composing a 'buyButton' variant by extending a 'baseButton' using the `tv` function. This approach allows for shared base styles and specific overrides for different button types. ```javascript import { tv } from 'tailwind-variants'; const baseButton = tv({ base: [ 'font-semibold', 'dark:text-white', 'py-1', 'px-3', 'rounded-full', 'active:opacity-80', 'bg-zinc-100', 'hover:bg-zinc-200', 'dark:bg-zinc-800', 'dark:hover:bg-zinc-800' ] }); const buyButton = tv({ extend: baseButton, base: [ 'text-sm', 'text-white', 'rounded-lg', 'shadow-lg', 'uppercase', 'tracking-wider', 'bg-blue-500', 'hover:bg-blue-600', 'shadow-blue-500/50', 'dark:bg-blue-500', 'dark:hover:bg-blue-600' ] }); return (
); /** * buyButton(); * * Result: * font-semibold dark:text-white py-1 px-3 active:opacity-80 text-sm text-white rounded-lg * shadow-lg shadow-blue-500/50 uppercase tracking-wider bg-blue-500 hover:bg-blue-600 * dark:bg-blue-500 dark:hover:bg-blue-600 */ ``` -------------------------------- ### Import from Lite Build Source: https://www.tailwind-variants.org/docs/getting-started Import necessary functions from the lite build of Tailwind Variants for a smaller bundle size. ```javascript import { tv, createTV, cn, cx } from 'tailwind-variants/lite'; ``` -------------------------------- ### Composing Button Components Source: https://www.tailwind-variants.org/docs/introduction This snippet illustrates component composition by extending a base button style to create a new 'buy button' variant. It merges styles from the base button and adds specific styles for the buy button. ```javascript import { tv } from 'tailwind-variants'; const baseButton = tv({ base: [ 'font-semibold', 'dark:text-white', 'py-1', 'px-3', 'rounded-full', 'active:opacity-80', 'bg-zinc-100', 'hover:bg-zinc-200', 'dark:bg-zinc-800', 'dark:hover:bg-zinc-800' ] }); const buyButton = tv({ extend: baseButton, base: [ 'text-sm', 'text-white', 'rounded-lg', 'shadow-lg', 'uppercase', 'tracking-wider', 'bg-blue-500', 'hover:bg-blue-600', 'shadow-blue-500/50', 'dark:bg-blue-500', 'dark:hover:bg-blue-600' ] }); return (
); /** * buyButton(); * * Result: * font-semibold dark:text-white py-1 px-3 active:opacity-80 text-sm text-white rounded-lg * shadow-lg shadow-blue-500/50 uppercase tracking-wider bg-blue-500 hover:bg-blue-600 * dark:bg-blue-500 dark:hover:bg-blue-600 */ ``` -------------------------------- ### Import cx from Tailwind Variants Source: https://www.tailwind-variants.org/docs/api-reference Import the `cx` function for class name concatenation. Use the lite build for a smaller bundle size if `tailwind-merge` conflict resolution is not needed. ```javascript // Original build (with tailwind-merge) import { cx } from 'tailwind-variants'; ``` ```javascript // Lite build (without tailwind-merge) import { cx } from 'tailwind-variants/lite'; ``` -------------------------------- ### Global Configuration with defaultConfig Source: https://www.tailwind-variants.org/docs/config Modifies the exported defaultConfig variable to set global configuration for all tv function calls. This change applies to both original and lite builds. ```javascript import { defaultConfig } from 'tailwind-variants'; defaultConfig.twMerge = false; ``` -------------------------------- ### Simple Class Concatenation with cx Source: https://www.tailwind-variants.org/docs/faq Use cx for lightweight class name concatenation when conflict resolution is not needed. It's available in both original and lite builds and offers a smaller bundle size. ```javascript import { cx } from 'tailwind-variants'; cx('text-blue-500', 'text-red-500'); // => "text-blue-500 text-red-500" (both included) ``` -------------------------------- ### Extend Button with Variants Source: https://www.tailwind-variants.org/docs/composing-components Shows how to compose a component with variants by extending a base button. New variants can be added while inheriting existing ones. Ensure the base component is defined before extending. ```javascript import { tv } from 'tailwind-variants'; const baseButton = tv({ base: 'font-semibold text-white rounded-full active:opacity-80', variants: { color: { primary: 'bg-blue-500 hover:bg-blue-700', secondary: 'bg-purple-500 hover:bg-purple-700', success: 'bg-green-500 hover:bg-green-700' }, size: { small: 'py-0 px-2 text-xs', medium: 'py-1 px-3 text-sm', large: 'py-1.5 px-3 text-md' } } }); const myButton = tv({ extend: baseButton, variants: { isSquared: { true: 'rounded-sm' } } // custom button styles }); myButton({ color: 'success', size: 'medium', isSquared: true }); /** * Result: * font-semibold text-white active:opacity-80 rounded-sm bg-purple-500 hover:bg-purple-700 py-1 px-3 text-sm */ ``` -------------------------------- ### Import from Lite Build in v3 Source: https://www.tailwind-variants.org/docs/migration To use the lite build in v3, which excludes `tailwind-merge`, import from `tailwind-variants/lite`. ```javascript import { createTV, tv, cn, cnBase } from 'tailwind-variants/lite'; ``` -------------------------------- ### Local Configuration with tv function Source: https://www.tailwind-variants.org/docs/config Applies configuration options, such as disabling twMerge, to a specific tv function call. This is useful for one-off configuration changes. ```javascript tv( { base: '' }, { twMerge: false // ... } ); ``` -------------------------------- ### Composing Action Button Component Source: https://www.tailwind-variants.org/docs/composing-components Shows how to compose a new button component (`actionButton`) by extending a base button style (`baseButton`). It demonstrates overriding base styles and combining them with new ones. ```javascript import { tv } from 'tailwind-variants'; const baseButton = tv({ base: 'font-medium text-sm px-3 py-1 bg-blue-500 text-white rounded-full active:opacity-80' }); const actionButton = tv({ base: [baseButton(), 'bg-red-500', 'rounded-xs'] }); actionButton(); /** * Result: * font-medium text-sm px-3 py-1 text-white active:opacity-80 bg-red-500 rounded-xs */ ``` -------------------------------- ### Extending Card Component with Slots Source: https://www.tailwind-variants.org/docs/composing-components Demonstrates extending a base card component (`cardBase`) with its slots. The `myCard` component inherits all slots from `cardBase` and shows how to use them in a React-like JSX structure. ```javascript import { tv } from 'tailwind-variants'; const cardBase = tv({ slots: { base: 'md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-gray-900', avatar: 'w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto drop-shadow-lg', wrapper: 'flex-1 pt-6 md:p-8 text-center md:text-left space-y-4', description: 'text-md font-medium', infoWrapper: 'font-medium', name: 'text-sm text-sky-500 dark:text-sky-400', role: 'text-sm text-slate-700 dark:text-slate-500' } }); const myCard = tv({ extend: cardBase // custom card styles }); const { base, avatar, wrapper, description, infoWrapper, name, role } = myCard(); return (

“Tailwind variants allows you to reduce repeated code in your project and make it more readable. They fixed the headache of building a design system with TailwindCSS.”

Zoey Lang
Full-stack developer, HeroUI
); ``` -------------------------------- ### Extend Base Button Styles Source: https://www.tailwind-variants.org/docs/composing-components Demonstrates extending a base button component with additional styles and variants using the `extend` prop. Useful for creating specialized button types from a common base. ```javascript import { tv } from 'tailwind-variants'; const baseButton = tv({ base: [ 'font-semibold', 'dark:text-white', 'py-1', 'px-3', 'rounded-full', 'active:opacity-80', 'bg-zinc-100', 'hover:bg-zinc-200', 'dark:bg-zinc-800', 'dark:hover:bg-zinc-800' ] }); const buyButton = tv({ extend: baseButton, base: [ 'text-sm', 'text-white', 'rounded-lg', 'shadow-lg', 'uppercase', 'tracking-wider', 'bg-blue-500', 'hover:bg-blue-600', 'shadow-blue-500/50', 'dark:bg-blue-500', 'dark:hover:bg-blue-600' ] }); return (
); /** * buyButton(); * * Result: * font-semibold dark:text-white py-1 px-3 active:opacity-80 text-sm text-white rounded-lg * shadow-lg shadow-blue-500/50 uppercase tracking-wider bg-blue-500 hover:bg-blue-600 * dark:bg-blue-500 dark:hover:bg-blue-600 */ ``` -------------------------------- ### React Pagination Component with Compound Slots Source: https://www.tailwind-variants.org/docs/slots Demonstrates a pagination component using tv() with defined slots for base, item, prev, and next. It showcases compound slots to apply common styles to multiple slots simultaneously, with additional styles applied based on the 'size' variant. ```jsx import { tv } from 'tailwind-variants'; const pagination = tv({ slots: { base: 'flex flex-wrap relative gap-1 max-w-fit', item: 'data-[active="true"]:bg-blue-500 data-[active="true"]:text-white', prev: '', next: '' }, variants: { size: { xs: {}, sm: {}, md: {} } }, defaultVariants: { size: 'md' }, compoundSlots: [ // if you dont specify any variant, it will always be applied { slots: ['item', 'prev', 'next'], class: [ 'flex', 'flex-wrap', 'truncate', 'box-border', 'outline-none', 'items-center', 'justify-center', 'bg-neutral-100', 'hover:bg-neutral-200', 'active:bg-neutral-300', 'text-neutral-500' ] // --> these classes will be applied to all slots }, // if you specify a variant, it will only be applied if the variant is active { slots: ['item', 'prev', 'next'], size: 'xs', class: 'w-7 h-7 text-xs' // --> these classes will be applied to all slots if size is xs }, { slots: ['item', 'prev', 'next'], size: 'sm', class: 'w-8 h-8 text-sm' // --> these classes will be applied to all slots if size is sm }, { slots: ['item', 'prev', 'next'], size: 'md', class: 'w-9 h-9 text-base' // --> these classes will be applied to all slots if size is md } ] }); // React implementation const App = () => { const { base, item, prev, next } = pagination(); return (
  • {'<'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 10
  • {'>'}
); }; export default App; ``` -------------------------------- ### Compose Components Manually Source: https://www.tailwind-variants.org/docs/faq While direct extension of multiple components is not supported, you can compose them manually by combining their base styles. ```javascript const baseButton = tv({ /* ... */ }); const iconButton = tv({ /* ... */ }); // Compose manually const combinedButton = tv({ base: [baseButton(), iconButton()] // additional variants... }); ``` -------------------------------- ### Define Component Slots with Tailwind Variants Source: https://www.tailwind-variants.org/docs/slots This snippet defines a 'tv' component with multiple slots for different parts of a product card. It includes base styles and color variants for buttons and size indicators. Use this to set up reusable component structures. ```jsx import { useState } from 'react'; import { tv } from 'tailwind-variants'; // Import your components import { RadioGroup, Radio } from '@components'; const item = tv({ slots: { base: 'flex flex-col mb-4 sm:flex-col p-6 bg-white dark:bg-stone-900 drop-shadow-xl rounded-xl', imageWrapper: 'flex-none w-full sm:w-48 h-48 mb-6 sm:mb-0 sm:h-auto relative z-10 before:absolute before:top-0 before:left-0 before:w-full before:h-full before:rounded-xl before:bg-[#18000E] before:bg-gradient-to-r before:from-[#010187]', img: 'sm:scale-125 absolute z-10 top-2 sm:left-2 inset-0 w-full h-full object-cover rounded-lg', title: 'relative w-full flex-none mb-2 text-2xl font-semibold text-stone-900 dark:text-white', price: 'relative font-semibold text-xl dark:text-white', previousPrice: 'relative line-through font-bold text-neutral-500 ml-3', percentOff: 'relative font-bold text-green-500 ml-3', sizeButton: 'cursor-pointer select-none relative font-semibold rounded-full w-10 h-10 flex items-center justify-center active:opacity-80 dark:text-white peer-checked:text-white', buyButton: 'text-xs sm:text-sm px-4 h-10 rounded-lg shadow-lg uppercase font-semibold tracking-wider text-white active:opacity-80', addToBagButton: 'text-xs sm:text-sm px-4 h-10 rounded-lg uppercase font-semibold tracking-wider border-2 active:opacity-80' }, variants: { color: { primary: { buyButton: 'bg-blue-500 shadow-blue-500/50', sizeButton: 'peer-checked:bg-blue', addToBagButton: 'text-blue-500 border-blue-500' }, secondary: { buyButton: 'bg-purple-500 shadow-purple-500/50', sizeButton: 'peer-checked:bg-purple', addToBagButton: 'text-purple-500 border-purple-500' }, success: { buyButton: 'bg-green-500 shadow-green-500/50', sizeButton: 'peer-checked:bg-green', addToBagButton: 'text-green-500 border-green-500' } } } }); const itemSizes = ['xs', 's', 'm', 'l', 'xl']; const App = () => { const [size, setSize] = useState('xs'); const [color, setColor] = useState('primary'); const { base, imageWrapper, img, title, price, previousPrice, percentOff, sizeButton, buyButton, addToBagButton } = item({ color }); return (

Nike Adapt BB 2.0

$279.97
$350
20% off
{itemSizes.map((itemSize) => ( ))}
Primary Secondary Success
); }; export default App; ``` -------------------------------- ### Add Multiple Variants to Button Source: https://www.tailwind-variants.org/docs/variants Shows how to define multiple variants ('color' and 'size') for a single component. This allows for more complex styling combinations. ```javascript import { tv } from 'tailwind-variants'; const button = tv({ base: 'font-semibold text-white py-1 px-3 rounded-full active:opacity-80', variants: { color: { primary: 'bg-blue-500 hover:bg-blue-700', secondary: 'bg-purple-500 hover:bg-purple-700', success: 'bg-green-500 hover:bg-green-700' }, size: { sm: 'py-1 px-3 text-xs', md: 'py-1.5 px-4 text-sm', lg: 'py-2 px-6 text-md' } } }); button({ color: 'primary', size: 'sm' }); /** * Result: * font-semibold text-white rounded-full active:opacity-80 bg-blue-500 hover:bg-blue-700 * py-1 px-3 text-xs */ button({ color: 'secondary', size: 'md' }); /** * Result: * font-semibold text-white rounded-full active:opacity-80 bg-purple-500 hover:bg-purple-700 * py-1.5 px-4 text-sm */ button({ color: 'success', size: 'lg' }); /** * Result: * font-semibold text-white rounded-full active:opacity-80 bg-green-500 hover:bg-green-700 * py-2 px-6 text-md */ ``` -------------------------------- ### Exporting defaultConfig as value in v3.2.0+ Source: https://www.tailwind-variants.org/docs/migration In v3.2.0 and later, `defaultConfig` is exported as a value, allowing direct import and modification for global configuration. ```javascript // v3.2.0+ import { defaultConfig } from 'tailwind-variants'; defaultConfig.twMerge = false; ``` -------------------------------- ### Migrating cn(...)() to cnMerge Source: https://www.tailwind-variants.org/docs/migration If you previously used `cn(...)()` for custom configurations, migrate to the `cnMerge` function for the same behavior. ```javascript // Before cn('px-2', 'px-4')({ twMerge: false }); // After cnMerge('px-2', 'px-4')({ twMerge: false }); ``` -------------------------------- ### Extend Button with Default and Compound Variants Source: https://www.tailwind-variants.org/docs/composing-components Illustrates extending a base button that includes `defaultVariants` and `compoundVariants`. This allows for pre-defined states and complex conditional styling to be inherited. ```javascript import { tv } from 'tailwind-variants'; const baseButton = tv({ base: 'font-semibold text-white rounded-full active:opacity-80', variants: { color: { primary: 'bg-blue-500 hover:bg-blue-700', secondary: 'bg-purple-500 hover:bg-purple-700', success: 'bg-green-500 hover:bg-green-700' }, size: { small: 'py-0 px-2 text-xs', medium: 'py-1 px-3 text-sm', large: 'py-1.5 px-3 text-md' } }, defaultVariants: { color: 'primary', size: 'medium' }, compoundVariants: [ { color: 'primary', size: 'medium', className: 'rounded-sm' } ] }); const myButton = tv({ extend: baseButton // custom button styles }); myButton(); /** * Result: * font-semibold text-white active:opacity-80 bg-blue-500 hover:bg-blue-700 py-1 px-3 text-sm rounded-sm */ ``` -------------------------------- ### Import Lite Build in Tailwind Variants Source: https://www.tailwind-variants.org/docs/faq To use the lite build of Tailwind Variants, which excludes `tailwind-merge`, change your import statement. ```javascript // Change your imports from: import { tv } from 'tailwind-variants'; // To: import { tv } from 'tailwind-variants/lite'; ``` -------------------------------- ### Basic Tailwind Variants Usage Source: https://www.tailwind-variants.org/docs/getting-started Define and use a 'tv' component with base styles, variants, compound variants, and default variants. ```javascript import { tv } from 'tailwind-variants'; const button = tv({ base: 'font-medium bg-blue-500 text-white rounded-full active:opacity-80', variants: { color: { primary: 'bg-blue-500 text-white', secondary: 'bg-purple-500 text-white' }, size: { sm: 'text-sm', md: 'text-base', lg: 'px-4 py-3 text-lg' } }, compoundVariants: [ { size: ['sm', 'md'], class: 'px-3 py-1' } ], defaultVariants: { size: 'md', color: 'primary' } }); return ( ); ``` -------------------------------- ### Basic Slot Definition Source: https://www.tailwind-variants.org/docs/slots Define a component with multiple slots using the `slots` key. Each slot can be accessed and applied independently. ```javascript import { tv } from 'tailwind-variants'; const card = tv({ slots: { base: 'md:flex bg-slate-100 rounded-xl p-8 md:p-0 dark:bg-gray-900', avatar: 'w-24 h-24 md:w-48 md:h-auto md:rounded-none rounded-full mx-auto drop-shadow-lg', wrapper: 'flex-1 pt-6 md:p-8 text-center md:text-left space-y-4', description: 'text-md font-medium', infoWrapper: 'font-medium', name: 'text-sm text-sky-500 dark:text-sky-400', role: 'text-sm text-slate-700 dark:text-slate-500' } }); const { base, avatar, wrapper, description, infoWrapper, name, role } = card(); return (

“Tailwind variants allows you to reduce repeated code in your project and make it more readable. They fixed the headache of building a design system with TailwindCSS.”

Zoey Lang
Full-stack developer, HeroUI
); ``` -------------------------------- ### Responsive Variants Source: https://www.tailwind-variants.org/docs/faq Handle responsive variants by using Tailwind's responsive prefixes directly within your variant definitions. ```javascript const component = tv({ base: 'text-sm md:text-base lg:text-lg', variants: { color: { primary: 'text-blue-500 md:text-blue-600', secondary: 'text-gray-500 md:text-gray-600' } } }); ``` -------------------------------- ### Slot Variant Overrides for Customization Source: https://www.tailwind-variants.org/docs/slots Illustrates how to override specific variants for individual slots within a component. This allows for fine-grained control over styles based on internal component state. ```javascript import { tv } from 'tailwind-variants'; const card = tv({ slots: { base: 'flex gap-2', tab: 'rounded' }, variants: { color: { primary: { tab: 'text-blue-500 dark:text-blue-400' }, secondary: { tab: 'text-purple-500 dark:text-purple-400' } }, isSelected: { true: { tab: 'font-bold' } } } }); const { base, tab } = card({ color: 'primary' }); return ( {items.map((item) => ( tab({ isSelected })} id={item.id}> {item.label} ))} ); ``` -------------------------------- ### Adding Multiple Color Variants to a Button Source: https://www.tailwind-variants.org/docs/examples Extends a button component by adding a 'success' color variant. This shows how to easily add more options to existing variants. ```javascript import { tv } from 'tailwind-variants'; const button = tv({ base: 'font-semibold text-white text-sm py-1 px-4 rounded-full active:opacity-80', variants: { color: { primary: 'bg-blue-500 hover:bg-blue-700', secondary: 'bg-purple-500 hover:bg-purple-700', success: 'bg-green-500 hover:bg-green-700' } } }); button({ color: 'secondary' }); /** * Result: * font-semibold text-white text-sm py-1 px-4 rounded-full active:opacity-80 bg-purple-500 * hover:bg-purple-700 */ ``` -------------------------------- ### cx Source: https://www.tailwind-variants.org/docs/api-reference A lightweight utility function for concatenating class names without any conflict resolution. It is recommended as a replacement for the deprecated `cnBase` function. ```APIDOC ## cx ### Description The `cx` function is a simple and lightweight utility for joining multiple class name strings and objects. Unlike `cn`, it does not perform any conflict resolution, making it faster for cases where merging logic is not required. It is the recommended replacement for the deprecated `cnBase` function. ### Usage ```javascript import { cx } from 'tailwind-variants'; // Example usage: cx('text-blue-500', 'font-bold', { 'italic': true }); // => "text-blue-500 font-bold italic" ``` ``` -------------------------------- ### Replacing cnBase with cx Source: https://www.tailwind-variants.org/docs/migration In v3.2.0+, `cnBase` is deprecated and should be replaced with the new `cx` function, which offers identical functionality for simple concatenation. ```javascript import { cnBase } from 'tailwind-variants'; // ... { cnBase('flex items-center justify-center gap-2', className); } ``` ```javascript import { cx } from 'tailwind-variants'; // ... { cx('flex items-center justify-center gap-2', className); } ```