* Refactor
* Support variants with quotes in them
We have to have two regexes here because this is actually ambiguous in the general case. The regex that generally handles `[&[foo='bar']]` would incorrectly match `['bar':'baz']` for instance. So, instead we’ll use multiple regexes and match both!
* Update changelog
* add tests for spaced around operators in CSS math functions
* fix CSS math functons besides calc not getting the love they deserve
* improve comment
* update changelog
* update changelog
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
* Fix issue with returning postcss nodes in addVariant
It’s not a supported use case but it didn’t use to break so let’s just fail silently
* Update changelog
* allow to return an array of format strings from matchVariant or
addVariant
* add parallel variant with function test
* upgrade test to use a function call
* allow to return parallel variants from variant function
Caveat: this now belongs to the same plugin and is not registered as
separate variants which means that sort order can differ.
* prevent crash if `.toMatchFormattedCss()` receives undefined
* update changelog
* ensure that we use a local list of variant functions
Now that a variant function can return a list of variant functions from
within the plugin, we have to make sure to executed and register those
functions as well.
However, we need to make sure that this list is local for the variant
and not "globally" registered otherwise we keep add a dynamic function
to the global list which results in duplicate output becaus multiple
duplicate variants will be registered.
* add little warning regarding potential clashes
* Update CHANGELOG.md
* Fix typo
* Support alpha modifier for theme color values
* Eliminate redundant object creation in resolveFunctionKeys
Building an object of N keys incrementally using Object.reduce + splat results in N intermediate objects. We should just create one object and assign each key.
* Switch to inline theme values in theme fn in config
* Add test case
And fix typos that were definitely not there
* Update changelog
* WIP
* use correct separator
* run all tests
* Fix regex
* add a few more tests
* name the experimental feature flag `variantGrouping`
* update changelog
* rename test file `variant-grouping`
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* Add prefers-contrast variants
* add tests for prefers contrast
* dark mode should have precedence over prefers contrast variants
* update changelog
Co-authored-by: Luke Warlow <projects@warlow.dev>
* Only apply hover styles when supported (future)
Co-Authored-By: Andrew Brown <browner12@gmail.com>
* update changelog
Co-authored-by: Andrew Brown <browner12@gmail.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
* Fix matchVariants that use at-rules and placeholders
* update changelog
* Update CHANGELOG.md
* Only parseVariant when result is defined
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
* update regex extractor
* implement `matchVariant` API
* add `matchVariant` test
* add `values` option to the `matchVariant` API
* move `matchVariant` tests to own file
* update changelog
* WIP
Still need to write error message
* Update error message
first pass at something better
* Detect invalid variant formats returned by functions
* Add proper error message
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
* register arbitrary variants
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.
* add tests for arbitrary variants
This still requires some work to the `defaultExtractor` to make sure it
all works with existing code.
* update changelog
* Fix candidate detection for arbitrary variants
* Refactor
* Add support for at rules
* Add test for attribute selectors
* Fix test
* Add attribute selector support
* Split top-level comma parsing into a generalized splitting routine
We can now split on any character at the top level with any nesting. We don’t balance brackets directly here but this is probably “enough”
* Split variants by separator at the top-level only
This means that the separator has to be ouside of balanced brackets
* Fix extraction when using custom variant separators
* Support custom separators when top-level splitting variants
* Add a second multi-character separator test
* Split tests for at-rule and at-rule with selector changes
* Add nested at-rule tests
* Fix space-less at-rule parsing in addVariant
* Add test for using with `@apply`
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
* Add failing test cases
* Flatten finalizeSelector code
* Use AST operations to format selector classes
With this change we only parse the selector once and operate on the AST until we need to turn it back into a selector. In addition this lets us solve an issue where .replace(…) did the wrong thing because it doesn’t understand that .base and .base-foo are two different classes
* Remove extraneous, non-matching selectors from utilities
* Update changelog
* Only check selectors containing base apply candidates for circular dependencies
When given a two rule like `html.dark .a, .b { … }` and `html.dark .c { @apply b }` we would see `.dark` in both the base rule and the rule being applied and consider it a circular dependency. However, the selectors `html.dark .a` and `.b` are considered on their own and is therefore do not introduce a circular dependency.
This better matches the user’s mental model that the selectors are just two definitions sharing the same properties.
* Update changelog
* Handle duplicate atrules without children
We assumed that all At Rule nodes had children. Including ones that do not and should not — for example `@import url(…);`. Since this is not the case we’ll skip adding children for nodes that don’t have any.
* Update changelog
Co-authored-by: Jordi Marimon Palarea <jordimarimon7@gmail.com>