File tree Expand file tree Collapse file tree 3 files changed +37
-0
lines changed Expand file tree Collapse file tree 3 files changed +37
-0
lines changed Original file line number Diff line number Diff line change @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
17
17
- Ignore consecutive semicolons in the CSS parser ([ #18532 ] ( https://github.com/tailwindlabs/tailwindcss/pull/18532 ) )
18
18
- Center the dropdown icon added to an input with a paired datalist ([ #18511 ] ( https://github.com/tailwindlabs/tailwindcss/pull/18511 ) )
19
19
- Extract candidates in Slang templates ([ #18565 ] ( https://github.com/tailwindlabs/tailwindcss/pull/18565 ) )
20
+ - Improve error messages when encountering invalid functional utility names ([ #18568 ] ( https://github.com/tailwindlabs/tailwindcss/pull/18568 ) )
20
21
21
22
## [ 4.1.11] - 2025-06-26
22
23
Original file line number Diff line number Diff line change @@ -4354,6 +4354,30 @@ describe('@utility', () => {
4354
4354
`[Error: \`@utility 💨\` defines an invalid utility name. Utilities should be alphanumeric and start with a lowercase letter.]` ,
4355
4355
)
4356
4356
} )
4357
+
4358
+ test ( 'A functional @utility must end in -*' , ( ) => {
4359
+ return expect (
4360
+ compileCss ( css `
4361
+ @utility foo* {
4362
+ color : red;
4363
+ }
4364
+ ` ) ,
4365
+ ) . rejects . toThrowErrorMatchingInlineSnapshot (
4366
+ `[Error: \`@utility foo*\` defines an invalid utility name. A functional utility must end in \`-*\`.]` ,
4367
+ )
4368
+ } )
4369
+
4370
+ test ( 'Only the last part of a functional @utility can be dynamic' , ( ) => {
4371
+ return expect (
4372
+ compileCss ( css `
4373
+ @utility my-* - utility {
4374
+ color : red;
4375
+ }
4376
+ ` ) ,
4377
+ ) . rejects . toThrowErrorMatchingInlineSnapshot (
4378
+ `[Error: \`@utility my-*-utility\` defines an invalid utility name. The dynamic portion marked by \`-*\` must appear once at the end.]` ,
4379
+ )
4380
+ } )
4357
4381
} )
4358
4382
4359
4383
test ( 'addBase' , async ( ) => {
Original file line number Diff line number Diff line change @@ -229,6 +229,18 @@ async function parseCss(
229
229
230
230
let utility = createCssUtility ( node )
231
231
if ( utility === null ) {
232
+ if ( ! node . params . endsWith ( '-*' ) ) {
233
+ if ( node . params . endsWith ( '*' ) ) {
234
+ throw new Error (
235
+ `\`@utility ${ node . params } \` defines an invalid utility name. A functional utility must end in \`-*\`.` ,
236
+ )
237
+ } else if ( node . params . includes ( '*' ) ) {
238
+ throw new Error (
239
+ `\`@utility ${ node . params } \` defines an invalid utility name. The dynamic portion marked by \`-*\` must appear once at the end.` ,
240
+ )
241
+ }
242
+ }
243
+
232
244
throw new Error (
233
245
`\`@utility ${ node . params } \` defines an invalid utility name. Utilities should be alphanumeric and start with a lowercase letter.` ,
234
246
)
You can’t perform that action at this time.
0 commit comments