Skip to content

Commit a6ee83e

Browse files
Plugin API: Allow custom utilities to start with @
1 parent 10a8f1a commit a6ee83e

File tree

3 files changed

+69
-1
lines changed

3 files changed

+69
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
- Nothing yet!
1111

12+
### Fixed
13+
14+
- Ensure support for JS plugins that contribute utilities starting with `@` ([#14793](https://github.com/tailwindlabs/tailwindcss/pull/14793))
15+
1216
## [4.0.0-alpha.30] - 2024-10-24
1317

1418
### Added

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

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2973,6 +2973,70 @@ describe('matchUtilities()', () => {
29732973
).toEqual('')
29742974
})
29752975

2976+
test('custom functional utilities can start with @', async () => {
2977+
async function run(candidates: string[]) {
2978+
let compiled = await compile(
2979+
css`
2980+
@plugin "my-plugin";
2981+
@tailwind utilities;
2982+
`,
2983+
2984+
{
2985+
async loadModule(id, base) {
2986+
return {
2987+
base,
2988+
module: ({ matchUtilities }: PluginAPI) => {
2989+
matchUtilities(
2990+
{ '@container': (value) => ({ container: value }) },
2991+
{
2992+
values: {
2993+
DEFAULT: 'inline-size',
2994+
normal: 'normal',
2995+
},
2996+
},
2997+
)
2998+
},
2999+
}
3000+
},
3001+
},
3002+
)
3003+
3004+
return compiled.build(candidates)
3005+
}
3006+
3007+
// Classes are emitted twice because we have a core utility already adding `@container`
3008+
expect(optimizeCss(await run(['@container', '@container-normal', 'hover:@container'])).trim())
3009+
.toMatchInlineSnapshot(`
3010+
".\\@container {
3011+
container-type: inline-size;
3012+
}
3013+
3014+
.\\@container-normal {
3015+
container-type: normal;
3016+
}
3017+
3018+
.\\@container {
3019+
container: inline-size;
3020+
}
3021+
3022+
.\\@container-normal {
3023+
container: normal;
3024+
}
3025+
3026+
@media (hover: hover) {
3027+
.hover\\:\\@container:hover {
3028+
container-type: inline-size;
3029+
}
3030+
}
3031+
3032+
@media (hover: hover) {
3033+
.hover\\:\\@container:hover {
3034+
container: inline-size;
3035+
}
3036+
}"
3037+
`)
3038+
})
3039+
29763040
test('custom functional utilities can return an array of rules', async () => {
29773041
let compiled = await compile(
29783042
css`

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ export type PluginAPI = {
7575
prefix(className: string): string
7676
}
7777

78-
const IS_VALID_UTILITY_NAME = /^[a-z][a-zA-Z0-9/%._-]*$/
78+
const IS_VALID_UTILITY_NAME = /^[a-z@][a-zA-Z0-9/%._-]*$/
7979

8080
export function buildPluginApi(
8181
designSystem: DesignSystem,

0 commit comments

Comments
 (0)