[Drawer] It isn't as expected in mobile with SvelteKit
Author: candidosalesCreated Mar 14, 2025Updated Jul 19, 2026
Labelstriage
Describe the bug
The drawer is not working as expected; I can't scroll inside, and the drawer is closing unpredictably. I don't know why. Do you have any assumptions?
My package.json
"devDependencies": {
"@beyonk/svelte-google-analytics": "^2.6.4",
"@playwright/test": "1.49.0",
"@svelte-put/intersect": "^4.0.0",
"@sveltejs/adapter-auto": "4.0.0",
"@sveltejs/adapter-vercel": "5.6.3",
"@sveltejs/kit": "2.19.0",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"@tailwindcss/typography": "^0.5.16",
"@types/gtag.js": "^0.0.20",
"@types/qs": "6.9.17",
"@typescript-eslint/eslint-plugin": "8.25.0",
"@typescript-eslint/parser": "8.25.0",
"autoprefixer": "^10.4.20",
"bits-ui": "1.3.11",
"clsx": "^2.1.1",
"eslint": "9.21.0",
"eslint-config-prettier": "^10.1.1",
"eslint-plugin-svelte": "^3.0.3",
"lucide-svelte": "0.479.0",
"postcss": "8.5.3",
"prettier": "^3.5.3",
"prettier-plugin-svelte": "3.3.3",
"prettier-plugin-tailwindcss": "0.6.11",
"sass": "1.83.0",
"svelte": "5.23.0",
"svelte-check": "4.1.5",
"svelte-google-materialdesign-icons": "^1.0.5",
"tailwind-merge": "^2.6.0",
"tailwind-variants": "^0.3.0",
"tailwindcss": "3.4.17",
"tailwindcss-animate": "^1.0.7",
"tslib": "^2.8.1",
"typescript": "5.7.2",
"vaul-svelte": "1.0.0-next.6",
"vite": "6.2.1",
"vitest": "3.0.6"
},
"type": "module",
"dependencies": {
"@candidosales/svelte-google-translate": "^0.0.15",
"@fontsource/albert-sans": "5.2.5",
"@googlemaps/js-api-loader": "^1.16.8",
"@sentry/cli": "2.42.1",
"@sentry/node": "9.5.0",
"@sentry/svelte": "9.5.0",
"@sentry/sveltekit": "9.5.0",
"@sentry/tracing": "^7.120.3",
"@types/google.maps": "3.58.1",
"@vercel/speed-insights": "^1.2.0",
"meilisearch": "0.49.0",
"prettier-plugin-tailwindcss": "0.6.11",
"qs": "^6.13.1",
"svelte-french-toast": "^1.2.0",
"svelte-local-storage-store": "^0.6.4",
"svelte-markdown": "^0.4.1",
"svelte-meta-tags": "^4.2.0",
"svelte-skeleton": "^1.3.1",
"tailwind-scrollbar-hide": "2.0.0"
}The implementation in +page.svelte.
<script lang="ts">
import Breadcrumb from '$lib/components/base/Breadcrumb.svelte';
import BannerCity from '$lib/components/BannerCity.svelte';
import MetaTagsSeo from '$lib/components/MetaTagsSeo.svelte';
import Link from '$lib/renderers/Link.svelte';
import SvelteMarkdown from 'svelte-markdown';
import CityContent from '$lib/components/CityContent.svelte';
import AdvertisingsPlace from '$lib/components/AdvertisingsPlace.svelte';
import { AdvertisingPlaceType } from '$lib/constants/advertising-places.js';
import { GoogleTranslate } from '@candidosales/svelte-google-translate';
import { GOOGLE_TRANSLATE_LANGUAGES } from '$lib/constants/locale.js';
import ModalGeolocation from '$lib/components/modals/ModalGeolocation.svelte';
import MenuNavigation from '$lib/components/base/MenuNavigation.svelte';
import * as Drawer from '$lib/components/ui/drawer';
import { ImageSize } from '$lib/constants/image-sizes.js';
const { data } = $props();
const renderers = {
link: Link
};
let breadcrumbItems: Array<App.Breadcrumb> = $derived.by(() => {
if (data.city) {
return [
{
url: '/cidades',
name: 'Cidades'
},
{
url: '',
name: data.city.name
}
];
}
return [];
});
let openDrawer = $state(false);
$effect(() => {
if (!openDrawer) {
setTimeout(() => {
cleanBodyStyle();
}, 1000);
}
return () => {
cleanBodyStyle();
};
});
const cleanBodyStyle = () => {
document.body.style = '';
};
</script>
<Drawer.Root bind:open={openDrawer}>
<main class="mx-auto mb-24 max-w-2xl bg-white px-4 py-4 lg:max-w-7xl lg:px-8">
{#if data.city}
<MetaTagsSeo
title={data.city.name ?? ''}
description={data.city.description ?? ''}
images={data.city.images}
/>
<div class="mb-8">
<Breadcrumb items={breadcrumbItems} />
</div>
<h1
data-testid="page-title"
class="page-title mb-4 text-2xl font-bold"
style:--title="title-{data.city.slug}"
>
{data.city.name ?? ''}
</h1>
<div class="mb-8 grid grid-cols-12 gap-4">
<div class="col-span-12 md:col-span-6">
<BannerCity
city={data.city}
showTitle={false}
showOverlay={false}
imageSize={ImageSize.cityBanner}
/>
</div>
<div class="col-span-12 md:col-span-6">
<div class="prose-base mb-4 h-48 overflow-hidden">
<SvelteMarkdown source={data?.city?.description ?? ''} renderers={renderers} />
</div>
<Drawer.Trigger
class="w-full rounded-full border bg-white px-5 py-3 text-base font-bold text-emerald-700 transition-all duration-300 ease-in-out hover:bg-emerald-100 focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:ring-offset-2 md:w-fit"
>Leia mais</Drawer.Trigger
>
<Drawer.Content
class="fixed bottom-0 left-0 right-0 mt-24 flex h-[96%] flex-col rounded-t-[10px] bg-white"
>
<button
class="absolute right-4 top-4 rounded-full border bg-white p-2 opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none"
id="bits-166"
data-dialog-close=""
data-state="open"
onclick={() => openDrawer = false}
><!----><svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
class="lucide-icon lucide lucide-x size-6"
><!----><path d="M18 6 6 18"></path><!----><path d="m6 6 12 12"
></path><!----><!----><!----></svg
><!----> <span class="sr-only">Close</span><!---->
</button>
<div
id="google-translate-element"
class="prose mx-auto flex w-full max-w-lg flex-col overflow-auto rounded-t-[10px] px-8 py-8 lg:prose-lg md:px-0"
>
<Drawer.Title class="text-3xl">{data?.city?.name}</Drawer.Title>
<SvelteMarkdown source={data?.city?.description ?? ''} renderers={renderers} />
<GoogleTranslate options={{ includedLanguages: GOOGLE_TRANSLATE_LANGUAGES }} />
<Drawer.Footer>
<Drawer.Close
class="w-full rounded-full border bg-white px-3 py-2 text-[0.875rem] font-bold text-emerald-700 transition-all duration-300 ease-in-out hover:bg-emerald-100 focus:outline-none focus:ring-2 focus:ring-emerald-500 focus:ring-offset-2"
>Fechar</Drawer.Close
>
</Drawer.Footer>
</div>
</Drawer.Content>
</div>
</div>
{#if data.advertisings && data.advertisings.length > 0}
<AdvertisingsPlace
items={data.advertisings}
place={AdvertisingPlaceType.homeAfterSubmenu}
/>
{/if}
<CityContent data={data} />
<ModalGeolocation />
<MenuNavigation />
{/if}
</main>
</Drawer.Root>Reproduction
You can check here: https://www.turismopiaui.com/cidades/joaquim-pires
Evidence
https://github.com/user-attachments/assets/548616ac-a682-4d71-8001-c50c4dc71d1d
Logs
System Info
System:
OS: macOS 15.3.1
CPU: (10) arm64 Apple M1 Pro
Memory: 88.34 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.14.0 - ~/.nvm/versions/node/v22.14.0/bin/node
Yarn: 4.3.1 - /opt/homebrew/bin/yarn
npm: 10.9.2 - ~/.nvm/versions/node/v22.14.0/bin/npm
pnpm: 10.2.1 - /opt/homebrew/bin/pnpm
bun: 1.2.5 - ~/.bun/bin/bun
Watchman: 2024.12.02.00 - /opt/homebrew/bin/watchman
Browsers:
Chrome: 134.0.6998.89
Safari: 18.3
npmPackages:
@sveltejs/kit: 2.19.0 => 2.19.0
bits-ui: 1.3.11 => 1.3.11
lucide-svelte: 0.479.0 => 0.479.0
svelte: 5.23.0 => 5.23.0
tailwindcss: 3.4.17 => 3.4.17
vaul-svelte: 1.0.0-next.6 => 1.0.0-next.6Severity
annoyance
Source: huntabyte/shadcn-svelte