fix: dismiss session modals when clicking the side margins#4374
fix: dismiss session modals when clicking the side margins#4374brantsrasmus wants to merge 2 commits into
Conversation
SessionModal and SessionProfileModal set their 1320px max width on an inner Column rather than on the Modal itself. The react-zen Modal box (placement="bottom") therefore stretched to the full viewport width (inset-x-0), so its transparent left/right margins sat on top of the underlay and swallowed outside-clicks. Only the thin offset strip above the sheet was dismissable. Move the width onto the Modal box via a CSS module — matching the existing pattern in ReplayModal — so the click-catcher is the centered ~1320px sheet and the side margins become real overlay again. Adds an e2e regression test covering left/right margin dismissal with an in-sheet control click.
|
@brantsrasmus is attempting to deploy a commit to the Umami Software Team on Vercel. A member of the Team first needs to authorize it. |
Greptile SummaryFixes a click-dismiss bug in
Confidence Score: 4/5Safe to merge — the fix is a narrow, well-understood CSS scoping change with a matching e2e regression test. The core fix is correct and follows the existing ReplayModal pattern, but SessionModal does not destructure and merge its className prop before spreading {...props}, meaning a caller that passes className would silently clobber styles.modal and revert the fix. No current caller does this, so there is no immediate breakage, but the inconsistency with ReplayModal is worth tidying before merge. src/app/(main)/websites/[websiteId]/sessions/SessionModal.tsx — className prop merging should follow the ReplayModal pattern. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant User
participant Underlay as react-aria Underlay
participant ModalBox as Modal Box (click-catcher)
participant Dialog
Note over User,Dialog: Before fix — modal box spans full viewport width
User->>ModalBox: clicks side margin (transparent area)
ModalBox-->>User: swallows click (no dismiss)
Note over User,Dialog: After fix — modal box is centered at max 1320px
User->>Underlay: clicks side margin (real underlay)
Underlay->>ModalBox: onDismiss triggered
ModalBox->>Dialog: closes modal
Dialog-->>User: modal dismissed, URL param cleared
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant User
participant Underlay as react-aria Underlay
participant ModalBox as Modal Box (click-catcher)
participant Dialog
Note over User,Dialog: Before fix — modal box spans full viewport width
User->>ModalBox: clicks side margin (transparent area)
ModalBox-->>User: swallows click (no dismiss)
Note over User,Dialog: After fix — modal box is centered at max 1320px
User->>Underlay: clicks side margin (real underlay)
Underlay->>ModalBox: onDismiss triggered
ModalBox->>Dialog: closes modal
Dialog-->>User: modal dismissed, URL param cleared
|
- SessionModal: merge caller-provided className with styles.modal instead
of letting it be clobbered by the {...props} spread (matches ReplayModal).
- e2e test: narrow boundingBox()/viewport nullability without non-null
assertions (keeps biome's noNonNullAssertion happy) via a getSheetBox
helper and a shared VIEWPORT constant.
Problem
The session detail modal (
SessionModal) and session profile modal (SessionProfileModal) can only be dismissed by clicking the thin area above the sheet — clicking the dark space to the left or right of the sheet does nothing.Cause
Both modals apply their
1320pxmax width to an inner<Column>rather than to the<Modal>itself:react-zen's
Modalwithplacement="bottom"renders the react-aria modal box asabsolute inset-x-0 bottom-0 h-[calc(100dvh-offset)]— i.e. full viewport width. react-aria only dismisses on interaction outside that box, but the box's transparent side margins sit on top of the underlay and swallow the click. Only theoffsetstrip above the sheet is real underlay, so only clicks there dismiss.ReplayModal(sameplacement="bottom") is unaffected because it correctly sets the width on the Modal box itself (via a CSS module), so its box is the centered ~1320px sheet.Fix
Move the width from the inner
Columnonto theModalbox via a CSS module, matching the existingReplayModalpattern. The click-catcher box is now the centered sheet, so the side margins become real overlay and dismiss on click.Testing
Adds an e2e regression test (
tests/e2e/session-modal-dismiss.spec.ts) that opens the modal on a wide viewport and asserts left- and right-margin clicks dismiss it, with an in-sheet control click that must keep it open. Verified the test fails ondevwithout this change and passes with it.Need help on this PR? Tag
/codesmithwith what you need. Autofix is disabled.