Repository navigation
Conversation
The header config, its items and spacers and the per-screen header coordinator are used by every container that hosts a stack of screens, so they stop carrying the `Stack` name and living under `ios/stack`: `RNSStackHeader*` becomes `RNSHeader*` in `ios/header`, `RNSStackScreenHeaderCoordinator` becomes `RNSHeaderCoordinator`, the iOS Fabric components are `RNSHeaderConfigIOS`, `RNSHeaderItemIOS` and `RNSHeaderItemSpacerIOS` (specs in `src/fabric/header`), and the shared C++ shadow nodes follow. The Android header stays a Stack feature: `RNSStackHeaderConfigAndroid`, `RNSStackHeaderSubview` and their Kotlin side are untouched. Mechanical rename, no behavior change; the public JS API of `Stack.HeaderConfig` is unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C43Zo2sKs9JZ7GfJJGLjyg
…elpers/stack and type it on RNSStackScreenProviding `RNSStackNavigationController` with its navigation bar and bar coordinator, `RNSStackOperation`, `RNSStackOperationCoordinator` and `RNSViewFrameChangeDelegate` are the machinery any container needs to host a stack of screens, not a part of the `Stack.Host` component; they move to `ios/helpers/stack` (the SPM header search paths gain the directory). The coordinator, the operations and the navigation controller take their screens as `UIView<RNSStackScreenProviding>` instead of `RNSStackScreenComponentView`, so that any React view whose controller can live on the stack's navigation controller may be a stack item. The protocol lives next to that machinery and `RNSStackScreenActivityMode` moves to its header. The navigation controller resolves the content scroll view of its top screen through `RNSContainerItem` instead of the `RNSStackScreenController` class, which is the only Stack v5 type it still referenced. Types only, no behavior change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C43Zo2sKs9JZ7GfJJGLjyg
…dent of the screen class `RNSStackScreenHeaderCoordinator` works on any `UIViewController` (it only touches the navigation item and the navigation controller), `RNSStackScreenProviding` exposes the screen's header coordinator, and `RNSStackHeaderConfig` resolves its screen through the protocol instead of asserting on `RNSStackScreenComponentView`. No behavior change. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C43Zo2sKs9JZ7GfJJGLjyg
…mn navigation controller `RNSSplitColumnController` is a native object without a React counterpart: it creates the navigation controller installed in a UISplitViewController column, observes the origin of its view through `RNSSplitColumnFrameObserver` and reports it to the host. The host creates one controller per column on the first update and only swaps their root screen controllers afterwards, instead of rebuilding navigation controllers on every children update. `RNSSplitNavigationController` and its frame origin delegate are replaced by the column controller and its delegate. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C43Zo2sKs9JZ7GfJJGLjyg
Every Split column is a navigation stack of `RNSSplitScreen`s. `Split.Column` with a `Split.Stack`
child renders no native view: it only provides the column index through context, and its
`Split.Screen`s (prop `column`) mount directly in the host. A plain `Split.Column` is a one-screen
column as before. Nothing between the host and the screens is a React view, so no view of the
React tree hangs outside the UIKit hierarchy.
Natively, `RNSSplitColumnController` owns the column's `RNSStackNavigationController` and drives
its stack the way `RNSStackHostComponentView` drives a standalone stack, through
`RNSStackOperationCoordinator` over the screens as `UIView<RNSStackScreenProviding>`. The host
routes each mounted screen to its column by index; screens mounted before the host controller
exists (it is created on `didMoveToWindow`) are replayed then. A screen popped natively reports
`onDismiss({ isNativeDismiss: true })`; its React unmount does not pop it again, because a pop is
only requested for a screen still on the column's navigation stack.
The column frame reported to the shadow tree comes from the navigation controller's view, not
from the screen view UIKit animates during transitions, and the screen controller is released a
turn after `invalidate` so that a pop pending after the mounting transaction still finds it.
JS API: `Split.Stack`, `Split.Screen` (`activityMode`, `screenKey`, `onDismiss`), scenario
`test-split-stack-columns-ios` following the Stack detach protocol (detach, then unmount on
`onDismiss`).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C43Zo2sKs9JZ7GfJJGLjyg
`RNSSplitScreen` accepts `RNSHeaderConfig` exactly like `RNSStackScreen`: the config is a subview of the screen, its items stay out of the view hierarchy, and `RNSHeaderCoordinator`, now owned by `RNSSplitScreenController` and exposed through `RNSStackScreenProviding`, applies it to the screen's navigation item in the column's `RNSStackNavigationController`. Without a header config a column keeps the system navigation bar as before. JS API: `Split.HeaderConfig` with its own `SplitHeaderConfigProps`; it renders the same neutral header config as `Stack.HeaderConfig`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C43Zo2sKs9JZ7GfJJGLjyg
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This was referenced Sep 19, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test with
TestSplitStackColumns. I'm dumping all commits from PoC based on the RFC https://github.com/software-mansion/react-native-screens-labs/pull/1805 (option B). The plan is to create a single PR for each commit from here.A
Splitcolumn becomes a navigation stack of screens with Stack v5 semantics. Nothing betweenSplit.Hostand the screens is a React view, so the problem of hanging views from #4602 doesn't happen.Proposed API for this option:
One commit per step, in the order of the RFC's implementation plan:
mainios/stack/headermoves toios/header,RNSStackHeader*becomesRNSHeader*. Android header should be aligned.Stack.Hostand typed onRNSStackScreenProviding.UIViewController; the header config resolves its screen through the protocol instead of asserting on the Stack screen class.6
RNSSplitColumnController(manager, not VC), a native object with no React counterpart which owns the column's navigation controller and its frame observer and replacesRNSSplitNavigationController.Split.Columnwith aSplit.Stackchild renders no native view and only provides its column id through context; the host routes each mounted screen to its column; the column controller drivesRNSStackOperationCoordinatoroverUIView<RNSStackScreenProviding>the wayStack.Hostdoes.Split.HeaderConfigrenders the neutral header config;RNSHeaderCoordinatorowned byRNSSplitScreenControllerapplies it to the column's navigation item.