Skip to content

Commit 54c3f30

Browse files
Do not allow variants to start with - (#18867)
This PR fixes an issue where custom variants with just `-` in the name were allowed but weren't actually picked up by Oxide so you couldn't use them anyway. The reason we allow `-` is for `kebab-style-variants`, which is very common, but you shouldn't use `-`, `--` or more in a variant name. It doesn't really solve the issue (#18863), but it fixes the inconsistencies in that exist today. Inconsistencies: | &nbsp; | `-:flex` | `--:flex` | | --: | :--: | :--: | | Oxide | ❌ | ❌ | | Tailwind Play | ✅ | ❌ | | Intellisense | ✅ | ✅ | - Oxide already had the correct rules setup, so this is expected - Tailwind Play uses Tailwind's core compile step, but it considers candidates that start with `--` as a CSS variable instead of a utility. This means that the `--:flex` was considered a CSS variable and skipped during compilation. - Intellisense uses the same APIs than Tailwind's core, but it didn't have the CSS variable check which resulted in the `--:flex` being "correct". With this PR, the matrix looks like this now: | &nbsp; | `-:flex` | `--:flex` | | --: | :--: | :--: | | Oxide | ❌ | ❌ | | Tailwind Play | ❌ | ❌ | | Intellisense | ❌ | ❌ | This should not be considered a breaking change because Oxide didn't pick up candidates with variants that start with a `-`. CSS for these candidates was never generated before. Closes: #18863 --------- Co-authored-by: Jordan Pittman <[email protected]>
1 parent 494051c commit 54c3f30

File tree

5 files changed

+25
-4
lines changed

5 files changed

+25
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2222
- Hide internal fields from completions in `matchUtilities` ([#18820](https://github.com/tailwindlabs/tailwindcss/pull/18820))
2323
- Ignore `.vercel` folders by default (can be overridden by `@source …` rules) ([#18855](https://github.com/tailwindlabs/tailwindcss/pull/18855))
2424
- Consider variants starting with `@-` to be invalid (e.g. `@-2xl:flex`) ([#18869](https://github.com/tailwindlabs/tailwindcss/pull/18869))
25+
- Do not allow custom variants to start with a `-` ([#18867](https://github.com/tailwindlabs/tailwindcss/pull/18867))
2526
- Upgrade: Migrate `aria` theme keys to `@custom-variant` ([#18815](https://github.com/tailwindlabs/tailwindcss/pull/18815))
2627
- Upgrade: Migrate `data` theme keys to `@custom-variant` ([#18816](https://github.com/tailwindlabs/tailwindcss/pull/18816))
2728
- Upgrade: Migrate `supports` theme keys to `@custom-variant` ([#18817](https://github.com/tailwindlabs/tailwindcss/pull/18817))

packages/tailwindcss/src/compat/plugin-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export function buildPluginApi({
119119
addVariant(name, variant) {
120120
if (!IS_VALID_VARIANT_NAME.test(name)) {
121121
throw new Error(
122-
`\`addVariant('${name}')\` defines an invalid variant name. Variants should only contain alphanumeric, dashes or underscore characters.`,
122+
`\`addVariant('${name}')\` defines an invalid variant name. Variants should only contain alphanumeric, dashes, or underscore characters and start with a lowercase letter or number.`,
123123
)
124124
}
125125

packages/tailwindcss/src/index.test.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3768,7 +3768,27 @@ describe('@custom-variant', () => {
37683768
@custom-variant foo:bar (&:hover, &:focus);
37693769
`),
37703770
).rejects.toThrowErrorMatchingInlineSnapshot(
3771-
`[Error: \`@custom-variant foo:bar\` defines an invalid variant name. Variants should only contain alphanumeric, dashes or underscore characters.]`,
3771+
`[Error: \`@custom-variant foo:bar\` defines an invalid variant name. Variants should only contain alphanumeric, dashes, or underscore characters and start with a lowercase letter or number.]`,
3772+
)
3773+
})
3774+
3775+
test('@custom-variant cannot contain dashes on its own', () => {
3776+
return expect(
3777+
compileCss(css`
3778+
@custom-variant - (&.dash);
3779+
`),
3780+
).rejects.toThrowErrorMatchingInlineSnapshot(
3781+
`[Error: \`@custom-variant -\` defines an invalid variant name. Variants should only contain alphanumeric, dashes, or underscore characters and start with a lowercase letter or number.]`,
3782+
)
3783+
})
3784+
3785+
test('@custom-variant cannot contain multiple dashes on their own', () => {
3786+
return expect(
3787+
compileCss(css`
3788+
@custom-variant --- (&.dashed);
3789+
`),
3790+
).rejects.toThrowErrorMatchingInlineSnapshot(
3791+
`[Error: \`@custom-variant ---\` defines an invalid variant name. Variants should only contain alphanumeric, dashes, or underscore characters and start with a lowercase letter or number.]`,
37723792
)
37733793
})
37743794

packages/tailwindcss/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ async function parseCss(
356356

357357
if (!IS_VALID_VARIANT_NAME.test(name)) {
358358
throw new Error(
359-
`\`@custom-variant ${name}\` defines an invalid variant name. Variants should only contain alphanumeric, dashes or underscore characters.`,
359+
`\`@custom-variant ${name}\` defines an invalid variant name. Variants should only contain alphanumeric, dashes, or underscore characters and start with a lowercase letter or number.`,
360360
)
361361
}
362362

packages/tailwindcss/src/variants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { DefaultMap } from './utils/default-map'
1818
import { isPositiveInteger } from './utils/infer-data-type'
1919
import { segment } from './utils/segment'
2020

21-
export const IS_VALID_VARIANT_NAME = /^@?[a-zA-Z0-9_-]*$/
21+
export const IS_VALID_VARIANT_NAME = /^@?[a-z0-9][a-zA-Z0-9_-]*$/
2222

2323
type VariantFn<T extends Variant['kind']> = (
2424
rule: Rule,

0 commit comments

Comments
 (0)