Skip to content

Commit e566a92

Browse files
authored
--default(…) should emit values as-is (#20392)
This PR fixes an issue where the `--default(…)` function that can be used as part of `@utility` definitions goes through the same pre-processing treatment as `--value(…)` and `--modifier(…)`. Instead the `--default(…)` value should be emitted as-is. The pre-processing treatment that's in place today is just to normalize the value(s) that could be formatted in a strange way if you are dealing with older Prettier / Biome versions. Some of the transformations we do ahead of time: - `--value(--spacing)` -> `--value(--spacing-*)` - `--value(--spacing- *)` -> `--value(--spacing-*)` - `--value(--text- * --line-height)` -> `--value(--text-*--line-height)` - `--value(--text --line-height)` -> `--value(--text-*--line-height)` - `--value(--text-\\* --line-height)` -> `--value(--text-*--line-height)` - `--value([ *])` -> `--value([*])` One of these steps is getting rid of the spaces, that means that if your `--default(…)` uses spaces, then we will get rid of it. ```css @theme inline { --text-box-trim-start: trim-start; --text-box-trim-end: trim-end; --text-box-trim-both: trim-both; --text-box-edge-cap: cap alphabetic; --text-box-edge-cap-text: cap text; --text-box-edge-ex: ex alphabetic; --text-box-edge-ex-text: ex text; --text-box-edge-text: text alphabetic; --text-box-edge-text-text: text text; } @Utility trim-* { text-box: --value('normal', 'inherit', 'initial', 'revert', 'revert-layer', 'unset'); text-box: --value(--text-box-trim-*) --modifier(--text-box-edge-*, --default(box alphabetic)); } ``` When you try to use this: ```html <div className="trim-both" /> ``` Then we get the following CSS out: ```css .trim-both { text-box: trim-both boxalphabetic; } ``` This PR fixes that, and now the proper CSS will be emitted: ```css .trim-both { text-box: trim-both box alphabetic; } ``` Fixes: #20391 ## Test plan 1. Added an regression test to make sure that `--default(…)` values are emitted as-is.
1 parent b8a5f85 commit e566a92

3 files changed

Lines changed: 38 additions & 0 deletions

File tree

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
- Prevent `@tailwindcss/vite` from crashing on every edit under Vite's experimental `bundledDev` mode ([#20379](https://github.com/tailwindlabs/tailwindcss/pull/20379))
2323
- Ensure `@tailwindcss/oxide` falls back to WASM on platforms without native bindings ([#20383](https://github.com/tailwindlabs/tailwindcss/pull/20383))
2424
- Detect classes in Ruby percent literals using angle brackets or custom delimiters (e.g. `%w<flex>`, `%w|flex|`), including in Slim and Haml templates ([#20387](https://github.com/tailwindlabs/tailwindcss/pull/20387))
25+
- Preserve whitespace in `--default(…)` values in custom functional utilities (e.g. `--default(box alphabetic)` no longer becomes `boxalphabetic`) ([#20392](https://github.com/tailwindlabs/tailwindcss/pull/20392))
2526

2627
## [4.3.3] - 2026-07-16
2728

packages/tailwindcss/src/utilities.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31000,6 +31000,34 @@ describe('custom utilities', () => {
3100031000
expect(await run(['example-123/foo'], input)).toEqual('')
3100131001
})
3100231002

31003+
test('the value of `--default(…)` is emitted as-is', async () => {
31004+
let input = css`
31005+
@theme reference {
31006+
--text-box-trim-trim-both: trim-both;
31007+
--text-box-edge-cap: cap alphabetic;
31008+
}
31009+
31010+
@utility trim-* {
31011+
text-box: --value(--text-box-trim-*)
31012+
--modifier(--text-box-edge-*, --default(box alphabetic));
31013+
}
31014+
31015+
@tailwind utilities;
31016+
`
31017+
31018+
expect(await run(['trim-trim-both', 'trim-trim-both/cap'], input)).toMatchInlineSnapshot(`
31019+
"
31020+
.trim-trim-both {
31021+
text-box: var(--text-box-trim-trim-both, trim-both) box alphabetic;
31022+
}
31023+
31024+
.trim-trim-both\\/cap {
31025+
text-box: var(--text-box-trim-trim-both, trim-both) var(--text-box-edge-cap, cap alphabetic);
31026+
}
31027+
"
31028+
`)
31029+
})
31030+
3100331031
test('modifiers', async () => {
3100431032
let input = css`
3100531033
@theme reference {

packages/tailwindcss/src/utilities.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6193,6 +6193,15 @@ export function createCssUtility(node: AtRule) {
61936193

61946194
let args = segment(ValueParser.toCss(fn.nodes), ',')
61956195
for (let [idx, arg] of args.entries()) {
6196+
arg = arg.trim()
6197+
6198+
// The value of `--default(…)` is emitted as-is, so it should not be
6199+
// normalized.
6200+
if (arg.startsWith('--default(')) {
6201+
args[idx] = arg
6202+
continue
6203+
}
6204+
61966205
// Transform escaped `\\*` -> `*`
61976206
arg = arg.replace(/\\\*/g, '*')
61986207

0 commit comments

Comments
 (0)