Skip to content

Arbitrary variants - #8299

Merged
adamwathan merged 18 commits into
masterfrom
arbitrary-variants
May 8, 2022
Merged

adamwathan merged 18 commits into
masterfrom
arbitrary-variants

Conversation

@RobinMalfait

Copy link
Copy Markdown
Contributor

With the new addVariant API, we have a beautiful way of creating new variants.

You can use it as:

addVariant('children', '& > *')

Now you can use the children: variant. The API uses a & as a reference for the candidate, which means that:

children:pl-4

Will result in:

.children\:pl-4 > * { .. }

Notice that the & was replaced by .children\:pl-4.

We can leverage this API to implement arbitrary variants, this means that you can write those &>* (Notice that we don't have spaces) inside a variant directly. An example of this can be:

<ul class="[&>*]:underline">
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>

Which generates the following css:

.\[\&\>\*\]\:underline > * {
  text-decoration-line: underline;
}

Now all the children of the ul will have an underline. The selector itself is a bit crazy since it contains the candidate which is the selector itself, it is just escaped.

Comment thread src/lib/defaultExtractor.js Outdated
yield regex.pattern([
// Variants
/((?=([^\s"'\\\[]+:))\2)?/,
/((?=([^\s"'\\]+:))\2)?/,

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will require some work to make it exactly right

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lol yep I was thinking about this. I'll throw this change against my new candidate refactor to see what breaks…

I had already tested support for arbitrary variant syntax (at least detection wise) in the form of [foo]:bar

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ngl I love this idea so much

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pushed a regex tweak to fix the tests 👍👍

With the new `addVariant` API, we have a beautiful way of creating new
variants.

You can use it as:
```js
addVariant('children', '& > *')
```

Now you can use the `children:` variant. The API uses a `&` as a
reference for the candidate, which means that:
```html
children:pl-4
```

Will result in:
```css
.children\:pl-4 > * { .. }
```

Notice that the `&` was replaced by `.children\:pl-4`.

We can leverage this API to implement arbitrary variants, this means
that you can write those `&>*` (Notice that we don't have spaces) inside
a variant directly. An example of this can be:
```html
<ul class="[&>*]:underline">
  <li>A</li>
  <li>B</li>
  <li>C</li>
</ul>
```
Which generates the following css:
```css
.\[\&\>\*\]\:underline > * {
  text-decoration-line: underline;
}
```

Now all the children of the `ul` will have an `underline`. The selector
itself is a bit crazy since it contains the candidate which is the
selector itself, it is just escaped.
This still requires some work to the `defaultExtractor` to make sure it
all works with existing code.
@RobinMalfait
RobinMalfait force-pushed the arbitrary-variants branch from 339939a to 7d49e55 Compare May 7, 2022 23:05
@simonswiss

Copy link
Copy Markdown
Contributor

This is rad! 🤙

@onmax

onmax commented May 8, 2022

Copy link
Copy Markdown

Wow, just requested this feature about one month ago and now is coming here. Timing couldn't be better. I have a few ideas in my head to create some plugins with this.

#8157

Keep up the hard work 🔥 🔥. Amazing!

@adamwathan

Copy link
Copy Markdown
Contributor

Added a failing test for attribute selectors like:

class="[&:[data-open]]:underline"

I think this one is going to be kind of tricky — we need to reliable extract that candidate from the template but to do that we need to worry about bracket balancing. We'll need to support multiple pairs too so the implementation probably can't be as naive as I'd wish:

class="[&:[data-foo][data-bar]:has([data-baz])]:underline"

@adamwathan adamwathan changed the title WIP: Arbitrary variants Arbitrary variants May 8, 2022
@adamwathan
adamwathan marked this pull request as ready for review May 8, 2022 16:24
@adamwathan
adamwathan merged commit be51739 into master May 8, 2022
@adamwathan
adamwathan deleted the arbitrary-variants branch May 8, 2022 16:24
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.