Skip to content

fix(react-positioning): improve safe zone hit testing - #36708

Open
JM (Yakubko) wants to merge 2 commits into
microsoft:masterfrom
Yakubko:fix/react-positioning-safe-zone-area
Open

fix(react-positioning): improve safe zone hit testing#36708
JM (Yakubko) wants to merge 2 commits into
microsoft:masterfrom
Yakubko:fix/react-positioning-safe-zone-area

Conversation

@Yakubko

@Yakubko JM (Yakubko) commented Sep 8, 2026

Copy link
Copy Markdown

Previous Behavior

useSafeZoneArea rendered four overlapping SVG triangles around the positioned container. Their geometry was stored in React state, causing the component to rerender repeatedly during pointer movement.

The generated safe zone could also cover more area than necessary because it included every container edge instead of only the edges facing the pointer.

useSafeZoneArea is used by the Fluent UI React Menu and can also be used with Popover to preserve the open state while the pointer travels from the trigger to the positioned surface.

New Behavior

  • Draws a single safe-zone polygon using only the container edges facing the pointer.
  • Updates SVG dimensions and paths imperatively, avoiding React rerenders during pointer movement.
  • Clips only the target element from the safe zone.
  • Keeps the SVG mounted to allow geometry updates without remounting.
  • Improves safe-zone behavior for consumers such as Menu and Popover.
  • Adds focused tests for all pointer directions.
  • Updates the debug story to make the behavior easier to inspect.

Browser Performance Comparison

Captured using the same scenario, browser version, recording duration, and pointer movement.

Before After
Screenshot 2026-09-07 at 13 55 11 Screenshot 2026-09-07 at 13 53 47
Metric Before After
React renders during pointer movement Every RAF 0
Scripting time 79ms 12ms
Rendering time 24ms 11ms

Testing

  • yarn nx run react-positioning:test
    • 24 test suites passed
    • 207 tests passed
    • 4 snapshots passed
  • yarn nx run react-positioning:e2e
    • 7 Cypress tests passed
  • react-positioning lint, type-check, and format checks passed.
  • react-positioning-stories lint, type-check, and format checks passed.

Change File

Includes a patch change file for @fluentui/react-positioning.

Reduce the safe zone to the container edges facing the pointer and update SVG geometry imperatively to avoid rerenders during pointer movement.

Add focused geometry coverage, update the debug story, and include a patch change file.

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.

🟢 Approval recommended

The implementation and tests are sound; only a non-blocking reversed metric in the PR description needs correction.

Pull request overview

Improves safe-zone hit testing while eliminating React rerenders during pointer movement.

Changes:

  • Replaces overlapping triangles with one directional polygon.
  • Updates SVG geometry imperatively and clips only the target.
  • Adds directional geometry tests and refreshes the debug story.

Merge confidence: 100/100. One non-blocking PR-description metric appears reversed.

File summaries
File Description
UseSafeZoneAreaDefault.stories.tsx Makes debug mode configurable.
SafeZoneArea.tsx Implements imperative polygon updates.
SafeZoneArea.styles.ts Renames polygon styles.
getSafeZonePoints.ts Computes facing container edges.
getSafeZonePoints.test.ts Covers eight pointer directions.
computeOutsideClipPath.ts Clips only the target rectangle.
computeOutsideClipPath.test.ts Updates clipping expectations.
SafeZoneArea.test.tsx.snap Updates rendered SVG snapshots.
Change file Records the positioning bug fix.
Review details
  • Files reviewed: 9/9 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

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.

3 participants