Self-host font added in Material-UI not working? - reactjs

I'm working on a Material-UI based project and trying to add some self-hosted fonts, since they're not available as google fonts. I've followed both the Material-UI and JSS docs, and I've come up with the following, but I can't find the reason why it's still not working. There are no errors either to give me a clue as to what's wrong.
import { createMuiTheme } from "#material-ui/core/styles";
import Windlass from "./fonts/Windlass.eot";
import Windlass2 from "./fonts/Windlass.woff";
const theme = createMuiTheme({
...
typography: {
useNextVariants: true,
fontFamily: [
'Windlass',
'Helvetica Neue',
'Helvetica'
].join(','),
fontSize: 16,
fontWeightLight: 400,
fontWeightRegular: 400,
fontWeightMedium: 600,
fontWeightBold: 700},
overrides: {
MuiCssBaseline: {
'#global': {
'#font-face': {
fontFamily: 'Windlass',
src: `url(${Windlass})`,
fallbacks: [
{src: `url(${Windlass}?#iefix) format(embedded-opentype)`},
{src: `url(${Windlass2}) format(woff)`}
]
}
}
}
}
});
export default theme;
The font name does seem to show up in the css when I inspect the element as
font-family: Windlass,Helvetica Neue,Helvetica;
but the text shows up as Helvetica Neue.

In case someone stumbles on this post.
Here is another way to add fonts to the Material UI theme. I followed the steps from the MUI webiste.
https://material-ui.com/customization/typography/
///myAwesomeFont.ts
import myAwesomeFontEot from '../assets/fonts/myAwesomeFont.eot';
import myAwesomeFontWoff from '../assets/fonts/myAwesomeFont.woff';
import myAwesomeFontWoff2 from '../assets/fonts/myAwesomeFont.woff2';
import myAwesomeFontBoldEot from '../assets/fonts/myAwesomeFont-Bold.eot';
import myAwesomeFontBoldWoff from '../assets/fonts/myAwesomeFont-Bold.woff';
import myAwesomeFontBoldWoff2 from '../assets/fonts/myAwesomeFont-Bold.woff2';
const myAwesomeFontRegular = {
fontFamily: 'myAwesomeFont',
fontStyle: 'normal',
fontWeight: 400,
src: `local('myAwesomeFont-Regular'),
url(${myAwesomeFontEot}),
url(${myAwesomeFontWoff}) format('woff'),
url(${myAwesomeFontWoff2}) format('woff2')`,
};
const myAwesomeFontBold = {
fontFamily: 'myAwesomeFont',
fontStyle: 'normal',
fontWeight: 700,
src: `local('myAwesomeFont-Bold'),
url(${myAwesomeFontEot}),
url(${myAwesomeFontWoff}) format('woff'),
url(${myAwesomeFontWoff2}) format('woff2')`,
};
export default [myAwesomeFontRegular, myAwesomeFontBold]
In Your theme provider file.
//default.theme.ts
import { createMuiTheme, Theme } from '#material-ui/core/styles';
import myAwesomeFontArray from './myAwesomeFont';
const theme: Theme = createMuiTheme({
typography: {
fontFamily: "myAwesomeFont, sans-serif",
fontSize: 16
},
overrides: {
MuiCssBaseline: {
'#global': {
'#font-face': [...myAwesomeFontArray],
},
},
},
});
After you've set this up. Open up your developer tools on the browser and verify that they're indeed being downloaded. This worked for me. I hope it works for you.

this is my config and it work, you need declare the font in index.css like this.
theme.js
import { createMuiTheme } from "#material-ui/core/styles";
// import gliberPath from "./Gilbert_Bold-Preview_1004.woff2"; // this is no need to add
let palette1 = {
type: "light"
};
let palette2 = {
type: "light"
};
// this is no need to add
// const gliber = {
// fontFamily: "Gliber",
// fontStyle: "normal",
// fontDisplay: "swap",
// fontWeight: 400,
// src: `
// local('Gliber'),
// url(${gliberPath}) format('woff2')
// `,
// };
const typography = {
fontFamily: ["Gliber","Roboto"].join(","), // there need add Gliber reference,your font family name should be place the first position
// this is no need to add
// overrides: {
// MuiCssBaseline: {
// "#global": {
// "#font-face": ['Gliber']
// }
// }
// }
};
let theme1 = createMuiTheme({ palette: palette1, typography });
let theme2 = createMuiTheme({ palette: palette2, typography });
export { theme1, theme2 };
index.css
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
/*add self host font */
#font-face {
font-family: 'Gliber';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url('./theme/Gilbert_Bold-Preview_1004.woff2') format('woff2');
}

Related

How to combine overrides in Material UI (React) - overwrite both theme styles and component styles

I have an issue when I try to customise both the overall theme styling and the component styling at once in Material UI.
I started with the below which works perfectly:
import { createTheme } from '#mui/material/styles';
const theme = createTheme({
palette: {
brand: '#0D3B66',
primary: {
main: '#4AA1FF',
},
},
typography: {
// Changes to default 'typography'.
fontFamily: '"Mukta", sans-serif',
fontWeight: 400,
h1: {
fontSize: 24,
},
}
})
export default theme
Then I wanted to add the following override as well to change theme breakpoint. (This also works perfectly alone).
However, when I combine both like this:
import { createTheme } from '#mui/material/styles';
let theme = createTheme({});
theme = createTheme(theme, {
components: {
MuiContainer: {
styleOverrides: {
maxWidthLg: {
[theme.breakpoints.up('lg')]: {
maxWidth: 1280 // Your custom value here
},
}
}
}
}
})
export default theme
Hence, I tried to combine these to form this final block:
import { createTheme } from '#mui/material/styles';
let theme = createTheme({});
theme = createTheme(theme, {
components: {
MuiContainer: {
styleOverrides: {
maxWidthLg: {
[theme.breakpoints.up('lg')]: {
maxWidth: 1280 // Your custom value here
},
}
}
}
},
palette: {
brand: '#0D3B66',
primary: {
main: '#4AA1FF',
},
},
typography: {
// Changes to default 'typography'.
fontFamily: '"Mukta", sans-serif',
fontWeight: 400,
h1: {
fontSize: 24,
},
}
})
export default theme
...I no longer see the palette changes take effect when combined... Maybe palette and typography need to be handled separately or on a different level?
I'm not sure how to do this, so any advice appreciated!
This code works perfect for me:
import React from 'react';
import './App.css';
import { createTheme, ThemeProvider } from '#mui/material/styles';
import { Button, Container } from '#mui/material';
let theme = createTheme({});
theme = createTheme(theme, {
components: {
MuiContainer: {
styleOverrides: {
maxWidthLg: {
[theme.breakpoints.up('lg')]: {
maxWidth: 1280
},
}
}
}
},
palette: {
brand: '#0D3B66',
primary: {
main: '#4caf50',
},
},
typography: {
fontFamily: '"Mukta", sans-serif',
fontWeight: 400,
h1: {
fontSize: 24,
},
}
});
function App() {
return (
<ThemeProvider theme={theme}>
<Container>
<Button>Primary</Button>
</Container>
</ThemeProvider>
);
}
export default App;
You can see the result:

How to change default typography for Textfields and such via theme in MUI v5?

Is there a way to map default typography for TextField and all my inputs via theme? I know I can do this
components: {
MuiInput: {
styleOverrides: {
root: {
fontSize: '16px',
lineHeight: '25px'
}
}
},
but I wish to find a way to map it to 'body2'
MuiInput: {
defaultProps: {
typographyProps???: {
variant: 'body2'
}
}
For using body2 font size value in another component, You need to access the theme object's typography property.
Then You will set the MUI TextFiled's font-size equal to that value from the theme object.
import { createTheme } from "#mui/material";
const theme = createTheme({});
theme!.components!.MuiTextField = {
styleOverrides: {
root: {
"& .MuiInputBase-input": {
fontSize: theme.typography.body2.fontSize, // this is the default mui body2 font-size
lineHeight: "25px", // and any other styles you want...
},
},
},
};
And You can change the body2 fontSize when defining the theme object:
const theme = createTheme({
typography: {
body2: {
fontSize: 80,
},
});
theme!.components!.MuiTextField = {
styleOverrides: {
root: {
"& .MuiInputBase-input": {
fontSize: theme.typography.body2.fontSize, // this will be 80px
lineHeight: "25px", // and any other styles you want...
},
},
},
};
EDIT:
If You are not ok with overriding the theme after defining it, You can use this approach:
import { createTheme } from "#mui/material";
const myBody2FontSize = 20px;
const theme = createTheme({
typography: {
body2: {
fontSize: myBody2FontSize,
},
},
components: {
MuiTextField: {
styleOverrides: {
root: {
"& .MuiInputBase-input": {
fontSize: myBody2FontSize , // this is the default mui body2 font-size
lineHeight: "25px", // and any other styles you want...
},
},
},
},
},
});
You could try setting it via classname. Its a bit awkward because an input doesnt actually use Typography internally.
MuiInput: {
defaultProps: {
className: 'MuiTypography-body2'
}
}
Or possibly
MuiTextField: {
defaultProps: {
InputProps: {className: 'MuiTypography-body2' }
}
}

Loading custom font Open Sans and its variants(bold ,semibold) in material ui

I'm using Material UI with Create React App and trying to include the "Open Sans" font that I downloaded in ttf format. Following the documentation on Material UI for self-hosted fonts, my current theme.js file looks like this:
import OpenSansRegular from "./fonts/OpenSans-Regular.ttf";
import OpenSansBold from "./fonts/OpenSans-Bold.ttf";
import OpenSansSemiBold from "./fonts/OpenSans-SemiBold.ttf";
import { createMuiTheme } from "#material-ui/core/styles";
const openSansRegular = {
fontFamily: "Open Sans",
fontStyle: "normal",
fontDisplay: "swap",
src: `
local("Open Sans"),
local("OpenSans-Regular")
url(${OpenSansRegular}) format("ttf")
`,
};
const openSansSemibold = {
fontFamily: "Open Sans",
fontStyle: "normal",
fontDisplay: "swap",
src: `
local("Open Sans"),
local("OpenSans-SemiBold")
url(${OpenSansSemiBold}) format("ttf")
`,
};
const openSansBold = {
fontFamily: "Open Sans",
fontStyle: "normal",
fontDisplay: "swap",
src: `
local("Open Sans"),
local("OpenSans-Bold")
url(${OpenSansBold}) format("ttf")
`,
};
const theme = createMuiTheme({
typography: {
fontFamily: "Open Sans",
fontSize: 14,
h1: {
fontSize: 20,
fontWeight: "bold",
},
h2: {
fontSize: 18,
fontWeight: "bold",
},
h3: {
fontSize: 16,
fontWeight: "bold",
},
overrides: {
MuiCssBaseline: {
"#global": {
"#font-face": [openSansRegular]
}
}
},
});
export default theme;
I am unable to figure out how to actually use its variants such as openSansSemiBold and openSansBold. Where exactly do I specify in the theme so they are recognized? And say I want a text to be semibold in some part of the app, how exactly I am going to refer to it?
I haven't been able to find a clear answer to this so far.
You can put all fonts into array.
var customFontFamily = [openSansRegular,openSansSemibold,openSansBold];
var customTypo = {
...
body1 :{
fontFamily: 'OpenSans-Regular',
},
h1:{
fontFamily: 'OpenSans-SemiBold',
},
h2:{
fontFamily: 'OpenSans-Bold',
},
...
};
const theme = createMuiTheme({
typography: customTypo
overrides: {
MuiCssBaseline: {
"#global": {
"#font-face": [customFontFamily]
}
}
},
});

Material-ui overwrite components gutter breakpoint styles TypeError: Cannot read property 'breakpoints' of undefined

I am doing something like this.
// theme.js
import { createMuiTheme } from '#material-ui/core/styles';
const theme = createMuiTheme({
overrides: {
MuiToolbar: {
gutters: {
[theme.breakpoints.up('sm')]: {
paddingLeft: '16px',
paddingRight: '16px',
},
},
},
},
palette: {
type: 'dark',
},
});
export default theme;
Error message: TypeError: Cannot read property 'breakpoints' of undefined.
I wanna get the theme style value and use for overwrite, how can i fixed this error.
24px gutter is too much for me for all theme style / components like paper, how can i easy to overwrite all gutter with 16px replace?
Thanks so much.
As answered in this question, you need to create an instance of the default theme, so you have an object to get breakpoints from:
import { createMuiTheme } from '#material-ui/core/styles';
const defaultTheme = createMuiTheme();
const theme = createMuiTheme({
overrides: {
MuiToolbar: {
gutters: {
[defaultTheme.breakpoints.up('sm')]: {
paddingLeft: '16px',
paddingRight: '16px',
},
},
},
},
palette: {
type: 'dark',
},
});
export default theme;
Regarding the "global" gutter property, Toolbar uses theme.mixins.gutters() to get the default gutter, so I think you have to override that. Looking into this function source, this should be the right override to set the gutter to 16px:
import { createMuiTheme } from '#material-ui/core/styles';
const defaultTheme = createMuiTheme();
const theme = createMuiTheme({
mixins: {
gutters: (styles = {}) => ({
paddingLeft: defaultTheme.spacing.unit * 2,
paddingRight: defaultTheme.spacing.unit * 2,
...styles,
[defaultTheme.breakpoints.up('sm')]: {
paddingLeft: defaultTheme.spacing.unit * 2,
paddingRight: defaultTheme.spacing.unit * 2,
...styles[defaultTheme.breakpoints.up('sm')],
},
}),
},
palette: {
type: 'dark',
},
});
export default theme;

Grommet UI -- Custom Color Schemes

I'm using grommet-ui with webpack and react.
How do I set my own color options.
Is there a way to use my own custom colors/color schemes in place of predefined colors like colorIndex="neutral-1".
Yes, there is a way to override them, but it is currently not documented. I would start checking the colors here:
https://github.com/grommet/grommet/blob/master/src/scss/grommet-core/_settings.color.scss
For example, neutral-1 is used from this array
$brand-neutral-colors: (#5d0cfb, #7026ff, #767676) !default;
In your index.scss you can replace that (!default allows replacement):
$brand-neutral-colors: (#333333, #7026ff, #767676)
We are working on adding documentation for custom theme variables.
For Grommet v2 users, you can leverage the theme capabilities and define a customTheme as a js object with your desired colors, following the current structure:
const customTheme = {
global: {
colors: {
// Overriding existing grommet colors
brand: "#4D4CDB",
"accent-1": "#6FFFB0",
"accent-2": "#7FFFB0",
"accent-3": "#8FFFB0",
"accent-4": "#9FFFB0",
"neutral-1": "#10873D",
"neutral-2": "#20873D",
"neutral-3": "#30873D",
"neutral-4": "#40873D",
focus: "#000",
// Setting new colors
blue: "#00C8FF",
green: "#17EBA0",
teal: "#82FFF2",
purple: "#F740FF",
red: "#FC6161",
orange: "#FFBC44",
yellow: "#FFEB59",
// you can also point to existing grommet colors
brightGreen: "accent-1",
deepGreen: "neutral-2"
}
}
};
...
export const Example = () => (
<Grommet theme={customTheme}>
<Box background="orange" >
<Text color="deepGreen">Custom Color</Text>
</Box>
</Grommet>
);
You can override any Grommet color that is mentioned in the docs in a similar fashion.
Wrapping your application with the Grommet component that is pointing to your customTheme object as shown on the example, will allow you full access to your custom colors across your application.
Check the pre-packed themes from https://github.com/grommet/grommet/tree/master/src/js/themes and choose the one that's closest to your goal
Then write your own, but only the parts you want to change
Roll your complete theme by merging the pre-packed with your prefs like so:
import React from 'reactn';
import { dark } from 'grommet/themes';
import { deepMerge } from 'grommet/utils';
import { generate } from 'grommet/themes/base';
import { FormDown } from 'grommet-icons';
const localTheme = {
global: {
font: {
family: 'Montserrat, Roboto, sans-serif',
size: '14px',
lineHeight: '20px'
},
colors: {
brand: '#4040DB',
focus: '#50c050',
[dark-5]: '#aaaaaa',
[dark-6]: '#bbbbbb',
// [light-1]: '#ededed', // has error "light not defined"
},
input: {
padding: '5px;', // this renders a 4px padding!
},
},
button: {
hoverIndicator: {
dark: { color: dark-6 },
light: { color: 'light-3' },
border: { radius: '5px' }
},
disabled: {
color: dark-4,
opacity: '0.6',
},
border: {
width: '1px',
color: 'rgb(238,238,238)',
radius: '4px'
},
padding: 'none',
},
select: {
background: 'dark-1',
icons: {
color: 'rgb(238,238,238)',
margin: '0px 0px',
down: <FormDown />,
},
control: {
open: {
color: 'rgb(238,238,0)'
}
},
options: {
container: {
pad: 'xxsmall',
background: 'dark-1'
},
text: {
margin: 'none',
size: 'small',
color: 'light-1',
},
},
container: {
extend: () => `
flex-grow: 1;
`,
}
},
textArea: {
// not working: background: ${ localTheme.global.colors[dark-2] }; // dark-2
extend: () => `
background: ${ '#333333' }; // dark-1
margin: 2px 0px;
height: 100px;
&:hover {
background: ${ '#555555' }; // dark-2
}
&:focus {
background: ${ '#555555' }; // dark-2
color: ${ '#ffffff' };
}
&::placeholder {
color: dark-5;
font-style: italic;
font-weight: 200;
}
`,
},
textInput: {
extend: `
background: ${ '#333333' }; // dark-1
margin: 2px 0px;
&:hover {
background: ${ '#555555' }; // dark-2
}
&:focus {
background: ${ '#555555' }; // dark-2
color: ${ '#ffffff' };
}
&::placeholder {
color: dark-5;
font-style: italic;
font-weight: 200;
}
`,
},
};
export default recipesTheme
Notice that some of the lines are failed experiments trying to overcome the flaky docs.
This exports a recipesTheme module to be used in the render method of App or whatever:
<Grommet full = { true } theme = { recipesTheme }>
There is this tool https://grommet-theme-builder.netlify.com/ that you can use to somehow see the effect of your changes.

Resources