next-theme-kit
Version:
Your ultimate companion for seamless dark and light theme handling in Next.js! 🎨 Simplify theme management with this powerful wrapper 🧪.
36 lines (29 loc) • 3.03 kB
JavaScript
import p, { memo, useState, useCallback, useEffect, useMemo, useContext } from 'react';
var x=t=>{let m=typeof window<"u",[o,r]=useState(!1);return useEffect(()=>{if(!m)return;let s=window.matchMedia(t),a=e=>r(e.matches);return r(s.matches),s.addEventListener("change",a),()=>{s.removeEventListener("change",a);}},[t,m]),o};var d="(prefers-color-scheme: dark)",S=["light","dark"],f="light",C=!0,A=!0,M=!1,v="theme",P="class",u="data-theme";var U=(t,m)=>{let o=typeof window<"u",[r,s]=useState(()=>{if(o)try{return window.localStorage.getItem(t)??m}catch{}return m}),a=e=>{if(o)try{s(e),window.localStorage.setItem(t,e);}catch{}};return useEffect(()=>{if(!o)return;let e=n=>{if(n.key===t)try{s(n.newValue??m);}catch{}};return window.addEventListener("storage",e),()=>{window.removeEventListener("storage",e);}},[t,o]),[r,a]};var D=memo(t=>{let{themes:m,mode:o,storageKey:r,useSystem:s,useColorScheme:a,useLocalStorage:e,defaultTheme:n}=t,c=(()=>`
!function () {
try {
const documentNode = document.documentElement;
if ('${o}' === 'class') {
const themes = [${m.map(E=>`'${E}'`).join(",")}];
documentNode.classList.remove(...themes);
}
const localValue = localStorage.getItem('${r}');
if (!localValue) {
localStorage.setItem('${r}', ${n});
if ('${o}' === 'class')
document.classList.add(${n});
else document.documentElement.setAttribute('${u}', theme);
return;
}
let theme = ${e} ? localValue : ${n};
if ('${o}' === 'class')
document.documentElement.classList.add(theme);
else document.documentElement.setAttribute('${u}', theme);
if (${s})
theme = window.matchMedia('${d}').matches ? 'dark' : 'light';
if (${a})
documentNode.style.colorScheme = theme;
} catch (e) {}
}();
`)();return p.createElement("script",{dangerouslySetInnerHTML:{__html:c}})},()=>!0);var k={theme:f,themes:S,setTheme:()=>{}},h=p.createContext(k),G=t=>{let{children:m,useColorScheme:o=A,useSystem:r=C,useLocalStorage:s=M,storageKey:a=v,themes:e=S,defaultTheme:n=f,mode:c=P}=t,[E,y]=U(a,n),g=x(d),[L,N]=useState(()=>{if(!(typeof window>"u"))return E||n}),_=()=>g?"dark":"light",T=useCallback(i=>{if(!i)return;let l=r?_():i;c==="class"?(document.documentElement.classList.remove(...e),document.documentElement.classList.add(l)):document.documentElement.setAttribute(u,l),o&&(document.documentElement.style.colorScheme=l),s&&y(l),N(i);},[]);useEffect(()=>{if(!r)return;let i=_();T(i);},[g]);let $=useMemo(()=>({themes:e,theme:L,setTheme:T}),[L,T]);return p.createElement(h.Provider,{value:$},p.createElement(D,{defaultTheme:n,themes:e,storageKey:a,useSystem:r,useColorScheme:o,useLocalStorage:s,mode:c}),m)};var w=()=>{let t=useContext(h);if(!t)throw new Error("Tried to use ThemeContext with no context avaiable!");return t};
export { h as ThemeContext, G as ThemeProvider, w as useTheme };