Skip to content

fix(layout): correct isLayoutCalculated always returning true#2642

Merged
gorhom merged 2 commits intogorhom:masterfrom
spsaucier:fix/isLayoutCalculated-always-true
Apr 8, 2026
Merged

fix(layout): correct isLayoutCalculated always returning true#2642
gorhom merged 2 commits intogorhom:masterfrom
spsaucier:fix/isLayoutCalculated-always-true

Conversation

@spsaucier
Copy link
Copy Markdown
Contributor

Summary

isLayoutCalculated in BottomSheet.tsx line 229 uses || (OR) instead of && (AND) when checking whether containerHeight has been provided:

// Current (always true)
if (containerHeight !== null || containerHeight !== undefined) {

// Fixed
if (containerHeight !== null && containerHeight !== undefined) {

x !== null || x !== undefined is a tautology — it evaluates to true for every possible value. This means isContainerHeightCalculated is always set to true on line 230, regardless of the actual container height state.

Impact

While the second guard (containerHeight !== INITIAL_LAYOUT_VALUE) usually catches this, the logical error means isLayoutCalculated can return true before layout measurements complete if containerHeight happens to be null or undefined rather than INITIAL_LAYOUT_VALUE. This allows evaluatePosition to run prematurely, potentially producing incorrect detent positions.

We observed a production issue where the bottom sheet's backdrop rendered correctly but the content panel was positioned off-screen (invisible), with onChange(index >= 0) still firing — leaving users stuck behind a non-dismissable backdrop. The premature layout calculation is a plausible contributing factor.

Change

Single character: ||&& on line 229 of src/components/bottomSheet/BottomSheet.tsx.

TwanLuttik added a commit to TwanLuttik/react-native-bottom-sheet that referenced this pull request Apr 8, 2026
- Fix gorhom#2642: isLayoutCalculated logic bug (|| should be &&) causing incorrect detent positions
- Fix gorhom#2498: prevent closing two modals at once by guarding splice with sheetIndex !== -1
- Fix gorhom#2342: use Math.floor on animatedIndex to fix Android freeze with reduced animations
- Fix gorhom#2595: React 19 compatibility and type safety for findNodeHandle web utility
@gorhom gorhom self-assigned this Apr 8, 2026
saucier-consulting and others added 2 commits April 8, 2026 21:13
The `isLayoutCalculated` derived value uses an OR condition to check
whether `containerHeight` has been provided:

    if (containerHeight !== null || containerHeight !== undefined)

This expression is always true for any value — if containerHeight is
null, the `!== undefined` branch is true, and vice versa. The intended
check should use AND:

    if (containerHeight !== null && containerHeight !== undefined)

Without this fix, `isLayoutCalculated` returns true before layout
measurements complete, allowing `evaluatePosition` to run with
`containerHeight = INITIAL_LAYOUT_VALUE (-999)`. This produces
incorrect detent positions and can cause the sheet's content panel to
animate to an off-screen position while the backdrop renders correctly
(since both are derived from the same animatedPosition, but the
incorrect initial animation target can leave the body off-screen after
the "completed" callback fires and the snap-point-change correction
races with the mount animation).

The second condition (`!== INITIAL_LAYOUT_VALUE`) still serves as the
primary guard, but the first condition should be logically correct so
it doesn't silently pass for null/undefined containerHeight values.
@gorhom gorhom force-pushed the fix/isLayoutCalculated-always-true branch from bc6eb05 to eccfff3 Compare April 8, 2026 19:15
@gorhom
Copy link
Copy Markdown
Owner

gorhom commented Apr 8, 2026

thanks @spsaucier, that was a good catch. i had also merged the initial value condition to prevent early setting the state to true

@gorhom gorhom merged commit eccd823 into gorhom:master Apr 8, 2026
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.

3 participants