{"id":11869,"library":"react-spring-bottom-sheet","title":"React Spring Bottom Sheet","description":"react-spring-bottom-sheet is a React component library designed for creating accessible, animated bottom sheets (also known as bottom drawers or modals) for web applications. It is built upon the `react-spring` library for physics-based animations and `react-use-gesture` for robust gesture control, delivering a smooth and interactive user experience. The current stable version is 3.4.1, which includes support for React 18. Key features include content drag expansion, customizable snap points, and an opt-out focus trap for accessibility. The library differentiates itself by its focus on combining delightful animations with strong accessibility standards through its underlying animation libraries and CSS custom properties for styling. While not adhering to a strict time-based release schedule, the project is actively maintained with updates addressing bug fixes, dependency compatibility, and new features as needed.","status":"active","version":"3.4.1","language":"javascript","source_language":"en","source_url":"https://github.com/stipsan/react-spring-bottom-sheet","tags":["javascript","animation","bottom-drawer","bottom-sheet","bottomsheet","dialog","drag-drop","draggableview","drawer","typescript"],"install":[{"cmd":"npm install react-spring-bottom-sheet","lang":"bash","label":"npm"},{"cmd":"yarn add react-spring-bottom-sheet","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-spring-bottom-sheet","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for any React component library.","package":"react","optional":false},{"reason":"Core animation library for physics-based transitions.","package":"react-spring","optional":false},{"reason":"Provides advanced gesture control for draggable interactions.","package":"react-use-gesture","optional":false}],"imports":[{"note":"The primary component for rendering a bottom sheet. Always a named import. CommonJS `require` is not officially supported and may lead to issues with `react-spring`'s ESM-first approach.","wrong":"const BottomSheet = require('react-spring-bottom-sheet').BottomSheet","symbol":"BottomSheet","correct":"import { BottomSheet } from 'react-spring-bottom-sheet'"},{"note":"TypeScript type for the ref object when you need to programmatically control the sheet (e.g., `snapTo`). Should be imported as a type.","wrong":"import { BottomSheetRef } from 'react-spring-bottom-sheet'","symbol":"BottomSheetRef","correct":"import type { BottomSheetRef } from 'react-spring-bottom-sheet'"},{"note":"Required for default styling. Ensure your build system processes CSS imports. Importing directly from the root might fail if not configured for direct file access.","wrong":"import 'react-spring-bottom-sheet/style.css'","symbol":"style.css","correct":"import 'react-spring-bottom-sheet/dist/style.css'"}],"quickstart":{"code":"import { useState, useRef } from 'react';\nimport { BottomSheet, BottomSheetRef } from 'react-spring-bottom-sheet';\nimport 'react-spring-bottom-sheet/dist/style.css';\n\nfunction MyBottomSheetComponent() {\n  const [open, setOpen] = useState(false);\n  const sheetRef = useRef<BottomSheetRef>(null);\n\n  const handleDismiss = () => {\n    console.log('Sheet dismissed');\n    setOpen(false);\n  };\n\n  const handleSnapToMax = () => {\n    if (sheetRef.current) {\n      sheetRef.current.snapTo(({ maxHeight }) => maxHeight);\n    }\n  };\n\n  return (\n    <>\n      <button onClick={() => setOpen(true)}>Open Bottom Sheet</button>\n      <BottomSheet\n        open={open}\n        onDismiss={handleDismiss}\n        ref={sheetRef}\n        snapPoints={({ minHeight, maxHeight }) => [\n          minHeight,\n          maxHeight * 0.5,\n          maxHeight,\n        ]}\n        header={<div>Sheet Header</div>}\n        footer={<div>Sheet Footer</div>}\n      >\n        <div style={{ padding: '16px' }}>\n          <h2>Welcome to the Bottom Sheet!</h2>\n          <p>This is some content inside the sheet. You can drag it up or down to different snap points.</p>\n          <p>The sheet will automatically adjust its height based on the content or snap to predefined points.</p>\n          <button onClick={handleSnapToMax}>Expand to full height</button>\n        </div>\n      </BottomSheet>\n    </>\n  );\n}\n\nexport default MyBottomSheetComponent;","lang":"typescript","description":"Demonstrates a controlled bottom sheet with open/close functionality, programmatic snap-to, multiple snap points, and custom header/footer. It includes the necessary CSS import."},"warnings":[{"fix":"Always pass an `onDismiss` prop that sets the `open` state to `false`, e.g., `<BottomSheet open={open} onDismiss={() => setOpen(false)} />`.","message":"The `open` prop is fully controlled. If `onDismiss` is not provided or does not update the `open` state to `false`, the bottom sheet will not close when users interact with the backdrop or press the Escape key.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Add `import 'react-spring-bottom-sheet/dist/style.css';` to your entry file or a relevant component file.","message":"The component relies on external CSS for styling. For the default look and feel, you must import `react-spring-bottom-sheet/dist/style.css`. Without it, the sheet will lack basic visual structure and animations.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Design child components to be resilient to unmounting/remounting, or manage their state externally if persistence across sheet closures is required. Avoid complex local state that needs to be preserved when the sheet is closed.","message":"When `open` is `false`, the `BottomSheet` component renders only a `@reach/dialog` placeholder and unmounts its children. Ensure your components inside the sheet handle being unmounted and remounted correctly to avoid unexpected state loss or re-initialization.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Refer to the documentation for available CSS custom properties (e.g., `--rsbs-bg`, `--rsbs-handle-bg`) and use them to customize the sheet's appearance. Copying `style.css` into your project allows full control.","message":"The library heavily uses CSS custom properties (`--rsbs-*`) for styling. Direct manipulation of styles via JavaScript or traditional CSS might be overridden or conflict with these variables, requiring developers to adjust the custom properties.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Only use `blocking={false}` when the sheet's behavior genuinely doesn't require a modal-like interaction that traps focus. For most dialog-like bottom sheets, keep `blocking={true}` (default) or ensure alternative accessibility considerations are made.","message":"The `blocking={false}` prop disables several accessibility behaviors, including focus-locking. While useful for non-modal scenarios (e.g., a draggable sidebar), it can degrade accessibility for users relying on keyboard navigation or screen readers.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure `react-spring` and its dependencies are correctly configured for your bundler. Check GitHub issues for workarounds related to `StrictMode` or specific framework versions. Consider alternative packages or forks if the issue persists and is framework-specific.","cause":"Often occurs when `react-spring` internal state is accessed before initialization or in a conflicting environment like strict mode or specific bundlers (e.g., Vite/Next.js v13+).","error":"TypeError: Cannot read properties of undefined (reading 'getValue')"},{"fix":"Verify that `open` is a boolean state variable and `onDismiss` correctly sets this state variable to `false`. E.g., `const [open, setOpen] = useState(false); <BottomSheet open={open} onDismiss={() => setOpen(false)} />`.","cause":"The `open` prop is not being properly controlled by `useState` and `onDismiss`, or the `onDismiss` callback isn't updating the `open` state correctly.","error":"Sheet does not animate or close on interaction"},{"fix":"Add `import 'react-spring-bottom-sheet/dist/style.css';` to your main application file (e.g., `App.tsx` or `index.tsx`). Ensure your bundler is configured to handle CSS imports.","cause":"The default CSS file `dist/style.css` was not imported, or your build system failed to process the CSS import.","error":"The bottom sheet appears without any styling or animations"},{"fix":"Update your project's `react` and `react-dom` packages to a compatible version (e.g., `^18.0.0`) or install the package with `--force` or `--legacy-peer-deps` (use with caution as it might lead to unexpected behavior).","cause":"Your project's React version does not satisfy the peer dependency requirements of `react-spring-bottom-sheet`.","error":"Peer dependency 'react@^16.14.0 || 17 || 18' not met"}],"ecosystem":"npm"}