Skip to content

Conversation

@weepaho3
Copy link

@weepaho3 weepaho3 commented Jan 2, 2026

Summary

Introducing a center direction and refactors the CSS/JS positioning logic to enable smooth, morphing transitions between all drawer directions (e.g., bottom <-> center ).

This allows developers to create responsive dialogs that maintain state (like form inputs) when resizing the window, offering a significantly better UX than the current standard practice.

Problem

Currently, the standard approach for "Responsive Dialogs" (as seen in the shadcn/ui examples) relies on conditional rendering:

// Current standard approach
if (isDesktop) {
  return <Dialog open={open}><ProfileForm /></Dialog>
}
return <Drawer open={open}><ProfileForm /></Drawer>

Issues with this approach:

  1. State Loss: When resizing from mobile to desktop, the component tree changes. The Drawer unmounts and the Dialog mounts. Any state (e.g., text typed into an <input> is lost.
  2. No Transition: The switch is abrupt. There’s no animation between directions.
  3. DX/Boilerplate: Requires maintaining two separate wrapper components.

💡 The Solution

Since vaul is built on top of Radix/Base UI Dialog primitives, we can handle the "Desktop Modal" state directly within vaul by adding a center direction.

By unifying the CSS transform logic for all directions, we can now simply change the direction prop dynamically:

const isMobile = useIsMobile()

return (
  <Drawer.Root direction={isMobile ? "bottom" : "center"}>
    <Drawer.Content>
       {/* State is preserved during resize! */}
       <ProfileForm />
    </Drawer.Content>
  </Drawer.Root>
)

🛠️ Changes

1. Unified Coordinate System

Previously, different directions used different CSS properties (top, bottom, left, right) which made CSS transitions between them impossible.
I refactored style.css so that all directions (including the new center) use a unified transform: translate3d(...) approach relative to consistent offsets (e.g., 50%).

2. center Direction

Added support for direction="center". This mimics a standard modal dialog behavior but keeps the vaul context alive.

3. Morphing vs. Entry Animation

Added a data-vaul-drawer-morphing attribute.

  • Initial Open: Plays the standard slide-in animation.
  • Resize/Prop Change: Disables the keyframe animation and uses a fluid CSS transition to "morph" the drawer to its new position (e.g., sliding from bottom to center).

4. Drag Logic Update

Updated the JS drag calculations (onDrag, resetDrawer) to respect the new CSS offsets, ensuring dragging works correctly.

Demo

I have added an responsive example to the example page.

@vercel
Copy link
Contributor

vercel bot commented Jan 2, 2026

@weepaho3 is attempting to deploy a commit to the borabaloglu's projects Team on Vercel.

A member of the Team first needs to authorize it.

- Adjusted `onDrag` transform calculation to offset from 100% for left/top directions, ensuring correct relative movement. - Updated `resetDrawer` to reset to 100% translation for left/top directions so the drawer stays visible in the open state. - Corrected `swipeToClose` calculation in `onRelease` to account for the inverted coordinate system of left/top drawers (calculating distance from the open 100%fix(core): correct drag gestures for left and top directions  - Adjusted `onDrag` transform calculation to offset from 100% for left/top directions, ensuring correct relative movement. - Updated `resetDrawer` to reset to 100% translation for left/top directions so the drawer stays visible in the open state. - Corrected `swipeToClose` calculation in `onRelease` to account for the inverted coordinate system of left/top drawers (calculating distance from the open 100% position).
@weepaho3 weepaho3 marked this pull request as draft January 3, 2026 11:17
@weepaho3
Copy link
Author

weepaho3 commented Jan 3, 2026

Sorry, I found some more bugs regarding drag behavior and animations, particularly for the top and left directions. I've fixed them now, so everything should be good to go.

You can preview the changes here: https://vaul-base-www.vercel.app/

@weepaho3 weepaho3 marked this pull request as ready for review January 3, 2026 14:40
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