Skip to content

Commit 81c883d

Browse files
committed
update error messages when using addComponents or matchComponents
Nothing new here, but this improves the error messages a bit when using `addComponents` or `matchComponents` because otherwise the error shows `addUtilities` or `matchUtilities`. These also add an additional note: > Note: in Tailwind CSS v4, `matchComponents` is an alias for `matchUtilities`.
1 parent e578238 commit 81c883d

File tree

2 files changed

+92
-4
lines changed

2 files changed

+92
-4
lines changed

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

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4444,6 +4444,43 @@ describe('addComponents()', () => {
44444444
}"
44454445
`)
44464446
})
4447+
4448+
test('throws on custom static utilities with an invalid name', async () => {
4449+
await expect(() => {
4450+
return compile(
4451+
css`
4452+
@plugin "my-plugin";
4453+
@layer utilities {
4454+
@tailwind utilities;
4455+
}
4456+
4457+
@theme reference {
4458+
--breakpoint-lg: 1024px;
4459+
}
4460+
`,
4461+
{
4462+
async loadModule(id, base) {
4463+
return {
4464+
path: '',
4465+
base,
4466+
module: ({ addComponents }: PluginAPI) => {
4467+
addComponents({
4468+
':hover > *': {
4469+
'text-box-trim': 'both',
4470+
'text-box-edge': 'cap alphabetic',
4471+
},
4472+
})
4473+
},
4474+
}
4475+
},
4476+
},
4477+
)
4478+
}).rejects.toThrowErrorMatchingInlineSnapshot(`
4479+
[Error: \`addComponents({ ':hover > *': … })\` defines an invalid utility selector. Components must be a single class name and start with a lowercase letter, eg. \`.scrollbar-none\`.
4480+
4481+
Note: in Tailwind CSS v4 \`addComponents\` is an alias for \`addUtilities\`.]
4482+
`)
4483+
})
44474484
})
44484485

44494486
describe('matchComponents()', () => {
@@ -4490,6 +4527,37 @@ describe('matchComponents()', () => {
44904527
}"
44914528
`)
44924529
})
4530+
4531+
test('throws on custom utilities with an invalid name', async () => {
4532+
await expect(() => {
4533+
return compile(
4534+
css`
4535+
@plugin "my-plugin";
4536+
@tailwind utilities;
4537+
`,
4538+
{
4539+
async loadModule(id, base) {
4540+
return {
4541+
path: '',
4542+
base,
4543+
module: ({ matchComponents }: PluginAPI) => {
4544+
matchComponents({
4545+
'.text-trim > *': () => ({
4546+
'text-box-trim': 'both',
4547+
'text-box-edge': 'cap alphabetic',
4548+
}),
4549+
})
4550+
},
4551+
}
4552+
},
4553+
},
4554+
)
4555+
}).rejects.toThrowErrorMatchingInlineSnapshot(`
4556+
[Error: \`matchComponents({ '.text-trim > *': … })\` defines an invalid utility name. Components should be alphanumeric and start with a lowercase letter, eg. \`scrollbar\`.
4557+
4558+
Note: in Tailwind CSS v4 \`matchComponents\` is an alias for \`matchUtilities\`.]
4559+
`)
4560+
})
44934561
})
44944562

44954563
describe('prefix()', () => {

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

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ export function buildPluginApi({
307307

308308
if (!foundValidUtility) {
309309
throw new Error(
310-
`\`addUtilities({ '${name}' : … })\` defines an invalid utility selector. Utilities must be a single class name and start with a lowercase letter, eg. \`.scrollbar-none\`.`,
310+
`\`addUtilities({ '${name}': … })\` defines an invalid utility selector. Utilities must be a single class name and start with a lowercase letter, eg. \`.scrollbar-none\`.`,
311311
)
312312
}
313313
}
@@ -347,7 +347,7 @@ export function buildPluginApi({
347347
for (let [name, fn] of Object.entries(utilities)) {
348348
if (!IS_VALID_UTILITY_NAME.test(name)) {
349349
throw new Error(
350-
`\`matchUtilities({ '${name}' : … })\` defines an invalid utility name. Utilities should be alphanumeric and start with a lowercase letter, eg. \`scrollbar\`.`,
350+
`\`matchUtilities({ '${name}': … })\` defines an invalid utility name. Utilities should be alphanumeric and start with a lowercase letter, eg. \`scrollbar\`.`,
351351
)
352352
}
353353

@@ -493,11 +493,31 @@ export function buildPluginApi({
493493
},
494494

495495
addComponents(components, options) {
496-
this.addUtilities(components, options)
496+
try {
497+
this.addUtilities(components, options)
498+
} catch (e) {
499+
if (e instanceof Error) {
500+
throw new Error(
501+
`${e.message.replaceAll('addUtilities', 'addComponents').replaceAll('Utilities', 'Components')}\n\nNote: in Tailwind CSS v4 \`addComponents\` is an alias for \`addUtilities\`.`,
502+
)
503+
} else {
504+
throw e
505+
}
506+
}
497507
},
498508

499509
matchComponents(components, options) {
500-
this.matchUtilities(components, options)
510+
try {
511+
this.matchUtilities(components, options)
512+
} catch (e) {
513+
if (e instanceof Error) {
514+
throw new Error(
515+
`${e.message.replaceAll('matchUtilities', 'matchComponents').replaceAll('Utilities', 'Components')}\n\nNote: in Tailwind CSS v4 \`matchComponents\` is an alias for \`matchUtilities\`.`,
516+
)
517+
} else {
518+
throw e
519+
}
520+
}
501521
},
502522

503523
theme: createThemeFn(

0 commit comments

Comments
 (0)