fix(editor): defend Monaco against Tailwind v4 Preflight reset (#90)#92
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe PR fixes Monaco editor layout broken by Tailwind v4 Preflight resets. A global transition rule is removed from globals.css and replaced with Monaco-specific CSS that restores ChangesMonaco Editor Layout Fix
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Verified in |
99f8c2f to
64d3714
Compare
Live reproducer in v1.0.16: the SQL editor renders with a ~600px gap
between the line-number gutter and the text, newline advancement is
broken, and Monaco's normally-invisible internal <textarea class=
"inputarea"> (used for keyboard/IME capture) shows through as a
visible bordered input at the cursor position.
Root cause: Tailwind v4's Preflight (in `@import "tailwindcss"`)
applies `box-sizing: border-box; margin: 0; padding: 0; border: 0
solid` to every element, plus `font: inherit; background-color:
transparent; opacity: 1` to form elements. Monaco was authored
against browser defaults (content-box, unstyled inputs with UA
opacity rules) and its layout calculations corrupt under those
resets — including the cursor/.view-lines positioning that drives
where text renders.
Fix: scoped reset in `globals.css` that re-establishes content-box
and reverts the form-element resets inside any `.monaco-editor`
subtree. Does not touch Tailwind utilities used elsewhere.
Also remove the unrelated `* { transition: background-color, border-
color }` rule from `globals.css`. Universal selector applied to
every element including Monaco's selection/highlight repaints. 31
of our own files already use explicit Tailwind `transition-colors`
utilities where intentional, so the practical loss is negligible.
Closes #90
64d3714 to
d25c92e
Compare
…yles work (#90) (#98) The v1.0.17 fix in PR #92 didn't actually resolve the bug — it blamed Tailwind v4 Preflight and added scoped CSS overrides, which were inert in production. The release shipped looking-fixed-locally but still broken on installed Tauri builds. After enabling DevTools in a local release build, the smoking gun was in the console: Applying inline style violates the following Content Security Policy directive 'style-src 'self' 'unsafe-inline' … 'nonce-…''. Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list. Tauri 2 auto-injects a nonce into our configured `style-src` for hardening. Per CSP spec, when a nonce is present, `'unsafe-inline'` is *ignored*. Monaco uses inline `style="top: Npx"` on every `.view-line` to position text — every cursor placement, every viewport calculation, every gutter element. With inline styles blocked, Monaco's DOM positions collapse to default (0,0), text stacks, and the normally-invisible `<textarea class="ime-text-area">` (used for keyboard/IME capture) shows through at its un-positioned default location. Why this didn't reproduce earlier: - `tauri dev`: Vite dev's CSP is permissive, no Tauri-injected nonce - Browser preview: no Tauri at all, no auto-CSP - Tauri release builds: Tauri's CSP augmentation kicks in Fix: `dangerousDisableAssetCspModification: ["style-src"]` in `tauri.conf.json` tells Tauri not to augment `style-src` with the nonce. Our intended `'unsafe-inline'` then actually works. `script-src` nonce protection is kept intact — that's the actually useful XSS defense. Side fix: `connect-src` was missing `http://ipc.localhost ipc:`, so every IPC command was failing the custom-protocol path and falling back to the slower postMessage interface. Added them. Closes #90 for real this time.
PR #92 added a `.monaco-editor` `box-sizing: content-box` block and form-element `revert` overrides on the theory that Tailwind v4 Preflight was corrupting Monaco's layout. The diagnosis was wrong (real cause was Tauri's CSP nonce on style-src — fixed in v1.0.18). The overrides were inert in production and the `revert` rules on form elements were arguably making things worse by reverting Monaco's intentional invisibility styles back to UA defaults. Removing them cleans up the codebase and the CHANGELOG history. No replacement needed — Monaco's own CSS handles everything correctly once the CSP isn't blocking inline styles.
Closes #90.
Summary
The SQL editor renders broken in v1.0.16 (live): ~600px gap between the line-number gutter and text, broken newline advancement, and Monaco's normally-invisible internal
<textarea class=\"inputarea\">(used for keyboard/IME capture) showing through as a visible bordered input at the cursor position. Reproduces on any fresh query tab.Root cause
Tailwind v4's Preflight (
@import \"tailwindcss\") applies to every element:```css
, ::after, ::before, ::backdrop, ::file-selector-button {
box-sizing: border-box;
margin: 0;
padding: 0;
border: 0 solid;
}
button, input, select, optgroup, textarea, ::file-selector-button {
font: inherit;
background-color: transparent;
opacity: 1;
/ ... */
}
```
Monaco's layout calculations were authored against browser defaults — content-box, unstyled form elements with UA opacity behavior. The
box-sizing: border-boxchange corrupts cursor /.view-linespositioning, and the form-element reset makes Monaco's hiddeninputareavisible because Monaco relied on default UA invisibility rather than explicit inline opacity:0 styling.This is a well-known Monaco × Tailwind v4 interaction.
Fix
Scoped reset in
src/styles/globals.cssthat re-establishes browser defaults inside any.monaco-editorsubtree:```css
.monaco-editor,
.monaco-editor *,
.monaco-editor *::before,
.monaco-editor *::after {
box-sizing: content-box;
}
.monaco-editor input,
.monaco-editor textarea {
font: revert;
background-color: revert;
opacity: revert;
}
.monaco-editor textarea { resize: none; }
```
Tailwind utilities elsewhere in the app are unaffected.
Drive-by cleanup
Also removed
* { transition: background-color 0.2s ease, border-color 0.2s ease }fromglobals.css. Universal selector applied to every element on the page, including Monaco's selection/highlight repaints — minor compositing artifact source. 31 of our own files already use explicit Tailwindtransition-colorsutilities where transitions are intended, so the practical regression surface is negligible.Test plan
npx vite buildcleannpm run tauri devand verify the editor renders flush against the gutter, newlines advance correctly, no visible input element at cursor, dirty-state dot positioned correctly in tab stripNotes
.view-linescomputed styles in DevTools to see what other Preflight rules are leaking through.main.Summary by CodeRabbit