Skip to content

fix: apply every entry of a content container style array - #2748

Open
bradreelee wants to merge 1 commit into
gorhom:masterfrom
bradreelee:fix/flatten-content-container-style
Open

fix: apply every entry of a content container style array#2748
bradreelee wants to merge 1 commit into
gorhom:masterfrom
bradreelee:fix/flatten-content-container-style

Conversation

@bradreelee

Copy link
Copy Markdown

Motivation

Closes #2383, which was reported in July 2025 with a correct diagnosis and then auto-closed by the stale bot without a fix. It still reproduces on 5.2.14.

useBottomSheetContentContainerStyle folds array styles with:

Array.isArray(_style) ? StyleSheet.compose(..._style) : _style

composeStyles(style1, style2) accepts exactly two arguments, so every entry from the third on is silently discarded — no error, no warning, and the // @ts-ignore on that line is what kept the arity mismatch quiet. Anything passed as a 3+ entry array to BottomSheetView's style or a scrollable's contentContainerStyle never reaches the view.

This bit us in production on Android. A sheet with enableContentPanningGesture={false} needs a background colour on the content wrapper (otherwise taps leak through to the backdrop), which makes the natural style array three entries long:

<BottomSheetView
  style={[
    styles.content,
    { backgroundColor: colors.background },          // hit-test target
    { paddingBottom: insets.bottom + spacing.xs },   // ← dropped
  ]}
>

The bottom safe-area padding disappeared and the sheet's primary button rendered underneath the Android navigation bar. Because the value was computed correctly and the style object looked right in the source, this was expensive to track down — nothing points at the library.

There is a second, related bug in the same call. compose returns [a, b], not a merged object, so the enableFooterMarginAdjustment branch immediately below destructures off an array:

const { paddingBottom, padding, paddingVertical } = flattenStyle; // always undefined

currentBottomPadding therefore stays 0, and the caller's bottom padding is replaced by 0 + footerHeight whenever an array is passed.

StyleSheet.flatten handles arrays of any length and depth and returns a real object, fixing both and letting the @ts-ignore go.

Verification

yarn typescript and yarn lint pass (the one remaining biome warning is pre-existing, in useBoundingClientRect.ts).

The repo has no test runner, so I verified against React Native's real composeStyles and flattenStyle rather than stand-ins — running the exact expression the hook uses, before and after:

1. bottom padding actually reaching the view
FAIL  before patch (3-element array)   expected 46, got undefined
PASS  after  patch (3-element array)   expected 46, got 46

2. footer-margin branch reading the caller padding
FAIL  before patch                     expected 46, got undefined
PASS  after  patch                     expected 46, got 46

3. two-element arrays were never affected
PASS  before patch (2-element array)   expected 46, got 46

composed value (before): [{"paddingHorizontal":20,"paddingTop":8},{"backgroundColor":"#26272B"}]
flattened value (after): {"paddingHorizontal":20,"paddingTop":8,"backgroundColor":"#26272B","paddingBottom":46}

Case 3 explains why this went unnoticed for so long: two-entry arrays, the overwhelmingly common case, behave identically before and after.

Happy to add the repro as a test if you'd like to set up a runner, or to port it to the example app instead.

`useBottomSheetContentContainerStyle` folded array styles with
`StyleSheet.compose(..._style)`, but `composeStyles(style1, style2)` accepts
exactly two arguments and silently drops the rest. Any array of three or more
entries passed to `BottomSheetView`'s `style` or a scrollable's
`contentContainerStyle` lost everything from the third entry on, with no error
or warning.

The same call is also why the name is misleading: `compose` returns `[a, b]`
rather than a merged object, so the `enableFooterMarginAdjustment` branch below
destructures `paddingBottom` / `padding` / `paddingVertical` off an array and
always reads `undefined`. The caller's bottom padding is then replaced by
`0 + footerHeight`.

`StyleSheet.flatten` handles arrays of any length and depth and returns a real
object, which fixes both and lets the `@ts-ignore` go.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Style arrays with 3+ elements are not fully applied

1 participant