Skip to content

feat(iOS, FormSheet v5): Add support for backgroundComponent#4100

Open
t0maboro wants to merge 1 commit into
@t0maboro/fit-to-contentsfrom
@t0maboro/formsheet-background-component
Open

feat(iOS, FormSheet v5): Add support for backgroundComponent#4100
t0maboro wants to merge 1 commit into
@t0maboro/fit-to-contentsfrom
@t0maboro/formsheet-background-component

Conversation

@t0maboro
Copy link
Copy Markdown
Contributor

@t0maboro t0maboro commented May 26, 2026

Description

This PR introduces the backgroundComponent prop to the iOS FormSheet. It allows rendering custom backgrounds that stretch to the native bounds of the modal.
When using detents="fitToContents", the React content wrapper inherently calculates its height based purely on its children. However, UIKit automatically appends the bottom safe area to the sheet's bounds. Previously, this meant the React content would end above the Home Indicator, leaving the uncollapsible safe area unstyled.

Important

Some components having a custom (or asynchronous) layout logic may not work properly with synchronous state updates that we're adapting for FormSheet, e.g. Image component from react-native doesn't work well, while 3p libs implementations are more resilient for working with synchronous updates.

react-native Image react-native-fast-image
Screen.Recording.2026-05-26.at.11.54.36.mov
Screen.Recording.2026-05-26.at.11.52.47.mov

Closes https://github.com/software-mansion/react-native-screens-labs/issues/1267

Changes

  • Added the backgroundComponent prop with wrapper having style={StyleSheet.absoluteFill} and pointerEvents="none"

Before & after - visual documentation

iOS 18 iOS 26
ios18.mov
ios26.mov

Test plan

Checklist

  • Included code example that can be used to test this change.
  • For visual changes, included screenshots / GIFs / recordings documenting the change.
  • For API changes, updated relevant public types.
  • Ensured that CI passes

@t0maboro t0maboro force-pushed the @t0maboro/formsheet-background-component branch from 561d8d8 to 6176a76 Compare May 26, 2026 11:23
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@t0maboro t0maboro force-pushed the @t0maboro/formsheet-background-component branch from 6176a76 to 7fbdaf2 Compare May 27, 2026 07:41
Copy link
Copy Markdown
Collaborator

@LKuchno LKuchno left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's wait with updating the 'Expected' sections of the scenarios until the team discussion, so we can decide which approach we want to follow.


## E2E test

Other: Planned, but will be implemented separately.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Following new naming (described in RFC), if we are planning to implement e2e test I would change this line to:

Suggested change
Other: Planned, but will be implemented separately.
TBD: Planned, but will be implemented separately.

Comment on lines +31 to +32
- [ ] Expected: The FormSheet opens smoothly.
- [ ] Expected: The background is the default system color (e.g., white or dark depending on the theme).
Copy link
Copy Markdown
Collaborator

@LKuchno LKuchno May 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should duplicate the Expected field. We could either combine both points into a single sentence, or list them as bullets under one Expected label, like this:

  • Expected:
  • The FormSheet opens smoothly.
  • The background is the default system color (e.g., white or dark depending on the theme).

OR
Expected:

  • The FormSheet opens smoothly.
  • The background is the default system color (e.g., white or dark depending on the theme).

Either way, I think we should align on one convention as a team so we have a clear reference going forward.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will follow the second approach and omit "Expected:". It is redundant, as we can assume that any checkbox under a step represents the expected behavior to be verified.

Copy link
Copy Markdown
Collaborator

@LKuchno LKuchno May 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

@kligarski kligarski left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

Comment on lines +109 to +113
* This component must be positioned absolutely to fill the entire bounds of the native
* sheet, including the bottom safe area provided by UIKit. It renders behind the `children`.
* Useful for adding custom background components that should extend to the very bottom
* edge of the sheet, bypassing the `fitToContents` height restrictions.
*
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's maybe add information that pointer events are disabled for this view.

*
* @platform ios
*/
backgroundComponent?: React.ReactNode | undefined;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use same render callback pattern as for header subviews?

#4079

- [ ] Expected: The FormSheet opens smoothly.
- [ ] Expected: A navy background is visible behind the text content.
- [ ] Expected: A thin green bar is visible at the top edge.
- [ ] Expected: A red bar is visible at the very bottom edge of the screen, successfully rendering underneath the navigation bar.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The navigation bar disappears after some time so referencing it here might be a bit confusing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same below.

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.

4 participants