Controlled drawer with `modal={false}` does not work because of bug in `useControllableState`
Author: skirstenCreated Oct 19, 2024Updated Aug 12, 2026
This took me a while to trace down, but basically a Drawer that is controlled and has modal false e.g.:
const [open, setOpen] = useState(false);
return (
<>
<Drawer open={open} onOpenChange={setOpen} modal={false}>
{/* ... */}
</Drawer>
{/* Button somewhere else outside */}
<Button onClick={() => setOpen(true)}>Open</Button>
</>
);and open is set from somewhere outside, it does not get to this line to hack the pointerEvents:
because if the prop changes it does not get to this line to call the handleChange function here: https://github.com/emilkowalski/vaul/blob/504102918ed53d5037c694b2f3300825b4e2f3fb/src/use-controllable-state.ts#L50
So to conclude, under these circumstances it will not remove the pointerEvents = "none" :cry:
Also I am curious why these awful hacks with the pointerEvents are necessary instead of just setting modal={false} on the DialogPrimitive.Root? Maybe this would break something else?
Source: emilkowalski/vaul