Repository navigation
Releases: ramssutharr/react-native-inline-sheet
Release list
v0.3.2 — native collection views get the scroll lock
Fixed
- iOS: a native
UICollectionViewin the body now takes part in the scroll↔sheet hand-off. The resolver only knew React lists, so a body whose list is native (the Giphy grid, for example) scrolled under a half-open sheet instead of expanding it to the top first. When the body holds no React scroll view, the first verticalUICollectionViewis used; pickers, date pickers and text views (and anything inside them) are never candidates.
Full Changelog: v0.3.1...v0.3.2
v0.3.1 — keyboard follows interactive dismissal
iOS fixes for the keyboard and gesture edges, back-ported from the frame's lift into a pure-Swift app where they were found in daily use.
Fixed
- Footer follows an interactive keyboard dismissal. A list with
keyboardDismissMode="interactive"drags the keyboard down with the finger, and iOS fires no keyboard notification for that, so the footer stayed lifted in mid-air until the keyboard had fully gone. A 1pt view now rides thekeyboardLayoutGuideand re-lays out the sheet on every move (iOS 17+ reads the guide without the safe area; iOS 15/16 treat the safe-area rest position as "no keyboard"). - No jump when the keyboard hides mid-drag. With
enableBlurKeyboardOnGesture, the resign fired a keyboard hide that animated the sheet to a detent while the finger was still moving it. While the sheet owns the drag, the hide only updates the lift; the release settles as usual. - In-gesture hand-off reports a settled layout. When the header reaches the top and the list takes the rest of the gesture, no settle follows, so
onChange/onLayoutChangenever fired and content kept the previous detent's body size. - Footer / handle unmount go through the same path as a height change, so an
autodetent re-settles and the layout event carries the new geometry. - Body unmount drops the content-lock observation instead of leaving it pinned to the old list.
- The content-sized height re-lays out even while resting at a fixed detent (dim progress, footer anchor), and the grabber is drawn above the slots so
grabberAreaHeight={0}cannot hide it.
Notes
- iOS only; Android is unchanged.
- The "lift unchanged" early return in the keyboard notification handler is gone: the guide tracker updates the lift first, and the handler still owns
keyboardBehaviorexpand /keyboardBlurBehaviorrestore and the events.
Full Changelog: v0.3.0...v0.3.1
v0.3.0 — presses survive a moving finger
Fix (iOS): buttons inside the sheet no longer drop presses on real devices. On Fabric, Pressable checks every touch-move against a rect from measure(), which reads the shadow tree. The shadow tree placed sheet content at the hidden host, not where the native sheet draws it. So any press that emitted a touch-move was lost: a slightly rolling finger, or just pressing harder on a 3D Touch iPhone. Simulator clicks emit no moves, which is why it never reproduced there. Each sheet slot now reports its real on-screen position to the shadow tree, so the measured and drawn rects match.
Fix (iOS): a tap that drifts is no longer taken as a drag. The sheet's pan now waits for 16pt of travel, the iOS counterpart of Android's touch slop.
Upgrading: this release adds a native component (NativeBottomSheetSlot), so run pod install after upgrading. No API changes; Android is unchanged.
v0.2.1 — date picker crash fix
Fixed
- iOS: crash when a sheet holds a
UIDatePicker(or a multilineTextInput). The plain-UIKit scroll view search ran whenever the React resolver found no list, latched onto the picker's internal table (aUIScrollView), and pinned its offset to 0 while the picker snapped it back, until the stack overflowed. The host's resolver is now authoritative; the UIKit-wide fallback only runs when no resolver is injected, and skips pickers and text views.
Full Changelog: v0.2.0...v0.2.1
v0.2.0 — gorhom parity
Everything @gorhom/bottom-sheet does that a user can see or feel, on the native frame. Sheets ported from gorhom keep their prop names and, from this release, their defaults.
Stacking
stackBehavior—'switch'(default: the sheet on top slides out with its content still mounted and comes back when the new one is dismissed),'push','replace'. No provider needed.name,useBottomSheetModal().dismiss(name?)/dismissAll(), anddismissAllSheets()outside React.- Ref gains
minimize()/restore().
Animated values (Reanimated, optional)
- Native
onPositionChangeemits the sheet's live position per frame, armed only while something listens. - A
useEventworklet writes it into shared values on the UI thread:animatedIndex/animatedPositionprops,useBottomSheetAnimated(), and gorhom'suseBottomSheet()shape. - Reanimated stays an optional peer; without it the same objects update when the sheet settles.
Modal mode
mode="modal"(or acontainerComponent) attaches to React Native's root surface view, above every screen, with React touches intact.
Sizing and gestures
- Detents are sorted by resolved height, so a content-sized detent lands wherever the content puts it (gorhom's dynamic-sizing rule). Every index refers to that order.
maxDynamicContentSize,snapToPosition(dp | '50%'),forceClose.enableContentPanningGesture,enableHandlePanningGesture.enableOverDrag/overDragResistanceFactorwith gorhom's exactsqrt(1 + excess) × factorcurve, from the handle or a body without a list.detachedwithstyleside margins ordetachedMargin, all corners rounded.- Custom
handleComponent, rendered natively in asheet-handleslot and given the animated values. presentOnMount/animateOnMountfor gorhom's non-modalBottomSheet.
Keyboard
keyboardBehavior="interactive"(keyboardMode="lift-sheet") is now hybrid: whatever the sheet cannot rise, the footer rises on its own, so a footer always clears the keyboard.keyboardBlurBehavior="restore"returns to the pre-keyboard detent.enableBlurKeyboardOnGesture(aliasdismissKeyboardOnDrag).- New
contentBottomInset: the content's own safe-area padding is spent over the keyboard instead of stacking on top of it.
Events
onChange(index, position, type)withSNAP_POINT_TYPE.PROVIDED | DYNAMIC.onAnimate(from, to, fromPosition, toPosition).onClosealias ofonDismiss.
Accessibility and motion
- VoiceOver / TalkBack labels on the backdrop and handle; the handle is an adjustable control that moves between detents.
- Reduce Motion (iOS) and animator duration scale (Android) shorten the springs.
Also in this release (from 0.1.1)
- Android: the hardware back press is claimed in JS while presented, so back closes the sheet instead of leaving the screen.
⚠️ Breaking: defaults now match gorhom 5.x
| 0.1.x | 0.2.0 | |
|---|---|---|
enableDynamicSizing |
false |
true |
enableOverDrag |
false |
true (2.5) |
keyboardBehavior |
expand to top | 'interactive' |
dismissKeyboardOnDrag |
true |
false |
| background | system, radius 24 | white, radius 15 |
| handle | 36×5 | 7.5% of the window × 4, 24dp area |
Migration: sheets with fixed detents that must not gain a content-sized detent need enableDynamicSizing={false}; an Instagram-style comments sheet wants keyboardBehavior="extend" and dismissKeyboardOnDrag. The backdrop keeps BottomSheetBackdrop's defaults (black, 0.5, close on press); pass backdropOpacity={0} for gorhom's bare default.
Not covered
Custom backdropComponent (accepted, not rendered), gorhom's footerComponent render prop, Reanimated animationConfigs, and RNGH simultaneousHandlers / waitFor.
Full Changelog: v0.1.0...v0.2.0
v0.1.0 — Initial release
Instagram-style native bottom sheet for React Native (Fabric / New Architecture).
The frame is native — present/dismiss spring, drag, detents, dim backdrop,
scroll ↔ sheet hand-off, keyboard handling, back gesture — implemented in UIKit
on iOS and Android Views on Android, with nothing running on the JS thread per
frame. The content is ordinary React.
Highlights
- Inline mode: the sheet attaches to the hosting screen's own native view —
above a tab bar, below anything the navigator pushes. Tap a name in comments,
the profile slides over the open sheet; pop, and the sheet is exactly where
you left it. - Gorhom-compatible API:
snapPoints('60%', dp,'CONTENT_HEIGHT'),
index,enableDynamicSizing,enablePanDownToClose,topInset,
bottomInset,backgroundStyle,handleIndicatorStyle,
handleComponent={null},backdropColor/backdropOpacity,
keyboardBehavior,onAnimate,onChange— and the same imperative ref
(present(data),dismiss,close,snapToIndex,expand,collapse). - Gorhom's gesture model: the list is locked at offset 0 unless the sheet is
fully expanded; a drag that reaches the top hands the rest of the gesture to
the list; a fling settles the sheet with the list still. - Keyboard: the footer slot is pinned to the visible bottom and lifted
natively; the sheet springs to its top detent when the keyboard opens
(expandOnKeyboard) and drops the keyboard when dragged (dismissKeyboardOnDrag). - Instagram footer: pinned at the screen edge while the sheet is at or above
its lowest detent; slides off with the sheet when dragged to dismiss. SheetRouter: push/pop multi-step content inside one sheet.useBottomSheetNativeLayout()/useBottomSheetNativeActions()for content.
Requirements
- React Native ≥ 0.80 with the New Architecture (Fabric)
- iOS 15.1+, Android minSdk 24
- Autolinked; run
pod installon iOS
Known limitations
- Inline mode only (a sheet that must sit above pushed screens — "modal" mode — is planned)
- A custom
handleComponentis not rendered natively yet (nullhides the grabber) - Ships untranspiled TypeScript: allow it through Jest's
transformIgnorePatterns