@designid/tokens 0.4.6 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/build.js +413 -76
- package/bin/watch.js +25 -2
- package/package.json +8 -11
- package/types/design-tokens.ts +1083 -0
- package/types/files.d.ts +116 -3
- package/types/index.d.ts +79 -0
- package/types/token.d.ts +31 -0
- package/types/typography.d.ts +51 -0
- package/types/utils.d.ts +49 -0
- package/bin/build-icons.js +0 -2
- package/example/tokens/border/composition.tokens.json +0 -31
- package/example/tokens/colors/brand/primary.tokens.json +0 -44
- package/example/tokens/colors/icon/mono.tokens.json +0 -15
- package/example/tokens/effect/shadow.tokens.json +0 -41
- package/example/tokens/font/family.tokens.json +0 -110
- package/example/tokens/font/h1.tokens.json +0 -59
- package/example/tokens/foundation.tokens.json +0 -145
|
@@ -0,0 +1,1083 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* W3C Design Tokens Format Module - TypeScript Types
|
|
3
|
+
* Based on the Design Tokens Community Group Draft (September 2025)
|
|
4
|
+
* https://deploy-preview-298--designtokensorg.netlify.app/tr/drafts/format/
|
|
5
|
+
*
|
|
6
|
+
* This file provides complete TypeScript type definitions for the W3C Design Tokens specification,
|
|
7
|
+
* including all basic types, composite types, references, aliases, and group structures.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// CORE DESIGN TOKEN INTERFACES
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Base properties available on all design tokens
|
|
16
|
+
*/
|
|
17
|
+
export interface DesignTokenBase {
|
|
18
|
+
/** The token's type - required if not inherited from parent groups */
|
|
19
|
+
$type?: string;
|
|
20
|
+
|
|
21
|
+
/** Human-readable description of the token's purpose */
|
|
22
|
+
$description?: string;
|
|
23
|
+
|
|
24
|
+
/** Enhanced vendor-specific extensions with mode and generators support */
|
|
25
|
+
$extensions?: EnhancedExtensionData;
|
|
26
|
+
|
|
27
|
+
/** Deprecation status and optional explanation */
|
|
28
|
+
$deprecated?: boolean | string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A design token with an explicit value
|
|
33
|
+
*/
|
|
34
|
+
export interface DesignToken<T = unknown> extends DesignTokenBase {
|
|
35
|
+
/** The token's value */
|
|
36
|
+
$value: T;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Reference to another token using curly brace syntax
|
|
41
|
+
*/
|
|
42
|
+
export type TokenReference = `{${string}}`;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* JSON Pointer reference using $ref property
|
|
46
|
+
*/
|
|
47
|
+
export interface JsonPointerReference {
|
|
48
|
+
$ref: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Composite string value that can contain multiple references and literal values
|
|
53
|
+
* Examples:
|
|
54
|
+
* - "{a.b.c}, 16px" (token reference + literal)
|
|
55
|
+
* - "{a.b} {a.c}" (multiple token references)
|
|
56
|
+
* - "16px {#/ref}" (literal + JSON pointer)
|
|
57
|
+
* - "{token.ref} solid {#/colors/primary}" (mixed reference types)
|
|
58
|
+
*/
|
|
59
|
+
export type CompositeStringValue = string & {
|
|
60
|
+
readonly __brand: 'CompositeStringValue';
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Union type for values that can be explicit, references, or composite strings
|
|
65
|
+
*/
|
|
66
|
+
export type ValueOrReference<T> = T | TokenReference | JsonPointerReference | CompositeStringValue;
|
|
67
|
+
|
|
68
|
+
// ============================================================================
|
|
69
|
+
// BASIC TYPES
|
|
70
|
+
// ============================================================================
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Color value in sRGB color space
|
|
74
|
+
* @see https://deploy-preview-298--designtokensorg.netlify.app/tr/drafts/color
|
|
75
|
+
*/
|
|
76
|
+
export interface ColorValue {
|
|
77
|
+
/** Color space identifier */
|
|
78
|
+
colorSpace: 'srgb';
|
|
79
|
+
/** RGB components as numbers between 0 and 1 */
|
|
80
|
+
components: [number, number, number];
|
|
81
|
+
/** Optional alpha channel (0-1) */
|
|
82
|
+
alpha?: number;
|
|
83
|
+
/** Hex representation (optional, for convenience) */
|
|
84
|
+
hex?: string;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Extended color value supporting additional color spaces and string formats
|
|
89
|
+
* Supports OKLCH, CSS color functions, and hex strings commonly used in design systems
|
|
90
|
+
*/
|
|
91
|
+
export type ExtendedColorValue =
|
|
92
|
+
| ColorValue
|
|
93
|
+
| string; // OKLCH string like "oklch(100% 0 236.74)" or hex like "#ff0000"
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Color design token with extended color space support
|
|
97
|
+
*/
|
|
98
|
+
export interface ColorToken extends DesignToken<ValueOrReference<ExtendedColorValue>> {
|
|
99
|
+
$type: 'color';
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Dimension value with numeric value and unit
|
|
104
|
+
*/
|
|
105
|
+
export interface DimensionValue {
|
|
106
|
+
/** Numeric value (integer or floating-point) */
|
|
107
|
+
value: number;
|
|
108
|
+
/** Unit of measurement */
|
|
109
|
+
unit: 'px' | 'rem';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Dimension design token
|
|
114
|
+
*/
|
|
115
|
+
export interface DimensionToken extends DesignToken<ValueOrReference<DimensionValue>> {
|
|
116
|
+
$type: 'dimension';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Font family value - string or array of strings
|
|
121
|
+
*/
|
|
122
|
+
export type FontFamilyValue = string | string[];
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Font family design token
|
|
126
|
+
*/
|
|
127
|
+
export interface FontFamilyToken extends DesignToken<ValueOrReference<FontFamilyValue>> {
|
|
128
|
+
$type: 'fontFamily';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Font weight numeric values
|
|
133
|
+
*/
|
|
134
|
+
export type FontWeightNumeric = number; // Range [1, 1000]
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Font weight string aliases
|
|
138
|
+
*/
|
|
139
|
+
export type FontWeightString =
|
|
140
|
+
| 'thin' | 'hairline' // 100
|
|
141
|
+
| 'extra-light' | 'ultra-light' // 200
|
|
142
|
+
| 'light' // 300
|
|
143
|
+
| 'normal' | 'regular' | 'book' // 400
|
|
144
|
+
| 'medium' // 500
|
|
145
|
+
| 'semi-bold' | 'demi-bold' // 600
|
|
146
|
+
| 'bold' // 700
|
|
147
|
+
| 'extra-bold' | 'ultra-bold' // 800
|
|
148
|
+
| 'black' | 'heavy' // 900
|
|
149
|
+
| 'extra-black' | 'ultra-black'; // 950
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Font weight value
|
|
153
|
+
*/
|
|
154
|
+
export type FontWeightValue = FontWeightNumeric | FontWeightString;
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Font weight design token
|
|
158
|
+
*/
|
|
159
|
+
export interface FontWeightToken extends DesignToken<ValueOrReference<FontWeightValue>> {
|
|
160
|
+
$type: 'fontWeight';
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Font face style values (CSS font-style property)
|
|
165
|
+
*/
|
|
166
|
+
export type FontFaceStyleValue = 'normal' | 'italic' | 'oblique';
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Font face format values
|
|
170
|
+
*/
|
|
171
|
+
export type FontFaceFormatValue = 'woff2' | 'woff' | 'ttf' | 'otf' | 'eot' | 'svg';
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Base font face properties
|
|
175
|
+
*/
|
|
176
|
+
interface BaseFontFace {
|
|
177
|
+
/** Font family name */
|
|
178
|
+
family: string;
|
|
179
|
+
/** Font style description */
|
|
180
|
+
style: string;
|
|
181
|
+
/** CSS font-style property value */
|
|
182
|
+
faceStyle: FontFaceStyleValue;
|
|
183
|
+
/** Font weight numeric value */
|
|
184
|
+
weight: FontWeightNumeric;
|
|
185
|
+
/** Font file format */
|
|
186
|
+
format: FontFaceFormatValue;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Font face value with conditional directory field
|
|
191
|
+
* - If src is a URL (starts with http:// or https://), directory is optional
|
|
192
|
+
* - If src is a file path, directory is required
|
|
193
|
+
*/
|
|
194
|
+
export type FontFaceValue = BaseFontFace & (
|
|
195
|
+
| {
|
|
196
|
+
/** HTTP or HTTPS URL to font file */
|
|
197
|
+
src: `http://${string}` | `https://${string}`;
|
|
198
|
+
/** Directory is optional for URLs */
|
|
199
|
+
directory?: string;
|
|
200
|
+
}
|
|
201
|
+
| {
|
|
202
|
+
/** File path or filename */
|
|
203
|
+
src: string;
|
|
204
|
+
/** Directory is required for file paths */
|
|
205
|
+
directory: string;
|
|
206
|
+
}
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Font face design token for web font definitions
|
|
211
|
+
*/
|
|
212
|
+
export interface FontFaceToken extends DesignToken<ValueOrReference<FontFaceValue>> {
|
|
213
|
+
$type: 'fontFace';
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Font face collection value - array of font face definitions
|
|
218
|
+
*/
|
|
219
|
+
export type FontFaceCollectionValue = FontFaceValue[];
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Font face collection design token for multiple web font definitions
|
|
223
|
+
*/
|
|
224
|
+
export interface FontFaceCollectionToken extends DesignToken<ValueOrReference<FontFaceCollectionValue>> {
|
|
225
|
+
$type: 'fontFaceCollection';
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Duration value with numeric value and unit
|
|
230
|
+
*/
|
|
231
|
+
export interface DurationValue {
|
|
232
|
+
/** Numeric value (integer or floating-point) */
|
|
233
|
+
value: number;
|
|
234
|
+
/** Unit of time */
|
|
235
|
+
unit: 'ms' | 's';
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Duration design token
|
|
240
|
+
*/
|
|
241
|
+
export interface DurationToken extends DesignToken<ValueOrReference<DurationValue>> {
|
|
242
|
+
$type: 'duration';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Cubic Bézier value as array of four control points
|
|
247
|
+
*/
|
|
248
|
+
export type CubicBezierValue = [number, number, number, number];
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Cubic Bézier design token
|
|
252
|
+
*/
|
|
253
|
+
export interface CubicBezierToken extends DesignToken<ValueOrReference<CubicBezierValue>> {
|
|
254
|
+
$type: 'cubicBezier';
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Number value
|
|
259
|
+
*/
|
|
260
|
+
export type NumberValue = number;
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Number design token
|
|
264
|
+
*/
|
|
265
|
+
export interface NumberToken extends DesignToken<ValueOrReference<NumberValue>> {
|
|
266
|
+
$type: 'number';
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* String value that can be literal or composite with references
|
|
271
|
+
*/
|
|
272
|
+
export type StringValue = string;
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* String design token - supports literal strings and composite strings with references
|
|
276
|
+
* @example
|
|
277
|
+
* // Literal string
|
|
278
|
+
* { $type: 'string', $value: 'bold' }
|
|
279
|
+
*
|
|
280
|
+
* // Composite string with token reference
|
|
281
|
+
* { $type: 'string', $value: '{font.weight.bold}, 16px' }
|
|
282
|
+
*
|
|
283
|
+
* // Composite string with multiple token references
|
|
284
|
+
* { $type: 'string', $value: '{font.weight} {font.size}px' }
|
|
285
|
+
*
|
|
286
|
+
* // Composite string with JSON pointer
|
|
287
|
+
* { $type: 'string', $value: '16px {#/colors/primary}' }
|
|
288
|
+
*
|
|
289
|
+
* // Mixed reference types in one string
|
|
290
|
+
* { $type: 'string', $value: '{font.weight} solid {#/colors/border}' }
|
|
291
|
+
*/
|
|
292
|
+
export interface StringToken extends DesignToken<ValueOrReference<StringValue>> {
|
|
293
|
+
$type: 'string';
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// ============================================================================
|
|
297
|
+
// COMPOSITE TYPES
|
|
298
|
+
// ============================================================================
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Stroke style string values
|
|
302
|
+
*/
|
|
303
|
+
export type StrokeStyleString =
|
|
304
|
+
| 'solid'
|
|
305
|
+
| 'dashed'
|
|
306
|
+
| 'dotted'
|
|
307
|
+
| 'double'
|
|
308
|
+
| 'groove'
|
|
309
|
+
| 'ridge'
|
|
310
|
+
| 'outset'
|
|
311
|
+
| 'inset';
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Line cap values for stroke style
|
|
315
|
+
*/
|
|
316
|
+
export type LineCap = 'round' | 'butt' | 'square';
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Stroke style object value
|
|
320
|
+
*/
|
|
321
|
+
export interface StrokeStyleObject {
|
|
322
|
+
/** Array of dash lengths alternating between dashes and gaps */
|
|
323
|
+
dashArray: ValueOrReference<DimensionValue>[];
|
|
324
|
+
/** Line cap style */
|
|
325
|
+
lineCap: LineCap;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
/**
|
|
329
|
+
* Stroke style value - string or object
|
|
330
|
+
*/
|
|
331
|
+
export type StrokeStyleValue = StrokeStyleString | StrokeStyleObject;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Stroke style design token
|
|
335
|
+
*/
|
|
336
|
+
export interface StrokeStyleToken extends DesignToken<ValueOrReference<StrokeStyleValue>> {
|
|
337
|
+
$type: 'strokeStyle';
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Border value object
|
|
342
|
+
*/
|
|
343
|
+
export interface BorderValue {
|
|
344
|
+
/** Border color */
|
|
345
|
+
color: ValueOrReference<ExtendedColorValue>;
|
|
346
|
+
/** Border width */
|
|
347
|
+
width: ValueOrReference<DimensionValue>;
|
|
348
|
+
/** Border style */
|
|
349
|
+
style: ValueOrReference<StrokeStyleValue>;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Border design token
|
|
354
|
+
*/
|
|
355
|
+
export interface BorderToken extends DesignToken<ValueOrReference<BorderValue>> {
|
|
356
|
+
$type: 'border';
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Transition value object
|
|
361
|
+
*/
|
|
362
|
+
export interface TransitionValue {
|
|
363
|
+
/** Duration of the transition */
|
|
364
|
+
duration: ValueOrReference<DurationValue>;
|
|
365
|
+
/** Delay before transition begins */
|
|
366
|
+
delay: ValueOrReference<DurationValue>;
|
|
367
|
+
/** Timing function for the transition */
|
|
368
|
+
timingFunction: ValueOrReference<CubicBezierValue>;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Transition design token
|
|
373
|
+
*/
|
|
374
|
+
export interface TransitionToken extends DesignToken<ValueOrReference<TransitionValue>> {
|
|
375
|
+
$type: 'transition';
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Shadow value object
|
|
380
|
+
*/
|
|
381
|
+
export interface ShadowValue {
|
|
382
|
+
/** Shadow color */
|
|
383
|
+
color: ValueOrReference<ExtendedColorValue>;
|
|
384
|
+
/** Horizontal offset */
|
|
385
|
+
offsetX: ValueOrReference<DimensionValue>;
|
|
386
|
+
/** Vertical offset */
|
|
387
|
+
offsetY: ValueOrReference<DimensionValue>;
|
|
388
|
+
/** Blur radius */
|
|
389
|
+
blur: ValueOrReference<DimensionValue>;
|
|
390
|
+
/** Spread radius */
|
|
391
|
+
spread: ValueOrReference<DimensionValue>;
|
|
392
|
+
/** Whether this is an inner shadow */
|
|
393
|
+
inset?: boolean;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Shadow design token - supports single shadow or array of shadows
|
|
398
|
+
*/
|
|
399
|
+
export interface ShadowToken extends DesignToken<ValueOrReference<ShadowValue | ShadowValue[]>> {
|
|
400
|
+
$type: 'shadow';
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Gradient stop object
|
|
405
|
+
*/
|
|
406
|
+
export interface GradientStop {
|
|
407
|
+
/** Color at this stop */
|
|
408
|
+
color: ValueOrReference<ExtendedColorValue>;
|
|
409
|
+
/** Position along gradient axis (0-1) */
|
|
410
|
+
position: ValueOrReference<NumberValue>;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Gradient value as array of stops
|
|
415
|
+
*/
|
|
416
|
+
export type GradientValue = GradientStop[];
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Gradient design token
|
|
420
|
+
*/
|
|
421
|
+
export interface GradientToken extends DesignToken<ValueOrReference<GradientValue>> {
|
|
422
|
+
$type: 'gradient';
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Typography value object
|
|
427
|
+
*/
|
|
428
|
+
export interface TypographyValue {
|
|
429
|
+
/** Font family */
|
|
430
|
+
fontFamily: ValueOrReference<FontFamilyValue>;
|
|
431
|
+
/** Font size */
|
|
432
|
+
fontSize: ValueOrReference<DimensionValue>;
|
|
433
|
+
/** Font weight */
|
|
434
|
+
fontWeight: ValueOrReference<FontWeightValue>;
|
|
435
|
+
/** Letter spacing */
|
|
436
|
+
letterSpacing: ValueOrReference<DimensionValue>;
|
|
437
|
+
/** Line height as multiplier */
|
|
438
|
+
lineHeight: ValueOrReference<NumberValue>;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Typography design token
|
|
443
|
+
*/
|
|
444
|
+
export interface TypographyToken extends DesignToken<ValueOrReference<TypographyValue>> {
|
|
445
|
+
$type: 'typography';
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// ============================================================================
|
|
449
|
+
// TOKEN UNION TYPES
|
|
450
|
+
// ============================================================================
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Union of all basic token types
|
|
454
|
+
*/
|
|
455
|
+
export type BasicTokenType =
|
|
456
|
+
| ColorToken
|
|
457
|
+
| DimensionToken
|
|
458
|
+
| FontFamilyToken
|
|
459
|
+
| FontWeightToken
|
|
460
|
+
| FontFaceToken
|
|
461
|
+
| FontFaceCollectionToken
|
|
462
|
+
| DurationToken
|
|
463
|
+
| CubicBezierToken
|
|
464
|
+
| NumberToken
|
|
465
|
+
| StringToken;
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Union of all composite token types
|
|
469
|
+
*/
|
|
470
|
+
export type CompositeTokenType =
|
|
471
|
+
| StrokeStyleToken
|
|
472
|
+
| BorderToken
|
|
473
|
+
| TransitionToken
|
|
474
|
+
| ShadowToken
|
|
475
|
+
| GradientToken
|
|
476
|
+
| TypographyToken;
|
|
477
|
+
|
|
478
|
+
/**
|
|
479
|
+
* Token type string literals
|
|
480
|
+
*/
|
|
481
|
+
export type TokenType =
|
|
482
|
+
| 'color'
|
|
483
|
+
| 'dimension'
|
|
484
|
+
| 'fontFamily'
|
|
485
|
+
| 'fontWeight'
|
|
486
|
+
| 'fontFace'
|
|
487
|
+
| 'fontFaceCollection'
|
|
488
|
+
| 'duration'
|
|
489
|
+
| 'cubicBezier'
|
|
490
|
+
| 'number'
|
|
491
|
+
| 'string'
|
|
492
|
+
| 'strokeStyle'
|
|
493
|
+
| 'border'
|
|
494
|
+
| 'transition'
|
|
495
|
+
| 'shadow'
|
|
496
|
+
| 'gradient'
|
|
497
|
+
| 'typography'
|
|
498
|
+
| 'composition';
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Union of all token types
|
|
502
|
+
*/
|
|
503
|
+
export type AnyToken = BasicTokenType | CompositeTokenType;
|
|
504
|
+
|
|
505
|
+
// ============================================================================
|
|
506
|
+
// GROUP DEFINITIONS
|
|
507
|
+
// ============================================================================
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* Base properties available on groups
|
|
511
|
+
*/
|
|
512
|
+
export interface GroupBase {
|
|
513
|
+
/** Group type for type inheritance */
|
|
514
|
+
$type?: TokenType;
|
|
515
|
+
|
|
516
|
+
/** Group description */
|
|
517
|
+
$description?: string;
|
|
518
|
+
|
|
519
|
+
/** Group extension reference */
|
|
520
|
+
$extends?: TokenReference | JsonPointerReference;
|
|
521
|
+
|
|
522
|
+
/** Group deprecation status */
|
|
523
|
+
$deprecated?: boolean | string;
|
|
524
|
+
|
|
525
|
+
/** Enhanced vendor-specific extensions with mode and generators support */
|
|
526
|
+
$extensions?: EnhancedExtensionData;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/**
|
|
530
|
+
* Root token within a group using reserved $root name
|
|
531
|
+
* Can be any token type, identified by the $root key in groups
|
|
532
|
+
*/
|
|
533
|
+
export type RootToken = AnyToken;
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Group containing tokens and nested groups
|
|
537
|
+
*/
|
|
538
|
+
export interface TokenGroup extends GroupBase {
|
|
539
|
+
/** Root token for the group */
|
|
540
|
+
$root?: RootToken;
|
|
541
|
+
|
|
542
|
+
/** Nested tokens and groups */
|
|
543
|
+
[key: string]: AnyToken | TokenGroup | unknown;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// ============================================================================
|
|
547
|
+
// FILE FORMAT DEFINITIONS
|
|
548
|
+
// ============================================================================
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Design tokens file structure
|
|
552
|
+
*/
|
|
553
|
+
export interface DesignTokensFile extends GroupBase {
|
|
554
|
+
/** Tokens and groups at the root level */
|
|
555
|
+
[tokenOrGroupName: string]: AnyToken | TokenGroup | unknown;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Media type for design token files
|
|
560
|
+
*/
|
|
561
|
+
export const DESIGN_TOKENS_MEDIA_TYPE = 'application/design-tokens+json';
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Recommended file extensions
|
|
565
|
+
*/
|
|
566
|
+
export const DESIGN_TOKENS_EXTENSIONS = ['.tokens', '.tokens.json'] as const;
|
|
567
|
+
|
|
568
|
+
// ============================================================================
|
|
569
|
+
// UTILITY TYPES
|
|
570
|
+
// ============================================================================
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Extract the value type from a token
|
|
574
|
+
*/
|
|
575
|
+
export type ExtractTokenValue<T> = T extends DesignToken<infer V> ? V : never;
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Check if a value is a token reference
|
|
579
|
+
*/
|
|
580
|
+
export type IsTokenReference<T> = T extends TokenReference ? true : false;
|
|
581
|
+
|
|
582
|
+
/**
|
|
583
|
+
* Check if a value is a JSON Pointer reference
|
|
584
|
+
*/
|
|
585
|
+
export type IsJsonPointerReference<T> = T extends JsonPointerReference ? true : false;
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* Resolve a value or reference to its actual type
|
|
589
|
+
*/
|
|
590
|
+
export type ResolveValue<T> = T extends ValueOrReference<infer V> ? V : T;
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Type guard for token references
|
|
594
|
+
*/
|
|
595
|
+
export function isTokenReference(value: unknown): value is TokenReference {
|
|
596
|
+
if (typeof value !== 'string' || !value.startsWith('{') || !value.endsWith('}')) {
|
|
597
|
+
return false;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
// Exclude composite strings (contain multiple references or non-reference text)
|
|
601
|
+
// A single token reference should only contain one set of braces
|
|
602
|
+
const innerContent = value.slice(1, -1);
|
|
603
|
+
return !innerContent.includes('{') && !innerContent.includes('}') && innerContent.trim() !== '';
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Type guard for JSON Pointer references
|
|
608
|
+
*/
|
|
609
|
+
export function isJsonPointerReference(value: unknown): value is JsonPointerReference {
|
|
610
|
+
return typeof value === 'object' && value !== null && '$ref' in value;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Type guard for composite string values
|
|
615
|
+
*/
|
|
616
|
+
export function isCompositeStringValue(value: unknown): value is CompositeStringValue {
|
|
617
|
+
if (typeof value !== 'string') return false;
|
|
618
|
+
|
|
619
|
+
// Check for token references {a.b.c} or JSON pointer references {#/path}
|
|
620
|
+
const tokenRefPattern = /\{[^}]+\}/g;
|
|
621
|
+
const matches = value.match(tokenRefPattern);
|
|
622
|
+
|
|
623
|
+
// Must contain at least one reference and have additional content
|
|
624
|
+
return !!(matches && matches.length > 0 && value.length > matches.join('').length);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* Extract all references from a composite string value
|
|
629
|
+
*/
|
|
630
|
+
export function extractReferencesFromCompositeString(value: CompositeStringValue): (TokenReference | JsonPointerReference)[] {
|
|
631
|
+
const tokenRefPattern = /\{[^}]+\}/g;
|
|
632
|
+
const matches = value.match(tokenRefPattern) || [];
|
|
633
|
+
|
|
634
|
+
return matches.map(match => {
|
|
635
|
+
if (match.startsWith('{#/')) {
|
|
636
|
+
// JSON Pointer reference
|
|
637
|
+
return { $ref: match.slice(2, -1) } as JsonPointerReference;
|
|
638
|
+
} else {
|
|
639
|
+
// Token reference
|
|
640
|
+
return match as TokenReference;
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
/**
|
|
646
|
+
* Parse a composite string into parts (references and literals)
|
|
647
|
+
*/
|
|
648
|
+
export function parseCompositeString(value: CompositeStringValue): Array<{ type: 'reference' | 'literal'; value: string; ref?: TokenReference | JsonPointerReference }> {
|
|
649
|
+
const parts: Array<{ type: 'reference' | 'literal'; value: string; ref?: TokenReference | JsonPointerReference }> = [];
|
|
650
|
+
const tokenRefPattern = /\{[^}]+\}/g;
|
|
651
|
+
let lastIndex = 0;
|
|
652
|
+
let match;
|
|
653
|
+
|
|
654
|
+
while ((match = tokenRefPattern.exec(value)) !== null) {
|
|
655
|
+
// Add literal part before the reference
|
|
656
|
+
if (match.index > lastIndex) {
|
|
657
|
+
const literalValue = value.slice(lastIndex, match.index);
|
|
658
|
+
if (literalValue) {
|
|
659
|
+
parts.push({ type: 'literal', value: literalValue });
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
// Add the reference part
|
|
664
|
+
const refValue = match[0];
|
|
665
|
+
if (refValue.startsWith('{#/')) {
|
|
666
|
+
// JSON Pointer reference - ref contains the JsonPointerReference object
|
|
667
|
+
parts.push({
|
|
668
|
+
type: 'reference',
|
|
669
|
+
value: refValue,
|
|
670
|
+
ref: { $ref: refValue.slice(2, -1) } as JsonPointerReference
|
|
671
|
+
});
|
|
672
|
+
} else {
|
|
673
|
+
// Token reference - ref contains the TokenReference (same as value for token refs)
|
|
674
|
+
parts.push({
|
|
675
|
+
type: 'reference',
|
|
676
|
+
value: refValue,
|
|
677
|
+
ref: refValue as TokenReference
|
|
678
|
+
});
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
lastIndex = match.index + match[0].length;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
// Add any remaining literal part
|
|
685
|
+
if (lastIndex < value.length) {
|
|
686
|
+
const literalValue = value.slice(lastIndex);
|
|
687
|
+
if (literalValue) {
|
|
688
|
+
parts.push({ type: 'literal', value: literalValue });
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
return parts;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* Type guard for mode extensions
|
|
697
|
+
*/
|
|
698
|
+
export function hasModeExtension(token: AnyToken): token is AnyToken & { $extensions: { $mode: ModeExtension } } {
|
|
699
|
+
return !!(token.$extensions?.$mode);
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
/**
|
|
703
|
+
* Type guard for generator extensions
|
|
704
|
+
*/
|
|
705
|
+
export function hasGeneratorExtension(token: AnyToken): token is AnyToken & { $extensions: { $generators: GeneratorsExtension } } {
|
|
706
|
+
return !!(token.$extensions?.$generators && Array.isArray(token.$extensions.$generators));
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Type guard for breakpoint extensions
|
|
711
|
+
*/
|
|
712
|
+
export function hasBreakpointExtension(token: AnyToken): token is AnyToken & { $extensions: { $breakpoints: BreakpointsExtension } } {
|
|
713
|
+
return !!(token.$extensions?.$breakpoints && typeof token.$extensions.$breakpoints === 'object');
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* Extract mode value for a specific mode
|
|
718
|
+
*/
|
|
719
|
+
export function getModeValue<T>(token: AnyToken, mode: keyof ModeExtension): ValueOrReference<T> | undefined {
|
|
720
|
+
if (!hasModeExtension(token)) return undefined;
|
|
721
|
+
return token.$extensions.$mode[mode] as ValueOrReference<T> | undefined;
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Get all generator suffixes for a token
|
|
726
|
+
*/
|
|
727
|
+
export function getGeneratorSuffixes(token: AnyToken): string[] {
|
|
728
|
+
if (!hasGeneratorExtension(token)) return [];
|
|
729
|
+
|
|
730
|
+
return token.$extensions.$generators.flatMap(generator =>
|
|
731
|
+
Object.keys(generator.value)
|
|
732
|
+
);
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Get all breakpoint media queries for a token
|
|
737
|
+
*/
|
|
738
|
+
export function getBreakpointQueries(token: AnyToken): string[] {
|
|
739
|
+
if (!hasBreakpointExtension(token)) return [];
|
|
740
|
+
|
|
741
|
+
return Object.keys(token.$extensions.$breakpoints);
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
/**
|
|
745
|
+
* Get breakpoint value for a specific media query
|
|
746
|
+
*/
|
|
747
|
+
export function getBreakpointValue<T>(token: AnyToken, mediaQuery: string): ValueOrReference<T> | undefined {
|
|
748
|
+
if (!hasBreakpointExtension(token)) return undefined;
|
|
749
|
+
|
|
750
|
+
const breakpointConfig = token.$extensions.$breakpoints[mediaQuery];
|
|
751
|
+
return breakpointConfig?.$value as ValueOrReference<T> | undefined;
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
/**
|
|
755
|
+
* Get breakpoint configuration for a specific media query
|
|
756
|
+
*/
|
|
757
|
+
export function getBreakpointConfig(token: AnyToken, mediaQuery: string) {
|
|
758
|
+
if (!hasBreakpointExtension(token)) return undefined;
|
|
759
|
+
|
|
760
|
+
return token.$extensions.$breakpoints[mediaQuery];
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
/**
|
|
764
|
+
* Extract token references from media query strings
|
|
765
|
+
*/
|
|
766
|
+
export function extractTokenReferencesFromMediaQuery(mediaQuery: string): (TokenReference | JsonPointerReference)[] {
|
|
767
|
+
// Treat media query as a composite string to extract references
|
|
768
|
+
const compositeValue = mediaQuery as CompositeStringValue;
|
|
769
|
+
return extractReferencesFromCompositeString(compositeValue);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
/**
|
|
773
|
+
* Generate derived token name with suffix
|
|
774
|
+
* @example generateDerivedTokenName("gray.n0", "@alpha1") => "gray.n0@alpha1"
|
|
775
|
+
*/
|
|
776
|
+
export function generateDerivedTokenName(baseName: string, suffix: string): string {
|
|
777
|
+
return `${baseName}${suffix}`;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Type guard for design tokens
|
|
782
|
+
*/
|
|
783
|
+
export function isDesignToken(value: unknown): value is AnyToken {
|
|
784
|
+
return typeof value === 'object' && value !== null && '$value' in value;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Type guard for groups
|
|
789
|
+
*/
|
|
790
|
+
export function isTokenGroup(value: unknown): value is TokenGroup {
|
|
791
|
+
return typeof value === 'object' && value !== null && !('$value' in value);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// ============================================================================
|
|
795
|
+
// VALIDATION TYPES
|
|
796
|
+
// ============================================================================
|
|
797
|
+
|
|
798
|
+
/**
|
|
799
|
+
* Validation error for design tokens
|
|
800
|
+
*/
|
|
801
|
+
export interface ValidationError {
|
|
802
|
+
/** Path to the invalid token or property */
|
|
803
|
+
path: string;
|
|
804
|
+
/** Error message */
|
|
805
|
+
message: string;
|
|
806
|
+
/** Error code for programmatic handling */
|
|
807
|
+
code: string;
|
|
808
|
+
/** Severity level */
|
|
809
|
+
severity: 'error' | 'warning';
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
/**
|
|
813
|
+
* Validation result for design token files
|
|
814
|
+
*/
|
|
815
|
+
export interface ValidationResult {
|
|
816
|
+
/** Whether the file is valid */
|
|
817
|
+
valid: boolean;
|
|
818
|
+
/** List of validation errors and warnings */
|
|
819
|
+
errors: ValidationError[];
|
|
820
|
+
/** Successfully parsed tokens */
|
|
821
|
+
tokens: Record<string, AnyToken>;
|
|
822
|
+
/** Successfully parsed groups */
|
|
823
|
+
groups: Record<string, TokenGroup>;
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/**
|
|
827
|
+
* Character restrictions for token and group names
|
|
828
|
+
* Names MUST NOT:
|
|
829
|
+
* - Begin with '$' (reserved for spec properties)
|
|
830
|
+
* - Contain '{', '}', or '.' (conflicts with reference syntax)
|
|
831
|
+
*/
|
|
832
|
+
export type ValidTokenName = string & {
|
|
833
|
+
readonly __brand: 'ValidTokenName';
|
|
834
|
+
};
|
|
835
|
+
|
|
836
|
+
/**
|
|
837
|
+
* Path to a token within a group structure
|
|
838
|
+
*/
|
|
839
|
+
export type TokenPath = string & {
|
|
840
|
+
readonly __brand: 'TokenPath';
|
|
841
|
+
};
|
|
842
|
+
|
|
843
|
+
// ============================================================================
|
|
844
|
+
// REFERENCE RESOLUTION TYPES
|
|
845
|
+
// ============================================================================
|
|
846
|
+
|
|
847
|
+
/**
|
|
848
|
+
* Reference resolution context
|
|
849
|
+
*/
|
|
850
|
+
export interface ResolutionContext {
|
|
851
|
+
/** The current file being processed */
|
|
852
|
+
file: DesignTokensFile;
|
|
853
|
+
/** Stack of references being resolved (for circular detection) */
|
|
854
|
+
resolutionStack: string[];
|
|
855
|
+
/** Root path for relative references */
|
|
856
|
+
rootPath?: string;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Reference resolution result
|
|
861
|
+
*/
|
|
862
|
+
export interface ResolutionResult<T = unknown> {
|
|
863
|
+
/** Whether resolution was successful */
|
|
864
|
+
success: boolean;
|
|
865
|
+
/** Resolved value (if successful) */
|
|
866
|
+
value?: T;
|
|
867
|
+
/** Error message (if unsuccessful) */
|
|
868
|
+
error?: string;
|
|
869
|
+
/** Path of the resolved token */
|
|
870
|
+
resolvedPath?: string;
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// ============================================================================
|
|
874
|
+
// ADVANCED GROUP FEATURES
|
|
875
|
+
// ============================================================================
|
|
876
|
+
|
|
877
|
+
/**
|
|
878
|
+
* Group inheritance semantics for $extends
|
|
879
|
+
*/
|
|
880
|
+
export interface InheritanceRules {
|
|
881
|
+
/** Local properties override inherited properties at same path */
|
|
882
|
+
overrideAtSamePath: true;
|
|
883
|
+
/** Properties at different paths are merged */
|
|
884
|
+
mergeAtDifferentPaths: true;
|
|
885
|
+
/** Complete property replacement (not property-by-property merge) */
|
|
886
|
+
completeReplacement: true;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* Processing order for group resolution
|
|
891
|
+
*/
|
|
892
|
+
export type ProcessingOrder = [
|
|
893
|
+
'localTokens', // Direct children with $value
|
|
894
|
+
'rootTokens', // Tokens with $root names
|
|
895
|
+
'extendedTokens', // Inherited via $extends
|
|
896
|
+
'nestedGroups' // Process recursively
|
|
897
|
+
];
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Type inheritance precedence order
|
|
901
|
+
*/
|
|
902
|
+
export type TypeInheritancePrecedence = [
|
|
903
|
+
'tokenExplicitType', // Token's explicit $type property
|
|
904
|
+
'resolvedGroupType', // Resolved group's $type (after extension)
|
|
905
|
+
'parentGroupType', // Parent group's $type (walking up hierarchy)
|
|
906
|
+
'invalid' // Token is invalid if no type determined
|
|
907
|
+
];
|
|
908
|
+
|
|
909
|
+
// ============================================================================
|
|
910
|
+
// EXTENSION AND PLUGIN TYPES
|
|
911
|
+
// ============================================================================
|
|
912
|
+
|
|
913
|
+
/**
|
|
914
|
+
* Extension data structure for vendor-specific data
|
|
915
|
+
*/
|
|
916
|
+
export interface ExtensionData {
|
|
917
|
+
/** Vendor identifier (reverse domain notation recommended) */
|
|
918
|
+
[vendorKey: string]: unknown;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/**
|
|
922
|
+
* Tool-specific extension interface
|
|
923
|
+
*/
|
|
924
|
+
export interface ToolExtension {
|
|
925
|
+
/** Tool identifier */
|
|
926
|
+
toolId: string;
|
|
927
|
+
/** Tool version */
|
|
928
|
+
version?: string;
|
|
929
|
+
/** Extension data */
|
|
930
|
+
data: unknown;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Mode-specific token values for theming (e.g., light/dark mode)
|
|
935
|
+
* Values can be explicit values or token references
|
|
936
|
+
* When referencing tokens, the referenced token's mode value is used if available
|
|
937
|
+
* Used as $extensions.$mode in design tokens
|
|
938
|
+
*/
|
|
939
|
+
export interface ModeExtension {
|
|
940
|
+
/** Dark mode value - can be explicit value or token reference */
|
|
941
|
+
dark?: ValueOrReference<unknown>;
|
|
942
|
+
/** Light mode value - can be explicit value or token reference */
|
|
943
|
+
light?: ValueOrReference<unknown>;
|
|
944
|
+
/** High contrast mode value */
|
|
945
|
+
'high-contrast'?: ValueOrReference<unknown>;
|
|
946
|
+
/** Custom mode values */
|
|
947
|
+
[modeName: string]: ValueOrReference<unknown> | undefined;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
/**
|
|
951
|
+
* Generator types for creating derived tokens
|
|
952
|
+
*/
|
|
953
|
+
export type GeneratorType =
|
|
954
|
+
| 'alpha' // Alpha/opacity variations
|
|
955
|
+
| 'hue' // Hue variations
|
|
956
|
+
| 'saturation' // Saturation variations
|
|
957
|
+
| 'lightness' // Lightness variations
|
|
958
|
+
| 'scale' // Scale variations for dimensions
|
|
959
|
+
| string; // Custom generator types
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* Generator configuration for creating derived tokens
|
|
963
|
+
* The key (e.g., "@alpha1", "@scale2x") becomes a suffix for the generated token name
|
|
964
|
+
* Original token "gray.n0" with "@alpha1": 1 generates "gray.n0@alpha1"
|
|
965
|
+
*/
|
|
966
|
+
export interface GeneratorConfig {
|
|
967
|
+
/** Generator type */
|
|
968
|
+
type: GeneratorType;
|
|
969
|
+
/**
|
|
970
|
+
* Generator values where key becomes token suffix and value is the generator parameter
|
|
971
|
+
* @example { "@alpha1": 1, "@alpha50": 50, "@alpha90": 90 }
|
|
972
|
+
* @example { "@scale2x": 2, "@scale05": 0.5 }
|
|
973
|
+
*/
|
|
974
|
+
value: Record<string, number | string>;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* Generators extension for creating derived tokens
|
|
979
|
+
* Used as $extensions.$generators in design tokens
|
|
980
|
+
*/
|
|
981
|
+
export type GeneratorsExtension = GeneratorConfig[];
|
|
982
|
+
|
|
983
|
+
/**
|
|
984
|
+
* Breakpoint-specific token values for responsive design
|
|
985
|
+
* Keys are CSS media queries (can contain token references)
|
|
986
|
+
* Values follow the same structure as regular design tokens
|
|
987
|
+
* Used as $extensions.$breakpoints in design tokens
|
|
988
|
+
*/
|
|
989
|
+
export interface BreakpointsExtension {
|
|
990
|
+
/**
|
|
991
|
+
* CSS media query as key (supports token references in composite strings)
|
|
992
|
+
* @example "(min-width: {foundation.breakpoint.lg})"
|
|
993
|
+
* @example "(prefers-color-scheme: dark)"
|
|
994
|
+
* @example "(min-width: 768px) and (orientation: landscape)"
|
|
995
|
+
* @example "@container (min-width: {container.sizes.md})"
|
|
996
|
+
*/
|
|
997
|
+
[mediaQuery: string]: {
|
|
998
|
+
/** Token type (can override base type) */
|
|
999
|
+
$type?: TokenType;
|
|
1000
|
+
/** Token value for this breakpoint */
|
|
1001
|
+
$value: ValueOrReference<unknown>;
|
|
1002
|
+
/** Token description */
|
|
1003
|
+
$description?: string;
|
|
1004
|
+
/** Nested extensions (like mode) for this breakpoint */
|
|
1005
|
+
$extensions?: EnhancedExtensionData;
|
|
1006
|
+
};
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
/**
|
|
1010
|
+
* Enhanced extension data with mode, generators, and breakpoints support
|
|
1011
|
+
* Uses $ prefix for reserved/standardized extensions
|
|
1012
|
+
*/
|
|
1013
|
+
export interface EnhancedExtensionData extends ExtensionData {
|
|
1014
|
+
/** Mode-specific values for theming */
|
|
1015
|
+
$mode?: ModeExtension;
|
|
1016
|
+
/** Generator configurations for derived tokens */
|
|
1017
|
+
$generators?: GeneratorsExtension;
|
|
1018
|
+
/** Breakpoint-specific values for responsive design */
|
|
1019
|
+
$breakpoints?: BreakpointsExtension;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
/**
|
|
1023
|
+
* Common extension patterns
|
|
1024
|
+
*/
|
|
1025
|
+
export interface CommonExtensions {
|
|
1026
|
+
/** Mode-specific token values */
|
|
1027
|
+
$mode?: ModeExtension;
|
|
1028
|
+
|
|
1029
|
+
/** Generator configurations for derived tokens */
|
|
1030
|
+
$generators?: GeneratorsExtension;
|
|
1031
|
+
|
|
1032
|
+
/** Breakpoint-specific values for responsive design */
|
|
1033
|
+
$breakpoints?: BreakpointsExtension;
|
|
1034
|
+
|
|
1035
|
+
/** Figma-specific data */
|
|
1036
|
+
'com.figma'?: {
|
|
1037
|
+
node?: {
|
|
1038
|
+
nodeId?: string;
|
|
1039
|
+
styleId?: string;
|
|
1040
|
+
[key: string]: unknown;
|
|
1041
|
+
};
|
|
1042
|
+
} | {
|
|
1043
|
+
/** SVG-specific data to be loaded into Figma */
|
|
1044
|
+
svg?: {
|
|
1045
|
+
id: string;
|
|
1046
|
+
[svgName: string]: string;
|
|
1047
|
+
};
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// ============================================================================
|
|
1052
|
+
// EXPORT ALL TYPES
|
|
1053
|
+
// ============================================================================
|
|
1054
|
+
|
|
1055
|
+
/**
|
|
1056
|
+
* Default export containing all types and utilities
|
|
1057
|
+
*/
|
|
1058
|
+
export default {
|
|
1059
|
+
// Constants
|
|
1060
|
+
DESIGN_TOKENS_MEDIA_TYPE,
|
|
1061
|
+
DESIGN_TOKENS_EXTENSIONS,
|
|
1062
|
+
|
|
1063
|
+
// Type guards
|
|
1064
|
+
isTokenReference,
|
|
1065
|
+
isJsonPointerReference,
|
|
1066
|
+
isCompositeStringValue,
|
|
1067
|
+
isDesignToken,
|
|
1068
|
+
isTokenGroup,
|
|
1069
|
+
hasModeExtension,
|
|
1070
|
+
hasGeneratorExtension,
|
|
1071
|
+
hasBreakpointExtension,
|
|
1072
|
+
|
|
1073
|
+
// Utilities
|
|
1074
|
+
getModeValue,
|
|
1075
|
+
getGeneratorSuffixes,
|
|
1076
|
+
getBreakpointQueries,
|
|
1077
|
+
getBreakpointValue,
|
|
1078
|
+
getBreakpointConfig,
|
|
1079
|
+
generateDerivedTokenName,
|
|
1080
|
+
extractReferencesFromCompositeString,
|
|
1081
|
+
extractTokenReferencesFromMediaQuery,
|
|
1082
|
+
parseCompositeString,
|
|
1083
|
+
};
|