@apexnative/navigation 1.0.0-alpha.1 → 1.0.0-alpha.3

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.
Files changed (163) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +147 -51
  3. package/android/CLAUDE.md +31 -6
  4. package/android/CORE.md +7 -2
  5. package/android/RECIPES.md +4 -3
  6. package/android/src/main/java/dev/apexnative/navigation/NavigationActivity.kt +29 -1
  7. package/android/src/main/java/dev/apexnative/navigation/options/StatusBarOptions.kt +7 -3
  8. package/android/src/main/java/dev/apexnative/navigation/react/ArrangementStates.kt +5 -4
  9. package/android/src/main/java/dev/apexnative/navigation/react/ErrorTexts.kt +75 -60
  10. package/android/src/main/java/dev/apexnative/navigation/react/Hinge.kt +3 -2
  11. package/android/src/main/java/dev/apexnative/navigation/react/OptionsCommands.kt +1 -1
  12. package/android/src/main/java/dev/apexnative/navigation/react/ScreenInsets.kt +5 -4
  13. package/android/src/main/java/dev/apexnative/navigation/react/ScreenRegions.kt +7 -6
  14. package/android/src/main/java/dev/apexnative/navigation/react/events/AppearanceDispatcher.kt +3 -35
  15. package/android/src/main/java/dev/apexnative/navigation/react/events/EventContract.kt +226 -0
  16. package/android/src/main/java/dev/apexnative/navigation/react/events/EventEmitter.kt +101 -87
  17. package/android/src/main/java/dev/apexnative/navigation/react/events/ScreenAppearance.kt +0 -6
  18. package/android/src/main/java/dev/apexnative/navigation/utils/UiUtils.kt +3 -3
  19. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/arrangement/SecondaryScreenPresenter.kt +13 -5
  20. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/BottomTabsController.kt +76 -13
  21. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/bottomtabs/TabItems.kt +3 -3
  22. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ComponentPresenter.kt +28 -7
  23. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/component/ScreenFrame.kt +1 -1
  24. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalAnimations.kt +22 -24
  25. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalCoordinator.kt +86 -16
  26. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalRecord.kt +21 -6
  27. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalSheet.kt +41 -23
  28. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/ModalViews.kt +24 -20
  29. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/modal/SheetStops.kt +25 -0
  30. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/BackCallbackState.kt +4 -0
  31. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/Navigator.kt +42 -4
  32. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/navigator/RootCoordinator.kt +29 -6
  33. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/overlay/OverlayCoordinator.kt +2 -0
  34. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ContainerBackground.kt +3 -3
  35. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/parent/ParentController.kt +3 -0
  36. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuController.kt +5 -3
  37. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuMotion.kt +4 -7
  38. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuPresenter.kt +16 -7
  39. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/sidemenu/SideMenuRules.kt +8 -1
  40. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/splitview/SplitViewController.kt +16 -2
  41. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/BackPreview.kt +287 -0
  42. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackController.kt +148 -6
  43. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackDisplay.kt +24 -0
  44. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackQueue.kt +51 -11
  45. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackTransitions.kt +26 -8
  46. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/StackViews.kt +105 -2
  47. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/stack/topbar/TopBarPresenter.kt +123 -8
  48. package/android/src/main/java/dev/apexnative/navigation/viewcontrollers/viewcontroller/ViewController.kt +19 -0
  49. package/android/src/main/java/dev/apexnative/navigation/views/animations/Curves.kt +29 -11
  50. package/android/src/main/java/dev/apexnative/navigation/views/bottomtabs/BottomTabs.kt +5 -5
  51. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementStep.kt +31 -0
  52. package/android/src/main/java/dev/apexnative/navigation/views/element/ElementTransitions.kt +85 -27
  53. package/android/src/main/java/dev/apexnative/navigation/views/element/TargetsWait.kt +5 -4
  54. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionTargets.kt +9 -6
  55. package/android/src/main/java/dev/apexnative/navigation/views/element/TransitionViews.kt +100 -0
  56. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ElementPictures.kt +45 -1
  57. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ImageMatrixAnimator.kt +3 -5
  58. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/PlainViewAnimator.kt +3 -5
  59. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ReactImageAnimator.kt +3 -5
  60. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/SharedAnimatorFactory.kt +2 -0
  61. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/TextChangeAnimator.kt +4 -6
  62. package/android/src/main/java/dev/apexnative/navigation/views/element/animators/ViewChangeAnimator.kt +4 -6
  63. package/android/src/main/java/dev/apexnative/navigation/views/stack/ScreenEdge.kt +15 -0
  64. package/android/src/main/java/dev/apexnative/navigation/views/stack/StackLayout.kt +137 -1
  65. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TitleBar.kt +8 -1
  66. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/TopBar.kt +26 -4
  67. package/android/src/main/java/dev/apexnative/navigation/views/stack/topbar/titlebar/ButtonBar.kt +4 -3
  68. package/cli/app.js +1 -1
  69. package/cli/project.js +6 -2
  70. package/cli/setup/index.js +13 -0
  71. package/cli/setup/steps/appDelegate.js +66 -11
  72. package/cli/setup/steps/sceneDelegate.js +108 -0
  73. package/docs-md/architecture/transitions.md +7 -1
  74. package/docs-md/containers/modals.md +4 -2
  75. package/docs-md/containers/overlays.md +3 -1
  76. package/docs-md/containers/side-menu.md +4 -2
  77. package/docs-md/containers/tabs.md +2 -0
  78. package/docs-md/flows/forms-in-a-modal.md +1 -1
  79. package/docs-md/guides/deep-links.md +15 -33
  80. package/docs-md/help/glossary.md +1 -1
  81. package/docs-md/index.json +8 -0
  82. package/docs-md/screen-ui/back-and-gestures.md +6 -0
  83. package/docs-md/screen-ui/system-ui.md +1 -1
  84. package/docs-md/start/installation.md +1 -0
  85. package/ios/Animations/ANNTransitionAnimator.mm +13 -11
  86. package/ios/Animations/ANNTransitionWait.mm +6 -7
  87. package/ios/Animations/Elements/ANNElementFinder.h +57 -0
  88. package/ios/Animations/Elements/ANNElementFinder.mm +174 -2
  89. package/ios/Animations/Elements/ANNElementTransition.h +7 -5
  90. package/ios/Animations/Elements/ANNElementTransition.mm +17 -19
  91. package/ios/Animations/Elements/ANNSharedElementFlight.h +13 -8
  92. package/ios/Animations/Elements/ANNSharedElementFlight.mm +59 -24
  93. package/ios/CLAUDE.md +10 -2
  94. package/ios/CORE.md +3 -2
  95. package/ios/Contract/ANNCommandAnswer.h +4 -3
  96. package/ios/Contract/ANNCommandAnswer.mm +12 -2
  97. package/ios/Contract/ANNCommandRunner.h +2 -2
  98. package/ios/Contract/ANNCommandRunner.mm +1 -1
  99. package/ios/Contract/ANNErrorTexts.h +6 -2
  100. package/ios/Contract/ANNErrorTexts.mm +18 -10
  101. package/ios/Core/ANNDeepLinkQueue.h +20 -1
  102. package/ios/Core/ANNDeepLinkQueue.mm +107 -12
  103. package/ios/Core/ANNErrorHandler.h +8 -3
  104. package/ios/Core/ANNErrorHandler.mm +17 -1
  105. package/ios/Core/ANNEventContract.h +246 -0
  106. package/ios/Core/ANNEventContract.mm +225 -0
  107. package/ios/Core/ANNEventEmitter.h +5 -1
  108. package/ios/Core/ANNEventEmitter.mm +117 -80
  109. package/ios/Core/ANNHinge.mm +6 -4
  110. package/ios/Core/ANNSceneDelegate.mm +25 -15
  111. package/ios/Core/ANNSystemUI.h +3 -2
  112. package/ios/Core/ANNSystemUI.mm +7 -0
  113. package/ios/Layouts/Arrangement/ANNArrangementViewController.mm +6 -4
  114. package/ios/Layouts/Modal/ANNModalCoordinator.mm +1 -1
  115. package/ios/Layouts/Modal/ANNModalPresentation.h +8 -5
  116. package/ios/Layouts/Modal/ANNModalPresentation.mm +12 -12
  117. package/ios/Layouts/Modal/ANNSheetPresenter.mm +83 -1
  118. package/ios/Layouts/Root/ANNRootCoordinator.mm +12 -3
  119. package/ios/Layouts/Screen/ANNComponentPresenter.h +11 -3
  120. package/ios/Layouts/Screen/ANNComponentPresenter.mm +34 -6
  121. package/ios/Layouts/Screen/ANNComponentViewController.mm +28 -7
  122. package/ios/Layouts/Screen/ANNNativeScreenContext.mm +7 -5
  123. package/ios/Layouts/Screen/ANNScreenInsets.mm +6 -4
  124. package/ios/Layouts/Screen/ANNScreenRegions.mm +9 -6
  125. package/ios/Layouts/SplitView/ANNSplitViewController.mm +4 -7
  126. package/ios/Options/ANNSheetOptions.h +4 -1
  127. package/ios/Public/ApexNavigation/ANNSceneDelegate.h +3 -0
  128. package/ios/RECIPES.md +2 -1
  129. package/ios/TurboModules/ANNTurboEventEmitter.mm +4 -35
  130. package/ios/TurboModules/ANNTurboModule.mm +5 -2
  131. package/lib/module/ARCHITECTURE.md +7 -4
  132. package/lib/module/api/app/createNavigation.js +2 -0
  133. package/lib/module/api/app/createNavigation.js.map +1 -1
  134. package/lib/module/api/hooks/useNavigation.js +8 -3
  135. package/lib/module/api/hooks/useNavigation.js.map +1 -1
  136. package/lib/module/api/linking/dispatchedLinks.js +23 -0
  137. package/lib/module/api/linking/dispatchedLinks.js.map +1 -0
  138. package/lib/module/interfaces/contract/errors.json +275 -0
  139. package/lib/typescript/api/app/createNavigation.d.ts.map +1 -1
  140. package/lib/typescript/api/hooks/useNavigation.d.ts.map +1 -1
  141. package/lib/typescript/api/linking/dispatchedLinks.d.ts +7 -0
  142. package/lib/typescript/api/linking/dispatchedLinks.d.ts.map +1 -0
  143. package/lib/typescript/interfaces/Events.d.ts +9 -0
  144. package/lib/typescript/interfaces/Events.d.ts.map +1 -1
  145. package/lib/typescript/interfaces/options/animations.d.ts +27 -18
  146. package/lib/typescript/interfaces/options/animations.d.ts.map +1 -1
  147. package/lib/typescript/interfaces/options/modals.d.ts +33 -24
  148. package/lib/typescript/interfaces/options/modals.d.ts.map +1 -1
  149. package/lib/typescript/interfaces/options/sideMenu.d.ts +7 -6
  150. package/lib/typescript/interfaces/options/sideMenu.d.ts.map +1 -1
  151. package/lib/typescript/interfaces/options/system.d.ts +10 -6
  152. package/lib/typescript/interfaces/options/system.d.ts.map +1 -1
  153. package/package.json +1 -1
  154. package/src/ARCHITECTURE.md +7 -4
  155. package/src/api/app/createNavigation.ts +2 -0
  156. package/src/api/hooks/useNavigation.ts +8 -3
  157. package/src/api/linking/dispatchedLinks.ts +18 -0
  158. package/src/interfaces/Events.ts +10 -0
  159. package/src/interfaces/contract/errors.json +275 -0
  160. package/src/interfaces/options/animations.ts +27 -18
  161. package/src/interfaces/options/modals.ts +33 -24
  162. package/src/interfaces/options/sideMenu.ts +7 -6
  163. package/src/interfaces/options/system.ts +10 -6
@@ -0,0 +1,225 @@
1
+ // Made by scripts/contract.mjs from the event types of src/interfaces/: change them and run the script again.
2
+
3
+ #import "ANNEventContract.h"
4
+
5
+ const struct ANNEventContractTable ANNEventContract = {
6
+ .AppLaunched = {.event = @"ANN.AppLaunched"},
7
+ .ArrangementChanged =
8
+ {
9
+ .event = @"ANN.ArrangementChanged",
10
+ .componentId = @"componentId",
11
+ .placement = @"placement",
12
+ .layout = @"layout",
13
+ .front = @"front",
14
+ .hidden = @"hidden",
15
+ },
16
+ .BottomAccessoryPlacementChanged =
17
+ {
18
+ .event = @"ANN.BottomAccessoryPlacementChanged",
19
+ .componentId = @"componentId",
20
+ .placement = @"placement",
21
+ },
22
+ .BottomTabLongPressed =
23
+ {
24
+ .event = @"ANN.BottomTabLongPressed",
25
+ .selectedTabIndex = @"selectedTabIndex",
26
+ .bottomTabsId = @"bottomTabsId",
27
+ },
28
+ .BottomTabPressed =
29
+ {
30
+ .event = @"ANN.BottomTabPressed",
31
+ .tabIndex = @"tabIndex",
32
+ .bottomTabsId = @"bottomTabsId",
33
+ .screenId = @"screenId",
34
+ .wasSelected = @"wasSelected",
35
+ },
36
+ .BottomTabSelected =
37
+ {
38
+ .event = @"ANN.BottomTabSelected",
39
+ .selectedTabIndex = @"selectedTabIndex",
40
+ .unselectedTabIndex = @"unselectedTabIndex",
41
+ .bottomTabsId = @"bottomTabsId",
42
+ },
43
+ .CommandCompleted =
44
+ {
45
+ .event = @"ANN.CommandCompleted",
46
+ .commandName = @"commandName",
47
+ .commandId = @"commandId",
48
+ .completionTime = @"completionTime",
49
+ },
50
+ .ComponentDidAppear =
51
+ {
52
+ .event = @"ANN.ComponentDidAppear",
53
+ .componentId = @"componentId",
54
+ .componentName = @"componentName",
55
+ .componentType = @"componentType",
56
+ },
57
+ .ComponentDidDisappear =
58
+ {
59
+ .event = @"ANN.ComponentDidDisappear",
60
+ .componentId = @"componentId",
61
+ .componentName = @"componentName",
62
+ .componentType = @"componentType",
63
+ },
64
+ .ComponentWillAppear =
65
+ {
66
+ .event = @"ANN.ComponentWillAppear",
67
+ .componentId = @"componentId",
68
+ .componentName = @"componentName",
69
+ .componentType = @"componentType",
70
+ },
71
+ .DeepLinkDispatched = {.event = @"ANN.DeepLinkDispatched", .url = @"url"},
72
+ .HingeChanged = {.event = @"ANN.HingeChanged", .state = @"state", .angle = @"angle"},
73
+ .KeyCommandPressed =
74
+ {
75
+ .event = @"ANN.KeyCommandPressed",
76
+ .componentId = @"componentId",
77
+ .keyCommandId = @"keyCommandId",
78
+ },
79
+ .ModalAttemptedToDismiss =
80
+ {
81
+ .event = @"ANN.ModalAttemptedToDismiss",
82
+ .componentId = @"componentId",
83
+ },
84
+ .ModalDismissed =
85
+ {
86
+ .event = @"ANN.ModalDismissed",
87
+ .componentId = @"componentId",
88
+ .componentName = @"componentName",
89
+ .modalsDismissed = @"modalsDismissed",
90
+ },
91
+ .NativeScreenCall =
92
+ {
93
+ .event = @"ANN.NativeScreenCall",
94
+ .componentId = @"componentId",
95
+ .callId = @"callId",
96
+ .kind = @"kind",
97
+ .name = @"name",
98
+ .args = @"args",
99
+ },
100
+ .NativeScreenReleased = {.event = @"ANN.NativeScreenReleased", .componentId = @"componentId"},
101
+ .NavigationButtonPressed =
102
+ {
103
+ .event = @"ANN.NavigationButtonPressed",
104
+ .componentId = @"componentId",
105
+ .buttonId = @"buttonId",
106
+ .selected = @"selected",
107
+ },
108
+ .NavigationStateChanged =
109
+ {
110
+ .event = @"ANN.NavigationStateChanged",
111
+ .screen = @"screen",
112
+ .tab = @"tab",
113
+ },
114
+ .NavigationStateChangedScreen = {.id = @"id", .name = @"name"},
115
+ .PreviewCompleted =
116
+ {
117
+ .event = @"ANN.PreviewCompleted",
118
+ .componentId = @"componentId",
119
+ .previewComponentId = @"previewComponentId",
120
+ },
121
+ .ScreenInsetsChanged =
122
+ {
123
+ .event = @"ANN.ScreenInsetsChanged",
124
+ .componentId = @"componentId",
125
+ .top = @"top",
126
+ .right = @"right",
127
+ .bottom = @"bottom",
128
+ .left = @"left",
129
+ },
130
+ .ScreenPopped = {.event = @"ANN.ScreenPopped", .componentId = @"componentId"},
131
+ .ScreenRegionRect = {.x = @"x", .y = @"y", .width = @"width", .height = @"height"},
132
+ .ScreenRegionsChanged =
133
+ {
134
+ .event = @"ANN.ScreenRegionsChanged",
135
+ .componentId = @"componentId",
136
+ .division = @"division",
137
+ .occlusion = @"occlusion",
138
+ },
139
+ .SearchBarCancelPressed =
140
+ {
141
+ .event = @"ANN.SearchBarCancelPressed",
142
+ .componentId = @"componentId",
143
+ },
144
+ .SearchBarSubmitted =
145
+ {
146
+ .event = @"ANN.SearchBarSubmitted",
147
+ .componentId = @"componentId",
148
+ .text = @"text",
149
+ .scope = @"scope",
150
+ .tokens = @"tokens",
151
+ },
152
+ .SearchBarUpdated =
153
+ {
154
+ .event = @"ANN.SearchBarUpdated",
155
+ .componentId = @"componentId",
156
+ .text = @"text",
157
+ .isFocused = @"isFocused",
158
+ .scope = @"scope",
159
+ .tokens = @"tokens",
160
+ },
161
+ .SearchSuggestionPicked =
162
+ {
163
+ .event = @"ANN.SearchSuggestionPicked",
164
+ .componentId = @"componentId",
165
+ .suggestionId = @"suggestionId",
166
+ },
167
+ .SheetDetentChanged =
168
+ {
169
+ .event = @"ANN.SheetDetentChanged",
170
+ .componentId = @"componentId",
171
+ .detent = @"detent",
172
+ },
173
+ .SlotDestroyed = {.event = @"ANN.SlotDestroyed", .componentId = @"componentId"},
174
+ .SplitViewColumnsStacked =
175
+ {
176
+ .event = @"ANN.SplitViewColumnsStacked",
177
+ .componentId = @"componentId",
178
+ .stacked = @"stacked",
179
+ },
180
+ .SplitViewDisplayModeChanged =
181
+ {
182
+ .event = @"ANN.SplitViewDisplayModeChanged",
183
+ .componentId = @"componentId",
184
+ .displayMode = @"displayMode",
185
+ .inspectorVisible = @"inspectorVisible",
186
+ },
187
+ .TitleRenamed = {.event = @"ANN.TitleRenamed", .componentId = @"componentId", .text = @"text"},
188
+ };
189
+
190
+ NSArray<NSString *> *ANNEventContractNames(void) {
191
+ return @[
192
+ ANNEventContract.AppLaunched.event,
193
+ ANNEventContract.ArrangementChanged.event,
194
+ ANNEventContract.BottomAccessoryPlacementChanged.event,
195
+ ANNEventContract.BottomTabLongPressed.event,
196
+ ANNEventContract.BottomTabPressed.event,
197
+ ANNEventContract.BottomTabSelected.event,
198
+ ANNEventContract.CommandCompleted.event,
199
+ ANNEventContract.ComponentDidAppear.event,
200
+ ANNEventContract.ComponentDidDisappear.event,
201
+ ANNEventContract.ComponentWillAppear.event,
202
+ ANNEventContract.DeepLinkDispatched.event,
203
+ ANNEventContract.HingeChanged.event,
204
+ ANNEventContract.KeyCommandPressed.event,
205
+ ANNEventContract.ModalAttemptedToDismiss.event,
206
+ ANNEventContract.ModalDismissed.event,
207
+ ANNEventContract.NativeScreenCall.event,
208
+ ANNEventContract.NativeScreenReleased.event,
209
+ ANNEventContract.NavigationButtonPressed.event,
210
+ ANNEventContract.NavigationStateChanged.event,
211
+ ANNEventContract.PreviewCompleted.event,
212
+ ANNEventContract.ScreenInsetsChanged.event,
213
+ ANNEventContract.ScreenPopped.event,
214
+ ANNEventContract.ScreenRegionsChanged.event,
215
+ ANNEventContract.SearchBarCancelPressed.event,
216
+ ANNEventContract.SearchBarSubmitted.event,
217
+ ANNEventContract.SearchBarUpdated.event,
218
+ ANNEventContract.SearchSuggestionPicked.event,
219
+ ANNEventContract.SheetDetentChanged.event,
220
+ ANNEventContract.SlotDestroyed.event,
221
+ ANNEventContract.SplitViewColumnsStacked.event,
222
+ ANNEventContract.SplitViewDisplayModeChanged.event,
223
+ ANNEventContract.TitleRenamed.event,
224
+ ];
225
+ }
@@ -22,7 +22,8 @@ NS_ASSUME_NONNULL_BEGIN
22
22
  /// Whether the JavaScript of this emitter still runs: its events go only then. Any thread.
23
23
  @property(nonatomic, readonly) BOOL isCurrent;
24
24
 
25
- /// Sends `ANN.<name>` with the payload as it is. From another queue it moves to the main queue first.
25
+ /// Sends the event `name` (`ANNEventContract.<Event>.event`, `ANN.<Event>`) with the payload as it is, its keys from
26
+ /// `ANNEventContract` too. From another queue it moves to the main queue first.
26
27
  - (void)sendEvent:(NSString *)name body:(nullable NSDictionary<NSString *, id> *)body;
27
28
 
28
29
  #pragma mark - The contract
@@ -85,6 +86,9 @@ NS_ASSUME_NONNULL_BEGIN
85
86
 
86
87
  - (void)sendSlotDestroyed:(NSString *)componentId;
87
88
 
89
+ /// `ANN.DeepLinkDispatched { url }` (iOS only): a link React Native's `Linking` didn't take, for JavaScript to hand it.
90
+ - (void)sendDeepLinkDispatched:(NSURL *)url;
91
+
88
92
  /// `ANN.TitleRenamed { componentId, text }` (EVT-TitleRenamed).
89
93
  - (void)sendTitleRenamed:(NSString *)componentId text:(NSString *)text;
90
94
 
@@ -1,5 +1,6 @@
1
1
  #import "ANNEventEmitter.h"
2
2
  #import "ANNAssert.h"
3
+ #import "ANNEventContract.h"
3
4
  #import "ANNReloadCoordinator.h"
4
5
  #import "ANNTurboEventEmitter.h"
5
6
  #import <React/RCTUtils.h>
@@ -24,8 +25,6 @@ static NSString *ANNComponentTypeName(ANNReactComponentType componentType) {
24
25
  static BOOL ANNAppLaunchedPending;
25
26
  static NSUInteger ANNAppLaunchedBundle;
26
27
 
27
- static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
28
-
29
28
  @implementation ANNEventEmitter
30
29
 
31
30
  - (instancetype)init {
@@ -42,12 +41,11 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
42
41
  // The generation is checked where the event goes out, on the main queue: an event sent from another queue just
43
42
  // before a reload is dropped too.
44
43
  - (void)sendEvent:(NSString *)name body:(NSDictionary<NSString *, id> *)body {
45
- NSString *eventName = [@"ANN." stringByAppendingString:name];
46
44
  RCTExecuteOnMainQueue(^{
47
45
  if (!self.isCurrent) {
48
46
  return;
49
47
  }
50
- [ANNTurboEventEmitter.current sendIfListened:eventName body:body];
48
+ [ANNTurboEventEmitter.current sendIfListened:name body:body];
51
49
  });
52
50
  }
53
51
 
@@ -62,7 +60,7 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
62
60
  return;
63
61
  }
64
62
  ANNAppLaunchedPending = NO;
65
- [eventEmitter sendIfListened:ANNAppLaunchedEvent body:nil];
63
+ [eventEmitter sendIfListened:ANNEventContract.AppLaunched.event body:nil];
66
64
  }
67
65
 
68
66
  + (void)eventEmitterListensToAppLaunched:(ANNTurboEventEmitter *)eventEmitter {
@@ -71,7 +69,7 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
71
69
  return;
72
70
  }
73
71
  ANNAppLaunchedPending = NO;
74
- [eventEmitter sendIfListened:ANNAppLaunchedEvent body:nil];
72
+ [eventEmitter sendIfListened:ANNEventContract.AppLaunched.event body:nil];
75
73
  }
76
74
 
77
75
  // Only an `AppLaunched` of the module's own JavaScript or an older one: the module is made while its bundle runs,
@@ -87,11 +85,12 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
87
85
  - (void)sendCommandCompleted:(NSString *)commandName
88
86
  commandId:(NSString *)commandId
89
87
  completionTime:(double)completionTime {
90
- [self sendEvent:@"CommandCompleted"
88
+ const auto &keys = ANNEventContract.CommandCompleted;
89
+ [self sendEvent:keys.event
91
90
  body:@{
92
- @"commandName" : commandName,
93
- @"commandId" : commandId,
94
- @"completionTime" : @(completionTime),
91
+ keys.commandName : commandName,
92
+ keys.commandId : commandId,
93
+ keys.completionTime : @(completionTime),
95
94
  }];
96
95
  }
97
96
 
@@ -100,7 +99,7 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
100
99
  - (void)sendComponentWillAppear:(NSString *)componentId
101
100
  componentName:(NSString *)componentName
102
101
  componentType:(ANNReactComponentType)componentType {
103
- [self sendComponentEvent:@"ComponentWillAppear"
102
+ [self sendComponentEvent:ANNEventContract.ComponentWillAppear.event
104
103
  componentId:componentId
105
104
  componentName:componentName
106
105
  componentType:componentType];
@@ -109,7 +108,7 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
109
108
  - (void)sendComponentDidAppear:(NSString *)componentId
110
109
  componentName:(NSString *)componentName
111
110
  componentType:(ANNReactComponentType)componentType {
112
- [self sendComponentEvent:@"ComponentDidAppear"
111
+ [self sendComponentEvent:ANNEventContract.ComponentDidAppear.event
113
112
  componentId:componentId
114
113
  componentName:componentName
115
114
  componentType:componentType];
@@ -118,21 +117,23 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
118
117
  - (void)sendComponentDidDisappear:(NSString *)componentId
119
118
  componentName:(NSString *)componentName
120
119
  componentType:(ANNReactComponentType)componentType {
121
- [self sendComponentEvent:@"ComponentDidDisappear"
120
+ [self sendComponentEvent:ANNEventContract.ComponentDidDisappear.event
122
121
  componentId:componentId
123
122
  componentName:componentName
124
123
  componentType:componentType];
125
124
  }
126
125
 
126
+ // The three appearance events have the same keys.
127
127
  - (void)sendComponentEvent:(NSString *)name
128
128
  componentId:(NSString *)componentId
129
129
  componentName:(NSString *)componentName
130
130
  componentType:(ANNReactComponentType)componentType {
131
+ const auto &keys = ANNEventContract.ComponentDidAppear;
131
132
  [self sendEvent:name
132
133
  body:@{
133
- @"componentId" : componentId ?: @"",
134
- @"componentName" : componentName ?: @"",
135
- @"componentType" : ANNComponentTypeName(componentType),
134
+ keys.componentId : componentId ?: @"",
135
+ keys.componentName : componentName ?: @"",
136
+ keys.componentType : ANNComponentTypeName(componentType),
136
137
  }];
137
138
  }
138
139
 
@@ -143,58 +144,76 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
143
144
  - (void)sendOnNavigationButtonPressed:(NSString *)componentId
144
145
  buttonId:(NSString *)buttonId
145
146
  selected:(NSNumber *)selected {
147
+ const auto &keys = ANNEventContract.NavigationButtonPressed;
146
148
  NSMutableDictionary *body =
147
- [@{@"componentId" : componentId ?: @"", @"buttonId" : buttonId ?: @""} mutableCopy];
149
+ [@{keys.componentId : componentId ?: @"", keys.buttonId : buttonId ?: @""} mutableCopy];
148
150
  if (selected) {
149
- body[@"selected"] = @(selected.boolValue);
151
+ body[keys.selected] = @(selected.boolValue);
150
152
  }
151
- [self sendEvent:@"NavigationButtonPressed" body:body];
153
+ [self sendEvent:keys.event body:body];
152
154
  }
153
155
 
154
156
  - (void)sendScreenPopped:(NSString *)componentId {
155
- [self sendEvent:@"ScreenPopped" body:@{@"componentId" : componentId ?: @""}];
157
+ const auto &keys = ANNEventContract.ScreenPopped;
158
+ [self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
156
159
  }
157
160
 
158
161
  - (void)sendNavigationStateChanged:(NSString *)screenId name:(NSString *)name tab:(NSNumber *)tab {
159
- id screen = screenId ? @{@"id" : screenId, @"name" : name ?: @""} : (id)NSNull.null;
160
- [self sendEvent:@"NavigationStateChanged"
161
- body:@{@"screen" : screen, @"tab" : tab ?: (id)NSNull.null}];
162
+ const auto &keys = ANNEventContract.NavigationStateChanged;
163
+ const auto &screenKeys = ANNEventContract.NavigationStateChangedScreen;
164
+ id screen = screenId ? @{screenKeys.id : screenId, screenKeys.name : name ?: @""}
165
+ : (id)NSNull.null;
166
+ [self sendEvent:keys.event body:@{keys.screen : screen, keys.tab : tab ?: (id)NSNull.null}];
162
167
  }
163
168
 
164
169
  - (void)sendScreenInsetsChanged:(NSString *)componentId
165
170
  insets:(NSDictionary<NSString *, NSNumber *> *)insets {
171
+ const auto &keys = ANNEventContract.ScreenInsetsChanged;
166
172
  NSMutableDictionary *body = [insets mutableCopy] ?: [NSMutableDictionary new];
167
- body[@"componentId"] = componentId;
168
- [self sendEvent:@"ScreenInsetsChanged" body:body];
173
+ body[keys.componentId] = componentId;
174
+ [self sendEvent:keys.event body:body];
169
175
  }
170
176
 
171
177
  - (void)sendScreenRegionsChanged:(NSString *)componentId
172
178
  regions:(NSDictionary<NSString *, NSArray *> *)regions {
179
+ const auto &keys = ANNEventContract.ScreenRegionsChanged;
173
180
  NSMutableDictionary *body = [regions mutableCopy] ?: [NSMutableDictionary new];
174
- body[@"componentId"] = componentId;
175
- [self sendEvent:@"ScreenRegionsChanged" body:body];
181
+ body[keys.componentId] = componentId;
182
+ [self sendEvent:keys.event body:body];
176
183
  }
177
184
 
178
185
  - (void)sendSlotDestroyed:(NSString *)componentId {
179
- [self sendEvent:@"SlotDestroyed" body:@{@"componentId" : componentId ?: @""}];
186
+ const auto &keys = ANNEventContract.SlotDestroyed;
187
+ [self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
188
+ }
189
+
190
+ - (void)sendDeepLinkDispatched:(NSURL *)url {
191
+ const auto &keys = ANNEventContract.DeepLinkDispatched;
192
+ [self sendEvent:keys.event body:@{keys.url : url.absoluteString ?: @""}];
180
193
  }
181
194
 
182
195
  - (void)sendTitleRenamed:(NSString *)componentId text:(NSString *)text {
183
- [self sendEvent:@"TitleRenamed"
184
- body:@{@"componentId" : componentId ?: @"", @"text" : text ?: @""}];
196
+ const auto &keys = ANNEventContract.TitleRenamed;
197
+ [self sendEvent:keys.event
198
+ body:@{keys.componentId : componentId ?: @"", keys.text : text ?: @""}];
185
199
  }
186
200
 
187
201
  - (void)sendKeyCommandPressed:(NSString *)componentId keyCommandId:(NSString *)keyCommandId {
188
- [self sendEvent:@"KeyCommandPressed"
189
- body:@{@"componentId" : componentId ?: @"", @"keyCommandId" : keyCommandId ?: @""}];
202
+ const auto &keys = ANNEventContract.KeyCommandPressed;
203
+ [self sendEvent:keys.event
204
+ body:@{
205
+ keys.componentId : componentId ?: @"",
206
+ keys.keyCommandId : keyCommandId ?: @"",
207
+ }];
190
208
  }
191
209
 
192
210
  - (void)sendPreviewCompleted:(NSString *)componentId
193
211
  previewComponentId:(NSString *)previewComponentId {
194
- [self sendEvent:@"PreviewCompleted"
212
+ const auto &keys = ANNEventContract.PreviewCompleted;
213
+ [self sendEvent:keys.event
195
214
  body:@{
196
- @"componentId" : componentId ?: @"",
197
- @"previewComponentId" : previewComponentId ?: @"",
215
+ keys.componentId : componentId ?: @"",
216
+ keys.previewComponentId : previewComponentId ?: @"",
198
217
  }];
199
218
  }
200
219
 
@@ -203,21 +222,24 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
203
222
  - (void)sendModalDismissed:(NSString *)componentId
204
223
  componentName:(NSString *)componentName
205
224
  modalsDismissed:(NSUInteger)modalsDismissed {
206
- [self sendEvent:@"ModalDismissed"
225
+ const auto &keys = ANNEventContract.ModalDismissed;
226
+ [self sendEvent:keys.event
207
227
  body:@{
208
- @"componentId" : componentId ?: @"",
209
- @"componentName" : componentName ?: @"",
210
- @"modalsDismissed" : @(modalsDismissed),
228
+ keys.componentId : componentId ?: @"",
229
+ keys.componentName : componentName ?: @"",
230
+ keys.modalsDismissed : @(modalsDismissed),
211
231
  }];
212
232
  }
213
233
 
214
234
  - (void)sendModalAttemptedToDismiss:(NSString *)componentId {
215
- [self sendEvent:@"ModalAttemptedToDismiss" body:@{@"componentId" : componentId ?: @""}];
235
+ const auto &keys = ANNEventContract.ModalAttemptedToDismiss;
236
+ [self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
216
237
  }
217
238
 
218
239
  - (void)sendSheetDetentChanged:(NSString *)componentId detent:(id)detent {
219
- [self sendEvent:@"SheetDetentChanged"
220
- body:@{@"componentId" : componentId ?: @"", @"detent" : detent ?: @""}];
240
+ const auto &keys = ANNEventContract.SheetDetentChanged;
241
+ [self sendEvent:keys.event
242
+ body:@{keys.componentId : componentId ?: @"", keys.detent : detent ?: @""}];
221
243
  }
222
244
 
223
245
  #pragma mark - Search
@@ -227,82 +249,94 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
227
249
  isFocused:(BOOL)isFocused
228
250
  scope:(NSString *)scope
229
251
  tokens:(NSArray<NSString *> *)tokens {
252
+ const auto &keys = ANNEventContract.SearchBarUpdated;
230
253
  NSMutableDictionary *body = [@{
231
- @"componentId" : componentId ?: @"",
232
- @"text" : text ?: @"",
233
- @"isFocused" : @(isFocused),
254
+ keys.componentId : componentId ?: @"",
255
+ keys.text : text ?: @"",
256
+ keys.isFocused : @(isFocused),
234
257
  } mutableCopy];
235
- body[@"scope"] = scope;
236
- body[@"tokens"] = tokens;
237
- [self sendEvent:@"SearchBarUpdated" body:body];
258
+ body[keys.scope] = scope;
259
+ body[keys.tokens] = tokens;
260
+ [self sendEvent:keys.event body:body];
238
261
  }
239
262
 
240
263
  - (void)sendOnSearchBarSubmitted:(NSString *)componentId
241
264
  text:(NSString *)text
242
265
  scope:(NSString *)scope
243
266
  tokens:(NSArray<NSString *> *)tokens {
267
+ const auto &keys = ANNEventContract.SearchBarSubmitted;
244
268
  NSMutableDictionary *body =
245
- [@{@"componentId" : componentId ?: @"", @"text" : text ?: @""} mutableCopy];
246
- body[@"scope"] = scope;
247
- body[@"tokens"] = tokens;
248
- [self sendEvent:@"SearchBarSubmitted" body:body];
269
+ [@{keys.componentId : componentId ?: @"", keys.text : text ?: @""} mutableCopy];
270
+ body[keys.scope] = scope;
271
+ body[keys.tokens] = tokens;
272
+ [self sendEvent:keys.event body:body];
249
273
  }
250
274
 
251
275
  - (void)sendOnSearchBarCancelPressed:(NSString *)componentId {
252
- [self sendEvent:@"SearchBarCancelPressed" body:@{@"componentId" : componentId ?: @""}];
276
+ const auto &keys = ANNEventContract.SearchBarCancelPressed;
277
+ [self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
253
278
  }
254
279
 
255
280
  - (void)sendOnSearchSuggestionPicked:(NSString *)componentId suggestionId:(NSString *)suggestionId {
256
- [self sendEvent:@"SearchSuggestionPicked"
257
- body:@{@"componentId" : componentId ?: @"", @"suggestionId" : suggestionId ?: @""}];
281
+ const auto &keys = ANNEventContract.SearchSuggestionPicked;
282
+ [self sendEvent:keys.event
283
+ body:@{
284
+ keys.componentId : componentId ?: @"",
285
+ keys.suggestionId : suggestionId ?: @"",
286
+ }];
258
287
  }
259
288
 
260
289
  #pragma mark - Split view, pair, hinge
261
290
 
262
291
  - (void)sendSplitViewColumnsStacked:(NSString *)componentId stacked:(BOOL)stacked {
263
- [self sendEvent:@"SplitViewColumnsStacked"
264
- body:@{@"componentId" : componentId ?: @"", @"stacked" : @(stacked)}];
292
+ const auto &keys = ANNEventContract.SplitViewColumnsStacked;
293
+ [self sendEvent:keys.event
294
+ body:@{keys.componentId : componentId ?: @"", keys.stacked : @(stacked)}];
265
295
  }
266
296
 
267
297
  - (void)sendSplitViewDisplayModeChanged:(NSString *)componentId
268
298
  displayMode:(NSString *)displayMode
269
299
  inspectorVisible:(NSNumber *)inspectorVisible {
300
+ const auto &keys = ANNEventContract.SplitViewDisplayModeChanged;
270
301
  NSMutableDictionary *body = [@{
271
- @"componentId" : componentId ?: @"",
272
- @"displayMode" : displayMode ?: @"automatic",
302
+ keys.componentId : componentId ?: @"",
303
+ keys.displayMode : displayMode ?: @"automatic",
273
304
  } mutableCopy];
274
- body[@"inspectorVisible"] = inspectorVisible;
275
- [self sendEvent:@"SplitViewDisplayModeChanged" body:body];
305
+ body[keys.inspectorVisible] = inspectorVisible;
306
+ [self sendEvent:keys.event body:body];
276
307
  }
277
308
 
278
309
  - (void)sendArrangementChanged:(NSString *)componentId state:(NSDictionary<NSString *, id> *)state {
310
+ const auto &keys = ANNEventContract.ArrangementChanged;
279
311
  NSMutableDictionary *body = [state mutableCopy] ?: [NSMutableDictionary new];
280
- body[@"componentId"] = componentId;
281
- [self sendEvent:@"ArrangementChanged" body:body];
312
+ body[keys.componentId] = componentId;
313
+ [self sendEvent:keys.event body:body];
282
314
  }
283
315
 
284
316
  - (void)sendHingeChanged:(NSDictionary<NSString *, id> *)value {
285
- [self sendEvent:@"HingeChanged" body:value ?: @{}];
317
+ [self sendEvent:ANNEventContract.HingeChanged.event body:value ?: @{}];
286
318
  }
287
319
 
288
320
  #pragma mark - Native screens, tabs
289
321
 
290
322
  - (void)sendNativeScreenCall:(NSDictionary<NSString *, id> *)call {
291
- [self sendEvent:@"NativeScreenCall" body:call];
323
+ [self sendEvent:ANNEventContract.NativeScreenCall.event body:call];
292
324
  }
293
325
 
294
326
  - (void)sendNativeScreenReleased:(NSString *)componentId {
295
- [self sendEvent:@"NativeScreenReleased" body:@{@"componentId" : componentId ?: @""}];
327
+ const auto &keys = ANNEventContract.NativeScreenReleased;
328
+ [self sendEvent:keys.event body:@{keys.componentId : componentId ?: @""}];
296
329
  }
297
330
 
298
331
  - (void)sendBottomTabSelected:(NSUInteger)selectedTabIndex
299
332
  unselectedTabIndex:(NSUInteger)unselectedTabIndex
300
333
  bottomTabsId:(NSString *)bottomTabsId {
301
- [self sendEvent:@"BottomTabSelected"
334
+ const auto &keys = ANNEventContract.BottomTabSelected;
335
+ [self sendEvent:keys.event
302
336
  body:@{
303
- @"selectedTabIndex" : @(selectedTabIndex),
304
- @"unselectedTabIndex" : @(unselectedTabIndex),
305
- @"bottomTabsId" : bottomTabsId ?: @"",
337
+ keys.selectedTabIndex : @(selectedTabIndex),
338
+ keys.unselectedTabIndex : @(unselectedTabIndex),
339
+ keys.bottomTabsId : bottomTabsId ?: @"",
306
340
  }];
307
341
  }
308
342
 
@@ -310,28 +344,31 @@ static NSString *const ANNAppLaunchedEvent = @"ANN.AppLaunched";
310
344
  bottomTabsId:(NSString *)bottomTabsId
311
345
  screenId:(NSString *)screenId
312
346
  wasSelected:(BOOL)wasSelected {
347
+ const auto &keys = ANNEventContract.BottomTabPressed;
313
348
  NSMutableDictionary *body = [@{
314
- @"tabIndex" : @(tabIndex),
315
- @"bottomTabsId" : bottomTabsId ?: @"",
316
- @"wasSelected" : @(wasSelected),
349
+ keys.tabIndex : @(tabIndex),
350
+ keys.bottomTabsId : bottomTabsId ?: @"",
351
+ keys.wasSelected : @(wasSelected),
317
352
  } mutableCopy];
318
- body[@"screenId"] = screenId;
319
- [self sendEvent:@"BottomTabPressed" body:body];
353
+ body[keys.screenId] = screenId;
354
+ [self sendEvent:keys.event body:body];
320
355
  }
321
356
 
322
357
  - (void)sendBottomTabLongPressed:(NSUInteger)selectedTabIndex
323
358
  bottomTabsId:(NSString *)bottomTabsId {
324
- [self sendEvent:@"BottomTabLongPressed"
359
+ const auto &keys = ANNEventContract.BottomTabLongPressed;
360
+ [self sendEvent:keys.event
325
361
  body:@{
326
- @"selectedTabIndex" : @(selectedTabIndex),
327
- @"bottomTabsId" : bottomTabsId ?: @"",
362
+ keys.selectedTabIndex : @(selectedTabIndex),
363
+ keys.bottomTabsId : bottomTabsId ?: @"",
328
364
  }];
329
365
  }
330
366
 
331
367
  - (void)sendBottomAccessoryPlacementChanged:(NSString *)componentId
332
368
  placement:(NSString *)placement {
333
- [self sendEvent:@"BottomAccessoryPlacementChanged"
334
- body:@{@"componentId" : componentId ?: @"", @"placement" : placement ?: @""}];
369
+ const auto &keys = ANNEventContract.BottomAccessoryPlacementChanged;
370
+ [self sendEvent:keys.event
371
+ body:@{keys.componentId : componentId ?: @"", keys.placement : placement ?: @""}];
335
372
  }
336
373
 
337
374
  @end