@tenphi/tasty 2.0.3 → 2.0.4

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 (322) hide show
  1. package/dist/{ssr/async-storage.js → async-storage-B7_o6FKt.js} +2 -2
  2. package/dist/async-storage-B7_o6FKt.js.map +1 -0
  3. package/dist/{ssr/collector.d.ts → collector-CkZ517g4.d.ts} +3 -3
  4. package/dist/{ssr/collector.js → collector-DXqvGOb1.js} +5 -10
  5. package/dist/collector-DXqvGOb1.js.map +1 -0
  6. package/dist/config-5jzS6k6B.js +10005 -0
  7. package/dist/config-5jzS6k6B.js.map +1 -0
  8. package/dist/config-DknGsfMo.d.ts +857 -0
  9. package/dist/{ssr/context.js → context-CkSg-kDT.js} +11 -3
  10. package/dist/context-CkSg-kDT.js.map +1 -0
  11. package/dist/core/index.d.ts +5 -34
  12. package/dist/core/index.js +5 -26
  13. package/dist/core-CtU6-9OC.js +1507 -0
  14. package/dist/core-CtU6-9OC.js.map +1 -0
  15. package/dist/{zero/extractor.js → css-writer-DHkX0JuE.js} +74 -11
  16. package/dist/css-writer-DHkX0JuE.js.map +1 -0
  17. package/dist/{ssr/format-global-rules.js → format-global-rules-Dbc_1tc3.js} +2 -2
  18. package/dist/format-global-rules-Dbc_1tc3.js.map +1 -0
  19. package/dist/format-rules-DH13ewDu.js +143 -0
  20. package/dist/format-rules-DH13ewDu.js.map +1 -0
  21. package/dist/{ssr/hydrate.js → hydrate-C1Gv-DoS.js} +3 -3
  22. package/dist/hydrate-C1Gv-DoS.js.map +1 -0
  23. package/dist/{styles/types.d.ts → index-PzENbpAq.d.ts} +701 -5
  24. package/dist/index-o7zV2yCr.d.ts +1561 -0
  25. package/dist/index.d.ts +5 -51
  26. package/dist/index.js +728 -35
  27. package/dist/index.js.map +1 -0
  28. package/dist/keyframes-b7X3UxDV.js +587 -0
  29. package/dist/keyframes-b7X3UxDV.js.map +1 -0
  30. package/dist/{utils/merge-styles.d.ts → merge-styles-C7KTy7MY.d.ts} +3 -3
  31. package/dist/{utils/merge-styles.js → merge-styles-Tgo3BbL2.js} +3 -4
  32. package/dist/merge-styles-Tgo3BbL2.js.map +1 -0
  33. package/dist/{utils/resolve-recipes.js → resolve-recipes-Ca2-5CxM.js} +4 -6
  34. package/dist/resolve-recipes-Ca2-5CxM.js.map +1 -0
  35. package/dist/ssr/astro-client.js +1 -1
  36. package/dist/ssr/astro.js +4 -4
  37. package/dist/ssr/index.d.ts +44 -4
  38. package/dist/ssr/index.js +4 -4
  39. package/dist/ssr/next.d.ts +1 -1
  40. package/dist/ssr/next.js +6 -6
  41. package/dist/ssr/next.js.map +1 -1
  42. package/dist/static/index.d.ts +91 -5
  43. package/dist/static/index.js +49 -3
  44. package/dist/static/index.js.map +1 -0
  45. package/dist/zero/babel.d.ts +1 -1
  46. package/dist/zero/babel.js +10 -6
  47. package/dist/zero/babel.js.map +1 -1
  48. package/dist/zero/index.d.ts +67 -3
  49. package/dist/zero/index.js +1 -2
  50. package/package.json +3 -3
  51. package/dist/_virtual/_rolldown/runtime.js +0 -7
  52. package/dist/chunks/cacheKey.d.ts +0 -1
  53. package/dist/chunks/cacheKey.js +0 -77
  54. package/dist/chunks/cacheKey.js.map +0 -1
  55. package/dist/chunks/definitions.d.ts +0 -37
  56. package/dist/chunks/definitions.js +0 -258
  57. package/dist/chunks/definitions.js.map +0 -1
  58. package/dist/chunks/index.d.ts +0 -1
  59. package/dist/chunks/renderChunk.d.ts +0 -1
  60. package/dist/chunks/renderChunk.js +0 -59
  61. package/dist/chunks/renderChunk.js.map +0 -1
  62. package/dist/compute-styles.d.ts +0 -31
  63. package/dist/compute-styles.js +0 -322
  64. package/dist/compute-styles.js.map +0 -1
  65. package/dist/config.d.ts +0 -407
  66. package/dist/config.js +0 -591
  67. package/dist/config.js.map +0 -1
  68. package/dist/counter-style/index.js +0 -51
  69. package/dist/counter-style/index.js.map +0 -1
  70. package/dist/debug.d.ts +0 -89
  71. package/dist/debug.js +0 -453
  72. package/dist/debug.js.map +0 -1
  73. package/dist/font-face/index.js +0 -63
  74. package/dist/font-face/index.js.map +0 -1
  75. package/dist/hooks/index.d.ts +0 -7
  76. package/dist/hooks/useCounterStyle.d.ts +0 -36
  77. package/dist/hooks/useCounterStyle.js +0 -65
  78. package/dist/hooks/useCounterStyle.js.map +0 -1
  79. package/dist/hooks/useFontFace.d.ts +0 -45
  80. package/dist/hooks/useFontFace.js +0 -66
  81. package/dist/hooks/useFontFace.js.map +0 -1
  82. package/dist/hooks/useGlobalStyles.d.ts +0 -46
  83. package/dist/hooks/useGlobalStyles.js +0 -88
  84. package/dist/hooks/useGlobalStyles.js.map +0 -1
  85. package/dist/hooks/useKeyframes.d.ts +0 -58
  86. package/dist/hooks/useKeyframes.js +0 -55
  87. package/dist/hooks/useKeyframes.js.map +0 -1
  88. package/dist/hooks/useProperty.d.ts +0 -81
  89. package/dist/hooks/useProperty.js +0 -96
  90. package/dist/hooks/useProperty.js.map +0 -1
  91. package/dist/hooks/useRawCSS.d.ts +0 -22
  92. package/dist/hooks/useRawCSS.js +0 -103
  93. package/dist/hooks/useRawCSS.js.map +0 -1
  94. package/dist/hooks/useStyles.d.ts +0 -40
  95. package/dist/hooks/useStyles.js +0 -31
  96. package/dist/hooks/useStyles.js.map +0 -1
  97. package/dist/injector/index.d.ts +0 -182
  98. package/dist/injector/index.js +0 -185
  99. package/dist/injector/index.js.map +0 -1
  100. package/dist/injector/injector.d.ts +0 -198
  101. package/dist/injector/injector.js +0 -651
  102. package/dist/injector/injector.js.map +0 -1
  103. package/dist/injector/sheet-manager.d.ts +0 -132
  104. package/dist/injector/sheet-manager.js +0 -699
  105. package/dist/injector/sheet-manager.js.map +0 -1
  106. package/dist/injector/types.d.ts +0 -235
  107. package/dist/keyframes/index.js +0 -206
  108. package/dist/keyframes/index.js.map +0 -1
  109. package/dist/parser/classify.js +0 -319
  110. package/dist/parser/classify.js.map +0 -1
  111. package/dist/parser/const.js +0 -60
  112. package/dist/parser/const.js.map +0 -1
  113. package/dist/parser/lru.js +0 -109
  114. package/dist/parser/lru.js.map +0 -1
  115. package/dist/parser/parser.d.ts +0 -25
  116. package/dist/parser/parser.js +0 -115
  117. package/dist/parser/parser.js.map +0 -1
  118. package/dist/parser/tokenizer.js +0 -69
  119. package/dist/parser/tokenizer.js.map +0 -1
  120. package/dist/parser/types.d.ts +0 -51
  121. package/dist/parser/types.js +0 -46
  122. package/dist/parser/types.js.map +0 -1
  123. package/dist/pipeline/conditions.d.ts +0 -134
  124. package/dist/pipeline/conditions.js +0 -406
  125. package/dist/pipeline/conditions.js.map +0 -1
  126. package/dist/pipeline/exclusive.js +0 -389
  127. package/dist/pipeline/exclusive.js.map +0 -1
  128. package/dist/pipeline/index.d.ts +0 -55
  129. package/dist/pipeline/index.js +0 -749
  130. package/dist/pipeline/index.js.map +0 -1
  131. package/dist/pipeline/materialize-contradictions.js +0 -125
  132. package/dist/pipeline/materialize-contradictions.js.map +0 -1
  133. package/dist/pipeline/materialize.js +0 -1038
  134. package/dist/pipeline/materialize.js.map +0 -1
  135. package/dist/pipeline/parseStateKey.d.ts +0 -15
  136. package/dist/pipeline/parseStateKey.js +0 -446
  137. package/dist/pipeline/parseStateKey.js.map +0 -1
  138. package/dist/pipeline/simplify.js +0 -725
  139. package/dist/pipeline/simplify.js.map +0 -1
  140. package/dist/pipeline/warnings.js +0 -18
  141. package/dist/pipeline/warnings.js.map +0 -1
  142. package/dist/plugins/index.d.ts +0 -2
  143. package/dist/plugins/okhsl-plugin.d.ts +0 -35
  144. package/dist/plugins/okhsl-plugin.js +0 -97
  145. package/dist/plugins/okhsl-plugin.js.map +0 -1
  146. package/dist/plugins/types.d.ts +0 -87
  147. package/dist/properties/index.js +0 -222
  148. package/dist/properties/index.js.map +0 -1
  149. package/dist/properties/property-type-resolver.d.ts +0 -24
  150. package/dist/properties/property-type-resolver.js +0 -90
  151. package/dist/properties/property-type-resolver.js.map +0 -1
  152. package/dist/rsc-cache.js +0 -79
  153. package/dist/rsc-cache.js.map +0 -1
  154. package/dist/ssr/async-storage.d.ts +0 -17
  155. package/dist/ssr/async-storage.js.map +0 -1
  156. package/dist/ssr/collect-auto-properties.js +0 -58
  157. package/dist/ssr/collect-auto-properties.js.map +0 -1
  158. package/dist/ssr/collector.js.map +0 -1
  159. package/dist/ssr/context.js.map +0 -1
  160. package/dist/ssr/format-global-rules.js.map +0 -1
  161. package/dist/ssr/format-keyframes.js +0 -69
  162. package/dist/ssr/format-keyframes.js.map +0 -1
  163. package/dist/ssr/format-property.js +0 -49
  164. package/dist/ssr/format-property.js.map +0 -1
  165. package/dist/ssr/format-rules.js +0 -73
  166. package/dist/ssr/format-rules.js.map +0 -1
  167. package/dist/ssr/hydrate.d.ts +0 -29
  168. package/dist/ssr/hydrate.js.map +0 -1
  169. package/dist/ssr/ssr-collector-ref.js +0 -29
  170. package/dist/ssr/ssr-collector-ref.js.map +0 -1
  171. package/dist/states/index.d.ts +0 -49
  172. package/dist/states/index.js +0 -170
  173. package/dist/states/index.js.map +0 -1
  174. package/dist/static/tastyStatic.d.ts +0 -46
  175. package/dist/static/tastyStatic.js +0 -30
  176. package/dist/static/tastyStatic.js.map +0 -1
  177. package/dist/static/types.d.ts +0 -49
  178. package/dist/static/types.js +0 -24
  179. package/dist/static/types.js.map +0 -1
  180. package/dist/styles/border.d.ts +0 -25
  181. package/dist/styles/border.js +0 -120
  182. package/dist/styles/border.js.map +0 -1
  183. package/dist/styles/color.d.ts +0 -14
  184. package/dist/styles/color.js +0 -26
  185. package/dist/styles/color.js.map +0 -1
  186. package/dist/styles/const.js +0 -17
  187. package/dist/styles/const.js.map +0 -1
  188. package/dist/styles/createStyle.js +0 -79
  189. package/dist/styles/createStyle.js.map +0 -1
  190. package/dist/styles/dimension.js +0 -109
  191. package/dist/styles/dimension.js.map +0 -1
  192. package/dist/styles/directional.js +0 -133
  193. package/dist/styles/directional.js.map +0 -1
  194. package/dist/styles/display.d.ts +0 -30
  195. package/dist/styles/display.js +0 -73
  196. package/dist/styles/display.js.map +0 -1
  197. package/dist/styles/fade.d.ts +0 -15
  198. package/dist/styles/fade.js +0 -62
  199. package/dist/styles/fade.js.map +0 -1
  200. package/dist/styles/fill.d.ts +0 -42
  201. package/dist/styles/fill.js +0 -51
  202. package/dist/styles/fill.js.map +0 -1
  203. package/dist/styles/flow.d.ts +0 -16
  204. package/dist/styles/flow.js +0 -12
  205. package/dist/styles/flow.js.map +0 -1
  206. package/dist/styles/gap.d.ts +0 -31
  207. package/dist/styles/gap.js +0 -38
  208. package/dist/styles/gap.js.map +0 -1
  209. package/dist/styles/height.d.ts +0 -17
  210. package/dist/styles/height.js +0 -19
  211. package/dist/styles/height.js.map +0 -1
  212. package/dist/styles/index.d.ts +0 -1
  213. package/dist/styles/index.js +0 -8
  214. package/dist/styles/index.js.map +0 -1
  215. package/dist/styles/inset.d.ts +0 -24
  216. package/dist/styles/inset.js +0 -34
  217. package/dist/styles/inset.js.map +0 -1
  218. package/dist/styles/list.d.ts +0 -16
  219. package/dist/styles/list.js +0 -100
  220. package/dist/styles/list.js.map +0 -1
  221. package/dist/styles/margin.d.ts +0 -24
  222. package/dist/styles/margin.js +0 -32
  223. package/dist/styles/margin.js.map +0 -1
  224. package/dist/styles/outline.d.ts +0 -29
  225. package/dist/styles/outline.js +0 -55
  226. package/dist/styles/outline.js.map +0 -1
  227. package/dist/styles/padding.d.ts +0 -24
  228. package/dist/styles/padding.js +0 -32
  229. package/dist/styles/padding.js.map +0 -1
  230. package/dist/styles/placement.d.ts +0 -37
  231. package/dist/styles/placement.js +0 -74
  232. package/dist/styles/placement.js.map +0 -1
  233. package/dist/styles/predefined.d.ts +0 -71
  234. package/dist/styles/predefined.js +0 -237
  235. package/dist/styles/predefined.js.map +0 -1
  236. package/dist/styles/preset.d.ts +0 -52
  237. package/dist/styles/preset.js +0 -127
  238. package/dist/styles/preset.js.map +0 -1
  239. package/dist/styles/radius.d.ts +0 -12
  240. package/dist/styles/radius.js +0 -83
  241. package/dist/styles/radius.js.map +0 -1
  242. package/dist/styles/scrollMargin.d.ts +0 -24
  243. package/dist/styles/scrollMargin.js +0 -32
  244. package/dist/styles/scrollMargin.js.map +0 -1
  245. package/dist/styles/scrollbar.d.ts +0 -25
  246. package/dist/styles/scrollbar.js +0 -51
  247. package/dist/styles/scrollbar.js.map +0 -1
  248. package/dist/styles/shadow.d.ts +0 -14
  249. package/dist/styles/shadow.js +0 -25
  250. package/dist/styles/shadow.js.map +0 -1
  251. package/dist/styles/shared.js +0 -17
  252. package/dist/styles/shared.js.map +0 -1
  253. package/dist/styles/transition.d.ts +0 -14
  254. package/dist/styles/transition.js +0 -159
  255. package/dist/styles/transition.js.map +0 -1
  256. package/dist/styles/width.d.ts +0 -17
  257. package/dist/styles/width.js +0 -19
  258. package/dist/styles/width.js.map +0 -1
  259. package/dist/tasty.d.ts +0 -134
  260. package/dist/tasty.js +0 -248
  261. package/dist/tasty.js.map +0 -1
  262. package/dist/types.d.ts +0 -184
  263. package/dist/utils/cache-wrapper.js +0 -21
  264. package/dist/utils/cache-wrapper.js.map +0 -1
  265. package/dist/utils/case-converter.js +0 -8
  266. package/dist/utils/case-converter.js.map +0 -1
  267. package/dist/utils/color-math.d.ts +0 -46
  268. package/dist/utils/color-math.js +0 -749
  269. package/dist/utils/color-math.js.map +0 -1
  270. package/dist/utils/color-space.d.ts +0 -5
  271. package/dist/utils/color-space.js +0 -228
  272. package/dist/utils/color-space.js.map +0 -1
  273. package/dist/utils/colors.d.ts +0 -5
  274. package/dist/utils/colors.js +0 -10
  275. package/dist/utils/colors.js.map +0 -1
  276. package/dist/utils/css-types.d.ts +0 -7
  277. package/dist/utils/deps-equal.js +0 -15
  278. package/dist/utils/deps-equal.js.map +0 -1
  279. package/dist/utils/dotize.d.ts +0 -26
  280. package/dist/utils/dotize.js +0 -122
  281. package/dist/utils/dotize.js.map +0 -1
  282. package/dist/utils/filter-base-props.d.ts +0 -15
  283. package/dist/utils/filter-base-props.js +0 -45
  284. package/dist/utils/filter-base-props.js.map +0 -1
  285. package/dist/utils/get-display-name.d.ts +0 -7
  286. package/dist/utils/get-display-name.js +0 -10
  287. package/dist/utils/get-display-name.js.map +0 -1
  288. package/dist/utils/has-keys.js +0 -13
  289. package/dist/utils/has-keys.js.map +0 -1
  290. package/dist/utils/hash.js +0 -14
  291. package/dist/utils/hash.js.map +0 -1
  292. package/dist/utils/is-dev-env.js +0 -19
  293. package/dist/utils/is-dev-env.js.map +0 -1
  294. package/dist/utils/is-valid-element-type.js +0 -15
  295. package/dist/utils/is-valid-element-type.js.map +0 -1
  296. package/dist/utils/merge-styles.js.map +0 -1
  297. package/dist/utils/mod-attrs.d.ts +0 -6
  298. package/dist/utils/mod-attrs.js +0 -20
  299. package/dist/utils/mod-attrs.js.map +0 -1
  300. package/dist/utils/process-tokens.d.ts +0 -17
  301. package/dist/utils/process-tokens.js +0 -83
  302. package/dist/utils/process-tokens.js.map +0 -1
  303. package/dist/utils/resolve-recipes.d.ts +0 -17
  304. package/dist/utils/resolve-recipes.js.map +0 -1
  305. package/dist/utils/selector-transform.js +0 -32
  306. package/dist/utils/selector-transform.js.map +0 -1
  307. package/dist/utils/string.js +0 -8
  308. package/dist/utils/string.js.map +0 -1
  309. package/dist/utils/styles.d.ts +0 -99
  310. package/dist/utils/styles.js +0 -220
  311. package/dist/utils/styles.js.map +0 -1
  312. package/dist/utils/typography.d.ts +0 -58
  313. package/dist/utils/typography.js +0 -51
  314. package/dist/utils/typography.js.map +0 -1
  315. package/dist/utils/warnings.d.ts +0 -16
  316. package/dist/utils/warnings.js +0 -16
  317. package/dist/utils/warnings.js.map +0 -1
  318. package/dist/zero/css-writer.d.ts +0 -45
  319. package/dist/zero/css-writer.js +0 -73
  320. package/dist/zero/css-writer.js.map +0 -1
  321. package/dist/zero/extractor.d.ts +0 -24
  322. package/dist/zero/extractor.js.map +0 -1
@@ -1,749 +0,0 @@
1
- import { Lru } from "../parser/lru.js";
2
- import { stringifyStyles } from "../utils/styles.js";
3
- import { createStyle } from "../styles/createStyle.js";
4
- import { STYLE_HANDLER_MAP } from "../styles/index.js";
5
- import { createStateParserContext, extractLocalPredefinedStates } from "../states/index.js";
6
- import { and, or, trueCondition } from "./conditions.js";
7
- import { simplifyCondition } from "./simplify.js";
8
- import { buildExclusiveConditions, expandExclusiveOrs, expandOrConditions, extractCompoundStates, isValueMapping, mergeEntriesByValue, parseStyleEntries } from "./exclusive.js";
9
- import { branchToCSS, buildAtRulesFromVariant, conditionToCSS, mergeVariantsIntoSelectorGroups, optimizeGroups, parentGroupsToCSS, rootGroupsToCSS, selectorGroupToCSS } from "./materialize.js";
10
- import { emitWarning } from "./warnings.js";
11
- import { parseStateKey } from "./parseStateKey.js";
12
- //#region src/pipeline/index.ts
13
- /**
14
- * Tasty Style Rendering Pipeline
15
- *
16
- * Main entrypoint for the style rendering pipeline. Transforms a `Styles`
17
- * object into an array of `CSSRule` objects ready for DOM injection.
18
- *
19
- * Per-handler stages (see docs/pipeline.md for full detail):
20
- * 0. PRE-PARSE NORMALIZATION - extractCompoundStates (exclusive.ts)
21
- * 1. PARSE CONDITIONS - parseStyleEntries + parseStateKey
22
- * 1b. MERGE ENTRIES BY VALUE - mergeEntriesByValue (exclusive.ts)
23
- * 2a. EXPAND USER OR BRANCHES - expandOrConditions (exclusive.ts)
24
- * 2b. BUILD EXCLUSIVE CONDITIONS - buildExclusiveConditions
25
- * 3. EXPAND DE MORGAN ORs - expandExclusiveOrs (exclusive.ts)
26
- * 4. COMPUTE STATE COMBINATIONS - computeStateCombinations
27
- * 5. CALL HANDLERS - run style handlers for each snapshot
28
- * 6. MERGE BY VALUE - mergeByValue (index.ts)
29
- * 7. MATERIALIZE CSS - conditionToCSS + materializeComputedRule
30
- *
31
- * Simplification (`simplifyCondition`) runs inside most stages; calls are
32
- * memoized by condition unique-id. The post-pass in `runPipeline` dedupes
33
- * identical rules and emits all `@starting-style` rules last so they win
34
- * the cascade over their equal-specificity normal counterparts.
35
- */
36
- const pipelineCache = new Lru(5e3);
37
- /**
38
- * Check if a cache key exists in the pipeline cache.
39
- * Used by renderStylesForChunk to avoid building filtered styles on cache hit.
40
- */
41
- function hasPipelineCacheEntry(cacheKey) {
42
- return pipelineCache.get(cacheKey) !== void 0;
43
- }
44
- /**
45
- * Clear the pipeline cache (for testing)
46
- */
47
- function clearPipelineCache() {
48
- pipelineCache.clear();
49
- }
50
- function runPipeline(styles, parserContext) {
51
- const allRules = [];
52
- processStyles(styles, "", parserContext, allRules);
53
- const seen = /* @__PURE__ */ new Set();
54
- const dedupedRules = allRules.filter((rule) => {
55
- const key = `${rule.selector}|${rule.declarations}|${rule.atRules?.join("|") ?? ""}|${rule.rootPrefix || ""}|${rule.startingStyle ? "1" : "0"}`;
56
- if (seen.has(key)) return false;
57
- seen.add(key);
58
- return true;
59
- });
60
- const normal = [];
61
- const starting = [];
62
- for (const rule of dedupedRules) if (rule.startingStyle) starting.push(rule);
63
- else normal.push(rule);
64
- return normal.concat(starting);
65
- }
66
- /**
67
- * Process styles at a given nesting level.
68
- *
69
- * Splits keys into nested-selector keys and style-handler keys, recurses
70
- * into nested selectors, then runs the per-handler stages 1–7 over the
71
- * style keys.
72
- */
73
- function processStyles(styles, selectorSuffix, parserContext, allRules) {
74
- const keys = Object.keys(styles);
75
- const selectorKeys = keys.filter((key) => isSelector(key));
76
- const styleKeys = keys.filter((key) => !isSelector(key) && !key.startsWith("@"));
77
- processNestedSelectors(styles, selectorKeys, selectorSuffix, parserContext, allRules);
78
- processHandlerQueue(buildHandlerQueue(styleKeys, styles), selectorSuffix, parserContext, allRules);
79
- }
80
- /**
81
- * Recurse into nested selector keys. Each nested key may expand into multiple
82
- * suffixes (comma-separated patterns); each suffix is processed independently
83
- * with the parent's parser context augmented for sub-element scope.
84
- */
85
- function processNestedSelectors(styles, selectorKeys, selectorSuffix, parserContext, allRules) {
86
- for (const key of selectorKeys) {
87
- const nestedStyles = styles[key];
88
- if (!nestedStyles || typeof nestedStyles !== "object") continue;
89
- const suffixes = getAllSelectors(key, nestedStyles);
90
- if (!suffixes) continue;
91
- const { $: _$, ...cleanedStyles } = nestedStyles;
92
- const subLocalStates = extractLocalPredefinedStates(cleanedStyles);
93
- const hasSubStates = Object.keys(subLocalStates).length > 0;
94
- const subContext = {
95
- ...parserContext,
96
- isSubElement: true,
97
- localPredefinedStates: hasSubStates ? {
98
- ...parserContext.localPredefinedStates,
99
- ...subLocalStates
100
- } : parserContext.localPredefinedStates
101
- };
102
- for (const suffix of suffixes) processStyles(cleanedStyles, selectorSuffix + suffix, subContext, allRules);
103
- }
104
- }
105
- /**
106
- * Run the per-handler pipeline (stages 1–7) over a handler queue and append
107
- * the resulting CSS rules to `allRules`.
108
- */
109
- function processHandlerQueue(handlerQueue, selectorSuffix, parserContext, allRules) {
110
- for (const { handler, styleMap } of handlerQueue) {
111
- const lookupStyles = handler.__lookupStyles;
112
- const mergedRules = mergeByValue(invokeHandler(handler, computeStateCombinations(buildExclusivesForHandler(lookupStyles, styleMap, parserContext), lookupStyles), selectorSuffix));
113
- for (const rule of mergedRules) {
114
- const cssRules = materializeComputedRule(rule);
115
- allRules.push(...cssRules);
116
- }
117
- }
118
- }
119
- /**
120
- * Stages 0–3 for a single handler: take the handler's looked-up style names,
121
- * resolve each style's value map into a list of mutually-exclusive entries.
122
- * Simple non-mapping values produce a single TRUE-conditioned entry.
123
- */
124
- function buildExclusivesForHandler(lookupStyles, styleMap, parserContext) {
125
- const exclusiveByStyle = /* @__PURE__ */ new Map();
126
- for (const styleName of lookupStyles) {
127
- const value = styleMap[styleName];
128
- if (value === void 0) continue;
129
- if (isValueMapping(value)) {
130
- const fullyExpanded = expandExclusiveOrs(buildExclusiveConditions(expandOrConditions(mergeEntriesByValue(parseStyleEntries(styleName, extractCompoundStates(value), (stateKey) => parseStateKey(stateKey, { context: parserContext }))))));
131
- exclusiveByStyle.set(styleName, fullyExpanded);
132
- } else exclusiveByStyle.set(styleName, [{
133
- styleKey: styleName,
134
- stateKey: "",
135
- value,
136
- condition: trueCondition(),
137
- priority: 0,
138
- exclusiveCondition: trueCondition()
139
- }]);
140
- }
141
- return exclusiveByStyle;
142
- }
143
- /**
144
- * Stage 5: invoke the handler for each state snapshot and translate its
145
- * return value into ComputedRule entries (one per declaration set, fanned
146
- * out across any `$` selector suffixes the handler returns).
147
- */
148
- function invokeHandler(handler, stateSnapshots, selectorSuffix) {
149
- const computedRules = [];
150
- for (const snapshot of stateSnapshots) {
151
- const result = handler(snapshot.values);
152
- if (!result) continue;
153
- const results = Array.isArray(result) ? result : [result];
154
- for (const r of results) {
155
- if (!r || typeof r !== "object") continue;
156
- const { $, ...styleProps } = r;
157
- const declarations = {};
158
- for (const [prop, val] of Object.entries(styleProps)) if (val != null && val !== "") declarations[prop] = String(val);
159
- if (Object.keys(declarations).length === 0) continue;
160
- const suffixes = $ ? (Array.isArray($) ? $ : [$]).map((s) => selectorSuffix + normalizeSelectorSuffix(String(s))) : [selectorSuffix];
161
- for (const suffix of suffixes) computedRules.push({
162
- condition: snapshot.condition,
163
- declarations,
164
- selectorSuffix: suffix
165
- });
166
- }
167
- }
168
- return computedRules;
169
- }
170
- /**
171
- * Check if a key is a CSS selector
172
- */
173
- function isSelector(key) {
174
- return key.startsWith("&") || key.startsWith(".") || /^[A-Z]/.test(key);
175
- }
176
- /**
177
- * Get all selector suffixes for a sub-element key.
178
- *
179
- * Handles three types of selector keys:
180
- * - `&` prefix: Raw selector suffix (e.g., `&:hover` → `:hover`)
181
- * - `.` prefix: Class selector (e.g., `.active` → ` .active`)
182
- * - Uppercase: Sub-element with optional `$` affix pattern
183
- *
184
- * @param key - The sub-element key (e.g., 'Label', '&:hover', '.active')
185
- * @param styles - The styles object, may contain `$` property for selector affix
186
- * @returns Array of selector suffixes, or null if invalid (with console warning)
187
- *
188
- * @example
189
- * getAllSelectors('Label', {})
190
- * // → [' [data-element="Label"]']
191
- *
192
- * getAllSelectors('Cell', { $: '>, >Body>' })
193
- * // → ['> [data-element="Cell"]', ' [data-element="Body"] > [data-element="Cell"]']
194
- */
195
- function getAllSelectors(key, styles) {
196
- if (key.startsWith("&")) return [key.slice(1)];
197
- if (key.startsWith(".")) return [` ${key}`];
198
- if (/^[A-Z]/.test(key)) {
199
- const affix = styles?.$;
200
- if (affix !== void 0) {
201
- const result = processAffix(String(affix), key);
202
- if (!result.valid) {
203
- emitWarning("INVALID_SELECTOR_AFFIX", result.reason);
204
- return null;
205
- }
206
- return result.selectors;
207
- }
208
- return [` [data-element="${key}"]`];
209
- }
210
- return null;
211
- }
212
- /**
213
- * Process selector affix pattern and return selector(s)
214
- *
215
- * Supports:
216
- * - Direct child: '>'
217
- * - Chained elements: '>Body>Row>'
218
- * - HTML tags (no key injection): 'h1', '>ul>li', 'button:hover'
219
- * - Universal selector: '*', 'h1 *'
220
- * - Pseudo-elements on root: '::before'
221
- * - Pseudo on sub-element: '@::before', '>@:hover'
222
- * - Classes: '.active', '>@.active'
223
- * - Multiple selectors: '>, >Body>'
224
- * - Sibling combinators (after element): '>Item+', '>Item~'
225
- */
226
- function processAffix(affix, key) {
227
- const trimmed = affix.trim();
228
- if (!trimmed) return {
229
- valid: true,
230
- selectors: [` [data-element="${key}"]`]
231
- };
232
- const patterns = trimmed.split(",").map((p) => p.trim());
233
- const selectors = [];
234
- for (const pattern of patterns) {
235
- const validation = validatePattern(pattern);
236
- if (!validation.valid) return validation;
237
- const selector = processSinglePattern(pattern, key);
238
- selectors.push(selector);
239
- }
240
- return {
241
- valid: true,
242
- selectors
243
- };
244
- }
245
- /**
246
- * Recognized token patterns for selector affix validation.
247
- *
248
- * These patterns are used to tokenize and validate `$` affix strings.
249
- * Order matters: more specific patterns must come first to avoid
250
- * partial matches (e.g., `::before` must match before `:` alone).
251
- *
252
- * Unrecognized tokens (like `#id`, `*`, or numbers) will cause validation to fail.
253
- */
254
- const VALID_TOKEN_PATTERNS = [
255
- /^[>+~]/,
256
- /^\*/,
257
- /^[A-Z][a-zA-Z0-9]*/,
258
- /^@/,
259
- /^::?[a-z][a-z0-9-]*(?:\([^)]*\))?/,
260
- /^\.[a-zA-Z_-][a-zA-Z0-9_-]*/,
261
- /^\[[^\]]+\]/,
262
- /^[a-z][a-z0-9-]*/,
263
- /^\s+/,
264
- /^&/
265
- ];
266
- /**
267
- * Scan a pattern for unrecognized tokens.
268
- *
269
- * Iterates through the pattern, consuming recognized tokens until
270
- * either the pattern is fully consumed (valid) or an unrecognized
271
- * character sequence is found (invalid).
272
- *
273
- * @param pattern - The selector pattern to validate
274
- * @returns The first unrecognized token found, or null if all tokens are valid
275
- *
276
- * @example
277
- * findUnrecognizedTokens('>Body>Row>') // → null (valid)
278
- * findUnrecognizedTokens('123') // → '123' (invalid)
279
- * findUnrecognizedTokens('#myId') // → '#' (invalid)
280
- */
281
- function findUnrecognizedTokens(pattern) {
282
- let remaining = pattern;
283
- while (remaining.length > 0) {
284
- let matched = false;
285
- for (const regex of VALID_TOKEN_PATTERNS) {
286
- const match = remaining.match(regex);
287
- if (match) {
288
- remaining = remaining.slice(match[0].length);
289
- matched = true;
290
- break;
291
- }
292
- }
293
- if (!matched) {
294
- const unrecognized = remaining.match(/^[^\s>+~@.:[\]A-Z]+/);
295
- return unrecognized ? unrecognized[0] : remaining[0];
296
- }
297
- }
298
- return null;
299
- }
300
- /**
301
- * Validate a selector pattern for structural correctness.
302
- *
303
- * Checks for:
304
- * 1. Out-of-scope selectors: Patterns starting with `+` or `~` target siblings
305
- * of the root element, which is outside the component's DOM scope.
306
- * 2. Consecutive combinators: Patterns like `>>` or `>+` are malformed CSS.
307
- * 3. Unrecognized tokens: Characters/sequences not matching valid CSS selectors.
308
- *
309
- * @param pattern - A single selector pattern (already split by comma)
310
- * @returns AffixResult indicating validity and error reason if invalid
311
- *
312
- * @example
313
- * validatePattern('>Body>Row>') // → { valid: true, selectors: [] }
314
- * validatePattern('+') // → { valid: false, reason: '...outside root scope...' }
315
- * validatePattern('>>') // → { valid: false, reason: '...consecutive combinators...' }
316
- */
317
- function validatePattern(pattern) {
318
- const trimmed = pattern.trim();
319
- if (/^[+~]/.test(trimmed)) return {
320
- valid: false,
321
- reason: `Selector affix "${pattern}" targets elements outside the root scope. Sibling selectors (+, ~) must be preceded by an element inside the root. Use ">Element+" or ">Element~" instead.`
322
- };
323
- if (/[>+~]{2,}/.test(trimmed.replace(/\s+/g, ""))) return {
324
- valid: false,
325
- reason: `Selector affix "${pattern}" contains consecutive combinators.`
326
- };
327
- const unrecognized = findUnrecognizedTokens(trimmed);
328
- if (unrecognized) return {
329
- valid: false,
330
- reason: `Selector affix "${pattern}" contains unrecognized token "${unrecognized}". Valid tokens: combinators (>, +, ~), element names (Uppercase), @ placeholder, pseudo (:hover, ::before), class (.name), attribute ([attr]).`
331
- };
332
- return {
333
- valid: true,
334
- selectors: []
335
- };
336
- }
337
- /**
338
- * Process a single selector pattern into a CSS selector suffix.
339
- *
340
- * This is the main transformation function that converts a `$` affix pattern
341
- * into a valid CSS selector suffix. It handles:
342
- *
343
- * 1. `@` placeholder replacement with `[data-element="key"]`
344
- * 2. Key injection based on pattern ending (see `shouldInjectKey`)
345
- * 3. Proper spacing for descendant vs direct child selectors
346
- *
347
- * @param pattern - A single validated selector pattern
348
- * @param key - The sub-element key to inject (e.g., 'Label', 'Cell')
349
- * @returns CSS selector suffix ready to append to the root selector
350
- *
351
- * @example
352
- * processSinglePattern('>', 'Row')
353
- * // → '> [data-element="Row"]'
354
- *
355
- * processSinglePattern('>Body>Row>', 'Cell')
356
- * // → '> [data-element="Body"] > [data-element="Row"] > [data-element="Cell"]'
357
- *
358
- * processSinglePattern('::before', 'Before')
359
- * // → '::before' (no key injection for pseudo on root)
360
- *
361
- * processSinglePattern('>@:hover', 'Item')
362
- * // → '> [data-element="Item"]:hover'
363
- */
364
- function processSinglePattern(pattern, key) {
365
- const normalized = pattern.replace(/^&/, "").trim();
366
- if (!normalized) return ` [data-element="${key}"]`;
367
- const startsWithPseudo = /^::?[a-z]/.test(normalized);
368
- let result = transformPattern(normalized);
369
- if (result.includes("@")) {
370
- result = result.replace(/@ (?=[.:])/g, "@");
371
- result = result.replace(/@/g, `[data-element="${key}"]`);
372
- if (!startsWithPseudo && !result.startsWith(" ")) result = " " + result;
373
- return result;
374
- }
375
- if (shouldInjectKey(normalized)) result = result + ` [data-element="${key}"]`;
376
- if (!startsWithPseudo && !result.startsWith(" ")) result = " " + result;
377
- return result;
378
- }
379
- /**
380
- * Transform a selector pattern by converting element names and normalizing spacing.
381
- *
382
- * This is a character-by-character tokenizer that:
383
- * - Converts uppercase names to `[data-element="Name"]` selectors
384
- * - Adds proper spacing around combinators (>, +, ~)
385
- * - Preserves lowercase tags, classes, pseudos, and attributes as-is
386
- * - Keeps @ placeholder for later replacement
387
- *
388
- * The tokenizer handles these token types in order:
389
- * 1. Whitespace (skipped)
390
- * 2. Combinators: >, +, ~ (add surrounding spaces)
391
- * 3. Universal selector: * (keep as-is with spacing)
392
- * 4. Uppercase names: Body, Row (convert to [data-element="..."])
393
- * 5. @ placeholder (keep for later replacement)
394
- * 6. Pseudo: :hover, ::before (attach to previous token)
395
- * 7. Tags: a, div, button (keep as-is with spacing)
396
- * 8. Classes: .active (attach to previous element/tag/placeholder)
397
- * 9. Attributes: [type="text"] (keep as-is)
398
- *
399
- * @param pattern - The raw selector pattern to transform
400
- * @returns Transformed pattern with proper CSS selector syntax
401
- *
402
- * @example
403
- * transformPattern('>Body>Row>')
404
- * // → '> [data-element="Body"] > [data-element="Row"] >'
405
- *
406
- * transformPattern('button.primary:hover')
407
- * // → 'button.primary:hover'
408
- */
409
- function transformPattern(pattern) {
410
- let result = "";
411
- let lastCh = "";
412
- let i = 0;
413
- while (i < pattern.length) {
414
- const char = pattern[i];
415
- if (/\s/.test(char)) {
416
- i++;
417
- continue;
418
- }
419
- if (/[>+~]/.test(char)) {
420
- if (result && lastCh !== " ") result += " ";
421
- result += char;
422
- lastCh = char;
423
- i++;
424
- continue;
425
- }
426
- if (char === "*") {
427
- if (result && lastCh !== " ") result += " ";
428
- result += "*";
429
- lastCh = "*";
430
- i++;
431
- continue;
432
- }
433
- if (/[A-Z]/.test(char)) {
434
- const nameStart = i;
435
- while (i < pattern.length && /[a-zA-Z0-9]/.test(pattern[i])) i++;
436
- if (result && lastCh !== " ") result += " ";
437
- const segment = `[data-element="${pattern.slice(nameStart, i)}"]`;
438
- result += segment;
439
- lastCh = "]";
440
- continue;
441
- }
442
- if (char === "@") {
443
- if (result && lastCh !== " ") result += " ";
444
- result += "@";
445
- lastCh = "@";
446
- i++;
447
- continue;
448
- }
449
- if (char === ":") {
450
- const pseudoStart = i;
451
- while (i < pattern.length && !/[\s>+~,@]/.test(pattern[i]) && !/[A-Z]/.test(pattern[i])) i++;
452
- const segment = pattern.slice(pseudoStart, i);
453
- result += segment;
454
- lastCh = segment[segment.length - 1] || lastCh;
455
- continue;
456
- }
457
- if (/[a-z]/.test(char)) {
458
- const tagStart = i;
459
- while (i < pattern.length && /[a-z0-9-]/.test(pattern[i])) i++;
460
- if (result && lastCh !== " ") result += " ";
461
- const segment = pattern.slice(tagStart, i);
462
- result += segment;
463
- lastCh = segment[segment.length - 1] || lastCh;
464
- continue;
465
- }
466
- if (char === ".") {
467
- const attachToLast = lastCh === "]" || lastCh === "@" || /[a-zA-Z0-9-]/.test(lastCh);
468
- if (result && !attachToLast && lastCh !== " ") result += " ";
469
- const clsStart = i;
470
- i++;
471
- while (i < pattern.length && /[a-zA-Z0-9_-]/.test(pattern[i])) i++;
472
- const segment = pattern.slice(clsStart, i);
473
- result += segment;
474
- lastCh = segment[segment.length - 1] || lastCh;
475
- continue;
476
- }
477
- if (char === "[") {
478
- const attachToLast = lastCh === "]" || lastCh === "@" || /[a-zA-Z0-9-]/.test(lastCh);
479
- if (result && !attachToLast && lastCh !== " ") result += " ";
480
- const attrStart = i;
481
- let depth = 0;
482
- while (i < pattern.length) {
483
- if (pattern[i] === "[") depth++;
484
- if (pattern[i] === "]") depth--;
485
- i++;
486
- if (depth === 0) break;
487
- }
488
- result += pattern.slice(attrStart, i);
489
- lastCh = "]";
490
- continue;
491
- }
492
- result += char;
493
- lastCh = char;
494
- i++;
495
- }
496
- return result;
497
- }
498
- /**
499
- * Determine if the sub-element key should be auto-injected based on pattern ending.
500
- *
501
- * Key injection rules (when no @ placeholder is present):
502
- *
503
- * | Pattern Ending | Inject Key? | Example | Result |
504
- * |----------------|-------------|---------|--------|
505
- * | Combinator (>, +, ~) | Yes | `'>Body>'` | `> [data-element="Body"] > [el]` |
506
- * | Uppercase element | Yes | `'>Body>Row'` | `> [el1] > [el2] [key]` |
507
- * | Lowercase tag | No | `'h1'` | ` h1` |
508
- * | Universal (*) | No | `'h1 *'` | ` h1 *` |
509
- * | Pseudo (:hover, ::before) | No | `'::before'` | `::before` |
510
- * | Class (.active) | No | `'.active'` | `.active` |
511
- * | Attribute ([type]) | No | `'[type="text"]'` | `[type="text"]` |
512
- *
513
- * @param pattern - The normalized pattern (after stripping &)
514
- * @returns true if key should be injected, false otherwise
515
- *
516
- * @example
517
- * shouldInjectKey('>') // → true (trailing combinator)
518
- * shouldInjectKey('>Body>Row') // → true (ends with element)
519
- * shouldInjectKey('h1') // → false (ends with tag)
520
- * shouldInjectKey('*') // → false (universal selector)
521
- * shouldInjectKey('::before') // → false (ends with pseudo)
522
- * shouldInjectKey('.active') // → false (ends with class)
523
- * shouldInjectKey('a:hover') // → false (ends with pseudo)
524
- * shouldInjectKey('button.primary') // → false (ends with class)
525
- */
526
- function shouldInjectKey(pattern) {
527
- const trimmed = pattern.trim();
528
- if (/[>+~]$/.test(trimmed)) return true;
529
- if (/(?:^|[\s>+~\]:])[A-Z][a-zA-Z0-9]*$/.test(trimmed)) return true;
530
- return false;
531
- }
532
- /**
533
- * Normalize selector suffix from $ property
534
- */
535
- function normalizeSelectorSuffix(suffix) {
536
- if (!suffix) return "";
537
- return suffix.startsWith("&") ? suffix.slice(1) : suffix;
538
- }
539
- /**
540
- * Build handler queue from style keys
541
- */
542
- function buildHandlerQueue(styleKeys, styles) {
543
- const queue = [];
544
- const seenHandlers = /* @__PURE__ */ new Set();
545
- for (const styleName of styleKeys) {
546
- let handlers = STYLE_HANDLER_MAP[styleName];
547
- if (!handlers) handlers = STYLE_HANDLER_MAP[styleName] = [createStyle(styleName)];
548
- for (const handler of handlers) {
549
- if (seenHandlers.has(handler)) continue;
550
- seenHandlers.add(handler);
551
- const lookupStyles = handler.__lookupStyles;
552
- const styleMap = {};
553
- for (const name of lookupStyles) {
554
- const val = styles[name];
555
- if (val !== void 0) styleMap[name] = val;
556
- }
557
- queue.push({
558
- handler,
559
- styleMap
560
- });
561
- }
562
- }
563
- return queue;
564
- }
565
- /**
566
- * Compute all valid state combinations for a handler's lookup styles
567
- */
568
- function computeStateCombinations(exclusiveByStyle, lookupStyles) {
569
- const combinations = cartesianProduct(lookupStyles.map((style) => exclusiveByStyle.get(style) || []));
570
- const snapshots = [];
571
- for (const combo of combinations) {
572
- const simplified = simplifyCondition(and(...combo.map((e) => e.exclusiveCondition)));
573
- if (simplified.kind === "false") continue;
574
- const values = {};
575
- for (const entry of combo) values[entry.styleKey] = entry.value;
576
- snapshots.push({
577
- condition: simplified,
578
- values
579
- });
580
- }
581
- return snapshots;
582
- }
583
- /**
584
- * Cartesian product of arrays
585
- */
586
- function cartesianProduct(arrays) {
587
- if (arrays.length === 0) return [[]];
588
- const nonEmpty = arrays.filter((a) => a.length > 0);
589
- if (nonEmpty.length === 0) return [[]];
590
- let result = [[]];
591
- for (const arr of nonEmpty) {
592
- const next = [];
593
- for (const combo of result) for (const item of arr) {
594
- const newCombo = new Array(combo.length + 1);
595
- for (let i = 0; i < combo.length; i++) newCombo[i] = combo[i];
596
- newCombo[combo.length] = item;
597
- next.push(newCombo);
598
- }
599
- result = next;
600
- }
601
- return result;
602
- }
603
- const declStringCache = /* @__PURE__ */ new WeakMap();
604
- function stringifyDeclarations(decl) {
605
- let cached = declStringCache.get(decl);
606
- if (cached === void 0) {
607
- cached = JSON.stringify(decl);
608
- declStringCache.set(decl, cached);
609
- }
610
- return cached;
611
- }
612
- /**
613
- * Merge rules with identical CSS output
614
- */
615
- function mergeByValue(rules) {
616
- const groups = /* @__PURE__ */ new Map();
617
- for (const rule of rules) {
618
- const key = `${rule.selectorSuffix}|${stringifyDeclarations(rule.declarations)}`;
619
- if (!groups.has(key)) groups.set(key, []);
620
- groups.get(key).push(rule);
621
- }
622
- const merged = [];
623
- for (const [, groupRules] of groups) if (groupRules.length === 1) merged.push(groupRules[0]);
624
- else {
625
- const mergedCondition = simplifyCondition(or(...groupRules.map((r) => r.condition)));
626
- merged.push({
627
- condition: mergedCondition,
628
- declarations: groupRules[0].declarations,
629
- selectorSuffix: groupRules[0].selectorSuffix
630
- });
631
- }
632
- return merged;
633
- }
634
- /**
635
- * Build selector fragment from a variant (without className prefix)
636
- */
637
- function buildSelectorFromVariant(variant, selectorSuffix) {
638
- let selector = "";
639
- selector += branchToCSS([...variant.modifierConditions, ...variant.pseudoConditions]);
640
- for (const group of variant.selectorGroups) selector += selectorGroupToCSS(group);
641
- if (variant.parentGroups.length > 0) selector += parentGroupsToCSS(variant.parentGroups);
642
- selector += selectorSuffix;
643
- const ownOptimized = optimizeGroups(variant.ownGroups);
644
- for (const group of ownOptimized) selector += selectorGroupToCSS(group);
645
- return selector;
646
- }
647
- /**
648
- * Materialize a computed rule to final CSS format
649
- *
650
- * Returns an array because OR conditions may generate multiple CSS rules
651
- * (when different branches have different at-rules)
652
- */
653
- function materializeComputedRule(rule) {
654
- const components = conditionToCSS(rule.condition);
655
- if (components.isImpossible || components.variants.length === 0) return [];
656
- const declarations = Object.entries(rule.declarations).map(([prop, value]) => `${prop}: ${value};`).join(" ");
657
- const getRootPrefixKey = (variant) => {
658
- return rootGroupsToCSS(variant.rootGroups) || "";
659
- };
660
- const byAtRules = /* @__PURE__ */ new Map();
661
- for (const variant of components.variants) {
662
- const atRules = buildAtRulesFromVariant(variant);
663
- const startingStyle = variant.startingStyle;
664
- const key = atRules.sort().join("|||") + "###" + getRootPrefixKey(variant) + "###" + (startingStyle ? "1" : "0");
665
- const group = byAtRules.get(key);
666
- if (group) group.variants.push(variant);
667
- else byAtRules.set(key, {
668
- variants: [variant],
669
- atRules,
670
- rootPrefix: rootGroupsToCSS(variant.rootGroups),
671
- startingStyle: startingStyle || void 0
672
- });
673
- }
674
- const rules = [];
675
- for (const [, group] of byAtRules) {
676
- const selectorFragments = mergeVariantsIntoSelectorGroups(group.variants).map((v) => buildSelectorFromVariant(v, rule.selectorSuffix));
677
- const cssRule = {
678
- selector: selectorFragments.length === 1 ? selectorFragments[0] : selectorFragments,
679
- declarations
680
- };
681
- if (group.atRules.length > 0) cssRule.atRules = group.atRules;
682
- if (group.rootPrefix) cssRule.rootPrefix = group.rootPrefix;
683
- if (group.startingStyle) cssRule.startingStyle = true;
684
- rules.push(cssRule);
685
- }
686
- return rules;
687
- }
688
- /**
689
- * Merge StyleResult entries that share the same selector and at-rules,
690
- * concatenating their declarations into a single rule.
691
- *
692
- * This reduces CSS output size when many style keys (e.g. design tokens)
693
- * resolve to the same selector/state combination.
694
- */
695
- function mergeStyleResults(results) {
696
- if (results.length <= 1) return results;
697
- const groups = /* @__PURE__ */ new Map();
698
- for (const result of results) {
699
- const key = `${result.atRules?.join("|") ?? ""}||${result.selector}||${result.startingStyle ? "1" : "0"}`;
700
- const existing = groups.get(key);
701
- if (existing) existing.declarations = existing.declarations ? `${existing.declarations} ${result.declarations}` : result.declarations;
702
- else groups.set(key, { ...result });
703
- }
704
- return Array.from(groups.values());
705
- }
706
- function renderStyles(styles, classNameOrSelector, options, pipelineCacheKey) {
707
- const directSelector = !!classNameOrSelector;
708
- let rules;
709
- if (pipelineCacheKey) rules = pipelineCache.get(pipelineCacheKey);
710
- if (!rules && !styles) return directSelector ? [] : { rules: [] };
711
- const cacheKey = pipelineCacheKey || stringifyStyles(styles);
712
- if (!rules) rules = pipelineCache.get(cacheKey);
713
- if (!rules) {
714
- rules = runPipeline(styles, createStateParserContext(styles));
715
- pipelineCache.set(cacheKey, rules);
716
- }
717
- if (directSelector) {
718
- const shouldDouble = options?.doubleSelector ?? false;
719
- return mergeStyleResults(rules.map((rule) => {
720
- const result = {
721
- selector: (Array.isArray(rule.selector) ? rule.selector : rule.selector ? [rule.selector] : [""]).map((part) => {
722
- let sel = part ? `${classNameOrSelector}${part}` : classNameOrSelector;
723
- if (shouldDouble && sel.startsWith(".")) {
724
- const classMatch = sel.match(/^\.[a-zA-Z_-][a-zA-Z0-9_-]*/);
725
- if (classMatch) sel = classMatch[0] + sel;
726
- }
727
- if (rule.rootPrefix) sel = `${rule.rootPrefix} ${sel}`;
728
- return sel;
729
- }).join(", "),
730
- declarations: rule.declarations
731
- };
732
- if (rule.atRules && rule.atRules.length > 0) result.atRules = rule.atRules;
733
- if (rule.startingStyle) result.startingStyle = true;
734
- return result;
735
- }));
736
- }
737
- return { rules: rules.map((r) => ({
738
- selector: Array.isArray(r.selector) ? r.selector.join("|||") : r.selector,
739
- declarations: r.declarations,
740
- atRules: r.atRules,
741
- needsClassName: true,
742
- rootPrefix: r.rootPrefix,
743
- startingStyle: r.startingStyle
744
- })) };
745
- }
746
- //#endregion
747
- export { clearPipelineCache, hasPipelineCacheEntry, isSelector, renderStyles };
748
-
749
- //# sourceMappingURL=index.js.map