0

So I have the following styling:

function Button({
  children,
  primary,
  secondary,
  success,
  warning,
  danger,
  outline,
  rounded,
}) {
  const classes = 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-500": outline && secondary,
    "text-green-500": outline && success,
    "text-yellow-400": outline && warning,
    "text-red-500": outline && danger,
  });

  return <button className={classes}>{children}</button>;
}

In Tailwind the last styles listed override the text color and the purpose of that is so if a button is outline then we do not want a text color of white because the background is white in an outline button, so we want the color of the text to change if the button is designated as outline. That is the purpose of the last four lines of classes, but it no longer works ever since I installed react-icons.

By no longer working I mean the "text-white" remains where outline is applied.

Now, I am wondering if the Button.propTypes solution is what clobbering it:

Button.propTypes = {
  checkVariationValue: ({ primary, secondary, success, warning, danger }) => {
    const count =
      Number(!!primary) +
      Number(!!secondary) +
      Number(!!warning) +
      Number(!!success) +
      Number(!!danger);

    if (count > 1) {
      return new Error(
        "Only one of primary, success, warning, danger can be true"
      );
    }
  },
};
Daniel
  • 14,004
  • 16
  • 96
  • 156

1 Answers1

1

When outline is truthy, you will end up in a situation where you will have conflicting classes, like text-white text-blue-500 (for truthy primary). Consider only having a single class with the same variant that applies the same property:

function Button({
  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": primary,
    "border-gray-900 bg-gray-900": secondary,
    "border-green-500 bg-green-500": success,
    "border-yellow-400 bg-yellow-400": warning,
    "border-red-500 bg-red-500": danger,
    "rounded-full": rounded,
    "text-white": !outline && (primary || secondary || success || warning || danger),
    "bg-white": outline,
    "text-blue-500": outline && primary,
    "text-gray-500": outline && secondary,
    "text-green-500": outline && success,
    "text-yellow-400": outline && warning,
    "text-red-500": outline && danger,
  });

  return <button className={classes}>{children}</button>;
}

ReactDOM.createRoot(document.getElementById('app')).render(
  <React.Fragment>
    <Button primary>Foo</Button>
    <Button primary outline>Foo</Button>
    <Button secondary>Foo</Button>
    <Button secondary outline>Foo</Button>
    <Button success>Foo</Button>
    <Button success outline>Foo</Button>
    <Button warning>Foo</Button>
    <Button warning outline>Foo</Button>
    <Button danger>Foo</Button>
    <Button danger outline>Foo</Button>
  </React.Fragment>
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js" integrity="sha512-8Q6Y9XnTbOE+JNvjBQwJ2H8S+UV4uA6hiRykhdtIyDYZ2TprdNmWOUaKdGzOhyr4dCyk287OejbPvwl7lrfqrQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js" integrity="sha512-MOCpqoRoisCTwJ8vQQiciZv0qcpROCidek3GTFS6KTk2+y7munJIlKCVkFCYY+p3ErYFXCjmFjnfTTRSC1OHWQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/classnames/2.3.2/index.min.js" integrity="sha512-GqhSAi+WYQlHmNWiE4TQsVa7HVKctQMdgUMA+1RogjxOPdv9Kj59/no5BEvJgpvuMTYw2JRQu/szumfVXdowag==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.tailwindcss.com"></script>

<div id="app"></div>
Wongjn
  • 8,544
  • 2
  • 8
  • 24
  • @Wongin, unfortunately what the above solution does is remove the outline look for the first two outline buttons that is for secondary and danger and leaves the third one of secondary with outline the same as before. – Daniel Jun 29 '23 at 18:11
  • Your question was about the text color, not about any outline. – Wongjn Jun 29 '23 at 18:17
  • @Wongin, the text color never changed in your solution, the idea being that if it is an outline button the text color should not be white, but one of the four at the end of the classes. I apologize if that was not clear I will edit my question. – Daniel Jun 29 '23 at 18:26
  • I have converted my solution to an inline snippet to demonstrate the that the outline button text colors are not white and are one of the four at the end of the classes. – Wongjn Jun 29 '23 at 18:34
  • @Wongin, ahh, that means then that the propTypes solution I have which was not included here is clobbering it. Let me edit the post so you can see what i am talking about. – Daniel Jun 29 '23 at 18:50
  • @Wongin, really odd, I thought maybe `Button.propTypes` might be affecting it but I removed it and the issue is still there and then I realized you removed `text-white` from the first five lines of the `classes` object and now it works, my apologies I did not see that detail before. – Daniel Jun 29 '23 at 18:59