Theming

React Storefront's theming builds on the patterns set forth by Material UI.

Theming in Material UI

The Material UI default theme

Creating a Theme

Create a theme using react-storefront/createTheme. This function accepts an object containing theme values, adds some defaults specific to the React Storefront framework, and passes the result onto Material UI's createMuiTheme().

The theme is typically specified in src/theme.js.

In addition to the theme properties provided by material UI, React Storefront allows provides the following configurable theme properties:

{
  palette: {
    // The colors for the Add to Cart and Checkout buttons
    addToCart: {
      background: green[500], // import green from '@material-ui/core/colors/green'
      contrastText: 'white'
    }
  },
  
  margins: {
    // vertical margin on Container component
    container: 15,

    // horizontal margin on Row component
    row: 15
  },

  zIndex: {
    amp: {
      // the z-index for modals in amp
      modal: 2147483646
    }
  },

  // The height of the app header
  headerHeight: 64,

  // Override the icon for all expanders in collapsed state - this should be a React component class, for example @material-ui/icons/Add
  ExpandIcon: null,

  // Override the icon for all expanders in expanded state - this should be a React component classm for example @material-ui/icons/Remove
  CollapseIcon: null
}

Component Style Overrides

In additional to the basic values that make up the theme, you can override any style on any Material UI or React Storefront component by specifying an overrides key in the theme config.

For example, to set the color of the counts for each facet in the Filter component to red:

import createTheme from 'react-storefront/createTheme'
import red from '@material-ui/core/colors/red'

export default createTheme({
  overrides: {
    MoovFilter: {
      itemsFound: {
        color: red[500]
      }
    }
  }
})

Styling your Components

Like Material UI, we recommend that you use JSS to style your components. JSS is a flexible, JSON syntax similar to CSS that is fully compatible with SSR.

To define styles for a component, use the @withStyles decorator:

import React, { Component } from 'react'
import withStyles from '@material-ui/core/styles/withStyles'

@withStyles(theme => ({
  root: {
    color: theme.palette.secondary.main // see https://material-ui-next.com/customization/default-theme/ for theme defaults
  }
}))
export default class MyComponent extends Component {

  render() {
    // @withStyles injects a classes prop 
    // Keys are the class names you define, values are globally safe class names.
    // This ensures that each class only affects the component to which it is assigned.
    const { classes } = this.props

    return (
      <div className={classes.root}>My styled component</div>
    )
  }

}

The @withStyles decorator generates unique class names over globally scoped class names. This will also help ensure that your class names are small and don't push the CSS size over the AMP limit.

Conditionally Applying Classes using classnames

React Storefront bundles a helpful utility called classnames that helps you conditionaly apply one or more classes to an element. For example, to apply a selected class to an element when state.selected is true:

import React, { Component } from 'react'
import withStyles from '@material-ui/core/styles/withStyles'

@withStyles(theme => ({
  root: {
    color: theme.palette.secondary.main
  },
  selected: {
    fontWeight: 'bold'
  }
}))
export default class MyComponent extends Component {

  state = {
    selected: false
  }

  render() {
    const { classes } = this.props
    const { selected } = this.state

    return (
      <button 
        type="button"
        className={
          classnames(classes.root, { selected: selected })
        }
        onClick={() => this.setState({ selected: !selected })}
      >
        My Button
      </button>
    )
  }

}