tw-in-js / twind-jsx-preprocessor

MIT License
11 stars 1 forks source link

Support css property #6

Open sastan opened 3 years ago

sastan commented 3 years ago

The css property could be used to pass arbitrary CSS objects.

<span css={{ color: theme('colors', 'blue.500') }}>Blue</span>

Output

import { tw as _tw, directive as _directive } from 'twind'

const _identity = (value) => value

// Indirection is for caching
const _css = (object) => _directive(_identity, object)

<span className={_tw`${_css({ color: theme('colors', 'blue.500') })}`}>Blue</span>

References:

itsMapleLeaf commented 3 years ago

While I can see the cleanliness benefits, especially when used alongside a tw prop, I'm hesitant to add this. I don't know the cleanliness is worth the extra concepts and complexity.

For fairness, I'll compare a before and after of this feature with some examples.


With just a CSS prop:

// before
<span tw={css({ color: theme('colors', 'blue.500') })}>Blue</span>

// after
<span css={{ color: theme('colors', 'blue.500') }}>Blue</span>

I don't think there's a huge DX upgrade here 🤷‍♂️ not much more to say


With a CSS prop + tw prop:

// before
<span tw={`font-bold ${css({ color: theme('colors', 'blue.500') })}`}>Blue</span>

// after
<span tw="font-bold" css={{ color: theme('colors', 'blue.500') }}>Blue</span>

Shorter, and less noisy by a considerable amount. I also like the ergonomics. With the first example, I had to convert to a template string before adding an extra class/css, but the second one, I just needed to add a new prop.


The second example does have me thinking it may be worth, but I also don't really hate converting to template strings either. Keeping it all in one prop I feel simplifies the mental model a bit. I can see arguments both ways

sastan commented 3 years ago

That sounds all fair. Most (styled) CSS-in-JS support such a property. It is meant as a compat layer. But I acknowledge your points.

One other point for the css property is that you do not need to import twind/css and save ~1.2kb.

sastan commented 3 years ago

I'm raising this mostly to have the same API with @twind/preact. Whether we support it or not we should aim to align both JSX like libraries. Should have talked to you before releasing @twind/react.

itsMapleLeaf commented 3 years ago

I'm raising this mostly to have the same API with @twind/preact. Whether we support it or not we should aim to align both JSX like libraries. Should have talked to you before releasing @twind/react.

Totally agree, and no worries, we have a lot of room to move in pre-beta (even though the JSX preprocessors have major releases; I just don't like major 0 versions 🤷)

That sounds all fair. Most (styled) CSS-in-JS support such a property. It is meant as a compat layer. But I acknowledge your points.

One other point for the css property is that you do not need to import twind/css and save ~1.2kb.

🤔 Also good points, though the savings only apply if they don't use any additional twind/css utilities, like animation and keyframes. Seems unlikely?

As for a potential migration path, a codemod is an idea I've had floating around my head. I've often done some simple regex replaces to convert from className={tw()} to tw={}, and manually handled the few remaining cases. In a world where we don't have the css prop, that could be another route, if someone needed that.