@apexnative/navigation 1.0.0-alpha.4 → 1.0.0-alpha.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +38 -0
- package/README.md +1 -1
- package/android/CLAUDE.md +23 -14
- package/android/CORE.md +32 -19
- package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +60 -13
- package/android/src/main/java/dev/apexnative/navigation/options/AnimationsOptions.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/options/BottomTabsOptions.kt +13 -8
- package/android/src/main/java/dev/apexnative/navigation/options/HardwareBackButtonOptions.kt +9 -1
- package/android/src/main/java/dev/apexnative/navigation/options/StackAnimationOptions.kt +40 -2
- package/android/src/main/java/dev/apexnative/navigation/react/CommandAnswer.kt +28 -13
- package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +7 -4
- package/android/src/main/java/dev/apexnative/navigation/react/NavigationTurboModule.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/react/ReactView.kt +39 -20
- package/android/src/main/java/dev/apexnative/navigation/react/ReloadCoordinator.kt +7 -6
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenEnvironment.kt +177 -0
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +19 -51
- package/android/src/main/java/dev/apexnative/navigation/react/ScrollEvents.kt +49 -128
- package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +30 -39
- package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +34 -7
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationState.kt +154 -0
- package/android/src/main/java/dev/apexnative/navigation/safearea/SafeAreaView.kt +12 -10
- package/android/src/main/java/dev/apexnative/navigation/slots/SlotScreenView.kt +12 -12
- package/android/src/main/java/dev/apexnative/navigation/utils/ViewExtensions.kt +0 -13
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/ArrangementController.kt +10 -7
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsCollapseBehavior.kt +5 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +22 -21
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowGeometry.kt +22 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabsRoom.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentViewController.kt +12 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ContentReadiness.kt +1 -1
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenReadiness.kt +103 -56
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenSafeArea.kt +29 -11
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/externalcomponent/ExternalComponentViewController.kt +2 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +20 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +119 -8
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +7 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetBack.kt +42 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackCheck.kt +50 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +45 -14
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +25 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -6
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +3 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/PreparedFrame.kt +3 -3
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackCommands.kt +2 -2
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +13 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +3 -0
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/ScreenSearch.kt +3 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/search/StackSearchPresenter.kt +2 -5
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/BarComponents.kt +5 -51
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +4 -9
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ScrollEventListener.kt +6 -9
- package/android/src/main/java/dev/apexnative/navigation/views/animations/AnimationLayer.kt +73 -0
- package/android/src/main/java/dev/apexnative/navigation/views/animations/ValueInterpolation.kt +14 -0
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabsLayout.kt +61 -2
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomBottomTabItemView.kt +0 -5
- package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/CustomTabRow.kt +72 -10
- package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +9 -2
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +11 -0
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/FlightGeometry.kt +318 -25
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +18 -20
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +17 -25
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +15 -22
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +12 -9
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +84 -35
- package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +49 -40
- package/cli/doctor/checks/splash.js +4 -22
- package/cli/splash/index.js +3 -1
- package/docs-md/architecture/transitions.md +4 -2
- package/docs-md/containers/modals.md +4 -2
- package/docs-md/containers/overlays.md +1 -1
- package/docs-md/containers/side-menu.md +1 -1
- package/docs-md/containers/tabs.md +2 -0
- package/docs-md/flows/bottom-sheets.md +1 -1
- package/docs-md/fundamentals/starting-the-app.md +1 -1
- package/docs-md/guides/cli.md +1 -2
- package/docs-md/help/glossary.md +2 -2
- package/docs-md/help/troubleshooting.md +23 -2
- package/docs-md/index.json +12 -0
- package/docs-md/migration/from-expo-router.md +1 -1
- package/docs-md/migration/from-react-native-navigation.md +1 -1
- package/docs-md/migration/from-react-navigation.md +2 -2
- package/docs-md/screen-ui/back-and-gestures.md +36 -0
- package/docs-md/screen-ui/bar-buttons.md +4 -4
- package/docs-md/screen-ui/search.md +1 -1
- package/docs-md/screen-ui/system-ui.md +16 -11
- package/docs-md/screen-ui/toolbar-and-fab.md +2 -2
- package/docs-md/screen-ui/top-bar.md +8 -4
- package/docs-md/start/installation.md +1 -1
- package/ios/Animations/ANNFrameDriver.mm +2 -0
- package/ios/Animations/Elements/ANNSharedElementFlight.mm +70 -4
- package/ios/Animations/Interpolators/ANNInterpolate.h +2 -30
- package/ios/Animations/Interpolators/ANNTransformParts.h +48 -0
- package/ios/Animations/Interpolators/ANNTransformParts.mm +507 -0
- package/ios/Animations/Interpolators/ANNViewTracks.h +6 -4
- package/ios/Animations/Interpolators/ANNViewTracks.mm +49 -9
- package/ios/CLAUDE.md +17 -15
- package/ios/CORE.md +30 -26
- package/ios/Contract/ANNCommandAnswer.h +9 -2
- package/ios/Contract/ANNCommandAnswer.mm +25 -12
- package/ios/Contract/ANNCommandRunner.h +8 -7
- package/ios/Contract/ANNCommandRunner.mm +21 -27
- package/ios/Contract/ANNLayoutNode.h +3 -3
- package/ios/Contract/ANNLayoutReader.h +3 -3
- package/ios/Core/ANNAppearanceDispatcher.h +5 -4
- package/ios/Core/ANNAppearanceDispatcher.mm +12 -1
- package/ios/Core/ANNJavaScriptCalls.h +11 -12
- package/ios/Core/ANNJavaScriptCalls.mm +7 -16
- package/ios/Core/ANNNavigationState.h +4 -6
- package/ios/Core/ANNNavigationState.mm +0 -4
- package/ios/Core/ANNReloadCoordinator.mm +4 -8
- package/ios/Core/ApexNavigation+Internal.h +1 -1
- package/ios/Layouts/Arrangement/ANNArrangementState.h +2 -17
- package/ios/Layouts/Arrangement/ANNArrangementState.mm +0 -38
- package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +4 -4
- package/ios/Layouts/Root/ANNSplashViewController.h +5 -3
- package/ios/Layouts/Root/ANNSplashViewController.mm +147 -0
- package/ios/Layouts/Screen/ANNComponentViewController.h +2 -2
- package/ios/Layouts/Screen/ANNComponentViewController.mm +9 -22
- package/ios/Layouts/Screen/ANNPreviewInteraction.h +7 -4
- package/ios/Layouts/Screen/ANNPreviewInteraction.mm +72 -10
- package/ios/Layouts/Screen/ANNScreenEnvironment.h +63 -0
- package/ios/Layouts/Screen/ANNScreenEnvironment.mm +181 -0
- package/ios/Layouts/Screen/ANNScreenRegions.h +3 -18
- package/ios/Layouts/Screen/ANNScreenRegions.mm +0 -38
- package/ios/Layouts/Screen/ANNScreenSafeArea.h +4 -9
- package/ios/Layouts/Screen/ANNScreenSafeArea.mm +14 -16
- package/ios/Layouts/Stack/ANNPreviewPush.h +7 -6
- package/ios/Layouts/Stack/ANNPreviewPush.mm +142 -27
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.h +12 -1
- package/ios/Layouts/Tabs/ANNBottomTabsAccessoryView.mm +23 -0
- package/ios/Layouts/Tabs/ANNBottomTabsController.mm +2 -1
- package/ios/Layouts/Tabs/ANNBottomTabsCustomRow.mm +8 -3
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.h +4 -0
- package/ios/Layouts/Tabs/ANNBottomTabsPresenter.mm +123 -36
- package/ios/Layouts/Tabs/ANNTabsDesign.h +6 -5
- package/ios/Layouts/Tabs/ANNTabsDesign.mm +9 -1
- package/ios/Layouts/Tabs/UITabBar+utils.h +5 -5
- package/ios/Layouts/Tabs/UITabBar+utils.mm +32 -13
- package/ios/Options/ANNBottomTabsOptions.h +2 -0
- package/ios/Options/ANNBottomTabsOptions.mm +1 -0
- package/ios/Options/ANNOptions.h +18 -0
- package/ios/Options/ANNOptions.mm +112 -1
- package/ios/Options/ANNOptionsReader.mm +110 -0
- package/ios/Options/Params/ANNParam.h +15 -0
- package/ios/Options/Params/ANNParam.mm +61 -0
- package/ios/Options/Params/Color.h +3 -0
- package/ios/Options/Params/Color.mm +21 -0
- package/ios/Options/Params/Image.h +4 -0
- package/ios/Options/Params/Image.mm +20 -0
- package/ios/React/ANNReactView.mm +6 -25
- package/ios/React/ANNSafeAreaViewComponentView.mm +26 -15
- package/ios/React/ANNSurfaceHostingView.h +6 -0
- package/ios/React/ANNSurfaceHostingView.mm +116 -0
- package/ios/TopBar/ANNBackButtonPresenter.mm +6 -5
- package/ios/TopBar/ANNBarAppearance.h +2 -1
- package/ios/TopBar/ANNBarAppearance.mm +111 -30
- package/ios/TopBar/ANNBarBackgroundComponent.mm +16 -0
- package/ios/TopBar/ANNBarButtonComponentView.h +4 -4
- package/ios/TopBar/ANNBarButtonComponentView.mm +1 -1
- package/ios/TopBar/ANNBarButtons.h +5 -3
- package/ios/TopBar/ANNBarButtons.mm +186 -17
- package/ios/TopBar/ANNLargeTitlePresenter.mm +24 -4
- package/ios/TopBar/ANNMainList.h +3 -0
- package/ios/TopBar/ANNMainList.mm +4 -0
- package/ios/TopBar/ANNScrollEdgeEffects.h +22 -6
- package/ios/TopBar/ANNScrollEdgeEffects.mm +123 -16
- package/ios/TopBar/ANNSearchPresenter.mm +2 -2
- package/ios/TopBar/ANNSearchResultsViewController.mm +5 -5
- package/ios/TopBar/ANNTopBarPresenter.h +3 -2
- package/ios/TopBar/ANNTopBarPresenter.mm +95 -22
- package/ios/TurboModules/ANNTurboModule.mm +20 -16
- package/lib/module/ARCHITECTURE.md +8 -4
- package/lib/module/api/commands/commands.js +54 -6
- package/lib/module/api/commands/commands.js.map +1 -1
- package/lib/module/api/hooks/useSafeAreaInsets.js +4 -3
- package/lib/module/api/hooks/useSafeAreaInsets.js.map +1 -1
- package/lib/module/api/options/OptionsChain.js +2 -2
- package/lib/module/engine/commands.js +21 -1
- package/lib/module/engine/commands.js.map +1 -1
- package/lib/module/engine/places.js +8 -0
- package/lib/module/engine/places.js.map +1 -1
- package/lib/module/engine/screens.js +29 -4
- package/lib/module/engine/screens.js.map +1 -1
- package/lib/typescript/api/app/createNavigation.d.ts +3 -3
- package/lib/typescript/api/commands/commands.d.ts.map +1 -1
- package/lib/typescript/api/commands/presentation.d.ts +4 -3
- package/lib/typescript/api/commands/presentation.d.ts.map +1 -1
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts +4 -3
- package/lib/typescript/api/hooks/useSafeAreaInsets.d.ts.map +1 -1
- package/lib/typescript/api/options/OptionsChain.d.ts +2 -2
- package/lib/typescript/engine/commands.d.ts.map +1 -1
- package/lib/typescript/engine/places.d.ts +2 -0
- package/lib/typescript/engine/places.d.ts.map +1 -1
- package/lib/typescript/engine/screens.d.ts +20 -6
- package/lib/typescript/engine/screens.d.ts.map +1 -1
- package/lib/typescript/interfaces/Options.d.ts +1 -1
- package/lib/typescript/interfaces/Options.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/animations.d.ts +30 -9
- package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/bottomTabs.d.ts +18 -5
- package/lib/typescript/interfaces/options/bottomTabs.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/buttons.d.ts +8 -8
- package/lib/typescript/interfaces/options/stack.d.ts +9 -0
- package/lib/typescript/interfaces/options/stack.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/system.d.ts +8 -5
- package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
- package/lib/typescript/interfaces/options/toolbar.d.ts +2 -2
- package/lib/typescript/interfaces/options/topBar.d.ts +32 -29
- package/lib/typescript/interfaces/options/topBar.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/ARCHITECTURE.md +8 -4
- package/src/api/app/createNavigation.ts +3 -3
- package/src/api/commands/commands.ts +48 -7
- package/src/api/commands/presentation.ts +4 -3
- package/src/api/hooks/useSafeAreaInsets.ts +4 -3
- package/src/api/options/OptionsChain.ts +2 -2
- package/src/engine/commands.ts +30 -6
- package/src/engine/places.ts +9 -0
- package/src/engine/screens.tsx +29 -8
- package/src/interfaces/Options.ts +1 -0
- package/src/interfaces/options/animations.ts +31 -9
- package/src/interfaces/options/bottomTabs.ts +18 -5
- package/src/interfaces/options/buttons.ts +8 -8
- package/src/interfaces/options/stack.ts +9 -0
- package/src/interfaces/options/system.ts +8 -5
- package/src/interfaces/options/toolbar.ts +2 -2
- package/src/interfaces/options/topBar.ts +32 -29
- package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +0 -42
- package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +0 -70
- package/android/src/main/java/dev/apexnative/navigation/react/events/NavigationStateReporter.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/react/events/StateHold.kt +0 -62
- package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/CustomTabRowPlacer.kt +0 -223
- package/ios/Layouts/Screen/ANNScreenInsets.h +0 -30
- package/ios/Layouts/Screen/ANNScreenInsets.mm +0 -70
|
@@ -43,7 +43,7 @@ export interface OptionsTopBarTitleDocument {
|
|
|
43
43
|
export interface OptionsTopBarTitle {
|
|
44
44
|
/**
|
|
45
45
|
* The text of the title. Setting it removes a React title. On iOS it is the title of the screen's navigation item,
|
|
46
|
-
* the label the system shows on the next screen's back button
|
|
46
|
+
* the label the system shows on the next screen's back button without the glass design, and what Rename edits. On Android it
|
|
47
47
|
* is one line cut with an ellipsis, and also the text of the large title; a title component set together with the
|
|
48
48
|
* text drops the text and the subtitle (with a warning in development).
|
|
49
49
|
*/
|
|
@@ -87,9 +87,9 @@ export interface OptionsTopBarTitle {
|
|
|
87
87
|
*/
|
|
88
88
|
document?: OptionsTopBarTitleDocument;
|
|
89
89
|
/**
|
|
90
|
-
* (iOS 26
|
|
90
|
+
* (iOS 26+, glass design) Puts the title on a Liquid Glass capsule like the buttons: `'regular'` or `'clear'`; `'none'` and any
|
|
91
91
|
* other value mean no capsule. A text title and the subtitle are two lines on the capsule; a component title sits on
|
|
92
|
-
* it as it is, the capsule taking its size.
|
|
92
|
+
* it as it is, the capsule taking its size. Without the glass design (see `UIDesignRequiresCompatibility`) and on Android it does nothing.
|
|
93
93
|
*/
|
|
94
94
|
glass?: 'regular' | 'clear' | 'none';
|
|
95
95
|
/** (Android) The height of the row of title and buttons, in dp. By default 64, regardless of `topBar.height`. */
|
|
@@ -110,15 +110,15 @@ export interface OptionsTopBarTitle {
|
|
|
110
110
|
/** The subtitle: a second line under the title. */
|
|
111
111
|
export interface OptionsTopBarSubtitle {
|
|
112
112
|
/**
|
|
113
|
-
* The text of the second line. An empty text removes it.
|
|
114
|
-
* large title and the collapsed bar, and on the capsule when the title has `glass`; a React title hides it.
|
|
115
|
-
*
|
|
113
|
+
* The text of the second line. An empty text removes it. With the glass design (iOS 26+, see `UIDesignRequiresCompatibility`) it is the system subtitle, under the title, the
|
|
114
|
+
* large title and the collapsed bar, and on the capsule when the title has `glass`; a React title hides it. Without
|
|
115
|
+
* it, it makes a two-line title view, only without a large title or a React title. On Android it is the line under
|
|
116
116
|
* the title, hidden when empty and dropped when the title is a component.
|
|
117
117
|
*/
|
|
118
118
|
text?: string;
|
|
119
119
|
/**
|
|
120
|
-
* The size of the font.
|
|
121
|
-
* font;
|
|
120
|
+
* The size of the font. With the glass design only what is set goes to the system subtitle, and any font option sets the whole
|
|
121
|
+
* font; without it the size is 12. On Android it is in sp, 14 by default.
|
|
122
122
|
*/
|
|
123
123
|
fontSize?: number;
|
|
124
124
|
/** The color of the subtitle. On Android the theme's on-surface-variant color by default. */
|
|
@@ -168,14 +168,14 @@ export interface OptionsTopBarBackButton {
|
|
|
168
168
|
*/
|
|
169
169
|
visible?: boolean;
|
|
170
170
|
/**
|
|
171
|
-
* (iOS) The text of the back button.
|
|
172
|
-
* the screen below is never shown;
|
|
171
|
+
* (iOS) The text of the back button. With the glass design (iOS 26+, see `UIDesignRequiresCompatibility`) the system button without it is an arrow alone,
|
|
172
|
+
* since the title of the screen below is never shown; without it, it is that title while it fits. It is set on the screen below, as
|
|
173
173
|
* its back button title.
|
|
174
174
|
*/
|
|
175
175
|
title?: string;
|
|
176
176
|
/**
|
|
177
177
|
* (iOS) `true` shows the title of the screen below (or `title`), `false` shows an arrow alone (the minimal mode).
|
|
178
|
-
* Without it the system decides;
|
|
178
|
+
* Without it the system decides; with the glass design that is the arrow.
|
|
179
179
|
*/
|
|
180
180
|
showTitle?: boolean;
|
|
181
181
|
/**
|
|
@@ -198,7 +198,7 @@ export interface OptionsTopBarBackButton {
|
|
|
198
198
|
/**
|
|
199
199
|
* A shape behind the icon, as for a button. It takes effect with a `color` of the shape. On iOS the icon (the
|
|
200
200
|
* chevron by default) is drawn on it and the back button becomes an own button that keeps the history menu unless
|
|
201
|
-
* `enableMenu` is `false`; without a capsule
|
|
201
|
+
* `enableMenu` is `false`; without a capsule with the glass design by default. On Android the arrow sits on the shape.
|
|
202
202
|
*/
|
|
203
203
|
iconBackground?: IconBackgroundOptions;
|
|
204
204
|
/**
|
|
@@ -219,7 +219,7 @@ export interface OptionsTopBarBackButton {
|
|
|
219
219
|
*/
|
|
220
220
|
displayMode?: 'default' | 'generic' | 'minimal';
|
|
221
221
|
/**
|
|
222
|
-
* (iOS 26
|
|
222
|
+
* (iOS 26+, glass design) Whether the Liquid Glass capsule under the back button is hidden. It works only for an own button with
|
|
223
223
|
* an `iconBackground`, where the shape is already drawn into the icon; the system button ignores it.
|
|
224
224
|
* @default true
|
|
225
225
|
*/
|
|
@@ -235,9 +235,9 @@ export interface OptionsTopBarBackButton {
|
|
|
235
235
|
/** The background of the bar: a color, a component, translucency and blur. */
|
|
236
236
|
export interface OptionsTopBarBackground {
|
|
237
237
|
/**
|
|
238
|
-
* The color of the bar. On iOS it fills both the standard look and the one at the scroll edge;
|
|
239
|
-
* then solid in this color instead of glass. A transparent color makes a transparent bar. It beats `blur` and
|
|
240
|
-
* `translucent`. With a large title
|
|
238
|
+
* The color of the bar. On iOS it fills both the standard look and the one at the scroll edge; with the glass design the bar is
|
|
239
|
+
* then solid in this color instead of glass; without it (`UIDesignRequiresCompatibility`) it is the opaque bar of before iOS 26. A transparent color makes a transparent bar. It beats `blur` and
|
|
240
|
+
* `translucent`. With a large title and the glass design the color is drawn into the list under the title, and the collapsed bar
|
|
241
241
|
* paints itself. On Android it is the background of the bar with the status bar strip, by default the theme's
|
|
242
242
|
* surface color, changing at once on push and pop. Together with `component` the color lies under the component.
|
|
243
243
|
*/
|
|
@@ -256,8 +256,8 @@ export interface OptionsTopBarBackground {
|
|
|
256
256
|
*/
|
|
257
257
|
component?: OptionsTopBarBackgroundComponent;
|
|
258
258
|
/**
|
|
259
|
-
* (iOS) Whether content shows through the bar. By default `true`
|
|
260
|
-
* the bar is glass
|
|
259
|
+
* (iOS) Whether content shows through the bar. By default `true` with the glass design (iOS 26+, see `UIDesignRequiresCompatibility`) and `false` without it. With `true`
|
|
260
|
+
* the bar is glass with the glass design and the system translucent bar without it; with `false` it is solid in the system color.
|
|
261
261
|
* `color` and `blur` beat it. Only an explicit `true` puts the screen under the bar.
|
|
262
262
|
*/
|
|
263
263
|
translucent?: boolean;
|
|
@@ -289,7 +289,7 @@ export interface OptionsTopBarBackgroundComponent {
|
|
|
289
289
|
export interface OptionsTopBarScrollEdgeAppearanceTitle {
|
|
290
290
|
/** The size of the font, handled like `topBar.title.fontSize`. */
|
|
291
291
|
fontSize?: number;
|
|
292
|
-
/** The color of the title at the edge.
|
|
292
|
+
/** The color of the title at the edge. With the glass design it is fixed during a push, like the usual title color. */
|
|
293
293
|
color?: Color;
|
|
294
294
|
/** The font family, handled like `topBar.title.fontFamily`. */
|
|
295
295
|
fontFamily?: FontFamily;
|
|
@@ -313,7 +313,7 @@ export interface OptionsTopBarScrollEdgeAppearanceBackground {
|
|
|
313
313
|
}
|
|
314
314
|
/**
|
|
315
315
|
* (iOS) How the bar looks while the list is at its top edge. Without `active` the edge looks as the usual bar, except
|
|
316
|
-
* for the transparency under a large title
|
|
316
|
+
* for the transparency under a large title with the glass design; the title and the border at the edge still come from the fields
|
|
317
317
|
* here or from the usual ones. Android doesn't read it.
|
|
318
318
|
*/
|
|
319
319
|
export interface OptionsTopBarScrollEdgeAppearance {
|
|
@@ -323,7 +323,7 @@ export interface OptionsTopBarScrollEdgeAppearance {
|
|
|
323
323
|
background?: OptionsTopBarScrollEdgeAppearanceBackground;
|
|
324
324
|
/**
|
|
325
325
|
* Whether the bar has a background of its own at the edge (`background`). With it the edge isn't made transparent
|
|
326
|
-
* under a large title, and
|
|
326
|
+
* under a large title, and with the glass design an opaque color covers the large title. A change by `mergeOptions` applies at
|
|
327
327
|
* once.
|
|
328
328
|
* @default false
|
|
329
329
|
*/
|
|
@@ -358,7 +358,7 @@ export interface OptionsTopBarLargeTitle {
|
|
|
358
358
|
* Whether the large title collapses into the bar as the list scrolls. With `false` on iOS the bar follows an empty
|
|
359
359
|
* scroll view instead of the list, so the title stays as at the top of the list; under the row it then needs a
|
|
360
360
|
* background (`background.color`, else a system blur), and `searchBar.hideOnScroll` doesn't work. On Android `false`
|
|
361
|
-
* leaves the bar as it is and stops listening to the list.
|
|
361
|
+
* leaves the bar as it is and stops listening to the list. With the glass design in a right-to-left layout nothing collapses.
|
|
362
362
|
* @default true
|
|
363
363
|
*/
|
|
364
364
|
collapseOnScroll?: boolean;
|
|
@@ -616,7 +616,7 @@ export interface OptionsTopBar {
|
|
|
616
616
|
/**
|
|
617
617
|
* The shape color behind the icons of the left buttons that have an `icon` image and no `iconBackground.color`; the
|
|
618
618
|
* size and corners come from the button's `iconBackground`, or the icon's size without corners. On iOS only image
|
|
619
|
-
* buttons, not SF Symbols, and without a capsule
|
|
619
|
+
* buttons, not SF Symbols, and without a capsule with the glass design. A color sent by `mergeOptions` repaints all the side's
|
|
620
620
|
* image buttons, those with their own shape color too.
|
|
621
621
|
*/
|
|
622
622
|
leftButtonBackgroundColor?: Color;
|
|
@@ -790,12 +790,15 @@ export interface OptionsScrollEdge {
|
|
|
790
790
|
}
|
|
791
791
|
/**
|
|
792
792
|
* (iOS 26+) The scroll edge effect of the scroll views of a screen: how the content fades or blurs where it scrolls
|
|
793
|
-
* under a bar. The scroll views draw it, and only where content goes under a bar.
|
|
794
|
-
*
|
|
795
|
-
* `
|
|
796
|
-
*
|
|
797
|
-
*
|
|
798
|
-
*
|
|
793
|
+
* under a bar. The scroll views draw it, and only where content goes under a bar. When the screen appears, it applies
|
|
794
|
+
* to the vertical lists and text views (a multi-line `TextInput`) in the view of the screen, except in hidden views
|
|
795
|
+
* (`display: none`). A list inside another vertical list gets none (UIKit draws no edge effect there); a scroll view
|
|
796
|
+
* that doesn't scroll vertically, like a pager, is searched for its lists. A list nested very deep in the screen's
|
|
797
|
+
* views may not get it. After React mounts, the main list of the screen gets it; a list mounted later gets it at the
|
|
798
|
+
* next appearance, or at a `mergeOptions` of `scrollEdgeEffect` or of the bar's background. The lists get the system
|
|
799
|
+
* effect back when the screen leaves or is destroyed, and a list React removes from the screen gets it back too. Under
|
|
800
|
+
* a bar with `background.color` or `background.component` there is no effect at the top unless the screen sets one for
|
|
801
|
+
* the top or for all edges. Before iOS 26 and on Android it does nothing.
|
|
799
802
|
*/
|
|
800
803
|
export interface OptionsScrollEdgeEffect {
|
|
801
804
|
/** Whether the effect is hidden on all four edges. The value of an edge beats it. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topBar.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/options/topBar.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"topBar.d.ts","sourceRoot":"","sources":["../../../../src/interfaces/options/topBar.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/ARCHITECTURE.md
CHANGED
|
@@ -248,10 +248,14 @@ name and on one id for two screens.
|
|
|
248
248
|
|
|
249
249
|
`usePreview(nativeID, { screen, props, actions })` works on iOS only. It arms a `pushPreview` from its screen: a push
|
|
250
250
|
with an id of its own (`Preview14`) and a `preview` option (`nativeID`, `commit`, the menu without its handlers, a
|
|
251
|
-
size). The native side
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
251
|
+
size). The native side makes the screen's node at once and gives the view with that `nativeID` a context menu that
|
|
252
|
+
previews it; a React screen gets its own root and renders when a press starts (the menu's configuration call, about
|
|
253
|
+
0.5 s before the preview), so a hundred previews hold no rendered screens until one is pressed. A screen of the one
|
|
254
|
+
tree (`appProvider`) and a native screen render at once. A tap on the preview pushes the screen, the push resolves, and
|
|
255
|
+
the hook arms the next one. A press of a menu item comes as `buttonPressed` of the preview's id, and the hook calls its
|
|
256
|
+
`onPress`. A preview that goes without being shown rejects its push, which the hook ignores. One that goes before its
|
|
257
|
+
first press never mounted a root, so the engine forgets what the push noted for it (`forgetUnmountedPreview` in
|
|
258
|
+
`src/engine/commands.ts`, after 1 s, unless a root of it mounted by then).
|
|
255
259
|
|
|
256
260
|
## The native side's contract
|
|
257
261
|
|
|
@@ -151,9 +151,9 @@ interface BaseConfig<
|
|
|
151
151
|
/** The look of the navigation: colors of the bars, tabs and backgrounds; `navigation.setTheme` changes it. */
|
|
152
152
|
theme?: NavigationTheme;
|
|
153
153
|
/**
|
|
154
|
-
* The edges on which every screen keeps its content out of its safe area. Without it:
|
|
155
|
-
*
|
|
156
|
-
* in its options.
|
|
154
|
+
* The edges on which every screen keeps its content out of its safe area. Without it: the top and the sides, but
|
|
155
|
+
* those where the content goes under a bar (`layout.safeAreaEdges`); the bottom is free and a list keeps clear of it
|
|
156
|
+
* with `useSafeAreaInsets()`. A screen gives its own with `safeArea(...)` in its options.
|
|
157
157
|
*/
|
|
158
158
|
safeArea?: { edges: SafeAreaEdge[] };
|
|
159
159
|
/** (iOS) The app's window, behind the screens: seen around a modal as it comes in. */
|
|
@@ -19,7 +19,7 @@ import { stackChild, type StackEntry } from '../layout/Stack';
|
|
|
19
19
|
import { badgeText } from '../layout/Tabs';
|
|
20
20
|
import { mergeOptions } from '../../engine/mergeOptions';
|
|
21
21
|
import { buildScreenOptions, type ScreenOptionsInput } from '../screens/defineScreen';
|
|
22
|
-
import { coversColumn, placeOf } from '../../engine/places';
|
|
22
|
+
import { coversColumn, firstScreenOf, placeOf, type ScreenPlace } from '../../engine/places';
|
|
23
23
|
import { command, placeFor } from './errors';
|
|
24
24
|
import type { ColumnConfig, ModalConfig, OverlayConfig, PushConfig } from './presentation';
|
|
25
25
|
import { defined, modalAnimations, pushAnimations } from './transitions';
|
|
@@ -30,6 +30,10 @@ const CLOSE_BUTTON = 'CloseButton';
|
|
|
30
30
|
// The modals shown by `showModal`, for the ids of their first screens.
|
|
31
31
|
let modals = 0;
|
|
32
32
|
|
|
33
|
+
// The stacks of the modals shown with a close button, by id: `setStack` and `replace` there give it to the new first
|
|
34
|
+
// screen. A stack's id is its modal's layer.
|
|
35
|
+
const closeButtonStacks = new Set<string>();
|
|
36
|
+
|
|
33
37
|
// The settings of a command with the props of the screen it shows.
|
|
34
38
|
type WithProps<Config> = Config & { props?: object };
|
|
35
39
|
|
|
@@ -115,7 +119,19 @@ export function popToRoot(fromId: string): Promise<string> {
|
|
|
115
119
|
export function setStack(fromId: string, entries: StackEntry[]): Promise<string> {
|
|
116
120
|
return command('setStack', () => {
|
|
117
121
|
placeFor('setStack', fromId, { stack: true });
|
|
118
|
-
|
|
122
|
+
const children = entries.map(stackChild);
|
|
123
|
+
const first = children[0]?.component;
|
|
124
|
+
if (!first || !hasCloseButton(placeOf(fromId))) {
|
|
125
|
+
return withSlots(() => engine.setStackRoot(fromId, children));
|
|
126
|
+
}
|
|
127
|
+
return afterLoading([first.name], () => {
|
|
128
|
+
// The screen's own buttons stay after the close button: the options of the layout replace them.
|
|
129
|
+
const id = first.id ?? nextId('Component');
|
|
130
|
+
const own = screenOptions(first.name, first.passProps ?? {});
|
|
131
|
+
const options = withCloseButton(mergeOptions(own, first.options ?? {}), id);
|
|
132
|
+
const withButton = { component: { ...first, id, options } };
|
|
133
|
+
return withSlots(() => engine.setStackRoot(fromId, [withButton, ...children.slice(1)]));
|
|
134
|
+
});
|
|
119
135
|
});
|
|
120
136
|
}
|
|
121
137
|
|
|
@@ -133,11 +149,12 @@ export function replace(
|
|
|
133
149
|
return afterLoading([name], () => {
|
|
134
150
|
const { props } = config;
|
|
135
151
|
const base = getActiveApp()?.presentation?.push;
|
|
136
|
-
const
|
|
152
|
+
const id = nextId('Component');
|
|
153
|
+
let options = showOptions(name, props, AS_PUSH, base?.options, config.options, {
|
|
137
154
|
app: pushAnimations(base?.transition),
|
|
138
155
|
call: pushAnimations(config.transition),
|
|
139
156
|
});
|
|
140
|
-
|
|
157
|
+
if (hasCloseButton(placeOf(fromId))) options = withCloseButton(options, id);
|
|
141
158
|
return withSlots(() =>
|
|
142
159
|
engine.setStackRoot(fromId, [screenLayout(name, props, options, id)])
|
|
143
160
|
).then(() => id);
|
|
@@ -192,16 +209,25 @@ function showModalNow(name: string, config: WithProps<ModalConfig>): Promise<str
|
|
|
192
209
|
app: modalAnimations(base.transition),
|
|
193
210
|
call: modalAnimations(call.transition),
|
|
194
211
|
});
|
|
195
|
-
|
|
212
|
+
// The stack gets its id here, so that the commands in it later know the modal had a close button.
|
|
213
|
+
const stackId = nextId('Stack');
|
|
214
|
+
const closeButton = settings.closeButton && settings.stack !== false;
|
|
215
|
+
if (closeButton) {
|
|
196
216
|
options = withCloseButton(options, screenId);
|
|
217
|
+
closeButtonStacks.add(stackId);
|
|
218
|
+
forgetWithStack(stackId, screenId);
|
|
219
|
+
}
|
|
197
220
|
if (call.onDismiss) whenScreenUnmounts(screenId, call.onDismiss);
|
|
198
221
|
const screen = screenLayout(name, props, options, screenId);
|
|
199
222
|
const presentation = presentationOptions(settings);
|
|
200
223
|
const layout: Layout =
|
|
201
224
|
settings.stack === false
|
|
202
225
|
? mergeLayoutOptions(screen, presentation)
|
|
203
|
-
: { stack: { children: [screen], options: presentation } };
|
|
204
|
-
|
|
226
|
+
: { stack: { id: stackId, children: [screen], options: presentation } };
|
|
227
|
+
const shown = withSlots(() => engine.showModal(layout));
|
|
228
|
+
// A modal that never showed has no stack to remember.
|
|
229
|
+
if (closeButton) shown.catch(() => closeButtonStacks.delete(stackId));
|
|
230
|
+
return shown;
|
|
205
231
|
}
|
|
206
232
|
|
|
207
233
|
export function dismissModal(modalId: string): Promise<string> {
|
|
@@ -340,6 +366,21 @@ export function holdLeave(screenId: string, onAttempt: () => void): () => void {
|
|
|
340
366
|
};
|
|
341
367
|
}
|
|
342
368
|
|
|
369
|
+
// Whether a screen is in the stack of a modal shown with a close button: the modal's own stack, not one in it.
|
|
370
|
+
function hasCloseButton(place: ScreenPlace | undefined): boolean {
|
|
371
|
+
return place?.stack != null && place.stack === place.layer && closeButtonStacks.has(place.stack);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// The stack of a modal is gone with its last first screen: one that unmounts with no other first screen noted after
|
|
375
|
+
// it (`setStack`, `replace` note theirs before the old one goes).
|
|
376
|
+
function forgetWithStack(stackId: string, screenId: string): void {
|
|
377
|
+
whenScreenUnmounts(screenId, () => {
|
|
378
|
+
const next = firstScreenOf(stackId);
|
|
379
|
+
if (next) forgetWithStack(stackId, next);
|
|
380
|
+
else closeButtonStacks.delete(stackId);
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
343
384
|
/** The options with a close button first at the leading edge, which dismisses the modal of the screen. */
|
|
344
385
|
function withCloseButton(options: Options, screenId: string): Options {
|
|
345
386
|
const close: NavigationButton = {
|
|
@@ -43,12 +43,13 @@ export interface ModalConfig {
|
|
|
43
43
|
stack?: boolean;
|
|
44
44
|
/**
|
|
45
45
|
* A close button at the leading edge of the modal's first screen, which dismisses the modal: the system one on iOS,
|
|
46
|
-
* an icon on Android. Its id and testID are `CloseButton`. Needs the stack.
|
|
46
|
+
* an icon on Android. Its id and testID are `CloseButton`. Needs the stack. A new first screen of that stack, from
|
|
47
|
+
* `setStack` or `replace`, gets it too.
|
|
47
48
|
*/
|
|
48
49
|
closeButton?: boolean;
|
|
49
50
|
/**
|
|
50
|
-
* Called once the modal is gone, whatever dismissed it: a command, a swipe, a new root. `setStack`
|
|
51
|
-
* modal
|
|
51
|
+
* Called once the modal is gone, whatever dismissed it: a command, a swipe, a new root. `setStack` and `replace`
|
|
52
|
+
* inside the modal replace its first screen, and call it too.
|
|
52
53
|
*/
|
|
53
54
|
onDismiss?: () => void;
|
|
54
55
|
/**
|
|
@@ -5,13 +5,14 @@ import { useScreen } from './screenHooks';
|
|
|
5
5
|
/**
|
|
6
6
|
* How much of this screen's content the bars and the system still cover on each side, past what the screen keeps its
|
|
7
7
|
* content off itself (`layout.safeAreaEdges`): 0 on an edge the screen pads, the whole inset on an edge its content goes
|
|
8
|
-
* under —
|
|
9
|
-
*
|
|
8
|
+
* under — the bottom by default (the home indicator, the navigation bar, a tab bar or toolbar the screen goes under),
|
|
9
|
+
* under a top bar, under the vertical bar at the side of iPhone Duo, every edge with `safeAreaEdges: []`. A list adds
|
|
10
|
+
* exactly this to its own padding. The native side measures every screen on its own, also the screens of
|
|
10
11
|
* `appProvider`.
|
|
11
12
|
*
|
|
12
13
|
* @example
|
|
13
14
|
* const insets = useSafeAreaInsets();
|
|
14
|
-
* <ScrollView contentContainerStyle={{
|
|
15
|
+
* <ScrollView contentContainerStyle={{ paddingBottom: 16 + insets.bottom }} />
|
|
15
16
|
*/
|
|
16
17
|
export function useSafeAreaInsets(): EdgeInsets {
|
|
17
18
|
const { id } = useScreen();
|
|
@@ -68,8 +68,8 @@ export abstract class OptionsChain {
|
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
70
|
* The edges on which the screen keeps its content out of its safe area (bars, status bar, home indicator, cutout);
|
|
71
|
-
* none with no edge. Without it:
|
|
72
|
-
* a
|
|
71
|
+
* none with no edge. Without it: the top and the sides, but those where the content goes under a bar; the bottom is
|
|
72
|
+
* free, and a list keeps clear of it with `useSafeAreaInsets()`. A large title leaves the top out by itself.
|
|
73
73
|
*/
|
|
74
74
|
safeArea(...edges: SafeAreaEdge[]): this {
|
|
75
75
|
return this.layout({ safeAreaEdges: edges });
|
package/src/engine/commands.ts
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
rootGoesOut,
|
|
18
18
|
sentRoot,
|
|
19
19
|
} from './rememberedOptions';
|
|
20
|
-
import { afterLoading } from './screens';
|
|
20
|
+
import { afterLoading, hasRoot, isReactScreen } from './screens';
|
|
21
21
|
import { holdSlot, isSlotName, removeSlots, showSlot, type SlotFrame } from './slots';
|
|
22
22
|
import { forgetTabsScreen, showScreensFrom } from './tabs';
|
|
23
23
|
|
|
@@ -229,16 +229,40 @@ export function push(
|
|
|
229
229
|
layoutsOf(componentId)
|
|
230
230
|
);
|
|
231
231
|
return whenNativeScreensReady([node], () =>
|
|
232
|
-
sendPush(commandId, componentId, node, prepares, wanted, goneOut).then(
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
232
|
+
sendPush(commandId, componentId, node, prepares, wanted, goneOut).then(
|
|
233
|
+
(shownId) => {
|
|
234
|
+
// A screen with a key went back to the one with the same key: the new screen never shows.
|
|
235
|
+
if (shownId !== node.id) forgetNeverShown(node.id);
|
|
236
|
+
return shownId;
|
|
237
|
+
},
|
|
238
|
+
(error: unknown) => {
|
|
239
|
+
if (rendersAtPress(node)) forgetUnmountedPreview(node.id);
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
)
|
|
237
243
|
);
|
|
238
244
|
})
|
|
239
245
|
);
|
|
240
246
|
}
|
|
241
247
|
|
|
248
|
+
// A preview's React screen with a root of its own renders only once the view is pressed (iOS): one whose preview went
|
|
249
|
+
// before that never mounts. A screen of the one tree mounts with its slot, a native screen has no root.
|
|
250
|
+
function rendersAtPress(node: LayoutNode): boolean {
|
|
251
|
+
return node.data.options?.preview?.nativeID !== undefined && isReactScreen(node.data.name ?? '');
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// A root started at a press that came just before the preview went can reach JavaScript after its push failed: without
|
|
255
|
+
// its props it would render the screen with none. Its notes go after this time, when no root of it has mounted by
|
|
256
|
+
// then; one that has clears them as it unmounts.
|
|
257
|
+
const PREVIEW_FORGET_DELAY = 1000;
|
|
258
|
+
|
|
259
|
+
function forgetUnmountedPreview(screenId: string): void {
|
|
260
|
+
if (hasRoot(screenId)) return;
|
|
261
|
+
setTimeout(() => {
|
|
262
|
+
if (!hasRoot(screenId)) forgetNeverShown(screenId);
|
|
263
|
+
}, PREVIEW_FORGET_DELAY);
|
|
264
|
+
}
|
|
265
|
+
|
|
242
266
|
// Everything a push noted for a screen that never mounts, which an unmount would clear.
|
|
243
267
|
function forgetNeverShown(screenId: string): void {
|
|
244
268
|
forgetProps(screenId);
|
package/src/engine/places.ts
CHANGED
|
@@ -65,6 +65,15 @@ export function placeOf(screenId: string): ScreenPlace | undefined {
|
|
|
65
65
|
return places.get(screenId);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/** The first screen of a stack, as the engine noted it; with a pair first, its primary. */
|
|
69
|
+
export function firstScreenOf(stack: string): string | undefined {
|
|
70
|
+
for (const [id, place] of places) {
|
|
71
|
+
if (place.stack === stack && place.index === 0 && place.arrangement?.placement !== 'secondary')
|
|
72
|
+
return id;
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
68
77
|
/** Notes that a screen is the primary of a pair shown alone, where the native side shows no pairs. */
|
|
69
78
|
export function noteAlone(screenId: string): void {
|
|
70
79
|
alone.add(screenId);
|
package/src/engine/screens.tsx
CHANGED
|
@@ -52,8 +52,15 @@ export type EngineScreen =
|
|
|
52
52
|
/** What the root of a React screen renders: the screen's id, and the props the command gave it. */
|
|
53
53
|
export type ScreenRootProps = { componentId: string } & Record<string, unknown>;
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* What React Native gives the root of a React screen: the screen's id, its root tag (none in a slot of the app's one
|
|
57
|
+
* tree), and the props the native side gives that root, a tab cell's `tabIndex`, `selected`, `badge`, `dot` and
|
|
58
|
+
* `dotColor`.
|
|
59
|
+
*/
|
|
60
|
+
export type NativeRootProps = { componentId: string; rootTag?: number } & Record<string, unknown>;
|
|
61
|
+
|
|
55
62
|
const screens = new Map<string, EngineScreen>();
|
|
56
|
-
const roots = new Map<string, ComponentType<
|
|
63
|
+
const roots = new Map<string, ComponentType<NativeRootProps>>();
|
|
57
64
|
let unmounted: ((screenId: string) => void) | undefined;
|
|
58
65
|
// The React roots mounted under each id, by their root tags. One id can have several: after a JavaScript reload React
|
|
59
66
|
// Native starts the roots of the old screens again in the new runtime, under the ids the new screens get too, and
|
|
@@ -62,6 +69,11 @@ let unmounted: ((screenId: string) => void) | undefined;
|
|
|
62
69
|
// has no tag: while the one tree shows a screen with the id, no root of that id lets it go.
|
|
63
70
|
const owners = new Map<string, Set<number>>();
|
|
64
71
|
|
|
72
|
+
/** Whether a React root of the screen with the id is mounted now (a slot of the app's one tree doesn't count). */
|
|
73
|
+
export function hasRoot(componentId: string): boolean {
|
|
74
|
+
return owners.has(componentId);
|
|
75
|
+
}
|
|
76
|
+
|
|
65
77
|
/** What runs when the root of a screen unmounts: the screen is gone. */
|
|
66
78
|
export function onScreenUnmounted(listener: (screenId: string) => void): void {
|
|
67
79
|
unmounted = listener;
|
|
@@ -193,20 +205,29 @@ export function isReactScreen(name: string): boolean {
|
|
|
193
205
|
return screen !== undefined && 'component' in screen;
|
|
194
206
|
}
|
|
195
207
|
|
|
208
|
+
/**
|
|
209
|
+
* The props a screen's component renders with: those a command left under its id ([stored]), the props the native side
|
|
210
|
+
* gave its root over them ([root]: a tab cell's state, which the docs promise arrives on top of `passProps`), and its
|
|
211
|
+
* id. The root tag stays with the root.
|
|
212
|
+
*/
|
|
213
|
+
export function screenProps(stored: object, root: NativeRootProps): ScreenRootProps {
|
|
214
|
+
const props: ScreenRootProps = { ...stored, ...root, componentId: root.componentId };
|
|
215
|
+
delete props.rootTag;
|
|
216
|
+
return props;
|
|
217
|
+
}
|
|
218
|
+
|
|
196
219
|
/**
|
|
197
220
|
* The root a React screen runs in: the screen with the props a command left for it under its id, and the new ones when
|
|
198
|
-
* options give its id new props
|
|
199
|
-
*
|
|
221
|
+
* options give its id new props, under the props the native side gives the root ([screenProps]). The slot of the app's
|
|
222
|
+
* one tree renders the same root.
|
|
200
223
|
*/
|
|
201
|
-
export function screenRoot(
|
|
202
|
-
name: string
|
|
203
|
-
): ComponentType<{ componentId: string; rootTag?: number }> | undefined {
|
|
224
|
+
export function screenRoot(name: string): ComponentType<NativeRootProps> | undefined {
|
|
204
225
|
const screen = screens.get(name);
|
|
205
226
|
if (!screen || !('component' in screen)) return undefined;
|
|
206
227
|
let root = roots.get(name);
|
|
207
228
|
if (!root) {
|
|
208
229
|
const Screen = screen.component();
|
|
209
|
-
root = function ScreenRoot(rootProps:
|
|
230
|
+
root = function ScreenRoot(rootProps: NativeRootProps) {
|
|
210
231
|
// In the app's one tree the slot renders the root, without a tag of its own.
|
|
211
232
|
const { componentId, rootTag } = rootProps;
|
|
212
233
|
const watch = useCallback(
|
|
@@ -240,7 +261,7 @@ export function screenRoot(
|
|
|
240
261
|
unmounted?.(componentId);
|
|
241
262
|
};
|
|
242
263
|
}, [componentId, rootTag]);
|
|
243
|
-
return <Screen {...props
|
|
264
|
+
return <Screen {...screenProps(props, rootProps)} />;
|
|
244
265
|
};
|
|
245
266
|
root.displayName = `ScreenRoot(${name})`;
|
|
246
267
|
roots.set(name, root);
|