mui / mui/base-ui

[drawer] Dismissible prop for drawers

Open
#4,541 2 comments 3 reactions 0 assignees View on GitHub
component: drawer has workaround type: new feature
Dominant language
TypeScript
Stars
10.9k
Forks
543
Avg merge
1d 20h
Merged PRs (30d)
101

Description

# Feature request

**NOTE:** I am aware that Base-UI refers to Dialogs for non-gesture controlled drawers, but I believe this request is different enough and has its own use cases.

## Summary

Add a `dismissible` prop to manually control whether the Drawer can be closed via gestures, backdrop click, or Escape key. This would make it possible for drawers to temporarily act like a non-dismissible alert. This could also be described as a bug, as the request stems from an issue while working with [Motion](https://motion.dev/) draggable elements inside of a drawer component, where the two elements end up fighting over gesture controls.

## Examples in other libraries

Vaul by Emil Kowalski, a popular drawer library for React, has this prop: [Other - non-dismissible](https://vaul.emilkowal.ski/other#non-dismissible)

## Motivation

In my case this forces the drawer to become non-gesture controlled while a drag is occurring, preventing accidental gesture dismissals of the drawer when not desired. This could also be used for forcing the drawer to stay open for some amount of time. This also just grants more manual control over how the drawer behaves when desired.

## Example

I have made a crude patch to get the desired behavior. Notice the buggy behavior in the example below where the drawer follow my cursor even after the drag has begun:
https://github.com/user-attachments/assets/dcd051d2-5c35-496d-b116-243df92ea975

Implementing a new "dismissible" prop into the drawer I am able to early return the events. **Note:** shouldn't this also be possible with `event.preventBaseUIHandler();`? Doesn't seem like that works though. The only slight issue with this is the return transition as the drawer gets offset from the initial touch event, but then afterwards is forced back to its initial resting position. Here is the behavior I somewhat desire with this feature request:
https://github.com/user-attachments/assets/c605d99d-fa3c-4dc5-8da9-38162069314e

## Alternative API changes

Instead of having a `dismissible` prop, this could also just be a `disableDrag` or `disableGestures` prop, since it is already possible to intercept final dismissals through the `onOpenChange` callback.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.