Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

muiThemeProvider improvement: global style provider #6020

Closed
PolGuixe opened this issue Jan 27, 2017 · 7 comments
Closed

muiThemeProvider improvement: global style provider #6020

PolGuixe opened this issue Jan 27, 2017 · 7 comments

Comments

@PolGuixe
Copy link
Contributor

It would be cool if the muiThemeProvider could apply a "global" style so other elements can inherit from it.

A good example is font color. So the muiTheme.palette.textColor can be inherited from other elements.

@clayne11
Copy link

It can. Create a higher-order-component like this (this example uses recompose):

import {PropTypes} from 'react'
import createHelper from 'recompose/createHelper'
import getContext from 'recompose/getContext'

const withMuiTheme = () => getContext({muiTheme: PropTypes.object.isRequired})

export default createHelper(withMuiTheme, 'withMuiTheme')

Then simply wrap the component you want to get the theme in with this HOC.

@oliviertassinari
Copy link
Member

oliviertassinari commented Jan 27, 2017

@PolGuixe You raise an important point. Should we apply a default style?
You mentioned the font color but it could also be any other property.
For instance, let's take the font family, we reset that style at the root of all our components, <Snackbar />, etc.
The other approach is to do what you suggest, applying at font-family higher in the DOM structure and let the cascading of the CSS take action.

I don't think that we should do it by default. That's quite intrusive.
What if a user is only using the <DatePicker /> and providing the <MuiThemeProvider /> high in the render try so that he has the maximum flexibility?

@clayne11 Is right, if your only concern is regarding how to access the this.context.muiTheme property, you can use recompose, recompact, or our helper: muiThemeable.

@PolGuixe
Copy link
Contributor Author

Thanks @clayne11 and @oliviertassinari. Currently I am using a <GlobalStyleProvider /> sitting just underneath of the <MuiThemeProvider />. Which does exactly that. Right now just for the color 😅
I just thought that it will be the task of the <MuiThemeProvider />, to keep it neat.

@oliviertassinari I agree with you that it shouldn't be by default. But it can be done in a way that it accepts the props to do it and the overhead for the people who don't need it is minimal. What do you think?

@oliviertassinari
Copy link
Member

I just thought that it will be the task of the , to keep it neat.

I wouldn't mix concern. For instance, you had to add an additional <div /> element in your PR, that's something that could break layout aside from bloating the dom of people that don't need it.

On the next branch, you would be able to use the withStyles Higher-order Component like this:

import React, { PropTypes } from 'react';
import { createStyleSheet } from 'jss-theme-reactor';
import withStyles from 'material-ui/styles/withStyles';

const styleSheet = createStyleSheet('Main', (theme) => ({
  root: {
    fontFamily: theme.typography.fontFamily,
  },
}));

const Main = (props) => {
  return (
    <div className={props.classes.root}>
      {props.children}
    </div>
  );
};

Main.propTypes = {
  children: PropTypes.node.isRequired,
  classes: PropTypes.object.isRequired,
};

export default withStyles(styleSheet)(Main);

Here is the equivalent on the master branch:

import React, { PropTypes } from 'react';
import muiThemeable from 'material-ui/styles/muiThemeable';

const Main = (props) => {
  const style = {
    fontFamily: props.muiTheme.baseTheme.fontFamily,
  }

  return (
    <div style={style}>
      {props.children}
    </div>
  );
};

Main.propTypes = {
  children: PropTypes.node.isRequired,
  muiTheme: PropTypes.object.isRequired,
};

export default muiThemeable()(Main);

That sounds simple enough. I'm wondering what the gain of abstracting that away.

@clayne11
Copy link

I don't really understand what you would be abstracting. It's already as simple as it can be IMO.

@PolGuixe
Copy link
Contributor Author

@oliviertassinari I see. Are muiThemable and withStyles an approach for injecting muiTheme as a prop?

Currently I just require muiTheme in contextTypes when I have a component that requires it e.g.

import React from 'react';

const getGlobalStyles = palette => ({
  color: palette.textColor,
});

class GlobalStyleProvider extends React.PureComponent {

  static contextTypes = {
    muiTheme: React.PropTypes.object.isRequired,
  }

  render() {
    const globalStyle = getGlobalStyles(this.context.muiTheme.palette);
    return (
      <div style={globalStyle}>
        {this.props.children}
      </div>
    );
  }
}

export default GlobalStyleProvider;

I can't see muiThemable doing anything else, so I assume they are equivalent. No so sure about what is doing withStyles. Is the new styling system changing a lot? Any place where I can follow the discussion?

@oliviertassinari
Copy link
Member

oliviertassinari commented Jan 28, 2017

Are muiThemable and withStyles an approach for injecting muiTheme as a prop?

@PolGuixe muiThemable is injecting the muiTheme as props, withStyles isn't. The styling solution on the next branch add more constraints, providing the theme would be vain. It's injecting the class names.

I just require muiTheme in contextTypes

⚠️ Avoid using the context API directly on your side. I'm not sure how that is going to change in the upcoming released of React. You should be able to switch to muiThemable() quite easily.

Is the new styling system changing a lot? Any place where I can follow the discussion?

It does change a lot. I have been talking about it. You can have a look at #4066. That's a long discussion.

I'm closing this issue as I think we went down the rabbit hole 🐰 .
Thanks for bringing it up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants