themesberg / flowbite-react

Official React components built for Flowbite and Tailwind CSS
https://flowbite-react.com
MIT License
1.82k stars 406 forks source link

The ThemeModeScript component ignores the mode parameter. Can't set dark theme as default #1168

Closed iwebexpert closed 4 months ago

iwebexpert commented 8 months ago

Steps to reproduce

I need a dark theme by default. In the previous version I added the dark class to the html tag. It worked. Now (v0.7.0) <ThemeModeScript mode="dark" /> removes my dark class from the html tag because of this, the light theme always goes first if the user has not changed it via <DarkThemeToggle />

My code:

export default function RootLayout({ children }: RootLayoutProps) {
  return (
    <html
      className="dark"
      lang="en"
    >
      <head>
        <ThemeModeScript mode="dark" />
      </head>
      <body className={inter.className}>
        <MainMenu />
        <main>{children}</main>
        <Footer />
      </body>
    </html>
  )
}

tailwind.config.ts

/**
 * @type {import('@types/tailwindcss/tailwind-config').TailwindConfig}
 */
import type { Config } from 'tailwindcss'

const config: Config = {
  content: ['node_modules/flowbite-react/lib/esm/**/*.js', './src/**/*.{ts,tsx}'],
  theme: {},
  plugins: [require('flowbite/plugin')],
  darkMode: 'class',
}
export default config

Current behavior

I clear localStorage and after refreshing the page, “flowbite-theme-mode: light” is always added. If I change the theme to dark, everything works. I need the main theme to be in dark mode the first time a user visits a site.

Expected behavior

If the user visits the site for the first time, a dark theme should be displayed.

Context

package.json:

 "dependencies": {
    "@hookform/resolvers": "^3.3.2",
    "@next/bundle-analyzer": "~14.0.3",
    "flowbite-react": "^0.7.0",
    "js-cookie": "^3.0.5",
    "next": "~14.0.3",
    "next-image-export-optimizer": "^1.11.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-fast-marquee": "^1.6.2",
    "react-hook-form": "^7.48.2",
    "react-phone-number-input": "^3.3.7",
    "react-snowfall": "^1.2.1",
    "zod": "^3.22.4",
    "zustand": "^4.4.7"
  },
  "devDependencies": {
    "@types/js-cookie": "^3.0.6",
    "@types/node": "^20.10.2",
    "@types/react": "^18.2.41",
    "@types/react-dom": "^18.2.17",
    "autoprefixer": "^10.4.16",
    "eslint": "^8.55.0",
    "eslint-config-next": "~14.0.3",
    "postcss": "^8.4.32",
    "tailwindcss": "^3.3.5",
    "typescript": "^5.3.2"
  }
SutuSebastian commented 6 months ago

I think I know where the problem is, now I have a couple of questions for u:

  1. are u using <Flowbite /> component with the theme={{ mode: "dark" }} on?
  2. are u using <Flowbite /> at all? if yes, where and how exactly

Thing is, u need to align the initial theme mode both with <ThemeModeScript /> and <Flowbite /> components.

I am currently looking into why probably just using <ThemeModeScript /> alone is not working properly.

SutuSebastian commented 6 months ago

Back with some updates:

Currently <ThemeModeScript /> computes the final mode prop in the following order:

localStorage => mode (prop) => defaultMode ("light"), then if value is auto it will infer the value from window.matchMedia(prefers-color-scheme) otherwise the computation before.

iwebexpert commented 4 months ago

I think I know where the problem is, now I have a couple of questions for u:

1. are u using `<Flowbite />` component with the `theme={{ mode: "dark" }}` on?

2. are u using `<Flowbite />` at all? if yes, where and how exactly

Thing is, u need to align the initial theme mode both with <ThemeModeScript /> and <Flowbite /> components.

I am currently looking into why probably just using <ThemeModeScript /> alone is not working properly.

You're absolutely right! I actually used a custom theme without the mode parameter. I'm currently using the following code for the theme:

const customTheme: CustomFlowbiteTheme = {...}
<Flowbite theme={{ theme: customTheme, mode: 'dark' }}>...</Flowbite>

And my main layout:

<head>
    <ThemeModeScript mode="dark" />
</head>

Everything works as expected. Thanks for solving the issue!