mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
* 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>
73 lines
1.8 KiB
JavaScript
73 lines
1.8 KiB
JavaScript
import { splitAtTopLevelOnly } from './splitAtTopLevelOnly'
|
|
|
|
let KEYWORDS = new Set(['inset', 'inherit', 'initial', 'revert', 'unset'])
|
|
let SPACE = /\ +(?![^(]*\))/g // Similar to the one above, but with spaces instead.
|
|
let LENGTH = /^-?(\d+|\.\d+)(.*?)$/g
|
|
|
|
export function parseBoxShadowValue(input) {
|
|
let shadows = Array.from(splitAtTopLevelOnly(input, ','))
|
|
return shadows.map((shadow) => {
|
|
let value = shadow.trim()
|
|
let result = { raw: value }
|
|
let parts = value.split(SPACE)
|
|
let seen = new Set()
|
|
|
|
for (let part of parts) {
|
|
// Reset index, since the regex is stateful.
|
|
LENGTH.lastIndex = 0
|
|
|
|
// Keyword
|
|
if (!seen.has('KEYWORD') && KEYWORDS.has(part)) {
|
|
result.keyword = part
|
|
seen.add('KEYWORD')
|
|
}
|
|
|
|
// Length value
|
|
else if (LENGTH.test(part)) {
|
|
if (!seen.has('X')) {
|
|
result.x = part
|
|
seen.add('X')
|
|
} else if (!seen.has('Y')) {
|
|
result.y = part
|
|
seen.add('Y')
|
|
} else if (!seen.has('BLUR')) {
|
|
result.blur = part
|
|
seen.add('BLUR')
|
|
} else if (!seen.has('SPREAD')) {
|
|
result.spread = part
|
|
seen.add('SPREAD')
|
|
}
|
|
}
|
|
|
|
// Color or unknown
|
|
else {
|
|
if (!result.color) {
|
|
result.color = part
|
|
} else {
|
|
if (!result.unknown) result.unknown = []
|
|
result.unknown.push(part)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Check if valid
|
|
result.valid = result.x !== undefined && result.y !== undefined
|
|
|
|
return result
|
|
})
|
|
}
|
|
|
|
export function formatBoxShadowValue(shadows) {
|
|
return shadows
|
|
.map((shadow) => {
|
|
if (!shadow.valid) {
|
|
return shadow.raw
|
|
}
|
|
|
|
return [shadow.keyword, shadow.x, shadow.y, shadow.blur, shadow.spread, shadow.color]
|
|
.filter(Boolean)
|
|
.join(' ')
|
|
})
|
|
.join(', ')
|
|
}
|