The Main Issue
I was just working on Building Button Component to use in my project and faced a problem with tailwindcss. so I am writing this article that could help others also facing this problem.
let’s see what we want to build first
children,
primary,
secondary,
success,
warning,
danger,
outline,
rounded
}) {
const classes = classNames(‘flex items-center px-3 py-1.5 border’, {
‘border-blue-500 bg-blue-500 text-white’: primary,
‘border-gray-900 bg-gray-900 text-white’: secondary,
‘border-green-500 bg-green-500 text-white’: success,
‘border-yellow-400 bg-yellow-400 text-white’: warning,
‘border-red-500 bg-red-500 text-white’: danger
});
return (
<button {…rest} className={classes}>
{children}
</button>
);
}
Imagine that you have a button with different button variation(primary,secondary,…) like image below
and you want to add more styles(outline,rounded). but in this situation we will face conflict in tailwindcss
let’s see code first then result
children,
primary,
secondary,
success,
warning,
danger,
outline,
rounded
}) {
const classes = classNames(‘flex items-center px-3 py-1.5 border’, {
‘border-blue-500 bg-blue-500 text-white’: primary,
‘border-gray-900 bg-gray-900 text-white’: secondary,
‘border-green-500 bg-green-500 text-white’: success,
‘border-yellow-400 bg-yellow-400 text-white’: warning,
‘border-red-500 bg-red-500 text-white’: danger,
’rounded-full’: rounded,
‘bg-white’: outline
});
return (
<button className={classes}>
{children}
</button>
);
}
In this case background color of outline will override the previous styles so we need to add more styles to resolve conflict like code below
children,
primary,
secondary,
success,
warning,
danger,
outline,
rounded
}) {
const classes = classNames(‘flex items-center px-3 py-1.5 border’, {
‘border-blue-500 bg-blue-500 text-white’: primary,
‘border-gray-900 bg-gray-900 text-white’: secondary,
‘border-green-500 bg-green-500 text-white’: success,
‘border-yellow-400 bg-yellow-400 text-white’: warning,
‘border-red-500 bg-red-500 text-white’: danger,
’rounded-full’: rounded,
‘bg-white’: outline,
‘text-blue-500’: outline && primary,
‘text-gray-900’: outline && secondary,
‘text-green-500’: outline && success,
‘text-yellow-400’: outline && warning,
‘text-red-500’: outline && danger,
});
return (
<button className={classes}>
{children}
</button>
);
}
So let’s see the result
As you see Although we set background color for both outline and variation but background color of outline overrides previous styles
So what is the solution?
In this situation the solution is tailwind-merge package. in this situation we wrap code with tailwind merge package and it solves the issue for us like code below.
children,
primary,
secondary,
success,
warning,
danger,
outline,
rounded,
…rest
}) {
const classes = twMerge(classNames(rest.className,’flex items-center px-3 py-1.5 border’, {
‘border-blue-500 bg-blue-500 text-white’: primary,
‘border-gray-900 bg-gray-900 text-white’: secondary,
‘border-green-500 bg-green-500 text-white’: success,
‘border-yellow-400 bg-yellow-400 text-white’: warning,
‘border-red-500 bg-red-500 text-white’: danger,
’rounded-full’: rounded,
‘bg-white’: outline,
‘text-blue-500’: outline && primary,
‘text-gray-900’: outline && secondary,
‘text-green-500’: outline && success,
‘text-yellow-400’: outline && warning,
‘text-red-500’: outline && danger,
}));
return (
<button {…rest} className={classes}>
{children}
</button>
);
}
as you see the problem is solved