I am struggling to change the font family on Material-UI. I am trying to set it for the whole project using MuiTheme. How can I do this using a font from Google Fonts?
Someone did this in another topic
import { createMuiTheme } from 'material-ui/styles';
import createPalette from 'material-ui/styles/palette';
import createTypography from 'material-ui/styles/typography';
const theme = createMuiTheme({
typography: createTypography(createPalette(), {
fontFamily: '"Comic Sans"',
})
});
class App extends Component {
render() {
return (
<MuiThemeProvider theme={theme}>
Related
This is how you create a theme and propagate it using MUI.
import { ThemeProvider } from "#mui/material";
const myTheme = createTheme({
backgroundColor: {
primary: "#f9f9fb",
secondary: "#ededf3",
tertiary: "#cbcbdc",
},
})
const Index: FC = () => {
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
};
Now, for some reason, I need to get the context of the MUI theme in my app.
I've search everywhere but it seems that they do not expose the context anywhere. I found 3 contexts in private-theming, styled-engine and styled-engine-sc but none of them worked.
How can I do that ?
The way you create the theme it wrong should be like following:
const theme = createTheme({
palette: {
primary: {
main: red[500],
},
},
});
with the property palette.
and the way to get values you could use the hook useTheme .
first import
import { useTheme } from "#mui/material";
and inside your components you can use the palette you set to your theme like:
const { palette } = useTheme();
MUI uses the context provided by the styled engine:
import { ThemeContext } from '#mui/styled-engine';
It can also be imported directly from your engine of choice (emotion in the example below):
import { ThemeContext } from '#emotion/react';
From the Material UI website, there seem to be multiple ways of theming, and I'm not sure which to use.
There's this method, which just seems to use pure React context. However, I don't see how main relates to the color. I'm not sure how it is a field that Checkbox is able to extract from, given we don't specify it in the HTML.
import * as React from 'react';
import { createTheme, ThemeProvider } from '#mui/material/styles';
import Checkbox from '#mui/material/Checkbox';
import { green, orange } from '#mui/material/colors';
const outerTheme = createTheme({
palette: {
primary: {
main: orange[500],
},
},
});
const innerTheme = createTheme({
palette: {
primary: {
main: green[500],
},
},
});
export default function ThemeNesting() {
return (
<ThemeProvider theme={outerTheme}>
<Checkbox defaultChecked />
<ThemeProvider theme={innerTheme}>
<Checkbox defaultChecked />
</ThemeProvider>
</ThemeProvider>
);
}
There's this method, which seems to make more sense. Here we explicitly extract the theme color via theme.status.danger and place it into the color field.
import * as React from 'react';
import Checkbox from '#mui/material/Checkbox';
import { createTheme, ThemeProvider, styled } from '#mui/material/styles';
import { orange } from '#mui/material/colors';
declare module '#mui/material/styles' {
interface Theme {
status: {
danger: string;
};
}
// allow configuration using `createTheme`
interface ThemeOptions {
status?: {
danger?: string;
};
}
}
const CustomCheckbox = styled(Checkbox)(({ theme }) => ({
color: theme.status.danger,
'&.Mui-checked': {
color: theme.status.danger,
},
}));
const theme = createTheme({
status: {
danger: orange[500],
},
});
export default function CustomStyles() {
return (
<ThemeProvider theme={theme}>
<CustomCheckbox defaultChecked />
</ThemeProvider>
);
}
I could also change the MUI nested component:
import * as React from 'react';
import { ThemeProvider, createTheme } from '#mui/material/styles';
import Button from '#mui/material/Button';
const theme = createTheme({
components: {
MuiButton: {
styleOverrides: {
root: {
fontSize: '1rem',
},
},
},
},
});
export default function GlobalThemeOverride() {
return (
<ThemeProvider theme={theme}>
<Button>font-size: 1rem</Button>
</ThemeProvider>
);
}
Which is the right way to theme?
Good evening, I've recently started using UI stuff and from what I've seen in version 5, the theme as you mentioned is used. Another way I'm styling it is using the SX props on the element.
https://mui.com/pt/system/the-sx-prop/
I spend a few days trying to customize the primary color and add two more colors to the palette. I was able to declare properly the new colors...but at the moment to see those new colors reflected on the button doesnt work. The button are taking the default properties even when I wrapped under the Themeprovider. I'm using storybook.
import React from "react";
import { Meta } from "#storybook/react/types-6-0";
import { Button } from "#mui/material";
import { createTheme, ThemeProvider, styled } from '#mui/material/styles';
const theme = createTheme({
palette: {
primary: {
contrastText: "#ff0000",
light: "#ff0000",
main: "#ff0000",
dark: "#ff0000"
},
tertiary: {
main: "#ff0000"
},
failure: {
main: "#ff0000"
}
}
});
const CustomStyles = () => {
return (
<ThemeProvider theme={theme}>
<Button variant="contained">Click me</Button>
</ThemeProvider>
);
}
const Template = () => {
return (
<CustomStyles />
);
};
export const Default = Template.bind({});
export default {
title: "mylib/Theme"
} as Meta;
This is how it looks
default button style
Themeprovider custom palette
As you may see, the ThemeProvider has the palette color definition...but some how the button doesnt take it.
Thanks in advance
Adding this to.storybook/preview.js was enough to solve my case. Follow the official migration guide on this matter to learn more.
//.storybook/preview.js
import { ThemeProvider } from '#mui/material/styles';
import { ThemeProvider as Emotion10ThemeProvider } from 'emotion-theming';
import { theme } from '../your/system/customTheme/path';
const defaultTheme = theme;
const withThemeProvider = (Story, context) => {
return (
<Emotion10ThemeProvider theme={defaultTheme}>
<ThemeProvider theme={defaultTheme}>
<Story {...context} />
</ThemeProvider>
</Emotion10ThemeProvider>
);
};
export const decorators = [withThemeProvider];
//another storybook exports.
EDIT: this issue seems to be related to stackoverflow.com/a/70254078/17724218 as OP commented below.
Whenever I use a container in material-ui, I have to manually set the maxWidth to false. Since I don't think I will ever require the maxWidth of the container to every be anything but 100% of the available space and it is what I expect container to work, I wanted to set it globally in my react app.
What I have to do every time
import React from "react";
import Container from "#material-ui/core/Container";
import Paper from "#material-ui/core/Paper";
export default function App() {
return (
<Container maxWidth={false}>
.
.
.
</Container>
);
}
I tried setting it in the createTheme, but it does not work.
const theme = createMuiTheme({
overrides: {
MuiContainer: {
root: {
maxWidth: `100%`,
},
},
},
});
Instead of trying to override the CSS, the simplest approach is to set the default for the prop:
const theme = createMuiTheme({
props: {
MuiContainer: {
maxWidth: false
}
}
});
Related answers:
Is it possible to override material-ui components default props?
How to override Material UI .MuiContainer-maxWidthLg?
I am using "material-ui": "^1.0.0-beta.33" for my project.
What I want to do is set primary palette color dynamically inside a react component (color will be fetched from some api).
Basically I want to override below:
const theme = createMuiTheme({
palette: {
primary: "some color from api"
},
})
Is there a way to set this in componentDidMount function of any component?
Reference: https://material-ui-next.com/
I created a component that uses MuiThemeProvider and wrap my entire app around that component. Below is the structure of the component.
import React, {Component} from "react";
import {connect} from "react-redux";
import {withStyles} from 'material-ui/styles';
import * as colors from 'material-ui/colors';
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
import { withRouter } from 'react-router-dom';
export class ThemeWrapperComponent extends Component {
constructor(props){
super(props);
}
render(){
return (
<MuiThemeProvider theme={createMuiTheme(
{
palette: {
primary: { main: **colorFromApi** },
}
)}>
<div>
{ this.props.children }
</div>
</MuiThemeProvider>
)
}
}
export const ThemeWrapper = withRouter(connect(mapStateToProps)(ThemeWrapperComponent));
Below is how I wrapped my app around this component:
<ThemeWrapper>
<div>
<Routes/>
</div>
</ThemeWrapper>
Now, whatever colour you are sending from the api gets applied to the whole theme. More customisation can be done based on requirement.
I'm doing exactly this. Even got it working with WebMIDI using MIDI controller sliders and knobs just for fun.
The basic strategy is to use createMuiTheme and ThemeProvider and to store the theme in your application store (context, state, redux), etc.
class ThemeManager extends React.Component {
getThemeJson = () => this.props.context.themeJson || defaultThemeJson
componentDidMount () {
const themeJson = this.getThemeJson()
const theme = createMuiTheme(themeJson)
this.props.setContext({ theme, themeJson })
}
render () {
const { children, context } = this.props
const theme = context.theme
return theme
? <ThemeProvider theme={theme}>{children}</ThemeProvider>
: children
}
}
https://github.com/platform9/pf9-ui-plugin/blob/master/src/app/ThemeManager.js
and then you simply update your application's state.
handleImport = themeStr => {
const themeJson = JSON.parse(themeStr)
const theme = createMuiTheme(themeJson)
this.props.setContext({ theme, themeJson })
}
https://github.com/platform9/pf9-ui-plugin/blob/master/src/app/plugins/theme/components/ImportExportPanel.js#L17