@aziontech/theme 2.6.0 → 4.0.0

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 (251) hide show
  1. package/README.md +73 -66
  2. package/dist/v4/globals.css +799 -79
  3. package/dist/v4/globals.scss +799 -79
  4. package/package.json +6 -23
  5. package/src/scripts/build-tokens.mjs +197 -230
  6. package/src/scripts/compile-primitives.js +79 -79
  7. package/src/scripts/compile-theme.js +70 -63
  8. package/src/scripts/css-vars.d.ts.map +1 -1
  9. package/src/scripts/css-vars.js +20 -16
  10. package/src/scripts/refs.js +2 -2
  11. package/src/scripts/resolve.d.ts.map +1 -1
  12. package/src/scripts/resolve.js +50 -47
  13. package/src/tokens/README.md +53 -74
  14. package/src/tokens/index.js +5 -5
  15. package/src/tokens/primitives/animations/animate.d.ts +10 -0
  16. package/src/tokens/primitives/animations/animate.d.ts.map +1 -1
  17. package/src/tokens/primitives/animations/animate.js +15 -5
  18. package/src/tokens/primitives/animations/ease.d.ts.map +1 -1
  19. package/src/tokens/primitives/animations/ease.js +3 -3
  20. package/src/tokens/primitives/animations/keyframes.d.ts +63 -0
  21. package/src/tokens/primitives/animations/keyframes.d.ts.map +1 -0
  22. package/src/tokens/primitives/animations/keyframes.js +69 -0
  23. package/src/tokens/primitives/border-widths.d.ts.map +1 -1
  24. package/src/tokens/primitives/border-widths.js +3 -3
  25. package/src/tokens/primitives/breakpoints.d.ts.map +1 -1
  26. package/src/tokens/primitives/breakpoints.js +3 -3
  27. package/src/tokens/primitives/colors/alpha.d.ts +80 -80
  28. package/src/tokens/primitives/colors/alpha.js +84 -84
  29. package/src/tokens/primitives/colors/brand.d.ts +22 -22
  30. package/src/tokens/primitives/colors/brand.js +28 -28
  31. package/src/tokens/primitives/colors/colors.d.ts +88 -88
  32. package/src/tokens/primitives/colors/colors.js +107 -107
  33. package/src/tokens/primitives/effects/blur.d.ts.map +1 -1
  34. package/src/tokens/primitives/effects/blur.js +3 -3
  35. package/src/tokens/primitives/effects/drop-shadow.d.ts.map +1 -1
  36. package/src/tokens/primitives/effects/drop-shadow.js +3 -3
  37. package/src/tokens/primitives/effects/inset-shadow.d.ts.map +1 -1
  38. package/src/tokens/primitives/effects/inset-shadow.js +3 -3
  39. package/src/tokens/primitives/effects/opacity.d.ts.map +1 -1
  40. package/src/tokens/primitives/effects/opacity.js +3 -3
  41. package/src/tokens/primitives/effects/perspective.js +3 -3
  42. package/src/tokens/primitives/effects/shadow.d.ts.map +1 -1
  43. package/src/tokens/primitives/effects/shadow.js +3 -3
  44. package/src/{azion/_fonts.scss → tokens/primitives/fonts.css} +19 -4
  45. package/src/tokens/primitives/ring-offset.d.ts.map +1 -1
  46. package/src/tokens/primitives/ring-offset.js +3 -3
  47. package/src/tokens/primitives/shape/aspect-video.d.ts.map +1 -1
  48. package/src/tokens/primitives/shape/aspect-video.js +2 -2
  49. package/src/tokens/primitives/shape/container.d.ts.map +1 -1
  50. package/src/tokens/primitives/shape/container.js +3 -3
  51. package/src/tokens/primitives/shape/height.d.ts.map +1 -1
  52. package/src/tokens/primitives/shape/height.js +3 -3
  53. package/src/tokens/primitives/shape/radius.d.ts.map +1 -1
  54. package/src/tokens/primitives/shape/radius.js +3 -3
  55. package/src/tokens/primitives/shape/size.d.ts.map +1 -1
  56. package/src/tokens/primitives/shape/size.js +3 -3
  57. package/src/tokens/primitives/shape/spacing.d.ts.map +1 -1
  58. package/src/tokens/primitives/shape/spacing.js +3 -3
  59. package/src/tokens/primitives/shape/width.d.ts.map +1 -1
  60. package/src/tokens/primitives/shape/width.js +4 -4
  61. package/src/tokens/primitives/typography/font-size.d.ts.map +1 -1
  62. package/src/tokens/primitives/typography/font-size.js +4 -4
  63. package/src/tokens/primitives/typography/font-weight.js +3 -3
  64. package/src/tokens/primitives/typography/leading.js +3 -3
  65. package/src/tokens/primitives/typography/line-height.d.ts.map +1 -1
  66. package/src/tokens/primitives/typography/line-height.js +3 -3
  67. package/src/tokens/primitives/typography/tracking.js +3 -3
  68. package/src/tokens/semantic/colors.js +17 -17
  69. package/src/tokens/semantic/containers.data.d.ts.map +1 -1
  70. package/src/tokens/semantic/containers.data.js +3 -3
  71. package/src/tokens/semantic/containers.js +25 -25
  72. package/src/tokens/semantic/spacings.data.d.ts.map +1 -1
  73. package/src/tokens/semantic/spacings.data.js +3 -3
  74. package/src/tokens/semantic/texts.data.d.ts +59 -28
  75. package/src/tokens/semantic/texts.data.d.ts.map +1 -1
  76. package/src/tokens/semantic/texts.data.js +90 -56
  77. package/src/tokens/theme/accent.js +6 -6
  78. package/src/tokens/theme/border.js +6 -6
  79. package/src/tokens/theme/code-sintax.d.ts +53 -0
  80. package/src/tokens/theme/code-sintax.d.ts.map +1 -0
  81. package/src/tokens/theme/code-sintax.js +28 -0
  82. package/src/tokens/theme/feedback/danger.js +6 -6
  83. package/src/tokens/theme/feedback/info.js +6 -6
  84. package/src/tokens/theme/feedback/success.js +6 -6
  85. package/src/tokens/theme/feedback/warning.js +6 -6
  86. package/src/tokens/theme/primary.js +6 -6
  87. package/src/tokens/theme/ring.js +6 -6
  88. package/src/tokens/theme/secondary.js +6 -6
  89. package/src/tokens/theme/surfaces.d.ts.map +1 -1
  90. package/src/tokens/theme/surfaces.js +6 -6
  91. package/src/tokens/theme/text.d.ts +6 -0
  92. package/src/tokens/theme/text.js +2 -0
  93. package/src/tokens/theme.d.ts +110 -110
  94. package/src/tokens/theme.js +9 -9
  95. package/default.js +0 -1
  96. package/dist/v3/globals.css +0 -855
  97. package/dist/v3/globals.scss +0 -855
  98. package/dist/v3/tailwind-preset.js +0 -510
  99. package/dist/v3/tailwind.config.js +0 -518
  100. package/src/azion/_custom.scss +0 -3
  101. package/src/azion/_extensions.scss +0 -37
  102. package/src/azion/_variables-widget.scss +0 -400
  103. package/src/azion/_variables.scss +0 -407
  104. package/src/azion/custom/_code.scss +0 -11
  105. package/src/azion/custom/_focus.scss +0 -5
  106. package/src/azion/custom/_scrollbehavior.scss +0 -6
  107. package/src/azion/custom/_selection.scss +0 -4
  108. package/src/azion/custom/_special-button.scss +0 -57
  109. package/src/azion/extended-components/_autocomplete.scss +0 -13
  110. package/src/azion/extended-components/_badge.scss +0 -53
  111. package/src/azion/extended-components/_breadcumb.scss +0 -18
  112. package/src/azion/extended-components/_button.scss +0 -134
  113. package/src/azion/extended-components/_calendar.scss +0 -310
  114. package/src/azion/extended-components/_carousel.scss +0 -9
  115. package/src/azion/extended-components/_checkbox.scss +0 -33
  116. package/src/azion/extended-components/_datatable.scss +0 -130
  117. package/src/azion/extended-components/_dialog.scss +0 -45
  118. package/src/azion/extended-components/_divider.scss +0 -37
  119. package/src/azion/extended-components/_dropdown.scss +0 -10
  120. package/src/azion/extended-components/_dropdownitem.scss +0 -13
  121. package/src/azion/extended-components/_inlinemessage.scss +0 -10
  122. package/src/azion/extended-components/_inputnumber.scss +0 -40
  123. package/src/azion/extended-components/_inputpassword.scss +0 -4
  124. package/src/azion/extended-components/_inputswitch.scss +0 -53
  125. package/src/azion/extended-components/_listbox.scss +0 -35
  126. package/src/azion/extended-components/_markdown.scss +0 -135
  127. package/src/azion/extended-components/_menuitem.scss +0 -22
  128. package/src/azion/extended-components/_multiselect.scss +0 -167
  129. package/src/azion/extended-components/_overlaypanel.scss +0 -18
  130. package/src/azion/extended-components/_picklist.scss +0 -25
  131. package/src/azion/extended-components/_progressbar.scss +0 -6
  132. package/src/azion/extended-components/_radiobutton.scss +0 -63
  133. package/src/azion/extended-components/_selectbutton.scss +0 -36
  134. package/src/azion/extended-components/_sidebar.scss +0 -28
  135. package/src/azion/extended-components/_splitbutton.scss +0 -22
  136. package/src/azion/extended-components/_tabmenu.scss +0 -21
  137. package/src/azion/extended-components/_tabview.scss +0 -41
  138. package/src/azion/extended-components/_tag.scss +0 -47
  139. package/src/azion/extended-components/_toast.scss +0 -9
  140. package/src/azion/extended-components/_tooltip.scss +0 -7
  141. package/src/azion/extended-components/_treeselect.scss +0 -10
  142. package/src/azion/extended-components/jsonform/_inputcheckbox.scss +0 -41
  143. package/src/azion/extended-components/jsonform/_inputtext.scss +0 -26
  144. package/src/azion/extended-components/jsonform/_label.scss +0 -185
  145. package/src/azion/extended-components/jsonform/_select.scss +0 -34
  146. package/src/azion/theme-base/_colors.scss +0 -18
  147. package/src/azion/theme-base/_common.scss +0 -75
  148. package/src/azion/theme-base/_components.scss +0 -103
  149. package/src/azion/theme-base/_mixins.scss +0 -250
  150. package/src/azion/theme-base/components/button/_button.scss +0 -567
  151. package/src/azion/theme-base/components/button/_speeddial.scss +0 -97
  152. package/src/azion/theme-base/components/button/_splitbutton.scss +0 -390
  153. package/src/azion/theme-base/components/data/_carousel.scss +0 -37
  154. package/src/azion/theme-base/components/data/_datatable.scss +0 -347
  155. package/src/azion/theme-base/components/data/_dataview.scss +0 -47
  156. package/src/azion/theme-base/components/data/_filter.scss +0 -138
  157. package/src/azion/theme-base/components/data/_orderlist.scss +0 -70
  158. package/src/azion/theme-base/components/data/_organizationchart.scss +0 -50
  159. package/src/azion/theme-base/components/data/_paginator.scss +0 -92
  160. package/src/azion/theme-base/components/data/_picklist.scss +0 -70
  161. package/src/azion/theme-base/components/data/_timeline.scss +0 -38
  162. package/src/azion/theme-base/components/data/_tree.scss +0 -90
  163. package/src/azion/theme-base/components/data/_treetable.scss +0 -251
  164. package/src/azion/theme-base/components/file/_fileupload.scss +0 -82
  165. package/src/azion/theme-base/components/input/_autocomplete.scss +0 -114
  166. package/src/azion/theme-base/components/input/_calendar.scss +0 -251
  167. package/src/azion/theme-base/components/input/_cascadeselect.scss +0 -106
  168. package/src/azion/theme-base/components/input/_checkbox.scss +0 -86
  169. package/src/azion/theme-base/components/input/_chips.scss +0 -53
  170. package/src/azion/theme-base/components/input/_colorpicker.scss +0 -18
  171. package/src/azion/theme-base/components/input/_dropdown.scss +0 -147
  172. package/src/azion/theme-base/components/input/_editor.scss +0 -122
  173. package/src/azion/theme-base/components/input/_inputgroup.scss +0 -74
  174. package/src/azion/theme-base/components/input/_inputnumber.scss +0 -5
  175. package/src/azion/theme-base/components/input/_inputswitch.scss +0 -62
  176. package/src/azion/theme-base/components/input/_inputtext.scss +0 -100
  177. package/src/azion/theme-base/components/input/_listbox.scss +0 -89
  178. package/src/azion/theme-base/components/input/_multiselect.scss +0 -166
  179. package/src/azion/theme-base/components/input/_password.scss +0 -33
  180. package/src/azion/theme-base/components/input/_radiobutton.scss +0 -78
  181. package/src/azion/theme-base/components/input/_rating.scss +0 -60
  182. package/src/azion/theme-base/components/input/_selectbutton.scss +0 -50
  183. package/src/azion/theme-base/components/input/_slider.scss +0 -49
  184. package/src/azion/theme-base/components/input/_togglebutton.scss +0 -52
  185. package/src/azion/theme-base/components/input/_treeselect.scss +0 -91
  186. package/src/azion/theme-base/components/menu/_breadcrumb.scss +0 -42
  187. package/src/azion/theme-base/components/menu/_contextmenu.scss +0 -39
  188. package/src/azion/theme-base/components/menu/_dock.scss +0 -95
  189. package/src/azion/theme-base/components/menu/_megamenu.scss +0 -55
  190. package/src/azion/theme-base/components/menu/_menu.scss +0 -33
  191. package/src/azion/theme-base/components/menu/_menubar.scss +0 -141
  192. package/src/azion/theme-base/components/menu/_panelmenu.scss +0 -153
  193. package/src/azion/theme-base/components/menu/_steps.scss +0 -56
  194. package/src/azion/theme-base/components/menu/_tabmenu.scss +0 -49
  195. package/src/azion/theme-base/components/menu/_tieredmenu.scss +0 -43
  196. package/src/azion/theme-base/components/messages/_inlinemessage.scss +0 -64
  197. package/src/azion/theme-base/components/messages/_message.scss +0 -100
  198. package/src/azion/theme-base/components/messages/_toast.scss +0 -100
  199. package/src/azion/theme-base/components/misc/_avatar.scss +0 -30
  200. package/src/azion/theme-base/components/misc/_badge.scss +0 -48
  201. package/src/azion/theme-base/components/misc/_blockui.scss +0 -0
  202. package/src/azion/theme-base/components/misc/_chip.scss +0 -39
  203. package/src/azion/theme-base/components/misc/_inplace.scss +0 -17
  204. package/src/azion/theme-base/components/misc/_progressbar.scss +0 -17
  205. package/src/azion/theme-base/components/misc/_progressspinner.scss +0 -49
  206. package/src/azion/theme-base/components/misc/_scrolltop.scss +0 -25
  207. package/src/azion/theme-base/components/misc/_skeleton.scss +0 -8
  208. package/src/azion/theme-base/components/misc/_tag.scss +0 -40
  209. package/src/azion/theme-base/components/misc/_terminal.scss +0 -12
  210. package/src/azion/theme-base/components/multimedia/_galleria.scss +0 -151
  211. package/src/azion/theme-base/components/multimedia/_image.scss +0 -54
  212. package/src/azion/theme-base/components/overlay/_confirmpopup.scss +0 -72
  213. package/src/azion/theme-base/components/overlay/_dialog.scss +0 -64
  214. package/src/azion/theme-base/components/overlay/_overlaypanel.scss +0 -38
  215. package/src/azion/theme-base/components/overlay/_sidebar.scss +0 -23
  216. package/src/azion/theme-base/components/overlay/_tooltip.scss +0 -33
  217. package/src/azion/theme-base/components/panel/_accordion.scss +0 -118
  218. package/src/azion/theme-base/components/panel/_card.scss +0 -30
  219. package/src/azion/theme-base/components/panel/_divider.scss +0 -40
  220. package/src/azion/theme-base/components/panel/_fieldset.scss +0 -51
  221. package/src/azion/theme-base/components/panel/_panel.scss +0 -47
  222. package/src/azion/theme-base/components/panel/_scrollpanel.scss +0 -11
  223. package/src/azion/theme-base/components/panel/_splitter.scss +0 -24
  224. package/src/azion/theme-base/components/panel/_tabview.scss +0 -66
  225. package/src/azion/theme-base/components/panel/_toolbar.scss +0 -11
  226. package/src/azion/theme-widget.scss +0 -9
  227. package/src/azion/theme.scss +0 -9
  228. package/src/azion/variables/_button.scss +0 -438
  229. package/src/azion/variables/_data.scss +0 -346
  230. package/src/azion/variables/_form.scss +0 -570
  231. package/src/azion/variables/_general.scss +0 -149
  232. package/src/azion/variables/_media.scss +0 -231
  233. package/src/azion/variables/_menu.scss +0 -287
  234. package/src/azion/variables/_message.scss +0 -145
  235. package/src/azion/variables/_misc.scss +0 -143
  236. package/src/azion/variables/_overlay.scss +0 -67
  237. package/src/azion/variables/_panel.scss +0 -327
  238. package/src/tests/primitives.html +0 -293
  239. package/src/tests/theme.html +0 -310
  240. package/src/tests/tokens.html +0 -87
  241. package/src/tokens/semantic/animations.d.ts +0 -3
  242. package/src/tokens/semantic/animations.d.ts.map +0 -1
  243. package/src/tokens/semantic/animations.js +0 -80
  244. package/src/tokens/semantic/spacings.d.ts +0 -3
  245. package/src/tokens/semantic/spacings.d.ts.map +0 -1
  246. package/src/tokens/semantic/spacings.js +0 -163
  247. package/src/tokens/semantic/texts.d.ts +0 -3
  248. package/src/tokens/semantic/texts.d.ts.map +0 -1
  249. package/src/tokens/semantic/texts.js +0 -299
  250. package/tokens.js +0 -7
  251. package/widget.js +0 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@aziontech/theme",
3
3
  "type": "module",
4
- "version": "2.6.0",
4
+ "version": "4.0.0",
5
5
  "author": "aziontech",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -12,14 +12,11 @@
12
12
  "scripts": {
13
13
  "pack:dry": "npm pack --dry-run",
14
14
  "format": "prettier --write scripts/ src/",
15
+ "build": "pnpm build:tokens",
15
16
  "build:tokens": "node src/scripts/build-tokens.mjs",
16
- "build:tokens:v3": "node src/scripts/build-tokens.mjs --target=v3",
17
- "build:tokens:v4": "node src/scripts/build-tokens.mjs --target=v4",
18
- "build:css:v3": "pnpm build:tokens:v3 && tailwindcss -c dist/v3/tailwind.config.js -i dist/v3/globals.css -o dist/v3/output.css",
19
- "test:tokens:v3": "pnpm build:css:v3 && open src/tests/tokens.html",
20
17
  "clean:dts": "find src -name '*.d.ts' -delete && find src -name '*.d.ts.map' -delete",
21
18
  "build:dts": "pnpm clean:dts && vue-tsc --declaration --emitDeclarationOnly",
22
- "prepack": "pnpm build:dts"
19
+ "prepack": "pnpm build:tokens && pnpm build:dts"
23
20
  },
24
21
  "publishConfig": {
25
22
  "access": "public"
@@ -35,7 +32,6 @@
35
32
  "token-generator"
36
33
  ],
37
34
  "dependencies": {
38
- "tailwindcss": "^3.4.17",
39
35
  "vue-tsc": "^3.2.5"
40
36
  },
41
37
  "devDependencies": {
@@ -52,26 +48,13 @@
52
48
  "files": [
53
49
  "src/",
54
50
  "dist/",
55
- "LICENSE",
56
- "default.js",
57
- "tokens.js",
58
- "widget.js"
51
+ "LICENSE"
59
52
  ],
60
53
  "exports": {
61
- ".": "./default.js",
54
+ ".": "./dist/v4/globals.css",
62
55
  "./animations": "./src/tokens/primitives/animations/animate.js",
63
56
  "./colors": "./src/tokens/primitives/colors/colors.js",
64
57
  "./texts": "./src/tokens/semantic/texts.data.js",
65
- "./tailwind-preset": "./dist/v3/tailwind-preset.js",
66
- "./tailwind-preset/v3": "./dist/v3/tailwind-preset.js",
67
- "./tailwind/semantic-spacings-plugin": "./src/tokens/semantic/spacings.js",
68
- "./tailwind/semantic-texts-plugin": "./src/tokens/semantic/texts.js",
69
- "./tailwind/semantic-animations-plugin": "./src/tokens/semantic/animations.js",
70
- "./globals.css": "./dist/v3/globals.css",
71
- "./globals.scss": "./dist/v3/globals.scss",
72
- "./v3/globals.css": "./dist/v3/globals.css",
73
- "./v3/globals.scss": "./dist/v3/globals.scss",
74
- "./v4/globals.css": "./dist/v4/globals.css",
75
- "./v4/globals.scss": "./dist/v4/globals.scss"
58
+ "./theme-colors": "./src/scripts/compile-theme.js"
76
59
  }
77
60
  }
@@ -1,44 +1,41 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * Build design tokens into self-contained stylesheets and Tailwind configs.
3
+ * Build design tokens into a Tailwind v4 stylesheet.
4
4
  *
5
5
  * Usage:
6
- * node build-tokens.mjs # emit both v3 and v4
7
- * node build-tokens.mjs --target=v3 # emit dist/v3/ only
8
- * node build-tokens.mjs --target=v4 # emit dist/v4/ only
6
+ * node build-tokens.mjs
9
7
  *
10
- * v3 output (legacy preset model):
11
- * - dist/v3/globals.css @tailwind directives + @layer + responsive vars
12
- * - dist/v3/globals.scss identical bytes, .scss extension
13
- * - dist/v3/tailwind.config.js full CJS config (content + theme.extend)
14
- * - dist/v3/tailwind-preset.js ESM preset (theme.extend only)
8
+ * Output:
9
+ * - dist/v4/globals.css @import "tailwindcss" + @theme + :root @media + @keyframes
10
+ * - dist/v4/globals.scss identical bytes, .scss extension
15
11
  *
16
- * v4 output (CSS-first):
17
- * - dist/v4/globals.css @import "tailwindcss" + @theme + :root @media
18
- * - dist/v4/globals.scss identical bytes
19
- *
20
- * Shared schema: primitives come from `tokens/primitives/**` (already
21
- * declarative). Semantic responsive tokens come from
22
- * `tokens/semantic/{containers,spacings,texts}.data.js`.
12
+ * Inputs:
13
+ * - `tokens/primitives/**` declarative primitives (colors, spacings,
14
+ * typography, breakpoints, animations, …)
15
+ * - `tokens/semantic/{containers,spacings,texts}.data.js`
16
+ * responsive-shaped semantic tokens
17
+ * - `tokens/primitives/animations/{animate,keyframes}.js`
18
+ * animation utilities (`--animate-*`) + `@keyframes`
19
+ * definitions + extra CSS (transform-origin) for
20
+ * popup-scale-*.
23
21
  *
24
22
  * No external deps — node:fs/promises, node:path, node:url only.
25
23
  */
26
24
 
27
- import { mkdir, writeFile } from 'node:fs/promises';
25
+ import { mkdir, readFile, writeFile } from 'node:fs/promises';
28
26
  import { dirname, resolve } from 'node:path';
29
27
  import { fileURLToPath } from 'node:url';
30
28
 
29
+ import { animate } from '../tokens/primitives/animations/animate.js';
30
+ import { animateExtras, keyframes } from '../tokens/primitives/animations/keyframes.js';
31
31
  import { breakpoints } from '../tokens/primitives/breakpoints.js';
32
32
  import { buildTrees, flatten } from './compile-primitives.js';
33
- import { compileThemeCss } from './compile-theme.js';
33
+ import { compileThemeCss, compileThemeVars } from './compile-theme.js';
34
34
  import { containersData } from '../tokens/semantic/containers.data.js';
35
35
  import { spacingsData } from '../tokens/semantic/spacings.data.js';
36
36
  import { textsData } from '../tokens/semantic/texts.data.js';
37
- import { semanticColors } from '../tokens/semantic/colors.js';
38
- import { createCssVars } from './css-vars.js';
39
37
 
40
38
  const BREAKPOINT_ORDER = ['sm', 'md', 'lg', 'xl', '2xl'];
41
- const V3_SELECTOR = ':root, [data-theme=light], .azion.azion-light';
42
39
 
43
40
  const kebab = (s) => s.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`);
44
41
 
@@ -90,31 +87,25 @@ const formatStateDecls = (rules) =>
90
87
  .map(([prop, val]) => `${kebab(prop)}: ${val}`)
91
88
  .join('; ');
92
89
 
93
- const SEMANTIC_PREFIXES = ['--text-', '--background-', '--border-'];
94
- const isSemanticVar = (key) => SEMANTIC_PREFIXES.some((p) => key.startsWith(p));
95
- const pickSemantic = (vars) =>
96
- Object.fromEntries(Object.entries(vars).filter(([k]) => isSemanticVar(k)));
97
-
98
- const buildSemanticColorVars = () => {
99
- const { light, dark } = createCssVars();
100
- return { light: pickSemantic(light), dark: pickSemantic(dark) };
101
- };
102
-
103
90
  const buildFlatModel = () => ({
104
91
  primitives: flattenPrimitives(),
105
92
  containers: flattenSingleValue(containersData, (k) => `--container-${k}`),
106
93
  spacings: flattenSingleValue(spacingsData, (k) => `--${k}`),
107
94
  texts: flattenBundle(textsData),
108
- semanticColors: buildSemanticColorVars(),
109
95
  });
110
96
 
111
- // ─── 3. Shared formatting helpers ──────────────────────────────────────────
97
+ // ─── 3. Formatting helpers ─────────────────────────────────────────────────
112
98
  const formatVars = (vars, indent) =>
113
99
  Object.entries(vars)
114
100
  .map(([k, v]) => `${indent}${k}: ${v};`)
115
101
  .join('\n');
116
102
 
117
- /** Component classes (.text-*, .gap-*, .px-container) — identical in v3/v4. */
103
+ /**
104
+ * Container / spacing / animation-extra classes — emitted inside `@layer components`.
105
+ * These are used bare (never behind Tailwind variants), so component-layer is fine.
106
+ * Typography classes are NOT here; they ship as `@utility` (see emitTextUtilities)
107
+ * so that variant modifiers like `data-[size=medium]:text-button-md` compile.
108
+ */
118
109
  const emitComponentClasses = (indent = ' ') => {
119
110
  const lines = [];
120
111
 
@@ -131,197 +122,164 @@ const emitComponentClasses = (indent = ' ') => {
131
122
  }
132
123
 
133
124
  lines.push('');
134
- lines.push(`${indent}/* ── Texts ── */`);
135
- for (const [key, bundle] of Object.entries(textsData)) {
136
- const baseProps = Object.keys(bundle).filter((prop) => prop !== 'states');
137
- const decls = baseProps
138
- .map((prop) => `${kebab(prop)}: var(--${key}-${kebab(prop)});`)
125
+ lines.push(`${indent}/* ── Animation extras (properties beyond the animation shorthand) ── */`);
126
+ for (const [selector, decls] of Object.entries(animateExtras)) {
127
+ const body = Object.entries(decls)
128
+ .map(([prop, val]) => `${prop}: ${val};`)
139
129
  .join(' ');
140
- lines.push(`${indent}.${key} { ${decls} }`);
130
+ lines.push(`${indent}.${selector} { ${body} }`);
131
+ }
132
+
133
+ return lines.join('\n');
134
+ };
141
135
 
136
+ /**
137
+ * Emit typography classes as Tailwind v4 `@utility` blocks so they participate
138
+ * in variant compilation (`data-[size=medium]:text-button-md`, `hover:text-link`,
139
+ * etc.). `@layer components` classes are opaque to v4's variant resolver and
140
+ * their modifiers silently drop, leaving elements at the inherited 16px.
141
+ */
142
+ const emitTextUtilities = () => {
143
+ const blocks = [];
144
+ for (const [key, bundle] of Object.entries(textsData)) {
145
+ const baseProps = Object.keys(bundle).filter((prop) => prop !== 'states');
146
+ const declLines = baseProps.map(
147
+ (prop) => ` ${kebab(prop)}: var(--${key}-${kebab(prop)});`,
148
+ );
149
+ const nested = [];
142
150
  if (bundle.states) {
143
151
  for (const [pseudo, rules] of Object.entries(bundle.states)) {
144
152
  const pseudoSuffix = pseudoClassName(pseudo);
145
- lines.push(`${indent}.${key}:${pseudoSuffix} { ${formatStateDecls(rules)}; }`);
153
+ nested.push(` &:${pseudoSuffix} { ${formatStateDecls(rules)}; }`);
146
154
  }
147
155
  }
156
+ blocks.push(`@utility ${key} {\n${[...declLines, ...nested].join('\n')}\n}`);
148
157
 
149
158
  if (bundle.transition) {
150
- lines.push(`${indent}@media (prefers-reduced-motion: reduce) {`);
151
- lines.push(`${indent} .${key} { transition: none; }`);
152
- lines.push(`${indent}}`);
159
+ blocks.push(
160
+ `@media (prefers-reduced-motion: reduce) {\n .${key} { transition: none; }\n}`,
161
+ );
153
162
  }
154
163
  }
155
-
156
- return lines.join('\n');
164
+ return blocks.join('\n\n');
157
165
  };
158
166
 
159
- // ─── 4. v3 emission (@tailwind directives + @layer) ────────────────────────
160
- const emitMediaBlockV3 = (bp, vars) =>
161
- [
162
- ` @media (min-width: ${breakpoints[bp]}) {`,
163
- ` ${V3_SELECTOR} {`,
164
- formatVars(vars, ' '),
165
- ` }`,
166
- ` }`,
167
- ].join('\n');
168
-
169
- const V3_DARK_SELECTOR = '[data-theme=dark], .dark, .azion.azion-dark';
170
-
171
- const emitCssV3 = () => {
172
- const m = buildFlatModel();
173
-
174
- const sections = [
175
- { title: 'Primitives', vars: m.primitives },
176
- { title: 'Containers', vars: m.containers._ || {} },
177
- { title: 'Spacings', vars: m.spacings._ || {} },
178
- { title: 'Texts', vars: m.texts._ || {} },
179
- { title: 'Semantic colors', vars: m.semanticColors.light },
180
- ];
181
-
182
- const baseBody = sections
183
- .filter((s) => Object.keys(s.vars).length > 0)
184
- .map((s) => ` /* ── ${s.title} ── */\n${formatVars(s.vars, ' ')}`)
185
- .join('\n\n');
186
-
187
- const mediaBlocks = [];
188
- for (const bp of BREAKPOINT_ORDER) {
189
- const merged = {
190
- ...(m.containers[bp] || {}),
191
- ...(m.spacings[bp] || {}),
192
- ...(m.texts[bp] || {}),
193
- };
194
- if (Object.keys(merged).length > 0) mediaBlocks.push(emitMediaBlockV3(bp, merged));
195
- }
196
-
197
- return [
198
- '/* generated by build-tokens.mjs — target: v3 — do not edit */',
199
- '',
200
- '@tailwind components;',
201
- '@tailwind utilities;',
202
- '',
203
- `${V3_SELECTOR} {`,
204
- baseBody,
205
- '}',
206
- '',
207
- mediaBlocks.join('\n\n'),
208
- '',
209
- `${V3_DARK_SELECTOR} {`,
210
- ` /* ── Semantic colors (dark) ── */`,
211
- formatVars(m.semanticColors.dark, ' '),
212
- '}',
213
- '',
214
- '/* ── Theme semantics (primary, secondary, surfaces, feedback, …) ── */',
215
- compileThemeCss(),
216
- '',
217
- '@layer components {',
218
- emitComponentClasses(),
219
- '}',
220
- '',
221
- ].join('\n');
167
+ /**
168
+ * Emit semantic color utilities (`text-*`, `bg-*`, `border-*`, `ring-*`).
169
+ *
170
+ * Tailwind v4's auto-generated color utilities pull from `@theme { --color-* }`,
171
+ * but our semantic tokens live under domain-specific prefixes (`--text-default`,
172
+ * `--bg-canvas`, `--border-default`, `--primary`) so v3's preset generated the
173
+ * classes by axis instead. Without them, `text-primary`, `bg-surface`, and
174
+ * `border-default` (heavily used across the webkit components — unchanged
175
+ * from dev) compile to nothing under v4.
176
+ *
177
+ * Rules:
178
+ * - Prefix-keyed tokens (`bg-*`, `text-*`, `border-*`, `ring-*`) become one
179
+ * utility on the matching axis: `@utility bg-canvas { background-color: var(--bg-canvas); }`.
180
+ * - Bare semantic tokens (`primary`, `accent`, `danger`, `warning`, `success`,
181
+ * `info`, `secondary`, and their `-mask`/`-selected`/`-contrast`/`-border`
182
+ * suffixes) become three utilities so a consumer can use `bg-primary`,
183
+ * `text-primary`, `border-primary` interchangeably.
184
+ * - `code-sintax-*` tokens are consumer-composed via arbitrary values in code
185
+ * highlighters and don't need a utility (skipped).
186
+ */
187
+ const AXIS_BY_PREFIX = {
188
+ 'bg-': { utility: (k) => k, prop: 'background-color' },
189
+ 'text-': { utility: (k) => k, prop: 'color' },
190
+ 'border-': { utility: (k) => k, prop: 'border-color' },
191
+ 'ring-': { utility: (k) => k, prop: '--tw-ring-color' },
222
192
  };
223
193
 
224
- const treeToVars = (tree, prefix) => {
225
- const out = {};
226
- for (const [key, val] of Object.entries(tree)) {
227
- if (val && typeof val === 'object' && !Array.isArray(val)) {
228
- out[key] = treeToVars(val, `${prefix}-${key}`);
229
- } else {
230
- out[key] = `var(${prefix}-${key})`;
194
+ const isCodeSintax = (key) => key.startsWith('code-sintax-');
195
+
196
+ const emitSemanticColorUtilities = () => {
197
+ const { light } = compileThemeVars();
198
+ const keys = Object.keys(light).map((k) => k.replace(/^--/, ''));
199
+ const blocks = [];
200
+ // Skip utilities already defined as typography (textsData) — `text-link`
201
+ // there ships the hover/focus states and would be silently overridden by
202
+ // a bare color-only utility emitted afterwards.
203
+ const emitted = new Set(Object.keys(textsData));
204
+
205
+ for (const key of keys) {
206
+ if (isCodeSintax(key)) continue;
207
+ const prefixEntry = Object.entries(AXIS_BY_PREFIX).find(([prefix]) =>
208
+ key.startsWith(prefix),
209
+ );
210
+ if (prefixEntry) {
211
+ const [, axis] = prefixEntry;
212
+ const utility = axis.utility(key);
213
+ if (emitted.has(utility)) continue;
214
+ emitted.add(utility);
215
+ blocks.push(`@utility ${utility} { ${axis.prop}: var(--${key}); }`);
216
+ continue;
217
+ }
218
+ // Bare token — expose on all three color axes.
219
+ for (const [prefix, axis] of Object.entries(AXIS_BY_PREFIX)) {
220
+ if (prefix === 'ring-') continue; // ring is opt-in, not for every token
221
+ const utility = `${prefix}${key}`;
222
+ if (emitted.has(utility)) continue;
223
+ emitted.add(utility);
224
+ blocks.push(`@utility ${utility} { ${axis.prop}: var(--${key}); }`);
231
225
  }
232
226
  }
233
- return out;
234
- };
235
-
236
- const buildPresetData = () => {
237
- const { refsTree } = buildTrees();
238
- const colors = treeToVars(refsTree.color, '--color');
239
- const fontWeight = refsTree.typography?.['font-weight']
240
- ? treeToVars(refsTree.typography['font-weight'], '--font-weight')
241
- : {};
242
- const dropShadow = refsTree.effects?.['drop-shadow']
243
- ? treeToVars(refsTree.effects['drop-shadow'], '--drop-shadow')
244
- : {};
245
- const lineHeight = refsTree.typography?.leading
246
- ? treeToVars(refsTree.typography.leading, '--leading')
247
- : {};
248
- const letterSpacing = refsTree.typography?.tracking
249
- ? treeToVars(refsTree.typography.tracking, '--tracking')
250
- : {};
251
-
252
- const fontSize = {};
253
- for (const [key, bundle] of Object.entries(textsData)) {
254
- if (!('fontSize' in bundle)) continue;
255
- if (bundle.fontSize === 'inherit') continue;
256
- const meta = {};
257
- if ('lineHeight' in bundle) meta.lineHeight = `var(--${key}-line-height)`;
258
- if ('letterSpacing' in bundle) meta.letterSpacing = `var(--${key}-letter-spacing)`;
259
- if ('fontWeight' in bundle) meta.fontWeight = `var(--${key}-font-weight)`;
260
- fontSize[key.replace(/^text-/, '')] = [`var(--${key}-font-size)`, meta];
261
- }
262
-
263
- return {
264
- theme: {
265
- extend: {
266
- colors,
267
- fontSize,
268
- fontWeight,
269
- dropShadow,
270
- lineHeight,
271
- letterSpacing,
272
- textColor: semanticColors.text,
273
- backgroundColor: semanticColors.background,
274
- borderColor: semanticColors.border,
275
- },
276
- },
277
- };
227
+ return blocks.join('\n');
278
228
  };
279
229
 
280
- const emitPresetV3 = () => {
281
- const data = buildPresetData();
282
- return [
283
- '/* generated by build-tokens.mjs — target: v3 — do not edit */',
284
- `const preset = ${JSON.stringify(data, null, 2)};`,
285
- 'export default preset;',
286
- '',
230
+ /**
231
+ * Restore browser affordances that Tailwind v4's preflight removed.
232
+ * v3 shipped `button { cursor: pointer }` by default; v4 does not, so every
233
+ * interactive element loses the hand cursor unless a component overrides it.
234
+ * Disabled controls keep the default cursor.
235
+ */
236
+ const emitBaseLayer = () =>
237
+ [
238
+ '@layer base {',
239
+ ' button:not(:disabled),',
240
+ ' [role="button"]:not([aria-disabled="true"]),',
241
+ ' summary {',
242
+ ' cursor: pointer;',
243
+ ' }',
244
+ '}',
287
245
  ].join('\n');
288
- };
289
246
 
290
- const emitTailwindConfigV3 = () => {
291
- const data = buildPresetData();
292
- const config = {
293
- content: ['./src/tests/**/*.html'],
294
- darkMode: ['class', '[data-theme="dark"]'],
295
- theme: data.theme,
296
- plugins: [],
297
- };
298
- return [
299
- '/* generated by build-tokens.mjs — target: v3 — do not edit */',
300
- `/** @type {import('tailwindcss').Config} */`,
301
- `module.exports = ${JSON.stringify(config, null, 2)};`,
302
- '',
303
- ].join('\n');
247
+ /** Emit `@keyframes` blocks at the top level of the stylesheet. */
248
+ const emitKeyframes = () => {
249
+ const blocks = [];
250
+ for (const [name, steps] of Object.entries(keyframes)) {
251
+ const body = Object.entries(steps)
252
+ .map(([step, decls]) => ` ${step} { ${decls}; }`)
253
+ .join('\n');
254
+ blocks.push(`@keyframes ${name} {\n${body}\n}`);
255
+ }
256
+ return blocks.join('\n\n');
304
257
  };
305
258
 
306
- // ─── 5. v4 emission (@import "tailwindcss" + @theme) ───────────────────────
259
+ // ─── 4. v4 emission (@import "tailwindcss" + @theme) ───────────────────────
307
260
  /**
308
- * v4 puts color primitives under `@theme` so Tailwind auto-generates
309
- * `bg-gray-50`, `text-violet-500`, etc. Semantic tokens stay in plain `:root`
310
- * (with `@media` overrides) so we keep full control of the component classes.
261
+ * v4 puts color primitives, breakpoints, and animation shorthands under
262
+ * `@theme` so Tailwind auto-generates `bg-gray-50`, `text-violet-500`,
263
+ * `sm:` screens, and `animate-*` utilities. Semantic tokens stay in plain
264
+ * `:root` (with `@media` overrides) so we keep full control of the
265
+ * component classes.
311
266
  *
312
- * Notes on v4 conventions used:
313
- * - `@theme { --color-* }` → color utilities.
314
- * - `@theme { --breakpoint-* }` → screens.
267
+ * Notes:
268
+ * - `@theme { --color-* }` → color utilities.
269
+ * - `@theme { --breakpoint-* }` → screens (`sm:`, `md:`, …).
270
+ * - `@theme { --animate-* }` → `animate-*` utilities (the shorthand
271
+ * references a `@keyframes` emitted
272
+ * later in the file).
315
273
  * - Semantic shape/typography tokens are NOT in @theme — we own their
316
274
  * class definitions in @layer components and they swap responsively
317
275
  * via `:root @media` overrides.
318
276
  */
277
+ const V4_SELECTOR = ':root, [data-theme=light], .azion.azion-light';
278
+
319
279
  const emitCssV4 = () => {
320
280
  const m = buildFlatModel();
321
281
  const primitivesEntries = Object.entries(m.primitives);
322
282
 
323
- // Split primitives: color/breakpoint go in @theme; everything else (shape,
324
- // typography, effects, border, ring-offset) stays in :root.
325
283
  const themeVars = {};
326
284
  const rootPrimitiveVars = {};
327
285
  for (const [k, v] of primitivesEntries) {
@@ -329,6 +287,10 @@ const emitCssV4 = () => {
329
287
  else rootPrimitiveVars[k] = v;
330
288
  }
331
289
 
290
+ for (const [name, shorthand] of Object.entries(animate)) {
291
+ themeVars[`--animate-${name}`] = shorthand;
292
+ }
293
+
332
294
  const semanticBase = {
333
295
  ...rootPrimitiveVars,
334
296
  ...(m.containers._ || {}),
@@ -354,63 +316,68 @@ const emitCssV4 = () => {
354
316
  }
355
317
 
356
318
  return [
357
- '/* generated by build-tokens.mjs — target: v4 — do not edit */',
319
+ '/* generated by build-tokens.mjs — do not edit */',
358
320
  '',
359
321
  '@import "tailwindcss";',
360
322
  '',
323
+ '/*',
324
+ ' * `@aziontech/webkit` components use arbitrary values (`bg-[var(--x)]`) that',
325
+ ' * Tailwind v4 only picks up when the source files are inside the scan.',
326
+ ' * Auto-detect scans the CWD only, so we point `@source` at the webkit',
327
+ ' * package via a monorepo-relative path (this file is under',
328
+ ' * `packages/theme/dist/v4/`; walking up three levels reaches `packages/`).',
329
+ ' */',
330
+ '@source "../../../webkit/src";',
331
+ '',
361
332
  '@theme {',
362
333
  formatVars(themeVars, ' '),
363
334
  '}',
364
335
  '',
365
- ':root, [data-theme=light], .azion.azion-light {',
336
+ `${V4_SELECTOR} {`,
366
337
  formatVars(semanticBase, ' '),
367
338
  '',
368
339
  mediaBlocks.join('\n\n'),
369
340
  '}',
370
341
  '',
342
+ '/* ── Theme semantics (primary, secondary, surfaces, feedback, …) ── */',
343
+ compileThemeCss(),
344
+ '',
345
+ emitKeyframes(),
346
+ '',
371
347
  '@layer components {',
372
348
  emitComponentClasses(),
373
349
  '}',
374
350
  '',
351
+ emitTextUtilities(),
352
+ '',
353
+ emitSemanticColorUtilities(),
354
+ '',
355
+ emitBaseLayer(),
356
+ '',
375
357
  ].join('\n');
376
358
  };
377
359
 
378
- // ─── 6. Write to disk ──────────────────────────────────────────────────────
360
+ // ─── 5. Write to disk ──────────────────────────────────────────────────────
379
361
  const __dirname = dirname(fileURLToPath(import.meta.url));
380
362
  const distRoot = resolve(__dirname, '../../dist');
381
363
 
382
- const writeV3 = async () => {
383
- const dir = resolve(distRoot, 'v3');
384
- await mkdir(dir, { recursive: true });
385
- const css = emitCssV3();
386
- await writeFile(resolve(dir, 'globals.css'), css, 'utf8');
387
- await writeFile(resolve(dir, 'globals.scss'), css, 'utf8');
388
- await writeFile(resolve(dir, 'tailwind-preset.js'), emitPresetV3(), 'utf8');
389
- await writeFile(resolve(dir, 'tailwind.config.js'), emitTailwindConfigV3(), 'utf8');
390
- console.log(`✓ v3 → ${dir}`);
391
- };
392
-
393
- const writeV4 = async () => {
394
- const dir = resolve(distRoot, 'v4');
395
- await mkdir(dir, { recursive: true });
396
- const css = emitCssV4();
397
- await writeFile(resolve(dir, 'globals.css'), css, 'utf8');
398
- await writeFile(resolve(dir, 'globals.scss'), css, 'utf8');
399
- console.log(`✓ v4 → ${dir}`);
400
- };
401
-
402
- // ─── 7. CLI ────────────────────────────────────────────────────────────────
403
- const parseTarget = () => {
404
- const arg = process.argv.find((a) => a.startsWith('--target='));
405
- if (!arg) return 'all';
406
- const value = arg.slice('--target='.length).toLowerCase();
407
- if (!['v3', 'v4', 'all'].includes(value)) {
408
- console.error(`Unknown --target=${value}. Use v3, v4, or all.`);
409
- process.exit(1);
410
- }
411
- return value;
412
- };
413
-
414
- const target = parseTarget();
415
- if (target === 'v3' || target === 'all') await writeV3();
416
- if (target === 'v4' || target === 'all') await writeV4();
364
+ const fontsCss = await readFile(
365
+ resolve(__dirname, '../tokens/primitives/fonts.css'),
366
+ 'utf8',
367
+ );
368
+
369
+ const dir = resolve(distRoot, 'v4');
370
+ await mkdir(dir, { recursive: true });
371
+ // `@import` must precede every other at-rule (CSS spec); `@font-face` before
372
+ // `@import "tailwindcss"` would silently invalidate the import and skip
373
+ // Tailwind's layer setup / utility generation. Splice fonts in AFTER the
374
+ // import line by looking for the marker in the emitted CSS.
375
+ const rawCss = emitCssV4();
376
+ const IMPORT_LINE = '@import "tailwindcss";';
377
+ const importIdx = rawCss.indexOf(IMPORT_LINE);
378
+ if (importIdx === -1) throw new Error('emitCssV4 output is missing the tailwind import line');
379
+ const afterImport = importIdx + IMPORT_LINE.length;
380
+ const css = `${rawCss.slice(0, afterImport)}\n\n${fontsCss}${rawCss.slice(afterImport)}`;
381
+ await writeFile(resolve(dir, 'globals.css'), css, 'utf8');
382
+ await writeFile(resolve(dir, 'globals.scss'), css, 'utf8');
383
+ console.log(`✓ v4 → ${dir}`);