@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 @@
1
+ {"version":3,"file":"theme-entry.cjs","names":[],"sources":["../../src/theme/theme-entry.ts"],"sourcesContent":["import type { ThemeEntry } from './theme-entry.types.ts'\nimport type { ThemeMap } from './theme-map.types.ts'\n\n/** Creates ThemeEntry from theme map and theme key. */\nexport function themeEntry<Themes extends ThemeMap>(\n\tthemes: Themes,\n\ttheme: keyof Themes\n): ThemeEntry<Themes> {\n\treturn { theme, value: themes[theme] }\n}\n"],"mappings":";;;AAIA,SAAgB,WACf,QACA,OACqB;AACrB,QAAO;EAAE;EAAO,OAAO,OAAO;EAAQ"}
@@ -0,0 +1,9 @@
1
+ import { ThemeMap } from "./theme-map.types.cjs";
2
+ import { ThemeEntry } from "./theme-entry.types.cjs";
3
+
4
+ //#region src/theme/theme-entry.d.ts
5
+ /** Creates ThemeEntry from theme map and theme key. */
6
+ declare function themeEntry<Themes extends ThemeMap>(themes: Themes, theme: keyof Themes): ThemeEntry<Themes>;
7
+ //#endregion
8
+ export { themeEntry };
9
+ //# sourceMappingURL=theme-entry.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-entry.d.cts","names":[],"sources":["../../src/theme/theme-entry.ts"],"sourcesContent":[],"mappings":";;;;;iBAIgB,0BAA0B,kBACjC,qBACK,SACX,WAAW"}
@@ -0,0 +1,9 @@
1
+ import { ThemeMap } from "./theme-map.types.mjs";
2
+ import { ThemeEntry } from "./theme-entry.types.mjs";
3
+
4
+ //#region src/theme/theme-entry.d.ts
5
+ /** Creates ThemeEntry from theme map and theme key. */
6
+ declare function themeEntry<Themes extends ThemeMap>(themes: Themes, theme: keyof Themes): ThemeEntry<Themes>;
7
+ //#endregion
8
+ export { themeEntry };
9
+ //# sourceMappingURL=theme-entry.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-entry.d.mts","names":[],"sources":["../../src/theme/theme-entry.ts"],"sourcesContent":[],"mappings":";;;;;iBAIgB,0BAA0B,kBACjC,qBACK,SACX,WAAW"}
@@ -0,0 +1,12 @@
1
+ //#region src/theme/theme-entry.ts
2
+ /** Creates ThemeEntry from theme map and theme key. */
3
+ function themeEntry(themes, theme) {
4
+ return {
5
+ theme,
6
+ value: themes[theme]
7
+ };
8
+ }
9
+
10
+ //#endregion
11
+ export { themeEntry };
12
+ //# sourceMappingURL=theme-entry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-entry.mjs","names":[],"sources":["../../src/theme/theme-entry.ts"],"sourcesContent":["import type { ThemeEntry } from './theme-entry.types.ts'\nimport type { ThemeMap } from './theme-map.types.ts'\n\n/** Creates ThemeEntry from theme map and theme key. */\nexport function themeEntry<Themes extends ThemeMap>(\n\tthemes: Themes,\n\ttheme: keyof Themes\n): ThemeEntry<Themes> {\n\treturn { theme, value: themes[theme] }\n}\n"],"mappings":";;AAIA,SAAgB,WACf,QACA,OACqB;AACrB,QAAO;EAAE;EAAO,OAAO,OAAO;EAAQ"}
@@ -0,0 +1,16 @@
1
+ import { ThemeMap } from "./theme-map.types.cjs";
2
+
3
+ //#region src/theme/theme-entry.types.d.ts
4
+
5
+ /**
6
+ * Theme entry is a pair of theme key and theme value.
7
+ *
8
+ * It is the basic value persisted by the theme stores.
9
+ */
10
+ interface ThemeEntry<Themes extends ThemeMap = ThemeMap> {
11
+ theme: keyof Themes;
12
+ value: Themes[keyof Themes];
13
+ }
14
+ //#endregion
15
+ export { ThemeEntry };
16
+ //# sourceMappingURL=theme-entry.types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-entry.types.d.cts","names":[],"sources":["../../src/theme/theme-entry.types.ts"],"sourcesContent":[],"mappings":";;;;;;AAOA;;;AACc,UADG,UACH,CAAA,eAD6B,QAC7B,GADwC,QACxC,CAAA,CAAA;EACN,KAAA,EAAA,MADM,MACN;EAAa,KAAA,EAAb,MAAa,CAAA,MAAA,MAAA,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { ThemeMap } from "./theme-map.types.mjs";
2
+
3
+ //#region src/theme/theme-entry.types.d.ts
4
+
5
+ /**
6
+ * Theme entry is a pair of theme key and theme value.
7
+ *
8
+ * It is the basic value persisted by the theme stores.
9
+ */
10
+ interface ThemeEntry<Themes extends ThemeMap = ThemeMap> {
11
+ theme: keyof Themes;
12
+ value: Themes[keyof Themes];
13
+ }
14
+ //#endregion
15
+ export { ThemeEntry };
16
+ //# sourceMappingURL=theme-entry.types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-entry.types.d.mts","names":[],"sources":["../../src/theme/theme-entry.types.ts"],"sourcesContent":[],"mappings":";;;;;;AAOA;;;AACc,UADG,UACH,CAAA,eAD6B,QAC7B,GADwC,QACxC,CAAA,CAAA;EACN,KAAA,EAAA,MADM,MACN;EAAa,KAAA,EAAb,MAAa,CAAA,MAAA,MAAA,CAAA"}
@@ -0,0 +1,10 @@
1
+ //#region src/theme/theme-map.types.d.ts
2
+ /**
3
+ * Record mapping theme keys to their values.
4
+ * Each value can be a single string or readonly string[] (e.g. multiple CSS classes).
5
+ * Used by all ThemeStore factories via the themes option.
6
+ */
7
+ type ThemeMap<Theme extends string = string> = Record<Theme, string | readonly string[]>;
8
+ //#endregion
9
+ export { ThemeMap };
10
+ //# sourceMappingURL=theme-map.types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-map.types.d.cts","names":[],"sources":["../../src/theme/theme-map.types.ts"],"sourcesContent":[],"mappings":";;AAKA;;;;KAAY,0CAA0C,OAAO"}
@@ -0,0 +1,10 @@
1
+ //#region src/theme/theme-map.types.d.ts
2
+ /**
3
+ * Record mapping theme keys to their values.
4
+ * Each value can be a single string or readonly string[] (e.g. multiple CSS classes).
5
+ * Used by all ThemeStore factories via the themes option.
6
+ */
7
+ type ThemeMap<Theme extends string = string> = Record<Theme, string | readonly string[]>;
8
+ //#endregion
9
+ export { ThemeMap };
10
+ //# sourceMappingURL=theme-map.types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-map.types.d.mts","names":[],"sources":["../../src/theme/theme-map.types.ts"],"sourcesContent":[],"mappings":";;AAKA;;;;KAAY,0CAA0C,OAAO"}
@@ -0,0 +1,25 @@
1
+ import { ThemeMap } from "../theme-map.types.cjs";
2
+ import { ThemeEntry } from "../theme-entry.types.cjs";
3
+
4
+ //#region src/theme/theme-store/async-theme-store.types.d.ts
5
+
6
+ /**
7
+ * Async variant of `ThemeStore` where read and write may return promises.
8
+ * Use for remote persistence, polling, or WebSocket-based sync.
9
+ *
10
+ * Same optional methods as `ThemeStore`:
11
+ *
12
+ * - **read** – Can return `Promise<ThemeEntry | undefined>` for async sources
13
+ * - **write** – Can return `Promise<void>` for async persistence
14
+ * - **subscribe** – Same signature as sync; observes external changes
15
+ *
16
+ * @typeParam Themes - Map of theme keys to their value types (string or readonly string[])
17
+ */
18
+ interface AsyncThemeStore<Themes extends ThemeMap = ThemeMap> {
19
+ read?: (() => ThemeEntry<Themes> | undefined | Promise<ThemeEntry<Themes> | undefined>) | undefined;
20
+ write?: ((entry: ThemeEntry<Themes> | undefined) => void | Promise<void>) | undefined;
21
+ subscribe?: ((handler: (entry: ThemeEntry<Themes> | undefined | null) => void) => () => void) | undefined;
22
+ }
23
+ //#endregion
24
+ export { AsyncThemeStore };
25
+ //# sourceMappingURL=async-theme-store.types.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-theme-store.types.d.cts","names":[],"sources":["../../../src/theme/theme-store/async-theme-store.types.ts"],"sourcesContent":[],"mappings":";;;;;;;AAeA;;;;;;;;;;AAI4D,UAJ3C,eAI2C,CAAA,eAJZ,QAIY,GAJD,QAIC,CAAA,CAAA;EAE1B,IAAA,CAAA,EAAA,CAAA,GAAA,GAJvB,UAIuB,CAJZ,MAIY,CAAA,GAAA,SAAA,GAJU,OAIV,CAJkB,UAIlB,CAJ6B,MAI7B,CAAA,GAAA,SAAA,CAAA,CAAA,GAAA,SAAA;EAAX,KAAA,CAAA,EAAA,CAAA,CAAA,KAAA,EAFL,UAEK,CAFM,MAEN,CAAA,GAAA,SAAA,EAAA,GAAA,IAAA,GAFqC,OAErC,CAAA,IAAA,CAAA,CAAA,GAAA,SAAA;EAAU,SAAA,CAAA,EAAA,CAAA,CAAA,OAAA,EAAA,CAAA,KAAA,EAAV,UAAU,CAAC,MAAD,CAAA,GAAA,SAAA,GAAA,IAAA,EAAA,GAAA,IAAA,EAAA,GAAA,GAAA,GAAA,IAAA,CAAA,GAAA,SAAA"}
@@ -0,0 +1,25 @@
1
+ import { ThemeMap } from "../theme-map.types.mjs";
2
+ import { ThemeEntry } from "../theme-entry.types.mjs";
3
+
4
+ //#region src/theme/theme-store/async-theme-store.types.d.ts
5
+
6
+ /**
7
+ * Async variant of `ThemeStore` where read and write may return promises.
8
+ * Use for remote persistence, polling, or WebSocket-based sync.
9
+ *
10
+ * Same optional methods as `ThemeStore`:
11
+ *
12
+ * - **read** – Can return `Promise<ThemeEntry | undefined>` for async sources
13
+ * - **write** – Can return `Promise<void>` for async persistence
14
+ * - **subscribe** – Same signature as sync; observes external changes
15
+ *
16
+ * @typeParam Themes - Map of theme keys to their value types (string or readonly string[])
17
+ */
18
+ interface AsyncThemeStore<Themes extends ThemeMap = ThemeMap> {
19
+ read?: (() => ThemeEntry<Themes> | undefined | Promise<ThemeEntry<Themes> | undefined>) | undefined;
20
+ write?: ((entry: ThemeEntry<Themes> | undefined) => void | Promise<void>) | undefined;
21
+ subscribe?: ((handler: (entry: ThemeEntry<Themes> | undefined | null) => void) => () => void) | undefined;
22
+ }
23
+ //#endregion
24
+ export { AsyncThemeStore };
25
+ //# sourceMappingURL=async-theme-store.types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-theme-store.types.d.mts","names":[],"sources":["../../../src/theme/theme-store/async-theme-store.types.ts"],"sourcesContent":[],"mappings":";;;;;;;AAeA;;;;;;;;;;AAI4D,UAJ3C,eAI2C,CAAA,eAJZ,QAIY,GAJD,QAIC,CAAA,CAAA;EAE1B,IAAA,CAAA,EAAA,CAAA,GAAA,GAJvB,UAIuB,CAJZ,MAIY,CAAA,GAAA,SAAA,GAJU,OAIV,CAJkB,UAIlB,CAJ6B,MAI7B,CAAA,GAAA,SAAA,CAAA,CAAA,GAAA,SAAA;EAAX,KAAA,CAAA,EAAA,CAAA,CAAA,KAAA,EAFL,UAEK,CAFM,MAEN,CAAA,GAAA,SAAA,EAAA,GAAA,IAAA,GAFqC,OAErC,CAAA,IAAA,CAAA,CAAA,GAAA,SAAA;EAAU,SAAA,CAAA,EAAA,CAAA,CAAA,OAAA,EAAA,CAAA,KAAA,EAAV,UAAU,CAAC,MAAD,CAAA,GAAA,SAAA,GAAA,IAAA,EAAA,GAAA,IAAA,EAAA,GAAA,GAAA,GAAA,IAAA,CAAA,GAAA,SAAA"}
@@ -0,0 +1,53 @@
1
+ const require_observe_attribute = require('../../../attributes/observe-attribute.cjs');
2
+ const require_resolve_theme_from_class_name = require('../../class-name/resolve-theme-from-class-name.cjs');
3
+ const require_theme_entry = require('../../theme-entry.cjs');
4
+ const require_dummy_theme_store = require('../../../testing/theme/dummy-theme-store.cjs');
5
+ const require_apply_theme_to_class_name = require('../../class-name/apply-theme-to-class-name.cjs');
6
+
7
+ //#region src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts
8
+ /**
9
+ * Creates a theme store that reads and writes via element class names.
10
+ *
11
+ * @param themes - Record mapping theme keys to class name(s)
12
+ * @param options.element - Element to operate on (defaults to document.documentElement)
13
+ * @returns ThemeStore
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }
18
+ * const store = classNameThemeStore(themes)
19
+ * store.read() // returns themeResult from element.className
20
+ * store.write(themeEntry(themes, 'grayscale'))
21
+ * store.subscribe((themeResult) => {})
22
+ * ```
23
+ */
24
+ function classNameThemeStore(themes, options) {
25
+ const element = options?.element ?? document?.documentElement;
26
+ if (!element) return require_dummy_theme_store.dummyThemeStore;
27
+ return {
28
+ read() {
29
+ const theme = require_resolve_theme_from_class_name.resolveThemeFromClassName(themes, element.className);
30
+ if (theme === void 0) return void 0;
31
+ return require_theme_entry.themeEntry(themes, theme);
32
+ },
33
+ write(entry) {
34
+ require_apply_theme_to_class_name.applyThemeToClassName(themes, element, entry);
35
+ },
36
+ subscribe(handler) {
37
+ let lastEmitted = null;
38
+ const observer = require_observe_attribute.observeAttributes({ class: (value) => {
39
+ const theme = value ? require_resolve_theme_from_class_name.resolveThemeFromClassName(themes, value) : void 0;
40
+ const entry = theme ? require_theme_entry.themeEntry(themes, theme) : void 0;
41
+ const key = theme ?? void 0;
42
+ if (lastEmitted === key) return;
43
+ lastEmitted = key;
44
+ handler(entry);
45
+ } }, element);
46
+ return () => observer.disconnect();
47
+ }
48
+ };
49
+ }
50
+
51
+ //#endregion
52
+ exports.classNameThemeStore = classNameThemeStore;
53
+ //# sourceMappingURL=class-name-theme-store.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-name-theme-store.cjs","names":["dummyThemeStore","resolveThemeFromClassName","themeEntry","lastEmitted: keyof Themes | undefined | null","observeAttributes"],"sources":["../../../../src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts"],"sourcesContent":["import type { Required } from 'type-plus'\nimport { observeAttributes } from '../../../attributes/observe-attribute.ts'\nimport { dummyThemeStore } from '../../../testing/theme/dummy-theme-store.ts'\nimport { applyThemeToClassName } from '../../class-name/apply-theme-to-class-name.ts'\nimport { resolveThemeFromClassName } from '../../class-name/resolve-theme-from-class-name.ts'\nimport { themeEntry } from '../../theme-entry.ts'\nimport type { ThemeMap } from '../../theme-map.types.ts'\nimport type { ThemeStore } from '../theme-store.types.ts'\n\n/**\n * Creates a theme store that reads and writes via element class names.\n *\n * @param themes - Record mapping theme keys to class name(s)\n * @param options.element - Element to operate on (defaults to document.documentElement)\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }\n * const store = classNameThemeStore(themes)\n * store.read() // returns themeResult from element.className\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((themeResult) => {})\n * ```\n */\nexport function classNameThemeStore<Themes extends ThemeMap>(\n\tthemes: Themes,\n\toptions?: { element?: Element | undefined }\n): Required<ThemeStore<Themes>> {\n\tconst element = options?.element ?? document?.documentElement\n\n\tif (!element) return dummyThemeStore\n\n\treturn {\n\t\tread() {\n\t\t\tconst theme = resolveThemeFromClassName(themes, element.className)\n\t\t\tif (theme === undefined) return undefined\n\t\t\treturn themeEntry(themes, theme)\n\t\t},\n\t\twrite(entry) {\n\t\t\tapplyThemeToClassName(themes, element, entry)\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\tlet lastEmitted: keyof Themes | undefined | null = null\n\t\t\tconst observer = observeAttributes(\n\t\t\t\t{\n\t\t\t\t\tclass: (value) => {\n\t\t\t\t\t\tconst theme = value ? resolveThemeFromClassName(themes, value) : undefined\n\t\t\t\t\t\tconst entry = theme ? themeEntry(themes, theme) : undefined\n\t\t\t\t\t\tconst key = theme ?? undefined\n\n\t\t\t\t\t\tif (lastEmitted === key) return\n\t\t\t\t\t\tlastEmitted = key\n\t\t\t\t\t\thandler(entry)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\telement\n\t\t\t)\n\t\t\treturn () => observer.disconnect()\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,oBACf,QACA,SAC+B;CAC/B,MAAM,UAAU,SAAS,WAAW,UAAU;AAE9C,KAAI,CAAC,QAAS,QAAOA;AAErB,QAAO;EACN,OAAO;GACN,MAAM,QAAQC,gEAA0B,QAAQ,QAAQ,UAAU;AAClE,OAAI,UAAU,OAAW,QAAO;AAChC,UAAOC,+BAAW,QAAQ,MAAM;;EAEjC,MAAM,OAAO;AACZ,2DAAsB,QAAQ,SAAS,MAAM;;EAE9C,UAAU,SAAS;GAClB,IAAIC,cAA+C;GACnD,MAAM,WAAWC,4CAChB,EACC,QAAQ,UAAU;IACjB,MAAM,QAAQ,QAAQH,gEAA0B,QAAQ,MAAM,GAAG;IACjE,MAAM,QAAQ,QAAQC,+BAAW,QAAQ,MAAM,GAAG;IAClD,MAAM,MAAM,SAAS;AAErB,QAAI,gBAAgB,IAAK;AACzB,kBAAc;AACd,YAAQ,MAAM;MAEf,EACD,QACA;AACD,gBAAa,SAAS,YAAY;;EAEnC"}
@@ -0,0 +1,28 @@
1
+ import { ThemeMap } from "../../theme-map.types.cjs";
2
+ import { ThemeStore } from "../theme-store.types.cjs";
3
+ import { Required } from "type-plus";
4
+
5
+ //#region src/theme/theme-store/class-name-theme-store/class-name-theme-store.d.ts
6
+
7
+ /**
8
+ * Creates a theme store that reads and writes via element class names.
9
+ *
10
+ * @param themes - Record mapping theme keys to class name(s)
11
+ * @param options.element - Element to operate on (defaults to document.documentElement)
12
+ * @returns ThemeStore
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }
17
+ * const store = classNameThemeStore(themes)
18
+ * store.read() // returns themeResult from element.className
19
+ * store.write(themeEntry(themes, 'grayscale'))
20
+ * store.subscribe((themeResult) => {})
21
+ * ```
22
+ */
23
+ declare function classNameThemeStore<Themes extends ThemeMap>(themes: Themes, options?: {
24
+ element?: Element | undefined;
25
+ }): Required<ThemeStore<Themes>>;
26
+ //#endregion
27
+ export { classNameThemeStore };
28
+ //# sourceMappingURL=class-name-theme-store.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-name-theme-store.d.cts","names":[],"sources":["../../../../src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAyBA;;;;;;;;;;;;;;iBAAgB,mCAAmC,kBAC1C;YACc;IACpB,SAAS,WAAW"}
@@ -0,0 +1,28 @@
1
+ import { ThemeMap } from "../../theme-map.types.mjs";
2
+ import { ThemeStore } from "../theme-store.types.mjs";
3
+ import { Required } from "type-plus";
4
+
5
+ //#region src/theme/theme-store/class-name-theme-store/class-name-theme-store.d.ts
6
+
7
+ /**
8
+ * Creates a theme store that reads and writes via element class names.
9
+ *
10
+ * @param themes - Record mapping theme keys to class name(s)
11
+ * @param options.element - Element to operate on (defaults to document.documentElement)
12
+ * @returns ThemeStore
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }
17
+ * const store = classNameThemeStore(themes)
18
+ * store.read() // returns themeResult from element.className
19
+ * store.write(themeEntry(themes, 'grayscale'))
20
+ * store.subscribe((themeResult) => {})
21
+ * ```
22
+ */
23
+ declare function classNameThemeStore<Themes extends ThemeMap>(themes: Themes, options?: {
24
+ element?: Element | undefined;
25
+ }): Required<ThemeStore<Themes>>;
26
+ //#endregion
27
+ export { classNameThemeStore };
28
+ //# sourceMappingURL=class-name-theme-store.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-name-theme-store.d.mts","names":[],"sources":["../../../../src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts"],"sourcesContent":[],"mappings":";;;;;;;;AAyBA;;;;;;;;;;;;;;iBAAgB,mCAAmC,kBAC1C;YACc;IACpB,SAAS,WAAW"}
@@ -0,0 +1,53 @@
1
+ import { observeAttributes } from "../../../attributes/observe-attribute.mjs";
2
+ import { resolveThemeFromClassName } from "../../class-name/resolve-theme-from-class-name.mjs";
3
+ import { themeEntry } from "../../theme-entry.mjs";
4
+ import { dummyThemeStore } from "../../../testing/theme/dummy-theme-store.mjs";
5
+ import { applyThemeToClassName } from "../../class-name/apply-theme-to-class-name.mjs";
6
+
7
+ //#region src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts
8
+ /**
9
+ * Creates a theme store that reads and writes via element class names.
10
+ *
11
+ * @param themes - Record mapping theme keys to class name(s)
12
+ * @param options.element - Element to operate on (defaults to document.documentElement)
13
+ * @returns ThemeStore
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }
18
+ * const store = classNameThemeStore(themes)
19
+ * store.read() // returns themeResult from element.className
20
+ * store.write(themeEntry(themes, 'grayscale'))
21
+ * store.subscribe((themeResult) => {})
22
+ * ```
23
+ */
24
+ function classNameThemeStore(themes, options) {
25
+ const element = options?.element ?? document?.documentElement;
26
+ if (!element) return dummyThemeStore;
27
+ return {
28
+ read() {
29
+ const theme = resolveThemeFromClassName(themes, element.className);
30
+ if (theme === void 0) return void 0;
31
+ return themeEntry(themes, theme);
32
+ },
33
+ write(entry) {
34
+ applyThemeToClassName(themes, element, entry);
35
+ },
36
+ subscribe(handler) {
37
+ let lastEmitted = null;
38
+ const observer = observeAttributes({ class: (value) => {
39
+ const theme = value ? resolveThemeFromClassName(themes, value) : void 0;
40
+ const entry = theme ? themeEntry(themes, theme) : void 0;
41
+ const key = theme ?? void 0;
42
+ if (lastEmitted === key) return;
43
+ lastEmitted = key;
44
+ handler(entry);
45
+ } }, element);
46
+ return () => observer.disconnect();
47
+ }
48
+ };
49
+ }
50
+
51
+ //#endregion
52
+ export { classNameThemeStore };
53
+ //# sourceMappingURL=class-name-theme-store.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"class-name-theme-store.mjs","names":["lastEmitted: keyof Themes | undefined | null"],"sources":["../../../../src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts"],"sourcesContent":["import type { Required } from 'type-plus'\nimport { observeAttributes } from '../../../attributes/observe-attribute.ts'\nimport { dummyThemeStore } from '../../../testing/theme/dummy-theme-store.ts'\nimport { applyThemeToClassName } from '../../class-name/apply-theme-to-class-name.ts'\nimport { resolveThemeFromClassName } from '../../class-name/resolve-theme-from-class-name.ts'\nimport { themeEntry } from '../../theme-entry.ts'\nimport type { ThemeMap } from '../../theme-map.types.ts'\nimport type { ThemeStore } from '../theme-store.types.ts'\n\n/**\n * Creates a theme store that reads and writes via element class names.\n *\n * @param themes - Record mapping theme keys to class name(s)\n * @param options.element - Element to operate on (defaults to document.documentElement)\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }\n * const store = classNameThemeStore(themes)\n * store.read() // returns themeResult from element.className\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((themeResult) => {})\n * ```\n */\nexport function classNameThemeStore<Themes extends ThemeMap>(\n\tthemes: Themes,\n\toptions?: { element?: Element | undefined }\n): Required<ThemeStore<Themes>> {\n\tconst element = options?.element ?? document?.documentElement\n\n\tif (!element) return dummyThemeStore\n\n\treturn {\n\t\tread() {\n\t\t\tconst theme = resolveThemeFromClassName(themes, element.className)\n\t\t\tif (theme === undefined) return undefined\n\t\t\treturn themeEntry(themes, theme)\n\t\t},\n\t\twrite(entry) {\n\t\t\tapplyThemeToClassName(themes, element, entry)\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\tlet lastEmitted: keyof Themes | undefined | null = null\n\t\t\tconst observer = observeAttributes(\n\t\t\t\t{\n\t\t\t\t\tclass: (value) => {\n\t\t\t\t\t\tconst theme = value ? resolveThemeFromClassName(themes, value) : undefined\n\t\t\t\t\t\tconst entry = theme ? themeEntry(themes, theme) : undefined\n\t\t\t\t\t\tconst key = theme ?? undefined\n\n\t\t\t\t\t\tif (lastEmitted === key) return\n\t\t\t\t\t\tlastEmitted = key\n\t\t\t\t\t\thandler(entry)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\telement\n\t\t\t)\n\t\t\treturn () => observer.disconnect()\n\t\t}\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,oBACf,QACA,SAC+B;CAC/B,MAAM,UAAU,SAAS,WAAW,UAAU;AAE9C,KAAI,CAAC,QAAS,QAAO;AAErB,QAAO;EACN,OAAO;GACN,MAAM,QAAQ,0BAA0B,QAAQ,QAAQ,UAAU;AAClE,OAAI,UAAU,OAAW,QAAO;AAChC,UAAO,WAAW,QAAQ,MAAM;;EAEjC,MAAM,OAAO;AACZ,yBAAsB,QAAQ,SAAS,MAAM;;EAE9C,UAAU,SAAS;GAClB,IAAIA,cAA+C;GACnD,MAAM,WAAW,kBAChB,EACC,QAAQ,UAAU;IACjB,MAAM,QAAQ,QAAQ,0BAA0B,QAAQ,MAAM,GAAG;IACjE,MAAM,QAAQ,QAAQ,WAAW,QAAQ,MAAM,GAAG;IAClD,MAAM,MAAM,SAAS;AAErB,QAAI,gBAAgB,IAAK;AACzB,kBAAc;AACd,YAAQ,MAAM;MAEf,EACD,QACA;AACD,gBAAa,SAAS,YAAY;;EAEnC"}
@@ -0,0 +1,121 @@
1
+ const require_theme_entry = require('../../theme-entry.cjs');
2
+ const require_dummy_theme_store = require('../../../testing/theme/dummy-theme-store.cjs');
3
+ const require_parse_stored_theme = require('../../_utils/parse-stored-theme.cjs');
4
+
5
+ //#region src/theme/theme-store/cookie-theme-store/cookie-theme-store.ts
6
+ function getCookieValue(name) {
7
+ if (typeof document === "undefined" || !document.cookie) return null;
8
+ const value = document.cookie.match(/* @__PURE__ */ new RegExp(`(?:^|;\\s*)${name}=([^;]*)`))?.[1];
9
+ return value !== void 0 ? decodeURIComponent(value) : null;
10
+ }
11
+ function setCookie(name, value, options) {
12
+ const parts = [`${name}=${encodeURIComponent(value)}`];
13
+ parts.push(`path=${options.path ?? "/"}`);
14
+ if (options.maxAge !== void 0) parts.push(`max-age=${options.maxAge}`);
15
+ if (options.sameSite !== void 0) parts.push(`samesite=${options.sameSite}`);
16
+ if (options.secure) parts.push("secure");
17
+ document.cookie = parts.join("; ");
18
+ }
19
+ function deleteCookie(name, path = "/") {
20
+ document.cookie = `${name}=; path=${path}; max-age=0`;
21
+ }
22
+ /**
23
+ * Creates a theme store backed by cookies.
24
+ *
25
+ * Persists across sessions. Cookies are sent with every request, so the server can
26
+ * read the theme during SSR to avoid flash of wrong theme. Cross-tab sync is not
27
+ * supported (cookies have no StorageEvent).
28
+ *
29
+ * @param themes - Record mapping theme keys to values (for validation)
30
+ * @param options.cookieName - Cookie name for theme storage
31
+ * @param options.path - Cookie path (default: '/')
32
+ * @param options.maxAge - Cookie max-age in seconds
33
+ * @param options.sameSite - Cookie sameSite attribute
34
+ * @param options.secure - Cookie secure attribute
35
+ * @returns ThemeStore
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }
40
+ * const store = cookieThemeStore(themes, { cookieName: 'theme' })
41
+ * store.read()
42
+ * store.write(themeEntry(themes, 'grayscale'))
43
+ * store.subscribe((themeResult) => {})
44
+ * ```
45
+ */
46
+ function cookieThemeStore(themes, options) {
47
+ const { cookieName, path = "/", maxAge, sameSite, secure } = options;
48
+ if (document.cookie === void 0) return require_dummy_theme_store.dummyThemeStore;
49
+ const handlers = /* @__PURE__ */ new Set();
50
+ let lastNotifiedKey = read()?.theme ?? void 0;
51
+ function read() {
52
+ const theme = require_parse_stored_theme.parseStoredTheme(themes, getCookieValue(cookieName));
53
+ if (theme === void 0) return void 0;
54
+ return require_theme_entry.themeEntry(themes, theme);
55
+ }
56
+ function notify() {
57
+ const result = read();
58
+ const key = result?.theme ?? void 0;
59
+ if (key === lastNotifiedKey) return;
60
+ lastNotifiedKey = key;
61
+ for (const h of handlers) h(result);
62
+ }
63
+ return {
64
+ read,
65
+ write(entry) {
66
+ try {
67
+ if (entry === void 0) deleteCookie(cookieName, path);
68
+ else {
69
+ const opts = { path };
70
+ if (maxAge !== void 0) opts.maxAge = maxAge;
71
+ if (sameSite !== void 0) opts.sameSite = sameSite;
72
+ if (secure) opts.secure = true;
73
+ setCookie(cookieName, JSON.stringify(entry), opts);
74
+ }
75
+ notify();
76
+ } catch {}
77
+ },
78
+ subscribe(handler) {
79
+ handlers.add(handler);
80
+ return () => {
81
+ handlers.delete(handler);
82
+ };
83
+ }
84
+ };
85
+ }
86
+ function getCookieFromHeader(cookieHeader, name) {
87
+ const value = cookieHeader.match(/* @__PURE__ */ new RegExp(`(?:^|;\\s*)${name}=([^;]*)`))?.[1];
88
+ return value !== void 0 ? decodeURIComponent(value.trim()) : null;
89
+ }
90
+ /**
91
+ * Reads the theme from cookies during SSR. Use with the request's Cookie header or
92
+ * a framework's cookie API (e.g. Next.js cookies()).
93
+ *
94
+ * @param cookieSource - Raw Cookie header string, or a getter (name) => value for framework APIs
95
+ * @param themes - Record mapping theme keys to values (for validation)
96
+ * @param options - Optional cookie name (default: 'theme')
97
+ * @returns ThemeEntry if valid cookie found, otherwise undefined
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * // With raw Cookie header (Express, Remix, etc.)
102
+ * const theme = getThemeFromCookie(request.headers.get('Cookie') ?? '', themes)
103
+ *
104
+ * // With Next.js cookies()
105
+ * const theme = getThemeFromCookie(
106
+ * (name) => cookies().get(name)?.value ?? undefined,
107
+ * themes
108
+ * )
109
+ * ```
110
+ */
111
+ function getThemeFromCookie(cookieSource, themes, options = {}) {
112
+ const cookieName = options.cookieName ?? "theme";
113
+ const theme = require_parse_stored_theme.parseStoredTheme(themes, typeof cookieSource === "function" ? cookieSource(cookieName) ?? null : cookieSource ? getCookieFromHeader(cookieSource, cookieName) : null);
114
+ if (theme === void 0) return void 0;
115
+ return require_theme_entry.themeEntry(themes, theme);
116
+ }
117
+
118
+ //#endregion
119
+ exports.cookieThemeStore = cookieThemeStore;
120
+ exports.getThemeFromCookie = getThemeFromCookie;
121
+ //# sourceMappingURL=cookie-theme-store.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie-theme-store.cjs","names":["dummyThemeStore","lastNotifiedKey: keyof Themes | undefined","parseStoredTheme","themeEntry","opts: {\n\t\t\t\t\t\tpath: string\n\t\t\t\t\t\tmaxAge?: number\n\t\t\t\t\t\tsameSite?: 'lax' | 'strict' | 'none'\n\t\t\t\t\t\tsecure?: boolean\n\t\t\t\t\t}"],"sources":["../../../../src/theme/theme-store/cookie-theme-store/cookie-theme-store.ts"],"sourcesContent":["import type { Required } from 'type-plus'\nimport { dummyThemeStore } from '../../../testing/theme/dummy-theme-store.ts'\nimport { parseStoredTheme } from '../../_utils/parse-stored-theme.ts'\nimport { themeEntry } from '../../theme-entry.ts'\nimport type { ThemeEntry } from '../../theme-entry.types.ts'\nimport type { ThemeMap } from '../../theme-map.types.ts'\nimport type { ThemeStore } from '../theme-store.types.ts'\n\nexport interface CookieThemeStoreOptions {\n\tcookieName: string\n\tpath?: string | undefined\n\tmaxAge?: number | undefined\n\tsameSite?: 'lax' | 'strict' | 'none' | undefined\n\tsecure?: boolean | undefined\n}\n\nfunction getCookieValue(name: string): string | null {\n\tif (typeof document === 'undefined' || !document.cookie) return null\n\tconst match = document.cookie.match(new RegExp(`(?:^|;\\\\s*)${name}=([^;]*)`))\n\tconst value = match?.[1]\n\treturn value !== undefined ? decodeURIComponent(value) : null\n}\n\nfunction setCookie(\n\tname: string,\n\tvalue: string,\n\toptions: {\n\t\tpath?: string | undefined\n\t\tmaxAge?: number | undefined\n\t\tsameSite?: 'lax' | 'strict' | 'none' | undefined\n\t\tsecure?: boolean | undefined\n\t}\n) {\n\tconst parts = [`${name}=${encodeURIComponent(value)}`]\n\tparts.push(`path=${options.path ?? '/'}`)\n\tif (options.maxAge !== undefined) parts.push(`max-age=${options.maxAge}`)\n\tif (options.sameSite !== undefined) parts.push(`samesite=${options.sameSite}`)\n\tif (options.secure) parts.push('secure')\n\t// biome-ignore lint/suspicious/noDocumentCookie: Cookie Store API has limited support; document.cookie is standard for theme persistence\n\tdocument.cookie = parts.join('; ')\n}\n\nfunction deleteCookie(name: string, path = '/') {\n\t// biome-ignore lint/suspicious/noDocumentCookie: Cookie Store API has limited support; document.cookie is standard for theme persistence\n\tdocument.cookie = `${name}=; path=${path}; max-age=0`\n}\n\n/**\n * Creates a theme store backed by cookies.\n *\n * Persists across sessions. Cookies are sent with every request, so the server can\n * read the theme during SSR to avoid flash of wrong theme. Cross-tab sync is not\n * supported (cookies have no StorageEvent).\n *\n * @param themes - Record mapping theme keys to values (for validation)\n * @param options.cookieName - Cookie name for theme storage\n * @param options.path - Cookie path (default: '/')\n * @param options.maxAge - Cookie max-age in seconds\n * @param options.sameSite - Cookie sameSite attribute\n * @param options.secure - Cookie secure attribute\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }\n * const store = cookieThemeStore(themes, { cookieName: 'theme' })\n * store.read()\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((themeResult) => {})\n * ```\n */\nexport function cookieThemeStore<Themes extends ThemeMap>(\n\tthemes: Themes,\n\toptions: CookieThemeStoreOptions\n): Required<ThemeStore<Themes>> {\n\tconst { cookieName, path = '/', maxAge, sameSite, secure } = options\n\n\tif (document.cookie === undefined) {\n\t\treturn dummyThemeStore\n\t}\n\n\tconst handlers = new Set<(theme: ThemeEntry<Themes> | undefined) => void>()\n\tlet lastNotifiedKey: keyof Themes | undefined = read()?.theme ?? undefined\n\n\tfunction read() {\n\t\tconst stored = getCookieValue(cookieName)\n\t\tconst theme = parseStoredTheme(themes, stored)\n\t\tif (theme === undefined) return undefined\n\t\treturn themeEntry(themes, theme)\n\t}\n\n\tfunction notify() {\n\t\tconst result = read()\n\t\tconst key = result?.theme ?? undefined\n\t\tif (key === lastNotifiedKey) return\n\t\tlastNotifiedKey = key\n\t\tfor (const h of handlers) h(result)\n\t}\n\n\treturn {\n\t\tread,\n\t\twrite(entry) {\n\t\t\ttry {\n\t\t\t\tif (entry === undefined) {\n\t\t\t\t\tdeleteCookie(cookieName, path)\n\t\t\t\t} else {\n\t\t\t\t\tconst opts: {\n\t\t\t\t\t\tpath: string\n\t\t\t\t\t\tmaxAge?: number\n\t\t\t\t\t\tsameSite?: 'lax' | 'strict' | 'none'\n\t\t\t\t\t\tsecure?: boolean\n\t\t\t\t\t} = { path }\n\t\t\t\t\tif (maxAge !== undefined) opts.maxAge = maxAge\n\t\t\t\t\tif (sameSite !== undefined) opts.sameSite = sameSite\n\t\t\t\t\tif (secure) opts.secure = true\n\t\t\t\t\tsetCookie(cookieName, JSON.stringify(entry), opts)\n\t\t\t\t}\n\t\t\t\tnotify()\n\t\t\t} catch {\n\t\t\t\t// Ignore quota or other errors\n\t\t\t}\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\thandlers.add(handler)\n\t\t\treturn () => {\n\t\t\t\thandlers.delete(handler)\n\t\t\t}\n\t\t}\n\t} satisfies ThemeStore<Themes>\n}\n\nfunction getCookieFromHeader(cookieHeader: string, name: string): string | null {\n\tconst match = cookieHeader.match(new RegExp(`(?:^|;\\\\s*)${name}=([^;]*)`))\n\tconst value = match?.[1]\n\treturn value !== undefined ? decodeURIComponent(value.trim()) : null\n}\n\n/**\n * Reads the theme from cookies during SSR. Use with the request's Cookie header or\n * a framework's cookie API (e.g. Next.js cookies()).\n *\n * @param cookieSource - Raw Cookie header string, or a getter (name) => value for framework APIs\n * @param themes - Record mapping theme keys to values (for validation)\n * @param options - Optional cookie name (default: 'theme')\n * @returns ThemeEntry if valid cookie found, otherwise undefined\n *\n * @example\n * ```ts\n * // With raw Cookie header (Express, Remix, etc.)\n * const theme = getThemeFromCookie(request.headers.get('Cookie') ?? '', themes)\n *\n * // With Next.js cookies()\n * const theme = getThemeFromCookie(\n * (name) => cookies().get(name)?.value ?? undefined,\n * themes\n * )\n * ```\n */\nexport function getThemeFromCookie<Themes extends ThemeMap>(\n\tcookieSource: string | null | undefined | ((name: string) => string | null | undefined),\n\tthemes: Themes,\n\toptions: { cookieName?: string | undefined } = {}\n): ThemeEntry<Themes> | undefined {\n\tconst cookieName = options.cookieName ?? 'theme'\n\tconst stored =\n\t\ttypeof cookieSource === 'function'\n\t\t\t? (cookieSource(cookieName) ?? null)\n\t\t\t: cookieSource\n\t\t\t\t? getCookieFromHeader(cookieSource, cookieName)\n\t\t\t\t: null\n\tconst theme = parseStoredTheme(themes, stored)\n\tif (theme === undefined) return undefined\n\treturn themeEntry(themes, theme)\n}\n"],"mappings":";;;;;AAgBA,SAAS,eAAe,MAA6B;AACpD,KAAI,OAAO,aAAa,eAAe,CAAC,SAAS,OAAQ,QAAO;CAEhE,MAAM,QADQ,SAAS,OAAO,sBAAM,IAAI,OAAO,cAAc,KAAK,UAAU,CAAC,GACvD;AACtB,QAAO,UAAU,SAAY,mBAAmB,MAAM,GAAG;;AAG1D,SAAS,UACR,MACA,OACA,SAMC;CACD,MAAM,QAAQ,CAAC,GAAG,KAAK,GAAG,mBAAmB,MAAM,GAAG;AACtD,OAAM,KAAK,QAAQ,QAAQ,QAAQ,MAAM;AACzC,KAAI,QAAQ,WAAW,OAAW,OAAM,KAAK,WAAW,QAAQ,SAAS;AACzE,KAAI,QAAQ,aAAa,OAAW,OAAM,KAAK,YAAY,QAAQ,WAAW;AAC9E,KAAI,QAAQ,OAAQ,OAAM,KAAK,SAAS;AAExC,UAAS,SAAS,MAAM,KAAK,KAAK;;AAGnC,SAAS,aAAa,MAAc,OAAO,KAAK;AAE/C,UAAS,SAAS,GAAG,KAAK,UAAU,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;AA2B1C,SAAgB,iBACf,QACA,SAC+B;CAC/B,MAAM,EAAE,YAAY,OAAO,KAAK,QAAQ,UAAU,WAAW;AAE7D,KAAI,SAAS,WAAW,OACvB,QAAOA;CAGR,MAAM,2BAAW,IAAI,KAAsD;CAC3E,IAAIC,kBAA4C,MAAM,EAAE,SAAS;CAEjE,SAAS,OAAO;EAEf,MAAM,QAAQC,4CAAiB,QADhB,eAAe,WAAW,CACK;AAC9C,MAAI,UAAU,OAAW,QAAO;AAChC,SAAOC,+BAAW,QAAQ,MAAM;;CAGjC,SAAS,SAAS;EACjB,MAAM,SAAS,MAAM;EACrB,MAAM,MAAM,QAAQ,SAAS;AAC7B,MAAI,QAAQ,gBAAiB;AAC7B,oBAAkB;AAClB,OAAK,MAAM,KAAK,SAAU,GAAE,OAAO;;AAGpC,QAAO;EACN;EACA,MAAM,OAAO;AACZ,OAAI;AACH,QAAI,UAAU,OACb,cAAa,YAAY,KAAK;SACxB;KACN,MAAMC,OAKF,EAAE,MAAM;AACZ,SAAI,WAAW,OAAW,MAAK,SAAS;AACxC,SAAI,aAAa,OAAW,MAAK,WAAW;AAC5C,SAAI,OAAQ,MAAK,SAAS;AAC1B,eAAU,YAAY,KAAK,UAAU,MAAM,EAAE,KAAK;;AAEnD,YAAQ;WACD;;EAIT,UAAU,SAAS;AAClB,YAAS,IAAI,QAAQ;AACrB,gBAAa;AACZ,aAAS,OAAO,QAAQ;;;EAG1B;;AAGF,SAAS,oBAAoB,cAAsB,MAA6B;CAE/E,MAAM,QADQ,aAAa,sBAAM,IAAI,OAAO,cAAc,KAAK,UAAU,CAAC,GACpD;AACtB,QAAO,UAAU,SAAY,mBAAmB,MAAM,MAAM,CAAC,GAAG;;;;;;;;;;;;;;;;;;;;;;;AAwBjE,SAAgB,mBACf,cACA,QACA,UAA+C,EAAE,EAChB;CACjC,MAAM,aAAa,QAAQ,cAAc;CAOzC,MAAM,QAAQF,4CAAiB,QAL9B,OAAO,iBAAiB,aACpB,aAAa,WAAW,IAAI,OAC7B,eACC,oBAAoB,cAAc,WAAW,GAC7C,KACyC;AAC9C,KAAI,UAAU,OAAW,QAAO;AAChC,QAAOC,+BAAW,QAAQ,MAAM"}
@@ -0,0 +1,65 @@
1
+ import { ThemeMap } from "../../theme-map.types.cjs";
2
+ import { ThemeEntry } from "../../theme-entry.types.cjs";
3
+ import { ThemeStore } from "../theme-store.types.cjs";
4
+ import { Required } from "type-plus";
5
+
6
+ //#region src/theme/theme-store/cookie-theme-store/cookie-theme-store.d.ts
7
+ interface CookieThemeStoreOptions {
8
+ cookieName: string;
9
+ path?: string | undefined;
10
+ maxAge?: number | undefined;
11
+ sameSite?: 'lax' | 'strict' | 'none' | undefined;
12
+ secure?: boolean | undefined;
13
+ }
14
+ /**
15
+ * Creates a theme store backed by cookies.
16
+ *
17
+ * Persists across sessions. Cookies are sent with every request, so the server can
18
+ * read the theme during SSR to avoid flash of wrong theme. Cross-tab sync is not
19
+ * supported (cookies have no StorageEvent).
20
+ *
21
+ * @param themes - Record mapping theme keys to values (for validation)
22
+ * @param options.cookieName - Cookie name for theme storage
23
+ * @param options.path - Cookie path (default: '/')
24
+ * @param options.maxAge - Cookie max-age in seconds
25
+ * @param options.sameSite - Cookie sameSite attribute
26
+ * @param options.secure - Cookie secure attribute
27
+ * @returns ThemeStore
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' }
32
+ * const store = cookieThemeStore(themes, { cookieName: 'theme' })
33
+ * store.read()
34
+ * store.write(themeEntry(themes, 'grayscale'))
35
+ * store.subscribe((themeResult) => {})
36
+ * ```
37
+ */
38
+ declare function cookieThemeStore<Themes extends ThemeMap>(themes: Themes, options: CookieThemeStoreOptions): Required<ThemeStore<Themes>>;
39
+ /**
40
+ * Reads the theme from cookies during SSR. Use with the request's Cookie header or
41
+ * a framework's cookie API (e.g. Next.js cookies()).
42
+ *
43
+ * @param cookieSource - Raw Cookie header string, or a getter (name) => value for framework APIs
44
+ * @param themes - Record mapping theme keys to values (for validation)
45
+ * @param options - Optional cookie name (default: 'theme')
46
+ * @returns ThemeEntry if valid cookie found, otherwise undefined
47
+ *
48
+ * @example
49
+ * ```ts
50
+ * // With raw Cookie header (Express, Remix, etc.)
51
+ * const theme = getThemeFromCookie(request.headers.get('Cookie') ?? '', themes)
52
+ *
53
+ * // With Next.js cookies()
54
+ * const theme = getThemeFromCookie(
55
+ * (name) => cookies().get(name)?.value ?? undefined,
56
+ * themes
57
+ * )
58
+ * ```
59
+ */
60
+ declare function getThemeFromCookie<Themes extends ThemeMap>(cookieSource: string | null | undefined | ((name: string) => string | null | undefined), themes: Themes, options?: {
61
+ cookieName?: string | undefined;
62
+ }): ThemeEntry<Themes> | undefined;
63
+ //#endregion
64
+ export { CookieThemeStoreOptions, cookieThemeStore, getThemeFromCookie };
65
+ //# sourceMappingURL=cookie-theme-store.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie-theme-store.d.cts","names":[],"sources":["../../../../src/theme/theme-store/cookie-theme-store/cookie-theme-store.ts"],"sourcesContent":[],"mappings":";;;;;;UAQiB,uBAAA;;EAAA,IAAA,CAAA,EAAA,MAAA,GAAA,SAAA;EA+DD,MAAA,CAAA,EAAA,MAAA,GAAA,SAAgB;EAAgB,QAAA,CAAA,EAAA,KAAA,GAAA,QAAA,GAAA,MAAA,GAAA,SAAA;EACvC,MAAA,CAAA,EAAA,OAAA,GAAA,SAAA;;;;;;AAsFT;;;;;;;;;;;;;;;;;;;;iBAvFgB,gCAAgC,kBACvC,iBACC,0BACP,SAAS,WAAW;;;;;;;;;;;;;;;;;;;;;;iBAoFP,kCAAkC,2GAEzC;;IAEN,WAAW"}