Skip to content

fix(staged): improve mobile full-screen dialogs#865

Merged
matt2e merged 8 commits into
mainfrom
full-screen-mobile-dialogs
Jul 7, 2026
Merged

fix(staged): improve mobile full-screen dialogs#865
matt2e merged 8 commits into
mainfrom
full-screen-mobile-dialogs

Conversation

@matt2e

@matt2e matt2e commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary:

  • Render mobile dialogs full-screen with safe-area and keyboard inset handling.
  • Keep alert dialogs compact and preserve dialog-specific styling on mobile.
  • Add viewport resizing support for the on-screen keyboard.

matt2e and others added 8 commits July 7, 2026 16:43
On narrow viewports (viewport.isMobile, 768px), Dialog.Content now renders
as an edge-to-edge full-screen panel instead of a centered card. Geometry
(position, inset, sizing, transform, radius, 100dvh height) is applied via
inline style so it cleanly overrides per-modal sizing classes without
specificity fights, while the structural classes callers pass (flex/p-0/
gap-0/overflow-hidden/drag-over border) are preserved. Safe-area padding
keeps the header/footer clear of notches and home indicators, and the
entrance animation slides up from the bottom on mobile while keeping zoom
on desktop.

dialog-content now calls watchViewport() on mount so viewport.isMobile
stays live even if the host screen never subscribed, and a new
fullScreenOnMobile prop (default true) lets a dialog opt out.

The default applies to NewSessionModal, SessionModal, NewProjectModal,
AddRepoModal, RenameBranchDialog, NoteModal, ActionOutputModal and
ImageViewerModal with no per-modal changes. DiffModal builds its own modal
(no dialog primitives) and the alert-dialog family uses a separate content
component, so confirmations stay centered and DiffModal is unaffected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Part 2 of the full-screen mobile dialog work. When the soft keyboard
opens, a 100dvh full-screen dialog does not shrink (the default
interactive-widget=resizes-visual), so the keyboard overlays the action
footer and hides the buttons. This pins the footer to the keyboard's top
edge with the body scrolling above it.

New src/lib/shared/keyboardInset.svelte.ts mirrors viewport.svelte.ts: it
tracks window.visualViewport resize/scroll, computes the keyboard height as
max(0, innerHeight - vv.height - vv.offsetTop), and publishes it both as
reactive `keyboard.inset` state and as a `--keyboard-inset` CSS custom
property on :root. watchKeyboardInset() wires the listeners and returns an
unsubscribe that tears them down and resets the inset. When
window.visualViewport is undefined (older/desktop webviews) the inset stays
0 and behaviour is unchanged.

dialog-content.svelte's mobile/full-screen branch now sets
height:calc(100dvh - var(--keyboard-inset, 0px)) and calls
watchKeyboardInset() on mount alongside watchViewport(), cleaning up both.
Existing safe-area padding is kept, so the footer clears the home indicator
while sitting on the keyboard's top edge.

No structural changes to the modals: NewSessionModal and SessionModal
already use a header / scrollable-body / pinned-footer flex column. The
prompt editor and transcript scrollers gain overscroll-behavior:contain so
momentum doesn't chain to the page behind the dialog, and NewSessionModal's
form-actions footer is marked flex-shrink:0 so it stays pinned.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Step 4 of the full-screen mobile dialog work: a Chromium-only enhancement
layered on top of the Part 2 visualViewport solution (089bd50e).

The viewport meta's content gains `interactive-widget=resizes-content`,
appended after the existing tokens (including user-scalable=no), which are
left intact. On Chromium-based engines this shrinks the layout viewport when
the soft keyboard opens, so a 100dvh full-screen dialog fits above the
keyboard without relying on the JS-driven --keyboard-inset fallback. iOS
Safari/WKWebView ignore the token and continue to use the Part 2
keyboardInset mechanism, which is unchanged.

Purely additive and harmless: no behavioural change on engines that don't
support the token, and no code changes elsewhere.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Use a dedicated alert dialog theme surface so alerts render white in light themes and on the lifted dark surface in dark themes. Constrain alert dialog width with mobile gutters so they remain compact instead of reading as full-screen dialogs.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Destructure caller-provided style props before spreading Dialog.Content rest props, then merge them with the mobile full-screen geometry. This prevents rest props from replacing the keyboard-aware full-screen styles while keeping custom inline styles available.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
Start dragging the Tauri window from full-screen dialog header regions, matching the normal top bar behavior while preserving interactive controls and caller pointer handlers.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
Align the new-session dialog footer controls with the 768px full-screen mobile breakpoint so the compact layout is used across the full mobile range. Give the submit button an explicit appearance-free accent fill to avoid WebKit/native button paint showing over the bottom edge.

Signed-off-by: Matt Toohey <contact@matttoohey.com>
@matt2e
matt2e requested review from baxen and wesbillman as code owners July 7, 2026 07:15
@matt2e
matt2e merged commit 0158f44 into main Jul 7, 2026
4 checks passed
@matt2e
matt2e deleted the full-screen-mobile-dialogs branch July 7, 2026 08:17
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.

1 participant