@symbiote-native/navigation 2.0.3 → 2.2.0

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 (320) hide show
  1. package/README.md +42 -12
  2. package/build/angular/drawer/index.js +29 -13
  3. package/build/angular/index.d.ts +4 -4
  4. package/build/angular/injectors/inject-navigation.js +1 -1
  5. package/build/angular/navigation-scope.directive.js +1 -1
  6. package/build/angular/search-bar-ref.directive.js +1 -1
  7. package/build/angular/stack/index.d.ts +2 -0
  8. package/build/angular/stack/index.js +43 -9
  9. package/build/angular/tabs/index.d.ts +1 -1
  10. package/build/angular/tabs/index.js +40 -13
  11. package/build/core/drawer-options/index.js +19 -5
  12. package/build/core/drawer-router-state/index.js +8 -2
  13. package/build/core/guards.js +3 -1
  14. package/build/core/header-bar-buttons.js +14 -4
  15. package/build/core/index.d.ts +6 -5
  16. package/build/core/index.js +7 -3
  17. package/build/core/navigator-state/index.js +12 -4
  18. package/build/core/render-drawer.js +4 -1
  19. package/build/core/render-stack.js +13 -4
  20. package/build/core/screen-options.js +1 -1
  21. package/build/core/search-bar-commands.js +1 -1
  22. package/build/core/stack-router-state/index.d.ts +2 -0
  23. package/build/core/stack-router-state/index.js +44 -0
  24. package/build/core/state-persistence/index.js +6 -2
  25. package/build/core/tab-router-state/index.d.ts +1 -0
  26. package/build/core/tab-router-state/index.js +27 -2
  27. package/build/react/drawer/index.js +59 -26
  28. package/build/react/index.d.ts +7 -7
  29. package/build/react/index.js +2 -2
  30. package/build/react/stack/index.js +47 -10
  31. package/build/react/tabs/index.js +36 -12
  32. package/build/solid/drawer/index.d.ts +22 -0
  33. package/build/solid/drawer/index.js +394 -0
  34. package/build/solid/drawer-screen-props.d.ts +13 -0
  35. package/build/solid/drawer-screen-props.js +2 -0
  36. package/build/solid/host.d.ts +2 -0
  37. package/build/solid/host.js +23 -0
  38. package/build/solid/index.d.ts +19 -0
  39. package/build/solid/index.js +24 -0
  40. package/build/solid/linking.d.ts +3 -0
  41. package/build/solid/linking.js +55 -0
  42. package/build/solid/navigation-context.d.ts +13 -0
  43. package/build/solid/navigation-context.js +37 -0
  44. package/build/solid/primitives/create-focus-effect.d.ts +1 -0
  45. package/build/solid/primitives/create-focus-effect.js +30 -0
  46. package/build/solid/primitives/create-is-focused.d.ts +2 -0
  47. package/build/solid/primitives/create-is-focused.js +31 -0
  48. package/build/solid/primitives/create-navigation-state.d.ts +3 -0
  49. package/build/solid/primitives/create-navigation-state.js +30 -0
  50. package/build/solid/primitives/index.d.ts +12 -0
  51. package/build/solid/primitives/index.js +8 -0
  52. package/build/solid/primitives/use-drawer-navigation.d.ts +5 -0
  53. package/build/solid/primitives/use-drawer-navigation.js +15 -0
  54. package/build/solid/primitives/use-navigation.d.ts +8 -0
  55. package/build/solid/primitives/use-navigation.js +23 -0
  56. package/build/solid/primitives/use-route.d.ts +3 -0
  57. package/build/solid/primitives/use-route.js +14 -0
  58. package/build/solid/primitives/use-stack-navigation.d.ts +5 -0
  59. package/build/solid/primitives/use-stack-navigation.js +19 -0
  60. package/build/solid/primitives/use-tab-navigation.d.ts +5 -0
  61. package/build/solid/primitives/use-tab-navigation.js +15 -0
  62. package/build/solid/screen-props.d.ts +19 -0
  63. package/build/solid/screen-props.js +9 -0
  64. package/build/solid/screen-registry.d.ts +31 -0
  65. package/build/solid/screen-registry.js +86 -0
  66. package/build/solid/screen.d.ts +6 -0
  67. package/build/solid/screen.js +69 -0
  68. package/build/solid/stack/index.d.ts +15 -0
  69. package/build/solid/stack/index.js +348 -0
  70. package/build/solid/tab-screen-props.d.ts +13 -0
  71. package/build/solid/tab-screen-props.js +3 -0
  72. package/build/solid/tabs/index.d.ts +14 -0
  73. package/build/solid/tabs/index.js +228 -0
  74. package/build/svelte/attachments.d.ts +5 -0
  75. package/build/svelte/attachments.js +61 -0
  76. package/build/svelte/descriptor-subtree.d.ts +3 -0
  77. package/build/svelte/descriptor-subtree.js +39 -0
  78. package/build/svelte/drawer/drawer-props.d.ts +14 -0
  79. package/build/svelte/drawer/drawer-props.js +3 -0
  80. package/build/svelte/drawer/index.d.ts +10 -0
  81. package/build/svelte/drawer/index.js +6 -0
  82. package/build/svelte/drawer/index.svelte +559 -0
  83. package/build/svelte/drawer/index.svelte.d.ts +10 -0
  84. package/build/svelte/drawer-screen-props.d.ts +13 -0
  85. package/build/svelte/drawer-screen-props.js +4 -0
  86. package/build/svelte/drawer-screen.svelte +25 -0
  87. package/build/svelte/drawer-screen.svelte.d.ts +4 -0
  88. package/build/svelte/index.d.ts +21 -0
  89. package/build/svelte/index.js +20 -0
  90. package/build/svelte/linking.svelte.d.ts +2 -0
  91. package/build/svelte/linking.svelte.js +55 -0
  92. package/build/svelte/navigation-context.d.ts +14 -0
  93. package/build/svelte/navigation-context.js +44 -0
  94. package/build/svelte/navigation-scope.svelte +27 -0
  95. package/build/svelte/navigation-scope.svelte.d.ts +9 -0
  96. package/build/svelte/registry-host.d.ts +1 -0
  97. package/build/svelte/registry-host.js +26 -0
  98. package/build/svelte/runes/index.d.ts +12 -0
  99. package/build/svelte/runes/index.js +12 -0
  100. package/build/svelte/runes/use-drawer-navigation.svelte.d.ts +6 -0
  101. package/build/svelte/runes/use-drawer-navigation.svelte.js +19 -0
  102. package/build/svelte/runes/use-focus-effect.svelte.d.ts +1 -0
  103. package/build/svelte/runes/use-focus-effect.svelte.js +31 -0
  104. package/build/svelte/runes/use-is-focused.svelte.d.ts +3 -0
  105. package/build/svelte/runes/use-is-focused.svelte.js +34 -0
  106. package/build/svelte/runes/use-navigation-state.svelte.d.ts +4 -0
  107. package/build/svelte/runes/use-navigation-state.svelte.js +39 -0
  108. package/build/svelte/runes/use-navigation.svelte.d.ts +9 -0
  109. package/build/svelte/runes/use-navigation.svelte.js +26 -0
  110. package/build/svelte/runes/use-route.svelte.d.ts +4 -0
  111. package/build/svelte/runes/use-route.svelte.js +12 -0
  112. package/build/svelte/runes/use-stack-navigation.svelte.d.ts +6 -0
  113. package/build/svelte/runes/use-stack-navigation.svelte.js +22 -0
  114. package/build/svelte/runes/use-tab-navigation.svelte.d.ts +6 -0
  115. package/build/svelte/runes/use-tab-navigation.svelte.js +19 -0
  116. package/build/svelte/screen-props.d.ts +21 -0
  117. package/build/svelte/screen-props.js +6 -0
  118. package/build/svelte/screen-registry.d.ts +17 -0
  119. package/build/svelte/screen-registry.js +57 -0
  120. package/build/svelte/screen.svelte +28 -0
  121. package/build/svelte/screen.svelte.d.ts +4 -0
  122. package/build/svelte/stack/index.d.ts +14 -0
  123. package/build/svelte/stack/index.js +7 -0
  124. package/build/svelte/stack/index.svelte +261 -0
  125. package/build/svelte/stack/index.svelte.d.ts +15 -0
  126. package/build/svelte/stack/stack-props.d.ts +20 -0
  127. package/build/svelte/stack/stack-props.js +4 -0
  128. package/build/svelte/stack/stack-screen.svelte +205 -0
  129. package/build/svelte/stack/stack-screen.svelte.d.ts +4 -0
  130. package/build/svelte/tab-screen-props.d.ts +13 -0
  131. package/build/svelte/tab-screen-props.js +4 -0
  132. package/build/svelte/tab-screen.svelte +26 -0
  133. package/build/svelte/tab-screen.svelte.d.ts +4 -0
  134. package/build/svelte/tabs/index.d.ts +8 -0
  135. package/build/svelte/tabs/index.js +6 -0
  136. package/build/svelte/tabs/index.svelte +269 -0
  137. package/build/svelte/tabs/index.svelte.d.ts +8 -0
  138. package/build/svelte/tabs/tab-props.d.ts +7 -0
  139. package/build/svelte/tabs/tab-props.js +3 -0
  140. package/build/vue/composables/use-navigation.js +5 -1
  141. package/build/vue/drawer/index.js +36 -13
  142. package/build/vue/index.d.ts +3 -3
  143. package/build/vue/navigation-context.js +1 -1
  144. package/build/vue/stack/index.js +43 -18
  145. package/build/vue/tabs/index.js +65 -39
  146. package/build-ngc/angular/drawer/index.js +40 -18
  147. package/build-ngc/angular/drawer/index.js.map +1 -1
  148. package/build-ngc/angular/drawer-screen.directive.js +3 -3
  149. package/build-ngc/angular/index.d.ts +4 -4
  150. package/build-ngc/angular/index.js.map +1 -1
  151. package/build-ngc/angular/injectors/inject-focus-effect.js.map +1 -1
  152. package/build-ngc/angular/injectors/inject-is-focused.js.map +1 -1
  153. package/build-ngc/angular/injectors/inject-navigation-state.js.map +1 -1
  154. package/build-ngc/angular/injectors/inject-navigation.js +1 -1
  155. package/build-ngc/angular/injectors/inject-navigation.js.map +1 -1
  156. package/build-ngc/angular/linking.js.map +1 -1
  157. package/build-ngc/angular/navigation-context.service.js +3 -3
  158. package/build-ngc/angular/navigation-context.service.js.map +1 -1
  159. package/build-ngc/angular/navigation-scope.directive.js +4 -4
  160. package/build-ngc/angular/navigation-scope.directive.js.map +1 -1
  161. package/build-ngc/angular/screen.directive.js +3 -3
  162. package/build-ngc/angular/screen.directive.js.map +1 -1
  163. package/build-ngc/angular/search-bar-ref.directive.js +4 -4
  164. package/build-ngc/angular/search-bar-ref.directive.js.map +1 -1
  165. package/build-ngc/angular/stack/index.d.ts +2 -0
  166. package/build-ngc/angular/stack/index.js +52 -14
  167. package/build-ngc/angular/stack/index.js.map +1 -1
  168. package/build-ngc/angular/tab-screen.directive.js +3 -3
  169. package/build-ngc/angular/tab-screen.directive.js.map +1 -1
  170. package/build-ngc/angular/tabs/index.d.ts +1 -1
  171. package/build-ngc/angular/tabs/index.js +43 -16
  172. package/build-ngc/angular/tabs/index.js.map +1 -1
  173. package/build-ngc/core/constants.js.map +1 -1
  174. package/build-ngc/core/drawer-options/index.js +19 -5
  175. package/build-ngc/core/drawer-options/index.js.map +1 -1
  176. package/build-ngc/core/drawer-router-state/index.js +8 -2
  177. package/build-ngc/core/drawer-router-state/index.js.map +1 -1
  178. package/build-ngc/core/guards.js +3 -1
  179. package/build-ngc/core/guards.js.map +1 -1
  180. package/build-ngc/core/header-bar-buttons.js +14 -4
  181. package/build-ngc/core/header-bar-buttons.js.map +1 -1
  182. package/build-ngc/core/index.d.ts +6 -5
  183. package/build-ngc/core/index.js +7 -3
  184. package/build-ngc/core/index.js.map +1 -1
  185. package/build-ngc/core/linking-config/index.js.map +1 -1
  186. package/build-ngc/core/navigation-events/index.js.map +1 -1
  187. package/build-ngc/core/navigator-handles/index.js.map +1 -1
  188. package/build-ngc/core/navigator-state/index.js +12 -4
  189. package/build-ngc/core/navigator-state/index.js.map +1 -1
  190. package/build-ngc/core/render-drawer.js +4 -1
  191. package/build-ngc/core/render-drawer.js.map +1 -1
  192. package/build-ngc/core/render-stack.js +13 -4
  193. package/build-ngc/core/render-stack.js.map +1 -1
  194. package/build-ngc/core/render-tabs.js.map +1 -1
  195. package/build-ngc/core/screen-options.js +1 -1
  196. package/build-ngc/core/screen-options.js.map +1 -1
  197. package/build-ngc/core/search-bar-commands.js +1 -1
  198. package/build-ngc/core/search-bar-commands.js.map +1 -1
  199. package/build-ngc/core/stack-router-state/index.d.ts +2 -0
  200. package/build-ngc/core/stack-router-state/index.js +45 -0
  201. package/build-ngc/core/stack-router-state/index.js.map +1 -0
  202. package/build-ngc/core/state-persistence/index.js +6 -2
  203. package/build-ngc/core/state-persistence/index.js.map +1 -1
  204. package/build-ngc/core/tab-router-state/index.d.ts +1 -0
  205. package/build-ngc/core/tab-router-state/index.js +27 -2
  206. package/build-ngc/core/tab-router-state/index.js.map +1 -1
  207. package/package.json +44 -16
  208. package/src/angular/drawer/index.ts +75 -29
  209. package/src/angular/index.ts +20 -4
  210. package/src/angular/injectors/inject-focus-effect.ts +8 -2
  211. package/src/angular/injectors/inject-is-focused.ts +6 -4
  212. package/src/angular/injectors/inject-navigation-state.ts +7 -4
  213. package/src/angular/injectors/inject-navigation.ts +12 -3
  214. package/src/angular/linking.ts +4 -1
  215. package/src/angular/navigation-context.service.ts +5 -2
  216. package/src/angular/navigation-scope.directive.ts +6 -2
  217. package/src/angular/screen.directive.ts +13 -3
  218. package/src/angular/search-bar-ref.directive.ts +10 -2
  219. package/src/angular/stack/index.ts +91 -24
  220. package/src/angular/tab-screen.directive.ts +3 -1
  221. package/src/angular/tabs/index.ts +54 -16
  222. package/src/core/constants.ts +6 -3
  223. package/src/core/drawer-options/index.ts +40 -13
  224. package/src/core/drawer-router-state/index.ts +11 -3
  225. package/src/core/guards.ts +3 -1
  226. package/src/core/header-bar-buttons.ts +41 -12
  227. package/src/core/index.ts +29 -5
  228. package/src/core/linking-config/index.ts +31 -10
  229. package/src/core/navigation-events/index.ts +8 -2
  230. package/src/core/navigator-handles/index.ts +8 -3
  231. package/src/core/navigator-props.ts +13 -4
  232. package/src/core/navigator-state/index.ts +24 -7
  233. package/src/core/render-drawer.ts +24 -9
  234. package/src/core/render-stack.ts +52 -13
  235. package/src/core/render-tabs.ts +24 -6
  236. package/src/core/screen-options.ts +15 -5
  237. package/src/core/search-bar-commands.ts +12 -3
  238. package/src/core/stack-router-state/index.ts +52 -0
  239. package/src/core/state-persistence/index.ts +13 -3
  240. package/src/core/tab-router-state/index.ts +35 -3
  241. package/src/react/drawer/index.ts +409 -330
  242. package/src/react/drawer-screen.ts +8 -2
  243. package/src/react/hooks/use-focus-effect.ts +8 -2
  244. package/src/react/hooks/use-is-focused.ts +6 -2
  245. package/src/react/hooks/use-navigation.ts +8 -2
  246. package/src/react/index.ts +37 -7
  247. package/src/react/linking.ts +4 -1
  248. package/src/react/navigation-context.ts +6 -2
  249. package/src/react/screen.ts +12 -3
  250. package/src/react/stack/index.ts +297 -220
  251. package/src/react/tab-screen.ts +3 -1
  252. package/src/react/tabs/index.ts +202 -139
  253. package/src/solid/drawer/index.ts +570 -0
  254. package/src/solid/drawer-screen-props.ts +24 -0
  255. package/src/solid/host.ts +29 -0
  256. package/src/solid/index.ts +87 -0
  257. package/src/solid/linking.ts +74 -0
  258. package/src/solid/navigation-context.ts +56 -0
  259. package/src/solid/primitives/create-focus-effect.ts +41 -0
  260. package/src/solid/primitives/create-is-focused.ts +41 -0
  261. package/src/solid/primitives/create-navigation-state.ts +44 -0
  262. package/src/solid/primitives/index.ts +12 -0
  263. package/src/solid/primitives/use-drawer-navigation.ts +25 -0
  264. package/src/solid/primitives/use-navigation.ts +44 -0
  265. package/src/solid/primitives/use-route.ts +18 -0
  266. package/src/solid/primitives/use-stack-navigation.ts +29 -0
  267. package/src/solid/primitives/use-tab-navigation.ts +25 -0
  268. package/src/solid/screen-props.ts +51 -0
  269. package/src/solid/screen-registry.ts +159 -0
  270. package/src/solid/screen.ts +80 -0
  271. package/src/solid/stack/index.ts +528 -0
  272. package/src/solid/tab-screen-props.ts +21 -0
  273. package/src/solid/tabs/index.ts +327 -0
  274. package/src/svelte/attachments.ts +70 -0
  275. package/src/svelte/descriptor-subtree.ts +51 -0
  276. package/src/svelte/drawer/drawer-props.ts +28 -0
  277. package/src/svelte/drawer/index.svelte +559 -0
  278. package/src/svelte/drawer/index.ts +10 -0
  279. package/src/svelte/drawer-screen-props.ts +26 -0
  280. package/src/svelte/drawer-screen.svelte +25 -0
  281. package/src/svelte/fabric-tree.test-helper.ts +95 -0
  282. package/src/svelte/index.ts +83 -0
  283. package/src/svelte/linking.svelte.ts +72 -0
  284. package/src/svelte/navigation-context.ts +62 -0
  285. package/src/svelte/navigation-scope.svelte +27 -0
  286. package/src/svelte/registry-host.ts +26 -0
  287. package/src/svelte/runes/index.ts +17 -0
  288. package/src/svelte/runes/use-drawer-navigation.svelte.ts +31 -0
  289. package/src/svelte/runes/use-focus-effect.svelte.ts +41 -0
  290. package/src/svelte/runes/use-is-focused.svelte.ts +38 -0
  291. package/src/svelte/runes/use-navigation-state.svelte.ts +48 -0
  292. package/src/svelte/runes/use-navigation.svelte.ts +49 -0
  293. package/src/svelte/runes/use-route.svelte.ts +16 -0
  294. package/src/svelte/runes/use-stack-navigation.svelte.ts +34 -0
  295. package/src/svelte/runes/use-tab-navigation.svelte.ts +29 -0
  296. package/src/svelte/screen-props.ts +50 -0
  297. package/src/svelte/screen-registry.ts +98 -0
  298. package/src/svelte/screen.svelte +28 -0
  299. package/src/svelte/stack/index.svelte +261 -0
  300. package/src/svelte/stack/index.ts +11 -0
  301. package/src/svelte/stack/stack-props.ts +31 -0
  302. package/src/svelte/stack/stack-screen.svelte +205 -0
  303. package/src/svelte/svelte-ambient.d.ts +6 -0
  304. package/src/svelte/svelte-compile.test-helper.ts +147 -0
  305. package/src/svelte/tab-screen-props.ts +22 -0
  306. package/src/svelte/tab-screen.svelte +26 -0
  307. package/src/svelte/tabs/index.svelte +269 -0
  308. package/src/svelte/tabs/index.ts +10 -0
  309. package/src/svelte/tabs/tab-props.ts +13 -0
  310. package/src/vue/composables/use-navigation-state.ts +7 -4
  311. package/src/vue/composables/use-navigation.ts +13 -3
  312. package/src/vue/drawer/index.ts +128 -41
  313. package/src/vue/drawer-screen.ts +12 -5
  314. package/src/vue/index.ts +15 -3
  315. package/src/vue/linking.ts +7 -2
  316. package/src/vue/navigation-context.ts +17 -5
  317. package/src/vue/screen.ts +7 -2
  318. package/src/vue/stack/index.ts +108 -43
  319. package/src/vue/tab-screen.ts +3 -1
  320. package/src/vue/tabs/index.ts +109 -68
@@ -35,7 +35,7 @@
35
35
  // self-registers instead: `adapters/angular/babel-register-composed.cjs` (a Metro babel preset
36
36
  // applied bundle-wide, not scoped to adapters/angular) scans this package's own AOT-compiled
37
37
  // (`ngc`) `ɵɵngDeclareComponent({selector: 'Stack', ...})` output and auto-calls
38
- // `registerComposedComponent('Stack')` at bundle time - same mechanism `.examples/angular`
38
+ // `registerComposedComponent('Stack')` at bundle time - same mechanism `examples/angular`
39
39
  // navigation-demo screens and `@symbiote-native/slider`'s `Slider` rely on for their own composed
40
40
  // components mounted statically or via `NgComponentOutlet`. Unregistered, `createElement('Stack')`
41
41
  // falls through to a real `createNode` call and RN paints its own "Unimplemented component"
@@ -73,6 +73,7 @@ import {
73
73
  createInitialNavigatorState,
74
74
  createNavigationEmitter,
75
75
  navigatorReducer,
76
+ reconcileStackRoutes,
76
77
  resolveHeaderInModalStackStyle,
77
78
  resolveScreenRenderPlan,
78
79
  resolveStackProps,
@@ -90,13 +91,18 @@ import type {
90
91
  import { NavigationScopeDirective } from '../navigation-scope.directive';
91
92
  import { SearchBarRefDirective } from '../search-bar-ref.directive';
92
93
  import { ScreenDirective } from '../screen.directive';
93
- import type { IAngularScreenOptions, IScreenOptionsArgs } from '../screen.directive';
94
+ import type {
95
+ IAngularScreenOptions,
96
+ IScreenOptionsArgs,
97
+ } from '../screen.directive';
94
98
 
95
99
  export type { INavigatorHandle } from '../../core';
96
100
 
97
101
  // backTitleVisible defaults to `true` on both platforms per the codegen spec's own default - no
98
102
  // ios/android divergence in v1 scope (mirrors react/stack.ts's own constant exactly).
99
- const NAVIGATOR_PLATFORM: INavigatorPlatform = { defaultHeaderBackTitleVisible: true };
103
+ const NAVIGATOR_PLATFORM: INavigatorPlatform = {
104
+ defaultHeaderBackTitleVisible: true,
105
+ };
100
106
 
101
107
  let stackInstanceCounter = 0;
102
108
 
@@ -161,7 +167,9 @@ let stackInstanceCounter = 0;
161
167
  </ng-template>
162
168
 
163
169
  <ng-template #headerAndContentTpl let-route let-index="index">
164
- <RNSScreenStackHeaderConfig [symbioteHostProps]="headerConfigProps(route, index)">
170
+ <RNSScreenStackHeaderConfig
171
+ [symbioteHostProps]="headerConfigProps(route, index)"
172
+ >
165
173
  @if (hasSearchBar(route)) {
166
174
  <RNSScreenStackHeaderSubview [symbioteHostProps]="headerSubviewProps">
167
175
  <RNSSearchBar
@@ -171,7 +179,9 @@ let stackInstanceCounter = 0;
171
179
  </RNSScreenStackHeaderSubview>
172
180
  }
173
181
  </RNSScreenStackHeaderConfig>
174
- <RNSScreenContentWrapper [symbioteHostProps]="contentWrapperProps(route, index)">
182
+ <RNSScreenContentWrapper
183
+ [symbioteHostProps]="contentWrapperProps(route, index)"
184
+ >
175
185
  <ng-container
176
186
  [symbioteNavigationScope]="route"
177
187
  [navigation]="this"
@@ -184,7 +194,8 @@ let stackInstanceCounter = 0;
184
194
  `,
185
195
  })
186
196
  export class Stack implements AfterContentInit, OnDestroy, INavigatorHandle {
187
- @ContentChildren(ScreenDirective) private readonly screenChildren!: QueryList<ScreenDirective>;
197
+ @ContentChildren(ScreenDirective)
198
+ private readonly screenChildren!: QueryList<ScreenDirective>;
188
199
 
189
200
  @Input() initialRouteName?: string;
190
201
  @Input() screenOptions?: IAngularScreenOptions;
@@ -214,7 +225,8 @@ export class Stack implements AfterContentInit, OnDestroy, INavigatorHandle {
214
225
 
215
226
  readonly push = (name: string, params?: unknown): void =>
216
227
  this.dispatch({ type: 'push', route: this.createRoute(name, params) });
217
- readonly pop = (count?: number): void => this.dispatch({ type: 'pop', count });
228
+ readonly pop = (count?: number): void =>
229
+ this.dispatch({ type: 'pop', count });
218
230
  readonly popToTop = (): void => this.dispatch({ type: 'popToTop' });
219
231
  readonly popTo = (key: string): void => this.dispatch({ type: 'popTo', key });
220
232
  readonly replace = (name: string, params?: unknown): void =>
@@ -223,14 +235,17 @@ export class Stack implements AfterContentInit, OnDestroy, INavigatorHandle {
223
235
  this.dispatch({ type: 'setParams', key, params });
224
236
  readonly reset = (nextState: INavigatorState): void =>
225
237
  this.dispatch({ type: 'reset', state: nextState });
226
- readonly canGoBack = (): boolean => (this.stateSignal()?.routes.length ?? 0) > 1;
238
+ readonly canGoBack = (): boolean =>
239
+ (this.stateSignal()?.routes.length ?? 0) > 1;
227
240
 
228
241
  ngAfterContentInit(): void {
229
242
  this.rebuildRegistry();
230
243
  this.initializeState();
231
- this.screenChildrenSubscription = this.screenChildren.changes.subscribe(() => {
232
- this.rebuildRegistry();
233
- });
244
+ this.screenChildrenSubscription = this.screenChildren.changes.subscribe(
245
+ () => {
246
+ this.rebuildRegistry();
247
+ },
248
+ );
234
249
  }
235
250
 
236
251
  ngOnDestroy(): void {
@@ -242,34 +257,66 @@ export class Stack implements AfterContentInit, OnDestroy, INavigatorHandle {
242
257
  for (const screen of this.screenChildren) {
243
258
  this.registry.set(screen.name, screen);
244
259
  }
260
+ this.reconcileWithRegistry();
261
+ }
262
+
263
+ // A `<ng-template symbioteScreen>` marker can leave the @ContentChildren query (a marker behind
264
+ // an `@if`, a data-driven screen list) while its route is still in the pushed history, which
265
+ // would leave that entry with nothing for componentFor() to mount (reconcileStackRoutes' header).
266
+ // The signal write lives HERE, in the query-change callback, and never in a computed/template
267
+ // accessor - reconciliation is a reaction to the registry changing, not a derivation of it.
268
+ private reconcileWithRegistry(): void {
269
+ const current = this.stateSignal();
270
+ if (current === undefined) return;
271
+ const next = reconcileStackRoutes(current, [...this.registry.keys()]);
272
+ if (next === current) return;
273
+ this.commitState(next);
245
274
  }
246
275
 
247
276
  private initializeState(): void {
248
277
  if (this.stateSignal() !== undefined) return;
249
- const initialRouteName = this.initialRouteName ?? this.registry.keys().next().value;
278
+ const initialRouteName =
279
+ this.initialRouteName ?? this.registry.keys().next().value;
250
280
  if (initialRouteName === undefined) {
251
281
  dlog('Stack: no <ng-template symbioteScreen> children registered');
252
282
  this.stateSignal.set(
253
- createInitialNavigatorState({ key: this.routeIdPrefix, name: '', params: undefined }),
283
+ createInitialNavigatorState({
284
+ key: this.routeIdPrefix,
285
+ name: '',
286
+ params: undefined,
287
+ }),
254
288
  );
255
289
  return;
256
290
  }
257
291
  this.stateSignal.set(
258
292
  createInitialNavigatorState(
259
- this.createRoute(initialRouteName, this.registry.get(initialRouteName)?.initialParams),
293
+ this.createRoute(
294
+ initialRouteName,
295
+ this.registry.get(initialRouteName)?.initialParams,
296
+ ),
260
297
  ),
261
298
  );
262
299
  }
263
300
 
264
301
  private createRoute(name: string, params: unknown): IRoute<unknown> {
265
302
  this.routeSequence += 1;
266
- return { key: `${this.routeIdPrefix}-${name}-${this.routeSequence}`, name, params };
303
+ return {
304
+ key: `${this.routeIdPrefix}-${name}-${this.routeSequence}`,
305
+ name,
306
+ params,
307
+ };
267
308
  }
268
309
 
269
310
  private dispatch(action: INavigatorAction): void {
270
311
  const current = this.stateSignal();
271
312
  if (current === undefined) return;
272
- const next = navigatorReducer(current, action);
313
+ this.commitState(navigatorReducer(current, action));
314
+ }
315
+
316
+ // The one write path into stateSignal, shared by a dispatched action and a registry-driven
317
+ // reconciliation: both invalidate the plan cache, broadcast to every still-live route, and prune
318
+ // the emitters of routes that are gone.
319
+ private commitState(next: INavigatorState): void {
273
320
  this.planCache.clear();
274
321
  this.stateSignal.set(next);
275
322
  const liveRouteKeys = new Set(next.routes.map(route => route.key));
@@ -340,7 +387,8 @@ export class Stack implements AfterContentInit, OnDestroy, INavigatorHandle {
340
387
  isAndroid: Platform.OS === 'android',
341
388
  screenPassthrough: {
342
389
  [SCREEN_ON_DISMISSED]: () => this.dispatch({ type: 'pop', count: 1 }),
343
- [SCREEN_ON_HEADER_BACK_BUTTON_CLICKED]: () => this.dispatch({ type: 'pop', count: 1 }),
390
+ [SCREEN_ON_HEADER_BACK_BUTTON_CLICKED]: () =>
391
+ this.dispatch({ type: 'pop', count: 1 }),
344
392
  [SCREEN_ON_APPEAR]: () => {
345
393
  dlog(`Stack: route "${route.name}" appeared (focus)`);
346
394
  this.emitterFor(route.key).emit(NAVIGATION_EVENT_FOCUS);
@@ -359,14 +407,19 @@ export class Stack implements AfterContentInit, OnDestroy, INavigatorHandle {
359
407
  }
360
408
 
361
409
  outerScreenIsModal(route: IRoute<unknown>, index: number): boolean {
362
- return this.planFor(route, index).screenViewName === RNS_MODAL_SCREEN_VIEW_NAME;
410
+ return (
411
+ this.planFor(route, index).screenViewName === RNS_MODAL_SCREEN_VIEW_NAME
412
+ );
363
413
  }
364
414
 
365
415
  isInModal(route: IRoute<unknown>, index: number): boolean {
366
416
  return this.planFor(route, index).inModal;
367
417
  }
368
418
 
369
- screenHostProps(route: IRoute<unknown>, index: number): Record<string, unknown> {
419
+ screenHostProps(
420
+ route: IRoute<unknown>,
421
+ index: number,
422
+ ): Record<string, unknown> {
370
423
  return this.planFor(route, index).screenProps;
371
424
  }
372
425
 
@@ -374,16 +427,25 @@ export class Stack implements AfterContentInit, OnDestroy, INavigatorHandle {
374
427
  return { style: resolveHeaderInModalStackStyle() };
375
428
  }
376
429
 
377
- innerScreenProps(route: IRoute<unknown>, index: number): Record<string, unknown> {
430
+ innerScreenProps(
431
+ route: IRoute<unknown>,
432
+ index: number,
433
+ ): Record<string, unknown> {
378
434
  const plan = this.planFor(route, index);
379
435
  return { style: plan.innerScreenStyle, activityState: plan.activityState };
380
436
  }
381
437
 
382
- contentWrapperProps(route: IRoute<unknown>, index: number): Record<string, unknown> {
438
+ contentWrapperProps(
439
+ route: IRoute<unknown>,
440
+ index: number,
441
+ ): Record<string, unknown> {
383
442
  return this.planFor(route, index).contentWrapperProps;
384
443
  }
385
444
 
386
- headerConfigProps(route: IRoute<unknown>, index: number): Record<string, unknown> {
445
+ headerConfigProps(
446
+ route: IRoute<unknown>,
447
+ index: number,
448
+ ): Record<string, unknown> {
387
449
  return this.planFor(route, index).headerConfig.props;
388
450
  }
389
451
 
@@ -391,11 +453,16 @@ export class Stack implements AfterContentInit, OnDestroy, INavigatorHandle {
391
453
  return this.mergedOptionsFor(route).headerSearchBarOptions !== undefined;
392
454
  }
393
455
 
394
- searchBarRef(route: IRoute<unknown>): { current: ISearchBarCommands | null } | undefined {
456
+ searchBarRef(
457
+ route: IRoute<unknown>,
458
+ ): { current: ISearchBarCommands | null } | undefined {
395
459
  return this.mergedOptionsFor(route).headerSearchBarOptions?.ref;
396
460
  }
397
461
 
398
- searchBarProps(route: IRoute<unknown>, index: number): Record<string, unknown> {
462
+ searchBarProps(
463
+ route: IRoute<unknown>,
464
+ index: number,
465
+ ): Record<string, unknown> {
399
466
  return this.planFor(route, index).searchBarProps ?? {};
400
467
  }
401
468
  }
@@ -12,7 +12,9 @@ export type ITabScreenOptionsArgs = {
12
12
  navigation: ITabNavigatorHandle;
13
13
  };
14
14
 
15
- export type ITabScreenOptionsResolver = (props: ITabScreenOptionsArgs) => ITabOptions;
15
+ export type ITabScreenOptionsResolver = (
16
+ props: ITabScreenOptionsArgs,
17
+ ) => ITabOptions;
16
18
 
17
19
  @Directive({
18
20
  selector: 'ng-template[symbioteTabScreen]',
@@ -39,6 +39,7 @@ import {
39
39
  createNavigationEmitter,
40
40
  diffFocusedRoute,
41
41
  isFocusedRoute,
42
+ reconcileTabRoutes,
42
43
  renderTabBar,
43
44
  tabRouterReducer,
44
45
  } from '../../core';
@@ -65,7 +66,12 @@ let tabInstanceCounter = 0;
65
66
  @Component({
66
67
  selector: 'Tab',
67
68
  standalone: true,
68
- imports: [NgComponentOutlet, NavigationScopeDirective, DescriptorOutlet, View],
69
+ imports: [
70
+ NgComponentOutlet,
71
+ NavigationScopeDirective,
72
+ DescriptorOutlet,
73
+ View,
74
+ ],
69
75
  changeDetection: ChangeDetectionStrategy.OnPush,
70
76
  template: `
71
77
  <View [style]="rootStyle">
@@ -100,7 +106,8 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
100
106
  // Keyed by name -> the LIVE TabScreenDirective instance - see stack.ts's matching comment for
101
107
  // why a snapshot copy would go stale on an in-place `[options]`/`[component]` change.
102
108
  private readonly registry = new Map<string, TabScreenDirective>();
103
- private tabScreenChildrenSubscription: { unsubscribe: () => void } | undefined;
109
+ private tabScreenChildrenSubscription:
110
+ { unsubscribe: () => void } | undefined;
104
111
 
105
112
  private readonly stateSignal = signal<ITabRouterState | undefined>(undefined);
106
113
  readonly state = this.stateSignal.asReadonly();
@@ -114,11 +121,11 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
114
121
  this.dispatch({ type: 'setParams', key, params });
115
122
 
116
123
  ngAfterContentInit(): void {
117
- this.rebuildRegistry();
118
- this.initializeState();
119
- this.tabScreenChildrenSubscription = this.tabScreenChildren.changes.subscribe(() => {
120
- this.rebuildRegistry();
121
- });
124
+ this.syncRegistry();
125
+ this.tabScreenChildrenSubscription =
126
+ this.tabScreenChildren.changes.subscribe(() => {
127
+ this.syncRegistry();
128
+ });
122
129
  }
123
130
 
124
131
  ngOnDestroy(): void {
@@ -141,10 +148,25 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
141
148
  }));
142
149
  }
143
150
 
144
- private initializeState(): void {
145
- if (this.stateSignal() !== undefined) return;
151
+ // A <ng-template symbioteTabScreen> can appear or disappear after mount (a marker behind an
152
+ // @if, a data-driven screen list), so the route list follows the LIVE query instead of staying
153
+ // frozen at whatever ngAfterContentInit first saw: reconcileTabRoutes (core) keeps each
154
+ // surviving route's key and accumulated params and moves focus only when the focused route is
155
+ // the one that left. Runs from the query's own `changes` subscription - an ordinary imperative
156
+ // callback, deliberately not a computed, since this writes the state signal.
157
+ private syncRegistry(): void {
158
+ this.rebuildRegistry();
146
159
  const routes = this.routesFromRegistry();
147
- if (routes.length === 0) dlog('Tab: no <ng-template symbioteTabScreen> children registered');
160
+ if (routes.length === 0)
161
+ dlog('Tab: no <ng-template symbioteTabScreen> children registered');
162
+ const current = this.stateSignal();
163
+ if (current !== undefined) {
164
+ this.stateSignal.set(reconcileTabRoutes(current, routes));
165
+ return;
166
+ }
167
+ // Seeding an empty list would resolve initialRouteName against nothing and lose it once the
168
+ // markers do arrive, so the state stays unseeded until at least one has registered.
169
+ if (routes.length === 0) return;
148
170
  this.stateSignal.set(createInitialTabState(routes, this.initialRouteName));
149
171
  }
150
172
 
@@ -154,9 +176,15 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
154
176
  this.stateSignal.set(tabRouterReducer(current, action));
155
177
  }
156
178
 
157
- private resolveTabOptions(entry: TabScreenDirective, route: IRoute<unknown>): ITabOptions {
179
+ private resolveTabOptions(
180
+ entry: TabScreenDirective,
181
+ route: IRoute<unknown>,
182
+ ): ITabOptions {
158
183
  const props: ITabScreenOptionsArgs = { route, navigation: this };
159
- const own = typeof entry.options === 'function' ? entry.options(props) : entry.options;
184
+ const own =
185
+ typeof entry.options === 'function'
186
+ ? entry.options(props)
187
+ : entry.options;
160
188
  return { ...this.screenOptions, ...own };
161
189
  }
162
190
 
@@ -193,8 +221,12 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
193
221
  focusedRouteEmitter(): INavigationEmitter {
194
222
  const key = this.focusedRoute()?.key;
195
223
  return untracked(() => {
196
- if (key === this.currentEmitterKey && this.currentEmitter) return this.currentEmitter;
197
- const { blurKey, focusKey } = diffFocusedRoute(this.currentEmitterKey, key);
224
+ if (key === this.currentEmitterKey && this.currentEmitter)
225
+ return this.currentEmitter;
226
+ const { blurKey, focusKey } = diffFocusedRoute(
227
+ this.currentEmitterKey,
228
+ key,
229
+ );
198
230
  if (blurKey !== undefined && this.currentEmitter) {
199
231
  dlog('Tab: previous route blurred');
200
232
  this.currentEmitter.emit(NAVIGATION_EVENT_BLUR);
@@ -243,12 +275,18 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
243
275
  });
244
276
 
245
277
  const focusedRoute = this.focusedRoute();
246
- const focusedEntry = focusedRoute ? this.registry.get(focusedRoute.name) : undefined;
278
+ const focusedEntry = focusedRoute
279
+ ? this.registry.get(focusedRoute.name)
280
+ : undefined;
247
281
  const focusedOptions =
248
282
  focusedEntry && focusedRoute
249
283
  ? this.resolveTabOptions(focusedEntry, focusedRoute)
250
284
  : this.screenOptions;
251
285
 
252
- return renderTabBar({ items, style: focusedOptions?.tabBarStyle, passthrough: {} });
286
+ return renderTabBar({
287
+ items,
288
+ style: focusedOptions?.tabBarStyle,
289
+ passthrough: {},
290
+ });
253
291
  }
254
292
  }
@@ -11,12 +11,14 @@ export const RNS_SCREEN_VIEW_NAME = 'RNSScreen';
11
11
  // render-stack.ts for why a formSheet/modal screen MUST use this different Fabric name.
12
12
  export const RNS_MODAL_SCREEN_VIEW_NAME = 'RNSModalScreen';
13
13
  export const RNS_SCREEN_STACK_VIEW_NAME = 'RNSScreenStack';
14
- export const RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME = 'RNSScreenStackHeaderConfig';
14
+ export const RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME =
15
+ 'RNSScreenStackHeaderConfig';
15
16
  // The header-subview leaf react-native-screens itself uses to host arbitrary framework children
16
17
  // (left/right/back/title/center/searchBar) inside the header. Registered here for ground-truth
17
18
  // parity, but unconsumed by any fold in v1 scope: renderHeaderConfig's Descriptor never takes
18
19
  // framework children (see render-stack.ts), so mounting a subview child is left to the adapter.
19
- export const RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME = 'RNSScreenStackHeaderSubview';
20
+ export const RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME =
21
+ 'RNSScreenStackHeaderSubview';
20
22
  export const RNS_SEARCH_BAR_VIEW_NAME = 'RNSSearchBar';
21
23
  // react-native-screens' own JS layer (ScreenStackItem -> DebugContainer -> ScreenContentWrapper)
22
24
  // ALWAYS wraps a screen's content in this native view, `collapsable: false` so Fabric can never
@@ -43,7 +45,8 @@ export const STACK_ON_FINISH_TRANSITIONING = 'onFinishTransitioning';
43
45
  // plain bar-button-item press, and a press on a (possibly nested) menu action of a 'menu'-type
44
46
  // bar-button item.
45
47
  export const HEADER_ON_PRESS_BAR_BUTTON_ITEM = 'onPressHeaderBarButtonItem';
46
- export const HEADER_ON_PRESS_BAR_BUTTON_MENU_ITEM = 'onPressHeaderBarButtonMenuItem';
48
+ export const HEADER_ON_PRESS_BAR_BUTTON_MENU_ITEM =
49
+ 'onPressHeaderBarButtonMenuItem';
47
50
 
48
51
  // RNSSearchBar event prop keys (all DirectEventHandler in the codegen spec). onClose/onOpen are
49
52
  // Android-only per the codegen spec's own comment.
@@ -7,7 +7,10 @@
7
7
  // PanResponder equivalent (see packages/navigation's README / the drawer feasibility note for the
8
8
  // full gap list).
9
9
 
10
- import type { IPanResponderGestureState, ISymbioteEvent } from '@symbiote-native/engine';
10
+ import type {
11
+ IPanResponderGestureState,
12
+ ISymbioteEvent,
13
+ } from '@symbiote-native/engine';
11
14
  import { isRecord } from '../guards';
12
15
  import type { IDrawerSlot } from '../render-drawer';
13
16
 
@@ -59,7 +62,9 @@ export function resolveDrawerType(options: IDrawerOptions): IDrawerType {
59
62
  return options.drawerType ?? DRAWER_DEFAULT_TYPE;
60
63
  }
61
64
 
62
- export function resolveDrawerPosition(options: IDrawerOptions): IDrawerPosition {
65
+ export function resolveDrawerPosition(
66
+ options: IDrawerOptions,
67
+ ): IDrawerPosition {
63
68
  return options.drawerPosition ?? DRAWER_DEFAULT_POSITION;
64
69
  }
65
70
 
@@ -90,7 +95,9 @@ export function isDrawerOverlayVisible(options: IDrawerOptions): boolean {
90
95
  // slide: panel AND content move together by the same delta, overlay fades in (content still
91
96
  // covers the panel partially as they slide in tandem, same as front visually at rest).
92
97
  // permanent: static, all zero (isDrawerAnimated() gates callers off this path already).
93
- export function resolveDrawerGeometry(options: IDrawerOptions): IDrawerGeometry {
98
+ export function resolveDrawerGeometry(
99
+ options: IDrawerOptions,
100
+ ): IDrawerGeometry {
94
101
  const width = resolveDrawerWidth(options);
95
102
  const type = resolveDrawerType(options);
96
103
  const sign = resolveDrawerPosition(options) === 'left' ? 1 : -1;
@@ -188,25 +195,37 @@ export function resolveDrawerSlotInterpolation(
188
195
  return {
189
196
  translateX: {
190
197
  inputRange: DRAWER_PROGRESS_INPUT_RANGE,
191
- outputRange: [geometry.contentTranslateXClosed, geometry.contentTranslateXOpen],
198
+ outputRange: [
199
+ geometry.contentTranslateXClosed,
200
+ geometry.contentTranslateXOpen,
201
+ ],
192
202
  },
193
203
  };
194
204
  case 'overlay':
195
205
  return {
196
206
  opacity: {
197
207
  inputRange: DRAWER_PROGRESS_INPUT_RANGE,
198
- outputRange: [geometry.overlayOpacityClosed, geometry.overlayOpacityOpen],
208
+ outputRange: [
209
+ geometry.overlayOpacityClosed,
210
+ geometry.overlayOpacityOpen,
211
+ ],
199
212
  },
200
213
  translateX: {
201
214
  inputRange: DRAWER_PROGRESS_INPUT_RANGE,
202
- outputRange: [geometry.contentTranslateXClosed, geometry.contentTranslateXOpen],
215
+ outputRange: [
216
+ geometry.contentTranslateXClosed,
217
+ geometry.contentTranslateXOpen,
218
+ ],
203
219
  },
204
220
  };
205
221
  case 'panel':
206
222
  return {
207
223
  translateX: {
208
224
  inputRange: DRAWER_PROGRESS_INPUT_RANGE,
209
- outputRange: [geometry.panelTranslateXClosed, geometry.panelTranslateXOpen],
225
+ outputRange: [
226
+ geometry.panelTranslateXClosed,
227
+ geometry.panelTranslateXOpen,
228
+ ],
210
229
  },
211
230
  };
212
231
  }
@@ -235,7 +254,9 @@ export function isSwipeStartInEdge(
235
254
  // ScrollView's way).
236
255
  const MOVE_CLAIM_THRESHOLD = 5;
237
256
 
238
- export function isHorizontalDrag(gestureState: IPanResponderGestureState): boolean {
257
+ export function isHorizontalDrag(
258
+ gestureState: IPanResponderGestureState,
259
+ ): boolean {
239
260
  return (
240
261
  Math.abs(gestureState.dx) > MOVE_CLAIM_THRESHOLD &&
241
262
  Math.abs(gestureState.dx) > Math.abs(gestureState.dy)
@@ -258,8 +279,10 @@ export function resolveSwipeIntent(
258
279
  // symmetrically for a right drawer's leftward drag).
259
280
  const signedDx = sign * gestureState.dx;
260
281
  const signedVx = sign * gestureState.vx;
261
- const minDistance = options.swipeMinDistance ?? DRAWER_DEFAULT_SWIPE_MIN_DISTANCE;
262
- const minVelocity = options.swipeMinVelocity ?? DRAWER_DEFAULT_SWIPE_MIN_VELOCITY;
282
+ const minDistance =
283
+ options.swipeMinDistance ?? DRAWER_DEFAULT_SWIPE_MIN_DISTANCE;
284
+ const minVelocity =
285
+ options.swipeMinVelocity ?? DRAWER_DEFAULT_SWIPE_MIN_VELOCITY;
263
286
 
264
287
  const pastDistance = Math.abs(signedDx) >= minDistance;
265
288
  const pastVelocity = Math.abs(signedVx) >= minVelocity;
@@ -276,7 +299,9 @@ export function clamp01(value: number): number {
276
299
  }
277
300
 
278
301
  function toFiniteNumber(value: unknown): number | undefined {
279
- return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
302
+ return typeof value === 'number' && Number.isFinite(value)
303
+ ? value
304
+ : undefined;
280
305
  }
281
306
 
282
307
  // The touch's real starting page-X, read off the raw event rather than gestureState.x0: the
@@ -293,7 +318,8 @@ export function startPageXOf(event: ISymbioteEvent): number | undefined {
293
318
  const direct = toFiniteNumber(nativeEvent.pageX);
294
319
  if (direct !== undefined) return direct;
295
320
  const touches = nativeEvent.touches;
296
- if (Array.isArray(touches) && isRecord(touches[0])) return toFiniteNumber(touches[0].pageX);
321
+ if (Array.isArray(touches) && isRecord(touches[0]))
322
+ return toFiniteNumber(touches[0].pageX);
297
323
  return undefined;
298
324
  }
299
325
 
@@ -323,7 +349,8 @@ export function shouldClaimDrawerSwipe(
323
349
  options: IDrawerOptions,
324
350
  phase: 'start' | 'move',
325
351
  ): boolean {
326
- if ((options.swipeEnabled ?? DRAWER_DEFAULT_SWIPE_ENABLED) === false) return false;
352
+ if ((options.swipeEnabled ?? DRAWER_DEFAULT_SWIPE_ENABLED) === false)
353
+ return false;
327
354
  if (!isDrawerAnimated(options)) return false;
328
355
  const startX = startPageXOf(event) ?? gestureState.x0;
329
356
  if (!isSwipeStartInEdge(startX, screenWidth, isOpen, options)) return false;
@@ -34,7 +34,11 @@ export function createInitialDrawerRouterState(
34
34
  return { routes, index: INITIAL_FOCUSED_INDEX, isOpen: false };
35
35
  }
36
36
  const index = routes.findIndex(route => route.name === initialRouteName);
37
- return { routes, index: index === -1 ? INITIAL_FOCUSED_INDEX : index, isOpen: false };
37
+ return {
38
+ routes,
39
+ index: index === -1 ? INITIAL_FOCUSED_INDEX : index,
40
+ isOpen: false,
41
+ };
38
42
  }
39
43
 
40
44
  // Mirrors @react-navigation/drawer's DrawerActions: jumpTo focuses a route by NAME (TabRouter's
@@ -49,7 +53,9 @@ export function drawerRouterReducer(
49
53
  case 'jumpTo': {
50
54
  const index = state.routes.findIndex(route => route.name === action.name);
51
55
  if (index === -1) return state;
52
- return index === state.index && !state.isOpen ? state : { ...state, index, isOpen: false };
56
+ return index === state.index && !state.isOpen
57
+ ? state
58
+ : { ...state, index, isOpen: false };
53
59
  }
54
60
 
55
61
  case 'openDrawer':
@@ -66,6 +72,8 @@ export function drawerRouterReducer(
66
72
  }
67
73
  }
68
74
 
69
- export function focusedDrawerRoute(state: IDrawerRouterState): IRouteEntry | undefined {
75
+ export function focusedDrawerRoute(
76
+ state: IDrawerRouterState,
77
+ ): IRouteEntry | undefined {
70
78
  return state.routes[state.index];
71
79
  }
@@ -19,5 +19,7 @@ export function isRecord(value: unknown): value is Record<string, unknown> {
19
19
  // navigator-state.ts (Stack) and tab-router-state.ts (Tabs) so the two reducers can't drift on
20
20
  // this rule independently.
21
21
  export function mergeParams(current: unknown, incoming: unknown): unknown {
22
- return isRecord(current) && isRecord(incoming) ? { ...current, ...incoming } : incoming;
22
+ return isRecord(current) && isRecord(incoming)
23
+ ? { ...current, ...incoming }
24
+ : incoming;
23
25
  }