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/internal/Token.ts
CHANGED
|
@@ -2,19 +2,28 @@
|
|
|
2
2
|
* Carries portable theme references and enforces their property domains.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
import
|
|
5
|
+
import * as Binding from './Binding.js'
|
|
6
6
|
import type * as Query from './Query.js'
|
|
7
7
|
import type * as Shorthands from './Shorthands.js'
|
|
8
|
-
import type * as Theme from '
|
|
8
|
+
import type * as Theme from './Theme.js'
|
|
9
|
+
import type * as ValueSyntax from './Value.js'
|
|
10
|
+
import type * as VariableSets from '../Vars.js'
|
|
9
11
|
import * as Literal from './Literal.js'
|
|
12
|
+
import * as VariableData from './VariableSets.js'
|
|
10
13
|
|
|
11
14
|
/** Checks a reference's property domain. */
|
|
12
15
|
export function accepts(
|
|
13
16
|
group: Group,
|
|
14
17
|
property: keyof Literal.Properties,
|
|
15
18
|
): boolean {
|
|
19
|
+
if (property.startsWith('--')) return true
|
|
20
|
+
if (group === 'number' || group === 'string') return false
|
|
16
21
|
if (group === 'color') return Literal.rule(property)?.kind === 'color'
|
|
17
22
|
if (group === 'borderColor') return /^border.*Color$/.test(property)
|
|
23
|
+
if (group === 'borderWidth')
|
|
24
|
+
return /^border(?:Block|Inline)?(?:Start|End|Top|Right|Bottom|Left)?Width$/.test(
|
|
25
|
+
property,
|
|
26
|
+
)
|
|
18
27
|
if (group === 'borderRadius') return /^border.*Radius$/.test(property)
|
|
19
28
|
if (group === 'textColor') return property === 'color'
|
|
20
29
|
|
|
@@ -57,6 +66,50 @@ export function accepts(
|
|
|
57
66
|
return group === property
|
|
58
67
|
}
|
|
59
68
|
|
|
69
|
+
/** Checks explicit variable values independently of shorthand category mappings. */
|
|
70
|
+
export function acceptsReference(
|
|
71
|
+
reference: Reference,
|
|
72
|
+
property: keyof Literal.Properties,
|
|
73
|
+
): boolean {
|
|
74
|
+
if (!reference.contract.variableSet) return accepts(reference.group, property)
|
|
75
|
+
if (property.startsWith('--')) return true
|
|
76
|
+
function check(value: Value): boolean {
|
|
77
|
+
if (is(value)) return acceptsReference(value, property)
|
|
78
|
+
if (typeof value === 'object') return Object.values(value).every(check)
|
|
79
|
+
if (typeof value === 'number') {
|
|
80
|
+
const rule = Literal.rule(property)
|
|
81
|
+
if (rule?.kind === 'number')
|
|
82
|
+
return (
|
|
83
|
+
value >= rule.min &&
|
|
84
|
+
value <= rule.max &&
|
|
85
|
+
(!rule.integer || Number.isInteger(value))
|
|
86
|
+
)
|
|
87
|
+
return value === 0 && Binding.accepts('length', property)
|
|
88
|
+
}
|
|
89
|
+
if (reference.group === 'color') return Binding.accepts('color', property)
|
|
90
|
+
if (reference.group === 'spacing')
|
|
91
|
+
return (
|
|
92
|
+
(Literal.rule(property)?.kind === 'compound' &&
|
|
93
|
+
accepts('spacing', property)) ||
|
|
94
|
+
Binding.accepts(
|
|
95
|
+
value.endsWith('%')
|
|
96
|
+
? value.startsWith('-')
|
|
97
|
+
? 'signedPercentage'
|
|
98
|
+
: 'percentage'
|
|
99
|
+
: value.startsWith('-')
|
|
100
|
+
? 'signedLength'
|
|
101
|
+
: 'length',
|
|
102
|
+
property,
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
return (
|
|
106
|
+
Literal.isLiteral(property, value) ||
|
|
107
|
+
Literal.rule(property)?.kind === 'compound'
|
|
108
|
+
)
|
|
109
|
+
}
|
|
110
|
+
return check(reference.value)
|
|
111
|
+
}
|
|
112
|
+
|
|
60
113
|
/** Rebinds validated scalar references to a explicitly owned contract identity. */
|
|
61
114
|
export function bind<tokens extends Theme.Tokens>(
|
|
62
115
|
original: Theme.Definition<tokens>,
|
|
@@ -64,6 +117,9 @@ export function bind<tokens extends Theme.Tokens>(
|
|
|
64
117
|
): Theme.Definition<tokens> {
|
|
65
118
|
type Tree = { [key: string]: Reference | Tree }
|
|
66
119
|
|
|
120
|
+
const metadata = original[definition]
|
|
121
|
+
const values = VariableData.rebind(metadata, contract)
|
|
122
|
+
|
|
67
123
|
function rebind(tree: Theme.References<Theme.Tokens>): Tree {
|
|
68
124
|
return Object.freeze(
|
|
69
125
|
Object.fromEntries(
|
|
@@ -74,7 +130,7 @@ export function bind<tokens extends Theme.Tokens>(
|
|
|
74
130
|
contract,
|
|
75
131
|
group: value.group,
|
|
76
132
|
path: value.path,
|
|
77
|
-
value: value.
|
|
133
|
+
value: values[value.path]!,
|
|
78
134
|
})
|
|
79
135
|
: rebind(value as Theme.References<Theme.Tokens>),
|
|
80
136
|
]),
|
|
@@ -96,7 +152,7 @@ export function bind<tokens extends Theme.Tokens>(
|
|
|
96
152
|
vars: variables(tokens),
|
|
97
153
|
},
|
|
98
154
|
definition,
|
|
99
|
-
{ value: Object.freeze({ ...
|
|
155
|
+
{ value: Object.freeze({ ...metadata, contract, values }) },
|
|
100
156
|
),
|
|
101
157
|
) as Theme.Definition<tokens>
|
|
102
158
|
}
|
|
@@ -106,8 +162,14 @@ export const complete = Symbol('zyzz.contract.complete')
|
|
|
106
162
|
|
|
107
163
|
/** Opaque data shared by a definition and its compatible extensions. */
|
|
108
164
|
export type Contract = {
|
|
165
|
+
/** Whether values belong to independent variables rather than fixed theme categories. */
|
|
166
|
+
readonly variableSet?: boolean | undefined
|
|
167
|
+
/** Configuration-local category-to-property mappings. */
|
|
168
|
+
readonly mappings?: VariableSets.Mappings | false | undefined
|
|
109
169
|
/** Web emission mode retained by configuration-bound theme handles. */
|
|
110
170
|
readonly cssOutput?: 'atomic' | 'grouped' | undefined
|
|
171
|
+
/** Fallback layer for declarations without an explicit layer. */
|
|
172
|
+
readonly defaultLayer?: string | undefined
|
|
111
173
|
/** Configuration-local property aliases, inherited by bound handles. */
|
|
112
174
|
readonly shorthands?: Shorthands.Map | undefined
|
|
113
175
|
readonly [complete]?: boolean | undefined
|
|
@@ -153,23 +215,24 @@ export function compose(
|
|
|
153
215
|
export const web = Symbol('zyzz.web.variable')
|
|
154
216
|
|
|
155
217
|
/** Web reference with the original token domain. */
|
|
156
|
-
export type Variable<group extends Group = Group> =
|
|
157
|
-
|
|
158
|
-
|
|
218
|
+
export type Variable<group extends Group = Group> = `var(--${string})` &
|
|
219
|
+
Reference<group> & {
|
|
220
|
+
readonly [web]: true
|
|
221
|
+
}
|
|
159
222
|
|
|
160
223
|
/** Replaces portable scalar leaves with web-only references. */
|
|
161
|
-
export type
|
|
224
|
+
export type Vars<tree> =
|
|
162
225
|
tree extends Reference<infer group>
|
|
163
226
|
? Variable<group>
|
|
164
|
-
: { readonly [key in keyof tree]:
|
|
227
|
+
: { readonly [key in keyof tree]: Vars<tree[key]> }
|
|
165
228
|
|
|
166
229
|
/** Creates web-only reference leaves without changing contract identities. */
|
|
167
|
-
export function variables<tree>(tree: tree):
|
|
230
|
+
export function variables<tree>(tree: tree): Vars<tree> {
|
|
168
231
|
if (is(tree))
|
|
169
232
|
return Object.freeze({
|
|
170
233
|
...tree,
|
|
171
234
|
[web]: true as const,
|
|
172
|
-
}) as unknown as
|
|
235
|
+
}) as unknown as Vars<tree>
|
|
173
236
|
|
|
174
237
|
return Object.freeze(
|
|
175
238
|
Object.fromEntries(
|
|
@@ -178,7 +241,7 @@ export function variables<tree>(tree: tree): Variables<tree> {
|
|
|
178
241
|
variables(value),
|
|
179
242
|
]),
|
|
180
243
|
),
|
|
181
|
-
) as
|
|
244
|
+
) as Vars<tree>
|
|
182
245
|
}
|
|
183
246
|
|
|
184
247
|
/** Internal definition metadata; never enumerable consumer output. */
|
|
@@ -186,9 +249,12 @@ export const definition = Symbol('zyzz.theme')
|
|
|
186
249
|
|
|
187
250
|
/** Supported scalar token groups. */
|
|
188
251
|
export type Group =
|
|
252
|
+
| 'number'
|
|
253
|
+
| 'string'
|
|
189
254
|
| 'backgroundColor'
|
|
190
255
|
| 'borderColor'
|
|
191
256
|
| 'borderRadius'
|
|
257
|
+
| 'borderWidth'
|
|
192
258
|
| 'color'
|
|
193
259
|
| 'margin'
|
|
194
260
|
| 'padding'
|
|
@@ -223,19 +289,53 @@ export function is(value: unknown): value is Reference {
|
|
|
223
289
|
|
|
224
290
|
/** Immutable theme data carried directly by each definition. */
|
|
225
291
|
export type Metadata = {
|
|
292
|
+
/** Original segments for typography paths containing query punctuation. */
|
|
293
|
+
readonly paths?: Readonly<Record<string, readonly string[]>> | undefined
|
|
226
294
|
readonly queries?: Query.Metadata | undefined
|
|
227
295
|
readonly contract: Contract
|
|
228
296
|
readonly values: Readonly<Record<string, Value>>
|
|
229
297
|
}
|
|
230
298
|
|
|
231
|
-
/**
|
|
232
|
-
export
|
|
233
|
-
[group in Extract<keyof tokens, Group>]: property extends Properties<group>
|
|
234
|
-
? Paths<NonNullable<tokens[group]>>
|
|
235
|
-
: never
|
|
236
|
-
}[Extract<keyof tokens, Group>]
|
|
299
|
+
/** Literal domain carried by explicit variable references during type checking. */
|
|
300
|
+
export const scalar = Symbol('zyzz.variable.scalar')
|
|
237
301
|
|
|
238
|
-
|
|
302
|
+
/** Inferred shorthand names whose leaves belong to a property domain. */
|
|
303
|
+
export type Names<
|
|
304
|
+
tokens,
|
|
305
|
+
property extends keyof Literal.Properties,
|
|
306
|
+
> = tokens extends {
|
|
307
|
+
readonly '~vars': { values: infer values; mappings: infer mappings }
|
|
308
|
+
}
|
|
309
|
+
? mappings extends false
|
|
310
|
+
? Paths<
|
|
311
|
+
Omit<values, 'breakpoints' | 'containers' | 'containerNames'>,
|
|
312
|
+
property
|
|
313
|
+
>
|
|
314
|
+
: {
|
|
315
|
+
[category in keyof values]: category extends keyof mappings
|
|
316
|
+
? mappings[category] extends readonly unknown[]
|
|
317
|
+
? property extends mappings[category][number]
|
|
318
|
+
? Paths<values[category], property>
|
|
319
|
+
: never
|
|
320
|
+
: never
|
|
321
|
+
: category extends Group
|
|
322
|
+
? property extends Properties<category>
|
|
323
|
+
? Paths<values[category], property>
|
|
324
|
+
: never
|
|
325
|
+
: never
|
|
326
|
+
}[keyof values]
|
|
327
|
+
: {
|
|
328
|
+
[group in Extract<
|
|
329
|
+
keyof tokens,
|
|
330
|
+
Group
|
|
331
|
+
>]: property extends Properties<group>
|
|
332
|
+
? Paths<NonNullable<tokens[group]>>
|
|
333
|
+
: never
|
|
334
|
+
}[Extract<keyof tokens, Group>]
|
|
335
|
+
|
|
336
|
+
type Paths<tree, property extends keyof Literal.Properties = never> = [
|
|
337
|
+
tree,
|
|
338
|
+
] extends [never]
|
|
239
339
|
? never
|
|
240
340
|
: string extends keyof tree
|
|
241
341
|
? string
|
|
@@ -243,72 +343,95 @@ type Paths<tree> = [tree] extends [never]
|
|
|
243
343
|
[key in Extract<keyof tree, number | string>]: NonNullable<
|
|
244
344
|
tree[key]
|
|
245
345
|
> extends Value
|
|
246
|
-
?
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
346
|
+
? [property] extends [never]
|
|
347
|
+
? PathKey<key>
|
|
348
|
+
: VariableSets.Scalar<
|
|
349
|
+
NonNullable<tree[key]>
|
|
350
|
+
> extends Literal.Properties[property] &
|
|
351
|
+
ValueSyntax.Checked<
|
|
352
|
+
Record<
|
|
353
|
+
property,
|
|
354
|
+
VariableSets.Scalar<NonNullable<tree[key]>>
|
|
355
|
+
>
|
|
356
|
+
>[property]
|
|
357
|
+
? PathKey<key>
|
|
358
|
+
: never
|
|
359
|
+
: `${key}.${Paths<NonNullable<tree[key]>, property>}`
|
|
255
360
|
}[Extract<keyof tree, number | string>]
|
|
256
361
|
|
|
362
|
+
type PathKey<key extends number | string> =
|
|
363
|
+
| key
|
|
364
|
+
| `${key}`
|
|
365
|
+
| (key extends `${infer numericKey extends number}`
|
|
366
|
+
? `${numericKey}` extends key
|
|
367
|
+
? numericKey
|
|
368
|
+
: never
|
|
369
|
+
: never)
|
|
370
|
+
|
|
257
371
|
/** Property domains accepted by each token group. */
|
|
258
|
-
export type Properties<group extends Group> =
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
| `blockSize`
|
|
267
|
-
| `bottom`
|
|
268
|
-
| `columnGap`
|
|
269
|
-
| `flexBasis`
|
|
270
|
-
| `gap`
|
|
271
|
-
| `height`
|
|
272
|
-
| `inlineSize`
|
|
273
|
-
| `inset${string}`
|
|
274
|
-
| `left`
|
|
275
|
-
| Exclude<
|
|
276
|
-
Extract<keyof Literal.Properties, `margin${string}`>,
|
|
277
|
-
'marginTrim'
|
|
278
|
-
>
|
|
279
|
-
| `maxBlockSize`
|
|
280
|
-
| `maxHeight`
|
|
281
|
-
| `maxInlineSize`
|
|
282
|
-
| `maxWidth`
|
|
283
|
-
| `minBlockSize`
|
|
284
|
-
| `minHeight`
|
|
285
|
-
| `minInlineSize`
|
|
286
|
-
| `minWidth`
|
|
287
|
-
| `padding${string}`
|
|
288
|
-
| `right`
|
|
289
|
-
| `rowGap`
|
|
290
|
-
| `scrollPadding${string}`
|
|
291
|
-
| `textDecorationThickness`
|
|
292
|
-
| `textIndent`
|
|
293
|
-
| `textUnderlineOffset`
|
|
294
|
-
| `top`
|
|
295
|
-
| `width`
|
|
372
|
+
export type Properties<group extends Group> = `--${string}` | Property<group>
|
|
373
|
+
|
|
374
|
+
type Property<group extends Group> = group extends 'number' | 'string'
|
|
375
|
+
? never
|
|
376
|
+
: group extends 'margin' | 'padding'
|
|
377
|
+
? Exclude<
|
|
378
|
+
Extract<keyof Literal.Properties, `${group}${string}`>,
|
|
379
|
+
'marginTrim'
|
|
296
380
|
>
|
|
297
|
-
: group extends '
|
|
298
|
-
?
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
381
|
+
: group extends 'spacing'
|
|
382
|
+
? Extract<
|
|
383
|
+
keyof Literal.Properties,
|
|
384
|
+
| `blockSize`
|
|
385
|
+
| `bottom`
|
|
386
|
+
| `columnGap`
|
|
387
|
+
| `flexBasis`
|
|
388
|
+
| `gap`
|
|
389
|
+
| `height`
|
|
390
|
+
| `inlineSize`
|
|
391
|
+
| `inset${string}`
|
|
392
|
+
| `left`
|
|
393
|
+
| Exclude<
|
|
394
|
+
Extract<keyof Literal.Properties, `margin${string}`>,
|
|
395
|
+
'marginTrim'
|
|
396
|
+
>
|
|
397
|
+
| `maxBlockSize`
|
|
398
|
+
| `maxHeight`
|
|
399
|
+
| `maxInlineSize`
|
|
400
|
+
| `maxWidth`
|
|
401
|
+
| `minBlockSize`
|
|
402
|
+
| `minHeight`
|
|
403
|
+
| `minInlineSize`
|
|
404
|
+
| `minWidth`
|
|
405
|
+
| `padding${string}`
|
|
406
|
+
| `right`
|
|
407
|
+
| `rowGap`
|
|
408
|
+
| `scrollPadding${string}`
|
|
409
|
+
| `textDecorationThickness`
|
|
410
|
+
| `textIndent`
|
|
411
|
+
| `textUnderlineOffset`
|
|
412
|
+
| `top`
|
|
413
|
+
| `width`
|
|
414
|
+
>
|
|
415
|
+
: group extends 'textColor'
|
|
416
|
+
? 'color'
|
|
417
|
+
: group extends 'color'
|
|
418
|
+
? {
|
|
419
|
+
[property in keyof typeof Literal.rules]: (typeof Literal.rules)[property] extends {
|
|
420
|
+
kind: 'color'
|
|
421
|
+
}
|
|
422
|
+
? property
|
|
423
|
+
: never
|
|
424
|
+
}[keyof typeof Literal.rules]
|
|
425
|
+
: group extends 'borderColor'
|
|
426
|
+
? Extract<keyof Literal.Properties, `border${string}Color`>
|
|
427
|
+
: group extends 'borderWidth'
|
|
428
|
+
? Exclude<
|
|
429
|
+
Extract<keyof Literal.Properties, `border${string}Width`>,
|
|
430
|
+
'borderImageWidth'
|
|
431
|
+
>
|
|
432
|
+
: group extends 'borderRadius'
|
|
433
|
+
? Extract<keyof Literal.Properties, `border${string}Radius`>
|
|
434
|
+
: group
|
|
312
435
|
|
|
313
436
|
/** Immutable portable reference retaining its defining fallback. */
|
|
314
437
|
export type Reference<group extends Group = Group> = {
|
|
@@ -333,11 +456,11 @@ export function resolve(value: unknown, options: resolve.Options): unknown {
|
|
|
333
456
|
?.value as Metadata | undefined
|
|
334
457
|
if (!data) throw new Error('Expected a theme definition.')
|
|
335
458
|
|
|
336
|
-
|
|
337
|
-
for (const group of [
|
|
459
|
+
const groups = [
|
|
338
460
|
'backgroundColor',
|
|
339
461
|
'borderColor',
|
|
340
462
|
'borderRadius',
|
|
463
|
+
'borderWidth',
|
|
341
464
|
'margin',
|
|
342
465
|
'padding',
|
|
343
466
|
'spacing',
|
|
@@ -348,7 +471,49 @@ export function resolve(value: unknown, options: resolve.Options): unknown {
|
|
|
348
471
|
'lineHeight',
|
|
349
472
|
'textColor',
|
|
350
473
|
'color',
|
|
351
|
-
] as const
|
|
474
|
+
] as const
|
|
475
|
+
|
|
476
|
+
if (data.contract.variableSet) {
|
|
477
|
+
for (const [path, entry] of Object.entries(data.values).sort(
|
|
478
|
+
([left], [right]) =>
|
|
479
|
+
groups.indexOf(left.split('.')[0] as (typeof groups)[number]) -
|
|
480
|
+
groups.indexOf(right.split('.')[0] as (typeof groups)[number]),
|
|
481
|
+
)) {
|
|
482
|
+
const [category, ...parts] = path.split('.')
|
|
483
|
+
const mappings = data.contract.mappings
|
|
484
|
+
const mapped = mappings === false ? undefined : mappings?.[category!]
|
|
485
|
+
if (
|
|
486
|
+
mappings === false
|
|
487
|
+
? path !== String(value)
|
|
488
|
+
: parts.join('.') !== String(value) ||
|
|
489
|
+
!(mapped
|
|
490
|
+
? mapped.includes(options.property)
|
|
491
|
+
: accepts(category as Group, options.property))
|
|
492
|
+
)
|
|
493
|
+
continue
|
|
494
|
+
return create({
|
|
495
|
+
contract: data.contract,
|
|
496
|
+
group: (() => {
|
|
497
|
+
let leaf: unknown = Object.getOwnPropertyDescriptor(
|
|
498
|
+
options.theme,
|
|
499
|
+
'tokens',
|
|
500
|
+
)?.value
|
|
501
|
+
for (const key of path.split('.'))
|
|
502
|
+
leaf =
|
|
503
|
+
leaf && typeof leaf === 'object'
|
|
504
|
+
? Object.getOwnPropertyDescriptor(leaf, key)?.value
|
|
505
|
+
: undefined
|
|
506
|
+
return is(leaf) ? leaf.group : (category as Group)
|
|
507
|
+
})(),
|
|
508
|
+
path,
|
|
509
|
+
value: entry,
|
|
510
|
+
})
|
|
511
|
+
}
|
|
512
|
+
return value
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
// Specific groups precede shared colors regardless of authored group order.
|
|
516
|
+
for (const group of groups) {
|
|
352
517
|
if (!accepts(group, options.property)) continue
|
|
353
518
|
|
|
354
519
|
const path = `${group}.${value}`
|
|
@@ -377,4 +542,12 @@ export declare namespace resolve {
|
|
|
377
542
|
export type Value =
|
|
378
543
|
| number
|
|
379
544
|
| string
|
|
380
|
-
|
|
|
545
|
+
| Reference
|
|
546
|
+
| { readonly dark: Value; readonly light: Value }
|
|
547
|
+
| Conditions
|
|
548
|
+
|
|
549
|
+
/** Ordered conditional values with an unconditional fallback. */
|
|
550
|
+
export type Conditions = {
|
|
551
|
+
readonly default: Value
|
|
552
|
+
readonly [query: `@media ${string}`]: Value
|
|
553
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** Describes nested typography sets and their property-aware token paths. @module */
|
|
2
|
+
import type * as Literal from './Literal.js'
|
|
3
|
+
import * as Token from './Token.js'
|
|
4
|
+
|
|
5
|
+
/** Responsive query blocks accepted within a typography set. */
|
|
6
|
+
export type Condition = `@media ${string}` | `@container ${string}`
|
|
7
|
+
|
|
8
|
+
/** Recognizes responsive blocks without accepting selectors or unrelated at-rules. */
|
|
9
|
+
export function condition(key: string): key is Condition {
|
|
10
|
+
return /^@(media|container)\s+\S/.test(key)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/** Expands one named set into portable field references and ordered query blocks. */
|
|
14
|
+
export function entries(
|
|
15
|
+
theme: object | undefined,
|
|
16
|
+
name: unknown,
|
|
17
|
+
explicit: ReadonlySet<string> = new Set(),
|
|
18
|
+
important = false,
|
|
19
|
+
): readonly (readonly [string, unknown])[] {
|
|
20
|
+
if (
|
|
21
|
+
!theme ||
|
|
22
|
+
typeof name !== 'string' ||
|
|
23
|
+
name.split('.').some((part) => part.startsWith('@'))
|
|
24
|
+
)
|
|
25
|
+
return []
|
|
26
|
+
let tree: unknown = Object.getOwnPropertyDescriptor(theme, 'tokens')?.value
|
|
27
|
+
for (const part of ['typography', ...name.split('.')]) {
|
|
28
|
+
if (!tree || typeof tree !== 'object') return []
|
|
29
|
+
tree = Object.getOwnPropertyDescriptor(tree, part)?.value
|
|
30
|
+
}
|
|
31
|
+
function expand(value: unknown): readonly (readonly [string, unknown])[] {
|
|
32
|
+
if (!value || typeof value !== 'object') return []
|
|
33
|
+
return Object.entries(value).flatMap(
|
|
34
|
+
([key, child]): (readonly [string, unknown])[] => {
|
|
35
|
+
if (
|
|
36
|
+
properties.includes(key as Property) &&
|
|
37
|
+
Token.is(child) &&
|
|
38
|
+
!explicit.has(key)
|
|
39
|
+
)
|
|
40
|
+
return [
|
|
41
|
+
[key, important ? Token.compose([child, ' !important']) : child],
|
|
42
|
+
]
|
|
43
|
+
if (condition(key)) {
|
|
44
|
+
const nested = expand(child)
|
|
45
|
+
return nested.length ? [[key, Object.fromEntries(nested)]] : []
|
|
46
|
+
}
|
|
47
|
+
return []
|
|
48
|
+
},
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
return expand(tree)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Lists expanded fields and queries in source-map traversal order. */
|
|
55
|
+
export function keys(
|
|
56
|
+
theme: object | undefined,
|
|
57
|
+
name: unknown,
|
|
58
|
+
explicit: ReadonlySet<string>,
|
|
59
|
+
): readonly string[] {
|
|
60
|
+
function collect(values: readonly (readonly [string, unknown])[]): string[] {
|
|
61
|
+
return values.flatMap(([key, value]) =>
|
|
62
|
+
condition(key)
|
|
63
|
+
? [key, ...collect(Object.entries(value as object))]
|
|
64
|
+
: [key],
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
return collect(entries(theme, name, explicit))
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Names of sets containing at least one typography declaration. */
|
|
71
|
+
export type Names<tokens> = tokens extends { typography: infer tree }
|
|
72
|
+
? Paths<tree>
|
|
73
|
+
: never
|
|
74
|
+
|
|
75
|
+
type Paths<tree> = string extends keyof tree
|
|
76
|
+
? string
|
|
77
|
+
: {
|
|
78
|
+
[key in Exclude<
|
|
79
|
+
Extract<keyof tree, string | number>,
|
|
80
|
+
Property | Condition
|
|
81
|
+
>]:
|
|
82
|
+
| (Extract<keyof tree[key], Property | Condition> extends never
|
|
83
|
+
? never
|
|
84
|
+
: `${key}`)
|
|
85
|
+
| `${key}.${Paths<tree[key]>}`
|
|
86
|
+
}[Exclude<Extract<keyof tree, string | number>, Property | Condition>]
|
|
87
|
+
|
|
88
|
+
/** Scalar properties applied by a typography set. */
|
|
89
|
+
export const properties = [
|
|
90
|
+
'fontFamily',
|
|
91
|
+
'fontSize',
|
|
92
|
+
'fontWeight',
|
|
93
|
+
'letterSpacing',
|
|
94
|
+
'lineHeight',
|
|
95
|
+
] as const
|
|
96
|
+
|
|
97
|
+
/** Property domain retained by each field in a set. */
|
|
98
|
+
export type Property = (typeof properties)[number]
|
|
99
|
+
|
|
100
|
+
/** A set may supply any of the five typography properties. */
|
|
101
|
+
export type Set = Pick<Literal.Properties, Property> & {
|
|
102
|
+
readonly [key in Condition]?: Set
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Nested names may contain sets and additional named variants. */
|
|
106
|
+
export type Sets = { readonly [name: string]: Set | Sets }
|
package/src/internal/Value.ts
CHANGED
|
@@ -22,37 +22,56 @@ export type Atom<value> =
|
|
|
22
22
|
*/
|
|
23
23
|
export type Accepted<style, properties> = {
|
|
24
24
|
[property in keyof style]: property extends keyof properties
|
|
25
|
-
? style[property] extends
|
|
26
|
-
?
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
? style[property]
|
|
25
|
+
? style[property] extends { readonly [Token.scalar]: infer scalar }
|
|
26
|
+
? property extends keyof Literal.Properties
|
|
27
|
+
? [scalar] extends [Literal.Properties[property]]
|
|
28
|
+
? style[property] & Checked<Record<property, scalar>>[property]
|
|
29
|
+
: never
|
|
31
30
|
: never
|
|
32
|
-
:
|
|
33
|
-
|
|
34
|
-
style[property]
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
? Fold<style[property]> extends Input<
|
|
46
|
-
| Lowercase<Extract<Literal.Properties[property], string>>
|
|
47
|
-
| Extract<Literal.Properties[property], number>
|
|
31
|
+
: References<style[property], Exclude<properties[property], undefined>> &
|
|
32
|
+
(style[property] extends Binding.Reference
|
|
33
|
+
? Binding.Reference<style[property]['type']> extends Exclude<
|
|
34
|
+
properties[property],
|
|
35
|
+
undefined
|
|
36
|
+
>
|
|
37
|
+
? style[property]
|
|
38
|
+
: never
|
|
39
|
+
: FunctionValue.Is<style[property]> extends true
|
|
40
|
+
? FunctionValue.Accepted<
|
|
41
|
+
style[property],
|
|
42
|
+
Exclude<properties[property], undefined>,
|
|
43
|
+
property
|
|
48
44
|
>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
45
|
+
: Exclude<style[property], undefined> extends Exclude<
|
|
46
|
+
properties[property],
|
|
47
|
+
undefined
|
|
48
|
+
>
|
|
49
|
+
? Exclude<style[property], undefined>
|
|
50
|
+
: property extends keyof Literal.Properties
|
|
51
|
+
? style[property] extends
|
|
52
|
+
| string
|
|
53
|
+
| readonly (number | string)[]
|
|
54
|
+
? Fold<style[property]> extends Input<
|
|
55
|
+
| Lowercase<
|
|
56
|
+
Extract<Literal.Properties[property], string>
|
|
57
|
+
>
|
|
58
|
+
| Extract<Literal.Properties[property], number>
|
|
59
|
+
>
|
|
60
|
+
? style[property]
|
|
61
|
+
: Exclude<properties[property], undefined>
|
|
62
|
+
: Exclude<properties[property], undefined>
|
|
63
|
+
: Exclude<properties[property], undefined>)
|
|
53
64
|
: never
|
|
54
65
|
}
|
|
55
66
|
|
|
67
|
+
type References<value, allowed> = value extends Token.Reference
|
|
68
|
+
? value extends Extract<allowed, Token.Reference>
|
|
69
|
+
? unknown
|
|
70
|
+
: never
|
|
71
|
+
: value extends readonly unknown[]
|
|
72
|
+
? { [key in keyof value]: References<value[key], allowed> }
|
|
73
|
+
: unknown
|
|
74
|
+
|
|
56
75
|
type Fold<value> = value extends string
|
|
57
76
|
? Lexical.Fold<Canonical<Spaces<Normalized<Lexical.Normalized<value>>>>>
|
|
58
77
|
: value extends readonly unknown[]
|