Skip to content

Ease the context popup's movement when it repositions #172

Description

@Azganoth

Summary

The context popup jumps between positions. Once it repositions against a changing selection, each change moves it a whole step at a time, and while a key repeat holds it moves once per keystroke. Easing that movement would make the popup read as one object following the text rather than a series of placements.

Expected behavior

The popup eases between positions when the selection it anchors to changes, including the repeated steps of a held Shift+Arrow.

Must remain stable: following the document scroll stays immediate, with no lag between the popup and the text it acts on; a popup opening does not animate in from its parked position; and a popup holding focus stays where it is.

Related context

Done when

  • Selection-driven repositioning is eased, including under key repeat.
  • Scrolling still moves the popup with no perceptible lag.
  • Opening the popup does not animate it in from off-screen.
  • Manual verification of all three; automated DOM tests cannot observe the motion.

Notes

Implementation direction

Radix positions through a transform on [data-radix-popper-content-wrapper], computed from React state, so scroll updates and selection updates are indistinguishable in CSS. Easing both would make the popup lag the text during a scroll, which is the one case that must stay immediate. What can tell them apart is the request: a selection change delivers a new one, a scroll does not, and EditorContextPopup.tsx already tracks that in a layout effect. Enabling the transition only while a new request settles is the smallest version.

PopperContent parks the wrapper at translate(0, -200%) until it is first positioned, so the transition must also be inactive for that first placement or the popup slides in from above on open.

Leafdown has no prefers-reduced-motion handling anywhere today. Whether this motion respects it, and whether that answer should apply to the app's existing open and close animations, is a decision this issue should settle rather than assume.

Out of scope

Metadata

Metadata

Assignees

Labels

FeatureNew feature or request

Projects

Status
Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions