Skip to content

fix(code-highlighter): make light-theme colors fully self-contained - #174

Merged
cc-hearts merged 2 commits into
mainfrom
fix/code-highlighter-light-line-number-token
Aug 7, 2026
Merged

fix(code-highlighter): make light-theme colors fully self-contained#174
cc-hearts merged 2 commits into
mainfrom
fix/code-highlighter-light-line-number-token

Conversation

@cc-hearts

@cc-hearts cc-hearts commented Aug 7, 2026

Copy link
Copy Markdown
Member

🤔 This is a ...

  • 🐞 Bug fix

🔗 Related Issues

💡 Background and Solution

The -light / -dark variants are self-contained color schemes driven by the user-controlled theme prop, so their colors must not follow the app color algorithm - this is the principle #172 established ("using colorText would break the mirrored case"). #172 only tokenized the dark side (plus the line-number light token in the first commit here); the rest of the light chrome still used global tokens.

Impact of the gap - in the mirrored case (app on the dark algorithm + theme="light"), the global tokens resolve to dark-algorithm values:

Global token (light rule) Light algo Dark algo (mirrored) Result on #fafafa
colorTextSecondary (lang label, buttons) rgba(0,0,0,0.65) rgba(255,255,255,0.65) invisible text/icons
colorTextQuaternary (line numbers) rgba(0,0,0,0.25) rgba(255,255,255,0.25) invisible line numbers
colorFillSecondary (header bg) rgba(0,0,0,0.06) rgba(255,255,255,0.12) header loses separation
colorBorderSecondary (borders) #f0f0f0 dark-algo value wrong borders

And the dark-theme root border used the global colorBorder instead of codeBorderColorDark, so in the opposite mirrored case (light algorithm + theme="dark") it drew a light #d9d9d9 outline around the dark card.

Solution

Add the missing light counterparts to the existing dark tokens and wire them in, so -light / -dark are now fully self-contained and symmetric:

New light token Replaces Dark counterpart (existing)
codeLineNumberColor colorTextQuaternary codeLineNumberColorDark
codeHeaderBg colorFillSecondary codeHeaderBgDark
codeBorderColor colorBorderSecondary (root / header-bottom / gutter-right) codeBorderColorDark
codeLangColor colorTextSecondary codeLangColorDark
codeBtnColor colorTextSecondary codeBtnColorDark
codeBtnHoverBg (light had no hover override) codeBtnHoverBgDark

Also: dark root border colorBorder -> codeBorderColorDark; light action buttons now mirror the dark side with !important + explicit hover background (the dark side already needed !important to beat antd Button .ant-btn-variant-text color).

Defaults preserve the previous common-case appearance - opaque hexes are the equivalent of the prior translucent global tokens composited over white (e.g. #f0f0f0 == colorBorderSecondary / colorFillSecondary over white), and the rgba text colors match the prior colorTextSecondary / colorTextQuaternary under the light algorithm. No visual change in the common case; only the mirrored cases are fixed.

📝 Change Log

Language Changelog
🇺🇸 English Fix CodeHighlighter rendering in the mirrored case (app color algorithm opposite to the component theme prop): line numbers, language label, and action buttons were invisible, the header lost separation, and borders were wrong. All light-theme colors are now self-contained component tokens (codeHeaderBg, codeBorderColor, codeLangColor, codeBtnColor, codeBtnHoverBg, codeLineNumberColor) matching the existing dark counterparts; the dark root border now reuses codeBorderColorDark.
🇨🇳 Chinese 修复 CodeHighlighter 在镜像场景(应用算法与组件 theme 相反)下的显示:行号、语言标签、操作按钮不可见,头部背景与内容区糊在一起,边框颜色错误。亮色主题所有颜色改为自包含的组件 token(codeHeaderBgcodeBorderColorcodeLangColorcodeBtnColorcodeBtnHoverBgcodeLineNumberColor),与已有暗色 token 一一对应;暗色根边框改用 codeBorderColorDark

The previous dark-theme fix (#172) added a self-contained
`codeLineNumberColorDark` token, but the light-theme line number color
still used the global `token.colorTextQuaternary`. The `-light` / `-dark`
variants are self-contained color schemes driven by the `theme` prop, so
their colors must not follow the app color algorithm.

In the mirrored case (app on the dark algorithm + `theme="light"`),
`colorTextQuaternary` resolves to `rgba(255, 255, 255, 0.25)` (from
`colorTextBase=#fff`), rendered on top of the `#fafafa` light background,
making the line numbers nearly invisible.

Add a `codeLineNumberColor` component token (light counterpart to
`codeLineNumberColorDark`), defaulting to `rgba(0, 0, 0, 0.25)` - the
effective color of `colorTextQuaternary` under the light algorithm
(`colorTextBase=#000` @ 0.25) - so the common-case appearance is
unchanged while the value no longer drifts with the app algorithm.
The previous commit only tokenized the line-number color. The rest of
the light-theme chrome still used algorithm-driven global tokens, so in
the mirrored case (app on the dark algorithm + `theme="light"`) the
language label and action buttons became invisible, the header lost
separation from the content, and the borders were wrong.

Add the missing light counterparts to the existing dark tokens and wire
them in, so `-light` / `-dark` are now fully self-contained and
symmetric:

- `codeHeaderBg`        (was `colorFillSecondary`)
- `codeBorderColor`     (was `colorBorderSecondary`, used on root /
  header-bottom / gutter-right)
- `codeLangColor`       (was `colorTextSecondary`)
- `codeBtnColor`        (was `colorTextSecondary`)
- `codeBtnHoverBg`      (light had no hover override; antd Button's
  algorithm-driven default was used)

Also fix the dark-theme root border, which used the global `colorBorder`
instead of the existing `codeBorderColorDark` - in the mirrored case
(light algorithm + `theme="dark"`) it drew a light `#d9d9d9` outline
around the dark card.

The light-theme action buttons now mirror the dark side: `!important`
plus an explicit hover background, so the override reliably beats antd
Button's `.ant-btn-variant-text` color (which is why the dark side
already needed `!important`).

Defaults preserve the previous common-case appearance: opaque hexes are
the equivalent of the prior translucent global tokens composited over
white (e.g. `#f0f0f0` == `colorBorderSecondary` / `colorFillSecondary`
over white), and the rgba text colors match the prior `colorTextSecondary`
under the light algorithm.
@cc-hearts cc-hearts changed the title fix(code-highlighter): make light-theme line number color self-contained fix(code-highlighter): make light-theme colors fully self-contained Aug 7, 2026
@cc-hearts
cc-hearts merged commit e794356 into main Aug 7, 2026
1 check passed
@cc-hearts
cc-hearts deleted the fix/code-highlighter-light-line-number-token branch August 7, 2026 12:28
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