0
# Class Name Utilities
1
2
Tailwind Variants provides comprehensive utility functions for conditional class name construction, object manipulation, and array processing. These utilities support both the main variant system and standalone usage for general-purpose class name manipulation.
3
4
## Class Name Functions
5
6
### cn
7
8
Conditional class name utility with optional tailwind-merge integration for automatic conflict resolution.
9
10
```typescript { .api }
11
const cn: <T extends CnOptions>(...classes: T) => (config?: TWMConfig) => CnReturn;
12
```
13
14
**Parameters:**
15
- `...classes` - Variable number of class values (strings, numbers, objects, arrays)
16
17
**Returns:** Function that accepts optional TWMConfig and returns the processed class string
18
19
**Usage:**
20
21
```typescript
22
import { cn } from "tailwind-variants";
23
24
// Basic usage
25
const classes = cn("px-4 py-2", "bg-blue-500", "text-white")();
26
// Returns: "px-4 py-2 bg-blue-500 text-white"
27
28
// Conditional classes with objects
29
const buttonClasses = cn(
30
"px-4 py-2 rounded",
31
{
32
"bg-blue-500": isPrimary,
33
"bg-red-500": isDanger,
34
"opacity-50": isDisabled,
35
}
36
)();
37
38
// With arrays
39
const classes = cn(
40
"base-class",
41
["conditional-class", isActive && "active-class"],
42
{ "hover:bg-gray-100": !isDisabled }
43
)();
44
45
// With tailwind-merge config
46
const classes = cn("px-4 px-6", "py-2 py-3")({ twMerge: true });
47
// Returns: "px-6 py-3" (conflicts resolved)
48
```
49
50
### cnBase
51
52
Base class name utility without tailwind-merge integration, providing core conditional class logic.
53
54
```typescript { .api }
55
const cnBase: <T extends CnOptions>(...classes: T) => CnReturn;
56
```
57
58
**Parameters:**
59
- `...classes` - Variable number of class values (strings, numbers, objects, arrays)
60
61
**Returns:** Processed class string or undefined
62
63
**Usage:**
64
65
```typescript
66
import { cnBase } from "tailwind-variants";
67
68
// Direct class name processing
69
const classes = cnBase(
70
"px-4 py-2",
71
isActive && "bg-blue-500",
72
{ "text-white": isActive, "text-gray-600": !isActive }
73
);
74
// Returns: "px-4 py-2 bg-blue-500 text-white" (if isActive is true)
75
76
// With nested arrays
77
const classes = cnBase([
78
"base-class",
79
["nested-class", isNested && "conditional-nested"]
80
]);
81
```
82
83
## String Utilities
84
85
### removeExtraSpaces
86
87
Removes extra whitespace and trims strings.
88
89
```typescript { .api }
90
const removeExtraSpaces: (str: string) => string;
91
```
92
93
**Parameters:**
94
- `str` - Input string to clean
95
96
**Returns:** String with extra spaces removed and trimmed
97
98
**Usage:**
99
100
```typescript
101
import { removeExtraSpaces } from "tailwind-variants/utils";
102
103
const cleaned = removeExtraSpaces(" px-4 py-2 bg-blue-500 ");
104
// Returns: "px-4 py-2 bg-blue-500"
105
```
106
107
### falsyToString
108
109
Converts specific falsy values to their string representations.
110
111
```typescript { .api }
112
const falsyToString: <T>(value: T) => T | string;
113
```
114
115
**Parameters:**
116
- `value` - Value to convert
117
118
**Returns:** Original value or string representation for false, true, 0
119
120
**Usage:**
121
122
```typescript
123
import { falsyToString } from "tailwind-variants/utils";
124
125
falsyToString(false); // Returns: "false"
126
falsyToString(true); // Returns: "true"
127
falsyToString(0); // Returns: "0"
128
falsyToString("test"); // Returns: "test"
129
```
130
131
## Object Utilities
132
133
### isEmptyObject
134
135
Checks if an object is empty or not an object.
136
137
```typescript { .api }
138
const isEmptyObject: (obj: unknown) => boolean;
139
```
140
141
**Parameters:**
142
- `obj` - Value to check
143
144
**Returns:** True if empty or not an object, false otherwise
145
146
**Usage:**
147
148
```typescript
149
import { isEmptyObject } from "tailwind-variants/utils";
150
151
isEmptyObject({}); // Returns: true
152
isEmptyObject({ a: 1 }); // Returns: false
153
isEmptyObject(null); // Returns: true
154
isEmptyObject("test"); // Returns: true
155
```
156
157
### isEqual
158
159
Performs shallow equality check for objects.
160
161
```typescript { .api }
162
const isEqual: (obj1: object, obj2: object) => boolean;
163
```
164
165
**Parameters:**
166
- `obj1` - First object to compare
167
- `obj2` - Second object to compare
168
169
**Returns:** True if objects have same keys and values, false otherwise
170
171
**Usage:**
172
173
```typescript
174
import { isEqual } from "tailwind-variants/utils";
175
176
isEqual({ a: 1, b: 2 }, { a: 1, b: 2 }); // Returns: true
177
isEqual({ a: 1 }, { a: 1, b: 2 }); // Returns: false
178
```
179
180
### isBoolean
181
182
Checks if a value is a boolean.
183
184
```typescript { .api }
185
const isBoolean: (value: unknown) => boolean;
186
```
187
188
**Parameters:**
189
- `value` - Value to check
190
191
**Returns:** True if value is true or false, false otherwise
192
193
**Usage:**
194
195
```typescript
196
import { isBoolean } from "tailwind-variants/utils";
197
198
isBoolean(true); // Returns: true
199
isBoolean(false); // Returns: true
200
isBoolean("true"); // Returns: false
201
isBoolean(1); // Returns: false
202
```
203
204
### joinObjects
205
206
Joins two objects with class value merging using cn.
207
208
```typescript { .api }
209
const joinObjects: <T extends Record<string, unknown>, U extends Record<string, unknown>>(
210
obj1: T,
211
obj2: U,
212
) => T & U;
213
```
214
215
**Parameters:**
216
- `obj1` - First object
217
- `obj2` - Second object to merge
218
219
**Returns:** Merged object with class values combined
220
221
**Usage:**
222
223
```typescript
224
import { joinObjects } from "tailwind-variants/utils";
225
226
const obj1 = { class: "px-4 py-2", color: "blue" };
227
const obj2 = { class: "bg-blue-500", size: "md" };
228
229
const merged = joinObjects(obj1, obj2);
230
// Returns: { class: "px-4 py-2 bg-blue-500", color: "blue", size: "md" }
231
```
232
233
### mergeObjects
234
235
Deep merges two objects with special handling for arrays and strings.
236
237
```typescript { .api }
238
const mergeObjects: <T extends object, U extends object>(
239
obj1: T,
240
obj2: U,
241
) => Record<string, unknown>;
242
```
243
244
**Parameters:**
245
- `obj1` - First object
246
- `obj2` - Second object to merge
247
248
**Returns:** Deeply merged object
249
250
**Usage:**
251
252
```typescript
253
import { mergeObjects } from "tailwind-variants/utils";
254
255
const obj1 = {
256
variants: { size: { sm: "text-sm" } },
257
classes: ["base-class"]
258
};
259
260
const obj2 = {
261
variants: { size: { md: "text-base" }, color: { primary: "bg-blue-500" } },
262
classes: ["additional-class"]
263
};
264
265
const merged = mergeObjects(obj1, obj2);
266
// Returns merged object with combined variants and flattened arrays
267
```
268
269
## Array Utilities
270
271
### flat
272
273
Recursively flattens array into a target array.
274
275
```typescript { .api }
276
const flat: <T>(arr: unknown[], target: T[]) => void;
277
```
278
279
**Parameters:**
280
- `arr` - Array to flatten
281
- `target` - Target array to populate
282
283
**Returns:** Void (modifies target array)
284
285
**Usage:**
286
287
```typescript
288
import { flat } from "tailwind-variants/utils";
289
290
const nested = ["a", ["b", ["c", "d"]], "e"];
291
const target: string[] = [];
292
293
flat(nested, target);
294
// target now contains: ["a", "b", "c", "d", "e"]
295
```
296
297
### flatArray
298
299
Flattens nested arrays.
300
301
```typescript { .api }
302
const flatArray: <T>(array: unknown[]) => T[];
303
```
304
305
**Parameters:**
306
- `array` - Array to flatten
307
308
**Returns:** Flattened array
309
310
**Usage:**
311
312
```typescript
313
import { flatArray } from "tailwind-variants/utils";
314
315
const nested = ["a", ["b", ["c", "d"]], "e"];
316
const flattened = flatArray<string>(nested);
317
// Returns: ["a", "b", "c", "d", "e"]
318
```
319
320
### flatMergeArrays
321
322
Flattens and merges multiple arrays, filtering out falsy values.
323
324
```typescript { .api }
325
const flatMergeArrays: <T>(...arrays: unknown[][]) => T[];
326
```
327
328
**Parameters:**
329
- `...arrays` - Multiple arrays to flatten and merge
330
331
**Returns:** Flattened and filtered array
332
333
**Usage:**
334
335
```typescript
336
import { flatMergeArrays } from "tailwind-variants/utils";
337
338
const result = flatMergeArrays<string>(
339
["a", ["b"]],
340
["c", null, "d"],
341
[["e", false, "f"]]
342
);
343
// Returns: ["a", "b", "c", "d", "e", "f"] (falsy values filtered out)
344
```
345
346
```typescript { .api }
347
const flatMergeArrays: <T>(...arrays: unknown[][]) => T[];
348
```
349
350
**Parameters:**
351
- `...arrays` - Multiple arrays to flatten and merge
352
353
**Returns:** Flattened and filtered array
354
355
**Usage:**
356
357
```typescript
358
import { flatMergeArrays } from "tailwind-variants/utils";
359
360
const result = flatMergeArrays<string>(
361
["a", ["b"]],
362
["c", null, "d"],
363
[["e", false, "f"]]
364
);
365
// Returns: ["a", "b", "c", "d", "e", "f"] (falsy values filtered out)
366
```
367
368
## Component Props Utility
369
370
### VariantProps
371
372
Extracts variant prop types from a TV component for use in component interfaces.
373
374
```typescript { .api }
375
type VariantProps<Component extends (...args: any) => any> = Omit<
376
OmitUndefined<Parameters<Component>[0]>,
377
"class" | "className"
378
>;
379
```
380
381
**Parameters:**
382
- `Component` - A TV component function
383
384
**Returns:** Type representing the variant props without class/className
385
386
**Usage:**
387
388
```typescript
389
import { tv, VariantProps } from "tailwind-variants";
390
391
const button = tv({
392
base: "font-medium rounded-lg",
393
variants: {
394
color: {
395
primary: "bg-blue-500 text-white",
396
secondary: "bg-gray-500 text-white",
397
},
398
size: {
399
sm: "px-3 py-1.5 text-sm",
400
md: "px-4 py-2 text-base",
401
},
402
},
403
});
404
405
// Extract props type for React component
406
type ButtonProps = VariantProps<typeof button> & {
407
children: React.ReactNode;
408
};
409
// Results in: { color?: "primary" | "secondary"; size?: "sm" | "md"; children: React.ReactNode; }
410
411
function Button({ color, size, children, ...props }: ButtonProps) {
412
return (
413
<button className={button({ color, size })} {...props}>
414
{children}
415
</button>
416
);
417
}
418
```
419
420
## Type Definitions
421
422
```typescript { .api }
423
type CnClassValue =
424
| string
425
| number
426
| bigint
427
| boolean
428
| null
429
| undefined
430
| CnClassDictionary
431
| CnClassArray;
432
433
interface CnClassDictionary {
434
[key: string]: any;
435
}
436
437
interface CnClassArray extends Array<CnClassValue> {}
438
439
type CnOptions = CnClassValue[];
440
441
type CnReturn = string | undefined;
442
443
interface TWMConfig {
444
twMerge?: boolean;
445
twMergeConfig?: TWMergeConfig;
446
}
447
448
type OmitUndefined<T> = T extends undefined ? never : T;
449
450
type StringToBoolean<T> = T extends "true" | "false" ? boolean : T;
451
```