Skip to content

Using classnames to dynamically style component with CSS based on props value

I am creating a set of reusable components (wrapped material-ui) which are being styled using CSS. I need to set the width of the component dynamically via a prop passed into the custom button.

I want to use classnames to merge the const root style defined for MyButton (I have stripped this back in the sandbox, but it sets colours, icons etc) and the dynamic sizeStyle which can be defined based on the prop passed in.

  const sizeStyle: JSON =  { minWidth: "300px !important"};


  //always apply the buttonstyle, only apply the size style if a width prop has been supplied
  const rootStyle: Object = classNames({
    buttonStyle: true,
    sizeStyle: props.width
  ///});   

I can’t see why the style isn’t being applied to the first button on the page where there is a prop passed through – I can see on the console that the two style are supposed to be applied.

Sandbox here: https://codesandbox.io/s/css-styling-custom-muibutton-width-as-prop-36w4r

TIA

Answer

you need to pass props to your useStyles(props) function, then inside this you can use props like styled-component.

Document link: https://material-ui.com/styles/basics/#adapting-based-on-props

// eslint-disable-next-line flowtype/no-weak-types
const useStyles = makeStyles({
  root: {
    //    minWidth: "300px !important",
    color: "#565656",
    backgroundColor: "salmon",
    borderRadius: 2,
    textTransform: "none",
    fontFamily: "Arial",
    fontSize: 16,
    letterSpacing: "89%", //'0.09em',
    boxShadow:
      "0px 1px 5px 0px rgba(0,0,0,0.2), 0px 2px 2px 0px rgba(0,0,0,0.14), 0px 3px 1px -2px rgba(0,0,0,0.12)",
    "&:disabled": {
      color: "#565656",
      opacity: 0.3,
      backgroundColor: "#fbb900"
    },
    minWidth: props => `${props.width}px`,
  },
  label: {
    textTransform: "capitalize",
    display: "flex",
    whiteSpace: "nowrap"
  }
});

// eslint-disable-next-line flowtype/require-return-type
function MyButton(props) {
  const { children, ...others } = props;
  const classes = useStyles(props);

  return (
    <Button
      {...props}
      classes={{
        root: classes.root,
        label: classes.label
      }}
    >
      {children}
    </Button>
  );
}

Modified version from your sandbox: https://codesandbox.io/s/css-styling-custom-muibutton-width-as-prop-pcdgk?fontsize=14&hidenavigation=1&theme=dark

Hope this help