lundi 21 juin 2021

How do I attach CSS styles based on React Component Prop?

I am trying to build a React Component Library, the Button component takes the following props :

<Button
  kind='primary' //secondary, ghost
  size='large' //small, large
  success
  shape='' //pill
  onClick={() => console.log("**clicked**")}
  >
  Button Click
</Button>

Based on what has been passed to props, I want to render a certain styles, like :

import { Colors } from "../Utils/Colors";
export default function Button({
  children,
  className,
  kind,
  size,
  shape,
  success,
  warning,
  error,
  ...props
}) {
  const btnStyle = {
    boxSizing: "border-box",
    display: "inline-block",
    border: "1px solid black",
    cursor: "pointer",
    borderRadius: shape == "pill" ? "100px" : "0px",
  };

  if (success || "") {
    Object.assign(btnStyle, {
      backgroundColor: Colors.success,
      color: "white",
      border: "1px solid" + Colors.sucess,
    });
  }

  if (warning) {
    Object.assign(btnStyle, {
      backgroundColor: Colors.warning,
      color: "white",
    });
  }
  if (error) {
    Object.assign(btnStyle, { backgroundColor: Colors.error, color: "white" });
  }

  if (kind == "primary") {
    Object.assign(btnStyle, {});
  }
  if (kind == "secondary") {
    Object.assign(btnStyle, {
      backgroundColor: "white",
    });
  }
  if (kind == "ghost") {
    Object.assign(btnStyle, { background: "none", border: "none" });
  }
 
  if (size == "mini") {
    Object.assign(btnStyle, { fontSize: "10px", padding: "4px 10px" });
  }

  if (size == "small") {
    Object.assign(btnStyle, { fontSize: "12px", padding: "6px 20px" });
  }

  if (size == "" || size == "medium") {
    Object.assign(btnStyle, { fontSize: "14px", padding: "8px 24px" });
  }

  if (size == "large") {
    Object.assign(btnStyle, { fontSize: "18px", padding: "10px 34px" });
  }

  if (kind === "default") {
    Object.assign(btnStyle, { color: "pink" });
  }

  return (
    <div>
      <button style={btnStyle} className={`btn ${className}`} {...props}>
        {children}
      </button>
    </div>
  );
}

As we can see, I am pushing a new Object style to btnStyle based on the props, which is certainly not a good way to do this. How can I optimize this?

What I have tried :

1 ) I have tried looking at popular open-source Design System like Base Web, Adobe Spectrum, but couldn't get far as the codebase is very structured.

2 ) I tried storing the styles in an array and pushing along the if-else condition, which is again the same thing.

3 ) Looked at other answers here on SO, found a few ones which only deals with appending CSS styles and variables, not really a component library sort of pattern.

3 ) I tried doing conditional styling in the btnStyle itself like :

borderRadius : ${ type == "pill" ? "10px" : "0px" }

But the above works in a very limited manner and only for two condition which is a problem in the kind prop.

Any helpful suggestion in the right direction will do wonders.

Thank You for reading this far.

Aucun commentaire:

Enregistrer un commentaire