DEV Community

Matheus Verissimo
Matheus Verissimo

Posted on • Edited on

Tailwindcss with react hooks

I like to use tailwindcss with react, but sometimes I feel lost with the amount of class on a single line, look.

<button className="inline-flex items-center p-2.5 text-sm text-slate-600 hover:text-slate-700 dark:text-slate-300 dark:hover:text-slate-200 .....">button</button>
Enter fullscreen mode Exit fullscreen mode

The first thing I thought to solve this "problem" was to create an object with these classes.

export const styles = {
  base: `
   inline-flex
   items-center

   p-2.5

   text-sm
   text-slate-600
   hover:text-slate-700
   dark:text-slate-300
   dark:hover:text-slate-200

   border
   rounded-lg

   bg-white
   hover:bg-gray-50
   dark:bg-gray-900
   dark:hover:bg-gray-800

   ease-in
   transition
   duration-150

   focus-visible:ring-1
   focus-visible:ring-blue-500
   focus-visible:border-blue-500
   focus-visible:outline-none
   dark:border-gray-800
   dark:focus-visible:border-blue-500
  `
}
Enter fullscreen mode Exit fullscreen mode

More readable, and clean.

import styles from './button.styles';

function Button(props) {
  return <button className={styles.base} {...props} />
}
Enter fullscreen mode Exit fullscreen mode

So, how I manage other classes or merge? To do this, I created a hook to handling theses classes.

import clsx from 'clsx';

export function createStyles<Classes = string>(input: Classes) {
  let useStyles = () => ({
    cx: clsx,
    classes: input,
  });

  return useStyles;
}
Enter fullscreen mode Exit fullscreen mode

Let's update our styles:

import { createStyles } from '@/utils/createStyles';

export const useStyles = createStyles({
  base: `
   inline-flex
   items-center

   p-2.5

   text-sm
   text-slate-600
   hover:text-slate-700
   dark:text-slate-300
   dark:hover:text-slate-200

   border
   rounded-lg

   bg-white
   hover:bg-gray-50
   dark:bg-gray-900
   dark:hover:bg-gray-800

   ease-in
   transition
   duration-150

   focus-visible:ring-1
   focus-visible:ring-blue-500
   focus-visible:border-blue-500
   focus-visible:outline-none
   dark:border-gray-800
   dark:focus-visible:border-blue-500
  `,
  appearances: {
    primary: 'bg-purple-600',
    success: 'bg-green-600',
  }
});
Enter fullscreen mode Exit fullscreen mode

and our component:

import { useStyles } from './button.styles';

function Button(props) {
  let { appearance = 'primary' } = props;
  let { cx, classes } = useStyles();

  return <button className={cx(classes.base, classes.appearances[appearance])} {...props} />
}
Enter fullscreen mode Exit fullscreen mode

With this approach, We keep each piece of the code with your responsibility, providing easy maintain.

Check the source:
https://github.com/mverissimo/react-tailwind-classnames

Top comments (0)