or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-api.mdindex.mdlite-mode.mdutilities.md
tile.json

tessl/npm-tailwind-variants

First-class variant API for Tailwind CSS that enables developers to create reusable component styles with type-safe variants, slots support, and automatic conflict resolution

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/tailwind-variants@3.1.x

To install, run

npx @tessl/cli install tessl/npm-tailwind-variants@3.1.0

index.mddocs/

Tailwind Variants

Tailwind Variants provides a first-class variant API for Tailwind CSS that enables developers to create reusable component styles with type-safe variants, slots support, and automatic conflict resolution. It offers a comprehensive solution for managing complex Tailwind CSS styling patterns through a chainable API that supports base styles, variants, compound variants, and default variants with full TypeScript support.

Package Information

  • Package Name: tailwind-variants
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install tailwind-variants

Optional conflict resolution:

npm install tailwind-merge

Core Imports

Full mode (with tailwind-merge support):

import { tv, createTV, cn, cnBase, defaultConfig, VariantProps } from "tailwind-variants";

Lite mode (smaller bundle, no conflict resolution):

import { tv, createTV, cn, cnBase, defaultConfig } from "tailwind-variants/lite";

Utilities only:

import { cn, falsyToString, isEmptyObject, flatArray, VariantProps } from "tailwind-variants/utils";

For CommonJS:

const { tv, createTV, cn } = require("tailwind-variants");

Basic Usage

import { tv } from "tailwind-variants";

// Simple component with 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",
      danger: "bg-red-500 text-white",
    },
    size: {
      sm: "text-sm px-4 py-2",
      md: "text-base px-6 py-3",
      lg: "text-lg px-8 py-4",
    },
  },
  defaultVariants: {
    color: "primary",
    size: "md",
  },
});

// Use the component
const primaryButton = button({ color: "primary", size: "lg" });
// Returns: "font-medium bg-blue-500 text-white rounded-full active:opacity-80 bg-blue-500 text-white text-lg px-8 py-4"

Architecture

Tailwind Variants is built around several key components:

  • tv Function: Main function for creating variant-enabled components with base styles, variants, and compound variants
  • Slots System: Named component parts that can each have their own styling variants
  • Conflict Resolution: Optional integration with tailwind-merge for automatic class conflict resolution
  • Type Safety: Full TypeScript support with generic type preservation and inference
  • Composition: Ability to extend and compose variant components through the extend option
  • Configuration: Global and per-component configuration for tailwind-merge integration

Capabilities

Core Variant API

The main tv function for creating styled components with variants, slots, compound variants, and default values. Supports both simple class-based styling and complex multi-slot component structures.

const tv: TV;

function createTV(config: TVConfig): TV;

interface TV {
  <V extends TVVariants<S, B, EV>, CV extends TVCompoundVariants<V, S, B, EV, ES>, DV extends TVDefaultVariants<V, S, EV, ES>, B extends ClassValue = undefined, S extends TVSlots = undefined, E extends TVReturnType = TVReturnType<V, S, B, EV extends undefined ? {} : EV, ES extends undefined ? {} : ES>, EV extends TVVariants<ES, B, E["variants"], ES> = E["variants"], ES extends TVSlots = E["slots"] extends TVSlots ? E["slots"] : undefined>(options: {
    extend?: E;
    base?: B;
    slots?: S;
    variants?: V;
    compoundVariants?: CV;
    compoundSlots?: TVCompoundSlots<V, S, B>[];
    defaultVariants?: DV;
  }, config?: TVConfig): TVReturnType<V, S, B, EV, ES, E>;
}

Core Variant API

Class Name Utilities

Utility functions for conditional class name construction with support for objects, arrays, and automatic conflict resolution via tailwind-merge integration.

const cn: <T extends CnOptions>(...classes: T) => (config?: TWMConfig) => CnReturn;

const cnBase: <T extends CnOptions>(...classes: T) => CnReturn;

Class Name Utilities

Lite Mode

Lightweight version of tailwind-variants with reduced bundle size, excluding tailwind-merge integration for applications that prefer minimal dependencies.

const tv: TVLite;

function createTV(): TVLite;

const cn: <T extends CnOptions>(...classes: T) => CnReturn;

Lite Mode

Component Props Extraction

Type utility for extracting variant props from TV components for use in component interfaces, enabling type-safe prop passing in React and other frameworks.

type VariantProps<Component extends (...args: any) => any> = Omit<
  OmitUndefined<Parameters<Component>[0]>,
  "class" | "className"
>;

Configuration Types

interface TVConfig {
  twMerge?: boolean;
  twMergeConfig?: TWMergeConfig;
}

interface TWMConfig {
  twMerge?: boolean;
  twMergeConfig?: TWMergeConfig;
}

type TWMergeConfig = MergeConfig & LegacyMergeConfig;

const defaultConfig: TVConfig;

Core Types

type ClassValue = string | number | bigint | boolean | null | undefined | ClassDictionary | ClassArray;

interface ClassDictionary {
  [key: string]: any;
}

interface ClassArray extends Array<ClassValue> {}

type CnOptions = ClassValue[];

type CnReturn = string | undefined;

type ClassProp<V extends unknown = ClassValue> = 
  | { class?: V; className?: never }
  | { class?: never; className?: V };

type OmitUndefined<T> = T extends undefined ? never : T;

type StringToBoolean<T> = T extends "true" | "false" ? boolean : T;

type VariantProps<Component extends (...args: any) => any> = Omit<
  OmitUndefined<Parameters<Component>[0]>,
  "class" | "className"
>;

type TVSlots = Record<string, ClassValue> | undefined;

type TVVariants<S extends TVSlots | undefined, B extends ClassValue | undefined = undefined, EV extends TVVariants<ES> | undefined = undefined, ES extends TVSlots | undefined = undefined> = 
  EV extends undefined 
    ? S extends undefined 
      ? {} 
      : { [key: string]: { [key: string]: S extends TVSlots ? SlotsClassValue<S, B> | ClassValue : ClassValue; }; }
    : { [K in keyof EV]: { [K2 in keyof EV[K]]: S extends TVSlots ? SlotsClassValue<S, B> | ClassValue : ClassValue; }; } | (S extends undefined ? {} : { [key: string]: { [key: string]: S extends TVSlots ? SlotsClassValue<S, B> | ClassValue : ClassValue; }; });