zyzz 0.0.5 → 0.0.7

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.
Files changed (91) hide show
  1. package/README.md +26 -1
  2. package/dist/Style.d.ts +3 -3
  3. package/dist/Style.d.ts.map +1 -1
  4. package/dist/Style.js +12 -1
  5. package/dist/Style.js.map +1 -1
  6. package/dist/babel/index.d.ts +2 -0
  7. package/dist/babel/index.d.ts.map +1 -1
  8. package/dist/babel/index.js +10 -1
  9. package/dist/babel/index.js.map +1 -1
  10. package/dist/compiler/Graph.d.ts +2 -0
  11. package/dist/compiler/Graph.d.ts.map +1 -1
  12. package/dist/compiler/Graph.js +19 -1
  13. package/dist/compiler/Graph.js.map +1 -1
  14. package/dist/compiler/Source.d.ts.map +1 -1
  15. package/dist/compiler/Source.js +5 -2
  16. package/dist/compiler/Source.js.map +1 -1
  17. package/dist/compiler/internal/Contributions.d.ts +1 -1
  18. package/dist/compiler/internal/Contributions.d.ts.map +1 -1
  19. package/dist/compiler/internal/Contributions.js +5 -3
  20. package/dist/compiler/internal/Contributions.js.map +1 -1
  21. package/dist/compiler/internal/Static.d.ts.map +1 -1
  22. package/dist/compiler/internal/Static.js +2 -0
  23. package/dist/compiler/internal/Static.js.map +1 -1
  24. package/dist/internal/Authoring.d.ts.map +1 -1
  25. package/dist/internal/Authoring.js +14 -0
  26. package/dist/internal/Authoring.js.map +1 -1
  27. package/dist/internal/Binding.d.ts +7 -0
  28. package/dist/internal/Binding.d.ts.map +1 -1
  29. package/dist/internal/Binding.js.map +1 -1
  30. package/dist/internal/Configuration.d.ts +1 -1
  31. package/dist/internal/Configuration.d.ts.map +1 -1
  32. package/dist/internal/Configuration.js +7 -6
  33. package/dist/internal/Configuration.js.map +1 -1
  34. package/dist/internal/Theme.d.ts +1 -1
  35. package/dist/internal/Theme.d.ts.map +1 -1
  36. package/dist/internal/Theme.js.map +1 -1
  37. package/dist/internal/Token.d.ts +3 -1
  38. package/dist/internal/Token.d.ts.map +1 -1
  39. package/dist/internal/Token.js +28 -3
  40. package/dist/internal/Token.js.map +1 -1
  41. package/dist/internal/Value.d.ts +22 -0
  42. package/dist/internal/Value.d.ts.map +1 -1
  43. package/dist/internal/Value.js +76 -9
  44. package/dist/internal/Value.js.map +1 -1
  45. package/dist/next/index.d.ts +8 -3
  46. package/dist/next/index.d.ts.map +1 -1
  47. package/dist/next/index.js +21 -10
  48. package/dist/next/index.js.map +1 -1
  49. package/dist/next/internal/Project.d.ts +28 -0
  50. package/dist/next/internal/Project.d.ts.map +1 -0
  51. package/dist/next/internal/Project.js +249 -0
  52. package/dist/next/internal/Project.js.map +1 -0
  53. package/dist/next/loader.d.ts +3 -5
  54. package/dist/next/loader.d.ts.map +1 -1
  55. package/dist/next/loader.js +14 -144
  56. package/dist/next/loader.js.map +1 -1
  57. package/dist/node/Reset.d.ts +3 -0
  58. package/dist/node/Reset.d.ts.map +1 -0
  59. package/dist/node/Reset.js +7 -0
  60. package/dist/node/Reset.js.map +1 -0
  61. package/dist/unplugin/index.d.ts +2 -0
  62. package/dist/unplugin/index.d.ts.map +1 -1
  63. package/dist/unplugin/index.js +2 -0
  64. package/dist/unplugin/index.js.map +1 -1
  65. package/dist/variants.d.ts +1 -1
  66. package/dist/variants.d.ts.map +1 -1
  67. package/dist/variants.js.map +1 -1
  68. package/dist/vite/index.d.ts +2 -0
  69. package/dist/vite/index.d.ts.map +1 -1
  70. package/dist/vite/index.js +38 -9
  71. package/dist/vite/index.js.map +1 -1
  72. package/package.json +1 -1
  73. package/src/Style.ts +42 -8
  74. package/src/babel/index.ts +23 -1
  75. package/src/compiler/Graph.ts +22 -0
  76. package/src/compiler/Source.ts +5 -1
  77. package/src/compiler/internal/Contributions.ts +5 -2
  78. package/src/compiler/internal/Static.ts +1 -0
  79. package/src/internal/Authoring.ts +21 -0
  80. package/src/internal/Binding.ts +30 -0
  81. package/src/internal/Configuration.ts +19 -13
  82. package/src/internal/Theme.ts +5 -1
  83. package/src/internal/Token.ts +34 -3
  84. package/src/internal/Value.ts +180 -10
  85. package/src/next/index.ts +34 -12
  86. package/src/next/internal/Project.ts +337 -0
  87. package/src/next/loader.ts +28 -190
  88. package/src/node/Reset.ts +7 -0
  89. package/src/unplugin/index.ts +4 -0
  90. package/src/variants.ts +1 -0
  91. package/src/vite/index.ts +43 -14
package/src/Style.ts CHANGED
@@ -68,13 +68,20 @@ export type Accepted<
68
68
  ? never
69
69
  : Value.Atom<Typography.Names<tokens>>
70
70
  : key extends keyof Literal.Properties
71
- ? Value.Accepted<
72
- Pick<style, key>,
73
- literal extends true
71
+ ? (literal extends true
72
+ ? LiteralDeclarations
73
+ : keyof tokens extends never
74
74
  ? LiteralDeclarations
75
- : DeclarationProperties<tokens>
76
- >[key] &
77
- Value.Checked<Pick<style, key>, tokens>[key]
75
+ : DeclarationProperties<tokens>)[key] extends style[key]
76
+ ? style[key]
77
+ : Value.Accepted<
78
+ Pick<style, key>,
79
+ literal extends true
80
+ ? LiteralDeclarations
81
+ : DeclarationProperties<tokens>
82
+ >[key] &
83
+ Value.Checked<Pick<style, key>, tokens>[key] &
84
+ Value.Tokens<style[key], tokens, key>
78
85
  : key extends Condition.Keys<tokens, key>
79
86
  ? [style[key]] extends [undefined]
80
87
  ? never
@@ -605,10 +612,11 @@ export function define(
605
612
  )
606
613
  continue
607
614
  }
615
+ const custom = parsed?.custom
608
616
  const scalar = parsed ? parsed.value : entry
609
617
 
610
618
  const resolved = (() => {
611
- if (!theme) return scalar
619
+ if (!theme || custom) return scalar
612
620
 
613
621
  if (typeof scalar !== 'string' && typeof scalar !== 'number')
614
622
  return scalar
@@ -645,6 +653,25 @@ export function define(
645
653
  continue
646
654
  }
647
655
 
656
+ if (
657
+ theme &&
658
+ !custom &&
659
+ Token.mapped(theme, key) &&
660
+ !Token.is(resolved) &&
661
+ !(Binding.is(resolved) && !resolved.name.startsWith('--z-d')) &&
662
+ !(
663
+ Token.isExpression(resolved) &&
664
+ resolved.parts.every((part) => Token.is(part) || part === '')
665
+ )
666
+ ) {
667
+ report(
668
+ 'invalid_value',
669
+ [name, authoredProperty],
670
+ 'Expected a configured token or a bracketed CSS value.',
671
+ )
672
+ continue
673
+ }
674
+
648
675
  const value = parsed && resolved === '0' ? 0 : resolved
649
676
 
650
677
  declarations.push(
@@ -774,6 +801,7 @@ export class InvalidError extends Error {
774
801
  type LiteralAtoms = {
775
802
  readonly [property in keyof Literal.Properties]-?: Value.Atom<
776
803
  | Exclude<Literal.Properties[property], undefined>
804
+ | `[${string}]`
777
805
  | Binding.Reference<'*'>
778
806
  | {
779
807
  [kind in Binding.Kind]: property extends Binding.Property<
@@ -812,7 +840,13 @@ export type NamedStyle<name extends string = string> = {
812
840
  /** Supported literal and token declarations. Unknown properties and undefined values are rejected. */
813
841
  export type DeclarationProperties<tokens extends Theme.Tokens = {}> = {
814
842
  readonly [property in keyof Literal.Properties]: Value.Fallbacks<
815
- | LiteralAtoms[property]
843
+ | (property extends `--${string}`
844
+ ? LiteralAtoms[property]
845
+ : [Token.Names<tokens, property>] extends [never]
846
+ ? LiteralAtoms[property]
847
+ :
848
+ | Value.Atom<`[${string}]`>
849
+ | Extract<LiteralAtoms[property], Binding.Reference>)
816
850
  | Value.Atom<Token.Names<tokens, property>>
817
851
  | {
818
852
  [group in Token.Group]: property extends Token.Properties<group>
@@ -36,6 +36,8 @@ export type WebOptions = {
36
36
  readonly cssOutput?: Transform.compile.Options['cssOutput']
37
37
  /** Portable identity. Defaults to the filename relative to Babel's root. */
38
38
  readonly moduleId?: string | undefined
39
+ /** Import the CSS reset once per transformed module. Defaults to false. */
40
+ readonly reset?: boolean | undefined
39
41
  /** Selects rewritten JavaScript and extracted CSS. */
40
42
  readonly target: 'web'
41
43
  }
@@ -326,7 +328,27 @@ export function zyzz(api: typeof Babel, options: Options): Babel.PluginObj {
326
328
  visitor:
327
329
  options.target !== 'web' && options.colorScheme === undefined
328
330
  ? NativeJsx.visitor(api, callables)
329
- : {},
331
+ : {
332
+ Program(path) {
333
+ if (options.target !== 'web' || !options.reset) return
334
+ if (
335
+ path.node.body.some(
336
+ (node) =>
337
+ node.type === 'ImportDeclaration' &&
338
+ node.source.value === 'zyzz/reset.css',
339
+ )
340
+ )
341
+ return
342
+
343
+ path.unshiftContainer(
344
+ 'body',
345
+ api.types.importDeclaration(
346
+ [],
347
+ api.types.stringLiteral('zyzz/reset.css'),
348
+ ),
349
+ )
350
+ },
351
+ },
330
352
  }
331
353
  return plugin
332
354
  }
@@ -65,6 +65,8 @@ export declare namespace compile {
65
65
  | undefined
66
66
  /** Complete source graph keyed by stable package-relative module identities. */
67
67
  readonly modules: Readonly<Record<string, string>>
68
+ /** Optional reset stylesheet supplied by the host, ordered before authored layers. */
69
+ readonly reset?: string | undefined
68
70
  }
69
71
 
70
72
  /** Compiled modules and their direct source dependencies. */
@@ -119,6 +121,7 @@ type Cache = {
119
121
  development: boolean
120
122
  extracted: ReadonlyMap<string, Source.extract.ReturnType>
121
123
  libraries: Readonly<Record<string, ReturnType<typeof Contract.read>>>
124
+ reset: string | undefined
122
125
  resolutions: Readonly<Record<string, string>>
123
126
  native: compile.Options['native']
124
127
  result: compile.ReturnType
@@ -148,11 +151,16 @@ function build(options: compile.Options, cache?: Cache): Cache {
148
151
  })
149
152
  )
150
153
  cache = undefined
154
+ if (options.native && options.reset !== undefined)
155
+ throw new Native.CompileError(
156
+ 'The CSS reset is only supported by web builds.',
157
+ )
151
158
  if (options.native && options.compiler === false)
152
159
  throw new Native.CompileError(
153
160
  'Native graph compilation requires source rewriting.',
154
161
  )
155
162
  if (cache?.compiler !== (options.compiler !== false)) cache = undefined
163
+ if (cache?.reset !== options.reset) cache = undefined
156
164
  if (cache?.cssOutput !== options.cssOutput) cache = undefined
157
165
  if (cache?.composition !== options.composition) cache = undefined
158
166
  const ids = Object.keys(options.modules).sort()
@@ -1063,6 +1071,7 @@ function build(options: compile.Options, cache?: Cache): Cache {
1063
1071
  ...(options.native.vars && { vars: { ...options.native.vars } }),
1064
1072
  ...(options.native.units && { units: { ...options.native.units } }),
1065
1073
  },
1074
+ reset: options.reset,
1066
1075
  resolutions: Object.freeze(resolutions),
1067
1076
  result: Object.freeze({
1068
1077
  contracts: Object.freeze(
@@ -1244,6 +1253,7 @@ function build(options: compile.Options, cache?: Cache): Cache {
1244
1253
  try {
1245
1254
  const sharedSections = ids.flatMap((id) => reachable(id, sharedVisited))
1246
1255
  const resetSource =
1256
+ (options.reset === undefined ? undefined : 'zyzz/reset.css') ??
1247
1257
  resetOwners[0] ??
1248
1258
  sharedSections.find((section) => section.key === 'optional-reset-order')
1249
1259
  ?.source
@@ -1262,6 +1272,17 @@ function build(options: compile.Options, cache?: Cache): Cache {
1262
1272
  },
1263
1273
  ]),
1264
1274
  ...sharedSections,
1275
+ ...(options.reset === undefined
1276
+ ? []
1277
+ : [
1278
+ {
1279
+ source: 'zyzz/reset.css',
1280
+ key: 'optional-reset',
1281
+ css: options.reset,
1282
+ content: options.reset,
1283
+ layers: [['reset']],
1284
+ },
1285
+ ]),
1265
1286
  ])
1266
1287
  } catch (error) {
1267
1288
  return fail(
@@ -1509,6 +1530,7 @@ function build(options: compile.Options, cache?: Cache): Cache {
1509
1530
  extracted,
1510
1531
  libraries: Object.freeze(libraries),
1511
1532
  native: undefined,
1533
+ reset: options.reset,
1512
1534
  resolutions: Object.freeze(resolutions),
1513
1535
  result: Object.freeze({
1514
1536
  ...(sharedCss
@@ -471,7 +471,10 @@ export function extract(options: extract.Options): extract.ReturnType {
471
471
 
472
472
  pending.sort((a, b) => a.start - b.start)
473
473
 
474
- const staticCalls = new Set(pending.map((call) => call.start))
474
+ const staticCalls = new Set([
475
+ ...pending.map((call) => call.start),
476
+ ...contributions.calls.map((call) => call.start),
477
+ ])
475
478
  const opaque = new Set(variables.references.keys())
476
479
  const normalized = new Map<number, Ast.Node | Error>()
477
480
  const selectorKeys = new Set<number>()
@@ -1365,6 +1368,7 @@ export function extract(options: extract.Options): extract.ReturnType {
1365
1368
  contributions,
1366
1369
  themes?.tokens ?? new Map(),
1367
1370
  contributionStarts,
1371
+ (node) => staticData.resolve(node, staticCalls),
1368
1372
  ),
1369
1373
  ...(themes?.calls ?? []).flatMap((call) =>
1370
1374
  call.options?.layers
@@ -506,12 +506,13 @@ export function extract(
506
506
  scanned: ReturnType<typeof scan>,
507
507
  tokens: ReadonlyMap<number, { end: number; reference: Token.Reference }>,
508
508
  starts?: number[],
509
+ resolve: (node: Ast.Node) => Ast.Node = Expression.unwrap,
509
510
  ): readonly Css.Contribution[] {
510
511
  const result: Css.Contribution[] = []
511
512
  function value(node: Ast.Node, property?: string): unknown {
512
513
  const reference = tokens.get(node.start)
513
514
  if (reference?.end === node.end) return reference.reference
514
- node = Expression.unwrap(node)
515
+ node = Expression.unwrap(resolve(node))
515
516
 
516
517
  const animation = scanned.references.get(node.start)
517
518
  if (animation) return animation
@@ -545,7 +546,9 @@ export function extract(
545
546
 
546
547
  if (node.type === 'TemplateLiteral') {
547
548
  const template = Expression.template(node, 0, (expression, prefix) => {
548
- const node = Expression.unwrap(expression)
549
+ const node = Expression.unwrap(resolve(expression))
550
+ if (node.type === 'Literal' && typeof node.value === 'string')
551
+ return node.value
549
552
  const name = scanned.references.get(node.start)
550
553
  const kind = name ? scanned.kinds.get(name) : undefined
551
554
  if (
@@ -117,6 +117,7 @@ export function create(
117
117
  const binding = scope.getDeclaration(node.name) ?? null
118
118
  if (!binding && node.name === 'undefined') absent.add(node.start)
119
119
  if (!binding || !values.has(binding.node.start)) return binding
120
+ if (ancestors.some((node) => node.type === 'TSTypeQuery')) return binding
120
121
 
121
122
  references.set(node.start, binding.node.start)
122
123
  const value = Expression.unwrap(values.get(binding.node.start)!)
@@ -74,6 +74,10 @@ export function create(
74
74
  if (!dynamic && !id && Object.keys(input as object).length === 0)
75
75
  Identity.requireId(undefined, 'Empty style')
76
76
 
77
+ if (id && !dynamic && options.theme)
78
+ Style.define({ style: body(input as Record<string, unknown>) } as never, {
79
+ vars: options.theme,
80
+ })
77
81
  const className = id
78
82
  ? `z-style-${id}`
79
83
  : Identity.style(
@@ -125,6 +129,23 @@ export function variants(
125
129
  options: Options = {},
126
130
  ): unknown {
127
131
  const id = Identity.requireId(options.id, 'variants')
132
+ if (options.theme) {
133
+ const styles = [
134
+ input.base,
135
+ ...Object.values(
136
+ (input.variants ?? {}) as Record<string, Record<string, unknown>>,
137
+ ).flatMap(Object.values),
138
+ ...((input.compoundVariants ?? []) as readonly { style: unknown }[]).map(
139
+ (entry) => entry.style,
140
+ ),
141
+ ]
142
+ for (const input of styles)
143
+ if (input && typeof input === 'object')
144
+ Style.define(
145
+ { style: body(input as Record<string, unknown>) } as never,
146
+ { vars: options.theme },
147
+ )
148
+ }
128
149
  const className = `z-style-${id}`
129
150
  const axes = Object.entries(
130
151
  (input.variants ?? {}) as Record<string, Record<string, unknown>>,
@@ -127,6 +127,36 @@ export type Checked<style> = {
127
127
  : unknown
128
128
  }
129
129
 
130
+ /** Excludes token-name slots, which cannot resolve token names during application. */
131
+ export type TokenSlots<style, values, tokens, mappings = {}> = {
132
+ [property in keyof style]: property extends keyof Literal.Properties
133
+ ? SlotValue<
134
+ style[property],
135
+ values[keyof values],
136
+ Token.Names<tokens, property>
137
+ >
138
+ : property extends keyof mappings
139
+ ? mappings[property] extends readonly (infer target extends
140
+ keyof Literal.Properties)[]
141
+ ? SlotValue<
142
+ style[property],
143
+ values[keyof values],
144
+ Token.Names<tokens, target>
145
+ >
146
+ : unknown
147
+ : property extends 'vars'
148
+ ? unknown
149
+ : style[property] extends Record<string, unknown>
150
+ ? TokenSlots<style[property], values, tokens, mappings>
151
+ : unknown
152
+ }
153
+
154
+ type SlotValue<value, inputs, names> = value extends readonly unknown[]
155
+ ? { [key in keyof value]: SlotValue<value[key], inputs, names> }
156
+ : Extract<Extract<value, inputs>, names> extends never
157
+ ? unknown
158
+ : never
159
+
130
160
  /** Rejects reserved callback field names and importance-bearing value domains. */
131
161
  export type Inputs<values> = {
132
162
  [key in keyof values]: key extends
@@ -277,14 +277,16 @@ export function create(
277
277
  })
278
278
  }
279
279
  }
280
- function boundVariants(
281
- definition: Record<string, unknown>,
282
- options: style.DefinitionOptions = {},
283
- ) {
284
- return Authoring.variants(definition, {
285
- ...options,
286
- output: input.output as style.Output | undefined,
287
- })
280
+ function boundVariants(theme?: Theme.Definition) {
281
+ return (
282
+ definition: Record<string, unknown>,
283
+ options: style.DefinitionOptions = {},
284
+ ) =>
285
+ Authoring.variants(definition, {
286
+ ...options,
287
+ output: input.output as style.Output | undefined,
288
+ theme,
289
+ })
288
290
  }
289
291
  function handle(theme: Theme.Definition, name: string) {
290
292
  const original = Token.bind(theme, contract)
@@ -313,7 +315,7 @@ export function create(
313
315
  })
314
316
  Object.assign(select, {
315
317
  style: boundStyle(original),
316
- variants: boundVariants,
318
+ variants: boundVariants(original),
317
319
  })
318
320
  return select
319
321
  }
@@ -410,7 +412,9 @@ export function create(
410
412
  ),
411
413
  theme: bound[input.defaultTheme],
412
414
  themes: Object.freeze(select),
413
- variants: boundVariants,
415
+ variants: boundVariants(
416
+ bound[input.defaultTheme] as unknown as Theme.Definition,
417
+ ),
414
418
  })
415
419
  }
416
420
 
@@ -424,7 +428,7 @@ export function create(
424
428
  script: Appearance.create([], { storageKey }),
425
429
  style: boundStyle(theme as unknown as Theme.Definition),
426
430
  theme,
427
- variants: boundVariants,
431
+ variants: boundVariants(theme as unknown as Theme.Definition),
428
432
  })
429
433
  }
430
434
 
@@ -436,7 +440,7 @@ export function create(
436
440
  appearance: Appearance.root([], { storageKey }),
437
441
  script: Appearance.create([], { storageKey }),
438
442
  style: boundStyle(theme),
439
- variants: boundVariants,
443
+ variants: boundVariants(theme),
440
444
  })
441
445
  }
442
446
 
@@ -590,7 +594,9 @@ export type StyleFactory<
590
594
  values: values,
591
595
  ) => styles &
592
596
  NoInfer<
593
- Body<styles, tokens, layers, mappings> & Binding.Checked<styles>
597
+ Body<styles, tokens, layers, mappings> &
598
+ Binding.Checked<styles> &
599
+ Binding.TokenSlots<styles, values, tokens, mappings>
594
600
  >) &
595
601
  Completion.Properties<tokens, NoInfer<styles>>,
596
602
  ...options: Parameters<callback> extends [Record<string, string | number>]
@@ -30,7 +30,11 @@ export type StyleFactory<tokens extends Tokens> = {
30
30
  styles: ((
31
31
  values: values,
32
32
  ) => styles &
33
- NoInfer<Style.Accepted<styles, tokens> & Binding.Checked<styles>>) &
33
+ NoInfer<
34
+ Style.Accepted<styles, tokens> &
35
+ Binding.Checked<styles> &
36
+ Binding.TokenSlots<styles, values, tokens>
37
+ >) &
34
38
  (values extends Binding.Inputs<values> ? unknown : never),
35
39
  options?: style.DefinitionOptions,
36
40
  ): style.Dynamic<values>
@@ -444,11 +444,11 @@ export type Reference<group extends Group = Group> = {
444
444
 
445
445
  const reference = Symbol('zyzz.token')
446
446
 
447
- /** Resolves shorthand tokens with literal precedence, with specific colors first. */
447
+ /** Resolves configured token names, with specific color groups first. */
448
448
  export function resolve(value: unknown, options: resolve.Options): unknown {
449
449
  if (
450
- (typeof value !== 'string' && typeof value !== 'number') ||
451
- Literal.isLiteral(options.property, value)
450
+ options.property.startsWith('--') ||
451
+ (typeof value !== 'string' && typeof value !== 'number')
452
452
  )
453
453
  return value
454
454
 
@@ -529,6 +529,37 @@ export function resolve(value: unknown, options: resolve.Options): unknown {
529
529
  return value
530
530
  }
531
531
 
532
+ /** Whether the configured catalog supplies tokens for a property. */
533
+ export function mapped(
534
+ theme: object,
535
+ property: keyof Literal.Properties,
536
+ ): boolean {
537
+ if (property.startsWith('--')) return false
538
+ const data = Object.getOwnPropertyDescriptor(theme, definition)
539
+ ?.value as Metadata
540
+ return Object.keys(data.values).some((path) => {
541
+ const category = path.split('.')[0]!
542
+ const targets =
543
+ data.contract.mappings === false
544
+ ? undefined
545
+ : data.contract.mappings?.[category]
546
+ if (
547
+ data.contract.mappings !== false &&
548
+ !(targets
549
+ ? targets.includes(property)
550
+ : accepts(category as Group, property))
551
+ )
552
+ return false
553
+ let leaf: unknown = Object.getOwnPropertyDescriptor(theme, 'tokens')?.value
554
+ for (const key of path.split('.'))
555
+ leaf =
556
+ leaf && typeof leaf === 'object'
557
+ ? Object.getOwnPropertyDescriptor(leaf, key)?.value
558
+ : undefined
559
+ return is(leaf) && acceptsReference(leaf, property)
560
+ })
561
+ }
562
+
532
563
  /** Input contract for theme token resolution. */
533
564
  export declare namespace resolve {
534
565
  /** Property domain and immutable theme metadata supplied by style validation. */