### Start Example App Packager
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CONTRIBUTING.md
Starts the Metro server for the example application. This is necessary to run the example app.
```sh
yarn example start
```
--------------------------------
### Install adapter dependencies
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/getting-started.md
Install specific dependencies based on the chosen adapter. Only install what is required for your implementation.
```bash
# For GorhomSheetAdapter (default bottom sheet adapter)
yarn add @gorhom/bottom-sheet react-native-gesture-handler
# For ModalAdapter — no extra dependencies (uses React Native's built-in Modal)
# For ReactNativeModalAdapter
yarn add react-native-modal
# For ActionsSheetAdapter
yarn add react-native-actions-sheet
# For SwmansionSheetAdapter (native / New Architecture only)
yarn add @swmansion/react-native-bottom-sheet react-native-safe-area-context
# Optional — only for SwmansionSheetAdapter's keyboardBehavior="inset"
yarn add react-native-keyboard-controller
```
--------------------------------
### Install core library
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/getting-started.md
Install the main package using yarn.
```bash
yarn add react-native-bottom-sheet-stack
```
--------------------------------
### Run Example App on Web
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CONTRIBUTING.md
Builds and runs the example application in a web browser.
```sh
yarn example web
```
--------------------------------
### Start Local Development Server
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/README.md
Starts a local development server for live previewing changes. The server opens automatically in a browser.
```bash
yarn start
```
--------------------------------
### Run Example App on iOS
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CONTRIBUTING.md
Builds and runs the example application on an iOS simulator or device.
```sh
yarn example ios
```
--------------------------------
### Run Example App on Android
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CONTRIBUTING.md
Builds and runs the example application on an Android device or emulator.
```sh
yarn example android
```
--------------------------------
### Install SwmansionSheetAdapter dependencies
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/swmansion.md
Install the required packages for the Swmansion bottom sheet adapter.
```bash
npm install @swmansion/react-native-bottom-sheet react-native-safe-area-context
```
--------------------------------
### Install Dependencies
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/README.md
Installs project dependencies using Yarn. Run this command after cloning the repository.
```bash
yarn
```
--------------------------------
### Install peer dependencies
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/getting-started.md
Install the required peer dependencies for the library to function.
```bash
yarn add react-native-reanimated react-native-safe-area-context react-native-teleport zustand
```
--------------------------------
### Install keyboard avoidance dependency
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/swmansion.md
Install the optional peer dependency required for the keyboardBehavior='inset' prop.
```bash
npm install react-native-keyboard-controller
```
--------------------------------
### Setup Provider and Host
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/getting-started.md
Wrap the application with the manager provider and place the host outside the scale view.
```tsx
import {
BottomSheetManagerProvider,
BottomSheetHost,
BottomSheetScaleView,
} from 'react-native-bottom-sheet-stack';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
export default function App() {
return (
);
}
```
--------------------------------
### Quick Example: Setting up and using react-native-bottom-sheet-stack
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/intro.md
This example demonstrates how to set up the BottomSheetManagerProvider, define a custom bottom sheet component, and open it using the useBottomSheetManager hook. It includes the necessary imports and component structures for basic integration.
```tsx
import { forwardRef } from 'react';
import { View, Text, Button } from 'react-native';
import { BottomSheetView } from '@gorhom/bottom-sheet';
import {
BottomSheetManagerProvider,
BottomSheetHost,
BottomSheetScaleView,
useBottomSheetManager,
useBottomSheetContext,
} from 'react-native-bottom-sheet-stack';
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
// 1. Define a bottom sheet component
const MySheet = forwardRef((props, ref) => {
const { close } = useBottomSheetContext();
return (
Hello from Bottom Sheet!
);
});
// 2. Setup provider and host
function App() {
return (
);
}
// 3. Open bottom sheets
function YourAppContent() {
const { open } = useBottomSheetManager();
return (
open( , { mode: 'push' })}
/>
);
}
```
--------------------------------
### Install react-native-modal
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/react-native-modal.md
Install the required dependency via npm.
```bash
npm install react-native-modal
```
--------------------------------
### Install ActionsSheetAdapter dependency
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/actions-sheet.md
Install the required react-native-actions-sheet package.
```bash
npm install react-native-actions-sheet
```
--------------------------------
### Install GorhomSheetAdapter dependencies
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/gorhom.md
Install the required peer dependencies for the GorhomSheetAdapter.
```bash
npm install @gorhom/bottom-sheet react-native-reanimated react-native-gesture-handler
```
--------------------------------
### Push Mode Example
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/navigation-modes.md
Demonstrates stacking sheets using the 'push' mode. Each sheet is added to the stack and remains until explicitly closed.
```tsx
open( , { mode: 'push' });
// Stack: [SheetA]
open( , { mode: 'push' });
// Stack: [SheetA, SheetB]
// Close SheetB -> Stack: [SheetA]
```
--------------------------------
### Usage Example for Navigation Modes
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/navigation-modes.md
A React component demonstrating how to use the 'open' function with different navigation modes ('push', 'switch', 'replace') via buttons.
```tsx
function NavigationExample() {
const { open } = useBottomSheetManager();
return (
open( , { mode: 'push' })}
/>
open( , { mode: 'switch' })}
/>
open( , { mode: 'replace' })}
/>
);
}
```
--------------------------------
### Implement Per-Sheet Adapter Choice
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/adapters.md
Example of mixing different adapter types within the same stack and controlling them via useBottomSheetControl.
```tsx
// Sheet 1: gorhom bottom sheet
// Sheet 2: custom modal adapter
// Open them in sequence — both participate in the same stack
const settings = useBottomSheetControl('settings');
const alert = useBottomSheetControl('alert');
settings.open({ scaleBackground: true });
// Later...
alert.open({ mode: 'push' }); // Modal pushes on top of bottom sheet
```
--------------------------------
### Basic Persistent Sheet Setup
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/persistent-sheets.md
Demonstrates how to set up and use a persistent sheet. Import `BottomSheetPersistent` and `useBottomSheetControl`. The persistent sheet is mounted within `BottomSheetManagerProvider` and controlled via its ID.
```tsx
import {
BottomSheetPersistent,
useBottomSheetControl,
} from 'react-native-bottom-sheet-stack';
function App() {
return (
{/* Persistent sheet - always mounted */}
);
}
function HomeScreen() {
const scanner = useBottomSheetControl('scanner');
return (
scanner.open({ scaleBackground: true })}
/>
);
}
```
--------------------------------
### Configure SwmansionSheetAdapter convenience props
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/swmansion.md
Examples of using the handle and fullHeight props to customize the sheet's appearance and layout.
```tsx
// Grab handle + full height + a flex:1 scrollable that binds to the sheet.
{/* ... */}
// Restyle the default pill.
{/* ... */}
// Or render your own handle for full control.
}>
{/* ... */}
```
--------------------------------
### Enable Scale Animation with Portal API
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/scale-animation.md
Use the useBottomSheetControl hook to get the open function and then call it with scaleBackground: true.
```tsx
const { open } = useBottomSheetControl('my-sheet');
open({ scaleBackground: true });
```
--------------------------------
### Switch Mode Example
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/navigation-modes.md
Illustrates the 'switch' mode where the current sheet is hidden and a new one is shown. The previous sheet is restored upon closing the new one.
```tsx
open( , { mode: 'push' });
// Stack: [SheetA (visible)]
open( , { mode: 'switch' });
// Stack: [SheetA (hidden), SheetB (visible)]
// Close SheetB -> SheetA becomes visible again
```
--------------------------------
### Replace Mode Example
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/navigation-modes.md
Shows how to use the 'replace' mode to close the current sheet and open a new one in its place, removing the previous sheet from the stack.
```tsx
open( , { mode: 'push' });
// Stack: [SheetA]
open( , { mode: 'replace' });
// Stack: [SheetB] (SheetA is removed)
```
--------------------------------
### Complete Type-Safe Bottom Sheet Example
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/type-safe-ids.md
Demonstrates the full integration of type-safe bottom sheets, including defining types, creating the sheet component, and using it within the application with type-checked parameters.
```tsx
// 1. Define types (src/types/bottom-sheet.d.ts)
declare module 'react-native-bottom-sheet-stack' {
interface BottomSheetPortalRegistry {
'user-details': {
userId: string;
showEmail: boolean;
};
}
}
// 2. Create the sheet component
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
const UserDetailsSheet = forwardRef((props, ref) => {
const { params, close } = useBottomSheetContext<'user-details'>();
return (
User: {params.userId}
{params.showEmail && email@example.com }
);
});
// 3. Use in your app
function App() {
const { open } = useBottomSheetControl('user-details');
return (
<>
open({
params: { userId: 'abc123', showEmail: true }
})}
/>
>
);
}
```
--------------------------------
### Implementing binary strategy for adapters
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/custom-adapters.md
Set the animated index to 0 for visible and -1 for hidden states to toggle backdrop opacity.
```tsx
const animatedIndex = useAnimatedIndex();
useImperativeHandle(ref, () => ({
expand: () => {
animatedIndex.set(0); // backdrop fully opaque
// ... show your overlay
},
close: () => {
animatedIndex.set(-1); // backdrop fully transparent
// ... hide your overlay
},
}), [animatedIndex]);
```
--------------------------------
### Override backdropComponent
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/gorhom.md
Example of overriding the default stack-aware backdrop with a custom gorhom backdrop component.
```tsx
import { BottomSheetBackdrop as GorhomBackdrop } from '@gorhom/bottom-sheet';
{/* ... */}
;
```
--------------------------------
### Import core and adapter modules
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Demonstrates the import patterns for core functionality versus specific adapter implementations.
```typescript
// Core — safe to import without any adapter deps installed
import { BottomSheetManagerProvider, useBottomSheetManager } from 'react-native-bottom-sheet-stack';
import { CustomModalAdapter } from 'react-native-bottom-sheet-stack'; // zero deps
// Adapters — import only when the underlying library is installed
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
import { ReactNativeModalAdapter } from 'react-native-bottom-sheet-stack/react-native-modal';
import { ActionsSheetAdapter } from 'react-native-bottom-sheet-stack/actions-sheet';
import { SwmansionSheetAdapter } from 'react-native-bottom-sheet-stack/swmansion';
```
--------------------------------
### Usage of Custom Adapter
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/custom-adapters.md
Demonstrates how to use the custom adapter either as inline content via the manager or as a portal.
```tsx
// As inline content
const { open } = useBottomSheetManager();
open(
Custom adapter content
,
{ mode: 'push' }
);
// As portal
```
--------------------------------
### Build Static Website
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/README.md
Generates the static content for the website into the 'build' directory. This output can be hosted on any static hosting service.
```bash
yarn build
```
--------------------------------
### Enable Scale Animation with open()
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/scale-animation.md
Open bottom sheets with the scaleBackground: true option to activate the scaling effect.
```tsx
open( , { scaleBackground: true });
```
--------------------------------
### State Preservation in Persistent Sheet
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/persistent-sheets.md
Shows how internal component state is preserved between open/close cycles for a persistent sheet. The `ScannerSheet` example preserves `scanResult` and `isScanning` states.
```tsx
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
const ScannerSheet = forwardRef((props, ref) => {
const { close } = useBottomSheetContext();
// State is preserved when sheet is closed and reopened
const [scanResult, setScanResult] = useState(null);
const [isScanning, setIsScanning] = useState(false);
const handleScan = () => {
setIsScanning(true);
// ... scanning logic
setScanResult('QR-ABC123');
setIsScanning(false);
};
return (
{scanResult ? (
Result: {scanResult}
) : (
)}
);
});
```
--------------------------------
### Using optional dependencies
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/custom-adapters.md
Use lazy require to keep wrapped libraries optional when publishing adapters.
```tsx
// Lazy import — won't crash if the library isn't installed
const ThirdPartySheet = require('third-party-sheet').default;
```
--------------------------------
### Deploy Website using SSH
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/README.md
Deploys the website using SSH. This command builds the site and pushes it to the 'gh-pages' branch, suitable for GitHub Pages hosting.
```bash
USE_SSH=true yarn deploy
```
--------------------------------
### Context Preservation in Themed Bottom Sheet
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/context-preservation.md
Shows how a bottom sheet defined with `BottomSheetPortal` retains access to React context, such as theme colors, by using `useTheme` within the sheet's component. This example uses `GorhomSheetAdapter` and `BottomSheetView`.
```tsx
import { useTheme } from './ThemeContext';
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
const ThemedSheet = forwardRef((props, ref) => {
const { colors } = useTheme(); // Context is preserved!
return (
Themed Content
);
});
function App() {
const { open } = useBottomSheetControl('themed-sheet');
return (
open()} />
);
}
```
--------------------------------
### Import Gorhom Adapter
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/adapters.md
Demonstrates the backward compatible import path for the Gorhom adapter.
```tsx
// These are equivalent:
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
import { BottomSheetManaged } from 'react-native-bottom-sheet-stack/gorhom';
```
--------------------------------
### Initialize useBottomSheetControl
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/hooks.md
Access sheet control methods by providing the unique portal sheet ID.
```tsx
const { open, close, closeAll, updateParams, resetParams } = useBottomSheetControl('my-sheet');
```
--------------------------------
### Implementing continuous strategy for adapters
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/custom-adapters.md
Pass the animated index shared value directly to the library for smooth backdrop interpolation during gestures.
```tsx
const animatedIndex = useAnimatedIndex();
// The library writes to the shared value during gestures:
```
--------------------------------
### Initialize useBottomSheetManager
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/hooks.md
Access the imperative sheet management methods.
```tsx
const { open, close, closeAll, clear } = useBottomSheetManager();
```
--------------------------------
### Publish New Versions
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CONTRIBUTING.md
Uses release-it to automate the process of publishing new versions to npm, including version bumping and tag creation.
```sh
yarn release
```
--------------------------------
### Visualize Persistent Mode Lifecycle
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Diagram illustrating the state transitions of a persistent sheet within the store.
```text
Component Mount → store.mount() → status: 'hidden' (in sheetsById, not in stackOrder)
│
open() called
│
▼
status: 'opening' (added to stackOrder)
│
animation done
│
▼
status: 'open'
│
close() called
│
▼
status: 'closing' → 'hidden'
(removed from stackOrder, kept in sheetsById)
Content stays mounted! State preserved!
│
open() again
│
▼
status: 'opening' (same content, same state)
```
--------------------------------
### Compare Bottom Sheet Modes
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Comparison of how different sheet modes manage state in the store after closing.
```text
INLINE MODE (useBottomSheetManager):
┌─────────────────────────────────────────────────────┐
│ sheetsById: { 'abc123': { content: , ... } } │
│ stackOrder: ['abc123'] │
└─────────────────────────────────────────────────────┘
After close: Sheet DELETED from sheetsById
PORTAL MODE (BottomSheetPortal):
┌─────────────────────────────────────────────────────┐
│ sheetsById: { 'user-sheet': { usePortal: true } } │
│ stackOrder: ['user-sheet'] │
└─────────────────────────────────────────────────────┘
After close: Sheet DELETED from sheetsById
PERSISTENT MODE (BottomSheetPersistent):
┌──────────────────────────────────────────────────────────────────┐
│ sheetsById: { 'scanner': { usePortal: true, keepMounted: true } }│
│ stackOrder: ['scanner'] │
└──────────────────────────────────────────────────────────────────┘
After close: Sheet KEPT in sheetsById with status: 'hidden'
Removed from stackOrder only
```
--------------------------------
### Run Unit Tests
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CONTRIBUTING.md
Executes the unit tests for the project using Jest.
```sh
yarn test
```
--------------------------------
### Lint Project Files
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CONTRIBUTING.md
Runs ESLint to check for code style and potential errors in the project files.
```sh
yarn lint
```
--------------------------------
### Implement Custom Adapter Component
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/custom-adapters.md
A template for creating a custom adapter component using forwardRef and imperative handles to bridge library-specific methods.
```tsx
import React, { useImperativeHandle } from 'react';
import type { SheetAdapterRef } from 'react-native-bottom-sheet-stack';
import {
createSheetEventHandlers,
useAdapterRef,
useAnimatedIndex,
useBottomSheetContext,
} from 'react-native-bottom-sheet-stack';
interface MyAdapterProps {
children: React.ReactNode;
// ... your library's props
}
export const MyAdapter = React.forwardRef(
({ children, ...props }, forwardedRef) => {
// 1. Get sheet context and adapter ref
const { id } = useBottomSheetContext();
const ref = useAdapterRef(forwardedRef);
// 2. Get event handlers for this sheet
const { handleDismiss, handleOpened, handleClosed } =
createSheetEventHandlers(id);
// 3. Get animated index (for backdrop/scale integration)
const animatedIndex = useAnimatedIndex();
// 4. Expose expand/close to the coordinator
useImperativeHandle(ref, () => ({
expand: () => {
// Call your library's "show" method
myLibraryRef.current?.show();
},
close: () => {
// Call your library's "hide" method
myLibraryRef.current?.hide();
},
}), []);
// 5. Wire up callbacks
const onShown = () => {
animatedIndex.set(0);
handleOpened();
};
const onUserDismiss = () => {
handleDismiss();
};
const onHidden = () => {
animatedIndex.set(-1);
handleClosed();
};
// 6. Render your library's component
return (
{children}
);
}
);
```
--------------------------------
### Open Sheet with Options
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/hooks.md
Trigger sheet opening with optional configuration and type-safe parameters.
```tsx
// Sheet without params (registry: 'simple-sheet': true)
open();
open({ scaleBackground: true });
// Sheet with params (registry: 'user-sheet': { userId: string })
open({
mode: 'push',
scaleBackground: true,
params: { userId: '123' } // Required when params defined in registry
});
```
--------------------------------
### Implement Bottom Sheet with Gorhom Adapter
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/README.md
Define a bottom sheet component, set up the provider and host, and trigger sheets from your application content.
```tsx
import { forwardRef } from 'react';
import { View, Text, Button } from 'react-native';
import { BottomSheetView } from '@gorhom/bottom-sheet';
import {
BottomSheetManagerProvider,
BottomSheetHost,
BottomSheetScaleView,
useBottomSheetManager,
useBottomSheetContext,
} from 'react-native-bottom-sheet-stack';
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
// 1. Define a bottom sheet component
const MySheet = forwardRef((props, ref) => {
const { close } = useBottomSheetContext();
return (
Hello from Bottom Sheet!
);
});
// 2. Setup provider and host
function App() {
return (
);
}
// 3. Open bottom sheets from anywhere
function YourAppContent() {
const { open } = useBottomSheetManager();
return (
open( , { mode: 'push' })}
/>
);
}
```
--------------------------------
### Configure SwmansionSheetAdapter with custom scrim
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/swmansion.md
Use the scrimColor prop to enable a native scrim, which automatically disables the manager's shared backdrop for that sheet.
```tsx
{/* ... */}
```
--------------------------------
### Configure React Compiler in babel.config.js
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Sets up the React Compiler plugin with strict mode enabled for React 19 compatibility.
```javascript
plugins: [
['babel-plugin-react-compiler', {
target: '19',
panicThreshold: 'all_errors', // Strict mode
}],
]
```
--------------------------------
### Initialize Sheet Reference Registry
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Global map for storing non-serializable BottomSheetMethods refs.
```typescript
const sheetRefsMap = new Map>();
```
--------------------------------
### Mixed Stacking Usage
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/custom-modal.md
Demonstrates how to push both bottom sheets and modals into the same stack.
```tsx
const { open } = useBottomSheetManager();
const modalControl = useBottomSheetControl('my-modal');
// Push a bottom sheet
open( , { mode: 'push' });
// Then push a modal on top
modalControl.open({ mode: 'push' });
// Both are in the stack — closing the modal returns to the bottom sheet
```
--------------------------------
### Project Directory Structure
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Visual representation of the source code organization.
```text
src/
├── index.tsx # Public exports (no 3rd-party adapter deps)
├── bottomSheet.store.ts # Zustand store (state + actions)
├── bottomSheetCoordinator.ts # Store ↔ adapter sync
├── refsMap.ts # Global sheet refs registry
├── animatedRegistry.ts # Global animated values registry
├── adapter.types.ts # SheetAdapterRef, SheetAdapterEvents types
├── portal.types.ts # Type-safe portal registry types
│
├── BottomSheetManager.provider.tsx # Root provider component
├── BottomSheetManager.context.tsx # Manager context definition
├── BottomSheet.context.ts # Sheet context definition
├── BottomSheetRef.context.ts # Ref context definition
│
├── BottomSheetHost.tsx # Sheet queue renderer
├── QueueItem.tsx # Individual sheet slot
├── BottomSheetPortal.tsx # Portal mode definition ('use no memo')
├── BottomSheetPersistent.tsx # Persistent sheet component
├── BottomSheetScaleView.tsx # Background scale wrapper
├── BottomSheetBackdrop.tsx # Custom backdrop component
│
├── useBottomSheetManager.tsx # Dynamic sheet opening hook
├── useBottomSheetControl.ts # Portal sheet control hook
├── useBottomSheetContext.ts # Sheet internal context hook
├── useBottomSheetStatus.ts # External status monitoring hook
├── useAdapterRef.ts # Adapter ref helper hook
├── useAnimatedIndex.ts # Animated index context hook
├── useBackHandler.ts # Android back button handler
├── useScaleAnimation.ts # Scale animation hooks
├── useSheetRenderData.ts # Render order computation hook
├── useEvent.ts # Stable callback utility
│
└── adapters/ # Each adapter is a separate subpath export
├── gorhom-sheet/ # → 'react-native-bottom-sheet-stack/gorhom'
│ ├── index.ts
│ └── GorhomSheetAdapter.tsx
├── custom-modal/ # → 'react-native-bottom-sheet-stack' (main)
│ ├── index.ts
│ └── CustomModalAdapter.tsx
├── react-native-modal/ # → 'react-native-bottom-sheet-stack/react-native-modal'
│ ├── index.ts
│ └── ReactNativeModalAdapter.tsx
├── actions-sheet/ # → 'react-native-bottom-sheet-stack/actions-sheet'
│ ├── index.ts
│ └── ActionsSheetAdapter.tsx
└── swmansion/ # → 'react-native-bottom-sheet-stack/swmansion'
├── index.ts
└── SwmansionSheetAdapter.tsx
```
--------------------------------
### Configure Navigation Modes
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Control how sheets are presented in the stack using push, switch, or replace modes.
```typescript
// Push: Stack sheets (both visible)
open({ mode: 'push' });
// Switch: Hide previous, show new (can restore)
open({ mode: 'switch' });
// Replace: Close previous, show new (cannot restore)
open({ mode: 'replace' });
```
--------------------------------
### Initialize Animated Index Registry
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Global map for storing SharedValue animated indices used for backdrop opacity interpolation.
```typescript
const animatedIndexRegistry = new Map>();
```
--------------------------------
### Handling fully-controlled libraries
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/custom-adapters.md
Map open and close actions to specific index values and handle dismissal based on index changes.
```tsx
const [index, setIndex] = useState(0); // 0 = collapsed
const openIndex = detents.length - 1;
useImperativeHandle(ref, () => ({
expand: () => setIndex(openIndex),
close: () => setIndex(0),
}), [openIndex]);
// Settle = animation finished → opened/closed
const onSettle = (i: number) =>
i > 0 ? (animatedIndex.set(0), handleOpened()) : (animatedIndex.set(-1), handleClosed());
// Index change = user-driven snap → reaching collapsed means dismiss
const onIndexChange = (i: number) => {
if (i <= 0) handleDismiss();
};
```
--------------------------------
### Intercept close with callback pattern
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/close-interception.md
Recommended pattern for integrating with UI dialogs like Alert.alert. Call onConfirm to proceed or onCancel to abort.
```tsx
useOnBeforeClose(({ onConfirm, onCancel }) => {
if (isDirty) {
Alert.alert('Discard?', '', [
{ text: 'Cancel', onPress: onCancel },
{ text: 'Discard', onPress: onConfirm },
]);
} else {
onConfirm();
}
});
```
--------------------------------
### Initialize BottomSheetManagerProvider
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/components.md
The root provider required to manage the bottom sheet stack. Configure scale animations using the scaleConfig prop.
```tsx
{children}
```
--------------------------------
### Deploy Website without SSH
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/README.md
Deploys the website without using SSH. Replace '' with your actual GitHub username. This command builds the site and pushes it to the 'gh-pages' branch.
```bash
GIT_USER= yarn deploy
```
--------------------------------
### Updating and Resetting Bottom Sheet Parameters
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/context-preservation.md
Demonstrates how to use `updateParams` to modify parameters of an already open sheet and `resetParams` to clear them. It also shows how to conditionally open a sheet or update its parameters based on its current state using `useBottomSheetStatus` and `useBottomSheetContext`.
```tsx
import {
BottomSheetPortal,
useBottomSheetControl,
useBottomSheetStatus,
useBottomSheetContext,
} from 'react-native-bottom-sheet-stack';
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
const UserSheet = forwardRef((props, ref) => {
const { params } = useBottomSheetContext<'user-sheet'>();
const [user, setUser] = useState(null);
useEffect(() => {
if (params?.userId) {
fetchUser(params.userId).then(setUser);
}
}, [params?.userId]);
return (
{user && {user.name} }
);
});
function UserList() {
const { open, updateParams, resetParams } = useBottomSheetControl('user-sheet');
const { isOpen } = useBottomSheetStatus('user-sheet');
const showUser = (userId: string) => {
if (isOpen) {
// Sheet already open - just update the params
updateParams({ userId });
} else {
// Open with initial params
open({ params: { userId } });
}
};
const clearSelection = () => {
// Reset params to undefined
resetParams();
};
return (
showUser('user-1')} />
showUser('user-2')} />
);
}
```
--------------------------------
### Implement GorhomSheetAdapter
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/gorhom.md
Basic implementation of a bottom sheet using GorhomSheetAdapter with snap points and a close action.
```tsx
import { GorhomSheetAdapter } from 'react-native-bottom-sheet-stack/gorhom';
import { BottomSheetView } from '@gorhom/bottom-sheet';
const MySheet = forwardRef((props, ref) => {
const { close } = useBottomSheetContext();
return (
Sheet content
);
});
```
--------------------------------
### Define package.json exports
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Configures subpath exports to isolate adapter dependencies from the main entry point.
```json
{
".": "./lib/commonjs/index.js",
"./gorhom": "./lib/commonjs/adapters/gorhom-sheet/index.js",
"./react-native-modal": "./lib/commonjs/adapters/react-native-modal/index.js",
"./actions-sheet": "./lib/commonjs/adapters/actions-sheet/index.js",
"./swmansion": "./lib/commonjs/adapters/swmansion/index.js"
}
```
--------------------------------
### Implement BottomSheetScaleView
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/components.md
Wraps app content to apply scale animations when sheets are opened with scaleBackground enabled.
```tsx
```
--------------------------------
### Handle index changes with SwmansionSheetAdapter
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/swmansion.md
Demonstrates using the onIndexChange prop to trigger haptics when the sheet expands, utilizing the provided nextIndex and prevIndex arguments.
```tsx
{
if (nextIndex > prevIndex) haptics.impact(); // opening / expanding
}}
>
{/* ... */}
```
--------------------------------
### Typecheck Project Files
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CONTRIBUTING.md
Verifies that all project files adhere to TypeScript type definitions.
```sh
yarn typecheck
```
--------------------------------
### Defining and Opening Sheets from Different Locations
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/context-preservation.md
Illustrates how to define a `BottomSheetPortal` in one component (`SettingsScreen`) and open it from another (`Header`) using `useBottomSheetControl`. Both components must be rendered within the same `BottomSheetManagerProvider`.
```tsx
// In screens/Settings.tsx - define the sheet
function SettingsScreen() {
return (
{/* ... settings UI */}
);
}
// In components/Header.tsx - open from anywhere
function Header() {
const { open } = useBottomSheetControl('language-picker');
return (
open()}>
);
}
```
--------------------------------
### Custom Spring Animation Configuration
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/scale-animation.md
Utilize spring animation for a more natural feel by configuring damping and stiffness within the animation settings.
```tsx
{/* ... */}
```
--------------------------------
### CloseAllOptions
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/types.md
Configuration options for the closeAll() method.
```APIDOC
## CloseAllOptions
### Description
Options for `closeAll()` available on both `useBottomSheetManager` and `useBottomSheetControl`.
### Properties
- **stagger** (number) - Optional - Delay in ms between each cascading close animation. Default: 100.
```
--------------------------------
### Configure closeAll options
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/hooks.md
Control the stagger animation timing when closing all sheets.
```tsx
// Default stagger (100ms between each close)
await closeAll();
// Custom stagger
await closeAll({ stagger: 200 });
// No stagger (all close at once)
await closeAll({ stagger: 0 });
```
--------------------------------
### Open Sheets with Scale
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Trigger sheet opening in either portal or inline mode with background scaling enabled.
```typescript
// Portal mode
const { open } = useBottomSheetControl('my-sheet');
open({ scaleBackground: true });
// Inline mode
const { open } = useBottomSheetManager();
open( , { scaleBackground: true });
```
--------------------------------
### Implementing CustomModalAdapter
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/custom-modal.md
Wraps modal content with CustomModalAdapter and utilizes useBottomSheetContext for control.
```tsx
import { CustomModalAdapter, useBottomSheetContext } from 'react-native-bottom-sheet-stack';
function MyModal() {
const { close } = useBottomSheetContext();
return (
Modal content
);
}
```
--------------------------------
### Configure open options
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/hooks.md
Customize sheet behavior during the open call, including ID assignment and animation modes.
```tsx
open( , {
id: 'my-sheet-id', // Custom ID (optional)
groupId: 'my-group', // Custom group (optional)
mode: 'push', // 'push' | 'switch' | 'replace'
scaleBackground: true, // Enable scale animation
});
```
--------------------------------
### Implement ActionsSheetAdapter in React
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/actions-sheet.md
Use the adapter to render an action sheet with custom snap points and gesture support.
```tsx
import { ActionsSheetAdapter } from 'react-native-bottom-sheet-stack/actions-sheet';
function MyActionsSheet() {
const { close } = useBottomSheetContext();
return (
Actions sheet with snap points
);
}
```
--------------------------------
### Implement ReactNativeModalAdapter
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/react-native-modal.md
Use the adapter to wrap modal content, utilizing the useBottomSheetContext hook for closing functionality.
```tsx
import { ReactNativeModalAdapter } from 'react-native-bottom-sheet-stack/react-native-modal';
function FancyModal() {
const { close } = useBottomSheetContext();
return (
Fancy animated modal
);
}
```
--------------------------------
### Implement SwmansionSheetAdapter
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/swmansion.md
Use the SwmansionSheetAdapter component to wrap content in a native bottom sheet, utilizing the useBottomSheetContext hook for imperative control.
```tsx
import { SwmansionSheetAdapter } from 'react-native-bottom-sheet-stack/swmansion';
import { useBottomSheetContext } from 'react-native-bottom-sheet-stack';
function MySheet() {
const { close } = useBottomSheetContext();
return (
Native bottom sheet
);
}
```
--------------------------------
### Basic Bottom Sheet Portal Usage
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/context-preservation.md
Demonstrates how to declare a bottom sheet using `BottomSheetPortal` and control its opening and closing with `useBottomSheetControl`. The sheet's content remains within the React tree, ensuring context access.
```tsx
import {
BottomSheetPortal,
useBottomSheetControl,
} from 'react-native-bottom-sheet-stack';
function MyComponent() {
const { open, close } = useBottomSheetControl('my-sheet');
return (
{/* Declare the portal - content stays in your React tree */}
{/* Control it imperatively */}
open({ scaleBackground: true })} />
);
}
```
--------------------------------
### Define OnBeforeCloseCallback type
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/types.md
Defines the callback structure for useOnBeforeClose, supporting both callback-based and return-value-based decision logic.
```tsx
type OnBeforeCloseCallback = (context: {
onConfirm: () => void;
onCancel: () => void;
}) => void | boolean | Promise;
```
--------------------------------
### OnBeforeCloseCallback
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/types.md
A callback type used with useOnBeforeClose to intercept and confirm bottom sheet closing actions.
```APIDOC
## OnBeforeCloseCallback
### Description
Callback type for `useOnBeforeClose`. Receives `onConfirm` and `onCancel` callbacks to call when the user makes a decision.
### Signature
```tsx
type OnBeforeCloseCallback = (context: {
onConfirm: () => void;
onCancel: () => void;
}) => void | boolean | Promise;
```
### Usage
- Call `onConfirm()` to allow the close.
- Call `onCancel()` to block the close.
- Return `true` to allow close, `false` to cancel, or a `Promise` for async confirmation.
```
--------------------------------
### Configure 'inset' keyboard behavior
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/swmansion.md
Use 'inset' for content-sized or fixed-height sheets where the sheet itself should handle keyboard padding. Ensure the content is a plain scrollable or view to avoid double-insetting.
```tsx
// Content-sized sheet with an input that should stay above the keyboard.
// Full-height list with a search field in the header.
} /* … */ />
```
--------------------------------
### Define CloseAllOptions interface
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/types.md
Configuration interface for the closeAll method, allowing customization of the animation stagger delay.
```tsx
interface CloseAllOptions {
/** Delay in ms between each cascading close animation. Default: 100 */
stagger?: number;
}
```
--------------------------------
### Control portal sheets with useBottomSheetControl
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/CLAUDE.md
Provides type-safe methods to open, close, and update parameters for pre-defined portal sheets.
```typescript
const { open, close, updateParams } = useBottomSheetControl('user-sheet');
open({ params: { userId: '123' } });
updateParams({ userId: '456' });
```
--------------------------------
### ScaleConfig Interface
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/api/types.md
Configuration object for scale animation properties.
```tsx
interface ScaleConfig {
scale?: number; // Scale factor (default: 0.92)
translateY?: number; // Y translation in pixels (default: 10)
borderRadius?: number; // Border radius when scaled (default: 12)
animation?: ScaleAnimationConfig; // Animation config (default: timing 300ms)
}
```
--------------------------------
### Handling libraries without separate phases
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/custom-adapters.md
Call both handleDismiss and handleClosed when the library fires a single close event.
```tsx
const onClose = () => {
handleDismiss();
handleClosed();
};
```
--------------------------------
### SwmansionSheetAdapter Props
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/built-in-adapters/swmansion.md
The SwmansionSheetAdapter component accepts several props to configure its behavior and appearance.
```APIDOC
## SwmansionSheetAdapter Props
### handle
- **Type**: `boolean | { color?: string, width?: number, height?: number } | ReactElement`
- **Default**: `false`
- **Description**: Renders a grab handle as a chrome layer over the surface and insets the content to clear it. Pass `true` for the default pill, an object to restyle it, or a React element for full control.
### fullHeight
- **Type**: `boolean`
- **Default**: `false`
- **Description**: Expands the sheet to the full available height. Ignored when explicit `detents` are passed.
### fillContent
- **Type**: `boolean`
- **Default**: `auto`
- **Description**: Stretches the content to fill the sheet (`flex: 1`). Set `true` for fixed-height sheets or `false` for content-sized ones.
### keyboardBehavior
- **Type**: `'none' | 'inset'`
- **Default**: `'none'`
- **Description**: Configures keyboard avoidance. `'inset'` insets the content by the keyboard height using `react-native-keyboard-controller`.
### cornerRadius
- **Type**: `number`
- **Default**: `surface default`
- **Description**: Top corner radius applied to the surface and used to clip the content to those corners.
```
--------------------------------
### Handling prop-controlled libraries
Source: https://github.com/arekkubaczkowski/react-native-bottom-sheet-stack/blob/main/docs/docs/custom-adapters.md
Use local state to toggle visibility props on the underlying library component.
```tsx
const [visible, setVisible] = useState(false);
useImperativeHandle(ref, () => ({
expand: () => setVisible(true),
close: () => setVisible(false),
}), []);
```