Introduce :user-valid & :user-invalid variants (#12370)
See - https://developer.mozilla.org/en-US/docs/Web/CSS/:user-valid - https://developer.mozilla.org/en-US/docs/Web/CSS/:user-invalid Just landed in Chrome, Firefox & Safari: - https://caniuse.com/mdn-css_selectors_user-valid - https://caniuse.com/mdn-css_selectors_user-invalid --------- Co-authored-by: Robin Malfait <malfait.robin@gmail.com> Co-authored-by: Philipp Spiess <hello@philippspiess.com>
This commit is contained in:
parent
c80c0b5128
commit
7326f64c41
6 changed files with 64 additions and 0 deletions
|
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
|
||||
- _Experimental_: Add `user-valid` and `user-invalid` variants ([#12370](https://github.com/tailwindlabs/tailwindcss/pull/12370))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Export `tailwindcss/lib/util/flattenColorPalette.js` for backward compatibility ([#16411](https://github.com/tailwindlabs/tailwindcss/pull/16411))
|
||||
|
|
|
|||
|
|
@ -11,5 +11,6 @@ export default defineConfig({
|
|||
},
|
||||
define: {
|
||||
'process.env.NODE_ENV': '"production"',
|
||||
'process.env.FEATURES_ENV': '"stable"',
|
||||
},
|
||||
})
|
||||
|
|
|
|||
|
|
@ -8405,6 +8405,8 @@ exports[`getVariants 1`] = `
|
|||
"required",
|
||||
"valid",
|
||||
"invalid",
|
||||
"user-valid",
|
||||
"user-invalid",
|
||||
"in-range",
|
||||
"out-of-range",
|
||||
"read-only",
|
||||
|
|
@ -8474,6 +8476,8 @@ exports[`getVariants 1`] = `
|
|||
"required",
|
||||
"valid",
|
||||
"invalid",
|
||||
"user-valid",
|
||||
"user-invalid",
|
||||
"in-range",
|
||||
"out-of-range",
|
||||
"read-only",
|
||||
|
|
@ -8527,6 +8531,8 @@ exports[`getVariants 1`] = `
|
|||
"required",
|
||||
"valid",
|
||||
"invalid",
|
||||
"user-valid",
|
||||
"user-invalid",
|
||||
"in-range",
|
||||
"out-of-range",
|
||||
"read-only",
|
||||
|
|
@ -8754,6 +8760,20 @@ exports[`getVariants 1`] = `
|
|||
"selectors": [Function],
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"hasDash": true,
|
||||
"isArbitrary": false,
|
||||
"name": "user-valid",
|
||||
"selectors": [Function],
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"hasDash": true,
|
||||
"isArbitrary": false,
|
||||
"name": "user-invalid",
|
||||
"selectors": [Function],
|
||||
"values": [],
|
||||
},
|
||||
{
|
||||
"hasDash": true,
|
||||
"isArbitrary": false,
|
||||
|
|
@ -8867,6 +8887,8 @@ exports[`getVariants 1`] = `
|
|||
"required",
|
||||
"valid",
|
||||
"invalid",
|
||||
"user-valid",
|
||||
"user-invalid",
|
||||
"in-range",
|
||||
"out-of-range",
|
||||
"read-only",
|
||||
|
|
@ -8920,6 +8942,8 @@ exports[`getVariants 1`] = `
|
|||
"required",
|
||||
"valid",
|
||||
"invalid",
|
||||
"user-valid",
|
||||
"user-invalid",
|
||||
"in-range",
|
||||
"out-of-range",
|
||||
"read-only",
|
||||
|
|
|
|||
|
|
@ -1 +1,3 @@
|
|||
export const enableRemoveUnusedThemeVariables = false
|
||||
|
||||
export const enableUserValid = process.env.FEATURES_ENV !== 'stable'
|
||||
|
|
|
|||
|
|
@ -325,6 +325,34 @@ test('invalid', async () => {
|
|||
expect(await run(['invalid/foo:flex'])).toEqual('')
|
||||
})
|
||||
|
||||
test('user-valid', async () => {
|
||||
expect(await run(['user-valid:flex', 'group-user-valid:flex', 'peer-user-valid:flex']))
|
||||
.toMatchInlineSnapshot(`
|
||||
".group-user-valid\\:flex:is(:where(.group):user-valid *), .peer-user-valid\\:flex:is(:where(.peer):user-valid ~ *) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.user-valid\\:flex:user-valid {
|
||||
display: flex;
|
||||
}"
|
||||
`)
|
||||
expect(await run(['user-valid/foo:flex'])).toEqual('')
|
||||
})
|
||||
|
||||
test('user-invalid', async () => {
|
||||
expect(await run(['user-invalid:flex', 'group-user-invalid:flex', 'peer-user-invalid:flex']))
|
||||
.toMatchInlineSnapshot(`
|
||||
".group-user-invalid\\:flex:is(:where(.group):user-invalid *), .peer-user-invalid\\:flex:is(:where(.peer):user-invalid ~ *) {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.user-invalid\\:flex:user-invalid {
|
||||
display: flex;
|
||||
}"
|
||||
`)
|
||||
expect(await run(['invalid/foo:flex'])).toEqual('')
|
||||
})
|
||||
|
||||
test('in-range', async () => {
|
||||
expect(await run(['in-range:flex', 'group-in-range:flex', 'peer-in-range:flex']))
|
||||
.toMatchInlineSnapshot(`
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {
|
|||
type StyleRule,
|
||||
} from './ast'
|
||||
import { type Variant } from './candidate'
|
||||
import { enableUserValid } from './feature-flags'
|
||||
import type { Theme } from './theme'
|
||||
import { compareBreakpoints } from './utils/compare-breakpoints'
|
||||
import { DefaultMap } from './utils/default-map'
|
||||
|
|
@ -692,6 +693,10 @@ export function createVariants(theme: Theme): Variants {
|
|||
staticVariant('required', ['&:required'])
|
||||
staticVariant('valid', ['&:valid'])
|
||||
staticVariant('invalid', ['&:invalid'])
|
||||
if (enableUserValid) {
|
||||
staticVariant('user-valid', ['&:user-valid'])
|
||||
staticVariant('user-invalid', ['&:user-invalid'])
|
||||
}
|
||||
staticVariant('in-range', ['&:in-range'])
|
||||
staticVariant('out-of-range', ['&:out-of-range'])
|
||||
staticVariant('read-only', ['&:read-only'])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue