@just-web/toolkits 2.0.0 → 3.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 (263) hide show
  1. package/dist/attributes/get-attribute.cjs +1 -1
  2. package/dist/attributes/get-attribute.cjs.map +1 -1
  3. package/dist/attributes/get-attribute.d.cts +2 -2
  4. package/dist/attributes/get-attribute.d.cts.map +1 -1
  5. package/dist/attributes/get-attribute.d.mts +2 -2
  6. package/dist/attributes/get-attribute.d.mts.map +1 -1
  7. package/dist/attributes/get-attribute.mjs +1 -1
  8. package/dist/attributes/get-attribute.mjs.map +1 -1
  9. package/dist/attributes/get-data-attribute.cjs +1 -1
  10. package/dist/attributes/get-data-attribute.cjs.map +1 -1
  11. package/dist/attributes/get-data-attribute.d.cts +2 -2
  12. package/dist/attributes/get-data-attribute.d.cts.map +1 -1
  13. package/dist/attributes/get-data-attribute.d.mts +2 -2
  14. package/dist/attributes/get-data-attribute.d.mts.map +1 -1
  15. package/dist/attributes/get-data-attribute.mjs +1 -1
  16. package/dist/attributes/get-data-attribute.mjs.map +1 -1
  17. package/dist/attributes/observe-attribute.cjs +11 -8
  18. package/dist/attributes/observe-attribute.cjs.map +1 -1
  19. package/dist/attributes/observe-attribute.d.cts +7 -7
  20. package/dist/attributes/observe-attribute.d.cts.map +1 -1
  21. package/dist/attributes/observe-attribute.d.mts +7 -7
  22. package/dist/attributes/observe-attribute.d.mts.map +1 -1
  23. package/dist/attributes/observe-attribute.mjs +11 -8
  24. package/dist/attributes/observe-attribute.mjs.map +1 -1
  25. package/dist/attributes/observe-data-attribute.cjs +7 -10
  26. package/dist/attributes/observe-data-attribute.cjs.map +1 -1
  27. package/dist/attributes/observe-data-attribute.d.cts +8 -11
  28. package/dist/attributes/observe-data-attribute.d.cts.map +1 -1
  29. package/dist/attributes/observe-data-attribute.d.mts +8 -11
  30. package/dist/attributes/observe-data-attribute.d.mts.map +1 -1
  31. package/dist/attributes/observe-data-attribute.mjs +7 -10
  32. package/dist/attributes/observe-data-attribute.mjs.map +1 -1
  33. package/dist/color-scheme/color-scheme.types.d.cts +11 -0
  34. package/dist/color-scheme/color-scheme.types.d.cts.map +1 -0
  35. package/dist/color-scheme/color-scheme.types.d.mts +11 -0
  36. package/dist/color-scheme/color-scheme.types.d.mts.map +1 -0
  37. package/dist/color-scheme/get-prefers-color-scheme.cjs +3 -1
  38. package/dist/color-scheme/get-prefers-color-scheme.cjs.map +1 -1
  39. package/dist/color-scheme/get-prefers-color-scheme.d.cts +7 -2
  40. package/dist/color-scheme/get-prefers-color-scheme.d.cts.map +1 -1
  41. package/dist/color-scheme/get-prefers-color-scheme.d.mts +7 -2
  42. package/dist/color-scheme/get-prefers-color-scheme.d.mts.map +1 -1
  43. package/dist/color-scheme/get-prefers-color-scheme.mjs +3 -1
  44. package/dist/color-scheme/get-prefers-color-scheme.mjs.map +1 -1
  45. package/dist/color-scheme/observe-prefers-color-scheme.cjs.map +1 -1
  46. package/dist/color-scheme/observe-prefers-color-scheme.d.cts +4 -1
  47. package/dist/color-scheme/observe-prefers-color-scheme.d.cts.map +1 -1
  48. package/dist/color-scheme/observe-prefers-color-scheme.d.mts +4 -1
  49. package/dist/color-scheme/observe-prefers-color-scheme.d.mts.map +1 -1
  50. package/dist/color-scheme/observe-prefers-color-scheme.mjs.map +1 -1
  51. package/dist/index.d.cts +2 -1
  52. package/dist/index.d.mts +2 -1
  53. package/dist/react/hooks/use-attribute.cjs +8 -9
  54. package/dist/react/hooks/use-attribute.cjs.map +1 -1
  55. package/dist/react/hooks/use-attribute.d.cts +4 -4
  56. package/dist/react/hooks/use-attribute.d.mts +4 -4
  57. package/dist/react/hooks/use-attribute.mjs +8 -9
  58. package/dist/react/hooks/use-attribute.mjs.map +1 -1
  59. package/dist/react/hooks/use-theme-by-class-name.cjs +1 -1
  60. package/dist/react/hooks/use-theme-by-class-name.cjs.map +1 -1
  61. package/dist/react/hooks/use-theme-by-class-name.d.cts +2 -2
  62. package/dist/react/hooks/use-theme-by-class-name.d.mts +2 -2
  63. package/dist/react/hooks/use-theme-by-class-name.mjs +1 -1
  64. package/dist/react/hooks/use-theme-by-class-name.mjs.map +1 -1
  65. package/dist/react/hooks/use-theme-by-data-attribute.cjs +1 -1
  66. package/dist/react/hooks/use-theme-by-data-attribute.cjs.map +1 -1
  67. package/dist/react/hooks/use-theme-by-data-attribute.d.cts +2 -2
  68. package/dist/react/hooks/use-theme-by-data-attribute.d.mts +2 -2
  69. package/dist/react/hooks/use-theme-by-data-attribute.mjs +1 -1
  70. package/dist/react/hooks/use-theme-by-data-attribute.mjs.map +1 -1
  71. package/dist/react/theme/create-theme-hook.cjs.map +1 -1
  72. package/dist/react/theme/create-theme-hook.mjs.map +1 -1
  73. package/dist/theme/_utils/parse-stored-theme.cjs +1 -1
  74. package/dist/theme/_utils/parse-stored-theme.cjs.map +1 -1
  75. package/dist/theme/_utils/parse-stored-theme.mjs +1 -1
  76. package/dist/theme/_utils/parse-stored-theme.mjs.map +1 -1
  77. package/dist/theme/_utils/set-theme-to-stores.cjs +1 -1
  78. package/dist/theme/_utils/set-theme-to-stores.cjs.map +1 -1
  79. package/dist/theme/_utils/set-theme-to-stores.mjs +1 -1
  80. package/dist/theme/_utils/set-theme-to-stores.mjs.map +1 -1
  81. package/dist/theme/class-name/parse-class-name.cjs +1 -1
  82. package/dist/theme/class-name/parse-class-name.cjs.map +1 -1
  83. package/dist/theme/class-name/parse-class-name.d.cts +2 -2
  84. package/dist/theme/class-name/parse-class-name.d.cts.map +1 -1
  85. package/dist/theme/class-name/parse-class-name.d.mts +2 -2
  86. package/dist/theme/class-name/parse-class-name.d.mts.map +1 -1
  87. package/dist/theme/class-name/parse-class-name.mjs +1 -1
  88. package/dist/theme/class-name/parse-class-name.mjs.map +1 -1
  89. package/dist/theme/class-name/read-class-name.cjs +1 -1
  90. package/dist/theme/class-name/read-class-name.cjs.map +1 -1
  91. package/dist/theme/class-name/read-class-name.d.cts +2 -2
  92. package/dist/theme/class-name/read-class-name.d.cts.map +1 -1
  93. package/dist/theme/class-name/read-class-name.d.mts +2 -2
  94. package/dist/theme/class-name/read-class-name.d.mts.map +1 -1
  95. package/dist/theme/class-name/read-class-name.mjs +1 -1
  96. package/dist/theme/class-name/read-class-name.mjs.map +1 -1
  97. package/dist/theme/class-name/stringify-class-name.cjs +4 -4
  98. package/dist/theme/class-name/stringify-class-name.cjs.map +1 -1
  99. package/dist/theme/class-name/stringify-class-name.d.cts +3 -3
  100. package/dist/theme/class-name/stringify-class-name.d.cts.map +1 -1
  101. package/dist/theme/class-name/stringify-class-name.d.mts +3 -3
  102. package/dist/theme/class-name/stringify-class-name.d.mts.map +1 -1
  103. package/dist/theme/class-name/stringify-class-name.mjs +4 -4
  104. package/dist/theme/class-name/stringify-class-name.mjs.map +1 -1
  105. package/dist/theme/class-name/subscribe-class-name.cjs +2 -3
  106. package/dist/theme/class-name/subscribe-class-name.cjs.map +1 -1
  107. package/dist/theme/class-name/subscribe-class-name.d.cts +2 -2
  108. package/dist/theme/class-name/subscribe-class-name.d.cts.map +1 -1
  109. package/dist/theme/class-name/subscribe-class-name.d.mts +2 -2
  110. package/dist/theme/class-name/subscribe-class-name.d.mts.map +1 -1
  111. package/dist/theme/class-name/subscribe-class-name.mjs +2 -3
  112. package/dist/theme/class-name/subscribe-class-name.mjs.map +1 -1
  113. package/dist/theme/class-name/write-class-name.cjs +2 -2
  114. package/dist/theme/class-name/write-class-name.cjs.map +1 -1
  115. package/dist/theme/class-name/write-class-name.d.cts +4 -4
  116. package/dist/theme/class-name/write-class-name.d.cts.map +1 -1
  117. package/dist/theme/class-name/write-class-name.d.mts +4 -4
  118. package/dist/theme/class-name/write-class-name.d.mts.map +1 -1
  119. package/dist/theme/class-name/write-class-name.mjs +2 -2
  120. package/dist/theme/class-name/write-class-name.mjs.map +1 -1
  121. package/dist/theme/compose-theme-stores.cjs.map +1 -1
  122. package/dist/theme/compose-theme-stores.mjs.map +1 -1
  123. package/dist/theme/cookie/write-cookie-theme.cjs +2 -2
  124. package/dist/theme/cookie/write-cookie-theme.cjs.map +1 -1
  125. package/dist/theme/cookie/write-cookie-theme.d.cts +2 -2
  126. package/dist/theme/cookie/write-cookie-theme.d.cts.map +1 -1
  127. package/dist/theme/cookie/write-cookie-theme.d.mts +2 -2
  128. package/dist/theme/cookie/write-cookie-theme.d.mts.map +1 -1
  129. package/dist/theme/cookie/write-cookie-theme.mjs +2 -2
  130. package/dist/theme/cookie/write-cookie-theme.mjs.map +1 -1
  131. package/dist/theme/data-attribute/parse-data-attribute.cjs +1 -1
  132. package/dist/theme/data-attribute/parse-data-attribute.cjs.map +1 -1
  133. package/dist/theme/data-attribute/parse-data-attribute.d.cts +2 -2
  134. package/dist/theme/data-attribute/parse-data-attribute.d.mts +2 -2
  135. package/dist/theme/data-attribute/parse-data-attribute.mjs +1 -1
  136. package/dist/theme/data-attribute/parse-data-attribute.mjs.map +1 -1
  137. package/dist/theme/data-attribute/read-data-attribute.cjs +1 -1
  138. package/dist/theme/data-attribute/read-data-attribute.cjs.map +1 -1
  139. package/dist/theme/data-attribute/read-data-attribute.d.cts +2 -2
  140. package/dist/theme/data-attribute/read-data-attribute.d.cts.map +1 -1
  141. package/dist/theme/data-attribute/read-data-attribute.d.mts +2 -2
  142. package/dist/theme/data-attribute/read-data-attribute.d.mts.map +1 -1
  143. package/dist/theme/data-attribute/read-data-attribute.mjs +1 -1
  144. package/dist/theme/data-attribute/read-data-attribute.mjs.map +1 -1
  145. package/dist/theme/data-attribute/stringify-data-attribute.cjs +4 -4
  146. package/dist/theme/data-attribute/stringify-data-attribute.cjs.map +1 -1
  147. package/dist/theme/data-attribute/stringify-data-attribute.d.cts +3 -3
  148. package/dist/theme/data-attribute/stringify-data-attribute.d.cts.map +1 -1
  149. package/dist/theme/data-attribute/stringify-data-attribute.d.mts +3 -3
  150. package/dist/theme/data-attribute/stringify-data-attribute.d.mts.map +1 -1
  151. package/dist/theme/data-attribute/stringify-data-attribute.mjs +4 -4
  152. package/dist/theme/data-attribute/stringify-data-attribute.mjs.map +1 -1
  153. package/dist/theme/data-attribute/subscribe-data-attribute.cjs +2 -3
  154. package/dist/theme/data-attribute/subscribe-data-attribute.cjs.map +1 -1
  155. package/dist/theme/data-attribute/subscribe-data-attribute.d.cts +2 -2
  156. package/dist/theme/data-attribute/subscribe-data-attribute.d.cts.map +1 -1
  157. package/dist/theme/data-attribute/subscribe-data-attribute.d.mts +2 -2
  158. package/dist/theme/data-attribute/subscribe-data-attribute.d.mts.map +1 -1
  159. package/dist/theme/data-attribute/subscribe-data-attribute.mjs +2 -3
  160. package/dist/theme/data-attribute/subscribe-data-attribute.mjs.map +1 -1
  161. package/dist/theme/data-attribute/write-data-attribute.cjs +3 -3
  162. package/dist/theme/data-attribute/write-data-attribute.cjs.map +1 -1
  163. package/dist/theme/data-attribute/write-data-attribute.d.cts +4 -4
  164. package/dist/theme/data-attribute/write-data-attribute.d.cts.map +1 -1
  165. package/dist/theme/data-attribute/write-data-attribute.d.mts +4 -4
  166. package/dist/theme/data-attribute/write-data-attribute.d.mts.map +1 -1
  167. package/dist/theme/data-attribute/write-data-attribute.mjs +3 -3
  168. package/dist/theme/data-attribute/write-data-attribute.mjs.map +1 -1
  169. package/dist/theme/local-storage/write-local-storage.cjs +1 -1
  170. package/dist/theme/local-storage/write-local-storage.cjs.map +1 -1
  171. package/dist/theme/local-storage/write-local-storage.d.cts +2 -2
  172. package/dist/theme/local-storage/write-local-storage.d.mts +2 -2
  173. package/dist/theme/local-storage/write-local-storage.mjs +1 -1
  174. package/dist/theme/local-storage/write-local-storage.mjs.map +1 -1
  175. package/dist/theme/session-storage/write-session-storage.cjs +1 -1
  176. package/dist/theme/session-storage/write-session-storage.cjs.map +1 -1
  177. package/dist/theme/session-storage/write-session-storage.d.cts +2 -2
  178. package/dist/theme/session-storage/write-session-storage.d.mts +2 -2
  179. package/dist/theme/session-storage/write-session-storage.mjs +1 -1
  180. package/dist/theme/session-storage/write-session-storage.mjs.map +1 -1
  181. package/dist/theme/theme-entry.types.d.cts +4 -2
  182. package/dist/theme/theme-entry.types.d.cts.map +1 -1
  183. package/dist/theme/theme-entry.types.d.mts +4 -2
  184. package/dist/theme/theme-entry.types.d.mts.map +1 -1
  185. package/dist/theme/theme-store/async-theme-store.types.d.cts +1 -1
  186. package/dist/theme/theme-store/async-theme-store.types.d.cts.map +1 -1
  187. package/dist/theme/theme-store/async-theme-store.types.d.mts +1 -1
  188. package/dist/theme/theme-store/async-theme-store.types.d.mts.map +1 -1
  189. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.cjs +1 -1
  190. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.cjs.map +1 -1
  191. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.cts +2 -2
  192. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.mts +2 -2
  193. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.mjs +1 -1
  194. package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.mjs.map +1 -1
  195. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.cjs +1 -1
  196. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.cjs.map +1 -1
  197. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.cts +3 -3
  198. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.mts +3 -3
  199. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.mjs +1 -1
  200. package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.mjs.map +1 -1
  201. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.cjs +1 -1
  202. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.cjs.map +1 -1
  203. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.d.cts +1 -1
  204. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.d.mts +1 -1
  205. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.mjs +1 -1
  206. package/dist/theme/theme-store/in-memory-theme-store/in-memory-theme-store.mjs.map +1 -1
  207. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.cts +1 -1
  208. package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.mts +1 -1
  209. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.cts +1 -1
  210. package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.mts +1 -1
  211. package/dist/theme/theme-store/theme-store.types.d.cts +1 -1
  212. package/dist/theme/theme-store/theme-store.types.d.cts.map +1 -1
  213. package/dist/theme/theme-store/theme-store.types.d.mts +1 -1
  214. package/dist/theme/theme-store/theme-store.types.d.mts.map +1 -1
  215. package/dist/theme/web-storage/write-web-storage.cjs +3 -3
  216. package/dist/theme/web-storage/write-web-storage.cjs.map +1 -1
  217. package/dist/theme/web-storage/write-web-storage.d.cts +2 -2
  218. package/dist/theme/web-storage/write-web-storage.d.mts +2 -2
  219. package/dist/theme/web-storage/write-web-storage.mjs +3 -3
  220. package/dist/theme/web-storage/write-web-storage.mjs.map +1 -1
  221. package/dist/utils/append-id.cjs +2 -2
  222. package/dist/utils/append-id.cjs.map +1 -1
  223. package/dist/utils/append-id.d.cts +3 -3
  224. package/dist/utils/append-id.d.mts +3 -3
  225. package/dist/utils/append-id.mjs +2 -2
  226. package/dist/utils/append-id.mjs.map +1 -1
  227. package/package.json +1 -1
  228. package/src/attributes/get-attribute.ts +5 -2
  229. package/src/attributes/get-data-attribute.ts +5 -2
  230. package/src/attributes/observe-attribute.ts +15 -10
  231. package/src/attributes/observe-data-attribute.ts +8 -11
  232. package/src/color-scheme/color-scheme.types.ts +7 -0
  233. package/src/color-scheme/get-prefers-color-scheme.ts +6 -4
  234. package/src/color-scheme/observe-prefers-color-scheme.ts +3 -1
  235. package/src/index.ts +1 -0
  236. package/src/react/hooks/use-attribute.ts +12 -13
  237. package/src/react/hooks/use-theme-by-class-name.ts +2 -2
  238. package/src/react/hooks/use-theme-by-data-attribute.ts +2 -2
  239. package/src/react/theme/create-theme-hook.ts +4 -6
  240. package/src/theme/_utils/parse-stored-theme.ts +2 -2
  241. package/src/theme/_utils/set-theme-to-stores.ts +3 -3
  242. package/src/theme/class-name/parse-class-name.ts +2 -2
  243. package/src/theme/class-name/read-class-name.ts +2 -2
  244. package/src/theme/class-name/stringify-class-name.ts +6 -6
  245. package/src/theme/class-name/subscribe-class-name.ts +3 -4
  246. package/src/theme/class-name/write-class-name.ts +4 -4
  247. package/src/theme/compose-theme-stores.ts +1 -1
  248. package/src/theme/cookie/write-cookie-theme.ts +3 -3
  249. package/src/theme/data-attribute/parse-data-attribute.ts +2 -2
  250. package/src/theme/data-attribute/read-data-attribute.ts +2 -2
  251. package/src/theme/data-attribute/stringify-data-attribute.ts +6 -6
  252. package/src/theme/data-attribute/subscribe-data-attribute.ts +3 -4
  253. package/src/theme/data-attribute/write-data-attribute.ts +5 -5
  254. package/src/theme/local-storage/write-local-storage.ts +2 -2
  255. package/src/theme/session-storage/write-session-storage.ts +2 -2
  256. package/src/theme/theme-entry.types.ts +5 -3
  257. package/src/theme/theme-store/async-theme-store.types.ts +1 -3
  258. package/src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts +2 -2
  259. package/src/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.ts +2 -2
  260. package/src/theme/theme-store/in-memory-theme-store/in-memory-theme-store.ts +1 -1
  261. package/src/theme/theme-store/theme-store.types.ts +1 -3
  262. package/src/theme/web-storage/write-web-storage.ts +5 -5
  263. package/src/utils/append-id.ts +3 -3
@@ -14,7 +14,7 @@ import { ParseStoredTheme, StringifyStoredTheme, ThemeEntry } from "../../theme-
14
14
  *
15
15
  * @param themes - Record mapping theme keys to attribute values
16
16
  * @param options.attributeName - Data attribute name (e.g. `data-theme`)
17
- * @param options.element - Element to operate on (defaults to document.documentElement)
17
+ * @param options.element - Element to operate on (accepts null e.g. from refs). Defaults to document.documentElement.
18
18
  * @param options.parse - Custom parser (default: parseDataAttribute with space separator)
19
19
  * @param options.stringify - Custom serializer (default: stringifyDataAttribute with space separator)
20
20
  * @returns ThemeStore
@@ -40,13 +40,13 @@ import { ParseStoredTheme, StringifyStoredTheme, ThemeEntry } from "../../theme-
40
40
  */
41
41
  declare function dataAttributeThemeStore<Themes extends ThemeMap>(themes: Themes, options: {
42
42
  attributeName: `data-${string}`;
43
- element?: Element | undefined;
43
+ element?: Element | null | undefined;
44
44
  parse?: ParseStoredTheme<Themes> | undefined;
45
45
  stringify?: StringifyStoredTheme<Themes> | undefined;
46
46
  }): {
47
47
  read(): ThemeEntry<Themes> | undefined;
48
48
  write(entry: ThemeEntry<Themes> | undefined): void;
49
- subscribe(handler: (theme: ThemeEntry<Themes> | null | undefined) => void): () => void;
49
+ subscribe(handler: (theme: ThemeEntry<Themes> | undefined) => void): () => void;
50
50
  };
51
51
  //#endregion
52
52
  export { dataAttributeThemeStore };
@@ -14,7 +14,7 @@ import { ParseStoredTheme, StringifyStoredTheme, ThemeEntry } from "../../theme-
14
14
  *
15
15
  * @param themes - Record mapping theme keys to attribute values
16
16
  * @param options.attributeName - Data attribute name (e.g. `data-theme`)
17
- * @param options.element - Element to operate on (defaults to document.documentElement)
17
+ * @param options.element - Element to operate on (accepts null e.g. from refs). Defaults to document.documentElement.
18
18
  * @param options.parse - Custom parser (default: parseDataAttribute with space separator)
19
19
  * @param options.stringify - Custom serializer (default: stringifyDataAttribute with space separator)
20
20
  * @returns ThemeStore
@@ -40,13 +40,13 @@ import { ParseStoredTheme, StringifyStoredTheme, ThemeEntry } from "../../theme-
40
40
  */
41
41
  declare function dataAttributeThemeStore<Themes extends ThemeMap>(themes: Themes, options: {
42
42
  attributeName: `data-${string}`;
43
- element?: Element | undefined;
43
+ element?: Element | null | undefined;
44
44
  parse?: ParseStoredTheme<Themes> | undefined;
45
45
  stringify?: StringifyStoredTheme<Themes> | undefined;
46
46
  }): {
47
47
  read(): ThemeEntry<Themes> | undefined;
48
48
  write(entry: ThemeEntry<Themes> | undefined): void;
49
- subscribe(handler: (theme: ThemeEntry<Themes> | null | undefined) => void): () => void;
49
+ subscribe(handler: (theme: ThemeEntry<Themes> | undefined) => void): () => void;
50
50
  };
51
51
  //#endregion
52
52
  export { dataAttributeThemeStore };
@@ -17,7 +17,7 @@ import { writeDataAttribute } from "../../data-attribute/write-data-attribute.mj
17
17
  *
18
18
  * @param themes - Record mapping theme keys to attribute values
19
19
  * @param options.attributeName - Data attribute name (e.g. `data-theme`)
20
- * @param options.element - Element to operate on (defaults to document.documentElement)
20
+ * @param options.element - Element to operate on (accepts null e.g. from refs). Defaults to document.documentElement.
21
21
  * @param options.parse - Custom parser (default: parseDataAttribute with space separator)
22
22
  * @param options.stringify - Custom serializer (default: stringifyDataAttribute with space separator)
23
23
  * @returns ThemeStore
@@ -1 +1 @@
1
- {"version":3,"file":"data-attribute-theme-store.mjs","names":[],"sources":["../../../../src/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.ts"],"sourcesContent":["import { SEPARATOR_SPACE } from '../../data-attribute/_constant.ts'\nimport { parseDataAttribute } from '../../data-attribute/parse-data-attribute.ts'\nimport { readDataAttribute } from '../../data-attribute/read-data-attribute.ts'\nimport { stringifyDataAttribute } from '../../data-attribute/stringify-data-attribute.ts'\nimport { subscribeDataAttribute } from '../../data-attribute/subscribe-data-attribute.ts'\nimport { writeDataAttribute } from '../../data-attribute/write-data-attribute.ts'\nimport type { ParseStoredTheme, StringifyStoredTheme } from '../../theme-entry.types.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 a data attribute.\n *\n * read: parse(themes, getDataAttribute(element, attribute)) → ThemeEntry\n * write: setAttribute(attribute, stringify(themes, getDataAttribute(element, attribute), entry))\n *\n * Supports space-separated attribute values by default. Use `parse` and `stringify` to customize\n * (e.g. comma-separated via curried parseDataAttribute/stringifyDataAttribute).\n *\n * @param themes - Record mapping theme keys to attribute values\n * @param options.attributeName - Data attribute name (e.g. `data-theme`)\n * @param options.element - Element to operate on (defaults to document.documentElement)\n * @param options.parse - Custom parser (default: parseDataAttribute with space separator)\n * @param options.stringify - Custom serializer (default: stringifyDataAttribute with space separator)\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'current', grayscale: 'grayscale' }\n * const store = dataAttributeThemeStore(themes, { attributeName: 'data-theme' })\n * store.read() // returns ThemeEntry from data attribute\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((entry) => {})\n * ```\n *\n * @example\n * ```ts\n * // Comma-separated\n * const store = dataAttributeThemeStore(themes, {\n * attributeName: 'data-theme',\n * parse: (t, v) => parseDataAttribute(t, v, { separator: ',' }),\n * stringify: (t, x, e) => stringifyDataAttribute(t, x, e, { separator: ',' })\n * })\n * ```\n */\nexport function dataAttributeThemeStore<Themes extends ThemeMap>(\n\tthemes: Themes,\n\toptions: {\n\t\tattributeName: `data-${string}`\n\t\telement?: Element | undefined\n\t\tparse?: ParseStoredTheme<Themes> | undefined\n\t\tstringify?: StringifyStoredTheme<Themes> | undefined\n\t}\n) {\n\tconst element = options.element ?? document?.documentElement\n\tconst {\n\t\tattributeName,\n\t\tparse = (t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }),\n\t\tstringify = (t, x, e) => stringifyDataAttribute(t, x, e, { separator: SEPARATOR_SPACE })\n\t} = options\n\n\treturn {\n\t\tread() {\n\t\t\treturn readDataAttribute(themes, attributeName, { element, parse })\n\t\t},\n\t\twrite(entry) {\n\t\t\twriteDataAttribute(themes, attributeName, entry, { element, stringify })\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\treturn subscribeDataAttribute(themes, attributeName, handler, { element, parse })\n\t\t}\n\t} satisfies ThemeStore<Themes>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,wBACf,QACA,SAMC;CACD,MAAM,UAAU,QAAQ,WAAW,UAAU;CAC7C,MAAM,EACL,eACA,SAAS,GAAG,MAAM,mBAAmB,GAAG,GAAG,EAAE,WAAW,iBAAiB,CAAC,EAC1E,aAAa,GAAG,GAAG,MAAM,uBAAuB,GAAG,GAAG,GAAG,EAAE,WAAW,iBAAiB,CAAC,KACrF;AAEJ,QAAO;EACN,OAAO;AACN,UAAO,kBAAkB,QAAQ,eAAe;IAAE;IAAS;IAAO,CAAC;;EAEpE,MAAM,OAAO;AACZ,sBAAmB,QAAQ,eAAe,OAAO;IAAE;IAAS;IAAW,CAAC;;EAEzE,UAAU,SAAS;AAClB,UAAO,uBAAuB,QAAQ,eAAe,SAAS;IAAE;IAAS;IAAO,CAAC;;EAElF"}
1
+ {"version":3,"file":"data-attribute-theme-store.mjs","names":[],"sources":["../../../../src/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.ts"],"sourcesContent":["import { SEPARATOR_SPACE } from '../../data-attribute/_constant.ts'\nimport { parseDataAttribute } from '../../data-attribute/parse-data-attribute.ts'\nimport { readDataAttribute } from '../../data-attribute/read-data-attribute.ts'\nimport { stringifyDataAttribute } from '../../data-attribute/stringify-data-attribute.ts'\nimport { subscribeDataAttribute } from '../../data-attribute/subscribe-data-attribute.ts'\nimport { writeDataAttribute } from '../../data-attribute/write-data-attribute.ts'\nimport type { ParseStoredTheme, StringifyStoredTheme } from '../../theme-entry.types.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 a data attribute.\n *\n * read: parse(themes, getDataAttribute(element, attribute)) → ThemeEntry\n * write: setAttribute(attribute, stringify(themes, getDataAttribute(element, attribute), entry))\n *\n * Supports space-separated attribute values by default. Use `parse` and `stringify` to customize\n * (e.g. comma-separated via curried parseDataAttribute/stringifyDataAttribute).\n *\n * @param themes - Record mapping theme keys to attribute values\n * @param options.attributeName - Data attribute name (e.g. `data-theme`)\n * @param options.element - Element to operate on (accepts null e.g. from refs). Defaults to document.documentElement.\n * @param options.parse - Custom parser (default: parseDataAttribute with space separator)\n * @param options.stringify - Custom serializer (default: stringifyDataAttribute with space separator)\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'current', grayscale: 'grayscale' }\n * const store = dataAttributeThemeStore(themes, { attributeName: 'data-theme' })\n * store.read() // returns ThemeEntry from data attribute\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((entry) => {})\n * ```\n *\n * @example\n * ```ts\n * // Comma-separated\n * const store = dataAttributeThemeStore(themes, {\n * attributeName: 'data-theme',\n * parse: (t, v) => parseDataAttribute(t, v, { separator: ',' }),\n * stringify: (t, x, e) => stringifyDataAttribute(t, x, e, { separator: ',' })\n * })\n * ```\n */\nexport function dataAttributeThemeStore<Themes extends ThemeMap>(\n\tthemes: Themes,\n\toptions: {\n\t\tattributeName: `data-${string}`\n\t\telement?: Element | null | undefined\n\t\tparse?: ParseStoredTheme<Themes> | undefined\n\t\tstringify?: StringifyStoredTheme<Themes> | undefined\n\t}\n) {\n\tconst element = options.element ?? document?.documentElement\n\tconst {\n\t\tattributeName,\n\t\tparse = (t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }),\n\t\tstringify = (t, x, e) => stringifyDataAttribute(t, x, e, { separator: SEPARATOR_SPACE })\n\t} = options\n\n\treturn {\n\t\tread() {\n\t\t\treturn readDataAttribute(themes, attributeName, { element, parse })\n\t\t},\n\t\twrite(entry) {\n\t\t\twriteDataAttribute(themes, attributeName, entry, { element, stringify })\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\treturn subscribeDataAttribute(themes, attributeName, handler, { element, parse })\n\t\t}\n\t} satisfies ThemeStore<Themes>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6CA,SAAgB,wBACf,QACA,SAMC;CACD,MAAM,UAAU,QAAQ,WAAW,UAAU;CAC7C,MAAM,EACL,eACA,SAAS,GAAG,MAAM,mBAAmB,GAAG,GAAG,EAAE,WAAW,iBAAiB,CAAC,EAC1E,aAAa,GAAG,GAAG,MAAM,uBAAuB,GAAG,GAAG,GAAG,EAAE,WAAW,iBAAiB,CAAC,KACrF;AAEJ,QAAO;EACN,OAAO;AACN,UAAO,kBAAkB,QAAQ,eAAe;IAAE;IAAS;IAAO,CAAC;;EAEpE,MAAM,OAAO;AACZ,sBAAmB,QAAQ,eAAe,OAAO;IAAE;IAAS;IAAW,CAAC;;EAEzE,UAAU,SAAS;AAClB,UAAO,uBAAuB,QAAQ,eAAe,SAAS;IAAE;IAAS;IAAO,CAAC;;EAElF"}
@@ -29,7 +29,7 @@ function inMemoryThemeStore(themes) {
29
29
  return {
30
30
  read,
31
31
  write(entry) {
32
- if (entry === void 0) {
32
+ if (entry == null) {
33
33
  if (value === void 0 || value === null) return;
34
34
  value = void 0;
35
35
  for (const fn of listeners) fn(void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory-theme-store.cjs","names":["value: keyof Themes | undefined | null","themeEntry"],"sources":["../../../../src/theme/theme-store/in-memory-theme-store/in-memory-theme-store.ts"],"sourcesContent":["import { 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\n/**\n * In-memory theme store. Transient state; no persistence.\n *\n * Bakes themes at creation. Validates theme keys on write; read/write use theme keys\n * and build ThemeEntry from the themes map, consistent with other stores.\n *\n * @param themes - Record mapping theme keys to values (for validation and entry construction)\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' } as const\n * const store = inMemoryThemeStore(themes)\n * store.read() // undefined when empty\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((themeResult) => {})\n * ```\n */\nexport function inMemoryThemeStore<Themes extends ThemeMap>(themes: Themes) {\n\tlet value: keyof Themes | undefined | null\n\tconst listeners = new Set<(v: ThemeEntry<Themes> | undefined) => void>()\n\n\tfunction read(): ThemeEntry<Themes> | undefined {\n\t\tif (value === undefined || value === null) return undefined\n\t\treturn themeEntry(themes, value)\n\t}\n\n\treturn {\n\t\tread,\n\t\twrite(entry) {\n\t\t\tif (entry === undefined) {\n\t\t\t\tif (value === undefined || value === null) return\n\t\t\t\tvalue = undefined\n\t\t\t\tfor (const fn of listeners) fn(undefined)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!(entry.theme in themes)) return\n\t\t\tif (value === entry.theme) return\n\t\t\tvalue = entry.theme\n\t\t\tfor (const fn of listeners) fn(themeEntry(themes, entry.theme))\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\tlisteners.add(handler)\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(handler)\n\t\t\t}\n\t\t}\n\t} satisfies ThemeStore<Themes>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,mBAA4C,QAAgB;CAC3E,IAAIA;CACJ,MAAM,4BAAY,IAAI,KAAkD;CAExE,SAAS,OAAuC;AAC/C,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,SAAOC,+BAAW,QAAQ,MAAM;;AAGjC,QAAO;EACN;EACA,MAAM,OAAO;AACZ,OAAI,UAAU,QAAW;AACxB,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,YAAQ;AACR,SAAK,MAAM,MAAM,UAAW,IAAG,OAAU;AACzC;;AAED,OAAI,EAAE,MAAM,SAAS,QAAS;AAC9B,OAAI,UAAU,MAAM,MAAO;AAC3B,WAAQ,MAAM;AACd,QAAK,MAAM,MAAM,UAAW,IAAGA,+BAAW,QAAQ,MAAM,MAAM,CAAC;;EAEhE,UAAU,SAAS;AAClB,aAAU,IAAI,QAAQ;AACtB,gBAAa;AACZ,cAAU,OAAO,QAAQ;;;EAG3B"}
1
+ {"version":3,"file":"in-memory-theme-store.cjs","names":["value: keyof Themes | undefined | null","themeEntry"],"sources":["../../../../src/theme/theme-store/in-memory-theme-store/in-memory-theme-store.ts"],"sourcesContent":["import { 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\n/**\n * In-memory theme store. Transient state; no persistence.\n *\n * Bakes themes at creation. Validates theme keys on write; read/write use theme keys\n * and build ThemeEntry from the themes map, consistent with other stores.\n *\n * @param themes - Record mapping theme keys to values (for validation and entry construction)\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' } as const\n * const store = inMemoryThemeStore(themes)\n * store.read() // undefined when empty\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((themeResult) => {})\n * ```\n */\nexport function inMemoryThemeStore<Themes extends ThemeMap>(themes: Themes) {\n\tlet value: keyof Themes | undefined | null\n\tconst listeners = new Set<(v: ThemeEntry<Themes> | undefined) => void>()\n\n\tfunction read(): ThemeEntry<Themes> | undefined {\n\t\tif (value === undefined || value === null) return undefined\n\t\treturn themeEntry(themes, value)\n\t}\n\n\treturn {\n\t\tread,\n\t\twrite(entry) {\n\t\t\tif (entry == null) {\n\t\t\t\tif (value === undefined || value === null) return\n\t\t\t\tvalue = undefined\n\t\t\t\tfor (const fn of listeners) fn(undefined)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!(entry.theme in themes)) return\n\t\t\tif (value === entry.theme) return\n\t\t\tvalue = entry.theme\n\t\t\tfor (const fn of listeners) fn(themeEntry(themes, entry.theme))\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\tlisteners.add(handler)\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(handler)\n\t\t\t}\n\t\t}\n\t} satisfies ThemeStore<Themes>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,mBAA4C,QAAgB;CAC3E,IAAIA;CACJ,MAAM,4BAAY,IAAI,KAAkD;CAExE,SAAS,OAAuC;AAC/C,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,SAAOC,+BAAW,QAAQ,MAAM;;AAGjC,QAAO;EACN;EACA,MAAM,OAAO;AACZ,OAAI,SAAS,MAAM;AAClB,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,YAAQ;AACR,SAAK,MAAM,MAAM,UAAW,IAAG,OAAU;AACzC;;AAED,OAAI,EAAE,MAAM,SAAS,QAAS;AAC9B,OAAI,UAAU,MAAM,MAAO;AAC3B,WAAQ,MAAM;AACd,QAAK,MAAM,MAAM,UAAW,IAAGA,+BAAW,QAAQ,MAAM,MAAM,CAAC;;EAEhE,UAAU,SAAS;AAClB,aAAU,IAAI,QAAQ;AACtB,gBAAa;AACZ,cAAU,OAAO,QAAQ;;;EAG3B"}
@@ -24,7 +24,7 @@ import { ThemeEntry } from "../../theme-entry.types.cjs";
24
24
  declare function inMemoryThemeStore<Themes extends ThemeMap>(themes: Themes): {
25
25
  read: () => ThemeEntry<Themes> | undefined;
26
26
  write(entry: ThemeEntry<Themes> | undefined): void;
27
- subscribe(handler: (theme: ThemeEntry<Themes> | null | undefined) => void): () => void;
27
+ subscribe(handler: (theme: ThemeEntry<Themes> | undefined) => void): () => void;
28
28
  };
29
29
  //#endregion
30
30
  export { inMemoryThemeStore };
@@ -24,7 +24,7 @@ import { ThemeEntry } from "../../theme-entry.types.mjs";
24
24
  declare function inMemoryThemeStore<Themes extends ThemeMap>(themes: Themes): {
25
25
  read: () => ThemeEntry<Themes> | undefined;
26
26
  write(entry: ThemeEntry<Themes> | undefined): void;
27
- subscribe(handler: (theme: ThemeEntry<Themes> | null | undefined) => void): () => void;
27
+ subscribe(handler: (theme: ThemeEntry<Themes> | undefined) => void): () => void;
28
28
  };
29
29
  //#endregion
30
30
  export { inMemoryThemeStore };
@@ -29,7 +29,7 @@ function inMemoryThemeStore(themes) {
29
29
  return {
30
30
  read,
31
31
  write(entry) {
32
- if (entry === void 0) {
32
+ if (entry == null) {
33
33
  if (value === void 0 || value === null) return;
34
34
  value = void 0;
35
35
  for (const fn of listeners) fn(void 0);
@@ -1 +1 @@
1
- {"version":3,"file":"in-memory-theme-store.mjs","names":["value: keyof Themes | undefined | null"],"sources":["../../../../src/theme/theme-store/in-memory-theme-store/in-memory-theme-store.ts"],"sourcesContent":["import { 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\n/**\n * In-memory theme store. Transient state; no persistence.\n *\n * Bakes themes at creation. Validates theme keys on write; read/write use theme keys\n * and build ThemeEntry from the themes map, consistent with other stores.\n *\n * @param themes - Record mapping theme keys to values (for validation and entry construction)\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' } as const\n * const store = inMemoryThemeStore(themes)\n * store.read() // undefined when empty\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((themeResult) => {})\n * ```\n */\nexport function inMemoryThemeStore<Themes extends ThemeMap>(themes: Themes) {\n\tlet value: keyof Themes | undefined | null\n\tconst listeners = new Set<(v: ThemeEntry<Themes> | undefined) => void>()\n\n\tfunction read(): ThemeEntry<Themes> | undefined {\n\t\tif (value === undefined || value === null) return undefined\n\t\treturn themeEntry(themes, value)\n\t}\n\n\treturn {\n\t\tread,\n\t\twrite(entry) {\n\t\t\tif (entry === undefined) {\n\t\t\t\tif (value === undefined || value === null) return\n\t\t\t\tvalue = undefined\n\t\t\t\tfor (const fn of listeners) fn(undefined)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!(entry.theme in themes)) return\n\t\t\tif (value === entry.theme) return\n\t\t\tvalue = entry.theme\n\t\t\tfor (const fn of listeners) fn(themeEntry(themes, entry.theme))\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\tlisteners.add(handler)\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(handler)\n\t\t\t}\n\t\t}\n\t} satisfies ThemeStore<Themes>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,mBAA4C,QAAgB;CAC3E,IAAIA;CACJ,MAAM,4BAAY,IAAI,KAAkD;CAExE,SAAS,OAAuC;AAC/C,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,SAAO,WAAW,QAAQ,MAAM;;AAGjC,QAAO;EACN;EACA,MAAM,OAAO;AACZ,OAAI,UAAU,QAAW;AACxB,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,YAAQ;AACR,SAAK,MAAM,MAAM,UAAW,IAAG,OAAU;AACzC;;AAED,OAAI,EAAE,MAAM,SAAS,QAAS;AAC9B,OAAI,UAAU,MAAM,MAAO;AAC3B,WAAQ,MAAM;AACd,QAAK,MAAM,MAAM,UAAW,IAAG,WAAW,QAAQ,MAAM,MAAM,CAAC;;EAEhE,UAAU,SAAS;AAClB,aAAU,IAAI,QAAQ;AACtB,gBAAa;AACZ,cAAU,OAAO,QAAQ;;;EAG3B"}
1
+ {"version":3,"file":"in-memory-theme-store.mjs","names":["value: keyof Themes | undefined | null"],"sources":["../../../../src/theme/theme-store/in-memory-theme-store/in-memory-theme-store.ts"],"sourcesContent":["import { 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\n/**\n * In-memory theme store. Transient state; no persistence.\n *\n * Bakes themes at creation. Validates theme keys on write; read/write use theme keys\n * and build ThemeEntry from the themes map, consistent with other stores.\n *\n * @param themes - Record mapping theme keys to values (for validation and entry construction)\n * @returns ThemeStore\n *\n * @example\n * ```ts\n * const themes = { current: 'theme-current', grayscale: 'theme-grayscale' } as const\n * const store = inMemoryThemeStore(themes)\n * store.read() // undefined when empty\n * store.write(themeEntry(themes, 'grayscale'))\n * store.subscribe((themeResult) => {})\n * ```\n */\nexport function inMemoryThemeStore<Themes extends ThemeMap>(themes: Themes) {\n\tlet value: keyof Themes | undefined | null\n\tconst listeners = new Set<(v: ThemeEntry<Themes> | undefined) => void>()\n\n\tfunction read(): ThemeEntry<Themes> | undefined {\n\t\tif (value === undefined || value === null) return undefined\n\t\treturn themeEntry(themes, value)\n\t}\n\n\treturn {\n\t\tread,\n\t\twrite(entry) {\n\t\t\tif (entry == null) {\n\t\t\t\tif (value === undefined || value === null) return\n\t\t\t\tvalue = undefined\n\t\t\t\tfor (const fn of listeners) fn(undefined)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif (!(entry.theme in themes)) return\n\t\t\tif (value === entry.theme) return\n\t\t\tvalue = entry.theme\n\t\t\tfor (const fn of listeners) fn(themeEntry(themes, entry.theme))\n\t\t},\n\t\tsubscribe(handler) {\n\t\t\tlisteners.add(handler)\n\t\t\treturn () => {\n\t\t\t\tlisteners.delete(handler)\n\t\t\t}\n\t\t}\n\t} satisfies ThemeStore<Themes>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,mBAA4C,QAAgB;CAC3E,IAAIA;CACJ,MAAM,4BAAY,IAAI,KAAkD;CAExE,SAAS,OAAuC;AAC/C,MAAI,UAAU,UAAa,UAAU,KAAM,QAAO;AAClD,SAAO,WAAW,QAAQ,MAAM;;AAGjC,QAAO;EACN;EACA,MAAM,OAAO;AACZ,OAAI,SAAS,MAAM;AAClB,QAAI,UAAU,UAAa,UAAU,KAAM;AAC3C,YAAQ;AACR,SAAK,MAAM,MAAM,UAAW,IAAG,OAAU;AACzC;;AAED,OAAI,EAAE,MAAM,SAAS,QAAS;AAC9B,OAAI,UAAU,MAAM,MAAO;AAC3B,WAAQ,MAAM;AACd,QAAK,MAAM,MAAM,UAAW,IAAG,WAAW,QAAQ,MAAM,MAAM,CAAC;;EAEhE,UAAU,SAAS;AAClB,aAAU,IAAI,QAAQ;AACtB,gBAAa;AACZ,cAAU,OAAO,QAAQ;;;EAG3B"}
@@ -33,7 +33,7 @@ declare function localStorageThemeStore<Themes extends ThemeMap>(themes: Themes,
33
33
  }): {
34
34
  read: () => ThemeEntry<Themes> | undefined;
35
35
  write(entry: ThemeEntry<Themes> | undefined): void;
36
- subscribe(handler: (theme: ThemeEntry<Themes> | null | undefined) => void): () => void;
36
+ subscribe(handler: (theme: ThemeEntry<Themes> | undefined) => void): () => void;
37
37
  };
38
38
  //#endregion
39
39
  export { localStorageThemeStore };
@@ -33,7 +33,7 @@ declare function localStorageThemeStore<Themes extends ThemeMap>(themes: Themes,
33
33
  }): {
34
34
  read: () => ThemeEntry<Themes> | undefined;
35
35
  write(entry: ThemeEntry<Themes> | undefined): void;
36
- subscribe(handler: (theme: ThemeEntry<Themes> | null | undefined) => void): () => void;
36
+ subscribe(handler: (theme: ThemeEntry<Themes> | undefined) => void): () => void;
37
37
  };
38
38
  //#endregion
39
39
  export { localStorageThemeStore };
@@ -33,7 +33,7 @@ declare function sessionStorageThemeStore<Themes extends ThemeMap>(themes: Theme
33
33
  }): {
34
34
  read: () => ThemeEntry<Themes> | undefined;
35
35
  write(entry: ThemeEntry<Themes> | undefined): void;
36
- subscribe(handler: (theme: ThemeEntry<Themes> | null | undefined) => void): () => void;
36
+ subscribe(handler: (theme: ThemeEntry<Themes> | undefined) => void): () => void;
37
37
  };
38
38
  //#endregion
39
39
  export { sessionStorageThemeStore };
@@ -33,7 +33,7 @@ declare function sessionStorageThemeStore<Themes extends ThemeMap>(themes: Theme
33
33
  }): {
34
34
  read: () => ThemeEntry<Themes> | undefined;
35
35
  write(entry: ThemeEntry<Themes> | undefined): void;
36
- subscribe(handler: (theme: ThemeEntry<Themes> | null | undefined) => void): () => void;
36
+ subscribe(handler: (theme: ThemeEntry<Themes> | undefined) => void): () => void;
37
37
  };
38
38
  //#endregion
39
39
  export { sessionStorageThemeStore };
@@ -26,7 +26,7 @@ import { ThemeEntry } from "../theme-entry.types.cjs";
26
26
  interface ThemeStore<Themes extends ThemeMap = ThemeMap> {
27
27
  read?: (() => ThemeEntry<Themes> | undefined) | undefined;
28
28
  write?: ((entry: ThemeEntry<Themes> | undefined) => void) | undefined;
29
- subscribe?: ((handler: (theme: ThemeEntry<Themes> | undefined | null) => void) => () => void) | undefined;
29
+ subscribe?: ((handler: (theme: ThemeEntry<Themes> | undefined) => void) => () => void) | undefined;
30
30
  }
31
31
  //#endregion
32
32
  export { ThemeStore };
@@ -1 +1 @@
1
- {"version":3,"file":"theme-store.types.d.cts","names":[],"sources":["../../../src/theme/theme-store/theme-store.types.ts"],"sourcesContent":[],"mappings":";;;;;;;AAuBA;;;;;;;;;;;;;;;;;;UAAiB,0BAA0B,WAAW;gBACvC,WAAW;mBACR,WAAW;iCAEN,WAAW"}
1
+ {"version":3,"file":"theme-store.types.d.cts","names":[],"sources":["../../../src/theme/theme-store/theme-store.types.ts"],"sourcesContent":[],"mappings":";;;;;;;AAuBA;;;;;;;;;;;;;;;;;;UAAiB,0BAA0B,WAAW;gBACvC,WAAW;mBACR,WAAW;iCACG,WAAW"}
@@ -26,7 +26,7 @@ import { ThemeEntry } from "../theme-entry.types.mjs";
26
26
  interface ThemeStore<Themes extends ThemeMap = ThemeMap> {
27
27
  read?: (() => ThemeEntry<Themes> | undefined) | undefined;
28
28
  write?: ((entry: ThemeEntry<Themes> | undefined) => void) | undefined;
29
- subscribe?: ((handler: (theme: ThemeEntry<Themes> | undefined | null) => void) => () => void) | undefined;
29
+ subscribe?: ((handler: (theme: ThemeEntry<Themes> | undefined) => void) => () => void) | undefined;
30
30
  }
31
31
  //#endregion
32
32
  export { ThemeStore };
@@ -1 +1 @@
1
- {"version":3,"file":"theme-store.types.d.mts","names":[],"sources":["../../../src/theme/theme-store/theme-store.types.ts"],"sourcesContent":[],"mappings":";;;;;;;AAuBA;;;;;;;;;;;;;;;;;;UAAiB,0BAA0B,WAAW;gBACvC,WAAW;mBACR,WAAW;iCAEN,WAAW"}
1
+ {"version":3,"file":"theme-store.types.d.mts","names":[],"sources":["../../../src/theme/theme-store/theme-store.types.ts"],"sourcesContent":[],"mappings":";;;;;;;AAuBA;;;;;;;;;;;;;;;;;;UAAiB,0BAA0B,WAAW;gBACvC,WAAW;mBACR,WAAW;iCACG,WAAW"}
@@ -1,7 +1,7 @@
1
1
 
2
2
  //#region src/theme/web-storage/write-web-storage.ts
3
3
  function defaultStringify(_themes, _existing, entry) {
4
- return entry === void 0 ? "" : JSON.stringify(entry);
4
+ return entry == null ? "" : JSON.stringify(entry);
5
5
  }
6
6
  /**
7
7
  * Writes a theme entry to a web storage (localStorage or sessionStorage).
@@ -10,7 +10,7 @@ function defaultStringify(_themes, _existing, entry) {
10
10
  *
11
11
  * @param themes - Record mapping theme keys to values (used by stringify)
12
12
  * @param storageKey - Storage key to write to
13
- * @param entry - Theme entry to write, or undefined to remove
13
+ * @param entry - Theme entry to write, or null/undefined to remove
14
14
  * @param options.storage - Storage object (localStorage or sessionStorage)
15
15
  * @param options.stringify - Custom serializer (default: JSON.stringify)
16
16
  * @param options.onError - Optional callback invoked when setItem/removeItem throws
@@ -18,7 +18,7 @@ function defaultStringify(_themes, _existing, entry) {
18
18
  function writeWebStorage(themes, storageKey, entry, options) {
19
19
  const { storage, stringify = defaultStringify, onError } = options;
20
20
  try {
21
- if (entry === void 0) storage.removeItem(storageKey);
21
+ if (entry == null) storage.removeItem(storageKey);
22
22
  else {
23
23
  const value = stringify(themes, storage.getItem(storageKey) ?? void 0, entry);
24
24
  storage.setItem(storageKey, value);
@@ -1 +1 @@
1
- {"version":3,"file":"write-web-storage.cjs","names":[],"sources":["../../../src/theme/web-storage/write-web-storage.ts"],"sourcesContent":["import type { StringifyStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\n\nfunction defaultStringify<Themes extends ThemeMap>(\n\t_themes: Themes,\n\t_existing: string | undefined,\n\tentry: ThemeEntry<Themes> | undefined\n): string {\n\treturn entry === undefined ? '' : JSON.stringify(entry)\n}\n\n/**\n * Writes a theme entry to a web storage (localStorage or sessionStorage).\n *\n * Performs setItem/removeItem only. Does not notify subscribers; the store must call notify() after this.\n *\n * @param themes - Record mapping theme keys to values (used by stringify)\n * @param storageKey - Storage key to write to\n * @param entry - Theme entry to write, or undefined to remove\n * @param options.storage - Storage object (localStorage or sessionStorage)\n * @param options.stringify - Custom serializer (default: JSON.stringify)\n * @param options.onError - Optional callback invoked when setItem/removeItem throws\n */\nexport function writeWebStorage<Themes extends ThemeMap>(\n\tthemes: Themes,\n\tstorageKey: string,\n\tentry: ThemeEntry<Themes> | undefined,\n\toptions: {\n\t\tstorage: Storage\n\t\tstringify?: StringifyStoredTheme<Themes> | undefined\n\t\tonError?: ((error: unknown) => void) | undefined\n\t}\n): void {\n\tconst { storage, stringify = defaultStringify, onError } = options\n\ttry {\n\t\tif (entry === undefined) {\n\t\t\tstorage.removeItem(storageKey)\n\t\t} else {\n\t\t\tconst existing = storage.getItem(storageKey) ?? undefined\n\t\t\tconst value = stringify(themes, existing, entry)\n\t\t\tstorage.setItem(storageKey, value)\n\t\t}\n\t} catch (error) {\n\t\tonError?.(error)\n\t}\n}\n"],"mappings":";;AAGA,SAAS,iBACR,SACA,WACA,OACS;AACT,QAAO,UAAU,SAAY,KAAK,KAAK,UAAU,MAAM;;;;;;;;;;;;;;AAexD,SAAgB,gBACf,QACA,YACA,OACA,SAKO;CACP,MAAM,EAAE,SAAS,YAAY,kBAAkB,YAAY;AAC3D,KAAI;AACH,MAAI,UAAU,OACb,SAAQ,WAAW,WAAW;OACxB;GAEN,MAAM,QAAQ,UAAU,QADP,QAAQ,QAAQ,WAAW,IAAI,QACN,MAAM;AAChD,WAAQ,QAAQ,YAAY,MAAM;;UAE3B,OAAO;AACf,YAAU,MAAM"}
1
+ {"version":3,"file":"write-web-storage.cjs","names":[],"sources":["../../../src/theme/web-storage/write-web-storage.ts"],"sourcesContent":["import type { StringifyStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\n\nfunction defaultStringify<Themes extends ThemeMap>(\n\t_themes: Themes,\n\t_existing: string | undefined,\n\tentry: ThemeEntry<Themes> | null | undefined\n): string {\n\treturn entry == null ? '' : JSON.stringify(entry)\n}\n\n/**\n * Writes a theme entry to a web storage (localStorage or sessionStorage).\n *\n * Performs setItem/removeItem only. Does not notify subscribers; the store must call notify() after this.\n *\n * @param themes - Record mapping theme keys to values (used by stringify)\n * @param storageKey - Storage key to write to\n * @param entry - Theme entry to write, or null/undefined to remove\n * @param options.storage - Storage object (localStorage or sessionStorage)\n * @param options.stringify - Custom serializer (default: JSON.stringify)\n * @param options.onError - Optional callback invoked when setItem/removeItem throws\n */\nexport function writeWebStorage<Themes extends ThemeMap>(\n\tthemes: Themes,\n\tstorageKey: string,\n\tentry: ThemeEntry<Themes> | null | undefined,\n\toptions: {\n\t\tstorage: Storage\n\t\tstringify?: StringifyStoredTheme<Themes> | undefined\n\t\tonError?: ((error: unknown) => void) | undefined\n\t}\n): void {\n\tconst { storage, stringify = defaultStringify, onError } = options\n\ttry {\n\t\tif (entry == null) {\n\t\t\tstorage.removeItem(storageKey)\n\t\t} else {\n\t\t\tconst existing = storage.getItem(storageKey) ?? undefined\n\t\t\tconst value = stringify(themes, existing, entry)\n\t\t\tstorage.setItem(storageKey, value)\n\t\t}\n\t} catch (error) {\n\t\tonError?.(error)\n\t}\n}\n"],"mappings":";;AAGA,SAAS,iBACR,SACA,WACA,OACS;AACT,QAAO,SAAS,OAAO,KAAK,KAAK,UAAU,MAAM;;;;;;;;;;;;;;AAelD,SAAgB,gBACf,QACA,YACA,OACA,SAKO;CACP,MAAM,EAAE,SAAS,YAAY,kBAAkB,YAAY;AAC3D,KAAI;AACH,MAAI,SAAS,KACZ,SAAQ,WAAW,WAAW;OACxB;GAEN,MAAM,QAAQ,UAAU,QADP,QAAQ,QAAQ,WAAW,IAAI,QACN,MAAM;AAChD,WAAQ,QAAQ,YAAY,MAAM;;UAE3B,OAAO;AACf,YAAU,MAAM"}
@@ -10,12 +10,12 @@ import { StringifyStoredTheme, ThemeEntry } from "../theme-entry.types.cjs";
10
10
  *
11
11
  * @param themes - Record mapping theme keys to values (used by stringify)
12
12
  * @param storageKey - Storage key to write to
13
- * @param entry - Theme entry to write, or undefined to remove
13
+ * @param entry - Theme entry to write, or null/undefined to remove
14
14
  * @param options.storage - Storage object (localStorage or sessionStorage)
15
15
  * @param options.stringify - Custom serializer (default: JSON.stringify)
16
16
  * @param options.onError - Optional callback invoked when setItem/removeItem throws
17
17
  */
18
- declare function writeWebStorage<Themes extends ThemeMap>(themes: Themes, storageKey: string, entry: ThemeEntry<Themes> | undefined, options: {
18
+ declare function writeWebStorage<Themes extends ThemeMap>(themes: Themes, storageKey: string, entry: ThemeEntry<Themes> | null | undefined, options: {
19
19
  storage: Storage;
20
20
  stringify?: StringifyStoredTheme<Themes> | undefined;
21
21
  onError?: ((error: unknown) => void) | undefined;
@@ -10,12 +10,12 @@ import { StringifyStoredTheme, ThemeEntry } from "../theme-entry.types.mjs";
10
10
  *
11
11
  * @param themes - Record mapping theme keys to values (used by stringify)
12
12
  * @param storageKey - Storage key to write to
13
- * @param entry - Theme entry to write, or undefined to remove
13
+ * @param entry - Theme entry to write, or null/undefined to remove
14
14
  * @param options.storage - Storage object (localStorage or sessionStorage)
15
15
  * @param options.stringify - Custom serializer (default: JSON.stringify)
16
16
  * @param options.onError - Optional callback invoked when setItem/removeItem throws
17
17
  */
18
- declare function writeWebStorage<Themes extends ThemeMap>(themes: Themes, storageKey: string, entry: ThemeEntry<Themes> | undefined, options: {
18
+ declare function writeWebStorage<Themes extends ThemeMap>(themes: Themes, storageKey: string, entry: ThemeEntry<Themes> | null | undefined, options: {
19
19
  storage: Storage;
20
20
  stringify?: StringifyStoredTheme<Themes> | undefined;
21
21
  onError?: ((error: unknown) => void) | undefined;
@@ -1,6 +1,6 @@
1
1
  //#region src/theme/web-storage/write-web-storage.ts
2
2
  function defaultStringify(_themes, _existing, entry) {
3
- return entry === void 0 ? "" : JSON.stringify(entry);
3
+ return entry == null ? "" : JSON.stringify(entry);
4
4
  }
5
5
  /**
6
6
  * Writes a theme entry to a web storage (localStorage or sessionStorage).
@@ -9,7 +9,7 @@ function defaultStringify(_themes, _existing, entry) {
9
9
  *
10
10
  * @param themes - Record mapping theme keys to values (used by stringify)
11
11
  * @param storageKey - Storage key to write to
12
- * @param entry - Theme entry to write, or undefined to remove
12
+ * @param entry - Theme entry to write, or null/undefined to remove
13
13
  * @param options.storage - Storage object (localStorage or sessionStorage)
14
14
  * @param options.stringify - Custom serializer (default: JSON.stringify)
15
15
  * @param options.onError - Optional callback invoked when setItem/removeItem throws
@@ -17,7 +17,7 @@ function defaultStringify(_themes, _existing, entry) {
17
17
  function writeWebStorage(themes, storageKey, entry, options) {
18
18
  const { storage, stringify = defaultStringify, onError } = options;
19
19
  try {
20
- if (entry === void 0) storage.removeItem(storageKey);
20
+ if (entry == null) storage.removeItem(storageKey);
21
21
  else {
22
22
  const value = stringify(themes, storage.getItem(storageKey) ?? void 0, entry);
23
23
  storage.setItem(storageKey, value);
@@ -1 +1 @@
1
- {"version":3,"file":"write-web-storage.mjs","names":[],"sources":["../../../src/theme/web-storage/write-web-storage.ts"],"sourcesContent":["import type { StringifyStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\n\nfunction defaultStringify<Themes extends ThemeMap>(\n\t_themes: Themes,\n\t_existing: string | undefined,\n\tentry: ThemeEntry<Themes> | undefined\n): string {\n\treturn entry === undefined ? '' : JSON.stringify(entry)\n}\n\n/**\n * Writes a theme entry to a web storage (localStorage or sessionStorage).\n *\n * Performs setItem/removeItem only. Does not notify subscribers; the store must call notify() after this.\n *\n * @param themes - Record mapping theme keys to values (used by stringify)\n * @param storageKey - Storage key to write to\n * @param entry - Theme entry to write, or undefined to remove\n * @param options.storage - Storage object (localStorage or sessionStorage)\n * @param options.stringify - Custom serializer (default: JSON.stringify)\n * @param options.onError - Optional callback invoked when setItem/removeItem throws\n */\nexport function writeWebStorage<Themes extends ThemeMap>(\n\tthemes: Themes,\n\tstorageKey: string,\n\tentry: ThemeEntry<Themes> | undefined,\n\toptions: {\n\t\tstorage: Storage\n\t\tstringify?: StringifyStoredTheme<Themes> | undefined\n\t\tonError?: ((error: unknown) => void) | undefined\n\t}\n): void {\n\tconst { storage, stringify = defaultStringify, onError } = options\n\ttry {\n\t\tif (entry === undefined) {\n\t\t\tstorage.removeItem(storageKey)\n\t\t} else {\n\t\t\tconst existing = storage.getItem(storageKey) ?? undefined\n\t\t\tconst value = stringify(themes, existing, entry)\n\t\t\tstorage.setItem(storageKey, value)\n\t\t}\n\t} catch (error) {\n\t\tonError?.(error)\n\t}\n}\n"],"mappings":";AAGA,SAAS,iBACR,SACA,WACA,OACS;AACT,QAAO,UAAU,SAAY,KAAK,KAAK,UAAU,MAAM;;;;;;;;;;;;;;AAexD,SAAgB,gBACf,QACA,YACA,OACA,SAKO;CACP,MAAM,EAAE,SAAS,YAAY,kBAAkB,YAAY;AAC3D,KAAI;AACH,MAAI,UAAU,OACb,SAAQ,WAAW,WAAW;OACxB;GAEN,MAAM,QAAQ,UAAU,QADP,QAAQ,QAAQ,WAAW,IAAI,QACN,MAAM;AAChD,WAAQ,QAAQ,YAAY,MAAM;;UAE3B,OAAO;AACf,YAAU,MAAM"}
1
+ {"version":3,"file":"write-web-storage.mjs","names":[],"sources":["../../../src/theme/web-storage/write-web-storage.ts"],"sourcesContent":["import type { StringifyStoredTheme, ThemeEntry } from '../theme-entry.types.ts'\nimport type { ThemeMap } from '../theme-map.types.ts'\n\nfunction defaultStringify<Themes extends ThemeMap>(\n\t_themes: Themes,\n\t_existing: string | undefined,\n\tentry: ThemeEntry<Themes> | null | undefined\n): string {\n\treturn entry == null ? '' : JSON.stringify(entry)\n}\n\n/**\n * Writes a theme entry to a web storage (localStorage or sessionStorage).\n *\n * Performs setItem/removeItem only. Does not notify subscribers; the store must call notify() after this.\n *\n * @param themes - Record mapping theme keys to values (used by stringify)\n * @param storageKey - Storage key to write to\n * @param entry - Theme entry to write, or null/undefined to remove\n * @param options.storage - Storage object (localStorage or sessionStorage)\n * @param options.stringify - Custom serializer (default: JSON.stringify)\n * @param options.onError - Optional callback invoked when setItem/removeItem throws\n */\nexport function writeWebStorage<Themes extends ThemeMap>(\n\tthemes: Themes,\n\tstorageKey: string,\n\tentry: ThemeEntry<Themes> | null | undefined,\n\toptions: {\n\t\tstorage: Storage\n\t\tstringify?: StringifyStoredTheme<Themes> | undefined\n\t\tonError?: ((error: unknown) => void) | undefined\n\t}\n): void {\n\tconst { storage, stringify = defaultStringify, onError } = options\n\ttry {\n\t\tif (entry == null) {\n\t\t\tstorage.removeItem(storageKey)\n\t\t} else {\n\t\t\tconst existing = storage.getItem(storageKey) ?? undefined\n\t\t\tconst value = stringify(themes, existing, entry)\n\t\t\tstorage.setItem(storageKey, value)\n\t\t}\n\t} catch (error) {\n\t\tonError?.(error)\n\t}\n}\n"],"mappings":";AAGA,SAAS,iBACR,SACA,WACA,OACS;AACT,QAAO,SAAS,OAAO,KAAK,KAAK,UAAU,MAAM;;;;;;;;;;;;;;AAelD,SAAgB,gBACf,QACA,YACA,OACA,SAKO;CACP,MAAM,EAAE,SAAS,YAAY,kBAAkB,YAAY;AAC3D,KAAI;AACH,MAAI,SAAS,KACZ,SAAQ,WAAW,WAAW;OACxB;GAEN,MAAM,QAAQ,UAAU,QADP,QAAQ,QAAQ,WAAW,IAAI,QACN,MAAM;AAChD,WAAQ,QAAQ,YAAY,MAAM;;UAE3B,OAAO;AACf,YAAU,MAAM"}
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * Appends a suffix to an ID if the ID is defined.
5
5
  *
6
- * @param id - The ID to append the suffix to.
6
+ * @param id - The ID to append the suffix to (accepts null e.g. from getAttribute).
7
7
  * @param suffix - The suffix to append to the ID.
8
- * @returns The ID with the suffix appended, or undefined if the ID is undefined.
8
+ * @returns The ID with the suffix appended, or undefined if the ID is null/undefined.
9
9
  */
10
10
  function appendId(id, suffix) {
11
11
  return id ? `${id}-${suffix}` : void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"append-id.cjs","names":[],"sources":["../../src/utils/append-id.ts"],"sourcesContent":["/**\n * Appends a suffix to an ID if the ID is defined.\n *\n * @param id - The ID to append the suffix to.\n * @param suffix - The suffix to append to the ID.\n * @returns The ID with the suffix appended, or undefined if the ID is undefined.\n */\nexport function appendId(id: string | undefined, suffix: string): string | undefined {\n\treturn id ? `${id}-${suffix}` : undefined\n}\n"],"mappings":";;;;;;;;;AAOA,SAAgB,SAAS,IAAwB,QAAoC;AACpF,QAAO,KAAK,GAAG,GAAG,GAAG,WAAW"}
1
+ {"version":3,"file":"append-id.cjs","names":[],"sources":["../../src/utils/append-id.ts"],"sourcesContent":["/**\n * Appends a suffix to an ID if the ID is defined.\n *\n * @param id - The ID to append the suffix to (accepts null e.g. from getAttribute).\n * @param suffix - The suffix to append to the ID.\n * @returns The ID with the suffix appended, or undefined if the ID is null/undefined.\n */\nexport function appendId(id: string | null | undefined, suffix: string): string | undefined {\n\treturn id ? `${id}-${suffix}` : undefined\n}\n"],"mappings":";;;;;;;;;AAOA,SAAgB,SAAS,IAA+B,QAAoC;AAC3F,QAAO,KAAK,GAAG,GAAG,GAAG,WAAW"}
@@ -2,11 +2,11 @@
2
2
  /**
3
3
  * Appends a suffix to an ID if the ID is defined.
4
4
  *
5
- * @param id - The ID to append the suffix to.
5
+ * @param id - The ID to append the suffix to (accepts null e.g. from getAttribute).
6
6
  * @param suffix - The suffix to append to the ID.
7
- * @returns The ID with the suffix appended, or undefined if the ID is undefined.
7
+ * @returns The ID with the suffix appended, or undefined if the ID is null/undefined.
8
8
  */
9
- declare function appendId(id: string | undefined, suffix: string): string | undefined;
9
+ declare function appendId(id: string | null | undefined, suffix: string): string | undefined;
10
10
  //#endregion
11
11
  export { appendId };
12
12
  //# sourceMappingURL=append-id.d.cts.map
@@ -2,11 +2,11 @@
2
2
  /**
3
3
  * Appends a suffix to an ID if the ID is defined.
4
4
  *
5
- * @param id - The ID to append the suffix to.
5
+ * @param id - The ID to append the suffix to (accepts null e.g. from getAttribute).
6
6
  * @param suffix - The suffix to append to the ID.
7
- * @returns The ID with the suffix appended, or undefined if the ID is undefined.
7
+ * @returns The ID with the suffix appended, or undefined if the ID is null/undefined.
8
8
  */
9
- declare function appendId(id: string | undefined, suffix: string): string | undefined;
9
+ declare function appendId(id: string | null | undefined, suffix: string): string | undefined;
10
10
  //#endregion
11
11
  export { appendId };
12
12
  //# sourceMappingURL=append-id.d.mts.map
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * Appends a suffix to an ID if the ID is defined.
4
4
  *
5
- * @param id - The ID to append the suffix to.
5
+ * @param id - The ID to append the suffix to (accepts null e.g. from getAttribute).
6
6
  * @param suffix - The suffix to append to the ID.
7
- * @returns The ID with the suffix appended, or undefined if the ID is undefined.
7
+ * @returns The ID with the suffix appended, or undefined if the ID is null/undefined.
8
8
  */
9
9
  function appendId(id, suffix) {
10
10
  return id ? `${id}-${suffix}` : void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"append-id.mjs","names":[],"sources":["../../src/utils/append-id.ts"],"sourcesContent":["/**\n * Appends a suffix to an ID if the ID is defined.\n *\n * @param id - The ID to append the suffix to.\n * @param suffix - The suffix to append to the ID.\n * @returns The ID with the suffix appended, or undefined if the ID is undefined.\n */\nexport function appendId(id: string | undefined, suffix: string): string | undefined {\n\treturn id ? `${id}-${suffix}` : undefined\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,SAAS,IAAwB,QAAoC;AACpF,QAAO,KAAK,GAAG,GAAG,GAAG,WAAW"}
1
+ {"version":3,"file":"append-id.mjs","names":[],"sources":["../../src/utils/append-id.ts"],"sourcesContent":["/**\n * Appends a suffix to an ID if the ID is defined.\n *\n * @param id - The ID to append the suffix to (accepts null e.g. from getAttribute).\n * @param suffix - The suffix to append to the ID.\n * @returns The ID with the suffix appended, or undefined if the ID is null/undefined.\n */\nexport function appendId(id: string | null | undefined, suffix: string): string | undefined {\n\treturn id ? `${id}-${suffix}` : undefined\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,SAAS,IAA+B,QAAoC;AAC3F,QAAO,KAAK,GAAG,GAAG,GAAG,WAAW"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@just-web/toolkits",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Toolkits for web applications",
5
5
  "homepage": "https://github.com/justland/just-web-foundation/tree/main/libs/toolkits",
6
6
  "repository": {
@@ -2,7 +2,7 @@
2
2
  * Gets the value of an attribute from an element.
3
3
  *
4
4
  * @param qualifiedName - The name of the attribute to get
5
- * @param element - The element to get the attribute from. Defaults to `document.documentElement`
5
+ * @param element - The element to get the attribute from (accepts null e.g. from refs). Defaults to `document.documentElement`
6
6
  * @returns The attribute value cast to type T, or null if the attribute doesn't exist
7
7
  *
8
8
  * @example
@@ -14,7 +14,10 @@
14
14
  * const testId = getAttribute('data-testid', element)
15
15
  * ```
16
16
  */
17
- export function getAttribute<T extends string>(qualifiedName: T, element?: Element | undefined) {
17
+ export function getAttribute<T extends string>(
18
+ qualifiedName: T,
19
+ element?: Element | null | undefined
20
+ ) {
18
21
  element = element ?? globalThis.document.documentElement
19
22
  return element.getAttribute(qualifiedName)
20
23
  }
@@ -5,11 +5,14 @@ import { getAttribute } from './get-attribute.ts'
5
5
  * Gets the value of a data attribute from an element.
6
6
  *
7
7
  * @param qualifiedName - The name of the data attribute to get
8
- * @param element - The element to get the data attribute from. Defaults to `document.documentElement`
8
+ * @param element - The element to get the data attribute from (accepts null e.g. from refs). Defaults to `document.documentElement`
9
9
  * @returns The data attribute value, or null if the attribute doesn't exist
10
10
  *
11
11
  * @example
12
12
  */
13
- export function getDataAttribute(qualifiedName: DataAttribute, element?: Element | undefined) {
13
+ export function getDataAttribute(
14
+ qualifiedName: DataAttribute,
15
+ element?: Element | null | undefined
16
+ ) {
14
17
  return getAttribute(qualifiedName, element)
15
18
  }
@@ -2,25 +2,30 @@
2
2
  * Observes attributes changes on an element and calls corresponding handlers.
3
3
  *
4
4
  * @param handlers - An object mapping attribute names to handler functions.
5
- * @param element - The element to observe. Defaults to `document.documentElement`.
6
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer.
5
+ * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`.
6
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
7
7
  *
8
8
  * @example
9
9
  * ```ts
10
- * const observer = observeAttributes({
11
- * 'data-theme': (attr, value) => console.log(`Theme changed to: ${value}`),
12
- * 'class': (attr, value) => console.log(`class changed to: ${value}`)
10
+ * const unsubscribe = observeAttributes({
11
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
12
+ * 'class': (value) => console.log(`class changed to: ${value}`)
13
13
  * });
14
14
  *
15
15
  * // Later, to stop observing:
16
- * observer.disconnect();
16
+ * unsubscribe();
17
17
  * ```
18
18
  */
19
19
  export function observeAttributes<T extends string>(
20
20
  handlers: Record<string, (value: T | null) => void>,
21
- element?: Element | undefined
22
- ) {
23
- element = element ?? globalThis.document.documentElement
21
+ element?: Element | null | undefined
22
+ ): () => void {
23
+ /* c8 ignore start */
24
+ if (typeof document === 'undefined') {
25
+ return () => {}
26
+ }
27
+ /* c8 ignore end */
28
+ element = element ?? document.documentElement
24
29
  const observer = new MutationObserver((mutations) => {
25
30
  for (const mutation of mutations) {
26
31
  const attribute = mutation.attributeName
@@ -33,5 +38,5 @@ export function observeAttributes<T extends string>(
33
38
  attributes: true,
34
39
  attributeFilter: Object.keys(handlers)
35
40
  })
36
- return observer
41
+ return () => observer.disconnect()
37
42
  }
@@ -3,27 +3,24 @@ import { observeAttributes } from './observe-attribute.ts'
3
3
  /**
4
4
  * Observes changes to `data-*` attributes on an element and calls corresponding handlers.
5
5
  *
6
- * @param options - Configuration options
7
- * @param options.handlers - An object mapping `data-*` attribute names to handler functions.
8
- * @param options.element - The element to observe. Defaults to `document.documentElement`
9
- * @returns {MutationObserver} The observer instance, which can be used to disconnect the observer
6
+ * @param handlers - An object mapping `data-*` attribute names to handler functions.
7
+ * @param element - The element to observe (accepts null e.g. from refs). Defaults to `document.documentElement`
8
+ * @returns An unsubscribe function to stop observing. Returns a no-op function in SSR environments.
10
9
  *
11
10
  * @example
12
11
  * ```ts
13
- * const observer = observeDataAttributes({
14
- * handlers: {
15
- * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
16
- * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
17
- * }
12
+ * const unsubscribe = observeDataAttributes({
13
+ * 'data-theme': (value) => console.log(`Theme changed to: ${value}`),
14
+ * 'data-mode': (value) => console.log(`Mode changed to: ${value}`)
18
15
  * });
19
16
  *
20
17
  * // Later, to stop observing:
21
- * observer.disconnect();
18
+ * unsubscribe();
22
19
  * ```
23
20
  */
24
21
  export function observeDataAttributes<T extends string, K extends `data-${string}`>(
25
22
  handlers: Record<K, (value: T | null) => void>,
26
- element?: Element | undefined
23
+ element?: Element | null | undefined
27
24
  ) {
28
25
  return observeAttributes(handlers, element)
29
26
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The color scheme of the system.
3
+ *
4
+ * Per {@link https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme Media Queries Level 5 § prefers-color-scheme},
5
+ * these are the only valid values exposed by the `prefers-color-scheme` media feature.
6
+ */
7
+ export type ColorScheme = 'light' | 'dark'
@@ -1,17 +1,19 @@
1
+ import type { ColorScheme } from './color-scheme.types.ts'
2
+
1
3
  /**
2
4
  * Gets the current preferred color scheme.
3
5
  * It can only be 'light' or 'dark'.
4
6
  *
5
- * Even if the browser preference is 'auto'/'device', it will return 'light' or 'dark'.
7
+ * Per {@link https://drafts.csswg.org/mediaqueries-5/#prefers-color-scheme Media Queries Level 5},
8
+ * the `prefers-color-scheme` media feature has only two valid values. Even if the browser
9
+ * preference is 'auto'/'device', it will return 'light' or 'dark'.
6
10
  *
7
11
  * When `matchMedia` is unavailable (e.g. SSR), returns `defaultColorScheme`.
8
12
  *
9
13
  * @param defaultColorScheme - Fallback when `matchMedia` is unavailable (default: `'light'`)
10
14
  * @returns 'light' or 'dark'
11
15
  */
12
- export function getPrefersColorScheme(
13
- defaultColorScheme: 'light' | 'dark' = 'light'
14
- ): 'light' | 'dark' {
16
+ export function getPrefersColorScheme(defaultColorScheme: ColorScheme = 'light'): ColorScheme {
15
17
  if (typeof matchMedia === 'undefined') return defaultColorScheme
16
18
  return matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'
17
19
  }
@@ -1,3 +1,5 @@
1
+ import type { ColorScheme } from './color-scheme.types.ts'
2
+
1
3
  /**
2
4
  * Observes system color scheme preference changes and calls handlers when they occur.
3
5
  *
@@ -13,7 +15,7 @@
13
15
  * cleanup()
14
16
  * ```
15
17
  */
16
- export function observePrefersColorScheme(handler: (value: 'light' | 'dark') => void) {
18
+ export function observePrefersColorScheme(handler: (value: ColorScheme) => void) {
17
19
  const m = globalThis.matchMedia('(prefers-color-scheme: light)')
18
20
  const listener = (event: MediaQueryListEvent) => {
19
21
  handler(event.matches ? 'light' : 'dark')
package/src/index.ts CHANGED
@@ -9,6 +9,7 @@ export * from './class-name/class-name-props.ts'
9
9
  export * from './class-name/clsx.ts'
10
10
  export * from './class-name/just-class-name.ts'
11
11
  export * from './class-name/resolve-class-name.ts'
12
+ export * from './color-scheme/color-scheme.types.ts'
12
13
  export * from './color-scheme/get-prefers-color-scheme.ts'
13
14
  export * from './color-scheme/observe-prefers-color-scheme.ts'
14
15
  export * from './style/css-properties.ts'