0
# CSS Class Utilities
1
2
The CSS Class Utilities provide comprehensive tools for managing CSS classes including Tailwind CSS class merging, object/array stringification, and deduplication. These utilities enable dynamic class composition and consistent styling across components.
3
4
## Capabilities
5
6
### Class Merging with Tailwind
7
8
Advanced CSS class merging that intelligently handles Tailwind CSS class conflicts and deduplication.
9
10
```typescript { .api }
11
/**
12
* Merge CSS classes with Tailwind-aware conflict resolution
13
* @param cssClasses - Variable number of CSS class inputs
14
* @returns Merged and deduplicated class string
15
*/
16
function mergeClass(...cssClasses: CssClass[]): string;
17
18
type CssClass = string | CssClassObject | CssClassArray;
19
interface CssClassObject {
20
[key: string]: any;
21
}
22
type CssClassArray = Array<string | CssClassObject>;
23
```
24
25
**Usage Examples:**
26
27
```typescript
28
import { mergeClass } from "@opentiny/vue-common";
29
30
// Merge simple class strings
31
const classes = mergeClass('btn', 'text-blue-500', 'hover:text-blue-700');
32
// Result: "btn text-blue-500 hover:text-blue-700"
33
34
// Handle Tailwind conflicts (later classes override earlier ones)
35
const conflictResolved = mergeClass('text-red-500', 'text-blue-500');
36
// Result: "text-blue-500" (blue overrides red)
37
38
// Mix strings, objects, and arrays
39
const mixed = mergeClass(
40
'base-class',
41
{ 'active': isActive, 'disabled': !enabled },
42
['flex', 'items-center'],
43
conditionalClass && 'extra-class'
44
);
45
46
// Responsive classes
47
const responsive = mergeClass(
48
'w-full',
49
'sm:w-1/2',
50
'md:w-1/3',
51
'lg:w-1/4'
52
);
53
```
54
55
### Class Stringification
56
57
Utilities for converting various CSS class formats to strings.
58
59
```typescript { .api }
60
/**
61
* Convert CSS classes to string format
62
* @param cssClasses - CSS classes in any supported format
63
* @returns Stringified CSS classes
64
*/
65
function stringifyCssClass(cssClasses: CssClass[] | CssClass): string;
66
67
/**
68
* Convert CSS class object to string
69
* @param cssClassObject - Object with class names as keys and boolean values
70
* @returns Space-separated class string
71
*/
72
function stringifyCssClassObject(cssClassObject: CssClassObject): string;
73
74
/**
75
* Convert CSS class array to string
76
* @param cssClassArray - Array of strings and/or objects
77
* @returns Space-separated class string
78
*/
79
function stringifyCssClassArray(cssClassArray: CssClassArray): string;
80
```
81
82
**Usage Examples:**
83
84
```typescript
85
import {
86
stringifyCssClass,
87
stringifyCssClassObject,
88
stringifyCssClassArray
89
} from "@opentiny/vue-common";
90
91
// Object to string conversion
92
const objectClasses = stringifyCssClassObject({
93
'btn': true,
94
'btn-primary': isPrimary,
95
'btn-disabled': !enabled,
96
'btn-large': size === 'large'
97
});
98
99
// Array to string conversion
100
const arrayClasses = stringifyCssClassArray([
101
'flex',
102
'items-center',
103
{ 'justify-between': spaceBetween },
104
isVisible && 'opacity-100'
105
]);
106
107
// Mixed formats to string
108
const mixedClasses = stringifyCssClass([
109
'container',
110
{ 'mx-auto': centered },
111
['px-4', 'py-2'],
112
'shadow-md'
113
]);
114
```
115
116
### Class Deduplication
117
118
Remove duplicate CSS classes while preserving order and handling complex class structures.
119
120
```typescript { .api }
121
/**
122
* Remove duplicate CSS classes
123
* @param cssClasses - CSS classes in any supported format
124
* @returns Deduplicated class string
125
*/
126
function deduplicateCssClass(cssClasses: CssClass[] | CssClass): string;
127
```
128
129
**Usage Examples:**
130
131
```typescript
132
import { deduplicateCssClass } from "@opentiny/vue-common";
133
134
// Remove duplicates from mixed sources
135
const deduplicated = deduplicateCssClass([
136
'btn btn-primary',
137
{ 'btn': true, 'hover:btn-hover': true },
138
['btn-primary', 'focus:outline-none'],
139
'btn btn-primary' // duplicates will be removed
140
]);
141
// Result: "btn btn-primary hover:btn-hover focus:outline-none"
142
143
// Handle complex nested structures
144
const complex = deduplicateCssClass([
145
'flex items-center',
146
{ 'flex': true, 'space-x-2': hasSpacing },
147
['items-center', 'justify-center'],
148
spaced && 'space-x-2'
149
]);
150
```
151
152
## Advanced Usage Patterns
153
154
### Conditional Class Application
155
156
Patterns for applying classes based on component state and props.
157
158
```typescript
159
import { mergeClass, hooks } from "@opentiny/vue-common";
160
161
export default {
162
setup(props) {
163
// Computed classes based on props
164
const containerClasses = hooks.computed(() => mergeClass(
165
'component-base',
166
{
167
'component-primary': props.type === 'primary',
168
'component-secondary': props.type === 'secondary',
169
'component-disabled': props.disabled,
170
'component-loading': props.loading
171
},
172
props.size === 'small' && 'component-sm',
173
props.size === 'large' && 'component-lg',
174
props.customClass
175
));
176
177
// Responsive classes
178
const responsiveClasses = hooks.computed(() => mergeClass(
179
'w-full',
180
'sm:w-1/2 sm:max-w-md',
181
'md:w-1/3 md:max-w-lg',
182
'lg:w-1/4 lg:max-w-xl'
183
));
184
185
return {
186
containerClasses,
187
responsiveClasses
188
};
189
}
190
};
191
```
192
193
### Theme-Based Class Management
194
195
Integration with theme systems for dynamic styling.
196
197
```typescript
198
import { mergeClass, hooks } from "@opentiny/vue-common";
199
200
export default {
201
setup(props) {
202
const theme = hooks.inject('theme', 'light');
203
204
const themeClasses = hooks.computed(() => {
205
const baseClasses = 'transition-colors duration-200';
206
207
const themeMap = {
208
light: 'bg-white text-gray-900 border-gray-200',
209
dark: 'bg-gray-900 text-white border-gray-700',
210
auto: 'bg-white dark:bg-gray-900 text-gray-900 dark:text-white'
211
};
212
213
return mergeClass(
214
baseClasses,
215
themeMap[theme.value] || themeMap.light,
216
props.variant === 'outlined' && 'border-2',
217
props.variant === 'filled' && 'shadow-md'
218
);
219
});
220
221
return {
222
themeClasses
223
};
224
}
225
};
226
```
227
228
### Form Control Class Patterns
229
230
Common patterns for form controls with validation states.
231
232
```typescript
233
import { mergeClass, hooks } from "@opentiny/vue-common";
234
235
export default {
236
setup(props) {
237
const inputClasses = hooks.computed(() => mergeClass(
238
// Base styles
239
'block w-full rounded-md border-0 py-1.5 px-3',
240
'text-gray-900 shadow-sm ring-1 ring-inset',
241
'placeholder:text-gray-400 focus:ring-2 focus:ring-inset',
242
'sm:text-sm sm:leading-6',
243
244
// Size variants
245
{
246
'py-1 px-2 text-xs': props.size === 'small',
247
'py-2 px-4 text-base': props.size === 'large'
248
},
249
250
// State-based styles
251
{
252
'ring-gray-300 focus:ring-indigo-600': !props.error && !props.success,
253
'ring-red-300 focus:ring-red-600': props.error,
254
'ring-green-300 focus:ring-green-600': props.success,
255
'bg-gray-50 cursor-not-allowed': props.disabled
256
}
257
));
258
259
const labelClasses = hooks.computed(() => mergeClass(
260
'block text-sm font-medium leading-6',
261
{
262
'text-gray-900': !props.error,
263
'text-red-600': props.error,
264
'text-green-600': props.success
265
}
266
));
267
268
return {
269
inputClasses,
270
labelClasses
271
};
272
}
273
};
274
```
275
276
## Integration with Design Systems
277
278
### Custom Design Tokens
279
280
Integration with custom design token systems.
281
282
```typescript
283
import { mergeClass, customDesignConfig } from "@opentiny/vue-common";
284
285
// Configure custom design system
286
customDesignConfig.designConfig = {
287
tokens: {
288
colors: {
289
primary: 'blue-600',
290
secondary: 'gray-600'
291
},
292
spacing: {
293
small: '0.5rem',
294
medium: '1rem',
295
large: '2rem'
296
}
297
}
298
};
299
300
// Use design tokens in components
301
export default {
302
setup(props) {
303
const buttonClasses = hooks.computed(() => mergeClass(
304
'inline-flex items-center justify-center',
305
'rounded-md font-medium transition-colors',
306
307
// Use design tokens
308
props.variant === 'primary' && `bg-${customDesignConfig.designConfig.tokens.colors.primary}`,
309
props.size === 'small' && `px-3 py-1.5 text-sm`,
310
props.size === 'medium' && `px-4 py-2 text-sm`,
311
props.size === 'large' && `px-6 py-3 text-base`
312
));
313
314
return {
315
buttonClasses
316
};
317
}
318
};
319
```
320
321
## Performance Considerations
322
323
The CSS utilities are optimized for performance:
324
325
- **Lazy Evaluation**: Class strings are only computed when needed
326
- **Memoization**: Repeated class combinations are cached when used in computed properties
327
- **Efficient Deduplication**: Uses Set-based deduplication for optimal performance
328
- **Memory Management**: No memory leaks from class string accumulation