Skip to content

refactor(iOS, FormSheet v5): Separate Behavior and Appearance#4084

Merged
t0maboro merged 9 commits into
mainfrom
@t0maboro/separate-behavior-from-appearance
May 27, 2026
Merged

refactor(iOS, FormSheet v5): Separate Behavior and Appearance#4084
t0maboro merged 9 commits into
mainfrom
@t0maboro/separate-behavior-from-appearance

Conversation

@t0maboro

Copy link
Copy Markdown
Contributor

Description

A follow-up for #4074 . It addresses the overloaded "Appearance" concept by logically separating visual updates from behavioral updates.

Previously, both visual props (e.g. grabber visibility) and structural props (e.g. detents) were grouped together under a single "Appearance" applicator. This PR introduces a more granular UpdateCoordinator and separates the logic.

Changes

  • Renamed RNSFormSheetAppearanceCoordinator to RNSFormSheetUpdateCoordinator.
  • Replaced old flags with RNSFormSheetUpdateFlags, having distinct Appearance, Behavior and Presentation flags.
  • Replaced RNSFormSheetAppearanceApplicator with RNSFormSheetConfigurationApplicator that processes both Appearance and Behavior providers and applies them inside a single block.
  • Refactored RNSFormSheetContentController to separate updateConfigurationIfNeeded from updatePresentationIfNeeded. flushPendingUpdates now configures the sheet first, then presents it.

Before & after - visual documentation

N/A - refactor

Test plan

Tested with existing SFTs for FormSheet.

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 changed the base branch from main to @t0maboro/move-config-to-controller May 22, 2026 10:40

Copilot AI left a comment

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.

Pull request overview

This PR refactors the iOS FormSheet v5 update pipeline by splitting “appearance” vs “behavior” changes, introducing a new RNSFormSheetUpdateCoordinator/RNSFormSheetUpdateFlags mechanism, and updating the content controller/applicator to apply configuration separately from presentation.

Changes:

  • Introduces RNSFormSheetUpdateFlags and RNSFormSheetUpdateCoordinator to track pending updates for Presentation/Appearance/Behavior.
  • Refactors RNSFormSheetContentController to flush configuration updates first, then presentation updates.
  • Replaces/removes the old “Appearance” coordinator/update-flags types and wires host prop invalidations to appearance vs behavior appropriately.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
ios/gamma/modals/form-sheet/RNSFormSheetUpdateFlags.h Adds new bitmask flags for presentation/appearance/behavior updates.
ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.h Declares the new coordinator API to aggregate and flush update flags.
ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.mm Implements flag bookkeeping and conditional execution helpers.
ios/gamma/modals/form-sheet/RNSFormSheetHostComponentView.mm Updates invalidation logic to distinguish appearance vs behavior changes.
ios/gamma/modals/form-sheet/RNSFormSheetContentController.mm Splits configuration vs presentation flush logic; adopts new coordinator/applicator.
ios/gamma/modals/form-sheet/RNSFormSheetContentController.h Exposes setNeedsBehaviorUpdate signal.
ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.h Introduces a configuration applicator interface accepting appearance + behavior providers.
ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm Applies sheet configuration (detents/scrolling + visual settings) using new flags/coordinator.
ios/gamma/modals/form-sheet/RNSFormSheetAppearanceUpdateFlags.h Removes legacy appearance update flags.
ios/gamma/modals/form-sheet/RNSFormSheetAppearanceCoordinator.h Removes legacy appearance coordinator API.
ios/gamma/modals/form-sheet/RNSFormSheetAppearanceCoordinator.mm Removes legacy appearance coordinator implementation.
ios/gamma/modals/form-sheet/RNSFormSheetAppearanceApplicator.h Removes legacy appearance applicator interface.
Comments suppressed due to low confidence (1)

ios/gamma/modals/form-sheet/RNSFormSheetConfigurationApplicator.mm:39

  • applyConfigurationIfNeeded… triggers on any of (Appearance|Behavior) flags, but the apply block always recalculates and reapplies both behavior (detents, scrolling, selected detent) and appearance. This means an appearance-only change (e.g. grabber/corner radius) will still reassign detents and scrolling config, which can cause unnecessary animations/layout work and undermines the intended separation. Consider capturing which sub-flags are actually set and only applying the corresponding property updates inside animateChanges:.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ios/gamma/modals/form-sheet/RNSFormSheetHostComponentView.mm Outdated
Comment thread ios/gamma/modals/form-sheet/RNSFormSheetContentController.mm
Comment thread ios/gamma/modals/form-sheet/RNSFormSheetUpdateCoordinator.h Outdated
@t0maboro t0maboro force-pushed the @t0maboro/separate-behavior-from-appearance branch from 8a4f39d to 77fe85e Compare May 22, 2026 11:44
Base automatically changed from @t0maboro/move-config-to-controller to main May 22, 2026 12:36
@t0maboro t0maboro force-pushed the @t0maboro/separate-behavior-from-appearance branch from 77fe85e to 0dea3f9 Compare May 22, 2026 12:37

@kligarski kligarski left a comment

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.

Looks very clean!


- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index
{
[_controller.contentView insertReactSubview:childComponentView atIndex:index];

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.

It's out of scope of this PR but it would be nice to remove React infix here to make the separation complete.

Comment on lines +44 to +46
- (void)applyConfigurationWithAppearanceProvider:(id<RNSFormSheetAppearanceProvider>)appearanceProvider
behaviorProvider:(id<RNSFormSheetBehaviorProvider>)behaviorProvider
controller:(RNSFormSheetContentController *)controller

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.

I guess that in the future we can split this to appearance and behavior (but still do it in one animateChanges block) but for now, there is just no need to do so, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

yup it makes sense, and we might consider that as a follow-up: https://github.com/software-mansion/react-native-screens-labs/issues/1501

@t0maboro t0maboro merged commit 4a48ee4 into main May 27, 2026
5 of 7 checks passed
@t0maboro t0maboro deleted the @t0maboro/separate-behavior-from-appearance branch May 27, 2026 07:06
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