How do I apply a Font Theme in React Material-UI? - reactjs

I'm trying to apply a google font to my Material-UI react project, but can't seem to get it to take. I'm using mui 0.14.2.
My index.html font load:
<link href='https://fonts.googleapis.com/css?family=PT+Sans:400,700' rel='stylesheet' type='text/css'>
My component where I apply the theme:
import ThemeManager from 'material-ui/lib/styles/theme-manager';
import LightRawTheme from 'material-ui/lib/styles/raw-themes/light-raw-theme';
const App = React.createClass({
childContextTypes: {
muiTheme: React.PropTypes.object,
},
getChildContext: function() {
return {
muiTheme: ThemeManager.modifyRawThemeFontFamily(ThemeManager.getMuiTheme(LightRawTheme), 'PT Sans, sans-serif')
}
},
...etc etc
}

The other answers don't seem to work for Material-UI v1. Here's what worked for me:
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}>
Here's another example for overriding the font while using the dark theme:
const theme = (() => {
const palette = createPalette({
type: 'dark',
});
const typography = createTypography(palette, {
fontFamily: '"Comic Sans"',
});
return createMuiTheme({
palette: palette,
typography: typography,
});
})();
The typography documentation for v1 is here although I had trouble getting the example working: https://material-ui-1dab0.firebaseapp.com/customization/themes#typography

If you're just looking to change the font of your material-ui theme, change muiTheme in the MuiThemeProvider provider component. The docs have an example here: http://www.material-ui.com/#/customization/themes
Should look something like this:
App.css
/* Load in your font */
#import url('https://fonts.googleapis.com/css?family=Lato');
App.js
// App.js
import './App.css'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
const font = "'Lato', sans-serif";
const muiTheme = getMuiTheme({
fontFamily: font
});
function App(props) {
return(
<MuiThemeProvider muiTheme={muiTheme}>
<div style={{fontFamily: font}}>...</div>
</MuiThemeProvider>
);
}
Note most of the components had to have their fonts updated, but I added fontFamily to the enclosing div (as seen above) as well in order for all to be updated (headers specifically for me).
If you're wondering what else you can override, it is probably easiest to just look at the code (https://github.com/callemall/material-ui/blob/master/src/styles/getMuiTheme.js) where it is defined

I figured this out. I did 2 things, the first of which I don't think mattered:
I switched to using a full raw theme, then implementing in-component like this:
getChildContext: function() {
return {
muiTheme: ThemeManager.getMuiTheme(rawTheme)
}
},
The second thing, which was more likely the culprit, was escaping the space in 'PT Sans', as follows:
//theme.js
import Colors from 'material-ui/lib/styles/colors';
import ColorManipulator from 'material-ui/lib/utils/color-manipulator';
import Spacing from 'material-ui/lib/styles/spacing';
import zIndex from 'material-ui/lib/styles/zIndex';
export default {
spacing: Spacing,
zIndex: zIndex,
fontFamily: 'PT\ Sans',
palette: {
primary1Color: Colors.cyan500,
primary2Color: Colors.cyan700,
primary3Color: Colors.lightBlack,
accent1Color: Colors.pinkA200,
accent2Color: Colors.grey100,
accent3Color: Colors.grey500,
textColor: Colors.darkBlack,
alternateTextColor: Colors.white,
canvasColor: Colors.white,
borderColor: Colors.grey300,
disabledColor: ColorManipulator.fade(Colors.darkBlack, 0.3),
pickerHeaderColor: Colors.cyan500,
}
};
Voila, as mundane and uninteresting a bug as you could hope for.

I'm using Material-UI version 3.9.2. I found this work-around.
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles'
import Typography from '#material-ui/core/Typography'
const theme = createMuiTheme({
palette: {
primary: { main: '#228e22' },
secondary: { main: '#4d4d4d' },
},
typography: {
useNextVariants: true,
fontFamily: '"Montserrat", Arial, Helvetica, sans-serif',
},
})
const Base = () => (
<MuiThemeProvider theme={theme}>
<Typography component="h1" variant="h1">
Hello
</Typography>
</MuiThemeProvider>
)

I use The bellow code and the result was successful. write the javascript bellow code in your own file and then write the #font-face in its CSS file:
import './App.css';
import { createMuiTheme, MuiThemeProvider } from '#material-ui/core/styles';
import createPalette from '#material-ui/core/styles/createPalette';
import createTypography from '#material-ui/core/styles/createTypography';
const theme = createMuiTheme({
typography: createTypography(createPalette({}), {
fontFamily: '"IRANSansWeb"'
}),
});
function App() {
return(
<MuiThemeProvider theme={theme}>
</MuiThemeProvider>
);
}
#font-face{
font-family: "IRANSansWeb";
src: url('./fonts/iransans/ttf/IRANSansWeb.ttf') format('ttf'),
url('./fonts/iransans/eot/IRANSansWeb.eot') format('eot'),
url('./fonts/iransans/woff/IRANSansWeb.woff') format('woff'),
url('./fonts/iransans/woff2/IRANSansWeb.woff2') format('woff2')
}

After update Material UI to:
"#mui/icons-material": "^5.0.4",
"#mui/lab": "^5.0.0-alpha.51",
"#mui/material": "^5.0.4",
"#mui/styles": "^5.0.1",
In your theme.js
import { createTheme } from "#mui/material/styles";
// Create a theme instance.
const theme = createTheme({
typography: {
fontFamily: '"Merienda", cursive',
},
palette: {
primary: {
main: "rgb(68, 139, 68)",
},
secondary: {
main: "rgb(141, 202, 141)",
// contrastText: "#fff",
},
spacing: 24,
},
});
export default theme;

Related

After switching from #material-ui to #mui theme is not applied

I began my project using #material-ui package and created a theme that was applied to my app properly
After switching to #mui theme is not applied anymore
theme definition:
import { createTheme } from '#mui/material/styles';
import "./fonts/fonts.module.css";
export const theme = createTheme({
palette: { ... },
shadows: ["none"],
typography: {
fontFamily: ...
button: {
textTransform: "none"
},
htmlFontSize: 16,
},
components: {
MuiCssBaseline: {
styleOverrides: {
fontFamily: "LatoLatinWeb"
}
}
}
});
Usage in MyComponent:
import { ThemeProvider } from "#mui/material/styles";
import { theme } from "../theme";
import { CssBaseline } from '#mui/material';
const MyComponent = () => {
...
return (
<ThemeProvider theme={theme}>
<CssBaseline/>
{children}
</ThemeProvider>
How can I fix this so the theme is applied?
Simplay add this
import CssBaseLine from '#mui/material/CssBaseline'

'Undefined' when attempting to pass MaterialUI theme props to styled components

I'm attempting to access my Material-UI theme props within a styled component, however I keep getting...
TypeError: Cannot read property 'primary' of undefined or similar errors in the browser.
Here is my custom theme (index.ts)
import { createMuiTheme } from "#material-ui/core";
import { blue } from "#material-ui/core/colors";
const theme = createMuiTheme({
palette: {
primary: {
main: blue[800],
contrastText: "#FFF"
},
secondary: {
main: blue[600],
contrastText: "#FFF"
}
},
typography : {
fontFamily: [
"Nunito",
"Roboto",
].join(",")
}
});
export default theme;
Here is where my theme wraps my application in the App.tsx
// Other imports
import theme from "../../app/theme/index";
const App: React.FC = () => {
return (
<>
<StylesProvider injectFirst>
<ThemeProvider theme={theme}>
// Routing stuff
</ThemeProvider>
</StylesProvider>
</>
);
};
export default App;
And here is where I am attempting to use my styled component
import { ListItem } from "#material-ui/core";
import React from "react";
import styled from "styled-components";
const Brand = styled(ListItem)`
background-color: ${props => props.theme.palette.primary.dark},
padding: ${props => props.theme.spacing(1)},
font-size: ${props => props.theme.typography.h6.fontSize},
font-weight: ${props => props.theme.typography.fontWeightMedium},
color: "white",
min-height: "64px",
padding-left: ${props => props.theme.spacing(6)}
`;
const SidebarNew: React.FC = () => {
return (
<Brand button>
// Stuff
</Brand>
);
};
export default SidebarNew;
This compiles but fails in the browser. What am I missing here?
If I use material-ui's built in styled like below, it appears to work, however I would prefer to use styled-components directly
const Brand = styled(ListItem)(({ theme }) => ({
backgroundColor: theme.palette.primary.dark,
padding: theme.spacing(1),
fontSize: theme.typography.h6.fontSize,
fontWeight: theme.typography.fontWeightMedium,
color: "white",
minHeight: 64,
paddingLeft: theme.spacing(6)
}));
You need to use ThemeProvider from styled-components (SCThemeProvider in the example below) in addition to the Material-UI ThemeProvider; otherwise styled-components won't know about your theme.
Here is a working example:
import {
createMuiTheme,
StylesProvider,
ThemeProvider
} from "#material-ui/core";
import { ThemeProvider as SCThemeProvider } from "styled-components";
import * as React from "react";
import Dashboard from "./Dashboard";
import "./styles.css";
const theme = createMuiTheme({
palette: {
primary: {
main: "#1a1aff",
contrastText: "#FFF"
},
secondary: {
main: "#ff3333",
contrastText: "#FFF"
}
},
typography: {
h5: {
fontSize: "10px"
}
}
});
export default function App() {
return (
<StylesProvider injectFirst>
<ThemeProvider theme={theme}>
<SCThemeProvider theme={theme}>
<Dashboard />
</SCThemeProvider>
</ThemeProvider>
</StylesProvider>
);
}

Global Styles with React and MUI

I'm new to React and MUI but I have to write an enterprise application with a nice styling. I would like to use some kind of global styles for my application (to be able to change it later on
) with functional components in react (maybe I will later add redux).
What's the best practice approach for global styles with react and material (latest versions)?
What about this one (ThemeProvider): https://material-ui.com/styles/advanced/?
I read about MuiThemeProvider but could not find it in the material version 4 documentation. Is it obsolete? What's the difference between MuiThemeProvider and ThemeProvider?
React (client side rendering) & Material (latest versions)
Backend: Node
In Material-UI v5, you can use GlobalStyles to do exactly that. From what I know, GlobalStyles is just a wrapper of emotion's Global component. The usage is pretty straightforward:
import GlobalStyles from "#mui/material/GlobalStyles";
<GlobalStyles
styles={{
h1: { color: "red" },
h2: { color: "green" },
body: { backgroundColor: "lightpink" }
}}
/>
Note that you don't even have to put it inside ThemeProvider, GlobalStyles uses the defaultTheme if not provided any:
return (
<>
<GlobalStyles
styles={(theme) => ({
h1: { color: theme.palette.primary.main },
h2: { color: "green" },
body: { backgroundColor: "lightpink" }
})}
/>
<h1>This is a h1 element</h1>
<h2>This is a h2 element</h2>
</>
);
Live Demo
You can actually write global styles with material UI:
const useStyles = makeStyles((theme) => ({
'#global': {
'.MuiPickersSlideTransition-transitionContainer.MuiPickersCalendarHeader-transitionContainer': {
order: -1,
},
'.MuiTypography-root.MuiTypography-body1.MuiTypography-alignCenter': {
fontWeight: 'bold',
}
}
}));
Global Styles with Material UI & React
// 1. GlobalStyles.js
import { createStyles, makeStyles } from '#material-ui/core';
const useStyles = makeStyles(() =>
createStyles({
'#global': {
html: {
'-webkit-font-smoothing': 'antialiased',
'-moz-osx-font-smoothing': 'grayscale',
height: '100%',
width: '100%'
},
'*, *::before, *::after': {
boxSizing: 'inherit'
},
body: {
height: '100%',
width: '100%'
},
'#root': {
height: '100%',
width: '100%'
}
}
})
);
const GlobalStyles = () => {
useStyles();
return null;
};
export default GlobalStyles;
** Then Use it in App.js like below**
// 2. App.js
import React from 'react';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import { Router } from 'react-router-dom';
import { NavBar, Routes, GlobalStyles, Routes } from '../';
const theme = createMuiTheme({
palette: {
primary: {
main: 'blue'
}
}
});
const App = () => {
return (
<MuiThemeProvider theme={theme}>
<Router>
<NavBar />
<GlobalStyles />
<Routes />
</Router>
</MuiThemeProvider>
);
};
export default App;
This Works for me with my react project.
For global styles you can use it like shown below.
This is the best implementation that has worked for me.
const theme = createMuiTheme({
overrides: {
MuiCssBaseline: {
'#global': {
html: {
WebkitFontSmoothing: 'auto',
},
},
},
},
});
// ...
return (
<ThemeProvider theme={theme}>
<CssBaseline />
{children}
</ThemeProvider>
);
For more reference: Global CSS
In my experience, using MuiThemeProvider and createMuiTheme have worked wonderfully. However, I am using Material-UI version 3.9.2.
MuiThemeProvider should wrap around your entire application. All you need to do in all of your components would be to instead of passing your styles object to with styles, pass a function that passes in the theme.
Ex:
import React from 'react';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import {NavBar, Routes} from '../'
const theme = createMuiTheme({
palette: {
primary: {
main: 'red'
},
},
/* whatever else you want to add here */
});
class App extends Component {
render() {
return (
<MuiThemeProvider theme={theme}>
<NavBar />
<Routes />
</MuiThemeProvider>
)
}
then in navbar let's say:
import React from 'react';
import { withStyles } from '#material-ui/core';
const styles = theme => ({
root: {
color: theme.palette.primary.main,,
}
})
const NavBar = ({classes}) => {
return <div className={classes.root}>navigation</div>
}
export default withStyles(styles)(NavBar);
Hope that helps, works very well for me!

Override Material UI Button Text

Material UI button defaults the text within the button to uppercase. I want to override the text with the button to be the same as I have typed and not be uppercase.
I have tried to override the styling by using texttransform - none
viewButton:
{
backgroundColor: "#00D2BC",
radius: "3px",
color: "#FFFFFF",
texttransform: "none"
}
<Button
className={classes.viewButton}
data-document={n.id}
onClick={this.handleView}
>
View Document
</Button>
Can anyone help with this.
Thanks
The only problem I see with the code in your question is that you have "texttransform" instead of "textTransform".
This aspect of the buttons is controlled by the theme (here, here, and here) so it is also possible to change this via the theme. I have demonstrated both approaches in the code below.
import React from "react";
import ReactDOM from "react-dom";
import {
makeStyles,
createMuiTheme,
MuiThemeProvider
} from "#material-ui/core/styles";
import Button from "#material-ui/core/Button";
const useStyles = makeStyles({
button: {
textTransform: "none"
}
});
const defaultTheme = createMuiTheme();
const theme = createMuiTheme({
typography: {
button: {
textTransform: "none"
}
}
});
function App() {
const classes = useStyles();
return (
<MuiThemeProvider theme={defaultTheme}>
<Button>Default Behavior</Button>
<Button className={classes.button}>Retain Case Via makeStyles</Button>
<MuiThemeProvider theme={theme}>
<Button>Retain Case Via theme change</Button>
</MuiThemeProvider>
</MuiThemeProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Here's a similar example but for v5 of Material-UI:
import React from "react";
import ReactDOM from "react-dom";
import { styled, createTheme, ThemeProvider } from "#material-ui/core/styles";
import Button from "#material-ui/core/Button";
const StyledButton = styled(Button)(`
text-transform: none;
`);
const defaultTheme = createTheme();
const theme1 = createTheme({
typography: {
button: {
textTransform: "none"
}
}
});
const theme2 = createTheme({
components: {
MuiButton: {
styleOverrides: {
root: {
textTransform: "none"
}
}
}
}
});
function App() {
return (
<ThemeProvider theme={defaultTheme}>
<Button>Default Behavior</Button>
<StyledButton>Retain Case Via styled</StyledButton>
<ThemeProvider theme={theme1}>
<Button>Retain Case Via theme change</Button>
</ThemeProvider>
<ThemeProvider theme={theme2}>
<Button>Retain Case Via alternate theme change</Button>
</ThemeProvider>
</ThemeProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
For those who don't wanna go an do this everywhere inside each components try global ovverrides,
const myTheme = createMuiTheme({
overrides: {
MuiButton: {
root: {
textTransform: 'none'
}
}
},
});
You make a theme object like so, and provide it to the theme provider which should wrap your app component in the index.js file
<ThemeProvider theme={myTheme}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</ThemeProvider>
Imports:
import { createMuiTheme, ThemeProvider } from '#material-ui/core/styles';
Per the docs, you should use the label class to override the text-transform property:
Use this style:
viewButtonLabel: { textTransform: "none" }
With this button:
<Button
className={classes.viewButton}
data-document={n.id}
onClick={this.handleView}
classes={{ label: classes.viewButtonLabel }}
>
This seems to work with V5
<Button sx={{ textTransform: 'none' }}>
Label
</Button>
https://mui.com/system/the-sx-prop/
I used Typography without playing with stying!
<Button>
<Typography style={{ textTransform: 'none' }}>Test Button</Typography>
</Button>
The answer of #Shamseer Ahammed provided the clue that finally solved this problem for me.
The use of the "overrides" property in the custom theme finally did the trick for me. I've spent days trying to do this with MuiTab instead of Button. I THINK this is the heuristic:
Use "overrides" in my theme to specify that I want to customize components
Use the component name (MuiButton or MuiTab) to specify a component to customize
Provide a key:value pair for the customization (textTransform: 'none').
I really wish the material-ui docs would make usage patterns like this more clear. I'd like there to be a middle-ground between trivial HelloWorld examples and the Component API nitty-gritty.
At least for me and my purposes, the answer from Shamseer Ahammed opened the door to my solution in a way that accepted answer did not.
import { createTheme, ThemeOptions } from '#mui/material/styles'
const defaultTheme: ThemeOptions = {
typography: {
button: {
textTransform: 'none',
},
},
}
export const lightTheme = createTheme({
palette: {
mode: 'light',
primary: {
main: '#ff2449',
light: '#ff6675',
dark: '#c40022',
},
},
...defaultTheme,
})
export const darkTheme = createTheme({
palette: {
mode: 'dark',
primary: {
main: '#f93c5b',
light: '#ff7588',
dark: '#bf0032',
},
},
...defaultTheme,
})
The MUI text transformation really sucks
I ended up changing the transformation for all the components which works great for me.
import { createTheme } from "#mui/material/styles";
import { ThemeProvider } from "#mui/material";
const theme = createTheme({
typography: {
allVariants: {
textTransform: "none",
},
},
});
<ThemeProvider theme={theme}>....</ThemeProvider>
instead of this long answer i will suggest a short answer
<Button>
<span style={{textTransform: 'none'}}>View Document</span>
</Button>

How to apply different color in AppBar Title MUI?

I am trying to use my custom color for AppBar header. The AppBar has title 'My AppBar'. I am using white as my primary theme color. It works well for the bar but the 'title' of the AppBar is also using same 'white' color'
Here is my code:
import React from 'react';
import * as Colors from 'material-ui/styles/colors';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import AppBar from 'material-ui/AppBar';
import TextField from 'material-ui/TextField';
const muiTheme = getMuiTheme({
palette: {
textColor: Colors.darkBlack,
primary1Color: Colors.white,
primary2Color: Colors.indigo700,
accent1Color: Colors.redA200,
pickerHeaderColor: Colors.darkBlack,
},
appBar: {
height: 60,
},
});
class Main extends React.Component {
render() {
// MuiThemeProvider takes the theme as a property and passed it down the hierarchy
// using React's context feature.
return (
<MuiThemeProvider muiTheme={muiTheme}>
<AppBar title="My AppBar">
<div>
< TextField hintText = "username" / >
< TextField hintText = "password" / >
</div>
</AppBar>
</MuiThemeProvider>
);
}
}
export default Main;
But, the palette styles override the AppBar 'title' color and no title is displaying. Should I include something or I have misplaced any ?
And this is my output :
If you ant to change your Appbar background in material ui design ....try following code
<AppBar style={{ background: '#2E3B55' }}>
or if you want to apply className then follow this step
first of all make create const var
const style = {
background : '#2E3B55';
};
<AppBar className={style}>
MUI v5 update
1. Use sx prop
<AppBar sx={{ bgcolor: "green" }}>
2. Set primary.main color in Palette
The Appbar background color uses the primary color provided from the theme by default.
const theme = createTheme({
palette: {
primary: {
main: "#00ff00"
}
}
});
3. Set AppBar default styles in styleOverrides
Use this one if you don't want to touch the primary.main value and potentially affect other components:
const theme = createTheme({
components: {
MuiAppBar: {
styleOverrides: {
colorPrimary: {
backgroundColor: "red"
}
}
}
}
});
From what I see in the material-ui sources, appBar title color is set by palette.alternateTextColor. If you add it to your style definition like that:
const muiTheme = getMuiTheme({
palette: {
textColor: Colors.darkBlack,
primary1Color: Colors.white,
primary2Color: Colors.indigo700,
accent1Color: Colors.redA200,
pickerHeaderColor: Colors.darkBlack,
alternateTextColor: Colors.redA200
},
appBar: {
height: 60,
},
});
You should see your title without need to style it manually inside each component.
There are more styling parameters to MuiTheme described here
Create your style using makeStyles():
const useStyles = makeStyles(theme => ({
root: {
boxShadow: "none",
backgroundColor: "#cccccc"
}
}));
Use the above style in your component:
const classes = useStyles();
<AppBar className={classes.root} />
Please make theme.js first.
- theme.js
import { red } from '#material-ui/core/colors';
import { createMuiTheme } from '#material-ui/core/styles';
export default createMuiTheme({
palette: {
primary: {
main: '#556cd6',
},
secondary: {
main: '#19857b',
},
error: {
main: red.A400,
},
background: {
default: '#fff',
},
},
});
Add these lines to index.js
import { ThemeProvider } from '#material-ui/core/styles'
import theme from './theme'
ReactDOM.render(
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>,
document.getElementById('root')
);
<AppBar position='static' color='secondary' elevation={2}>
...
</AppBar>
*** important ***
secondary: {
main: '#19857b',
},
color='secondary'
Finally, I came to know about titleStyle for styling title in AppBar.
const titleStyles = {
title: {
cursor: 'pointer'
},
color:{
color: Colors.redA200
}
};
<AppBar title={<span style={titleStyles.title}>Title</span>} titleStyle={titleStyles.color}> .............
</AppBar>
By default it uses palette's contrastText prop (v3):
const theme = createMuiTheme({
palette: {
primary: {
contrastText: 'rgba(0,0,0,0.8)'
}
},
});
first of all, add const to the file. Then apply to the line u need as following shown.
const styles = { button: { margin: 15,}, appBarBackground:{ background : '#2E3B55' }};
Then add it to the line as shown down
style={styles.button}
style={styles.appBarBackground}
You cat add this inline your code
<AppBar title="My AppBar" style={{ backgroundColor: '#2196F3' }} >
or if your css
import './home.css';
put this to your code
.title {
text-align: left;
background-color: black !important;}
Hope to help.
Working on #NearHuscarl answer. If you want the styles to be applied no matter which appbar color you are on: E.g. <Appbar color="secondary" or <Appbar color="primary". You could alternatively use the root property:
const theme = createTheme({
components: {
MuiAppBar: {
root: {
colorPrimary: {
backgroundColor: "red"
}
}
}
}
});
The difference is the root keyword
You can set the background color directly using sx property
<AppBar variant='elevated' sx={{backgroundColor:'#19857b'}}>

Resources