πŸ”§
Setup
Start using TSS, with or without MUI
tss-react has over 232 000 monthly NPM download and fewer than 300 ⭐️ on GitHub.
If you use TSS in production, please consider giving the project a star.
With MUI
Standalone
yarn add tss-react @emotion/react @mui/material @emotion/styled
If you are migrating from @material-ui/core (v4) to @mui/material (v5) checkout the migration guide from MUI's documentation website here.
import { makeStyles, withStyles } from "tss-react/mui"; // "tss-react/mui-compat" if your project is using Typescript < 4.4
import Button from "@mui/material/Button";
​
type Props = {
className?: string;
};
​
export function MyButton(props: Props) {
const { className } = props;
​
const [isClicked, setIsClicked] = useState(false);
​
const { classes, cx } = useStyles({ "color": isClicked ? "blue": "red" });
​
//Thanks to cx, className will take priority over classes.root 🀩
//With TSS you must stop using clsx and use cx instead.
//More info here: https://github.com/mui/material-ui/pull/31802#issuecomment-1093478971
return (
<Button
className={cx(classes.root, className)}
onClick={()=> setIsClicked(true)}
>
hello world
</Button>
);
}
​
const useStyles = makeStyles<{ color: "red" | "blue" }>()(
(theme, { color }) => ({
"root": {
color,
"&:hover": {
"color": theme.palette.primary.main
}
}
})
);
Keep @emotion/styled as a dependency of your project.
Even if you never use it explicitly, it's a peer dependency of @mui/material.
yarn add tss-react @emotion/react
// src/theme.ts
​
import { createMakeStyles } from "tss-react"; //"tss-react/compat" if your project is using Typescript < 4.4
​
function useTheme() {
return {
"primaryColor": "#32CD32",
};
}
​
export const {
makeStyles,
withStyles,
useStyles
} = createMakeAndWithStyles({ useTheme });
​
// src/components/MyComponents.tsx
​
import { makeStyles } from "../theme";
​
export function MyComponent(props: Props) {
const { className } = props;
​
const [color, setColor] = useState<"red" | "blue">("red");
​
const { classes, cx } = useStyles({ color });
​
//Thanks to cx, className will take priority over classes.root 🀩
return <span className={cx(classes.root, className)}>hello world</span>;
}
​
const useStyles = makeStyles<{ color: "red" | "blue" }>()(
(theme, { color }) => ({
"root": {
color,
"&:hover": {
"backgroundColor": theme.primaryColor
}
}
})
);
If you don't want to end up writing things like:
import { makeStyles } from "../../../../../../theme";
You can put "baseUrl": "src" in your tsconfig.json and import things relative to your src/ directory.
In the above example it would be:
import { makeStyles } from "theme";
You can detect unused classes with this ESLint plugin.
Last modified 1mo ago
Copy link
Edit on GitHub