@carry0987/darkmode
Advanced tools
Comparing version 1.0.7 to 1.1.0
type DarkModeCallback = () => void; | ||
type DarkModeCallbackWithMode = (currentMode: string) => void; | ||
interface DarkModeOptions { | ||
buttonSelector: string | HTMLElement | null; | ||
onChange: DarkModeCallbackWithMode; | ||
@@ -26,3 +27,3 @@ onDark: DarkModeCallback; | ||
private readonly invertDarkModeObj; | ||
constructor(buttonSelector: string | HTMLElement | null, options?: Partial<DarkModeOptions>); | ||
constructor(options?: Partial<DarkModeOptions>); | ||
/** | ||
@@ -41,2 +42,7 @@ * Initialization | ||
destroy(): void; | ||
/** | ||
* Switch directly to a specified mode | ||
* @param mode The color mode to switch to ('dark' or 'light') | ||
*/ | ||
switchMode(mode: string): void; | ||
set onChange(callback: (currentMode: string) => void); | ||
@@ -43,0 +49,0 @@ set onDark(callback: () => void); |
@@ -75,6 +75,7 @@ function reportError(...error) { | ||
static instance = null; | ||
static version = '1.0.7'; | ||
static version = '1.1.0'; | ||
darkModeToggleButton; | ||
options; | ||
defaults = { | ||
buttonSelector: null, | ||
onChange: (currentMode) => { }, | ||
@@ -102,6 +103,16 @@ onDark: () => { }, | ||
}; | ||
constructor(buttonSelector, options = {}) { | ||
constructor(options = {}) { | ||
if (DarkMode.instance) { | ||
return DarkMode.instance; | ||
} | ||
this.init(options); | ||
DarkMode.instance = this; | ||
Object.seal(this); | ||
} | ||
/** | ||
* Initialization | ||
*/ | ||
init(option) { | ||
const userOptions = deepMerge(this.defaults, option); | ||
const { buttonSelector } = userOptions; | ||
let buttonElement = null; | ||
@@ -114,14 +125,5 @@ if (buttonSelector !== null) { | ||
} | ||
this.init(buttonElement, options); | ||
DarkMode.instance = this; | ||
Object.seal(this); | ||
} | ||
/** | ||
* Initialization | ||
*/ | ||
init(element, option) { | ||
const userOptions = deepMerge(this.defaults, option); | ||
userOptions.autoDetect = !userOptions.preferSystem ? userOptions.autoDetect : true; | ||
this.options = userOptions; | ||
this.darkModeToggleButton = element; | ||
this.darkModeToggleButton = buttonElement; | ||
this.onChangeCallback = this.options.onChange || this.onChangeCallback; | ||
@@ -236,2 +238,22 @@ this.onDarkCallback = this.options.onDark || this.onDarkCallback; | ||
} | ||
/** | ||
* Switch directly to a specified mode | ||
* @param mode The color mode to switch to ('dark' or 'light') | ||
*/ | ||
switchMode(mode) { | ||
if (!this.validColorModeKeys[mode]) | ||
return; | ||
const updatedSetting = this.applyCustomDarkModeSettings(mode); | ||
if (updatedSetting) { | ||
this.onChangeCallback(updatedSetting); | ||
if (updatedSetting === 'dark') { | ||
this.onDarkCallback(); | ||
} | ||
else { | ||
this.onLightCallback(); | ||
} | ||
// Save the new setting to localStorage | ||
setLocalValue(this.options.darkModeStorageKey, updatedSetting); | ||
} | ||
} | ||
// Getters and setters | ||
@@ -238,0 +260,0 @@ set onChange(callback) { |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).DarkMode=e()}(this,(function(){"use strict";function t(e,...o){if(!o.length)return e;const r=o.shift();if(r)for(const o in r)if(Object.prototype.hasOwnProperty.call(r,o)){const n=r[o],s=o;"object"!=typeof(i=n)||null===i||Array.isArray(i)?e[s]=n:(e[s]&&"object"==typeof e[s]||(e[s]={}),t(e[s],n))}var i;return t(e,...o)}function e(t,e=!0){let o=window.localStorage.getItem(t);if(e)try{o=JSON.parse(o)}catch(t){!function(...t){console.error(...t)}("Error while parsing stored json value: ",t)}return o}class o{static instance=null;static version="1.0.7";darkModeToggleButton;options;defaults={onChange:t=>{},onDark:()=>{},onLight:()=>{},autoDetect:!0,preferSystem:!1,rootElement:document.documentElement,darkModeStorageKey:"user-color-scheme",darkModeMediaQueryKey:"--color-mode",rootElementDarkModeAttributeName:"data-user-color-scheme"};onChangeCallback=t=>{};onDarkCallback=()=>{};onLightCallback=()=>{};validColorModeKeys={dark:!0,light:!0};invertDarkModeObj={dark:"light",light:"dark"};constructor(t,e={}){if(o.instance)return o.instance;let r=null;if(null!==t&&(r=function(t,e,o){if("string"!=typeof t)return t;let r=document;return null===e&&o?r=o:e&&e instanceof Node&&"querySelector"in e?r=e:o&&o instanceof Node&&"querySelector"in o&&(r=o),"all"===e?r.querySelectorAll(t):r.querySelector(t)}(t),!r))throw new Error("ToggleButton could not be found with the selector provided.");this.init(r,e),o.instance=this,Object.seal(this)}init(e,r){const i=t(this.defaults,r);i.autoDetect=!!i.preferSystem||i.autoDetect,this.options=i,this.darkModeToggleButton=e,this.onChangeCallback=this.options.onChange||this.onChangeCallback,this.onDarkCallback=this.options.onDark||this.onDarkCallback,this.onLightCallback=this.options.onLight||this.onLightCallback,this.setupDarkMode(),console.log(`DarkMode is loaded, version: ${o.version}`)}setupDarkMode(){this.options.preferSystem&&this.resetRootDarkModeAttribute();let t=this.options.preferSystem?null:e(this.options.darkModeStorageKey);null===t&&this.options.autoDetect?t=this.getModeFromSystemPreference():null===t&&(t="light"),this.applyCustomDarkModeSettings(t),"dark"===t?this.onDarkCallback():this.onLightCallback(),this.bindEvents(),(this.options.autoDetect||this.options.preferSystem)&&this.listenToSystemDarkModeChange()}bindEvents(){null!==this.darkModeToggleButton&&this.darkModeToggleButton.addEventListener("click",(()=>{const t=this.toggleCustomDarkMode();this.applyCustomDarkModeSettings(t),t&&(this.onChangeCallback(t),"dark"===t?this.onDarkCallback():"light"===t&&this.onLightCallback())}))}getModeFromSystemPreference(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}getModeFromCSSMediaQuery(){const t=getComputedStyle(this.options.rootElement).getPropertyValue(this.options.darkModeMediaQueryKey);return t.length?t.replace(/\"/g,"").trim():"dark"===t?"dark":"light"}resetRootDarkModeAttribute(){var t;this.options.rootElement.removeAttribute(this.options.rootElementDarkModeAttributeName),t=this.options.darkModeStorageKey,window.localStorage.removeItem(t)}applyCustomDarkModeSettings(t){const o=t||e(this.options.darkModeStorageKey)||this.getModeFromCSSMediaQuery();return this.validColorModeKeys[o]?this.options.rootElement.setAttribute(this.options.rootElementDarkModeAttributeName,o):this.resetRootDarkModeAttribute(),this.darkModeToggleButton&&this.darkModeToggleButton instanceof Element&&(this.darkModeToggleButton.classList.remove("dm-"+this.invertDarkModeObj[o]),this.darkModeToggleButton.classList.add("dm-"+o)),o}toggleCustomDarkMode(){let t=e(this.options.darkModeStorageKey);if(this.validColorModeKeys[t])t=this.invertDarkModeObj[t];else{if(null!==t)return;t=this.invertDarkModeObj[this.getModeFromCSSMediaQuery()]}return function(t,e,o=!0){o&&(e=JSON.stringify(e)),window.localStorage.setItem(t,e)}(this.options.darkModeStorageKey,t),t}listenToSystemDarkModeChange(){window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",(t=>{if(null===e(this.options.darkModeStorageKey)){const e=t.matches?"dark":"light";this.applyCustomDarkModeSettings(e),this.onChangeCallback(e),"dark"===e?this.onDarkCallback():this.onLightCallback()}}))}destroy(){this.resetRootDarkModeAttribute()}set onChange(t){this.onChangeCallback=t}set onDark(t){this.onDarkCallback=t}set onLight(t){this.onLightCallback=t}}return o})); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).DarkMode=e()}(this,(function(){"use strict";function t(e,...o){if(!o.length)return e;const r=o.shift();if(r)for(const o in r)if(Object.prototype.hasOwnProperty.call(r,o)){const n=r[o],s=o;"object"!=typeof(i=n)||null===i||Array.isArray(i)?e[s]=n:(e[s]&&"object"==typeof e[s]||(e[s]={}),t(e[s],n))}var i;return t(e,...o)}function e(t,e,o=!0){o&&(e=JSON.stringify(e)),window.localStorage.setItem(t,e)}function o(t,e=!0){let o=window.localStorage.getItem(t);if(e)try{o=JSON.parse(o)}catch(t){!function(...t){console.error(...t)}("Error while parsing stored json value: ",t)}return o}class r{static instance=null;static version="1.1.0";darkModeToggleButton;options;defaults={buttonSelector:null,onChange:t=>{},onDark:()=>{},onLight:()=>{},autoDetect:!0,preferSystem:!1,rootElement:document.documentElement,darkModeStorageKey:"user-color-scheme",darkModeMediaQueryKey:"--color-mode",rootElementDarkModeAttributeName:"data-user-color-scheme"};onChangeCallback=t=>{};onDarkCallback=()=>{};onLightCallback=()=>{};validColorModeKeys={dark:!0,light:!0};invertDarkModeObj={dark:"light",light:"dark"};constructor(t={}){if(r.instance)return r.instance;this.init(t),r.instance=this,Object.seal(this)}init(e){const o=t(this.defaults,e),{buttonSelector:i}=o;let n=null;if(null!==i&&(n=function(t,e,o){if("string"!=typeof t)return t;let r=document;return null===e&&o?r=o:e&&e instanceof Node&&"querySelector"in e?r=e:o&&o instanceof Node&&"querySelector"in o&&(r=o),"all"===e?r.querySelectorAll(t):r.querySelector(t)}(i),!n))throw new Error("ToggleButton could not be found with the selector provided.");o.autoDetect=!!o.preferSystem||o.autoDetect,this.options=o,this.darkModeToggleButton=n,this.onChangeCallback=this.options.onChange||this.onChangeCallback,this.onDarkCallback=this.options.onDark||this.onDarkCallback,this.onLightCallback=this.options.onLight||this.onLightCallback,this.setupDarkMode(),console.log(`DarkMode is loaded, version: ${r.version}`)}setupDarkMode(){this.options.preferSystem&&this.resetRootDarkModeAttribute();let t=this.options.preferSystem?null:o(this.options.darkModeStorageKey);null===t&&this.options.autoDetect?t=this.getModeFromSystemPreference():null===t&&(t="light"),this.applyCustomDarkModeSettings(t),"dark"===t?this.onDarkCallback():this.onLightCallback(),this.bindEvents(),(this.options.autoDetect||this.options.preferSystem)&&this.listenToSystemDarkModeChange()}bindEvents(){null!==this.darkModeToggleButton&&this.darkModeToggleButton.addEventListener("click",(()=>{const t=this.toggleCustomDarkMode();this.applyCustomDarkModeSettings(t),t&&(this.onChangeCallback(t),"dark"===t?this.onDarkCallback():"light"===t&&this.onLightCallback())}))}getModeFromSystemPreference(){return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light"}getModeFromCSSMediaQuery(){const t=getComputedStyle(this.options.rootElement).getPropertyValue(this.options.darkModeMediaQueryKey);return t.length?t.replace(/\"/g,"").trim():"dark"===t?"dark":"light"}resetRootDarkModeAttribute(){var t;this.options.rootElement.removeAttribute(this.options.rootElementDarkModeAttributeName),t=this.options.darkModeStorageKey,window.localStorage.removeItem(t)}applyCustomDarkModeSettings(t){const e=t||o(this.options.darkModeStorageKey)||this.getModeFromCSSMediaQuery();return this.validColorModeKeys[e]?this.options.rootElement.setAttribute(this.options.rootElementDarkModeAttributeName,e):this.resetRootDarkModeAttribute(),this.darkModeToggleButton&&this.darkModeToggleButton instanceof Element&&(this.darkModeToggleButton.classList.remove("dm-"+this.invertDarkModeObj[e]),this.darkModeToggleButton.classList.add("dm-"+e)),e}toggleCustomDarkMode(){let t=o(this.options.darkModeStorageKey);if(this.validColorModeKeys[t])t=this.invertDarkModeObj[t];else{if(null!==t)return;t=this.invertDarkModeObj[this.getModeFromCSSMediaQuery()]}return e(this.options.darkModeStorageKey,t),t}listenToSystemDarkModeChange(){window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",(t=>{if(null===o(this.options.darkModeStorageKey)){const e=t.matches?"dark":"light";this.applyCustomDarkModeSettings(e),this.onChangeCallback(e),"dark"===e?this.onDarkCallback():this.onLightCallback()}}))}destroy(){this.resetRootDarkModeAttribute()}switchMode(t){if(!this.validColorModeKeys[t])return;const o=this.applyCustomDarkModeSettings(t);o&&(this.onChangeCallback(o),"dark"===o?this.onDarkCallback():this.onLightCallback(),e(this.options.darkModeStorageKey,o))}set onChange(t){this.onChangeCallback=t}set onDark(t){this.onDarkCallback=t}set onLight(t){this.onLightCallback=t}}return r})); |
{ | ||
"name": "@carry0987/darkmode", | ||
"version": "1.0.7", | ||
"version": "1.1.0", | ||
"description": "A simple and lightweight JavaScript library for dark mode toggle with localStorage support.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18307
331