next-react-theme
Version:
A flexible theme provider for Next.js and react applications
2 lines (1 loc) • 1.27 kB
JavaScript
"use client";import{createContext as p,useLayoutEffect as g,useContext as y,useEffect as a,useState as c}from"react";var i=t=>localStorage.getItem(t)??"",l=(t,e)=>{localStorage.setItem(t,e)},d=["default","red","rose","orange","green","blue","yellow","violet"];import{jsx as C}from"react/jsx-runtime";var T=p(void 0),v=({children:t,colorScheme:e=!1,colors:f=d,disableTransition:h})=>{let[o,m]=c(null),[r,u]=c(null);return g(()=>{if(m(i("theme")||"system"),e&&u(i("color")||"default"),!h){let n="background-color 0.5s ease-in, color 0.5s ease-in";document.documentElement.style.transition=n,document.body.style.transition=n}},[e]),a(()=>{if(!o)return;let n=window.matchMedia("(prefers-color-scheme: dark)"),s=()=>document.documentElement.classList.toggle("dark",o==="dark"||o==="system"&&n.matches);return s(),l("theme",o),o==="system"&&n.addEventListener("change",s),()=>n.removeEventListener("change",s)},[o]),a(()=>{document.documentElement.setAttribute("data-color",r&&e?r:""),r&&l("color",r)},[r,e]),o===null||e&&r===null?null:C(T.Provider,{value:{theme:o,setTheme:m,color:r??"N/A",setColor:e?u:()=>{},colors:e?f:[]},children:t})},x=()=>{let t=y(T);if(!t)throw new Error("useTheme must be used within ThemeProvider");return t};export{v as ThemeProvider,x as useTheme};