javascriptreactjstailwind-cssreact-contexttailwind-in-js

Why can't I pass variable as a className to tailwind-css?


I am trying to pass a context variable as a value to tailwind className in react. As per tailwind documentation bg-[hex-val] is used to pass custom color codes to background color.

I'm using Template literals to pass context variable as value.

NavBar.js

import { useContext } from 'react';
import { AiOutlineMenu } from 'react-icons/ai';
import ThemeToggle from './ThemeToggle';
import ThemeContext from '../context/ThemeContext';



const NavBar = () => {
    const { colors } = useContext(ThemeContext); 


    return <div className="w-screen h-46 bg-secondary-dark grid grid-cols-6 gap-4 content-center">
        
        {//below line is not working}

        <p className={`bg-[${colors.secondary}] text-text-white`}>Some words</p>
        <AiOutlineMenu style={{color:"white",fontSize:"1.5rem"}} className='ms-4 place-self-start col-span-5 '/>
        <ThemeToggle />
      
    </div>
}

export default NavBar;

ThemeContext.js

import { createContext,useState } from "react"

const ThemeContext = createContext();

const ThemeProvider = ({ children })=>{

    const [darkTheme, setTheme] = useState(true);
    
    const colors = {
        primary: darkTheme ? "#282828" : "#E8E8E8",
        secondary: darkTheme ? "#FFFFFF" : "#FFFFFF",
        secondary2: darkTheme ? '#232323' : '#ECECEC',
        card: darkTheme ?'#383838' : 'F3EFEF',
        buttons: darkTheme ? '#504D4D' : '#C0C0C0',
        buttonActive: darkTheme ? '#A9A9A9' : '#828282'
    }

    const handleTheme = (themeParam)=>{
        setTheme(themeParam);
    }
    return<>
            <ThemeContext.Provider value={{darkTheme, handleTheme, colors}}>
                {children}
            </ThemeContext.Provider>
        </>
}

export {ThemeProvider};
export default ThemeContext;

I have tried using classNames npm package to combine context variable and other classnames but no luck!


Solution

  • As per the documentation:

    The most important implication of how Tailwind extracts class names is that it will only find classes that exist as complete unbroken strings in your source files.

    If you use string interpolation or concatenate partial class names together, Tailwind will not find them and therefore will not generate the corresponding CSS:

    Don’t construct class names dynamically

    <div class="text-{{ error ? 'red' : 'green' }}-600"></div>
    

    In the example above, the strings text-red-600 and text-green-600 do not exist, so Tailwind will not generate those classes. Instead, make sure any class names you’re using exist in full:

    Always use complete class names

    <div class="{{ error ? 'text-red-600' : 'text-green-600' }}"></div>
    

    You could consider using full class names in definitions, like:

    const colors = {
      // …
      secondary: darkTheme ? "bg-[#FFFFFF]" : "bg-[#FFFFFF]",
      // …
    }:
    
    <p className={`${colors.secondary} text-text-white`}>
    

    Or you could look at using the style attribute like:

    <p className="text-text-white" style={{ backgroundColor: colors.secondary }}>