I'm new to React and Material UI, i'm trying to add some custom styles to the MUI buttons by using the createMuiTheme.
I've followed the docs and pretty much copied the example but it's having no effect and no errors are being thrown in the console.
I've been banging my head against this for a while now and I can't see what the problem is, what am I missing?
import React from 'react';
import { createMuiTheme } from '#material-ui/core/styles';
import { ThemeProvider } from '#material-ui/styles';
import Button from '#material-ui/core/Button';
const mytheme = createMuiTheme({
palette: {
primary: { main: '#1565C0'},
secondary: { main: '#11cb5f' },
},
});
export const PrimaryButton = (props) => {
return (
<ThemeProvider theme={mytheme}>
<a href={props.buttonLink}>
<Button
style={{ ...props.styles}}
onClick={props.handleClick}
variant='contained' color='primary' size='large'
>
{props.buttonText}
</Button>
</a>
</ThemeProvider>
);
};
export const SecondaryButton = (props) => {
return (
<ThemeProvider theme={mytheme}>
<Button
style={{...props.styles }}
value={props.value || ''}
onClick={props.handleClick}
variant='outlined' color='secondary' size='large'
>
{props.buttonText}
</Button>
</ThemeProvider>
)
}
It is working. Try to change this:
variant='outlined'
by
variant='contained'
Related
I've used Ryan Cogswell's answer to have my project compatible to RTL.
But for some reason, the Material-ui icon <Send/> didn't flip accordingly. Is it because it's not compatible to RTL? Or am I missing something?
Here's an example showing that the Send icon doesn't flip:
import React from "react";
import { create } from "jss";
import rtl from "jss-rtl";
import {
StylesProvider,
jssPreset,
ThemeProvider,
createMuiTheme
} from "#material-ui/core/styles";
import CssBaseline from "#material-ui/core/CssBaseline";
import TextField from "#material-ui/core/TextField";
import Button from "#material-ui/core/Button";
import Box from "#material-ui/core/Box";
import SendIcon from "#material-ui/icons/Send";
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
const ltrTheme = createMuiTheme({ direction: "ltr" });
const rtlTheme = createMuiTheme({ direction: "rtl" });
function AppContent() {
const [isRtl, setIsRtl] = React.useState(false);
React.useLayoutEffect(() => {
document.body.setAttribute("dir", isRtl ? "rtl" : "ltr");
}, [isRtl]);
return (
<ThemeProvider theme={isRtl ? rtlTheme : ltrTheme}>
<CssBaseline />
<Box m={2}>
<TextField label={isRtl ? "بريد الكتروني او هاتف" : "Email or Phone"} />
<br />
<SendIcon />
<br />
Current Direction: {isRtl ? "rtl" : "ltr"}
<br />
<Button onClick={() => setIsRtl(!isRtl)}>Toggle direction</Button>
</Box>
</ThemeProvider>
);
}
export default function App() {
return (
<StylesProvider jss={jss}>
<AppContent />
</StylesProvider>
);
}
Thanks
Material-UI icons are not automatically flipped for rtl. This is discussed some here: https://github.com/mui-org/material-ui/issues/22726.
Here is an example of one way to handle this for the Send icon (and this approach should be usable for other icons as well):
const DirectionAwareSendIcon = withStyles((theme) => ({
root: {
transform: theme.direction === "rtl" ? "scaleX(-1)" : undefined
}
}))(SendIcon);
It is also possible to handle this globally using overrides in the theme:
MuiSvgIcon: {
root: {
"body[dir=rtl] &": {
transform: "scaleX(-1)"
}
}
}
There is some risk that this could conflict with styling in some Material-UI components which use transform in the default styles, but the examples that I have looked at so far (e.g. AccordionSummary), seem to still work fine. This global approach would currently cause issues for TablePaginationActions and PaginationItem which both swap which icons they use based on theme.direction. This global approach would then flip the already-flipped icon, so if you use either of these components you would need to take this into consideration.
There are also some icons where flipping is not desirable, for instance icons with a recognizable symbol such as Help ("?") and AttachMoney ("$"), so my recommendation would be the first approach of just explicitly adding the flipping behavior to the icons that need it.
Here's a full working example with the theme approach:
import React from "react";
import { create } from "jss";
import rtl from "jss-rtl";
import {
StylesProvider,
jssPreset,
ThemeProvider,
createMuiTheme
} from "#material-ui/core/styles";
import CssBaseline from "#material-ui/core/CssBaseline";
import TextField from "#material-ui/core/TextField";
import Button from "#material-ui/core/Button";
import Box from "#material-ui/core/Box";
import SendIcon from "#material-ui/icons/Send";
const overrides = {
MuiSvgIcon: {
root: {
"body[dir=rtl] &": {
transform: "scaleX(-1)"
}
}
}
};
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
const ltrTheme = createMuiTheme({ direction: "ltr" });
const rtlTheme = createMuiTheme({ direction: "rtl", overrides });
function AppContent() {
const [isRtl, setIsRtl] = React.useState(false);
React.useLayoutEffect(() => {
document.body.setAttribute("dir", isRtl ? "rtl" : "ltr");
}, [isRtl]);
return (
<ThemeProvider theme={isRtl ? rtlTheme : ltrTheme}>
<CssBaseline />
<Box m={2}>
<TextField label={isRtl ? "بريد الكتروني او هاتف" : "Email or Phone"} />
<br />
<SendIcon />
<br />
Current Direction: {isRtl ? "rtl" : "ltr"}
<br />
<Button onClick={() => setIsRtl(!isRtl)}>Toggle direction</Button>
</Box>
</ThemeProvider>
);
}
export default function App() {
return (
<StylesProvider jss={jss}>
<AppContent />
</StylesProvider>
);
}
I'm using Material-Ui in my React Project !
i followed the steps in the documentation to allow RTL in my project and all work fine !
except the TextField Component
LTR DIRECTION :
RTL DIRECTION
Like you see ! the problem is with the label still in left ( the input text work fine )
App.js file
import React, {useState} from 'react';
//i18n
import {withTranslation} from "react-i18next";
import './i18n';
//jss
import { create } from 'jss';
import rtl from 'jss-rtl';
import { StylesProvider, jssPreset } from '#material-ui/core/styles';
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
function App(props) {
// initialize Language
const { i18n } = props;
const [ prefLang, setPrefLang] = useState(i18n.language);
let theme =createMuiTheme({
palette : {
primary : {
main : '#ed5ac0',
},
},
typography : {
fontFamily : "lalezar, cursive",
h3 : {
fontSize : 1.4,
},
h4 : {
fontSize : 1.5
},
fontAwseomeSize : {
xs : "14px",
sm : "14px",
md : "16px"
},
responsiveFont : {
xs : "20px",
sm : "12.5px",
md : "14px"
},
highLight : {
md : "25px"
},
subHighLight : {
md : "18px"
}
},
}
);
return (
<BrowserRouter>
<LangContext.Provider
value ={{
prefLang,
setPrefLang
}}
>
<CssBaseline/>
<ThemeProvider theme={theme}>
<StylesProvider jss={jss}>
<Grid dir={(prefLang === "ar") ? "rtl" : "ltr"}>
{/*<AppHeader/>*/}
<ContentRouter/>
</Grid>
</StylesProvider>
</ThemeProvider>
</LangContext.Provider>
</BrowserRouter>
);
}
export default withTranslation()(App);
My Form Component
const LoginForm = () => {
return (
<>
<Backdrop style={{ zIndex : 999 , color : theme.palette.primary.main}} open={backdrop} >
<CircularProgress color="inherit" />
</Backdrop>
<form onSubmit={formik.handleSubmit} style={{width: "100%", marginTop: "20px"}}>
{ userNotFound ? <Alert style={{marginBottom : "20px"}} variant="outlined" severity="error">
This is an error alert — check it out!
</Alert> : null}
<TextField
id="identifier"
name="identifier"
onChange={formik.handleChange}
value={formik.values.identifier}
label={t('formIdentifier')}
fullWidth
/>
{formik.touched.identifier && formik.errors.identifier ?
(
<Alert style={{ marginTop :"10px"}} variant="outlined" severity="error">{formik.errors.identifier}</Alert>
) : null}
<TextField
style={{marginTop: "50px"}}
id="password"
name="password"
type="password"
onChange={formik.handleChange}
value={formik.values.password}
label={t('formPassword')}
fullWidth
/>
{formik.touched.password && formik.errors.password ?
(
<Alert style={{ marginTop :"10px"}} variant="outlined" severity="error">{formik.errors.password}</Alert>
) : null}
<Button type="submit" color="primary">{t('login')}</Button>
</form>
</>
);
};
My Theme.js File
import createMuiTheme from "#material-ui/core/styles/createMuiTheme";
let theme =createMuiTheme({
direction : 'rtl',
palette : {
primary : {
main : '#ed5ac0',
},
},
typography : {
fontFamily : "Merienda One, sans-serif",
h3 : {
fontSize : 1.4,
},
h4 : {
fontSize : 1.5
},
fontAwseomeSize : {
xs : "14px",
sm : "14px",
md : "16px"
},
responsiveFont : {
xs : "20px",
sm : "12.5px",
md : "14px"
},
highLight : {
md : "40px"
}
},
}
);
export default theme;
Any suggestion to make the label RTL ?
The documentation contains four steps for rtl support:
Set the dir attribute on the body element.
In my examples below, this is handled by the following:
React.useLayoutEffect(() => {
document.body.setAttribute("dir", isRtl ? "rtl" : "ltr");
}, [isRtl]);
Set the direction in the theme.
In my examples below, I am toggling between two themes:
const ltrTheme = createTheme({ direction: "ltr" });
const rtlTheme = createTheme({ direction: "rtl" });
...
<ThemeProvider theme={isRtl ? rtlTheme : ltrTheme}>
...
</ThemeProvider>
Install the rtl plugin.
For v4 (using JSS), this means installing jss-rtl.
For v5 (using Emotion), this means installing stylis-plugin-rtl.
Load the rtl plugin.
Below is a v4 example showing how to load the rtl plugin for JSS (v5 example further down).
For performance reasons it is important to avoid re-rendering StylesProvider, so this should not be in a component with state that can change and therefore trigger a re-render. In my own app, I have the StylesProvider element in my index.js file as the first element inside the call to react-dom render.
import rtl from "jss-rtl";
import {
StylesProvider,
jssPreset
} from "#material-ui/core/styles";
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
export default function App() {
return (
<StylesProvider jss={jss}>
<AppContent />
</StylesProvider>
);
}
The example below includes a TextField and you can see that the label's position toggles correctly.
import React from "react";
import { create } from "jss";
import rtl from "jss-rtl";
import {
StylesProvider,
jssPreset,
ThemeProvider,
createTheme
} from "#material-ui/core/styles";
import CssBaseline from "#material-ui/core/CssBaseline";
import TextField from "#material-ui/core/TextField";
import Button from "#material-ui/core/Button";
import Box from "#material-ui/core/Box";
// Configure JSS
const jss = create({ plugins: [...jssPreset().plugins, rtl()] });
const ltrTheme = createTheme({ direction: "ltr" });
const rtlTheme = createTheme({ direction: "rtl" });
function AppContent() {
const [isRtl, setIsRtl] = React.useState(false);
const [value, setValue] = React.useState("initial value");
React.useLayoutEffect(() => {
document.body.setAttribute("dir", isRtl ? "rtl" : "ltr");
}, [isRtl]);
return (
<ThemeProvider theme={isRtl ? rtlTheme : ltrTheme}>
<CssBaseline />
<Box m={2}>
<TextField
variant="outlined"
value={value}
onChange={(event) => setValue(event.target.value)}
label={isRtl ? "بريد الكتروني او هاتف" : "Email or Phone"}
/>
<br />
<br />
Current Direction: {isRtl ? "rtl" : "ltr"}
<br />
<Button onClick={() => setIsRtl(!isRtl)}>Toggle direction</Button>
</Box>
</ThemeProvider>
);
}
export default function App() {
return (
<StylesProvider jss={jss}>
<AppContent />
</StylesProvider>
);
}
Below is an equivalent example for v5 using Emotion.
import React from "react";
import rtlPlugin from "stylis-plugin-rtl";
import { CacheProvider } from "#emotion/react";
import createCache from "#emotion/cache";
import { ThemeProvider, createTheme } from "#mui/material/styles";
import CssBaseline from "#mui/material/CssBaseline";
import TextField from "#mui/material/TextField";
import Button from "#mui/material/Button";
import Box from "#mui/material/Box";
import { prefixer } from "stylis";
const cacheLtr = createCache({
key: "muiltr"
});
const cacheRtl = createCache({
key: "muirtl",
// prefixer is the only stylis plugin by default, so when
// overriding the plugins you need to include it explicitly
// if you want to retain the auto-prefixing behavior.
stylisPlugins: [prefixer, rtlPlugin]
});
const ltrTheme = createTheme({ direction: "ltr" });
const rtlTheme = createTheme({ direction: "rtl" });
export default function App() {
const [isRtl, setIsRtl] = React.useState(false);
const [value, setValue] = React.useState("initial value");
React.useLayoutEffect(() => {
document.body.setAttribute("dir", isRtl ? "rtl" : "ltr");
}, [isRtl]);
return (
<CacheProvider value={isRtl ? cacheRtl : cacheLtr}>
<ThemeProvider theme={isRtl ? rtlTheme : ltrTheme}>
<CssBaseline />
<Box m={2}>
<TextField
value={value}
onChange={(event) => setValue(event.target.value)}
label={isRtl ? "بريد الكتروني او هاتف" : "Email or Phone"}
/>
<br />
<br />
Current Direction: {isRtl ? "rtl" : "ltr"}
<br />
<Button onClick={() => setIsRtl(!isRtl)}>Toggle direction</Button>
</Box>
</ThemeProvider>
</CacheProvider>
);
}
In addition, I have a later answer that discusses flipping icons: material-ui icons won't flip when I change to RTL.
Another solution I've found to set this for specific component is to add it via native JS after component is rendered.
First I created a ref to the input element:
const inputRef = createRef()
<TextField inputRef={inputRef} />
Then added a useEffect hook to perform once on each render:
useEffect(() => {
if(inputRef)
inputRef.current.dir = 'auto'
}, [])
Not the most beautiful code, but it sure works 😉
RTL for specific components, and not the whole app:
MUI rtl documentation and the accepted answer pertain to the entire application.
If you want just a few components here and there, all you need to do is create a simple wrapper component, and children will have rtl. No need for a theme provider.
Just be sure to wrap the children with a <div dir="rtl">.
Wrapper Component:
import React from 'react';
import rtlPlugin from "stylis-plugin-rtl";
import { CacheProvider } from "#emotion/react";
import createCache from "#emotion/cache";
import { prefixer } from 'stylis'
const cacheRtl = createCache({
key: "muirtl",
stylisPlugins: [prefixer, rtlPlugin]
});
const RtlProvider = ({ children }) => {
return (
<CacheProvider value={cacheRtl}>
<div dir="rtl">
{children}
</div>
</CacheProvider>
);
};
export default RtlProvider;
Simple Implementation
return (
<RtlProvider>
<TextField label="my label"/>
</RtlProvider>
)
Making CacheProvider tag as a youngest parent for your content, such like below:
<ThemeProvider>
<ScrollToTop />
<BaseOptionChartStyle />
<CacheProvider value={cacheRtl}>
<Router />
</CacheProvider>
</ThemeProvider>
*note:
(Router) includes the various textFields
apart from theme and jss-rtl and stuff that Ryan Cogswell said, there's one tiny problem that i found no where after days of searching (just 3-4 days actualy :)).
and that is the import statement.
make sure youre import statement is like the following:
import TextField from "#material-ui/core/TextField"; //true
if youre import statement is like following, none of those theming and jss stuff works:
import TextField from "#mui/material/TextField"; //false
I am new to React and MUI and maybe I am just missing something.
I am trying to make a button with color='warning' that is defined in my palette like this (the theme works and I can use primary and secondary colors):
const theme = createMuiTheme({
palette: {
primary: {
main: '#70B657'
},
secondary: {
light: '#2face3',
main: '#4199D8',
contrastText: '#ffcc00'
},
warning: {
main: '#BC211D'
}
}
});
I noticed in the documentation that the <Button> color prop only takes default|inherit|primary|secondary so it is not possible to use it like that.
So what is the CORRECT or best practice to use warning colored button in Material-UI? I think this is a basic thing and should be pretty easy to achieve..??
Preferably a solution that does not involve making several different Themes and importing them when needed.
Thanks!
Usage:
const useStyles = makeStyles(theme => ({
root: {
color: theme.palette.warning.main
}
}));
Full code:
import React from "react";
import "./styles.css";
import { Button } from "#material-ui/core";
import { createMuiTheme, ThemeProvider } from "#material-ui/core/styles";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = makeStyles(theme => ({
root: {
color: theme.palette.warning.main
}
}));
function YourComponent() {
const classes = useStyles();
return (
<div className="App">
<Button variant="contained" classes={{ root: classes.root }}>
Secondary
</Button>
</div>
);
}
const theme = createMuiTheme({
palette: {
warning: { main: "#FFFFFF" }
}
});
export default function App() {
return (
<ThemeProvider theme={theme}>
<YourComponent />
</ThemeProvider>
);
}
Update
Pass props to makeStyles
import React from "react";
import "./styles.css";
import { makeStyles } from "#material-ui/core/styles";
const useStyles = props =>
makeStyles(theme => ({
root: {
color: props.value === "111" ? "red" : "blue"
}
}));
const Comp = props => {
const classes = useStyles(props)();
return <input defaultValue={props.value} className={classes.root} />;
};
export default function App() {
return (
<div className="App">
<div>
<Comp value={"111"} />
</div>
<div>
<Comp value={"222"} />
</div>
</div>
);
}
yeah I don't understand why the first example would work and the second dont.
app component
const theme = createMuiTheme({
palette: {
primary: {
main: '#bed000',
},
secondary: {
main: '#110b36',
},
error: {
main: '#B33A3A',
},
},
})
<MuiThemeProvider theme={theme}>
<Route exact path="/" component={LoginView} />
</MuiThemeProvider>
<LoginView>
<TextField
autoFocus
label="Contraseña"
name="Password"
type="Password"
value={values.Password}
onChange={handleChange}
onBlur={handleBlur}
fullWidth
color={touched.Password && errors.Password ? "primary" : "secondary"}
/>
<TextField
autoFocus
label="Contraseña"
name="Password"
type="Password"
value={values.Password}
onChange={handleChange}
onBlur={handleBlur}
fullWidth
color={touched.Password && errors.Password ? "error" : "secondary"}
/>
</LoginView>
I am trying simplest ever theme toggle in react with context and don't seem to be able to get the icon re-render when context changes. Everything else works just fine: colors, background image... It renders either of icons depending on initial state, but icon doesn't update when theme is toggled.
import React, { useContext } from "react"
import { ThemeContext } from "../../contexts/ThemeContext"
const ThemeToggle = () => {
const { isDarkMode, dark, light, toggleTheme } = useContext(ThemeContext)
const theme = isDarkMode ? dark : light
return (
<li
style={{ background: theme.bgPrimary, color: theme.text }}
onClick={toggleTheme}
>
<i className={theme.ico} />
</li>
)
}
export default ThemeToggle
Context:
import React, { Component, createContext } from "react"
export const ThemeContext = createContext()
class ThemeContexProvider extends Component {
state = {
isDarkMode: false,
light: {
text: "#333",
bgPrimary: "#eee",
bgSecondary: "#333",
ico: "fas fa-moon"
},
dark: {
text: "#ddd",
bgPrimary: "#000003",
bgSecondary: "#bbb",
ico: "fas fa-sun"
}
}
toggleTheme = () => {
this.setState({ isDarkMode: !this.state.isDarkMode })
}
render() {
return (
<ThemeContext.Provider
value={{ ...this.state, toggleTheme: this.toggleTheme }}
>
{this.props.children}
</ThemeContext.Provider>
)
}
}
export default ThemeContexProvider
I fixed this installing dedicated react fa package, still don't know why above doesn't work. This works though:
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome"
import { faMoon } from "#fortawesome/free-solid-svg-icons"
import { faSun } from "#fortawesome/free-solid-svg-icons"
//.....
return (
<li
style={{ background: theme.bgPrimary, color: theme.text }}
onClick={toggleTheme}
>
{isDarkMode ? (
<FontAwesomeIcon icon={faSun} />
) : (
<FontAwesomeIcon icon={faMoon} />
)}
</li>
I suspect the spaces in your ico property could be the issue. Normally this isn't an issue for state/props. Context is possibly to blame for this. This might fix it:
<i className={`fas ${theme.ico}`} />
Replace your context ico properties with just the class that changes fa-moon and fa-sun
You could have used key props in the icon tag. Keys help React identify which items have changed. So it can rerender your icon.
{isDarkMode ? (
<i key={1} icon={faSun} />
) : (
<i key={2} icon={faMoon} />
)}
I have create a component that needs to have custom styles, so I used createStyles({}). This seems to have worked (almost) as I want it to. I have also used createGenerateClassName({}) to indicate I need deterministic style names. However, the two do not seem to be working together. While the standard MUI components no longer have the hash number as part of the class name, the custom styles do. What need to change to support deterministic styles for every class name?
Here is the code I have:
import {Component, ComponentMeta, ComponentProps, SizeObject} from '#xyz/abc' // real name removed here due to restrictions
import {Button, Paper} from '#material-ui/core'
import {createGenerateClassName, createStyles, MuiThemeProvider, Theme, withStyles} from '#material-ui/core/styles'
import JssProvider from 'react-jss/lib/JssProvider'
const theme = createMuiTheme({
palette: {
primary: {
main: 'blue',
},
secondary: {
main: 'green',
},
error: {
main: 'red',
},
},
typography: {
useNextVariants: true,
},
})
const styles = ({palette, spacing}: Theme) =>
createStyles({
button: {
backgroundColor: '#2196f3',
},
buttonDark: {
backgroundColor: '#880e4f',
},
buttonLight: {
backgroundColor: '#e1bee7',
},
})
const generateClassName = createGenerateClassName({
dangerouslyUseGlobalCSS: true,
})
class AnalysisSelector extends Component<ComponentProps, any> {
render() {
const {classes} = this.props
return (
<MuiThemeProvider theme={theme}>
<JssProvider generateClassName={generateClassName}>
<Paper {...this.props.emit()} className={'paperContainer'}>
<Button className={classes.button}>Primary Light</Button>
<Button className={classes.buttonLight}>Primary</Button>
<Button className={classes.buttonDark}>Primary Dark</Button>
</Paper>
</JssProvider>
</MuiThemeProvider>
)
}
}
export const MNOAnalysisSelector = withStyles(styles, {name: 'mnoButton'})(AnalysisSelector)
Finally here is the rendered HTML:
<button class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-flat mnoButton-button-1" tabindex="0" type="button">
<span class="MuiButton-label">Primary Light</span>
<span class="MuiTouchRipple-root"></span>
</button>
<button class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-flat mnoButton-buttonLight-3" tabindex="0" type="button">
<span class="MuiButton-label">Primary</span>
<span class="MuiTouchRipple-root"></span>
</button>
<button class="MuiButtonBase-root MuiButton-root MuiButton-text MuiButton-flat mnoButton-buttonDark-2" tabindex="0" type="button">
<span class="MuiButton-label">Primary Dark</span>
<span class="MuiTouchRipple-root"></span>
</button>
</div>
I am fine with the class names being mnoButton-button, mnoButton-buttonLight, and mnoButton-buttonDark, I just need the ending hash removed.
Thanks for any suggestions / assistance.
You can use global class names as documented in v4 here: https://next.material-ui.com/styles/advanced/#jss-plugin-global
jss-plugin-global is included in v3 as well, so the same approach will work with it.
The only way for the other syntax to create global names is if the name passed to withStyles starts with "Mui" (which I wouldn't recommend doing).
I've shown both approaches in the code below.
import React from "react";
import { withStyles } from "#material-ui/core/styles";
import Button from "#material-ui/core/Button";
const styles = theme => ({
"#global": {
".mnoButton-button": {
backgroundColor: "#2196f3"
},
".mnoButton-buttonDark": {
backgroundColor: "#880e4f"
},
".mnoButton-buttonLight": {
backgroundColor: "#e1bee7"
}
},
button: {
backgroundColor: "purple",
color: "white"
}
});
const MyButtons = ({ classes }) => {
return (
<>
<Button className="mnoButton-button">Hello World</Button>
<Button className="mnoButton-buttonDark">Hello World</Button>
<Button className="mnoButton-buttonLight">Hello World</Button>
<Button className={classes.button}>Hello World</Button>
</>
);
};
export default withStyles(styles, { name: "Mui-mnoButton" })(MyButtons);
Source: github
import { StylesProvider, createGenerateClassName } from '#material-ui/core/styles';
// other imports
const generateClassName = (rule, styleSheet) =>
`${styleSheet.options.classNamePrefix}-${rule.key}`;
test(deterministic classnames, () => {
render(
<StylesProvider generateClassName={generateClassName}>
<App />
</StylesProvider>
);
});