Skip to content

feat: Implement subviews layout in header for iOS stack v5#3868

Draft
kmichalikk wants to merge 19 commits intomainfrom
@kmichalikk/stack-header-v5-ios
Draft

feat: Implement subviews layout in header for iOS stack v5#3868
kmichalikk wants to merge 19 commits intomainfrom
@kmichalikk/stack-header-v5-ios

Conversation

@kmichalikk
Copy link
Copy Markdown
Contributor

@kmichalikk kmichalikk commented Apr 10, 2026

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

Description

This PR adds basic support for header configuration under new stack v5 on iOS. The primary focus here is to support the layout of custom react views inside the header. The following places could host a custom view:

  • leftBarButtonItems: multiple items, any of which can be react view
  • rightBarButtonItems: same as above
  • titleView: custom view to replace the regular title
  • subtitleView: to replace subview, below the title
  • larbeSubtitleView: custom view below large title

They are expected to be laid out seemlessly along native elements & with shadow state position matching the native hierarchy.

The configuration flow in new implementation follows roughly this diagram:

header-config-flow

It was decided to give each item (no matter if it ends up as custom view or regular label button) a react native component. This way, each change to the props of each item maintains the same update flow: whenever props are updated, the menu item gets invalidated, which notifies the header config, which triggers the rebuild.

Caution

Optimization of the menu rebuild is not handled in this PR. For now, each invalidation triggers full menu rebuild. Same goes for any other optimization. This is an MVP implementation which will be iterated upon.

Caution

For now, no configuration is allowed for back button. Value of leftItemsSupplementBackButton is hardcoded to YES so no matter if left items are present or not, the back button is present. In fact, if the back button is not present, back gestures don't work - also tested on native app. So it's set to always be visible. DOUBLE CAUTION: default iOS gesture recognizer has this behavior. If we add a custom recognizer delegate, presence of back button won't affect the ability to swipe to pop.

Caution

HeaderConfig is not exposed outside StackContainer. Testing the header requires modifying the values directly in StackContainer. The API is not final and is subject to change any time.

Important

I hadn't really considered item menus implementation (shown by long pressing items, if configured). Menus can hold native items (custom views don't work), and can be nested. The "configure-by-native-component" flow would be awkward for such menus. We need a better API for this. I hope it to be seamless with the API proposed here.

Important

Let's make sure we are okay with the proposed implementation. I want to have the same item configuration logic for toolbar in the future.

Before & after - visual documentation

stack-v5-header.mov

Test plan

For now, there are props: title, left and right items, titleItem, subtitleItem, largeSubtitleItem, largeTitleEnabled. TitleItem should take precedence over title. The title controls both regular and large title.

There are regular label buttons and custom view buttons. There are also spacers (fixed, fixed + width, flexible; for header, only fixed works on iOS 26, fixed with width works on iOS 18, flexible will work on toolbar when it will be introduced).

Setting the props should work. Mixing custom and regular buttons should work. See StackContainer.tsx for available item configuration. The shadow tree position should match whatever is visible on the screen. Button in, out, click events should work (added console.log())

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

@kmichalikk kmichalikk marked this pull request as draft April 10, 2026 08:49
@kmichalikk kmichalikk force-pushed the @kmichalikk/stack-header-v5-ios branch from 9f7743a to 3126537 Compare April 10, 2026 08:50
@kmichalikk kmichalikk self-assigned this Apr 10, 2026
@kmichalikk kmichalikk force-pushed the @kmichalikk/stack-v5-with-queue-ios branch from d8a04d2 to 2571b25 Compare April 13, 2026 15:34
Base automatically changed from @kmichalikk/stack-v5-with-queue-ios to main April 14, 2026 16:05
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.

1 participant