search

Home  >  Q&A  >  body text

Dynamically construct class names in TailwindCss

<p>I'm currently building a component library using TailwindCss for my next project, and I just ran into a small problem with the Button component. </p> <p>I passed props like <code>'primary'</code> or <code>'secondary'</code> which works the same as what I did in <code>tailwind.config.js< ;/code> and then I want to assign it to the button component using <code>Template Lites</code> like this: <code>bg-${color}-500</ code></p> <pre class="brush:php;toolbar:false;"><button className={` w-40 rounded-lg p-3 m-2 font-bold transition-all duration-100 border-2 active:scale-[0.98] bg-${color}-500 `} onClick={onClick} type="button" tabIndex={0} > {children} </button></pre> <p>The class name displays fine in the browser, it shows <code>bg-primary-500</code> in the DOM, but not in the Applied Styles tab. </p> <p>Theme configuration is as follows:</p> <pre class="brush:php;toolbar:false;">theme: { extend: { colors: { primary: { 500: '#B76B3F', }, secondary: { 500: '#344055', }, }, }, },</pre> <p>But it doesn't apply any styles. If I just manually add <code>bg-primary-500</code> it works fine. </p> <p>Honestly, I'm just wondering if this is because the JIT compiler isn't picking up dynamic class names, or if I'm doing something wrong (or if this isn't the way to use tailWind). </p> <p>Any help is welcome, thanks in advance! </p>
P粉147747637P粉147747637466 days ago562

reply all(2)I'll reply

  • P粉034571623

    P粉0345716232023-08-25 09:28:28

    It is not recommended to write Tailwind CSS classes in this way. Even JIT mode is not supported, to quote the Tailwind CSS documentation: "Tailwind does not include a client runtime of any kind, so class names need to be statically extracted at build time and cannot be relied upon in the client ”

    reply
    0
  • P粉530519234

    P粉5305192342023-08-25 00:45:37

    So after finding out that this way of working is deprecated and the JIT does not support it (thanks to the generous commenter). I've changed the approach to a more "configuration" based approach.

    Basically, I define a const with a base configuration of different props and apply them to the component. This requires more maintenance, but it gets the job done.

    This is a configuration example. (no typing required for now) and some better refactoring, but you'll get the idea.

    const buttonConfig = {
      // Colors
      primary: {
        bgColor: 'bg-primary-500',
        color: 'text-white',
        outline:
          'border-primary-500 text-primary-500 bg-opacity-0 hover:bg-opacity-10',
      },
      secondary: {
        bgColor: 'bg-secondary-500',
        color: 'text-white',
        outline:
          'border-secondary-500 text-secondary-500 bg-opacity-0 hover:bg-opacity-10',
      },
    
      // Sizes
      small: 'px-3 py-2',
      medium: 'px-4 py-2',
      large: 'px-5 py-2',
    };
    

    Then I apply the style like this:

    <motion.button
        whileTap={{ scale: 0.98 }}
        className={`
        rounded-lg font-bold transition-all duration-100 border-2 focus:outline-none
        ${buttonConfig[size]}
        ${outlined && buttonConfig[color].outline}
        ${buttonConfig[color].bgColor} ${buttonConfig[color].color}`}
        onClick={onClick}
        type="button"
        tabIndex={0}
      >
        {children}
      </motion.button>

    reply
    0
  • Cancelreply