-
-
Notifications
You must be signed in to change notification settings - Fork 32.7k
Add "Theme" high order component and "theme" decorator #797
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
Conversation
|
👍 HOC |
|
Done. |
Add "Theme" high order component and "theme" decorator
|
Thanks @SimonDegraeve |
|
Is there any way we can do this without having to do this weird construct: For example, in my app this results in this: I realise this is needed, because of this part of your code: Would it work (no React expert here, yet....) if we set them on the children directly? Instead of having to wrap it in a function. Something like https://github.com/martyjs/marty-lib/blob/e2640804254e796dd9ce03332e05239a2881c24d/modules/application/applicationContainer.js I think it would look like this: Then it would look nice if the result was something like: |
|
Guess what, I just tried it, and my guess worked: Or even: Now I got rid of the function in my app code's Should I create another PR to discuss and improve on this? |
|
Actually, I'll leave it here, I whipped this up for my case (without the decorator) which seems to work nicely: import React from 'react';
import { Styles } from 'material-ui';
import extend from './../../vendor/lodash/object/extend';
var ThemeManager = Styles.ThemeManager;
class Theme extends React.Component {
getChildContext() {
return {
muiTheme: this.themeManager.getCurrentTheme(),
muiThemeManager: this.themeManager
};
}
componentWillMount() {
this.themeManager = new ThemeManager();
if (this.props.theme) {
this.themeManager.setTheme(this.props.theme);
}
}
render() {
var _props = this.props;
var children = _props.children;
if (children) {
return React.createElement(children.type, extend({
muiTheme: this.themeManager.getCurrentTheme(),
muiThemeManager: this.themeManager
}, children.props));
}
}
}
Theme.displayName = 'Theme';
Theme.propTypes = {
theme: React.PropTypes.object
};
Theme.childContextTypes = {
muiTheme: React.PropTypes.object.isRequired,
muiThemeManager: React.PropTypes.object.isRequired
};
export default Theme;And my app now has: import Theme from './util/theme-component';
import theme from './theme';
log('Running React.render with router.');
app.router.run(function (Handler, state) {
app.routeActions.activate(state);
React.render(
<Theme theme={theme}>
<ApplicationContainer app={app}>
<Handler {...state} />
</ApplicationContainer>
</Theme>,
document.body);
});Which actually makes me happy, since it's now a nice higher order component without having to depend on a function. |
|
Indeed I could use something like this. |
|
Ah yes, that looks even nicer, safer checking :) |
|
Hello, For example, App is my top-component import React from "react"
import { Theme } from "material-ui"
export default class App {
render() {
return (
<Theme>
{props => <div className="App">{this.props.children}</div>}
</Theme>
)
}
}And then deeper in the tree : import React from "react"
import { RaisedButton } from "material-ui"
export default class NestedComponent {
render() {
return (
<div className="NestedComponent">
<RaisedButton label="Awesome Button" />
</div>
)
}
} |
|
See here: as of now, context is only passed through the owner-ownee relationship (not the parent-child relationship). This is to be changed in a future version of react. I understand that the following construct: <Theme theme={myTheme}>
{props => // props contains the ThemeManager instance in "themeManager" property (also added to context)
<RaisedButton label='Super Button' primary={true}/>
}
</Theme>is used so that context from the Theme HOC can be passed down as owner-based context instead of parent-based context. Please correct me if my understanding is wrong. However, down the chain of hierarchy, I can still see some warnings pop up (that say that parent-based and owner-based contexts differ). Is this is a known issue? If so, is there an identified work-around? Hopefully, with React v0.14 (where contexts are passed only based on the parent-child relationship), this will be as simple as: <Theme theme={myTheme}>
<RaisedButton label='Super Button' primary={true}/>
</Theme> |
You can use it to set the theme and the context required by material-ui.
There is two ways to use it.