I am using Typescript, React. Material-UI (now MUI) and Webpack.
I am trying to apply a theme using material-ui's ThemeProvider but it only seems to apply that theme to components that are not from the material-ui library.
import React from 'react'
import { ThemeProvider, CssBaseline } from '#material-ui/core'
import { createTheme } from '#material-ui/core/styles'
import Router from './components/Router'
import NavBar from './components/NavBar'
import Toolbar from '#mui/material/Toolbar'
import Container from '#mui/material/Container'
export function App(): JSX.Element {
const theme = createTheme({
palette: {
type: 'dark',
primary: {
main: '#ffeb3b',
},
secondary: {
main: '#795548',
},
},
})
return (
<ThemeProvider theme={theme}>
<NavBar />
<Toolbar />
<Container>
<Router />
</Container>
<CssBaseline />
</ThemeProvider>
)
}
The I can see darkmode being toggled so long as the backdrop for the app is not a MUI paper element. Also my AppBar contained within my NavBar component does not change color when I change the palette main colors.
Putting the theme into a different file does not help. And I have already run Yarn upgrade so everything should be up to date. What is going on?
I was working on Filled Inputs in form of TextFields as well as FilledInput. I need a solution to make the background color of all the FilledInputs, currently, I am using makeStyle and adding class names to each component, which seems redundant.
Can someone give a better workaround, like changing some property in the theme?
From the FilledInput API docs we can learn that:
The MuiFilledInput name can be used for providing default props or
style overrides at the theme level.
And from this this guide in overriding MUI CSS globally we can learn to use overrides key of the theme to potentially change every single style injected by Material-UI into the DOM
Sample Code:
import React from "react";
import { createMuiTheme, ThemeProvider } from "#material-ui/core/styles";
import FilledInput from "#material-ui/core/FilledInput";
const theme = createMuiTheme({
overrides: {
// Style sheet name
MuiFilledInput: {
// Name of the rule
root: {
backgroundColor: "orange"
}
}
}
});
function OverridesCss() {
return (
<ThemeProvider theme={theme}>
<FilledInput placeholder="sample placeholder" />
</ThemeProvider>
);
}
export default OverridesCss;
I'm working on a React-redux app project and I'm new to material-ui theming. I created a theme object in a separate theme.js file, outlined as follows:
const theme = createMuiTheme({
palette: {
primary: blue,
error: {
main: red[300],
},
background: {
default: indigo[50],
},
}
})
export default theme;
And I rendered MuiThemeProvider in my outer layer of the app in index.js:
ReactDOM.render(
<Provider store={store}>
<MuiThemeProvider theme={theme}>
<App />
</MuiThemeProvider>
</Provider>,
document.getElementById("root")
);
My question is that, my app's currently showing the correct background color but I don't know how to properly use the color I created in my palette in other parts of my app. For example, I tried to assign the primary color blue to a title in App.js:
<CardContent color="primary">
TITLE
</CardContent>
But it didn't work. Everything's imported properly. No error. The font color isn't changed. Any idea?
By the way, I've seen tutorial using ThemeProvider tag, what's the difference between ThemeProvider and MuiThemeProvider, which one do you recommend using in general?
Your problem is not in the theming probably, From Material-ui documentation Card Content doesn't accept the color parameter
Card Content
I would try :
<CardContent>
<Typography color="primary">
Hello world
</Typography>
</CardContent>
I'm trying to import and use the Yellowtail font (from Google Fonts) in my React app in a Material-UI theme.
As far as i know all google fonts are on npm, I've installed it, with the
npm install typeface-yellowtail --save
command.
I have imported it in App.js, put it in the font-family part of the theme, passed the theme to the MuiThemeProvider, but it does not work. What did I miss?
This is what i have inside of App.js (header contains an AppBar with some grids and body contains only an h1 text for testing)
import React, { Component, Fragment } from 'react';
import Header from './Components/Layouts/Header';
import AppBody from './Components/Layouts/AppBody';
import Footer from './Components/Layouts/Footer';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core';
import 'typeface-yellowtail';
const theme = createMuiTheme({
typography: {
fontFamily:
'"Yellowtail", cursive',
},
});
class App extends Component {
render() {
return (
<MuiThemeProvider theme={theme}>
<Header />
<AppBody />
<Footer />
</MuiThemeProvider>
);
}
}
export default App;
Instead of installing via npm, you can just first load CSS file.
#import url('https://fonts.googleapis.com/css?family=Yellowtail&display=swap');
Import this CSS file
import './assets/css/yellowtail.css';
Now you don't need to use any #font-face. This can be used with font families like normal.
You are missing three things:
Import the npm package as something
Use the CssBaseline component
Add an override to the object provided to createMuiTheme()
See example:
import React, { Component, Fragment } from 'react';
import Header from './Components/Layouts/Header';
import AppBody from './Components/Layouts/AppBody';
import Footer from './Components/Layouts/Footer';
import { MuiThemeProvider, createMuiTheme, CssBaseline } from '#material-ui/core';
import yellowtail from 'typeface-yellowtail';
const theme = createMuiTheme({
typography: {
fontFamily:
'"Yellowtail", cursive',
},
overrides: {
MuiCssBaseline: {
'#global': {
'#font-face': [yellowtail],
},
},
},
});
class App extends Component {
render() {
return (
<MuiThemeProvider theme={theme}>
<CssBaseline />
<Header />
<AppBody />
<Footer />
</MuiThemeProvider>
);
}
}
export default App;
Example CodeSandbox (MUI v3): https://codesandbox.io/s/late-pond-gqql4?file=/index.js
Example CodeSandbox (MUI v4): https://codesandbox.io/s/pensive-monad-eqwlx?file=/index.js
Notes
MuiThemeProvider changed to ThemeProvider in the transition from Material-UI v3 to v4. If you are on v4, this is the only change needed - this example code otherwise works on both versions.
You must wrap text in Material-UI's Typography component for the font to be used.
There is a much easier way of doing this that doesn't require a .css file or installing any extra packages.
If your font is available over a CDN like Google Fonts then just imported into the root HTML file of your app:
<link
href="https://fonts.googleapis.com/css2?family=Yellowtail&display=swap"
rel="stylesheet"
/>
Then add one line in the Material-UI theme:
const theme = createTheme({
typography: { fontFamily: ["Yellowtail", "cursive"].join(",") }
});
Working codesandbox example with Material-UI v5.
Update: Since #ekkis mentioned I'm adding further details on how to include the Google Font. The following answer assumes you're using Material UI v4.10.1
Install the gatsby-plugin-web-font-loader to install Google font.
Edit gatsby-config.js to include the plugin and the Google font.
module.exports = {
plugins: [
{
resolve: "gatsby-plugin-web-font-loader",
options: {
google: {
families: ["Domine", "Work Sans", "Happy Monkey", "Merriweather", "Open Sans", "Lato", "Montserrat"]
}
}
},
]
}
To use the font, create a file called theme.js in src/components
import {
createMuiTheme,
responsiveFontSizes
} from "#material-ui/core/styles"
let theme = createMuiTheme({
typography: {
fontFamily: [
"Work Sans",
"serif"
].join(","),
fontSize: 18,
}
})
// To use responsive font sizes, include the following line
theme = responsiveFontSizes(theme)
export default theme
Now that you've the theme export, you can use it in your components.
Import theme on to your components. Let's say <Layout /> is your main component.
// src/components/layout.js
/**
* External
*/
import React from "react"
import PropTypes from "prop-types"
import {
ThemeProvider
} from "#material-ui/styles"
import { Typography } from "#material-ui/core"
/**
* Internal
*/
import theme from "./theme"
const Layout = ({ children }) => {
return (
<>
<ThemeProvider theme={theme}>
<Typography variant="body1">Hello World!</Typography>
</ThemeProvider>
</>
)
}
To use Google font in other components, just use
<Typography ...>Some Text</Typography>
As long as these components use as their parent, these components will continue to use the Google Font. Hope this helps.
Old Answer:
Place your text in the Typography component to reflect the Google Font you installed via npm
import { Typography } from "#material-ui/core"
Assume you have some text in <AppBody>
<AppBody>
Hello World!
</AppBody>
The above text should now be changed to
<AppBody>
<Typography variant="body1">Hello World!</Typography>
</AppBody>
Refer Material UI docs for the different variants.
I have define my font in main CSS file(index.css)
#font-face {
font-family: 'mikhak';
src: url(./fonts/mikhak.ttf) format("truetype")
}
and then in the App.tsx I added theme
const theme = createTheme({
typography: {
fontFamily: 'mikhak, Raleway, Arial',
}
});
ReactDOM.render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>,
document.getElementById('root')
);
Note that it is for Typography components.
This worked for me:
Install your font as a package using #fontsource on npm, i.e:
npm i #fontsource/work-sans
Add to your _app.js your import, this makes your package (font) accessible globally
const workSans = require('#fontsource/work-sans');
In your theme modify your typography:
...
typography: {
fontFamily: 'Work Sans',
}
...
That's it!
I want to add to #georgeos answer that a small revision of the proposed solution worked for me:
export const theme = createTheme({
...
components: {
MuiCssBaseline: {
styleOverrides: {
'#global': {
'#font-face': [Inter, Nunito],
},
},
},
},
...
});
I also needed to add the following to the app.ts file (source):
function App(){
...
return (
<ThemeProvider theme={theme}>
<CssBaseline enableColorScheme /> <---
...
</ThemeProvider>);
...
}
I am trying to look for documentation or code example how can I specify addition colors in Material UI theme.
Right now I have following theme configuration
const theme = createMuiTheme({
palette: {
primary: {
main: "#B31728"
},
secondary: {
main: "#202833"
}
},
...
Now I have a case where I want to use a color for successful operations such as
import { green } from "#material-ui/core/colors";
<Fragment>
{isVerified ? (
<VerifiedUser style={{ color: green[500] }} />
) : (
<Error color="primary" />
)}
</Fragment>
I want to set the color of VerifiedUser Icon in the same way it is set for Error Icon. But the theme palette configuration only has primary and secondary intentions. How can I set a color lets say "success" so that I can be able to pass it like
<VerifiedUser color="success" />
For Material-UI, you can only assign inherit primary secondary default to color, you can customize primary and secondary through createMuiTheme.
To apply your custom theme into component, use MuiThemeProvider :
<MuiThemeProvider theme={theme}>
//your component
</MuiThemeProvider>
Therefore, if you want to generate green theme component, you can create a theme, then use MuiThemeProvider to wrap your component.
Code sample(generate green button):
import React from 'react';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
const theme = createMuiTheme({
palette: {
primary: { main: '#00FF00' }
});
function GreenButton() {
return (
<MuiThemeProvider theme={theme}>
<Button color="primary">This is green button</Button>
</MuiThemeProvider>
);
}
Further reading: Customize Material-UI with your theme