npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-adaptive-bottom-sheet

v1.1.4

Published

A flexible self-measuring, gesture-driven adaptive bottom sheet for React Native with keyboard avoidance and smooth animations

Downloads

63

Readme

React Native Adaptive Bottom Sheet

A flexible, self-measuring, gesture-driven adaptive bottom sheet for React Native with multiple presentation modes, keyboard avoidance, and smooth animations.

Features

  • Adaptive Height - Automatically measures content or use fixed height
  • Multiple Presentation Modes - Bottom sheet, dialog, sidebar, or auto-detect
  • Type-Safe Props - Discriminated unions ensure you only use props valid for each mode
  • Gesture Driven - Smooth drag-to-close gestures with spring animations
  • Keyboard Avoidance - Optional keyboard handling
  • Customizable - Custom headers, themes, and styling per slot
  • Performance - Built with Reanimated 3 for 60fps animations
  • Safe Areas - Respects device safe areas (configurable)
  • Portal Based - Renders above all content using portal system

Installation

npm install react-native-adaptive-bottom-sheet
# or
yarn add react-native-adaptive-bottom-sheet
# or
pnpm install react-native-adaptive-bottom-sheet

Peer Dependencies

npm install react-native-gesture-handler react-native-reanimated react-native-safe-area-context react-native-worklets react-native-svg

Follow the setup instructions for each:

Important: Your app must have GestureHandlerRootView and SafeAreaProvider at the root level.

Quick Start

import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import { AdaptiveBottomSheetProvider } from 'react-native-adaptive-bottom-sheet';

export default function App() {
  return (
    <GestureHandlerRootView style={{ flex: 1 }}>
      <SafeAreaProvider>
        <AdaptiveBottomSheetProvider>
          {/* Your app content */}
        </AdaptiveBottomSheetProvider>
      </SafeAreaProvider>
    </GestureHandlerRootView>
  );
}
import { useBottomSheet, AdaptiveBottomSheet } from 'react-native-adaptive-bottom-sheet';

function MyComponent() {
  const sheet = useBottomSheet();

  return (
    <>
      <Button title="Open" onPress={() => sheet.openSheet()} />

      <AdaptiveBottomSheet bottomSheetInstance={sheet}>
        <Text>Hello Bottom Sheet!</Text>
      </AdaptiveBottomSheet>
    </>
  );
}

Presentation Modes

The component supports 4 presentation modes, each with its own specific props:

| Mode | Description | Specific Props | |------|-------------|----------------| | bottomSheet | Traditional sheet sliding from bottom | None | | dialog | Centered modal dialog | dialogDragToClose | | sidebar | Horizontal panel from left/right | sidebarPosition, sidebarWidth, sidebarMinWidth, sidebarMaxWidth, sidebarDragToClose | | auto | Auto-selects based on screen width | All mode-specific props |

Type-Safe Props by Mode

The library uses discriminated unions to ensure type safety. TypeScript will show an error if you try to use props that don't belong to the selected mode:

// ✅ Correct - sidebar props with mode="sidebar"
<AdaptiveBottomSheet
  mode="sidebar"
  sidebarPosition="right"
  sidebarWidth={350}
/>

// ✅ Correct - dialog props with mode="dialog"
<AdaptiveBottomSheet
  mode="dialog"
  dialogDragToClose={false}
/>

// ❌ TypeScript Error - sidebarWidth doesn't exist on DialogModeProps
<AdaptiveBottomSheet
  mode="dialog"
  sidebarWidth={300}
/>

// ✅ Correct - mode="auto" accepts all props (runtime resolution)
<AdaptiveBottomSheet
  mode="auto"
  tabletBreakpoint={1024}
  dialogDragToClose={false}
  sidebarPosition="left"
/>

Bottom Sheet Mode

Default mode. Slides up from the bottom of the screen.

<AdaptiveBottomSheet
  mode="bottomSheet"
  bottomSheetInstance={sheet}
>
  <YourContent />
</AdaptiveBottomSheet>

Dialog Mode

Centered modal with optional drag-to-close.

<AdaptiveBottomSheet
  mode="dialog"
  bottomSheetInstance={sheet}
  dialogDragToClose={false}
>
  <YourContent />
</AdaptiveBottomSheet>

Sidebar Mode

Horizontal panel that slides from left or right edge.

<AdaptiveBottomSheet
  mode="sidebar"
  bottomSheetInstance={sheet}
  sidebarPosition="right"
  sidebarWidth={320}
  sidebarDragToClose={true}
>
  <NavigationMenu />
</AdaptiveBottomSheet>

Auto Mode (Responsive)

Automatically switches between modes based on screen width:

  • Width < breakpoint → bottomSheet
  • Width >= breakpoint → dialog
<AdaptiveBottomSheet
  mode="auto"
  bottomSheetInstance={sheet}
  tabletBreakpoint={768}
>
  <YourContent />
</AdaptiveBottomSheet>

API Reference

useBottomSheet(initialValue?: boolean)

Hook that returns a controller object for managing the bottom sheet.

const sheet = useBottomSheet();

sheet.openSheet();           // Open the sheet
sheet.closeSheet();          // Close the sheet
sheet.toggleSheet();         // Toggle open/close
sheet.isOpen;                // Current state (boolean)
sheet.instanceID;            // Unique identifier

Props

Common Props (All Modes)

| Prop | Type | Default | Description | |------|------|---------|-------------| | children | ReactNode | required | Content to display | | bottomSheetInstance | BottomSheetHook | required | Controller from useBottomSheet | | maxHeight | number | screen - 90 | Maximum height | | fixedHeight | number | - | Fixed height (disables auto-sizing) | | headerComponent | ReactNode | - | Custom header | | hideCloseButton | boolean | false | Hide close button | | disableBackdropDismiss | boolean | false | Prevent backdrop tap dismiss | | avoidKeyboard | boolean | false | Push up when keyboard opens | | onDismiss | () => void | - | Callback on dismiss | | darkMode | boolean | false | Enable dark theme | | styles | BottomSheetStyleOverrides | - | Style overrides by slot | | renderCloseIcon | (params) => ReactNode | - | Custom close icon | | closeButtonProps | TouchableOpacityProps | - | Close button props | | tabletBreakpoint | number | 768 | Width breakpoint for auto mode | | disableSafeArea | boolean | false | Ignore safe area insets |

Dialog Mode Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | dialogDragToClose | boolean | true | Enable vertical drag to dismiss |

Sidebar Mode Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | sidebarPosition | 'left' \| 'right' | 'left' | Which edge to slide from | | sidebarWidth | number | - | Fixed width (overrides min/max) | | sidebarMinWidth | number | 280 | Minimum width | | sidebarMaxWidth | number | 400 | Maximum width | | sidebarDragToClose | boolean | true | Enable horizontal drag to dismiss |

Style Overrides

Customize appearance per slot:

<AdaptiveBottomSheet
  bottomSheetInstance={sheet}
  styles={{
    backdrop: { backgroundColor: 'rgba(0,0,0,0.7)' },
    sheet: { backgroundColor: '#1a1a1a', borderRadius: 24 },
    header: { paddingHorizontal: 16 },
    content: { padding: 20 },
    closeButton: { opacity: 0.8 },
    sidebarContainer: { /* sidebar mode only */ },
  }}
/>

Reserved keys (controlled by animations, will warn if overridden):

  • sheet: transform, opacity, position, zIndex, bottom, top, left, right
  • backdrop: opacity, position, zIndex, top, left, right, bottom

Safe Area Control

By default, the sheet respects device safe areas (notch, home indicator). Disable this when rendering inside a container that already handles insets:

<AdaptiveBottomSheet
  bottomSheetInstance={sheet}
  disableSafeArea={true}
>
  <YourContent />
</AdaptiveBottomSheet>

TypeScript Exports

import {
  // Component & Hook
  AdaptiveBottomSheet,
  AdaptiveBottomSheetProvider,
  useBottomSheet,

  // Types
  type BottomSheetProps,           // Main discriminated union
  type CommonBottomSheetProps,     // Shared props
  type BottomSheetModeProps,       // mode="bottomSheet"
  type DialogModeProps,            // mode="dialog"
  type SidebarModeProps,           // mode="sidebar"
  type AutoModeProps,              // mode="auto"
  type BottomSheetStyleOverrides,
  type PresentationMode,
  type SidebarPosition,

  // Type Guards
  isSidebarMode,
  isDialogMode,
  isBottomSheetMode,
  isAutoMode,
} from 'react-native-adaptive-bottom-sheet';

Examples

Fixed Height

<AdaptiveBottomSheet
  bottomSheetInstance={sheet}
  fixedHeight={400}
>
  <YourContent />
</AdaptiveBottomSheet>

With Custom Header

<AdaptiveBottomSheet
  bottomSheetInstance={sheet}
  headerComponent={
    <View style={styles.header}>
      <Text style={styles.title}>Settings</Text>
    </View>
  }
  hideCloseButton
>
  <YourContent />
</AdaptiveBottomSheet>

Keyboard Avoidance

<AdaptiveBottomSheet
  bottomSheetInstance={sheet}
  avoidKeyboard
>
  <TextInput placeholder="Type here..." />
</AdaptiveBottomSheet>

Sidebar Navigation

<AdaptiveBottomSheet
  mode="sidebar"
  bottomSheetInstance={menuSheet}
  sidebarPosition="left"
  sidebarWidth={280}
  darkMode
>
  <NavigationMenu onNavigate={() => menuSheet.closeSheet()} />
</AdaptiveBottomSheet>

Responsive Modal

<AdaptiveBottomSheet
  mode="auto"
  bottomSheetInstance={sheet}
  tabletBreakpoint={768}
  dialogDragToClose={false}
  maxHeight={500}
>
  <ModalContent />
</AdaptiveBottomSheet>

Requirements

  • React Native >= 0.64.0
  • React >= 16.8.0
  • react-native-gesture-handler >= 2.0.0
  • react-native-reanimated >= 3.0.0
  • react-native-safe-area-context >= 4.0.0
  • react-native-worklets >= 0.5.0
  • react-native-svg >= 13.0.0

License

MIT