Package Exports
- tss-react
- tss-react/compat
- tss-react/cssAndCx
- tss-react/dsfr
- tss-react/mui
- tss-react/mui-compat
- tss-react/next
- tss-react/next/appDir
- tss-react/next/pagesDir
- tss-react/nextJs
Readme
✨ Dynamic CSS-in-TS styles engine, based on Emotion ✨
Home - Documentation - Playground
- ✅ Seamless integration with MUI.
- ✅ Works in Next.js App and Page Router.
- ✅ Dynamic Style Generation: With TSS, you can instantly generate styles based on the properties and internal states of components. Although this currently limits RSC support, the capabilities it offers are remarkable. In comparison, "no runtime" solutions such as PandaCSS or Vanilla Extract may not meet the same flexibility. For an illustration of tasks simplified by TSS but complicated with "no runtime" solutions, refer to this example.
- ✅
withStylesAPI support. - ✅ Offers a type-safe equivalent of the JSS
$syntax. - ✅ Custom
@emotioncache support. - ✅ Build on top of
@emotion/react, it has very little impact on the bundle size alongside mui (~5kB minziped). - ✅ Maintained for the foreseeable future, issues are dealt with within good delays.
- ✅ As fast as
emotion(see the difference with mui'smakeStyles) - ✅ Library authors:
tss-reactwon’t be yet another entry in yourpeerDependencies.
'tss-react' can be used as a replacement for
@material-ui v4 makeStyles and 'react-jss'.
The more ⭐️ the project gets, the more time I spend improving and maintaining it. Thank you for your support 😊
While this module is written in TypeScript, using TypeScript in your application is optional (but recommended as it comes with outstanding benefits to both you and your codebase).
https://user-images.githubusercontent.com/6702424/166390575-0530e16b-4aff-4914-a8fa-20b02da829cc.mov
Changelog highlights
Click to expand
v4.7.0
- Reduce bundle size when using Next.js Pages dir setup, fixes #147 The _app bundle sent to the client is down from ~160Kb to ~11Kb
v4.5.0
- Provide support for Next 13 appDir.
v4.3.0
- Provide an alternative setup for peoples experiencing styles inconsistencies after upgrading to MUI v5 using TSS.
- Better Next.js integration API.
v4.2.0
- Re introduce
<TssCacheProvider />
v4.1.0
- Publish an ESM distribution. Many thanks to @jiby-aurum for he's help. This fixes many bug when working in Vite.
v4.0.0
- No need to provide an emotion cache explicitly, MUI and TSS can share the same emotion cache.
No special instruction to make TSS work with SSR.
v3.7.1
- Retrocompatibility with React 16. Ref
v3.3.1
- I.E is almost supported out of the box (See note at the end of this sections)
Breaking changes in v3
- New API for nested selectors. We no longer use
createRef(). labelhave been renamednamefor helping the migration from the old mui API.
Development
Running the demo apps:
git clone https://github.com/garronej/tss-react
cd tss-react
yarn
yarn build
npx tsc -w & npx tsc --module es2015 --outDir dist/esm -w
# Open another Terminal
yarn start_spa # For testing in in a Create React App setup
yarn start_ssr # For testing in a Next.js setup
yarn start_appdir # Next.js 13 setup in App directory modeFAQ
Click to expand
Why this instead of the hook API of Material UI v4?
First of all because makeStyle is deprecated in @material-ui v5 but also
because it has some major flaws. Let's consider this example:
import { makeStyles, createStyles } from "@material-ui/core/styles";
type Props = {
color: "red" | "blue";
};
const useStyles = makeStyles(theme =>
createStyles<"root" | "label", { color: "red" | "blue" }>({
"root": {
"backgroundColor": theme.palette.primary.main
},
"label": ({ color }) => ({
color
})
})
);
function MyComponent(props: Props) {
const classes = useStyles(props);
return (
<div className={classes.root}>
<span className={classes.label}>Hello World</span>
</div>
);
}Two pain points:
- Because TypeScript doesn't support partial argument inference,
we have to explicitly enumerate the classes name as an union type
"root" | "label". - We shouldn't have to import
createStylesto get correct typings.
Let's now compare with tss-react
import { makeStyles } from "./makeStyles";
type Props = {
color: "red" | "blue";
};
const { useStyles } = makeStyles<{ color: "red" | "blue" }>()(
(theme, { color }) => ({
"root": {
"backgroundColor": theme.palette.primary.main
},
"label": { color }
})
);
function MyComponent(props: Props) {
const { classes } = useStyles(props);
return (
<div className={classes.root}>
<span className={classes.label}>Hello World</span>
</div>
);
}Benefits:
- Less verbose, same type safety.
- You don't need to remember how things are supposed to be named, just let intellisense guide you.
Besides, the hook api of material-ui, have other problems:
Why this instead of Styled component ?
See this issue
Compile error TS1023
If you get this error:
node_modules/tss-react/index.d.ts:18:10 - error TS1023: An index signature parameter type must be either 'string' or 'number'.
18 [mediaQuery: `@media${string}`]: { [RuleName_1 in keyof ClassNameByRuleName]?: import("./types").CSSObject | undefined; };
~~~~~~~~~~it means that you need to update TypeScript to a version >= 4.4.
If you can't use import { } from "tss-react/compat"; instead of import { } from "tss-react".
Only withStyles() will have slightly inferior type inference.