No more hard to use and dismiss modal experiences for mobile users.
react-sheet-slide provides a fully draggable sheet
that properly blocks weird overscrolling and focus bugs. Then on desktop
this component optionally supports a fully-featured modal.
Alternatively the sheet can be used on desktop as-well if so desired.
- Responsive way to display blocking modal-like content on mobile web-apps.
- Accessible with proper scroll & focus blocking, with
Escto close on desktop.
- Supports dark and light mode out of the box
- Customizable detents
- Similar API to Apple’s UIKit sheet
- Supports Server-Side rendering.
- Built with css-modules (no styled-in-js library needed)
yarn add react-sheet-slide @react-spring/web@^9 @use-gesture/react@^10
npm install react-sheet-slide @react-spring/web@^9 @use-gesture/react@^10
This library is largely based on the fantastic react-spring-bottom-sheet. While react-spring-bottom-sheet is much more feature-packed than
react-sheet-slide, supporting more props like many different callbacks on sheet snap start/end.
However the extra dependencies like
xstate and the
resize-observer polyfill can lead to a larger bundle size.
react-spring as a dependencies instead of a peer dependencies limits users of the library from
controlling the version of
react-spring they use. It can also lead to 2 versions of
react-spring being bundled,
if the user is using a newer or older major version than the library.
By simplifying the API these libraries can be removed, and by moving
react-spring to a peer dependencies
makes the library have a much lighther footprint. Also
react-sheet-slide includes a
dark mode and a fully-featured desktop modal that can be enabled for non-mobile users.
It also adds support for a backdrop animation similar to Apple’s UIKit.
react-sheet-slide includes a
Portal component however other portal can be used like
@mui/base. The one included is just of modified version of
@reach/portal however with support for string refs and defaults to
rss-backdrop is required to apply to the sheet backdrop effect. Omitting it will disable any backdrop styles on the sheet.
react-sheet-slide will also set a
body background when the sheet is open to create the inset for the backdrop effect.
As such it is recommended to apply the background to a top level
div or other container, in addition to the
If you want to keep your
body background, use
Set if the sheet is open. When this prop is changed the sheet
will animate and the unmount/remount. When the component fully unmounts,
onClosewill be called.
Called when the sheet is dragged down or the user clicks on the backdrop. Also called when the user presses
This method should include
openis false. Otherwise the sheet may not close properly.
Called when the sheet finishes the close animation and is fully unmounted.
The default detent size that the sheet will open to.
List of available detents that the sheet will catch on. Reccomened to set to either
props => [detents.large(props), detents.medium(props)]
to mimic the UIKit behaviour however can be customized using the callback.
Prop to control if dark mode is enabled. By default this will use the system
Prop to control when a modal should be used instead of a sheet. If your app will likely only be used on mobile
Otherwise it will default to true on any device larger than
(max-width: 640px)to use a modal on desktop.
Determines if scrolling up on the sheet body will expand the sheet. Once the sheet is expanded
to the max detent, the sheet will be scrollable. Disabled by default to provide a more predictable scroll behaviour
however enabling it if possible is recommended.
The sheet also supports forwarding a ref that will be added onto the sheet root.