zyzz 0.0.19 → 0.0.21
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 +9 -9
- package/dist/Config.d.ts +1 -0
- package/dist/Config.d.ts.map +1 -1
- package/dist/Config.js.map +1 -1
- package/dist/Style.d.ts +7 -0
- package/dist/Style.d.ts.map +1 -1
- package/dist/Style.js +1 -5
- package/dist/Style.js.map +1 -1
- package/dist/Vars.d.ts +22 -15
- package/dist/Vars.d.ts.map +1 -1
- package/dist/Vars.js +26 -0
- package/dist/Vars.js.map +1 -1
- package/dist/cli/index.js +5 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/compiler/Graph.d.ts +3 -0
- package/dist/compiler/Graph.d.ts.map +1 -1
- package/dist/compiler/Graph.js +44 -37
- package/dist/compiler/Graph.js.map +1 -1
- package/dist/compiler/Source.d.ts +4 -0
- package/dist/compiler/Source.d.ts.map +1 -1
- package/dist/compiler/Source.js +66 -6
- package/dist/compiler/Source.js.map +1 -1
- package/dist/compiler/Transform.d.ts +4 -1
- package/dist/compiler/Transform.d.ts.map +1 -1
- package/dist/compiler/Transform.js +32 -46
- package/dist/compiler/Transform.js.map +1 -1
- package/dist/compiler/internal/Catalogs.d.ts.map +1 -1
- package/dist/compiler/internal/Catalogs.js +6 -1
- package/dist/compiler/internal/Catalogs.js.map +1 -1
- package/dist/compiler/internal/Compositions.d.ts.map +1 -1
- package/dist/compiler/internal/Compositions.js +5 -0
- 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 +5 -1
- package/dist/compiler/internal/Configurations.js.map +1 -1
- package/dist/compiler/internal/Contract.d.ts +4 -1
- package/dist/compiler/internal/Contract.d.ts.map +1 -1
- package/dist/compiler/internal/Contract.js +73 -138
- package/dist/compiler/internal/Contract.js.map +1 -1
- package/dist/compiler/internal/Contributions.d.ts.map +1 -1
- package/dist/compiler/internal/Contributions.js +1 -3
- package/dist/compiler/internal/Contributions.js.map +1 -1
- package/dist/compiler/internal/Dynamic.d.ts +1 -1
- package/dist/compiler/internal/Dynamic.d.ts.map +1 -1
- package/dist/compiler/internal/Dynamic.js +5 -5
- package/dist/compiler/internal/Dynamic.js.map +1 -1
- package/dist/compiler/internal/Names.d.ts +5 -0
- package/dist/compiler/internal/Names.d.ts.map +1 -0
- package/dist/compiler/internal/Names.js +37 -0
- package/dist/compiler/internal/Names.js.map +1 -0
- package/dist/compiler/internal/Selectors.d.ts +1 -1
- package/dist/compiler/internal/Selectors.d.ts.map +1 -1
- package/dist/compiler/internal/Selectors.js +5 -2
- package/dist/compiler/internal/Selectors.js.map +1 -1
- package/dist/compiler/internal/Stylesheets.js +2 -2
- package/dist/compiler/internal/Stylesheets.js.map +1 -1
- package/dist/compiler/internal/Themes.d.ts.map +1 -1
- package/dist/compiler/internal/Themes.js +85 -24
- package/dist/compiler/internal/Themes.js.map +1 -1
- package/dist/compiler/internal/Vars.d.ts +2 -0
- package/dist/compiler/internal/Vars.d.ts.map +1 -1
- package/dist/compiler/internal/Vars.js +7 -1
- package/dist/compiler/internal/Vars.js.map +1 -1
- package/dist/default.d.ts +11 -15
- package/dist/default.d.ts.map +1 -1
- package/dist/default.js +13 -14
- package/dist/default.js.map +2 -2
- package/dist/default.js.zyzz.json +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/internal/Authoring.d.ts.map +1 -1
- package/dist/internal/Authoring.js +8 -3
- package/dist/internal/Authoring.js.map +1 -1
- package/dist/internal/Binding.d.ts +4 -0
- package/dist/internal/Binding.d.ts.map +1 -1
- package/dist/internal/Binding.js +2 -0
- package/dist/internal/Binding.js.map +1 -1
- package/dist/internal/Configuration.d.ts +2 -2
- package/dist/internal/Configuration.d.ts.map +1 -1
- package/dist/internal/Configuration.js +4 -2
- package/dist/internal/Configuration.js.map +1 -1
- package/dist/internal/Identity.d.ts +3 -3
- package/dist/internal/Identity.d.ts.map +1 -1
- package/dist/internal/Identity.js +11 -9
- package/dist/internal/Identity.js.map +1 -1
- package/dist/internal/Theme.js +2 -2
- package/dist/internal/Theme.js.map +1 -1
- package/dist/internal/Token.d.ts +16 -3
- package/dist/internal/Token.d.ts.map +1 -1
- package/dist/internal/Token.js +11 -2
- package/dist/internal/Token.js.map +1 -1
- package/dist/internal/VariableSets.d.ts.map +1 -1
- package/dist/internal/VariableSets.js +19 -2
- package/dist/internal/VariableSets.js.map +1 -1
- package/dist/node/Host.d.ts +2 -0
- package/dist/node/Host.d.ts.map +1 -1
- package/dist/node/Host.js +9 -0
- package/dist/node/Host.js.map +1 -1
- package/dist/react-native/StyleSheet.js +2 -0
- package/dist/react-native/StyleSheet.js.map +1 -1
- package/dist/runtime/Composition.d.ts +1 -1
- package/dist/runtime/ConditionalRecipe.d.ts +1 -1
- package/dist/runtime/PayloadRecipe.d.ts +1 -1
- package/dist/runtime/Recipe.d.ts +1 -1
- package/dist/styleFunction.d.ts +1 -1
- package/dist/styleFunction.d.ts.map +1 -1
- package/dist/styleFunction.js.map +1 -1
- package/dist/variable.js +1 -1
- package/dist/variable.js.map +1 -1
- package/dist/variants.d.ts +14 -6
- package/dist/variants.d.ts.map +1 -1
- package/dist/variants.js.map +1 -1
- package/dist/vite/index.d.ts +2 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +111 -42
- package/dist/vite/index.js.map +1 -1
- package/dist/web/Css.d.ts +7 -2
- package/dist/web/Css.d.ts.map +1 -1
- package/dist/web/Css.js +46 -39
- package/dist/web/Css.js.map +1 -1
- package/dist/web/internal/ClassName.d.ts +13 -2
- package/dist/web/internal/ClassName.d.ts.map +1 -1
- package/dist/web/internal/ClassName.js +17 -30
- package/dist/web/internal/ClassName.js.map +1 -1
- package/dist/web/internal/Themes.d.ts +3 -0
- package/dist/web/internal/Themes.d.ts.map +1 -1
- package/dist/web/internal/Themes.js +52 -24
- package/dist/web/internal/Themes.js.map +1 -1
- package/package.json +1 -1
- package/src/Config.ts +5 -0
- package/src/Style.ts +4 -1
- package/src/Vars.ts +88 -29
- package/src/cli/index.ts +5 -0
- package/src/compiler/Graph.ts +60 -46
- package/src/compiler/Source.ts +86 -5
- package/src/compiler/Transform.ts +42 -60
- package/src/compiler/internal/Catalogs.ts +9 -1
- package/src/compiler/internal/Compositions.ts +7 -0
- package/src/compiler/internal/Configurations.ts +5 -1
- package/src/compiler/internal/Contract.ts +104 -239
- package/src/compiler/internal/Contributions.ts +1 -5
- package/src/compiler/internal/Dynamic.ts +14 -9
- package/src/compiler/internal/Names.ts +48 -0
- package/src/compiler/internal/Selectors.ts +6 -1
- package/src/compiler/internal/Stylesheets.ts +2 -2
- package/src/compiler/internal/Themes.ts +115 -35
- package/src/compiler/internal/Vars.ts +9 -1
- package/src/default.ts +17 -20
- package/src/index.ts +15 -0
- package/src/internal/Authoring.ts +9 -3
- package/src/internal/Binding.ts +5 -0
- package/src/internal/Configuration.ts +7 -4
- package/src/internal/Identity.ts +14 -12
- package/src/internal/Theme.ts +2 -2
- package/src/internal/Token.ts +52 -12
- package/src/internal/VariableSets.ts +26 -2
- package/src/node/Host.ts +22 -0
- package/src/react-native/StyleSheet.ts +6 -0
- package/src/styleFunction.ts +1 -3
- package/src/variable.ts +1 -1
- package/src/variants.ts +38 -16
- package/src/vite/index.ts +137 -51
- package/src/web/Css.ts +83 -49
- package/src/web/internal/ClassName.ts +31 -36
- package/src/web/internal/Themes.ts +79 -29
|
@@ -144,6 +144,7 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
144
144
|
const imports = new Set<number>()
|
|
145
145
|
const variableImports = new Set<number>()
|
|
146
146
|
const configImports = new Set<number>()
|
|
147
|
+
const factoryImports = new Map<number, 'create' | 'define' | 'extend'>()
|
|
147
148
|
const configs = new Map<string, Link>()
|
|
148
149
|
const configBindings = new Map<number, Link>()
|
|
149
150
|
const factoryReferences = new Set<number>()
|
|
@@ -188,11 +189,31 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
188
189
|
: specifier.imported.value) === 'Config'
|
|
189
190
|
)
|
|
190
191
|
configImports.add(specifier.start)
|
|
192
|
+
else if (
|
|
193
|
+
specifier.type === 'ImportSpecifier' &&
|
|
194
|
+
specifier.importKind !== 'type' &&
|
|
195
|
+
['defineConfig', 'defineVars', 'extendVars'].includes(
|
|
196
|
+
specifier.imported.type === 'Identifier'
|
|
197
|
+
? specifier.imported.name
|
|
198
|
+
: specifier.imported.value,
|
|
199
|
+
)
|
|
200
|
+
) {
|
|
201
|
+
const name =
|
|
202
|
+
specifier.imported.type === 'Identifier'
|
|
203
|
+
? specifier.imported.name
|
|
204
|
+
: specifier.imported.value
|
|
205
|
+
if (name === 'defineConfig')
|
|
206
|
+
factoryImports.set(specifier.start, 'create')
|
|
207
|
+
else if (name === 'defineVars')
|
|
208
|
+
factoryImports.set(specifier.start, 'define')
|
|
209
|
+
else factoryImports.set(specifier.start, 'extend')
|
|
210
|
+
}
|
|
191
211
|
}
|
|
192
212
|
|
|
193
213
|
if (
|
|
194
214
|
!imports.size &&
|
|
195
215
|
!configImports.size &&
|
|
216
|
+
!factoryImports.size &&
|
|
196
217
|
!Object.keys(options.links ?? {}).length
|
|
197
218
|
)
|
|
198
219
|
return undefined
|
|
@@ -251,6 +272,7 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
251
272
|
|
|
252
273
|
const namespaces = new Set<string>()
|
|
253
274
|
const configNamespaces = new Set<string>()
|
|
275
|
+
const factoryFunctions = new Map<string, 'create' | 'define' | 'extend'>()
|
|
254
276
|
const variableNamespaces = new Set<string>()
|
|
255
277
|
for (const node of program.body)
|
|
256
278
|
if (node.type === 'ImportDeclaration')
|
|
@@ -264,6 +286,11 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
264
286
|
if (imports.has(specifier.start)) namespaces.add(specifier.local.name)
|
|
265
287
|
else if (configImports.has(specifier.start))
|
|
266
288
|
configNamespaces.add(specifier.local.name)
|
|
289
|
+
else if (factoryImports.has(specifier.start))
|
|
290
|
+
factoryFunctions.set(
|
|
291
|
+
specifier.local.name,
|
|
292
|
+
factoryImports.get(specifier.start)!,
|
|
293
|
+
)
|
|
267
294
|
|
|
268
295
|
function resolve(node: Ast.Node): Link | undefined {
|
|
269
296
|
if (node.type === 'Identifier') {
|
|
@@ -426,6 +453,35 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
426
453
|
if (node.type === 'TSAsExpression' || node.type === 'TSSatisfiesExpression')
|
|
427
454
|
return data(node.expression, derived)
|
|
428
455
|
|
|
456
|
+
if (node.type === 'CallExpression' && !node.optional) {
|
|
457
|
+
const callee = node.callee
|
|
458
|
+
if (
|
|
459
|
+
callee.type === 'MemberExpression' &&
|
|
460
|
+
!callee.computed &&
|
|
461
|
+
!callee.optional &&
|
|
462
|
+
callee.object.type === 'Identifier' &&
|
|
463
|
+
variableNamespaces.has(callee.object.name) &&
|
|
464
|
+
derived?.name !== callee.object.name &&
|
|
465
|
+
callee.property.type === 'Identifier' &&
|
|
466
|
+
callee.property.name === 'compose'
|
|
467
|
+
) {
|
|
468
|
+
if (node.arguments.length !== 2)
|
|
469
|
+
return fail(
|
|
470
|
+
'Vars.compose requires a literal domain and parts array.',
|
|
471
|
+
node,
|
|
472
|
+
)
|
|
473
|
+
const group = data(node.arguments[0]!, derived)
|
|
474
|
+
const parts = data(node.arguments[1]!, derived)
|
|
475
|
+
if ((group !== 'color' && group !== 'spacing') || !Array.isArray(parts))
|
|
476
|
+
return fail(
|
|
477
|
+
'Vars.compose requires a literal domain and parts array.',
|
|
478
|
+
node,
|
|
479
|
+
)
|
|
480
|
+
factoryReferences.add(callee.start)
|
|
481
|
+
return Vars.compose(group, parts)
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
429
485
|
if (
|
|
430
486
|
node.type === 'Literal' &&
|
|
431
487
|
(typeof node.value === 'string' || typeof node.value === 'number')
|
|
@@ -536,37 +592,52 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
536
592
|
registerAlias({ declaration, statement, variable })
|
|
537
593
|
|
|
538
594
|
const expression = variable.init
|
|
539
|
-
if (
|
|
540
|
-
expression?.type !== 'CallExpression' ||
|
|
541
|
-
expression.callee.type !== 'MemberExpression' ||
|
|
542
|
-
expression.callee.object.type !== 'Identifier' ||
|
|
543
|
-
(!namespaces.has(expression.callee.object.name) &&
|
|
544
|
-
!configNamespaces.has(expression.callee.object.name))
|
|
545
|
-
)
|
|
546
|
-
continue
|
|
595
|
+
if (expression?.type !== 'CallExpression' || expression.optional) continue
|
|
547
596
|
|
|
548
597
|
const member = expression.callee
|
|
598
|
+
const directFactory =
|
|
599
|
+
member.type === 'Identifier'
|
|
600
|
+
? factoryFunctions.get(member.name)
|
|
601
|
+
: undefined
|
|
549
602
|
if (
|
|
550
|
-
|
|
551
|
-
member.
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
603
|
+
!directFactory &&
|
|
604
|
+
(member.type !== 'MemberExpression' ||
|
|
605
|
+
member.object.type !== 'Identifier' ||
|
|
606
|
+
(!namespaces.has(member.object.name) &&
|
|
607
|
+
!configNamespaces.has(member.object.name)) ||
|
|
608
|
+
member.computed ||
|
|
609
|
+
member.optional ||
|
|
610
|
+
member.property.type !== 'Identifier' ||
|
|
611
|
+
!(
|
|
612
|
+
configNamespaces.has(member.object.name)
|
|
613
|
+
? ['create']
|
|
614
|
+
: ['define', 'extend']
|
|
615
|
+
).includes(member.property.name))
|
|
559
616
|
)
|
|
560
617
|
continue
|
|
561
618
|
|
|
619
|
+
const config =
|
|
620
|
+
directFactory === 'create' ||
|
|
621
|
+
(member.type === 'MemberExpression' &&
|
|
622
|
+
member.object.type === 'Identifier' &&
|
|
623
|
+
configNamespaces.has(member.object.name))
|
|
624
|
+
const method =
|
|
625
|
+
member.type === 'MemberExpression' &&
|
|
626
|
+
member.property.type === 'Identifier'
|
|
627
|
+
? member.property.name
|
|
628
|
+
: directFactory
|
|
629
|
+
const variableSet =
|
|
630
|
+
directFactory === 'define' ||
|
|
631
|
+
directFactory === 'extend' ||
|
|
632
|
+
(member.type === 'MemberExpression' &&
|
|
633
|
+
member.object.type === 'Identifier' &&
|
|
634
|
+
variableNamespaces.has(member.object.name))
|
|
635
|
+
|
|
562
636
|
if (
|
|
563
637
|
(statement.type === 'ExportNamedDeclaration' && !options.linked) ||
|
|
564
638
|
declaration.kind !== 'const' ||
|
|
565
639
|
(variable.id.type !== 'Identifier' &&
|
|
566
|
-
!(
|
|
567
|
-
configNamespaces.has(expression.callee.object.name) &&
|
|
568
|
-
variable.id.type === 'ObjectPattern'
|
|
569
|
-
))
|
|
640
|
+
!(config && variable.id.type === 'ObjectPattern'))
|
|
570
641
|
)
|
|
571
642
|
fail(
|
|
572
643
|
'Define local themes with a module-level const; exported themes require source linking.',
|
|
@@ -601,10 +672,7 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
601
672
|
fail('Configuration destructuring requires a binding.', variable)
|
|
602
673
|
|
|
603
674
|
let name = `${options.namespace}-${binding}`
|
|
604
|
-
if (
|
|
605
|
-
!configNamespaces.has(expression.callee.object.name) &&
|
|
606
|
-
member.property.name === 'define'
|
|
607
|
-
) {
|
|
675
|
+
if (!config && method === 'define') {
|
|
608
676
|
const argument = expression.arguments[1]
|
|
609
677
|
const callback = argument && Expression.unwrap(argument)
|
|
610
678
|
const id = Identifiers.explicit(
|
|
@@ -617,7 +685,7 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
617
685
|
if (id !== undefined) name = Identity.requireId(id, 'Vars.define')
|
|
618
686
|
}
|
|
619
687
|
|
|
620
|
-
if (
|
|
688
|
+
if (config) {
|
|
621
689
|
try {
|
|
622
690
|
const link = Configurations.collect({
|
|
623
691
|
data,
|
|
@@ -772,7 +840,7 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
772
840
|
let output: Call['output']
|
|
773
841
|
|
|
774
842
|
try {
|
|
775
|
-
if (
|
|
843
|
+
if (method === 'define') {
|
|
776
844
|
if (
|
|
777
845
|
expression.arguments.length < 1 ||
|
|
778
846
|
expression.arguments.length > 3
|
|
@@ -786,9 +854,6 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
786
854
|
|
|
787
855
|
tokenType = type(expression.arguments[0]!)
|
|
788
856
|
|
|
789
|
-
const variableSet = variableNamespaces.has(
|
|
790
|
-
expression.callee.object.name,
|
|
791
|
-
)
|
|
792
857
|
const argument = expression.arguments[1]
|
|
793
858
|
const callback = argument && Expression.unwrap(argument)
|
|
794
859
|
if (
|
|
@@ -860,7 +925,7 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
860
925
|
)
|
|
861
926
|
|
|
862
927
|
factoryReferences.add(base!.start)
|
|
863
|
-
definition =
|
|
928
|
+
definition = variableSet
|
|
864
929
|
? VariableSets.theme(
|
|
865
930
|
Vars.extend(
|
|
866
931
|
VariableSets.from(themes[parent.name]![Token.definition]),
|
|
@@ -876,7 +941,7 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
876
941
|
'id-',
|
|
877
942
|
)
|
|
878
943
|
)
|
|
879
|
-
name = definition.className.slice('
|
|
944
|
+
name = definition.className.slice('z-theme-'.length)
|
|
880
945
|
tokenType = parent.tokenType
|
|
881
946
|
output = parent.output
|
|
882
947
|
}
|
|
@@ -892,7 +957,7 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
892
957
|
}
|
|
893
958
|
|
|
894
959
|
const call = Object.freeze({
|
|
895
|
-
...(
|
|
960
|
+
...(variableSet
|
|
896
961
|
? {
|
|
897
962
|
variableSet: true,
|
|
898
963
|
directVariables: true,
|
|
@@ -912,6 +977,11 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
912
977
|
: {}),
|
|
913
978
|
})
|
|
914
979
|
|
|
980
|
+
definition = Token.bind(
|
|
981
|
+
definition,
|
|
982
|
+
definition[Token.definition].contract,
|
|
983
|
+
binding,
|
|
984
|
+
)
|
|
915
985
|
calls.push(call)
|
|
916
986
|
definitions.set(variable.id.start, call)
|
|
917
987
|
factories.add(expression.start)
|
|
@@ -1286,12 +1356,22 @@ export function collect(program: Ast.Program, options: collect.Options) {
|
|
|
1286
1356
|
|
|
1287
1357
|
if (
|
|
1288
1358
|
binding?.type === 'Import' &&
|
|
1289
|
-
(imports.has(binding.node.start) ||
|
|
1359
|
+
(imports.has(binding.node.start) ||
|
|
1360
|
+
configImports.has(binding.node.start) ||
|
|
1361
|
+
factoryImports.has(binding.node.start))
|
|
1290
1362
|
) {
|
|
1363
|
+
if (
|
|
1364
|
+
factoryImports.has(binding.node.start) &&
|
|
1365
|
+
parent.type === 'CallExpression' &&
|
|
1366
|
+
factories.has(parent.start)
|
|
1367
|
+
)
|
|
1368
|
+
return true
|
|
1369
|
+
|
|
1291
1370
|
if (
|
|
1292
1371
|
parent.type === 'MemberExpression' &&
|
|
1293
1372
|
grandparent?.type === 'CallExpression' &&
|
|
1294
|
-
factories.has(grandparent.start)
|
|
1373
|
+
(factories.has(grandparent.start) ||
|
|
1374
|
+
factoryReferences.has(parent.start))
|
|
1295
1375
|
)
|
|
1296
1376
|
return true
|
|
1297
1377
|
|
|
@@ -6,6 +6,7 @@ import * as Theme from '../../internal/Theme.js'
|
|
|
6
6
|
import type * as Css from '../../web/Css.js'
|
|
7
7
|
import * as Identity from '../../internal/Identity.js'
|
|
8
8
|
import * as Expression from './Expression.js'
|
|
9
|
+
import * as Names from './Names.js'
|
|
9
10
|
import type * as Scope from './Scope.js'
|
|
10
11
|
import type * as Themes from './Themes.js'
|
|
11
12
|
import { InvalidError } from './Themes.js'
|
|
@@ -14,6 +15,8 @@ import { InvalidError } from './Themes.js'
|
|
|
14
15
|
export type Call = {
|
|
15
16
|
/** Exclusive source offset. */
|
|
16
17
|
readonly end: number
|
|
18
|
+
/** Whether the consumer supplied a portable variable identity. */
|
|
19
|
+
readonly explicit?: boolean | undefined
|
|
17
20
|
/** Fixed scalar reference retained in portable metadata. */
|
|
18
21
|
readonly slots: Readonly<Record<string, Binding.Reference>>
|
|
19
22
|
/** Inclusive source offset. */
|
|
@@ -28,6 +31,7 @@ export function collect(
|
|
|
28
31
|
links: Readonly<Record<string, Themes.Link>> = {},
|
|
29
32
|
moduleId = namespace,
|
|
30
33
|
) {
|
|
34
|
+
const authoredNames = Names.collect(program)
|
|
31
35
|
const imports = new Set<number>()
|
|
32
36
|
const external = new Map<number, Themes.Link>()
|
|
33
37
|
for (const statement of program.body) {
|
|
@@ -187,6 +191,7 @@ export function collect(
|
|
|
187
191
|
})
|
|
188
192
|
|
|
189
193
|
const calls: Call[] = []
|
|
194
|
+
const explicit = new Set<number>()
|
|
190
195
|
const definitions = new Map<number, Themes.Link>()
|
|
191
196
|
const registrations: Css.Contribution[] = []
|
|
192
197
|
const registrationStarts: number[] = []
|
|
@@ -275,8 +280,10 @@ export function collect(
|
|
|
275
280
|
descriptor[key] = literal as string | number | boolean
|
|
276
281
|
}
|
|
277
282
|
|
|
283
|
+
if (descriptor.id !== undefined) explicit.add(call.start)
|
|
284
|
+
|
|
278
285
|
const name =
|
|
279
|
-
`--z
|
|
286
|
+
`--z-${descriptor.id === undefined ? authoredNames.get(call.start)! : Identity.requireId(typeof descriptor.id === 'string' ? descriptor.id : undefined, 'variable').slice(3)}` as const
|
|
280
287
|
if (value && Object.keys(descriptor).some((key) => key !== 'id')) {
|
|
281
288
|
const syntax =
|
|
282
289
|
kind === 'signedLength'
|
|
@@ -325,6 +332,7 @@ export function collect(
|
|
|
325
332
|
variable: true as const,
|
|
326
333
|
})
|
|
327
334
|
const entry = Object.freeze({
|
|
335
|
+
explicit: explicit.has(call.start),
|
|
328
336
|
start: call.start,
|
|
329
337
|
end: call.end,
|
|
330
338
|
slots: Object.freeze({ value: slot }),
|
package/src/default.ts
CHANGED
|
@@ -41,11 +41,10 @@ void [spin, ping, pulse, bounce]
|
|
|
41
41
|
*/
|
|
42
42
|
export const tokens = {
|
|
43
43
|
animate: {
|
|
44
|
-
spin: 'z-kid-
|
|
45
|
-
ping: 'z-kid-
|
|
46
|
-
pulse:
|
|
47
|
-
|
|
48
|
-
bounce: 'z-kid-7a-79-7a-7a-2d-62-6f-75-6e-63-65 1s infinite',
|
|
44
|
+
spin: 'z-kid-zyzz_2d_spin 1s linear infinite',
|
|
45
|
+
ping: 'z-kid-zyzz_2d_ping 1s cubic-bezier(0, 0, 0.2, 1) infinite',
|
|
46
|
+
pulse: 'z-kid-zyzz_2d_pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
|
|
47
|
+
bounce: 'z-kid-zyzz_2d_bounce 1s infinite',
|
|
49
48
|
},
|
|
50
49
|
aspect: {
|
|
51
50
|
video: '16 / 9',
|
|
@@ -80,8 +79,8 @@ export const tokens = {
|
|
|
80
79
|
1000: { dark: '#fef3dc', light: '#4e2009' },
|
|
81
80
|
},
|
|
82
81
|
background: {
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
primary: { dark: '#000', light: '#fafafa' },
|
|
83
|
+
surface: { dark: '#0a0a0a', light: '#fff' },
|
|
85
84
|
},
|
|
86
85
|
black: '#000',
|
|
87
86
|
blue: {
|
|
@@ -169,7 +168,6 @@ export const tokens = {
|
|
|
169
168
|
900: { dark: '#ff6166', light: '#cb2a2f' },
|
|
170
169
|
1000: { dark: '#feecee', light: '#391417' },
|
|
171
170
|
},
|
|
172
|
-
surface: { dark: '#0a0a0a', light: '#fff' },
|
|
173
171
|
teal: {
|
|
174
172
|
100: { dark: '#04201b', light: '#eefcf9' },
|
|
175
173
|
200: { dark: '#062822', light: '#e5faf6' },
|
|
@@ -428,14 +426,14 @@ export const tokens = {
|
|
|
428
426
|
fontSize: '20px',
|
|
429
427
|
fontWeight: 400,
|
|
430
428
|
letterSpacing: '0px',
|
|
431
|
-
lineHeight: '
|
|
429
|
+
lineHeight: '28px',
|
|
432
430
|
strong: {
|
|
433
431
|
fontFamily:
|
|
434
432
|
'Geist, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
|
|
435
433
|
fontSize: '20px',
|
|
436
434
|
fontWeight: 550,
|
|
437
435
|
letterSpacing: '0px',
|
|
438
|
-
lineHeight: '
|
|
436
|
+
lineHeight: '28px',
|
|
439
437
|
},
|
|
440
438
|
},
|
|
441
439
|
'24': {
|
|
@@ -681,13 +679,13 @@ export const tokens = {
|
|
|
681
679
|
/** Default appearance, restoration script, and authoring helpers with bundled light/dark tokens. */
|
|
682
680
|
// Generated from tokens by scripts/default-theme.ts; edit tokens and regenerate.
|
|
683
681
|
const config = Config.create({
|
|
682
|
+
id: 'default',
|
|
684
683
|
vars: {
|
|
685
684
|
animate: {
|
|
686
|
-
spin: 'z-kid-
|
|
687
|
-
ping: 'z-kid-
|
|
688
|
-
pulse:
|
|
689
|
-
|
|
690
|
-
bounce: 'z-kid-7a-79-7a-7a-2d-62-6f-75-6e-63-65 1s infinite',
|
|
685
|
+
spin: 'z-kid-zyzz_2d_spin 1s linear infinite',
|
|
686
|
+
ping: 'z-kid-zyzz_2d_ping 1s cubic-bezier(0, 0, 0.2, 1) infinite',
|
|
687
|
+
pulse: 'z-kid-zyzz_2d_pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
|
|
688
|
+
bounce: 'z-kid-zyzz_2d_bounce 1s infinite',
|
|
691
689
|
},
|
|
692
690
|
aspect: {
|
|
693
691
|
video: '16 / 9',
|
|
@@ -722,8 +720,8 @@ const config = Config.create({
|
|
|
722
720
|
1000: { dark: '#fef3dc', light: '#4e2009' },
|
|
723
721
|
},
|
|
724
722
|
background: {
|
|
725
|
-
|
|
726
|
-
|
|
723
|
+
primary: { dark: '#000', light: '#fafafa' },
|
|
724
|
+
surface: { dark: '#0a0a0a', light: '#fff' },
|
|
727
725
|
},
|
|
728
726
|
black: '#000',
|
|
729
727
|
blue: {
|
|
@@ -811,7 +809,6 @@ const config = Config.create({
|
|
|
811
809
|
900: { dark: '#ff6166', light: '#cb2a2f' },
|
|
812
810
|
1000: { dark: '#feecee', light: '#391417' },
|
|
813
811
|
},
|
|
814
|
-
surface: { dark: '#0a0a0a', light: '#fff' },
|
|
815
812
|
teal: {
|
|
816
813
|
100: { dark: '#04201b', light: '#eefcf9' },
|
|
817
814
|
200: { dark: '#062822', light: '#e5faf6' },
|
|
@@ -1070,14 +1067,14 @@ const config = Config.create({
|
|
|
1070
1067
|
fontSize: '20px',
|
|
1071
1068
|
fontWeight: 400,
|
|
1072
1069
|
letterSpacing: '0px',
|
|
1073
|
-
lineHeight: '
|
|
1070
|
+
lineHeight: '28px',
|
|
1074
1071
|
strong: {
|
|
1075
1072
|
fontFamily:
|
|
1076
1073
|
'Geist, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"',
|
|
1077
1074
|
fontSize: '20px',
|
|
1078
1075
|
fontWeight: 550,
|
|
1079
1076
|
letterSpacing: '0px',
|
|
1080
|
-
lineHeight: '
|
|
1077
|
+
lineHeight: '28px',
|
|
1081
1078
|
},
|
|
1082
1079
|
},
|
|
1083
1080
|
'24': {
|
package/src/index.ts
CHANGED
|
@@ -8,6 +8,21 @@ export * as Config from './Config.js'
|
|
|
8
8
|
export { style } from './styleFunction.js'
|
|
9
9
|
/** Ordered composition of applied styling props. */
|
|
10
10
|
export { cx } from './cx.js'
|
|
11
|
+
/**
|
|
12
|
+
* Creates isolated authoring with optional vars and named alternatives.
|
|
13
|
+
* @alias Config.create
|
|
14
|
+
*/
|
|
15
|
+
export { create as defineConfig } from './Config.js'
|
|
16
|
+
/**
|
|
17
|
+
* Creates immutable typed variable sets without emitting CSS.
|
|
18
|
+
* @alias Vars.define
|
|
19
|
+
*/
|
|
20
|
+
export { define as defineVars } from './Vars.js'
|
|
21
|
+
/**
|
|
22
|
+
* Overrides variable values while preserving their shared contract.
|
|
23
|
+
* @alias Vars.extend
|
|
24
|
+
*/
|
|
25
|
+
export { extend as extendVars } from './Vars.js'
|
|
11
26
|
/** Inferred component inputs from callable style definitions. */
|
|
12
27
|
export type * as Props from './Props.js'
|
|
13
28
|
/** Typed literal style definitions and validation diagnostics. */
|
|
@@ -3,6 +3,7 @@ import type { style } from '../styleFunction.js'
|
|
|
3
3
|
import * as Html from '../runtime/CompositionHtml.js'
|
|
4
4
|
import * as Identity from './Identity.js'
|
|
5
5
|
import * as Props from '../runtime/Props.js'
|
|
6
|
+
import * as Token from './Token.js'
|
|
6
7
|
import * as Style from '../Style.js'
|
|
7
8
|
import type * as Theme from './Theme.js'
|
|
8
9
|
|
|
@@ -66,10 +67,12 @@ export function create(
|
|
|
66
67
|
options: Options = {},
|
|
67
68
|
): style.ReturnType {
|
|
68
69
|
const dynamic = typeof input === 'function'
|
|
70
|
+
const identity = options.theme?.[Token.definition].contract[Token.identity]
|
|
71
|
+
const namespace = identity?.startsWith('id-') ? identity.slice(3) : undefined
|
|
69
72
|
const id =
|
|
70
73
|
options.id === undefined
|
|
71
74
|
? undefined
|
|
72
|
-
: Identity.requireId(options.id, 'style')
|
|
75
|
+
: `id-${namespace ? `${namespace}-` : ''}${Identity.requireId(options.id, 'style').slice(3)}`
|
|
73
76
|
if (dynamic && !id) Identity.requireId(undefined, 'Dynamic style')
|
|
74
77
|
if (!dynamic && !id && Object.keys(input as object).length === 0)
|
|
75
78
|
Identity.requireId(undefined, 'Empty style')
|
|
@@ -90,6 +93,7 @@ export function create(
|
|
|
90
93
|
{ style: body(input as Record<string, unknown>) },
|
|
91
94
|
{ vars: options.theme },
|
|
92
95
|
).styles[0]!,
|
|
96
|
+
namespace,
|
|
93
97
|
)
|
|
94
98
|
const props = Props.create({ className })
|
|
95
99
|
const apply = (values?: style.Options & Record<string, unknown>) => {
|
|
@@ -128,7 +132,9 @@ export function variants(
|
|
|
128
132
|
input: Record<string, unknown>,
|
|
129
133
|
options: Options = {},
|
|
130
134
|
): unknown {
|
|
131
|
-
const
|
|
135
|
+
const identity = options.theme?.[Token.definition].contract[Token.identity]
|
|
136
|
+
const namespace = identity?.startsWith('id-') ? identity.slice(3) : undefined
|
|
137
|
+
const id = `id-${namespace ? `${namespace}-` : ''}${Identity.requireId(options.id, 'variants').slice(3)}`
|
|
132
138
|
if (options.theme) {
|
|
133
139
|
const styles = [
|
|
134
140
|
input.base,
|
|
@@ -157,7 +163,7 @@ export function variants(
|
|
|
157
163
|
return (values: Record<string, unknown> & style.Options = {}) => {
|
|
158
164
|
const result = { ...props(values as style.Options) } as {
|
|
159
165
|
className: string
|
|
160
|
-
style?: style.Props['style']
|
|
166
|
+
style?: NonNullable<style.Props['style']>
|
|
161
167
|
[key: `data-${string}`]: string | undefined
|
|
162
168
|
}
|
|
163
169
|
const bindings: Record<string, string | number> = {}
|
package/src/internal/Binding.ts
CHANGED
|
@@ -15,10 +15,15 @@ export type Kind =
|
|
|
15
15
|
| 'signedLength'
|
|
16
16
|
| 'signedPercentage'
|
|
17
17
|
|
|
18
|
+
/** Marks callback inputs that require an explicit custom token escape. */
|
|
19
|
+
export const dynamic = Symbol('zyzz.binding.dynamic')
|
|
20
|
+
|
|
18
21
|
/** A compiler-assigned web custom property with its scalar domain. */
|
|
19
22
|
export type Reference<kind extends Domain = Domain> = {
|
|
20
23
|
/** Fixed CSS custom-property name. */
|
|
21
24
|
readonly name: `--${string}`
|
|
25
|
+
/** Internal callback provenance, independent of the emitted variable name. */
|
|
26
|
+
readonly [dynamic]?: true | undefined
|
|
22
27
|
/** Scalar domain used by authoring types and runtime primitive checks. */
|
|
23
28
|
readonly type: kind
|
|
24
29
|
/** Distinguishes slots from theme references. */
|
|
@@ -163,6 +163,9 @@ export function create(
|
|
|
163
163
|
)
|
|
164
164
|
throw new InvalidError(`Unknown configuration option: ${key}`)
|
|
165
165
|
|
|
166
|
+
if (input.id !== undefined && (typeof input.id !== 'string' || !input.id))
|
|
167
|
+
throw new InvalidError('id must be a nonempty string.')
|
|
168
|
+
|
|
166
169
|
if (
|
|
167
170
|
input.storageKey !== undefined &&
|
|
168
171
|
(typeof input.storageKey !== 'string' || !input.storageKey)
|
|
@@ -291,7 +294,7 @@ export function create(
|
|
|
291
294
|
function handle(theme: Theme.Definition, name: string) {
|
|
292
295
|
const original = Token.bind(theme, contract)
|
|
293
296
|
const className = () =>
|
|
294
|
-
`
|
|
297
|
+
`z-theme-${Identity.requireId(typeof input.id === 'string' ? input.id : undefined, 'Config.create').slice(3)}-${Identity.name(name)}`
|
|
295
298
|
const select = (options: { colorScheme?: string } = {}) => {
|
|
296
299
|
const scheme = options.colorScheme
|
|
297
300
|
const selection =
|
|
@@ -433,7 +436,7 @@ export function create(
|
|
|
433
436
|
}
|
|
434
437
|
|
|
435
438
|
const theme =
|
|
436
|
-
shorthands || input.defaultLayer !== undefined
|
|
439
|
+
shorthands || input.defaultLayer !== undefined || input.id !== undefined
|
|
437
440
|
? Token.bind(Theme.define({}), contract)
|
|
438
441
|
: undefined
|
|
439
442
|
return finish({
|
|
@@ -452,7 +455,7 @@ export declare namespace create {
|
|
|
452
455
|
readonly cssOutput?: 'atomic' | 'grouped' | undefined
|
|
453
456
|
/** Fallback CSS layer for bound styles and variants; unlayered when omitted. */
|
|
454
457
|
readonly defaultLayer?: string | undefined
|
|
455
|
-
/**
|
|
458
|
+
/** Consumer-owned namespace; required for uncompiled variable configs. */
|
|
456
459
|
readonly id?: string | undefined
|
|
457
460
|
/** Explicit ordered property aliases; none are installed by default. */
|
|
458
461
|
readonly shorthands?: Shorthands.Map | undefined
|
|
@@ -839,7 +842,7 @@ export type VariableOptions = {
|
|
|
839
842
|
readonly defaultLayer?: string | undefined
|
|
840
843
|
/** Required default key when vars contains named sets. */
|
|
841
844
|
readonly defaultVars?: string | undefined
|
|
842
|
-
/**
|
|
845
|
+
/** Consumer-owned namespace; required for uncompiled variable configs. */
|
|
843
846
|
readonly id?: string | undefined
|
|
844
847
|
/** Ordered CSS layer names. */
|
|
845
848
|
readonly layers?: readonly string[] | undefined
|
package/src/internal/Identity.ts
CHANGED
|
@@ -25,13 +25,6 @@ export function compact(value: string): string {
|
|
|
25
25
|
return result
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
/** Encodes an explicit identity without losing punctuation or Unicode distinctions. */
|
|
29
|
-
export function encode(value: string): string {
|
|
30
|
-
return Array.from(value, (character) =>
|
|
31
|
-
character.codePointAt(0)!.toString(16),
|
|
32
|
-
).join('-')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
28
|
/** Keeps an authored label readable while its separate hash disambiguates spelling. */
|
|
36
29
|
export function label(value: string): string {
|
|
37
30
|
return (
|
|
@@ -42,18 +35,27 @@ export function label(value: string): string {
|
|
|
42
35
|
)
|
|
43
36
|
}
|
|
44
37
|
|
|
38
|
+
/** Encodes one name segment, reserving hyphens for path boundaries. */
|
|
39
|
+
export function name(value: string): string {
|
|
40
|
+
return Array.from(value, (character) =>
|
|
41
|
+
/^[a-zA-Z0-9]$/.test(character)
|
|
42
|
+
? character
|
|
43
|
+
: `_${character.codePointAt(0)!.toString(16)}_`,
|
|
44
|
+
).join('')
|
|
45
|
+
}
|
|
46
|
+
|
|
45
47
|
/** Requires an explicit identity at an uncompiled authoring boundary. */
|
|
46
48
|
export function requireId(id: string | undefined, kind: string): string {
|
|
47
49
|
if (!id)
|
|
48
50
|
throw new Error(
|
|
49
51
|
`${kind} requires an explicit id without the compiler plugin.`,
|
|
50
52
|
)
|
|
51
|
-
return `id-${
|
|
53
|
+
return `id-${name(id)}`
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
/** Names one callback input independently of its declaration order. */
|
|
55
57
|
export function slot(id: string, field: string): `--${string}` {
|
|
56
|
-
return `--z
|
|
58
|
+
return `--z-${id.startsWith('id-') ? id.slice(3) : id}-${name(field)}`
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
/** Hashes a canonical value using two independent 32-bit accumulators. */
|
|
@@ -69,7 +71,7 @@ export function hash(value: string): string {
|
|
|
69
71
|
}
|
|
70
72
|
|
|
71
73
|
/** Names ordered style data consistently in runtime and extraction. */
|
|
72
|
-
export function style(input: Style.NamedStyle): string {
|
|
74
|
+
export function style(input: Style.NamedStyle, namespace?: string): string {
|
|
73
75
|
function value(input: Style.Declaration['value']): unknown {
|
|
74
76
|
if (Binding.is(input)) return ['variable', input.name]
|
|
75
77
|
if (Token.is(input))
|
|
@@ -105,12 +107,12 @@ export function style(input: Style.NamedStyle): string {
|
|
|
105
107
|
!!declaration.important,
|
|
106
108
|
])
|
|
107
109
|
}
|
|
108
|
-
return `z
|
|
110
|
+
return `z-${namespace ? `${namespace}-` : ''}content-${name(JSON.stringify(shape(input)))}`
|
|
109
111
|
}
|
|
110
112
|
|
|
111
113
|
/** Names a complete ordered composition, including repeated definitions. */
|
|
112
114
|
export function composition(names: readonly string[]): string {
|
|
113
|
-
return `z-compose-${
|
|
115
|
+
return `z-compose-${name(JSON.stringify(names))}`
|
|
114
116
|
}
|
|
115
117
|
|
|
116
118
|
/** Names a stylesheet declaration with a caller-owned identity. */
|
package/src/internal/Theme.ts
CHANGED
|
@@ -599,10 +599,10 @@ function build(
|
|
|
599
599
|
Object.defineProperty(
|
|
600
600
|
{
|
|
601
601
|
get className(): string {
|
|
602
|
-
if (scope) return `
|
|
602
|
+
if (scope) return `z-theme-${scope}`
|
|
603
603
|
const id = contract[Token.identity]
|
|
604
604
|
if (!id?.startsWith('id-')) throw new MissingTransformError()
|
|
605
|
-
return `
|
|
605
|
+
return `z-theme-${id.slice(3)}`
|
|
606
606
|
},
|
|
607
607
|
style: (styles?: unknown, options: style.DefinitionOptions = {}) => {
|
|
608
608
|
if (!contract[Token.identity])
|