cssinjs / aphrodite-jss

Aphrodite-like API on top of JSS.
MIT License
92 stars 17 forks source link

How to Dynamically Theme Components #6

Closed liveresume closed 7 years ago

liveresume commented 7 years ago

The docs say theming can be done without headaches but I am having trouble doing just that. What is the recommended approach to theming?

I am currently using jss and react and wrote some mods so I can do:

const styles = (theme) => ({
  button: {
    color: theme.palette.primary
  }
})

@injectSheet(styles)
class Button extends React.Component {
  render () {
    const { s, label } = this.props
    return (
      <button className={s.button}>
        <div>{ label }</div>
      </button>
    )
  }
}

This way I can also dynamically modify the theme and have changes instantly appear. Change Theme -> HOC detects change -> HOC updates its WrappedComponent

Problem with this approach, this lib, and react, is that if the theme is changed then every style needs to be recalculated. In order to update react we could simply update the stylesheet, and the DOM would take care of everything. But this is only possible if the classnames have not changed. If they do change the react comps need updating.

My thoughts on how this could work with your lib and without integrating with React: Change Theme -> Stylesheet.create (yours wrapped by my code) detects theme change -> triggers a stylesheet update -> DOM automatically updates everything

I believe that for this to work the classnames must remain the same.

If they can not, then I require an HOC to pass new classnames down as props which will trigger the React update. Of course if this is the only way then there is no place for this lib + react + dynamic theming. Correct?

Any ideas?

kof commented 7 years ago

We will be working on a different theming approach for core jss soon. As of for aphrodisiac you can simply pass the style objects down to children.