mui / material-ui

Material UI: Ready-to-use foundational React components, free forever. It includes Material UI, which implements Google's Material Design.
https://mui.com/material-ui/
MIT License
92.42k stars 31.84k forks source link

[Question] How to change the `barColorPrimary` style dynamically for `LinearProgress`? #11307

Closed franklixuefei closed 6 years ago

franklixuefei commented 6 years ago

Question

How am I able to change the bar color of LinearProgress component dynamically? For example, I would like the color code to be a prop of my component, and in my component, I would like to set the color of the linear progress bar to be that color.


class MyComponent extends React.Component {
  render() {
    const { barColor } = this.props; // the color code, e.g, #efefef
    return (
    <LinearProgress 
      variant="determinate" 
      value={progressBar.quantity} 
      classes={{
        barColorPrimary: <how am I able to associate the barColor here?>
      }}
    />
    );
  }
}

Your Environment

Tech Version
Material-UI beta 44
React 16.2.0
oliviertassinari commented 6 years ago

@franklixuefei It's the second time I see this feedback, let's do something about it. Some options:

  1. Add a specific property for this use case.
  2. Add a styles API to mimic the classes API. Only one key should be enough to start with: styles.bar.
  3. Add a barProps property. Might be overkill.
franklixuefei commented 6 years ago

@oliviertassinari from the options you listed out, I believe the 1st or the 2nd is better. If you think about CircularProgress, it does not expose the styles api, but just the size property so that you can control the size of it. So to make things consistent, your 1st option seems reasonable. However, as time goes by, there might be more and more similar requests like this, that require us to expose more properties. So from a scalable perspective, I think your 2nd option stands out. So I vote for your 2nd option

Add a styles API to mimic the classes API. Only one key should be enough to start with: styles.bar.

However, in doing so, we'd better support styles api for other components as well, for the sake of consistency.

BTW, I'm using cssinjs directly as a quick hack for now, and here is how it looks like:

{this.state.progressBarsInfo.map((progressBar) => {
  const barColorStyle = jss.createStyleSheet({
    bar: {
      ['background-color']: progressBar.color
    }
  }).attach();
  return (
    <LinearProgress
      variant="determinate"
      value={total ? progressBar.quantity / total * 100 : 0}
      classes={{
        root: classnames(classes.bar, classes.transparentBackground),
        barColorPrimary: barColorStyle.classes.bar
      }}
      key={progressBar.name}
    />
  );
})}
oliviertassinari commented 6 years ago

@franklixuefei Yeah, I think that option 3 is overkill. I'm happy with 1. or 2.

adeelibr commented 6 years ago

@oliviertassinari can i work on this?

adeelibr commented 6 years ago

I have made a PR. Now this is how you can change the primary color on Linear Progress

<LinearProgress
   styles={{
     bar: {
       backgroundColor: 'purple',
     },
  }}
/>

Kindly review the PR https://github.com/mui-org/material-ui/pull/11782

franklixuefei commented 6 years ago

before #7633 is supported, there is still no easy way to resolve this issue.

oliviertassinari commented 6 years ago

The new documentation section is live: https://material-ui.com/customization/overrides/#2-dynamic-variation-for-a-one-time-situation. Right now, people have to either use CSS variables or Theme nesting.

fauskanger commented 5 years ago

I tried to use the example with theme nesting, but the example seems to crash in https://codesandbox.io/s/8n5vl4xxyl - and in my project I get a warning:

Material-UI: you are providing a theme function property to the MuiThemeProvider component: <MuiThemeProvider theme={outerTheme => outerTheme} /> However, no outer theme is present. Make sure a theme is already injected higher in the React tree or provide a theme object.

fauskanger commented 5 years ago

I already use withTheme()