[Bug]: Paint CodeEditor from the theme instead of CodeMirror's light default - #4025
[Bug]: Paint CodeEditor from the theme instead of CodeMirror's light default#4025fashxp wants to merge 8 commits into
Conversation
CodeMirror defaults to its light colour set, which paints an opaque white surface while the text colour is inherited from the theme, so on a dark theme the editor was white on white. The chrome now comes from the tokens, and the dark syntax set is selected when the surface is dark since CSS cannot reach those colours. Co-Authored-By: Claude <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Updates CodeEditor to integrate CodeMirror with Studio theme colors and syntax highlighting.
Changes:
- Derives CodeMirror syntax theme from surface luminance.
- Applies Studio tokens to editor chrome.
- Adds color parsing and luminance tests.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
assets/js/src/core/utils/color.ts |
Adds dark-surface detection. |
assets/js/src/core/utils/color.test.ts |
Tests color parsing and classification. |
assets/js/src/core/components/code-editor/code-editor.tsx |
Selects a theme from the surface color. |
assets/js/src/core/components/code-editor/code-editor.styles.tsx |
Themes CodeMirror chrome with Studio tokens. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Addresses the review on #4025. `theme="dark"` installed the whole oneDark bundle, whose chrome won over the tokens for search matches, brackets, fold placeholders and tooltips; the token rules also overrode a caller's own theme extension, and a translucent surface colour was read as if it were opaque. Co-Authored-By: Claude <noreply@anthropic.com>
A stylesheet has to out-specify selectors it does not own, and it lost: the focused selection stayed at CodeMirror's #233, 1.26:1 on pimcore-dark. A theme registers above the base themes, so ties go to it by construction. The same hook now also themes the three editors that render CodeMirror directly, including the asset text editor, which had the identical defect. Co-Authored-By: Claude <noreply@anthropic.com>
|
Reviewed and acted on in 95a5331. Everything below was reproduced before changing anything. The blocker was real and I reproduced it. On Taken the structural recommendation. The chrome is now The two dead rules are gone. Confirmed The three siblings are covered. Threshold moved to 0.179 (where contrast against white equals contrast against black) with a test that pins it, since the suite would have passed with anything in (0.0722, 0.7152). Search-match salience: the two now use different hues rather than two steps of one ramp, so "a hit" and "the current hit" are distinguishable. Panel chrome is now token-driven and verified live — panel On the selection colour, your framing led somewhere useful. A band has to move away from the surface, and the direction differs per theme, so no single token works:
Two points I'm not acting on, with reasons. The Corrections to the review. Two things it got slightly wrong: the PR body said 4 tests where jest reported 5 (stale, now 6), and the dark-syntax figures were indeed measured through the agent-bundle wrapper on One Dark's own Still not driven end to end: the |
One expression describing every separator the syntax allows reached a complexity of 24. Matching the wrapper and splitting the inside is simpler and covers the same forms, but accepts non-numeric channels, so those are now rejected rather than read as black — and therefore as dark. Co-Authored-By: Claude <noreply@anthropic.com>
|



Why
CodeMirror defaults to its own light colour set, which paints an opaque white surface
while the text colour is inherited from the Studio theme. On a dark theme that leaves
every editor white on white — measured on
pimcore-dark:What
EditorView.baseThemeregisters atPrec.lowestand mounts first, so a normal-precedencetheme wins ties by construction instead of by hand-counted specificity.
oneDarkbundle(which carries chrome that would win over the tokens).
{ dark }on the theme is whatmakes CodeMirror's own base themes pick their dark variants.
isDarkSurface(token.colorBgContainer)),not from a theme id, so a theme registered by a bundle works too.
CodeEditor—TextEditor(which backs theasset text editor and is SDK-public), the email-log text preview and the translation HTML
preview. They keep rendering
ReactCodeMirrordirectly becauseCodeEditoroverwritesclassName, which carries their sizing.Token choices and the reasoning behind them are in comments at the call sites.
Backward compatibility
code-editor.styles.tsxis untouched, so every rule that applied before still applies.A caller passing its own
themekeeps it and keeps control of the visuals — the tokentheme is not appended on that path. One DOM detail: with no
themesupplied the wrapperclass goes from
cm-theme-lighttocm-theme-none; nothing in this repo stylescm-theme*.Verification
Driven through a running Studio in both themes, on the core
robots.txteditor and theasset text editor (no bundle involved). Contrast measured on the rendered DOM:
pimcore-darkstudio-default-lightSearch panel chrome confirmed token-driven. Dark syntax colours 5.6–9.9:1 on the surface.
Not driven end to end: the
.cm-searchMatchfills — the panel opens and its chrome isconfirmed, but match state would not register from a synthetic input event.
Gates:
tsc --noEmitclean · eslint clean ·color.test.ts7 passed.🤖 Generated with Claude Code
https://claude.ai/code/session_01CWjetJ3XSrzdSZpYFG3N57