use-color-theme
Version:
A custom React Hook to help you implement a "color theme" component.
2 lines (1 loc) • 1.78 kB
JavaScript
import e from"@use-it/event-listener";import{useState as t,useCallback as r,useEffect as n,useMemo as o}from"react";import i from"use-persisted-state";var a=function(){},u={classList:{add:a,remove:a}},s=function(e,r,n){void 0===n&&(n=global);var o=e?i(e,r):t,a=n.matchMedia?n.matchMedia("(prefers-color-scheme: dark)"):{},s={addEventListener:function(e,t){return a.addListener&&a.addListener(t)},removeEventListener:function(e,t){return a.removeListener&&a.removeListener(t)}},c="(prefers-color-scheme: dark)"===a.media,d=n.document&&n.document.body||u;return{usePersistedcolorThemeState:o,getDefaultOnChange:function(e,t){return void 0===e&&(e=d),void 0===t&&(t=["light-theme","dark-theme"]),function(r){t.forEach(function(t){return e.classList.remove(t)}),e.classList.add(r)}},mediaQueryEventTarget:s,getInitialValue:function(e){return c?a.matches:e}}};export default function(t,i){void 0===t&&(t="light-theme"),void 0===i&&(i={});var a=i.element,u=i.classNames;void 0===u&&(u=["light-theme","dark-theme"]);var c=i.onChange,d=i.storageKey;void 0===d&&(d="colorTheme");var l=i.storageProvider,m=i.global;u.reduce(function(e,t){if(e.length>0&&e.includes(t))throw new Error("Duplicate Classnames are not allowed.");return e.push(t),e},[]);var f=o(function(){return s(d,l,m)},[d,l,m]),h=f.getDefaultOnChange,v=f.mediaQueryEventTarget,g=(0,f.usePersistedcolorThemeState)((0,f.getInitialValue)(t)),p=g[0],L=g[1],E=o(function(){return c||h(a,u)},[c,a,u,h]);return n(function(){E(p)},[E,p]),e("change",function(e){var t=e.matches;return L(function(){return t?"dark-theme":"light-theme"})},v),{value:p,set:r(function(e){return L(function(){return u.includes(e)?e:u[0]})},[L,u]),toggle:r(function(){return L(function(e){var t=u.length,r=u.indexOf(e);return r!==t-1?u[r+1]:u[0]})},[L,u])}}