question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Requirements for making tss-react compatible for Material-UI makeStyles replacement

See original GitHub issue

Following up on our discussion started in https://github.com/mui-org/material-ui/issues/26571 about how we can make tss-react compatible as a replacement for the makeStyles API for v5. I’ve done some initial testing. Here are some thoughts:

SSR

Have you tried to configure nextjs to work with tss-react? It uses @emotion/css so I believe some extra steps would be required. This would be the first requirement so that we could use it together with material-ui. Our docs (the Material-UI’s) can be a good candidate for testing this out.

API suggestions

Here are some suggestions regarding the API itself:

I wouldn’t return named options, if there is only one option returned. For example:

-const { createUseClassNames } = createUseClassNamesFactory({ useTheme }); // createUseClassNames is the only option
+const makeStyles = createUseClassNamesFactory({ useTheme });

-const { useClassNames } = createUseClassNames()(
+const useStyles = makeStyles()(
  (theme)=> ({
    root: {
      color: theme.palette.primary.main,
    },
  })
);

With this, we can actually make the API closer to the v4 makeStyles API. We could overcome this by adding adapters, but I will leave it to you.


Question: Is it really necessary to invoke function createUseClassNames() and then propagate the input to the next function call? What are the arguments required there? Can it be omitted?


I am open to help and move this forward 😃

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:8
  • Comments:11 (5 by maintainers)

github_iconTop GitHub Comments

7reactions
clytrascommented, Jul 18, 2021

Well, I am very passionate about this topic. Let me make my case and if you aren’t convinced I’ll make the API changes, even if I think it’s a mistake, because I’d like this colab to go through.

First, I believe it’s almost always better to return results of functions wrapped into an object, even if there is only one result. The reasoning behind that is that a large part of a developer’s job is to give meaningful and consistent names to things. By providing the results with a default name, we switch the responsibility of finding a suitable name from the API users to the API designer. This is huge for consistency and quality of life for developers. What happen in practice if we don’t do that is that users either refer to documentation examples every time or come up with uninspired names.

No, it’s not right to return always an object when we want to return a single value; IMO this is a bad practise. End users must have a direct freedom to name things as they want; we should not create things just having in mind beginners that will make up weird names, teams and experienced developers will always be consistent regarding the names they’re using. A library shouldn’t care what internal names a project shall use. Most users and especially beginners, will always read the documentation when they’ll start to learn how to develop (using MUI for example) so they’ll see what naming convention the framework is using.

An other awkward thing about this, is when we want to create multiple useClassNames or multiple useStyles, then we’re forced to do ugly destructuring renaming like:

const { useClassNames: useComp1ClassNames } = createUseClassNames(...)

const { useClassNames: useComp2ClassNames } = createUseClassNames(...)

const { useClassNames: useComp3ClassNames } = createUseClassNames(...)

instead of:

const useComp1ClassNames = createUseClassNames(...)

const useComp2ClassNames = createUseClassNames(...)

const useComp3ClassNames = createUseClassNames(...)

Libraries should not be opinionated regarding naming conventions and should not enforce any king of end naming.

7reactions
garronejcommented, Jul 11, 2021

Hi @mnajdova,

SSR

Have you tried to configure nextjs to work with tss-react? It uses @emotion/css so I believe some extra steps would be required. This would be the first requirement so that we could use it together with material-ui. Our docs (the Material-UI’s) can be a good candidate for testing this out.

I haven’t tested it yet. I can make time for that on the week-end.

Is this still true?

Question: Is it really necessary to invoke function createUseClassNames() and then propagate the input to the next function call? What are the arguments required there? Can it be omitted?

Yes, it unfortunately is necessary in order to get the type inference working.
The root of the problem is that TypeScript doesn’t support partial argument inference. In other word we can’t have a generic function with two type argument, specify one and let the other be inferred. Consider this example:

 createStyles<"root" | "label", { color: string; }>({
    "root": {
        "backgroundColor": "blue"
    },
    "label": ({ color })=>({
        color
    })
})

We shouldn’t have to explicitly provide "root" | "label" it should be inferable from the object passed in argument.
But because we have to specify { color: string; } we have to put "root" | "label" as well.
The only way to circumvent this limitation is to use the higher order function pattern as implemented in tss-react.

API suggestions

Here are some suggestions regarding the API itself:

I wouldn’t return named options, if there is only one option returned. For example:

-const { createUseClassNames } = createUseClassNamesFactory({ useTheme }); // createUseClassNames is the only option
+const makeStyles = createUseClassNamesFactory({ useTheme });

-const { useClassNames } = createUseClassNames()(
+const useStyles = makeStyles()(
  (theme)=> ({
    root: {
      color: theme.palette.primary.main,
    },
  })
);

With this, we can actually make the API closer to the v4 makeStyles API. We could overcome this by adding adapters, but I will leave it to you.

Well, I am very passionate about this topic. Let me make my case and if you aren’t convinced I’ll make the API changes, even if I think it’s a mistake, because I’d like this colab to go through.

First, I believe it’s almost always better to return results of functions wrapped into an object, even if there is only one result. The reasoning behind that is that a large part of a developer’s job is to give meaningful and consistent names to things. By providing the results with a default name, we switch the responsibility of finding a suitable name from the API users to the API designer.
This is huge for consistency and quality of life for developers.
What happen in practice if we don’t do that is that users either refer to documentation examples every time or come up with uninspired names.
On the other hand, this kind of flow is only possible with named returns:

Maybe it is more critical for me than for others because I am dyslexic but I know I am knot the only one for whom this pattern is life changing.

Beside I am convinced that we should ditch the old naming scheme: makeStyles -> useStyles -> classes it is arbitrary and inconsistent, createUseClassNames -> useClassNames -> classNames make much more sense although being a bit longer.
I understand the willingness to keep the naming familiar but users will have some refactoring to do if they want to switch from the V4 hook API to TSS. It’s now or never the time to ditch the legacy naming scheme.

Best regards

Read more comments on GitHub >

github_iconTop Results From Across the Web

Migrating to v5: getting started - Material UI - MUI
The minimum supported version of React has been increased from v16.8.0 to v17.0.0. If you are using a React version below 17.0.0, update...
Read more >
tss-react - npm
'tss-react' is intended to be the replacement for @material-ui v4 makeStyles and 'react-jss' . If you like TSS consider giving the project a ......
Read more >
Material UI 5 - the easiest way to migrate from makeStyles to ...
Material UI version 5 has cool new stuff, and also many breaking changes. The migration tool is also... Tagged with material, react, ...
Read more >
Material UI: useStyles (makeStyles) has lower priority after ...
I prefer to use tss-react rather than other ways when I use @mui-v5. I've followed a way that makes useStyle priority over @mui...
Read more >
makeStyles -> useStyles - TSS - Setup
It is like the option.name in material-ui v4's makeStyles . It's also required to for theme style overrides. const useStyles = makeStyles({ "name": ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found