Conversation
* feat!: synchronous per-detent container layout Size the container to the sheet's visible height per detent instead of screen height / largest detent. Requires RN 0.82+. - iOS: report all size changes; immediate state updates relayout Yoga within the same UIKit layout pass - Android: per-detent state sizing (grow before animation, shrink on settle); remove scroll expansion padding workaround - JS: container always fills the sheet so flex layouts track detents - Web: sized flex wrapper for non-scrollable sheets (auto/form keep content-fit flow) * feat(ios): drop AutoLayout constraints in favor of Yoga layout Container and footer frames now come purely from Yoga (synchronous state updates land them in the same UIKit layout pass). Footer is pinned via bottom:0 style; keyboard avoidance uses a transform. Removes LayoutUtil. * feat!: auto-detect scrollables, deprecate scrollable prop ScrollViews/FlatLists now plug in directly like a regular view: - Content fills the sheet by default (except with auto detents, which derive height from natural content) - Native scroll wiring (insets, keyboard, nested scrolling, edge effects) always applies to the detected ScrollView - iOS: removed scrollview frame-forcing; Yoga owns the frame - scrollable prop is deprecated and a no-op on native * feat(android): resize container in realtime while dragging Track the sheet's visible height per-frame during drag (and post-release settle) so the container resizes with the finger like iOS, killing the settle flicker. Skip detent reconfigure mid-drag — the size change is driven by the drag itself and resetting behavior state kills the gesture. * feat(android): synchronous Fabric state updates via JNI Kotlin's StateWrapper.updateState is hardcoded async, so the container's Yoga layout lagged the sheet by a frame or two during drags (footer jumping). Bridge to ConcreteState::updateState with unstable_Immediate — commits and mounts within the same UI-thread frame, like iOS. Falls back to the async path when the codegen lib isn't loadable (merged-so builds). * docs: add PR link to changelog entries * chore(docs): require Node 24 for Vercel builds * chore: run install * feat(web): track sheet visible height in realtime while dragging * feat!: remove deprecated scrollable prop Scrollables are auto-detected — the prop was already a no-op on native. Web now always uses the sized content-fill layout for plugged scrollables. Docs updated for auto-detection.
* feat: support auto detent with scrollables Content shadow node fills the container (flexGrow/flexShrink via Fabric state) when a ScrollView is pinned so the viewport is bounded per detent, while the auto detent height is measured from the ScrollView's content size (contentFrame - scrollFrame + contentSize). Size reports coalesce to the next tick when pinned to avoid mid-transaction frame mismatches, and iOS seeds screen dimensions pre-present so content can lay out and measure before presenting (parity with Android). * fix(ios): resolve auto detent height lazily for correct initial size The auto detent captured contentHeight as a constant when detents were set up, so a first present raced in-flight content measurement and opened at a stale size before resizing. The resolver now reads contentHeight + headerHeight at layout time, and size changes during presentation invalidate detents so the in-flight animation retargets. * fix(ios): keep detents stable across present/dismiss transitions Size changes no longer reassign sheet.detents (which re-lays out the whole presentation stack, glitching the sheet behind). Auto/peek detents resolve lazily from snapshots; size changes just refresh snapshots + invalidateDetents. Measure heights synchronously at present time so no mid-flight retarget snaps the animation, and drop size updates while dismissing or not presented. * chore(example): add item button to FlatListSheet to showcase auto detent resize * chore(example): start FlatListSheet with 10 items * docs: changelog for #743 * docs: drop bug fix changelog entry for #743 * docs: one changelog entry per pr * chore(example): add remove item button to FlatListSheet * feat(web): support auto detent with plugged scrollables Mirror native: a plugged scrollable keeps the bounded (sized) layout so its viewport can scroll, while the auto detent resolves from the natural height (viewport replaced by scroll content size), observed for resizes. Also fixes drag release being swallowed when the lowest snap offset is 0 (clamped auto) — wrapper overshoot now counts as movement — and switches the drawer to overflow: clip so browser scroll-into-view can't offset it and block sheet drags. * chore: flatlist sheet auto detent only
* refactor(ios): unify position tracking into a single display link Replace the five position tracking paths (layout emission, pan gesture emission, fake transition view + coordinator timer, interactive dismiss link, dispatch_after settle hacks) with one self-stopping CADisplayLink that samples the presented view's live position. - livePosition: model position + presentation-vs-model delta in window space + container translation; ancestor animations compose, persistent transforms cancel out - Settle is detected (still frames + no in-flight animations) instead of timed, and consumes pending detent changes and offset learning - Offset learning is now flag-driven, so keyboard/rotation moves no longer risk corrupting learned detent offsets - Kicks cascade up the sheet stack so a parent emits realtime while it moves behind a presenting/dragging child sheet - Drag-release snaps and programmatic resizes are now realtime-tracked (actual UIKit spring) instead of a single non-realtime emit * chore: changelog
* feat!: content lays out naturally like a regular view Content no longer fills the sheet by default. It wraps its children's natural height like a regular view or a react-navigation screen — pass `flex: 1` via `style` to fill the sheet's visible height per detent. Scroll views are only special-cased for keyboard handling and `auto` sizing (where the sheet height derives from the scroll content, so the viewport is force-bounded). For fixed detents, bound scrollables with `flex: 1` like any regular view. * docs: changelog for #746
* feat: add headerOptions prop with absolute header position * docs: add headerOptions documentation * docs: add changelog entry
* feat!: add footerOptions prop with relative footer position Footer now lays out relative by default — it takes up space below the content (pinned to the bottom edge via Yoga) and its height is included in the auto detent calculation. Set footerOptions.position to 'absolute' to restore the previous floating behavior. * feat: exclude relative footer from peek detent calculation A relative footer is laid out below the content, so it's pushed off-screen at the peek detent and contributes no height.
* feat: relative footer owns the bottom inset for auto detent * docs: changelog
* feat: footer owns the bottom inset adjustment A relative footer now absorbs the bottom safe-area inset as padding via a custom shadow node (state-driven, like the content view) — its background fills the inset and the auto height stays consistent with or without a footer. Applied on iOS, Android, and Web. * fix(android): apply footer inset padding synchronously The async state update raced setupSheetDetents — the behavior could be configured against the unpadded footer height, landing the auto detent an inset short. Bridge the footer state through TrueSheetStateUpdater (unstable_Immediate) so the footer is padded in the same frame. * feat: footer owns the inset for absolute position too The footer absorbs the bottom safe-area inset whenever insetAdjustment is automatic, regardless of position. The inset is skipped while the keyboard is open — the footer hugs the keyboard with no gap. Peek detents exclude the inset when an absolute footer carries it, avoiding a double count. * chore(example): set footer background via footerStyle The native footer absorbs the bottom inset, so the background must be on the footer component itself to fill it. Drops the manual inset padding left in GestureSheet. * docs: update changelog
…osition Absolute footers reserve content bottom padding; relative footers don't.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
* fix: keyboard scroll misses the bottom inset with a footer The footer's safe-area inset drop raced the keyboard caret scroll and detent setup on iOS (async state update) — push it with unstable_Immediate like the container size, matching Android's sync updater. An absolute footer rises above the keyboard and covers the content's bottom edge, but the keyboard inset only compensated the keyboard — include the footer's occlusion (height minus the dropped inset) on both platforms so focused inputs clear the footer without a manually tuned keyboardScrollOffset. * docs: changelog entry for #752
Keyboard-open drags read as negative slideOffset (detents collapse to the expanded position), sinking the footer behind the keyboard. On release, the keyboard-hide reconfigure shrinks the container without repositioning the bottom-pinned footer, and onSlide skipped positioning during keyboard transitions - reposition same-frame and on every slide frame instead.
TextInput touches raise disallow-intercept (native + JS responder block), which is only swallowed for draggable EditText targets - but targets inside the pinned scrollable never qualified. When the scrollable can't scroll (fully expanded, content fits) it can't nested-drag the sheet either, so the gesture died. Only skip the draggable-chain check when the pinned scrollable can actually scroll or hosts pull-to-refresh.
* fix(ios): skip size reports while stacked behind a child sheet * docs: changelog
* fix: relative footer stays in the layout flow behind the keyboard Only an absolute footer floats above the keyboard now. A relative footer keeps its position and safe-area inset, and the keyboard scroll inset subtracts its height since it shields part of the keyboard's overlap. * docs: changelog
* chore: upgrade examples to Expo SDK 57 and RN 0.86 - expo example → SDK 57 (expo ~57.0.7, expo-* 57.x) - react-native 0.85.3 → 0.86.0 across root, bare, expo, shared - reanimated 4.3.1 → 4.5.0, worklets 0.8.3 → 0.10.0, gesture-handler ~2.32.0 - drop react-native canBecomeFirstResponder patch (upstreamed in 0.86) - keep react-native-screens 4.25.2 (SDK 57 pinned) + TrueSheet modal patch - regenerate bare ios Podfile.lock/pbxproj for RN 0.86 * docs: changelog * fix(example): bump bare React-Core-prebuilt to 0.86.0 Stale 0.85.3 prebuilt React.xcframework linked old jsi (Runtime&), crashing on launch against RN 0.86's IRuntime& symbol.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v4 layout rewrite — the sheet lays out synchronously per detent with Yoga owning all frames