withStyles

MyComponent.tsx
import { withStyles } from "tss-react/mui";
type Props = {
className?: string;cod
classes?: Partial<Record<"root" | "label", string>>;
colorSmall: string;
};
function MyComponent(props: Props) {
const classes = withStyles.getClasses(props);
return (
{/* props.classeName and props.classes.root are merged, props.className get higher specificity */}
<div className={classes.root}>
<span className={classes.text}>The background color should be different when the screen is small.</span>
</div>
);
}
const MyComponentStyled = withStyles(
MyComponent,
(theme, props) => ({
root: {
backgroundColor: theme.palette.primary.main,
height: 100
},
text: {
border: "1px solid red"
},
"@media (max-width: 960px)": {
root: {
backgroundColor: props.colorSmall
}
}
})
);
export default MyComponentStyled;
import MyComponent from "./MyComponent";
render(
<MyComponent
className="foo bar"
classes={{ text: "baz baz" }}
colorSmall="cyan"
/>
);
The main reason you would use
withStyles
over makeStyles
is to support class based components.MyComponent.tsx
import * as React from "react";
import { withStyles } from "tss-react/mui";
export type Props ={
className?: string;
classes?: Partial<Record<"root" | "span", string>>;
isBig: boolean;
};
class MyComponent extends React.Component<Props> {
render() {
const classes = withStyles.getClasses(this.props);
return (
{/* props.classeName and props.classes.root are merged, props.className get higher specificity */}
<div className={classes.root}>
<span className={classes.span}>The background color should be different when the screen is small.</span>
</div>
);
}
}
const MyComponentStyled = withStyles(
MyComponent,
(theme, props) => ({
root: {
backgroundColor: theme.palette.primary.main,
height: props.isBig ? 100 : 50
},
span: {
border: "1px solid red"
},
"@media (max-width: 960px)": {
root: {
backgroundColor: "red"
}
}
})
);
export default MyComponentStyled;
import MyComponent from "./MyComponent";
render(
<MyComponent
className="foo bar"
classes={{ text: "baz baz" }}
colorSmall="cyan"
/>
);
Your component can also only have a
className
prop (and no classes
).MyComponent.tsx
import * as React from "react";
import { withStyles } from "tss-react/mui";
export type Props ={
className?: string;
isBig: boolean;
};
class MyComponent extends React.Component<Props> {
render() {
const classes = withStyles.getClasses(this.props);
return (
<div className={classes.root}>
The background color should be different when the screen is small.
</div>
);
}
}
const MyComponentStyled = withStyles(
MyComponent,
(theme, props) => ({
"root": {
"backgroundColor": theme.palette.primary.main,
"height": props.isBig ? 100 : 50
},
"@media (max-width: 960px)": {
"root": {
"backgroundColor": "red"
}
}
})
);
export default MyComponentStyled;
import MyComponent from "./MyComponent";
render(
<MyComponent
className="foo bar"
colorSmall="cyan"
/>
);
You can also pass a mui component like for example
<Button />
and you'll be able to overwrite every rule name of the component (it uses the classes
prop).import Button from "@mui/material/Button";
import { withStyles } from "tss-react/mui";
const MyStyledButton = withStyles(Button, {
root: {
backgroundColor: "grey"
}
text: {
color: "red"
},
"@media (max-width: 960px)": {
text: {
color: "blue"
}
}
});
What's very powerfull about the withStyles API it it's capable to infer the type of the nested overwritable classes, example:

import Breadcrumbs from "@mui/material/Breadcrumbs";
import { withStyles } from "tss-react/mui";
const MyBreadcrumbs = withStyles(
Breadcrumbs,
(theme, props, classes) => {
ol: {
[`& .${classes.separator}`]: {
color: theme.palette.primary.main
}
}
}
);
import { withStyles } from "tss-react/mui";
const MyAnchorStyled = withStyles("a", (theme, { href }) => ({
root: {
border: "1px solid black",
backgroundColor: href?.startsWith("https")
? theme.palette.primary.main
: "red"
}
}));
You can experiment with those examples here live here, you can also run it locally with
yarn start_spa
.To ease debugging you can specify a name that will appear in every class names. It is like the
option.name
in material-ui v4's makeStyles
.import { withStyles } from "tss-react/mui";
const MyDiv = withStyles("div", {
root: {
/* ... */
}
}, { name: "MyDiv" });
//The class apllied to the div will be like: "css-xxxxxx-MyDiv-root"
If you want to use
withStyles
instead of styled
for the extra type safety it provides:Before:
import { styled } from '@mui/material/styles';
import Popper from '@mui/material/Popper';
const StyledPopper = styled(Popper)({
border: '1px solid red',
'& .Mui-autoComplete-listBox': {
boxSizing: 'border-box',
'& ul': {
padding: 0,
margin: 0
}
},
"@media (max-width: 960px)": {
color: "blue"
}
});
After (just wrap everything into
root
):import { withStyles } from 'tss-react/mui';
import Popper from '@mui/material/Popper';
const StyledPopper = withStyles(Popper, {
root: {
border: '1px solid red',
'& .Mui-autoComplete-listBox': {
boxSizing: 'border-box',
'& ul': {
padding: 0,
margin: 0
}
},
"@media (max-width: 960px)": {
color: "blue"
}
}
});
Last modified 4mo ago