I'm coding a Button component in ReactJS which receives some props for styling it. for example primary
, rounded
and outline
. I join classNames with the className
function which comes from "classnames" library.
import className from 'classnames'
interface ButtonProps {
children: any // Elements that placed in the Button
outline?: boolean // Adds outline to the Button, removes background color and change font color
rounded?: boolean // Adds border radius to the Button
primary?: boolean // Adds blue background color to the Button
[key: string]: any // Add some more props for example event handlers
}
function Button({
children,
outline,
rounded,
primary,
...rest
}: ButtonProps) {
const classNames =
className(
'flex items-center select-none px-3 py-0.5 border border-2 font-medium',
{
'text-white bg-blue-600 border-blue-600': primary,
'rounded-lg': rounded,
'text-blue-500 bg-transparent': outline && primary,
},
rest.className
)
return (
<button {...rest} className={classNames}>
{children}
</button>
)
}
when I set primary
prop alone, the Button will appear like this:
and classnames from the browser inspector is flex items-center select-none px-3 py-0.5 border border-2 font-medium text-white bg-blue-600 border-blue-600
which is true and what we expect. but when I add outline
along with primary
prop, the Button will appear like this:
and classnames is flex items-center select-none px-3 py-0.5 border border-2 font-medium text-white bg-blue-600 border-blue-600 text-blue-500 bg-transparent
as you can see, bg-transparent
and text-blue-500
comes after than bg-blue-600
and text-white
, then must override them. according to the pictures, bg-blue-600
will be overrided by bg-transparent
, but text-white
does not overrided by text-blue-500
.
this screen comes from CSS styles part of Developer tools:
why this happen and how can I fix this problem?
Thanks
You should not apply multiple class names that apply the same property on the same element with the same variant at the same time. With outline
and primary
truthy values, you'll get conflicting text-white
and text-blue-600
as well as conflicting bg-blue-600
and bg-transparent
. Instead only apply of these at any one time, like:
const classNames =
className(
'flex items-center select-none px-3 py-0.5 border border-2 font-medium',
{
'border-blue-600': primary,
'text-white bg-blue-600': primary && !outline,
'rounded-lg': rounded,
'text-blue-500 bg-transparent': outline && primary,
},
rest.className
)