0

I'm having some trouble following the docs on how to get this to work

I have a component that has some styles created, for the most part, all of these styles will apply to wherever this component is rendered but sometimes depending on what page the app is routed to I will want to change the overall height of the component on those pages. I figured I could just do this by passing in some new height props of some sort to follow a more theme centric approach. How would I get this to work with my current setup?

The styles file

const styles = theme => ({
  root: {
    backgroundSize: 'cover',
    padding: '25px 20px',
    boxSizing: 'border-box',
    backgroundPosition: '50% 0',
    backgroundColor: 'rgba(40,70,94,.7)',
    backgroundBlendMode: 'multiply',
    ...theme.root
  }
});

export default styles;

The component file

import React from 'react';
import styles from './EventTop.styles';
import injectSheet, { ThemeProvider } from 'react-jss';

const EventTop = (props) => (
  <ThemeProvider theme={props.theme}>
    <aside className={props.classes.root} style={{ backgroundImage: `url(${props.event.event_logo})` }}>
      <div className="wrapper">
        <div className="event-info">
          <span className="event-time">
            7:00 PM
          </span>
          <span className="event-date">
            27 Jun 2020
          </span>
          <span className="event-end-time">
            Ends at 10:00 PM
          </span>
          <span className="event-title">
            Bidr Gala
          </span>
          <span className="event-attire">
            Cocktail Attire
          </span>
        </div>
      </div>
    </aside>
  </ThemeProvider>
);

export default injectSheet(styles)(EventTop);

And then when I render it I pictured something like this

<EventTop event={this.props.events.currentEvent} theme={{ height: 'calc(100vh - 64px)' }}/>

But when I try to console log out the theme getting passed to the style generator I don't see the theme coming in.

I have Material UI installed and the whole app is wrapped in it's MuiThemeProvider

<Provider store={store}>
  <MuiThemeProvider theme={theme}>
    <App>
      <Reboot />
      <AppRouter />
    </App>
  </MuiThemeProvider>
</Provider>

And this is the theme I'm actually seeing the material theme and not my own merged anywhere in it.

Jordan
  • 2,393
  • 4
  • 30
  • 60

2 Answers2

1

Here is how I got this to work

First I moved the stateless component into a new file

EventTop.component.jsx

import React from 'react';
import Moment from 'react-moment';
import styles from './EventTop.styles';

import themableWrapper from '../Themable';

const EventTopComponent = (props) => (
  <aside className={props.classes.root} style={{ backgroundImage: `url(${props.event.event_logo})` }}>
    <div className="wrapper">
      <div className={props.classes.eventInfo}>
        <span className={props.classes.eventTime}>
          <Moment parse="HH:mm:ss" format="h:mm A">{props.event.start_time}</Moment>
        </span>
        <span className={props.classes.eventDate}>
          <Moment parse="YYYY-MM-DD" format="D MMM YYYY">{props.event.event_date}</Moment>
        </span>
        <span className={props.classes.eventEndTime}>
          Ends at <Moment parse="HH:mm:ss" format="h:mm A">{props.event.end_time}</Moment>
        </span>
        <span className={props.classes.eventTitle}>
          {props.event.auction_title}
        </span>
        <span className={props.classes.eventAttire}>
          {props.event.attire}
        </span>
      </div>
    </div>
  </aside>
);

export default themableWrapper(styles)(EventTopComponent);

Then in the EventTop.jsx I import the stateless component and return another stateless component but this one is wrapped in a new themable wrapper

import React from 'react';
import EventTopComponent from './EventTop.component';

import { Themable } from '../Themable';

const EventTop = ({ theme, ...rest }) => (
  <Themable theme={theme}>
    <EventTopComponent {...rest} />
  </Themable>
);

export default EventTop;

Inside the new themable file, I have some exports setup

import injectSheet, { createTheming } from 'react-jss';

export const theming = createTheming('__NEW_THEME_NAMESPACE__');
export const { ThemeProvider: Themable } = theming;

export default (styles) => injectSheet(styles, { theming });

And then in the style generator, I can use something like lodash to merge my incoming theme with the default styles setup

EventTop.styles.js

import { merge } from 'lodash';

const styles = theme => {
  return merge({
    root: {
      backgroundSize: 'cover',
      padding: '25px 20px',
      boxSizing: 'border-box',
      backgroundPosition: '50% 0',
      backgroundColor: 'rgba(40,70,94,.7)',
      backgroundBlendMode: 'multiply',
    },
    eventInfo: {
      flexGrow: '1',
      display: 'flex',
      flexDirection: 'column',
      justifyContent: 'flex-end',
      textAlign: 'left',
      paddingTop: '20px',
      fontWeight: '700',
      color: 'white'
    },
    eventTime: {
      fontSize: '55px'
    },
    eventDate: {
      fontSize: '43px'
    },
    eventEndTime: {
      fontSize: '30px'
    },
    eventTitle: {
      fontSize: '70px'
    },
    eventAttire: {
      fontSize: '30px'
    }
  }, theme);
};

export default styles;

In order for this to work with MuiThemeProvider wrapping the whole app I have to set up a new namespace, and then use the createTheme to make a new theme provider instance. This then needs to wrap the actual component code which is why I opted to create essentially a "container" component and the actual component as separate pieces so I could keep the logic separate. Plus this still allows me to make one stateless and the other not if I so choose

Jordan
  • 2,393
  • 4
  • 30
  • 60
0

You are confusing MuiThemeProvider and the one from react-jss.

Oleg Isonen
  • 1,463
  • 10
  • 10
  • I want the whole app to use the `MuiTheme` and then my custom component to also have it's own theme with inherited styles from the `MuiTheme`. Do I need to not use the exports from `react-jss` if I want to also use `MuiTheme`? – Jordan Mar 05 '18 at 16:49