0
# Tailwind Variants
1
2
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.
3
4
## Package Information
5
6
- **Package Name**: tailwind-variants
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install tailwind-variants`
10
11
**Optional conflict resolution:**
12
```bash
13
npm install tailwind-merge
14
```
15
16
## Core Imports
17
18
**Full mode (with tailwind-merge support):**
19
20
```typescript
21
import { tv, createTV, cn, cnBase, defaultConfig, VariantProps } from "tailwind-variants";
22
```
23
24
**Lite mode (smaller bundle, no conflict resolution):**
25
26
```typescript
27
import { tv, createTV, cn, cnBase, defaultConfig } from "tailwind-variants/lite";
28
```
29
30
**Utilities only:**
31
32
```typescript
33
import { cn, falsyToString, isEmptyObject, flatArray, VariantProps } from "tailwind-variants/utils";
34
```
35
36
For CommonJS:
37
38
```javascript
39
const { tv, createTV, cn } = require("tailwind-variants");
40
```
41
42
## Basic Usage
43
44
```typescript
45
import { tv } from "tailwind-variants";
46
47
// Simple component with variants
48
const button = tv({
49
base: "font-medium bg-blue-500 text-white rounded-full active:opacity-80",
50
variants: {
51
color: {
52
primary: "bg-blue-500 text-white",
53
secondary: "bg-purple-500 text-white",
54
danger: "bg-red-500 text-white",
55
},
56
size: {
57
sm: "text-sm px-4 py-2",
58
md: "text-base px-6 py-3",
59
lg: "text-lg px-8 py-4",
60
},
61
},
62
defaultVariants: {
63
color: "primary",
64
size: "md",
65
},
66
});
67
68
// Use the component
69
const primaryButton = button({ color: "primary", size: "lg" });
70
// Returns: "font-medium bg-blue-500 text-white rounded-full active:opacity-80 bg-blue-500 text-white text-lg px-8 py-4"
71
```
72
73
## Architecture
74
75
Tailwind Variants is built around several key components:
76
77
- **tv Function**: Main function for creating variant-enabled components with base styles, variants, and compound variants
78
- **Slots System**: Named component parts that can each have their own styling variants
79
- **Conflict Resolution**: Optional integration with tailwind-merge for automatic class conflict resolution
80
- **Type Safety**: Full TypeScript support with generic type preservation and inference
81
- **Composition**: Ability to extend and compose variant components through the extend option
82
- **Configuration**: Global and per-component configuration for tailwind-merge integration
83
84
## Capabilities
85
86
### Core Variant API
87
88
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.
89
90
```typescript { .api }
91
const tv: TV;
92
93
function createTV(config: TVConfig): TV;
94
95
interface TV {
96
<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: {
97
extend?: E;
98
base?: B;
99
slots?: S;
100
variants?: V;
101
compoundVariants?: CV;
102
compoundSlots?: TVCompoundSlots<V, S, B>[];
103
defaultVariants?: DV;
104
}, config?: TVConfig): TVReturnType<V, S, B, EV, ES, E>;
105
}
106
```
107
108
[Core Variant API](./core-api.md)
109
110
### Class Name Utilities
111
112
Utility functions for conditional class name construction with support for objects, arrays, and automatic conflict resolution via tailwind-merge integration.
113
114
```typescript { .api }
115
const cn: <T extends CnOptions>(...classes: T) => (config?: TWMConfig) => CnReturn;
116
117
const cnBase: <T extends CnOptions>(...classes: T) => CnReturn;
118
```
119
120
[Class Name Utilities](./utilities.md)
121
122
### Lite Mode
123
124
Lightweight version of tailwind-variants with reduced bundle size, excluding tailwind-merge integration for applications that prefer minimal dependencies.
125
126
```typescript { .api }
127
const tv: TVLite;
128
129
function createTV(): TVLite;
130
131
const cn: <T extends CnOptions>(...classes: T) => CnReturn;
132
```
133
134
[Lite Mode](./lite-mode.md)
135
136
### Component Props Extraction
137
138
Type utility for extracting variant props from TV components for use in component interfaces, enabling type-safe prop passing in React and other frameworks.
139
140
```typescript { .api }
141
type VariantProps<Component extends (...args: any) => any> = Omit<
142
OmitUndefined<Parameters<Component>[0]>,
143
"class" | "className"
144
>;
145
```
146
147
## Configuration Types
148
149
```typescript { .api }
150
interface TVConfig {
151
twMerge?: boolean;
152
twMergeConfig?: TWMergeConfig;
153
}
154
155
interface TWMConfig {
156
twMerge?: boolean;
157
twMergeConfig?: TWMergeConfig;
158
}
159
160
type TWMergeConfig = MergeConfig & LegacyMergeConfig;
161
162
const defaultConfig: TVConfig;
163
```
164
165
## Core Types
166
167
```typescript { .api }
168
type ClassValue = string | number | bigint | boolean | null | undefined | ClassDictionary | ClassArray;
169
170
interface ClassDictionary {
171
[key: string]: any;
172
}
173
174
interface ClassArray extends Array<ClassValue> {}
175
176
type CnOptions = ClassValue[];
177
178
type CnReturn = string | undefined;
179
180
type ClassProp<V extends unknown = ClassValue> =
181
| { class?: V; className?: never }
182
| { class?: never; className?: V };
183
184
type OmitUndefined<T> = T extends undefined ? never : T;
185
186
type StringToBoolean<T> = T extends "true" | "false" ? boolean : T;
187
188
type VariantProps<Component extends (...args: any) => any> = Omit<
189
OmitUndefined<Parameters<Component>[0]>,
190
"class" | "className"
191
>;
192
193
type TVSlots = Record<string, ClassValue> | undefined;
194
195
type TVVariants<S extends TVSlots | undefined, B extends ClassValue | undefined = undefined, EV extends TVVariants<ES> | undefined = undefined, ES extends TVSlots | undefined = undefined> =
196
EV extends undefined
197
? S extends undefined
198
? {}
199
: { [key: string]: { [key: string]: S extends TVSlots ? SlotsClassValue<S, B> | ClassValue : ClassValue; }; }
200
: { [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; }; });
201
```