Skip to content

Fix unstyled modals in dev: re-read document styles after page load#4242

Merged
evanpelle merged 1 commit into
mainfrom
fix-dev-modal-styles
Jun 12, 2026
Merged

Fix unstyled modals in dev: re-read document styles after page load#4242
evanpelle merged 1 commit into
mainfrom
fix-dev-modal-styles

Conversation

@evanpelle

Copy link
Copy Markdown
Collaborator

Problem

Since #4229, modals render unstyled in npm run dev (no black backdrop, no Tailwind styling). Production/staging is unaffected.

documentStylesSheet() reads the document's <style> tags once, at module-eval time. In dev, Vite injects the Tailwind styles during module evaluation — after that read — so the shared constructed stylesheet ended up with 7 CSS rules instead of the full Tailwind sheet. In production the styles come from a <link rel=stylesheet> that is fetched by URL, so timing doesn't matter there.

Fix

If the document hasn't finished loading when the sheet is first created, re-populate it once on the window load event (which fires after the entry module graph — and therefore all style injection — completes). Constructed stylesheets are live, so already-rendered components pick the styles up without re-rendering. The existing HMR re-populate hook is unchanged.

Test plan

  • Reproduced in dev with headless Chromium: shared sheet had 7 rules, modal unstyled
  • After fix: sheet has full Tailwind rules, solo modal renders with correct dark styling (screenshot-verified)
  • npx tsc --noEmit, ESLint clean
  • Client test suite: 458 tests pass

🤖 Generated with Claude Code

documentStylesSheet() read the document's <style> tags once at module-eval
time, but in dev Vite injects the Tailwind styles during module evaluation,
after that read — so shadow-DOM modals got a near-empty stylesheet (7 rules
instead of the full Tailwind sheet) and rendered unstyled. Production was
unaffected because the styles come from a <link> that is fetched by URL.

Re-populate the constructed sheet once the window load event fires;
constructed sheets are live, so already-rendered components pick the
styles up automatically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ad02cf93-4433-461d-85f4-cc0d54584bd1

📥 Commits

Reviewing files that changed from the base of the PR and between 27054bd and a4e590c.

📒 Files selected for processing (1)
  • src/client/components/baseComponents/SharedStyles.ts

Walkthrough

The PR fixes a development-time race condition where the shared stylesheet module initializes before Vite injects the page's <style> tags. The documentStylesSheet() function now checks if the page has finished loading and registers a one-time window.load listener to re-populate the stylesheet, ensuring it captures all injected styles.

Changes

Dev HMR Stylesheet Population Fix

Layer / File(s) Summary
Load-time stylesheet re-population
src/client/components/baseComponents/SharedStyles.ts
documentStylesSheet() conditionally adds a window.load listener that re-populates the shared CSSStyleSheet when the module initializes before the page fully loads, solving the race condition with Vite's style injection in dev.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

Stylesheets waiting, page still loading slow,
A race condition steals the Vite glow,
One listener waits for the page's done,
Then populates the sheet—dev victory won! 🎨✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: fixing unstyled modals in dev by re-reading document styles after page load, which directly matches the changeset's core purpose.
Description check ✅ Passed The description provides clear context about the problem (timing issue with Vite style injection), the fix (re-populate on load event), and test verification, all directly related to the changeset.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed due to a network error.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@evanpelle evanpelle added this to the v32 milestone Jun 12, 2026
@evanpelle evanpelle merged commit eeb5f7e into main Jun 12, 2026
15 of 18 checks passed
@evanpelle evanpelle deleted the fix-dev-modal-styles branch June 12, 2026 16:26
@github-project-automation github-project-automation Bot moved this from Triage to Complete in OpenFront Release Management Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Complete

Development

Successfully merging this pull request may close these issues.

1 participant