Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always forcing dark mode even if I set the mode to light #36

Open
leandroluk opened this issue Nov 9, 2022 · 3 comments
Open

Always forcing dark mode even if I set the mode to light #36

leandroluk opened this issue Nov 9, 2022 · 3 comments

Comments

@leandroluk
Copy link

leandroluk commented Nov 9, 2022

I created a simple NextJS project to test this lib and I'm using MantineUI with dark mode active on my system. The implementation is like this:

// src/pages/_app.tsx
import { MantineProvider, MantineThemeOverride } from '@mantine/core';
import { useHotkeys } from '@mantine/hooks';
import withDarkMode, { MODE, useDarkMode } from 'next-dark-mode';
import { AppProps } from 'next/app';

function App({ Component, pageProps }: AppProps) {
  const { darkModeActive, switchToDarkMode, switchToLightMode } = useDarkMode();

  useHotkeys([['mod+J', darkModeActive ? switchToLightMode : switchToDarkMode]]);

  return (
    <MantineProvider 
      withGlobalStyles 
      withNormalizeCSS 
      theme={{ colorScheme: darkModeActive ? 'dark' : 'light' }}>
      <Component {...pageProps} />
    </MantineProvider>
  );
}

export default withDarkMode(App, { defaultMode: MODE.LIGHT });
// src/pages/index.tsx

export default function Index() {
  return 'Index'
}

When starting the project and opening the index page, dark mode is activated. If I use the key combination "CMD + J" (or "CTRL + J" on Windows), the theme will change to light mode, but if the page is refreshed, this change will not be kept.

How to solve this?

@leandroluk
Copy link
Author

leandroluk commented Nov 9, 2022

I created a clone of the library inside the project and created a solution to the problem, Here's the solution:

1ª create a new variable in configuration

// config.ts

export interface Config {
  disableAutoMode: boolean
  // ...
}

export const defaultConfig: Config = {
  disableAutoMode: false,
  // ...
}

2º update the context to exists the new config

// darkModeContext.ts

export const DarkModeContext = createContext({
  disableAutoMode: defaultConfig.disableAutoMode,
  // ...
})

3ª update the HOC to no run darkmodejs.onChange if this config is passed:

// index.tsx

// ...

export default function withDarkMode(App: NextLayoutComponentType | any, config?: Partial<Config>) {
  const { autoModeCookieName, cookieOptions, darkModeCookieName, defaultMode, disableAutoMode } = {
    ...defaultConfig,
    ...config,
  };

  function DarkMode({ autoMode, darkMode, ...props }: AppProps) {
    const [state, setState] = useState({
      disableAutoMode,
      // ...
    })

    useEffect(() => {
      const { removeListeners } = darkmodejs({
        onChange: (activeTheme, themes) => {
          if (disableAutoMode) return;
          switch (activeTheme) {
            // ...
          }
        },
      });

      return removeListeners;
    }, []);

    const app = <App darkMode={state} {...props} />;

    return <DarkModeContext.Provider value={state}>{app}</DarkModeContext.Provider>;
  }

  DarkMode.getInitialProps = async (appContext: AppContext) => {
    / ...
  };

  DarkMode.displayName = `withDarkMode(${App.displayName || App.name || 'App'})`;

  return DarkMode;
}

export { MODE, useDarkMode };

4º add the configuration when use the HOF

import withDarkMode, { MODE, useDarkMode } from '$/libs/darkMode';
import { AppProps } from 'next/app';

function App({ Component, pageProps }: AppProps) {
  return <Component {...pageProps} />
}

export default withDarkMode(App, { disableAutoMode: true });

@xeoneux
Copy link
Owner

xeoneux commented Nov 10, 2022

Hi @leandroluk
This would only happen in development and not production because of how React 18 reruns the component lifecycle.
I have yet to think of a solution to this but for the time being you can switch strictMode off in next.config.js

const nextConfig = {
  reactStrictMode: false
}

@leandroluk
Copy link
Author

Ho @xeoneux,

I brought you a solution, adding just an "if" and a configuration variable to the lib in a simple way, no?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants