@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
@@ -1,17 +1,18 @@
1
1
  export * from './constants';
2
2
  export { createInitialNavigatorState, navigatorReducer, computeActivityState, isTopRoute, } from './navigator-state';
3
- export type { IRoute, INavigatorState, INavigatorAction } from './navigator-state';
3
+ export type { IRoute, INavigatorState, INavigatorAction, } from './navigator-state';
4
+ export { reconcileStackRoutes } from './stack-router-state';
4
5
  export type { IStackAnimation, IStackPresentation, IHeaderBackButtonDisplayMode, IHeaderUserInterfaceStyle, IOptionalBooleanNativeProp, ISheetAllowedDetents, ISheetLargestUndimmedDetent, ISheetInitialDetent, IHeaderBarButtonIcon, IHeaderBarButtonItemBadge, IHeaderBarButtonItemAction, IHeaderBarButtonMenuAction, IHeaderBarButtonSubmenu, IHeaderBarButtonItemMenu, IHeaderBarButtonItemSpacing, IHeaderBarButtonItem, ISearchBarAutoCapitalize, ISearchBarPlacement, ISearchBarOptions, IScreenOrientation, IScreenOptions, INavigatorPlatform, IScreenViewProps, IHeaderConfigViewProps, IStackViewProps, ISearchBarViewProps, } from './navigator-props';
5
- export { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView } from './screen-options';
6
+ export { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView, } from './screen-options';
6
7
  export { buildSearchBarHandle } from './search-bar-commands';
7
8
  export type { ISearchBarCommands } from './search-bar-commands';
8
9
  export { resolveScreenProps, resolveStackProps, renderHeaderConfig, resolveSearchBarProps, resolveScreenContentWrapperStyle, resolveScreenViewName, isHeaderInModal, resolveHeaderInModalStackStyle, resolveHeaderInModalScreenStyle, buildSearchBarPassthrough, resolveScreenRenderPlan, } from './render-stack';
9
10
  export type { IScreenRenderPlanInput, IScreenRenderPlan } from './render-stack';
10
- export { serializeNavigatorState, deserializeNavigatorState } from './state-persistence';
11
+ export { serializeNavigatorState, deserializeNavigatorState, } from './state-persistence';
11
12
  export { createNavigationEmitter, diffFocusedRoute, NAVIGATION_EVENT_FOCUS, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_STATE, NAVIGATION_EVENT_BEFORE_REMOVE, } from './navigation-events';
12
13
  export type { INavigationEmitter, INavigationEventListener, INavigationEventName, IFocusTransition, } from './navigation-events';
13
14
  export { isRecord } from './guards';
14
- export { createInitialTabState, tabRouterReducer, isFocusedRoute } from './tab-router-state';
15
+ export { createInitialTabState, tabRouterReducer, reconcileTabRoutes, isFocusedRoute, } from './tab-router-state';
15
16
  export type { ITabRouterState, ITabRouterAction } from './tab-router-state';
16
17
  export type { ITabBarIcon, ITabOptions } from './tab-options';
17
18
  export { renderTabBarItem, renderTabBar } from './render-tabs';
@@ -19,7 +20,7 @@ export type { ITabBarItemView, ITabBarViewProps } from './render-tabs';
19
20
  export { resolveRouteFromUrl, resolveUrlFromRoute } from './linking-config';
20
21
  export type { ILinkingConfig, IScreenLinkingConfig } from './linking-config';
21
22
  export { createInitialDrawerRouterState, drawerRouterReducer, focusedDrawerRoute, } from './drawer-router-state';
22
- export type { IDrawerRouterState, IDrawerRouterAction } from './drawer-router-state';
23
+ export type { IDrawerRouterState, IDrawerRouterAction, } from './drawer-router-state';
23
24
  export type { IDrawerType, IDrawerPosition, IDrawerOptions, IDrawerScreenOptions, IDrawerGeometry, ISwipeIntent, } from './drawer-options';
24
25
  export { DRAWER_DEFAULT_TYPE, DRAWER_DEFAULT_POSITION, DRAWER_DEFAULT_WIDTH, DRAWER_DEFAULT_OVERLAY_COLOR, DRAWER_DEFAULT_SWIPE_ENABLED, DRAWER_DEFAULT_SWIPE_EDGE_WIDTH, DRAWER_DEFAULT_SWIPE_MIN_DISTANCE, DRAWER_DEFAULT_SWIPE_MIN_VELOCITY, resolveDrawerType, resolveDrawerPosition, resolveDrawerWidth, isDrawerAnimated, isDrawerOverlayVisible, resolveDrawerGeometry, isSwipeStartInEdge, isHorizontalDrag, resolveSwipeIntent, clamp01, startPageXOf, resolveDragProgress, shouldClaimDrawerSwipe, resolveDrawerSlotInterpolation, } from './drawer-options';
25
26
  export type { IDrawerInterpolationRange, IDrawerContentSlotInterpolation, IDrawerOverlaySlotInterpolation, IDrawerPanelSlotInterpolation, } from './drawer-options';
@@ -7,10 +7,14 @@
7
7
  // the descriptor bridge.
8
8
  export * from './constants.js';
9
9
  export { createInitialNavigatorState, navigatorReducer, computeActivityState, isTopRoute, } from './navigator-state/index.js';
10
- export { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView } from './screen-options.js';
10
+ // Drops history entries whose `<Stack.Screen>` marker has unregistered - see
11
+ // stack-router-state.ts's header for why the Stack's history needs this and the Tab's projection
12
+ // does not.
13
+ export { reconcileStackRoutes } from './stack-router-state/index.js';
14
+ export { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView, } from './screen-options.js';
11
15
  export { buildSearchBarHandle } from './search-bar-commands.js';
12
16
  export { resolveScreenProps, resolveStackProps, renderHeaderConfig, resolveSearchBarProps, resolveScreenContentWrapperStyle, resolveScreenViewName, isHeaderInModal, resolveHeaderInModalStackStyle, resolveHeaderInModalScreenStyle, buildSearchBarPassthrough, resolveScreenRenderPlan, } from './render-stack.js';
13
- export { serializeNavigatorState, deserializeNavigatorState } from './state-persistence/index.js';
17
+ export { serializeNavigatorState, deserializeNavigatorState, } from './state-persistence/index.js';
14
18
  export { createNavigationEmitter, diffFocusedRoute, NAVIGATION_EVENT_FOCUS, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_STATE, NAVIGATION_EVENT_BEFORE_REMOVE, } from './navigation-events/index.js';
15
19
  // Runtime guards shared across core (and re-exported for adapters narrowing their own untyped
16
20
  // inputs - vnode props, gesture/event data, persisted JSON) - see guards.ts's header for which
@@ -18,7 +22,7 @@ export { createNavigationEmitter, diffFocusedRoute, NAVIGATION_EVENT_FOCUS, NAVI
18
22
  export { isRecord } from './guards.js';
19
23
  // Bottom-tabs navigator: a FOCUSED-INDEX router (not a stack - see tab-router-state.ts) driving
20
24
  // a pure-JS tab bar render, framework-agnostic and shared verbatim by every adapter.
21
- export { createInitialTabState, tabRouterReducer, isFocusedRoute } from './tab-router-state/index.js';
25
+ export { createInitialTabState, tabRouterReducer, reconcileTabRoutes, isFocusedRoute, } from './tab-router-state/index.js';
22
26
  export { renderTabBarItem, renderTabBar } from './render-tabs.js';
23
27
  // Linking config: resolves a URL to a route (and back), the piece @react-navigation's
24
28
  // NavigationContainer `linking` prop provides on top of the framework-agnostic Linking module.
@@ -3,7 +3,7 @@
3
3
  // in its router, minus the React-specific action-creator/linking machinery. Route identity
4
4
  // (`key`) is generated by the CALLER (the adapter, via React's useId or an equivalent) - the
5
5
  // reducer never invents identity itself, so it stays a pure (state, action) => state function.
6
- import { SCREEN_ACTIVITY_STATE_FOCUSED, SCREEN_ACTIVITY_STATE_INACTIVE } from '../constants.js';
6
+ import { SCREEN_ACTIVITY_STATE_FOCUSED, SCREEN_ACTIVITY_STATE_INACTIVE, } from '../constants.js';
7
7
  import { mergeParams } from '../guards.js';
8
8
  export function createInitialNavigatorState(initialRoute) {
9
9
  return { routes: [initialRoute] };
@@ -22,7 +22,9 @@ export function navigatorReducer(state, action) {
22
22
  return { routes: state.routes.slice(0, nextLength) };
23
23
  }
24
24
  case 'popToTop':
25
- return state.routes.length <= 1 ? state : { routes: state.routes.slice(0, 1) };
25
+ return state.routes.length <= 1
26
+ ? state
27
+ : { routes: state.routes.slice(0, 1) };
26
28
  case 'popTo': {
27
29
  const index = state.routes.findIndex(route => route.key === action.key);
28
30
  if (index === -1)
@@ -51,7 +53,11 @@ export function navigatorReducer(state, action) {
51
53
  params: mergeParams(target.params, action.params),
52
54
  };
53
55
  return {
54
- routes: [...state.routes.slice(0, index), nextRoute, ...state.routes.slice(index + 1)],
56
+ routes: [
57
+ ...state.routes.slice(0, index),
58
+ nextRoute,
59
+ ...state.routes.slice(index + 1),
60
+ ],
55
61
  };
56
62
  }
57
63
  // Mirrors @react-navigation's CommonActions.reset / BaseRouter's RESET handler: the payload
@@ -74,7 +80,9 @@ export function navigatorReducer(state, action) {
74
80
  // exceeds routesLength - 1, this formula never produces a decrease across a push or pop.
75
81
  export function computeActivityState(index, routesLength) {
76
82
  const focusedIndex = routesLength - 1;
77
- return index > focusedIndex ? SCREEN_ACTIVITY_STATE_INACTIVE : SCREEN_ACTIVITY_STATE_FOCUSED;
83
+ return index > focusedIndex
84
+ ? SCREEN_ACTIVITY_STATE_INACTIVE
85
+ : SCREEN_ACTIVITY_STATE_FOCUSED;
78
86
  }
79
87
  export function isTopRoute(index, routesLength) {
80
88
  return index === routesLength - 1;
@@ -69,7 +69,10 @@ function panelBaseStyle(options) {
69
69
  export function renderDrawer(view, options) {
70
70
  const type = resolveDrawerType(options);
71
71
  const content = el('symbiote-view', { ...view.contentPassthrough, style: CONTENT_STYLE }, []);
72
- const panel = el('symbiote-view', { ...view.panelPassthrough, style: [panelBaseStyle(options), view.drawerStyle] }, []);
72
+ const panel = el('symbiote-view', {
73
+ ...view.panelPassthrough,
74
+ style: [panelBaseStyle(options), view.drawerStyle],
75
+ }, []);
73
76
  const slots = { content, panel };
74
77
  if (isDrawerOverlayVisible(options)) {
75
78
  slots.overlay = el('symbiote-view', {
@@ -11,7 +11,7 @@
11
11
  import { el } from '@symbiote-native/components';
12
12
  import { HEADER_ON_PRESS_BAR_BUTTON_ITEM, HEADER_ON_PRESS_BAR_BUTTON_MENU_ITEM, RNS_MODAL_SCREEN_VIEW_NAME, RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME, RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME, RNS_SCREEN_VIEW_NAME, RNS_SEARCH_BAR_VIEW_NAME, SEARCH_BAR_ON_BLUR, SEARCH_BAR_ON_CANCEL_BUTTON_PRESS, SEARCH_BAR_ON_CHANGE_TEXT, SEARCH_BAR_ON_CLOSE, SEARCH_BAR_ON_FOCUS, SEARCH_BAR_ON_OPEN, SEARCH_BAR_ON_SEARCH_BUTTON_PRESS, STACK_DEFAULT_ANIMATION, STACK_DEFAULT_PRESENTATION, } from './constants.js';
13
13
  import { computeActivityState } from './navigator-state/index.js';
14
- import { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView } from './screen-options.js';
14
+ import { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView, } from './screen-options.js';
15
15
  // Mirrors react-native-screens' ScreenStackItem.tsx (getPositioningStyle): a formSheet's content
16
16
  // wrapper does not get `flex: 1`. RNSScreen.mm's updateBounds pushes the sheet's live native size
17
17
  // into Fabric's shadow state on every frame of a detent drag, and a `bottom: 0`-pinned wrapper
@@ -65,7 +65,9 @@ export function resolveScreenViewName(stackPresentation, isAndroid) {
65
65
  stackPresentation === 'push' ||
66
66
  stackPresentation === 'containedModal' ||
67
67
  stackPresentation === 'containedTransparentModal';
68
- return isPlainPresentation ? RNS_SCREEN_VIEW_NAME : RNS_MODAL_SCREEN_VIEW_NAME;
68
+ return isPlainPresentation
69
+ ? RNS_SCREEN_VIEW_NAME
70
+ : RNS_MODAL_SCREEN_VIEW_NAME;
69
71
  }
70
72
  export function resolveScreenContentWrapperStyle(stackPresentation, headerHidden, headerTranslucent, isAndroid) {
71
73
  let baseStyles;
@@ -96,13 +98,20 @@ export function resolveScreenContentWrapperStyle(stackPresentation, headerHidden
96
98
  export function isHeaderInModal(stackPresentation, headerHidden, isAndroid) {
97
99
  if (isAndroid)
98
100
  return false;
99
- return (stackPresentation ?? STACK_DEFAULT_PRESENTATION) !== 'push' && !headerHidden;
101
+ return ((stackPresentation ?? STACK_DEFAULT_PRESENTATION) !== 'push' &&
102
+ !headerHidden);
100
103
  }
101
104
  // Inner-modal wrapper styles for isHeaderInModal: the inner RNSScreenStack fills its outer
102
105
  // RNSScreen, and the inner RNSScreen fills the stack absolutely on all four edges. This mirrors
103
106
  // react-native-screens' own `styles.container` / `StyleSheet.absoluteFill` for this exact pair.
104
107
  const HEADER_IN_MODAL_STACK_STYLE = { flex: 1 };
105
- const HEADER_IN_MODAL_SCREEN_STYLE = { position: 'absolute', top: 0, start: 0, end: 0, bottom: 0 };
108
+ const HEADER_IN_MODAL_SCREEN_STYLE = {
109
+ position: 'absolute',
110
+ top: 0,
111
+ start: 0,
112
+ end: 0,
113
+ bottom: 0,
114
+ };
106
115
  export function resolveHeaderInModalStackStyle() {
107
116
  return HEADER_IN_MODAL_STACK_STYLE;
108
117
  }
@@ -7,7 +7,7 @@
7
7
  // The header bar-button payload+dispatch cluster (id-tagging, onPress lookup) lives in
8
8
  // header-bar-buttons.ts - self-contained, consumed here only as a black box by
9
9
  // resolveHeaderConfigView.
10
- import { buildHeaderBarButtonDispatch, prepareHeaderBarButtonItems } from './header-bar-buttons.js';
10
+ import { buildHeaderBarButtonDispatch, prepareHeaderBarButtonItems, } from './header-bar-buttons.js';
11
11
  // These sentinels must be kept in sync with react-native-screens' native side - they are RNS's
12
12
  // own compat values for the 'fitToContents'/'large'/'medium'/'all' legacy presets, replicated
13
13
  // here because we drive RNSScreen directly (no react-native-screens JS component in the path).
@@ -5,7 +5,7 @@
5
5
  // buildScrollViewHandle exactly (same lazy-getter shape); the adapter supplies the node getter
6
6
  // and its own framework-specific ref field (see react/screen.ts's IReactSearchBarOptions - the
7
7
  // ref itself is per-adapter, same split as IPressableProps).
8
- import { dispatchViewCommand, dlog } from '@symbiote-native/engine';
8
+ import { dispatchViewCommand, dlog, } from '@symbiote-native/engine';
9
9
  // dispatchViewCommand itself dlogs a "node not committed" skip; this null case (the ref never
10
10
  // attached to a live RNSSearchBar at all - e.g. the header's search bar isn't mounted, or a
11
11
  // stale handle outlived its screen) was the one unlogged gap, silently indistinguishable from
@@ -0,0 +1,2 @@
1
+ import type { INavigatorState } from '../navigator-state';
2
+ export declare function reconcileStackRoutes(state: INavigatorState, registeredNames: readonly string[]): INavigatorState;
@@ -0,0 +1,44 @@
1
+ // StackRouter: the registry-reconciliation half (framework-agnostic, zero render). A Stack's route
2
+ // list is navigation HISTORY, not a projection of the registered `<Stack.Screen>` markers the way a
3
+ // Tab's is (tab-router-state) - it seeds exactly one route and grows only through push/replace. So
4
+ // a marker that unregisters while its route still sits in the history (a marker behind an `{#if}`,
5
+ // a data-driven screen list) leaves behind an entry nothing can render: the route stays, the
6
+ // adapter's componentFor() finds no screen, and the user is parked on a blank RNSScreen with no
7
+ // way to tell what happened. Mirrors @react-navigation/routers' StackRouter.getStateForRouteNames-
8
+ // Change, which filters those routes out of the history and pulls the focused index back into
9
+ // range.
10
+ //
11
+ // Deliberately NOT a navigatorReducer action: this is not something a caller dispatches, it is a
12
+ // reaction to the registry changing underneath an unchanged history, and each adapter observes
13
+ // that change through its own lifecycle. Keeping it a separate pure function lets every adapter
14
+ // wire it its own way without teaching the reducer about a registry it has never seen.
15
+ // The contract, and the two places it deliberately parts from upstream:
16
+ //
17
+ // - SURVIVORS KEEP THEIR IDENTITY. A stack route's key is COUNTER-derived (every adapter's
18
+ // createRoute increments a per-navigator sequence), not name-derived like a tab route's, so
19
+ // re-deriving the list from the registry would hand every survivor a brand-new key and remount
20
+ // live screens. Only the phantom entries go; every other route object passes through by
21
+ // reference, params included.
22
+ //
23
+ // - THE FOCUSED ROUTE IS THE TOP ONE. This state carries no `index` field: the focused route is
24
+ // always the last one (see computeActivityState's comment for why no route can outrank it), so
25
+ // upstream's `index: Math.min(state.index, routes.length - 1)` degenerates here to "the last
26
+ // survivor". Dropping the FOCUSED route therefore lands the user on the nearest still-registered
27
+ // route beneath it - where a pop() would have left them - rather than on nothing.
28
+ //
29
+ // - THE ROUTE LIST IS NEVER EMPTIED. `routes.length - 1` IS the focused index, so an empty list
30
+ // means no focused route at all - the blank screen this function exists to prevent. When nothing
31
+ // in the history survives (every marker gone, or the whole screen set swapped for new names) the
32
+ // state is returned UNCHANGED. Upstream instead pushes a freshly nanoid()-keyed route for
33
+ // initialRouteName; we cannot, because minting a route key belongs to the caller here
34
+ // (navigator-state.ts's header) and a derivation that mints one would allocate a new key on every
35
+ // re-run. Unchanged is also the right answer for the usual cause of a momentarily empty registry
36
+ // - markers unregistering and re-registering across a re-render - since the next run reconciles
37
+ // for real.
38
+ export function reconcileStackRoutes(state, registeredNames) {
39
+ const routes = state.routes.filter(route => registeredNames.includes(route.name));
40
+ // filter preserves order, so an unchanged length means nothing was dropped.
41
+ if (routes.length === state.routes.length || routes.length === 0)
42
+ return state;
43
+ return { routes };
44
+ }
@@ -7,10 +7,14 @@ import { isRecord } from '../guards.js';
7
7
  // params: undefined}`, and JSON.stringify drops undefined-valued keys - a JSON round trip of a
8
8
  // perfectly valid route legitimately arrives here without a `params` key at all.
9
9
  function isRoute(value) {
10
- return isRecord(value) && typeof value.key === 'string' && typeof value.name === 'string';
10
+ return (isRecord(value) &&
11
+ typeof value.key === 'string' &&
12
+ typeof value.name === 'string');
11
13
  }
12
14
  function isNavigatorState(value) {
13
- return isRecord(value) && Array.isArray(value.routes) && value.routes.every(isRoute);
15
+ return (isRecord(value) &&
16
+ Array.isArray(value.routes) &&
17
+ value.routes.every(isRoute));
14
18
  }
15
19
  export function serializeNavigatorState(state) {
16
20
  return state;
@@ -15,5 +15,6 @@ export type ITabRouterAction = {
15
15
  params: unknown;
16
16
  };
17
17
  export declare function createInitialTabState(routes: readonly IRouteEntry[], initialRouteName?: string): ITabRouterState;
18
+ export declare function reconcileTabRoutes(state: ITabRouterState, nextRoutes: readonly IRouteEntry[]): ITabRouterState;
18
19
  export declare function tabRouterReducer(state: ITabRouterState, action: ITabRouterAction): ITabRouterState;
19
20
  export declare function isFocusedRoute(index: number, focusedIndex: number): boolean;
@@ -14,6 +14,25 @@ export function createInitialTabState(routes, initialRouteName) {
14
14
  const index = routes.findIndex(route => route.name === initialRouteName);
15
15
  return { routes, index: index === -1 ? INITIAL_FOCUSED_INDEX : index };
16
16
  }
17
+ // A screen marker can appear or disappear after mount (a marker behind an `{#if}`, a data-driven
18
+ // screen list), so a navigator's route list has to follow its registry instead of staying frozen
19
+ // at whatever createInitialTabState saw first. Mirrors TabRouter.getStateForRouteNamesChange:
20
+ // membership and order come from `nextRoutes`, but a route that survives keeps its IDENTITY (its
21
+ // key) and everything jumpTo/setParams accumulated onto its params - only genuinely new names
22
+ // take their entry from `nextRoutes`. Focus follows the previously focused route's NAME, so an
23
+ // unrelated screen disappearing never moves the user; when the focused route is the one that
24
+ // disappeared, focus falls back to the first route, the same landing spot every unresolvable
25
+ // focus gets here (createInitialTabState's own fallback).
26
+ export function reconcileTabRoutes(state, nextRoutes) {
27
+ const routes = nextRoutes.map(next => state.routes.find(route => route.name === next.name) ?? next);
28
+ const isUnchanged = routes.length === state.routes.length &&
29
+ routes.every((route, at) => route === state.routes[at]);
30
+ if (isUnchanged)
31
+ return state;
32
+ const focusedName = state.routes[state.index]?.name;
33
+ const index = routes.findIndex(route => route.name === focusedName);
34
+ return { routes, index: index === -1 ? INITIAL_FOCUSED_INDEX : index };
35
+ }
17
36
  // jumpTo moves the focused index to an existing route by name and optionally merges params
18
37
  // (navigation.jumpTo(name, params) - the tab-actions doc's own signature); it never adds,
19
38
  // removes, or reorders routes (mirrors TabRouter: JUMP_TO is a no-op when the target name isn't
@@ -30,7 +49,10 @@ export function tabRouterReducer(state, action) {
30
49
  }
31
50
  const target = state.routes[index];
32
51
  const routes = state.routes.slice();
33
- routes[index] = { ...target, params: mergeParams(target.params, action.params) };
52
+ routes[index] = {
53
+ ...target,
54
+ params: mergeParams(target.params, action.params),
55
+ };
34
56
  return { ...state, index, routes };
35
57
  }
36
58
  case 'setParams': {
@@ -39,7 +61,10 @@ export function tabRouterReducer(state, action) {
39
61
  return state;
40
62
  const target = state.routes[index];
41
63
  const routes = state.routes.slice();
42
- routes[index] = { ...target, params: mergeParams(target.params, action.params) };
64
+ routes[index] = {
65
+ ...target,
66
+ params: mergeParams(target.params, action.params),
67
+ };
43
68
  return { ...state, routes };
44
69
  }
45
70
  default:
@@ -15,8 +15,8 @@
15
15
  // @symbiote-native/engine), which is sufficient for a solid drawer but NOT byte-for-byte parity -
16
16
  // see the explicit gap list at the bottom of this file.
17
17
  import { createElement, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useMemo, useReducer, useRef, } from 'react';
18
- import { Animated, PanResponder, useWindowDimensions } from '@symbiote-native/react';
19
- import { dlog } from '@symbiote-native/engine';
18
+ import { Animated, PanResponder, useWindowDimensions, } from '@symbiote-native/react';
19
+ import { dlog, } from '@symbiote-native/engine';
20
20
  import { DRAWER_DEFAULT_OVERLAY_COLOR, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_FOCUS, createInitialDrawerRouterState, createNavigationEmitter, drawerChildOrder, drawerRouterReducer, isDrawerAnimated, renderDrawer, resolveDragProgress, resolveDrawerGeometry, resolveDrawerSlotInterpolation, resolveSwipeIntent, shouldClaimDrawerSwipe, } from '../../core/index.js';
21
21
  import { collectRegistry } from '../collect-registry.js';
22
22
  import { NavigationContext } from '../navigation-context.js';
@@ -25,7 +25,9 @@ function isDrawerScreenElement(child) {
25
25
  return isValidElement(child) && child.type === DrawerScreen;
26
26
  }
27
27
  function resolveDrawerScreenOptions(entry, optionsArgs, screenOptions) {
28
- const own = typeof entry.options === 'function' ? entry.options(optionsArgs) : entry.options;
28
+ const own = typeof entry.options === 'function'
29
+ ? entry.options(optionsArgs)
30
+ : entry.options;
29
31
  return { ...screenOptions, ...own };
30
32
  }
31
33
  const DRAWER_SNAP_DURATION = 250;
@@ -71,8 +73,10 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
71
73
  optionsRef.current = options;
72
74
  const screenWidthRef = useRef(screenWidth);
73
75
  screenWidthRef.current = screenWidth;
74
- const isOpenRef = useRef(state.isOpen);
75
- isOpenRef.current = state.isOpen;
76
+ // The whole router state, not just its isOpen bit: jumpTo below has to re-run the reducer to
77
+ // learn what the dispatch actually produced, and that needs the routes too.
78
+ const stateRef = useRef(state);
79
+ stateRef.current = state;
76
80
  const animateProgressTo = useCallback((open) => {
77
81
  // Investigation instrumentation (Drawer openDrawer-no-op / toggleDrawer-no-animation bug):
78
82
  // every imperative caller (openDrawer/closeDrawer/toggleDrawer/jumpTo) funnels through here,
@@ -92,40 +96,48 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
92
96
  }, [progress]);
93
97
  const handle = useMemo(() => ({
94
98
  openDrawer: () => {
95
- dlog(`Drawer: openDrawer() called, isOpen=${isOpenRef.current} at t=${Date.now()}`);
99
+ dlog(`Drawer: openDrawer() called, isOpen=${stateRef.current.isOpen} at t=${Date.now()}`);
96
100
  animateProgressTo(true);
97
101
  dispatch({ type: 'openDrawer' });
98
102
  },
99
103
  closeDrawer: () => {
100
- dlog(`Drawer: closeDrawer() called, isOpen=${isOpenRef.current} at t=${Date.now()}`);
104
+ dlog(`Drawer: closeDrawer() called, isOpen=${stateRef.current.isOpen} at t=${Date.now()}`);
101
105
  animateProgressTo(false);
102
106
  dispatch({ type: 'closeDrawer' });
103
107
  },
104
108
  toggleDrawer: () => {
105
- dlog(`Drawer: toggleDrawer() called, isOpen=${isOpenRef.current} at t=${Date.now()}`);
106
- animateProgressTo(!isOpenRef.current);
109
+ dlog(`Drawer: toggleDrawer() called, isOpen=${stateRef.current.isOpen} at t=${Date.now()}`);
110
+ animateProgressTo(!stateRef.current.isOpen);
107
111
  dispatch({ type: 'toggleDrawer' });
108
112
  },
109
113
  jumpTo: (name) => {
110
- dispatch({ type: 'jumpTo', name });
111
- if (isOpenRef.current)
114
+ // An unregistered name is a documented reducer no-op that hands the SAME state back, so
115
+ // animating off `isOpen` alone would slide the panel shut while the router still says
116
+ // open. useReducer's dispatch is async - stateRef only catches up on the next render - so
117
+ // the reducer (a pure function) is re-run here to learn what the dispatch produces, and
118
+ // the animation runs only on a genuine open -> closed transition.
119
+ const action = { type: 'jumpTo', name };
120
+ const current = stateRef.current;
121
+ const next = drawerRouterReducer(current, action);
122
+ dispatch(action);
123
+ if (current.isOpen && !next.isOpen)
112
124
  animateProgressTo(false);
113
125
  },
114
126
  }), [animateProgressTo]);
115
127
  useImperativeHandle(forwardedRef, () => handle, [handle]);
116
128
  const panResponder = useRef(PanResponder.create({
117
- onStartShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, screenWidthRef.current, isOpenRef.current, optionsRef.current, 'start'),
118
- onMoveShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, screenWidthRef.current, isOpenRef.current, optionsRef.current, 'move'),
129
+ onStartShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, screenWidthRef.current, stateRef.current.isOpen, optionsRef.current, 'start'),
130
+ onMoveShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, screenWidthRef.current, stateRef.current.isOpen, optionsRef.current, 'move'),
119
131
  onPanResponderGrant: () => {
120
132
  dlog('Drawer: gesture grant');
121
- dragStartProgress.current = isOpenRef.current ? 1 : 0;
133
+ dragStartProgress.current = stateRef.current.isOpen ? 1 : 0;
122
134
  },
123
135
  onPanResponderMove: (_event, gestureState) => {
124
136
  const nextProgress = resolveDragProgress(gestureState, dragStartProgress.current, optionsRef.current);
125
137
  progress.setValue(nextProgress);
126
138
  },
127
139
  onPanResponderRelease: (_event, gestureState) => {
128
- const intent = resolveSwipeIntent(gestureState, isOpenRef.current, optionsRef.current);
140
+ const intent = resolveSwipeIntent(gestureState, stateRef.current.isOpen, optionsRef.current);
129
141
  const open = intent === 'open';
130
142
  dlog(`Drawer: gesture release -> ${open ? 'open' : 'close'}`);
131
143
  animateProgressTo(open);
@@ -133,17 +145,29 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
133
145
  },
134
146
  onPanResponderTerminate: () => {
135
147
  dlog('Drawer: gesture terminated, snapping back');
136
- animateProgressTo(isOpenRef.current);
148
+ animateProgressTo(stateRef.current.isOpen);
137
149
  },
138
150
  })).current;
139
151
  const animated = isDrawerAnimated(options);
140
152
  const geometry = useMemo(() => resolveDrawerGeometry(options), [options.drawerType, options.drawerPosition, options.drawerWidth]);
141
- const panelSlot = animated ? resolveDrawerSlotInterpolation(geometry, 'panel') : undefined;
142
- const contentSlot = animated ? resolveDrawerSlotInterpolation(geometry, 'content') : undefined;
143
- const overlaySlot = animated ? resolveDrawerSlotInterpolation(geometry, 'overlay') : undefined;
144
- const panelTranslateX = panelSlot ? progress.interpolate(panelSlot.translateX) : undefined;
145
- const contentTranslateX = contentSlot ? progress.interpolate(contentSlot.translateX) : undefined;
146
- const overlayOpacity = overlaySlot ? progress.interpolate(overlaySlot.opacity) : undefined;
153
+ const panelSlot = animated
154
+ ? resolveDrawerSlotInterpolation(geometry, 'panel')
155
+ : undefined;
156
+ const contentSlot = animated
157
+ ? resolveDrawerSlotInterpolation(geometry, 'content')
158
+ : undefined;
159
+ const overlaySlot = animated
160
+ ? resolveDrawerSlotInterpolation(geometry, 'overlay')
161
+ : undefined;
162
+ const panelTranslateX = panelSlot
163
+ ? progress.interpolate(panelSlot.translateX)
164
+ : undefined;
165
+ const contentTranslateX = contentSlot
166
+ ? progress.interpolate(contentSlot.translateX)
167
+ : undefined;
168
+ const overlayOpacity = overlaySlot
169
+ ? progress.interpolate(overlaySlot.opacity)
170
+ : undefined;
147
171
  // The overlay is a full-screen absolutely-positioned sibling BELOW content in paint order
148
172
  // (see render-drawer.ts's drawerChildOrder) - for 'front' that's fine since content never moves,
149
173
  // but for 'slide' content itself translates away by contentTranslateX, and without following it
@@ -151,9 +175,13 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
151
175
  // underneath instead of just the content sliver it's meant to dim. Tying overlay to the SAME
152
176
  // translateX as content keeps it registered exactly under content, wherever content actually is
153
177
  // (resolveDrawerSlotInterpolation's 'overlay' overload returns that same content delta).
154
- const overlayTranslateX = overlaySlot ? progress.interpolate(overlaySlot.translateX) : undefined;
178
+ const overlayTranslateX = overlaySlot
179
+ ? progress.interpolate(overlaySlot.translateX)
180
+ : undefined;
155
181
  const focusedRoute = state.routes[state.index];
156
- const focusedEntry = focusedRoute ? registry.get(focusedRoute.name) : undefined;
182
+ const focusedEntry = focusedRoute
183
+ ? registry.get(focusedRoute.name)
184
+ : undefined;
157
185
  if (focusedRoute && !focusedEntry) {
158
186
  dlog(`Drawer: no screen registered for route name "${focusedRoute.name}"`);
159
187
  }
@@ -240,8 +268,13 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
240
268
  : { transform: [{ translateX: contentTranslateX }] },
241
269
  overlay: overlayOpacity === undefined
242
270
  ? undefined
243
- : { opacity: overlayOpacity, transform: [{ translateX: overlayTranslateX }] },
244
- panel: panelTranslateX === undefined ? undefined : { transform: [{ translateX: panelTranslateX }] },
271
+ : {
272
+ opacity: overlayOpacity,
273
+ transform: [{ translateX: overlayTranslateX }],
274
+ },
275
+ panel: panelTranslateX === undefined
276
+ ? undefined
277
+ : { transform: [{ translateX: panelTranslateX }] },
245
278
  };
246
279
  function renderSlot(slot) {
247
280
  const descriptor = slots.get(slot);
@@ -2,14 +2,14 @@ import '../register';
2
2
  export { Stack } from './stack';
3
3
  export type { INavigatorHandle, IStackProps } from './stack';
4
4
  export { Screen } from './screen';
5
- export type { IScreenOptionsArgs, IScreenOptionsResolver, IScreenProps } from './screen';
6
- export type { IScreenOptions, IStackAnimation, IStackPresentation } from '../core';
7
- export { useNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState } from './hooks';
5
+ export type { IScreenOptionsArgs, IScreenOptionsResolver, IScreenProps, } from './screen';
6
+ export type { IScreenOptions, IStackAnimation, IStackPresentation, } from '../core';
7
+ export { useNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './hooks';
8
8
  export type { INavigationHandle } from './hooks';
9
- export { useStackNavigation, useTabNavigation, useDrawerNavigation } from './hooks';
9
+ export { useStackNavigation, useTabNavigation, useDrawerNavigation, } from './hooks';
10
10
  export type { IStackNavigationHandle, ITabNavigationHandle, IDrawerNavigationHandle, } from './hooks';
11
11
  export { NavigationContext } from './navigation-context';
12
- export type { INavigationContextValue, IAnyNavigatorHandle } from './navigation-context';
12
+ export type { INavigationContextValue, IAnyNavigatorHandle, } from './navigation-context';
13
13
  export { useLinkingIntegration } from './linking';
14
14
  export type { ILinkingConfig, IScreenLinkingConfig } from '../core';
15
15
  export { Tab } from './tabs';
@@ -18,7 +18,7 @@ export { TabScreen } from './tab-screen';
18
18
  export type { ITabScreenOptionsArgs, ITabScreenOptionsResolver, ITabScreenProps, } from './tab-screen';
19
19
  export type { ITabOptions, ITabBarIcon } from '../core';
20
20
  export { Drawer } from './drawer';
21
- export type { IDrawerNavigatorHandle, IDrawerProps, IDrawerDescriptorMap } from './drawer';
21
+ export type { IDrawerNavigatorHandle, IDrawerProps, IDrawerDescriptorMap, } from './drawer';
22
22
  export { DrawerScreen } from './drawer-screen';
23
23
  export type { IDrawerScreenOptionsArgs, IDrawerScreenOptionsResolver, IDrawerScreenProps, } from './drawer-screen';
24
- export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition } from '../core';
24
+ export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition, } from '../core';
@@ -5,8 +5,8 @@
5
5
  import '../register';
6
6
  export { Stack } from './stack/index.js';
7
7
  export { Screen } from './screen.js';
8
- export { useNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState } from './hooks/index.js';
9
- export { useStackNavigation, useTabNavigation, useDrawerNavigation } from './hooks/index.js';
8
+ export { useNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './hooks/index.js';
9
+ export { useStackNavigation, useTabNavigation, useDrawerNavigation, } from './hooks/index.js';
10
10
  export { NavigationContext } from './navigation-context.js';
11
11
  export { useLinkingIntegration } from './linking.js';
12
12
  // Tab: the bottom-tabs navigator, a PURE-JS UI (no react-native-screens views involved, so no