-
Notifications
You must be signed in to change notification settings - Fork 30
feat!: rewrite with more modern and flexible approach #99
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?
Conversation
…ration and easing and border radius configurable using CSS vars, deprecate `defaultOpen` (use `open` or `:open="true"`, update deps
… `v-if` and initially open, make sure latest `drawerEl` element is re-retrieved in `setTimeout`, fix broken `onNestedOpenChange` call
|
|
Any feedback would be greatly appreciated! |
packages/vaul-vue/src/DrawerRoot.vue
Outdated
| defaultValue: props.defaultOpen, | ||
| passive: (props.open === undefined) as false, | ||
| }) as WritableComputedRef<boolean> | ||
| const open = defineModel<boolean>('open', { |
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.
defineModel is Vue 3.4+ feature, I also would prefer to use defineModel and no longer worry about compatibility with older versions of Vue
However Reka-ui is still using useVModel in the codebase so let's use useVModel instead
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.
Ah that's a shame, but a valid point. I see Reka UI requires Vue ^3.2.0. Interestingly, vaul-vue seems to target Vue ^3.3.0 in its peer dependencies, but also lists Vue ^3.4.5 in the regular dependencies? So besides listing it twice, it doesn't seem to follow the same requirements as Reka UI. What is your vision on that?
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.
That is a mistake, that vue is in the dependencies in vaul-vue package.json it should be only in peerDependencies
See https://github.com/emilkowalski/vaul/blob/main/package.json#L62
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.
Ah it's just copied over from the React version. Are you planning on fixing this one yourself, or do you want a separate PR or have it included in this one?
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.
Can I? I would glad to help on this case,
I'll push a commit in this PR if you allow :)
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.
Of course! Any help finishing up this PR is very welcome 😄
|
Hi, Thanks for the PR and detailed explanation |
|
There are still some changes that need to consider for example Also I didn't check the rest of the examples will check them later |
|
This issue happens with and without my changes |
|
It would be nice if you re-check the upstream |
|
well i like the CSS-based approach, but the problem is that it has performance issues. Recalculate style is taking so long because of the usage of Also found this related issue This issue only gets worse if you have more children in your main component. |
|
https://github.com/metkm/vaul-vue/tree/css-based I don't think I can pass the offset value as a CSS variable because of the performance cost. I think I will pass that value to slot. Similar to how https://vueuse.org/core/useWindowSize/#component-usage current performance of the drawer, playing like crazy with it. Average of 5ms. Probably can be optimized more |
|
I wonder if desktop users would want this experience. Dragging with the mouse and collapsing the drawer (not using scroll wheel). I've implemented this custom scroll because I wanted to be able to close the drawer even when scrolling is started and reaches the end. 2025-08-19.23-19-42.mp4Another solution to this is using touch events on mobile and pointer events on desktop. But it looks like safari doesn't support TouchEvents for some reason. |
|
Link to the pr #111 |
Thanks for sharing! It would help maintainers to understand your PR if you could write down all changes and whether they are breaking or not. I haven't got the time right now to check your PR, but I'm curious to see the results! 😄 |
Yeah, I'm going to add a description sometime. Props and stuff 90% the same. Using it is not much different |
Great! Is usage substantially different from the current version of vaul-vue and/or usage with the breaking changes in my PR? And another question: do you think we could finalize my PR (together) and then continue on yours, or would that be suboptimal? |
Nope, Usage should be pretty much the same. Except I don't have some new
I think it would be suboptimal because I moved stuff around. We can merge this and then continue on my PR just to get them deleted because I've moved them on my PR lol. I think the best way is just to add CSS variables to my PR and continue from there. When you have time, you can compare them |



I worked on a big rewrite of vaul-vue this week, because I ran into limitations, all kinds of bugs and lack of customization.
This rewrite has a lot of changes, but I think they're all for the better:
defaultOpenprop is deprecated in favor ofopenattribute,:open="true".defineModelinstead ofuseVModel, theopenprop now has less control limitations. If someone uses the:open="ref"way, the dialog still closes on escape/click outside/DrawerCloseclick, but the ref does not get updated. However, if the prop is updated by the parent component, the drawer does react to that.defineModelforactiveSnapPointas well.--vaul-closed-percentageon the wrapper, which is used by the default styling to applytranslate/scaleetcetera that works, even when you resize your screen while the drawer is open.--vaul-durationand--vaul-easingon their:rootto adjust transition durations and easings.--vaul-closed-percentageto apply custom styling on their drawer wrappers.--vaul-wrapper-border-radiusto apply a custom target border-radius on their drawer wrappers. This does not have to be inpx, but can be%/rem/emetcetera. E.g. when setting--vaul-wrapper-border-radius: 2remthe drawer will have aborder-radiusof2remwhen the drawer is open.--vaul-wrapper-scale-px-unitlessto apply a custom target shrink/grow on their drawer wrappers. Values have to be unitless, such as-30(shrinks wrapper 30px when drawer is open),40(grows wrapper 40px when drawer is open).shouldScaleBackgroundset tofalsenow, to prevent issues with a parent drawer that also scales the background.open/:open="true"/:v-model:open="true"on initial setup.vaul-vuesets with--vaul, rename animations to kebab case with thevaulprefix as well.package-lock.json, since we usepnpm.TODO:
:activeon the drawer itself does not seem to work, so transitions do not get disabled on the drawer wrapper when the drawer is being dragged.setTimeout, usetransitionend/animationendevents instead if possible.A little demo of what's possible with this approach:
Screencast from 30-03-25 10:46:51.webm