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
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
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
MilkdownEditor.cssunder.leafdown-context-popup; the transform this would ease belongs to the Radix-owned wrapper around it.Done when
Notes
Implementation direction
Radix positions through a
transformon[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, andEditorContextPopup.tsxalready tracks that in a layout effect. Enabling the transition only while a new request settles is the smallest version.PopperContentparks the wrapper attranslate(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-motionhandling 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