Why this customTheme is not applied to my buttons - reactjs

Why this customTheme is not applied to my buttons. I'm using the MUI 5. Please tell me where I'm making the mistakes & how to resolve this.
import React from 'react';
import NavBar from './components/NavBar';
import { createTheme, ThemeProvider } from '#mui/material/styles';
import { Button } from '#mui/material';
const customTheme = createTheme({
overrides: {
MuiButton: {
outlined: {
backgroundImage: 'linear-gradient(to top, #d299c2 0%, #fef9d7 100%)',
color: 'green'
},
text: {
color: "red"
}
}
}
})
function App() {
return (
<div id='appDiv2'>
<ThemeProvider theme={customTheme}>
<NavBar />
<Button variant='outlined'> Test Button </Button>
</ThemeProvider>
<DirectionSnackbar />
</div>
);
}
export default App;

The structure of the theme object depends on the version of MaterialUI. If you use latest, the scheme should be
const theme = createTheme({
components: {
// Name of the component
MuiButton: {
styleOverrides: {
// Name of the slot
outlined: {
backgroundImage: 'linear-gradient(to top, #d299c2 0%, #fef9d7 100%)',
color: 'green'
},
text: {
color: "red"
}
},
},
},
});
https://mui.com/customization/theme-components/#global-style-overrides

Related

Access theme defined with MUI in a styled component

I'm using MUI's theming capabilities. I have a file theming.js that has:
import { createTheme } from '#mui/material/styles';
export const myTheme = createTheme({
palette: {
primary: {
main: '#BD72A8',
},
secondary: {
main: '#00A0BE',
},
},
});
I'm attempting to create a styled component that draws on the theme's palette. Here's what I have so far:
import { withTheme } from "#material-ui/core/styles";
const LeftSidebar = withTheme(styled.div`
display: inline-block;
width: 25%;
border: 2px solid ${props => props.theme.palette.secondary.main};
border-radius: 4px;
`);
return (
<ThemeProvider theme={myTheme}>
<LeftSidebar>
...
</LeftSidebar>
</ThemeProvider>
)
The styles component LeftSidebar is picking up the other styles I define, but it's not using the secondary color on my palette as defined in theming.js. In fact, it looks like it's falling onto a different definition of 'theme', because this code results in the border's color being #f50057 - not the secondary color I chose at all, but also not blank.
Can anybody help me understand what I'm doing wrong in trying to combine MUI and styled components?
**try this**
import * as React from 'react';
import { styled, createTheme, ThemeProvider } from '#mui/system';
interface MyThemeComponentProps {
color?: 'primary' | 'secondary';
variant?: 'normal' | 'dashed';
}
const customTheme = createTheme({
components: {
MyThemeComponent: {
styleOverrides: {
root: {
color: 'darkslategray',
},
primary: {
color: 'darkblue',
},
secondary: {
color: 'darkred',
backgroundColor: 'pink',
},
},
variants: [
{
props: { variant: 'dashed', color: 'primary' },
style: {
border: '1px dashed darkblue',
},
},
{
props: { variant: 'dashed', color: 'secondary' },
style: {
border: '1px dashed darkred',
},
},
],
},
},
});
const MyThemeComponent = styled('div', {
// Configure which props should be forwarded on DOM
shouldForwardProp: (prop) =>
prop !== 'color' && prop !== 'variant' && prop !== 'sx',
name: 'MyThemeComponent',
slot: 'Root',
// We are specifying here how the styleOverrides are being applied based on props
overridesResolver: (props, styles) => [
styles.root,
props.color === 'primary' && styles.primary,
props.color === 'secondary' && styles.secondary,
],
})<MyThemeComponentProps>(({ theme }) => ({
backgroundColor: 'aliceblue',
padding: theme.spacing(1),
}));
export default function UsingOptions() {
return (
<ThemeProvider theme={customTheme}>
<MyThemeComponent sx={{ m: 1 }} color="primary" variant="dashed">
Primary
</MyThemeComponent>
<MyThemeComponent sx={{ m: 1 }} color="secondary">
Secondary
</MyThemeComponent>
</ThemeProvider>
);
}
Inspired by this SO question, I kept tinkering around and learned that it wasn't working because I was using the ThemeProvider from MUI, whereas it works if I use the ThemeProvider from styled-components. In other words, this now works:
import styled, { ThemeProvider } from 'styled-components';
const LeftSidebar = styled.div`
...
border: 2px solid ${props => props.theme.palette.secondary.main};
`;
...
<ThemeProvider theme={mnemoTheme}>
<LeftSidebar>
...

'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!

How to change Error color and underline color on input focus using material-ui v1.0.0-beta.40

I am using Material-UI v1.0.0-beta.40 and I want to change the border color and error text color.
How can this be done?
One of the ways to do it is inside of MuiTheme
import { createMuiTheme } from 'material-ui/styles';
const myTheme = createMuiTheme({
overrides:{
MuiInput: {
underline: {
'&:after': {
backgroundColor: 'any_color_hex',
}
},
},
}
});
export default myTheme;
and then import it into your component and use:
import {MuiThemeProvider} from 'material-ui/styles';
import myTheme from './components/myTheme'
<MuiThemeProvider theme = {myTheme}>
<TextField />
</MuiThemeProvider>
Hope this helps!
You can accomplish that by using errorStyle attribute
errorStyle The style object to use to override error styles
Version 0.20.0
<TextField
hintText="Hint Text"
errorText="This field is required"
errorStyle={{color: 'green'}}
/>
Working Demo
Version 1.0.0 beta
const styles = theme => ({
greenLabel: {
color: '#4CAF50',
},
greenUnderline: {
'&:before': {
backgroundColor: '#4CAF50',
},
},
greenUnderline: {
'&:after': {
backgroundColor: '#4CAF50',
},
},
});
<FormControl >
<InputLabel style={{color: 'green'}} htmlFor="name-simple">Error</InputLabel>
<Input classes={{ inkbar: classes.greenInkbar, underline: classes.greenUnderline }} id="name-simple" value={this.state.name} onChange={this.handleChange} />
</FormControl>
Here is the solution based on most recent changes by material-ui v1. Hope It's help
import { createMuiTheme } from '#material-ui/core/styles';
const inputBoxTheme = createMuiTheme({
overrides:{
MuiInput: {
underline: {
'&:after': {
borderBottom: '2px solid #fff',
},
"&:after": {
borderBottom: '2px solid #fff',
}
},
},
}
});
export default inputBoxTheme;
import { MuiThemeProvider } from '#material-ui/core/styles';
import inputBoxTheme from './theme/inputBoxTheme'
<MuiThemeProvider theme = {inputBoxTheme}>
<TextField />
</MuiThemeProvider>
An override isn't necessary to change the error color globally. It can be defined wherever you define your global colors / theme elements. For example:
import createMuiTheme from '#material-ui/core/styles/createMuiTheme';
export default createMuiTheme({
palette: {
primary: {
main: '#FFFFFF',
},
secondary: {
main: '#6200EE',
},
error: {
main: '#D0180B',
},
},
});

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