-
-
Notifications
You must be signed in to change notification settings - Fork 32
Improve mobile modal UX with bottom sheet style #901
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -47,7 +47,7 @@ export function setTrigger(el: HTMLElement) { | |||||||||
| role="dialog" | ||||||||||
| aria-modal="true" | ||||||||||
| aria-labelledby={titleId} | ||||||||||
| class="z-[2000] flex flex-col overflow-auto border border-gray-300 bg-white p-6 shadow-2xl fixed inset-0 w-full h-full dark:border-white/95 dark:bg-dark md:inset-auto md:top-1/2 md:left-1/2 md:w-80 md:max-h-[90vh] md:h-auto md:rounded-xl md:translate-x-[-50%] md:translate-y-[-50%]" | ||||||||||
| class="z-[2000] flex flex-col overflow-hidden border border-gray-300 bg-white shadow-2xl fixed inset-x-4 bottom-4 max-h-[85dvh] rounded-2xl dark:border-white/95 dark:bg-dark sm:inset-auto sm:top-1/2 sm:left-1/2 sm:w-80 sm:max-h-[90vh] sm:h-auto sm:rounded-xl sm:translate-x-[-50%] sm:translate-y-[-50%] sm:px-6 sm:py-6 px-5 py-5" | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2. Background click-through actions On mobile the modal is no longer full-screen (fixed inset-x-4 bottom-4 ...), but there is no backdrop element to intercept pointer events; taps above the bottom sheet can activate underlying links/buttons and then close the modal via OutClick. This can cause unintended navigation or actions (e.g., footer links behind LanguageModal or app cards behind AppDownloadModal). Agent Prompt
|
||||||||||
| > | ||||||||||
| <div class="mb-4 flex items-center justify-between"> | ||||||||||
| <h2 id={titleId} class="text-lg font-semibold text-primary dark:text-white"> | ||||||||||
|
|
@@ -56,7 +56,9 @@ export function setTrigger(el: HTMLElement) { | |||||||||
| <CloseButton on:click={() => (open = false)} /> | ||||||||||
| </div> | ||||||||||
|
|
||||||||||
| <slot /> | ||||||||||
| <div class="flex-1 overflow-y-auto -mx-5 px-5"> | ||||||||||
|
||||||||||
| <div class="flex-1 overflow-y-auto -mx-5 px-5"> | |
| <div class="min-h-0 flex-1 overflow-y-auto -mx-5 px-5"> |
Copilot
AI
Apr 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The inner wrapper uses -mx-5 px-5 to counteract the modal’s horizontal padding, but the modal padding becomes sm:px-6 on larger screens. Since the inner wrapper doesn’t also switch to 6, the content area will be horizontally misaligned relative to the header on sm+. Make the negative margins/padding responsive as well (e.g., match sm:px-6 with sm:-mx-6 sm:px-6) or remove the negative margins approach.
| <div class="flex-1 overflow-y-auto -mx-5 px-5"> | |
| <div class="flex-1 overflow-y-auto -mx-5 px-5 sm:-mx-6 sm:px-6"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. Modal scroll can be clipped 🐞 Bug ≡ Correctness
The new scroll wrapper is a flex child inside a column flex parent with a max-height, but it lacks min-h-0, so it may not shrink and the parent’s overflow-hidden will clip content instead of allowing scrolling. Any modal whose slot content exceeds max-h-[85dvh] can become partially inaccessible.
Agent Prompt
## Issue description
`Modal.svelte` uses a `flex flex-col` container with `max-h-*` and `overflow-hidden`, and delegates scrolling to an inner `flex-1 overflow-y-auto` wrapper. Without `min-h-0`, the inner flex item may not shrink, so it won’t become scrollable and content gets clipped.
## Issue Context
The modal is used for list-based content (language selection, app store links) where the slot content can exceed the sheet height.
## Fix Focus Areas
- src/components/Modal.svelte[50-61]
## Suggested change
Add `min-h-0` to the scroll container (or to an appropriate flex wrapper) so it can shrink and scroll:
- e.g. `class="min-h-0 flex-1 overflow-y-auto ..."`
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a viewport backdrop/inert layer for true modal behavior.
At Line 50, the dialog is now a floating panel, but there’s no full-screen backdrop layer. With
aria-modal="true", background content should not remain interactable; currently, taps outside the sheet can hit underlying page controls.💡 Suggested structural fix
{`#if` open} - <OutClick on:outclick={() => (open = false)}> + <div class="fixed inset-0 z-[1999] bg-black/40" aria-hidden="true"></div> + <OutClick on:outclick={() => (open = false)}> <div bind:this={modalEl} transition:fly={{ y: 200, duration: 300 }} role="dialog" aria-modal="true" aria-labelledby={titleId} - class="z-[2000] flex flex-col overflow-hidden border border-gray-300 bg-white shadow-2xl fixed inset-x-4 bottom-4 max-h-[85dvh] rounded-2xl dark:border-white/95 dark:bg-dark sm:inset-auto sm:top-1/2 sm:left-1/2 sm:w-80 sm:max-h-[90vh] sm:h-auto sm:rounded-xl sm:translate-x-[-50%] sm:translate-y-[-50%] sm:px-6 sm:py-6 px-5 py-5" + class="z-[2000] fixed inset-x-4 bottom-4 flex flex-col overflow-hidden rounded-2xl border border-gray-300 bg-white shadow-2xl max-h-[85dvh] px-5 py-5 dark:border-white/95 dark:bg-dark sm:inset-auto sm:left-1/2 sm:top-1/2 sm:h-auto sm:w-80 sm:max-h-[90vh] sm:translate-x-[-50%] sm:translate-y-[-50%] sm:rounded-xl sm:px-6 sm:py-6" >🤖 Prompt for AI Agents