feat: Add toggling items with managed flow to menu#4194
Open
kmichalikk wants to merge 5 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR adds toggleable (multi-select) and singleSelection (radio-group) behavior to iOS stack header menus in the gamma API, including a new native-to-JS selection-change event and state tracking to keep checkmarks in sync.
Changes:
- Added
onMenuSelectionChangedas a new iOS Fabric event and JS-side wiring to dispatch selection changes to the correct menu callback. - Extended menu JS types (
itemType,initialToggleState,singleSelection,onSelectionChanged) and implemented iOS-side parsing + toggle/radio state tracking + menu rebuilding. - Updated the iOS SFT scenario and app screen to exercise action/toggle/singleSelection behavior.
Reviewed changes
Copilot reviewed 22 out of 22 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| src/fabric/gamma/stack/StackHeaderConfigIOSNativeComponent.ts | Adds the onMenuSelectionChanged native event type/prop for iOS Fabric. |
| src/components/gamma/stack/header/utils.ts | Adds JS-side menu tree validation (warnings for unsupported callback configurations). |
| src/components/gamma/stack/header/StackHeaderConfig.ios.tsx | Wires the new native selection-change event to menu.onSelectionChanged and runs callback validation. |
| src/components/gamma/stack/header/ios/StackHeaderMenu.ios.types.ts | Extends public JS menu types with toggle/radio props and selection callback. |
| ios/gamma/stack/header/RNSStackHeaderMenuToggleStateTracker.mm | Implements native toggle/radio state storage for menu items. |
| ios/gamma/stack/header/RNSStackHeaderMenuToggleStateTracker.h | Declares the toggle/radio state tracker interface. |
| ios/gamma/stack/header/RNSStackHeaderMenuMapper.mm | Parses singleSelection, itemType, and initialToggleState from the menu prop dictionary. |
| ios/gamma/stack/header/RNSStackHeaderMenuEventsDelegate.h | Adds delegate method for selection-change events. |
| ios/gamma/stack/header/RNSStackHeaderMenuData.mm | Stores parsed menu/menuItem fields for toggle/radio behavior. |
| ios/gamma/stack/header/RNSStackHeaderMenuData.h | Defines RNSMenuItemType and new data fields (singleSelection, initialToggleState, etc.). |
| ios/gamma/stack/header/RNSStackHeaderMenuCoordinator.mm | Builds UIMenu/UIAction elements with toggle/radio behavior and emits selection changes. |
| ios/gamma/stack/header/RNSStackHeaderMenuCoordinator.h | Updates coordinator API to accept a toggle state tracker. |
| ios/gamma/stack/header/RNSStackHeaderItemDataProviding.h | Exposes the toggle state tracker from header items to the menu builder. |
| ios/gamma/stack/header/RNSStackHeaderItemComponentView.mm | Instantiates a tracker when a menu is set/changed. |
| ios/gamma/stack/header/RNSStackHeaderItemComponentView.h | Exposes the tracker as a property. |
| ios/gamma/stack/header/RNSStackHeaderContentFactory.mm | Passes the tracker into menu construction when creating bar button items. |
| ios/gamma/stack/header/RNSStackHeaderConfigEventEmitter.mm | Emits the new selection-change event to JS (via Fabric event emitter). |
| ios/gamma/stack/header/RNSStackHeaderConfigEventEmitter.h | Declares the new selection-change emission method. |
| ios/gamma/stack/header/RNSStackHeaderConfigComponentView.mm | Implements selection-change delegate method and forces menu rebuild to refresh checkmarks. |
| apps/src/tests/single-feature-tests/stack-v5/test-stack-header-menu-ios/scenario.md | Updates the manual test scenario for action/toggle/singleSelection. |
| apps/src/tests/single-feature-tests/stack-v5/test-stack-header-menu-ios/scenario-description.ts | Updates scenario description text to reflect new coverage. |
| apps/src/tests/single-feature-tests/stack-v5/test-stack-header-menu-ios/index.tsx | Updates the scenario screen to demonstrate toggles and singleSelection menus. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
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.
Closes https://github.com/software-mansion/react-native-screens-labs/issues/1187
Closes https://github.com/software-mansion/react-native-screens-labs/issues/1137
Description
This PR adds support for toggleable items with optional singleSelection flag.
onPresscallbackitemTypeis set to'toggle', then it doesn't react toonPressbut rather its parent menu sends anonSelectionChangedcallback for all child items of toggle type (this means that menu can contain both actions and toggles, andonSelectionChangedsends only the ids of toggles)toggleby default and cannot be set toaction(issues a warning)onSelectionChangedis triggered only when selected value changes, clicking on the same item does nothingChanges
itemType: 'action' | 'toggle' | 'inherit' | undefinedprop,inheritby default, which givestoggleforsingleSelectionmenus andactionotherwiseinitialToggleStatefor toggles (forsingleSelection, user is warned for setting it to true for multiple items, only first is applied)onSelectionChangedcallback to menuBefore & after - visual documentation
Test plan
See test-stack-header-menu-ios SFT
Checklist