@just-web/toolkits 1.0.0 → 2.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.
- package/dist/react/hooks/use-theme-by-class-name.cjs +1 -5
- package/dist/react/hooks/use-theme-by-class-name.cjs.map +1 -1
- package/dist/react/hooks/use-theme-by-class-name.d.cts.map +1 -1
- package/dist/react/hooks/use-theme-by-class-name.d.mts.map +1 -1
- package/dist/react/hooks/use-theme-by-class-name.mjs +1 -5
- package/dist/react/hooks/use-theme-by-class-name.mjs.map +1 -1
- package/dist/react/hooks/use-theme-by-data-attribute.cjs +1 -6
- package/dist/react/hooks/use-theme-by-data-attribute.cjs.map +1 -1
- package/dist/react/hooks/use-theme-by-data-attribute.d.cts.map +1 -1
- package/dist/react/hooks/use-theme-by-data-attribute.d.mts.map +1 -1
- package/dist/react/hooks/use-theme-by-data-attribute.mjs +1 -6
- package/dist/react/hooks/use-theme-by-data-attribute.mjs.map +1 -1
- package/dist/react/hooks/use-theme-by-local-storage.cjs +1 -5
- package/dist/react/hooks/use-theme-by-local-storage.cjs.map +1 -1
- package/dist/react/hooks/use-theme-by-local-storage.d.cts.map +1 -1
- package/dist/react/hooks/use-theme-by-local-storage.d.mts.map +1 -1
- package/dist/react/hooks/use-theme-by-local-storage.mjs +1 -5
- package/dist/react/hooks/use-theme-by-local-storage.mjs.map +1 -1
- package/dist/theme/_utils/match-attribute-value-to-theme.cjs +29 -0
- package/dist/theme/_utils/match-attribute-value-to-theme.cjs.map +1 -0
- package/dist/theme/_utils/match-attribute-value-to-theme.mjs +28 -0
- package/dist/theme/_utils/match-attribute-value-to-theme.mjs.map +1 -0
- package/dist/theme/_utils/parse-stored-theme.cjs +61 -7
- package/dist/theme/_utils/parse-stored-theme.cjs.map +1 -1
- package/dist/theme/_utils/parse-stored-theme.mjs +61 -7
- package/dist/theme/_utils/parse-stored-theme.mjs.map +1 -1
- package/dist/theme/_utils/resolve-theme-map-value.cjs +19 -0
- package/dist/theme/_utils/resolve-theme-map-value.cjs.map +1 -0
- package/dist/theme/_utils/resolve-theme-map-value.mjs +17 -0
- package/dist/theme/_utils/resolve-theme-map-value.mjs.map +1 -0
- package/dist/theme/class-name/parse-class-name.cjs +32 -0
- package/dist/theme/class-name/parse-class-name.cjs.map +1 -0
- package/dist/theme/class-name/parse-class-name.d.cts +20 -0
- package/dist/theme/class-name/parse-class-name.d.cts.map +1 -0
- package/dist/theme/class-name/parse-class-name.d.mts +20 -0
- package/dist/theme/class-name/parse-class-name.d.mts.map +1 -0
- package/dist/theme/class-name/parse-class-name.mjs +31 -0
- package/dist/theme/class-name/parse-class-name.mjs.map +1 -0
- package/dist/theme/class-name/read-class-name.cjs +20 -0
- package/dist/theme/class-name/read-class-name.cjs.map +1 -0
- package/dist/theme/class-name/read-class-name.d.cts +20 -0
- package/dist/theme/class-name/read-class-name.d.cts.map +1 -0
- package/dist/theme/class-name/read-class-name.d.mts +20 -0
- package/dist/theme/class-name/read-class-name.d.mts.map +1 -0
- package/dist/theme/class-name/read-class-name.mjs +20 -0
- package/dist/theme/class-name/read-class-name.mjs.map +1 -0
- package/dist/theme/class-name/stringify-class-name.cjs +31 -0
- package/dist/theme/class-name/stringify-class-name.cjs.map +1 -0
- package/dist/theme/class-name/stringify-class-name.d.cts +21 -0
- package/dist/theme/class-name/stringify-class-name.d.cts.map +1 -0
- package/dist/theme/class-name/stringify-class-name.d.mts +21 -0
- package/dist/theme/class-name/stringify-class-name.d.mts.map +1 -0
- package/dist/theme/class-name/stringify-class-name.mjs +31 -0
- package/dist/theme/class-name/stringify-class-name.mjs.map +1 -0
- package/dist/theme/class-name/subscribe-class-name.cjs +31 -0
- package/dist/theme/class-name/subscribe-class-name.cjs.map +1 -0
- package/dist/theme/class-name/subscribe-class-name.d.cts +21 -0
- package/dist/theme/class-name/subscribe-class-name.d.cts.map +1 -0
- package/dist/theme/class-name/subscribe-class-name.d.mts +21 -0
- package/dist/theme/class-name/subscribe-class-name.d.mts.map +1 -0
- package/dist/theme/class-name/subscribe-class-name.mjs +31 -0
- package/dist/theme/class-name/subscribe-class-name.mjs.map +1 -0
- package/dist/theme/class-name/write-class-name.cjs +20 -0
- package/dist/theme/class-name/write-class-name.cjs.map +1 -0
- package/dist/theme/class-name/write-class-name.d.cts +20 -0
- package/dist/theme/class-name/write-class-name.d.cts.map +1 -0
- package/dist/theme/class-name/write-class-name.d.mts +20 -0
- package/dist/theme/class-name/write-class-name.d.mts.map +1 -0
- package/dist/theme/class-name/write-class-name.mjs +20 -0
- package/dist/theme/class-name/write-class-name.mjs.map +1 -0
- package/dist/theme/cookie/_cookie-utils.cjs +37 -0
- package/dist/theme/cookie/_cookie-utils.cjs.map +1 -0
- package/dist/theme/cookie/_cookie-utils.mjs +33 -0
- package/dist/theme/cookie/_cookie-utils.mjs.map +1 -0
- package/dist/theme/cookie/read-cookie-theme.cjs +22 -0
- package/dist/theme/cookie/read-cookie-theme.cjs.map +1 -0
- package/dist/theme/cookie/read-cookie-theme.d.cts +22 -0
- package/dist/theme/cookie/read-cookie-theme.d.cts.map +1 -0
- package/dist/theme/cookie/read-cookie-theme.d.mts +22 -0
- package/dist/theme/cookie/read-cookie-theme.d.mts.map +1 -0
- package/dist/theme/cookie/read-cookie-theme.mjs +22 -0
- package/dist/theme/cookie/read-cookie-theme.mjs.map +1 -0
- package/dist/theme/cookie/write-cookie-theme.cjs +29 -0
- package/dist/theme/cookie/write-cookie-theme.cjs.map +1 -0
- package/dist/theme/cookie/write-cookie-theme.d.cts +24 -0
- package/dist/theme/cookie/write-cookie-theme.d.cts.map +1 -0
- package/dist/theme/cookie/write-cookie-theme.d.mts +24 -0
- package/dist/theme/cookie/write-cookie-theme.d.mts.map +1 -0
- package/dist/theme/cookie/write-cookie-theme.mjs +29 -0
- package/dist/theme/cookie/write-cookie-theme.mjs.map +1 -0
- package/dist/theme/data-attribute/_constant.cjs +7 -0
- package/dist/theme/data-attribute/_constant.cjs.map +1 -0
- package/dist/theme/data-attribute/_constant.mjs +6 -0
- package/dist/theme/data-attribute/_constant.mjs.map +1 -0
- package/dist/theme/data-attribute/parse-data-attribute.cjs +24 -0
- package/dist/theme/data-attribute/parse-data-attribute.cjs.map +1 -0
- package/dist/theme/data-attribute/parse-data-attribute.d.cts +21 -0
- package/dist/theme/data-attribute/parse-data-attribute.d.cts.map +1 -0
- package/dist/theme/data-attribute/parse-data-attribute.d.mts +21 -0
- package/dist/theme/data-attribute/parse-data-attribute.d.mts.map +1 -0
- package/dist/theme/data-attribute/parse-data-attribute.mjs +24 -0
- package/dist/theme/data-attribute/parse-data-attribute.mjs.map +1 -0
- package/dist/theme/data-attribute/read-data-attribute.cjs +23 -0
- package/dist/theme/data-attribute/read-data-attribute.cjs.map +1 -0
- package/dist/theme/data-attribute/read-data-attribute.d.cts +21 -0
- package/dist/theme/data-attribute/read-data-attribute.d.cts.map +1 -0
- package/dist/theme/data-attribute/read-data-attribute.d.mts +21 -0
- package/dist/theme/data-attribute/read-data-attribute.d.mts.map +1 -0
- package/dist/theme/data-attribute/read-data-attribute.mjs +23 -0
- package/dist/theme/data-attribute/read-data-attribute.mjs.map +1 -0
- package/dist/theme/data-attribute/stringify-data-attribute.cjs +33 -0
- package/dist/theme/data-attribute/stringify-data-attribute.cjs.map +1 -0
- package/dist/theme/data-attribute/stringify-data-attribute.d.cts +23 -0
- package/dist/theme/data-attribute/stringify-data-attribute.d.cts.map +1 -0
- package/dist/theme/data-attribute/stringify-data-attribute.d.mts +23 -0
- package/dist/theme/data-attribute/stringify-data-attribute.d.mts.map +1 -0
- package/dist/theme/data-attribute/stringify-data-attribute.mjs +33 -0
- package/dist/theme/data-attribute/stringify-data-attribute.mjs.map +1 -0
- package/dist/theme/data-attribute/subscribe-data-attribute.cjs +28 -0
- package/dist/theme/data-attribute/subscribe-data-attribute.cjs.map +1 -0
- package/dist/theme/data-attribute/subscribe-data-attribute.d.cts +22 -0
- package/dist/theme/data-attribute/subscribe-data-attribute.d.cts.map +1 -0
- package/dist/theme/data-attribute/subscribe-data-attribute.d.mts +22 -0
- package/dist/theme/data-attribute/subscribe-data-attribute.d.mts.map +1 -0
- package/dist/theme/data-attribute/subscribe-data-attribute.mjs +28 -0
- package/dist/theme/data-attribute/subscribe-data-attribute.mjs.map +1 -0
- package/dist/theme/data-attribute/write-data-attribute.cjs +30 -0
- package/dist/theme/data-attribute/write-data-attribute.cjs.map +1 -0
- package/dist/theme/data-attribute/write-data-attribute.d.cts +21 -0
- package/dist/theme/data-attribute/write-data-attribute.d.cts.map +1 -0
- package/dist/theme/data-attribute/write-data-attribute.d.mts +21 -0
- package/dist/theme/data-attribute/write-data-attribute.d.mts.map +1 -0
- package/dist/theme/data-attribute/write-data-attribute.mjs +30 -0
- package/dist/theme/data-attribute/write-data-attribute.mjs.map +1 -0
- package/dist/theme/local-storage/read-local-storage.cjs +22 -0
- package/dist/theme/local-storage/read-local-storage.cjs.map +1 -0
- package/dist/theme/local-storage/read-local-storage.d.cts +19 -0
- package/dist/theme/local-storage/read-local-storage.d.cts.map +1 -0
- package/dist/theme/local-storage/read-local-storage.d.mts +19 -0
- package/dist/theme/local-storage/read-local-storage.d.mts.map +1 -0
- package/dist/theme/local-storage/read-local-storage.mjs +22 -0
- package/dist/theme/local-storage/read-local-storage.mjs.map +1 -0
- package/dist/theme/local-storage/write-local-storage.cjs +26 -0
- package/dist/theme/local-storage/write-local-storage.cjs.map +1 -0
- package/dist/theme/local-storage/write-local-storage.d.cts +23 -0
- package/dist/theme/local-storage/write-local-storage.d.cts.map +1 -0
- package/dist/theme/local-storage/write-local-storage.d.mts +23 -0
- package/dist/theme/local-storage/write-local-storage.d.mts.map +1 -0
- package/dist/theme/local-storage/write-local-storage.mjs +26 -0
- package/dist/theme/local-storage/write-local-storage.mjs.map +1 -0
- package/dist/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.cjs +20 -0
- package/dist/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.cjs.map +1 -0
- package/dist/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.d.cts +23 -0
- package/dist/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.d.cts.map +1 -0
- package/dist/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.d.mts +23 -0
- package/dist/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.d.mts.map +1 -0
- package/dist/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.mjs +20 -0
- package/dist/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.mjs.map +1 -0
- package/dist/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.cjs +20 -0
- package/dist/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.cjs.map +1 -0
- package/dist/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.d.cts +20 -0
- package/dist/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.d.cts.map +1 -0
- package/dist/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.d.mts +20 -0
- package/dist/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.d.mts.map +1 -0
- package/dist/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.mjs +20 -0
- package/dist/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.mjs.map +1 -0
- package/dist/theme/session-storage/read-session-storage.cjs +22 -0
- package/dist/theme/session-storage/read-session-storage.cjs.map +1 -0
- package/dist/theme/session-storage/read-session-storage.d.cts +19 -0
- package/dist/theme/session-storage/read-session-storage.d.cts.map +1 -0
- package/dist/theme/session-storage/read-session-storage.d.mts +19 -0
- package/dist/theme/session-storage/read-session-storage.d.mts.map +1 -0
- package/dist/theme/session-storage/read-session-storage.mjs +22 -0
- package/dist/theme/session-storage/read-session-storage.mjs.map +1 -0
- package/dist/theme/session-storage/write-session-storage.cjs +26 -0
- package/dist/theme/session-storage/write-session-storage.cjs.map +1 -0
- package/dist/theme/session-storage/write-session-storage.d.cts +23 -0
- package/dist/theme/session-storage/write-session-storage.d.cts.map +1 -0
- package/dist/theme/session-storage/write-session-storage.d.mts +23 -0
- package/dist/theme/session-storage/write-session-storage.d.mts.map +1 -0
- package/dist/theme/session-storage/write-session-storage.mjs +26 -0
- package/dist/theme/session-storage/write-session-storage.mjs.map +1 -0
- package/dist/theme/theme-entry.types.d.cts +11 -1
- package/dist/theme/theme-entry.types.d.cts.map +1 -1
- package/dist/theme/theme-entry.types.d.mts +11 -1
- package/dist/theme/theme-entry.types.d.mts.map +1 -1
- package/dist/theme/theme-map.types.d.cts +11 -3
- package/dist/theme/theme-map.types.d.cts.map +1 -1
- package/dist/theme/theme-map.types.d.mts +11 -3
- package/dist/theme/theme-map.types.d.mts.map +1 -1
- package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.cjs +21 -18
- package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.cjs.map +1 -1
- package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.cts +5 -0
- package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.cts.map +1 -1
- package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.mts +5 -0
- package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.d.mts.map +1 -1
- package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.mjs +21 -18
- package/dist/theme/theme-store/class-name-theme-store/class-name-theme-store.mjs.map +1 -1
- package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.cjs +18 -36
- package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.cjs.map +1 -1
- package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.d.cts +5 -3
- package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.d.cts.map +1 -1
- package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.d.mts +5 -3
- package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.d.mts.map +1 -1
- package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.mjs +18 -36
- package/dist/theme/theme-store/cookie-theme-store/cookie-theme-store.mjs.map +1 -1
- package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.cjs +39 -19
- package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.cjs.map +1 -1
- package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.cts +28 -5
- package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.cts.map +1 -1
- package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.mts +28 -5
- package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.d.mts.map +1 -1
- package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.mjs +39 -19
- package/dist/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.mjs.map +1 -1
- package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.cjs +13 -12
- package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.cjs.map +1 -1
- package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.cts +7 -1
- package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.cts.map +1 -1
- package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.mts +7 -1
- package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.d.mts.map +1 -1
- package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.mjs +13 -12
- package/dist/theme/theme-store/local-storage-theme-store/local-storage-theme-store.mjs.map +1 -1
- package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.cjs +4 -5
- package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.cjs.map +1 -1
- package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.d.cts.map +1 -1
- package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.d.mts.map +1 -1
- package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.mjs +4 -5
- package/dist/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.mjs.map +1 -1
- package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.cjs +13 -12
- package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.cjs.map +1 -1
- package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.cts +7 -1
- package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.cts.map +1 -1
- package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.mts +7 -1
- package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.d.mts.map +1 -1
- package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.mjs +13 -12
- package/dist/theme/theme-store/session-storage-theme-store/session-storage-theme-store.mjs.map +1 -1
- package/dist/theme/web-storage/read-web-storage.cjs +20 -0
- package/dist/theme/web-storage/read-web-storage.cjs.map +1 -0
- package/dist/theme/web-storage/read-web-storage.d.cts +21 -0
- package/dist/theme/web-storage/read-web-storage.d.cts.map +1 -0
- package/dist/theme/web-storage/read-web-storage.d.mts +21 -0
- package/dist/theme/web-storage/read-web-storage.d.mts.map +1 -0
- package/dist/theme/web-storage/read-web-storage.mjs +20 -0
- package/dist/theme/web-storage/read-web-storage.mjs.map +1 -0
- package/dist/theme/web-storage/write-web-storage.cjs +33 -0
- package/dist/theme/web-storage/write-web-storage.cjs.map +1 -0
- package/dist/theme/web-storage/write-web-storage.d.cts +25 -0
- package/dist/theme/web-storage/write-web-storage.d.cts.map +1 -0
- package/dist/theme/web-storage/write-web-storage.d.mts +25 -0
- package/dist/theme/web-storage/write-web-storage.d.mts.map +1 -0
- package/dist/theme/web-storage/write-web-storage.mjs +32 -0
- package/dist/theme/web-storage/write-web-storage.mjs.map +1 -0
- package/dist/theme.cjs +41 -1
- package/dist/theme.d.cts +23 -3
- package/dist/theme.d.mts +23 -3
- package/dist/theme.mjs +21 -1
- package/package.json +1 -1
- package/src/react/hooks/use-theme-by-class-name.ts +3 -8
- package/src/react/hooks/use-theme-by-data-attribute.ts +3 -10
- package/src/react/hooks/use-theme-by-local-storage.ts +3 -9
- package/src/testing/theme/theme-result-card.tsx +1 -0
- package/src/theme/_utils/match-attribute-value-to-theme.ts +36 -0
- package/src/theme/_utils/parse-stored-theme.ts +52 -12
- package/src/theme/_utils/resolve-theme-map-value.ts +15 -0
- package/src/theme/class-name/parse-class-name.ts +31 -0
- package/src/theme/class-name/read-class-name.ts +24 -0
- package/src/theme/class-name/stringify-class-name.ts +36 -0
- package/src/theme/class-name/subscribe-class-name.ts +39 -0
- package/src/theme/class-name/write-class-name.ts +24 -0
- package/src/theme/cookie/_cookie-utils.ts +45 -0
- package/src/theme/cookie/read-cookie-theme.ts +33 -0
- package/src/theme/cookie/write-cookie-theme.ts +48 -0
- package/src/theme/data-attribute/_constant.ts +1 -0
- package/src/theme/data-attribute/parse-data-attribute.ts +25 -0
- package/src/theme/data-attribute/read-data-attribute.ts +29 -0
- package/src/theme/data-attribute/stringify-data-attribute.ts +39 -0
- package/src/theme/data-attribute/subscribe-data-attribute.ts +39 -0
- package/src/theme/data-attribute/write-data-attribute.ts +40 -0
- package/src/theme/local-storage/read-local-storage.ts +23 -0
- package/src/theme/local-storage/write-local-storage.ts +31 -0
- package/src/theme/prefers-color-scheme-theme/read-prefers-color-scheme-theme.ts +30 -0
- package/src/theme/prefers-color-scheme-theme/subscribe-prefers-color-scheme-theme.ts +24 -0
- package/src/theme/session-storage/read-session-storage.ts +23 -0
- package/src/theme/session-storage/write-session-storage.ts +31 -0
- package/src/theme/theme-entry.types.ts +19 -0
- package/src/theme/theme-map.types.ts +9 -2
- package/src/theme/theme-store/class-name-theme-store/class-name-theme-store.ts +19 -25
- package/src/theme/theme-store/cookie-theme-store/cookie-theme-store.ts +18 -63
- package/src/theme/theme-store/data-attribute-theme-store/data-attribute-theme-store.ts +41 -28
- package/src/theme/theme-store/local-storage-theme-store/local-storage-theme-store.ts +17 -20
- package/src/theme/theme-store/prefers-color-scheme-theme-store/prefers-color-scheme-theme-store.ts +4 -5
- package/src/theme/theme-store/session-storage-theme-store/session-storage-theme-store.ts +17 -20
- package/src/theme/web-storage/read-web-storage.ts +22 -0
- package/src/theme/web-storage/write-web-storage.ts +46 -0
- package/src/theme.ts +20 -0
- package/dist/theme/class-name/apply-theme-to-class-name.cjs +0 -23
- package/dist/theme/class-name/apply-theme-to-class-name.cjs.map +0 -1
- package/dist/theme/class-name/apply-theme-to-class-name.mjs +0 -22
- package/dist/theme/class-name/apply-theme-to-class-name.mjs.map +0 -1
- package/dist/theme/class-name/resolve-theme-from-class-name.cjs +0 -23
- package/dist/theme/class-name/resolve-theme-from-class-name.cjs.map +0 -1
- package/dist/theme/class-name/resolve-theme-from-class-name.mjs +0 -22
- package/dist/theme/class-name/resolve-theme-from-class-name.mjs.map +0 -1
- package/dist/theme/data-attribute/apply-theme-to-data-attribute.cjs +0 -23
- package/dist/theme/data-attribute/apply-theme-to-data-attribute.cjs.map +0 -1
- package/dist/theme/data-attribute/apply-theme-to-data-attribute.mjs +0 -22
- package/dist/theme/data-attribute/apply-theme-to-data-attribute.mjs.map +0 -1
- package/dist/theme/data-attribute/resolve-theme-from-data-attribute.cjs +0 -23
- package/dist/theme/data-attribute/resolve-theme-from-data-attribute.cjs.map +0 -1
- package/dist/theme/data-attribute/resolve-theme-from-data-attribute.mjs +0 -22
- package/dist/theme/data-attribute/resolve-theme-from-data-attribute.mjs.map +0 -1
- package/src/theme/class-name/apply-theme-to-class-name.ts +0 -26
- package/src/theme/class-name/resolve-theme-from-class-name.ts +0 -22
- package/src/theme/data-attribute/apply-theme-to-data-attribute.ts +0 -27
- package/src/theme/data-attribute/resolve-theme-from-data-attribute.ts +0 -23
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { matchAttributeValueToTheme } from '../_utils/match-attribute-value-to-theme.ts'
|
|
2
|
+
import { themeEntry } from '../theme-entry.ts'
|
|
3
|
+
import type { ThemeEntry } from '../theme-entry.types.ts'
|
|
4
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
5
|
+
import { SEPARATOR_SPACE } from './_constant.ts'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Parses a data attribute value string into a ThemeEntry.
|
|
9
|
+
*
|
|
10
|
+
* Pure function: no DOM access. Uses first token when separator is defined.
|
|
11
|
+
*
|
|
12
|
+
* @param themes - Record mapping theme keys to attribute values
|
|
13
|
+
* @param value - Raw attribute value string (e.g. from getAttribute)
|
|
14
|
+
* @param options.separator - When defined, split by separator and use first token (default: space)
|
|
15
|
+
* @returns ThemeEntry if a match is found, otherwise undefined
|
|
16
|
+
*/
|
|
17
|
+
export function parseDataAttribute<Themes extends ThemeMap>(
|
|
18
|
+
themes: Themes,
|
|
19
|
+
value: string | undefined,
|
|
20
|
+
options?: { separator?: string | undefined } | undefined
|
|
21
|
+
): ThemeEntry<Themes> | undefined {
|
|
22
|
+
const separator = options?.separator ?? SEPARATOR_SPACE
|
|
23
|
+
const theme = matchAttributeValueToTheme(themes, value ?? null, { separator })
|
|
24
|
+
return theme !== undefined ? themeEntry(themes, theme) : undefined
|
|
25
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { getDataAttribute } from '../../attributes/get-data-attribute.ts'
|
|
2
|
+
import type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'
|
|
3
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
4
|
+
import { SEPARATOR_SPACE } from './_constant.ts'
|
|
5
|
+
import { parseDataAttribute } from './parse-data-attribute.ts'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Reads a theme entry from a data attribute on an element.
|
|
9
|
+
*
|
|
10
|
+
* @param themes - Record mapping theme keys to attribute values
|
|
11
|
+
* @param attributeName - Data attribute name (e.g. `data-theme`)
|
|
12
|
+
* @param options.element - Element to read from (defaults to document.documentElement)
|
|
13
|
+
* @param options.parse - Custom parser (default: parseDataAttribute with space separator)
|
|
14
|
+
* @returns ThemeEntry if found, undefined otherwise. Returns undefined when element is not available (e.g. SSR).
|
|
15
|
+
*/
|
|
16
|
+
export function readDataAttribute<Themes extends ThemeMap>(
|
|
17
|
+
themes: Themes,
|
|
18
|
+
attributeName: `data-${string}`,
|
|
19
|
+
options?:
|
|
20
|
+
| { element?: Element | undefined; parse?: ParseStoredTheme<Themes> | undefined }
|
|
21
|
+
| undefined
|
|
22
|
+
): ThemeEntry<Themes> | undefined {
|
|
23
|
+
const element = options?.element ?? document?.documentElement
|
|
24
|
+
if (!element) return undefined
|
|
25
|
+
const parse =
|
|
26
|
+
options?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }))
|
|
27
|
+
const raw = getDataAttribute(attributeName, element) ?? undefined
|
|
28
|
+
return parse(themes, raw)
|
|
29
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { resolveThemeMapValue } from '../_utils/resolve-theme-map-value.ts'
|
|
2
|
+
import type { ThemeEntry } from '../theme-entry.types.ts'
|
|
3
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
4
|
+
import { SEPARATOR_SPACE } from './_constant.ts'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Stringifies a ThemeEntry for a data attribute value.
|
|
8
|
+
*
|
|
9
|
+
* Pure function: no DOM access. Removes all theme values from existing, then adds entry's value(s).
|
|
10
|
+
* Aligns with stringifyClassName logic.
|
|
11
|
+
*
|
|
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)
|
|
15
|
+
* @param options.separator - Token separator (default: space)
|
|
16
|
+
* @returns Attribute value string
|
|
17
|
+
*/
|
|
18
|
+
export function stringifyDataAttribute<Themes extends ThemeMap>(
|
|
19
|
+
themes: Themes,
|
|
20
|
+
existing: string | undefined,
|
|
21
|
+
entry: ThemeEntry<Themes> | undefined,
|
|
22
|
+
options?: { separator?: string | undefined } | undefined
|
|
23
|
+
): string {
|
|
24
|
+
const separator = options?.separator ?? SEPARATOR_SPACE
|
|
25
|
+
const allThemeValues = Object.values(themes).flatMap((v) => {
|
|
26
|
+
const resolved = resolveThemeMapValue(v)
|
|
27
|
+
return Array.isArray(resolved) ? [...resolved] : [resolved]
|
|
28
|
+
})
|
|
29
|
+
const existingTokens = existing?.trim() ? existing.trim().split(separator) : []
|
|
30
|
+
const withoutThemeValues = existingTokens.filter((t) => !allThemeValues.includes(t.trim()))
|
|
31
|
+
const newTokens =
|
|
32
|
+
entry !== undefined
|
|
33
|
+
? (() => {
|
|
34
|
+
const resolved = resolveThemeMapValue(entry.value)
|
|
35
|
+
return Array.isArray(resolved) ? [resolved[0]] : [resolved]
|
|
36
|
+
})()
|
|
37
|
+
: []
|
|
38
|
+
return [...withoutThemeValues, ...newTokens].filter(Boolean).join(separator)
|
|
39
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { observeDataAttributes } from '../../attributes/observe-data-attribute.ts'
|
|
2
|
+
import type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'
|
|
3
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
4
|
+
import { SEPARATOR_SPACE } from './_constant.ts'
|
|
5
|
+
import { parseDataAttribute } from './parse-data-attribute.ts'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Subscribes to changes on a data attribute and invokes the handler with parsed theme entries.
|
|
9
|
+
*
|
|
10
|
+
* @param themes - Record mapping theme keys to attribute values
|
|
11
|
+
* @param attributeName - Data attribute name (e.g. `data-theme`)
|
|
12
|
+
* @param handler - Callback invoked when the attribute changes
|
|
13
|
+
* @param options.element - Element to observe (defaults to document.documentElement)
|
|
14
|
+
* @param options.parse - Custom parser (default: parseDataAttribute with space separator)
|
|
15
|
+
* @returns Unsubscribe function. Returns a no-op function when element is not available (e.g. SSR).
|
|
16
|
+
*/
|
|
17
|
+
export function subscribeDataAttribute<Themes extends ThemeMap>(
|
|
18
|
+
themes: Themes,
|
|
19
|
+
attributeName: `data-${string}`,
|
|
20
|
+
handler: (entry: ThemeEntry<Themes> | undefined) => void,
|
|
21
|
+
options?:
|
|
22
|
+
| { element?: Element | undefined; parse?: ParseStoredTheme<Themes> | undefined }
|
|
23
|
+
| undefined
|
|
24
|
+
): () => void {
|
|
25
|
+
const element = options?.element ?? document?.documentElement
|
|
26
|
+
if (!element) return () => {}
|
|
27
|
+
const parse =
|
|
28
|
+
options?.parse ?? ((t, v) => parseDataAttribute(t, v, { separator: SEPARATOR_SPACE }))
|
|
29
|
+
const observer = observeDataAttributes<string, `data-${string}`>(
|
|
30
|
+
{
|
|
31
|
+
[attributeName]: (value) => {
|
|
32
|
+
const entry = parse(themes, value ?? undefined)
|
|
33
|
+
handler(entry)
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
element
|
|
37
|
+
)
|
|
38
|
+
return () => observer.disconnect()
|
|
39
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getDataAttribute } from '../../attributes/get-data-attribute.ts'
|
|
2
|
+
import type { StringifyStoredTheme, ThemeEntry } from '../theme-entry.types.ts'
|
|
3
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
4
|
+
import { SEPARATOR_SPACE } from './_constant.ts'
|
|
5
|
+
import { stringifyDataAttribute } from './stringify-data-attribute.ts'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Writes a theme entry to a data attribute on an element.
|
|
9
|
+
*
|
|
10
|
+
* @param themes - Record mapping theme keys to attribute values
|
|
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)
|
|
14
|
+
* @param options.stringify - Custom serializer (default: stringifyDataAttribute with space separator)
|
|
15
|
+
*/
|
|
16
|
+
export function writeDataAttribute<Themes extends ThemeMap>(
|
|
17
|
+
themes: Themes,
|
|
18
|
+
attributeName: `data-${string}`,
|
|
19
|
+
entry: ThemeEntry<Themes> | undefined,
|
|
20
|
+
options?:
|
|
21
|
+
| { element?: Element | undefined; stringify?: StringifyStoredTheme<Themes> | undefined }
|
|
22
|
+
| undefined
|
|
23
|
+
): void {
|
|
24
|
+
const element = options?.element ?? document?.documentElement
|
|
25
|
+
if (!element) return
|
|
26
|
+
const stringify =
|
|
27
|
+
options?.stringify ??
|
|
28
|
+
((t, x, e) => stringifyDataAttribute(t, x, e, { separator: SEPARATOR_SPACE }))
|
|
29
|
+
if (entry === undefined) {
|
|
30
|
+
element.removeAttribute(attributeName)
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
const existing = getDataAttribute(attributeName, element) ?? undefined
|
|
34
|
+
const result = stringify(themes, existing, entry)
|
|
35
|
+
if (result === '') {
|
|
36
|
+
element.removeAttribute(attributeName)
|
|
37
|
+
} else {
|
|
38
|
+
element.setAttribute(attributeName, result)
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'
|
|
2
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
3
|
+
import { readWebStorage } from '../web-storage/read-web-storage.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Reads a theme entry from localStorage.
|
|
7
|
+
*
|
|
8
|
+
* @param themes - Record mapping theme keys to values (for validation)
|
|
9
|
+
* @param storageKey - localStorage key to read from
|
|
10
|
+
* @param options.parse - Custom parser (default: parseStoredTheme)
|
|
11
|
+
* @returns ThemeEntry if found, undefined otherwise. Returns undefined when localStorage is unavailable (e.g. SSR).
|
|
12
|
+
*/
|
|
13
|
+
export function readLocalStorage<Themes extends ThemeMap>(
|
|
14
|
+
themes: Themes,
|
|
15
|
+
storageKey: string,
|
|
16
|
+
options?: { parse?: ParseStoredTheme<Themes> | undefined }
|
|
17
|
+
): ThemeEntry<Themes> | undefined {
|
|
18
|
+
if (!window?.localStorage) return undefined
|
|
19
|
+
return readWebStorage(themes, storageKey, {
|
|
20
|
+
storage: window.localStorage,
|
|
21
|
+
parse: options?.parse
|
|
22
|
+
})
|
|
23
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { StringifyStoredTheme, ThemeEntry } from '../theme-entry.types.ts'
|
|
2
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
3
|
+
import { writeWebStorage } from '../web-storage/write-web-storage.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Writes a theme entry to localStorage.
|
|
7
|
+
*
|
|
8
|
+
* Performs setItem/removeItem only. Does not notify subscribers; the store must call notify() after this.
|
|
9
|
+
*
|
|
10
|
+
* @param themes - Record mapping theme keys to values (used by stringify)
|
|
11
|
+
* @param storageKey - localStorage key to write to
|
|
12
|
+
* @param entry - Theme entry to write, or undefined to remove
|
|
13
|
+
* @param options.stringify - Custom serializer (default: JSON.stringify)
|
|
14
|
+
* @param options.onError - Optional callback invoked when storage write throws
|
|
15
|
+
*/
|
|
16
|
+
export function writeLocalStorage<Themes extends ThemeMap>(
|
|
17
|
+
themes: Themes,
|
|
18
|
+
storageKey: string,
|
|
19
|
+
entry: ThemeEntry<Themes> | undefined,
|
|
20
|
+
options?: {
|
|
21
|
+
stringify?: StringifyStoredTheme<Themes> | undefined
|
|
22
|
+
onError?: ((error: unknown) => void) | undefined
|
|
23
|
+
}
|
|
24
|
+
): void {
|
|
25
|
+
if (!window?.localStorage) return
|
|
26
|
+
writeWebStorage(themes, storageKey, entry, {
|
|
27
|
+
storage: window.localStorage,
|
|
28
|
+
stringify: options?.stringify,
|
|
29
|
+
onError: options?.onError
|
|
30
|
+
})
|
|
31
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { getPrefersColorScheme } from '../../color-scheme/get-prefers-color-scheme.ts'
|
|
2
|
+
import { themeEntry } from '../theme-entry.ts'
|
|
3
|
+
import type { ThemeEntry } from '../theme-entry.types.ts'
|
|
4
|
+
|
|
5
|
+
type PrefersColorSchemeThemes = {
|
|
6
|
+
light: string | readonly string[]
|
|
7
|
+
dark: string | readonly string[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface ReadPrefersColorSchemeThemeOptions {
|
|
11
|
+
defaultColorScheme?: 'light' | 'dark' | undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Reads a theme entry from the system `prefers-color-scheme` media query.
|
|
16
|
+
*
|
|
17
|
+
* Themes must only include `light` and `dark` keys—this mirrors the system preference.
|
|
18
|
+
*
|
|
19
|
+
* @param themes - Record with `light` and `dark` keys mapping to theme values
|
|
20
|
+
* @param options.defaultColorScheme - Fallback when matchMedia is unavailable (e.g. SSR, default: 'light')
|
|
21
|
+
* @returns ThemeEntry for current system preference
|
|
22
|
+
*/
|
|
23
|
+
export function readPrefersColorSchemeTheme<Themes extends PrefersColorSchemeThemes>(
|
|
24
|
+
themes: Themes,
|
|
25
|
+
options?: ReadPrefersColorSchemeThemeOptions | undefined
|
|
26
|
+
): ThemeEntry<Themes> {
|
|
27
|
+
const defaultColorScheme = options?.defaultColorScheme ?? 'light'
|
|
28
|
+
const scheme = getPrefersColorScheme(defaultColorScheme)
|
|
29
|
+
return themeEntry(themes, scheme)
|
|
30
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { observePrefersColorScheme } from '../../color-scheme/observe-prefers-color-scheme.ts'
|
|
2
|
+
import { themeEntry } from '../theme-entry.ts'
|
|
3
|
+
import type { ThemeEntry } from '../theme-entry.types.ts'
|
|
4
|
+
|
|
5
|
+
type PrefersColorSchemeThemes = {
|
|
6
|
+
light: string | readonly string[]
|
|
7
|
+
dark: string | readonly string[]
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Subscribes to system `prefers-color-scheme` changes and invokes the handler with theme entries.
|
|
12
|
+
*
|
|
13
|
+
* Themes must only include `light` and `dark` keys—this mirrors the system preference.
|
|
14
|
+
*
|
|
15
|
+
* @param themes - Record with `light` and `dark` keys mapping to theme values
|
|
16
|
+
* @param handler - Callback invoked when the color scheme preference changes
|
|
17
|
+
* @returns Unsubscribe function
|
|
18
|
+
*/
|
|
19
|
+
export function subscribePrefersColorSchemeTheme<Themes extends PrefersColorSchemeThemes>(
|
|
20
|
+
themes: Themes,
|
|
21
|
+
handler: (entry: ThemeEntry<Themes>) => void
|
|
22
|
+
): () => void {
|
|
23
|
+
return observePrefersColorScheme((scheme) => handler(themeEntry(themes, scheme)))
|
|
24
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ParseStoredTheme, ThemeEntry } from '../theme-entry.types.ts'
|
|
2
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
3
|
+
import { readWebStorage } from '../web-storage/read-web-storage.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Reads a theme entry from sessionStorage.
|
|
7
|
+
*
|
|
8
|
+
* @param themes - Record mapping theme keys to values (for validation)
|
|
9
|
+
* @param storageKey - sessionStorage key to read from
|
|
10
|
+
* @param options.parse - Custom parser (default: parseStoredTheme)
|
|
11
|
+
* @returns ThemeEntry if found, undefined otherwise. Returns undefined when sessionStorage is unavailable (e.g. SSR).
|
|
12
|
+
*/
|
|
13
|
+
export function readSessionStorage<Themes extends ThemeMap>(
|
|
14
|
+
themes: Themes,
|
|
15
|
+
storageKey: string,
|
|
16
|
+
options?: { parse?: ParseStoredTheme<Themes> | undefined }
|
|
17
|
+
): ThemeEntry<Themes> | undefined {
|
|
18
|
+
if (!window?.sessionStorage) return undefined
|
|
19
|
+
return readWebStorage(themes, storageKey, {
|
|
20
|
+
storage: window.sessionStorage,
|
|
21
|
+
parse: options?.parse
|
|
22
|
+
})
|
|
23
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { StringifyStoredTheme, ThemeEntry } from '../theme-entry.types.ts'
|
|
2
|
+
import type { ThemeMap } from '../theme-map.types.ts'
|
|
3
|
+
import { writeWebStorage } from '../web-storage/write-web-storage.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Writes a theme entry to sessionStorage.
|
|
7
|
+
*
|
|
8
|
+
* Performs setItem/removeItem only. Does not notify subscribers; the store must call notify() after this.
|
|
9
|
+
*
|
|
10
|
+
* @param themes - Record mapping theme keys to values (used by stringify)
|
|
11
|
+
* @param storageKey - sessionStorage key to write to
|
|
12
|
+
* @param entry - Theme entry to write, or undefined to remove
|
|
13
|
+
* @param options.stringify - Custom serializer (default: JSON.stringify)
|
|
14
|
+
* @param options.onError - Optional callback invoked when storage write throws
|
|
15
|
+
*/
|
|
16
|
+
export function writeSessionStorage<Themes extends ThemeMap>(
|
|
17
|
+
themes: Themes,
|
|
18
|
+
storageKey: string,
|
|
19
|
+
entry: ThemeEntry<Themes> | undefined,
|
|
20
|
+
options?: {
|
|
21
|
+
stringify?: StringifyStoredTheme<Themes> | undefined
|
|
22
|
+
onError?: ((error: unknown) => void) | undefined
|
|
23
|
+
}
|
|
24
|
+
): void {
|
|
25
|
+
if (!window?.sessionStorage) return
|
|
26
|
+
writeWebStorage(themes, storageKey, entry, {
|
|
27
|
+
storage: window.sessionStorage,
|
|
28
|
+
stringify: options?.stringify,
|
|
29
|
+
onError: options?.onError
|
|
30
|
+
})
|
|
31
|
+
}
|
|
@@ -9,3 +9,22 @@ export interface ThemeEntry<Themes extends ThemeMap = ThemeMap> {
|
|
|
9
9
|
theme: keyof Themes
|
|
10
10
|
value: Themes[keyof Themes]
|
|
11
11
|
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Function type for parsing stored string into ThemeEntry.
|
|
15
|
+
* Used as options.parse in persisting theme stores.
|
|
16
|
+
*/
|
|
17
|
+
export type ParseStoredTheme<Themes extends ThemeMap> = (
|
|
18
|
+
themes: Themes,
|
|
19
|
+
value: string | undefined
|
|
20
|
+
) => ThemeEntry<Themes> | undefined
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Function type for stringify ThemeEntry to a stored string.
|
|
24
|
+
* Used as options.stringify in persisting theme stores.
|
|
25
|
+
*/
|
|
26
|
+
export type StringifyStoredTheme<Themes extends ThemeMap> = (
|
|
27
|
+
themes: Themes,
|
|
28
|
+
existing: string | undefined,
|
|
29
|
+
entry: ThemeEntry<Themes> | undefined
|
|
30
|
+
) => string
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polymorphic theme value: string, array, or object with themeValue.
|
|
3
|
+
* The object form allows storing extra user metadata in persistent stores (localStorage, etc.).
|
|
4
|
+
*/
|
|
5
|
+
export type ThemeMapValue = string | readonly string[] | { themeValue: string | readonly string[] }
|
|
6
|
+
|
|
1
7
|
/**
|
|
2
8
|
* Record mapping theme keys to their values.
|
|
3
|
-
* Each value can be a single string
|
|
9
|
+
* Each value can be a single string, readonly string[] (e.g. multiple CSS classes),
|
|
10
|
+
* or { themeValue: string | string[] } for polymorphic values with extra metadata.
|
|
4
11
|
* Used by all ThemeStore factories via the themes option.
|
|
5
12
|
*/
|
|
6
|
-
export type ThemeMap<Theme extends string = string> = Record<Theme,
|
|
13
|
+
export type ThemeMap<Theme extends string = string> = Record<Theme, ThemeMapValue>
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import type { Required } from 'type-plus'
|
|
2
|
-
import { observeAttributes } from '../../../attributes/observe-attribute.ts'
|
|
3
2
|
import { dummyThemeStore } from '../../../testing/theme/dummy-theme-store.ts'
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { parseClassName } from '../../class-name/parse-class-name.ts'
|
|
4
|
+
import { readClassName } from '../../class-name/read-class-name.ts'
|
|
5
|
+
import { stringifyClassName } from '../../class-name/stringify-class-name.ts'
|
|
6
|
+
import { subscribeClassName } from '../../class-name/subscribe-class-name.ts'
|
|
7
|
+
import { writeClassName } from '../../class-name/write-class-name.ts'
|
|
8
|
+
import type { ParseStoredTheme, StringifyStoredTheme } from '../../theme-entry.types.ts'
|
|
7
9
|
import type { ThemeMap } from '../../theme-map.types.ts'
|
|
8
10
|
import type { ThemeStore } from '../theme-store.types.ts'
|
|
9
11
|
|
|
@@ -12,6 +14,8 @@ import type { ThemeStore } from '../theme-store.types.ts'
|
|
|
12
14
|
*
|
|
13
15
|
* @param themes - Record mapping theme keys to class name(s)
|
|
14
16
|
* @param options.element - Element to operate on (defaults to document.documentElement)
|
|
17
|
+
* @param options.parse - Custom parser (default: parseClassName)
|
|
18
|
+
* @param options.stringify - Custom serializer (default: stringifyClassName)
|
|
15
19
|
* @returns ThemeStore
|
|
16
20
|
*
|
|
17
21
|
* @example
|
|
@@ -25,38 +29,28 @@ import type { ThemeStore } from '../theme-store.types.ts'
|
|
|
25
29
|
*/
|
|
26
30
|
export function classNameThemeStore<Themes extends ThemeMap>(
|
|
27
31
|
themes: Themes,
|
|
28
|
-
options?: {
|
|
32
|
+
options?: {
|
|
33
|
+
element?: Element | undefined
|
|
34
|
+
parse?: ParseStoredTheme<Themes> | undefined
|
|
35
|
+
stringify?: StringifyStoredTheme<Themes> | undefined
|
|
36
|
+
}
|
|
29
37
|
): Required<ThemeStore<Themes>> {
|
|
30
38
|
const element = options?.element ?? document?.documentElement
|
|
31
39
|
|
|
32
40
|
if (!element) return dummyThemeStore
|
|
33
41
|
|
|
42
|
+
const parse = options?.parse ?? parseClassName
|
|
43
|
+
const stringify = options?.stringify ?? stringifyClassName
|
|
44
|
+
|
|
34
45
|
return {
|
|
35
46
|
read() {
|
|
36
|
-
|
|
37
|
-
if (theme === undefined) return undefined
|
|
38
|
-
return themeEntry(themes, theme)
|
|
47
|
+
return readClassName(themes, { element, parse })
|
|
39
48
|
},
|
|
40
49
|
write(entry) {
|
|
41
|
-
|
|
50
|
+
writeClassName(themes, entry, { element, stringify })
|
|
42
51
|
},
|
|
43
52
|
subscribe(handler) {
|
|
44
|
-
|
|
45
|
-
const observer = observeAttributes(
|
|
46
|
-
{
|
|
47
|
-
class: (value) => {
|
|
48
|
-
const theme = value ? resolveThemeFromClassName(themes, value) : undefined
|
|
49
|
-
const entry = theme ? themeEntry(themes, theme) : undefined
|
|
50
|
-
const key = theme ?? undefined
|
|
51
|
-
|
|
52
|
-
if (lastEmitted === key) return
|
|
53
|
-
lastEmitted = key
|
|
54
|
-
handler(entry)
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
element
|
|
58
|
-
)
|
|
59
|
-
return () => observer.disconnect()
|
|
53
|
+
return subscribeClassName(themes, handler, { element, parse })
|
|
60
54
|
}
|
|
61
55
|
}
|
|
62
56
|
}
|
|
@@ -1,48 +1,20 @@
|
|
|
1
1
|
import type { Required } from 'type-plus'
|
|
2
2
|
import { dummyThemeStore } from '../../../testing/theme/dummy-theme-store.ts'
|
|
3
3
|
import { parseStoredTheme } from '../../_utils/parse-stored-theme.ts'
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
4
|
+
import { getCookieFromHeader } from '../../cookie/_cookie-utils.ts'
|
|
5
|
+
import { readCookieTheme } from '../../cookie/read-cookie-theme.ts'
|
|
6
|
+
import { writeCookieTheme } from '../../cookie/write-cookie-theme.ts'
|
|
7
|
+
import type { ParseStoredTheme, ThemeEntry } from '../../theme-entry.types.ts'
|
|
6
8
|
import type { ThemeMap } from '../../theme-map.types.ts'
|
|
7
9
|
import type { ThemeStore } from '../theme-store.types.ts'
|
|
8
10
|
|
|
9
|
-
export interface CookieThemeStoreOptions {
|
|
11
|
+
export interface CookieThemeStoreOptions<Themes extends ThemeMap = ThemeMap> {
|
|
10
12
|
cookieName: string
|
|
11
13
|
path?: string | undefined
|
|
12
14
|
maxAge?: number | undefined
|
|
13
15
|
sameSite?: 'lax' | 'strict' | 'none' | undefined
|
|
14
16
|
secure?: boolean | undefined
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
function getCookieValue(name: string): string | null {
|
|
18
|
-
if (typeof document === 'undefined' || !document.cookie) return null
|
|
19
|
-
const match = document.cookie.match(new RegExp(`(?:^|;\\s*)${name}=([^;]*)`))
|
|
20
|
-
const value = match?.[1]
|
|
21
|
-
return value !== undefined ? decodeURIComponent(value) : null
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
function setCookie(
|
|
25
|
-
name: string,
|
|
26
|
-
value: string,
|
|
27
|
-
options: {
|
|
28
|
-
path?: string | undefined
|
|
29
|
-
maxAge?: number | undefined
|
|
30
|
-
sameSite?: 'lax' | 'strict' | 'none' | undefined
|
|
31
|
-
secure?: boolean | undefined
|
|
32
|
-
}
|
|
33
|
-
) {
|
|
34
|
-
const parts = [`${name}=${encodeURIComponent(value)}`]
|
|
35
|
-
parts.push(`path=${options.path ?? '/'}`)
|
|
36
|
-
if (options.maxAge !== undefined) parts.push(`max-age=${options.maxAge}`)
|
|
37
|
-
if (options.sameSite !== undefined) parts.push(`samesite=${options.sameSite}`)
|
|
38
|
-
if (options.secure) parts.push('secure')
|
|
39
|
-
// biome-ignore lint/suspicious/noDocumentCookie: Cookie Store API has limited support; document.cookie is standard for theme persistence
|
|
40
|
-
document.cookie = parts.join('; ')
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function deleteCookie(name: string, path = '/') {
|
|
44
|
-
// biome-ignore lint/suspicious/noDocumentCookie: Cookie Store API has limited support; document.cookie is standard for theme persistence
|
|
45
|
-
document.cookie = `${name}=; path=${path}; max-age=0`
|
|
17
|
+
parse?: ParseStoredTheme<Themes> | undefined
|
|
46
18
|
}
|
|
47
19
|
|
|
48
20
|
/**
|
|
@@ -58,6 +30,7 @@ function deleteCookie(name: string, path = '/') {
|
|
|
58
30
|
* @param options.maxAge - Cookie max-age in seconds
|
|
59
31
|
* @param options.sameSite - Cookie sameSite attribute
|
|
60
32
|
* @param options.secure - Cookie secure attribute
|
|
33
|
+
* @param options.parse - Optional custom parser for stored string (default: parseStoredTheme)
|
|
61
34
|
* @returns ThemeStore
|
|
62
35
|
*
|
|
63
36
|
* @example
|
|
@@ -71,9 +44,9 @@ function deleteCookie(name: string, path = '/') {
|
|
|
71
44
|
*/
|
|
72
45
|
export function cookieThemeStore<Themes extends ThemeMap>(
|
|
73
46
|
themes: Themes,
|
|
74
|
-
options: CookieThemeStoreOptions
|
|
47
|
+
options: CookieThemeStoreOptions<Themes>
|
|
75
48
|
): Required<ThemeStore<Themes>> {
|
|
76
|
-
const { cookieName, path = '/', maxAge, sameSite, secure } = options
|
|
49
|
+
const { cookieName, path = '/', maxAge, sameSite, secure, parse = parseStoredTheme } = options
|
|
77
50
|
|
|
78
51
|
if (document.cookie === undefined) {
|
|
79
52
|
return dummyThemeStore
|
|
@@ -83,10 +56,7 @@ export function cookieThemeStore<Themes extends ThemeMap>(
|
|
|
83
56
|
let lastNotifiedKey: keyof Themes | undefined = read()?.theme ?? undefined
|
|
84
57
|
|
|
85
58
|
function read() {
|
|
86
|
-
|
|
87
|
-
const theme = parseStoredTheme(themes, stored)
|
|
88
|
-
if (theme === undefined) return undefined
|
|
89
|
-
return themeEntry(themes, theme)
|
|
59
|
+
return readCookieTheme(themes, { cookieName, path, parse })
|
|
90
60
|
}
|
|
91
61
|
|
|
92
62
|
function notify() {
|
|
@@ -101,20 +71,13 @@ export function cookieThemeStore<Themes extends ThemeMap>(
|
|
|
101
71
|
read,
|
|
102
72
|
write(entry) {
|
|
103
73
|
try {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
secure?: boolean
|
|
112
|
-
} = { path }
|
|
113
|
-
if (maxAge !== undefined) opts.maxAge = maxAge
|
|
114
|
-
if (sameSite !== undefined) opts.sameSite = sameSite
|
|
115
|
-
if (secure) opts.secure = true
|
|
116
|
-
setCookie(cookieName, JSON.stringify(entry), opts)
|
|
117
|
-
}
|
|
74
|
+
writeCookieTheme(themes, entry, {
|
|
75
|
+
cookieName,
|
|
76
|
+
path,
|
|
77
|
+
maxAge,
|
|
78
|
+
sameSite,
|
|
79
|
+
secure
|
|
80
|
+
})
|
|
118
81
|
notify()
|
|
119
82
|
} catch {
|
|
120
83
|
// Ignore quota or other errors
|
|
@@ -129,12 +92,6 @@ export function cookieThemeStore<Themes extends ThemeMap>(
|
|
|
129
92
|
} satisfies ThemeStore<Themes>
|
|
130
93
|
}
|
|
131
94
|
|
|
132
|
-
function getCookieFromHeader(cookieHeader: string, name: string): string | null {
|
|
133
|
-
const match = cookieHeader.match(new RegExp(`(?:^|;\\s*)${name}=([^;]*)`))
|
|
134
|
-
const value = match?.[1]
|
|
135
|
-
return value !== undefined ? decodeURIComponent(value.trim()) : null
|
|
136
|
-
}
|
|
137
|
-
|
|
138
95
|
/**
|
|
139
96
|
* Reads the theme from cookies during SSR. Use with the request's Cookie header or
|
|
140
97
|
* a framework's cookie API (e.g. Next.js cookies()).
|
|
@@ -168,7 +125,5 @@ export function getThemeFromCookie<Themes extends ThemeMap>(
|
|
|
168
125
|
: cookieSource
|
|
169
126
|
? getCookieFromHeader(cookieSource, cookieName)
|
|
170
127
|
: null
|
|
171
|
-
|
|
172
|
-
if (theme === undefined) return undefined
|
|
173
|
-
return themeEntry(themes, theme)
|
|
128
|
+
return parseStoredTheme(themes, stored ?? undefined)
|
|
174
129
|
}
|