Skip to content

fix(preset-wind4): keep the [color:...] type hint intact when parsing colors - #5299

Merged
zyyv merged 1 commit into
unocss:mainfrom
giaBaoJS:fix/wind4-color-type-hint
Sep 5, 2026
Merged

zyyv merged 1 commit into
unocss:mainfrom
giaBaoJS:fix/wind4-color-type-hint

Conversation

@giaBaoJS

@giaBaoJS giaBaoJS commented Sep 1, 2026 •

Copy link
Copy Markdown
Contributor

Description

In preset-wind4, an arbitrary value carrying a color: data-type hint produces no CSS at all for most color utilities:

text-[color:red]          -> (nothing)
text-[color:var(--color)] -> (nothing)
bg-[color:#000]           -> (nothing)
ring-[color:red]          -> (nothing)
outline-[color:red]       -> (nothing)
decoration-[color:red]    -> (nothing)
fill-[color:red]          -> (nothing)

border-[color:*] works, because #5206 made the border rules strip the hint with h.bracketOfColor before reaching parseColor. Every other color utility goes straight to parseColor and silently yields nothing.

Cause

parseColor splits the body on / and : with getStringComponents:

https://github.com/unocss/unocss/blob/main/packages-presets/preset-wind4/src/utils/utilities.ts#L103

getStringComponents defaults its grouping characters to ( and ), so square brackets do not protect their content. For [color:red] the colon is seen at depth 0 and the body is split into ["[color", "red]"]. front is then [color, which cannot match bracketTypeRe, so the type-hint branch immediately below it is unreachable for every bracketed value, and the utility resolves to a color named [color with an opacity of red].

preset-mini does the same split through splitShorthand, which passes '[' / ']' explicitly and is unaffected:

https://github.com/unocss/unocss/blob/main/packages-presets/preset-mini/src/_utils/utilities.ts#L76

preset-wind4 has its own copy of that helper with the same correct arguments at utilities.ts:76, so the two splitters in the same file disagree.

Fix

Pass '[' / ']' to getStringComponents in parseColor, matching splitShorthand right above it. One line.

text-[color:red]          -> color:color-mix(in oklab, red var(--un-text-opacity), transparent)
text-[color:var(--color)] -> color:color-mix(in oklab, var(--color) var(--un-text-opacity), transparent)
bg-[color:#000]           -> background-color:color-mix(in oklab, #000 var(--un-bg-opacity), transparent)

Opacity and interpolation modifiers still compose: text-[color:red]/50 and text-[color:red]:50/display-p3 resolve as expected, and border-[color:*] is unchanged.

Tests

No separate test case. The coverage lives in the shared targets list:

  • bg-[color:#000], ring-[color:red], outline-[color:red], decoration-[color:red] and fill-[color:red] added to test/assets/preset-wind4-targets.ts, next to the border-[color:*] entries already there. text-[color:*] is already covered by presetMiniTargets.
  • Three entries drop out of the "safe differences" list in the targets test, since text-[color:--variable], text-[color:var(--color)] and text-[color:var(--color-x)]:[trick] now generate CSS.
  • test/assets/output/preset-wind4-targets.css picks up the new selectors. The three text- ones merge into the existing rule groups for their untyped equivalents, i.e. they produce byte-identical declarations to text-[--variable] and text-[var(--color)].
  • No other snapshot in the suite changes.

Verified by reverting only the source change, rebuilding, and re-running: text-, bg-, outline- and fill- lose their rules entirely, ring-[color:red] falls through to the ring-width rule as calc(red + var(--un-ring-offset-width)), and decoration-[color:red] becomes text-decoration-thickness:red.

@giaBaoJS
giaBaoJS requested review from antfu and zyyv as code owners September 1, 2026 09:52
@netlify

netlify Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for unocss ready!

Built without sensitive environment variables

Name Link
🔨 Latest commit 829b62e
🔍 Latest deploy log https://app.netlify.com/projects/unocss/deploys/6a9ab9cf4003a10008797e28
😎 Deploy Preview https://deploy-preview-5299--unocss.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@pkg-pr-new

pkg-pr-new Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

commit: 829b62e

Comment thread test/preset-wind4.test.ts Outdated
await expect(css).toMatchFileSnapshot('./assets/output/preset-wind4-reset.css')
})

it('color type hint in arbitrary values', async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to write a separate test case for this.

@giaBaoJS
giaBaoJS force-pushed the fix/wind4-color-type-hint branch from cdd9f3b to 829b62e Compare September 4, 2026 12:30
@giaBaoJS

giaBaoJS commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

Dropped the separate test case. The coverage now lives in the shared targets list: bg-[color:#000], ring-[color:red], outline-[color:red], decoration-[color:red] and fill-[color:red] go into test/assets/preset-wind4-targets.ts next to the existing border-[color:*] entries, and text-[color:*] was already in presetMiniTargets and just stops being listed as a safe difference.

Also rebased onto main. The only conflict was in test/preset-wind4.test.ts, where #5301 added its blend mode global keywords case at the same spot my test block was inserted; since that block is gone, I kept main's version.

Counterfactual after the rebase, rebuilt each time because the tests resolve the built preset: reverting only parseColor makes text-, bg-, outline- and fill- produce nothing, ring-[color:red] fall through to the ring-width rule as calc(red + var(--un-ring-offset-width)), and decoration-[color:red] become text-decoration-thickness:red. Full suite is green with the fix in place.

@zyyv
zyyv added this pull request to the merge queue Sep 5, 2026
Merged via the queue into unocss:main with commit db937ba Sep 5, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Sponsor
SponsoredKunjungi sekarang
Promo