diff --git a/src/index.tsx b/src/index.tsx index c8b00ef..1023e91 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -18,6 +18,10 @@ export type NextTopLoaderProps = { * @default "#29d" */ color?: string; + /** + * Color for the TopLoader in dark mode. + */ + darkColor?: string; /** * The initial position for the TopLoader in percentage, 0.08 is 8%. * @default 0.08 @@ -60,10 +64,11 @@ export type NextTopLoaderProps = { * @ you can disable it by setting it to `false` */ shadow?: string | false; -} +}; const NextTopLoader = ({ color: propColor, + darkColor: propDarkColor, height: propHeight, showSpinner, crawl, @@ -73,31 +78,31 @@ const NextTopLoader = ({ speed, shadow, }: NextTopLoaderProps) => { + const [isDarkMode, setIsDarkMode] = React.useState(false); + const defaultColor = '#29d'; const defaultHeight = 3; const color = propColor ?? defaultColor; + const darkColor = propDarkColor ?? color; const height = propHeight ?? defaultHeight; // Any falsy (except undefined) will disable the shadow - const boxShadow = !shadow && shadow !== undefined - ? '' - : shadow + const boxShadow = + !shadow && shadow !== undefined + ? '' + : shadow ? `box-shadow:${shadow}` : `box-shadow:0 0 10px ${color},0 0 5px ${color}`; const styles = ( ); @@ -112,6 +117,15 @@ const NextTopLoader = ({ speed: speed ?? 200, }); + const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); + + function handleChange(event: MediaQueryListEvent) { + setIsDarkMode(event.matches); + } + + mediaQuery.addEventListener('change', handleChange); + setIsDarkMode(mediaQuery.matches); + function isAnchorOfCurrentUrl(currentUrl: string, newUrl: string) { const currentUrlObj = new URL(currentUrl); const newUrlObj = new URL(newUrl); @@ -146,13 +160,13 @@ const NextTopLoader = ({ if (anchor) { const currentUrl = window.location.href; const newUrl = (anchor as HTMLAnchorElement).href; - const isExternalLink = (anchor as HTMLAnchorElement).target === "_blank"; + const isExternalLink = (anchor as HTMLAnchorElement).target === '_blank'; const isAnchor = isAnchorOfCurrentUrl(currentUrl, newUrl); if (newUrl === currentUrl || isAnchor || isExternalLink) { NProgress.start(); NProgress.done(); [].forEach.call(npgclass, function (el: Element) { - el.classList.remove("nprogress-busy"); + el.classList.remove('nprogress-busy'); }); } else { NProgress.start(); @@ -161,7 +175,7 @@ const NextTopLoader = ({ history.pushState = function () { NProgress.done(); [].forEach.call(npgclass, function (el: Element) { - el.classList.remove("nprogress-busy"); + el.classList.remove('nprogress-busy'); }); // eslint-disable-next-line prefer-rest-params, @typescript-eslint/no-explicit-any return pushState.apply(history, arguments as any); @@ -178,11 +192,11 @@ const NextTopLoader = ({ } // Add the global click event listener - document.addEventListener("click", handleClick); + document.addEventListener('click', handleClick); // Clean up the global click event listener when the component is unmounted return () => { - document.removeEventListener("click", handleClick); + document.removeEventListener('click', handleClick); }; }, []); @@ -192,6 +206,7 @@ export default NextTopLoader; NextTopLoader.propTypes = { color: PropTypes.string, + darkColor: PropTypes.string, height: PropTypes.number, showSpinner: PropTypes.bool, crawl: PropTypes.bool, @@ -199,8 +214,5 @@ NextTopLoader.propTypes = { initialPosition: PropTypes.number, easing: PropTypes.string, speed: PropTypes.number, - shadow: PropTypes.oneOfType([ - PropTypes.string, - PropTypes.bool, - ]), + shadow: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]), };