emilkowalski / vaul

A drawer component for React.
https://vaul.emilkowal.ski
MIT License
6.45k stars 215 forks source link

Compatibility with portals (shadcn popover, select, etc) #482

Open bfischer1121 opened 1 month ago

bfischer1121 commented 1 month ago

Since portals are hard-coded by default in shadcn, it would be nice if this library didn't auto-close them when dismissible=false.

It's difficult to figure out this is the cause. I initially thought it was a z-index issue (will fix things in chrome but not safari), then tried switching to controlled+timers to avoid the auto-closing behavior (doesn't solve for scrolling / navigating within the panel), then found that it didn't work with portals (https://github.com/emilkowalski/vaul/issues/301#issuecomment-2384973532)

Related: https://github.com/emilkowalski/vaul/issues/479

ggrantrowberry commented 1 month ago

@bfischer1121 have you found any way around this? I am having the same issues

maiconcarraro commented 1 month ago

@ggrantrowberry for my project I had a similar issue when using sonner, clicking in the notification would close the drawer, so I used this snippet, you probably can adapt to include other portals: https://github.com/radix-ui/primitives/issues/2690#issuecomment-1945449832

bfischer1121 commented 1 month ago

Yeah, adding a "portal" prop to all the shadcn components got around it. e.g.,

const SelectContent = React.forwardRef<
  React.ElementRef<typeof SelectPrimitive.Content>,
  React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> & { portal?: boolean }
>(({ className, children, position = 'popper', portal = false, ...props }, ref) => {
  const content = ...
  return portal ? <SelectPrimitive.Portal>{content}</SelectPrimitive.Portal> : content
}
faiz-097 commented 4 weeks ago

@maiconcarraro thumbing down, do you have any solution sir?

maiconcarraro commented 4 weeks ago

I have a comment above yours w/ a strategy to stop propagation from the Drawer(Dialog)Content, you can try that which worked for me... and you can always send a PR fixing like I did for other issues that I faced, just saying "Vaul is useless" is a very very unprofessional/childish. Be aware that your comments notifies other people listening to this thread.

faiz-097 commented 4 weeks ago

image

@maiconcarraro Can you tell me even after having a much higher z-index in the bottom fixed items ,why they are not clickable on drawer opened, that's the basic things that vaul is lacking, i know i should not say that it's useless but there isn't any solution of these basic things here (z-index is not the issue here )

Drawer Component Code:- import { Divider } from 'antd'; import { identity } from 'lodash-es'; import { X } from 'phosphor-react'; import React from 'react'; import { Drawer } from 'vaul';

const SwipeableDrawer = ({ open = false, onClose = identity, placement = 'right', style = {}, title = null, children = <></>, width = 400, height = '100%', selfClosable = true, }) => { return (

e.stopPropagation()} className={ placement === 'bottom' ? `flex flex-col fixed bottom-0 left-0 right-0 !w-full` : `flex flex-col h-full w-[400px] fixed bottom-0 right-0` } style={{ zIndex: '1000', borderRadius: placement === 'bottom' ? '20px 20px 0 0' : '20px', right: placement === 'bottom' ? 0 : 10, top: placement === 'bottom' ? 'unset' : 10, height: placement === 'bottom' ? height || '50%' : 'calc(100% - 20px)', width: placement === 'bottom' ? '100%' : width || 400, }} >
{placement === 'bottom' &&
} {title && ( {selfClosable ? (
{title} onClose()} className="cursor-pointer" />
) : ( title )}
)}
{children}
); }; export default SwipeableDrawer;
maiconcarraro commented 4 weeks ago

@faiz-097 when opening the drawer it sets body to pointer events none, if you want to have other elements clickable that arent related to the dialog you need to force "pointer-events: auto" (depending on situation you may need !important.

in my first comment linking to radix discussion, you can see a person sharing this image

you can identify this inspecting the web and checking the styling applied to your element

faiz-097 commented 4 weeks ago

@maiconcarraro thanks, it did worked, apologies for that comment but there are a lot of stuffs that I am facing regarding the vaul drawer still. my project heavily depends on the drawer and other components on top of it so sometimes finding a solution becomes challenging

maiconcarraro commented 4 weeks ago

that's ok, just try to be nice everyone here is a human, and they also have their work to do, I'm not a maintainer... but burnout from open source is a real thing, most of people using this library is because of shadcn which works very well especially combined with Radix and using dialog for desktop + vaul for mobile/tablets (less elements to compete pointers events)... it may not work very well yet w/ antd, which can be related to not use radix, but you might try get help from antd developers as well

maiconcarraro commented 4 weeks ago

@faiz-097 just curious why you decided to use vaul if antd also has a drawer component: https://ant.design/components/drawer looking the source code it uses rc-drawer which can be another approach for your project, just sharing alternatives in case you are only looking for a drawer for desktop

faiz-097 commented 4 weeks ago

@maiconcarraro antd drawer is not swipeable, material UI gives it, but we cannot install a new and in fact large npm package just for using a drawer, that's the major issue, I was unable to find any package that provides swipeable drawer, then I got to know about vaul!

maiconcarraro commented 4 weeks ago

@faiz-097 is the swipeable feature required for desktop or mobile/tablet only? for our product we use dialog while in desktop (mouse use) and vaul only for mobile/tablet (gesture use)

I found this one using only framer-motion/spring: https://www.reddit.com/r/reactjs/comments/k7arz4/a_swipeable_spring_animated_side_drawer_using/ there is a comment linking to the github repo, you may be able to only use the sidebar or mimic the code.

faiz-097 commented 4 weeks ago

@maiconcarraro it's required in both desktop and mobile, right drawer for desktop and bottom drawer for mobile, vaul seemed simple that's why I went for it