@tenphi/tasty 0.0.0-snapshot.bbd10c7 → 0.0.0-snapshot.bbfcd75

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 (370) hide show
  1. package/README.md +196 -140
  2. package/dist/babel-Zs1Q03qt.d.ts +83 -0
  3. package/dist/chunks/async-storage-CG5HnUT5.js +20 -0
  4. package/dist/chunks/async-storage-CG5HnUT5.js.map +1 -0
  5. package/dist/chunks/build-config-CUQVwdWF.js +42 -0
  6. package/dist/chunks/build-config-CUQVwdWF.js.map +1 -0
  7. package/dist/chunks/collector-B0LTHw6Z.js +208 -0
  8. package/dist/chunks/collector-B0LTHw6Z.js.map +1 -0
  9. package/dist/chunks/config-engine-C3pF9EK9.js +267 -0
  10. package/dist/chunks/config-engine-C3pF9EK9.js.map +1 -0
  11. package/dist/chunks/css-definitions-D_it4XZH.js +875 -0
  12. package/dist/chunks/css-definitions-D_it4XZH.js.map +1 -0
  13. package/dist/chunks/css-resources-BN8apgxt.js +142 -0
  14. package/dist/chunks/css-resources-BN8apgxt.js.map +1 -0
  15. package/dist/{debug.js → chunks/debug-C9LeNVoJ.js} +187 -139
  16. package/dist/chunks/debug-C9LeNVoJ.js.map +1 -0
  17. package/dist/chunks/dsl-C5yuAn41.js +1373 -0
  18. package/dist/chunks/dsl-C5yuAn41.js.map +1 -0
  19. package/dist/chunks/hydration-TRcz5vnk.js +41 -0
  20. package/dist/chunks/hydration-TRcz5vnk.js.map +1 -0
  21. package/dist/chunks/react-runtime-O-OUrKLH.js +557 -0
  22. package/dist/chunks/react-runtime-O-OUrKLH.js.map +1 -0
  23. package/dist/chunks/runtime-engine-DvnE2g-E.js +2437 -0
  24. package/dist/chunks/runtime-engine-DvnE2g-E.js.map +1 -0
  25. package/dist/chunks/runtime-state-BTDqSYBk.js +127 -0
  26. package/dist/chunks/runtime-state-BTDqSYBk.js.map +1 -0
  27. package/dist/{utils/merge-styles.js → chunks/shared-utils-DWA4LjIa.js} +55 -55
  28. package/dist/chunks/shared-utils-DWA4LjIa.js.map +1 -0
  29. package/dist/chunks/style-engine-C1ECBZxR.js +5131 -0
  30. package/dist/chunks/style-engine-C1ECBZxR.js.map +1 -0
  31. package/dist/{zero/extractor.js → chunks/zero-engine-B6EnYcXY.js} +89 -82
  32. package/dist/chunks/zero-engine-B6EnYcXY.js.map +1 -0
  33. package/dist/collector-hl5KNH7k.d.ts +165 -0
  34. package/dist/config-DWL1ZYue.d.ts +1358 -0
  35. package/dist/core/index.d.ts +5 -34
  36. package/dist/core/index.js +9 -27
  37. package/dist/index-D9N9GV24.d.ts +1947 -0
  38. package/dist/index.d.ts +5 -51
  39. package/dist/index.js +11 -36
  40. package/dist/{utils/merge-styles.d.ts → merge-styles-C_oMoJVd.d.ts} +3 -3
  41. package/dist/ssr/astro-client.js +6 -0
  42. package/dist/ssr/astro-client.js.map +1 -0
  43. package/dist/ssr/astro-middleware-extract-static.d.ts +11 -0
  44. package/dist/ssr/astro-middleware-extract-static.js +9 -0
  45. package/dist/ssr/astro-middleware-extract-static.js.map +1 -0
  46. package/dist/ssr/astro-middleware-extract.d.ts +11 -0
  47. package/dist/ssr/astro-middleware-extract.js +9 -0
  48. package/dist/ssr/astro-middleware-extract.js.map +1 -0
  49. package/dist/ssr/astro-middleware-static.d.ts +18 -0
  50. package/dist/ssr/astro-middleware-static.js +7 -0
  51. package/dist/ssr/astro-middleware-static.js.map +1 -0
  52. package/dist/ssr/astro-middleware.d.ts +19 -0
  53. package/dist/ssr/astro-middleware.js +7 -0
  54. package/dist/ssr/astro-middleware.js.map +1 -0
  55. package/dist/ssr/astro.d.ts +117 -11
  56. package/dist/ssr/astro.js +204 -48
  57. package/dist/ssr/astro.js.map +1 -1
  58. package/dist/ssr/index.d.ts +37 -4
  59. package/dist/ssr/index.js +6 -6
  60. package/dist/ssr/index.js.map +1 -1
  61. package/dist/ssr/next-config.d.ts +66 -0
  62. package/dist/ssr/next-config.js +124 -0
  63. package/dist/ssr/next-config.js.map +1 -0
  64. package/dist/ssr/next.d.ts +14 -5
  65. package/dist/ssr/next.js +31 -46
  66. package/dist/ssr/next.js.map +1 -1
  67. package/dist/static/index.d.ts +91 -5
  68. package/dist/static/index.js +31 -3
  69. package/dist/static/index.js.map +1 -0
  70. package/dist/static/inject.js.map +1 -1
  71. package/dist/types-jKZNpias.d.ts +1616 -0
  72. package/dist/zero/babel.d.ts +2 -182
  73. package/dist/zero/babel.js +82 -113
  74. package/dist/zero/babel.js.map +1 -1
  75. package/dist/zero/index.d.ts +81 -3
  76. package/dist/zero/index.js +2 -3
  77. package/dist/zero/next.d.ts +1 -1
  78. package/dist/zero/next.js +0 -31
  79. package/dist/zero/next.js.map +1 -1
  80. package/docs/README.md +20 -12
  81. package/docs/adoption.md +59 -32
  82. package/docs/ai-agents.md +229 -0
  83. package/docs/comparison.md +76 -48
  84. package/docs/configuration.md +566 -69
  85. package/docs/debug.md +37 -23
  86. package/docs/design-system.md +63 -32
  87. package/docs/dsl.md +527 -179
  88. package/docs/getting-started.md +62 -41
  89. package/docs/injector.md +157 -51
  90. package/docs/methodology.md +69 -37
  91. package/docs/migration-v3.md +285 -0
  92. package/docs/pipeline.md +744 -0
  93. package/docs/plugins.md +353 -0
  94. package/docs/{runtime.md → react-api.md} +176 -67
  95. package/docs/runtime-benchmarks.md +377 -0
  96. package/docs/ssr.md +350 -94
  97. package/docs/styles.md +108 -27
  98. package/docs/tasty-static.md +149 -87
  99. package/package.json +121 -23
  100. package/tasty.config.ts +6 -0
  101. package/dist/_virtual/_rolldown/runtime.js +0 -7
  102. package/dist/chunks/cacheKey.js +0 -77
  103. package/dist/chunks/cacheKey.js.map +0 -1
  104. package/dist/chunks/definitions.d.ts +0 -37
  105. package/dist/chunks/definitions.js +0 -258
  106. package/dist/chunks/definitions.js.map +0 -1
  107. package/dist/chunks/index.d.ts +0 -1
  108. package/dist/chunks/renderChunk.d.ts +0 -1
  109. package/dist/chunks/renderChunk.js +0 -59
  110. package/dist/chunks/renderChunk.js.map +0 -1
  111. package/dist/compute-styles.d.ts +0 -31
  112. package/dist/compute-styles.js +0 -356
  113. package/dist/compute-styles.js.map +0 -1
  114. package/dist/config.d.ts +0 -372
  115. package/dist/config.js +0 -507
  116. package/dist/config.js.map +0 -1
  117. package/dist/counter-style/index.js +0 -51
  118. package/dist/counter-style/index.js.map +0 -1
  119. package/dist/debug.d.ts +0 -89
  120. package/dist/debug.js.map +0 -1
  121. package/dist/font-face/index.js +0 -63
  122. package/dist/font-face/index.js.map +0 -1
  123. package/dist/hooks/index.d.ts +0 -7
  124. package/dist/hooks/useCounterStyle.d.ts +0 -50
  125. package/dist/hooks/useCounterStyle.js +0 -45
  126. package/dist/hooks/useCounterStyle.js.map +0 -1
  127. package/dist/hooks/useFontFace.d.ts +0 -43
  128. package/dist/hooks/useFontFace.js +0 -69
  129. package/dist/hooks/useFontFace.js.map +0 -1
  130. package/dist/hooks/useGlobalStyles.d.ts +0 -30
  131. package/dist/hooks/useGlobalStyles.js +0 -77
  132. package/dist/hooks/useGlobalStyles.js.map +0 -1
  133. package/dist/hooks/useKeyframes.d.ts +0 -56
  134. package/dist/hooks/useKeyframes.js +0 -63
  135. package/dist/hooks/useKeyframes.js.map +0 -1
  136. package/dist/hooks/useProperty.d.ts +0 -79
  137. package/dist/hooks/useProperty.js +0 -108
  138. package/dist/hooks/useProperty.js.map +0 -1
  139. package/dist/hooks/useRawCSS.d.ts +0 -53
  140. package/dist/hooks/useRawCSS.js +0 -34
  141. package/dist/hooks/useRawCSS.js.map +0 -1
  142. package/dist/hooks/useStyles.d.ts +0 -40
  143. package/dist/hooks/useStyles.js +0 -29
  144. package/dist/hooks/useStyles.js.map +0 -1
  145. package/dist/injector/index.d.ts +0 -166
  146. package/dist/injector/index.js +0 -166
  147. package/dist/injector/index.js.map +0 -1
  148. package/dist/injector/injector.d.ts +0 -166
  149. package/dist/injector/injector.js +0 -464
  150. package/dist/injector/injector.js.map +0 -1
  151. package/dist/injector/sheet-manager.d.ts +0 -136
  152. package/dist/injector/sheet-manager.js +0 -733
  153. package/dist/injector/sheet-manager.js.map +0 -1
  154. package/dist/injector/types.d.ts +0 -204
  155. package/dist/keyframes/index.js +0 -206
  156. package/dist/keyframes/index.js.map +0 -1
  157. package/dist/parser/classify.js +0 -319
  158. package/dist/parser/classify.js.map +0 -1
  159. package/dist/parser/const.js +0 -60
  160. package/dist/parser/const.js.map +0 -1
  161. package/dist/parser/lru.js +0 -109
  162. package/dist/parser/lru.js.map +0 -1
  163. package/dist/parser/parser.d.ts +0 -25
  164. package/dist/parser/parser.js +0 -115
  165. package/dist/parser/parser.js.map +0 -1
  166. package/dist/parser/tokenizer.js +0 -69
  167. package/dist/parser/tokenizer.js.map +0 -1
  168. package/dist/parser/types.d.ts +0 -51
  169. package/dist/parser/types.js +0 -46
  170. package/dist/parser/types.js.map +0 -1
  171. package/dist/pipeline/conditions.d.ts +0 -134
  172. package/dist/pipeline/conditions.js +0 -406
  173. package/dist/pipeline/conditions.js.map +0 -1
  174. package/dist/pipeline/exclusive.js +0 -230
  175. package/dist/pipeline/exclusive.js.map +0 -1
  176. package/dist/pipeline/index.d.ts +0 -55
  177. package/dist/pipeline/index.js +0 -708
  178. package/dist/pipeline/index.js.map +0 -1
  179. package/dist/pipeline/materialize.js +0 -1103
  180. package/dist/pipeline/materialize.js.map +0 -1
  181. package/dist/pipeline/parseStateKey.d.ts +0 -15
  182. package/dist/pipeline/parseStateKey.js +0 -446
  183. package/dist/pipeline/parseStateKey.js.map +0 -1
  184. package/dist/pipeline/simplify.js +0 -515
  185. package/dist/pipeline/simplify.js.map +0 -1
  186. package/dist/pipeline/warnings.js +0 -18
  187. package/dist/pipeline/warnings.js.map +0 -1
  188. package/dist/plugins/index.d.ts +0 -2
  189. package/dist/plugins/okhsl-plugin.d.ts +0 -35
  190. package/dist/plugins/okhsl-plugin.js +0 -97
  191. package/dist/plugins/okhsl-plugin.js.map +0 -1
  192. package/dist/plugins/types.d.ts +0 -76
  193. package/dist/properties/index.js +0 -222
  194. package/dist/properties/index.js.map +0 -1
  195. package/dist/properties/property-type-resolver.d.ts +0 -24
  196. package/dist/properties/property-type-resolver.js +0 -90
  197. package/dist/properties/property-type-resolver.js.map +0 -1
  198. package/dist/ssr/async-storage.d.ts +0 -17
  199. package/dist/ssr/async-storage.js +0 -34
  200. package/dist/ssr/async-storage.js.map +0 -1
  201. package/dist/ssr/collect-auto-properties.js +0 -39
  202. package/dist/ssr/collect-auto-properties.js.map +0 -1
  203. package/dist/ssr/collector.d.ts +0 -102
  204. package/dist/ssr/collector.js +0 -219
  205. package/dist/ssr/collector.js.map +0 -1
  206. package/dist/ssr/format-global-rules.js +0 -22
  207. package/dist/ssr/format-global-rules.js.map +0 -1
  208. package/dist/ssr/format-keyframes.js +0 -69
  209. package/dist/ssr/format-keyframes.js.map +0 -1
  210. package/dist/ssr/format-property.js +0 -49
  211. package/dist/ssr/format-property.js.map +0 -1
  212. package/dist/ssr/format-rules.js +0 -73
  213. package/dist/ssr/format-rules.js.map +0 -1
  214. package/dist/ssr/hydrate.d.ts +0 -22
  215. package/dist/ssr/hydrate.js +0 -49
  216. package/dist/ssr/hydrate.js.map +0 -1
  217. package/dist/ssr/ssr-collector-ref.js +0 -12
  218. package/dist/ssr/ssr-collector-ref.js.map +0 -1
  219. package/dist/states/index.d.ts +0 -49
  220. package/dist/states/index.js +0 -170
  221. package/dist/states/index.js.map +0 -1
  222. package/dist/static/tastyStatic.d.ts +0 -46
  223. package/dist/static/tastyStatic.js +0 -30
  224. package/dist/static/tastyStatic.js.map +0 -1
  225. package/dist/static/types.d.ts +0 -49
  226. package/dist/static/types.js +0 -24
  227. package/dist/static/types.js.map +0 -1
  228. package/dist/styles/border.d.ts +0 -25
  229. package/dist/styles/border.js +0 -120
  230. package/dist/styles/border.js.map +0 -1
  231. package/dist/styles/color.d.ts +0 -14
  232. package/dist/styles/color.js +0 -26
  233. package/dist/styles/color.js.map +0 -1
  234. package/dist/styles/const.js +0 -17
  235. package/dist/styles/const.js.map +0 -1
  236. package/dist/styles/createStyle.js +0 -79
  237. package/dist/styles/createStyle.js.map +0 -1
  238. package/dist/styles/dimension.js +0 -109
  239. package/dist/styles/dimension.js.map +0 -1
  240. package/dist/styles/directional.js +0 -133
  241. package/dist/styles/directional.js.map +0 -1
  242. package/dist/styles/display.d.ts +0 -30
  243. package/dist/styles/display.js +0 -73
  244. package/dist/styles/display.js.map +0 -1
  245. package/dist/styles/fade.d.ts +0 -15
  246. package/dist/styles/fade.js +0 -62
  247. package/dist/styles/fade.js.map +0 -1
  248. package/dist/styles/fill.d.ts +0 -42
  249. package/dist/styles/fill.js +0 -51
  250. package/dist/styles/fill.js.map +0 -1
  251. package/dist/styles/flow.d.ts +0 -16
  252. package/dist/styles/flow.js +0 -12
  253. package/dist/styles/flow.js.map +0 -1
  254. package/dist/styles/gap.d.ts +0 -31
  255. package/dist/styles/gap.js +0 -38
  256. package/dist/styles/gap.js.map +0 -1
  257. package/dist/styles/height.d.ts +0 -17
  258. package/dist/styles/height.js +0 -19
  259. package/dist/styles/height.js.map +0 -1
  260. package/dist/styles/index.d.ts +0 -1
  261. package/dist/styles/index.js +0 -8
  262. package/dist/styles/index.js.map +0 -1
  263. package/dist/styles/inset.d.ts +0 -24
  264. package/dist/styles/inset.js +0 -34
  265. package/dist/styles/inset.js.map +0 -1
  266. package/dist/styles/list.d.ts +0 -16
  267. package/dist/styles/list.js +0 -100
  268. package/dist/styles/list.js.map +0 -1
  269. package/dist/styles/margin.d.ts +0 -24
  270. package/dist/styles/margin.js +0 -32
  271. package/dist/styles/margin.js.map +0 -1
  272. package/dist/styles/outline.d.ts +0 -29
  273. package/dist/styles/outline.js +0 -55
  274. package/dist/styles/outline.js.map +0 -1
  275. package/dist/styles/padding.d.ts +0 -24
  276. package/dist/styles/padding.js +0 -32
  277. package/dist/styles/padding.js.map +0 -1
  278. package/dist/styles/placement.d.ts +0 -37
  279. package/dist/styles/placement.js +0 -74
  280. package/dist/styles/placement.js.map +0 -1
  281. package/dist/styles/predefined.d.ts +0 -71
  282. package/dist/styles/predefined.js +0 -237
  283. package/dist/styles/predefined.js.map +0 -1
  284. package/dist/styles/preset.d.ts +0 -52
  285. package/dist/styles/preset.js +0 -127
  286. package/dist/styles/preset.js.map +0 -1
  287. package/dist/styles/radius.d.ts +0 -12
  288. package/dist/styles/radius.js +0 -83
  289. package/dist/styles/radius.js.map +0 -1
  290. package/dist/styles/scrollMargin.d.ts +0 -24
  291. package/dist/styles/scrollMargin.js +0 -32
  292. package/dist/styles/scrollMargin.js.map +0 -1
  293. package/dist/styles/scrollbar.d.ts +0 -25
  294. package/dist/styles/scrollbar.js +0 -51
  295. package/dist/styles/scrollbar.js.map +0 -1
  296. package/dist/styles/shadow.d.ts +0 -14
  297. package/dist/styles/shadow.js +0 -25
  298. package/dist/styles/shadow.js.map +0 -1
  299. package/dist/styles/shared.js +0 -17
  300. package/dist/styles/shared.js.map +0 -1
  301. package/dist/styles/transition.d.ts +0 -14
  302. package/dist/styles/transition.js +0 -159
  303. package/dist/styles/transition.js.map +0 -1
  304. package/dist/styles/types.d.ts +0 -564
  305. package/dist/styles/width.d.ts +0 -17
  306. package/dist/styles/width.js +0 -19
  307. package/dist/styles/width.js.map +0 -1
  308. package/dist/tasty.d.ts +0 -134
  309. package/dist/tasty.js +0 -240
  310. package/dist/tasty.js.map +0 -1
  311. package/dist/types.d.ts +0 -184
  312. package/dist/utils/cache-wrapper.js +0 -21
  313. package/dist/utils/cache-wrapper.js.map +0 -1
  314. package/dist/utils/case-converter.js +0 -8
  315. package/dist/utils/case-converter.js.map +0 -1
  316. package/dist/utils/color-math.d.ts +0 -46
  317. package/dist/utils/color-math.js +0 -749
  318. package/dist/utils/color-math.js.map +0 -1
  319. package/dist/utils/color-space.d.ts +0 -5
  320. package/dist/utils/color-space.js +0 -228
  321. package/dist/utils/color-space.js.map +0 -1
  322. package/dist/utils/colors.d.ts +0 -5
  323. package/dist/utils/colors.js +0 -10
  324. package/dist/utils/colors.js.map +0 -1
  325. package/dist/utils/css-types.d.ts +0 -7
  326. package/dist/utils/dotize.d.ts +0 -26
  327. package/dist/utils/dotize.js +0 -122
  328. package/dist/utils/dotize.js.map +0 -1
  329. package/dist/utils/filter-base-props.d.ts +0 -15
  330. package/dist/utils/filter-base-props.js +0 -45
  331. package/dist/utils/filter-base-props.js.map +0 -1
  332. package/dist/utils/get-display-name.d.ts +0 -7
  333. package/dist/utils/get-display-name.js +0 -10
  334. package/dist/utils/get-display-name.js.map +0 -1
  335. package/dist/utils/has-keys.js +0 -13
  336. package/dist/utils/has-keys.js.map +0 -1
  337. package/dist/utils/is-dev-env.js +0 -19
  338. package/dist/utils/is-dev-env.js.map +0 -1
  339. package/dist/utils/is-valid-element-type.js +0 -15
  340. package/dist/utils/is-valid-element-type.js.map +0 -1
  341. package/dist/utils/merge-styles.js.map +0 -1
  342. package/dist/utils/mod-attrs.d.ts +0 -6
  343. package/dist/utils/mod-attrs.js +0 -20
  344. package/dist/utils/mod-attrs.js.map +0 -1
  345. package/dist/utils/process-tokens.d.ts +0 -17
  346. package/dist/utils/process-tokens.js +0 -83
  347. package/dist/utils/process-tokens.js.map +0 -1
  348. package/dist/utils/resolve-recipes.d.ts +0 -17
  349. package/dist/utils/resolve-recipes.js +0 -146
  350. package/dist/utils/resolve-recipes.js.map +0 -1
  351. package/dist/utils/selector-transform.js +0 -32
  352. package/dist/utils/selector-transform.js.map +0 -1
  353. package/dist/utils/string.js +0 -8
  354. package/dist/utils/string.js.map +0 -1
  355. package/dist/utils/styles.d.ts +0 -99
  356. package/dist/utils/styles.js +0 -220
  357. package/dist/utils/styles.js.map +0 -1
  358. package/dist/utils/typography.d.ts +0 -47
  359. package/dist/utils/typography.js +0 -51
  360. package/dist/utils/typography.js.map +0 -1
  361. package/dist/utils/warnings.d.ts +0 -16
  362. package/dist/utils/warnings.js +0 -16
  363. package/dist/utils/warnings.js.map +0 -1
  364. package/dist/zero/css-writer.d.ts +0 -45
  365. package/dist/zero/css-writer.js +0 -73
  366. package/dist/zero/css-writer.js.map +0 -1
  367. package/dist/zero/extractor.d.ts +0 -24
  368. package/dist/zero/extractor.js.map +0 -1
  369. package/docs/PIPELINE.md +0 -519
  370. /package/dist/{chunks/cacheKey.d.ts → ssr/astro-client.d.ts} +0 -0
@@ -1,6 +1,10 @@
1
- # Runtime API
1
+ # React API
2
2
 
3
- The React-specific `tasty()` component factory, component props, and hooks. `tasty()` components are hook-free and compatible with React Server Components — no `'use client'` directive needed. For the shared style language (state maps, tokens, units, extending semantics), see [Style DSL](dsl.md). For global configuration, see [Configuration](configuration.md). For the broader docs map, see the [Docs Hub](README.md).
3
+ Use `tasty()` to turn state-aware style definitions into normal React components, extend existing Tasty components, and expose typed styling APIs to consumers.
4
+
5
+ All Tasty style functions — `tasty()` components, `useStyles()`, `useGlobalStyles()`, `useRawCSS()`, `useKeyframes()`, `useProperty()`, `useFontFace()`, `useCounterStyle()`, and `useFunction()` — are hook-free and compatible with React Server Components. No `'use client'` directive is needed. For state maps, tokens, units, and extension semantics, see [Style DSL](dsl.md). For global configuration, see [Configuration](configuration.md). For the broader docs map, see the [Docs Hub](README.md).
6
+
7
+ > **Note:** This file was previously named `runtime.md`. All functionality documented here works in both server and client contexts — "runtime" referred to style computation during React rendering, not to client-side JavaScript.
4
8
 
5
9
  ---
6
10
 
@@ -40,6 +44,32 @@ const PrimaryButton = tasty(Button, {
40
44
 
41
45
  Style maps merge intelligently — see [Style DSL — Extending vs. Replacing State Maps](dsl.md#extending-vs-replacing-state-maps) for extend mode, replace mode, `@inherit`, `null`, and `false` tombstones.
42
46
 
47
+ `tasty(Component, ...)` always wraps `Component` and forwards every prop to it, so `Component` must be Tasty-aware (i.e. it accepts `styles`, `mods`, `qa`, etc. and renders them through its own Tasty pipeline). To apply styles to a third-party component or a string DOM tag via `className`, use the options-only form with `as`:
48
+
49
+ ```jsx
50
+ import NextLink from 'next/link';
51
+
52
+ const Link = tasty({
53
+ as: NextLink,
54
+ styles: {
55
+ color: { '': '#accent-text', ':hover': '#text' },
56
+ textDecoration: 'underline',
57
+ },
58
+ styleProps: ['padding'],
59
+ });
60
+
61
+ const Span = tasty({
62
+ as: 'span',
63
+ styles: { preset: 'strong' },
64
+ });
65
+
66
+ <Link href="/blog" padding="1x">
67
+ Blog
68
+ </Link>;
69
+ ```
70
+
71
+ The wrapped component only needs to forward `className` (and ideally `style`/`ref`). Tasty-specific props (`qa`, `qaVal`, `mods`, `tokens`, `styleProps`, `modProps`, `tokenProps`) are consumed by Tasty and never leak to the DOM.
72
+
43
73
  ---
44
74
 
45
75
  ## Style Props
@@ -58,7 +88,7 @@ const FlexibleBox = tasty({
58
88
 
59
89
  <FlexibleBox gap="2x" align="center" fill="#surface">
60
90
  Content
61
- </FlexibleBox>
91
+ </FlexibleBox>;
62
92
  ```
63
93
 
64
94
  Style props accept state maps, so responsive values work through the same API:
@@ -72,6 +102,26 @@ Style props accept state maps, so responsive values work through the same API:
72
102
 
73
103
  For predefined style prop lists (`FLOW_STYLES`, `POSITION_STYLES`, `DIMENSION_STYLES`, etc.) and guidance on which props to expose per component category, see [Methodology — styleProps as the public API](methodology.md#styleprops-as-the-public-api).
74
104
 
105
+ ### Always-available style props
106
+
107
+ A small set of style properties — `display`, `font`, `preset`, `hide`, `whiteSpace`, `opacity`, and `transition` — are always harvested as style props on every `tasty()` component, even when `styleProps` is omitted. This means you can pass `<Card display="grid" />` or `<Text preset="h1" />` without declaring them. When you do declare `styleProps`, these base props are unioned with your list (not replaced).
108
+
109
+ ---
110
+
111
+ ## `Element`
112
+
113
+ `Element` is the unstyled base component exported from the main entry — equivalent to `tasty({})` (a `div` with no default styles). It accepts all Tasty props (`styles`, `styleProps`, `mods`, `tokens`, `as`, `qa`, `theme`, the `is*` props, etc.) and is useful as a generic styled box or as a building block for layout primitives.
114
+
115
+ ```jsx
116
+ import { Element } from '@tenphi/tasty';
117
+
118
+ <Element as="section" padding="4x" fill="#surface">
119
+ Content
120
+ </Element>;
121
+ ```
122
+
123
+ > Note: `Element` shadows the global DOM `Element` type when imported from `@tenphi/tasty`. In files that need the DOM type, alias the import: `import { Element as TastyElement } from '@tenphi/tasty'`.
124
+
75
125
  ---
76
126
 
77
127
  ## Mod Props
@@ -110,9 +160,9 @@ Map modifier names to type descriptors for precise TypeScript types:
110
160
  ```tsx
111
161
  const Button = tasty({
112
162
  modProps: {
113
- isLoading: Boolean, // isLoading?: boolean
114
- isSelected: Boolean, // isSelected?: boolean
115
- size: ['small', 'medium', 'large'] as const, // size?: 'small' | 'medium' | 'large'
163
+ isLoading: Boolean, // isLoading?: boolean
164
+ isSelected: Boolean, // isSelected?: boolean
165
+ size: ['small', 'medium', 'large'] as const, // size?: 'small' | 'medium' | 'large'
116
166
  },
117
167
  styles: {
118
168
  padding: { '': '2x 4x', 'size=small': '1x 2x', 'size=large': '3x 6x' },
@@ -120,18 +170,20 @@ const Button = tasty({
120
170
  },
121
171
  });
122
172
 
123
- <Button isLoading size="large">Submit</Button>
173
+ <Button isLoading size="large">
174
+ Submit
175
+ </Button>;
124
176
  // Renders: <button data-is-loading="" data-size="large">Submit</button>
125
177
  ```
126
178
 
127
179
  Available type descriptors:
128
180
 
129
- | Descriptor | TypeScript type | Example |
130
- |---|---|---|
131
- | `Boolean` | `boolean` | `isLoading: Boolean` |
132
- | `String` | `string` | `label: String` |
133
- | `Number` | `number` | `count: Number` |
134
- | `['a', 'b'] as const` | `'a' \| 'b'` | `size: ['sm', 'md', 'lg'] as const` |
181
+ | Descriptor | TypeScript type | Example |
182
+ | --------------------- | --------------- | ----------------------------------- |
183
+ | `Boolean` | `boolean` | `isLoading: Boolean` |
184
+ | `String` | `string` | `label: String` |
185
+ | `Number` | `number` | `count: Number` |
186
+ | `['a', 'b'] as const` | `'a' \| 'b'` | `size: ['sm', 'md', 'lg'] as const` |
135
187
 
136
188
  ### Merge with `mods`
137
189
 
@@ -144,11 +196,11 @@ Mod props and the `mods` object can be used together. Mod props take precedence:
144
196
 
145
197
  ### When to use `modProps` vs `mods`
146
198
 
147
- | Use case | Recommendation |
148
- |---|---|
199
+ | Use case | Recommendation |
200
+ | -------------------------------------------- | -------------------------------------------------------- |
149
201
  | Component has a fixed set of known modifiers | `modProps` — cleaner API, better TypeScript autocomplete |
150
- | Component needs arbitrary/dynamic modifiers | `mods` — open-ended `Record<string, ModValue>` |
151
- | Both fixed and dynamic | Combine: `modProps` for known keys, `mods` for ad-hoc |
202
+ | Component needs arbitrary/dynamic modifiers | `mods` — open-ended `Record<string, ModValue>` |
203
+ | Both fixed and dynamic | Combine: `modProps` for known keys, `mods` for ad-hoc |
152
204
 
153
205
  For architecture guidance on when to use modifiers vs `styleProps`, see [Methodology — modProps and mods](methodology.md#modprops-and-mods).
154
206
 
@@ -178,7 +230,7 @@ const ProgressBar = tasty({
178
230
 
179
231
  <ProgressBar progress="75%" accentColor="#purple" />
180
232
  // 'progress' → $progress → --progress
181
- // 'accentColor' → #accent → --accent-color + --accent-color-oklch
233
+ // 'accentColor' → #accent → --accent-color
182
234
  ```
183
235
 
184
236
  ### Object form
@@ -194,7 +246,7 @@ const Card = tasty({
194
246
  styles: { padding: '$card-size', fill: '#card-accent' },
195
247
  });
196
248
 
197
- <Card size="4x" color="#purple" />
249
+ <Card size="4x" color="#purple" />;
198
250
  ```
199
251
 
200
252
  ### Merge with `tokens`
@@ -213,11 +265,11 @@ const Bar = tasty({
213
265
 
214
266
  ### When to use `tokenProps` vs `tokens`
215
267
 
216
- | Use case | Recommendation |
217
- |---|---|
218
- | Component has a fixed set of known token keys | `tokenProps` — cleaner API, better TypeScript autocomplete |
219
- | Component needs arbitrary/dynamic token values | `tokens` — open-ended `Record<string, TokenValue>` |
220
- | Both fixed and dynamic | Combine: `tokenProps` for known keys, `tokens` for ad-hoc |
268
+ | Use case | Recommendation |
269
+ | ---------------------------------------------- | ---------------------------------------------------------- |
270
+ | Component has a fixed set of known token keys | `tokenProps` — cleaner API, better TypeScript autocomplete |
271
+ | Component needs arbitrary/dynamic token values | `tokens` — open-ended `Record<string, TokenValue>` |
272
+ | Both fixed and dynamic | Combine: `tokenProps` for known keys, `tokens` for ad-hoc |
221
273
 
222
274
  For architecture guidance, see [Methodology — tokenProps](methodology.md#tokenprops).
223
275
 
@@ -236,11 +288,11 @@ const Button = tasty({
236
288
  variants: {
237
289
  default: { fill: '#blue', color: '#white' },
238
290
  danger: { fill: '#red', color: '#white' },
239
- outline: { fill: 'transparent', color: '#blue', border: '1bw solid #blue' },
291
+ outline: { fill: '#clear', color: '#blue', border: '1bw solid #blue' },
240
292
  },
241
293
  });
242
294
 
243
- <Button variant="danger">Delete</Button>
295
+ <Button variant="danger">Delete</Button>;
244
296
  ```
245
297
 
246
298
  ### Extending Variants with Base State Maps
@@ -296,7 +348,7 @@ const Card = tasty({
296
348
  <Card>
297
349
  <Card.Title>Card Title</Card.Title>
298
350
  <Card.Content>Card content</Card.Content>
299
- </Card>
351
+ </Card>;
300
352
  ```
301
353
 
302
354
  Each entry in `elements` can be a tag name string or a config object:
@@ -322,7 +374,7 @@ const Card = tasty({
322
374
 
323
375
  <Card>
324
376
  <div data-element="Title">Card Title</div>
325
- </Card>
377
+ </Card>;
326
378
  ```
327
379
 
328
380
  ### Selector Affix (`$`)
@@ -351,11 +403,15 @@ On the client, CSS is injected synchronously into the DOM (idempotent via the in
351
403
 
352
404
  ---
353
405
 
354
- ## Hooks
406
+ ## Style Functions
407
+
408
+ All style functions below are plain functions (not React hooks) and can be used in any environment: client components, SSR with a `ServerStyleCollector`, and React Server Components. They retain their `use` prefix for backward compatibility, but do not use any React hooks internally.
409
+
410
+ In server-only contexts, components that use only Tasty style functions ship no Tasty styling runtime. Astro without `client:*` directives produces no client JavaScript; server-only Next.js RSC follows the same Tasty architecture, while final output depends on the application deployment. Tasty never forces the `'use client'` boundary — that decision belongs to your component when it needs React interactivity (state, effects, event handlers).
355
411
 
356
412
  ### useStyles
357
413
 
358
- Generate a className from a style object. Thin wrapper around `computeStyles()` that adds React context-based SSR collector discovery for backward compatibility:
414
+ Generate a className from a style object. Thin wrapper around `computeStyles()`:
359
415
 
360
416
  ```tsx
361
417
  import { useStyles } from '@tenphi/tasty';
@@ -373,7 +429,7 @@ function MyComponent() {
373
429
 
374
430
  ### useGlobalStyles
375
431
 
376
- Inject global styles for a CSS selector:
432
+ Inject global styles for a CSS selector. Accepts an optional third argument with an `id` for update tracking — when the styles change, the previous injection is disposed and the new one is injected:
377
433
 
378
434
  ```tsx
379
435
  import { useGlobalStyles } from '@tenphi/tasty';
@@ -389,9 +445,18 @@ function ThemeStyles() {
389
445
  }
390
446
  ```
391
447
 
448
+ A slot — the `id`, or the selector when no `id` is given — holds exactly one
449
+ injection **per `root`**. So:
450
+
451
+ - Changing the styles replaces the previous CSS rather than adding to it.
452
+ - Passing styles that produce no CSS (for example `{}`) clears the slot.
453
+ - The same selector used in two shadow roots keeps a separate injection in each.
454
+ - Two independent call sites that share a selector share a slot, and the last
455
+ render wins. Give them distinct `id`s if they should coexist.
456
+
392
457
  ### useRawCSS
393
458
 
394
- Inject raw CSS strings:
459
+ Inject raw CSS strings. Accepts an optional `id` in the options for update tracking — when the CSS changes for the same id, the previous injection is replaced:
395
460
 
396
461
  ```tsx
397
462
  import { useRawCSS } from '@tenphi/tasty';
@@ -405,6 +470,9 @@ function GlobalReset() {
405
470
  }
406
471
  ```
407
472
 
473
+ An `id` slot holds one injection per `root`. Without an `id` the CSS is deduped
474
+ by content and permanent — there is nothing to replace it with later.
475
+
408
476
  ### useKeyframes
409
477
 
410
478
  Inject `@keyframes` rules and return the generated animation name:
@@ -418,14 +486,14 @@ function Spinner() {
418
486
  from: { transform: 'rotate(0deg)' },
419
487
  to: { transform: 'rotate(360deg)' },
420
488
  },
421
- { name: 'spin' }
489
+ { name: 'spin' },
422
490
  );
423
491
 
424
492
  return <div style={{ animation: `${spin} 1s linear infinite` }} />;
425
493
  }
426
494
  ```
427
495
 
428
- `useKeyframes()` also supports a factory function with dependencies:
496
+ `useKeyframes()` also supports a factory function. Without a `name` the factory runs on every invocation and deduplication is handled internally by content hash; with a `name`, matching deps skip the factory entirely:
429
497
 
430
498
  ```tsx
431
499
  function Pulse({ scale }: { scale: number }) {
@@ -434,13 +502,24 @@ function Pulse({ scale }: { scale: number }) {
434
502
  '0%': { transform: 'scale(1)' },
435
503
  '100%': { transform: `scale(${scale})` },
436
504
  }),
437
- [scale]
505
+ [scale],
506
+ { name: 'pulse' },
438
507
  );
439
508
 
440
- return <div style={{ animation: `${pulse} 500ms ease-in-out alternate infinite` }} />;
509
+ return (
510
+ <div
511
+ style={{ animation: `${pulse} 500ms ease-in-out alternate infinite` }}
512
+ />
513
+ );
441
514
  }
442
515
  ```
443
516
 
517
+ Passing `name` claims a slot owned by that one call site, per `root` — much like
518
+ `id` in `useGlobalStyles()` and `useRawCSS()`. When the steps change the previous
519
+ `@keyframes` rule is disposed and the name is reused, so the rules don't
520
+ accumulate and the returned name stays stable. Anonymous keyframes are permanent
521
+ and shared by content.
522
+
444
523
  ### useProperty
445
524
 
446
525
  Register a CSS `@property` rule so a custom property can animate smoothly:
@@ -487,8 +566,16 @@ For multiple weights/styles, pass an array:
487
566
 
488
567
  ```tsx
489
568
  useFontFace('Brand Sans', [
490
- { src: 'url("/fonts/brand-regular.woff2") format("woff2")', fontWeight: 400, fontDisplay: 'swap' },
491
- { src: 'url("/fonts/brand-bold.woff2") format("woff2")', fontWeight: 700, fontDisplay: 'swap' },
569
+ {
570
+ src: 'url("/fonts/brand-regular.woff2") format("woff2")',
571
+ fontWeight: 400,
572
+ fontDisplay: 'swap',
573
+ },
574
+ {
575
+ src: 'url("/fonts/brand-bold.woff2") format("woff2")',
576
+ fontWeight: 700,
577
+ fontDisplay: 'swap',
578
+ },
492
579
  ]);
493
580
  ```
494
581
 
@@ -506,11 +593,14 @@ Inject a `@counter-style` rule and get back the counter style name. Permanent
506
593
  import { useCounterStyle } from '@tenphi/tasty';
507
594
 
508
595
  function EmojiList() {
509
- const styleName = useCounterStyle({
510
- system: 'cyclic',
511
- symbols: '"👍"',
512
- suffix: '" "',
513
- }, { name: 'thumbs' });
596
+ const styleName = useCounterStyle(
597
+ {
598
+ system: 'cyclic',
599
+ symbols: '"👍"',
600
+ suffix: '" "',
601
+ },
602
+ { name: 'thumbs' },
603
+ );
514
604
 
515
605
  return (
516
606
  <ol style={{ listStyleType: styleName }}>
@@ -521,43 +611,62 @@ function EmojiList() {
521
611
  }
522
612
  ```
523
613
 
524
- Factory form with dependencies:
614
+ Signature:
615
+
616
+ ```ts
617
+ function useCounterStyle(
618
+ descriptors: CounterStyleDescriptors,
619
+ options?: { name?: string; root?: Document | ShadowRoot },
620
+ ): string;
621
+ ```
622
+
623
+ ### useFunction
624
+
625
+ Register a CSS `@function` (custom function). Permanent — no cleanup on unmount. Deduplicates by function name. The function name accepts `$$name` (matching the call site `$$name(...)`), `$name`, or `--name`.
525
626
 
526
627
  ```tsx
527
- function DynamicList({ marker }: { marker: string }) {
528
- const styleName = useCounterStyle(
529
- () => ({
530
- system: 'cyclic',
531
- symbols: `"${marker}"`,
532
- suffix: '" "',
533
- }),
534
- [marker],
535
- );
628
+ import { tasty, useFunction } from '@tenphi/tasty';
629
+
630
+ const Box = tasty({ styles: { margin: '$$negative(10px) top' } });
536
631
 
537
- return <ol style={{ listStyleType: styleName }}>...</ol>;
632
+ function Layout() {
633
+ useFunction('$$negative', { args: ['$value'], result: '(-1 * $value)' });
634
+ return <Box />;
538
635
  }
539
636
  ```
540
637
 
541
- Signatures:
638
+ Call the function through the Tasty DSL rather than a raw `style` prop. An inline `style` value reaches the browser unparsed, so the `$$name(...)` sugar is never expanded — and under `configure({ polyfills: { functions: true } })` it silently does nothing, because the polyfill rewrites calls at parse time.
542
639
 
543
- ```ts
544
- function useCounterStyle(
545
- descriptors: CounterStyleDescriptors,
546
- options?: { name?: string; root?: Document | ShadowRoot },
547
- ): string;
640
+ Inside a `tasty()` component you call functions with the same `$$name(...)` sugar:
548
641
 
549
- function useCounterStyle(
550
- factory: () => CounterStyleDescriptors,
551
- deps: readonly unknown[],
552
- options?: { name?: string; root?: Document | ShadowRoot },
553
- ): string;
642
+ ```tsx
643
+ const Box = tasty({
644
+ styles: {
645
+ '@function': { $$negative: { args: ['$value'], result: '(-1 * $value)' } },
646
+ margin: '$$negative(10px) top',
647
+ },
648
+ });
649
+ ```
650
+
651
+ Signature:
652
+
653
+ ```ts
654
+ function useFunction(
655
+ name: string,
656
+ definition: FunctionDefinition,
657
+ options?: { root?: Document | ShadowRoot },
658
+ ): void;
554
659
  ```
555
660
 
661
+ See the [Functions section of the DSL reference](dsl.md#functions-function) for the full descriptor shape, token conventions, and value-sugar support. `@function` is an experimental CSS feature — unsupported browsers safely ignore the native rule, or enable the [`polyfills.functions`](configuration.md#polyfills) inline polyfill for full cross-browser support.
662
+
556
663
  ### Troubleshooting
557
664
 
558
665
  - Styles are not updating: make sure `configure()` runs before first render, and verify the generated class name or global rule with [Debug Utilities](debug.md).
559
- - SSR output looks wrong: check the [SSR guide](ssr.md) for collector setup. `computeStyles()` discovers the SSR collector via `AsyncLocalStorage` or the global getter registered by `TastyRegistry`.
666
+ - SSR output looks wrong: check the [SSR guide](ssr.md) for collector setup. All style functions discover the SSR collector via `AsyncLocalStorage` or the global getter registered by `TastyRegistry`.
560
667
  - Animation/custom property issues: prefer `useKeyframes()` and `useProperty()` over raw CSS when you want Tasty to manage injection and SSR collection for you.
668
+ - For dynamic styles that change over the component lifecycle, use the `id` option in `useGlobalStyles()` and `useRawCSS()` to enable update tracking.
669
+ - RSC inline mode: CSS accumulated by standalone style functions (`useGlobalStyles`, `useRawCSS`, etc.) is flushed into inline `<style>` tags by the next `tasty()` component in the render tree. If your page uses only standalone style functions without any `tasty()` component, the CSS will not be emitted. Ensure at least one `tasty()` component is present in each RSC render tree.
561
670
 
562
671
  ---
563
672
 
@@ -567,6 +676,6 @@ function useCounterStyle(
567
676
  - **[Methodology](methodology.md)** — Recommended patterns: root + sub-elements, styleProps, tokens, wrapping
568
677
  - **[Configuration](configuration.md)** — Tokens, recipes, custom units, style handlers, TypeScript extensions
569
678
  - **[Style Properties](styles.md)** — Complete reference for all enhanced style properties
570
- - **[Zero Runtime (tastyStatic)](tasty-static.md)** — Build-time static styling with Babel plugin
679
+ - **[Build-Time Extraction (`tastyStatic`)](tasty-static.md)** — Static styling with the Babel plugin
571
680
  - **[Server-Side Rendering](ssr.md)** — SSR setup for Next.js, Astro, and generic frameworks
572
681
  - **[Debug Utilities](debug.md)** — Inspect injected CSS, cache state, and active styles at runtime