zyzz 0.0.20 → 0.0.22

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 (298) hide show
  1. package/Zyzz.podspec +16 -0
  2. package/dist/Style.d.ts +10 -1
  3. package/dist/Style.d.ts.map +1 -1
  4. package/dist/Style.js +1 -5
  5. package/dist/Style.js.map +1 -1
  6. package/dist/babel/NativeJsx.d.ts.map +1 -1
  7. package/dist/babel/NativeJsx.js +204 -12
  8. package/dist/babel/NativeJsx.js.map +1 -1
  9. package/dist/babel/index.d.ts +6 -2
  10. package/dist/babel/index.d.ts.map +1 -1
  11. package/dist/babel/index.js +10 -1
  12. package/dist/babel/index.js.map +1 -1
  13. package/dist/compiler/Graph.d.ts +3 -0
  14. package/dist/compiler/Graph.d.ts.map +1 -1
  15. package/dist/compiler/Graph.js +108 -37
  16. package/dist/compiler/Graph.js.map +1 -1
  17. package/dist/compiler/Native.d.ts +6 -3
  18. package/dist/compiler/Native.d.ts.map +1 -1
  19. package/dist/compiler/Native.js +142 -24
  20. package/dist/compiler/Native.js.map +1 -1
  21. package/dist/compiler/Source.d.ts +6 -0
  22. package/dist/compiler/Source.d.ts.map +1 -1
  23. package/dist/compiler/Source.js +80 -11
  24. package/dist/compiler/Source.js.map +1 -1
  25. package/dist/compiler/Transform.d.ts +4 -1
  26. package/dist/compiler/Transform.d.ts.map +1 -1
  27. package/dist/compiler/Transform.js +32 -46
  28. package/dist/compiler/Transform.js.map +1 -1
  29. package/dist/compiler/internal/Catalogs.d.ts.map +1 -1
  30. package/dist/compiler/internal/Catalogs.js +6 -1
  31. package/dist/compiler/internal/Catalogs.js.map +1 -1
  32. package/dist/compiler/internal/Compositions.d.ts.map +1 -1
  33. package/dist/compiler/internal/Compositions.js +5 -0
  34. package/dist/compiler/internal/Compositions.js.map +1 -1
  35. package/dist/compiler/internal/Configurations.d.ts +2 -0
  36. package/dist/compiler/internal/Configurations.d.ts.map +1 -1
  37. package/dist/compiler/internal/Configurations.js +23 -4
  38. package/dist/compiler/internal/Configurations.js.map +1 -1
  39. package/dist/compiler/internal/Contract.d.ts +4 -1
  40. package/dist/compiler/internal/Contract.d.ts.map +1 -1
  41. package/dist/compiler/internal/Contract.js +97 -151
  42. package/dist/compiler/internal/Contract.js.map +1 -1
  43. package/dist/compiler/internal/Contributions.d.ts.map +1 -1
  44. package/dist/compiler/internal/Contributions.js +8 -4
  45. package/dist/compiler/internal/Contributions.js.map +1 -1
  46. package/dist/compiler/internal/Descriptors.d.ts.map +1 -1
  47. package/dist/compiler/internal/Descriptors.js +11 -2
  48. package/dist/compiler/internal/Descriptors.js.map +1 -1
  49. package/dist/compiler/internal/Dynamic.d.ts +1 -1
  50. package/dist/compiler/internal/Dynamic.d.ts.map +1 -1
  51. package/dist/compiler/internal/Dynamic.js +5 -5
  52. package/dist/compiler/internal/Dynamic.js.map +1 -1
  53. package/dist/compiler/internal/Names.d.ts +5 -0
  54. package/dist/compiler/internal/Names.d.ts.map +1 -0
  55. package/dist/compiler/internal/Names.js +37 -0
  56. package/dist/compiler/internal/Names.js.map +1 -0
  57. package/dist/compiler/internal/NativeBindings.d.ts +24 -26
  58. package/dist/compiler/internal/NativeBindings.d.ts.map +1 -1
  59. package/dist/compiler/internal/NativeBindings.js +61 -8
  60. package/dist/compiler/internal/NativeBindings.js.map +1 -1
  61. package/dist/compiler/internal/NativeMedia.d.ts +14 -0
  62. package/dist/compiler/internal/NativeMedia.d.ts.map +1 -0
  63. package/dist/compiler/internal/NativeMedia.js +287 -0
  64. package/dist/compiler/internal/NativeMedia.js.map +1 -0
  65. package/dist/compiler/internal/NativeVars.d.ts +28 -0
  66. package/dist/compiler/internal/NativeVars.d.ts.map +1 -0
  67. package/dist/compiler/internal/NativeVars.js +157 -0
  68. package/dist/compiler/internal/NativeVars.js.map +1 -0
  69. package/dist/compiler/internal/PackedStyles.d.ts +2 -0
  70. package/dist/compiler/internal/PackedStyles.d.ts.map +1 -1
  71. package/dist/compiler/internal/PackedStyles.js +2 -0
  72. package/dist/compiler/internal/PackedStyles.js.map +1 -1
  73. package/dist/compiler/internal/Selectors.d.ts +1 -1
  74. package/dist/compiler/internal/Selectors.d.ts.map +1 -1
  75. package/dist/compiler/internal/Selectors.js +5 -2
  76. package/dist/compiler/internal/Selectors.js.map +1 -1
  77. package/dist/compiler/internal/Stylesheets.js +2 -2
  78. package/dist/compiler/internal/Stylesheets.js.map +1 -1
  79. package/dist/compiler/internal/Themes.d.ts +22 -1
  80. package/dist/compiler/internal/Themes.d.ts.map +1 -1
  81. package/dist/compiler/internal/Themes.js +120 -4
  82. package/dist/compiler/internal/Themes.js.map +1 -1
  83. package/dist/compiler/internal/Vars.d.ts +3 -1
  84. package/dist/compiler/internal/Vars.d.ts.map +1 -1
  85. package/dist/compiler/internal/Vars.js +14 -3
  86. package/dist/compiler/internal/Vars.js.map +1 -1
  87. package/dist/default.d.ts +4 -4
  88. package/dist/default.d.ts.map +1 -1
  89. package/dist/default.js +9 -9
  90. package/dist/default.js.map +2 -2
  91. package/dist/default.js.zyzz.json +1 -1
  92. package/dist/internal/Authoring.d.ts.map +1 -1
  93. package/dist/internal/Authoring.js +8 -3
  94. package/dist/internal/Authoring.js.map +1 -1
  95. package/dist/internal/Binding.d.ts +4 -0
  96. package/dist/internal/Binding.d.ts.map +1 -1
  97. package/dist/internal/Binding.js +2 -0
  98. package/dist/internal/Binding.js.map +1 -1
  99. package/dist/internal/Completion.d.ts +1 -1
  100. package/dist/internal/Completion.d.ts.map +1 -1
  101. package/dist/internal/Configuration.d.ts +2 -2
  102. package/dist/internal/Configuration.d.ts.map +1 -1
  103. package/dist/internal/Configuration.js +4 -2
  104. package/dist/internal/Configuration.js.map +1 -1
  105. package/dist/internal/Identity.d.ts +3 -3
  106. package/dist/internal/Identity.d.ts.map +1 -1
  107. package/dist/internal/Identity.js +11 -9
  108. package/dist/internal/Identity.js.map +1 -1
  109. package/dist/internal/Targets.d.ts.map +1 -1
  110. package/dist/internal/Targets.js +2 -0
  111. package/dist/internal/Targets.js.map +1 -1
  112. package/dist/internal/Theme.js +2 -2
  113. package/dist/internal/Theme.js.map +1 -1
  114. package/dist/internal/Token.d.ts +3 -1
  115. package/dist/internal/Token.d.ts.map +1 -1
  116. package/dist/internal/Token.js +9 -2
  117. package/dist/internal/Token.js.map +1 -1
  118. package/dist/internal/Value.d.ts +7 -0
  119. package/dist/internal/Value.d.ts.map +1 -1
  120. package/dist/internal/Value.js.map +1 -1
  121. package/dist/internal/VariableSets.js +1 -1
  122. package/dist/internal/VariableSets.js.map +1 -1
  123. package/dist/metro/Graph.d.ts +22 -7
  124. package/dist/metro/Graph.d.ts.map +1 -1
  125. package/dist/metro/Graph.js +179 -42
  126. package/dist/metro/Graph.js.map +1 -1
  127. package/dist/metro/Watch.d.ts +28 -4
  128. package/dist/metro/Watch.d.ts.map +1 -1
  129. package/dist/metro/Watch.js +39 -7
  130. package/dist/metro/Watch.js.map +1 -1
  131. package/dist/metro/index.d.ts +15 -4
  132. package/dist/metro/index.d.ts.map +1 -1
  133. package/dist/metro/index.js +27 -0
  134. package/dist/metro/index.js.map +1 -1
  135. package/dist/metro/transformer.d.ts +5 -1
  136. package/dist/metro/transformer.d.ts.map +1 -1
  137. package/dist/metro/transformer.js +5 -3
  138. package/dist/metro/transformer.js.map +1 -1
  139. package/dist/node/Host.d.ts.map +1 -1
  140. package/dist/node/Host.js +2 -0
  141. package/dist/node/Host.js.map +1 -1
  142. package/dist/react-native/StyleSheet.d.ts +3 -2
  143. package/dist/react-native/StyleSheet.d.ts.map +1 -1
  144. package/dist/react-native/StyleSheet.js +17 -34
  145. package/dist/react-native/StyleSheet.js.map +1 -1
  146. package/dist/react-native/index.d.ts +1 -1
  147. package/dist/react-native/index.d.ts.map +1 -1
  148. package/dist/react-native/index.js +1 -1
  149. package/dist/react-native/index.js.map +1 -1
  150. package/dist/react-native/index.native.d.ts +5 -0
  151. package/dist/react-native/index.native.js +20 -0
  152. package/dist/react-native/index.native.js.map +7 -0
  153. package/dist/react-native/internal/Calculation.d.ts +7 -0
  154. package/dist/react-native/internal/Calculation.d.ts.map +1 -0
  155. package/dist/react-native/internal/Calculation.js +134 -0
  156. package/dist/react-native/internal/Calculation.js.map +1 -0
  157. package/dist/react-native/internal/Device.js +191 -0
  158. package/dist/react-native/internal/Device.js.map +7 -0
  159. package/dist/react-native/internal/NativeZyzz.js +7 -0
  160. package/dist/react-native/internal/NativeZyzz.js.map +7 -0
  161. package/dist/react-native/internal/Scalar.d.ts.map +1 -1
  162. package/dist/react-native/internal/Scalar.js +9 -2
  163. package/dist/react-native/internal/Scalar.js.map +1 -1
  164. package/dist/react-native/internal/Store.d.ts +32 -0
  165. package/dist/react-native/internal/Store.d.ts.map +1 -0
  166. package/dist/react-native/internal/Store.js +57 -0
  167. package/dist/react-native/internal/Store.js.map +1 -0
  168. package/dist/react-native/internal/Tokens.d.ts +21 -0
  169. package/dist/react-native/internal/Tokens.d.ts.map +1 -0
  170. package/dist/react-native/internal/Tokens.js +58 -0
  171. package/dist/react-native/internal/Tokens.js.map +1 -0
  172. package/dist/react-native/internal/Viewport.d.ts +6 -0
  173. package/dist/react-native/internal/Viewport.d.ts.map +1 -0
  174. package/dist/react-native/internal/Viewport.js +4 -0
  175. package/dist/react-native/internal/Viewport.js.map +1 -0
  176. package/dist/react-native/react.d.ts +74 -11
  177. package/dist/react-native/react.d.ts.map +1 -1
  178. package/dist/react-native/react.js +111 -12
  179. package/dist/react-native/react.js.map +1 -1
  180. package/dist/react-native/reanimated.d.ts +39 -0
  181. package/dist/react-native/reanimated.d.ts.map +1 -0
  182. package/dist/react-native/reanimated.js +76 -0
  183. package/dist/react-native/reanimated.js.map +1 -0
  184. package/dist/runtime/NativeContext.d.ts +10 -1
  185. package/dist/runtime/NativeContext.d.ts.map +1 -1
  186. package/dist/runtime/NativeContext.js +67 -14
  187. package/dist/runtime/NativeContext.js.map +1 -1
  188. package/dist/runtime/NativeDynamic.d.ts +3 -2
  189. package/dist/runtime/NativeDynamic.d.ts.map +1 -1
  190. package/dist/runtime/NativeDynamic.js +32 -7
  191. package/dist/runtime/NativeDynamic.js.map +1 -1
  192. package/dist/runtime/NativeStatic.d.ts +23 -0
  193. package/dist/runtime/NativeStatic.d.ts.map +1 -0
  194. package/dist/runtime/NativeStatic.js +106 -0
  195. package/dist/runtime/NativeStatic.js.map +1 -0
  196. package/dist/runtime/NativeVars.d.ts +53 -0
  197. package/dist/runtime/NativeVars.d.ts.map +1 -0
  198. package/dist/runtime/NativeVars.js +77 -0
  199. package/dist/runtime/NativeVars.js.map +1 -0
  200. package/dist/runtime/index.d.ts +4 -0
  201. package/dist/runtime/index.d.ts.map +1 -1
  202. package/dist/runtime/index.js +4 -0
  203. package/dist/runtime/index.js.map +1 -1
  204. package/dist/runtime/internal/NativeMedia.d.ts +25 -0
  205. package/dist/runtime/internal/NativeMedia.d.ts.map +1 -0
  206. package/dist/runtime/internal/NativeMedia.js +36 -0
  207. package/dist/runtime/internal/NativeMedia.js.map +1 -0
  208. package/dist/variable.js +1 -1
  209. package/dist/variable.js.map +1 -1
  210. package/dist/vite/index.d.ts.map +1 -1
  211. package/dist/vite/index.js +43 -47
  212. package/dist/vite/index.js.map +1 -1
  213. package/dist/web/Css.d.ts +7 -2
  214. package/dist/web/Css.d.ts.map +1 -1
  215. package/dist/web/Css.js +76 -57
  216. package/dist/web/Css.js.map +1 -1
  217. package/dist/web/internal/ClassName.d.ts +13 -2
  218. package/dist/web/internal/ClassName.d.ts.map +1 -1
  219. package/dist/web/internal/ClassName.js +17 -30
  220. package/dist/web/internal/ClassName.js.map +1 -1
  221. package/dist/web/internal/Themes.d.ts +3 -2
  222. package/dist/web/internal/Themes.d.ts.map +1 -1
  223. package/dist/web/internal/Themes.js +54 -28
  224. package/dist/web/internal/Themes.js.map +1 -1
  225. package/dist/web/page.d.ts +2 -0
  226. package/dist/web/page.d.ts.map +1 -1
  227. package/native/NativeZyzz.cpp +215 -0
  228. package/native/NativeZyzz.h +52 -0
  229. package/native/ZyzzSpecJSI.h +65 -0
  230. package/native/android/CMakeLists.txt +8 -0
  231. package/native/android/ZyzzSpec-generated.cpp +50 -0
  232. package/native/android/ZyzzSpec.h +31 -0
  233. package/native/ios/ZyzzModuleProvider.mm +13 -0
  234. package/package.json +39 -1
  235. package/react-native.config.ts +14 -0
  236. package/src/Style.ts +15 -9
  237. package/src/babel/NativeJsx.ts +305 -28
  238. package/src/babel/index.ts +21 -3
  239. package/src/compiler/Graph.ts +135 -46
  240. package/src/compiler/Native.ts +158 -26
  241. package/src/compiler/Source.ts +115 -10
  242. package/src/compiler/Transform.ts +42 -60
  243. package/src/compiler/internal/Catalogs.ts +9 -1
  244. package/src/compiler/internal/Compositions.ts +7 -0
  245. package/src/compiler/internal/Configurations.ts +27 -4
  246. package/src/compiler/internal/Contract.ts +130 -260
  247. package/src/compiler/internal/Contributions.ts +8 -6
  248. package/src/compiler/internal/Descriptors.ts +12 -8
  249. package/src/compiler/internal/Dynamic.ts +14 -9
  250. package/src/compiler/internal/Names.ts +48 -0
  251. package/src/compiler/internal/NativeBindings.ts +98 -15
  252. package/src/compiler/internal/NativeMedia.ts +342 -0
  253. package/src/compiler/internal/NativeVars.ts +228 -0
  254. package/src/compiler/internal/PackedStyles.ts +4 -0
  255. package/src/compiler/internal/Selectors.ts +6 -1
  256. package/src/compiler/internal/Stylesheets.ts +2 -2
  257. package/src/compiler/internal/Themes.ts +193 -3
  258. package/src/compiler/internal/Vars.ts +21 -2
  259. package/src/default.ts +9 -10
  260. package/src/internal/Authoring.ts +8 -2
  261. package/src/internal/Binding.ts +5 -0
  262. package/src/internal/Completion.ts +6 -3
  263. package/src/internal/Configuration.ts +7 -4
  264. package/src/internal/Identity.ts +14 -12
  265. package/src/internal/Targets.ts +2 -0
  266. package/src/internal/Theme.ts +2 -2
  267. package/src/internal/Token.ts +11 -1
  268. package/src/internal/Value.ts +20 -0
  269. package/src/internal/VariableSets.ts +1 -1
  270. package/src/metro/Graph.ts +235 -50
  271. package/src/metro/Watch.ts +95 -10
  272. package/src/metro/index.ts +62 -4
  273. package/src/metro/transformer.ts +21 -11
  274. package/src/node/Host.ts +3 -0
  275. package/src/react-native/StyleSheet.ts +28 -44
  276. package/src/react-native/index.native.ts +10 -0
  277. package/src/react-native/index.ts +1 -1
  278. package/src/react-native/internal/Calculation.ts +159 -0
  279. package/src/react-native/internal/Device.ts +231 -0
  280. package/src/react-native/internal/NativeZyzz.ts +20 -0
  281. package/src/react-native/internal/Scalar.ts +13 -2
  282. package/src/react-native/internal/Store.ts +78 -0
  283. package/src/react-native/internal/Tokens.ts +85 -0
  284. package/src/react-native/internal/Viewport.ts +8 -0
  285. package/src/react-native/react.ts +211 -19
  286. package/src/react-native/reanimated.ts +162 -0
  287. package/src/runtime/NativeContext.ts +88 -17
  288. package/src/runtime/NativeDynamic.ts +35 -10
  289. package/src/runtime/NativeStatic.ts +145 -0
  290. package/src/runtime/NativeVars.ts +189 -0
  291. package/src/runtime/index.ts +6 -0
  292. package/src/runtime/internal/NativeMedia.ts +63 -0
  293. package/src/variable.ts +1 -1
  294. package/src/vite/index.ts +52 -60
  295. package/src/web/Css.ts +123 -74
  296. package/src/web/internal/ClassName.ts +31 -36
  297. package/src/web/internal/Themes.ts +62 -39
  298. package/src/web/page.ts +2 -0
@@ -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-v${descriptor.id === undefined ? `${namespace}-${call.start}` : Identity.requireId(typeof descriptor.id === 'string' ? descriptor.id : undefined, 'variable')}` as const
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 }),
@@ -469,6 +477,7 @@ export function collect(
469
477
  function reference(
470
478
  node: Extract<Ast.Node, { type: 'Identifier' | 'JSXIdentifier' }>,
471
479
  parent: Ast.Node,
480
+ ancestors: readonly Ast.Node[],
472
481
  binding: Walker.ScopeTrackerNode | null,
473
482
  ) {
474
483
  if (binding?.type === 'Import' && imports.has(binding.node.start))
@@ -480,7 +489,17 @@ export function collect(
480
489
  : node,
481
490
  ) ?? resolve(node)
482
491
  if (!link) return false
483
- if (link.call.start >= 0 && node.start < link.call.end)
492
+ // Reads inside functions wait for a call, so only module-scope reads must follow the declaration.
493
+ if (
494
+ link.call.start >= 0 &&
495
+ node.start < link.call.end &&
496
+ !ancestors.some(
497
+ (ancestor) =>
498
+ ancestor.type === 'ArrowFunctionExpression' ||
499
+ ancestor.type === 'FunctionDeclaration' ||
500
+ ancestor.type === 'FunctionExpression',
501
+ )
502
+ )
484
503
  throw new InvalidError('Vars must be declared before use.', node)
485
504
  return true
486
505
  }
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-7a-79-7a-7a-2d-73-70-69-6e 1s linear infinite',
45
- ping: 'z-kid-7a-79-7a-7a-2d-70-69-6e-67 1s cubic-bezier(0, 0, 0.2, 1) infinite',
46
- pulse:
47
- 'z-kid-7a-79-7a-7a-2d-70-75-6c-73-65 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
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',
@@ -680,13 +679,13 @@ export const tokens = {
680
679
  /** Default appearance, restoration script, and authoring helpers with bundled light/dark tokens. */
681
680
  // Generated from tokens by scripts/default-theme.ts; edit tokens and regenerate.
682
681
  const config = Config.create({
682
+ id: 'default',
683
683
  vars: {
684
684
  animate: {
685
- spin: 'z-kid-7a-79-7a-7a-2d-73-70-69-6e 1s linear infinite',
686
- ping: 'z-kid-7a-79-7a-7a-2d-70-69-6e-67 1s cubic-bezier(0, 0, 0.2, 1) infinite',
687
- pulse:
688
- 'z-kid-7a-79-7a-7a-2d-70-75-6c-73-65 2s cubic-bezier(0.4, 0, 0.6, 1) infinite',
689
- 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',
690
689
  },
691
690
  aspect: {
692
691
  video: '16 / 9',
@@ -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 id = Identity.requireId(options.id, 'variants')
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,
@@ -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. */
@@ -11,9 +11,12 @@ export type Properties<
11
11
  styles = Record<string, unknown>,
12
12
  > = {
13
13
  readonly [property in keyof Literal.Properties & keyof styles]?:
14
- | (string extends Literal.Properties[property]
15
- ? never
16
- : Literal.Properties[property])
14
+ // Configured tokens replace literal CSS values, so only token names are suggested.
15
+ | ([Token.Names<tokens, property>] extends [never]
16
+ ? string extends Literal.Properties[property]
17
+ ? never
18
+ : Literal.Properties[property]
19
+ : never)
17
20
  | Token.Names<tokens, property>
18
21
  | (string & {})
19
22
  | number
@@ -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
- `z_theme-${Identity.requireId(typeof input.id === 'string' ? input.id : undefined, 'Config.create')}-${name.replace(/[^a-zA-Z0-9-]/g, (character) => `_${character.charCodeAt(0).toString(16)}_`)}`
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
- /** Stable theme identity required without source rewriting. */
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
- /** Stable identity required without source rewriting. */
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
@@ -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-${encode(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-d${id}-${encode(field)}`
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-content-${hash(JSON.stringify(shape(input)))}`
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-${hash(JSON.stringify(names))}`
115
+ return `z-compose-${name(JSON.stringify(names))}`
114
116
  }
115
117
 
116
118
  /** Names a stylesheet declaration with a caller-owned identity. */
@@ -147,6 +147,8 @@ export function copy(
147
147
  export function web<name extends string>(
148
148
  style: Style.NamedStyle<name>,
149
149
  ): Style.NamedStyle<name> {
150
+ if (!style.rules && !style.targets) return style
151
+
150
152
  const rules = style.rules?.map((rule) => ({
151
153
  ...rule,
152
154
  style: web(rule.style),
@@ -599,10 +599,10 @@ function build(
599
599
  Object.defineProperty(
600
600
  {
601
601
  get className(): string {
602
- if (scope) return `z_theme-${scope}`
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 `z_theme-${id}-${Identity.hash(JSON.stringify(values))}`
605
+ return `z-theme-${id.slice(3)}`
606
606
  },
607
607
  style: (styles?: unknown, options: style.DefinitionOptions = {}) => {
608
608
  if (!contract[Token.identity])
@@ -333,6 +333,7 @@ export function acceptsReference(
333
333
  export function bind<tokens extends Theme.Tokens>(
334
334
  original: Theme.Definition<tokens>,
335
335
  contract: Contract,
336
+ cssName?: string,
336
337
  ): Theme.Definition<tokens> {
337
338
  type Tree = { [key: string]: Reference | Tree }
338
339
 
@@ -371,7 +372,14 @@ export function bind<tokens extends Theme.Tokens>(
371
372
  vars: variables(tokens),
372
373
  },
373
374
  definition,
374
- { value: Object.freeze({ ...metadata, contract, values }) },
375
+ {
376
+ value: Object.freeze({
377
+ ...metadata,
378
+ ...(cssName !== undefined ? { cssName } : {}),
379
+ contract,
380
+ values,
381
+ }),
382
+ },
375
383
  ),
376
384
  ) as Theme.Definition<tokens>
377
385
  }
@@ -520,6 +528,8 @@ export function is(value: unknown): value is Reference {
520
528
 
521
529
  /** Immutable theme data carried directly by each definition. */
522
530
  export type Metadata = {
531
+ /** Authored scope name, independent of private graph ownership. */
532
+ readonly cssName?: string | undefined
523
533
  /** Original segments for typography paths containing query punctuation. */
524
534
  readonly paths?: Readonly<Record<string, readonly string[]>> | undefined
525
535
  readonly queries?: Query.Metadata | undefined
@@ -190,6 +190,26 @@ type CheckedArray<values, property extends PropertyKey, tokens> = {
190
190
  >[property]
191
191
  }
192
192
 
193
+ /** Lists the values a token-constrained property accepts, so mismatch diagnostics name them. */
194
+ export type Mismatch<tokens, property extends keyof Literal.Properties> =
195
+ // Resolving through a conditional prints the expected values instead of this alias's arguments.
196
+ tokens extends unknown
197
+ ? Expected<
198
+ | Extract<Token.Names<tokens, property>, string>
199
+ | NumericNames<Token.Names<tokens, property>>
200
+ | `${string} !custom`
201
+ >
202
+ : never
203
+
204
+ // An object brand never reduces with a string literal, so the diagnostic keeps the expected values.
205
+ type Expected<values> = { readonly [expected]: values }
206
+
207
+ declare const expected: unique symbol
208
+
209
+ type NumericNames<names> = names extends `${infer value extends number}`
210
+ ? value
211
+ : never
212
+
193
213
  /** Requires tokens for properties with configured values. */
194
214
  export type Tokens<
195
215
  value,
@@ -33,7 +33,7 @@ export function theme(
33
33
  get: () => {
34
34
  const identity = metadata.contract[Token.identity]
35
35
  return identity
36
- ? `z_theme-${identity}-${Identity.hash(JSON.stringify(metadata.values))}`
36
+ ? `z-theme-${identity.startsWith('id-') ? identity.slice(3) : Identity.name(identity)}`
37
37
  : original.className
38
38
  },
39
39
  enumerable: true,