How can I use breakpoints inside createMuiTheme? Material UI & React.js - reactjs

Maybe not the right approach but I want to create some 'global' styles for headings for example. Something like this:
const myTheme = createMuiTheme({
headings: {
h1: {
fontSize: 28,
// Obviously this does not work...
[theme.breakpoints.down('sm')]: {
fontSize: 24
},
},
h2: {
fontSize: 24,
}
}
}
then I can use them in my components like this:
const styles = (theme) => ({
myElement: {
...theme.headings.h1,
// ... other styles
}
}
This does work but the issue I face is I want the headings to be responsive and respect Material UI's breakpoints, but I can't use them inside the createMuiTheme itself? What is the way to do this correctly so I can just spread in my styles that INCLUDE the responsive styles all in one?

You can use the createBreakpoints method
Example:
// theme.js
import createBreakpoints from '#material-ui/core/styles/createBreakpoints'
import { createMuiTheme } from '#material-ui/core/styles'
const breakpoints = createBreakpoints({})
const theme = createMuiTheme({
overrides: {
MuiTab: {
root: {
[breakpoints.up('md')]: {
minWidth: '200px',
backgroundColor: 'yellow',
},
},
},
},
})
export default theme
(tested: material-ui 4.0.1)

V5 update
Preferred solution is to create an intermediate theme (source):
let theme = createTheme()
theme = createTheme(theme , {
h5: {
fontSize: "1.5", //24px
fontWeight: title.fontWeight,
fontFamily: sansSerif(title.fontFamily),
letterSpacing: title.letterSpacing,
lineHeight: "2.1rem", //34px
color: "#636e72",
[theme.breakpoints.between("xs", "sm")]: {
fontSize: "1.25rem", // 20px
lineHeight: "1.9rem", // 30px
},
[theme.breakpoints.between("sm", "md")]: {
fontSize: "1.4rem", //24px
lineHeight: "2rem", // 35px
},
},
})
If you used createBreakpoints: as pointed out by #Ricardo Canelas comment, createBreakpoints has simply moved, right import is now: import createBreakpoints from "#mui/system/createTheme/createBreakpoints". However, keep in mind that this is still a private API at the time of writing so can move/break at any version update.
Preferred solution is to use an intermediate theme.

From https://github.com/mui-org/material-ui/issues/18017#issuecomment-545914925
import { createMuiTheme } from "#material-ui/core/styles";
const theme = createMuiTheme();
theme.overrides = {
MuiTypography: {
hero: {
[theme.breakpoints.up('md')]:{
fontSize: '11rem',
background: 'red',
},
fontSize: '3.75rem',
lineHeight: '5rem',
fontWeight: 700,
},
},
};

This is a side note, but if you want to change the values of the breakpoints you can edit the breakpoints object created with createBreakpoints({}):
import createBreakpoints from '#material-ui/core/styles/createBreakpoints'
const breakpoints = createBreakpoints({})
// outputs {xs: 0, sm: 600, md: 960, lg: 1280, xl: 1920}
breakpoints.values.lg = 1024
// outputs {xs: 0, sm: 600, md: 960, lg: 1024, xl: 1920}
You could also add additional breakpoints in a similar way if you didn't want to edit the existing items:
breakpoints.values['xxl'] = 3000
// outputs {xs: 0, sm: 600, md: 960, lg: 1280, xl: 1920, xxl: 3000}
In my project the breakpoints that Material-UI has set (xs: 0, sm: 600, etc.) didn't line up with the ones I was using already in my project, so I had to change them.

const theme = createMuiTheme();
theme.typography.h3 = {
fontSize: '1.2rem',
'#media (min-width:600px)': {
fontSize: '1.5rem',
},
[theme.breakpoints.up('md')]: {
fontSize: '2.4rem',
},
};
https://material-ui.com/customization/typography/#responsive-font-sizes

You can also use something like this -
MuiInputBase: {
defaultProps: {
sx: {
fontSize: {
xs: '16px',
md: '14px',
},
},
},
},

Related

Access custom palette from Material UI theme in sx/style props

Having trouble accessing my custom Material UI palette for some reason. I have created a custom theme in Theme.js like so:
import { createTheme, ThemeProvider } from "#mui/material/styles";
import { NextRequest } from "next/server";
import Inter from "typeface-inter";
const theme = createTheme({
palette: {
background: {
default: "#120C18",
},
primary: {
main: "#21172a",
},
secondary: {
main: "#33283e",
},
info: {
main: "#756c7c",
},
},
typography: {
fontFamily:
"Inter",
h1: {
font: "Inter",
fontSize: "min(3vw, 70px)",
fontWeight: "bold",
lineHeight: "1.15",
},
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 1000,
lg: 1200,
xl: 1600,
},
},
export default function Theme({ children }) {
return <ThemeProvider theme={theme}>{children}</ThemeProvider>;
}
then I imported and wrapped App.js in and all of my overrides work fine. But for the custom palette, I can't seem to access it in the sx or style props of certain components. I am trying to use something like theme.palette.primary.main or color="primary" but can't get anything to work.
How can I use the colors from the palette in my sx or style props?

Chakra UI spacing not matching expected defaults for padding and margin

I'm working on converting my app from rebass to chakra and currently dealing with a component that needs 16px padding on mobile, and 24px padding on tablet/desktop. In my component I have <Component px={[4, 6, 6]} />
Looking at this chart, I would expect to be able to use these numbers 4, 6 because I have confirmed the font-size is 16px. However, the actual values I'm seeing are 32px on mobile and 128px for tablet/desktop. I think something might be up with my chakra setup because I'm even unable to use inbetween values like 3.5, however I have had no problems with it so far.
My chakra setup is pretty simple at the moment because I'm early in the migration and I'm not messing with the default chakra values for the space key so I don't know what's causing these weird numbers.
const config: ThemeConfig = {
initialColorMode: 'dark',
useSystemColorMode: false,
}
const Button: ComponentStyleConfig = {
baseStyle: {
fontWeight: 'bold',
},
variants: {
primary: {
letterSpacing: '-0.19px',
borderRadius: '30px',
paddingLeft: '45px',
paddingTop: '14px',
paddingRight: '45px',
paddingBottom: '14px',
height: '56px',
backgroundColor: colors.white,
color: colors.black,
},
},
// The default size and variant values
defaultProps: {
variant: 'primary',
},
}
const theme = {
colors,
styles: globalStyles,
components: {
Button,
},
}
export default extendTheme({ ...theme, config })

Stepper vertical line detaches when label wraps over multiple lines?

The text inside my MaterialUI Stepper // StepLabel sometimes wraps over multiple lines.
I need to keep the vertical StepConnectors attached the StepIcons regardless of the number of lines of text in the label.
I've tried other solutions such as using CSS pseudo tags, but I hit a wall every time I try to work those changes into our existing solution.
Massive thanks in advance to anyone who can help.
Sandbox
https://codesandbox.io/s/practical-chebyshev-4hktl?file=/src/App.js
Current Screenshot
Existing ThemeOptions
import {
ThemeOptions,
createTheme,
ThemeProvider,
CssBaseline
} from "#material-ui/core";
export const themeOptions: ThemeOptions = {
overrides: {
MuiStepper: {
root: {
backgroundColor: "transparent" // remove set background
}
},
MuiStepConnector: {
vertical: {
padding: 0,
width: 5,
marginLeft: 8 // half icon
},
lineVertical: {
top: "calc(-50%)",
bottom: "calc(50%)",
borderLeftWidth: "2px",
marginLeft: "-1px", // center (1/2 width)
marginTop: "-6px", // add -ve margin to top and bottom ...
marginBottom: "-6px", // ... to hide gap due to smaller icon
borderColor: "lightgrey",
"$active &, $completed &": {
borderLeftWidth: "4px",
marginLeft: "-2px",
borderColor: "blue"
}
}
},
MuiStepLabel: {
label: {
textAlign: "left",
fontSize: "1.25rem",
"&$active": {
fontWeight: 400
},
"&$completed": {
fontWeight: 400
}
},
iconContainer: {
paddingRight: 12
}
},
MuiStepIcon: {
root: {
display: "block",
fontSize: "1rem",
color: "lightgrey",
"&$completed": {
color: "blue"
},
"&$active": {
color: "blue"
}
}
}
}
};
Just in case anyone finds this in the future, we compromised on the ​implementation to deliver the task.
Instead of having a variable height on the MuiStepLabel, it was given a fixed height to keep the StepIcons the same distance apart. If you imagine the below screenshot with a different font size + spacing, it ended up looking OK, but not ideal.
Before
// src/Theme/index.tsx
export const themeOptions: ThemeOptions = {
overrides: {
MuiStepConnector: {
marginTop: "-6px",
marginBottom: "-6px",
}
MuiStepLabel: {}
}
}
After
// src/Theme/index.tsx
export const themeOptions: ThemeOptions = {
overrides: {
MuiStepConnector: {
marginTop: "-2px",
marginBottom: "-4px",
minHeight: "calc(24px + 0.5rem)",
},
MuiStepLabel: {
height: "1.25rem",
lineHeight: "1.25rem",
}
}
}
Sandbox
https://codesandbox.io/s/epic-bohr-0p7fj?file=/src/Theme/index.ts

Material UI : Reference other properties of createMuiTheme inside theme.ts file?

When importing theme like this (in filename.style.ts) :
import theme from 'common/theme';
I can access the different properties, like for example
theme.breakpoints.down('md')
I am trying to reference the same property inside the theme.ts file, but ofcourse.. theme. is not valid here, so i'm trying to to find a way i can re-use / reference it.
As you see on MuiTable i'm trying to access breakpoints and palette/primary.
theme.ts
import createMuiTheme from '#material-ui/core/styles/createMuiTheme';
export const MuiPaperBackgroundColor = '#f7f8f6';
export default createMuiTheme({
spacing: 8,
breakpoints: {
values: {
xs: 0, sm: 600, md: 960, lg: 1280, xl: 1650,
},
},
palette: {
primary: {
main: '#3f18aa',
extraLight: 'rgb(193, 181, 227)',
noDataColor: '#cccccc',
cardBgColor: '#ECECEC',
chartColors: [
'#E77F42',
'#F3C3A3',
],
},
overrides: {
MuiTable: {
root: {
whiteSpace: 'nowrap',
[theme.breakpoints.down('md')]: {
'& tr': {
'& td:first-child, & th:first-child': {
position: 'sticky',
left: 0,
backgroundColor: theme.palette.header.main,
color: theme.palette.primary.contrastText,
zIndex: 2,
},
},
},
},
},
},
});
Build your theme out of the individual material-ui packages. Here's how I did it:
import createMuiTheme from '#material-ui/core/styles/createMuiTheme';
import createBreakpoints from '#material-ui/core/styles/createBreakpoints';
const breakpoints = createBreakpoints({
// your settings
});
const theme = createMuiTheme({
breakpoints,
overrides: {
MuiTable: {
root: {
[breakpoints.down('md')]: {
// style
},
},
},
},
});
Ricky's solution is nice in praxis but Material warns against importing deeper than two levels (#material-ui/core/styles/foo in this case) because that is considered private and not part of any public contract. I.e., it can change any release.
It might not work with Breakpoints, but colours or fontWeights and such can be easily shared as plain constants declared before. But I am also sceptical if it's a good idea to include responsiveness in this declaration in first place.
You can attach the props after the theme is declared.
let theme = createMuiTheme({
overrides: {
MuiAppBar: {
root: {
transform: 'translateZ(0)'
}
}
},
props: {
MuiIconButton: {
disableRipple: true
}
}
});
theme = responsiveFontSizes(theme);
theme.overrides.MuiCssBaseline = {
'#global': {
'.testMe': {
color: 'red'
},
'.container-std': {
[theme.breakpoints.up('lg')]: {
maxWidth: '1200px',
marginLeft: 'auto',
marginRight: 'auto'
}
},
'.container-wide': {
margin: theme.spacing(2, 2)
}
}
};

Adding breakpoint to custom theme in Material UI Next (reactjs)

I'm creating a custom theme with mui as follows:
export default createMuiTheme({
breakpoints: {
keys: [
"xxs",
"xs",
"sm",
"md",
"lg",
"xl",
],
values: {
xxs: 0,
xs: 414, // iPhone X and below in portrait mode
sm: 600,
md: 960,
lg: 1280,
xl: 1920,
},
},
})
But when I try to use it in a class declaration like so:
const styles = theme => ({
root: {
[theme.breakpoints.down('xxs')]: {
textAlign: "center",
padding: theme.spacing.unit * 2,
},
},
})
I get the following CSS:
#media (max-width:NaNpx) {
.root-3 {
padding: 16px;
text-align: center;
}
}
Is there a special way to add a custom breakpoint vs. just modifying existing ones?
Currently it is only possible to customize the values of the predefined breakpoints. Here is an example:
const theme = createMuiTheme({
breakpoints: {
values: {
xs: 0,
sm: 450,
md: 600,
lg: 900,
xl: 1200
}
}
});
The breakpoint names cannot be configured. There is a comment in createBreakpoints.js explaining this:
// Sorted ASC by size. That's important.
// It can't be configured as it's used statically for propTypes.
export const keys = ['xs', 'sm', 'md', 'lg', 'xl'];
UPDATE (September 2018):
This feature has been requested and is currently under discussion. See material-ui/issues/11649
In case you prefer not to change the default values,
You can use a quick workaround,
use the theme breakpoints field to change the breakpoint value where needed.
For example:
xxl breakpoint
[theme.breakpoints.up(theme.breakpoints.values.xl + CUSTOM_BREAKPOINT_DIFFERENCE)]: {
padding: "0 3.5rem",
},

Resources