File size: 1,683 Bytes
04ec17f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
import { PersistedState, watch } from "runed";
import { themeStorageKey } from "./storage-keys.svelte.js";
import { isBrowser, noopStorage } from "./utils.js";
class CustomTheme {
#storage = isBrowser ? localStorage : noopStorage;
#initialValue = this.#storage.getItem(themeStorageKey.current);
#value = this.#initialValue === null || this.#initialValue === undefined ? "" : this.#initialValue;
#persisted = $state(this.#makePersisted());
#makePersisted(value = this.#value) {
return new PersistedState(themeStorageKey.current, value, {
serializer: {
serialize: (v) => {
if (typeof v !== "string")
return "";
return v;
},
deserialize: (v) => v,
},
});
}
constructor() {
$effect.root(() => {
return watch.pre(() => themeStorageKey.current, (_, prevStorageKey) => {
const currModeValue = this.#persisted.current;
this.#persisted = this.#makePersisted(currModeValue);
if (prevStorageKey) {
localStorage.removeItem(prevStorageKey);
}
});
});
}
/**
* The current theme.
* @returns The current theme.
*/
get current() {
return this.#persisted.current;
}
/**
* Set the current theme.
* @param newValue The new theme to set.
*/
set current(newValue) {
this.#persisted.current = newValue;
}
}
/**
* A custom theme to apply and persist to the root `html` element.
*/
export const customTheme = new CustomTheme();
|