4.8.6 β€’ Published 11 months ago

tss-react-mara v4.8.6

Weekly downloads
-
License
MIT
Repository
github
Last release
11 months ago

πŸ†• tss-react supports Next.js 13 App Router πŸ₯³.

πŸ—³οΈ I've opened a pool about introducing a new API.

'tss-react' is intended to be the 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 😊

$ yarn add tss-react @emotion/react

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

In SSR everything should work with JavaScript disabled!

Changelog highlights

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

v4.3.0

v4.2.0

v4.1.0

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

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 mode

FAQ

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 createStyles to 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:

  • One major bug: see issue
  • JSS has poor performances compared to emotion source

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.