ui icon indicating copy to clipboard operation
ui copied to clipboard

[bug]: Astro Dark Mode Guide Flicker

Open discoverlance-com opened this issue 1 year ago • 5 comments

Describe the bug

Based on the current dark mode setup guide for Astro, https://ui.shadcn.com/docs/dark-mode/astro, there's a flicker of the dark mode on the page as seen in the video below.

The flicker happens and is noticeable when my theme is set to dark or system (that is dark mode).

The issue seems to be tied to the src/components/ModeToggle.tsx component and the dark mode state changes.

Basically, the theme is initially set to "theme-light" in React.useState,

  const [theme, setThemeState] = React.useState<
    "theme-light" | "dark" | "system"
  >("theme-light");

I tried to console.log the theme in the second React.useEffect check where the dark mode is set on the documentElement and realised that initially, it's set to "theme-light" which comes from the initial theme state and then, it's later set to the dark(as seen in the console in the video). This causes a flicker as the theme will first be set to light mode by removing the dark class from the documentElement and then later added. Even though, it's quite fast, it's still noticeable as a flicker on the page.

I suggest an update to the documentation by initially setting the theme to null (so in typescript, we can accept null as one of the union types), then performing a null check and only updating the documentElement if the theme is not null. This fixes the issue of flicker in dark mode. Updated code below:

  const [theme, setThemeState] = React.useState<
    "theme-light" | "dark" | "system" | null
  >(null);

  React.useEffect(() => {
    const isDarkMode = document.documentElement.classList.contains("dark");
    setThemeState(isDarkMode ? "dark" : "theme-light");
  }, []);

  React.useEffect(() => {
    if (theme !== null) {
      const isDark =
        theme === "dark" ||
        (theme === "system" &&
          window.matchMedia("(prefers-color-scheme: dark)").matches);
      document.documentElement.classList[isDark ? "add" : "remove"]("dark");
    }
  }, [theme]);

Screen recording 2024-10-20 21.59.36.webm

Affected component/components

Dark Mode

How to reproduce

  1. Go to shadcn astro installation to set up a new astro project with shadcn.
  2. Setup dark mode with the shadcn astro dark mode documentation.
  3. Change your theme to dark mode and refresh page

Codesandbox/StackBlitz link

https://stackblitz.com/edit/withastro-astro-awu25v?file=src%2Fcomponents%2FModeToggle.tsx

Logs

// console logs

{
    "theme": "theme-light"
}

{
    "theme": "dark"
}

System Info

-

Before submitting

  • [X] I've made research efforts and searched the documentation
  • [X] I've searched for existing issues

discoverlance-com avatar Oct 20 '24 22:10 discoverlance-com

Same issue here. Any update?

hbk671104 avatar Dec 01 '24 03:12 hbk671104

Same issue here. Any update?

You can try the solution I suggested. Does that work?

discoverlance-com avatar Dec 01 '24 17:12 discoverlance-com

Image

pythoncarpenter avatar Feb 11 '25 02:02 pythoncarpenter

Any updates on this? Is there any native way to initially render dark theme? I have same issue with remix(react router framework)

skorphil avatar Feb 23 '25 16:02 skorphil

I'm seeing the same issue with next-theme provider

seawatts avatar Mar 11 '25 20:03 seawatts

Thanks, your solution for Astro.js works!

OreQr avatar May 02 '25 20:05 OreQr

Any updates?

Adam-Elmi avatar May 25 '25 12:05 Adam-Elmi