Skip to content

@remotion/studio: Clear stale hover backgrounds - #10068

Merged
JonnyBurger merged 1 commit into
mainfrom
clear-stale-hover-backgrounds
Aug 3, 2026
Merged

@remotion/studio: Clear stale hover backgrounds#10068
JonnyBurger merged 1 commit into
mainfrom
clear-stale-hover-backgrounds

Conversation

@JonnyBurger

Copy link
Copy Markdown
Member

Closes #9886

Problem

Hover backgrounds of Studio controls were driven by React state (pointerentersetHovered(true), pointerleavesetHovered(false)) and rendered as inline styles. When Studio runs inside an <iframe> (as in Browser Studio), browsers can fail to deliver pointerleave when the pointer exits the frame. A single missed event left the hover background stuck indefinitely, e.g. on Add Solid and menubar items.

Fix

Purely visual hover styling is now driven by CSS :hover, which the browser maintains itself and self-corrects even when boundary events are dropped. Because each control has different idle/hover/selected colors, a shared injected stylesheet reads them from inherited CSS custom properties that components set inline:

  • New packages/studio/src/helpers/hoverable.ts: class names, a hoverableStyle() helper emitting the four CSS variables (idle/hover × background/color), and the injected CSS. The rules use doubled class names to win over the .css-reset * rule regardless of stylesheet injection order, and * descendant selectors re-establish color inheritance inside hoverable elements so text and currentColor-based icons follow the hover state. Hover rules are gated behind @media (hover: hover) to avoid sticky tap-hover on touch devices.
  • Migrated the shared primitives: InlineAction (used by the render queue, sidebar toggles, undo/redo, asset rows etc.), InspectorInlineAction (Add Solid, including the segmented variant with its reveal-on-hover trailing icon) and the menubar MenuItem. Icons receive currentColor instead of a resolved color string.
  • Intentional states remain in React and are visually unaffected: selected (open menu) still drives the menubar highlight, and MenuItem's pointerenter handler is kept solely for the switch-menu-while-open logic.

Components where hover state drives logic (revealing row action buttons, submenu open delay, timeline/canvas hover sync) are unchanged and can migrate to this mechanism incrementally.

Test

Added a Playwright regression test to the Browser Studio e2e suite that hovers Add Solid, then suppresses all pointer/mouse leave events at window capture (simulating the lost events at the iframe boundary), moves the pointer away and asserts the background resets; same for a menubar item. The test fails against the previous implementation (background stays stuck at rgba(255, 255, 255, 0.06)) and passes with this fix.

Also verified in the regular Studio (packages/example) that idle, hovered, selected and open-menu states as well as hover-switching between open menus are visually unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
bugs Ready Ready Preview Aug 2, 2026 4:47pm
remotion Ready Ready Preview Aug 2, 2026 4:47pm

Request Review

@pullfrog pullfrog Bot 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.

✅ No new issues found.

Reviewed changes

  • hoverable.ts — New shared module with CSS class names, a hoverableStyle() helper that emits four CSS custom properties (idle/hover × background/color) via inline style, and an injected stylesheet with @media (hover: hover) gating, doubled-class-name specificity to beat .css-reset *, and * descendant selectors for currentColor inheritance.
  • InlineAction — Drops useState(false) hover and the onPointerEnter/onPointerLeave handlers; spreads hoverableStyle into the inline style and passes CURRENT_COLOR to renderAction instead of WHITE/LIGHT_TEXT.
  • InspectorInlineAction — Same migration for the single and segmented variants; the segmented trailing icon reveal switches from a ternary rendering hiddenSegmentedTrailingIcon (opacity 0) to CSS group-hover rules with HOVER_GROUP_REVEAL_CLASS_NAME.
  • MenuItem — Background and color styling moved to hoverableStyle; onPointerEnter kept solely for the submenu-switch-while-open logic, onPointerLeave and setHovered removed.
  • inject-css.ts — Wires makeHoverableCSS() into the global injected stylesheet.
  • Browser Studio Playwright test — Hovers "Add Solid" and a menubar item, suppresses pointerleave/mouseleave events at window capture (simulating the iframe boundary bug), moves the pointer away, and asserts backgrounds reset to rgba(0,0,0,0).

Pullfrog  | View workflow run | Using DeepSeek Pro (free via Pullfrog for OSS) (Claude Opus not used — the program covers this model; add its provider key to run your pick) | 𝕏

@JonnyBurger
JonnyBurger merged commit bc37f83 into main Aug 3, 2026
44 of 46 checks passed
@JonnyBurger
JonnyBurger deleted the clear-stale-hover-backgrounds branch August 3, 2026 06:28
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.

@remotion/browser-studio: Clear stale hover backgrounds

1 participant