cssinjs / jss

JSS is an authoring tool for CSS which uses JavaScript as a host language.
https://cssinjs.org
MIT License
7.06k stars 397 forks source link

Using the hooks API in a Component Library - support passing classes to the useStyles hook and merging the classes #1276

Open FinestV opened 4 years ago

FinestV commented 4 years ago

The problem We currently use react-jss as our styling system in our in house component lIbrary which packages and publishes components on a private feed similar to npm. We have other applications that consume the component library, some that also use react-jss and some that use css modules.

react-jss has worked well as the withStyles HOC allows the apps to pass additional classes to each component and withStyles will merge these classes in. This means both set of CSS rules will be sent to the browser and applied in cascading order.

The new hooks API however has dropped support for classes and is not backwards compatible.

A possible alternative using JS object merging has been discussed here https://github.com/cssinjs/jss/issues/1221. Notice in this solution the CSS rule set it replaced completely but usually the consumer only wants to override one or two CSS properties. The current system of classes and withStyles is more powerful and allows for finer grained control over which properties are to be overridden.

The potential solution The useStyles hook would treat classes as a "magic" parameter similar to withStyles. If provided useStyles would merge these classes with the new classes it creates internally.

Implementation If this sounds like something we want to keep in scope for react-jss I will have a go at implementation. If not we will write our own createUseStyles wrapper which is specific to our solution that uses the "classes" convention.

HenriBeck commented 4 years ago

@FinestV Why not do the merging yourselves? You can write a small function similar to https://github.com/cssinjs/jss/blob/master/packages/react-jss/src/utils/mergeClasses.js and then just merge them in the function component

kof commented 4 years ago

@HenriBeck making it a task for the user is an option, but I wonder if this should be part of react-jss, since it's something that many people will need. I have an additional idea to make it support sort of tiny state machine. Something I played with, by no means a final version gist. It could be a separate package though.

HenriBeck commented 4 years ago

I mean we can provide the helpers or even an overrideClasses option (naming TBD) for the useStyles function as well

kof commented 4 years ago

If built-in into useStyles, it could be something like this: const classes = useStyles(props) and props already contains props.classes, so classes is automatically merged. I wonder though if this is going to be a breaking change already. I mean technically it is, but maybe in reality it isn't.

LAKnoKAL commented 3 years ago

Gonna bump it up unless anyone can pass codesandbox link with example :) I'm running with the same issue as @FinestV does. We have design-system (which is our own internal library) and main application. I need to override specific styles of component and expecting them to be overridden through the order of generated classes. Turns out createUseStyles() invocation from the library is the latest one in the three - https://cssinjs.org/react-jss?v=v10.3.0#injection-order

As a temporary solution, I pass a style object as a prop and use it inside lib's createUseStyles -

label: props => ({
    position: 'relative',
    cursor: 'pointer',
    fontSize: '1em',
    fontWeight: 400,
    padding: '0 0.25em 0',

    ...props.labelStyles
  })