Improve before and after variants (#5820)

* remove unused `withRule`

* ensure all ::before and ::after elements have content

* update --tw-content for the content plugin

* simplify `before` and `after` variants

* update tests, to reflect changes

* make new `format` and `wrap` API's private for now

* allow returning a format string from `addVariant` callback

* add `content: var(--tw-content)` for before/after variants

* update tests to add `content: var(--tw-content)`

* update changelog
This commit is contained in:
Robin Malfait 2021-10-18 18:11:34 +02:00 • committed by GitHub
parent f12c0e1fa5
commit 36c880abab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 69 additions and 63 deletions

View file

@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed
- Don't use pointer cursor on disabled buttons by default ([#5772](https://github.com/tailwindlabs/tailwindcss/pull/5772))
- Improve `addVariant` API ([#5809](https://github.com/tailwindlabs/tailwindcss/pull/5809))
- Set default content value in preflight instead of within each before/after utility ([#5820](https://github.com/tailwindlabs/tailwindcss/pull/5820))
### Added
@ -21,11 +21,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add all standard `cursor-*` values by default ([#5734](https://github.com/tailwindlabs/tailwindcss/pull/5734))
- Add `grow-*` and `shrink-*` utilities, deprecate `flex-grow-*` and `flex-shrink-*` ([#5733](https://github.com/tailwindlabs/tailwindcss/pull/5733))
- Add `text-decoration-color` utilities ([#5760](https://github.com/tailwindlabs/tailwindcss/pull/5760))
- Add declarative `addVariant` syntax ([#5809](https://github.com/tailwindlabs/tailwindcss/pull/5809))
### Fixed
- Configure chokidar's `awaitWriteFinish` setting to avoid occasional stale builds on Windows ([#5774](https://github.com/tailwindlabs/tailwindcss/pull/5774))
- Fix CLI `--content` option ([#5775](https://github.com/tailwindlabs/tailwindcss/pull/5775))
- Fix before/after utilities overriding custom content values at larger breakpoints ([#5820](https://github.com/tailwindlabs/tailwindcss/pull/5820))
## [3.0.0-alpha.1] - 2021-10-01

View file

@ -22,37 +22,34 @@ export let variantPlugins = {
addVariant('file', '&::file-selector-button')
// TODO: Use `addVariant('before', '*::before')` instead, once `content`
// fix is implemented.
addVariant('before', ({ format, withRule }) => {
format('&::before')
withRule((rule) => {
addVariant('before', ({ container }) => {
container.walkRules((rule) => {
let foundContent = false
rule.walkDecls('content', () => {
foundContent = true
})
if (!foundContent) {
rule.prepend(postcss.decl({ prop: 'content', value: '""' }))
rule.prepend(postcss.decl({ prop: 'content', value: 'var(--tw-content)' }))
}
})
return '&::before'
})
// TODO: Use `addVariant('after', '*::after')` instead, once `content`
// fix is implemented.
addVariant('after', ({ format, withRule }) => {
format('&::after')
withRule((rule) => {
addVariant('after', ({ container }) => {
container.walkRules((rule) => {
let foundContent = false
rule.walkDecls('content', () => {
foundContent = true
})
if (!foundContent) {
rule.prepend(postcss.decl({ prop: 'content', value: '""' }))
rule.prepend(postcss.decl({ prop: 'content', value: 'var(--tw-content)' }))
}
})
return '&::after'
})
},
@ -112,22 +109,22 @@ export let variantPlugins = {
},
directionVariants: ({ addVariant }) => {
addVariant('ltr', ({ format }) => {
addVariant('ltr', () => {
log.warn('rtl-experimental', [
'The RTL features in Tailwind CSS are currently in preview.',
'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
])
format('[dir="ltr"] &')
return '[dir="ltr"] &'
})
addVariant('rtl', ({ format }) => {
addVariant('rtl', () => {
log.warn('rtl-experimental', [
'The RTL features in Tailwind CSS are currently in preview.',
'Preview features are not covered by semver, and may be improved in breaking ways at any time.',
])
format('[dir="rtl"] &')
return '[dir="rtl"] &'
})
},
@ -2265,5 +2262,7 @@ export let corePlugins = {
{ filterDefault: true }
),
willChange: createUtilityPlugin('willChange', [['will-change', ['will-change']]]),
content: createUtilityPlugin('content'),
content: createUtilityPlugin('content', [
['content', ['--tw-content', ['content', 'var(--tw-content)']]],
]),
}

View file

@ -12,6 +12,11 @@
border-color: currentColor; /* 2 */
}
::before,
::after {
--tw-content: '';
}
/*
1. Use a consistent sensible line-height in all browsers.
2. Prevent adjustments of font size after orientation changes in iOS.

View file

@ -143,26 +143,30 @@ function applyVariant(variant, matches, context) {
}
let ruleWithVariant = variantFunction({
// Public API
get container() {
prepareBackup()
return clone
},
separator: context.tailwindConfig.separator,
modifySelectors,
// Private API for now
wrap(wrapper) {
let nodes = clone.nodes
clone.removeAll()
wrapper.append(nodes)
clone.append(wrapper)
},
withRule(modify) {
clone.walkRules(modify)
},
format(selectorFormat) {
collectedFormats.push(selectorFormat)
},
})
if (typeof ruleWithVariant === 'string') {
collectedFormats.push(ruleWithVariant)
}
if (ruleWithVariant === null) {
continue
}

View file

@ -217,7 +217,10 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
addVariant(variantName, variantFunctions, options = {}) {
variantFunctions = [].concat(variantFunctions).map((variantFunction) => {
if (typeof variantFunction !== 'string') {
return variantFunction
// Safelist public API functions
return ({ modifySelectors, container, separator }) => {
return variantFunction({ modifySelectors, container, separator })
}
}
variantFunction = variantFunction

View file

@ -1011,13 +1011,16 @@
will-change: var(--will-change);
}
.content-\[\'hello\'\] {
content: 'hello';
--tw-content: 'hello';
content: var(--tw-content);
}
.content-\[attr\(content-before\)\] {
content: attr(content-before);
--tw-content: attr(content-before);
content: var(--tw-content);
}
.content-\[\'\>\'\] {
content: '>';
--tw-content: '>';
content: var(--tw-content);
}
@media (min-width: 1024px) {
.lg\:grid-cols-\[200px\2c repeat\(auto-fill\2c minmax\(15\%\2c 100px\)\)\2c 300px\] {

View file

@ -176,15 +176,18 @@ it('should convert _ to spaces', () => {
}
.content-\\[_hello_world_\\] {
content: hello world;
--tw-content: hello world;
content: var(--tw-content);
}
.content-\\[___abc____\\] {
content: abc;
--tw-content: abc;
content: var(--tw-content);
}
.content-\\[\\'__hello__world__\\'\\] {
content: ' hello world ';
--tw-content: ' hello world ';
content: var(--tw-content);
}
`)
})
@ -199,7 +202,8 @@ it('should not convert escaped underscores with spaces', () => {
return run('@tailwind utilities', config).then((result) => {
return expect(result.css).toMatchFormattedCss(css`
.content-\[\'snake\\_case\'\] {
content: 'snake_case';
--tw-content: 'snake_case';
content: var(--tw-content);
}
`)
})

View file

@ -968,5 +968,6 @@
will-change: transform;
}
.content-none {
content: none;
--tw-content: none;
content: var(--tw-content);
}

View file

@ -22,7 +22,8 @@ test('arbitrary values with quotes', async () => {
return run('@tailwind utilities', config).then((result) => {
expect(result.css).toMatchFormattedCss(css`
.content-\[\'hello\]\'\] {
content: 'hello]';
--tw-content: 'hello]';
content: var(--tw-content);
}
`)
})

View file

@ -121,12 +121,12 @@ test('with pseudo-element variants', async () => {
}
/* --- */
.before\:scale-x-110::before {
content: '';
content: var(--tw-content);
--tw-scale-x: 1.1;
transform: var(--tw-transform);
}
.after\:rotate-3::after {
content: '';
content: var(--tw-content);
--tw-rotate: 3deg;
transform: var(--tw-transform);
}
@ -205,12 +205,12 @@ test('with multi-class pseudo-element variants', async () => {
}
/* --- */
.group:hover .group-hover\:before\:scale-x-110::before {
content: '';
content: var(--tw-content);
--tw-scale-x: 1.1;
transform: var(--tw-transform);
}
.peer:focus ~ .peer-focus\:after\:rotate-3::after {
content: '';
content: var(--tw-content);
--tw-rotate: 3deg;
transform: var(--tw-transform);
}
@ -253,12 +253,12 @@ test('with multi-class pseudo-element and pseudo-class variants', async () => {
}
/* --- */
.group:hover .group-hover\:hover\:before\:scale-x-110::before:hover {
content: '';
content: var(--tw-content);
--tw-scale-x: 1.1;
transform: var(--tw-transform);
}
.peer:focus ~ .peer-focus\:focus\:after\:rotate-3::after:focus {
content: '';
content: var(--tw-content);
--tw-rotate: 3deg;
transform: var(--tw-transform);
}
@ -288,7 +288,6 @@ test('with apply', async () => {
}
.baz::before {
content: '';
@apply rotate-45;
}
@ -351,13 +350,12 @@ test('with apply', async () => {
transform: var(--tw-transform);
}
.bar::before {
content: '';
content: var(--tw-content);
--tw-scale-x: 1.1;
--tw-scale-y: 1.1;
transform: var(--tw-transform);
}
.baz::before {
content: '';
--tw-rotate: 45deg;
transform: var(--tw-transform);
}
@ -408,22 +406,18 @@ test('legacy pseudo-element syntax is supported', async () => {
@tailwind utilities;
.a:before {
content: '';
@apply rotate-45;
}
.b:after {
content: '';
@apply rotate-3;
}
.c:first-line {
content: '';
@apply rotate-1;
}
.d:first-letter {
content: '';
@apply rotate-6;
}
`
@ -447,22 +441,18 @@ test('legacy pseudo-element syntax is supported', async () => {
}
/* --- */
.a:before {
content: '';
--tw-rotate: 45deg;
transform: var(--tw-transform);
}
.b:after {
content: '';
--tw-rotate: 3deg;
transform: var(--tw-transform);
}
.c:first-line {
content: '';
--tw-rotate: 1deg;
transform: var(--tw-transform);
}
.d:first-letter {
content: '';
--tw-rotate: 6deg;
transform: var(--tw-transform);
}

View file

@ -165,20 +165,20 @@
color: rgb(255 255 255 / var(--tw-text-opacity));
}
.before\:block::before {
content: '';
content: var(--tw-content);
display: block;
}
.before\:bg-red-500::before {
content: '';
content: var(--tw-content);
--tw-bg-opacity: 1;
background-color: rgb(239 68 68 / var(--tw-bg-opacity));
}
.after\:flex::after {
content: '';
content: var(--tw-content);
display: flex;
}
.after\:uppercase::after {
content: '';
content: var(--tw-content);
text-transform: uppercase;
}
.first\:shadow-md:first-child {

View file

@ -61,9 +61,7 @@ describe('custom advanced variants', () => {
],
plugins: [
function ({ addVariant }) {
addVariant('prose-headings', ({ format }) => {
return format(':where(&) :is(h1, h2, h3, h4)')
})
addVariant('prose-headings', ':where(&) :is(h1, h2, h3, h4)')
},
],
}
@ -89,9 +87,7 @@ describe('custom advanced variants', () => {
],
plugins: [
function ({ addVariant }) {
addVariant('prose-headings', ({ format }) => {
return format(':where(&) :is(h1, h2, h3, h4)')
})
addVariant('prose-headings', ':where(&) :is(h1, h2, h3, h4)')
},
],
}
@ -121,9 +117,7 @@ describe('custom advanced variants', () => {
],
plugins: [
function ({ addVariant }) {
addVariant('prose-headings', ({ format }) => {
return format(':where(&) :is(h1, h2, h3, h4)')
})
addVariant('prose-headings', ':where(&) :is(h1, h2, h3, h4)')
},
],
}