using theme.spacing inside theme definition - javascript

I have the following theme setup:
export const themeDefault = createTheme({
themeName: 'Default (Mortgage Hub)',
spacing: 4,
...typography,
palette,
components: {
MuiButton: {
styleOverrides: {
root: {
paddingLeft: theme.spacing(12),
paddingRight: theme.spacing(4),
border: '10px',
},
},
},
},
})
And I would like to use theme.spacing inside however, of course. Theme is not defined yet. I have tried to use makeStyles & useTheme however these are hooks. So of course they will not work.
Are you able to supply styleOverrides once the theme has been indicated?

The styleOverrides feature of the theme is extremely powerful and versatile. In the Overrides based on props portion of the documentation, you can find an example of specifying a callback within the styleOverrides which then gives you access to the component's props and state (via ownerState) and the theme.
Below is an example showing how the callback syntax gives you access to the theme as well as showing how you can leverage ownerState to do conditional styles based on the props passed to a component (e.g. based on whether or not startIcon was specified or which variant was used or any combination of interest).
import * as React from "react";
import Stack from "#mui/material/Stack";
import Button from "#mui/material/Button";
import { createTheme, ThemeProvider } from "#mui/material/styles";
import SaveIcon from "#mui/icons-material/Save";
const theme = createTheme({
themeName: "Default (Mortgage Hub)",
spacing: 4,
components: {
MuiButton: {
styleOverrides: {
root: ({ ownerState, theme }) => {
const conditionalStyles = {};
if (ownerState.startIcon !== undefined) {
conditionalStyles.paddingLeft = theme.spacing(6);
if (ownerState.variant === "outlined") {
conditionalStyles.border = "5px solid black";
conditionalStyles["&:hover"] = { border: "5px solid grey" };
}
} else {
conditionalStyles.paddingLeft = theme.spacing(4);
}
return {
...conditionalStyles,
paddingRight: theme.spacing(4)
};
}
}
}
}
});
export default function BasicButtons() {
return (
<ThemeProvider theme={theme}>
<Stack spacing={2} direction="row">
<Button variant="text">Text</Button>
<Button variant="contained">Contained</Button>
<Button variant="outlined">Outlined</Button>
<Button startIcon={<SaveIcon />} variant="contained">
Contained with startIcon
</Button>
<Button startIcon={<SaveIcon />} variant="outlined">
Outlined with startIcon
</Button>
</Stack>
</ThemeProvider>
);
}

Related

Why is my AppBar MUI styled component not changing style on state change?

I'm trying to change the app bar color upon scrolling. I used a MaterialUI styled feature to create my app bar. I checked the value of the state in the console and it is changing correctly. Unfortunately, the app bar does not react to the state change of my passed prop on the styled component which is supposed to be the trigger for the component background color.
Here is the styled component code:
const AppBar = styled(MUIAppBar)(({ theme, scrollNav }) => ({
backgroundColor: !scrollNav ? '#E6EEF4 !important' : 'red !important',
position: 'fixed',
color: '#232F3D',
paddingTop: theme.spacing(2),
paddingBottom: theme.spacing(2),
}))
Here is the trigger for the state change:
const [scrollNav, setScrollNav] = useState(false)
const changeNav = () => {
setScrollNav(window.scrollY >= 96 ? true : false)
}
useEffect(() => {
window.addEventListener('scroll', changeNav)
}, [])
Here is how I pass the state to the styled component:
<AppBar position="fixed" scrollNav={scrollNav}></AppBar>
This example may helpful
Spread the props
Codesandbox link
import { styled } from "#mui/styles";
import { Button, createTheme, ThemeProvider } from "#mui/material";
import { useState } from "react";
const appTheme = createTheme({
palette: {
primary: {
main: "#e56339"
}
}
});
const StyledDiv = styled("div")(({ theme, ...props }) => ({
// background: theme.palette.primary?.main, //theme usage
background: props?.toggled ? "red" : "blue"
}));
export default function App() {
const [toggle, setToggle] = useState(false);
return (
<div>
<ThemeProvider theme={appTheme}>
<StyledDiv toggled={toggle}>Styled div</StyledDiv>
</ThemeProvider>
<div style={{margin:10}}>
<Button variant="contained" onClick={() => setToggle((pre) => !pre)}>toggle</Button>
</div>
</div>
);
}

React.useContext() keeps returning undefined?

I'm using Next.js and React, using react hooks + context to manage state. However, I've run into this issue, where React.useContext() returns undefined even though I'm passing in my context object (or so I think, anyway). Am I missing something really obvious? What's happening?
I've created the context in a const called CartContext, and then in my provider component, I have created the value object and passed it as a prop to CartContext.Provider (see below, in _app.js). I made sure the context provider was wrapping my components by adding an <h1> element just to make sure.
The problem seems to occur in index.js. I've imported the CartContext from ./_app.js and then passed it as the argument to useContext() which is supposedly what I should do, but it keeps throwing this error:
"TypeError: Cannot destructure property 'firstSample' of 'react__WEBPACK_IMPORTED_MODULE_0___default.a.useContext(...)' as it is undefined"
which from what I have gathered tells me that useContext() is returning undefined.
_app.js (wraps all pages)
import React from 'react'
import '../styles/global.css';
import theme from '../components/customTheme';
import { ThemeProvider } from '#material-ui/core/styles';
const MyApp = props => {
const { Component, pageProps, store } = props
return (
<ContextProvider>
<ThemeProvider theme={theme}>
<Component {...pageProps} />
</ThemeProvider>
</ContextProvider>
)
}
// Context
export const CartContext = React.createContext()
function ContextProvider({ children }) {
const value = {
firstSample: "Test",
exampleFunction: () => {alert("Hello World")},
}
return (
<CartContext.Provider value={value}>
<h1>The provider works</h1>
{children}
</CartContext.Provider>
)
}
export default MyApp;
index.js
import Nav from '../components/nav';
import Footer from '../components/footer';
import Product from '../components/product';
import { makeStyles } from '#material-ui/core/styles';
import CartContext from './_app';
import {
Typography,
Button
} from '#material-ui/core';
const useStyles = makeStyles({
body: {
margin: '13vh 0 3vh',
backgroundColor: ' white',
textAlign: 'left'
},
earnWrapper: {
display: 'block',
textAlign: 'left',
backgroundColor: 'white',
width: 'calc(100% - 4vh)',
margin: '5% 2vh 12%',
borderRadius: '25px',
transition: '0.3s',
boxShadow: '0px 5px 20px #dedede'
},
earnContent: {
padding: '7%',
textAlign: 'left',
display: 'inline-block'
},
earntCaption: {
color: 'grey',
},
earntAmount: {
margin: '0.5vh 0 1.5vh'
},
withdraw: {
width: '130px',
height: '40px'
},
shareInfo: {
margin: '5% 2vh',
textAlign: 'left'
},
products: {
textAlign: 'center ',
width: '100%'
}
});
export default function Home(props) {
const styles = useStyles();
// Grab data from parent context
const { firstSample } = React.useContext(
CartContext
)
return (
<div>
<DefaultHead
title="Oorigin | Home"
/>
<Nav isLoggedIn={true} />
<div className={styles.body}>
<div className={styles.earnWrapper}>
<div className={styles.earnContent}>
<Typography className={styles.earntCaption} variant="caption">You've earned</Typography>
<Typography className={styles.earntAmount} variant="h4">S$18.50</Typography>
<Button className={styles.withdraw} disableElevation variant="contained" color="primary">Withdraw</Button>
</div>
</div>
<div className={styles.shareInfo}>
<Typography><b>Shop, Share, Earn</b></Typography>
<Typography><br/>Shop products you like, share products you love, and earn up to 10% commission on every qualifying sale you refer</Typography>
</div>
<div className={styles.products}>
<Product
imgURL="../TestItem1.svg"
imgAlt="Test Product"
title="Disinfecting Air Purifying Solution"
price={(22.80).toFixed(2)}
link="/products/staticProduct"
/>
<Product
imgURL="../TestItem2.svg"
imgAlt="Test Product"
title="Disinfecting Air Purifying Solution"
price={(22.80).toFixed(2)}
/>
<Product
imgURL="../TestItem3.svg"
imgAlt="Test Product"
title="Disinfecting Air Purifying Solution"
price={(22.80).toFixed(2)}
/>
<Product
imgURL="../TestItem4.svg"
imgAlt="Test Product"
title="Disinfecting Air Purifying Solution"
price={(22.80).toFixed(2)}
/>
</div>
</div>
<Footer/>
<h1>{firstSample}</h1>
</div>
);
}
Ok so it was a really simple mistake, I imported CartContext in index.js as
import cartContex from _app.js, when it should be with curley brackets because it is not the default export. So the corrected (functional) code is simply: import { cartContext } from _app.js
There are some problems with your code, I do not understand why your createContext stays with the component<MyApp />.
Problems:
In the MyApp component you are doingexport default MyApp and export CartContext, I believe this is not possible.
Your createContext is without adefaultValue, maybe that's the reason to return undefined. See the example in the documentation
I believe that by making these changes your code should work, or at least you can evolve with your problem.
It would be easier to help with a codesandbox.
Try to import like this :
import { CartContext } from './_app';

material-ui overwrite theme with useStyles / jss

How can you override the Material-UI theme using styles without using !important?
const theme = createMuiTheme({
overrides: {
MuiInputBase: {
input: {
background: '#dd7711',
padding: 10,
},
},
},
},
})
export default makeStyles(theme => ({
hutber: {
background: '#000',
color: '#fff',
},
}))
function SpacingGrid() {
const classes = useStyles()
return <MuiThemeProvider theme={theme}><Input label="Outlined" variant="outlined" className={classes.hutber} /></MuiThemeProvider>
}
Output:
As you can see, the only way to override the styles are be creating another theme :O I would like to know if styles
The reason the override was not working was because specifying the className prop is equivalent to specifying the root CSS class for Input, but your theme overrides are on the input CSS class which is applied to a different element (the root element is a div, the input element is an <input> element within that div).
In my example below, you can see two different approaches for targeting the <input> element. The first approach uses a nested selector to target .MuiInputBase-input. The second approach uses the classes prop (instead of className) and provides the overrides as the input CSS class.
import React from "react";
import ReactDOM from "react-dom";
import {
createMuiTheme,
MuiThemeProvider,
makeStyles
} from "#material-ui/core/styles";
import Input from "#material-ui/core/Input";
const theme = createMuiTheme({
overrides: {
MuiInputBase: {
input: {
background: "#dd7711",
padding: 10
}
}
}
});
const useStyles = makeStyles(theme => ({
hutber: {
"& .MuiInputBase-input": {
background: "#000",
color: "#fff"
}
},
alternateApproach: {
background: "#000",
color: "#fff"
}
}));
function App() {
const classes = useStyles();
return (
<MuiThemeProvider theme={theme}>
<Input defaultValue="Without overrides" variant="outlined" />
<br />
<br />
<Input
defaultValue="With overrides"
variant="outlined"
className={classes.hutber}
/>
<br />
<br />
<Input
defaultValue="Alternate approach"
variant="outlined"
classes={{ input: classes.alternateApproach }}
/>
</MuiThemeProvider>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Warning: Prop `className` did not match ~ Material UI css arbitrarily breaks on reload

Video reproducing the error/missing css
I know there are already dated versions of this question on stack overflow, like React + Material-UI - Warning: Prop className did not match.
However, when I attempt to google and research people's solutions, there is just no clear answer. Any answers I could find don't match my stack.
My stack:
Node JS
Next JS
Material UI
And from what I could glean from answers to questions like next.js & material-ui - getting them to work is that there is some measure of incompatibility when it comes to Next JS and Material UI.
Code-wise, here is my Appbar component. Initially I was not exporting my useStyles object, but I ended up doing it in a pitiful attempt to follow along with Material UI's express guide to "server rendering". There has to be a fix that doesn't involve changing like every file I have.
import React from 'react';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import IconButton from '#material-ui/core/IconButton';
import Typography from '#material-ui/core/Typography';
import InputBase from '#material-ui/core/InputBase';
import { fade } from '#material-ui/core/styles/colorManipulator';
import { makeStyles } from '#material-ui/core/styles';
import MenuIcon from '#material-ui/icons/Menu';
import SearchIcon from '#material-ui/icons/Search';
import {connectSearchBox} from 'react-instantsearch-dom';
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1,
},
menuButton: {
marginRight: theme.spacing(2),
},
title: {
flexGrow: 1,
display: 'none',
[theme.breakpoints.up('sm')]: {
display: 'block',
},
},
search: {
position: 'relative',
borderRadius: theme.shape.borderRadius,
backgroundColor: fade(theme.palette.common.white, 0.15),
'&:hover': {
backgroundColor: fade(theme.palette.common.white, 0.25),
},
marginLeft: 0,
width: '100%',
[theme.breakpoints.up('sm')]: {
marginLeft: theme.spacing(1),
width: 'auto',
},
},
searchIcon: {
width: theme.spacing(7),
height: '100%',
position: 'absolute',
pointerEvents: 'none',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
},
inputRoot: {
color: 'inherit',
},
inputInput: {
padding: theme.spacing(1, 1, 1, 7),
transition: theme.transitions.create('width'),
width: '100%',
[theme.breakpoints.up('sm')]: {
width: 300,
'&:focus': {
width: 400,
},
},
}
}));
function SearchBox({currentRefinement, refine}){
const classes = useStyles();
return(
<InputBase
type="search"
value={currentRefinement}
onChange={event => refine(event.currentTarget.value)}
placeholder="Search by state, park name, keywords..."
classes = {{
root: classes.inputRoot,
input: classes.inputInput,
}}
/>
)
}
const CustomSearchBox = connectSearchBox(SearchBox);
function SearchAppBar() {
const classes = useStyles();
return (
<div className={classes.root}>
<AppBar position="static" color="primary">
<Toolbar>
<IconButton
edge="start"
className={classes.menuButton}
color="inherit"
aria-label="Open drawer"
>
<MenuIcon />
</IconButton>
<Typography className={classes.title} variant="h6" noWrap>
Title
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<CustomSearchBox/>
</div>
</Toolbar>
</AppBar>
</div>
);
}
export {SearchAppBar, useStyles};
I was just digging around random parts of the internet looking for answers to this error, accidentally npm install'ed styled-components as part of this answer on a Github issue (because they have a very similar object to the counterpart in Material UI called ServerStyleSheet (vs Material UI's ServerStyleSheets), so obviously that didn't work.
BUT......... I ended up just using the ServerStyleSheet fix to try to make it agreeable with Material UI's ServerStyleSheets object, and ended up with this new _document.js.
I'm still dumbfounded I was able to refactor an entirely different fix to make this work but I tested it and it fixes the problem entirely, now reloads are fine.
import Document, { Html, Head, Main, NextScript } from 'next/document';
import {ServerStyleSheets} from "#material-ui/styles";
class MyDocument extends Document {
static async getInitialProps(ctx) {
const sheet = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
try{
ctx.renderPage = () => originalRenderPage({
enhanceApp: App => props => sheet.collect(<App {...props}/>)
});
const initialProps = await Document.getInitialProps(ctx);
return { ...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
)
}
} finally {
ctx.renderPage(sheet)
}
}
render() {
return (
<Html>
<Head>
<link rel="shortcut icon" type="image/png" href="../static/favicon.ico"/>
<style>{`body { margin: 0 } /* custom! */`}</style>
<meta name="viewport"content="width=device-width, initial-scale=1.0" />
</Head>
<body className="custom_class">
<Main />
<NextScript />
</body>
</Html>
)}
}
export default MyDocument;
If you wanna see how crazy it was that it worked, here is the fix for the same error in styled-components:
export default MyDocument;
import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'
export default class MyDocument extends Document {
static async getInitialProps (ctx) {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: App => props => sheet.collectStyles(<App {...props} />)
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
)
}
} finally {
sheet.seal()
}
}
}
I hope this helped someone with the mess that is Material-UI + Next.js
For my part, adding { name: "MuiExample_Component" } in the makeStyle hook works for some reason. I found this solution while digging on internet. I would appreciate if someone could tell me if it's a good solution or not, but here is the code :
const useStyles = makeStyles({
card: {
backgroundColor: "#f7f7f7",
width: "33%",
},
title: {
color: "#0ab5db",
fontWeight: "bold",
},
description: {
fontSize: "1em"
}
}, { name: "MuiExample_Component" });

MUI customize button color?

I am struggling to modify button colors in MUI next (v1).
How would I set muitheme to behave similarity to bootstrap, so I could just use "btn-danger" for red, "btn-success" for green... ?
I tried with custom className but it doesn't work properly (hover color does't change) and it seems repetitive. What options do I have?
In MUI v5, this is how you create customized colors in your theme for your MUI Button. The primary and secondary colors are created the same way under the hood:
const { palette } = createTheme();
const { augmentColor } = palette;
const createColor = (mainColor) => augmentColor({ color: { main: mainColor } });
const theme = createTheme({
palette: {
anger: createColor('#F40B27'),
apple: createColor('#5DBA40'),
steelBlue: createColor('#5C76B7'),
violet: createColor('#BC00A3'),
},
});
Usage
<Button color="anger" variant="contained">
anger
</Button>
<Button color="apple" variant="contained">
apple
</Button>
<Button color="steelBlue" variant="contained">
steelBlue
</Button>
<Button color="violet" variant="contained">
violet
</Button>
If you're using typescript, you also need to add additional types for the colors you just defined:
declare module '#mui/material/styles' {
interface CustomPalette {
anger: PaletteColorOptions;
apple: PaletteColorOptions;
steelBlue: PaletteColorOptions;
violet: PaletteColorOptions;
}
interface Palette extends CustomPalette {}
interface PaletteOptions extends CustomPalette {}
}
declare module '#mui/material/Button' {
interface ButtonPropsColorOverrides {
anger: true;
apple: true;
steelBlue: true;
violet: true;
}
}
Live Demo
Related Answers
How to add custom MUI palette colors
Change primary and secondary colors in MUI
You can try this
<Button
style={{
borderRadius: 35,
backgroundColor: "#21b6ae",
padding: "18px 36px",
fontSize: "18px"
}}
variant="contained"
>
Submit
</Button>
I came up with this solution using Brendans answer in this thread. Hopefully it'll help someone in a similar situation.
import React, { Component } from 'react'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles'
import Button from 'material-ui/Button'
import { red, blue } from 'material-ui/colors'
const redTheme = createMuiTheme({ palette: { primary: red } })
const blueTheme = createMuiTheme({ palette: { primary: blue } })
class Buttons extends Component {
render = () => (
<div className="ledger-actions-module">
<MuiThemeProvider theme={redTheme}>
<Button color="primary" variant="raised">
Delete
</Button>
</MuiThemeProvider>
<MuiThemeProvider theme={blueTheme}>
<Button color="primary" variant="raised">
Update
</Button>
</MuiThemeProvider>
</div>
)
}
There is a mistake with Bagelfp's answer, and some other things to consider;
First, 'error' is not a supported color theme in material-ui#next v1's Button component. Only 'default', 'inherit', 'primary' and 'secondary' are accepted by the color prop.
Here is the approach I have found to be the easiest so far. First, choose your two most common theme colors and place them at the root of your app.
import React from 'react';
import { Component } from './Component.js'
import { MuiThemeProvider, createMuiTheme } from 'material-ui/styles';
const theme = createMuiTheme({
palette: {
primary: 'purple',
secondary: 'green',
error: 'red',
},
});
export class App extends Component {
render() {
return (
<MuiThemeProvider theme={theme}>
<Component />
...
</MuiThemeProvider>
);
}
}
Then in your component, choose the theme with your desired color;
import React from 'react';
import Button from 'material-ui/Button';
export const Component = (props) => (
<div>
<Button variant="fab" color="primary">
I am purple, click me!
</Button>
</div>
)
If you need a third and fourth color, you can export Component.js with a new palette just like you did in App.js.
This is the only solution I have found that allows me to retain the darkened hover effect (none of the official override examples retain functioning hover). I really wish I could find a way to simply drop in a new theme color when calling Button, but for now this is the most simple way to do it.
EDIT: My new preferred method is to create a CustomButton component using styled-components and material-ui buttonbase. I also place the styled-components theme provider at the root of my app alongside my MuiThemeProvider. This gives me easy access to additional theme colors in all my styled-components without importing and dropping in more ThemeProviders. In the case of my CustomButton, I just give it a theme prop, which is passed right down to the css in styled(ButtonBase). See the styled-component docs for more info.
Try this:
import * as React from 'react';
import Button, { ButtonProps } from "#material-ui/core/Button";
import { Theme } from '#material-ui/core';
import { withStyles } from '#material-ui/styles';
const styles: (theme: Theme) => any = (theme) => {
return {
root:{
backgroundColor: theme.palette.error.main,
color: theme.palette.error.contrastText,
"&:hover":{
backgroundColor: theme.palette.error.dark
},
"&:disabled":{
backgroundColor: theme.palette.error.light
}
}
};
};
export const ButtonContainedError = withStyles(styles)((props: ButtonProps) => {
const { className, ...rest } = props;
const classes = props.classes||{};
return <Button {...props} className={`${className} ${classes.root}`} variant="contained" />
});
Now you have a ButtonContainedError to use anywhere.
And it is consistent with your theme.
Here is an example typescript implementation:
import React from "react";
import { createStyles, Theme, makeStyles } from "#material-ui/core/styles";
import capitalize from "lodash/capitalize";
import MuiButton, {
ButtonProps as MuiButtonProps
} from "#material-ui/core/Button";
export type ColorTypes =
| "primary"
| "secondary"
| "error"
| "success"
| "warning"
| "default"
| "inherit"
| "info";
type ButtonProps = { color: ColorTypes } & Omit<MuiButtonProps, "color">;
const useStyles = makeStyles<Theme>(theme =>
createStyles({
outlinedSuccess: {
borderColor: theme.palette.success.main,
color: theme.palette.success.main
},
outlinedError: {
borderColor: theme.palette.error.main,
color: theme.palette.error.main
},
outlinedWarning: {
borderColor: theme.palette.warning.main,
color: theme.palette.warning.main
},
outlinedInfo: {
borderColor: theme.palette.info.main,
color: theme.palette.info.main
},
containedSuccess: {
backgroundColor: theme.palette.success.main,
color: theme.palette.success.contrastText,
"&:hover": {
backgroundColor: theme.palette.success.dark
}
},
containedError: {
backgroundColor: theme.palette.error.main,
color: theme.palette.error.contrastText,
"&:hover": {
backgroundColor: theme.palette.error.dark
}
},
containedWarning: {
backgroundColor: theme.palette.warning.main,
color: theme.palette.warning.contrastText,
"&:hover": {
backgroundColor: theme.palette.warning.dark
}
},
containedInfo: {
backgroundColor: theme.palette.info.main,
color: theme.palette.info.contrastText,
"&:hover": {
backgroundColor: theme.palette.info.dark
}
}
})
);
const Button: React.FC<ButtonProps> = ({ children, color, ...props }) => {
const classes = useStyles();
const className = classes?.[`${props.variant}${capitalize(color)}`];
const colorProp =
["default", "inherit", "primary", "secondary"].indexOf(color) > -1
? (color as "default" | "inherit" | "primary" | "secondary")
: undefined;
return (
<MuiButton {...props} color={colorProp} className={className}>
{children}
</MuiButton>
);
};
Button.displayName = "Button";
export default Button;
with this you can do <Button variant="contained" color="success"> with autocomplete and warning free :)
Update:
In Material UI V5 this is achievable in a much more elegant way. You can just add a color to the palette and the button will automatically support it! Their documentation has a great example of how to do this: https://mui.com/customization/palette/#adding-new-colors
You can use theme.palette.getContrastText() to calculate the correct text color based on a background color value.
import { Button, makeStyles } from '#material-ui/core';
const useStyles = makeStyles((theme) => ({
deleteButton: {
// to make a red delete button
color: theme.palette.getContrastText(theme.palette.error.main),
background: theme.palette.error.main,
}
}));
export const DeleteButton = () => {
const classes = useStyles();
return (
<Button className={classes.deleteButton}>Delete</Button>
);
}
first try to install npm install #material-ui/styles the
apply styles according to material documentation, for react class component you can use below code:
import React, {Component} from "react";
import { styled } from '#material-ui/styles';
import Button from '#material-ui/core/Button';
const MyButton = styled(Button)({
background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
border: 0,
borderRadius: 3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
color: 'white',
height: 48,
padding: '0 30px',
});
class AprinClass extends Component {
render() {
return (
<MyButton>Styled Components</MyButton>
)
}
}
export default AprinClass;
for more information with references please check my blog in medium.
https://medium.com/#farbodaprin/how-to-make-a-customisable-material-ui-button-a85b6534afe5
You could create a theme with palettes defined for each of their 3 supported intentions (primary, secondary, error), and then use the color prop on <Button> to use those. In your example the btn-danger could be <Button color='error'>
EDIT: Brendan's answer is correct here that error is not supported for Button. According to the documentation Button only supports intentions that "make sense for this component.", so only primary and secondary would work here.
From their docs (trimmed down a little here):
const theme = createMuiTheme({
palette: {
primary: purple,
secondary: red
}
});
function Palette() {
return (
<MuiThemeProvider theme={theme}>
<div>
<Button color="primary">{'Primary'}</Button>
<Button color="secondary">{'Secondary'}</Button>
</div>
</MuiThemeProvider>
);
}
See Brendan's Answer for a more realistic example of creating themes for your components.
The easiest way to change the button color is to add the "style" attribute. Here's an example of a green button I created:
import Button from '#material-ui/core/Button';
<Button
variant="contained"
color="primary"
style={{ backgroundColor: '#357a38' }}
>
Run
</Button>
From 2022/05:
According to the official Doc: Customize MUI with your theme, you need to use ThemeProvider and createTheme.
First, customize the primary color like this,
import {ThemeProvider, createTheme} from '#mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: '#000000',
},
},
});
Then wrap your App or anywhere your want with the ThemeProvider component, and set the color props of your Button component to primary.
function YourApp() {
// logic omitted
return (
<ThemeProvider theme={theme}>
<YourApp>
<Button color="primary">Click me</Button>
</YourApp>
</ThemeProvider>
);
}
I found out that !important works in the classes. (React Hooks)
const styles "...etc..." = (theme: Theme) => ({
buttonWarning: {
backgroundColor: theme.palette.warning.dark + '!important'
}
}))
Then in the button
const classes = styles();
<Button className={classes.buttonWarning}>Hello</Button>
Use This sx props it gives more understanding and also more relative to the MUI. in most of the MUI components, they use these props.
import {Button} from '#mui/material'
<Button variant="contained" sx={{
borderRadius: 35,
backgroundColor: "#21b6ae",
padding: "18px 36px",
fontSize: "18px",
**color:"white"**
}} >
elevation
</Button>
Export any color from '#mui/material/colors'; (Docs)
import { pink } from '#mui/material/colors';
and use like this
<Button variant="contained" sx={{ backgroundColor: pink[700] }}>Check</Button>

Categories