Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for parsing the ::part() selectors #48

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

cray0000
Copy link

Parse ::part() selectors when parsePartSelectors: true option is passed.

@coveralls
Copy link

Pull Request Test Coverage Report for Build 370

  • 1 of 1 (100.0%) changed or added relevant line in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.04%) to 98.925%

Totals Coverage Status
Change from base Build 237: 0.04%
Covered Lines: 102
Relevant Lines: 102

💛 - Coveralls

@kristerkari
Copy link
Owner

Sorry @cray0000 , I have totally not noticed this one.

What is the use case for the ::part() selectors? This parser is meant for React Native, not Web.

@cray0000
Copy link
Author

cray0000 commented Jul 20, 2021

hi @kristerkari , it's something which is supposed to be working together with the styleName functionality. I've made a framework with your css libraries playing a big role in it: https://github.com/startupjs/startupjs

Regarding the ::part() specifically:

I forked some of your stuff related to classnames/stylenames and extended it with the emulation of styling parts of components following the ::part() css standard but using the foobarStyle naming convention to represent the parts and automatically pass them into JSX elements.

So when you write the following in css file:

// index.styl
.card
  background: red
  padding: 8px
  &:part(title)
    color: blue
  &:part(footer)
    padding: green

this will get compiled into passing not just the style object into the JSX element with styleName='card', but it will actually transform JSX to pass multiple style properties through the splat:

<Card styleName='card' />

will get transformed to:

<Card {...styles.card} />

where styles.card would have:

{
  style: { ... },
  titleStyle: { ... },
  footerStyle: { ... }
}

it's actually not just a simple styles.card, but a result of a function call, where it also dynamically merges any existing properties in the right order.

And then from the JSX side I also added support for the part attribute, which does a following transform:

<View part='root'>
  <View part='title'>

will be transformed to (root is a magic name which gets transformed to just style):

<View style={style}>
  <View style={titleStyle}>

and again it's a bit more complex than that, supporting merging in styles from the styleName and reusing style attribute if it exists. And it will also automatically destructure style and titleStyle from the component props.

If you are interested in looking at the test cases and implementation, you can find it here:

https://github.com/startupjs/startupjs/tree/master/packages/babel-plugin-rn-stylename-to-style#part-selector

Tests for the JSX transformation are in __test__ and the tests for the dynamic CSS selectors matching (done in runtime, similar to how you match @media) are in test.

And regarding this PR -- I'm not actually sure if it makes sense to merge it, since ::part() is supposed to work together with that enhanced fork of handling the styleName from my startupjs monorepo (@startupjs/babel-plugin-rn-stylename-to-style).

Let me know what you think.

@kristerkari
Copy link
Owner

@cray0000 Thank you for the detailed explanation!

i’m not home at the moment, but I’m happy to add the change if you have libraries that are using the parser. It should be safe to add since it’s behind a flag.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants