@digdir/designsystemet 0.0.0-chore-remove-cli-tsx-20260701060359

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 (266) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +104 -0
  3. package/dist/bin/config.d.ts +14 -0
  4. package/dist/bin/config.d.ts.map +1 -0
  5. package/dist/bin/config.js +58 -0
  6. package/dist/bin/config.js.map +1 -0
  7. package/dist/bin/designsystemet.d.ts +1 -0
  8. package/dist/bin/designsystemet.js +174 -0
  9. package/dist/bin/designsystemet.js.map +1 -0
  10. package/dist/bin/options.d.ts +24 -0
  11. package/dist/bin/options.d.ts.map +1 -0
  12. package/dist/bin/options.js +25 -0
  13. package/dist/bin/options.js.map +1 -0
  14. package/dist/config.schema.json +181 -0
  15. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BorderValues.js +11 -0
  16. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BorderValues.js.map +1 -0
  17. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BoxShadowTypes.js +10 -0
  18. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BoxShadowTypes.js.map +1 -0
  19. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BoxShadowValues.js +15 -0
  20. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/BoxShadowValues.js.map +1 -0
  21. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/ColorModifierTypes.js +12 -0
  22. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/ColorModifierTypes.js.map +1 -0
  23. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/ColorSpaceTypes.js +12 -0
  24. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/ColorSpaceTypes.js.map +1 -0
  25. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/Properties.js +55 -0
  26. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/Properties.js.map +1 -0
  27. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/StrokeStyleValues.js +16 -0
  28. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/StrokeStyleValues.js.map +1 -0
  29. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenSetStatus.d.ts +11 -0
  30. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenSetStatus.d.ts.map +1 -0
  31. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenSetStatus.js +11 -0
  32. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenSetStatus.js.map +1 -0
  33. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenTypes.js +34 -0
  34. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenTypes.js.map +1 -0
  35. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TypographyValues.js +17 -0
  36. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TypographyValues.js.map +1 -0
  37. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/types/ThemeObject.d.ts +16 -0
  38. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/types/ThemeObject.d.ts.map +1 -0
  39. package/dist/node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/types/index.js +11 -0
  40. package/dist/package.js +7 -0
  41. package/dist/package.js.map +1 -0
  42. package/dist/src/automigrate.d.ts +5 -0
  43. package/dist/src/automigrate.d.ts.map +1 -0
  44. package/dist/src/automigrate.js +35 -0
  45. package/dist/src/automigrate.js.map +1 -0
  46. package/dist/src/colors/colorMetadata.d.ts +60 -0
  47. package/dist/src/colors/colorMetadata.d.ts.map +1 -0
  48. package/dist/src/colors/colorMetadata.js +261 -0
  49. package/dist/src/colors/colorMetadata.js.map +1 -0
  50. package/dist/src/colors/index.d.ts +5 -0
  51. package/dist/src/colors/index.js +5 -0
  52. package/dist/src/colors/theme.d.ts +34 -0
  53. package/dist/src/colors/theme.d.ts.map +1 -0
  54. package/dist/src/colors/theme.js +113 -0
  55. package/dist/src/colors/theme.js.map +1 -0
  56. package/dist/src/colors/types.d.ts +67 -0
  57. package/dist/src/colors/types.d.ts.map +1 -0
  58. package/dist/src/colors/types.js +26 -0
  59. package/dist/src/colors/types.js.map +1 -0
  60. package/dist/src/colors/utils.d.ts +132 -0
  61. package/dist/src/colors/utils.d.ts.map +1 -0
  62. package/dist/src/colors/utils.js +246 -0
  63. package/dist/src/colors/utils.js.map +1 -0
  64. package/dist/src/index.d.ts +10 -0
  65. package/dist/src/index.js +11 -0
  66. package/dist/src/migrations/beta-to-v1.d.ts +5 -0
  67. package/dist/src/migrations/beta-to-v1.d.ts.map +1 -0
  68. package/dist/src/migrations/beta-to-v1.js +342 -0
  69. package/dist/src/migrations/beta-to-v1.js.map +1 -0
  70. package/dist/src/migrations/codemods/css/plugins.d.ts +9 -0
  71. package/dist/src/migrations/codemods/css/plugins.d.ts.map +1 -0
  72. package/dist/src/migrations/codemods/css/plugins.js +37 -0
  73. package/dist/src/migrations/codemods/css/plugins.js.map +1 -0
  74. package/dist/src/migrations/codemods/css/run.d.ts +14 -0
  75. package/dist/src/migrations/codemods/css/run.d.ts.map +1 -0
  76. package/dist/src/migrations/codemods/css/run.js +25 -0
  77. package/dist/src/migrations/codemods/css/run.js.map +1 -0
  78. package/dist/src/migrations/color-rename-next49.d.ts +5 -0
  79. package/dist/src/migrations/color-rename-next49.d.ts.map +1 -0
  80. package/dist/src/migrations/color-rename-next49.js +48 -0
  81. package/dist/src/migrations/color-rename-next49.js.map +1 -0
  82. package/dist/src/migrations/flatten-color-categories.d.ts +12 -0
  83. package/dist/src/migrations/flatten-color-categories.d.ts.map +1 -0
  84. package/dist/src/migrations/flatten-color-categories.js +58 -0
  85. package/dist/src/migrations/flatten-color-categories.js.map +1 -0
  86. package/dist/src/migrations/index.d.ts +17 -0
  87. package/dist/src/migrations/index.d.ts.map +1 -0
  88. package/dist/src/migrations/index.js +13 -0
  89. package/dist/src/migrations/index.js.map +1 -0
  90. package/dist/src/schemas/helpers.d.ts +42 -0
  91. package/dist/src/schemas/helpers.d.ts.map +1 -0
  92. package/dist/src/schemas/helpers.js +96 -0
  93. package/dist/src/schemas/helpers.js.map +1 -0
  94. package/dist/src/schemas/v1/schema.d.ts +173 -0
  95. package/dist/src/schemas/v1/schema.d.ts.map +1 -0
  96. package/dist/src/schemas/v1/schema.js +65 -0
  97. package/dist/src/schemas/v1/schema.js.map +1 -0
  98. package/dist/src/schemas/v1.1/schema.d.ts +165 -0
  99. package/dist/src/schemas/v1.1/schema.d.ts.map +1 -0
  100. package/dist/src/schemas/v1.1/schema.js +56 -0
  101. package/dist/src/schemas/v1.1/schema.js.map +1 -0
  102. package/dist/src/tokens/build.d.ts +8 -0
  103. package/dist/src/tokens/build.d.ts.map +1 -0
  104. package/dist/src/tokens/build.js +43 -0
  105. package/dist/src/tokens/build.js.map +1 -0
  106. package/dist/src/tokens/create/files.d.ts +19 -0
  107. package/dist/src/tokens/create/files.d.ts.map +1 -0
  108. package/dist/src/tokens/create/files.js +48 -0
  109. package/dist/src/tokens/create/files.js.map +1 -0
  110. package/dist/src/tokens/create/generators/$designsystemet.d.ts +8 -0
  111. package/dist/src/tokens/create/generators/$designsystemet.d.ts.map +1 -0
  112. package/dist/src/tokens/create/generators/$designsystemet.js +12 -0
  113. package/dist/src/tokens/create/generators/$designsystemet.js.map +1 -0
  114. package/dist/src/tokens/create/generators/$metadata.d.ts +15 -0
  115. package/dist/src/tokens/create/generators/$metadata.d.ts.map +1 -0
  116. package/dist/src/tokens/create/generators/$metadata.js +25 -0
  117. package/dist/src/tokens/create/generators/$metadata.js.map +1 -0
  118. package/dist/src/tokens/create/generators/$themes.d.ts +28 -0
  119. package/dist/src/tokens/create/generators/$themes.d.ts.map +1 -0
  120. package/dist/src/tokens/create/generators/$themes.js +158 -0
  121. package/dist/src/tokens/create/generators/$themes.js.map +1 -0
  122. package/dist/src/tokens/create/generators/primitives/color-scheme.d.ts +9 -0
  123. package/dist/src/tokens/create/generators/primitives/color-scheme.d.ts.map +1 -0
  124. package/dist/src/tokens/create/generators/primitives/color-scheme.js +71 -0
  125. package/dist/src/tokens/create/generators/primitives/color-scheme.js.map +1 -0
  126. package/dist/src/tokens/create/generators/primitives/globals.d.ts +7 -0
  127. package/dist/src/tokens/create/generators/primitives/globals.d.ts.map +1 -0
  128. package/dist/src/tokens/create/generators/primitives/globals.js +144 -0
  129. package/dist/src/tokens/create/generators/primitives/globals.js.map +1 -0
  130. package/dist/src/tokens/create/generators/primitives/size.d.ts +8 -0
  131. package/dist/src/tokens/create/generators/primitives/size.d.ts.map +1 -0
  132. package/dist/src/tokens/create/generators/primitives/size.js +149 -0
  133. package/dist/src/tokens/create/generators/primitives/size.js.map +1 -0
  134. package/dist/src/tokens/create/generators/primitives/typography.d.ts +10 -0
  135. package/dist/src/tokens/create/generators/primitives/typography.d.ts.map +1 -0
  136. package/dist/src/tokens/create/generators/primitives/typography.js +218 -0
  137. package/dist/src/tokens/create/generators/primitives/typography.js.map +1 -0
  138. package/dist/src/tokens/create/generators/semantic/color.d.ts +7 -0
  139. package/dist/src/tokens/create/generators/semantic/color.d.ts.map +1 -0
  140. package/dist/src/tokens/create/generators/semantic/color.js +19 -0
  141. package/dist/src/tokens/create/generators/semantic/color.js.map +1 -0
  142. package/dist/src/tokens/create/generators/semantic/style.d.ts +7 -0
  143. package/dist/src/tokens/create/generators/semantic/style.d.ts.map +1 -0
  144. package/dist/src/tokens/create/generators/semantic/style.js +420 -0
  145. package/dist/src/tokens/create/generators/semantic/style.js.map +1 -0
  146. package/dist/src/tokens/create/generators/themes/theme.d.ts +7 -0
  147. package/dist/src/tokens/create/generators/themes/theme.d.ts.map +1 -0
  148. package/dist/src/tokens/create/generators/themes/theme.js +105 -0
  149. package/dist/src/tokens/create/generators/themes/theme.js.map +1 -0
  150. package/dist/src/tokens/create.d.ts +10 -0
  151. package/dist/src/tokens/create.d.ts.map +1 -0
  152. package/dist/src/tokens/create.js +40 -0
  153. package/dist/src/tokens/create.js.map +1 -0
  154. package/dist/src/tokens/format.d.ts +19 -0
  155. package/dist/src/tokens/format.d.ts.map +1 -0
  156. package/dist/src/tokens/format.js +42 -0
  157. package/dist/src/tokens/format.js.map +1 -0
  158. package/dist/src/tokens/generate-config.d.ts +14 -0
  159. package/dist/src/tokens/generate-config.d.ts.map +1 -0
  160. package/dist/src/tokens/generate-config.js +154 -0
  161. package/dist/src/tokens/generate-config.js.map +1 -0
  162. package/dist/src/tokens/index.d.ts +5 -0
  163. package/dist/src/tokens/index.js +4 -0
  164. package/dist/src/tokens/process/configs/color.d.ts +8 -0
  165. package/dist/src/tokens/process/configs/color.d.ts.map +1 -0
  166. package/dist/src/tokens/process/configs/color.js +50 -0
  167. package/dist/src/tokens/process/configs/color.js.map +1 -0
  168. package/dist/src/tokens/process/configs/semantic.d.ts +7 -0
  169. package/dist/src/tokens/process/configs/semantic.d.ts.map +1 -0
  170. package/dist/src/tokens/process/configs/semantic.js +49 -0
  171. package/dist/src/tokens/process/configs/semantic.js.map +1 -0
  172. package/dist/src/tokens/process/configs/shared.d.ts +14 -0
  173. package/dist/src/tokens/process/configs/shared.d.ts.map +1 -0
  174. package/dist/src/tokens/process/configs/shared.js +21 -0
  175. package/dist/src/tokens/process/configs/shared.js.map +1 -0
  176. package/dist/src/tokens/process/configs/size-mode.d.ts +7 -0
  177. package/dist/src/tokens/process/configs/size-mode.d.ts.map +1 -0
  178. package/dist/src/tokens/process/configs/size-mode.js +30 -0
  179. package/dist/src/tokens/process/configs/size-mode.js.map +1 -0
  180. package/dist/src/tokens/process/configs/size.d.ts +7 -0
  181. package/dist/src/tokens/process/configs/size.d.ts.map +1 -0
  182. package/dist/src/tokens/process/configs/size.js +36 -0
  183. package/dist/src/tokens/process/configs/size.js.map +1 -0
  184. package/dist/src/tokens/process/configs/type-scale.d.ts +7 -0
  185. package/dist/src/tokens/process/configs/type-scale.d.ts.map +1 -0
  186. package/dist/src/tokens/process/configs/type-scale.js +51 -0
  187. package/dist/src/tokens/process/configs/type-scale.js.map +1 -0
  188. package/dist/src/tokens/process/configs/typography.d.ts +7 -0
  189. package/dist/src/tokens/process/configs/typography.d.ts.map +1 -0
  190. package/dist/src/tokens/process/configs/typography.js +66 -0
  191. package/dist/src/tokens/process/configs/typography.js.map +1 -0
  192. package/dist/src/tokens/process/configs.d.ts +18 -0
  193. package/dist/src/tokens/process/configs.d.ts.map +1 -0
  194. package/dist/src/tokens/process/configs.js +74 -0
  195. package/dist/src/tokens/process/configs.js.map +1 -0
  196. package/dist/src/tokens/process/formats/css/color.d.ts +8 -0
  197. package/dist/src/tokens/process/formats/css/color.d.ts.map +1 -0
  198. package/dist/src/tokens/process/formats/css/color.js +64 -0
  199. package/dist/src/tokens/process/formats/css/color.js.map +1 -0
  200. package/dist/src/tokens/process/formats/css/semantic.d.ts +7 -0
  201. package/dist/src/tokens/process/formats/css/semantic.d.ts.map +1 -0
  202. package/dist/src/tokens/process/formats/css/semantic.js +31 -0
  203. package/dist/src/tokens/process/formats/css/semantic.js.map +1 -0
  204. package/dist/src/tokens/process/formats/css/size-mode.d.ts +7 -0
  205. package/dist/src/tokens/process/formats/css/size-mode.d.ts.map +1 -0
  206. package/dist/src/tokens/process/formats/css/size-mode.js +52 -0
  207. package/dist/src/tokens/process/formats/css/size-mode.js.map +1 -0
  208. package/dist/src/tokens/process/formats/css/size.d.ts +16 -0
  209. package/dist/src/tokens/process/formats/css/size.d.ts.map +1 -0
  210. package/dist/src/tokens/process/formats/css/size.js +95 -0
  211. package/dist/src/tokens/process/formats/css/size.js.map +1 -0
  212. package/dist/src/tokens/process/formats/css/type-scale.d.ts +7 -0
  213. package/dist/src/tokens/process/formats/css/type-scale.d.ts.map +1 -0
  214. package/dist/src/tokens/process/formats/css/type-scale.js +57 -0
  215. package/dist/src/tokens/process/formats/css/type-scale.js.map +1 -0
  216. package/dist/src/tokens/process/formats/css/typography.d.ts +7 -0
  217. package/dist/src/tokens/process/formats/css/typography.d.ts.map +1 -0
  218. package/dist/src/tokens/process/formats/css/typography.js +31 -0
  219. package/dist/src/tokens/process/formats/css/typography.js.map +1 -0
  220. package/dist/src/tokens/process/formats/css.d.ts +15 -0
  221. package/dist/src/tokens/process/formats/css.d.ts.map +1 -0
  222. package/dist/src/tokens/process/formats/css.js +20 -0
  223. package/dist/src/tokens/process/formats/css.js.map +1 -0
  224. package/dist/src/tokens/process/output/declarations.d.ts +9 -0
  225. package/dist/src/tokens/process/output/declarations.d.ts.map +1 -0
  226. package/dist/src/tokens/process/output/declarations.js +38 -0
  227. package/dist/src/tokens/process/output/declarations.js.map +1 -0
  228. package/dist/src/tokens/process/output/tailwind.d.ts +7 -0
  229. package/dist/src/tokens/process/output/tailwind.d.ts.map +1 -0
  230. package/dist/src/tokens/process/output/tailwind.js +47 -0
  231. package/dist/src/tokens/process/output/tailwind.js.map +1 -0
  232. package/dist/src/tokens/process/output/theme.d.ts +31 -0
  233. package/dist/src/tokens/process/output/theme.d.ts.map +1 -0
  234. package/dist/src/tokens/process/output/theme.js +85 -0
  235. package/dist/src/tokens/process/output/theme.js.map +1 -0
  236. package/dist/src/tokens/process/platform.d.ts +69 -0
  237. package/dist/src/tokens/process/platform.d.ts.map +1 -0
  238. package/dist/src/tokens/process/platform.js +128 -0
  239. package/dist/src/tokens/process/platform.js.map +1 -0
  240. package/dist/src/tokens/process/transformers.d.ts +10 -0
  241. package/dist/src/tokens/process/transformers.d.ts.map +1 -0
  242. package/dist/src/tokens/process/transformers.js +56 -0
  243. package/dist/src/tokens/process/transformers.js.map +1 -0
  244. package/dist/src/tokens/process/utils/getMultidimensionalThemes.d.ts +38 -0
  245. package/dist/src/tokens/process/utils/getMultidimensionalThemes.d.ts.map +1 -0
  246. package/dist/src/tokens/process/utils/getMultidimensionalThemes.js +112 -0
  247. package/dist/src/tokens/process/utils/getMultidimensionalThemes.js.map +1 -0
  248. package/dist/src/tokens/process/utils/kebab-case.d.ts +8 -0
  249. package/dist/src/tokens/process/utils/kebab-case.d.ts.map +1 -0
  250. package/dist/src/tokens/process/utils/kebab-case.js +11 -0
  251. package/dist/src/tokens/process/utils/kebab-case.js.map +1 -0
  252. package/dist/src/tokens/types.d.ts +71 -0
  253. package/dist/src/tokens/types.d.ts.map +1 -0
  254. package/dist/src/tokens/types.js +1 -0
  255. package/dist/src/tokens/utils.d.ts +62 -0
  256. package/dist/src/tokens/utils.d.ts.map +1 -0
  257. package/dist/src/tokens/utils.js +123 -0
  258. package/dist/src/tokens/utils.js.map +1 -0
  259. package/dist/src/types.d.ts +1 -0
  260. package/dist/src/types.js +10 -0
  261. package/dist/src/types.js.map +1 -0
  262. package/dist/src/utils/filesystem.d.ts +47 -0
  263. package/dist/src/utils/filesystem.d.ts.map +1 -0
  264. package/dist/src/utils/filesystem.js +117 -0
  265. package/dist/src/utils/filesystem.js.map +1 -0
  266. package/package.json +87 -0
@@ -0,0 +1,85 @@
1
+ import { version } from "../../../../package.js";
2
+ import { sizeComparator } from "../../utils.js";
3
+ import pc from "picocolors";
4
+ import * as R from "ramda";
5
+ //#region src/tokens/process/output/theme.ts
6
+ const defaultFileHeader = `build: v${version}`;
7
+ const getFileNameWithoutExtension = (path) => {
8
+ const pathSegments = path.split("/");
9
+ return pathSegments[pathSegments.length - 1].split(".").slice(0, -1).join(".");
10
+ };
11
+ /**
12
+ * Generates theme-specific CSS files from Style Dictionary build results.
13
+ *
14
+ * @param processedBuilds - The processed build results containing formatted CSS outputs
15
+ * grouped by themes and other permutations.
16
+ * @param fileHeader - Optional header to be included in the generated CSS files.
17
+ * @returns An array of `OutputFile` objects, each representing a theme-specific CSS file
18
+ * with its destination and content.
19
+ *
20
+ * @remarks
21
+ * - The function groups the build results by theme and ensures a deterministic order
22
+ * for the sections of the entry CSS file using a predefined sort order.
23
+ * - If a CSS section does not have a defined sort order the section is added to the end of the entry file.
24
+ * - The generated CSS files include a header with metadata and layer definitions.
25
+ */
26
+ const createThemeCSSFiles = ({ processedBuilds, fileHeader = defaultFileHeader }) => {
27
+ const groupedByTheme = {};
28
+ for (const [_, buildResults] of Object.entries(processedBuilds)) for (const buildResult of buildResults) {
29
+ const themeName = buildResult.permutation.theme;
30
+ const newOutputs = buildResult.formatted;
31
+ if (R.isNotEmpty(newOutputs)) {
32
+ const currentOutputs = groupedByTheme[themeName] ?? [];
33
+ groupedByTheme[themeName] = R.concat(currentOutputs, newOutputs);
34
+ }
35
+ }
36
+ /**
37
+ * Defines a sort order for the sections of the entry CSS file.
38
+ * This ensures a deterministic order, whereas earlier this was nondeterministic
39
+ */
40
+ const sortOrder = [
41
+ "size-mode/",
42
+ "type-scale",
43
+ "color-scheme/light",
44
+ "typography/secondary",
45
+ "size",
46
+ "semantic",
47
+ "color-scheme/dark",
48
+ "color-scheme/contrast",
49
+ "typography/primary",
50
+ "color/"
51
+ ];
52
+ const sortByDefinedOrder = R.sortBy((file) => {
53
+ const filePath = file.destination || "";
54
+ const sortIndex = sortOrder.findIndex((sortElement) => {
55
+ if (sortElement.endsWith("/")) return filePath.includes(sortElement);
56
+ return filePath.includes(`${sortElement}.css`);
57
+ });
58
+ if (sortIndex === -1) {
59
+ console.error(pc.yellow(`WARNING: CSS section does not have a defined sort order: ${filePath.replace(".css", "")}`));
60
+ console.log(pc.dim(`
61
+ The section will currently be added to the end of the entry file, but the exact
62
+ order may change due to nondeterminism.`.trim()));
63
+ return Infinity;
64
+ }
65
+ return sortIndex;
66
+ });
67
+ const header = `@charset "UTF-8";
68
+ /*
69
+ ${fileHeader}
70
+ */
71
+
72
+ `;
73
+ const sortAlphabetically = R.sort(R.ascend((x) => x.destination || ""));
74
+ const sortBySize = R.sortBy(R.pipe((s) => getFileNameWithoutExtension(s.destination ?? ""), sizeComparator));
75
+ const pickOutputs = R.map(R.view(R.lensProp("output")));
76
+ const themeCSSFile = R.pipe(sortAlphabetically, sortBySize, sortByDefinedOrder, pickOutputs, R.join("\n"), (content) => header + content);
77
+ return Object.entries(groupedByTheme).map(([theme, files]) => ({
78
+ destination: `${theme}.css`,
79
+ output: themeCSSFile(files)
80
+ }));
81
+ };
82
+ //#endregion
83
+ export { createThemeCSSFiles, defaultFileHeader };
84
+
85
+ //# sourceMappingURL=theme.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme.js","names":["pkg.version"],"sources":["../../../../../src/tokens/process/output/theme.ts"],"sourcesContent":["import pc from 'picocolors';\nimport * as R from 'ramda';\nimport pkg from '../../../../package.json' with { type: 'json' };\nimport type { OutputFile } from '../../types.ts';\nimport { sizeComparator } from '../../utils.ts';\nimport type { ProcessReturn } from '../platform.ts';\n\nexport const defaultFileHeader = `build: v${pkg.version}`;\n\ntype CreateThemeCSSFiles = {\n /** The processed build results containing formatted CSS outputs grouped by themes and other permutations. */\n processedBuilds: ProcessReturn;\n /** Optional header to be included in the generated CSS files. */\n fileHeader?: string;\n};\n\nconst getFileNameWithoutExtension = (path: string) => {\n const pathSegments = path.split('/');\n return pathSegments[pathSegments.length - 1].split('.').slice(0, -1).join('.');\n};\n\n/**\n * Generates theme-specific CSS files from Style Dictionary build results.\n *\n * @param processedBuilds - The processed build results containing formatted CSS outputs\n * grouped by themes and other permutations.\n * @param fileHeader - Optional header to be included in the generated CSS files.\n * @returns An array of `OutputFile` objects, each representing a theme-specific CSS file\n * with its destination and content.\n *\n * @remarks\n * - The function groups the build results by theme and ensures a deterministic order\n * for the sections of the entry CSS file using a predefined sort order.\n * - If a CSS section does not have a defined sort order the section is added to the end of the entry file.\n * - The generated CSS files include a header with metadata and layer definitions.\n */\nexport const createThemeCSSFiles = ({\n processedBuilds,\n fileHeader = defaultFileHeader,\n}: CreateThemeCSSFiles): OutputFile[] => {\n const groupedByTheme: Record<string, OutputFile[]> = {};\n\n for (const [_, buildResults] of Object.entries(processedBuilds)) {\n for (const buildResult of buildResults) {\n const themeName = buildResult.permutation.theme;\n const newOutputs = buildResult.formatted;\n if (R.isNotEmpty(newOutputs)) {\n const currentOutputs = groupedByTheme[themeName] ?? [];\n groupedByTheme[themeName] = R.concat(currentOutputs, newOutputs);\n }\n }\n }\n\n /**\n * Defines a sort order for the sections of the entry CSS file.\n * This ensures a deterministic order, whereas earlier this was nondeterministic\n */\n const sortOrder = [\n 'size-mode/',\n 'type-scale',\n 'color-scheme/light',\n 'typography/secondary',\n 'size',\n 'semantic',\n 'color-scheme/dark',\n 'color-scheme/contrast',\n 'typography/primary',\n 'color/',\n ];\n\n const sortByDefinedOrder = R.sortBy<OutputFile>((file) => {\n const filePath = file.destination || '';\n const sortIndex = sortOrder.findIndex((sortElement) => {\n if (sortElement.endsWith('/')) {\n return filePath.includes(sortElement);\n }\n return filePath.includes(`${sortElement}.css`);\n });\n if (sortIndex === -1) {\n // Ensure file names that don't have a specified sort order appear last\n console.error(\n pc.yellow(`WARNING: CSS section does not have a defined sort order: ${filePath.replace('.css', '')}`),\n );\n console.log(\n pc.dim(\n `\nThe section will currently be added to the end of the entry file, but the exact\norder may change due to nondeterminism.`.trim(),\n ),\n );\n\n return Infinity;\n }\n return sortIndex;\n });\n\n const header = `@charset \"UTF-8\";\n/*\n${fileHeader}\n*/\n\n`;\n\n const sortAlphabetically = R.sort<OutputFile>(R.ascend((x) => x.destination || ''));\n const sortBySize = R.sortBy<OutputFile>(\n R.pipe((s) => getFileNameWithoutExtension(s.destination ?? ''), sizeComparator),\n );\n const pickOutputs = R.map<OutputFile, string>(R.view(R.lensProp('output')));\n\n const themeCSSFile = R.pipe(\n sortAlphabetically,\n sortBySize,\n sortByDefinedOrder,\n pickOutputs,\n R.join('\\n'),\n (content) => header + content,\n );\n\n const themeCSSFiles: OutputFile[] = Object.entries(groupedByTheme).map(([theme, files]) => ({\n destination: `${theme}.css`,\n output: themeCSSFile(files),\n }));\n\n return themeCSSFiles;\n};\n"],"mappings":";;;;;AAOA,MAAa,oBAAoB,WAAWA;AAS5C,MAAM,+BAA+B,SAAiB;CACpD,MAAM,eAAe,KAAK,MAAM,GAAG;CACnC,OAAO,aAAa,aAAa,SAAS,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,GAAG;AAC/E;;;;;;;;;;;;;;;;AAiBA,MAAa,uBAAuB,EAClC,iBACA,aAAa,wBAC0B;CACvC,MAAM,iBAA+C,CAAC;CAEtD,KAAK,MAAM,CAAC,GAAG,iBAAiB,OAAO,QAAQ,eAAe,GAC5D,KAAK,MAAM,eAAe,cAAc;EACtC,MAAM,YAAY,YAAY,YAAY;EAC1C,MAAM,aAAa,YAAY;EAC/B,IAAI,EAAE,WAAW,UAAU,GAAG;GAC5B,MAAM,iBAAiB,eAAe,cAAc,CAAC;GACrD,eAAe,aAAa,EAAE,OAAO,gBAAgB,UAAU;EACjE;CACF;;;;;CAOF,MAAM,YAAY;EAChB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAEA,MAAM,qBAAqB,EAAE,QAAoB,SAAS;EACxD,MAAM,WAAW,KAAK,eAAe;EACrC,MAAM,YAAY,UAAU,WAAW,gBAAgB;GACrD,IAAI,YAAY,SAAS,GAAG,GAC1B,OAAO,SAAS,SAAS,WAAW;GAEtC,OAAO,SAAS,SAAS,GAAG,YAAY,KAAK;EAC/C,CAAC;EACD,IAAI,cAAc,IAAI;GAEpB,QAAQ,MACN,GAAG,OAAO,4DAA4D,SAAS,QAAQ,QAAQ,EAAE,GAAG,CACtG;GACA,QAAQ,IACN,GAAG,IACD;;yCAE+B,KAAK,CACtC,CACF;GAEA,OAAO;EACT;EACA,OAAO;CACT,CAAC;CAED,MAAM,SAAS;;EAEf,WAAW;;;;CAKX,MAAM,qBAAqB,EAAE,KAAiB,EAAE,QAAQ,MAAM,EAAE,eAAe,EAAE,CAAC;CAClF,MAAM,aAAa,EAAE,OACnB,EAAE,MAAM,MAAM,4BAA4B,EAAE,eAAe,EAAE,GAAG,cAAc,CAChF;CACA,MAAM,cAAc,EAAE,IAAwB,EAAE,KAAK,EAAE,SAAS,QAAQ,CAAC,CAAC;CAE1E,MAAM,eAAe,EAAE,KACrB,oBACA,YACA,oBACA,aACA,EAAE,KAAK,IAAI,IACV,YAAY,SAAS,OACxB;CAOA,OALoC,OAAO,QAAQ,cAAc,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY;EAC1F,aAAa,GAAG,MAAM;EACtB,QAAQ,aAAa,KAAK;CAC5B,EAEmB;AACrB"}
@@ -0,0 +1,69 @@
1
+ import { GetStyleDictionaryConfig } from "./configs/shared.js";
2
+ import { OutputFile, ThemePermutation, TokenSet } from "../types.js";
3
+ import { ProcessedThemeObject } from "./utils/getMultidimensionalThemes.js";
4
+ import { TransformedToken } from "style-dictionary/types";
5
+
6
+ //#region src/tokens/process/platform.d.ts
7
+ type SharedOptions = {
8
+ /** Enable verbose output */verbose: boolean; /** Set the default color for ":root" */
9
+ defaultColor?: string; /** Set the default size mode */
10
+ defaultSize?: string; /** Set the available size modes */
11
+ sizeModes?: string[]; /** Token Studio `$themes.json` content */
12
+ processed$themes: ProcessedThemeObject[]; /** Build token format map */
13
+ buildTokenFormats: Record<string, {
14
+ token: TransformedToken;
15
+ formatted: string;
16
+ }[]>;
17
+ };
18
+ type BuildOptions = {
19
+ type: 'build'; /** Design tokens path */
20
+ tokensDir: string; /** Tailwind CSS configuration */
21
+ tailwind?: boolean;
22
+ } & SharedOptions;
23
+ type FormatOptions = {
24
+ type: 'format'; /** Tokensets */
25
+ tokenSets: Map<string, TokenSet>;
26
+ } & SharedOptions;
27
+ type ProcessOptions = BuildOptions | FormatOptions;
28
+ type ProcessedBuildConfigs<T> = Record<keyof typeof buildConfigs, T>;
29
+ type ProcessReturn = ProcessedBuildConfigs<BuildResult[]>;
30
+ type BuildResult = {
31
+ permutation: ThemePermutation;
32
+ formatted: OutputFile[];
33
+ tokens: TransformedToken[];
34
+ };
35
+ declare let buildOptions: SharedOptions;
36
+ declare const buildConfigs: {
37
+ typography: {
38
+ getConfig: GetStyleDictionaryConfig;
39
+ dimensions: "typography"[];
40
+ };
41
+ sizeMode: {
42
+ getConfig: GetStyleDictionaryConfig;
43
+ dimensions: "size"[];
44
+ };
45
+ size: {
46
+ getConfig: GetStyleDictionaryConfig;
47
+ dimensions: "semantic"[];
48
+ };
49
+ typeScale: {
50
+ getConfig: GetStyleDictionaryConfig;
51
+ dimensions: "semantic"[];
52
+ };
53
+ 'color-scheme': {
54
+ getConfig: GetStyleDictionaryConfig;
55
+ dimensions: "color-scheme"[];
56
+ };
57
+ color: {
58
+ getConfig: GetStyleDictionaryConfig;
59
+ dimensions: "color"[];
60
+ };
61
+ semantic: {
62
+ getConfig: GetStyleDictionaryConfig;
63
+ dimensions: "semantic"[];
64
+ };
65
+ };
66
+ declare function processPlatform(options: ProcessOptions): Promise<ProcessReturn>;
67
+ //#endregion
68
+ export { BuildOptions, FormatOptions, ProcessReturn, buildOptions, processPlatform };
69
+ //# sourceMappingURL=platform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.d.ts","names":[],"sources":["../../../../src/tokens/process/platform.ts"],"mappings":";;;;;;KAQK,aAAA;8BAEH,OAAA,WAFG;EAIH,YAAA;EAEA,WAAA,WAM2C;EAJ3C,SAAA,aAIyB;EAFzB,gBAAA,EAAkB,oBAAA,IARlB;EAUA,iBAAA,EAAmB,MAAA;IAAiB,KAAA,EAAO,gBAAA;IAAkB,SAAA;EAAA;AAAA;AAAA,KAGnD,YAAA;EACV,IAAA,WAJoC;EAMpC,SAAA,UAN6D;EAQ7D,QAAA;AAAA,IACE,aAAa;AAAA,KAEL,aAAA;EACV,IAAA;EAEA,SAAA,EAAW,GAAA,SAAY,QAAA;AAAA,IACrB,aAAA;AAAA,KAEC,cAAA,GAAiB,YAAA,GAAe,aAAa;AAAA,KAE7C,qBAAA,MAA2B,MAAA,cAAoB,YAAA,EAAc,CAAA;AAAA,KAEtD,aAAA,GAAgB,qBAAqB,CAAC,WAAA;AAAA,KAE7C,WAAA;EACH,WAAA,EAAa,gBAAA;EACb,SAAA,EAAW,UAAA;EACX,MAAA,EAAQ,gBAAA;AAAA;AAAA,YAgBC,YAAA,EAAc,aAIxB;AAAA,cAOK,YAAA;;eAQiC,wBAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAEjB,eAAA,CAAgB,OAAA,EAAS,cAAA,GAAiB,OAAA,CAAQ,aAAA"}
@@ -0,0 +1,128 @@
1
+ import { configs, getConfigsForThemeDimensions } from "./configs.js";
2
+ import { getThemeColors } from "./utils/getMultidimensionalThemes.js";
3
+ import pc from "picocolors";
4
+ import * as R from "ramda";
5
+ import StyleDictionary from "style-dictionary";
6
+ //#region src/tokens/process/platform.ts
7
+ const initResult = {
8
+ formatted: [],
9
+ tokens: [],
10
+ permutation: {
11
+ "color-scheme": "",
12
+ color: "",
13
+ semantic: "",
14
+ size: "",
15
+ theme: "",
16
+ typography: ""
17
+ }
18
+ };
19
+ let buildOptions = {
20
+ verbose: false,
21
+ processed$themes: [],
22
+ buildTokenFormats: {}
23
+ };
24
+ const sd = new StyleDictionary();
25
+ const buildConfigs = {
26
+ typography: {
27
+ getConfig: configs.typographyVariables,
28
+ dimensions: ["typography"]
29
+ },
30
+ sizeMode: {
31
+ getConfig: configs.sizeModeVariables,
32
+ dimensions: ["size"]
33
+ },
34
+ size: {
35
+ getConfig: configs.sizeVariables,
36
+ dimensions: ["semantic"]
37
+ },
38
+ typeScale: {
39
+ getConfig: configs.typeScaleVariables,
40
+ dimensions: ["semantic"]
41
+ },
42
+ "color-scheme": {
43
+ getConfig: configs.colorSchemeVariables,
44
+ dimensions: ["color-scheme"]
45
+ },
46
+ color: {
47
+ getConfig: configs.colorVariables,
48
+ dimensions: ["color"]
49
+ },
50
+ semantic: {
51
+ getConfig: configs.semanticVariables,
52
+ dimensions: ["semantic"]
53
+ }
54
+ };
55
+ async function processPlatform(options) {
56
+ const { type, processed$themes } = options;
57
+ const platform = "css";
58
+ const tokenSets = type === "format" ? options.tokenSets : void 0;
59
+ const tokensDir = type === "build" ? options.tokensDir : void 0;
60
+ const UNSAFE_DEFAULT_COLOR = process.env.UNSAFE_DEFAULT_COLOR ?? "";
61
+ if (UNSAFE_DEFAULT_COLOR) console.warn(pc.yellow(`\n⚠️ UNSAFE_DEFAULT_COLOR is set to ${pc.blue(UNSAFE_DEFAULT_COLOR)}. This will override the default color.`));
62
+ /** For sharing build options in other files */
63
+ buildOptions = options;
64
+ buildOptions.defaultColor = UNSAFE_DEFAULT_COLOR;
65
+ if (!buildOptions.defaultColor) {
66
+ const customColors = getThemeColors(processed$themes);
67
+ buildOptions.defaultColor = R.head(customColors);
68
+ }
69
+ if (buildOptions.defaultColor) console.log(`\n🎨 Using ${pc.blue(buildOptions.defaultColor)} as default color`);
70
+ const sizeModes = processed$themes.filter((x) => x.group === "size").map((x) => x.name);
71
+ buildOptions.sizeModes = sizeModes;
72
+ if (!buildOptions.defaultSize) {
73
+ const defaultSize = R.head(sizeModes);
74
+ buildOptions.defaultSize = defaultSize;
75
+ }
76
+ if (buildOptions.defaultSize) console.log(`\n📏 Using ${pc.blue(buildOptions.defaultSize)} as default size`);
77
+ const buildAndSdConfigs = R.map((buildConfig) => {
78
+ const sdConfigs = getConfigsForThemeDimensions(buildConfig.getConfig, processed$themes, buildConfig.dimensions, {
79
+ tokensDir,
80
+ tokenSets
81
+ });
82
+ const unknownConfigs = buildConfig.dimensions.map((dimension) => sdConfigs.filter((x) => x.permutation[dimension] === "unknown"));
83
+ for (const unknowns of unknownConfigs) if (unknowns.length === sdConfigs.length) buildConfig.enabled = () => false;
84
+ return {
85
+ buildConfig,
86
+ sdConfigs
87
+ };
88
+ }, buildConfigs);
89
+ const processedBuilds = {
90
+ "color-scheme": [initResult],
91
+ color: [initResult],
92
+ semantic: [initResult],
93
+ typography: [initResult],
94
+ sizeMode: [initResult],
95
+ size: [initResult],
96
+ typeScale: [initResult]
97
+ };
98
+ try {
99
+ for (const [buildName, { buildConfig, sdConfigs }] of R.toPairs(buildAndSdConfigs)) {
100
+ if (!(buildConfig.enabled?.() ?? true)) continue;
101
+ if (sdConfigs.length > 0) {
102
+ console.log(`\n🍱 Building ${pc.green(buildConfig.name ?? buildName)}`);
103
+ processedBuilds[buildName] = await Promise.all(sdConfigs.map(async (sdConfig) => {
104
+ const { config, permutation } = sdConfig;
105
+ const modeMessage = ["theme", ...buildConfig.dimensions].map((x) => permutation[x]).join(" - ");
106
+ const logMessage = R.isNil(buildConfig.log) ? modeMessage : buildConfig?.log(sdConfig);
107
+ console.log(logMessage);
108
+ const sdOptions = { cache: true };
109
+ const sdExtended = await sd.extend(config);
110
+ const result = {
111
+ permutation,
112
+ formatted: await sdExtended.formatPlatform(platform, sdOptions),
113
+ tokens: (await sdExtended.getPlatformTokens(platform, sdOptions)).allTokens
114
+ };
115
+ return Promise.resolve(result);
116
+ }));
117
+ }
118
+ }
119
+ } catch (err) {
120
+ if (err instanceof Error) err.message = err.message.replace("log.verbosity \"verbose\" or use ", "");
121
+ throw err;
122
+ }
123
+ return processedBuilds;
124
+ }
125
+ //#endregion
126
+ export { buildOptions, processPlatform };
127
+
128
+ //# sourceMappingURL=platform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform.js","names":[],"sources":["../../../../src/tokens/process/platform.ts"],"sourcesContent":["import pc from 'picocolors';\nimport * as R from 'ramda';\nimport StyleDictionary from 'style-dictionary';\nimport type { TransformedToken } from 'style-dictionary/types';\nimport type { BuildConfig, OutputFile, ThemePermutation, TokenSet } from '../types.ts';\nimport { configs, getConfigsForThemeDimensions } from './configs.ts';\nimport { getThemeColors, type ProcessedThemeObject } from './utils/getMultidimensionalThemes.ts';\n\ntype SharedOptions = {\n /** Enable verbose output */\n verbose: boolean;\n /** Set the default color for \":root\" */\n defaultColor?: string;\n /** Set the default size mode */\n defaultSize?: string;\n /** Set the available size modes */\n sizeModes?: string[];\n /** Token Studio `$themes.json` content */\n processed$themes: ProcessedThemeObject[];\n /** Build token format map */\n buildTokenFormats: Record<string, { token: TransformedToken; formatted: string }[]>;\n};\n\nexport type BuildOptions = {\n type: 'build';\n /** Design tokens path */\n tokensDir: string;\n /** Tailwind CSS configuration */\n tailwind?: boolean;\n} & SharedOptions;\n\nexport type FormatOptions = {\n type: 'format';\n /** Tokensets */\n tokenSets: Map<string, TokenSet>;\n} & SharedOptions;\n\ntype ProcessOptions = BuildOptions | FormatOptions;\n\ntype ProcessedBuildConfigs<T> = Record<keyof typeof buildConfigs, T>;\n\nexport type ProcessReturn = ProcessedBuildConfigs<BuildResult[]>;\n\ntype BuildResult = {\n permutation: ThemePermutation;\n formatted: OutputFile[];\n tokens: TransformedToken[];\n};\n\nconst initResult: BuildResult = {\n formatted: [],\n tokens: [],\n permutation: {\n 'color-scheme': '',\n color: '',\n semantic: '',\n size: '',\n theme: '',\n typography: '',\n },\n};\n\nexport let buildOptions: SharedOptions = {\n verbose: false,\n processed$themes: [],\n buildTokenFormats: {},\n};\n\nconst sd = new StyleDictionary();\n\n/*\n * Declarative configuration of the build output\n */\nconst buildConfigs = {\n typography: { getConfig: configs.typographyVariables, dimensions: ['typography'] },\n sizeMode: { getConfig: configs.sizeModeVariables, dimensions: ['size'] },\n size: { getConfig: configs.sizeVariables, dimensions: ['semantic'] },\n typeScale: { getConfig: configs.typeScaleVariables, dimensions: ['semantic'] },\n 'color-scheme': { getConfig: configs.colorSchemeVariables, dimensions: ['color-scheme'] },\n color: { getConfig: configs.colorVariables, dimensions: ['color'] },\n semantic: { getConfig: configs.semanticVariables, dimensions: ['semantic'] },\n} satisfies Record<string, BuildConfig>;\n\nexport async function processPlatform(options: ProcessOptions): Promise<ProcessReturn> {\n const { type, processed$themes } = options;\n const platform = 'css';\n const tokenSets = type === 'format' ? options.tokenSets : undefined;\n const tokensDir = type === 'build' ? options.tokensDir : undefined;\n\n const UNSAFE_DEFAULT_COLOR = process.env.UNSAFE_DEFAULT_COLOR ?? '';\n if (UNSAFE_DEFAULT_COLOR) {\n console.warn(\n pc.yellow(\n `\\n⚠️ UNSAFE_DEFAULT_COLOR is set to ${pc.blue(UNSAFE_DEFAULT_COLOR)}. This will override the default color.`,\n ),\n );\n }\n\n /** For sharing build options in other files */\n buildOptions = options;\n buildOptions.defaultColor = UNSAFE_DEFAULT_COLOR;\n\n if (!buildOptions.defaultColor) {\n const customColors = getThemeColors(processed$themes);\n buildOptions.defaultColor = R.head(customColors);\n }\n\n if (buildOptions.defaultColor) {\n console.log(`\\n🎨 Using ${pc.blue(buildOptions.defaultColor)} as default color`);\n }\n\n const sizeModes = processed$themes.filter((x) => x.group === 'size').map((x) => x.name);\n buildOptions.sizeModes = sizeModes;\n if (!buildOptions.defaultSize) {\n const defaultSize = R.head(sizeModes);\n buildOptions.defaultSize = defaultSize;\n }\n if (buildOptions.defaultSize) {\n console.log(`\\n📏 Using ${pc.blue(buildOptions.defaultSize)} as default size`);\n }\n\n const buildAndSdConfigs = R.map((buildConfig: BuildConfig) => {\n const sdConfigs = getConfigsForThemeDimensions(buildConfig.getConfig, processed$themes, buildConfig.dimensions, {\n tokensDir,\n tokenSets,\n });\n\n // Disable build if all sdConfigs dimensions permutation are unknown\n const unknownConfigs = buildConfig.dimensions.map((dimension) =>\n sdConfigs.filter((x) => x.permutation[dimension] === 'unknown'),\n );\n for (const unknowns of unknownConfigs) {\n if (unknowns.length === sdConfigs.length) {\n buildConfig.enabled = () => false;\n }\n }\n\n return {\n buildConfig,\n sdConfigs,\n };\n }, buildConfigs);\n\n const processedBuilds: ProcessedBuildConfigs<Array<BuildResult>> = {\n 'color-scheme': [initResult],\n color: [initResult],\n semantic: [initResult],\n typography: [initResult],\n sizeMode: [initResult],\n size: [initResult],\n typeScale: [initResult],\n };\n\n try {\n for (const [buildName, { buildConfig, sdConfigs }] of R.toPairs(buildAndSdConfigs)) {\n if (!(buildConfig.enabled?.() ?? true)) {\n continue;\n }\n\n if (sdConfigs.length > 0) {\n console.log(`\\n🍱 Building ${pc.green(buildConfig.name ?? buildName)}`);\n\n const results = await Promise.all(\n sdConfigs.map(async (sdConfig) => {\n const { config, permutation } = sdConfig;\n\n const modes: Array<keyof ThemePermutation> = ['theme', ...buildConfig.dimensions];\n const modeMessage = modes.map((x) => permutation[x]).join(' - ');\n const logMessage = R.isNil(buildConfig.log) ? modeMessage : buildConfig?.log(sdConfig);\n console.log(logMessage);\n\n const sdOptions = { cache: true };\n const sdExtended = await sd.extend(config);\n const formatted = await sdExtended.formatPlatform(platform, sdOptions);\n const tokens = (await sdExtended.getPlatformTokens(platform, sdOptions)).allTokens;\n\n const result: BuildResult = {\n permutation,\n formatted: formatted as OutputFile[],\n tokens,\n };\n\n return Promise.resolve(result);\n }),\n );\n\n processedBuilds[buildName] = results;\n }\n }\n } catch (err) {\n // Fix crash error message from StyleDictionary from\n // > Use log.verbosity \"verbose\" or use CLI option --verbose for more details.\n // to\n // > Use CLI option --verbose for more details.\n if (err instanceof Error) {\n err.message = err.message.replace('log.verbosity \"verbose\" or use ', '');\n }\n throw err;\n }\n\n return processedBuilds;\n}\n"],"mappings":";;;;;;AAiDA,MAAM,aAA0B;CAC9B,WAAW,CAAC;CACZ,QAAQ,CAAC;CACT,aAAa;EACX,gBAAgB;EAChB,OAAO;EACP,UAAU;EACV,MAAM;EACN,OAAO;EACP,YAAY;CACd;AACF;AAEA,IAAW,eAA8B;CACvC,SAAS;CACT,kBAAkB,CAAC;CACnB,mBAAmB,CAAC;AACtB;AAEA,MAAM,KAAK,IAAI,gBAAgB;AAK/B,MAAM,eAAe;CACnB,YAAY;EAAE,WAAW,QAAQ;EAAqB,YAAY,CAAC,YAAY;CAAE;CACjF,UAAU;EAAE,WAAW,QAAQ;EAAmB,YAAY,CAAC,MAAM;CAAE;CACvE,MAAM;EAAE,WAAW,QAAQ;EAAe,YAAY,CAAC,UAAU;CAAE;CACnE,WAAW;EAAE,WAAW,QAAQ;EAAoB,YAAY,CAAC,UAAU;CAAE;CAC7E,gBAAgB;EAAE,WAAW,QAAQ;EAAsB,YAAY,CAAC,cAAc;CAAE;CACxF,OAAO;EAAE,WAAW,QAAQ;EAAgB,YAAY,CAAC,OAAO;CAAE;CAClE,UAAU;EAAE,WAAW,QAAQ;EAAmB,YAAY,CAAC,UAAU;CAAE;AAC7E;AAEA,eAAsB,gBAAgB,SAAiD;CACrF,MAAM,EAAE,MAAM,qBAAqB;CACnC,MAAM,WAAW;CACjB,MAAM,YAAY,SAAS,WAAW,QAAQ,YAAY,KAAA;CAC1D,MAAM,YAAY,SAAS,UAAU,QAAQ,YAAY,KAAA;CAEzD,MAAM,uBAAuB,QAAQ,IAAI,wBAAwB;CACjE,IAAI,sBACF,QAAQ,KACN,GAAG,OACD,uCAAuC,GAAG,KAAK,oBAAoB,EAAE,wCACvE,CACF;;CAIF,eAAe;CACf,aAAa,eAAe;CAE5B,IAAI,CAAC,aAAa,cAAc;EAC9B,MAAM,eAAe,eAAe,gBAAgB;EACpD,aAAa,eAAe,EAAE,KAAK,YAAY;CACjD;CAEA,IAAI,aAAa,cACf,QAAQ,IAAI,cAAc,GAAG,KAAK,aAAa,YAAY,EAAE,kBAAkB;CAGjF,MAAM,YAAY,iBAAiB,QAAQ,MAAM,EAAE,UAAU,MAAM,CAAC,CAAC,KAAK,MAAM,EAAE,IAAI;CACtF,aAAa,YAAY;CACzB,IAAI,CAAC,aAAa,aAAa;EAC7B,MAAM,cAAc,EAAE,KAAK,SAAS;EACpC,aAAa,cAAc;CAC7B;CACA,IAAI,aAAa,aACf,QAAQ,IAAI,cAAc,GAAG,KAAK,aAAa,WAAW,EAAE,iBAAiB;CAG/E,MAAM,oBAAoB,EAAE,KAAK,gBAA6B;EAC5D,MAAM,YAAY,6BAA6B,YAAY,WAAW,kBAAkB,YAAY,YAAY;GAC9G;GACA;EACF,CAAC;EAGD,MAAM,iBAAiB,YAAY,WAAW,KAAK,cACjD,UAAU,QAAQ,MAAM,EAAE,YAAY,eAAe,SAAS,CAChE;EACA,KAAK,MAAM,YAAY,gBACrB,IAAI,SAAS,WAAW,UAAU,QAChC,YAAY,gBAAgB;EAIhC,OAAO;GACL;GACA;EACF;CACF,GAAG,YAAY;CAEf,MAAM,kBAA6D;EACjE,gBAAgB,CAAC,UAAU;EAC3B,OAAO,CAAC,UAAU;EAClB,UAAU,CAAC,UAAU;EACrB,YAAY,CAAC,UAAU;EACvB,UAAU,CAAC,UAAU;EACrB,MAAM,CAAC,UAAU;EACjB,WAAW,CAAC,UAAU;CACxB;CAEA,IAAI;EACF,KAAK,MAAM,CAAC,WAAW,EAAE,aAAa,gBAAgB,EAAE,QAAQ,iBAAiB,GAAG;GAClF,IAAI,EAAE,YAAY,UAAU,KAAK,OAC/B;GAGF,IAAI,UAAU,SAAS,GAAG;IACxB,QAAQ,IAAI,iBAAiB,GAAG,MAAM,YAAY,QAAQ,SAAS,GAAG;IA0BtE,gBAAgB,aAAa,MAxBP,QAAQ,IAC5B,UAAU,IAAI,OAAO,aAAa;KAChC,MAAM,EAAE,QAAQ,gBAAgB;KAGhC,MAAM,cAAc,CAD0B,SAAS,GAAG,YAAY,UAC9C,CAAC,CAAC,KAAK,MAAM,YAAY,EAAE,CAAC,CAAC,KAAK,KAAK;KAC/D,MAAM,aAAa,EAAE,MAAM,YAAY,GAAG,IAAI,cAAc,aAAa,IAAI,QAAQ;KACrF,QAAQ,IAAI,UAAU;KAEtB,MAAM,YAAY,EAAE,OAAO,KAAK;KAChC,MAAM,aAAa,MAAM,GAAG,OAAO,MAAM;KAIzC,MAAM,SAAsB;MAC1B;MACA,WAAW,MALW,WAAW,eAAe,UAAU,SAAS;MAMnE,SALc,MAAM,WAAW,kBAAkB,UAAU,SAAS,EAAA,CAAG;KAMzE;KAEA,OAAO,QAAQ,QAAQ,MAAM;IAC/B,CAAC,CACH;GAGF;EACF;CACF,SAAS,KAAK;EAKZ,IAAI,eAAe,OACjB,IAAI,UAAU,IAAI,QAAQ,QAAQ,qCAAmC,EAAE;EAEzE,MAAM;CACR;CAEA,OAAO;AACT"}
@@ -0,0 +1,10 @@
1
+ import { Transform } from "style-dictionary/types";
2
+
3
+ //#region src/tokens/process/transformers.d.ts
4
+ declare const sizeRem: Transform;
5
+ declare const typographyName: Transform;
6
+ declare const resolveMath: Transform;
7
+ declare const unitless: Transform;
8
+ //#endregion
9
+ export { resolveMath, sizeRem, typographyName, unitless };
10
+ //# sourceMappingURL=transformers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformers.d.ts","names":[],"sources":["../../../../src/tokens/process/transformers.ts"],"mappings":";;;cAQa,OAAA,EAAS,SAyBrB;AAAA,cAEY,cAAA,EAAgB,SAS5B;AAAA,cAEY,WAAA,EAAa,SAWzB;AAAA,cAEY,QAAA,EAAU,SAMtB"}
@@ -0,0 +1,56 @@
1
+ import { getValue, pathStartsWithOneOf, typeEquals } from "../utils.js";
2
+ import * as R from "ramda";
3
+ import { checkAndEvaluateMath } from "@tokens-studio/sd-transforms";
4
+ //#region src/tokens/process/transformers.ts
5
+ const isPx = R.test(/\b\d+px\b/g);
6
+ const sizeRem = {
7
+ name: "ds/size/toRem",
8
+ type: "value",
9
+ transitive: true,
10
+ filter: (token) => {
11
+ const hasWantedType = typeEquals(["dimension", "fontsize"], token);
12
+ const hasWantedPath = pathStartsWithOneOf(["border-radius", "font-size"], token);
13
+ return hasWantedType && hasWantedPath;
14
+ },
15
+ transform: (token, config) => {
16
+ const value = getValue(token);
17
+ if (isPx(value)) {
18
+ const baseFont = config.basePxFontSize || 16;
19
+ const size = parseInt(value, 10);
20
+ if (size === 0) return "0";
21
+ return `${size / baseFont}rem`;
22
+ }
23
+ return value;
24
+ }
25
+ };
26
+ const typographyName = {
27
+ name: "name/typography",
28
+ type: "name",
29
+ transitive: true,
30
+ filter: (token) => pathStartsWithOneOf(["typography"], token),
31
+ transform: (token) => {
32
+ return token.name.replace("-typography", "");
33
+ }
34
+ };
35
+ const resolveMath = {
36
+ name: "ds/resolveMath",
37
+ type: "value",
38
+ transitive: true,
39
+ filter: (token) => {
40
+ const isValidValue = ["string", "object"].includes(typeof getValue(token));
41
+ const isTokenOfInterest = !pathStartsWithOneOf(["border-radius"], token);
42
+ return isValidValue && isTokenOfInterest;
43
+ },
44
+ transform: (token, platformCfg) => checkAndEvaluateMath(token, platformCfg.mathFractionDigits)
45
+ };
46
+ const unitless = {
47
+ name: "ds/unitless",
48
+ type: "value",
49
+ transitive: true,
50
+ filter: (token) => pathStartsWithOneOf(["size", "_size"], token),
51
+ transform: (token) => parseInt(getValue(token), 10)
52
+ };
53
+ //#endregion
54
+ export { resolveMath, sizeRem, typographyName, unitless };
55
+
56
+ //# sourceMappingURL=transformers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformers.js","names":[],"sources":["../../../../src/tokens/process/transformers.ts"],"sourcesContent":["import { checkAndEvaluateMath } from '@tokens-studio/sd-transforms';\nimport * as R from 'ramda';\nimport type { Transform } from 'style-dictionary/types';\n\nimport { getValue, pathStartsWithOneOf, typeEquals } from '../utils.ts';\n\nconst isPx = R.test(/\\b\\d+px\\b/g);\n\nexport const sizeRem: Transform = {\n name: 'ds/size/toRem',\n type: 'value',\n transitive: true,\n filter: (token) => {\n const hasWantedType = typeEquals(['dimension', 'fontsize'], token);\n const hasWantedPath = pathStartsWithOneOf(['border-radius', 'font-size' /*, ['_size', 'mode-font-size']*/], token);\n\n return hasWantedType && hasWantedPath;\n },\n transform: (token, config) => {\n const value = getValue<string>(token);\n\n if (isPx(value)) {\n const baseFont = (config.basePxFontSize as unknown as number) || 16;\n const size = parseInt(value, 10);\n\n if (size === 0) {\n return '0';\n }\n\n return `${size / baseFont}rem`;\n }\n return value;\n },\n};\n\nexport const typographyName: Transform = {\n name: 'name/typography',\n type: 'name',\n transitive: true,\n // expanded tokens have different type so we match on path instead\n filter: (token) => pathStartsWithOneOf(['typography'], token),\n transform: (token) => {\n return token.name.replace('-typography', '');\n },\n};\n\nexport const resolveMath: Transform = {\n name: 'ds/resolveMath',\n type: 'value',\n transitive: true,\n filter: (token) => {\n const isValidValue = ['string', 'object'].includes(typeof getValue(token));\n const isTokenOfInterest = !pathStartsWithOneOf(['border-radius'], token);\n\n return isValidValue && isTokenOfInterest;\n },\n transform: (token, platformCfg) => checkAndEvaluateMath(token, platformCfg.mathFractionDigits),\n};\n\nexport const unitless: Transform = {\n name: 'ds/unitless',\n type: 'value',\n transitive: true,\n filter: (token) => pathStartsWithOneOf(['size', '_size'], token),\n transform: (token) => parseInt(getValue<string>(token), 10),\n};\n"],"mappings":";;;;AAMA,MAAM,OAAO,EAAE,KAAK,YAAY;AAEhC,MAAa,UAAqB;CAChC,MAAM;CACN,MAAM;CACN,YAAY;CACZ,SAAS,UAAU;EACjB,MAAM,gBAAgB,WAAW,CAAC,aAAa,UAAU,GAAG,KAAK;EACjE,MAAM,gBAAgB,oBAAoB,CAAC,iBAAiB,WAA6C,GAAG,KAAK;EAEjH,OAAO,iBAAiB;CAC1B;CACA,YAAY,OAAO,WAAW;EAC5B,MAAM,QAAQ,SAAiB,KAAK;EAEpC,IAAI,KAAK,KAAK,GAAG;GACf,MAAM,WAAY,OAAO,kBAAwC;GACjE,MAAM,OAAO,SAAS,OAAO,EAAE;GAE/B,IAAI,SAAS,GACX,OAAO;GAGT,OAAO,GAAG,OAAO,SAAS;EAC5B;EACA,OAAO;CACT;AACF;AAEA,MAAa,iBAA4B;CACvC,MAAM;CACN,MAAM;CACN,YAAY;CAEZ,SAAS,UAAU,oBAAoB,CAAC,YAAY,GAAG,KAAK;CAC5D,YAAY,UAAU;EACpB,OAAO,MAAM,KAAK,QAAQ,eAAe,EAAE;CAC7C;AACF;AAEA,MAAa,cAAyB;CACpC,MAAM;CACN,MAAM;CACN,YAAY;CACZ,SAAS,UAAU;EACjB,MAAM,eAAe,CAAC,UAAU,QAAQ,CAAC,CAAC,SAAS,OAAO,SAAS,KAAK,CAAC;EACzE,MAAM,oBAAoB,CAAC,oBAAoB,CAAC,eAAe,GAAG,KAAK;EAEvE,OAAO,gBAAgB;CACzB;CACA,YAAY,OAAO,gBAAgB,qBAAqB,OAAO,YAAY,kBAAkB;AAC/F;AAEA,MAAa,WAAsB;CACjC,MAAM;CACN,MAAM;CACN,YAAY;CACZ,SAAS,UAAU,oBAAoB,CAAC,QAAQ,OAAO,GAAG,KAAK;CAC/D,YAAY,UAAU,SAAS,SAAiB,KAAK,GAAG,EAAE;AAC5D"}
@@ -0,0 +1,38 @@
1
+ import { ThemeDimension, ThemePermutation } from "../../types.js";
2
+ import { ThemeObject } from "../../../../node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/types/ThemeObject.js";
3
+
4
+ //#region src/tokens/process/utils/getMultidimensionalThemes.d.ts
5
+ /**
6
+ * Find the theme permutations that are relevant for the given theme dimensions.
7
+ *
8
+ * Technically, for the given dimensions all permutations are included, while for other
9
+ * dimensions the first permutation is used.
10
+ *
11
+ * @param processed$themes Theme objects from $themes.json (Tokens Studio)
12
+ * @param dimensions Which theme dimensions to return permutations for.
13
+ * 'theme' (e.g. altinn/digdir/uutilsynet) is always implicitly included.
14
+ * @returns the relevant theme permutations
15
+ */
16
+ declare const getMultidimensionalThemes: (processed$themes: ProcessedThemeObject[], dimensions: ThemeDimension[]) => PermutatedTheme[];
17
+ type PermutatedTheme = {
18
+ name: string;
19
+ selectedTokenSets: string[];
20
+ permutation: ThemePermutation;
21
+ };
22
+ declare const processed: unique symbol;
23
+ /**
24
+ * A Tokens Studio {@link ThemeObject} which has been processed for easier use in code
25
+ */
26
+ type ProcessedThemeObject = ThemeObject & {
27
+ [processed]: true;
28
+ };
29
+ /**
30
+ * Normalise theme names and theme group names for easier use in code
31
+ * @param theme A theme object from $themes.json
32
+ * @returns Processed theme object
33
+ */
34
+ declare function processThemeObject(theme: ThemeObject | ProcessedThemeObject): ProcessedThemeObject;
35
+ declare const getThemeColors: (processed$themes: ProcessedThemeObject[]) => string[];
36
+ //#endregion
37
+ export { ProcessedThemeObject, getMultidimensionalThemes, getThemeColors, processThemeObject };
38
+ //# sourceMappingURL=getMultidimensionalThemes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMultidimensionalThemes.d.ts","names":[],"sources":["../../../../../src/tokens/process/utils/getMultidimensionalThemes.ts"],"mappings":";;;;;;AAmBA;;;;;;;;;cAAa,yBAAA,GAA6B,gBAAA,EAAkB,oBAAA,IAAwB,UAAA,EAAY,cAAA,OAAgB,eAAA;AAAA,KAiB3G,eAAA;EACH,IAAA;EACA,iBAAA;EACA,WAAA,EAAa,gBAAgB;AAAA;AAAA,cAGzB,SAAA;;;;KAIM,oBAAA,GAAuB,WAAA;EAAA,CAAiB,SAAS;AAAA;;;AAP9B;AAAA;;iBAkBf,kBAAA,CAAmB,KAAA,EAAO,WAAA,GAAc,oBAAA,GAAuB,oBAAA;AAAA,cAyGlE,cAAA,GAAkB,gBAAwC,EAAtB,oBAAoB"}
@@ -0,0 +1,112 @@
1
+ import { TokenSetStatus } from "../../../../node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/constants/TokenSetStatus.js";
2
+ import "../../../../node_modules/.pnpm/@tokens-studio_types@0.5.2/node_modules/@tokens-studio/types/dist/types/index.js";
3
+ import { buildOptions } from "../platform.js";
4
+ import { kebabCase } from "./kebab-case.js";
5
+ import pc from "picocolors";
6
+ import * as R from "ramda";
7
+ //#region src/tokens/process/utils/getMultidimensionalThemes.ts
8
+ /**
9
+ * Find the theme permutations that are relevant for the given theme dimensions.
10
+ *
11
+ * Technically, for the given dimensions all permutations are included, while for other
12
+ * dimensions the first permutation is used.
13
+ *
14
+ * @param processed$themes Theme objects from $themes.json (Tokens Studio)
15
+ * @param dimensions Which theme dimensions to return permutations for.
16
+ * 'theme' (e.g. altinn/digdir/uutilsynet) is always implicitly included.
17
+ * @returns the relevant theme permutations
18
+ */
19
+ const getMultidimensionalThemes = (processed$themes, dimensions) => {
20
+ const verboseLogging = buildOptions?.verbose;
21
+ const grouped$themes = groupThemes(processed$themes);
22
+ const permutations = permutateThemes(grouped$themes);
23
+ const ALL_DEPENDENT_ON = ["theme"];
24
+ const nonDependentKeys = R.keys(grouped$themes).filter((x) => ![...ALL_DEPENDENT_ON, ...dimensions].includes(x));
25
+ if (verboseLogging) {
26
+ console.log(pc.cyan(`🔎 Finding theme permutations for ${dimensions}`));
27
+ console.log(pc.cyan(` (ignoring permutations for ${nonDependentKeys})`));
28
+ }
29
+ return permutations.filter((val) => {
30
+ return nonDependentKeys.map((x) => val.permutation[x] === grouped$themes[x][0].name).every((x) => x);
31
+ });
32
+ };
33
+ const processed = Symbol("Type brand for ProcessedThemeObject");
34
+ function isProcessed(theme) {
35
+ return Boolean(theme[processed]);
36
+ }
37
+ /**
38
+ * Normalise theme names and theme group names for easier use in code
39
+ * @param theme A theme object from $themes.json
40
+ * @returns Processed theme object
41
+ */
42
+ function processThemeObject(theme) {
43
+ if (isProcessed(theme)) return theme;
44
+ const result = {
45
+ ...theme,
46
+ [processed]: true
47
+ };
48
+ if (result.group) result.group = kebabCase(result.group);
49
+ result.name = kebabCase(result.name);
50
+ return result;
51
+ }
52
+ function groupThemes(themes) {
53
+ const groups = {};
54
+ for (const theme of themes) if (theme.group) {
55
+ const groupKey = theme.group;
56
+ groups[groupKey] = [...groups[groupKey] ?? [], theme];
57
+ } else throw new Error(`Theme ${theme.name} does not have a group property, which is required for multi-dimensional theming.`);
58
+ return groups;
59
+ }
60
+ const hasUnknownProps = R.pipe(R.values, R.none(R.equals("unknown")), R.not);
61
+ function permutateThemes(groups) {
62
+ const separator = "_";
63
+ return cartesian(Object.values(groups)).map((perm) => {
64
+ const permutatedTheme = perm.reduce((acc, theme) => {
65
+ const { group, name, selectedTokenSets } = theme;
66
+ let updatedPermutation = acc.permutation;
67
+ if (group) {
68
+ const groupProp = R.lensProp(group);
69
+ updatedPermutation = R.set(groupProp, name, updatedPermutation);
70
+ }
71
+ const updatedName = `${String(acc.name)}${acc ? separator : ""}${name}`;
72
+ const sets = [...acc.selectedTokenSets, ...filterTokenSets(selectedTokenSets)];
73
+ return {
74
+ permutation: updatedPermutation,
75
+ name: updatedName,
76
+ selectedTokenSets: sets
77
+ };
78
+ }, {
79
+ name: "",
80
+ selectedTokenSets: [],
81
+ permutation: {
82
+ "color-scheme": "unknown",
83
+ color: "unknown",
84
+ theme: "unknown",
85
+ semantic: "unknown",
86
+ size: "unknown",
87
+ typography: "unknown"
88
+ }
89
+ });
90
+ if (hasUnknownProps(permutatedTheme)) throw Error(`Theme ${permutatedTheme.name} has unknown props: ${JSON.stringify(permutatedTheme)}`);
91
+ const uniqueTokenSets = new Set(permutatedTheme.selectedTokenSets);
92
+ return {
93
+ ...permutatedTheme,
94
+ selectedTokenSets: Array.from(uniqueTokenSets)
95
+ };
96
+ });
97
+ }
98
+ function filterTokenSets(tokensets) {
99
+ return Object.entries(tokensets).filter(([, val]) => val !== TokenSetStatus.DISABLED).sort((a, b) => {
100
+ if (a[1] === TokenSetStatus.SOURCE && b[1] === TokenSetStatus.ENABLED) return -1;
101
+ if (a[1] === TokenSetStatus.ENABLED && b[1] === TokenSetStatus.SOURCE) return 1;
102
+ return 0;
103
+ }).map((entry) => entry[0]);
104
+ }
105
+ function cartesian(a) {
106
+ return a.reduce((a, b) => a.flatMap((d) => b.map((e) => [d, e].flat())));
107
+ }
108
+ const getThemeColors = (processed$themes) => Array.from(new Set(processed$themes.filter((x) => x.group === "color").map((x) => x.name)));
109
+ //#endregion
110
+ export { getMultidimensionalThemes, getThemeColors, processThemeObject };
111
+
112
+ //# sourceMappingURL=getMultidimensionalThemes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMultidimensionalThemes.js","names":[],"sources":["../../../../../src/tokens/process/utils/getMultidimensionalThemes.ts"],"sourcesContent":["import type { ThemeObject } from '@tokens-studio/types';\nimport { TokenSetStatus } from '@tokens-studio/types';\nimport pc from 'picocolors';\nimport * as R from 'ramda';\nimport type { ThemeDimension, ThemePermutation } from '../../types.ts';\nimport { buildOptions } from '../platform.ts';\nimport { kebabCase } from './kebab-case.ts';\n\n/**\n * Find the theme permutations that are relevant for the given theme dimensions.\n *\n * Technically, for the given dimensions all permutations are included, while for other\n * dimensions the first permutation is used.\n *\n * @param processed$themes Theme objects from $themes.json (Tokens Studio)\n * @param dimensions Which theme dimensions to return permutations for.\n * 'theme' (e.g. altinn/digdir/uutilsynet) is always implicitly included.\n * @returns the relevant theme permutations\n */\nexport const getMultidimensionalThemes = (processed$themes: ProcessedThemeObject[], dimensions: ThemeDimension[]) => {\n const verboseLogging = buildOptions?.verbose;\n const grouped$themes = groupThemes(processed$themes);\n const permutations = permutateThemes(grouped$themes);\n const ALL_DEPENDENT_ON: ThemeDimension[] = ['theme'];\n const keys = R.keys(grouped$themes);\n const nonDependentKeys = keys.filter((x) => ![...ALL_DEPENDENT_ON, ...dimensions].includes(x));\n if (verboseLogging) {\n console.log(pc.cyan(`🔎 Finding theme permutations for ${dimensions}`));\n console.log(pc.cyan(` (ignoring permutations for ${nonDependentKeys})`));\n }\n return permutations.filter((val: PermutatedTheme) => {\n const filters = nonDependentKeys.map((x) => val.permutation[x] === grouped$themes[x][0].name);\n return filters.every((x) => x);\n });\n};\n\ntype PermutatedTheme = {\n name: string;\n selectedTokenSets: string[];\n permutation: ThemePermutation;\n};\n\nconst processed: unique symbol = Symbol('Type brand for ProcessedThemeObject');\n/**\n * A Tokens Studio {@link ThemeObject} which has been processed for easier use in code\n */\nexport type ProcessedThemeObject = ThemeObject & { [processed]: true };\n\nfunction isProcessed(theme: ThemeObject): theme is ProcessedThemeObject {\n return Boolean((theme as ProcessedThemeObject)[processed]);\n}\n\n/**\n * Normalise theme names and theme group names for easier use in code\n * @param theme A theme object from $themes.json\n * @returns Processed theme object\n */\nexport function processThemeObject(theme: ThemeObject | ProcessedThemeObject): ProcessedThemeObject {\n if (isProcessed(theme)) {\n return theme;\n }\n const result: ProcessedThemeObject = { ...theme, [processed]: true };\n if (result.group) {\n result.group = kebabCase(result.group);\n }\n result.name = kebabCase(result.name);\n return result;\n}\n\ntype GroupedThemes = Record<keyof ThemePermutation, ProcessedThemeObject[]>;\n\nfunction groupThemes(themes: ProcessedThemeObject[]): GroupedThemes {\n const groups = {} as GroupedThemes;\n for (const theme of themes) {\n if (theme.group) {\n const groupKey = theme.group as keyof GroupedThemes;\n groups[groupKey] = [...(groups[groupKey] ?? []), theme];\n } else {\n throw new Error(\n `Theme ${theme.name} does not have a group property, which is required for multi-dimensional theming.`,\n );\n }\n }\n return groups;\n}\n\nconst hasUnknownProps = R.pipe(R.values, R.none(R.equals('unknown')), R.not);\n\nfunction permutateThemes(groups: GroupedThemes): PermutatedTheme[] {\n const separator = '_';\n // Create theme permutations\n const permutations = cartesian(Object.values(groups)) as Array<ThemeObject[]>;\n\n const permutatedThemes = permutations.map((perm) => {\n const permutatedTheme = perm.reduce(\n (acc, theme) => {\n const { group, name, selectedTokenSets } = theme;\n let updatedPermutation = acc.permutation;\n\n if (group) {\n const groupProp = R.lensProp<ThemePermutation>(group as keyof ThemePermutation);\n updatedPermutation = R.set(groupProp, name, updatedPermutation);\n }\n\n const updatedName = `${String(acc.name)}${acc ? separator : ''}${name}`;\n const sets = [...acc.selectedTokenSets, ...filterTokenSets(selectedTokenSets)];\n\n return {\n permutation: updatedPermutation,\n name: updatedName,\n selectedTokenSets: sets,\n };\n },\n {\n name: '',\n selectedTokenSets: [],\n permutation: {\n 'color-scheme': 'unknown',\n color: 'unknown',\n theme: 'unknown',\n semantic: 'unknown',\n size: 'unknown',\n typography: 'unknown',\n },\n } as PermutatedTheme,\n );\n\n if (hasUnknownProps(permutatedTheme)) {\n throw Error(`Theme ${permutatedTheme.name} has unknown props: ${JSON.stringify(permutatedTheme)}`);\n }\n\n const uniqueTokenSets = new Set(permutatedTheme.selectedTokenSets);\n\n return { ...permutatedTheme, selectedTokenSets: Array.from(uniqueTokenSets) };\n });\n\n return permutatedThemes;\n}\n\nfunction filterTokenSets(tokensets: Record<string, TokenSetStatus>) {\n return (\n Object.entries(tokensets)\n .filter(([, val]) => val !== TokenSetStatus.DISABLED)\n // ensure source type sets are always ordered before enabled type sets\n .sort((a, b) => {\n if (a[1] === TokenSetStatus.SOURCE && b[1] === TokenSetStatus.ENABLED) {\n return -1;\n }\n if (a[1] === TokenSetStatus.ENABLED && b[1] === TokenSetStatus.SOURCE) {\n return 1;\n }\n return 0;\n })\n .map((entry) => entry[0])\n );\n}\n\n// cartesian permutations: [[1,2], [3,4]] -> [[1,3], [1,4], [2,3], [2,4]]\nfunction cartesian(a: Array<unknown[]>) {\n return a.reduce((a, b) => a.flatMap((d) => b.map((e) => [d, e].flat())));\n}\n\nexport const getThemeColors = (processed$themes: ProcessedThemeObject[]) =>\n Array.from(new Set<string>(processed$themes.filter((x) => x.group === 'color').map((x) => x.name)));\n"],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ //#region src/tokens/process/utils/kebab-case.d.ts
2
+ /**
3
+ * Function to convert a string to kebab-case.
4
+ */
5
+ declare function kebabCase(str: string): string;
6
+ //#endregion
7
+ export { kebabCase };
8
+ //# sourceMappingURL=kebab-case.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kebab-case.d.ts","names":[],"sources":["../../../../../src/tokens/process/utils/kebab-case.ts"],"mappings":";;AAGA;;iBAAgB,SAAA,CAAU,GAAW"}
@@ -0,0 +1,11 @@
1
+ //#region src/tokens/process/utils/kebab-case.ts
2
+ /**
3
+ * Function to convert a string to kebab-case.
4
+ */
5
+ function kebabCase(str) {
6
+ return str.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
7
+ }
8
+ //#endregion
9
+ export { kebabCase };
10
+
11
+ //# sourceMappingURL=kebab-case.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kebab-case.js","names":[],"sources":["../../../../../src/tokens/process/utils/kebab-case.ts"],"sourcesContent":["/**\n * Function to convert a string to kebab-case.\n */\nexport function kebabCase(str: string): string {\n return str\n .replace(/([a-z])([A-Z])/g, '$1-$2') // Handle camelCase\n .replace(/[\\s_]+/g, '-') // Replace spaces and underscores with hyphens\n .toLowerCase();\n}\n"],"mappings":";;;;AAGA,SAAgB,UAAU,KAAqB;CAC7C,OAAO,IACJ,QAAQ,mBAAmB,OAAO,CAAC,CACnC,QAAQ,WAAW,GAAG,CAAC,CACvB,YAAY;AACjB"}