Skip to content
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

[Bug]: Drawer state broken when nesting from another Drawer or DropdownMenu from Kobalte #80

Open
Vexcited opened this issue Mar 7, 2025 · 3 comments
Assignees
Labels
bug Unexpected behaviour in the code of corvu help wanted Extra attention is needed

Comments

@Vexcited
Copy link

Vexcited commented Mar 7, 2025

Bug description

In my app, I have a DropdownMenu from Kobalte and when clicking an item from this menu, it opens a Drawer from corvu using open and onOpenChange.

When I do this, it'll automatically close the Drawer. If I log the output of onOpenChange, it shows me false two times.

It does NOT only happens with elements from Kobalte, if I want to open another Drawer from a Drawer, it also does it.

Reproduction Link

https://stackblitz.com/edit/vexcited-corvu-drawer-issue-repro?file=src%2FApp.jsx

Reproduction Steps

  1. Click on Open Drawer
  2. Click on "Open another drawer !"
  3. See the new drawer close itself because of onOpenChange

Expected behavior

I expected the new drawer from not closing itself automatically.

Additional context

It's actually worse with an DropdownMenu item, because it'll close itself but after this I won't be able to interact anymore with the app because the drawer seems like to be still there.

2025-03-07.14-47-05.mp4

The code for this looks like this...

const [isReportDrawerOpened, setReportDrawerOpen] = createSignal(false);

return (
<>
 <Drawer open={isReportDrawerOpened()} onOpenChange={setReportDrawerOpen} breakPoints={[0.75]}>
  {(props) => (
    <>
      <Drawer.Trigger class="w-fit mx-auto rd-lg bg-white/10 px-4 py-3 text-lg font-medium transition-all duration-100 hover:bg-white/20 active:translate-y-0.5">
        Open Drawer
      </Drawer.Trigger>
      <Drawer.Portal>
        <Drawer.Overlay
          class="fixed inset-0 z-50 corvu-transitioning:transition-colors corvu-transitioning:duration-500 corvu-transitioning:ease-[cubic-bezier(0.32,0.72,0,1)]"
          style={{
            'background-color': `rgb(0 0 0 / ${
              0.5 * props.openPercentage
            })`,
          }}
        />
        <Drawer.Content class="corvu-transitioning:transition-transform corvu-transitioning:duration-500 corvu-transitioning:ease-[cubic-bezier(0.32,0.72,0,1)] fixed inset-x-0 bottom-0 z-50 flex h-full max-h-125 flex-col rounded-t-lg border-t-4 border-white/40 bg-black pt-3 after:absolute after:inset-x-0 after:top-[calc(100%-1px)] after:h-1/2 after:bg-inherit  md:select-none">
          <div class="h-1 w-10 self-center rounded-full bg-white/40" />
          <Drawer.Label class="mt-2 text-center text-xl font-bold">
            I'm a drawer!
          </Drawer.Label>
          <Drawer.Description class="mt-1 text-center">
            Drag down to close me.
          </Drawer.Description>
        </Drawer.Content>
      </Drawer.Portal>
    </>
  )}
 </Drawer>
 <DropdownMenu>
  <DropdownMenu.Trigger class="ml-auto hover:bg-white/8 rounded-full p-1.5 -mr-1.5 transition-colors">
    <DropdownMenu.Icon>
      <MdiDotsVertical class="text-xl" />
    </DropdownMenu.Icon>
  </DropdownMenu.Trigger>
  <DropdownMenu.Portal>
    <DropdownMenu.Content class="min-w-[220px] p-2 bg-[#080808] rounded-xl outline-none border border-white/8 transform-origin-[var(--kb-menu-content-transform-origin)]">
      <DropdownMenu.Item class="cursor-pointer rounded-lg py-1.5 px-4 hover:bg-white/8 text-red/80 hover:text-white"
        onSelect={() => setReportDrawerOpen(true)}
      >
        Report
      </DropdownMenu.Item>
    </DropdownMenu.Content>
  </DropdownMenu.Portal>
</DropdownMenu>
</>
);

2025-03-07.14-51-02.mp4

Also, thanks you so much for your quick patches, you're doing an awesome work and Corvu is such a treasure !

@Vexcited Vexcited added the bug (unverified) A bug yet to be verified label Mar 7, 2025
@GiyoMoon
Copy link
Member

GiyoMoon commented Mar 8, 2025

hm this is tricky to solve, it's actually two issues that come to play here:

  • In your stackblitz repro the problem is that the first drawer moves the focus to the trigger after the closing transition finishes, which causes the other drawer to close too because the focus moves outside of it. You could prevent that by doing onOutsideFocus={e => e.preventDefault()} on the first drawer to prevent focusing outside if you're opening a new drawer anyways.
  • With the dropdown, it's probably the same issue and that the drawer opens with a pointerdown event and closes instantly again with the pointerup event. You could either solve this with using <Drawer.Trigger> as the element in the dropdown (In kobalte you can use the as prop) or you can set closeOnOutsidePointerStrategy="pointerdown" so that it doesn't close instantly. You probably also have to set onCloseAutoFocus={e => e.preventDefault() on the Kobalte DropdownMenu.Content to solve the first issue here.

I have to think about what first party solution could be satisfying here, sadly it's not a quick fix so I can't promise anything soon.

@GiyoMoon GiyoMoon added bug Unexpected behaviour in the code of corvu help wanted Extra attention is needed and removed bug (unverified) A bug yet to be verified labels Mar 8, 2025
@Vexcited
Copy link
Author

Vexcited commented Mar 10, 2025

Using what you said...

<Drawer
  trapFocus={false}
  onOutsideFocus={e => e.preventDefault()}
  ...
> ... </Drawer>

Works enough for me !
Not sure if I should keep this issue opened, I'll let you decide what to do !

Thanks for the help at least, and good luck for trying to fix this in a proper way !

@dannylin108
Copy link

I noticed, if open a Drawer from kobalte's DropdownMenu by setting Drawer's open property to `true', it can not be closed afterwards.

This is a reproduction repo:

https://stackblitz.com/~/github.com/dannylin108/parkui-bug-report/tree/corvu

Steps:

  1. Open Kobalte Dropdown
  2. Select 'Open Corvu Drawer'
  3. Drawer will open, but can't be closed by any means.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Unexpected behaviour in the code of corvu help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants