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

Set color-scheme: dark with Tailwind and custom themes #221

Open
sspenst opened this issue Oct 5, 2023 · 2 comments
Open

Set color-scheme: dark with Tailwind and custom themes #221

sspenst opened this issue Oct 5, 2023 · 2 comments

Comments

@sspenst
Copy link

sspenst commented Oct 5, 2023

I have a bunch of themes on my site and I'd like to get it so I can use dark: Tailwind classes with specific themes. In the snippet below I would like theme-modern to be a dark mode theme:

<ThemeProvider themes={['theme-modern', 'theme-light', 'theme-dark']} attribute='class'>

I saw your post here so I've been trying the following with no luck yet:

[data-theme="theme-modern"] {
  color-scheme: dark;
}

Wondering if Tailwind is supported for this use case or if I'm missing a step somewhere. Thanks!

@CSpencerND
Copy link

@sspenst I made a theme called dim and added the following to my global css:

:is(.dim .dark\:prose-invert) {
    --tw-prose-body: var(--tw-prose-invert-body);
    --tw-prose-headings: var(--tw-prose-invert-headings);
    --tw-prose-lead: var(--tw-prose-invert-lead);
    --tw-prose-links: var(--tw-prose-invert-links);
    --tw-prose-bold: var(--tw-prose-invert-bold);
    --tw-prose-counters: var(--tw-prose-invert-counters);
    --tw-prose-bullets: var(--tw-prose-invert-bullets);
    --tw-prose-hr: var(--tw-prose-invert-hr);
    --tw-prose-quotes: var(--tw-prose-invert-quotes);
    --tw-prose-quote-borders: var(--tw-prose-invert-quote-borders);
    --tw-prose-captions: var(--tw-prose-invert-captions);
    --tw-prose-kbd: var(--tw-prose-invert-kbd);
    --tw-prose-kbd-shadows: var(--tw-prose-invert-kbd-shadows);
    --tw-prose-code: var(--tw-prose-invert-code);
    --tw-prose-pre-code: var(--tw-prose-invert-pre-code);
    --tw-prose-pre-bg: var(--tw-prose-invert-pre-bg);
    --tw-prose-th-borders: var(--tw-prose-invert-th-borders);
    --tw-prose-td-borders: var(--tw-prose-invert-td-borders);
}

I don't know if that's what you're looking for but it did the job for my use-case.

@sspenst
Copy link
Author

sspenst commented Dec 13, 2023

@CSpencerND your comment gave me some inspiration to try this again and I finally got it working. The difficulty for my case is that I want two classes:

  • one for my custom theme (eg theme-modern)
  • one for dark mode

next-themes allows mapping custom themes to different class names, but in my case I need to map each class to multiple class names. I think my implementation could be a lot simpler if this was a feature:

<ThemeProvider
  attribute='class'
  themes={Object.values(Theme)}
  value={{
    [Theme.Modern]: ['dark', 'theme-modern'],
    [Theme.Light]: ['light', 'theme-light'],
    ...
  }}
>

What I ended up doing was creating a new attribute data-theme-dark that I keep track of manually based on the the current theme, and then updated my Tailwind config to have:

  darkMode: [
    'class',
    '[data-theme-dark="true"]',
  ],

I then used the idea from #77 (comment) to update the color-scheme:

[data-theme-dark="true"] {
  color-scheme: dark;
}

Finally, for dark mode to work instantly I had to add the following script:

<script dangerouslySetInnerHTML={{
  __html: `
!function() {
  const theme = localStorage.getItem('theme');

  // set data-theme-dark for Tailwind dark classes
  document.documentElement.setAttribute('data-theme-dark', theme === 'theme-light' ? 'false' : 'true');

  // check for an invalid theme and default to theme-modern
  // ThemeProvider doesn't handle this case with defaultTheme so we have to do it manually here
  if (!${JSON.stringify(Object.values(Theme))}.includes(theme)) {
    localStorage.setItem('theme', 'theme-modern');
  }
}();
  `,
}} />

It would be great if there was a simple way to do this with next-themes, but for now this seems to get the job done.

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