or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

adapter.mdbreakpoints.mdcomposition-hooks.mdcss-utilities.mddesign-system.mdindex.mdsetup.mdsvg-icons.mdtheme-mode.md

css-utilities.mddocs/

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