or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

config.mdextraction.mdgenerator.mdindex.mdrules-variants.mdtypes.mdutilities.md

utilities.mddocs/

0

# Utilities and Helpers

1

2

UnoCSS Core provides a comprehensive utility library with functions for CSS processing, type manipulation, selector escaping, variant group handling, and development helpers.

3

4

## Array and Type Utilities

5

6

```typescript { .api }

7

function toArray<T>(value: T | T[] = []): T[];

8

function uniq<T>(value: T[]): T[];

9

function uniqueBy<T>(array: readonly T[], equalFn: (a: T, b: T) => boolean): T[];

10

function isString(s: any): s is string;

11

function notNull<T>(value: T | null | undefined): value is T;

12

function noop(): void;

13

```

14

15

**Basic type and array manipulation:**

16

- **toArray**: Converts single values or arrays to arrays

17

- **uniq**: Removes duplicate values from arrays

18

- **uniqueBy**: Removes duplicates using custom comparison function

19

- **isString**: Type guard for string values

20

- **notNull**: Type guard for non-null values

21

- **noop**: No-operation function

22

23

### Usage Examples

24

25

```typescript

26

import { toArray, uniq, uniqueBy, isString } from '@unocss/core';

27

28

// Convert to array

29

toArray('single') // ['single']

30

toArray(['already', 'array']) // ['already', 'array']

31

32

// Remove duplicates

33

uniq(['a', 'b', 'a', 'c']) // ['a', 'b', 'c']

34

35

// Remove duplicates with custom comparison

36

const items = [{ id: 1, name: 'A' }, { id: 1, name: 'B' }, { id: 2, name: 'C' }];

37

uniqueBy(items, (a, b) => a.id === b.id) // [{ id: 1, name: 'A' }, { id: 2, name: 'C' }]

38

39

// Type checking

40

if (isString(value)) {

41

// TypeScript knows value is string here

42

console.log(value.toUpperCase());

43

}

44

```

45

46

## CSS Processing Utilities

47

48

```typescript { .api }

49

function normalizeCSSEntries(obj: string | CSSEntriesInput | CSSObjectInput): string | CSSEntries;

50

function normalizeCSSValues(obj: CSSValueInput | string | (CSSValueInput | string)[]): (string | CSSEntries)[];

51

function entriesToCss(arr?: CSSEntries): string;

52

function clearIdenticalEntries(entry: CSSEntries): CSSEntries;

53

54

const VirtualKey: string = '__virtual_key__';

55

```

56

57

**CSS data processing:**

58

- **normalizeCSSEntries**: Converts CSS objects/entries to normalized format

59

- **normalizeCSSValues**: Normalizes various CSS value input formats

60

- **entriesToCss**: Converts CSS entries to CSS string

61

- **clearIdenticalEntries**: Removes duplicate CSS properties

62

- **VirtualKey**: Special key for virtual CSS properties

63

64

### CSS Processing Examples

65

66

```typescript

67

import { normalizeCSSEntries, entriesToCss } from '@unocss/core';

68

69

// Normalize CSS input

70

const entries = normalizeCSSEntries({

71

color: 'red',

72

margin: '1rem',

73

padding: '0.5rem'

74

});

75

76

// Convert to CSS string

77

const css = entriesToCss([

78

['color', 'red'],

79

['margin', '1rem'],

80

['padding', '0.5rem']

81

]);

82

// Result: "color:red;margin:1rem;padding:0.5rem;"

83

```

84

85

## Object Manipulation Utilities

86

87

```typescript { .api }

88

function mergeDeep<T>(original: T, patch: DeepPartial<T>, mergeArray?: boolean): T;

89

function clone<T>(val: T): T;

90

function isObject(item: any): item is Record<string, any>;

91

```

92

93

**Deep object operations:**

94

- **mergeDeep**: Deep merges objects with optional array merging

95

- **clone**: Creates deep copy of values (objects, arrays, primitives)

96

- **isObject**: Type guard for plain objects

97

98

### Object Utility Examples

99

100

```typescript

101

import { mergeDeep, clone } from '@unocss/core';

102

103

// Deep merge objects

104

const original = { theme: { colors: { primary: 'blue' } } };

105

const patch = { theme: { colors: { secondary: 'red' } } };

106

const merged = mergeDeep(original, patch);

107

// Result: { theme: { colors: { primary: 'blue', secondary: 'red' } } }

108

109

// Clone objects

110

const original = { nested: { value: 42 } };

111

const cloned = clone(original);

112

cloned.nested.value = 100; // original.nested.value is still 42

113

```

114

115

## Selector Escaping

116

117

```typescript { .api }

118

function escapeSelector(str: string): string;

119

function escapeRegExp(string: string): string;

120

const e: typeof escapeSelector;

121

```

122

123

**CSS selector escaping:**

124

- **escapeSelector**: Escapes CSS selector strings according to CSS spec

125

- **escapeRegExp**: Escapes regex special characters

126

- **e**: Short alias for escapeSelector

127

128

### Escaping Examples

129

130

```typescript

131

import { escapeSelector, e } from '@unocss/core';

132

133

// Escape CSS selectors

134

escapeSelector('bg-red-500') // '.bg-red-500'

135

escapeSelector('w-1/2') // '.w-1\\/2'

136

escapeSelector('2xl:text-lg') // '.\\32 xl\\:text-lg'

137

138

// Short alias

139

e('hover:bg-blue') // '.hover\\:bg-blue'

140

```

141

142

## Rule and Shortcut Type Guards

143

144

```typescript { .api }

145

function isStaticRule(rule: Rule<any>): rule is StaticRule;

146

function isStaticShortcut(sc: Shortcut<any>): sc is StaticShortcut;

147

function isRawUtil(util: ParsedUtil | RawUtil | StringifiedUtil): util is RawUtil;

148

```

149

150

**Type discrimination:**

151

- **isStaticRule**: Checks if rule is static (string matcher)

152

- **isStaticShortcut**: Checks if shortcut is static

153

- **isRawUtil**: Checks if utility is raw CSS

154

155

## Variant Group Processing

156

157

```typescript { .api }

158

function parseVariantGroup(str: string | MagicString, separators?: string[], depth?: number): {

159

prefixes: string[];

160

hasChanged: boolean;

161

groupsByOffset: Map<number, VariantGroup>;

162

expanded: string;

163

};

164

165

function expandVariantGroup(str: string, separators?: string[], depth?: number): string;

166

function expandVariantGroup(str: MagicString, separators?: string[], depth?: number): MagicString;

167

168

function collapseVariantGroup(str: string, prefixes: string[]): string;

169

function makeRegexClassGroup(separators?: string[]): RegExp;

170

```

171

172

**Variant group manipulation:**

173

- **parseVariantGroup**: Parses variant group syntax with detailed information

174

- **expandVariantGroup**: Expands variant groups into individual classes

175

- **collapseVariantGroup**: Collapses classes back into variant groups

176

- **makeRegexClassGroup**: Creates regex for matching variant groups

177

178

### Variant Group Examples

179

180

```typescript

181

import { expandVariantGroup, collapseVariantGroup } from '@unocss/core';

182

183

// Expand variant groups

184

expandVariantGroup('hover:(bg-red text-white)')

185

// Result: 'hover:bg-red hover:text-white'

186

187

expandVariantGroup('md:(flex items-center) lg:(grid grid-cols-2)')

188

// Result: 'md:flex md:items-center lg:grid lg:grid-cols-2'

189

190

// Collapse back to groups

191

collapseVariantGroup('hover:bg-red hover:text-white', ['hover:'])

192

// Result: 'hover:(bg-red text-white)'

193

```

194

195

## Enhanced Data Structures

196

197

### CountableSet

198

199

```typescript { .api }

200

class CountableSet<K> extends Set<K> {

201

getCount(key: K): number;

202

setCount(key: K, count: number): this;

203

add(key: K): this;

204

delete(key: K): boolean;

205

clear(): void;

206

}

207

208

function isCountableSet<T = string>(value: any): value is CountableSet<T>;

209

```

210

211

Set that tracks occurrence frequency for each item.

212

213

### TwoKeyMap

214

215

```typescript { .api }

216

class TwoKeyMap<K1, K2, V> {

217

get(key1: K1, key2: K2): V | undefined;

218

getFallback(key1: K1, key2: K2, fallback: V): V;

219

set(key1: K1, key2: K2, value: V): this;

220

has(key1: K1, key2: K2): boolean;

221

delete(key1: K1, key2: K2): boolean;

222

deleteTop(key1: K1): boolean;

223

map<T>(fn: (v: V, k1: K1, k2: K2) => T): T[];

224

}

225

```

226

227

Two-level map for nested key-value storage.

228

229

### BetterMap

230

231

```typescript { .api }

232

class BetterMap<K, V> extends Map<K, V> {

233

getFallback(key: K, fallback: V): V;

234

map<R>(mapFn: (value: V, key: K) => R): R[];

235

flatMap<R extends readonly unknown[]>(mapFn: (value: V, key: K) => R): R[number][];

236

}

237

```

238

239

Enhanced Map with utility methods.

240

241

### Data Structure Examples

242

243

```typescript

244

import { CountableSet, TwoKeyMap, BetterMap } from '@unocss/core';

245

246

// CountableSet usage

247

const classes = new CountableSet(['flex', 'p-4', 'flex']);

248

classes.getCount('flex') // 2

249

classes.getCount('p-4') // 1

250

251

// TwoKeyMap usage

252

const cache = new TwoKeyMap<string, string, number>();

253

cache.set('theme', 'dark', 1);

254

cache.set('theme', 'light', 2);

255

cache.get('theme', 'dark') // 1

256

257

// BetterMap usage

258

const map = new BetterMap();

259

map.set('a', 1);

260

map.set('b', 2);

261

map.getFallback('c', 3) // Sets and returns 3

262

map.map((value, key) => `${key}:${value}`) // ['a:1', 'b:2', 'c:3']

263

```

264

265

## Layer Utilities

266

267

```typescript { .api }

268

function withLayer<T extends object>(layer: string, rules: Rule<T>[]): Rule<T>[];

269

```

270

271

Adds layer metadata to rules.

272

273

```typescript

274

import { withLayer } from '@unocss/core';

275

276

const componentRules = [

277

['btn', { padding: '0.5rem 1rem' }],

278

['card', { border: '1px solid #ccc' }]

279

];

280

281

const layeredRules = withLayer('components', componentRules);

282

// All rules now have layer: 'components' metadata

283

```

284

285

## Event System

286

287

```typescript { .api }

288

function createNanoEvents<Events extends EventsMap = DefaultEvents>(): Emitter<Events>;

289

290

interface Emitter<Events extends EventsMap = DefaultEvents> {

291

events: Partial<{ [E in keyof Events]: Events[E][] }>;

292

on<K extends keyof Events>(event: K, cb: Events[K]): Unsubscribe;

293

emit<K extends keyof Events>(event: K, ...args: Parameters<Events[K]>): void;

294

}

295

296

interface Unsubscribe {

297

(): void;

298

}

299

```

300

301

Lightweight event emitter for internal communication.

302

303

## Warning System

304

305

```typescript { .api }

306

function warnOnce(msg: string): void;

307

```

308

309

Warns once per unique message to avoid spam.

310

311

```typescript

312

import { warnOnce } from '@unocss/core';

313

314

// Only shows warning once even if called multiple times

315

warnOnce('Deprecated feature used');

316

warnOnce('Deprecated feature used'); // Silent

317

```

318

319

## Validator Utilities

320

321

```typescript { .api }

322

function isAttributifySelector(selector: string): boolean;

323

function isValidSelector(selector?: string): boolean;

324

function normalizeVariant(variant: Variant<any>): VariantObject<any>;

325

```

326

327

**Validation helpers:**

328

- **isAttributifySelector**: Checks if selector uses attributify syntax

329

- **isValidSelector**: Validates CSS selector format

330

- **normalizeVariant**: Converts variant functions to objects

331

332

### Validation Examples

333

334

```typescript

335

import { isAttributifySelector, isValidSelector } from '@unocss/core';

336

337

// Check selector types

338

isAttributifySelector('[bg-red~=""]') // true

339

isAttributifySelector('.bg-red') // false

340

341

// Validate selectors

342

isValidSelector('valid-class') // true

343

isValidSelector('') // false

344

isValidSelector('123invalid') // false

345

```