DEV Community

heydrigh ribeiro
heydrigh ribeiro

Posted on

Writing cleaner code with Tailwind CSS in React

As a React developer, you might have faced challenges with managing multiple conditionals for styles in your components. Inline styles, while straightforward, can quickly become messy and hard to maintain. In this article, I'll share a solution to this problem by using a dictionary to handle styles more effectively. We'll also address a common issue with Tailwind CSS IntelliSense in VSCode and how to fix it.

The Issue: Multiple conditionals for styles

Let's start with a common scenario. You have a Button component with different styles based on its type prop. Here's an example:

import { ButtonProps } from './types'

const Button = ({ type = 'primary', children, ...rest }: ButtonProps) => {
  return (
    <button
      className={
        type === 'primary'
          ? 'bg-blue-500 text-white px-4 py-2 rounded'
          : type === 'secondary'
          ? 'bg-gray-500 text-white px-4 py-2 rounded'
          : 'border border-blue-500 text-blue-500 bg-transparent px-4 py-2 rounded'
      }
      {...rest}
    >
      {children}
    </button>
  )
}

export default Button
Enter fullscreen mode Exit fullscreen mode

While this approach works, it can become unwieldy as the number of conditionals increases. It's also harder to maintain and less readable.

The Solution: Using a dictionary for styles

A cleaner approach is to use a dictionary to manage styles. This method improves code readability and takes advantage of TypeScript's typing system. Here's how you can refactor the Button component:

import { ButtonProps, ButtonTypes } from './types'

const Button = ({ type = 'primary', children, ...rest }: ButtonProps) => {
  const typeVariantClasses: Record<ButtonTypes, string> = {
    primary: 'bg-blue-500 text-white px-4 py-2 rounded',
    secondary: 'bg-gray-500 text-white px-4 py-2 rounded',
    outlined: 'border border-blue-500 text-blue-500 bg-transparent px-4 py-2 rounded',
  }

  const buttonClass = typeVariantClasses[type]

  return (
    <button className={buttonClass} {...rest}>
      {children}
    </button>
  )
}

export default Button

Enter fullscreen mode Exit fullscreen mode

By using a dictionary, you separate the styling logic from the component rendering, making your code cleaner and more maintainable.

The New Issue: Loss of Tailwind CSS IntelliSense

One downside of this approach is the loss of Tailwind CSS IntelliSense in VSCode. When you define your classes in a dictionary, VSCode no longer recognizes them as Tailwind classes, which means you lose the helpful IntelliSense suggestions.

The Workaround: Configuring Tailwind CSS IntelliSense

Thankfully, there's a way to bring back Tailwind CSS IntelliSense for these dynamic class names. Add the following line to your VSCode user settings:

"tailwindCSS.classAttributes": ["class", "className", ".*Styles.*", ".*Classes.*"]

This configuration tells VSCode to recognize any attribute that includes Styles or Classes as a Tailwind class. Here's what it looks like in practice:

With this setting, you'll get Tailwind CSS IntelliSense suggestions for dynamically generated class names, making your development process smoother and more efficient.

Result

Conclusion

By refactoring your components to use a dictionary for styles, you can write cleaner and more maintainable code. And with the VSCode configuration tweak, you don't have to sacrifice the convenience of Tailwind CSS intelliSense. Give this approach a try in your next project and enjoy the benefits of cleaner code and improved developer experience.

Top comments (1)

Collapse
 
dfarrell profile image
Daniel Farrell

Didn't think about this – thanks for sharing!