0
votes

I'm using material-ui-next and have customized the theme to use my color styles and a custom font. eg. Typography subheading

I'm now attempting to render a component to string for use in a google maps info window. The default material-ui theme is available in the callback styles object passed to withStyles, but none of my customizations are available on the theme argument in the styles callback nor are they applied. The rendered string renders otherwise correctly (albeit w/o events which I sorta expected).

More concisely, when rendering normally, customizations apply. When rendering to string, they do not.

A simple example would be a component that runs withStyles correctly, but return the div instead of the target component ala:

let output = ReactDOMServer.renderToString(component); return <div dangerouslySetInnerHTML={{__html: output}} />

Any tips how I can get my theme customizations to be passed into the withStyles callback theme argument?

1

1 Answers

0
votes

The solution was to make a parent component that renders the target component as a child of the ThemeProvider. There are still no event handlers (as expected), but the theme customizations apply.

Here's the solution:

MyThemeProvider.js (component can also easily be reused for SSR)

export default function MyThemeProvider({children}) {
  const muiTheme = createMuiTheme({
    typography: {
      fontFamily: '"Bryant", "Helvetica", "Arial", sans-serif',
    },
    palette: {
      primary: customBluePalette,
    },
    // ... 
  });
  return (<MuiThemeProvider theme={muiTheme}>{ children }</MuiThemeProvider>);
}

MapInfoWindowContent.js (here, this only really exists to wrap VenueRenderer with our theme provider)

import MyThemeProvider from '../MyThemeProvider';
import VenueRenderer from '../VenueRenderer';
export default function MapInfoWindowContent({resource}) {
  return (<MyThemeProvider><VenueRenderer resource={resource} /></MyThemeProvider>);
}

VenueRenderer (the styled class - can be used independently of MapInfoWindowContent too)

const styles = (theme) => {
    // theme.palette.primary['500'] comes from customBluePalette so the injection worked.
}
// ...
export default withStyles(styles, { withTheme: true })(VenueRenderer);

In some other component that needs the HTML str

import ReactDOMServer from 'react-dom/server'
import MapInfoWindowContent from '../MapInfoWindowContent';

let infoWindowComponent = (<MapInfoWindowContent resource={ ... }/>);
let output = ReactDOMServer.renderToString(infoWindowComponent);
// output will have correctly injected classNames that contain customizations