Skip to content

fix(preset): resolve the alpha placeholder of theme() calls without opacity - #11

Merged
nekomeowww merged 2 commits into
mainfrom
fix/preset-theme-fn-alpha
Oct 28, 2026
Merged

nekomeowww merged 2 commits into
mainfrom
fix/preset-theme-fn-alpha

Conversation

@nekomeowww

Copy link
Copy Markdown
Member

Summary

In CSS processed by transformerDirectives, theme('colors.primary.400') produced an invalid colour ending in / %alpha), so browsers dropped the declaration. Found while migrating AIRI's hand-made tints to chromatic colours, which currently have to write theme('colors.primary.400 / 100%').

Cause

  • Chromatic's theme colours carry an alpha placeholder (/ %alpha). Opacity utilities like bg-primary-500/50 need it, because the nested calc() inside oklch() cannot be parsed to insert an opacity otherwise.
  • transformThemeString of @unocss/rule-utils (66.7.5), which backs theme(), only resolves the placeholder when the call has an opacity. Without one it returns the raw string.
  • The preset's postprocess cannot fix it: theme() is expanded in the CSS source by the directives transformer, not by the generator.

Fix

The preset now ships a source transformer:

  • enforce: 'pre', CSS ids only. It runs before the directives transformer, which uses the default pass.
  • It rewrites theme('colors.<one of the preset's colours>[.<shade>]') calls without an opacity to theme('colors.… /1'), so the directives transformer resolves the placeholder to 1. That is the value UnoCSS uses for an omitted opacity elsewhere (colorToString).
  • Calls with an opacity, other colours (e.g. colors.red.500) and non-CSS files are untouched.
  • post would not work: in a build, Vite's CSS plugin has already extracted the CSS by then.

This can be removed once UnoCSS resolves the placeholder for theme() without an explicit opacity. An upstream fix in transformThemeString would be a one-liner and would also help other themes that use %alpha / <alpha-value>.

Test plan

  • New shared.theme.test.ts runs the merged transformers in the order @unocss/vite uses (pre → default → post). It covers single / double quotes, DEFAULT, every configured colour, an explicit opacity, a default value, the v1 model, other colours, and non-CSS files.
  • Mutation check: without the transformer, 4 of the 5 new tests fail.
  • Real Vite: a temporary theme('colors.primary.400') rule in the playground is served as a valid colour and computes to oklch(0.729 0.207 344) in Chrome. The rule was removed afterwards.
  • pnpm lint, pnpm typecheck, pnpm build, pnpm test:run (31 tests).

🤖 Generated with Claude Code

…pacity

`theme('colors.primary.400')` in CSS (transformerDirectives) left
`/ %alpha` behind, because `transformThemeString` of @unocss/rule-utils
only resolves alpha placeholders when the call has an opacity, so the
declaration was dropped. `postprocess` cannot reach it: `theme()` is
expanded in the CSS source, not by the generator.

The preset now ships a `pre` transformer that gives `theme()` calls of
its own colours without an opacity an explicit `/1` before the
directives transformer expands them. Calls with an opacity, other
colours and non-CSS files are left alone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@netlify

netlify Bot commented Oct 28, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for proj-airi-chromatic ready!

Name Link
🔨 Latest commit 99ab13b
🔍 Latest deploy log https://app.netlify.com/projects/proj-airi-chromatic/deploys/6ae1f4bcab29f44ae9fc651f
😎 Deploy Preview https://deploy-preview-11--proj-airi-chromatic.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.

`typeof import('magic-string')` does not resolve from packages/preset on
a clean install (the preset does not depend on magic-string), which
failed CI's typecheck. Derive the type from `SourceCodeTransformer`
instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@nekomeowww
nekomeowww merged commit 217c39b into main Oct 28, 2026
7 checks passed
@nekomeowww
nekomeowww deleted the fix/preset-theme-fn-alpha branch October 28, 2026 13:15
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.

1 participant