0
# Vanilla Extract Sprinkles
1
2
Vanilla Extract Sprinkles is a zero-runtime atomic CSS framework that generates static utility classes for vanilla-extract. It enables developers to create type-safe, custom atomic CSS systems by defining properties, conditions (media queries, selectors), and shorthands through a declarative configuration API. All CSS is generated at build time with optional lightweight runtime composition for dynamic styling.
3
4
## Package Information
5
6
- **Package Name**: @vanilla-extract/sprinkles
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**:
10
- npm: `npm install @vanilla-extract/sprinkles`
11
- yarn: `yarn add @vanilla-extract/sprinkles`
12
- pnpm: `pnpm add @vanilla-extract/sprinkles`
13
14
## Core Imports
15
16
```typescript
17
import { defineProperties, createSprinkles } from "@vanilla-extract/sprinkles";
18
```
19
20
For utilities:
21
22
```typescript
23
import { createMapValueFn, createNormalizeValueFn } from "@vanilla-extract/sprinkles";
24
```
25
26
For runtime usage:
27
28
```typescript
29
import { createSprinkles } from "@vanilla-extract/sprinkles/createRuntimeSprinkles";
30
```
31
32
For standalone utilities:
33
34
```typescript
35
import { createMapValueFn, createNormalizeValueFn } from "@vanilla-extract/sprinkles/createUtils";
36
```
37
38
## Basic Usage
39
40
```typescript
41
import { defineProperties, createSprinkles } from "@vanilla-extract/sprinkles";
42
43
// Define properties with conditions and values
44
const responsiveProperties = defineProperties({
45
conditions: {
46
mobile: {},
47
tablet: { '@media': 'screen and (min-width: 768px)' },
48
desktop: { '@media': 'screen and (min-width: 1024px)' }
49
},
50
defaultCondition: 'mobile',
51
properties: {
52
display: ['none', 'flex', 'block', 'inline'],
53
flexDirection: ['row', 'column'],
54
paddingTop: {
55
small: '4px',
56
medium: '8px',
57
large: '16px'
58
}
59
},
60
shorthands: {
61
padding: ['paddingTop', 'paddingBottom', 'paddingLeft', 'paddingRight'],
62
paddingX: ['paddingLeft', 'paddingRight'],
63
paddingY: ['paddingTop', 'paddingBottom']
64
}
65
});
66
67
// Create sprinkles function
68
export const sprinkles = createSprinkles(responsiveProperties);
69
70
// Use in .css.ts files (build-time)
71
export const container = sprinkles({
72
display: 'flex',
73
paddingX: 'small',
74
flexDirection: {
75
mobile: 'column',
76
desktop: 'row'
77
}
78
});
79
80
// Use at runtime
81
const dynamicClass = sprinkles({
82
display: 'flex',
83
paddingTop: ['small', 'medium', 'large']
84
});
85
```
86
87
## Architecture
88
89
Vanilla Extract Sprinkles is built around several key concepts:
90
91
- **Properties Definition**: `defineProperties` creates atomic CSS class configurations with support for conditions, shorthands, and responsive arrays
92
- **Sprinkles Function**: `createSprinkles` generates a type-safe function that composes utility classes
93
- **Build-time Generation**: All CSS classes are generated during build via vanilla-extract's file scope
94
- **Runtime Composition**: Optional runtime usage for dynamic class composition with minimal overhead
95
- **Type Safety**: Full TypeScript support with conditional types and property validation
96
- **Conditions System**: Support for media queries, selectors, @supports, and @container queries
97
98
## Capabilities
99
100
### Property Definition
101
102
Core functionality for defining atomic CSS properties with conditions, shorthands, and responsive configurations. This is the foundation for creating custom utility class systems.
103
104
```typescript { .api }
105
function defineProperties<
106
Properties extends AtomicProperties,
107
Conditions extends BaseConditions,
108
DefaultCondition extends keyof Conditions | Array<keyof Conditions> | false
109
>(
110
options: ConditionalAtomicOptions<Properties, Conditions, DefaultCondition>
111
): ConditionalAtomicStyles<Properties, Conditions, DefaultCondition>;
112
```
113
114
[Property Definition](./property-definition.md)
115
116
### Sprinkles Creation
117
118
Transform property definitions into type-safe utility functions that generate CSS class names. Supports both build-time and runtime usage patterns.
119
120
```typescript { .api }
121
function createSprinkles<Args extends ReadonlyArray<SprinklesProperties>>(
122
...config: Args
123
): SprinklesFn<Args>;
124
125
type SprinklesFn<Args extends ReadonlyArray<SprinklesProperties>> = ((
126
props: SprinkleProps<Args>
127
) => string) & { properties: Set<keyof SprinkleProps<Args>> };
128
```
129
130
[Sprinkles Creation](./sprinkles-creation.md)
131
132
### Conditional Value Utilities
133
134
Helper functions for working with conditional values in responsive and theme-based styling scenarios.
135
136
```typescript { .api }
137
function createMapValueFn<SprinklesProperties extends Conditions<string>>(
138
properties: SprinklesProperties
139
): <OutputValue, Value>(
140
value: Value,
141
fn: (inputValue: ExtractValue<Value>, key: string) => OutputValue
142
) => OutputValue | Partial<Record<string, OutputValue>>;
143
144
function createNormalizeValueFn<SprinklesProperties extends Conditions<string>>(
145
properties: SprinklesProperties
146
): <Value>(
147
value: ConditionalValue<SprinklesProperties, Value>
148
) => Partial<Record<string, Value>>;
149
```
150
151
[Conditional Value Utilities](./conditional-value-utilities.md)
152
153
### Runtime Sprinkles
154
155
Lightweight runtime version of sprinkles creation for dynamic styling without build-time constraints.
156
157
```typescript { .api }
158
function createSprinkles<Args extends ReadonlyArray<SprinklesProperties>>(
159
...args: Args
160
): SprinklesFn<Args>;
161
```
162
163
[Runtime Sprinkles](./runtime-sprinkles.md)
164
165
## Types
166
167
```typescript { .api }
168
type ConditionalValue<
169
SprinklesProperties extends Conditions<string>,
170
Value extends string | number | boolean
171
> =
172
| Value
173
| Partial<Record<string, Value>>
174
| ResponsiveArrayByMaxLength<number, Value>;
175
176
type RequiredConditionalValue<
177
SprinklesProperties extends Conditions<string>,
178
Value extends string | number | boolean
179
> = Value | RequiredConditionalObject<string, string, Value> | ResponsiveArray<number, Value>;
180
181
interface ResponsiveArray<Length extends number, Value> extends ReadonlyArray<Value> {
182
0: Value;
183
length: Length;
184
}
185
186
interface SprinklesProperties {
187
styles: {
188
[property: string]:
189
| ConditionalWithResponsiveArrayProperty
190
| ConditionalProperty
191
| ShorthandProperty
192
| UnconditionalProperty;
193
};
194
}
195
196
interface ConditionalPropertyValue {
197
defaultClass: string | undefined;
198
conditions: {
199
[conditionName: string]: string;
200
};
201
}
202
203
interface ConditionalProperty {
204
values: {
205
[valueName: string]: ConditionalPropertyValue;
206
};
207
}
208
209
interface UnconditionalProperty {
210
values: {
211
[valueName: string]: {
212
defaultClass: string;
213
};
214
};
215
}
216
217
interface ShorthandProperty {
218
mappings: Array<string>;
219
}
220
221
interface ConditionalWithResponsiveArrayProperty {
222
responsiveArray: Array<string>;
223
values: {
224
[valueName: string]: ConditionalPropertyValue;
225
};
226
}
227
228
type AtomicProperties = {
229
[Property in keyof CSSProperties]?:
230
| Record<string, CSSProperties[Property] | Omit<StyleRule, ConditionKey>>
231
| ReadonlyArray<CSSProperties[Property]>;
232
} | Record<string, Record<string | number, Omit<StyleRule, ConditionKey>>>;
233
234
type BaseConditions = { [conditionName: string]: Partial<Record<ConditionKey, string>> };
235
236
type ConditionKey = '@media' | '@supports' | '@container' | 'selector';
237
238
type AtomicCSSProperties = {
239
[Property in keyof CSSProperties]?:
240
| Record<string, CSSProperties[Property] | Omit<StyleRule, ConditionKey>>
241
| ReadonlyArray<CSSProperties[Property]>;
242
};
243
244
type AtomicCustomProperties = Record<
245
string,
246
Record<string | number, Omit<StyleRule, ConditionKey>>
247
>;
248
249
type ResponsiveArrayByMaxLength<MaxLength extends number, Value> =
250
MaxLength extends 1 ? ResponsiveArray<1, Value | null> :
251
MaxLength extends 2 ? ResponsiveArray<1 | 2, Value | null> :
252
MaxLength extends 3 ? ResponsiveArray<1 | 2 | 3, Value | null> :
253
MaxLength extends 4 ? ResponsiveArray<1 | 2 | 3 | 4, Value | null> :
254
MaxLength extends 5 ? ResponsiveArray<1 | 2 | 3 | 4 | 5, Value | null> :
255
MaxLength extends 6 ? ResponsiveArray<1 | 2 | 3 | 4 | 5 | 6, Value | null> :
256
MaxLength extends 7 ? ResponsiveArray<1 | 2 | 3 | 4 | 5 | 6 | 7, Value | null> :
257
MaxLength extends 8 ? ResponsiveArray<1 | 2 | 3 | 4 | 5 | 6 | 7 | 8, Value | null> :
258
never;
259
260
type ResponsiveArrayConfig<Value> = ResponsiveArray<2 | 3 | 4 | 5 | 6 | 7 | 8, Value>;
261
262
type ConditionalAtomicOptions<
263
Properties extends AtomicProperties,
264
Conditions extends BaseConditions,
265
DefaultCondition extends keyof Conditions | Array<keyof Conditions> | false
266
> = {
267
'@layer'?: string;
268
properties: Properties;
269
conditions: Conditions;
270
defaultCondition: DefaultCondition;
271
};
272
273
type UnconditionalAtomicOptions<Properties extends AtomicProperties> = {
274
'@layer'?: string;
275
properties: Properties;
276
};
277
278
type ShorthandOptions<
279
Properties extends AtomicProperties,
280
Shorthands extends { [shorthandName: string]: Array<keyof Properties> }
281
> = {
282
shorthands: Shorthands;
283
};
284
285
type ResponsiveArrayOptions<
286
Conditions extends BaseConditions,
287
ResponsiveLength extends number
288
> = {
289
responsiveArray: ResponsiveArrayConfig<keyof Conditions> & {
290
length: ResponsiveLength;
291
};
292
};
293
```
294
295
## Deprecated Exports
296
297
The following exports are deprecated but still available for backward compatibility:
298
299
### Main Entry (@vanilla-extract/sprinkles)
300
301
```typescript { .api }
302
/**
303
* @deprecated Use `defineProperties` instead
304
*/
305
const createAtomicStyles = defineProperties;
306
307
/**
308
* @deprecated Use `createSprinkles` instead
309
*/
310
const createAtomsFn = createSprinkles;
311
```
312
313
### Runtime Entry (@vanilla-extract/sprinkles/createRuntimeSprinkles)
314
315
```typescript { .api }
316
/**
317
* @deprecated Use `createSprinkles` instead
318
*/
319
const createAtomsFn = createSprinkles;
320
```
321
322
### Migration Guide
323
324
**From createAtomicStyles to defineProperties:**
325
326
```typescript
327
// Old (deprecated)
328
import { createAtomicStyles } from "@vanilla-extract/sprinkles";
329
const styles = createAtomicStyles({ /* config */ });
330
331
// New (recommended)
332
import { defineProperties } from "@vanilla-extract/sprinkles";
333
const styles = defineProperties({ /* config */ });
334
```
335
336
**From createAtomsFn to createSprinkles:**
337
338
```typescript
339
// Old (deprecated) - Build-time
340
import { createAtomsFn } from "@vanilla-extract/sprinkles";
341
const atoms = createAtomsFn(properties);
342
343
// New (recommended) - Build-time
344
import { createSprinkles } from "@vanilla-extract/sprinkles";
345
const sprinkles = createSprinkles(properties);
346
347
// Old (deprecated) - Runtime
348
import { createAtomsFn } from "@vanilla-extract/sprinkles/createRuntimeSprinkles";
349
const atoms = createAtomsFn(properties);
350
351
// New (recommended) - Runtime
352
import { createSprinkles } from "@vanilla-extract/sprinkles/createRuntimeSprinkles";
353
const sprinkles = createSprinkles(properties);
354
```