CtrlK
BlogDocsLog inGet started
Tessl Logo

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

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

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; }; });

docs

core-api.md

index.md

lite-mode.md

utilities.md

tile.json