mode-watcher
Advanced tools
Comparing version 0.0.3 to 0.0.4
/// <reference types="svelte" /> | ||
/** Derived store with either `"light"` or `"dark"` depending on the current mode */ | ||
export declare const mode: import("svelte/store").Readable<"light" | "dark">; | ||
/** Readonly store with either `"light"` or `"dark"` depending on the active mode */ | ||
export declare const mode: import("svelte/store").Readable<"dark" | "light">; | ||
/** | ||
* Getters | ||
*/ | ||
/** Get the OS preference */ | ||
export declare function getModeOsPrefers(): boolean; | ||
/** Get the automatic preference */ | ||
export declare function getModeAutoPrefers(): boolean; | ||
/** Set the current mode */ | ||
export declare function setModeCurrent(value: boolean): void; | ||
/** Get the operating system preference */ | ||
export declare function getSystemPrefersMode(): 'dark' | 'light'; | ||
/** Set the active mode */ | ||
export declare function setActiveMode(value: 'dark' | 'light'): void; | ||
/** | ||
* Lightswitch Utility | ||
*/ | ||
/** Set the visible light/dark mode on page load */ | ||
export declare function setInitialClassState(): void; | ||
/** | ||
* Auto Mode Watcher | ||
* Set light/dark class based on user/system preference | ||
* | ||
* Should be added to <head> to prevent FOUC | ||
* | ||
* This function needs to be able to be stringified and thus it cannot use other functions | ||
*/ | ||
/** Automatically set the visible light/dark updates on change */ | ||
export declare function autoModeWatcher(): void; | ||
/** | ||
* Toggle between light and dark mode | ||
*/ | ||
export declare function setInitialClassState(): void; | ||
/** Toggle between light and dark mode */ | ||
export declare function toggleMode(): void; | ||
/** | ||
* Set the mode to light or dark | ||
*/ | ||
export declare function setMode(mode: 'light' | 'dark'): void; | ||
/** | ||
* Reset the mode to OS preference | ||
*/ | ||
/** Set the mode to light or dark */ | ||
export declare function setMode(mode: 'dark' | 'light'): void; | ||
/** Reset the mode to operating system preference */ | ||
export declare function resetMode(): void; |
138
dist/mode.js
// Modified version of the light switch by: https://skeleton.dev | ||
import { derived, get } from 'svelte/store'; | ||
import { persisted } from 'svelte-persisted-store'; | ||
import { readonly } from 'svelte/store'; | ||
/** | ||
* Stores | ||
* ---- | ||
* TRUE: Light mode | FALSE: Dark mode | ||
*/ | ||
const modeOsPrefers = persisted('modeOsPrefers', false); | ||
const modeUserPrefers = persisted('modeUserPrefers', undefined); | ||
const modeCurrent = persisted('modeCurrent', false); | ||
/** Derived store with either `"light"` or `"dark"` depending on the current mode */ | ||
export const mode = derived(modeCurrent, ($modeCurrent) => ($modeCurrent ? 'light' : 'dark')); | ||
const systemPrefersMode = persisted('systemPrefersMode', 'dark'); | ||
const userPrefersMode = persisted('userPrefersMode', undefined); | ||
const activeMode = persisted('mode', 'dark'); | ||
/** Readonly store with either `"light"` or `"dark"` depending on the active mode */ | ||
export const mode = readonly(activeMode); | ||
/** | ||
* Getters | ||
*/ | ||
/** Get the OS preference */ | ||
export function getModeOsPrefers() { | ||
const prefersLightMode = window.matchMedia('(prefers-color-scheme: light)').matches; | ||
modeOsPrefers.set(prefersLightMode); | ||
/** Get the operating system preference */ | ||
export function getSystemPrefersMode() { | ||
const prefersLightMode = window.matchMedia('(prefers-color-scheme: light)').matches | ||
? 'light' | ||
: 'dark'; | ||
systemPrefersMode.set(prefersLightMode); | ||
return prefersLightMode; | ||
} | ||
/** Get the User preference */ | ||
function getModeUserPrefers() { | ||
return get(modeUserPrefers); | ||
} | ||
/** Get the automatic preference */ | ||
export function getModeAutoPrefers() { | ||
const os = getModeOsPrefers(); | ||
const user = getModeUserPrefers(); | ||
return user !== undefined ? user : os; | ||
} | ||
/** | ||
@@ -37,18 +27,17 @@ * Setters | ||
/** Set the user preference */ | ||
function setModeUserPrefers(value) { | ||
modeUserPrefers.set(value); | ||
function setUserPrefersMode(value) { | ||
userPrefersMode.set(value); | ||
} | ||
/** Set the current mode */ | ||
export function setModeCurrent(value) { | ||
/** Set the active mode */ | ||
export function setActiveMode(value) { | ||
const htmlEl = document.documentElement; | ||
const classDark = 'dark'; | ||
if (value === true) { | ||
htmlEl.classList.remove(classDark); | ||
if (value === 'light') { | ||
htmlEl.classList.remove('dark'); | ||
htmlEl.style.colorScheme = 'light'; | ||
} | ||
else { | ||
htmlEl.classList.add(classDark); | ||
htmlEl.classList.add('dark'); | ||
htmlEl.style.colorScheme = 'dark'; | ||
} | ||
modeCurrent.set(value); | ||
activeMode.set(value); | ||
} | ||
@@ -58,74 +47,55 @@ /** | ||
*/ | ||
/** Set the visible light/dark mode on page load */ | ||
/** | ||
* Set light/dark class based on user/system preference | ||
* | ||
* Should be added to <head> to prevent FOUC | ||
* | ||
* This function needs to be able to be stringified and thus it cannot use other functions | ||
*/ | ||
export function setInitialClassState() { | ||
const htmlEl = document.documentElement; | ||
const condLocalStorageUserPrefs = localStorage.getItem('modeUserPrefers') === 'false'; | ||
const condLocalStorageUserPrefsExist = !('modeUserPrefers' in localStorage); | ||
const condMatchMedia = window.matchMedia('(prefers-color-scheme: dark)').matches; | ||
if (condLocalStorageUserPrefs || (condLocalStorageUserPrefsExist && condMatchMedia)) { | ||
htmlEl.classList.add('dark'); | ||
htmlEl.style.colorScheme = 'dark'; | ||
let userPref = null; | ||
try { | ||
userPref = JSON.parse(localStorage.getItem('userPrefersMode') || 'null'); | ||
} | ||
else { | ||
catch { | ||
// ignore JSON parsing errors | ||
} | ||
const systemPref = window.matchMedia('(prefers-color-scheme: light)').matches ? 'light' : 'dark'; | ||
if (userPref === 'light' || (userPref === null && systemPref === 'light')) { | ||
htmlEl.classList.remove('dark'); | ||
htmlEl.style.colorScheme = 'light'; | ||
} | ||
} | ||
/** | ||
* Auto Mode Watcher | ||
*/ | ||
/** Automatically set the visible light/dark updates on change */ | ||
export function autoModeWatcher() { | ||
const mql = window.matchMedia('(prefers-color-scheme: dark)'); | ||
function setMode(value) { | ||
const htmlEl = document.documentElement; | ||
const classDark = 'dark'; | ||
if (value === true) { | ||
htmlEl.classList.remove(classDark); | ||
htmlEl.style.colorScheme = 'light'; | ||
} | ||
else { | ||
htmlEl.classList.add(classDark); | ||
htmlEl.style.colorScheme = 'dark'; | ||
} | ||
else { | ||
htmlEl.classList.add('dark'); | ||
htmlEl.style.colorScheme = 'dark'; | ||
} | ||
setMode(mql.matches); | ||
mql.onchange = () => { | ||
setMode(mql.matches); | ||
}; | ||
} | ||
/** | ||
* Toggle between light and dark mode | ||
*/ | ||
/** Toggle between light and dark mode */ | ||
export function toggleMode() { | ||
modeCurrent.update((curr) => { | ||
const next = !curr; | ||
setModeUserPrefers(next); | ||
setModeCurrent(next); | ||
activeMode.update((curr) => { | ||
const next = curr === 'dark' ? 'light' : 'dark'; | ||
setUserPrefersMode(next); | ||
setActiveMode(next); | ||
return next; | ||
}); | ||
} | ||
/** | ||
* Set the mode to light or dark | ||
*/ | ||
/** Set the mode to light or dark */ | ||
export function setMode(mode) { | ||
modeCurrent.update((curr) => { | ||
const next = mode === 'light'; | ||
if (curr === next) | ||
activeMode.update((curr) => { | ||
if (curr === mode) | ||
return curr; | ||
setModeUserPrefers(next); | ||
setModeCurrent(next); | ||
return next; | ||
setUserPrefersMode(mode); | ||
setActiveMode(mode); | ||
return mode; | ||
}); | ||
} | ||
/** | ||
* Reset the mode to OS preference | ||
*/ | ||
/** Reset the mode to operating system preference */ | ||
export function resetMode() { | ||
modeCurrent.update(() => { | ||
setModeUserPrefers(undefined); | ||
const next = getModeOsPrefers(); | ||
setModeCurrent(next); | ||
activeMode.update(() => { | ||
setUserPrefersMode(undefined); | ||
const next = getSystemPrefersMode(); | ||
setActiveMode(next); | ||
return next; | ||
}); | ||
} |
{ | ||
"name": "mode-watcher", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"exports": { | ||
@@ -5,0 +5,0 @@ ".": { |
Sorry, the diff of this file is not supported yet
8760
146