zyzz 0.0.2 → 0.0.5
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/README.md +34 -19
- package/dist/Config.d.ts +16 -167
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js +7 -246
- package/dist/Config.js.map +1 -1
- package/dist/Style.d.ts +19 -13
- package/dist/Style.d.ts.map +1 -1
- package/dist/Style.js +73 -7
- package/dist/Style.js.map +1 -1
- package/dist/Vars.d.ts +114 -0
- package/dist/Vars.d.ts.map +1 -0
- package/dist/Vars.js +42 -0
- package/dist/Vars.js.map +1 -0
- package/dist/compiler/Graph.js +11 -8
- package/dist/compiler/Graph.js.map +1 -1
- package/dist/compiler/Native.d.ts +5 -5
- package/dist/compiler/Native.d.ts.map +1 -1
- package/dist/compiler/Native.js +21 -21
- package/dist/compiler/Native.js.map +1 -1
- package/dist/compiler/Source.d.ts +10 -6
- package/dist/compiler/Source.d.ts.map +1 -1
- package/dist/compiler/Source.js +66 -11
- package/dist/compiler/Source.js.map +1 -1
- package/dist/compiler/Transform.d.ts +1 -1
- package/dist/compiler/Transform.d.ts.map +1 -1
- package/dist/compiler/Transform.js +59 -21
- package/dist/compiler/Transform.js.map +1 -1
- package/dist/compiler/internal/Compositions.d.ts +5 -0
- package/dist/compiler/internal/Compositions.d.ts.map +1 -1
- package/dist/compiler/internal/Compositions.js +22 -3
- package/dist/compiler/internal/Compositions.js.map +1 -1
- package/dist/compiler/internal/Configurations.d.ts.map +1 -1
- package/dist/compiler/internal/Configurations.js +73 -12
- package/dist/compiler/internal/Configurations.js.map +1 -1
- package/dist/compiler/internal/Contract.d.ts +1 -1
- package/dist/compiler/internal/Contract.d.ts.map +1 -1
- package/dist/compiler/internal/Contract.js +162 -13
- package/dist/compiler/internal/Contract.js.map +1 -1
- package/dist/compiler/internal/Contributions.js +1 -1
- package/dist/compiler/internal/Contributions.js.map +1 -1
- package/dist/compiler/internal/Dynamic.js +1 -1
- package/dist/compiler/internal/Dynamic.js.map +1 -1
- package/dist/compiler/internal/Expression.d.ts +3 -0
- package/dist/compiler/internal/Expression.d.ts.map +1 -1
- package/dist/compiler/internal/Expression.js +21 -0
- package/dist/compiler/internal/Expression.js.map +1 -1
- package/dist/compiler/internal/Identifiers.d.ts +1 -1
- package/dist/compiler/internal/Identifiers.d.ts.map +1 -1
- package/dist/compiler/internal/Identifiers.js +2 -2
- package/dist/compiler/internal/Identifiers.js.map +1 -1
- package/dist/compiler/internal/NativeBindings.d.ts +1 -1
- package/dist/compiler/internal/NativeBindings.d.ts.map +1 -1
- package/dist/compiler/internal/NativeBindings.js +3 -3
- package/dist/compiler/internal/NativeBindings.js.map +1 -1
- package/dist/compiler/internal/PackedStyles.d.ts +1 -1
- package/dist/compiler/internal/PackedStyles.d.ts.map +1 -1
- package/dist/compiler/internal/PackedStyles.js +15 -25
- package/dist/compiler/internal/PackedStyles.js.map +1 -1
- package/dist/compiler/internal/Recipes.js +1 -1
- package/dist/compiler/internal/Recipes.js.map +1 -1
- package/dist/compiler/internal/Selectors.js +1 -1
- package/dist/compiler/internal/Selectors.js.map +1 -1
- package/dist/compiler/internal/Themes.d.ts +12 -3
- package/dist/compiler/internal/Themes.d.ts.map +1 -1
- package/dist/compiler/internal/Themes.js +192 -52
- package/dist/compiler/internal/Themes.js.map +1 -1
- package/dist/compiler/internal/{Variables.d.ts → Vars.d.ts} +1 -1
- package/dist/compiler/internal/Vars.d.ts.map +1 -0
- package/dist/compiler/internal/{Variables.js → Vars.js} +3 -3
- package/dist/compiler/internal/Vars.js.map +1 -0
- package/dist/default.d.ts +451 -1649
- package/dist/default.d.ts.map +1 -1
- package/dist/default.js +389 -80
- package/dist/default.js.map +2 -2
- package/dist/default.js.zyzz.json +1 -1
- package/dist/esbuild/index.d.ts +3 -0
- package/dist/esbuild/index.d.ts.map +1 -0
- package/dist/esbuild/index.js +5 -0
- package/dist/esbuild/index.js.map +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/index.js.map +1 -1
- package/dist/internal/Authoring.d.ts +1 -1
- package/dist/internal/Authoring.d.ts.map +1 -1
- package/dist/internal/Authoring.js +4 -4
- package/dist/internal/Authoring.js.map +1 -1
- package/dist/internal/Binding.d.ts +1 -1
- package/dist/internal/Binding.d.ts.map +1 -1
- package/dist/internal/Completion.d.ts +19 -0
- package/dist/internal/Completion.d.ts.map +1 -0
- package/dist/internal/Completion.js +2 -0
- package/dist/internal/Completion.js.map +1 -0
- package/dist/internal/Condition.d.ts +3 -1
- package/dist/internal/Condition.d.ts.map +1 -1
- package/dist/internal/Condition.js.map +1 -1
- package/dist/internal/Configuration.d.ts +248 -0
- package/dist/internal/Configuration.d.ts.map +1 -0
- package/dist/internal/Configuration.js +343 -0
- package/dist/internal/Configuration.js.map +1 -0
- package/dist/internal/Shorthands.d.ts +1 -1
- package/dist/internal/Shorthands.d.ts.map +1 -1
- package/dist/internal/Shorthands.js +1 -0
- package/dist/internal/Shorthands.js.map +1 -1
- package/dist/{Theme.d.ts → internal/Theme.d.ts} +24 -19
- package/dist/internal/Theme.d.ts.map +1 -0
- package/dist/{Theme.js → internal/Theme.js} +57 -14
- package/dist/internal/Theme.js.map +1 -0
- package/dist/internal/Token.d.ts +46 -16
- package/dist/internal/Token.d.ts.map +1 -1
- package/dist/internal/Token.js +89 -5
- package/dist/internal/Token.js.map +1 -1
- package/dist/internal/Typography.d.ts +31 -0
- package/dist/internal/Typography.d.ts.map +1 -0
- package/dist/internal/Typography.js +54 -0
- package/dist/internal/Typography.js.map +1 -0
- package/dist/internal/Value.d.ts +6 -1
- package/dist/internal/Value.d.ts.map +1 -1
- package/dist/internal/Value.js.map +1 -1
- package/dist/internal/VariableSets.d.ts +20 -0
- package/dist/internal/VariableSets.d.ts.map +1 -0
- package/dist/internal/VariableSets.js +317 -0
- package/dist/internal/VariableSets.js.map +1 -0
- package/dist/next/loader.js +15 -5
- package/dist/next/loader.js.map +1 -1
- package/dist/node/Host.d.ts.map +1 -1
- package/dist/node/Host.js +1 -1
- package/dist/node/Host.js.map +1 -1
- package/dist/react-native/Host.d.ts +2 -2
- package/dist/react-native/Host.d.ts.map +1 -1
- package/dist/react-native/Host.js +4 -4
- package/dist/react-native/Host.js.map +1 -1
- package/dist/react-native/StyleSheet.d.ts +9 -8
- package/dist/react-native/StyleSheet.d.ts.map +1 -1
- package/dist/react-native/StyleSheet.js +29 -23
- package/dist/react-native/StyleSheet.js.map +1 -1
- package/dist/react-native/Variants.d.ts +3 -3
- package/dist/react-native/Variants.d.ts.map +1 -1
- package/dist/react-native/Variants.js +2 -2
- package/dist/react-native/react.d.ts +1 -1
- package/dist/react-native/react.d.ts.map +1 -1
- package/dist/react-native/react.js +5 -5
- package/dist/react-native/react.js.map +1 -1
- package/dist/rollup/index.d.ts +3 -0
- package/dist/rollup/index.d.ts.map +1 -0
- package/dist/rollup/index.js +5 -0
- package/dist/rollup/index.js.map +1 -0
- package/dist/runtime/Appearance.d.ts +7 -7
- package/dist/runtime/Appearance.d.ts.map +1 -1
- package/dist/runtime/Appearance.js +15 -15
- package/dist/runtime/Appearance.js.map +1 -1
- package/dist/runtime/Dynamic.d.ts.map +1 -1
- package/dist/runtime/Dynamic.js +4 -1
- package/dist/runtime/Dynamic.js.map +1 -1
- package/dist/runtime/NativeContext.d.ts +4 -4
- package/dist/runtime/NativeContext.d.ts.map +1 -1
- package/dist/runtime/NativeContext.js +5 -5
- package/dist/runtime/NativeContext.js.map +1 -1
- package/dist/runtime/NativeDynamic.d.ts +1 -1
- package/dist/runtime/NativeDynamic.d.ts.map +1 -1
- package/dist/runtime/NativeDynamic.js.map +1 -1
- package/dist/runtime/Props.d.ts +1 -1
- package/dist/runtime/Props.js +3 -3
- package/dist/runtime/Props.js.map +1 -1
- package/dist/runtime/Selection.d.ts +14 -10
- package/dist/runtime/Selection.d.ts.map +1 -1
- package/dist/runtime/Selection.js +19 -18
- package/dist/runtime/Selection.js.map +1 -1
- package/dist/styleFunction.d.ts +14 -14
- package/dist/styleFunction.d.ts.map +1 -1
- package/dist/styleFunction.js.map +1 -1
- package/dist/unplugin/index.d.ts +20 -0
- package/dist/unplugin/index.d.ts.map +1 -0
- package/dist/unplugin/index.js +498 -0
- package/dist/unplugin/index.js.map +1 -0
- package/dist/variants.d.ts +3 -3
- package/dist/variants.d.ts.map +1 -1
- package/dist/variants.js.map +1 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +6 -3
- package/dist/vite/index.js.map +1 -1
- package/dist/web/Css.d.ts +4 -3
- package/dist/web/Css.d.ts.map +1 -1
- package/dist/web/Css.js +4 -4
- package/dist/web/Css.js.map +1 -1
- package/dist/web/internal/Themes.d.ts +3 -2
- package/dist/web/internal/Themes.d.ts.map +1 -1
- package/dist/web/internal/Themes.js +42 -6
- package/dist/web/internal/Themes.js.map +1 -1
- package/dist/webpack/index.d.ts +3 -0
- package/dist/webpack/index.d.ts.map +1 -0
- package/dist/webpack/index.js +5 -0
- package/dist/webpack/index.js.map +1 -0
- package/package.json +23 -2
- package/src/Config.ts +43 -684
- package/src/Style.ts +167 -40
- package/src/Vars.ts +299 -0
- package/src/compiler/Graph.ts +14 -9
- package/src/compiler/Native.ts +29 -32
- package/src/compiler/Source.ts +85 -18
- package/src/compiler/Transform.ts +78 -22
- package/src/compiler/internal/Compositions.ts +36 -3
- package/src/compiler/internal/Configurations.ts +83 -11
- package/src/compiler/internal/Contract.ts +223 -17
- package/src/compiler/internal/Contributions.ts +1 -1
- package/src/compiler/internal/Dynamic.ts +1 -1
- package/src/compiler/internal/Expression.ts +26 -0
- package/src/compiler/internal/Identifiers.ts +2 -1
- package/src/compiler/internal/NativeBindings.ts +3 -3
- package/src/compiler/internal/PackedStyles.ts +22 -26
- package/src/compiler/internal/Recipes.ts +1 -1
- package/src/compiler/internal/Selectors.ts +1 -1
- package/src/compiler/internal/Themes.ts +266 -57
- package/src/compiler/internal/{Variables.ts → Vars.ts} +2 -2
- package/src/default.ts +868 -156
- package/src/esbuild/index.ts +5 -0
- package/src/index.ts +4 -4
- package/src/internal/Authoring.ts +5 -7
- package/src/internal/Binding.ts +1 -1
- package/src/internal/Completion.ts +42 -0
- package/src/internal/Condition.ts +31 -1
- package/src/internal/Configuration.ts +970 -0
- package/src/internal/Shorthands.ts +2 -0
- package/src/{Theme.ts → internal/Theme.ts} +174 -48
- package/src/internal/Token.ts +258 -85
- package/src/internal/Typography.ts +106 -0
- package/src/internal/Value.ts +45 -26
- package/src/internal/VariableSets.ts +458 -0
- package/src/next/loader.ts +19 -5
- package/src/node/Host.ts +1 -2
- package/src/react-native/Host.ts +6 -6
- package/src/react-native/StyleSheet.ts +49 -42
- package/src/react-native/Variants.ts +3 -3
- package/src/react-native/react.ts +6 -6
- package/src/rollup/index.ts +5 -0
- package/src/runtime/Appearance.ts +20 -20
- package/src/runtime/Dynamic.ts +4 -1
- package/src/runtime/NativeContext.ts +8 -8
- package/src/runtime/NativeDynamic.ts +2 -4
- package/src/runtime/Props.ts +3 -3
- package/src/runtime/Selection.ts +44 -33
- package/src/styleFunction.ts +22 -19
- package/src/unplugin/index.ts +600 -0
- package/src/variants.ts +7 -5
- package/src/vite/index.ts +5 -4
- package/src/web/Css.ts +10 -7
- package/src/web/internal/Themes.ts +52 -9
- package/src/webpack/index.ts +5 -0
- package/dist/Theme.d.ts.map +0 -1
- package/dist/Theme.js.map +0 -1
- package/dist/compiler/internal/Variables.d.ts.map +0 -1
- package/dist/compiler/internal/Variables.js.map +0 -1
package/src/Style.ts
CHANGED
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
* Copies typed style declarations into immutable, ordered, target-independent data.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
+
import * as VariableSets from './internal/VariableSets.js'
|
|
6
|
+
import type * as Vars from './Vars.js'
|
|
5
7
|
import * as Condition from './internal/Condition.js'
|
|
6
8
|
import * as Query from './internal/Query.js'
|
|
7
9
|
import * as Binding from './internal/Binding.js'
|
|
8
10
|
import type * as Literal from './internal/Literal.js'
|
|
9
11
|
import * as Token from './internal/Token.js'
|
|
12
|
+
import * as Typography from './internal/Typography.js'
|
|
10
13
|
import * as Value from './internal/Value.js'
|
|
11
|
-
import type * as Theme from './Theme.js'
|
|
14
|
+
import type * as Theme from './internal/Theme.js'
|
|
12
15
|
import * as Targets from './internal/Targets.js'
|
|
13
16
|
|
|
14
17
|
/** Validates only authored keys, recursively retaining nested token inference. */
|
|
@@ -24,7 +27,8 @@ export type Accepted<
|
|
|
24
27
|
| Condition.Keys<tokens, Keys<style>>
|
|
25
28
|
| 'selectors'
|
|
26
29
|
| 'targets'
|
|
27
|
-
| '
|
|
30
|
+
| 'typography'
|
|
31
|
+
| 'vars'
|
|
28
32
|
>,
|
|
29
33
|
never
|
|
30
34
|
> &
|
|
@@ -45,38 +49,46 @@ export type Accepted<
|
|
|
45
49
|
: never
|
|
46
50
|
}
|
|
47
51
|
: never
|
|
48
|
-
: key extends '
|
|
52
|
+
: key extends 'vars'
|
|
49
53
|
? style[key] extends Record<string, unknown>
|
|
50
54
|
? {
|
|
51
55
|
[name in keyof style[key]]: style[key][name] extends
|
|
52
56
|
| number
|
|
53
57
|
| string
|
|
54
58
|
? Literal.Checked<style[key][name]>
|
|
55
|
-
:
|
|
59
|
+
: literal extends true
|
|
60
|
+
? never
|
|
61
|
+
: style[key][name] extends Token.Reference
|
|
62
|
+
? style[key][name]
|
|
63
|
+
: never
|
|
56
64
|
}
|
|
57
65
|
: never
|
|
58
|
-
: key extends
|
|
59
|
-
?
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
66
|
+
: key extends 'typography'
|
|
67
|
+
? literal extends true
|
|
68
|
+
? never
|
|
69
|
+
: Value.Atom<Typography.Names<tokens>>
|
|
70
|
+
: key extends keyof Literal.Properties
|
|
71
|
+
? Value.Accepted<
|
|
72
|
+
Pick<style, key>,
|
|
73
|
+
literal extends true
|
|
74
|
+
? LiteralDeclarations
|
|
75
|
+
: DeclarationProperties<tokens>
|
|
76
|
+
>[key] &
|
|
77
|
+
Value.Checked<Pick<style, key>, tokens>[key]
|
|
78
|
+
: key extends Condition.Keys<tokens, key>
|
|
79
|
+
? [style[key]] extends [undefined]
|
|
80
|
+
? never
|
|
81
|
+
: NonNullable<style[key]> extends Record<string, unknown>
|
|
82
|
+
?
|
|
83
|
+
| Accepted<
|
|
84
|
+
NonNullable<style[key]>,
|
|
85
|
+
tokens,
|
|
86
|
+
literal,
|
|
87
|
+
targets
|
|
88
|
+
>
|
|
89
|
+
| Extract<style[key], undefined>
|
|
90
|
+
: never
|
|
91
|
+
: never
|
|
80
92
|
}
|
|
81
93
|
: never)
|
|
82
94
|
|
|
@@ -162,6 +174,22 @@ export type Declaration = {
|
|
|
162
174
|
* @returns Immutable definitions retaining the inferred style-name union.
|
|
163
175
|
* @throws {InvalidError} If the input structure cannot represent ordered declarations.
|
|
164
176
|
*/
|
|
177
|
+
export function define<
|
|
178
|
+
const values extends Vars.Values,
|
|
179
|
+
const styles extends Record<string, unknown>,
|
|
180
|
+
>(
|
|
181
|
+
styles: styles &
|
|
182
|
+
NoInfer<Exact<styles, Vars.Mapped<values, {}>>> & {
|
|
183
|
+
[key in keyof styles]: WithoutRelationships<styles[key]>
|
|
184
|
+
},
|
|
185
|
+
options: {
|
|
186
|
+
readonly vars: Vars.Definition<values>
|
|
187
|
+
readonly locations?: readonly SourceLocation[]
|
|
188
|
+
},
|
|
189
|
+
): Definition<
|
|
190
|
+
`${Extract<keyof styles, string | number>}`,
|
|
191
|
+
Targets.Domains<styles>
|
|
192
|
+
>
|
|
165
193
|
export function define<
|
|
166
194
|
const styles extends Record<string, unknown>,
|
|
167
195
|
const tokens extends Theme.Tokens,
|
|
@@ -189,6 +217,11 @@ export function define(
|
|
|
189
217
|
styles: Record<string, unknown>,
|
|
190
218
|
options: define.Options = {},
|
|
191
219
|
): Definition {
|
|
220
|
+
const theme =
|
|
221
|
+
options.vars &&
|
|
222
|
+
(typeof Reflect.get(options.vars, 'style') === 'function'
|
|
223
|
+
? (options.vars as Theme.Definition)
|
|
224
|
+
: VariableSets.theme(options.vars as Vars.Definition))
|
|
192
225
|
if ((options[nesting] ?? 0) > 128)
|
|
193
226
|
throw new InvalidError([
|
|
194
227
|
{
|
|
@@ -293,7 +326,7 @@ export function define(
|
|
|
293
326
|
if (name.length === 0)
|
|
294
327
|
report('invalid_structure', [name], 'Style names must not be empty.')
|
|
295
328
|
|
|
296
|
-
const mappings =
|
|
329
|
+
const mappings = theme?.[Token.definition].contract.shorthands
|
|
297
330
|
const authored = entries(style, [name]).filter(
|
|
298
331
|
([key, value]) => key !== 'targets' || value !== undefined,
|
|
299
332
|
)
|
|
@@ -364,21 +397,61 @@ export function define(
|
|
|
364
397
|
continue
|
|
365
398
|
}
|
|
366
399
|
|
|
367
|
-
const properties = authored.flatMap(
|
|
368
|
-
(
|
|
369
|
-
(
|
|
370
|
-
|
|
400
|
+
const properties = authored.flatMap(
|
|
401
|
+
([property, input]): readonly (readonly [string, unknown, string])[] => {
|
|
402
|
+
if (property !== 'typography')
|
|
403
|
+
return (mappings?.[property] ?? [property]).map(
|
|
404
|
+
(target) => [target, input, property] as const,
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
const parsed = Value.parse(input, 'fontFamily')
|
|
408
|
+
if (parsed && 'invalid' in parsed) {
|
|
409
|
+
report(
|
|
410
|
+
'invalid_value',
|
|
411
|
+
[name, property],
|
|
412
|
+
'Importance requires the suffix " !important".',
|
|
413
|
+
)
|
|
414
|
+
return []
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const path = parsed?.value ?? input
|
|
418
|
+
const entries = Typography.entries(theme, path)
|
|
419
|
+
if (!entries.length) {
|
|
420
|
+
report(
|
|
421
|
+
'invalid_value',
|
|
422
|
+
[name, property],
|
|
423
|
+
'Expected a named typography set from the bound theme.',
|
|
424
|
+
)
|
|
425
|
+
return []
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Explicit declarations in this block override the corresponding preset fields.
|
|
429
|
+
const explicit = new Set(
|
|
430
|
+
authored.flatMap(([property]) => mappings?.[property] ?? [property]),
|
|
431
|
+
)
|
|
432
|
+
return Typography.entries(theme, path, explicit, parsed?.important).map(
|
|
433
|
+
([field, value]) => [field, value, property] as const,
|
|
434
|
+
)
|
|
435
|
+
},
|
|
371
436
|
)
|
|
372
437
|
|
|
373
438
|
if (properties.some(([key]) => Condition.is(key))) {
|
|
374
439
|
const rules: Rule[] = []
|
|
375
440
|
|
|
376
|
-
|
|
441
|
+
const blocks = authored.flatMap(([key, input]) =>
|
|
442
|
+
key === 'typography'
|
|
443
|
+
? properties
|
|
444
|
+
.filter(([, , original]) => original === key)
|
|
445
|
+
.map(([property, value]) => [property, value] as const)
|
|
446
|
+
: [[key, input] as const],
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
for (const [key, input] of blocks) {
|
|
377
450
|
try {
|
|
378
451
|
const condition = Condition.is(key)
|
|
379
452
|
? Query.resolve(
|
|
380
453
|
key,
|
|
381
|
-
|
|
454
|
+
theme?.[Token.definition].queries ?? {
|
|
382
455
|
breakpoints: {},
|
|
383
456
|
containers: {},
|
|
384
457
|
containerNames: [],
|
|
@@ -535,7 +608,7 @@ export function define(
|
|
|
535
608
|
const scalar = parsed ? parsed.value : entry
|
|
536
609
|
|
|
537
610
|
const resolved = (() => {
|
|
538
|
-
if (!
|
|
611
|
+
if (!theme) return scalar
|
|
539
612
|
|
|
540
613
|
if (typeof scalar !== 'string' && typeof scalar !== 'number')
|
|
541
614
|
return scalar
|
|
@@ -545,7 +618,7 @@ export function define(
|
|
|
545
618
|
|
|
546
619
|
const resolved = Token.resolve(scalar, {
|
|
547
620
|
property: key,
|
|
548
|
-
theme
|
|
621
|
+
theme,
|
|
549
622
|
})
|
|
550
623
|
|
|
551
624
|
if (Token.is(resolved)) {
|
|
@@ -559,6 +632,19 @@ export function define(
|
|
|
559
632
|
return resolved
|
|
560
633
|
})()
|
|
561
634
|
|
|
635
|
+
if (
|
|
636
|
+
Token.is(resolved) &&
|
|
637
|
+
resolved.contract.variableSet &&
|
|
638
|
+
!Token.acceptsReference(resolved, key)
|
|
639
|
+
) {
|
|
640
|
+
report(
|
|
641
|
+
'invalid_value',
|
|
642
|
+
[name, authoredProperty],
|
|
643
|
+
'Variable value is incompatible with this property.',
|
|
644
|
+
)
|
|
645
|
+
continue
|
|
646
|
+
}
|
|
647
|
+
|
|
562
648
|
const value = parsed && resolved === '0' ? 0 : resolved
|
|
563
649
|
|
|
564
650
|
declarations.push(
|
|
@@ -583,9 +669,48 @@ export function define(
|
|
|
583
669
|
|
|
584
670
|
if (diagnostics.length) throw new InvalidError(diagnostics)
|
|
585
671
|
|
|
672
|
+
const defaultLayer = theme?.[Token.definition].contract.defaultLayer
|
|
673
|
+
// Apply defaults after validation to retain authored diagnostic paths and explicit layer nesting.
|
|
674
|
+
function layered(style: NamedStyle): NamedStyle {
|
|
675
|
+
const { targets, ...body } = style
|
|
676
|
+
const rules = (() => {
|
|
677
|
+
if (style.rules)
|
|
678
|
+
return style.rules.map((rule) =>
|
|
679
|
+
rule.condition === '@layer' || rule.condition?.startsWith('@layer ')
|
|
680
|
+
? rule
|
|
681
|
+
: Object.freeze({ ...rule, style: layered(rule.style) }),
|
|
682
|
+
)
|
|
683
|
+
|
|
684
|
+
if (!style.declarations.length) return []
|
|
685
|
+
|
|
686
|
+
return [
|
|
687
|
+
Object.freeze({
|
|
688
|
+
condition: `@layer ${defaultLayer}`,
|
|
689
|
+
style: Object.freeze(body),
|
|
690
|
+
}),
|
|
691
|
+
]
|
|
692
|
+
})()
|
|
693
|
+
|
|
694
|
+
return Object.freeze({
|
|
695
|
+
...body,
|
|
696
|
+
declarations: style.rules ? style.declarations : Object.freeze([]),
|
|
697
|
+
rules: Object.freeze(rules),
|
|
698
|
+
...(targets
|
|
699
|
+
? {
|
|
700
|
+
targets: Object.freeze({
|
|
701
|
+
...targets,
|
|
702
|
+
...(targets.web ? { web: layered(targets.web) } : {}),
|
|
703
|
+
}),
|
|
704
|
+
}
|
|
705
|
+
: {}),
|
|
706
|
+
})
|
|
707
|
+
}
|
|
708
|
+
|
|
586
709
|
// Validated names are precisely the input's enumerable string keys.
|
|
587
710
|
return Object.freeze({
|
|
588
|
-
styles: Object.freeze(
|
|
711
|
+
styles: Object.freeze(
|
|
712
|
+
defaultLayer && !options[nesting] ? output.map(layered) : output,
|
|
713
|
+
),
|
|
589
714
|
})
|
|
590
715
|
}
|
|
591
716
|
|
|
@@ -601,11 +726,11 @@ export declare namespace define {
|
|
|
601
726
|
} & ([tokens] extends [never]
|
|
602
727
|
? {
|
|
603
728
|
/** Optional themes do not enable shorthand inference. */
|
|
604
|
-
readonly
|
|
729
|
+
readonly vars?: Theme.Definition | Vars.Definition | undefined
|
|
605
730
|
}
|
|
606
731
|
: {
|
|
607
732
|
/** Shorthand inference requires a defined token contract. */
|
|
608
|
-
readonly
|
|
733
|
+
readonly vars: Theme.Definition<tokens>
|
|
609
734
|
})
|
|
610
735
|
}
|
|
611
736
|
|
|
@@ -691,7 +816,7 @@ export type DeclarationProperties<tokens extends Theme.Tokens = {}> = {
|
|
|
691
816
|
| Value.Atom<Token.Names<tokens, property>>
|
|
692
817
|
| {
|
|
693
818
|
[group in Token.Group]: property extends Token.Properties<group>
|
|
694
|
-
? Token.Reference<group>
|
|
819
|
+
? Value.Atom<Token.Reference<group> | Token.Variable<group>>
|
|
695
820
|
: never
|
|
696
821
|
}[Token.Group]
|
|
697
822
|
>
|
|
@@ -707,6 +832,8 @@ export type Properties<
|
|
|
707
832
|
readonly targets?:
|
|
708
833
|
| (targets extends true ? TargetBranches<tokens> : never)
|
|
709
834
|
| undefined
|
|
835
|
+
/** Applies a named typography set. Explicit fields in the same block take precedence. */
|
|
836
|
+
readonly typography?: Value.Atom<Typography.Names<tokens>>
|
|
710
837
|
}
|
|
711
838
|
|
|
712
839
|
/** Nested literal declarations retain exact keys at every depth. */
|
|
@@ -739,7 +866,7 @@ type WithoutRelationships<value> = value extends readonly unknown[]
|
|
|
739
866
|
? unknown
|
|
740
867
|
: value extends object
|
|
741
868
|
? {
|
|
742
|
-
[key in keyof value]: key extends symbol | 'selectors' | '
|
|
869
|
+
[key in keyof value]: key extends symbol | 'selectors' | 'vars'
|
|
743
870
|
? never
|
|
744
871
|
: key extends keyof Literal.Properties
|
|
745
872
|
? unknown
|
package/src/Vars.ts
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
/** Defines immutable variable sets and compatible scoped overrides. @module */
|
|
2
|
+
import type * as Typography from './internal/Typography.js'
|
|
3
|
+
import type * as Theme from './internal/Theme.js'
|
|
4
|
+
import * as Identity from './internal/Identity.js'
|
|
5
|
+
import type * as Literal from './internal/Literal.js'
|
|
6
|
+
import * as Token from './internal/Token.js'
|
|
7
|
+
import * as VariableSets from './internal/VariableSets.js'
|
|
8
|
+
import type { style } from './styleFunction.js'
|
|
9
|
+
|
|
10
|
+
/** Portable scalar reference with its accepted value domain. */
|
|
11
|
+
export type Reference<group extends Token.Group = Token.Group> =
|
|
12
|
+
Token.Reference<group>
|
|
13
|
+
|
|
14
|
+
const shape = Symbol('zyzz.variables.shape')
|
|
15
|
+
|
|
16
|
+
/** A scalar, a color-scheme pair, or ordered media overrides with a required default. */
|
|
17
|
+
export type Value =
|
|
18
|
+
| string
|
|
19
|
+
| number
|
|
20
|
+
| Token.Reference
|
|
21
|
+
| {
|
|
22
|
+
readonly light: string | Token.Reference
|
|
23
|
+
readonly dark: string | Token.Reference
|
|
24
|
+
}
|
|
25
|
+
| ({ readonly default: Value } & {
|
|
26
|
+
readonly [query: `@media ${string}`]: Value
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
/** Nested categories and variable paths. */
|
|
30
|
+
export type Values = {
|
|
31
|
+
readonly [key: string]: Value | Values | readonly string[]
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Immutable references retaining their shared set contract. */
|
|
35
|
+
export type Definition<values extends Values = Values> = (Values extends values
|
|
36
|
+
? {}
|
|
37
|
+
: References<values>) & {
|
|
38
|
+
/** Authored value shape retained for inference. */
|
|
39
|
+
readonly [shape]: values
|
|
40
|
+
/** Compiler-owned identity and values. */
|
|
41
|
+
readonly [Token.definition]: Token.Metadata
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** Reference tree preserving the domain of each scalar leaf. */
|
|
45
|
+
export type References<values, root extends boolean = true> = {
|
|
46
|
+
readonly [key in Exclude<
|
|
47
|
+
keyof values,
|
|
48
|
+
root extends true ? 'breakpoints' | 'containers' | 'containerNames' : never
|
|
49
|
+
>]: values[key] extends Value
|
|
50
|
+
? Token.Reference<Domain<Scalar<values[key]>>> & {
|
|
51
|
+
readonly [Token.scalar]: Scalar<values[key]>
|
|
52
|
+
}
|
|
53
|
+
: References<values[key], false>
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Resolves the scalar types represented by all conditional branches. */
|
|
57
|
+
export type Scalar<value> = Value extends value
|
|
58
|
+
? string | number
|
|
59
|
+
: value extends { readonly [Token.scalar]: infer scalar }
|
|
60
|
+
? scalar
|
|
61
|
+
: value extends readonly string[]
|
|
62
|
+
? value
|
|
63
|
+
: value extends Token.Reference<infer group>
|
|
64
|
+
? group extends 'color'
|
|
65
|
+
? Literal.Color
|
|
66
|
+
: group extends 'spacing'
|
|
67
|
+
? Literal.Length
|
|
68
|
+
: group extends 'number'
|
|
69
|
+
? number
|
|
70
|
+
: string
|
|
71
|
+
: value extends { default: unknown }
|
|
72
|
+
? Scalar<value[keyof value]>
|
|
73
|
+
: value extends { light: infer light; dark: infer dark }
|
|
74
|
+
? Scalar<light | dark>
|
|
75
|
+
: value
|
|
76
|
+
|
|
77
|
+
/** Scalar domain shared by compatible set alternatives. */
|
|
78
|
+
export type Domain<value> = [value] extends [Literal.Color]
|
|
79
|
+
? 'color'
|
|
80
|
+
: [value] extends [Literal.Length]
|
|
81
|
+
? 'spacing'
|
|
82
|
+
: [value] extends [number]
|
|
83
|
+
? 'number'
|
|
84
|
+
: 'string'
|
|
85
|
+
|
|
86
|
+
/** Creates typed references without emitting CSS or reading the environment. */
|
|
87
|
+
export function define<const values extends Values>(
|
|
88
|
+
values: values & NoInfer<Validated<values, false, true>>,
|
|
89
|
+
options?: style.DefinitionOptions,
|
|
90
|
+
): Definition<values>
|
|
91
|
+
/** Deeply merges derived leaves, rejecting duplicate paths and leaf/category conflicts. */
|
|
92
|
+
export function define<
|
|
93
|
+
const values extends Values,
|
|
94
|
+
const derived extends Values,
|
|
95
|
+
>(
|
|
96
|
+
values: values & NoInfer<Validated<values, false, true>>,
|
|
97
|
+
derive: ((vars: References<values>) => derived) &
|
|
98
|
+
NoInfer<(vars: References<values>) => Validated<derived, false, true>>,
|
|
99
|
+
options?: style.DefinitionOptions,
|
|
100
|
+
): Definition<Merge<values, derived>>
|
|
101
|
+
export function define(
|
|
102
|
+
values: Values,
|
|
103
|
+
derive: style.DefinitionOptions | ((vars: References<Values>) => Values) = {},
|
|
104
|
+
options: style.DefinitionOptions = {},
|
|
105
|
+
): Definition {
|
|
106
|
+
if (typeof derive !== 'function') options = derive
|
|
107
|
+
|
|
108
|
+
const contract = Object.freeze({
|
|
109
|
+
variableSet: true,
|
|
110
|
+
...(options.id === undefined
|
|
111
|
+
? {}
|
|
112
|
+
: {
|
|
113
|
+
[Token.identity]: Identity.requireId(options.id, 'Vars.define'),
|
|
114
|
+
[Token.complete]: true,
|
|
115
|
+
}),
|
|
116
|
+
})
|
|
117
|
+
const base = VariableSets.build(values, contract)
|
|
118
|
+
if (typeof derive !== 'function') return base
|
|
119
|
+
|
|
120
|
+
const merged = VariableSets.merge(values, derive(base as References<Values>))
|
|
121
|
+
return VariableSets.build(merged, contract)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
type Merge<base, derived> = {
|
|
125
|
+
readonly [key in keyof base | keyof derived]: key extends keyof derived
|
|
126
|
+
? key extends keyof base
|
|
127
|
+
? Merge<base[key], derived[key]>
|
|
128
|
+
: derived[key]
|
|
129
|
+
: key extends keyof base
|
|
130
|
+
? base[key]
|
|
131
|
+
: never
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** Replaces existing leaves while preserving paths, domains, and reference identity. */
|
|
135
|
+
export function extend<const values extends Values>(
|
|
136
|
+
variables: Definition<values>,
|
|
137
|
+
overrides: Overrides<values>,
|
|
138
|
+
): Definition<values> {
|
|
139
|
+
const metadata = Object.getOwnPropertyDescriptor(variables, Token.definition)
|
|
140
|
+
?.value as Token.Metadata | undefined
|
|
141
|
+
if (!metadata?.contract.variableSet)
|
|
142
|
+
throw new InvalidError([], 'Expected a variable set.')
|
|
143
|
+
return VariableSets.build(
|
|
144
|
+
overrides,
|
|
145
|
+
metadata.contract,
|
|
146
|
+
metadata.values,
|
|
147
|
+
metadata.queries,
|
|
148
|
+
metadata.paths,
|
|
149
|
+
) as Definition<values>
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Partial compatible overrides. Conditional leaves are replaced in full. */
|
|
153
|
+
export type Overrides<values> = {
|
|
154
|
+
readonly [key in keyof values]?: values[key] extends Value
|
|
155
|
+
? Conditional<Compatible<Scalar<values[key]>>>
|
|
156
|
+
: Overrides<values[key]>
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
type Conditional<scalar> =
|
|
160
|
+
| scalar
|
|
161
|
+
| {
|
|
162
|
+
readonly default: Conditional<scalar>
|
|
163
|
+
readonly [query: `@media ${string}`]: Conditional<scalar>
|
|
164
|
+
}
|
|
165
|
+
type Compatible<scalar> = [scalar] extends [Literal.Color]
|
|
166
|
+
?
|
|
167
|
+
| Literal.Color
|
|
168
|
+
| Token.Reference<'color'>
|
|
169
|
+
| {
|
|
170
|
+
readonly light: Literal.Color | Token.Reference<'color'>
|
|
171
|
+
readonly dark: Literal.Color | Token.Reference<'color'>
|
|
172
|
+
}
|
|
173
|
+
: [scalar] extends [Literal.Length]
|
|
174
|
+
? Literal.Length | Token.Reference<'spacing'>
|
|
175
|
+
: [scalar] extends [number]
|
|
176
|
+
? number | Token.Reference<'number'>
|
|
177
|
+
: string | Token.Reference<'string'>
|
|
178
|
+
|
|
179
|
+
/** Category names mapped to the CSS properties that accept their shorthand tokens. */
|
|
180
|
+
export type Mappings = Readonly<
|
|
181
|
+
Record<string, readonly (keyof Literal.Properties)[]>
|
|
182
|
+
>
|
|
183
|
+
|
|
184
|
+
/** Type carrier for configured shorthand lookup. */
|
|
185
|
+
export type Mapped<values, mappings> = (Pick<
|
|
186
|
+
values,
|
|
187
|
+
keyof values &
|
|
188
|
+
('breakpoints' | 'containers' | 'containerNames' | 'typography')
|
|
189
|
+
> extends infer metadata extends Theme.Tokens
|
|
190
|
+
? metadata
|
|
191
|
+
: {}) & {
|
|
192
|
+
readonly color?: undefined
|
|
193
|
+
readonly '~vars': {
|
|
194
|
+
readonly values: values
|
|
195
|
+
readonly mappings: mappings
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Reads the values declared by a reusable definition or inline set. */
|
|
200
|
+
export type Extract<input> = input extends { readonly [shape]: infer values }
|
|
201
|
+
? values
|
|
202
|
+
: input
|
|
203
|
+
|
|
204
|
+
/** Invalid variable data with the offending path. */
|
|
205
|
+
export class InvalidError extends Error {
|
|
206
|
+
/** Creates a diagnostic for invalid data at the supplied path. */
|
|
207
|
+
constructor(
|
|
208
|
+
readonly path: readonly string[],
|
|
209
|
+
message: string,
|
|
210
|
+
) {
|
|
211
|
+
super(`${JSON.stringify(path)}: ${message}`)
|
|
212
|
+
}
|
|
213
|
+
/** Stable diagnostic name. */
|
|
214
|
+
override name = 'Vars.InvalidError'
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
type Validated<
|
|
218
|
+
value,
|
|
219
|
+
typography extends boolean = false,
|
|
220
|
+
root extends boolean = false,
|
|
221
|
+
> = Values extends value
|
|
222
|
+
? value
|
|
223
|
+
: value extends readonly string[]
|
|
224
|
+
? never
|
|
225
|
+
: value extends Token.Reference
|
|
226
|
+
? value
|
|
227
|
+
: value extends string | number
|
|
228
|
+
? Literal.Checked<value>
|
|
229
|
+
: root extends true
|
|
230
|
+
? {
|
|
231
|
+
readonly [key in keyof value]: key extends 'containerNames'
|
|
232
|
+
? value[key] extends readonly string[]
|
|
233
|
+
? value[key]
|
|
234
|
+
: never
|
|
235
|
+
: key extends
|
|
236
|
+
| `${string}.${string}`
|
|
237
|
+
| `${string}!${string}`
|
|
238
|
+
| `@${string}`
|
|
239
|
+
| ''
|
|
240
|
+
? never
|
|
241
|
+
: Validated<
|
|
242
|
+
value[key],
|
|
243
|
+
key extends 'typography' ? true : false
|
|
244
|
+
>
|
|
245
|
+
}
|
|
246
|
+
: value extends { default: infer base }
|
|
247
|
+
? Conditional<Compatible<Scalar<base>>> &
|
|
248
|
+
Record<
|
|
249
|
+
Exclude<keyof value, 'default' | `@media ${string}`>,
|
|
250
|
+
never
|
|
251
|
+
>
|
|
252
|
+
: value extends { light: unknown; dark: unknown }
|
|
253
|
+
? Pair<value>
|
|
254
|
+
: keyof value extends 'light' | 'dark'
|
|
255
|
+
? Pair<value>
|
|
256
|
+
: {
|
|
257
|
+
readonly [key in keyof value]: key extends
|
|
258
|
+
| `${string}.${string}`
|
|
259
|
+
| `${string}!${string}`
|
|
260
|
+
| `@${string}`
|
|
261
|
+
| ''
|
|
262
|
+
? typography extends true
|
|
263
|
+
? key extends Typography.Condition
|
|
264
|
+
? Validated<value[key], true>
|
|
265
|
+
: never
|
|
266
|
+
: never
|
|
267
|
+
: Validated<
|
|
268
|
+
value[key],
|
|
269
|
+
key extends 'typography' ? true : typography
|
|
270
|
+
>
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/** Applies a compatible variable set and optional color scheme to a scope. */
|
|
274
|
+
export type Selector<
|
|
275
|
+
name extends string,
|
|
276
|
+
output extends style.Output = 'react',
|
|
277
|
+
> = {
|
|
278
|
+
<
|
|
279
|
+
const selection extends {
|
|
280
|
+
readonly set?: name | undefined
|
|
281
|
+
readonly colorScheme?: 'light' | 'dark' | 'light dark' | undefined
|
|
282
|
+
} = {},
|
|
283
|
+
>(
|
|
284
|
+
options?: selection &
|
|
285
|
+
Record<Exclude<keyof selection, 'set' | 'colorScheme'>, never>,
|
|
286
|
+
): style.Props<output>
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
type Pair<value> = {
|
|
290
|
+
readonly light: Literal.Color | Token.Reference<'color'>
|
|
291
|
+
readonly dark: Literal.Color | Token.Reference<'color'>
|
|
292
|
+
} & Record<Exclude<keyof value, 'light' | 'dark'>, never>
|
|
293
|
+
|
|
294
|
+
/** Configured references and a selector for compatible scopes. */
|
|
295
|
+
export type Bound<
|
|
296
|
+
values extends Values,
|
|
297
|
+
name extends string = never,
|
|
298
|
+
output extends style.Output = 'react',
|
|
299
|
+
> = Definition<values> & Selector<name, output>
|