Skip to content

[Feature request] Native footer slot pinned to the sheet's visible bottom edge #62

Description

@falcondpr

What

A footer prop on BottomSheet / ModalBottomSheet — a sibling to the existing surface slot — that renders a React-composed view pinned to the sheet's visible bottom edge natively, staying frame-perfect while the sheet is dragged, snapped, or resized.

<BottomSheet
  index={index}
  onIndexChange={setIndex}
  surface={/* ... */}
  footer={
    <View style={styles.footer}>
      <Button title="Confirm" onPress={onConfirm} />
    </View>
  }
>
  {/* scrollable content */}
</BottomSheet>

Ideally the content region would also account for the footer's height (similar to how the content-region inset works today), so scrollables inside the sheet can scroll their last items above the footer rather than behind it.

Why

A fixed action area (confirm/cancel buttons, a total-price bar, a "add to cart" CTA) is one of the most common bottom-sheet compositions, and there is currently no first-class way to build one:

  • Absolutely positioning a footer inside the sheet content doesn't work during drags: the sheet container is translated natively, so a content-anchored footer moves off-screen with it as the sheet collapses, and content-size updates go through the shadow tree asynchronously.
  • The documented position-tracking approach (onPositionChange + wrapNativeView={Animated.createAnimatedComponent} + a useEvent worklet) can counter-translate a footer on the UI thread, and it works well — but it reintroduces a Reanimated dependency and per-frame handler work for what is arguably core sheet composition. Not requiring Reanimated is one of this library's stated advantages over @gorhom/bottom-sheet.
  • Rendering the footer outside the sheet as a screen-bottom sibling loses modal layering (it sits below the scrim/portal), keyboard avoidance, and show/hide coordination with the sheet.

For comparison, @gorhom/bottom-sheet ships BottomSheetFooter for exactly this reason, and it's one of its most-used building blocks. Since this library already moves positioning into native code and already has the surface slot precedent, a natively pinned footer seems like a natural fit for the architecture: the native host knows the visible bottom edge every frame (including during springs and keyboard avoidance), so it can hold the footer there with no JS involvement.

Things that would need defining (happy to discuss):

  • Interaction with keyboard avoidance — presumably the footer rides above the keyboard with the sheet.
  • Interaction with the detached / floating-card sheets proposed in feat: support detached floating-card sheets #58, where the visible bottom edge is lifted by bottomInset.
  • Whether the footer's height feeds 'content' detent sizing.

If this sounds reasonable, I'd be glad to help test it, or take a shot at a PR if maintainers can offer some pointers on the preferred native approach.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions