Mr Mime
Mr Mime

Reputation: 163

MaterialUi custom breakpoints not applied

Based on this question, I tried to have a theme that uses a common config file(that should be used by other themes as well). So I figured the breakpoints would be a good starting point since they should be the same across all the themes.

I have the common part like

const BREAKPOINTS = {
  xs: 0,
  sm: 768,
  md: 960,
  lg: 1280,
  xl: 1920,
};

const commonConstants = {
  breakpoints: {
    values: BREAKPOINTS,
  },
};

export default commonConstants;

Then I create my theme like

const defaultTheme = responsiveFontSizes(createMuiTheme(myTheme, commonConstants));

If I console.log my theme object, it will display the correct breakpoint values but will not apply them(the default one will be applied). However, if the breakpoint object is added directly inside the theme objectmyTheme (i.e. not uside of the theme), the correct breakpoints are applied. What am I missing here? If the final theme object has the same structure, why is it working differently?

Upvotes: 4

Views: 6351

Answers (2)

David Jimison
David Jimison

Reputation: 9

In order to effectively override breakpoints in the default MuiTheme (as shown in Ryan Cogswell answer Option 1) you must use the createBreakpoints function passing in the values and keys elements.

Based on Ryan's answer, I found the following solution to work.

import { createMuiTheme } from "@material-ui/core/styles";
import createBreakpoints from "@material-ui/core/styles/createBreakpoints";

const BREAKPOINTS = {
  xs: 0,
  sm: 768,
  md: 960,
  lg: 1280,
  xl: 1920
};

const breakpointsFull = createBreakpoints({
    values: {...BREAKPOINTS},
    keys: Object.keys(BREAKPOINTS),
  });

const myTheme = { other: "stuff" };
const theme = createMuiTheme({ 
   default: myTheme, 
   breakpoints: breakpointsFull,
});

This strategy enables easy modification of the BREAKPOINTS variable, and correctly assigns it into the object. Using the createBreakpoints Mui function will generate functions for up and down, which allow you to check against breakpoints in your code for example:

const isSmallScreen = UseMediaQuery(theme.breakpoints.down('sm'))

Upvotes: 0

Ryan Cogswell
Ryan Cogswell

Reputation: 81036

Several portions of the theme (e.g. palette, breakpoints, spacing, typography) have additional processing associated with them that creates additional entries in the theme based on the options passed in. This additional processing is only applied to the object passed as the first argument to createMuiTheme. Any additional arguments are merged in after the additional processing.

For breakpoints, that additional processing is contained in the createBreakpoints function. This creates the various functions that leverage the breakpoint values (e.g. theme.breakpoints.up, theme.breakpoints.down, etc.). When you pass in custom breakpoint values via a second argument, those values are not being used in the creation of those breakpoint functions.

There are two main options for addressing this.

Option 1: Apply the additional processing yourself

import { createMuiTheme } from "@material-ui/core/styles";
import createBreakpoints from "@material-ui/core/styles/createBreakpoints";

const BREAKPOINTS = {
  xs: 0,
  sm: 768,
  md: 960,
  lg: 1280,
  xl: 1920
};

const breakpointsFull = {
  breakpoints: createBreakpoints({
    values: BREAKPOINTS
  })
};
const myTheme = { other: "stuff" };
const theme = createMuiTheme(myTheme, breakpointsFull);

Option 2: Merge your custom breakpoint values into the first argument to createMuiTheme

import { createMuiTheme } from "@material-ui/core/styles";

const BREAKPOINTS = {
  xs: 0,
  sm: 768,
  md: 960,
  lg: 1280,
  xl: 1920
};

const breakpointsValues = {
  breakpoints: {
    values: BREAKPOINTS
  }
};

const myTheme = { other: "stuff" };
const theme = createMuiTheme({ ...myTheme, ...breakpointsValues });

Here's a working example demonstrating the problem with your current approach as well as the two alternatives:

import React from "react";
import { createMuiTheme } from "@material-ui/core/styles";
import createBreakpoints from "@material-ui/core/styles/createBreakpoints";

const BREAKPOINTS = {
  xs: 0,
  sm: 768,
  md: 960,
  lg: 1280,
  xl: 1920
};

const breakpointsValues = {
  breakpoints: {
    values: BREAKPOINTS
  }
};
const breakpointsFull = {
  breakpoints: createBreakpoints({
    values: BREAKPOINTS
  })
};
const myTheme = { other: "stuff" };
const badTheme = createMuiTheme(myTheme, breakpointsValues);
const goodTheme1 = createMuiTheme(myTheme, breakpointsFull);
const goodTheme2 = createMuiTheme({ ...myTheme, ...breakpointsValues });
export default function App() {
  return (
    <ul>
      <li>badTheme.breakpoints.values.sm: {badTheme.breakpoints.values.sm}</li>
      <li>badTheme.breakpoints.up("sm"): {badTheme.breakpoints.up("sm")}</li>
      <li>
        goodTheme1.breakpoints.values.sm: {goodTheme1.breakpoints.values.sm}
      </li>
      <li>
        goodTheme1.breakpoints.up("sm"): {goodTheme1.breakpoints.up("sm")}
      </li>
      <li>
        goodTheme2.breakpoints.values.sm: {goodTheme2.breakpoints.values.sm}
      </li>
      <li>
        goodTheme2.breakpoints.up("sm"): {goodTheme2.breakpoints.up("sm")}
      </li>
    </ul>
  );
}

Edit theme custom breakpoints

Upvotes: 4

Related Questions