The popover scaffold — Portal + panelRef + pos signal + getBoundingClientRect() + makeEventListener(document, ...) for outside-click + keydown for Escape — is now duplicated across four sites:
| File |
Lines |
packages/client/src/settings/SettingsPopover.tsx |
60-87 |
packages/client/src/terminal/PrUnavailablePopover.tsx |
114-140 |
packages/client/src/recorder/RecordPopover.tsx |
50-89 |
packages/client/src/right-panel/CodeFilterBar.tsx |
50-90 |
PrUnavailablePopover.tsx:6 even acknowledges "Portal + click-outside + Escape mirror SettingsPopover" — the duplication has been recognized in-tree.
Each call site reimplements a viewport-clamp formula (Math.max(8, Math.min(rect.left, innerWidth - panelWidth - 8))) with hardcoded 8px pad. CodeFilterBar promotes it to VIEWPORT_PAD.
A useAnchoredPopover({ triggerRef, onDismiss, panelMinWidth }) hook returning { panelRef, style, isOpen, open, close } would absorb ~30 lines per call site and unify the clamp.
Alternative: adopt @corvu/popover (Corvu is already in the project for dialog, tooltip, drawer, resizable) which provides positioning, outside-click, escape, portal, aria out of the box.
Out of scope for #791 — that PR added the 4th instance; this issue tracks the extraction.
Filed from the /do simplify pass on PR #791.
The popover scaffold —
Portal+panelRef+possignal +getBoundingClientRect()+makeEventListener(document, ...)for outside-click +keydownfor Escape — is now duplicated across four sites:packages/client/src/settings/SettingsPopover.tsxpackages/client/src/terminal/PrUnavailablePopover.tsxpackages/client/src/recorder/RecordPopover.tsxpackages/client/src/right-panel/CodeFilterBar.tsxPrUnavailablePopover.tsx:6even acknowledges "Portal + click-outside + Escape mirror SettingsPopover" — the duplication has been recognized in-tree.Each call site reimplements a viewport-clamp formula (
Math.max(8, Math.min(rect.left, innerWidth - panelWidth - 8))) with hardcoded 8px pad.CodeFilterBarpromotes it toVIEWPORT_PAD.A
useAnchoredPopover({ triggerRef, onDismiss, panelMinWidth })hook returning{ panelRef, style, isOpen, open, close }would absorb ~30 lines per call site and unify the clamp.Alternative: adopt
@corvu/popover(Corvu is already in the project fordialog,tooltip,drawer,resizable) which provides positioning, outside-click, escape, portal, aria out of the box.Out of scope for #791 — that PR added the 4th instance; this issue tracks the extraction.
Filed from the
/dosimplify pass on PR #791.