forked from tsai/budibase
4 changed files with 143 additions and 26 deletions
@ -0,0 +1,43 @@ |
|||
import { get, writable } from "svelte/store" |
|||
|
|||
export const localStorageStore = (localStorageKey, initialValue) => { |
|||
const store = writable(initialValue, () => { |
|||
// Hydrate from local storage when we get a new subscriber
|
|||
hydrate() |
|||
|
|||
// Listen for local storage changes and keep store in sync
|
|||
const storageListener = ({ key }) => key === localStorageKey && hydrate() |
|||
window.addEventListener("storage", storageListener) |
|||
return () => window.removeEventListener("storage", storageListener) |
|||
}) |
|||
|
|||
// New store setter which updates the store and localstorage
|
|||
const set = value => { |
|||
store.set(value) |
|||
localStorage.setItem(localStorageKey, JSON.stringify(value)) |
|||
} |
|||
|
|||
// New store updater which updates the store and localstorage
|
|||
const update = updaterFn => set(updaterFn(get(store))) |
|||
|
|||
// Hydrates the store from localstorage
|
|||
const hydrate = () => { |
|||
const localValue = localStorage.getItem(localStorageKey) |
|||
if (localValue == null) { |
|||
set(initialValue) |
|||
} else { |
|||
try { |
|||
store.set(JSON.parse(localValue)) |
|||
} catch { |
|||
set(initialValue) |
|||
} |
|||
} |
|||
} |
|||
|
|||
// Patch the default svelte store functions with our overrides
|
|||
return { |
|||
...store, |
|||
set, |
|||
update, |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
import { localStorageStore } from "./localStorage" |
|||
|
|||
export const getThemeStore = () => { |
|||
const themeElement = document.documentElement |
|||
const initialValue = { |
|||
darkMode: false, |
|||
hue: 208, |
|||
saturation: 9, |
|||
lightness: 16, |
|||
} |
|||
|
|||
const store = localStorageStore("bb-theme", initialValue) |
|||
|
|||
// Sets a CSS variable on the root document element
|
|||
function setCSSVariable(prop, value) { |
|||
themeElement.style.setProperty(prop, value) |
|||
} |
|||
|
|||
// Resets the custom theme to the default dark theme.
|
|||
// The reset option is only available when dark theme is on, which is why it
|
|||
// sets dark mode to true here
|
|||
store.reset = () => { |
|||
store.set({ |
|||
...initialValue, |
|||
darkMode: true, |
|||
}) |
|||
} |
|||
|
|||
// Update theme when store changes
|
|||
store.subscribe(theme => { |
|||
themeElement.classList[theme.darkMode ? "add" : "remove"]("dark") |
|||
setCSSVariable("--theme-hue", Math.round(theme.hue)) |
|||
setCSSVariable("--theme-saturation", `${Math.round(theme.saturation)}%`) |
|||
setCSSVariable("--theme-brightness", `${Math.round(theme.lightness)}%`) |
|||
}) |
|||
|
|||
return store |
|||
} |
|||
Loading…
Reference in new issue