0.1.2 β€’ Published 7 months ago

react-native-sheet-transitions v0.1.2

Weekly downloads
-
License
MIT
Repository
github
Last release
7 months ago

React Native Sheet Transitions 🎭

Beautiful iOS-like sheet transitions for React Native, Expo Go, and Web. Provides smooth, native-feeling custom modal transitions with gesture-based interactions.

Demo

Features ✨

  • πŸ”„ Smooth scale transitions
  • πŸ‘† Gesture-based dismissal with haptic feedback
  • πŸ“± iOS-like modal animations
  • 🎨 Customizable animations
  • πŸŒ— Two animation modes: incremental & decremental
  • 🎯 Border radius sync with gestures
  • πŸ” Opacity animations
  • πŸ“ Multi-directional dragging support

⚠️ Work in Progress: This package is under active development and not yet recommended for production use. Breaking changes may occur frequently. Feel free to contribute by submitting PRs or reporting issues!

Installation πŸ“¦

npm install react-native-sheet-transitions
# or
yarn add react-native-sheet-transitions
# or
bun add react-native-sheet-transitions

Peer Dependencies

npm install react-native-reanimated react-native-gesture-handler

Basic Usage πŸš€

  1. Wrap your app with SheetProvider:
import { SheetProvider } from 'react-native-sheet-transitions'

export default function App() {
  return (
    <SheetProvider>
      <Navigation />
    </SheetProvider>
  )
}
  1. Use SheetScreen in your modal:
import { SheetScreen } from 'react-native-sheet-transitions'

export default function ModalScreen() {
  const router = useRouter()
  
  return (
    <SheetScreen 
      onClose={() => router.back()}
      dragDirections={{ toBottom: true }}
      opacityOnGestureMove={true}
      containerRadiusSync={true}
    >
      <YourContent />
    </SheetScreen>
  )
}

API Reference πŸ“š

SheetProvider Props

PropTypeDefaultDescription
springConfigSpringConfig{ damping: 15, stiffness: 150, mass: 0.5 }Spring animation configuration
resizeType'incremental' \| 'decremental''decremental'Scale animation mode
enableForWebbooleanfalseEnable animations on web platform (not recommended)

SheetScreen Props

PropTypeDefaultDescription
onClose() => voidrequiredCallback when sheet is dismissed
scaleFactornumber0.83Scale factor for background content
dragThresholdnumber150Distance required to trigger dismiss
springConfigSpringConfig{ damping: 15, stiffness: 60, mass: 0.6, restDisplacementThreshold: 0.01, restSpeedThreshold: 0.01 }Spring animation config
dragDirectionsDragDirections{ toBottom: true }Enabled drag directions
isScrollablebooleanfalseEnable scroll handling for content
opacityOnGestureMovebooleanfalseEnable opacity animation during drag
containerRadiusSyncbooleantrueSync border radius with drag
initialBorderRadiusnumber50Initial border radius value
styleViewStyleundefinedAdditional container styles
disableSyncScaleOnDragDownbooleanfalseDisable scale sync during drag
customBackgroundReactNodeundefinedCustom background component with fade animation
onOpenStart() => voidundefinedCalled when sheet starts opening animation
onOpenEnd() => voidundefinedCalled when sheet opening animation completes
onCloseStart() => voidundefinedCalled when user gesture triggers close
onCloseEnd() => voidundefinedCalled when close animation completes (replaces onClose if provided)
onBelowThreshold() => voidundefinedCalled when drag goes below threshold after exceeding it
disableRootScalebooleanfalseDisable background scaling effect
disableSheetContentResizeOnDragDownbooleanfalseDisable sheet content scaling during drag down

Types

interface SpringConfig {
  damping?: number
  stiffness?: number
  mass?: number
  velocity?: number
}

interface DragDirections {
  toTop?: boolean
  toBottom?: boolean
  toLeft?: boolean
  toRight?: boolean
}

Advanced Usage πŸ”§

Incremental Scale Mode

Background scales up instead of down:

<SheetProvider resizeType="incremental">
  <App />
</SheetProvider>

Custom Animation Config

<SheetScreen 
  springConfig={{
    damping: 15,
    stiffness: 120,
    mass: 0.8
  }}
  scaleFactor={0.85}
  dragThreshold={100}
  opacityOnGestureMove={true}
  containerRadiusSync={true}
  initialBorderRadius={40}
>
  <Content />
</SheetScreen>

Multi-directional Dragging

<SheetScreen 
  dragDirections={{
    toBottom: true,
    toLeft: true,
    toRight: true
  }}
  onClose={handleClose}
>
  <Content />
</SheetScreen>

Custom Background

You can add a custom background component that fades in/out with the modal:

import { BlurView } from 'expo-blur'

<SheetScreen 
  customBackground={
    <BlurView 
      intensity={20} 
      style={StyleSheet.absoluteFill}
    />
  }
  onClose={handleClose}
>
  <Content />
</SheetScreen>

The background component will:

  • Fade in when modal opens
  • Fade out when modal closes
  • Be positioned absolutely behind the modal content
  • Not sync opacity with drag gestures

Expo Router Integration πŸ”—

Configure your modal screen:

// app/_layout.tsx
import { Stack } from 'expo-router'
import { SheetProvider } from 'react-native-sheet-transitions'

export default function Layout() {
  return (
    <SheetProvider>
      <Stack>
        <Stack.Screen name="index" />
        <Stack.Screen 
          name="modal" 
          options={{
            presentation: 'transparentModal',
            contentStyle: { backgroundColor: 'transparent' }
          }}
        />
      </Stack>
    </SheetProvider>
  )
}

Contributing 🀝

Pull requests are welcome! For major changes:

  1. Fork the repository
  2. Create your feature branch
  3. Commit your changes
  4. Push to the branch
  5. Open a pull request

Lifecycle Callbacks

The SheetScreen component provides several callbacks for precise control:

interface SheetScreenProps {
  // Called when sheet starts opening animation
  onOpenStart?: () => void
  
  // Called when sheet opening animation completes
  onOpenEnd?: () => void
  
  // Called when user drags above threshold
  onCloseStart?: () => void
  
  // Called when user drags below threshold
  onBelowThreshold?: () => void
  
  // Called when close animation completes
  onCloseEnd?: () => void
}

Example with Haptic Feedback

<SheetScreen
  onCloseStart={() => {
    // Warn user they can release to close
    Haptics.notificationAsync(Haptics.NotificationFeedbackType.Warning)
  }}
  onBelowThreshold={() => {
    // Reset state when going below threshold
  }}
  onCloseEnd={() => {
    // Success haptic when sheet closes
    Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success)
    router.back()
  }}
>
  {/* content */}
</SheetScreen>

Platform Specific Behavior πŸ“±

Background Scaling

The background scaling effect (where the previous screen scales down when the sheet opens) is:

  • βœ… Enabled by default on iOS
  • ❌ Disabled by default on Android and Web
  • Can be disabled on iOS using disableRootScale={true}
<SheetScreen 
  disableRootScale={true}  // Disable background scaling even on iOS
  onClose={handleClose}
>
  <Content />
</SheetScreen>

Web Platform Support ⚠️

By default, sheet transitions are disabled on web platforms for better UX and accessibility. Web modals should follow web platform conventions.

If you need to enable animations on web:

<SheetProvider enableForWeb={true}>
  <App />
</SheetProvider>

Note: Enabling sheet transitions on web is not recommended as it can:

  • Interfere with native web accessibility features
  • Create inconsistent UX across different browsers
  • Impact performance on lower-end devices
  • Break expected web modal behaviors

Consider using native web modals or dialogs for better user experience on web platforms.

Roadmap πŸ—ΊοΈ

High Priority

  • Fix Scrolling gesture handling and momentum issues
  • Multiple Portal support for nested sheets
  • iOS-like sheet detents (snap points)
    • Configurable small, medium, large positions
    • Custom snap point values
    • Default snap point configuration
    • Smooth animations between detents
    • Gesture-based snapping behavior

Plans

  • Enhanced gesture controls
    • Velocity-based dismissal
    • Directional lock
  • Accessibility improvements
    • Screen reader support
    • Reduced motion preferences
    • Focus support
  • More animations
    • Shared element transitions
  • Better web support
    • Keyboard navigation
    • Focus trapping

License πŸ“„

MIT Β© saulamsal

0.1.2

7 months ago

0.1.1

7 months ago

0.1.0

8 months ago