mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
ensure DEFAULT is taken into account for matchVariant (#9603)
This means that if you define your `matchVariant` as:
```js
matchVariant('foo', (value) => '.foo-${value} &')
```
Then you can't use `foo:underline`, if you want to be able to use
`foo:underline` then you have to define a `DEFAULT` value:
```js
matchVariant('foo', (value) => '.foo-${value} &', {
values: {
DEFAULT: 'bar'
}
})
```
Now `foo:underline` will generate `.foo-bar &` as a selector!
This commit is contained in:
parent
24fc365173
commit
ddb9b4d7bc
@ -145,7 +145,7 @@ function applyVariant(variant, matches, context) {
|
||||
}
|
||||
|
||||
/** @type {{modifier: string | null, value: string | null}} */
|
||||
let args = { modifier: null, value: null }
|
||||
let args = { modifier: null, value: sharedState.NONE }
|
||||
|
||||
// Retrieve "modifier"
|
||||
{
|
||||
|
||||
@ -577,6 +577,8 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
||||
let modifiersEnabled = flagEnabled(tailwindConfig, 'generalizedModifiers')
|
||||
|
||||
for (let [key, value] of Object.entries(options?.values ?? {})) {
|
||||
if (key === 'DEFAULT') continue
|
||||
|
||||
api.addVariant(
|
||||
isSpecial ? `${variant}${key}` : `${variant}-${key}`,
|
||||
({ args, container }) =>
|
||||
@ -594,13 +596,20 @@ function buildPluginApi(tailwindConfig, context, { variantList, variantMap, offs
|
||||
)
|
||||
}
|
||||
|
||||
let hasDefault = 'DEFAULT' in (options?.values ?? {})
|
||||
|
||||
api.addVariant(
|
||||
variant,
|
||||
({ args, container }) =>
|
||||
variantFn(
|
||||
args.value,
|
||||
({ args, container }) => {
|
||||
if (args.value === sharedState.NONE && !hasDefault) {
|
||||
return null
|
||||
}
|
||||
|
||||
return variantFn(
|
||||
args.value === sharedState.NONE ? options.values.DEFAULT : args.value,
|
||||
modifiersEnabled ? { modifier: args.modifier, container } : { container }
|
||||
),
|
||||
)
|
||||
},
|
||||
{
|
||||
...options,
|
||||
id,
|
||||
|
||||
@ -8,6 +8,8 @@ export const contextSourcesMap = new Map()
|
||||
export const sourceHashMap = new Map()
|
||||
export const NOT_ON_DEMAND = new String('*')
|
||||
|
||||
export const NONE = Symbol('__NONE__')
|
||||
|
||||
export function resolveDebug(debug) {
|
||||
if (debug === undefined) {
|
||||
return false
|
||||
|
||||
@ -656,3 +656,135 @@ it('should guarantee that we are not passing values from other variants to the w
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should default to the DEFAULT value for variants', () => {
|
||||
let config = {
|
||||
content: [
|
||||
{
|
||||
raw: html`
|
||||
<div>
|
||||
<div class="foo:underline"></div>
|
||||
</div>
|
||||
`,
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
plugins: [
|
||||
({ matchVariant }) => {
|
||||
matchVariant('foo', (value) => `.foo${value} &`, {
|
||||
values: {
|
||||
DEFAULT: '.bar',
|
||||
},
|
||||
})
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
.foo.bar .foo\:underline {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should not generate anything if the matchVariant does not have a DEFAULT value configured', () => {
|
||||
let config = {
|
||||
content: [
|
||||
{
|
||||
raw: html`
|
||||
<div>
|
||||
<div class="foo:underline"></div>
|
||||
</div>
|
||||
`,
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
plugins: [
|
||||
({ matchVariant }) => {
|
||||
matchVariant('foo', (value) => `.foo${value} &`)
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css``)
|
||||
})
|
||||
})
|
||||
|
||||
it('should be possible to use `null` as a DEFAULT value', () => {
|
||||
let config = {
|
||||
content: [
|
||||
{
|
||||
raw: html`
|
||||
<div>
|
||||
<div class="foo:underline"></div>
|
||||
</div>
|
||||
`,
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
plugins: [
|
||||
({ matchVariant }) => {
|
||||
matchVariant('foo', (value) => `.foo${value === null ? '-good' : '-bad'} &`, {
|
||||
values: { DEFAULT: null },
|
||||
})
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
.foo-good .foo\:underline {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
it('should be possible to use `undefined` as a DEFAULT value', () => {
|
||||
let config = {
|
||||
content: [
|
||||
{
|
||||
raw: html`
|
||||
<div>
|
||||
<div class="foo:underline"></div>
|
||||
</div>
|
||||
`,
|
||||
},
|
||||
],
|
||||
corePlugins: { preflight: false },
|
||||
plugins: [
|
||||
({ matchVariant }) => {
|
||||
matchVariant('foo', (value) => `.foo${value === undefined ? '-good' : '-bad'} &`, {
|
||||
values: { DEFAULT: undefined },
|
||||
})
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
let input = css`
|
||||
@tailwind utilities;
|
||||
`
|
||||
|
||||
return run(input, config).then((result) => {
|
||||
expect(result.css).toMatchFormattedCss(css`
|
||||
.foo-good .foo\:underline {
|
||||
text-decoration-line: underline;
|
||||
}
|
||||
`)
|
||||
})
|
||||
})
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user