JNavith / tailwindcss-theme-variants

Media-query- or JavaScript-based theme variants with fallback for Tailwind CSS
https://tailwindcss-theme-variants.web.app/
MIT License
192 stars 5 forks source link

Shows no background even when theme is applied #12

Closed deadcoder0904 closed 3 years ago

deadcoder0904 commented 3 years ago

First of all, the README was very confusing to me so it must be my mistake but I can't get it to work.

tailwind.config.js

plugins: [
    themeVariants({
        group: 'colors',
        themes: {
            red: {
                selector: '.red-theme',
            },
            blue: {
                selector: '.blue-theme',
            },
            yellow: {
                selector: '.yellow-theme',
            },
            pink: {
                selector: '.pink-theme',
            },
            indigo: {
                selector: '.indigo-theme',
            },
            orange: {
                selector: '.orange-theme',
            },
            green: {
                selector: '.green-theme',
            },
        },
    }),
],

Button.tsx

<button
    className={clsx(
        'inline-flex items-center px-4 py-2 text-sm font-medium text-white indigo:bg-indigo-600
         red:bg-red-500 border border-transparent rounded-md shadow-sm select-none hover:indigo:bg-indigo-700
         red:hover:bg-red-500 focus:outline-none focus:ring-2 focus:ring-offset-2 indigo:focus:ring-indigo-500
         red:focus:ring-red-500',
    )}
    onClick={() => {
        downloadImage(image)
    }}
>
    Download Image
</button>

I have used indigo & red in the button above. I've also tried using indigo-theme & red-theme but it still gives no background.

Also, I don't know how to use it with hover: & focus: because Idk if I've to put indigo:focus: or focus:indigo:.

Do let me know if it's a mistake on my part, thanks.

JNavith commented 3 years ago

First of all, the README was very confusing to me so it must be my mistake but I can't get it to work.

No, it's not your fault! I'm planning a revamp of the documentation but time limitations / other obligations and priorities have prevented me from doing so.

Also, I don't know how to use it with hover: & focus: because Idk if I've to put indigo:focus: or focus:indigo:.

It's indigo:focus: and indigo:hover:.

plugins: [
    themeVariants({
        group: 'colors',
        themes: {
            red: {
                selector: '.red-theme',
            },
            blue: {
                selector: '.blue-theme',
            },
            yellow: {
                selector: '.yellow-theme',
            },
            pink: {
                selector: '.pink-theme',
            },
            indigo: {
                selector: '.indigo-theme',
            },
            orange: {
                selector: '.orange-theme',
            },
            green: {
                selector: '.green-theme',
            },
        },
    }),
],

Note that because baseSelector was omitted that it defaulted to :root. This means you need to put the indigo-theme class on the root element (almost certainly the html tag) to activate the indigo theme. And so on for the other colors:

<html class="indigo-theme">
   <body>
        <!-- a bunch of other elements and nesting (it doesn't really matter)... -->

        <button class="text-white bg-gray-600 indigo:bg-indigo-600 indigo:hover:bg-indigo-800 indigo:focus:ring-indigo-500">Indigo on the indigo theme, otherwise it's gray</button>
  </body>
</html>

If you want any parent element with the theme selector to activate themes, specify baseSelector: "":


plugins: [
    themeVariants({
        group: 'colors',
                baseSelector: "",
        themes: {
            ...
        },
    }),
],

and write markup like this:

<html> <!-- classes here don't matter anymore -->
  <body>
    <!-- a bunch of other elements and nesting (it doesn't really matter)... -->

    <div class="indigo-theme">
      <button class="text-white bg-gray-600 indigo:bg-indigo-600 indigo:hover:bg-indigo-800 indigo:focus:ring-indigo-500">Indigo on the indigo theme, otherwise it's gray</button>
    </div>
  </body>
</html>

This is not the default option because it prevents the fallback feature from working, should you ever want to use that.

Also, make sure you've enabled the ["colors", "colors:hover", "colors:focus"] variants for the backgroundColor, ringColor, and textColor utilities!

deadcoder0904 commented 3 years ago

Thank you that looks well-explained. I just went back to theming with Mobx like:

<Listbox.Button
    className={clsx(
        'relative w-full py-2 pl-3 pr-10 text-left bg-white border border-gray-300 rounded-md shadow-sm cursor-default select-none focus:outline-none focus:ring-1 sm:text-sm',
        {
            'focus:ring-red-500 focus:border-red-500': sidebar === 'red',
            'focus:ring-blue-500 focus:border-blue-500': sidebar === 'blue',
            'focus:ring-yellow-500 focus:border-yellow-500': sidebar === 'yellow',
            'focus:ring-pink-500 focus:border-pink-500': sidebar === 'pink',
            'focus:ring-indigo-500 focus:border-indigo-500': sidebar === 'indigo',
            'focus:ring-orange-500 focus:border-orange-500': sidebar === 'orange',
            'focus:ring-green-500 focus:border-green-500': sidebar === 'green',
        }
    )}
>

Which in my opinion looks more cleaner thanks to clsx. I'd probably jump back on this later :)

JNavith commented 3 years ago

Thank you that looks well-explained. I just went back to theming with Mobx like:

<Listbox.Button
  className={clsx(
      'relative w-full py-2 pl-3 pr-10 text-left bg-white border border-gray-300 rounded-md shadow-sm cursor-default select-none focus:outline-none focus:ring-1 sm:text-sm',
      {
          'focus:ring-red-500 focus:border-red-500': sidebar === 'red',
          'focus:ring-blue-500 focus:border-blue-500': sidebar === 'blue',
          'focus:ring-yellow-500 focus:border-yellow-500': sidebar === 'yellow',
          'focus:ring-pink-500 focus:border-pink-500': sidebar === 'pink',
          'focus:ring-indigo-500 focus:border-indigo-500': sidebar === 'indigo',
          'focus:ring-orange-500 focus:border-orange-500': sidebar === 'orange',
          'focus:ring-green-500 focus:border-green-500': sidebar === 'green',
      }
  )}
>

Which in my opinion looks more cleaner thanks to clsx. I'd probably jump back on this later :)

@deadcoder0904 Have you seen the "Semantics" section of the documentation? It's meant to make theming like this more maintainable (by collecting it all into one spot):

plugins: [
    themeVariants({
        group: 'colors',
        themes: {
            red: {
                selector: '.red-theme',
                                semantics: {
                                        colors: {
                                                "sidebar-ring": "red-500",
                                                "sidebar-border": "red-500",
                                        },
                                },
            },
            blue: {
                selector: '.blue-theme',
                                semantics: {
                                        colors: {
                                                "sidebar-ring": "blue-500",
                                                "sidebar-border": "blue-500",
                                        },
                                },
            },
            yellow: {
                selector: '.yellow-theme',
                                semantics: {
                                        colors: {
                                                "sidebar-ring": "yellow-500",
                                                "sidebar-border": "yellow-500",
                                        },
                                },
            },
            pink: {
                selector: '.pink-theme',
                                semantics: {
                                        colors: {
                                                "sidebar-ring": "pink-500",
                                                "sidebar-border": "pink-500",
                                        },
                                },
            },
            indigo: {
                selector: '.indigo-theme',
                                semantics: {
                                        colors: {
                                                "sidebar-ring": "indigo-500",
                                                "sidebar-border": "indigo-500",
                                        },
                                },
            },
            orange: {
                selector: '.orange-theme',
                                semantics: {
                                        colors: {
                                                "sidebar-ring": "orange-500",
                                                "sidebar-border": "orange-500",
                                        },
                                },
            },
            green: {
                selector: '.green-theme',
                                semantics: {
                                        colors: {
                                                "sidebar-ring": "green-500",
                                                "sidebar-border": "green-500",
                                        },
                                },
            },
        },
    }),
],

I know it's marked as experimental but I have no intention to change this ^ configuration. (But, actually, I have no tests to confirm that ringColor works).

So that makes the HTML like this:

<button class="relative w-full py-2 pl-3 pr-10 text-left bg-white border border-gray-300 rounded-md shadow-sm cursor-default select-none focus:outline-none focus:ring-1 sm:text-sm
               focus:ring-sidebar-ring focus:border-sidebar-border"
>

    Button
</button>
deadcoder0904 commented 3 years ago

@JakeNavith I haven't but that looks really great. However, it's another abstraction but I think it will make the classNames more compact. Maybe I'll give this project a shot in my next project. For now, it'll be too much unnecessary work :)