This is my theme.ts file where I created my Muitheme and my fontfamily
import 'typeface-inconsolata'
import 'typeface-quicksand'
import { createMuiTheme, responsiveFontSizes } from '#material-ui/core'
import indigo from '#material-ui/core/colors/indigo'
import yellow from '#material-ui/core/colors/pink'
import red from '#material-ui/core/colors/red'
const theme = createMuiTheme({
typography: {
fontFamily: 'typeface-inconsolata, typeface-quicksand',
fontSize: 17,
fontWeightLight: 300,
fontWeightRegular: 400,
fontWeightMedium: 500,
},
palette: {
primary: indigo,
secondary: red,
error: yellow,
// Used by `getContrastText()` to maximize the contrast between the background and
// the text.
contrastThreshold: 4,
// Used to shift a color's luminance by approximately
// two indexes within its tonal palette.
// E.g., shift from Red 500 to Red 300 or Red 700.
tonalOffset: 0.6,
},
})
export const responsiveTheme = responsiveFontSizes(theme)
This is my App.tsx file where my component is, so I want to change the fonts of the words in the Appbar and in the Grid
import {
AppBar,
Card,
CardHeader,
Container,
createStyles,
Grid,
makeStyles,
Toolbar,
Typography,
} from '#material-ui/core'
import CssBaseline from '#material-ui/core/CssBaseline'
import { ThemeProvider } from '#material-ui/styles'
import React, { FC } from 'react'
import logo from '../icons/logo.svg'
import { responsiveTheme } from '../theme'
const useStyles = makeStyles(theme =>
createStyles({
main: {
height: '90vh',
background: `url(${logo}) no-repeat center / 200px`,
marginTop: theme.spacing(10),
},
})
)
const App: FC = () => {
const classes = useStyles()
return (
<ThemeProvider theme={responsiveTheme}>
<CssBaseline />
<Container maxWidth="lg">
<AppBar color="secondary" position="fixed">
<Toolbar>
<Typography variant="h6" noWrap>
Projektvorlage
</Typography>
</Toolbar>
</AppBar>
<div className={classes.main}>
<Grid container spacing={2} justify="center">
{['Pfannkuchen', 'Pizza', 'Salat', 'Nudeln mit Tomatensauce'].map(
recipe => (
<Grid key={recipe} item xs={12} md={6} lg={4}>
<Card>
<CardHeader title={recipe} />
</Card>
</Grid>
)
)}
</Grid>
</div>
</Container>
</ThemeProvider>
)
}
export default App
So basically I want to change the fonts of the texts but I dont know how to use my fontfamily. There are "variants" but I don't understand what they mean exactly, Im new to react/typescript.
If you want to continue introducing styles via Material-UI, what I would do is create myself in the parent that wraps all the global styles, like the following ones:
globalStyles.styles.tsx
import { createStyles } from "#material-ui/core/styles";
export const globalStyles = (theme: Theme) => createStyles({
"#global": {
body: {
maxHeight: "100vh",
margin: 0,
fontFamily:
},
"#root": {
maxHeight: "100vh",
},
});
app.component.tsx
const AppInner: React.FC<AppProps> = props => { ... };
const App = withStyles(globalStyles)(AppInner);
PD: App component must be inside of <ThemeProvider theme={responsiveTheme}>...</ThemeProvider>
Related
I am creating a react frontend using Material UI. I have created a basic Paper component and I want to change its background color and set it to the primary color set in ThemeProvider. Following is my code
import React from 'react'
import './App.css'
import 'fontsource-roboto'
import { Grid } from '#mui/material'
import { ThemeProvider, createTheme } from '#mui/material/styles'
import { responsiveFontSizes } from '#mui/material'
import { CssBaseline } from '#mui/material'
import Button from '#mui/material/Button'
import { Typography } from '#mui/material'
import { Box } from '#mui/system'
import { Paper } from '#mui/material'
const defaultTheme = createTheme({
palette: {
primary: {
main: '#091425',
contrastText: '#E2DEDE'
},
secondary: {
main: '#e0164a',
contrastText: '#E2DEDE'
}
},
})
function App() {
return (
<ThemeProvider theme={defaultTheme}>
<Typography variant='h1'>Sample Text</Typography>
<Button variant = "contained" color="primary">Sample Button</Button>
<Grid container justifyContent= "center">
<Paper elevation = {10} backgroundColor= "primary" style= {{height: 75, width: 75}} />
</Grid>
</ThemeProvider>
)
}
export default App;
The primary color is applied correctly to the button element but not to the paper. Any help appreciated.
The color is not applied to paper because it doesn´t have a backgroundColor prop as you can see here.
You can do it using the sx prop (docs here):
<Paper
sx={{
backgroundColor: "primary.main"
}}
elevation={10}
style={{ height: 75, width: 75 }}
/>
About your question, you can try to use sx to set the background color, I provide you an example and let you try.
<Grid>
<Paper sx={{backgroundColor: '#091425'}} />
</Grid>
I'm trying to create a theme for my Next.JS application with MUI version 5. I created the Theme in my layout component, and I expected the Theme to have effect in other child components. but I can't seem to get my Button to change from the default primary colour. It does work with the "h1"tag, and I'm wondering why it works for the h1 tag and not for the Button component.
//layout component
import { AppBar, Container, CssBaseline, Toolbar, Typography ,createTheme, ThemeProvider} from '#mui/material';
import useStyles from '../utils/styles';
export default function Layout({ title, children, description }) {
const theme = createTheme({
typography: {
h1: {
fontSize: '1.6rem',
fontWeight: 400,
margin: '1rem 0', // this is working
},
h2: {
fontSize: '1.4rem',
fontWeight: 400, // this is working
margin: '1rem 0',
},
palette: {
type: 'light',
primary: { // this is not working
main: '#f0c000',
},
secondary: {
main: '#208080',
},
},
},
});
const classes = useStyles()
return (
<div>
<ThemeProvider theme={theme}>
<CssBaseline/>
<AppBar position="static" className={classes.navbar}>
<Toolbar>
<Typography>App</Typography>
</Toolbar>
</AppBar>
<Container className={classes.main}>{children}</Container>
<footer className={classes.footer}>
<Typography>All right reserved</Typography>
</footer>
</ThemeProvider>
</div>
);
}
Component where I want to use the Theme :
import useStyles from '../../utils/styles'
import { useTheme } from '#mui/material';
export default function ButtonScreen() {
const theme = useTheme();
const classes = useStyles();
return (
// this h1 tag responds to the Theme style provided in the layout component
<Typography component="h1" variant="h1">
Button Action
</Typography>
//The button default colour still persist, even with the theme in place.
<Button fullWidth variant='contained' color="primary">Click me</Button>
)
}
Can someone help me figure out what I am missing here?!
I have created a theme in the index of my React.JS project using MUI. When I try to apply my style to my Appbar the theme does not correctly modify the menu button nor the menu itself. the button looks generic default and the menu remains white when it should match the color of the Appbar itself.
My index.tsx looks as such:
import React from "react";
import ReactDOM from "react-dom";
import AppbarTop from "./AppbarTop";
import { Router } from "react-router";
import { createBrowserHistory } from "history";
import AdapterDateFns from "#mui/lab/AdapterDateFns";
import { LocalizationProvider } from "#mui/lab";
import { createTheme } from "#mui/material";
import { ThemeProvider } from "#mui/styles";
import { StyledEngineProvider } from "#mui/material/styles";
const customHistory = createBrowserHistory();
const theme = createTheme({
palette: {
primary: {
main: "#242526"
},
secondary: {
main: "#d975d0"
},
text: {
primary: "#E4E6EB",
secondary: "#B0B3B8"
},
background: {
default: "#242526",
paper: "#242526"
}
}
});
ReactDOM.render(
<React.StrictMode>
<LocalizationProvider dateAdapter={AdapterDateFns}>
<Router history={customHistory}>
<ThemeProvider theme={theme}>
<StyledEngineProvider injectFirst>
<AppbarTop />
</StyledEngineProvider>
</ThemeProvider>
</Router>
</LocalizationProvider>
</React.StrictMode>,
document.getElementById("root")
);
My appbar.tsx looks like this:
import React from "react";
import {
AppBar,
Box,
Button,
Container,
Menu,
MenuItem,
Toolbar
} from "#mui/material";
import HomeIcon from "#mui/icons-material/Home";
import { makeStyles } from "#mui/styles";
const useStyles = makeStyles((theme?: any) => ({
appBar: {
background: theme.palette.primary.main,
height: "60px",
position: "relative"
}
}));
const AppbarTop: React.FC<{ [key: string]: any }> = () => {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState<any>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<>
<AppBar position="static" className={classes.appBar}>
<Toolbar>
<Button
id="basic-button"
aria-controls="basic-menu"
aria-haspopup="true"
aria-expanded={open ? "true" : undefined}
onClick={handleClick}
>
Dashboard
</Button>
<Menu
id="basic-menu"
anchorEl={anchorEl}
open={open}
onClose={handleClose}
MenuListProps={{
"aria-labelledby": "basic-button"
}}
>
<MenuItem onClick={handleClose}>
<HomeIcon />{" "}
</MenuItem>
</Menu>
{/*test speed dial*/}
<Container maxWidth="sm"></Container>
<Box></Box>
</Toolbar>
</AppBar>
</>
);
};
export default AppbarTop;
Can someone please explain what I am missing?
Change this line:
import { ThemeProvider } from "#mui/styles";
To:
import { ThemeProvider } from "#mui/material/styles";
Reason: There are 2 ThemeProviders here
The one from #mui/styles: This ThemeProvider does send the Theme object down via context, it works fine, you can still access it using the useTheme hook:
const theme = useTheme();
return <Box sx={{ width: 10, height: 10, bgcolor: theme.palette.primary.main }} />
The one from #mui/material/styles: This ThemeProvider is a wrapper of the above, but it also injects the theme to the StyledEngineThemeContext.Provider, which allows you to access the theme when using MUI API (sx prop/styled()). The problem here is that the Button and Menu components uses the styled() API under-the-hood so the ThemeProvider needs to be imported from #mui/material/styles to make it work.
return <Box sx={{ width: 10, height: 10, bgcolor: 'primary.main' }} />
Related answers
Difference between #mui/material/styles and #mui/styles?
Cannot use palette colors from MUI theme
MUI - makeStyles - Cannot read properties of undefined
Material UI Dark Mode
Hi i've found this https://github.com/Learus/react-material-ui-carousel to use it on my website. But i've encountered 2 problems:
In order to set the autoPlay state, i have to change it to class which leads to unable to use const classes = useStyles() so does anyone know what should i do?
I have 3 jpg photos saved in the img folder under the same directory and i have no idea why the photos cant be loaded in my localhost.
Here is my code:
import React from 'react';
import { createMuiTheme } from '#material-ui/core';
import { ThemeProvider } from '#material-ui/core';
import { makeStyles } from '#material-ui/core/styles';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import Button from '#material-ui/core/Button';
import Tooltip from '#material-ui/core/Tooltip';
import Carousel from 'react-material-ui-carousel';
import CarouselSlide from 'react-material-ui-carousel';
import Card from '#material-ui/core/Card';
import CardMedia from '#material-ui/core/CardMedia';
import CardContent from '#material-ui/core/CardContent';
const theme = createMuiTheme ({
palette: {
primary:{
main:'#3c52b2'
}
}
})
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1,
},
Button: {
"&:hover": {
backgroundColor: "#fff !important"
}
},
title: {
flexGrow: 1,
},
}));
export default function UMainPage (){
const pictures = [
{image:'./2.jpg', title:'Iu 1'},
{image:'./3.jpg', title:'Iu 2'},
{image:'./4.jpg', title:'Iu 3'}
];
const classes = useStyles();
return (
<ThemeProvider theme={theme}>
<AppBar position="static">
<Toolbar>
<Typography variant="h6" className={classes.title}>
清动订馆平台
</Typography>
<Button color="inherit">首页</Button>
<Button color="inherit">历史订单</Button>
<Tooltip disableFocusListener disableTouchListener title="登录账号">
<Button color="inherit">未登录</Button>
</Tooltip>
</Toolbar>
</AppBar>
<Carousel>
{pictures.map(({image, title}) => (
<CarouselSlide key={image}>
<Card>
<CardMedia
image={image}
title={title}
style={{
height: 0,
paddingTop: '25%',
}}
/>
<CardContent>
<Typography>{title}</Typography>
</CardContent>
</Card>
</CarouselSlide>
))}
</Carousel>
</ThemeProvider>
);
}
In order to set autoPlay you should pass it to Carousel like this:
<Carousel autoPlay>
...
</Carousel>
If you want to have ability to change it you should keep in state:
const [autoPlay, setAutoPlay] = useState(true);
You should import your images first and then keep them in the pictures array:
import image2 from "./2.jpg";
import image3 from "./3.jpg";
import image4 from "./4.jpg";
...
const pictures = [
{ image: image2, title: "Iu 1" },
{ image: image3, title: "Iu 2" },
{ image: image4, title: "Iu 3" },
];
import React from 'react';
import Component from './components/Component';
import { createMuiTheme, makeStyles, ThemeProvider } from '#material-ui/core/styles';;
const theme = createMuiTheme({
container: {
width: '100%',
paddingRight: '15px',
paddingLeft: '15px',
marginRight: 'auto',
marginLeft: 'auto'
},
flexColumn: {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
}
});
function App() {
return (
<ThemeProvider theme={theme}>
<div className="App">
<Component />
</div>
</ThemeProvider>
);
}
export default App;
The theme provided above goes inside the component Component.
import React, { useState } from "react";
import { makeStyles } from '#material-ui/core/styles';
import { useTheme } from '#material-ui/core/styles';
import classNames from 'classnames';
const useStyles = makeStyles(() => ({
bar: {
flexGrow: 1,
padding: '.8rem .8rem',
lineHeight: '1.5em',
fontSize: '18px',
},
alert: {
color: 'white',
backgroundColor: 'red',
},
}));
export default function Component (props) {
const theme = useTheme();
const classes = useStyles();
const [focus, setFocus] = useState(false);
return (
<div>
<div style={theme.flexColumn} className={classNames(classes.alert, classes.bar)}>
<div>
</div>
</div>
</div>
);
}
Is this the proper way to use useTheme and className? The issue with this is that I can't use the styles defined with createMuiTheme and fetched through the ThemeProvider inside the className attribute, which means sometimes the styling inside classNames and style may conflict with one another. I couldn't find an example where the styling provided inside createMuiTheme is used with className.
If you want to reuse classes in MUI, you should create an external style file, then import this file into the components that you want to use this style. Try this:
In sharedStyles:
export const layout = {
header: {
fontSize: "1.5em",
color: "blue"
},
footer: {
fontSize: "0.8em"
}
};
const sharedStyles = theme => ({
grow: {
flexGrow: 1
},
defaultPadding: {
padding: theme.spacing.unit * 3 + "px"
},
"layout.header": layout.header
});
export default sharedStyles;
In a component:
import React from "react";
import { withStyles } from "#material-ui/core/styles";
import Paper from "#material-ui/core/Paper";
import sharedStyles, { layout } from "./sharedStyles";
import Typography from "#material-ui/core/Typography";
function Dashboard(props) {
const { classes } = props;
return (
<Paper className={classes.defaultPadding}>
<Typography variant="body1" gutterBottom>
Hello <span className={classes.someOtherStyle}>World</span>
</Typography>
<Typography
component="h2"
variant="h1"
gutterBottom
className={classes["layout.header"]}
>
Heading
</Typography>
<Typography
component="h2"
variant="h1"
gutterBottom
className={classes.header}
>
Heading 2
</Typography>
</Paper>
);
}
const styles = theme => ({
...sharedStyles(theme),
header: layout.header,
someOtherStyle: {
color: "red"
}
});
export default withStyles(styles)(Dashboard);