shadcn-ui / taxonomy

An open source application built using the new router, server components and everything new in Next.js 13.
https://tx.shadcn.com
MIT License
18.43k stars 2.57k forks source link

NextJS Theme Detection (Change Image Based On The Current Theme) #204

Open danialhawari opened 1 year ago

danialhawari commented 1 year ago

Hey everyone,

I would like to change images based on the current mode in the browser (light mode and dark mode) but it did not work. I have tried several ways to do this but to no avail. Only dark image is displayed but not the light image. I have used different browser, took a look for the prefers-color-scheme and my theme in global.css file but still ...

What I did was:

theme-image.module.css:

.imgDark {
    display: none;
  }

  @media (prefers-color-scheme: dark) {
    .imgLight {
      display: none;
    }
    .imgDark {
      display: unset;
    }
  }

theme-image.tsx:

/* eslint-disable jsx-a11y/alt-text */
import styles from "@/styles/theme-image.module.css"
import Image, { ImageProps } from "next/image"

type Props = Omit<ImageProps, 'src' | 'priority' | 'loading'> & {
  srcLight: string
  srcDark: string
}

export const ThemeImage = (props: Props) => {
  const { srcLight, srcDark, ...rest } = props

  return (
    <>
      <Image src={srcLight} className={styles.imgLight} {...rest} />
      <Image src={srcDark} className={styles.imgDark} {...rest}  />
    </>
  )
}

page.tsx

import { ThemeImage } from "@/components/theme-image"
import Image from "next/image"

export default async function IndexPage() {

  return (
    <>
   <div>
      <ThemeImage
      srcLight="light.svg"
      srcDark="dark.svg"
      width={1000}
      height={1000}
      alt="LOGO"
      /> 
   </div>
   </>

)
}

Do you have any solution for this?

Thank you very much

danialhawari commented 1 year ago

It works now with TailwindCSS.

import Image from "next/image"

export default async function IndexPage() {

  return (
    <>
   <div>
        <Image
        src="icon-light.svg"
        width={64}
        height={64}
        alt="Icon"
        className="block dark:hidden"
        />
        <Image
        src="icon-dark.svg"
        width={64}
        height={64}
        alt="Icon"
        className="hidden dark:block"
        /> 
   </div>
   </>
)
}