@just-web/toolkits 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (449) hide show
  1. package/dist/_internal/utils/try-parse-json.cjs +14 -0
  2. package/dist/_internal/utils/try-parse-json.cjs.map +1 -0
  3. package/dist/_internal/utils/try-parse-json.mjs +13 -0
  4. package/dist/_internal/utils/try-parse-json.mjs.map +1 -0
  5. package/dist/_virtual/rolldown_runtime.cjs +29 -0
  6. package/dist/attributes/data-attribute.d.cts +17 -0
  7. package/dist/attributes/data-attribute.d.cts.map +1 -0
  8. package/dist/attributes/data-attribute.d.mts +17 -0
  9. package/dist/attributes/data-attribute.d.mts.map +1 -0
  10. package/dist/attributes/get-attribute.cjs +26 -0
  11. package/dist/attributes/get-attribute.cjs.map +1 -0
  12. package/dist/attributes/get-attribute.d.cts +21 -0
  13. package/dist/attributes/get-attribute.d.cts.map +1 -0
  14. package/dist/attributes/get-attribute.d.mts +21 -0
  15. package/dist/attributes/get-attribute.d.mts.map +1 -0
  16. package/dist/attributes/get-attribute.mjs +25 -0
  17. package/dist/attributes/get-attribute.mjs.map +1 -0
  18. package/dist/attributes/get-data-attribute.cjs +19 -0
  19. package/dist/attributes/get-data-attribute.cjs.map +1 -0
  20. package/dist/attributes/get-data-attribute.d.cts +17 -0
  21. package/dist/attributes/get-data-attribute.d.cts.map +1 -0
  22. package/dist/attributes/get-data-attribute.d.mts +17 -0
  23. package/dist/attributes/get-data-attribute.d.mts.map +1 -0
  24. package/dist/attributes/get-data-attribute.mjs +19 -0
  25. package/dist/attributes/get-data-attribute.mjs.map +1 -0
  26. package/dist/attributes/observe-attribute.cjs +40 -0
  27. package/dist/attributes/observe-attribute.cjs.map +1 -0
  28. package/dist/attributes/observe-attribute.d.cts +23 -0
  29. package/dist/attributes/observe-attribute.d.cts.map +1 -0
  30. package/dist/attributes/observe-attribute.d.mts +23 -0
  31. package/dist/attributes/observe-attribute.d.mts.map +1 -0
  32. package/dist/attributes/observe-attribute.mjs +39 -0
  33. package/dist/attributes/observe-attribute.mjs.map +1 -0
  34. package/dist/attributes/observe-data-attribute.cjs +31 -0
  35. package/dist/attributes/observe-data-attribute.cjs.map +1 -0
  36. package/dist/attributes/observe-data-attribute.d.cts +26 -0
  37. package/dist/attributes/observe-data-attribute.d.cts.map +1 -0
  38. package/dist/attributes/observe-data-attribute.d.mts +26 -0
  39. package/dist/attributes/observe-data-attribute.d.mts.map +1 -0
  40. package/dist/attributes/observe-data-attribute.mjs +31 -0
  41. package/dist/attributes/observe-data-attribute.mjs.map +1 -0
  42. package/dist/children/just-children.d.cts +37 -0
  43. package/dist/children/just-children.d.cts.map +1 -0
  44. package/dist/children/just-children.d.mts +37 -0
  45. package/dist/children/just-children.d.mts.map +1 -0
  46. package/dist/children/resolve-children.cjs +11 -0
  47. package/dist/children/resolve-children.cjs.map +1 -0
  48. package/dist/children/resolve-children.d.cts +9 -0
  49. package/dist/children/resolve-children.d.cts.map +1 -0
  50. package/dist/children/resolve-children.d.mts +9 -0
  51. package/dist/children/resolve-children.d.mts.map +1 -0
  52. package/dist/children/resolve-children.mjs +10 -0
  53. package/dist/children/resolve-children.mjs.map +1 -0
  54. package/dist/class-name/class-name-props.d.cts +11 -0
  55. package/dist/class-name/class-name-props.d.cts.map +1 -0
  56. package/dist/class-name/class-name-props.d.mts +11 -0
  57. package/dist/class-name/class-name-props.d.mts.map +1 -0
  58. package/dist/class-name/clsx.cjs +3 -0
  59. package/dist/class-name/clsx.d.cts +2 -0
  60. package/dist/class-name/clsx.d.mts +2 -0
  61. package/dist/class-name/clsx.mjs +3 -0
  62. package/dist/class-name/just-class-name.d.cts +36 -0
  63. package/dist/class-name/just-class-name.d.cts.map +1 -0
  64. package/dist/class-name/just-class-name.d.mts +36 -0
  65. package/dist/class-name/just-class-name.d.mts.map +1 -0
  66. package/dist/class-name/resolve-class-name.cjs +12 -0
  67. package/dist/class-name/resolve-class-name.cjs.map +1 -0
  68. package/dist/class-name/resolve-class-name.d.cts +8 -0
  69. package/dist/class-name/resolve-class-name.d.cts.map +1 -0
  70. package/dist/class-name/resolve-class-name.d.mts +8 -0
  71. package/dist/class-name/resolve-class-name.d.mts.map +1 -0
  72. package/dist/class-name/resolve-class-name.mjs +10 -0
  73. package/dist/class-name/resolve-class-name.mjs.map +1 -0
  74. package/dist/color-scheme/get-prefers-color-scheme.cjs +21 -0
  75. package/dist/color-scheme/get-prefers-color-scheme.cjs.map +1 -0
  76. package/dist/color-scheme/get-prefers-color-scheme.d.cts +16 -0
  77. package/dist/color-scheme/get-prefers-color-scheme.d.cts.map +1 -0
  78. package/dist/color-scheme/get-prefers-color-scheme.d.mts +16 -0
  79. package/dist/color-scheme/get-prefers-color-scheme.d.mts.map +1 -0
  80. package/dist/color-scheme/get-prefers-color-scheme.mjs +20 -0
  81. package/dist/color-scheme/get-prefers-color-scheme.mjs.map +1 -0
  82. package/dist/color-scheme/observe-prefers-color-scheme.cjs +29 -0
  83. package/dist/color-scheme/observe-prefers-color-scheme.cjs.map +1 -0
  84. package/dist/color-scheme/observe-prefers-color-scheme.d.cts +20 -0
  85. package/dist/color-scheme/observe-prefers-color-scheme.d.cts.map +1 -0
  86. package/dist/color-scheme/observe-prefers-color-scheme.d.mts +20 -0
  87. package/dist/color-scheme/observe-prefers-color-scheme.d.mts.map +1 -0
  88. package/dist/color-scheme/observe-prefers-color-scheme.mjs +28 -0
  89. package/dist/color-scheme/observe-prefers-color-scheme.mjs.map +1 -0
  90. package/dist/index.cjs +39 -0
  91. package/dist/index.d.cts +26 -0
  92. package/dist/index.d.mts +26 -0
  93. package/dist/index.mjs +20 -0
  94. package/dist/react/hooks/use-attribute.cjs +41 -0
  95. package/dist/react/hooks/use-attribute.cjs.map +1 -0
  96. package/dist/react/hooks/use-attribute.d.cts +21 -0
  97. package/dist/react/hooks/use-attribute.d.cts.map +1 -0
  98. package/dist/react/hooks/use-attribute.d.mts +21 -0
  99. package/dist/react/hooks/use-attribute.d.mts.map +1 -0
  100. package/dist/react/hooks/use-attribute.mjs +40 -0
  101. package/dist/react/hooks/use-attribute.mjs.map +1 -0
  102. package/dist/react/hooks/use-prefers-color-scheme.cjs +42 -0
  103. package/dist/react/hooks/use-prefers-color-scheme.cjs.map +1 -0
  104. package/dist/react/hooks/use-prefers-color-scheme.d.cts +29 -0
  105. package/dist/react/hooks/use-prefers-color-scheme.d.cts.map +1 -0
  106. package/dist/react/hooks/use-prefers-color-scheme.d.mts +29 -0
  107. package/dist/react/hooks/use-prefers-color-scheme.d.mts.map +1 -0
  108. package/dist/react/hooks/use-prefers-color-scheme.mjs +41 -0
  109. package/dist/react/hooks/use-prefers-color-scheme.mjs.map +1 -0
  110. package/dist/react/hooks/use-theme-by-class-name.cjs +60 -0
  111. package/dist/react/hooks/use-theme-by-class-name.cjs.map +1 -0
  112. package/dist/react/hooks/use-theme-by-class-name.d.cts +34 -0
  113. package/dist/react/hooks/use-theme-by-class-name.d.cts.map +1 -0
  114. package/dist/react/hooks/use-theme-by-class-name.d.mts +34 -0
  115. package/dist/react/hooks/use-theme-by-class-name.d.mts.map +1 -0
  116. package/dist/react/hooks/use-theme-by-class-name.mjs +59 -0
  117. package/dist/react/hooks/use-theme-by-class-name.mjs.map +1 -0
  118. package/dist/react/hooks/use-theme-by-data-attribute.cjs +73 -0
  119. package/dist/react/hooks/use-theme-by-data-attribute.cjs.map +1 -0
  120. package/dist/react/hooks/use-theme-by-data-attribute.d.cts +39 -0
  121. package/dist/react/hooks/use-theme-by-data-attribute.d.cts.map +1 -0
  122. package/dist/react/hooks/use-theme-by-data-attribute.d.mts +39 -0
  123. package/dist/react/hooks/use-theme-by-data-attribute.d.mts.map +1 -0
  124. package/dist/react/hooks/use-theme-by-data-attribute.mjs +72 -0
  125. package/dist/react/hooks/use-theme-by-data-attribute.mjs.map +1 -0
  126. package/dist/react/hooks/use-theme-by-local-storage.cjs +53 -0
  127. package/dist/react/hooks/use-theme-by-local-storage.cjs.map +1 -0
  128. package/dist/react/hooks/use-theme-by-local-storage.d.cts +37 -0
  129. package/dist/react/hooks/use-theme-by-local-storage.d.cts.map +1 -0
  130. package/dist/react/hooks/use-theme-by-local-storage.d.mts +37 -0
  131. package/dist/react/hooks/use-theme-by-local-storage.d.mts.map +1 -0
  132. package/dist/react/hooks/use-theme-by-local-storage.mjs +52 -0
  133. package/dist/react/hooks/use-theme-by-local-storage.mjs.map +1 -0
  134. package/dist/react/hooks/use-theme-stores.cjs +40 -0
  135. package/dist/react/hooks/use-theme-stores.cjs.map +1 -0
  136. package/dist/react/hooks/use-theme-stores.d.cts +38 -0
  137. package/dist/react/hooks/use-theme-stores.d.cts.map +1 -0
  138. package/dist/react/hooks/use-theme-stores.d.mts +38 -0
  139. package/dist/react/hooks/use-theme-stores.d.mts.map +1 -0
  140. package/dist/react/hooks/use-theme-stores.mjs +39 -0
  141. package/dist/react/hooks/use-theme-stores.mjs.map +1 -0
  142. package/dist/react/theme/create-theme-hook.cjs +105 -0
  143. package/dist/react/theme/create-theme-hook.cjs.map +1 -0
  144. package/dist/react/theme/create-theme-hook.d.cts +29 -0
  145. package/dist/react/theme/create-theme-hook.d.cts.map +1 -0
  146. package/dist/react/theme/create-theme-hook.d.mts +29 -0
  147. package/dist/react/theme/create-theme-hook.d.mts.map +1 -0
  148. package/dist/react/theme/create-theme-hook.mjs +104 -0
  149. package/dist/react/theme/create-theme-hook.mjs.map +1 -0
  150. package/dist/react.cjs +15 -0
  151. package/dist/react.d.cts +8 -0
  152. package/dist/react.d.mts +8 -0
  153. package/dist/react.mjs +9 -0
  154. package/dist/style/css-properties.d.cts +20 -0
  155. package/dist/style/css-properties.d.cts.map +1 -0
  156. package/dist/style/css-properties.d.mts +20 -0
  157. package/dist/style/css-properties.d.mts.map +1 -0
  158. package/dist/style/define-css-properties.cjs +25 -0
  159. package/dist/style/define-css-properties.cjs.map +1 -0
  160. package/dist/style/define-css-properties.d.cts +24 -0
  161. package/dist/style/define-css-properties.d.cts.map +1 -0
  162. package/dist/style/define-css-properties.d.mts +24 -0
  163. package/dist/style/define-css-properties.d.mts.map +1 -0
  164. package/dist/style/define-css-properties.mjs +24 -0
  165. package/dist/style/define-css-properties.mjs.map +1 -0
  166. package/dist/style/get-css-variable-value.cjs +11 -0
  167. package/dist/style/get-css-variable-value.cjs.map +1 -0
  168. package/dist/style/get-css-variable-value.d.cts +22 -0
  169. package/dist/style/get-css-variable-value.d.cts.map +1 -0
  170. package/dist/style/get-css-variable-value.d.mts +22 -0
  171. package/dist/style/get-css-variable-value.d.mts.map +1 -0
  172. package/dist/style/get-css-variable-value.mjs +10 -0
  173. package/dist/style/get-css-variable-value.mjs.map +1 -0
  174. package/dist/style/just-style.d.cts +44 -0
  175. package/dist/style/just-style.d.cts.map +1 -0
  176. package/dist/style/just-style.d.mts +44 -0
  177. package/dist/style/just-style.d.mts.map +1 -0
  178. package/dist/style/resolve-style.cjs +14 -0
  179. package/dist/style/resolve-style.cjs.map +1 -0
  180. package/dist/style/resolve-style.d.cts +11 -0
  181. package/dist/style/resolve-style.d.cts.map +1 -0
  182. package/dist/style/resolve-style.d.mts +11 -0
  183. package/dist/style/resolve-style.d.mts.map +1 -0
  184. package/dist/style/resolve-style.mjs +13 -0
  185. package/dist/style/resolve-style.mjs.map +1 -0
  186. package/dist/style/style-props.d.cts +13 -0
  187. package/dist/style/style-props.d.cts.map +1 -0
  188. package/dist/style/style-props.d.mts +13 -0
  189. package/dist/style/style-props.d.mts.map +1 -0
  190. package/dist/style/to-dom-style.cjs +33 -0
  191. package/dist/style/to-dom-style.cjs.map +1 -0
  192. package/dist/style/to-dom-style.d.cts +29 -0
  193. package/dist/style/to-dom-style.d.cts.map +1 -0
  194. package/dist/style/to-dom-style.d.mts +29 -0
  195. package/dist/style/to-dom-style.d.mts.map +1 -0
  196. package/dist/style/to-dom-style.mjs +32 -0
  197. package/dist/style/to-dom-style.mjs.map +1 -0
  198. package/dist/testing/theme/dummy-theme-store.cjs +11 -0
  199. package/dist/testing/theme/dummy-theme-store.cjs.map +1 -0
  200. package/dist/testing/theme/dummy-theme-store.mjs +10 -0
  201. package/dist/testing/theme/dummy-theme-store.mjs.map +1 -0
  202. package/dist/theme/_utils/get-theme-from-stores.cjs +24 -0
  203. package/dist/theme/_utils/get-theme-from-stores.cjs.map +1 -0
  204. package/dist/theme/_utils/get-theme-from-stores.mjs +23 -0
  205. package/dist/theme/_utils/get-theme-from-stores.mjs.map +1 -0
  206. package/dist/theme/_utils/observe-theme-from-stores.cjs +39 -0
  207. package/dist/theme/_utils/observe-theme-from-stores.cjs.map +1 -0
  208. package/dist/theme/_utils/observe-theme-from-stores.mjs +39 -0
  209. package/dist/theme/_utils/observe-theme-from-stores.mjs.map +1 -0
  210. package/dist/theme/_utils/parse-stored-theme.cjs +22 -0
  211. package/dist/theme/_utils/parse-stored-theme.cjs.map +1 -0
  212. package/dist/theme/_utils/parse-stored-theme.mjs +22 -0
  213. package/dist/theme/_utils/parse-stored-theme.mjs.map +1 -0
  214. package/dist/theme/_utils/set-theme-to-stores.cjs +16 -0
  215. package/dist/theme/_utils/set-theme-to-stores.cjs.map +1 -0
  216. package/dist/theme/_utils/set-theme-to-stores.mjs +15 -0
  217. package/dist/theme/_utils/set-theme-to-stores.mjs.map +1 -0
  218. package/dist/theme/class-name/apply-theme-to-class-name.cjs +23 -0
  219. package/dist/theme/class-name/apply-theme-to-class-name.cjs.map +1 -0
  220. package/dist/theme/class-name/apply-theme-to-class-name.mjs +22 -0
  221. package/dist/theme/class-name/apply-theme-to-class-name.mjs.map +1 -0
  222. package/dist/theme/class-name/resolve-theme-from-class-name.cjs +23 -0
  223. package/dist/theme/class-name/resolve-theme-from-class-name.cjs.map +1 -0
  224. package/dist/theme/class-name/resolve-theme-from-class-name.mjs +22 -0
  225. package/dist/theme/class-name/resolve-theme-from-class-name.mjs.map +1 -0
  226. package/dist/theme/compose-theme-stores.cjs +74 -0
  227. package/dist/theme/compose-theme-stores.cjs.map +1 -0
  228. package/dist/theme/compose-theme-stores.d.cts +33 -0
  229. package/dist/theme/compose-theme-stores.d.cts.map +1 -0
  230. package/dist/theme/compose-theme-stores.d.mts +33 -0
  231. package/dist/theme/compose-theme-stores.d.mts.map +1 -0
  232. package/dist/theme/compose-theme-stores.mjs +74 -0
  233. package/dist/theme/compose-theme-stores.mjs.map +1 -0
  234. package/dist/theme/data-attribute/apply-theme-to-data-attribute.cjs +23 -0
  235. package/dist/theme/data-attribute/apply-theme-to-data-attribute.cjs.map +1 -0
  236. package/dist/theme/data-attribute/apply-theme-to-data-attribute.mjs +22 -0
  237. package/dist/theme/data-attribute/apply-theme-to-data-attribute.mjs.map +1 -0
  238. package/dist/theme/data-attribute/resolve-theme-from-data-attribute.cjs +23 -0
  239. package/dist/theme/data-attribute/resolve-theme-from-data-attribute.cjs.map +1 -0
  240. package/dist/theme/data-attribute/resolve-theme-from-data-attribute.mjs +22 -0
  241. package/dist/theme/data-attribute/resolve-theme-from-data-attribute.mjs.map +1 -0
  242. package/dist/theme/theme-entry.cjs +13 -0
  243. package/dist/theme/theme-entry.cjs.map +1 -0
  244. package/dist/theme/theme-entry.d.cts +9 -0
  245. package/dist/theme/theme-entry.d.cts.map +1 -0
  246. package/dist/theme/theme-entry.d.mts +9 -0
  247. package/dist/theme/theme-entry.d.mts.map +1 -0
  248. package/dist/theme/theme-entry.mjs +12 -0
  249. package/dist/theme/theme-entry.mjs.map +1 -0
  250. package/dist/theme/theme-entry.types.d.cts +16 -0
  251. package/dist/theme/theme-entry.types.d.cts.map +1 -0
  252. package/dist/theme/theme-entry.types.d.mts +16 -0
  253. package/dist/theme/theme-entry.types.d.mts.map +1 -0
  254. package/dist/theme/theme-map.types.d.cts +10 -0
  255. package/dist/theme/theme-map.types.d.cts.map +1 -0
  256. package/dist/theme/theme-map.types.d.mts +10 -0
  257. package/dist/theme/theme-map.types.d.mts.map +1 -0
  258. package/dist/theme/theme-store/async-theme-store.types.d.cts +25 -0
  259. package/dist/theme/theme-store/async-theme-store.types.d.cts.map +1 -0
  260. package/dist/theme/theme-store/async-theme-store.types.d.mts +25 -0
  261. package/dist/theme/theme-store/async-theme-store.types.d.mts.map +1 -0
  262. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.cjs +53 -0
  263. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.cjs.map +1 -0
  264. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.cts +28 -0
  265. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.cts.map +1 -0
  266. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.mts +28 -0
  267. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.mts.map +1 -0
  268. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.mjs +53 -0
  269. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.mjs.map +1 -0
  270. package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.cjs +121 -0
  271. package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.cjs.map +1 -0
  272. package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.d.cts +65 -0
  273. package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.d.cts.map +1 -0
  274. package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.d.mts +65 -0
  275. package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.d.mts.map +1 -0
  276. package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.mjs +120 -0
  277. package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.mjs.map +1 -0
  278. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.cjs +51 -0
  279. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.cjs.map +1 -0
  280. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.cts +30 -0
  281. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.cts.map +1 -0
  282. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.mts +30 -0
  283. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.mts.map +1 -0
  284. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.mjs +51 -0
  285. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.mjs.map +1 -0
  286. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.cjs +54 -0
  287. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.cjs.map +1 -0
  288. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.d.cts +31 -0
  289. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.d.cts.map +1 -0
  290. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.d.mts +31 -0
  291. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.d.mts.map +1 -0
  292. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.mjs +54 -0
  293. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.mjs.map +1 -0
  294. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.cjs +67 -0
  295. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.cjs.map +1 -0
  296. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.cts +34 -0
  297. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.cts.map +1 -0
  298. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.mts +34 -0
  299. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.mts.map +1 -0
  300. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.mjs +67 -0
  301. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.mjs.map +1 -0
  302. package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.cjs +39 -0
  303. package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.cjs.map +1 -0
  304. package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.d.cts +32 -0
  305. package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.d.cts.map +1 -0
  306. package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.d.mts +32 -0
  307. package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.d.mts.map +1 -0
  308. package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.mjs +39 -0
  309. package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.mjs.map +1 -0
  310. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.cjs +67 -0
  311. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.cjs.map +1 -0
  312. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.cts +34 -0
  313. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.cts.map +1 -0
  314. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.mts +34 -0
  315. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.mts.map +1 -0
  316. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.mjs +67 -0
  317. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.mjs.map +1 -0
  318. package/dist/theme/theme-store/theme-store-factory.types.d.cts +10 -0
  319. package/dist/theme/theme-store/theme-store-factory.types.d.cts.map +1 -0
  320. package/dist/theme/theme-store/theme-store-factory.types.d.mts +10 -0
  321. package/dist/theme/theme-store/theme-store-factory.types.d.mts.map +1 -0
  322. package/dist/theme/theme-store/theme-store.types.d.cts +33 -0
  323. package/dist/theme/theme-store/theme-store.types.d.cts.map +1 -0
  324. package/dist/theme/theme-store/theme-store.types.d.mts +33 -0
  325. package/dist/theme/theme-store/theme-store.types.d.mts.map +1 -0
  326. package/dist/theme.cjs +20 -0
  327. package/dist/theme.d.cts +15 -0
  328. package/dist/theme.d.mts +15 -0
  329. package/dist/theme.mjs +11 -0
  330. package/dist/units/get-rem-to-px-scale.cjs +30 -0
  331. package/dist/units/get-rem-to-px-scale.cjs.map +1 -0
  332. package/dist/units/get-rem-to-px-scale.d.cts +21 -0
  333. package/dist/units/get-rem-to-px-scale.d.cts.map +1 -0
  334. package/dist/units/get-rem-to-px-scale.d.mts +21 -0
  335. package/dist/units/get-rem-to-px-scale.d.mts.map +1 -0
  336. package/dist/units/get-rem-to-px-scale.mjs +29 -0
  337. package/dist/units/get-rem-to-px-scale.mjs.map +1 -0
  338. package/dist/units/px-2-num.cjs +23 -0
  339. package/dist/units/px-2-num.cjs.map +1 -0
  340. package/dist/units/px-2-num.d.cts +19 -0
  341. package/dist/units/px-2-num.d.cts.map +1 -0
  342. package/dist/units/px-2-num.d.mts +19 -0
  343. package/dist/units/px-2-num.d.mts.map +1 -0
  344. package/dist/units/px-2-num.mjs +22 -0
  345. package/dist/units/px-2-num.mjs.map +1 -0
  346. package/dist/units/px-2-rem.cjs +31 -0
  347. package/dist/units/px-2-rem.cjs.map +1 -0
  348. package/dist/units/px-2-rem.d.cts +25 -0
  349. package/dist/units/px-2-rem.d.cts.map +1 -0
  350. package/dist/units/px-2-rem.d.mts +25 -0
  351. package/dist/units/px-2-rem.d.mts.map +1 -0
  352. package/dist/units/px-2-rem.mjs +30 -0
  353. package/dist/units/px-2-rem.mjs.map +1 -0
  354. package/dist/units/rem-2-px.cjs +31 -0
  355. package/dist/units/rem-2-px.cjs.map +1 -0
  356. package/dist/units/rem-2-px.d.cts +25 -0
  357. package/dist/units/rem-2-px.d.cts.map +1 -0
  358. package/dist/units/rem-2-px.d.mts +25 -0
  359. package/dist/units/rem-2-px.d.mts.map +1 -0
  360. package/dist/units/rem-2-px.mjs +30 -0
  361. package/dist/units/rem-2-px.mjs.map +1 -0
  362. package/dist/utils/append-id.cjs +16 -0
  363. package/dist/utils/append-id.cjs.map +1 -0
  364. package/dist/utils/append-id.d.cts +12 -0
  365. package/dist/utils/append-id.d.cts.map +1 -0
  366. package/dist/utils/append-id.d.mts +12 -0
  367. package/dist/utils/append-id.d.mts.map +1 -0
  368. package/dist/utils/append-id.mjs +15 -0
  369. package/dist/utils/append-id.mjs.map +1 -0
  370. package/package.json +120 -0
  371. package/readme.md +15 -0
  372. package/src/_internal/utils/try-parse-json.ts +8 -0
  373. package/src/attributes/data-attribute.ts +49 -0
  374. package/src/attributes/get-attribute.ts +20 -0
  375. package/src/attributes/get-data-attribute.ts +15 -0
  376. package/src/attributes/observe-attribute.ts +37 -0
  377. package/src/attributes/observe-data-attribute.ts +29 -0
  378. package/src/children/just-children-fn-props.editor.default.tsx +29 -0
  379. package/src/children/just-children-props.editor.default.tsx +17 -0
  380. package/src/children/just-children.editor.default.tsx +11 -0
  381. package/src/children/just-children.ts +37 -0
  382. package/src/children/resolve-children.ts +16 -0
  383. package/src/class-name/class-name-props.editor.tsx +13 -0
  384. package/src/class-name/class-name-props.ts +7 -0
  385. package/src/class-name/clsx.ts +3 -0
  386. package/src/class-name/just-class-name-props.editor.default.tsx +23 -0
  387. package/src/class-name/just-class-name-resolver-state.editor.default.tsx +18 -0
  388. package/src/class-name/just-class-name.editor.default-class-name.tsx +28 -0
  389. package/src/class-name/just-class-name.editor.default.tsx +14 -0
  390. package/src/class-name/just-class-name.editor.type-param.tsx +25 -0
  391. package/src/class-name/just-class-name.ts +36 -0
  392. package/src/class-name/resolve-class-name.ts +12 -0
  393. package/src/color-scheme/get-prefers-color-scheme.ts +17 -0
  394. package/src/color-scheme/observe-prefers-color-scheme.ts +24 -0
  395. package/src/index.ts +25 -0
  396. package/src/react/hooks/use-attribute.ts +59 -0
  397. package/src/react/hooks/use-prefers-color-scheme.ts +42 -0
  398. package/src/react/hooks/use-theme-by-class-name.ts +69 -0
  399. package/src/react/hooks/use-theme-by-data-attribute.ts +84 -0
  400. package/src/react/hooks/use-theme-by-local-storage.ts +68 -0
  401. package/src/react/hooks/use-theme-stores.ts +83 -0
  402. package/src/react/theme/create-theme-hook.ts +197 -0
  403. package/src/react.ts +7 -0
  404. package/src/style/css-properties.ts +20 -0
  405. package/src/style/define-css-properties.ts +23 -0
  406. package/src/style/get-css-variable-value.ts +32 -0
  407. package/src/style/just-style-props.editor.default.tsx +17 -0
  408. package/src/style/just-style-resolver-state.editor.default.tsx +22 -0
  409. package/src/style/just-style.editor.default.tsx +17 -0
  410. package/src/style/just-style.editor.type-param.tsx +31 -0
  411. package/src/style/just-style.ts +60 -0
  412. package/src/style/resolve-style.ts +23 -0
  413. package/src/style/style-props.editor.tsx +13 -0
  414. package/src/style/style-props.ts +8 -0
  415. package/src/style/to-dom-style.ts +36 -0
  416. package/src/testing/button.theme.ts +21 -0
  417. package/src/testing/button.tsx +11 -0
  418. package/src/testing/log-panel.tsx +14 -0
  419. package/src/testing/theme/dummy-theme-store.ts +7 -0
  420. package/src/testing/theme/theme-result-card.tsx +43 -0
  421. package/src/testing/theme/theme-store-demo.tsx +87 -0
  422. package/src/theme/_utils/get-theme-from-stores.ts +34 -0
  423. package/src/theme/_utils/observe-theme-from-stores.ts +57 -0
  424. package/src/theme/_utils/parse-stored-theme.ts +21 -0
  425. package/src/theme/_utils/set-theme-to-stores.ts +23 -0
  426. package/src/theme/class-name/apply-theme-to-class-name.ts +26 -0
  427. package/src/theme/class-name/resolve-theme-from-class-name.ts +22 -0
  428. package/src/theme/compose-theme-stores.ts +139 -0
  429. package/src/theme/data-attribute/apply-theme-to-data-attribute.ts +27 -0
  430. package/src/theme/data-attribute/resolve-theme-from-data-attribute.ts +23 -0
  431. package/src/theme/theme-entry.ts +10 -0
  432. package/src/theme/theme-entry.types.ts +11 -0
  433. package/src/theme/theme-map.types.ts +6 -0
  434. package/src/theme/theme-store/async-theme-store.types.ts +24 -0
  435. package/src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts +62 -0
  436. package/src/theme/theme-store/cookie-theme-store/cookie-theme-store.ts +174 -0
  437. package/src/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.ts +60 -0
  438. package/src/theme/theme-store/in-memory-theme-store/in-memory-theme-store.ts +54 -0
  439. package/src/theme/theme-store/local-storage-theme-store/local-storage-theme-store.ts +83 -0
  440. package/src/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.ts +43 -0
  441. package/src/theme/theme-store/session-storage-theme-store/session-storage-theme-store.ts +83 -0
  442. package/src/theme/theme-store/theme-store-factory.types.ts +9 -0
  443. package/src/theme/theme-store/theme-store.types.ts +30 -0
  444. package/src/theme.ts +14 -0
  445. package/src/units/get-rem-to-px-scale.ts +27 -0
  446. package/src/units/px-2-num.ts +17 -0
  447. package/src/units/px-2-rem.ts +30 -0
  448. package/src/units/rem-2-px.ts +30 -0
  449. package/src/utils/append-id.ts +10 -0
@@ -0,0 +1,197 @@
1
+ import { useCallback, useSyncExternalStore } from 'react'
2
+ import type { Required } from 'type-plus'
3
+ import {
4
+ type ComposeThemeStoreEntry,
5
+ type ComposeThemeStoresOptions,
6
+ composeThemeStores
7
+ } from '../../theme/compose-theme-stores.ts'
8
+ import { themeEntry } from '../../theme/theme-entry.ts'
9
+ import type { ThemeEntry } from '../../theme/theme-entry.types.ts'
10
+ import type { ThemeMap } from '../../theme/theme-map.types.ts'
11
+ import type { AsyncThemeStore } from '../../theme/theme-store/async-theme-store.types.ts'
12
+ import type { ThemeStoreFactory } from '../../theme/theme-store/theme-store-factory.types.ts'
13
+
14
+ /**
15
+ * Creates a React hook for theme selection that reads from and writes to composed theme stores.
16
+ *
17
+ * The returned hook subscribes to store changes via `useSyncExternalStore`, supports SSR
18
+ * (uses `defaultTheme` for server snapshot), and returns a `[theme, setTheme]` tuple.
19
+ * Channels are cached per store configuration and default theme for efficient reuse.
20
+ *
21
+ * @param themes - ThemeMap mapping theme keys to their values (e.g. CSS class names)
22
+ * @param stores - Array of 1–8 theme stores or factory configs (see ComposeThemeStoreEntry)
23
+ * @param options.defaultTheme - Fallback theme key when stores return empty; also used for SSR
24
+ * @returns A `useTheme` hook that returns `[currentTheme, setTheme]` tuple
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * const useTheme = createThemeHook(themes, [localStorageStore], { defaultTheme: 'light' })
29
+ * const [theme, setTheme] = useTheme()
30
+ * setTheme('dark')
31
+ * ```
32
+ */
33
+ export function createThemeHook<
34
+ Themes extends ThemeMap,
35
+ A extends ThemeStoreFactory<Themes> = never,
36
+ B extends ThemeStoreFactory<Themes> = never,
37
+ C extends ThemeStoreFactory<Themes> = never,
38
+ D extends ThemeStoreFactory<Themes> = never,
39
+ E extends ThemeStoreFactory<Themes> = never,
40
+ F extends ThemeStoreFactory<Themes> = never,
41
+ G extends ThemeStoreFactory<Themes> = never,
42
+ H extends ThemeStoreFactory<Themes> = never
43
+ >(
44
+ themes: Themes,
45
+ stores: readonly [
46
+ store1: ComposeThemeStoreEntry<Themes, A>,
47
+ store2?: ComposeThemeStoreEntry<Themes, B>,
48
+ store3?: ComposeThemeStoreEntry<Themes, C>,
49
+ store4?: ComposeThemeStoreEntry<Themes, D>,
50
+ store5?: ComposeThemeStoreEntry<Themes, E>,
51
+ store6?: ComposeThemeStoreEntry<Themes, F>,
52
+ store7?: ComposeThemeStoreEntry<Themes, G>,
53
+ store8?: ComposeThemeStoreEntry<Themes, H>
54
+ ],
55
+ options?: ComposeThemeStoresOptions<Themes>
56
+ ): (
57
+ overrideDefaultTheme?: keyof Themes | undefined
58
+ ) => [keyof Themes | undefined, (theme: keyof Themes) => void] {
59
+ const { defaultTheme } = options ?? {}
60
+ return function useTheme(overrideDefaultTheme?: keyof Themes | undefined) {
61
+ const effectiveDefault = overrideDefaultTheme ?? defaultTheme
62
+ const channel = getOrCreateChannel<Themes, A, B, C, D, E, F, G, H>(themes, stores, {
63
+ defaultTheme: effectiveDefault
64
+ })
65
+
66
+ const theme = useSyncExternalStore<keyof Themes | undefined>(
67
+ channel.subscribe,
68
+ channel.getSnapshot,
69
+ channel.getServerSnapshot
70
+ )
71
+
72
+ const setTheme = useCallback(
73
+ async (newTheme: keyof Themes) => {
74
+ await channel.setTheme(newTheme)
75
+ },
76
+ [channel]
77
+ )
78
+
79
+ return [theme, setTheme]
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Creates a subscription channel bridging a composed theme store to React's useSyncExternalStore.
85
+ * Manages listeners, initial async read from store, and delegates setTheme to store.write.
86
+ *
87
+ * @internal
88
+ */
89
+ function createSharedChannel<Themes extends ThemeMap>(
90
+ themes: Themes,
91
+ composedStore: Required<AsyncThemeStore<Themes>>,
92
+ defaultTheme: keyof Themes | undefined
93
+ ) {
94
+ let lastTheme: keyof Themes | undefined = defaultTheme
95
+ const listeners = new Set<(theme: keyof Themes | undefined) => void>()
96
+
97
+ const notify = (theme: keyof Themes | undefined) => {
98
+ lastTheme = theme
99
+ for (const fn of listeners) {
100
+ fn(theme)
101
+ }
102
+ }
103
+
104
+ const handleStoreUpdate = (entry: ThemeEntry<Themes> | undefined | null) => {
105
+ notify(entry?.theme ?? defaultTheme)
106
+ }
107
+
108
+ // Initial read to populate lastTheme (compose store subscribe has no initial notify)
109
+ void Promise.resolve(composedStore.read()).then(
110
+ (entry: ThemeEntry<Themes> | undefined | null) => {
111
+ notify(entry?.theme ?? defaultTheme)
112
+ }
113
+ )
114
+
115
+ let unobserve: () => void = composedStore.subscribe(handleStoreUpdate)
116
+ let isSubscribedToStore = true
117
+
118
+ const subscribe = (listener: (theme: keyof Themes | undefined) => void) => {
119
+ if (!isSubscribedToStore) {
120
+ unobserve = composedStore.subscribe(handleStoreUpdate)
121
+ isSubscribedToStore = true
122
+ }
123
+ listeners.add(listener)
124
+ listener(lastTheme)
125
+ return () => {
126
+ listeners.delete(listener)
127
+ if (listeners.size === 0) {
128
+ unobserve()
129
+ isSubscribedToStore = false
130
+ }
131
+ }
132
+ }
133
+
134
+ const getSnapshot = (): keyof Themes | undefined => lastTheme
135
+ const getServerSnapshot = (): keyof Themes | undefined => defaultTheme
136
+
137
+ return {
138
+ subscribe,
139
+ getSnapshot,
140
+ getServerSnapshot,
141
+ setTheme: (theme: keyof Themes) => composedStore.write(themeEntry(themes, theme))
142
+ }
143
+ }
144
+
145
+ const channelsByStores = new WeakMap<
146
+ object,
147
+ Map<string | undefined, ReturnType<typeof createSharedChannel<any>>>
148
+ >()
149
+
150
+ /**
151
+ * Returns a cached shared channel for the given themes, stores, and defaultTheme.
152
+ * Channels are keyed by stores (WeakMap) and defaultTheme to avoid duplicate subscriptions.
153
+ *
154
+ * @internal
155
+ */
156
+ function getOrCreateChannel<
157
+ Themes extends ThemeMap,
158
+ A extends ThemeStoreFactory<Themes> = never,
159
+ B extends ThemeStoreFactory<Themes> = never,
160
+ C extends ThemeStoreFactory<Themes> = never,
161
+ D extends ThemeStoreFactory<Themes> = never,
162
+ E extends ThemeStoreFactory<Themes> = never,
163
+ F extends ThemeStoreFactory<Themes> = never,
164
+ G extends ThemeStoreFactory<Themes> = never,
165
+ H extends ThemeStoreFactory<Themes> = never
166
+ >(
167
+ themes: Themes,
168
+ stores: readonly [
169
+ store1: ComposeThemeStoreEntry<Themes, A>,
170
+ store2?: ComposeThemeStoreEntry<Themes, B>,
171
+ store3?: ComposeThemeStoreEntry<Themes, C>,
172
+ store4?: ComposeThemeStoreEntry<Themes, D>,
173
+ store5?: ComposeThemeStoreEntry<Themes, E>,
174
+ store6?: ComposeThemeStoreEntry<Themes, F>,
175
+ store7?: ComposeThemeStoreEntry<Themes, G>,
176
+ store8?: ComposeThemeStoreEntry<Themes, H>
177
+ ],
178
+ options?: ComposeThemeStoresOptions<Themes> | undefined
179
+ ) {
180
+ const { defaultTheme } = options ?? {}
181
+ const storesKey = stores as unknown as object
182
+ let byDefault = channelsByStores.get(storesKey) as Map<
183
+ keyof Themes | undefined,
184
+ ReturnType<typeof createSharedChannel<Themes>>
185
+ >
186
+ if (!byDefault) {
187
+ byDefault = new Map<keyof Themes | undefined, ReturnType<typeof createSharedChannel<Themes>>>()
188
+ channelsByStores.set(storesKey, byDefault as any)
189
+ }
190
+ let channel = byDefault.get(defaultTheme) as ReturnType<typeof createSharedChannel<Themes>>
191
+ if (!channel) {
192
+ const composedStore = composeThemeStores(themes, stores, { defaultTheme })
193
+ channel = createSharedChannel<Themes>(themes, composedStore, defaultTheme)
194
+ byDefault.set(defaultTheme, channel)
195
+ }
196
+ return channel
197
+ }
package/src/react.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './react/hooks/use-attribute.ts'
2
+ export * from './react/hooks/use-prefers-color-scheme.ts'
3
+ export * from './react/hooks/use-theme-by-class-name.ts'
4
+ export * from './react/hooks/use-theme-by-data-attribute.ts'
5
+ export * from './react/hooks/use-theme-by-local-storage.ts'
6
+ export * from './react/hooks/use-theme-stores.ts'
7
+ export * from './react/theme/create-theme-hook.ts'
@@ -0,0 +1,20 @@
1
+ import type { Properties } from 'csstype'
2
+
3
+ declare module 'csstype' {
4
+ interface Properties<TLength = (string & {}) | 0, TTime = string & {}> extends CustomProperties {}
5
+ }
6
+
7
+ /** Custom CSS properties (variables) with `--` prefix. */
8
+ interface CustomProperties {
9
+ [k: `--${string}`]: string
10
+ }
11
+
12
+ /**
13
+ * Widens CSS properties to support custom properties.
14
+ * Allows for string or number values for standard properties,
15
+ * and string values for custom properties with '--' prefix.
16
+ * Defined as a union so plain Properties (e.g. from React) are assignable.
17
+ */
18
+ export interface CSSProperties<TLength = string | number, TTime = string & {}>
19
+ extends Properties<TLength, TTime>,
20
+ CustomProperties {}
@@ -0,0 +1,23 @@
1
+ import type { CSSProperties } from './css-properties.ts'
2
+
3
+ /**
4
+ * Defines CSS properties including custom properties.
5
+ * This function is used to properly type CSS properties when defining styles,
6
+ * especially when using CSS custom properties (variables).
7
+ *
8
+ * @param style - CSS properties object that can include both standard and custom properties
9
+ * @returns The same style object with proper typing
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * defineCSSProperties({
14
+ * color: 'red',
15
+ * '--custom-color': '#ff0000'
16
+ * })
17
+ * ```
18
+ */
19
+ export function defineCSSProperties<TLength = 0 | (string & {}), TTime = string & {}>(
20
+ style: CSSProperties<TLength, TTime>
21
+ ) {
22
+ return style as CSSProperties
23
+ }
@@ -0,0 +1,32 @@
1
+ import type { CreateTuple } from 'type-plus'
2
+
3
+ /**
4
+ * Retrieves CSS custom property values from the specified element.
5
+ *
6
+ * @param element - The HTML element to get property values from
7
+ * @param props - CSS custom property names to retrieve, must be in the format `--property-name`
8
+ * @returns Array of property values corresponding to the requested custom properties
9
+ */
10
+ export function getCSSVariableValue<Props extends Array<`--${string}`>>(
11
+ element: HTMLElement,
12
+ ...props: Props
13
+ ): CreateTuple<Props['length'], string>
14
+ /**
15
+ * Retrieves CSS custom property values from `document.body`.
16
+ *
17
+ * @param props - CSS custom property names to retrieve, must be in the format `--property-name`
18
+ * @returns Array of property values corresponding to the requested custom properties
19
+ */
20
+ export function getCSSVariableValue<Props extends Array<`--${string}`>>(
21
+ ...props: Props
22
+ ): CreateTuple<Props['length'], string>
23
+ export function getCSSVariableValue<Props extends Array<`--${string}`>>(
24
+ element: unknown,
25
+ ...props: Props
26
+ ) {
27
+ if (typeof element === 'string') {
28
+ return getCSSVariableValue(globalThis.document.body, element as `--${string}`, ...props)
29
+ }
30
+ const style = globalThis.getComputedStyle(element as HTMLElement)
31
+ return props.map((v) => style.getPropertyValue(v)) as any
32
+ }
@@ -0,0 +1,17 @@
1
+ import type { JustStyleProps } from '@just-web/toolkits'
2
+ import { resolveStyle } from '@just-web/toolkits'
3
+ import { StoryCard } from '@repobuddy/storybook'
4
+ import type { PropsWithChildren } from 'react'
5
+
6
+ function Badge({ style, ...rest }: PropsWithChildren<JustStyleProps>) {
7
+ const props = { style: { padding: '0.25rem 0.5rem', backgroundColor: 'rgb(96 165 250)' } }
8
+ return <div {...rest} style={resolveStyle(props, style)} />
9
+ }
10
+
11
+ export default () => (
12
+ <StoryCard appearance="output">
13
+ <Badge style={{ fontWeight: 'bold' }}>Override</Badge>
14
+ <Badge style={(renderProps) => ({ ...renderProps.style, fontWeight: 'lighter' })}>Amend</Badge>
15
+ <Badge style={() => undefined}>Unstyled</Badge>
16
+ </StoryCard>
17
+ )
@@ -0,0 +1,22 @@
1
+ import type { JustStyleFnProps } from '@just-web/toolkits'
2
+
3
+ function boxTheme(renderProps?: JustStyleFnProps) {
4
+ return {
5
+ ...renderProps,
6
+ style: {
7
+ ...renderProps?.style,
8
+ padding: '0.5rem',
9
+ border: '1px solid rgb(203 213 225)',
10
+ borderRadius: '0.25rem'
11
+ }
12
+ }
13
+ }
14
+
15
+ export default () => {
16
+ const props = boxTheme()
17
+ return (
18
+ <button type="button" {...props}>
19
+ Hello World
20
+ </button>
21
+ )
22
+ }
@@ -0,0 +1,17 @@
1
+ import type { JustStyle } from '@just-web/toolkits'
2
+ import { StoryCard } from '@repobuddy/storybook'
3
+
4
+ const functionStyle: JustStyle<{ isSelected?: boolean | undefined }> = (renderProps) =>
5
+ renderProps.isSelected
6
+ ? { ...renderProps.style, backgroundColor: 'rgb(147 197 253)' }
7
+ : renderProps.style
8
+
9
+ export default () => {
10
+ return (
11
+ <StoryCard appearance="output">
12
+ <div style={functionStyle({ style: { padding: '0.5rem' }, isSelected: true })}>
13
+ Result: selected (blue background)
14
+ </div>
15
+ </StoryCard>
16
+ )
17
+ }
@@ -0,0 +1,31 @@
1
+ import type { JustStyle } from '@just-web/toolkits'
2
+ import { StoryCard } from '@repobuddy/storybook'
3
+
4
+ interface ButtonRenderProps {
5
+ isDisabled?: boolean | undefined
6
+ isPressed?: boolean | undefined
7
+ }
8
+
9
+ const styleWhenDisabled: JustStyle<ButtonRenderProps> = (renderProps) =>
10
+ renderProps.isDisabled
11
+ ? { ...renderProps.style, opacity: 0.5, cursor: 'not-allowed' }
12
+ : renderProps.style
13
+
14
+ const styleWhenActive: JustStyle<ButtonRenderProps> = (renderProps) =>
15
+ renderProps.isPressed
16
+ ? { ...renderProps.style, outline: '2px solid rgb(59 130 246)' }
17
+ : renderProps.style
18
+
19
+ export default () => {
20
+ const renderProps: ButtonRenderProps = { isDisabled: true, isPressed: true }
21
+ return (
22
+ <StoryCard appearance="output">
23
+ <div style={styleWhenDisabled({ ...renderProps, style: { padding: '0.5rem' } })}>
24
+ disabled style
25
+ </div>
26
+ <div style={styleWhenActive({ ...renderProps, style: { padding: '0.5rem' } })}>
27
+ active style
28
+ </div>
29
+ </StoryCard>
30
+ )
31
+ }
@@ -0,0 +1,60 @@
1
+ import type { AnyRecord } from 'type-plus'
2
+ import type { CSSProperties } from './css-properties.ts'
3
+
4
+ type DefaultLength = 0 | (string & {})
5
+ type DefaultTime = string & {}
6
+
7
+ /**
8
+ * Props interface for components that accept a render-props-aware `style`.
9
+ *
10
+ * Use this when defining component props that support the same `style` contract as {@link JustStyle}:
11
+ * a static object, a resolver function that receives render props (including existing `style`), or `undefined`.
12
+ *
13
+ * @typeParam RenderProps - Record type for render props. When `style` is a function, it receives `RenderProps` merged with `{ style?: CSSProperties }`.
14
+ * @typeParam TLength - CSS length type (default: `0 | (string & {})`).
15
+ * @typeParam TTime - CSS time type (default: `string & {}`).
16
+ */
17
+ export interface JustStyleProps<
18
+ RenderProps extends AnyRecord = AnyRecord,
19
+ TLength = DefaultLength,
20
+ TTime = DefaultTime
21
+ > {
22
+ style?: JustStyle<RenderProps, TLength, TTime> | undefined
23
+ }
24
+
25
+ /**
26
+ * A `style` type that can be static or computed from render props.
27
+ *
28
+ * - `CSSProperties`: The value is merged with the existing `style` in render props (override wins).
29
+ * - `undefined`: Uses the existing `style` from render props as-is.
30
+ * - `function`: Process the render props and return the desired `style`.
31
+ *
32
+ * @typeParam RenderProps - Record type for render props. Resolvers receive `RenderProps` merged with `{ style?: CSSProperties }`.
33
+ * @typeParam TLength - CSS length type (default: `0 | (string & {})`).
34
+ * @typeParam TTime - CSS time type (default: `string & {}`).
35
+ */
36
+ export type JustStyle<
37
+ RenderProps extends AnyRecord = AnyRecord,
38
+ TLength = DefaultLength,
39
+ TTime = DefaultTime
40
+ > =
41
+ | ((
42
+ renderProps: JustStyleFnProps<RenderProps, TLength, TTime>
43
+ ) => CSSProperties<TLength, TTime> | undefined)
44
+ | CSSProperties<TLength, TTime>
45
+ | undefined
46
+
47
+ /**
48
+ * The props type for `JustStyle` resolver functions.
49
+ *
50
+ * @typeParam RenderProps - Record type for render props.
51
+ * @typeParam TLength - CSS length type (default: `0 | (string & {})`).
52
+ * @typeParam TTime - CSS time type (default: `string & {}`).
53
+ */
54
+ export type JustStyleFnProps<
55
+ RenderProps extends AnyRecord = AnyRecord,
56
+ TLength = DefaultLength,
57
+ TTime = DefaultTime
58
+ > = RenderProps & {
59
+ style?: CSSProperties<TLength, TTime> | undefined
60
+ }
@@ -0,0 +1,23 @@
1
+ import type { AnyRecord } from 'type-plus'
2
+ import type { CSSProperties } from './css-properties.ts'
3
+ import type { JustStyle, JustStyleFnProps } from './just-style.ts'
4
+
5
+ type DefaultLength = 0 | (string & {})
6
+ type DefaultTime = string & {}
7
+
8
+ export function resolveStyle<
9
+ RenderProps extends AnyRecord = AnyRecord,
10
+ TLength = DefaultLength,
11
+ TTime = DefaultTime
12
+ >(
13
+ renderProps: JustStyleFnProps<RenderProps, TLength, TTime>,
14
+ style?: JustStyle<RenderProps, TLength, TTime>
15
+ ): CSSProperties<TLength, TTime> | undefined {
16
+ if (typeof style === 'function') {
17
+ return style(renderProps)
18
+ }
19
+ if (style !== undefined) {
20
+ return { ...renderProps.style, ...style } as CSSProperties<TLength, TTime>
21
+ }
22
+ return renderProps.style
23
+ }
@@ -0,0 +1,13 @@
1
+ import type { StyleProps } from '@just-web/toolkits'
2
+ import { StoryCard } from '@repobuddy/storybook'
3
+ import type { PropsWithChildren } from 'react'
4
+
5
+ export default () => (
6
+ <StoryCard appearance="output">
7
+ <MyComponent style={{ color: 'red', fontWeight: 'bold' }}>Hello in red and bold</MyComponent>
8
+ </StoryCard>
9
+ )
10
+
11
+ function MyComponent({ style, children }: PropsWithChildren<StyleProps>) {
12
+ return <div style={style}>{children}</div>
13
+ }
@@ -0,0 +1,8 @@
1
+ import type { CSSProperties } from './css-properties.ts'
2
+
3
+ /**
4
+ * Interface for component props that include a style property.
5
+ */
6
+ export type StyleProps<TLength = 0 | (string & {}), TTime = string & {}> = {
7
+ style?: CSSProperties<TLength, TTime> | undefined
8
+ }
@@ -0,0 +1,36 @@
1
+ import type { CSSProperties } from './css-properties.ts'
2
+
3
+ /**
4
+ * Converts React-style CSS properties to DOM style properties.
5
+ * This function handles both standard CSS properties and custom properties,
6
+ * ensuring proper formatting for DOM style application.
7
+ *
8
+ * @param style - React-style CSS properties object
9
+ * @returns DOM style properties object
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * const domStyle = toDomStyle({
14
+ * backgroundColor: 'red',
15
+ * '--custom-color': '#ff0000'
16
+ * })
17
+ * if (domStyle && element.style) {
18
+ * for (const [key, value] of Object.entries(domStyle)) {
19
+ * element.style.setProperty(key, value)
20
+ * }
21
+ * }
22
+ * ```
23
+ */
24
+ export function toDomStyle(style: CSSProperties | undefined) {
25
+ if (style === undefined) return undefined
26
+
27
+ const result: Record<string, string | null> = {}
28
+
29
+ for (const [key, value] of Object.entries(style)) {
30
+ result[
31
+ key.startsWith('--') ? key : key.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`)
32
+ ] = value
33
+ }
34
+
35
+ return result
36
+ }
@@ -0,0 +1,21 @@
1
+ import type { ButtonRenderProps } from 'react-aria-components'
2
+ import { twMerge } from 'tailwind-merge'
3
+ import type { JustClassName, JustClassNameFnProps } from '../class-name/just-class-name.ts'
4
+ import { resolveClassName } from '../class-name/resolve-class-name.ts'
5
+
6
+ export const buttonTheme = {
7
+ className(
8
+ state: JustClassNameFnProps<ButtonRenderProps>,
9
+ className: JustClassName<ButtonRenderProps> | undefined
10
+ ) {
11
+ return twMerge(
12
+ resolveClassName(
13
+ {
14
+ ...state,
15
+ className: 'bg-cyan-700 text-white px-4 py-2 rounded-md shadow-md active:bg-cyan-800'
16
+ },
17
+ className
18
+ )
19
+ )
20
+ }
21
+ }
@@ -0,0 +1,11 @@
1
+ import { forwardRef } from 'react'
2
+ import { Button as RacButton, type ButtonProps as RacButtonProps } from 'react-aria-components'
3
+ import type { JustClassNameProps } from '../class-name/just-class-name.ts'
4
+ import { buttonTheme } from './button.theme.ts'
5
+
6
+ type ButtonProps = Omit<RacButtonProps, 'className'> &
7
+ JustClassNameProps<Omit<RacButtonProps, 'className'>>
8
+
9
+ export const Button = forwardRef<HTMLButtonElement, ButtonProps>(({ className, ...props }, ref) => (
10
+ <RacButton ref={ref} className={(state) => buttonTheme.className(state, className)} {...props} />
11
+ ))
@@ -0,0 +1,14 @@
1
+ import { StoryCard } from '@repobuddy/storybook'
2
+
3
+ export function LogPanel({ title, log }: { title: string; log: string[] }) {
4
+ return (
5
+ <StoryCard appearance="output">
6
+ <h2 className="mb-2">{title}</h2>
7
+ {log.map((entry, i) => (
8
+ <pre key={i} className="font-mono">
9
+ {entry}
10
+ </pre>
11
+ ))}
12
+ </StoryCard>
13
+ )
14
+ }
@@ -0,0 +1,7 @@
1
+ import type { ThemeStore } from '../../theme/theme-store/theme-store.types.ts'
2
+
3
+ export const dummyThemeStore = {
4
+ read: () => undefined,
5
+ write: () => {},
6
+ subscribe: () => () => {}
7
+ } satisfies ThemeStore
@@ -0,0 +1,43 @@
1
+ import { StoryCard } from '@repobuddy/storybook'
2
+ import { appendId } from '../../utils/append-id.ts'
3
+
4
+ type ThemeResult = {
5
+ theme?: unknown
6
+ value?: unknown
7
+ }
8
+
9
+ type ThemeResultCardProps = {
10
+ result: ThemeResult | null | undefined
11
+ title: string
12
+ 'data-testid'?: string | undefined
13
+ }
14
+
15
+ function formatValue(value: unknown): string {
16
+ if (value === null) return '(missing)'
17
+ if (value === '') return '(empty)'
18
+ if (Array.isArray(value)) return `[${value.join(', ')}]`
19
+ return String(value)
20
+ }
21
+
22
+ export function ThemeResultCard({
23
+ result,
24
+ title,
25
+ 'data-testid': dataTestId
26
+ }: ThemeResultCardProps) {
27
+ return (
28
+ <StoryCard title={title} data-testid={dataTestId} appearance="output">
29
+ <p>
30
+ theme:{' '}
31
+ <span data-testid={appendId(dataTestId, 'theme')}>
32
+ {result?.theme === undefined ? '(undefined)' : String(result?.theme)}
33
+ </span>
34
+ </p>
35
+ <p>
36
+ value:{' '}
37
+ <span data-testid={appendId(dataTestId, 'value')}>
38
+ {result?.value === undefined ? '(undefined)' : formatValue(result?.value)}
39
+ </span>
40
+ </p>
41
+ </StoryCard>
42
+ )
43
+ }