Styles as a function of state or context

Doing prop-dependent styles is foundational to Styletron Themer. But how can you make your styles adapt to component state? Or context?

Consider the typical usage of the Styled component:

class MyComponent extends Component {
  render() {
    return (
      <Styled
        name = 'MyComponent'
        staticStyle = {staticStyle}
        dynamicStyle = {dynamicStyle}
        {...this.props}    // <= notice this
      >
        {...}
      </Styled>
    );
  }
}

// this might be your dynamic style function. it only responds
// to one prop, "isSelected"
//
function dynamicStyle({props, componentTheme}) {
  return Object.assign({}, componentTheme, {
    props.isSelected && {background: 'blue'}
  });
}

The API indicates that you must pass your component's props up to the Styled component in a spread: {...this.props}. This allows Styled to invoke your dynamicStyle function with the correct prop values.

Now let's unpack the spread, just to understand what's happening. Again, this component has only one significant prop, isSelected:

class MyComponent extends Component {
  render() {
    return (
      <Styled
        name = 'MyComponent'
        staticStyle = {staticStyle}
        dynamicStyle = {dynamicStyle}
        isSelected = {this.props.isSelected} // <= notice this
      >
        {...}
      </Styled>
    );
  }
}

In this example, we pass isSelected directly, rather than as part of the props spread. You really should use the spread (see API), but for now, we're just highlighting an important feature of the Styled component:

You can pass it any props you like, and they will be passed on to your dynamic styling function.

Now we can show the final example, in which the value of isSelected is captured in component state. We've also brought back the props spread:

class MyComponent extends Component {
  render() {
    return (
      <Styled
        name = 'MyComponent'
        staticStyle = {staticStyle}
        dynamicStyle = {dynamicStyle}
        isSelected = {this.state.isSelected} // <= notice this
        {...this.props}
      >
        {...}
      </Styled>
    );
  }
}

// the styling function is unchanged. it doesn't know where the
// "isSelected" prop came from... it just uses it as it's received.
//
function dynamicStyle({props, componentTheme}) {
  return Object.assign({}, componentTheme, {
    props.isSelected && {background: 'blue'}
  });
}

Boom. This technique can be used to pass any values you need from your component to your styling function.

results matching ""

    No results matching ""