@just-web/toolkits 2.0.0 → 2.1.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 +1 -1
  18. package/dist/attributes/observe-attribute.cjs.map +1 -1
  19. package/dist/attributes/observe-attribute.d.cts +2 -2
  20. package/dist/attributes/observe-attribute.d.cts.map +1 -1
  21. package/dist/attributes/observe-attribute.d.mts +2 -2
  22. package/dist/attributes/observe-attribute.d.mts.map +1 -1
  23. package/dist/attributes/observe-attribute.mjs +1 -1
  24. package/dist/attributes/observe-attribute.mjs.map +1 -1
  25. package/dist/attributes/observe-data-attribute.cjs +1 -1
  26. package/dist/attributes/observe-data-attribute.cjs.map +1 -1
  27. package/dist/attributes/observe-data-attribute.d.cts +2 -2
  28. package/dist/attributes/observe-data-attribute.d.cts.map +1 -1
  29. package/dist/attributes/observe-data-attribute.d.mts +2 -2
  30. package/dist/attributes/observe-data-attribute.d.mts.map +1 -1
  31. package/dist/attributes/observe-data-attribute.mjs +1 -1
  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 +7 -7
  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 +7 -7
  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 +1 -1
  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 +1 -1
  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 +1 -1
  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 +1 -1
  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 +2 -2
  231. package/src/attributes/observe-data-attribute.ts +2 -2
  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 +11 -11
  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 +2 -2
  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 +2 -2
  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
@@ -10,13 +10,13 @@ import { SEPARATOR_SPACE } from './_constant.ts'
10
10
  * Pure function: no DOM access. Uses first token when separator is defined.
11
11
  *
12
12
  * @param themes - Record mapping theme keys to attribute values
13
- * @param value - Raw attribute value string (e.g. from getAttribute)
13
+ * @param value - Raw attribute value string (e.g. from getAttribute; accepts null)
14
14
  * @param options.separator - When defined, split by separator and use first token (default: space)
15
15
  * @returns ThemeEntry if a match is found, otherwise undefined
16
16
  */
17
17
  export function parseDataAttribute<Themes extends ThemeMap>(
18
18
  themes: Themes,
19
- value: string | undefined,
19
+ value: string | null | undefined,
20
20
  options?: { separator?: string | undefined } | undefined
21
21
  ): ThemeEntry<Themes> | undefined {
22
22
  const separator = options?.separator ?? SEPARATOR_SPACE
@@ -9,7 +9,7 @@ import { parseDataAttribute } from './parse-data-attribute.ts'
9
9
  *
10
10
  * @param themes - Record mapping theme keys to attribute values
11
11
  * @param attributeName - Data attribute name (e.g. `data-theme`)
12
- * @param options.element - Element to read from (defaults to document.documentElement)
12
+ * @param options.element - Element to read from (accepts null e.g. from refs). Defaults to document.documentElement.
13
13
  * @param options.parse - Custom parser (default: parseDataAttribute with space separator)
14
14
  * @returns ThemeEntry if found, undefined otherwise. Returns undefined when element is not available (e.g. SSR).
15
15
  */
@@ -17,7 +17,7 @@ export function readDataAttribute<Themes extends ThemeMap>(
17
17
  themes: Themes,
18
18
  attributeName: `data-${string}`,
19
19
  options?:
20
- | { element?: Element | undefined; parse?: ParseStoredTheme<Themes> | undefined }
20
+ | { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }
21
21
  | undefined
22
22
  ): ThemeEntry<Themes> | undefined {
23
23
  const element = options?.element ?? document?.documentElement
@@ -10,15 +10,15 @@ import { SEPARATOR_SPACE } from './_constant.ts'
10
10
  * Aligns with stringifyClassName logic.
11
11
  *
12
12
  * @param themes - Record mapping theme keys to attribute values (used to identify theme tokens)
13
- * @param existing - Current attribute value string
14
- * @param entry - Theme entry to stringify, or undefined to clear theme (keeps non-theme tokens)
13
+ * @param existing - Current attribute value string (accepts null e.g. from getAttribute)
14
+ * @param entry - Theme entry to stringify, or null/undefined to clear theme (keeps non-theme tokens)
15
15
  * @param options.separator - Token separator (default: space)
16
16
  * @returns Attribute value string
17
17
  */
18
18
  export function stringifyDataAttribute<Themes extends ThemeMap>(
19
19
  themes: Themes,
20
- existing: string | undefined,
21
- entry: ThemeEntry<Themes> | undefined,
20
+ existing: string | null | undefined,
21
+ entry: ThemeEntry<Themes> | null | undefined,
22
22
  options?: { separator?: string | undefined } | undefined
23
23
  ): string {
24
24
  const separator = options?.separator ?? SEPARATOR_SPACE
@@ -26,10 +26,10 @@ export function stringifyDataAttribute<Themes extends ThemeMap>(
26
26
  const resolved = resolveThemeMapValue(v)
27
27
  return Array.isArray(resolved) ? [...resolved] : [resolved]
28
28
  })
29
- const existingTokens = existing?.trim() ? existing.trim().split(separator) : []
29
+ const existingTokens = (existing ?? '')?.trim() ? (existing ?? '').trim().split(separator) : []
30
30
  const withoutThemeValues = existingTokens.filter((t) => !allThemeValues.includes(t.trim()))
31
31
  const newTokens =
32
- entry !== undefined
32
+ entry != null
33
33
  ? (() => {
34
34
  const resolved = resolveThemeMapValue(entry.value)
35
35
  return Array.isArray(resolved) ? [resolved[0]] : [resolved]
@@ -10,7 +10,7 @@ import { parseDataAttribute } from './parse-data-attribute.ts'
10
10
  * @param themes - Record mapping theme keys to attribute values
11
11
  * @param attributeName - Data attribute name (e.g. `data-theme`)
12
12
  * @param handler - Callback invoked when the attribute changes
13
- * @param options.element - Element to observe (defaults to document.documentElement)
13
+ * @param options.element - Element to observe (accepts null e.g. from refs). Defaults to document.documentElement.
14
14
  * @param options.parse - Custom parser (default: parseDataAttribute with space separator)
15
15
  * @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).
16
16
  */
@@ -19,7 +19,7 @@ export function subscribeDataAttribute<Themes extends ThemeMap>(
19
19
  attributeName: `data-${string}`,
20
20
  handler: (entry: ThemeEntry<Themes> | undefined) => void,
21
21
  options?:
22
- | { element?: Element | undefined; parse?: ParseStoredTheme<Themes> | undefined }
22
+ | { element?: Element | null | undefined; parse?: ParseStoredTheme<Themes> | undefined }
23
23
  | undefined
24
24
  ): () => void {
25
25
  const element = options?.element ?? document?.documentElement
@@ -9,16 +9,16 @@ import { stringifyDataAttribute } from './stringify-data-attribute.ts'
9
9
  *
10
10
  * @param themes - Record mapping theme keys to attribute values
11
11
  * @param attributeName - Data attribute name (e.g. `data-theme`)
12
- * @param entry - Theme entry to write, or undefined to remove the theme
13
- * @param options.element - Element to write to (defaults to document.documentElement)
12
+ * @param entry - Theme entry to write, or null/undefined to remove the theme
13
+ * @param options.element - Element to write to (accepts null e.g. from refs). Defaults to document.documentElement.
14
14
  * @param options.stringify - Custom serializer (default: stringifyDataAttribute with space separator)
15
15
  */
16
16
  export function writeDataAttribute<Themes extends ThemeMap>(
17
17
  themes: Themes,
18
18
  attributeName: `data-${string}`,
19
- entry: ThemeEntry<Themes> | undefined,
19
+ entry: ThemeEntry<Themes> | null | undefined,
20
20
  options?:
21
- | { element?: Element | undefined; stringify?: StringifyStoredTheme<Themes> | undefined }
21
+ | { element?: Element | null | undefined; stringify?: StringifyStoredTheme<Themes> | undefined }
22
22
  | undefined
23
23
  ): void {
24
24
  const element = options?.element ?? document?.documentElement
@@ -26,7 +26,7 @@ export function writeDataAttribute<Themes extends ThemeMap>(
26
26
  const stringify =
27
27
  options?.stringify ??
28
28
  ((t, x, e) => stringifyDataAttribute(t, x, e, { separator: SEPARATOR_SPACE }))
29
- if (entry === undefined) {
29
+ if (entry == null) {
30
30
  element.removeAttribute(attributeName)
31
31
  return
32
32
  }
@@ -9,14 +9,14 @@ import { writeWebStorage } from '../web-storage/write-web-storage.ts'
9
9
  *
10
10
  * @param themes - Record mapping theme keys to values (used by stringify)
11
11
  * @param storageKey - localStorage 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.stringify - Custom serializer (default: JSON.stringify)
14
14
  * @param options.onError - Optional callback invoked when storage write throws
15
15
  */
16
16
  export function writeLocalStorage<Themes extends ThemeMap>(
17
17
  themes: Themes,
18
18
  storageKey: string,
19
- entry: ThemeEntry<Themes> | undefined,
19
+ entry: ThemeEntry<Themes> | null | undefined,
20
20
  options?: {
21
21
  stringify?: StringifyStoredTheme<Themes> | undefined
22
22
  onError?: ((error: unknown) => void) | undefined
@@ -9,14 +9,14 @@ import { writeWebStorage } from '../web-storage/write-web-storage.ts'
9
9
  *
10
10
  * @param themes - Record mapping theme keys to values (used by stringify)
11
11
  * @param storageKey - sessionStorage 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.stringify - Custom serializer (default: JSON.stringify)
14
14
  * @param options.onError - Optional callback invoked when storage write throws
15
15
  */
16
16
  export function writeSessionStorage<Themes extends ThemeMap>(
17
17
  themes: Themes,
18
18
  storageKey: string,
19
- entry: ThemeEntry<Themes> | undefined,
19
+ entry: ThemeEntry<Themes> | null | undefined,
20
20
  options?: {
21
21
  stringify?: StringifyStoredTheme<Themes> | undefined
22
22
  onError?: ((error: unknown) => void) | undefined
@@ -13,18 +13,20 @@ export interface ThemeEntry<Themes extends ThemeMap = ThemeMap> {
13
13
  /**
14
14
  * Function type for parsing stored string into ThemeEntry.
15
15
  * Used as options.parse in persisting theme stores.
16
+ * Value accepts null (e.g. from getItem, getAttribute, cookie parsing).
16
17
  */
17
18
  export type ParseStoredTheme<Themes extends ThemeMap> = (
18
19
  themes: Themes,
19
- value: string | undefined
20
+ value: string | null | undefined
20
21
  ) => ThemeEntry<Themes> | undefined
21
22
 
22
23
  /**
23
24
  * Function type for stringify ThemeEntry to a stored string.
24
25
  * Used as options.stringify in persisting theme stores.
26
+ * Existing accepts null (e.g. from getAttribute, getItem); entry accepts null for remove/clear.
25
27
  */
26
28
  export type StringifyStoredTheme<Themes extends ThemeMap> = (
27
29
  themes: Themes,
28
- existing: string | undefined,
29
- entry: ThemeEntry<Themes> | undefined
30
+ existing: string | null | undefined,
31
+ entry: ThemeEntry<Themes> | null | undefined
30
32
  ) => string
@@ -18,7 +18,5 @@ export interface AsyncThemeStore<Themes extends ThemeMap = ThemeMap> {
18
18
  | (() => ThemeEntry<Themes> | undefined | Promise<ThemeEntry<Themes> | undefined>)
19
19
  | undefined
20
20
  write?: ((entry: ThemeEntry<Themes> | undefined) => void | Promise<void>) | undefined
21
- subscribe?:
22
- | ((handler: (entry: ThemeEntry<Themes> | undefined | null) => void) => () => void)
23
- | undefined
21
+ subscribe?: ((handler: (entry: ThemeEntry<Themes> | undefined) => void) => () => void) | undefined
24
22
  }
@@ -13,7 +13,7 @@ import type { ThemeStore } from '../theme-store.types.ts'
13
13
  * Creates a theme store that reads and writes via element class names.
14
14
  *
15
15
  * @param themes - Record mapping theme keys to class name(s)
16
- * @param options.element - Element to operate on (defaults to document.documentElement)
16
+ * @param options.element - Element to operate on (accepts null e.g. from refs). Defaults to document.documentElement.
17
17
  * @param options.parse - Custom parser (default: parseClassName)
18
18
  * @param options.stringify - Custom serializer (default: stringifyClassName)
19
19
  * @returns ThemeStore
@@ -30,7 +30,7 @@ import type { ThemeStore } from '../theme-store.types.ts'
30
30
  export function classNameThemeStore<Themes extends ThemeMap>(
31
31
  themes: Themes,
32
32
  options?: {
33
- element?: Element | undefined
33
+ element?: Element | null | undefined
34
34
  parse?: ParseStoredTheme<Themes> | undefined
35
35
  stringify?: StringifyStoredTheme<Themes> | undefined
36
36
  }
@@ -19,7 +19,7 @@ import type { ThemeStore } from '../theme-store.types.ts'
19
19
  *
20
20
  * @param themes - Record mapping theme keys to attribute values
21
21
  * @param options.attributeName - Data attribute name (e.g. `data-theme`)
22
- * @param options.element - Element to operate on (defaults to document.documentElement)
22
+ * @param options.element - Element to operate on (accepts null e.g. from refs). Defaults to document.documentElement.
23
23
  * @param options.parse - Custom parser (default: parseDataAttribute with space separator)
24
24
  * @param options.stringify - Custom serializer (default: stringifyDataAttribute with space separator)
25
25
  * @returns ThemeStore
@@ -47,7 +47,7 @@ export function dataAttributeThemeStore<Themes extends ThemeMap>(
47
47
  themes: Themes,
48
48
  options: {
49
49
  attributeName: `data-${string}`
50
- element?: Element | undefined
50
+ element?: Element | null | undefined
51
51
  parse?: ParseStoredTheme<Themes> | undefined
52
52
  stringify?: StringifyStoredTheme<Themes> | undefined
53
53
  }
@@ -33,7 +33,7 @@ export function inMemoryThemeStore<Themes extends ThemeMap>(themes: Themes) {
33
33
  return {
34
34
  read,
35
35
  write(entry) {
36
- if (entry === undefined) {
36
+ if (entry == null) {
37
37
  if (value === undefined || value === null) return
38
38
  value = undefined
39
39
  for (const fn of listeners) fn(undefined)
@@ -24,7 +24,5 @@ import type { ThemeMap } from '../theme-map.types.ts'
24
24
  export interface ThemeStore<Themes extends ThemeMap = ThemeMap> {
25
25
  read?: (() => ThemeEntry<Themes> | undefined) | undefined
26
26
  write?: ((entry: ThemeEntry<Themes> | undefined) => void) | undefined
27
- subscribe?:
28
- | ((handler: (theme: ThemeEntry<Themes> | undefined | null) => void) => () => void)
29
- | undefined
27
+ subscribe?: ((handler: (theme: ThemeEntry<Themes> | undefined) => void) => () => void) | undefined
30
28
  }
@@ -4,9 +4,9 @@ import type { ThemeMap } from '../theme-map.types.ts'
4
4
  function defaultStringify<Themes extends ThemeMap>(
5
5
  _themes: Themes,
6
6
  _existing: string | undefined,
7
- entry: ThemeEntry<Themes> | undefined
7
+ entry: ThemeEntry<Themes> | null | undefined
8
8
  ): string {
9
- return entry === undefined ? '' : JSON.stringify(entry)
9
+ return entry == null ? '' : JSON.stringify(entry)
10
10
  }
11
11
 
12
12
  /**
@@ -16,7 +16,7 @@ function defaultStringify<Themes extends ThemeMap>(
16
16
  *
17
17
  * @param themes - Record mapping theme keys to values (used by stringify)
18
18
  * @param storageKey - Storage key to write to
19
- * @param entry - Theme entry to write, or undefined to remove
19
+ * @param entry - Theme entry to write, or null/undefined to remove
20
20
  * @param options.storage - Storage object (localStorage or sessionStorage)
21
21
  * @param options.stringify - Custom serializer (default: JSON.stringify)
22
22
  * @param options.onError - Optional callback invoked when setItem/removeItem throws
@@ -24,7 +24,7 @@ function defaultStringify<Themes extends ThemeMap>(
24
24
  export function writeWebStorage<Themes extends ThemeMap>(
25
25
  themes: Themes,
26
26
  storageKey: string,
27
- entry: ThemeEntry<Themes> | undefined,
27
+ entry: ThemeEntry<Themes> | null | undefined,
28
28
  options: {
29
29
  storage: Storage
30
30
  stringify?: StringifyStoredTheme<Themes> | undefined
@@ -33,7 +33,7 @@ export function writeWebStorage<Themes extends ThemeMap>(
33
33
  ): void {
34
34
  const { storage, stringify = defaultStringify, onError } = options
35
35
  try {
36
- if (entry === undefined) {
36
+ if (entry == null) {
37
37
  storage.removeItem(storageKey)
38
38
  } else {
39
39
  const existing = storage.getItem(storageKey) ?? undefined
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Appends a suffix to an ID if the ID is defined.
3
3
  *
4
- * @param id - The ID to append the suffix to.
4
+ * @param id - The ID to append the suffix to (accepts null e.g. from getAttribute).
5
5
  * @param suffix - The suffix to append to the ID.
6
- * @returns The ID with the suffix appended, or undefined if the ID is undefined.
6
+ * @returns The ID with the suffix appended, or undefined if the ID is null/undefined.
7
7
  */
8
- export function appendId(id: string | undefined, suffix: string): string | undefined {
8
+ export function appendId(id: string | null | undefined, suffix: string): string | undefined {
9
9
  return id ? `${id}-${suffix}` : undefined
10
10
  }