Importing a dynamic MaterialUI theme object from a separate file?

Viewed 853

Can someone help me understand the correct syntax for allowing a dynamic theme object to be imported from a separate file?

I am trying to get the system theme from a media query and then set the theme dynamically.

This works fine if I leave everything all in the main App function like this: https://stackblitz.com/edit/theme-builder-working-all-in-one?file=index.js

But I want to have it broken up into different files for organization in the example below but my attempt is broken, I get the error: themeProvider_js_1.default is not a function

broken example: https://stackblitz.com/edit/theme-builder-broken?file=index.js

This is a second try of refactoring, no errors, I can see the ThemeObject existing in the console log but the system theme isn't being applied: https://stackblitz.com/edit/theme-builder-broken-btyufg?file=index.js

Code for the future: working code, but I want to refactor this so the theme and media query objects are outside of the App component:

import React from 'react';
import { render } from 'react-dom';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
import CssBaseline from '@material-ui/core/CssBaseline';

function App() {

  const prefersDarkMode = useMediaQuery('(prefers-color-scheme)');

  const theme = React.useMemo(
    () =>
      createMuiTheme({
        palette: {
          type: prefersDarkMode ? 'dark' : 'light',
        },
      }),
    [prefersDarkMode],
  );

  return (
    <ThemeProvider theme={theme}>
    <CssBaseline/>
        <p>
          Start editing to see some magic happen :)
        </p>
    </ThemeProvider>
  );
}

render(<App />, document.getElementById('root'));

broken refactor attempt:

App component

import React from 'react';
import { render } from 'react-dom';
import useMediaQuery from '@material-ui/core/useMediaQuery';
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';

import themeBuilder from './themeProvider.js'

function App() {

  return (
    <ThemeProvider theme={themeBuilder()}>
        <p>
          Start editing to see some magic happen :)
        </p>
    </ThemeProvider>
  );
}

render(<App />, document.getElementById('root'));

themeBuilder

import React from 'react';
import { createMuiTheme } from '@material-ui/core/styles';
import useMediaQuery from '@material-ui/core/useMediaQuery';

function themeBuilder() {

const prefersDarkMode = useMediaQuery('(prefers-color-scheme)');

const theme = React.useMemo(
    () =>
      createMuiTheme({
        palette: {
          type: prefersDarkMode ? 'dark' : 'light',
        },
      }),
    [prefersDarkMode],
  );

  return theme
}
1 Answers

I think you're missing export default in themeProvider.js

export default function themeBuilder() {

const prefersDarkMode = useMediaQuery('(prefers-color-scheme)');

const theme = React.useMemo(
    () =>
      createMuiTheme({
        palette: {
          type: prefersDarkMode ? 'dark' : 'light',
        },
      }),
    [prefersDarkMode],
  );

  return theme
}
Related