UI: Rework Monaco editor theme to match Chakra UI palette#64748
Open
shivaam wants to merge 4 commits intoapache:mainfrom
Open
UI: Rework Monaco editor theme to match Chakra UI palette#64748shivaam wants to merge 4 commits intoapache:mainfrom
shivaam wants to merge 4 commits intoapache:mainfrom
Conversation
1 task
shivaam
commented
Apr 5, 2026
airflow-core/src/airflow/ui/src/context/colorMode/useMonacoTheme.ts
Outdated
Show resolved
Hide resolved
Contributor
Author
@pierrejeambrun handled the nits and the PR is ready for local testing |
pierrejeambrun
approved these changes
Apr 10, 2026
airflow-core/src/airflow/ui/src/context/colorMode/useMonacoTheme.ts
Outdated
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment.
Pull request overview
Registers custom airflow-light / airflow-dark Monaco themes derived from Chakra UI tokens, and wires them into all Monaco editor usages so editor chrome matches the app’s design system.
Changes:
- Add
useMonacoThemehook that defines and selects the Monaco theme based on current Chakra color mode. - Update all Monaco editor call sites (
Editor+DiffEditor) to use the hook’sbeforeMount+theme. - Add unit tests covering theme selection and one-time registration behavior.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| airflow-core/src/airflow/ui/src/context/colorMode/useMonacoTheme.ts | Defines custom Monaco themes using Chakra CSS variables and exposes beforeMount + theme. |
| airflow-core/src/airflow/ui/src/context/colorMode/useMonacoTheme.test.ts | Tests theme name selection and single registration behavior. |
| airflow-core/src/airflow/ui/src/context/colorMode/index.ts | Exports useMonacoTheme from the colorMode barrel. |
| airflow-core/src/airflow/ui/src/pages/Dag/Code/Code.tsx | Uses useMonacoTheme for the DAG code viewer Monaco editor. |
| airflow-core/src/airflow/ui/src/pages/Dag/Code/CodeDiffViewer.tsx | Uses useMonacoTheme for the DAG code diff Monaco editor. |
| airflow-core/src/airflow/ui/src/components/JsonEditor.tsx | Uses useMonacoTheme for the JSON editor component. |
| airflow-core/src/airflow/ui/src/components/RenderedJsonField.tsx | Uses useMonacoTheme for read-only rendered JSON Monaco editor instances. |
airflow-core/src/airflow/ui/src/context/colorMode/useMonacoTheme.test.ts
Outdated
Show resolved
Hide resolved
Register custom airflow-light and airflow-dark Monaco themes derived from Chakra UI color tokens so that the DAG Code viewer, diff viewer, and JSON editors visually integrate with the rest of the app instead of using Monaco's default vs/vs-dark themes. The new useMonacoTheme hook rasterizes a single pixel through a 2D canvas and reads it back via getImageData to convert Chakra's OKLCH color values into the #rrggbb strings that Monaco's defineTheme accepts — ctx.fillStyle readback cannot be used because modern Chrome preserves the original OKLCH string. Themes are registered once via a module-level flag and then passed to every Monaco editor via the beforeMount callback. closes: apache#64253
Address review feedback: React Compiler handles memoization, so the useCallback wrapper around defineAirflowMonacoThemes is redundant. Pass the function reference directly instead. Also fix prettier formatting in tests.
Address review feedback: the canvas-based cssVarToHex was brittle (depended on Canvas2D rendering and browser-specific fillStyle behavior, and required canvas mocking in happy-dom tests). Replace it with culori's parse/formatHex, which handles OKLCH and other modern color spaces directly with no DOM rasterization. Also add afterEach(vi.restoreAllMocks()) to the tests so the getComputedStyle spy does not leak between runs.
061ca08 to
7dba46a
Compare
Contributor
Author
|
Pushed 7dba46a addressing review feedback: Canvas → culori for color conversion (@pierrejeambrun) |
unparseable -> unparsable.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
Register custom
airflow-light/airflow-darkMonaco themes derived from Chakra UI color tokens so that every Monaco editor in the UI (DAG Code viewer, code diff viewer, JSON editor, RenderedJsonField) visually integrates with the rest of the app instead of using Monaco's defaultvs/vs-darkthemes.closes: #64253
Open Questions
themesRegisteredflag sodefineThemeonly runs on the first
beforeMount. Without it, pages with many editors (e.g.XCom table with ~50 rows) re-register themes on every mount. Measured cost without the guard: ~4ms on a 50-editor page. Negligible. Happy to drop the flag for simpler code + tests if you prefer..
defineThemeonly accepts#rrggbb. I convert by rasterizing a 1x1 canvas pixel and reading back sRGBvia
getImageData. I checkedctx.fillStylereadback — it preserves the OKLCH string unchanged on Chrome 111+, so that path silently fails (this is what PR Rework Monaco editor style to match Chakra UI color palette #64268 does).Implementation notes
useMonacoTheme(src/context/colorMode/useMonacoTheme.ts) — registers both custom themes exactly once via a module-level flag, returns a stablebeforeMountcallback and the correct theme name for the current color mode.inherit: true+ emptyrules— Monaco's default syntax highlighting (keywords, strings, comments) is preserved. Only editor shell colors (background, foreground, gutter, selection, scrollbar, line numbers) are overridden.getImageData— Chakra v3 uses OKLCH colors.ctx.fillStylereadback cannot be relied on because Chrome 111+ preserves the OKLCH string instead of converting to hex, which Monaco would silently ignore.RenderedJsonFieldrows) don't pay the cost on every mount.JsonEditor,RenderedJsonField,Code,CodeDiffViewer) are updated to use the hook. No changes to component structure, dynamic height behavior, or any other behavior beyond theme wiring.How to test
breeze start-airflow --dev-mode --load-example-dagsWas generative AI tooling used to co-author this PR?
Generated-by: Claude Code (Opus 4.6) following the guidelines