Simone
Simone

Reputation: 1337

Extend JSS style class instead of overwriting it

In my React app, I use React JSS for styling. Suppose I have these two files (skipping imports and another non interesting stuff).

This is App.js:

const styles = {
  root: {
    backgroundColor: '#ffffff',
  },
  header: {
    backgroundColor: '#ff0000',
  }
};

class App extends Component {
  render() {
    const { classes } = this.props;
    return (
        <div className={classes.root}>
          <Header classes={{ root: classes.header }}/>
        </div>
    );
  }
}

export default withStyles(styles)(App);

and this is Header.js:

const styles = theme => ({
    root: {
        backgroundColor: '#0000ff',
        padding: '1em',
    },
});

class Header extends Component {
    render() {
        const { classes } = this.props;
        return (
            <header className={classes.root}>
                Hello header
            </header>
        );
    }
}

export default withStyles(styles)(Header);

What I would like to have is "overriding" the style of the root component of Header without overwriting it completely. I can do either of two things:

  1. use <Header className={classes.header}/>, which results in the header element having the class App-root-0-1-2, which means the background is blue with the padding;

  2. use <Header classes={{ root: classes.header }}/> (as above), which results in the header element having the class App-header-0-1-2, which means the background is read without padding.

It seems I can only have either the style defined by the component OR the one that the parent defines to override it. However, I would like to extend the internal style with the one passed by the parent - of course, with the parent taking precedence in conflicts. In this case, I wish to have the red background with the padding.

How can I achieve that? Is it impossible - do I need to pass the editable style as a property?

Upvotes: 0

Views: 1691

Answers (1)

janhartmann
janhartmann

Reputation: 15003

You can provide an external class name and use classnames (https://github.com/JedWatson/classnames) (or just inline them) to conditionally render this class name if present:

import classNames from "classnames";

const styles = theme => ({
    root: {
        backgroundColor: '#0000ff',
        padding: '1em',
    },
});

class Header extends Component {
    render() {
        const { classes, className } = this.props;
        return (
            <header 
              className={classNames({ 
                [classes.root]: true, 
                [className]: className 
              })}>
                Hello header
            </header>
        );
    }
}

export default withStyles(styles)(Header);

Then use it:

<Header className={classes.myParentClass} />

This will result in a class names, e.g. Header-root-0-1-2 App-myParentClass-0-4-3

Upvotes: 1

Related Questions