ruby-on-railsrubyreactjsisomorphichyperstack

Material UI Themes and Hyperstack


Material UI (React) uses a theaming solution where the theme object is created in JS then passed into the top level component. Creating the theme object in Opal can be complicated as the Material component expects a JS function to be passed in which actually creates the theme on the fly.

Has anyone got an example of this working well?


Solution

  • After some experimentation, I got this working well by mixing JS and Opal code so here is the solution in case anyone else comes up with this. (There may be a better 'more Opal' solution, so if there is please do post an alternative answer, but the one below does work well.

    First import the JS libraries with webpack:

    import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
    import indigo from '@material-ui/core/colors/indigo';
    import pink from '@material-ui/core/colors/pink';
    import red from '@material-ui/core/colors/red';
    global.createMuiTheme = createMuiTheme;
    global.MuiThemeProvider = MuiThemeProvider;
    global.indigo = indigo;
    global.pink = pink;
    global.red = red;
    

    Add the following to your Javascript assets:

    // app/assets/javascripts/my_theme.js
    const my_theme = createMuiTheme(
      { palette: {
        primary: { main: pink[500] },
        secondary: { main: indigo[500] }
      }
    });
    

    Then provide the theme in your top-level Component code:

    class MyRouter < HyperComponent
      include Hyperstack::Router
    
      render(DIV) do
        MuiThemeProvider(theme: `my_theme` ) do
          CssBaseline do
            ...
          end
        end
      end
    end