UNPKG

website-theme-switcher

Version:

A lightweight, framework-agnostic JavaScript library for seamless theme switching between light and dark modes

3 lines (2 loc) 4.54 kB
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).WebsiteThemeSwitcher={})}(this,function(e){"use strict";class t{constructor(e={}){this.currentTheme="light",this.options={defaultTheme:"light",storageKey:"theme",enableSystemPreference:!1,transitionDuration:300,themes:["light","dark"],onThemeChange:()=>{},debug:!1,enableTouchGestures:!1,touchThreshold:50,...e}}static init(e){return t.instance||(t.instance=new t(e),t.instance.setupEventListeners(),t.instance.setInitialTheme()),t.instance}static getInstance(){return t.instance}setupEventListeners(){this.setupButtonSwitchers(),this.setupToggleSwitchers(),this.setupSelectSwitchers(),this.options.enableTouchGestures&&this.setupTouchGestures()}setupButtonSwitchers(){document.querySelectorAll("[data-set-theme]").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault();const s=e.getAttribute("data-set-theme")||"",h=e.getAttribute("data-act-class"),i=e.getAttribute("data-key");s&&this.setTheme(s,i||void 0),h&&(document.querySelectorAll("[data-set-theme]").forEach(e=>{e.classList.remove(h)}),e.classList.add(h))})})}setupToggleSwitchers(){document.querySelectorAll("[data-toggle-theme]").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault();const s=e.getAttribute("data-toggle-theme"),h=e.getAttribute("data-act-class"),i=e.getAttribute("data-key");if(s){const e=s.split(","),t=this.getCurrentTheme(i||void 0);if(e.length>=2){const s=t===e[0]?e[1]:e[0];this.setTheme(s,i||void 0)}}h&&document.querySelectorAll("[data-toggle-theme]").forEach(e=>{e.classList.toggle(h)})})})}setupSelectSwitchers(){document.querySelectorAll("[data-choose-theme]").forEach(e=>{e.addEventListener("change",t=>{const s=t.target.value,h=e.getAttribute("data-key");s?h?this.setTheme(s,h):this.setTheme(s):h?this.removeTheme(h):this.removeTheme()})})}setupTouchGestures(){let e=0,t=0,s=!1;document.addEventListener("touchstart",h=>{e=h.touches[0]?.clientX||0,t=h.touches[0]?.clientY||0,s=!1}),document.addEventListener("touchmove",h=>{if(!s){const i=h.touches[0]?.clientX||0,n=h.touches[0]?.clientY||0,o=Math.abs(i-e),r=Math.abs(n-t);if(o>this.options.touchThreshold&&o>r){s=!0;const t=i>e?"right":"left";this.handleSwipeGesture(t)}}})}handleSwipeGesture(e){const t=this.getCurrentTheme(),s=this.options.themes.indexOf(t);if("right"===e&&s>0){const e=this.options.themes[s-1];e&&this.setTheme(e)}else if("left"===e&&s<this.options.themes.length-1){const e=this.options.themes[s+1];e&&this.setTheme(e)}}setInitialTheme(){const e=this.getSavedTheme(),s=t.getSystemPreference();e&&this.options.themes.includes(e)?this.currentTheme=e:this.options.enableSystemPreference&&s?this.currentTheme="dark":this.currentTheme=this.options.defaultTheme,this.applyTheme(this.currentTheme)}getSavedTheme(e){try{const t=e||this.options.storageKey;return localStorage.getItem(t)}catch{return null}}saveTheme(e,t){try{const s=t||this.options.storageKey;localStorage.setItem(s,e)}catch(e){this.options.debug&&console.warn("WebsiteThemeSwitcher: Failed to save theme to localStorage:",e)}}applyTheme(e){e?document.documentElement.setAttribute("data-theme",e):document.documentElement.removeAttribute("data-theme"),this.currentTheme=e,this.options.onThemeChange&&this.options.onThemeChange(e),this.options.debug&&console.log("WebsiteThemeSwitcher: Theme applied:",e)}setTheme(e,t){e&&this.options.themes.includes(e)&&(this.applyTheme(e),t?this.saveTheme(e,t):this.saveTheme(e))}removeTheme(e){this.applyTheme(""),e?this.saveTheme("",e):this.saveTheme("")}getCurrentTheme(e){return e?this.getSavedTheme(e)||"":this.currentTheme}toggleTheme(e=["light","dark"]){const t=this.getCurrentTheme(),s=e.indexOf(t),h=e[(s+1)%e.length];h&&this.setTheme(h)}isDarkMode(){return"dark"===this.currentTheme}static getSystemPreference(){return window.matchMedia("(prefers-color-scheme: dark)").matches}createSwitcher(e){const{type:t,element:s,themes:h,onChange:i}=e;if(s&&"custom"===t)s.addEventListener("click",()=>{const e=this.getCurrentTheme(),t=(h.indexOf(e)+1)%h.length,s=h[t];s&&(this.setTheme(s),i&&i(s))})}loadTheme(e,t){const s=document.createElement("style");s.textContent=`\n [data-theme="${e}"] {\n ${Object.entries(t).map(([e,t])=>`${e}: ${t};`).join("\n ")}\n }\n `,document.head.appendChild(s),this.options.themes.includes(e)||this.options.themes.push(e)}destroy(){t.instance=void 0}}e.WebsiteThemeSwitcher=t}); //# sourceMappingURL=index.umd.js.map