emilkowalski / vaul

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

Feature Request: Drawer should be able to confine itself within the immediate parent html element #448

Closed ayadav42 closed 1 month ago

ayadav42 commented 1 month ago

The drawer works great. It would be nice if the drawer could contain itself within a container. For example in a react component such as the following:

export default function Dashboard({}: DashboardProps) {
  const parentRef = useRef<HTMLDivElement>(null);

  return (
    <SearchPanelContextProvider>
      <div className='flex-none w-96 h-full pt-3'>
        <SearchPanel />
      </div>
      <div
        id='main-panel'
        ref={parentRef}
        className='flex flex-col flex-grow w-full h-full bg-slate-50 relative'>
        <FacilitiesMap />
        <BottomDrawer container={parentRef} />
      </div>
    </SearchPanelContextProvider>
  );
}

The drawer should attach itself to the parent div 'main-panel' and align its position and adjust its dimensions. It should pop up from the bottom left of the div and not the main html body. It's width should also be restricted to the width of the parent div. Basically, with respect to the above example, it should not cover 'SearchPanel'.

emilkowalski commented 1 month ago

You can use the container prop for it! It's not well documented, but just passing a ref into Drawer.Root should be enough! :)

Documentation will come soon.

ayadav42 commented 1 month ago

Thanks for responding!!

I tried the 'container' prop, I even traced that the container reference I'm passing is reaching Drawer.Root or not, but for some reason the drawer attaches itself to main document body when it pops up rather than the passed container. At which point I thought, maybe, passing the container is not supposed to achieve what I want, which is to limit the width. I think appending to the root body html element is the default behavior of React Dialog and is inherited as it is. I may be entirely mistaken though.

If there's an example where the width of the drawer limits itself to the passed container's width, I would appreciate it if you could please share. If not, I am happy to share a simple reproduction of the problem.

Thanks for creating this wonderful and clean widget though.

emilkowalski commented 1 month ago

Can you provide a demo of what you tried?

ayadav42 commented 1 month ago

I created a simple next js app with a single page here -> Vaul-Drawer-Demo.

Here is the codesandbox.

I don't know what I'm doing wrong but what I'm trying to achieve is make the drawer limit its width to the main panel and not cross over into the side panel. Below is a screenshot from the above sandbox.

Screenshot 2024-10-04 at 5 31 04 PM

Please let me know if you need anything else.

ayadav42 commented 1 month ago

bumping the message above just in case.

viktorrenkema commented 3 weeks ago

This should do exactly what you want @ayadav42 : https://codesandbox.io/p/github/ayadav42/vaul-drawer-demo/csb-yqhq53/draft/elastic-agnesi?import=true

clementoriol commented 2 weeks ago

Adding my findings about this feature (rendering the drawer into a different element)

However, there's some confusion by the fact that the Vaul.Portal also has a (undocumented) container prop. It's unclear when we should use one vs the other, or both, or removing the Portal altogether...

Would love some more info / examples on this