MUI - dark theme doesn't change anything - reactjs

I am new to MUI, but all was pretty easy to understand beside changing to dark theme.
I opened documentation of MUI at page where there are examples with dark theme. I copied the first example and it didn't work to me. Why doesn't this simple code example change my MUI theme to 'dark' mode? from here I understood that I need to add more components, but I didn't really understand what does it mean. If I don't add DOM tree it doesn't work? Why the background doesn't change?!
import React from 'react';
import { ThemeProvider, createTheme } from '#mui/material/styles';
function App() {
const darkTheme = createTheme({
palette: {
mode: 'dark'
},
});
return (
<ThemeProvider theme={darkTheme}>
Hello World
</ThemeProvider>
);
}
export default App;

You shoul add <CssBaseline />
import React from 'react';
import { ThemeProvider, createTheme } from '#mui/material/styles';
function App() {
const darkTheme = createTheme({
palette: {
mode: 'dark'
},
});
return (
<ThemeProvider theme={darkTheme}>
<CssBaseline />
Hello World
</ThemeProvider>
);
}
export default App;

Related

can't change background color in theme Material-UI

I have been trying to define a custom theme using material UI and defining a default background colour for it. But the changes are not taking effect while other pallete options are working. Can anybody tell me what I'm doing wrong? As far as I can tell this is the way to change the colour.
Here's my code
theme.ts
import { createTheme } from '#mui/material';
import {red} from '#mui/material/colors';
const theme = createTheme({
palette: {
background: {
default: '#FFD600',
paper: '#FFD600',
},
},
});
export default theme;
my entry file
import '../styles/globals.css';
import {ThemeProvider} from "#mui/material/styles"
import theme from '../theme'
function MyApp({ Component, pageProps }) {
return (
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
);
}
export default MyApp;
EDIT: It seems to be changing the background for the components I have used with material-UI but not for other components I may define.
e.g. Here. I used the card component of MUI and the background was changed but I need it to change the background colour of the whole page
EDIT2: The component one worked because I defined paper colour, but I still cant get default to work
So the reason it's still not working is that we need to import CssBaseline for it to work. CssBaseline implements background.default color according to the doc.
Here's how it'll work
import '../styles/globals.css';
import {ThemeProvider} from "#mui/material/styles"
import theme from '../theme'
import { CssBaseline } from '#mui/material/';
function MyApp({ Component, pageProps }) {
return (
<ThemeProvider theme={theme}>
<CssBaseline/>
<Component {...pageProps} />
</ThemeProvider>
);
}
export default MyApp;
Still weird how the paper property works but for default you need to import additional dependencies

React Mui Appbar theming

I tried theming MUI AppBar but I have no idea about theming.
Can I style an AppBar with theme without using styled component or other style api?
palette.js
import { createTheme } from '#mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: "#000F04"
}
}
});
App.js
import theme from "../../styles/palette";
import { ThemeProvider } from '#mui/material/styles';
const App = () => {
return (
<ThemeProvider theme={theme}>
<AppBar position="static" color="primary">
<Toolbar>
</Toolbar>
</AppBar>
</ThemeProvider>
)
}
Your codesandbox work.
Use the sx props if you need to add specific style. https://mui.com/system/the-sx-prop/
You can too overide style on the theme: https://mui.com/customization/theme-components/#heading-global-style-overrides

ThemeProvider does not apply theme to child components from material ui library

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?

Can we keep different themes for different pages in react with styled components website? [duplicate]

I'm using styled-components in my React app and wanting to use a dynamic theme. Some areas it will use my dark theme, some will use the light. Because the styled components have to be declared outside of the component they are used in, how do we pass through a theme dynamically?
That's exactly what the ThemeProvider component is for!
Your styled components have access to a special theme prop when they interpolate a function:
const Button = styled.button`
background: ${props => props.theme.primary};
`
This <Button /> component will now respond dynamically to a theme defined by a ThemeProvider. How do you define a theme? Pass any object to the theme prop of the ThemeProvider:
const theme = {
primary: 'palevioletred',
};
<ThemeProvider theme={theme}>
<Button>I'm now palevioletred!</Button>
</ThemeProvider>
We provide the theme to your styled components via context, meaning no matter how many components or DOM nodes are in between the component and the ThemeProvider it'll still work exactly the same:
const theme = {
primary: 'palevioletred',
};
<ThemeProvider theme={theme}>
<div>
<SidebarContainer>
<Sidebar>
<Button>I'm still palevioletred!</Button>
</Sidebar>
</SidebarContainer>
</div>
</ThemeProvider>
This means you can wrap your entire app in a single ThemeProvider, and all of your styled components will get that theme. You can swap that one property out dynamically to change between a light and a dark theme!
You can have as few or as many ThemeProviders in your app as you want. Most apps will only need one to wrap the entire app, but to have a part of your app be light themed and some other part dark themed you would just wrap them in two ThemeProviders that have different themes:
const darkTheme = {
primary: 'black',
};
const lightTheme = {
primary: 'white',
};
<div>
<ThemeProvider theme={lightTheme}>
<Main />
</ThemeProvider>
<ThemeProvider theme={darkTheme}>
<Sidebar />
</ThemeProvider>
</div>
Any styled component anywhere inside Main will now be light themed, and any styled component anywhere inside Sidebar will be dark themed. They adapt depending on which area of the application they are rendered in, and you don't have to do anything to make it happen! 🎉
I encourage you to check out our docs about theming, as styled-components was very much built with that in mind.
One of the big pain points of styles in JS before styled-components existed was that the previous libraries did encapsulation and colocation of styles very well, but none of them had proper theming support. If you want to learn more about other pain points we had with existing libraries I'd encourage you to watch my talk at ReactNL where I released styled-components. (note: styled-components' first appearance is at ~25 minutes in, don't be surprised!)
While this question was originally for having multiple themes running at the same time, I personally wanted to dynamically switch in runtime one single theme for the whole app.
Here's how I achieved it: (I'll be using TypeScript and hooks in here. For plain JavaScript just remove the types, as, and interface):
I have also included all the imports at the top of each block code just in case.
We define our theme.ts file
//theme.ts
import baseStyled, { ThemedStyledInterface } from 'styled-components';
export const lightTheme = {
all: {
borderRadius: '0.5rem',
},
main: {
color: '#FAFAFA',
textColor: '#212121',
bodyColor: '#FFF',
},
secondary: {
color: '#757575',
},
};
// Force both themes to be consistent!
export const darkTheme: Theme = {
// Make properties the same on both!
all: { ...lightTheme.all },
main: {
color: '#212121',
textColor: '#FAFAFA',
bodyColor: '#424242',
},
secondary: {
color: '#616161',
},
};
export type Theme = typeof lightTheme;
export const styled = baseStyled as ThemedStyledInterface<Theme>;
Then in our main entry, in this case App.tsx we define the <ThemeProvider> before every component that's going to use the theme.
// app.tsx
import React, { memo, Suspense, lazy, useState } from 'react';
import { Router } from '#reach/router';
// The header component that switches the styles.
import Header from './components/header';
// Personal component
import { Loading } from './components';
import { ThemeProvider } from 'styled-components';
// Bring either the lightTheme, or darkTheme, whichever you want to make the default
import { lightTheme } from './components/styles/theme';
// Own code.
const Home = lazy(() => import('./views/home'));
const BestSeller = lazy(() => import('./views/best-seller'));
/**
* Where the React APP main layout resides:
*/
function App() {
// Here we set the default theme of the app. In this case,
// we are setting the lightTheme. If you want the dark, import the `darkTheme` object.
const [theme, setTheme] = useState(lightTheme);
return (
<Suspense fallback={<Loading />}>
<ThemeProvider theme={theme}>
<React.Fragment>
{/* We pass the setTheme function (lift state up) to the Header */}
<Header setTheme={setTheme} />
<Router>
<Home path="/" />
<BestSeller path="/:listNameEncoded" />
</Router>
</React.Fragment>
</ThemeProvider>
</Suspense>
);
}
export default memo(App);
And in header.tsx we pass the setTheme to the component (Lifting the state up):
// header.tsx
import React, { memo, useState } from 'react';
import styled, { ThemedStyledInterface } from 'styled-components';
import { Theme, lightTheme, darkTheme } from '../styles/theme';
// We have nice autocomplete functionality
const Nav = styled.nav`
background-color: ${props => props.theme.colors.primary};
`;
// We define the props that will receive the setTheme
type HeaderProps = {
setTheme: React.Dispatch<React.SetStateAction<Theme>>;
};
function Header(props:
function setLightTheme() {
props.setTheme(lightTheme);
}
function setDarkTheme() {
props.setTheme(darkTheme);
}
// We then set the light or dark theme according to what we want.
return (
<Nav>
<h1>Book App</h1>
<button onClick={setLightTheme}>Light </button>
<button onClick={setDarkTheme}> Dark </button>
</Nav>
);
}
export default memo(Header);
Here's something that did the job for me:
import * as React from 'react';
import { connect } from 'react-redux';
import { getStateField } from 'app/redux/reducers/recordings';
import { lightTheme, darkTheme, ThemeProvider as SCThemeProvider } from 'app/utils/theme';
import { GlobalStyle } from 'app/utils/globalStyles';
interface ThemeProviderProps {
children: JSX.Element;
isLightMode?: boolean;
}
const ThemeProvider = ({ children, isLightMode }: ThemeProviderProps) => {
return (
<SCThemeProvider theme={isLightMode ? lightTheme : darkTheme}>
<React.Fragment>
{children}
<GlobalStyle />
</React.Fragment>
</SCThemeProvider>
);
};
export const ConnectedThemeProvider = connect((state) => ({
isLightMode: getStateField('isLightMode', state)
}))(ThemeProvider);

Change primary and secondary colors in MUI

I have a react app using MUI. When you import a button, you can set its style using primary={true} or secondary={true}. I want to change the primary and secondary colors. I found out that I can do that this way:
const theme = createMuiTheme({
palette: {
primary: '#00bcd4',
secondary: '#ff4081'
}
});
and then here I can use it:
<MuiThemeProvider theme={theme}>
<App/>
</MuiThemeProvider>
But I got an error: createMuiTheme is not a function...
I went into the MUI package and found out that there is not such file and when I import createMuiTheme, I get undefined. It's supposed to be imported from material-ui/styles/theme but it actually doesn't have this folder at all!
I was using material-ui#0.19.4. I updated this package to v20 and there is still no such folder anyway.
New Answer
With the latest version of Material UI, createMuiTheme is deprecated now. Hence, instead of that we should use createTheme
import React from 'react';
import { render } from 'react-dom';
import { MuiThemeProvider, createTheme } from '#material-ui/core/styles';
import Root from './Root';
// use default theme
// const theme = createTheme();
// Or Create your Own theme:
const theme = createTheme({
palette: {
secondary: {
main: '#E33E7F'
}
}
});
function App() {
return (
<MuiThemeProvider theme={theme}>
<Root />
</MuiThemeProvider>
);
}
render(<App />, document.querySelector('#app'));
Old answer
From https://material-ui.com/customization/themes/:
import React from 'react';
import { render } from 'react-dom';
import { MuiThemeProvider, createMuiTheme } from '#material-ui/core/styles';
import Root from './Root';
// use default theme
// const theme = createMuiTheme();
// Or Create your Own theme:
const theme = createMuiTheme({
palette: {
secondary: {
main: '#E33E7F'
}
}
});
function App() {
return (
<MuiThemeProvider theme={theme}>
<Root />
</MuiThemeProvider>
);
}
render(<App />, document.querySelector('#app'));
The two diferrences with the documentation i noticed is the name of the prop for the MuiThemeProvider:
<MuiThemeProvider muiTheme={muiTheme}>
<AppBar title="My AppBar" />
</MuiThemeProvider>
And the function is not createMuiTheme but getMuiTheme:
import getMuiTheme from 'material-ui/styles/getMuiTheme';
Update:
If you open the light theme from the package, they are not using primary or secondary, maybe you should try like that?
You should be using v1-beta as the docs recommend. I had these issues myself and realised that I was using an outdated version of MUI.
npm install material-ui#next
Import:
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
Create your theme:
const theme = createMuiTheme({
palette: {
secondary: {
main: '#d32f2f'
}
},
});
Apply it to your button:
<MuiThemeProvider theme={theme}>
<Button
onClick={this.someMethod}
variant="raised"
color="secondary"
</Button>
</MuiThemeProvider>
Usually if you get any import issues regarding MUI, then it's almost every time some version problem.
If you want to use a custom color, put it in the main property of an object. MUI will use that color to calculate the dark, light and contrastText values besides the main one.
dark, light: a darker and lighter versions of the main color.
contrastText: the color of the text if the background color is the main color.
The example below:
const theme = createTheme({
palette: {
primary: {
main: '#ff0000', // very red
},
secondary: {
main: '#00fff0', // very cyan
},
},
});
Generates the following color properties in the primary and secondary object:
const theme = useTheme();
const { main, dark, light, contrastText } = theme.palette.primary;
// same with secondary
// const { main, dark, light, contrastText } = theme.palette.secondary;
You can also use MUI colors by passing the color object directly to primary or secondary property. This time, MUI uses the property 500 (for example amber[500]) to calculate 3 other colors. The code below:
import { amber, deepPurple } from '#mui/material/colors';
const theme = createTheme({
palette: {
primary: amber,
secondary: deepPurple,
},
});
Generates the following color properties in the primary and secondary object, Note that because you pass the whole color, all other shades from 50 to A700 are also available as a small side-effect:
Live Demo
Related Answers
How to add custom MUI palette colors
Material-UI: how to access all palette shades inside component
The new API for MUI Material v5 is described in https://mui.com/material-ui/customization/theming/.
import * as React from 'react';
import { red } from '#mui/material/colors';
import { ThemeProvider, createTheme } from '#mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: red[500],
},
},
});
const App = () =>
<ThemeProvider theme={theme}>...</ThemeProvider>;

Resources