Skip to content

switches to a portal architecture for fake fullscreen div - #14292

Open
HarveyPeachey wants to merge 1 commit into
WS-2916-toucan-fake-fullscreenfrom
WS-2916-toucan-fake-fullscreen-portal
Open

switches to a portal architecture for fake fullscreen div#14292
HarveyPeachey wants to merge 1 commit into
WS-2916-toucan-fake-fullscreenfrom
WS-2916-toucan-fake-fullscreen-portal

Conversation

@HarveyPeachey

Copy link
Copy Markdown
Contributor

Resolves JIRA:

Summary

A very high-level summary of easily-reproducible changes that can be understood by non-devs, and why these changes where made.

Code changes

  • List key code changes that have been made.

Testing

  1. List the steps required to test this PR.

Useful Links

Copilot AI review requested due to automatic review settings August 5, 2026 08:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates MediaLoader’s “fake fullscreen” implementation to use a portal-based backdrop layer rendered at the document root, addressing stacking-context issues (notably on iOS Safari) while keeping the elevated player wrapper above the backdrop.

Changes:

  • Introduces FakeFullscreenLayer, which portals the fullscreen backdrop <div> to document.body after mount to avoid hydration mismatches.
  • Introduces FakeFullscreenStyles, which injects the shared fake-fullscreen CSS into document.head once per page (guarded by a fixed style element id) and applies the CSP nonce when provided.
  • Replaces the previous in-tree backdrop <div> and Helmet-injected <style> with the new portal/style-injection approach.
Suppressed comments (1)

src/app/components/MediaLoader/index.tsx:80

  • FakeFullscreenLayer now portals the backdrop into document.body, which is a significant DOM-structure change from the previous in-tree backdrop. Please add a test to assert the backdrop element is rendered under document.body (not within the MediaLoader container) and that toggling fake fullscreen adds/removes the active class as expected.
const FakeFullscreenLayer = ({ isActive }: { isActive: boolean }) => {
  // Defer the portal until after mount so the hydration render matches the
  // server (both render nothing). Portalling during hydration would insert the
  // backdrop into <body> before hydration completes, causing a mismatch.
  const [isMounted, setIsMounted] = useState(false);

Comment on lines +57 to +61
const FakeFullscreenStyles = ({ nonce }: { nonce?: string | null }) => {
useEffect(() => {
if (document.getElementById(FAKE_FULLSCREEN_STYLE_ID)) return;

const styleElement = document.createElement('style');
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.

2 participants