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

Allow nested providers #254

Open
shekharkhedekar opened this issue Feb 13, 2024 · 5 comments
Open

Allow nested providers #254

shekharkhedekar opened this issue Feb 13, 2024 · 5 comments
Labels
enhancement New feature or request v1 Planned for v1

Comments

@shekharkhedekar
Copy link

shekharkhedekar commented Feb 13, 2024

I've got cases (stories in storybook) where I want to have multiple ThemeProviders
e.g.

// Top level storybook theme
<ThemeProvider forcedTheme="light">

   // Individual Story
    <ThemeProvider forcedTheme="light">
        // LIGHT VERSION OF COMPONENT
    </ThemeProvider>
    <ThemeProvider forcedTheme="dark">
        // DARK VERSION OF COMPONENT
    </ThemeProvider>
</ThemeProvider>

This currently does not work because of this code.

Currently, I'm forking your package and removing those lines to allow for nested providers. I'm also adding a component to add the theme class on container of the provider if the forcedTheme is set so the children will get the correct styles.

Not sure if this contradicts your original design, but it would be useful to us.

@shrekuu
Copy link

shrekuu commented Feb 18, 2024

Hi @shekharkhedekar , I am using next-themes with TailwindCSS. It seems I can simply achieve nested themes like this:

  1. I add some config in Tailwind config:
import plugin from 'tailwindcss/plugin';

export default {
  darkMode: 'class',
  plugins: [  
    plugin(function ({ addUtilities }) {
      const utilities = {
        // light, dark color scheme
        '.light': {
          'color-scheme': 'light',
        },
        '.dark': {
          'color-scheme': 'dark',
        },
      };
      addUtilities(utilities);
    }),
  ],
};

Then I can simply use this light or dark in any element like this:

'use client';

export default function Page() {
  return (
    <div className="border border-red-400 p-2">
      <h1>default theme</h1>
      <input type="text" />
      <div className="border border-red-400 p-2 light">
        <h1>light</h1>
        <input type="text" />
        <div className="border border-red-400 p-2 dark">
          <h1>dark</h1>
          <input type="text" />
          <div className="border border-red-400 p-2 light">
            <h1>light</h1>
            <input type="text" />
          </div>
        </div>
      </div>
    </div>
  );
}
image

When I toggle the theme to light in next-themes, the nested dark section stays dark. Cool! This is just what I wanted.
image

In my app, I am forcing it to use dark theme by default in my outermost layout.tsx file.

<NextThemesProvider defaultTheme="dark" attribute="class">
...
</NextThemesProvider>

@shekharkhedekar
Copy link
Author

@shrekuu we we're doing that as well, but we also needed to reference resolvedTheme in the nested theme, which always referenced the top level theme and produced inaccurate results.

@universse
Copy link

I made a library that supports this use case https://github.com/universse/palettez.
Here's a demo https://palettez-nextjs-demo.vercel.app/multi-store-with-server-persistence.
Hope it helps.

@RafaelFerreiraTVD
Copy link

@trm217 any news about this?
Would like to understand why are you not allowing to nest the ThemeProvider?

@trm217
Copy link
Collaborator

trm217 commented Oct 22, 2024

@RafaelFerreiraTVD no news unfortunately. The owner of this project has been unresponsive for almost half a year now. Once the repo is being actively maintained again, I can look into this, once I have the time for it.

As to why it is not possible as of now, this is simply due to how it's currently implemented. All theme providers share the same context, so if you nest them, the useTheme hook will always only relate to the closest context provider.
We would have to change the API quite substantially for nested ThemeProviders to work.

@trm217 trm217 added enhancement New feature or request and removed triage labels Nov 7, 2024
@trm217 trm217 self-assigned this Nov 7, 2024
@trm217 trm217 added the v1 Planned for v1 label Nov 7, 2024
@trm217 trm217 removed their assignment Dec 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request v1 Planned for v1
Projects
None yet
Development

No branches or pull requests

5 participants