Code Monkey home page Code Monkey logo

vaul-svelte's Introduction

npm version npm downloads license

Vaul-Svelte is an unstyled drawer component for Svelte that can be used as a Dialog replacement on tablet and mobile devices. It uses Bits' Dialog primitive under the hood and is inspired by this tweet.

This is a port of Vaul for React, which was created by Emil Kowalski.

Usage

To start using the library, install it in your project:

npm install vaul-svelte

Use the drawer in your app.

<script>
	import { Drawer } from "vaul-svelte";
</script>

<Drawer.Root>
	<Drawer.Trigger>Open</Drawer.Trigger>
	<Drawer.Portal>
		<Drawer.Content>
			<p>Content</p>
		</Drawer.Content>
		<Drawer.Overlay />
	</Drawer.Portal>
</Drawer.Root>

Examples

Play around with the examples on StackBlitz:

API Reference

Root

Contains all parts of a dialog. Use shouldScaleBackground to enable background scaling, it requires an element with [data-vaul-drawer-wrapper] data attribute to scale its background. Can be controlled by binding to the open prop, or using theonOpenChange prop.

Additional props:

closeThreshold: Number between 0 and 1 that determines when the drawer should be closed. Example: threshold of 0.5 would close the drawer if the user swiped for 50% of the height of the drawer or more.

scrollLockTimeout: Duration for which the drawer is not draggable after scrolling content inside of the drawer. Defaults to 500ms

snapPoints: Array of numbers from 0 to 100 that corresponds to % of the screen a given snap point should take up. Should go from least visible. Example [0.2, 0.5, 0.8]. You can also use px values, which doesn't take screen height into account.

fadeFromIndex: Index of a snapPoint from which the overlay fade should be applied. Defaults to the last snap point.

direction: Direction of the drawer. Can be top, bottom, left, or right. Defaults to bottom.

backgroundColor: Background color of the body when the drawer is open and shouldScaleBackground is true. Defaults to black.

[data-vaul-no-drag]: When interacting with an element with this data attribute, the drawer won't be dragged.

Trigger

The button that opens the dialog. Props.

Content

Content that should be rendered in the drawer. Props.

Overlay

A layer that covers the inert portion of the view when the dialog is open. Props.

Title

An accessible title to be announced when the dialog is opened. Props.

Description

An optional accessible description to be announced when the dialog is opened. Props.

Close

The button that closes the dialog. Props.

Portal

Portals your drawer into the body.

Sponsors

This project is supported by the following beautiful people/organizations:

Logos from Sponsors

License

Published under the MIT license. Made by @huntabyte and community ๐Ÿ’›

vaul-svelte's People

Contributors

basokant avatar github-actions[bot] avatar huntabyte avatar jeannemas avatar neimadt avatar pheuter avatar shyakadavis avatar turbotobias avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vaul-svelte's Issues

Drawer handle drags the whole window down when using Arc Browser

Describe the bug

Only with Arc Browser, on MacOS, when using the mouse to drag the drawer down and close it, the entire browser windows gets pulled down and the drawer half-closes but remains open.

It does happen only when applying sufficient speed, if slowly, it works as expected.

I'm not sure if this is something that has to be fixed in Vaul or Arc.

Screenshot 2024-03-29 at 11 49 33 Screenshot 2024-03-29 at 11 50 19

Reproduction

On Arc Browser

  1. go on https://www.vaul-svelte.com/
  2. open drawer
  3. drag with mouse with sufficient speed (slowly almost always works)

Logs

No response

System Info

System:
    OS: macOS 14.2.1
    CPU: (12) arm64 Apple M2 Max
    Memory: 4.24 GB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.2.0 - ~/.n/bin/node
    Yarn: 1.22.19 - ~/.npm/bin/yarn
    npm: 9.6.6 - ~/.n/bin/npm
    pnpm: 8.15.1 - ~/.npm/bin/pnpm
  Browsers:
    Brave Browser: 123.1.64.109
    Safari: 17.2.1
  npmPackages:
    @sveltejs/kit: ^2.5.4 => 2.5.4
    bits-ui: ^0.21.1 => 0.21.1
    svelte: ^4.2.12 => 4.2.12
    typescript: ^5.4.3 => 5.4.3
    vaul-svelte: ^0.3.0 => 0.3.0

Severity

annoyance

Svelte 3.x support?

Describe the feature in detail (code, mocks, or screenshots encouraged)

Hey guys, love your work, and everything you do!

Would it be possible to support Svelte 3.x, i'm assuming it's not as simple as downgrading svelte in package.json?

I have a few svelte projects, and some of them are still on 3.x, and can't upgrade to 4 yet.

What type of pull request would this be?

None

Provide relevant links or additional information.

No response

Dragging to close doesn't work on scrollable content

I tried using the example from https://stackblitz.com/edit/vaul-svelte-scrollable-with-inputs in my phone and I couldn't drag the bottomsheet down from the scrollable content to close it.

Steps to reproduce it:

  1. On your phone (or in mobile emulation from chrome devtools) go to https://stackblitz.com/edit/vaul-svelte-scrollable-with-inputs
  2. Click on the button to open the drawer
  3. Drag the bottomsheet from the scrollable content to close it
  4. See error (it gets janky)

API

Describe the feature in detail (code, mocks, or screenshots encouraged)

Thanks for porting this to svelte!

A code-only API (not bound to components) would be tremendously helpful, e.g. for triggering the drawer/modal in shallow routing (sveltekit) or just closing it from an lower component (like a form). Thx!

What type of pull request would this be?

None

Provide relevant links or additional information.

No response

Directions 'left' and 'top' are broken

Describe the bug

Setting direction prop to 'left' or 'top' results in a weird behavior when opening the drawer.

Reproduction

https://stackblitz.com/edit/vaul-svelte-snap-points-1wzvnr?file=src%2Froutes%2F%2Bpage.svelte

Logs

No error

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.3 - /usr/local/bin/pnpm
  npmPackages:
    @sveltejs/kit: ^2.0.0 => 2.0.6 
    svelte: ^4.2.7 => 4.2.8 
    typescript: ^5.0.0 => 5.3.3 
    vaul-svelte: latest => 0.3.0

Severity

annoyance

background: black inline style added to body but not cleaned up

Describe the bug

See repro below. The demo site has an overlay div that makes this problem not visible but in my app the background suddenly turns black after opening the modal.

Screen.Recording.2024-02-23.at.01.30.48.mov

Reproduction

  1. Go to https://www.vaul-svelte.com/
  2. Open web inspector, check body, no inline styles present
  3. Open Drawer, close drawer
  4. Body now has background: black; inline style

Logs

No response

System Info

-

Severity

annoyance

'openFocus' property does not work

Describe the bug

When opening a drawer containing form elements (i.e. textarea) I would like to focus a specific element. Tried to use the openFocus for that reason. But focus is not set. Compared to bits-ui Dialog where all works like expected. I put both usecases in the Stackblitz.

Reproduction

https://stackblitz.com/edit/vitejs-vite-q4c9mb?file=src%2FApp.svelte

Logs

No response

System Info

[email protected]
   System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.3 - /usr/local/bin/pnpm
  npmPackages:
    bits-ui: 0.18.6 => 0.18.6 
    svelte: ^4.2.12 => 4.2.12 
    typescript: ^5.2.2 => 5.3.3 
    vaul-svelte: 0.2.4 => 0.2.4

Severity

annoyance

Ability to keep the drawer always open, slightly ajar

Describe the feature in detail (code, mocks, or screenshots encouraged)

I have a use case for an "always on" mobile navigation that can be expanded to reveal more options.

Since vaul-svelte has the ability to open a drawer at multiple snap points, it could be possible to have a default "closed" / minimized state and a expanded / opened state.

Below is a screenshot of the native drawer UI in Apple maps:

Apple Maps Interactive Globe, by Apple

When the drawer is in this state (closed/minimized), its children are still capable of receiving input (the search field).

Moreover, the drawer wouldn't behave as a modal in the minimized state. This means that users would still be able to interact with the UI elements behind the drawer (the globe).

I'm not exactly sure if the current API can accommodate this behavior, and would like to start a discussion about implementing such a design.

Thank you for your time!

What type of pull request would this be?

Enhancement

Provide relevant links or additional information.

The original React version of vaul closed a similar issue.
Although a solution was suggested, it seems like it isn't accessible and has unexpected behaviors.

bug: open not triggering correctly

Describe the bug

When using the open prop to switch the modal/drawer, after the first open/close, it won't correctly trigger anymore, even blocking scroll.

Reproduction

Use open={true} to init, then close the modal. You will notice that the page behind is not scrollable anymore (chrome latest).

Logs

No response

System Info

System:
    OS: macOS 10.15.7
    CPU: (6) x64 Intel(R) Core(TM) i5-8500 CPU @ 3.00GHz
    Memory: 1.31 GB / 40.00 GB
    Shell: 3.2.57 - /bin/bash
  Binaries:
    Node: 20.11.0 - /usr/local/bin/node
    Yarn: 1.22.17 - /usr/local/bin/yarn
    npm: 7.10.0 - ~/node_modules/.bin/npm
  Browsers:
    Chrome: 121.0.6167.184
    Firefox: 123.0
    Safari: 15.6.1
  npmPackages:
    @sveltejs/kit: ^2.5.0 => 2.5.0 
    bits-ui: ^0.18.1 => 0.18.1 
    svelte: 5.0.0-next.51 => 5.0.0-next.51 
    typescript: ^5.3.3 => 5.3.3 
    vaul-svelte: ^0.2.3 => 0.2.3

Severity

annoyance

Limit on:pointerdown to primary mouse button

Describe the feature in detail (code, mocks, or screenshots encouraged)

The content.svelte component uses on:pointerdown. Any mouse button can trigger this event.

Would it be possible that, if a mouse is triggering the event, to limit it to the primary mouse button?

What type of pull request would this be?

None

Provide relevant links or additional information.

No response

How do you trigger the modal to open without putting the button in Drawer.Root?

Change Type

Addition

Proposed Changes

๐Ÿ‘‹ Based on the example I don't understand how to trigger the dialog to open from other places in my application. Is there some way to trigger the drawer to open programmatically?

I'm trying to make an extendable modal where the content can be injected dynamically, so I need to first set my context to the correct component to put in the modal and then trigger the modal to open, but I don't understand how I can do that with the included Drawer.Trigger component.

(Safari) inconsistent close behavior on escape keydown

Describe the bug

There is no exit animation on the escape button click when we change initial focus.
In the attached video, I'm pressing "esc" to close the panel. The closing animation is smooth when I don't click away from the initial input box. However, when I click on something else, e.g. text below, press esc, then there is no closing animation. Tested on macOS Safari.

Screen.Recording.2024-01-20.at.15.32.31.mov

Reproduction

  1. Open scrollable drawer: https://www.vaul-svelte.com/examples on desktop.
  2. Click away from the initial input box.
  3. Close with esc.

Logs

No response

System Info

macOS Safari.

Note that it works on Chrome on macOS.

Severity

annoyance

Styling with plain CSS?

Change Type

Addition

Proposed Changes

๐Ÿ‘‹ What is the best way to style this without Tailwind? I've ported the demo to normal CSS, is there a way to avoid the :global selector?

I tried prefixing with .wrapper :global(.drawer-overlay) to scope it down but the overlay renders outside the component tree you place it in, so it does not work as it's no longer a descendent of my wrapper.

<script>
	import { Drawer } from 'vaul-svelte';
</script>

<div data-vaul-drawer-wrapper class="wrapper">
	<Drawer.Root shouldScaleBackground>
		<Drawer.Trigger>Open Drawer</Drawer.Trigger>
		<Drawer.Portal>
			<Drawer.Overlay class="drawer-overlay" />
			<Drawer.Content class="drawer-content">
				<div class="content-wrapper">
					<div class="drag-handle" />
					<div class="mx-auto max-w-md">
						<Drawer.Title class="drawer-title">Unstyled drawer for Svelte.</Drawer.Title>
						<p class="paragraph">
							This component can be used as a replacement for a Dialog on mobile and tablet devices.
						</p>
						<p class="paragraph">
							It uses
							<a href="https://www.bits-ui.com/docs/components/dialog" class="link" target="_blank">
								Bits' Dialog primitive
							</a>
							under the hood and is inspired by
							<a
								href="https://twitter.com/devongovett/status/1674470185783402496"
								class="link"
								target="_blank"
							>
								this tweet.
							</a>
						</p>
					</div>
				</div>
				<div class="footer">Hello world 123</div>
			</Drawer.Content>
		</Drawer.Portal>
	</Drawer.Root>
</div>

<style>
	.wrapper {
		min-height: 100vh;
		background-color: white;
	}

	:global(.drawer-overlay) {
		position: fixed;
		inset: 0;
		background-color: rgba(0, 0, 0, 0.4);
	}

	:global(.drawer-content) {
		position: fixed;
		bottom: 0;
		left: 0;
		right: 0;
		margin-top: 24px;
		display: flex;
		height: 96%;
		flex-direction: column;
		border-radius: 10px 10px 0 0;
		background-color: #f4f4f5; /* bg-zinc-100 */
	}

	:global(.content-wrapper) {
		flex: 1;
		border-radius: 10px 10px 0 0;
		background-color: white;
		padding: 16px; /* p-4 */
	}

	.drag-handle {
		margin: 0 auto 32px;
		height: 6px;
		width: 48px;
		flex-shrink: 0;
		border-radius: 9999px;
		background-color: #d4d4d8;
	}

	:global(.drawer-title) {
		margin-bottom: 16px; /* mb-4 */
		font-weight: 500; /* font-medium */
	}

	.paragraph {
		margin-bottom: 8px; /* mb-2, mb-8 */
		color: #71717a; /* text-zinc-600 */
	}

	.link {
		text-decoration: underline;
	}

	.footer {
		margin-top: auto;
		border-top: 1px solid #e4e4e7; /* border-zinc-200 */
		background-color: #f4f4f5; /* bg-zinc-100 */
		padding: 16px; /* p-4 */
	}
</style>

update bits-ui version and svelte support

Describe the feature in detail (code, mocks, or screenshots encouraged)

update versions

What type of pull request would this be?

Other

Provide relevant links or additional information.

No response

Doesn't work after certain svelte 5 version

Describe the bug

It works on svelte version ^5.0.0-next.184

But on ^5.0.0-next.222, it stops working, would be really great if it could be fixed

Reproduction

It works on svelte version ^5.0.0-next.184

But on ^5.0.0-next.222, it stops working, would be really great if it could be fixed

I can't suddenly touch and drag to close the drawer when I update to 222

Logs

No response

System Info

Sveltekit ^5.0.0-next.184

Severity

annoyance

Requires Double Click to Reopen After Swipe Close

Issue Description:

On mobile devices, when I swipe it down to close, I can't reopen it by clicking the button just once; instead, I need to click the button twice. This behavior is inconsistent with the expected behavior, where the drawer should open again with a single click after being closed by swiping down.

Steps to Reproduce:

  1. Open the drawer by clicking the button.
  2. Swipe the drawer down to close it.
  3. Attempt to reopen the drawer by clicking the button.

Expected Behavior:

The drawer should reopen with a single click after being closed by swiping down.

Actual Behavior:

The drawer requires two clicks to reopen after being closed by swiping down or need to click outside to enable the button.

UI Bug

Describe the bug

I have a weird blue rectangle when I open the Drawer for the first time on my IPhone 13 (see image below). This is true for safari, firefox and chrome on my phone. But on desktop everything works fine.

You can also test it for yourself on my website: https://stocknear.com/
Just scroll down please until you see the info svg

WhatsApp Image 2024-01-19 at 17 43 24

Reproduction

<div>
          <Drawer.Root>
            <Drawer.Trigger>
              <label class="text-white text-xl p-4 font-medium flex flex-row items-center">
                Trending
                <svg class="ml-1 mt-0.5 w-5 h-5 inline-block" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg" fill="gray"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"> <title></title> <g id="Complete"> <g id="info-circle"> <g> <circle cx="12" cy="12" data-name="--Circle" fill="none" id="_--Circle" r="10" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"></circle> <line fill="none" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="12" x2="12" y1="12" y2="16"></line> <line fill="none" stroke="gray" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" x1="12" x2="12" y1="8" y2="8"></line> </g> </g> </g> </g></svg>
              </label>
            </Drawer.Trigger>
            <Drawer.Portal>
              <Drawer.Overlay class="fixed inset-0 bg-black/40" />
              <Drawer.Content
                class="fixed bottom-0 left-0 right-0 z-50  mt-24 flex h-auto flex-col rounded-t-[10px] bg-[#191919]"
              >
                <div class="flex-1 rounded-t-[10px] bg-[#191919] p-4">
                  <div class="mx-auto mb-8 h-1.5 w-20 flex-shrink-0 rounded-full bg-[#404040]" />
                  <div class="max-w-md m-auto text-center mb-10">
                    <Drawer.Title class="text-white text-xl mb-2 font-medium">
                      Trending
                    </Drawer.Title>
                    <p class="mb-10 text-white">
                      Explore today's market highlights, including top gainers, losers and the most actively traded stocks.
                    </p>

                      <Drawer.Close>
                        <label class="px-7 py-2 rounded-full border border-[#0DDE00] bg-[#0DDE00] text-center text-black">
                          OK
                        </label>
                      </Drawer.Close>
                    
                  </div>
                </div>
              </Drawer.Content>
            </Drawer.Portal>
          </Drawer.Root>
        </div>

Logs

No response

System Info

System:
    OS: Linux 6.5 Ubuntu 22.04.3 LTS 22.04.3 LTS (Jammy Jellyfish)
    CPU: (16) x64 AMD Ryzen 7 1700 Eight-Core Processor
    Memory: 7.94 GB / 15.55 GB
    Container: Yes
    Shell: 5.1.16 - /bin/bash
  Binaries:
    Node: 18.17.1 - /usr/bin/node
    npm: 9.6.7 - /usr/bin/npm
    bun: 1.0.23 - /snap/bin/bun
  Browsers:
    Chrome: 120.0.6099.224
  npmPackages:
    @sveltejs/kit: ^1.28.0 => 1.30.3 
    svelte: ^4.2.0 => 4.2.8 
    typescript: ^5.1.3 => 5.3.3 
    vaul-svelte: ^0.0.7 => 0.0.7

Severity

annoyance

Is there a way to subscribe to the drawer's closed percentage?

Describe the feature in detail (code, mocks, or screenshots encouraged)

The scale background feature transition is absolutely beautiful and it's based on the drawer's closed percentage, but my app has a different glowy effect that appears when the drawer is open and disappears when it's closed. I have it running with a simple svelte transition:fade but that's not nearly as cool as what you have setup. I'd love to have the opacity react with the drawer's percentage closed but can't figure it out for the life of me. Is there any way to bind to this variable or a hacky solution of any kind?

I would greatly appreciate a push in the right direction.

Thank you for this amazing package ๐Ÿ˜€

What type of pull request would this be?

Docs

Provide relevant links or additional information.

No response

Children does not exist on Props

Describe the bug

Using this with shadcn-svelte, however the prop children doesn't exist.
2024-03-13 at 11 01 34

The drawer still works, but building the app fails because of the type checking.

Reproduction

<script lang="ts>
...

import * as Drawer from '$lib/components/ui/drawer'
</script>

...
<Drawer.Root>
	<Drawer.Trigger>
		<Button>Click Me</Button>
	</Drawer.Trigger>
	<Drawer.Content>
		<Drawer.Header>
			<Drawer.Title>Are you sure absolutely sure?</Drawer.Title>
			<Drawer.Description>This action cannot be undone.</Drawer.Description>
		</Drawer.Header>
	</Drawer.Content>
</Drawer.Root>

drawer.svelte

<script lang="ts">
	import { Drawer as DrawerPrimitive } from 'vaul-svelte';

	type $$Props = DrawerPrimitive.Props;
	export let shouldScaleBackground: $$Props['shouldScaleBackground'] = true;
	export let open: $$Props['open'] = false;
	export let activeSnapPoint: $$Props['activeSnapPoint'] = undefined;
</script>

<DrawerPrimitive.Root {shouldScaleBackground} bind:open bind:activeSnapPoint {...$$restProps}>
	<slot />
</DrawerPrimitive.Root>

Logs

none

System Info

System:
    OS: macOS 14.4
    CPU: (12) arm64 Apple M2 Pro
    Memory: 123.91 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.10.0 - ~/.nvm/versions/node/v20.10.0/bin/node
    Yarn: 1.22.21 - ~/.nvm/versions/node/v20.10.0/bin/yarn
    npm: 10.2.3 - ~/.nvm/versions/node/v20.10.0/bin/npm
    pnpm: 8.11.0 - ~/.nvm/versions/node/v20.10.0/bin/pnpm
  Browsers:
    Chrome: 122.0.6261.112
    Edge: 122.0.2365.80
    Safari: 17.4

Severity

annoyance

Portal prop doesn't do anything

Describe the bug

Thanks for a great lib!

I'm trying to render the dialog on the main tag instead of the body.
<main id="main> ...
I've tried to pass 'main' to the portal prop but it doesn't do anything, it always renders on the body. I also tried to pass the element but same issue there.

To be able to use my theme colors in the dialog it needs to be rendered inside my theme wrapper which is inside the body in my setup.

Reproduction

https://stackblitz.com/edit/vaul-svelte-scaled-sj4vif?file=src%2Froutes%2F%2Bpage.svelte

Logs

No response

System Info

System:
    OS: macOS 14.1.2
    CPU: (8) arm64 Apple M1 Pro
    Memory: 89.36 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.18.0 - ~/.nvm/versions/node/v18.18.0/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 9.8.1 - ~/.nvm/versions/node/v18.18.0/bin/npm
  Browsers:
    Chrome: 120.0.6099.216
    Safari: 17.1.2
  npmPackages:
    @sveltejs/kit: ^2.0.3 => 2.0.3 
    svelte: ^4.2.8 => 4.2.8 
    typescript: ^5.3.3 => 5.3.3 
    vaul-svelte: ^0.0.7 => 0.0.7

Severity

annoyance

Animation Stops Working When Programmatically Opening and Closing Drawer

Describe the bug

I've encountered an issue where the animation for the drawer component ceases to function after programmatically opening and closing it. When using the Drawer.Trigger method, the animations perform as expected, smoothly opening and closing the drawer. However, when I attempt to control the drawer's visibility through direct programmatic methods, the animation no longer works. The drawer still opens and closes but without the intended animation, resulting in a less fluid user experience.

Reproduction

https://stackblitz.com/edit/vitejs-vite-pzyvfm?file=src%2FApp.svelte

Logs

No response

System Info

System:
    OS: macOS 14.3
    CPU: (10) arm64 Apple M2 Pro
    Memory: 113.78 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.19.0 - 
    npm: 10.2.5 - 
    pnpm: 8.15.0 -
  Browsers:
    Chrome: 121.0.6167.139
    Safari: 17.3
  npmPackages:
    @sveltejs/kit: ^2.3.3 => 2.3.3 
    svelte: 4.2.8 => 4.2.8 
    typescript: ^5.3.3 => 5.3.3 
    vaul-svelte: ^0.2.2 => 0.2.2

Severity

annoyance

Bug: Closing drawer programatically leads to no exit transition

Issue Description:

On mobile devices, changing the open prop/using Drawer.Close (e.g., using the close button in the drawer) breaks the exit transition and no animation is seen.

Steps to Reproduce:

  1. Open the drawer by clicking the button on the shadcn-svelte website from a mobile device.
  2. Click on Edit Profile.
  3. Click on the cancel button in the footer section.

Expected Behavior:

The drawer should close with the appropriate exit animation (sliding down).

Actual Behavior:

No exit transition is seen and drawer jumps back to closed state.

Missing type definitions for `Close`, `Content`, `Trigger` components from library

Describe the bug

As mentionned (as an example) here sveltejs/language-tools#2371, VaulSvelte is missing type definitions for the Close, Content and Trigger components, as can be seen in the picture down below:

Screenshot 2024-05-20 at 13 07 47

Reproduction

No real repro, but you can follow the demo/example on sveltejs/language-tools#2371

Logs

No response

System Info

System:
    OS: macOS 14.5
    CPU: (8) arm64 Apple M2
    Memory: 80.41 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 22.1.0 - ~/.nvm/versions/node/v22.1.0/bin/node
    Yarn: 1.22.19 - ~/Library/pnpm/yarn
    npm: 10.7.0 - ~/.nvm/versions/node/v22.1.0/bin/npm
    pnpm: 9.1.0 - ~/Library/pnpm/pnpm
    bun: 0.1.6 - ~/.bun/bin/bun
  Browsers:
    Chrome: 124.0.6367.209
    Safari: 17.5

Severity

blocking an upgrade

Input gets hidden on bind:value

Describe the bug

First of all, I thank u for ur work and videos. They are the best!

When on:input or bind:value used, the last input gets hidden by the mobile keyboard once user types in.

Alternative Solution to use on:change instead but it ain't ideal since I wanna trigger e.g a button enabled if form input gets a new value.

<script lang="ts">

       let value = {
		value1: '',
		value2: '',
		value3: '',
	};

	function onChange(event: Event, v: string) {
		const target = event.target as HTMLInputElement;
		value[v] = target.value;
	}
</script>
	
<input
	class="my-8 border border-gray-400"
	placeholder="Input"
	on:change={(e) => onChange(e, 'value1')}
/>

Reproduction

Here is the sandboxed project

<script lang="ts">
    import { Drawer } from 'vaul-svelte';

    let value1: string;
    let value2: string;
    let value3: string;
</script>

<Drawer.Root>
    <Drawer.Trigger>Open Drawer</Drawer.Trigger>
    <Drawer.Overlay class="fixed inset-0 bg-black/40" />
    <Drawer.Content
        class="fixed bottom-0 left-0 right-0 flex max-h-[96%] flex-col rounded-t-[10px] bg-white"
    >
        <div class="mx-auto flex w-full max-w-md flex-col overflow-auto rounded-t-[10px] p-4">
            <input class="my-8 border border-gray-400" placeholder="Input" bind:value={value1} />
            <p>
                But I must explain to you how all this mistaken idea of denouncing pleasure and praising
                pain was born and I will give you a complete account of the system, and expound the actual
                teachings of the great explorer of the truth, the master-builder of human happiness. No one
                rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who
                do not know how to pursue pleasure rationally encounter consequences that are extremely
                painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself,
                because it is pain, but because occasionally circumstances occur in which toil and pain can
                procure him some great pleasure. To take a trivial example, which of us ever undertakes
                laborious physical exercise, except to obtain some advantage from it? But who has any right
                to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences,
                or one who avoids a pain that produces no resultant pleasure?
            </p>
            <input class="my-8 border border-gray-400" placeholder="Input" bind:value={value2} />
            <p>
                On the other hand, we denounce with righteous indignation and dislike men who are so
                beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that
                they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to
                those who fail in their duty through weakness of will, which is the same as saying through
                shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a
                free hour, when our power of choice is untrammelled and when nothing prevents our being able
                to do what we like best, every pleasure is to be welcomed and every pain avoided. But in
                certain circumstances and owing to the claims of duty or the obligations of business it will
                frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man
                therefore always holds in these matters to this principle of selection: he rejects pleasures
                to secure other greater pleasures, or else he endures pains to avoid worse pains.
            </p>
            <input bind:value={value3} class="my-8 border border-gray-400" placeholder="Input" />
        </div>
    </Drawer.Content>
</Drawer.Root>
RPReplay_Final1724180643.MP4

Logs

No response

System Info

Test: Iphone 11 (IOS 17.5.1)

Severity

annoyance

Mouse selection doesn't work inside Vaul

Describe the bug

Hi! Thanks for the awesome port.

Mouse selection doesn't seem to work inside Vaul content component. Is there any way to make it work? Potentially by disabling close gesture (or making it work only at the top of the drawer)?

Reproduction

Try to select any text in demo Vaul: https://www.vaul-svelte.com/examples.

Logs

No response

System Info

System:
    OS: macOS 14.2.1
    CPU: (8) arm64 Apple M1 Pro
  Browsers:
    Safari: 17.2.1

Severity

annoyance

Nested Drawer drag close also closes the parent drawer.

Describe the bug

When we use nested drawer and we use drag close on nested drawer it also closes parent drawer.

Issue: https://stackblitz.com/edit/vaul-svelte-nested-drawers?file=src%2Froutes%2F%2Bpage.svelte - Svelte Version

Screen.Recording.2024-07-29.at.11.50.58.AM.mov

Expected Behaviour: https://codesandbox.io/p/devbox/drawer-non-dismissable-forked-5z2r3j?file=%2Fapp%2Fmy-drawer.tsx - React version

Screen.Recording.2024-07-29.at.11.51.18.AM.mov

Reproduction

Use https://www.vaul-svelte.com/examples - nested drawer here and you will see when closing nested drawer by drag also closes parent drawer.

Logs

No response

System Info

System:
    OS: macOS 14.3
    CPU: (10) arm64 Apple M2 Pro
    Memory: 81.92 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
    npm: 10.4.0 - ~/.nvm/versions/node/v20.11.0/bin/npm
    pnpm: 9.4.0 - ~/Library/pnpm/pnpm
    bun: 1.1.7 - ~/.bun/bin/bun
  Browsers:
    Brave Browser: 126.1.67.123
    Chrome: 126.0.6478.183
    Safari: 17.3
    Safari Technology Preview: 17.4
  npmPackages:
    @sveltejs/kit: ^2.5.18 => 2.5.18 
    bits-ui: ^0.21.12 => 0.21.12 
    svelte: ^4.2.18 => 4.2.18 
    typescript: ^5.5.4 => 5.5.4 
    vaul-svelte: ^0.3.2 => 0.3.2 

- Tested on chrome only.

Severity

blocking all usage of vaul-svelte

Support `[data-vaul-no-drag]` to prevent dragging on specific elements

Describe the feature in detail (code, mocks, or screenshots encouraged)

The React version of Vaul recently added support to disable dragging on specific elements. I'm currently experiencing issues with drag on inputs - when I drag and release above an input, the input gets focused and the scroll does a jagged snap.

[data-vaul-no-drag]: When interacting with an element with this data attribute, the drawer won't be dragged.
https://arc.net/l/quote/fvdgmtwh

What type of pull request would this be?

New Feature

Provide relevant links or additional information.

https://arc.net/l/quote/fvdgmtwh
https://github.com/emilkowalski/vaul#root

Drawer closes when I click on a button inside it

Describe the bug

I have a Drawer with multiple buttons inside it. None of them are programmed to close the drawer but when I click on any of them the drawer closes.

Reproduction

Here's my code (+page.svelte):

<Drawer.Root bind:open={$isDrawerOpen}>
	<Player {musics} {length} cover={album.cover} {raf} />
</Drawer.Root>

And the child component that contains the drawer content (player.svelte):

<Drawer.Portal>
	<Drawer.Overlay class="fixed inset-0 bg-black/40" />
	<Drawer.Content
		class="hidden md:grid bodrer-t-gray-5 fixed bottom-0 left-0 right-0 grid grid-cols-[2fr_2fr_5fr_1fr] items-center justify-between gap-4 rounded-t-md border-t bg-gray-1 px-4 py-6"
	>
		<div class="flex items-center gap-2">
			<Button
				intent="ghost"
				size="icon"
				on:click={() => prevTrack(musics, length)}
			>
				<SkipBack />
			</Button>
			<Button
				intent="primary"
				rounded="full"
				size="icon"
				on:click={() => playPauseTrack(raf)}
				disabled={$isLoading}
			>
				{#if $isLoading}
					<Loader2Icon class="animate-spin" />
				{:else if $isPlaying}
					<Pause />
				{:else}
					<Play />
				{/if}
			</Button>
			<Button
				intent="ghost"
				size="icon"
				on:click={() => nextTrack(musics, length)}
			>
				<SkipForward />
			</Button>
			<Button intent="ghost" size="icon">
				<Heart />
			</Button>
		</div>
	</Drawer.Content>
</Drawer.Portal>

None of the buttons change the value of $isDrawerOpen so I don't understand why it still closes the drawer.

Logs

No response

System Info

System:
    OS: Linux 6.6 Ubuntu 23.10 23.10 (Mantic Minotaur)
    CPU: (12) x64 12th Gen Intel(R) Core(TM) i7-1255U
    Memory: 4.68 GB / 15.33 GB
    Container: Yes
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.10.0 - /usr/local/bin/node
    npm: 10.2.5 - /usr/local/bin/npm
    pnpm: 8.13.1 - /usr/local/bin/pnpm
  Browsers:
    Chrome: 120.0.6099.109
  npmPackages:
    @sveltejs/kit: ^2.0.0 => 2.5.1 
    bits-ui: ^0.19.7 => 0.19.7 
    svelte: 4.2.12 => 4.2.12 
    typescript: ^5.0.0 => 5.3.3 
    vaul-svelte: ^0.3.0 => 0.3.0

Severity

annoyance

SvelteKit and Vite CSS :global Error

Whenever I try to use the Drawer.Root component in your port of shadcn-svelte, it throws an error like this:

[plugin:vite-plugin-svelte] {{PROJECT ROOT}}/node_modules/vaul-svelte/dist/vaul/components/root.svelte:145:9 Expected a valid CSS identifier
{{PROJECT ROOT}}/node_modules/vaul-svelte/dist/vaul/components/root.svelte:145:9

143|  	}
144|  
145|  	:global(
   |           ^
146|  			[data-vaul-overlay][data-vaul-snap-points='true']:not(
147|  					[data-vaul-snap-points-overlay='true']

Use of Portal

Change Type

Addition

Proposed Changes

Can you confirm if the portal prop is supported to target a different rendering location and how we use it, I'm currently trying:

<Drawer.Root bind:open={dialogOpen} portal="#app"> but it doesn't seem to work

(Safari) Dragging no longer works in Safari.

Describe the bug

It looks like the newest release broke dragging in Safari (macOS). Dragging works as expected on Chrome.

Reproduction

Go to https://www.vaul-svelte.com, open drawer, try dragging from top in Safari.

Logs

No response

System Info

Browsers:
    Safari: 17.3
  npmPackages:
    @sveltejs/kit: ^2.5.0 => 2.5.0
    bits-ui: ^0.16.0 => 0.16.0
    svelte: ^4.2.9 => 4.2.9
    typescript: ^5.3.3 => 5.3.3
    vaul-svelte: ^0.2.1 => 0.2.1

Severity

annoyance

Adding snapPoints breaks scrolling into view for inputs when keyboard opens

Describe the bug

when you add snapPoints (even just one), to the drawer , if you have a form, then when you open the keyboard, the focused input does not scroll into view.

I would also say that the scrolling action (when working) is very aggressive, i.e. it scrolls the content so much that the input in focus is hard aligned to the top of the drawer. Would it be possible to knock that back a notch!?

Reproduction

Stackblitz will not reproduce because you cannot open on a mobile

Logs

No response

System Info

System:
    OS: Linux 6.1 Amazon Linux 2023
    CPU: (4) x64 AMD EPYC 7571
    Memory: 5.47 GB / 15.45 GB
    Container: Yes
    Shell: 5.2.15 - /bin/bash
  Binaries:
    Node: 20.11.0 - ~/.nvm/versions/node/v20.11.0/bin/node
    Yarn: 1.22.19 - ~/.npm-global/bin/yarn
    npm: 8.15.1 - ~/.npm-global/bin/npm
    pnpm: 8.15.0 - ~/.local/share/pnpm/pnpm
  npmPackages:
    svelte: ^4.2.8 => 4.2.8 
    typescript: ^5.3.3 => 5.3.3

Observed both with chrome and safari on iPhone.

Severity

annoyance

Scrollable drawers have a bad frame rate when dragging

Describe the bug

This is happening on in Chrome on Android and destroys the silky smooth authentic.

Any thoughts on a fix?

Reproduction

The scrollable example has the problem

Logs

No response

System Info

Android

Severity

annoyance

close on outside click doesn't work for nested drawers

Describe the bug

if there is a drawer in another drawer clicking outside for either Drawer.Content won't do anything

Reproduction

https://stackblitz.com/edit/vaul-svelte-nested-drawers

open stackblitz, open drawer and click outside

Logs

No response

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.3 - /usr/local/bin/pnpm
  npmPackages:
    @sveltejs/kit: ^2.0.0 => 2.0.6 
    svelte: ^4.2.7 => 4.2.8 
    typescript: ^5.0.0 => 5.3.3 
    vaul-svelte: latest => 0.3.0


### Severity

annoyance

Drawer disappear on iOS when using an input with bind:value

Describe the bug

Drawer disappear on Safari on iPhone when having an input inside the drawer with a bind:value. I have added a minimal reproduction for this.

The same issue appears when using shadcn-svelte and the drawer component.

Video showing the reproduction of this bug

RPReplay_Final1710677900.MP4

Reproduction

  • Start a new Svelte kit Project
  • Install vaul -> npm install vaul svelte
  • Copy paste the snippet below into root +page.svelte
  • Run npm run dev --host and use the Network address to open the site on your iPhone
<script>
	import { Drawer } from 'vaul-svelte';

	let value = '';
</script>

<div data-vaul-drawer-wrapper style="background: #fff; height: 100dvh;">
	<h1>Welcome to SvelteKit</h1>
	<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>

	<Drawer.Root shouldScaleBackground>
		<Drawer.Trigger>Open Drawer</Drawer.Trigger>
		<Drawer.Portal>
			<Drawer.Overlay style="position: fixed; background: #00000040; inset: 0;" />
			<Drawer.Content style="position: fixed; bottom: 0px; left: 0px; right: 0px;">
				<div style="border-radius: 25px 25px 0 0; background: #fff; padding: 12px;">
					<p>Content</p>
					<label>
                        Without binded value
						<input style="font-size: 16px;" />
					</label>
					<label>
						With binded value
						<input style="font-size: 16px;" bind:value />
					</label>
				</div>
			</Drawer.Content>
			<Drawer.Overlay />
		</Drawer.Portal>
	</Drawer.Root>
</div>

Logs

No response

System Info

iPhone 12 Pro
iOS: 17.3.1

Severity

blocking all usage of vaul-svelte

Cannot scroll to all examples on mobile devices

Describe the bug

On the examples page https://www.vaul-svelte.com/examples a device with a height smaller than ~ 780px cannot reach all the examples because the page cannot be scrolled.

Removing overflow: hidden from html and body while also removing min-height: 4000px; from body should fix this.

I am curious.

Why is min-height: 4000px; set on the body and why did you opt to remove vertical scrollbars from the example page ?

Reproduction

Screenshot_20240606_180752

Open https://www.vaul-svelte.com/examples in any browser and minimize the viewport height under ~ 780px.

Logs

no logs

System Info

no system info

Severity

annoyance

Possible to associate triggers with content

Describe the feature in detail (code, mocks, or screenshots encouraged)

Maybe this is already possible - apologies if it is.

It would be good to have a way to:

  • have multiple triggers and content, each having an association, or link - similar to a Label and input field.

image

That way, using the above image as an example a menu of drawer options (triggers and content) would be possible.

What type of pull request would this be?

Enhancement

Provide relevant links or additional information.

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.