@symbiote-native/navigation 1.0.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 (455) hide show
  1. package/LICENSE +21 -0
  2. package/build/angular/drawer/index.d.ts +76 -0
  3. package/build/angular/drawer/index.js +508 -0
  4. package/build/angular/drawer-screen.directive.d.ts +14 -0
  5. package/build/angular/drawer-screen.directive.js +87 -0
  6. package/build/angular/index.d.ts +23 -0
  7. package/build/angular/index.js +22 -0
  8. package/build/angular/injectors/index.d.ts +13 -0
  9. package/build/angular/injectors/index.js +8 -0
  10. package/build/angular/injectors/inject-drawer-navigation.d.ts +4 -0
  11. package/build/angular/injectors/inject-drawer-navigation.js +12 -0
  12. package/build/angular/injectors/inject-focus-effect.d.ts +2 -0
  13. package/build/angular/injectors/inject-focus-effect.js +29 -0
  14. package/build/angular/injectors/inject-is-focused.d.ts +2 -0
  15. package/build/angular/injectors/inject-is-focused.js +20 -0
  16. package/build/angular/injectors/inject-navigation-state.d.ts +3 -0
  17. package/build/angular/injectors/inject-navigation-state.js +35 -0
  18. package/build/angular/injectors/inject-navigation.d.ts +7 -0
  19. package/build/angular/injectors/inject-navigation.js +16 -0
  20. package/build/angular/injectors/inject-route.d.ts +3 -0
  21. package/build/angular/injectors/inject-route.js +20 -0
  22. package/build/angular/injectors/inject-stack-navigation.d.ts +4 -0
  23. package/build/angular/injectors/inject-stack-navigation.js +15 -0
  24. package/build/angular/injectors/inject-tab-navigation.d.ts +4 -0
  25. package/build/angular/injectors/inject-tab-navigation.js +11 -0
  26. package/build/angular/linking.d.ts +3 -0
  27. package/build/angular/linking.js +43 -0
  28. package/build/angular/navigation-context.service.d.ts +13 -0
  29. package/build/angular/navigation-context.service.js +105 -0
  30. package/build/angular/navigation-scope.directive.d.ts +10 -0
  31. package/build/angular/navigation-scope.directive.js +90 -0
  32. package/build/angular/screen.directive.d.ts +22 -0
  33. package/build/angular/screen.directive.js +90 -0
  34. package/build/angular/search-bar-ref.directive.d.ts +10 -0
  35. package/build/angular/search-bar-ref.directive.js +88 -0
  36. package/build/angular/stack/index.d.ts +55 -0
  37. package/build/angular/stack/index.js +386 -0
  38. package/build/angular/tab-screen.directive.d.ts +14 -0
  39. package/build/angular/tab-screen.directive.js +87 -0
  40. package/build/angular/tabs/index.d.ts +42 -0
  41. package/build/angular/tabs/index.js +263 -0
  42. package/build/core/constants.d.ts +27 -0
  43. package/build/core/constants.js +61 -0
  44. package/build/core/drawer-options/index.d.ts +64 -0
  45. package/build/core/drawer-options/index.js +200 -0
  46. package/build/core/drawer-router-state/index.d.ts +21 -0
  47. package/build/core/drawer-router-state/index.js +40 -0
  48. package/build/core/guards.d.ts +2 -0
  49. package/build/core/guards.js +22 -0
  50. package/build/core/header-bar-buttons.d.ts +9 -0
  51. package/build/core/header-bar-buttons.js +163 -0
  52. package/build/core/index.d.ts +29 -0
  53. package/build/core/index.js +32 -0
  54. package/build/core/linking-config/index.d.ts +13 -0
  55. package/build/core/linking-config/index.js +171 -0
  56. package/build/core/navigation-events/index.d.ts +16 -0
  57. package/build/core/navigation-events/index.js +57 -0
  58. package/build/core/navigator-handles/index.d.ts +30 -0
  59. package/build/core/navigator-handles/index.js +15 -0
  60. package/build/core/navigator-props.d.ts +216 -0
  61. package/build/core/navigator-props.js +7 -0
  62. package/build/core/navigator-state/index.d.ts +36 -0
  63. package/build/core/navigator-state/index.js +81 -0
  64. package/build/core/render-drawer.d.ts +13 -0
  65. package/build/core/render-drawer.js +88 -0
  66. package/build/core/render-stack.d.ts +35 -0
  67. package/build/core/render-stack.js +294 -0
  68. package/build/core/render-tabs.d.ts +20 -0
  69. package/build/core/render-tabs.js +97 -0
  70. package/build/core/screen-options.d.ts +4 -0
  71. package/build/core/screen-options.js +133 -0
  72. package/build/core/search-bar-commands.d.ts +10 -0
  73. package/build/core/search-bar-commands.js +42 -0
  74. package/build/core/state-persistence/index.d.ts +3 -0
  75. package/build/core/state-persistence/index.js +23 -0
  76. package/build/core/tab-options.d.ts +13 -0
  77. package/build/core/tab-options.js +10 -0
  78. package/build/core/tab-router-state/index.d.ts +19 -0
  79. package/build/core/tab-router-state/index.js +51 -0
  80. package/build/react/collect-registry.d.ts +4 -0
  81. package/build/react/collect-registry.js +15 -0
  82. package/build/react/drawer/index.d.ts +29 -0
  83. package/build/react/drawer/index.js +277 -0
  84. package/build/react/drawer-screen.d.ts +14 -0
  85. package/build/react/drawer-screen.js +8 -0
  86. package/build/react/hooks/index.d.ts +12 -0
  87. package/build/react/hooks/index.js +8 -0
  88. package/build/react/hooks/use-drawer-navigation.d.ts +4 -0
  89. package/build/react/hooks/use-drawer-navigation.js +12 -0
  90. package/build/react/hooks/use-focus-effect.d.ts +2 -0
  91. package/build/react/hooks/use-focus-effect.js +29 -0
  92. package/build/react/hooks/use-is-focused.d.ts +1 -0
  93. package/build/react/hooks/use-is-focused.js +22 -0
  94. package/build/react/hooks/use-navigation-state/index.d.ts +2 -0
  95. package/build/react/hooks/use-navigation-state/index.js +39 -0
  96. package/build/react/hooks/use-navigation.d.ts +7 -0
  97. package/build/react/hooks/use-navigation.js +16 -0
  98. package/build/react/hooks/use-route.d.ts +2 -0
  99. package/build/react/hooks/use-route.js +8 -0
  100. package/build/react/hooks/use-stack-navigation.d.ts +4 -0
  101. package/build/react/hooks/use-stack-navigation.js +14 -0
  102. package/build/react/hooks/use-tab-navigation.d.ts +4 -0
  103. package/build/react/hooks/use-tab-navigation.js +12 -0
  104. package/build/react/index.d.ts +24 -0
  105. package/build/react/index.js +21 -0
  106. package/build/react/linking.d.ts +3 -0
  107. package/build/react/linking.js +47 -0
  108. package/build/react/navigation-context.d.ts +10 -0
  109. package/build/react/navigation-context.js +22 -0
  110. package/build/react/screen.d.ts +22 -0
  111. package/build/react/screen.js +7 -0
  112. package/build/react/stack/index.d.ts +13 -0
  113. package/build/react/stack/index.js +202 -0
  114. package/build/react/tab-screen.d.ts +15 -0
  115. package/build/react/tab-screen.js +8 -0
  116. package/build/react/tabs/index.d.ts +12 -0
  117. package/build/react/tabs/index.js +116 -0
  118. package/build/register.d.ts +7 -0
  119. package/build/register.js +58 -0
  120. package/build/vue/composables/index.d.ts +12 -0
  121. package/build/vue/composables/index.js +8 -0
  122. package/build/vue/composables/use-drawer-navigation.d.ts +5 -0
  123. package/build/vue/composables/use-drawer-navigation.js +15 -0
  124. package/build/vue/composables/use-focus-effect.d.ts +1 -0
  125. package/build/vue/composables/use-focus-effect.js +31 -0
  126. package/build/vue/composables/use-is-focused.d.ts +2 -0
  127. package/build/vue/composables/use-is-focused.js +28 -0
  128. package/build/vue/composables/use-navigation-state.d.ts +3 -0
  129. package/build/vue/composables/use-navigation-state.js +29 -0
  130. package/build/vue/composables/use-navigation.d.ts +8 -0
  131. package/build/vue/composables/use-navigation.js +13 -0
  132. package/build/vue/composables/use-route.d.ts +3 -0
  133. package/build/vue/composables/use-route.js +9 -0
  134. package/build/vue/composables/use-stack-navigation.d.ts +5 -0
  135. package/build/vue/composables/use-stack-navigation.js +18 -0
  136. package/build/vue/composables/use-tab-navigation.d.ts +5 -0
  137. package/build/vue/composables/use-tab-navigation.js +15 -0
  138. package/build/vue/drawer/index.d.ts +19 -0
  139. package/build/vue/drawer/index.js +390 -0
  140. package/build/vue/drawer-screen.d.ts +14 -0
  141. package/build/vue/drawer-screen.js +12 -0
  142. package/build/vue/index.d.ts +21 -0
  143. package/build/vue/index.js +19 -0
  144. package/build/vue/linking.d.ts +3 -0
  145. package/build/vue/linking.js +57 -0
  146. package/build/vue/navigation-context.d.ts +16 -0
  147. package/build/vue/navigation-context.js +65 -0
  148. package/build/vue/screen.d.ts +21 -0
  149. package/build/vue/screen.js +12 -0
  150. package/build/vue/stack/index.d.ts +9 -0
  151. package/build/vue/stack/index.js +279 -0
  152. package/build/vue/tab-screen.d.ts +14 -0
  153. package/build/vue/tab-screen.js +11 -0
  154. package/build/vue/tabs/index.d.ts +10 -0
  155. package/build/vue/tabs/index.js +209 -0
  156. package/build-ngc/angular/drawer/index.d.ts +79 -0
  157. package/build-ngc/angular/drawer/index.js +479 -0
  158. package/build-ngc/angular/drawer/index.js.map +1 -0
  159. package/build-ngc/angular/drawer-screen.directive.d.ts +17 -0
  160. package/build-ngc/angular/drawer-screen.directive.js +32 -0
  161. package/build-ngc/angular/drawer-screen.directive.js.map +1 -0
  162. package/build-ngc/angular/drawer.d.ts +79 -0
  163. package/build-ngc/angular/drawer.js +475 -0
  164. package/build-ngc/angular/drawer.js.map +1 -0
  165. package/build-ngc/angular/index.d.ts +23 -0
  166. package/build-ngc/angular/index.js +23 -0
  167. package/build-ngc/angular/index.js.map +1 -0
  168. package/build-ngc/angular/injectors/index.d.ts +13 -0
  169. package/build-ngc/angular/injectors/index.js +9 -0
  170. package/build-ngc/angular/injectors/index.js.map +1 -0
  171. package/build-ngc/angular/injectors/inject-drawer-navigation.d.ts +4 -0
  172. package/build-ngc/angular/injectors/inject-drawer-navigation.js +13 -0
  173. package/build-ngc/angular/injectors/inject-drawer-navigation.js.map +1 -0
  174. package/build-ngc/angular/injectors/inject-focus-effect.d.ts +2 -0
  175. package/build-ngc/angular/injectors/inject-focus-effect.js +30 -0
  176. package/build-ngc/angular/injectors/inject-focus-effect.js.map +1 -0
  177. package/build-ngc/angular/injectors/inject-is-focused.d.ts +2 -0
  178. package/build-ngc/angular/injectors/inject-is-focused.js +22 -0
  179. package/build-ngc/angular/injectors/inject-is-focused.js.map +1 -0
  180. package/build-ngc/angular/injectors/inject-navigation-state.d.ts +3 -0
  181. package/build-ngc/angular/injectors/inject-navigation-state.js +37 -0
  182. package/build-ngc/angular/injectors/inject-navigation-state.js.map +1 -0
  183. package/build-ngc/angular/injectors/inject-navigation.d.ts +7 -0
  184. package/build-ngc/angular/injectors/inject-navigation.js +17 -0
  185. package/build-ngc/angular/injectors/inject-navigation.js.map +1 -0
  186. package/build-ngc/angular/injectors/inject-route.d.ts +3 -0
  187. package/build-ngc/angular/injectors/inject-route.js +21 -0
  188. package/build-ngc/angular/injectors/inject-route.js.map +1 -0
  189. package/build-ngc/angular/injectors/inject-stack-navigation.d.ts +4 -0
  190. package/build-ngc/angular/injectors/inject-stack-navigation.js +16 -0
  191. package/build-ngc/angular/injectors/inject-stack-navigation.js.map +1 -0
  192. package/build-ngc/angular/injectors/inject-tab-navigation.d.ts +4 -0
  193. package/build-ngc/angular/injectors/inject-tab-navigation.js +12 -0
  194. package/build-ngc/angular/injectors/inject-tab-navigation.js.map +1 -0
  195. package/build-ngc/angular/linking.d.ts +3 -0
  196. package/build-ngc/angular/linking.js +44 -0
  197. package/build-ngc/angular/linking.js.map +1 -0
  198. package/build-ngc/angular/navigation-context.service.d.ts +16 -0
  199. package/build-ngc/angular/navigation-context.service.js +63 -0
  200. package/build-ngc/angular/navigation-context.service.js.map +1 -0
  201. package/build-ngc/angular/navigation-scope.directive.d.ts +13 -0
  202. package/build-ngc/angular/navigation-scope.directive.js +42 -0
  203. package/build-ngc/angular/navigation-scope.directive.js.map +1 -0
  204. package/build-ngc/angular/screen.directive.d.ts +25 -0
  205. package/build-ngc/angular/screen.directive.js +35 -0
  206. package/build-ngc/angular/screen.directive.js.map +1 -0
  207. package/build-ngc/angular/search-bar-ref.directive.d.ts +13 -0
  208. package/build-ngc/angular/search-bar-ref.directive.js +44 -0
  209. package/build-ngc/angular/search-bar-ref.directive.js.map +1 -0
  210. package/build-ngc/angular/stack/index.d.ts +58 -0
  211. package/build-ngc/angular/stack/index.js +406 -0
  212. package/build-ngc/angular/stack/index.js.map +1 -0
  213. package/build-ngc/angular/stack.d.ts +58 -0
  214. package/build-ngc/angular/stack.js +402 -0
  215. package/build-ngc/angular/stack.js.map +1 -0
  216. package/build-ngc/angular/tab-screen.directive.d.ts +17 -0
  217. package/build-ngc/angular/tab-screen.directive.js +32 -0
  218. package/build-ngc/angular/tab-screen.directive.js.map +1 -0
  219. package/build-ngc/angular/tabs/index.d.ts +45 -0
  220. package/build-ngc/angular/tabs/index.js +231 -0
  221. package/build-ngc/angular/tabs/index.js.map +1 -0
  222. package/build-ngc/angular/tabs.d.ts +45 -0
  223. package/build-ngc/angular/tabs.js +231 -0
  224. package/build-ngc/angular/tabs.js.map +1 -0
  225. package/build-ngc/core/constants.d.ts +27 -0
  226. package/build-ngc/core/constants.js +62 -0
  227. package/build-ngc/core/constants.js.map +1 -0
  228. package/build-ngc/core/drawer-options/index.d.ts +64 -0
  229. package/build-ngc/core/drawer-options/index.js +201 -0
  230. package/build-ngc/core/drawer-options/index.js.map +1 -0
  231. package/build-ngc/core/drawer-options.d.ts +64 -0
  232. package/build-ngc/core/drawer-options.js +201 -0
  233. package/build-ngc/core/drawer-options.js.map +1 -0
  234. package/build-ngc/core/drawer-router-state/index.d.ts +21 -0
  235. package/build-ngc/core/drawer-router-state/index.js +41 -0
  236. package/build-ngc/core/drawer-router-state/index.js.map +1 -0
  237. package/build-ngc/core/drawer-router-state.d.ts +21 -0
  238. package/build-ngc/core/drawer-router-state.js +41 -0
  239. package/build-ngc/core/drawer-router-state.js.map +1 -0
  240. package/build-ngc/core/guards.d.ts +2 -0
  241. package/build-ngc/core/guards.js +23 -0
  242. package/build-ngc/core/guards.js.map +1 -0
  243. package/build-ngc/core/header-bar-buttons.d.ts +9 -0
  244. package/build-ngc/core/header-bar-buttons.js +164 -0
  245. package/build-ngc/core/header-bar-buttons.js.map +1 -0
  246. package/build-ngc/core/href.d.ts +16 -0
  247. package/build-ngc/core/href.js +55 -0
  248. package/build-ngc/core/href.js.map +1 -0
  249. package/build-ngc/core/index.d.ts +29 -0
  250. package/build-ngc/core/index.js +33 -0
  251. package/build-ngc/core/index.js.map +1 -0
  252. package/build-ngc/core/linking-config/index.d.ts +13 -0
  253. package/build-ngc/core/linking-config/index.js +172 -0
  254. package/build-ngc/core/linking-config/index.js.map +1 -0
  255. package/build-ngc/core/linking-config.d.ts +13 -0
  256. package/build-ngc/core/linking-config.js +172 -0
  257. package/build-ngc/core/linking-config.js.map +1 -0
  258. package/build-ngc/core/navigation-events/index.d.ts +16 -0
  259. package/build-ngc/core/navigation-events/index.js +58 -0
  260. package/build-ngc/core/navigation-events/index.js.map +1 -0
  261. package/build-ngc/core/navigation-events.d.ts +16 -0
  262. package/build-ngc/core/navigation-events.js +58 -0
  263. package/build-ngc/core/navigation-events.js.map +1 -0
  264. package/build-ngc/core/navigator-handles/index.d.ts +30 -0
  265. package/build-ngc/core/navigator-handles/index.js +16 -0
  266. package/build-ngc/core/navigator-handles/index.js.map +1 -0
  267. package/build-ngc/core/navigator-handles.d.ts +30 -0
  268. package/build-ngc/core/navigator-handles.js +16 -0
  269. package/build-ngc/core/navigator-handles.js.map +1 -0
  270. package/build-ngc/core/navigator-props.d.ts +216 -0
  271. package/build-ngc/core/navigator-props.js +8 -0
  272. package/build-ngc/core/navigator-props.js.map +1 -0
  273. package/build-ngc/core/navigator-state/index.d.ts +36 -0
  274. package/build-ngc/core/navigator-state/index.js +82 -0
  275. package/build-ngc/core/navigator-state/index.js.map +1 -0
  276. package/build-ngc/core/navigator-state.d.ts +36 -0
  277. package/build-ngc/core/navigator-state.js +82 -0
  278. package/build-ngc/core/navigator-state.js.map +1 -0
  279. package/build-ngc/core/render-drawer.d.ts +13 -0
  280. package/build-ngc/core/render-drawer.js +89 -0
  281. package/build-ngc/core/render-drawer.js.map +1 -0
  282. package/build-ngc/core/render-stack.d.ts +35 -0
  283. package/build-ngc/core/render-stack.js +295 -0
  284. package/build-ngc/core/render-stack.js.map +1 -0
  285. package/build-ngc/core/render-tabs.d.ts +20 -0
  286. package/build-ngc/core/render-tabs.js +98 -0
  287. package/build-ngc/core/render-tabs.js.map +1 -0
  288. package/build-ngc/core/screen-options.d.ts +4 -0
  289. package/build-ngc/core/screen-options.js +134 -0
  290. package/build-ngc/core/screen-options.js.map +1 -0
  291. package/build-ngc/core/search-bar-commands.d.ts +10 -0
  292. package/build-ngc/core/search-bar-commands.js +43 -0
  293. package/build-ngc/core/search-bar-commands.js.map +1 -0
  294. package/build-ngc/core/search-params.d.ts +9 -0
  295. package/build-ngc/core/search-params.js +60 -0
  296. package/build-ngc/core/search-params.js.map +1 -0
  297. package/build-ngc/core/state-persistence/index.d.ts +3 -0
  298. package/build-ngc/core/state-persistence/index.js +24 -0
  299. package/build-ngc/core/state-persistence/index.js.map +1 -0
  300. package/build-ngc/core/state-persistence.d.ts +3 -0
  301. package/build-ngc/core/state-persistence.js +24 -0
  302. package/build-ngc/core/state-persistence.js.map +1 -0
  303. package/build-ngc/core/tab-options.d.ts +13 -0
  304. package/build-ngc/core/tab-options.js +11 -0
  305. package/build-ngc/core/tab-options.js.map +1 -0
  306. package/build-ngc/core/tab-router-state/index.d.ts +19 -0
  307. package/build-ngc/core/tab-router-state/index.js +52 -0
  308. package/build-ngc/core/tab-router-state/index.js.map +1 -0
  309. package/build-ngc/core/tab-router-state.d.ts +19 -0
  310. package/build-ngc/core/tab-router-state.js +52 -0
  311. package/build-ngc/core/tab-router-state.js.map +1 -0
  312. package/build-ngc/register.d.ts +7 -0
  313. package/build-ngc/register.js +59 -0
  314. package/build-ngc/register.js.map +1 -0
  315. package/codegen-specs/FullWindowOverlayNativeComponent.ts +13 -0
  316. package/codegen-specs/ModalScreenNativeComponent.ts +129 -0
  317. package/codegen-specs/NativeScreensModule.ts +8 -0
  318. package/codegen-specs/NativeScreensModule.web.ts +1 -0
  319. package/codegen-specs/ScreenContainerNativeComponent.ts +8 -0
  320. package/codegen-specs/ScreenContentWrapperNativeComponent.ts +9 -0
  321. package/codegen-specs/ScreenFooterNativeComponent.ts +6 -0
  322. package/codegen-specs/ScreenNativeComponent.ts +133 -0
  323. package/codegen-specs/ScreenNavigationContainerNativeComponent.ts +11 -0
  324. package/codegen-specs/ScreenStackHeaderConfigNativeComponent.ts +99 -0
  325. package/codegen-specs/ScreenStackHeaderSubviewNativeComponent.ts +25 -0
  326. package/codegen-specs/ScreenStackNativeComponent.ts +17 -0
  327. package/codegen-specs/SearchBarNativeComponent.ts +101 -0
  328. package/codegen-specs/codegenUtils.ts +6 -0
  329. package/codegen-specs/gamma/ScrollViewMarkerNativeComponent.ts +15 -0
  330. package/codegen-specs/gamma/modals/form-sheet/FormSheetContentWrapperNativeComponent.ts +10 -0
  331. package/codegen-specs/gamma/modals/form-sheet/FormSheetHostNativeComponent.ts +47 -0
  332. package/codegen-specs/gamma/split/SplitHostNativeComponent.ts +124 -0
  333. package/codegen-specs/gamma/split/SplitScreenNativeComponent.ts +24 -0
  334. package/codegen-specs/gamma/stack/StackHeaderConfigAndroidNativeComponent.ts +144 -0
  335. package/codegen-specs/gamma/stack/StackHeaderConfigIOSNativeComponent.ts +34 -0
  336. package/codegen-specs/gamma/stack/StackHeaderItemIOSNativeComponent.ts +47 -0
  337. package/codegen-specs/gamma/stack/StackHeaderItemSpacerIOSNativeComponent.ts +20 -0
  338. package/codegen-specs/gamma/stack/StackHeaderSubviewAndroidNativeComponent.ts +27 -0
  339. package/codegen-specs/gamma/stack/StackHostNativeComponent.ts +8 -0
  340. package/codegen-specs/gamma/stack/StackScreenNativeComponent.ts +42 -0
  341. package/codegen-specs/safe-area/SafeAreaViewNativeComponent.ts +24 -0
  342. package/codegen-specs/tabs/TabsBottomAccessoryContentNativeComponent.ts +15 -0
  343. package/codegen-specs/tabs/TabsBottomAccessoryNativeComponent.ts +19 -0
  344. package/codegen-specs/tabs/TabsHostAndroidNativeComponent.ts +69 -0
  345. package/codegen-specs/tabs/TabsHostIOSNativeComponent.ts +92 -0
  346. package/codegen-specs/tabs/TabsScreenAndroidNativeComponent.ts +112 -0
  347. package/codegen-specs/tabs/TabsScreenIOSNativeComponent.ts +171 -0
  348. package/package.json +201 -0
  349. package/react-native.config.cjs +58 -0
  350. package/src/angular/drawer/drawer.test.ts +299 -0
  351. package/src/angular/drawer/index.ts +546 -0
  352. package/src/angular/drawer-screen.directive.ts +28 -0
  353. package/src/angular/index.ts +63 -0
  354. package/src/angular/injectors/index.ts +13 -0
  355. package/src/angular/injectors/inject-drawer-navigation.ts +21 -0
  356. package/src/angular/injectors/inject-focus-effect.ts +37 -0
  357. package/src/angular/injectors/inject-is-focused.ts +28 -0
  358. package/src/angular/injectors/inject-navigation-state.ts +46 -0
  359. package/src/angular/injectors/inject-navigation.ts +26 -0
  360. package/src/angular/injectors/inject-route.ts +25 -0
  361. package/src/angular/injectors/inject-stack-navigation.ts +24 -0
  362. package/src/angular/injectors/inject-tab-navigation.ts +20 -0
  363. package/src/angular/injectors/injectors.test.ts +247 -0
  364. package/src/angular/injectors/use-typed-navigation.test.ts +229 -0
  365. package/src/angular/linking.ts +55 -0
  366. package/src/angular/navigation-context.service.ts +68 -0
  367. package/src/angular/navigation-scope.directive.ts +31 -0
  368. package/src/angular/nested-navigation.test.ts +189 -0
  369. package/src/angular/screen.directive.ts +48 -0
  370. package/src/angular/search-bar-ref.directive.ts +38 -0
  371. package/src/angular/stack/index.ts +401 -0
  372. package/src/angular/stack/stack.test.ts +419 -0
  373. package/src/angular/tab-screen.directive.ts +26 -0
  374. package/src/angular/tabs/index.ts +254 -0
  375. package/src/angular/tabs/tabs.test.ts +249 -0
  376. package/src/core/constants.ts +68 -0
  377. package/src/core/drawer-options/drawer-options.test.ts +415 -0
  378. package/src/core/drawer-options/index.ts +331 -0
  379. package/src/core/drawer-router-state/drawer-router-state.test.ts +116 -0
  380. package/src/core/drawer-router-state/index.ts +71 -0
  381. package/src/core/guards.ts +23 -0
  382. package/src/core/header-bar-buttons.ts +212 -0
  383. package/src/core/index.ts +170 -0
  384. package/src/core/linking-config/index.ts +209 -0
  385. package/src/core/linking-config/linking-config.test.ts +109 -0
  386. package/src/core/navigation-events/index.ts +94 -0
  387. package/src/core/navigation-events/navigation-events.test.ts +56 -0
  388. package/src/core/navigator-handles/index.ts +63 -0
  389. package/src/core/navigator-handles/navigator-handles.test.ts +46 -0
  390. package/src/core/navigator-props.ts +323 -0
  391. package/src/core/navigator-state/index.ts +112 -0
  392. package/src/core/navigator-state/navigator-state.test.ts +80 -0
  393. package/src/core/render-drawer.ts +123 -0
  394. package/src/core/render-stack.ts +414 -0
  395. package/src/core/render-tabs.ts +138 -0
  396. package/src/core/screen-options.ts +181 -0
  397. package/src/core/search-bar-commands.ts +57 -0
  398. package/src/core/state-persistence/index.ts +30 -0
  399. package/src/core/state-persistence/state-persistence.test.ts +42 -0
  400. package/src/core/tab-options.ts +25 -0
  401. package/src/core/tab-router-state/index.ts +75 -0
  402. package/src/core/tab-router-state/tab-router-state.test.ts +34 -0
  403. package/src/globals.d.ts +4 -0
  404. package/src/react/collect-registry.ts +19 -0
  405. package/src/react/drawer/drawer.test.tsx +472 -0
  406. package/src/react/drawer/index.ts +451 -0
  407. package/src/react/drawer-screen.ts +29 -0
  408. package/src/react/hooks/hooks.test.tsx +199 -0
  409. package/src/react/hooks/index.ts +12 -0
  410. package/src/react/hooks/use-drawer-navigation.ts +21 -0
  411. package/src/react/hooks/use-focus-effect.ts +36 -0
  412. package/src/react/hooks/use-is-focused.ts +26 -0
  413. package/src/react/hooks/use-navigation-state/index.ts +47 -0
  414. package/src/react/hooks/use-navigation-state/use-navigation-state.test.ts +85 -0
  415. package/src/react/hooks/use-navigation.ts +36 -0
  416. package/src/react/hooks/use-route.ts +11 -0
  417. package/src/react/hooks/use-stack-navigation.ts +23 -0
  418. package/src/react/hooks/use-tab-navigation.ts +21 -0
  419. package/src/react/hooks/use-typed-navigation.test.tsx +187 -0
  420. package/src/react/index.ts +52 -0
  421. package/src/react/linking.ts +59 -0
  422. package/src/react/navigation-context.ts +40 -0
  423. package/src/react/nested-navigation.test.tsx +145 -0
  424. package/src/react/screen.ts +44 -0
  425. package/src/react/stack/index.ts +323 -0
  426. package/src/react/stack/stack.test.tsx +514 -0
  427. package/src/react/tab-screen.ts +30 -0
  428. package/src/react/tabs/index.ts +204 -0
  429. package/src/react/tabs/tabs.test.tsx +256 -0
  430. package/src/register.ts +59 -0
  431. package/src/vue/composables/composables.test.ts +221 -0
  432. package/src/vue/composables/index.ts +12 -0
  433. package/src/vue/composables/use-drawer-navigation.ts +25 -0
  434. package/src/vue/composables/use-focus-effect.ts +37 -0
  435. package/src/vue/composables/use-is-focused.ts +34 -0
  436. package/src/vue/composables/use-navigation-state.ts +38 -0
  437. package/src/vue/composables/use-navigation.ts +30 -0
  438. package/src/vue/composables/use-route.ts +13 -0
  439. package/src/vue/composables/use-stack-navigation.ts +28 -0
  440. package/src/vue/composables/use-tab-navigation.ts +25 -0
  441. package/src/vue/composables/use-typed-navigation.test.ts +205 -0
  442. package/src/vue/drawer/drawer.test.ts +451 -0
  443. package/src/vue/drawer/index.ts +550 -0
  444. package/src/vue/drawer-screen.ts +32 -0
  445. package/src/vue/index.ts +70 -0
  446. package/src/vue/linking.ts +69 -0
  447. package/src/vue/navigation-context.ts +87 -0
  448. package/src/vue/nested-navigation.test.ts +155 -0
  449. package/src/vue/screen.ts +52 -0
  450. package/src/vue/stack/index.ts +376 -0
  451. package/src/vue/stack/stack.test.ts +501 -0
  452. package/src/vue/tab-screen.ts +29 -0
  453. package/src/vue/tabs/index.ts +302 -0
  454. package/src/vue/tabs/tabs.test.ts +278 -0
  455. package/symbiote-navigation.podspec +84 -0
@@ -0,0 +1,550 @@
1
+ // Drawer, the Vue lifecycle half. The open/closed + focused-route router (drawer-router-state)
2
+ // and the pure swipe/geometry math (drawer-options) live in @symbiote-native/navigation core,
3
+ // shared verbatim with the React/Angular adapters; here Vue supplies the lifecycle - a plain ref
4
+ // for the router (Vue's twin of useReducer), a PanResponder for the swipe gesture (built ONCE in
5
+ // setup, its callbacks reading options/window-width/isOpen LIVE off Vue's own reactive `attrs` /
6
+ // composable refs at gesture time - Vue's reactivity already gives every gesture callback the
7
+ // CURRENT value with no ref-mirroring dance, unlike React's useRef(value); value = X every
8
+ // render), an Animated.Value driving the slide/opacity transforms, and expose() for the
9
+ // open/close/toggle/jumpTo handle - mirroring tabs.ts's shape (Tab is the closer sibling: both are
10
+ // fixed-route-list, no-react-native-screens navigators; Stack's push/pop + native-screen bridging
11
+ // don't apply here).
12
+ //
13
+ // FEASIBILITY NOTE (see the drawer skill / PR description for the full writeup, mirrored from
14
+ // react/drawer.ts): the REAL @react-navigation/drawer is built on react-native-gesture-handler +
15
+ // react-native-reanimated, neither of which this codebase depends on. What's built here reaches
16
+ // the same swipe-to-open/close + front/back/slide/permanent behavior using only PanResponder +
17
+ // Animated (both already in @symbiote-native/engine), which is sufficient for a solid drawer but
18
+ // NOT byte-for-byte parity - see the explicit gap list at the bottom of this file (verbatim from
19
+ // the React twin - the gaps are architectural, not adapter-specific).
20
+
21
+ import {
22
+ defineComponent,
23
+ h,
24
+ nextTick,
25
+ onMounted,
26
+ onUnmounted,
27
+ shallowRef,
28
+ useId,
29
+ watch,
30
+ } from '@vue/runtime-core';
31
+ import type { VNode } from '@vue/runtime-core';
32
+ import {
33
+ Animated,
34
+ PanResponder,
35
+ normalizeVueAttrs,
36
+ useWindowDimensions,
37
+ } from '@symbiote-native/vue';
38
+ import type { IPanResponderGestureState, ISymbioteEvent } from '@symbiote-native/vue';
39
+ import type { IDescriptor } from '@symbiote-native/components';
40
+ import { dlog } from '@symbiote-native/engine';
41
+ import type { IStyleProp, IViewStyle } from '@symbiote-native/engine';
42
+ import {
43
+ DRAWER_DEFAULT_OVERLAY_COLOR,
44
+ NAVIGATION_EVENT_BLUR,
45
+ NAVIGATION_EVENT_FOCUS,
46
+ createInitialDrawerRouterState,
47
+ createNavigationEmitter,
48
+ diffFocusedRoute,
49
+ drawerChildOrder,
50
+ drawerRouterReducer,
51
+ isDrawerAnimated,
52
+ isRecord,
53
+ renderDrawer,
54
+ resolveDragProgress,
55
+ resolveDrawerGeometry,
56
+ resolveDrawerSlotInterpolation,
57
+ resolveSwipeIntent,
58
+ shouldClaimDrawerSwipe,
59
+ } from '../../core';
60
+ import type {
61
+ IDrawerDescriptorMap,
62
+ IDrawerNavigatorHandle,
63
+ IDrawerOptions,
64
+ IDrawerPosition,
65
+ IDrawerRouterState,
66
+ IDrawerScreenOptions,
67
+ IDrawerSlot,
68
+ IDrawerType,
69
+ INavigationEmitter,
70
+ IRoute,
71
+ } from '../../core';
72
+ import { NavigationScope, injectNavigationScope } from '../navigation-context';
73
+ import { DrawerScreen } from '../drawer-screen';
74
+ import type { IDrawerScreenOptionsArgs, IDrawerScreenProps } from '../drawer-screen';
75
+
76
+ export type { IDrawerNavigatorHandle, IDrawerDescriptorMap } from '../../core';
77
+
78
+ // React's `renderDrawerContent` render-PROP becomes a scoped SLOT here, mirroring Pressable's own
79
+ // `slots.default(state)` scoped-slot precedent in this codebase.
80
+
81
+ export type IDrawerContentSlotProps = {
82
+ state: IDrawerRouterState;
83
+ descriptors: IDrawerDescriptorMap;
84
+ navigation: IDrawerNavigatorHandle;
85
+ };
86
+
87
+ // React's `children?: ReactNode` becomes Vue's default slot instead (registered screens, read via
88
+ // collectRegistry below); `renderDrawerContent` becomes the `drawerContent` scoped slot above.
89
+ export type IDrawerProps = IDrawerOptions & {
90
+ initialRouteName?: string;
91
+ drawerStyle?: IStyleProp<IViewStyle>;
92
+ };
93
+
94
+ type IDrawerRegistryEntry = {
95
+ component: IDrawerScreenProps['component'];
96
+ options: IDrawerScreenProps['options'];
97
+ initialParams: unknown;
98
+ };
99
+
100
+ function asString(value: unknown): string | undefined {
101
+ return typeof value === 'string' ? value : undefined;
102
+ }
103
+
104
+ function asNumber(value: unknown): number | undefined {
105
+ return typeof value === 'number' ? value : undefined;
106
+ }
107
+
108
+ function asBoolean(value: unknown): boolean | undefined {
109
+ return typeof value === 'boolean' ? value : undefined;
110
+ }
111
+
112
+ function isStyleProp(value: unknown): value is IStyleProp<IViewStyle> {
113
+ return isRecord(value);
114
+ }
115
+
116
+ const DRAWER_TYPES: ReadonlyArray<IDrawerType> = ['front', 'back', 'slide', 'permanent'];
117
+ // .some() itself doesn't narrow `value`'s type back at the call site - the `value is IDrawerType`
118
+ // predicate on THIS function is what lets asDrawerType's ternary return `value` typed, mirroring
119
+ // Modal's isOrientation guard (adapters/vue/src/components/modal.ts).
120
+ function isDrawerType(value: unknown): value is IDrawerType {
121
+ return typeof value === 'string' && DRAWER_TYPES.some(type => type === value);
122
+ }
123
+ function asDrawerType(value: unknown): IDrawerType | undefined {
124
+ return isDrawerType(value) ? value : undefined;
125
+ }
126
+
127
+ const DRAWER_POSITIONS: ReadonlyArray<IDrawerPosition> = ['left', 'right'];
128
+ function isDrawerPosition(value: unknown): value is IDrawerPosition {
129
+ return typeof value === 'string' && DRAWER_POSITIONS.some(position => position === value);
130
+ }
131
+ function asDrawerPosition(value: unknown): IDrawerPosition | undefined {
132
+ return isDrawerPosition(value) ? value : undefined;
133
+ }
134
+
135
+ function asComponent(value: unknown): IDrawerScreenProps['component'] | undefined {
136
+ if (typeof value === 'function') return value as IDrawerScreenProps['component'];
137
+ return isRecord(value) ? (value as IDrawerScreenProps['component']) : undefined;
138
+ }
139
+
140
+ // IDrawerScreenOptions carries only `title`/`drawerLabel`, small enough for direct field guards -
141
+ // kept as a single cast-at-the-edge helper anyway for symmetry with stack.ts/tabs.ts's
142
+ // asScreenOptions/asTabOptions (same CLAUDE.md-sanctioned I/O-edge narrowing).
143
+ function asDrawerScreenOptions(value: unknown): IDrawerScreenOptions | undefined {
144
+ return isRecord(value) ? (value as IDrawerScreenOptions) : undefined;
145
+ }
146
+
147
+ function asDrawerScreenOptionsOrResolver(value: unknown): IDrawerScreenProps['options'] {
148
+ if (typeof value === 'function') return value as IDrawerScreenProps['options'];
149
+ return asDrawerScreenOptions(value);
150
+ }
151
+
152
+ function collectRegistry(vnodes: readonly VNode[]): Map<string, IDrawerRegistryEntry> {
153
+ const registry = new Map<string, IDrawerRegistryEntry>();
154
+ for (const vnode of vnodes) {
155
+ if (vnode.type !== DrawerScreen || !isRecord(vnode.props)) continue;
156
+ const name = asString(vnode.props.name);
157
+ const component = asComponent(vnode.props.component);
158
+ if (name === undefined || component === undefined) continue;
159
+ registry.set(name, {
160
+ component,
161
+ options: asDrawerScreenOptionsOrResolver(vnode.props.options),
162
+ initialParams: vnode.props.initialParams,
163
+ });
164
+ }
165
+ return registry;
166
+ }
167
+
168
+ function resolveDrawerScreenOptions(
169
+ entry: IDrawerRegistryEntry,
170
+ screenComponentProps: IDrawerScreenOptionsArgs,
171
+ ): IDrawerScreenOptions {
172
+ if (typeof entry.options === 'function') return entry.options(screenComponentProps);
173
+ return entry.options ?? {};
174
+ }
175
+
176
+ const DRAWER_SNAP_DURATION = 250;
177
+
178
+ const DrawerImpl = defineComponent<IDrawerProps>(
179
+ (_props, { attrs: rawAttrs, slots, expose }) => {
180
+ const attrs = normalizeVueAttrs(rawAttrs);
181
+
182
+ // Read BEFORE this Drawer establishes its own per-screen NavigationScope below - becomes the
183
+ // `parent` link a nested screen's useNavigation().getParent() walks. undefined when this
184
+ // Drawer is the nesting root.
185
+ const ambientScopeRef = injectNavigationScope();
186
+
187
+ function currentOptions(): IDrawerOptions {
188
+ return {
189
+ drawerType: asDrawerType(attrs.drawerType),
190
+ drawerPosition: asDrawerPosition(attrs.drawerPosition),
191
+ drawerWidth: asNumber(attrs.drawerWidth),
192
+ overlayColor: asString(attrs.overlayColor),
193
+ swipeEnabled: asBoolean(attrs.swipeEnabled),
194
+ swipeEdgeWidth: asNumber(attrs.swipeEdgeWidth),
195
+ swipeMinDistance: asNumber(attrs.swipeMinDistance),
196
+ swipeMinVelocity: asNumber(attrs.swipeMinVelocity),
197
+ };
198
+ }
199
+
200
+ let routeSequence = 0;
201
+ const routeIdPrefix = useId();
202
+
203
+ function buildRoutes(registry: Map<string, IDrawerRegistryEntry>): IRoute<unknown>[] {
204
+ return Array.from(registry.entries()).map(([name, entry]) => {
205
+ routeSequence += 1;
206
+ return {
207
+ key: `${routeIdPrefix}-${name}-${routeSequence}`,
208
+ name,
209
+ params: entry.initialParams,
210
+ };
211
+ });
212
+ }
213
+
214
+ const initialRegistry = collectRegistry(slots.default?.() ?? []);
215
+ const initialRoutes = buildRoutes(initialRegistry);
216
+ if (initialRoutes.length === 0) dlog('Drawer: no <Drawer.Screen> children registered');
217
+
218
+ const state = shallowRef(
219
+ createInitialDrawerRouterState(initialRoutes, asString(attrs.initialRouteName)),
220
+ );
221
+
222
+ function dispatch(action: Parameters<typeof drawerRouterReducer>[1]): void {
223
+ state.value = drawerRouterReducer(state.value, action);
224
+ }
225
+
226
+ const windowDimensions = useWindowDimensions();
227
+
228
+ // progress: 0 closed -> 1 open, the single Animated.Value every slide/opacity transform below
229
+ // interpolates from. A plain `const` (not a ref): setup() runs once, so this needs no
230
+ // re-creation guard the way React's useRef(new Animated.Value(...)).current does.
231
+ const progress = new Animated.Value(state.value.isOpen ? 1 : 0);
232
+ // Where a drag STARTS from, in progress units. Always exactly 0 or 1: a gesture only ever
233
+ // begins at rest, since terminate/release always snap the value back to a resting state
234
+ // before another grant can fire.
235
+ let dragStartProgress = 0;
236
+
237
+ function animateProgressTo(open: boolean): void {
238
+ dlog(`Drawer: animateProgressTo(open=${open}) starting at t=${Date.now()}`);
239
+ Animated.timing(progress, {
240
+ toValue: open ? 1 : 0,
241
+ duration: DRAWER_SNAP_DURATION,
242
+ // Native-driver wiring is deferred for v1 - see this file's header feasibility note. The
243
+ // JS timing loop still drives every frame, same as any other non-native-driven
244
+ // Animated.timing in this codebase.
245
+ useNativeDriver: false,
246
+ }).start();
247
+ }
248
+
249
+ const handle: IDrawerNavigatorHandle = {
250
+ openDrawer: () => {
251
+ dlog(`Drawer: openDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
252
+ animateProgressTo(true);
253
+ dispatch({ type: 'openDrawer' });
254
+ },
255
+ closeDrawer: () => {
256
+ dlog(`Drawer: closeDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
257
+ animateProgressTo(false);
258
+ dispatch({ type: 'closeDrawer' });
259
+ },
260
+ toggleDrawer: () => {
261
+ dlog(`Drawer: toggleDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
262
+ animateProgressTo(!state.value.isOpen);
263
+ dispatch({ type: 'toggleDrawer' });
264
+ },
265
+ jumpTo: (name: string) => {
266
+ // Captured BEFORE dispatch: unlike React's isOpenRef (only refreshed at the TOP of the
267
+ // next render, so it still holds the pre-dispatch value here since React batches the
268
+ // re-render asynchronously), this ref's `.value` mutates SYNCHRONOUSLY inside dispatch -
269
+ // reading it after dispatch would already see the reducer's own isOpen: false.
270
+ const wasOpen = state.value.isOpen;
271
+ dispatch({ type: 'jumpTo', name });
272
+ if (wasOpen) animateProgressTo(false);
273
+ },
274
+ };
275
+ expose(handle);
276
+
277
+ const panResponder = PanResponder.create({
278
+ onStartShouldSetPanResponder: (
279
+ event: ISymbioteEvent,
280
+ gestureState: IPanResponderGestureState,
281
+ ): boolean =>
282
+ shouldClaimDrawerSwipe(
283
+ event,
284
+ gestureState,
285
+ windowDimensions.value.width,
286
+ state.value.isOpen,
287
+ currentOptions(),
288
+ 'start',
289
+ ),
290
+ onMoveShouldSetPanResponder: (
291
+ event: ISymbioteEvent,
292
+ gestureState: IPanResponderGestureState,
293
+ ): boolean =>
294
+ shouldClaimDrawerSwipe(
295
+ event,
296
+ gestureState,
297
+ windowDimensions.value.width,
298
+ state.value.isOpen,
299
+ currentOptions(),
300
+ 'move',
301
+ ),
302
+ onPanResponderGrant: (): void => {
303
+ dlog('Drawer: gesture grant');
304
+ dragStartProgress = state.value.isOpen ? 1 : 0;
305
+ },
306
+ onPanResponderMove: (
307
+ _event: ISymbioteEvent,
308
+ gestureState: IPanResponderGestureState,
309
+ ): void => {
310
+ progress.setValue(resolveDragProgress(gestureState, dragStartProgress, currentOptions()));
311
+ },
312
+ onPanResponderRelease: (
313
+ _event: ISymbioteEvent,
314
+ gestureState: IPanResponderGestureState,
315
+ ): void => {
316
+ const intent = resolveSwipeIntent(gestureState, state.value.isOpen, currentOptions());
317
+ const open = intent === 'open';
318
+ dlog(`Drawer: gesture release -> ${open ? 'open' : 'close'}`);
319
+ animateProgressTo(open);
320
+ dispatch(open ? { type: 'openDrawer' } : { type: 'closeDrawer' });
321
+ },
322
+ onPanResponderTerminate: (): void => {
323
+ dlog('Drawer: gesture terminated, snapping back');
324
+ animateProgressTo(state.value.isOpen);
325
+ },
326
+ });
327
+
328
+ // Only the focused route's screen is ever mounted (like Tab, unlike Stack which keeps every
329
+ // pushed route alive). One emitter per route.key, created lazily and cached for the
330
+ // navigator's whole lifetime (mirrors stack.ts's own `emitters` map) - see tabs.ts's matching
331
+ // comment for why a stable per-key lookup, not a recreate-on-change scheme, is what actually
332
+ // avoids racing Vue's own render/mount cycle regardless of which watch `flush` timing is used.
333
+ function focusedKeyOf(current: IDrawerRouterState): string | undefined {
334
+ return current.routes[current.index]?.key;
335
+ }
336
+
337
+ const emitters = new Map<string, INavigationEmitter>();
338
+ function emitterFor(routeKey: string): INavigationEmitter {
339
+ let emitter = emitters.get(routeKey);
340
+ if (emitter === undefined) {
341
+ emitter = createNavigationEmitter();
342
+ emitters.set(routeKey, emitter);
343
+ }
344
+ return emitter;
345
+ }
346
+
347
+ // Emitted from onMounted (NOT from inside the render closure below, which runs before the
348
+ // focused screen's own component ever mounts - an emit there always has zero subscribers).
349
+ let focusedRouteKey = focusedKeyOf(state.value);
350
+
351
+ onMounted(() => {
352
+ if (focusedRouteKey !== undefined) {
353
+ dlog(`Drawer: route "${focusedRouteKey}" focused at t=${Date.now()}`);
354
+ emitterFor(focusedRouteKey).emit(NAVIGATION_EVENT_FOCUS);
355
+ }
356
+ });
357
+
358
+ // The bookkeeping (which key is focused) updates immediately so the render closure below
359
+ // always reads the right route; the actual emit is deferred to nextTick(), which resolves
360
+ // only after the CURRENT flush cycle fully drains - including the newly-focused screen's own
361
+ // onMounted (subscribing its useIsFocused/useFocusEffect listeners). flush:'post' alone is
362
+ // NOT enough here: it only guarantees this callback runs after THIS component's own render
363
+ // effect, not after an arbitrary sibling post-flush job (a just-mounted child's onMounted)
364
+ // that may be queued after it in the same batch - nextTick is the one API that waits for the
365
+ // WHOLE cycle, not just this watcher's own slot in it.
366
+ watch(
367
+ () => focusedKeyOf(state.value),
368
+ nextKey => {
369
+ const { blurKey, focusKey } = diffFocusedRoute(focusedRouteKey, nextKey);
370
+ if (blurKey === undefined && focusKey === undefined) return;
371
+ focusedRouteKey = nextKey;
372
+ nextTick(() => {
373
+ if (blurKey !== undefined) {
374
+ dlog(`Drawer: route "${blurKey}" blurred at t=${Date.now()}`);
375
+ emitterFor(blurKey).emit(NAVIGATION_EVENT_BLUR);
376
+ }
377
+ if (focusKey !== undefined) {
378
+ dlog(`Drawer: route "${focusKey}" focused at t=${Date.now()}`);
379
+ emitterFor(focusKey).emit(NAVIGATION_EVENT_FOCUS);
380
+ }
381
+ });
382
+ },
383
+ );
384
+ onUnmounted(() => {
385
+ if (focusedRouteKey !== undefined) emitterFor(focusedRouteKey).emit(NAVIGATION_EVENT_BLUR);
386
+ });
387
+
388
+ return () => {
389
+ const registry = collectRegistry(slots.default?.() ?? []);
390
+ const options = currentOptions();
391
+ const drawerStyle = isStyleProp(attrs.drawerStyle) ? attrs.drawerStyle : undefined;
392
+
393
+ if (registry.size === 0) dlog('Drawer: no <Drawer.Screen> children registered');
394
+
395
+ const animated = isDrawerAnimated(options);
396
+ const geometry = resolveDrawerGeometry(options);
397
+
398
+ const panelTranslateX = animated
399
+ ? progress.interpolate(resolveDrawerSlotInterpolation(geometry, 'panel').translateX)
400
+ : undefined;
401
+ const contentTranslateX = animated
402
+ ? progress.interpolate(resolveDrawerSlotInterpolation(geometry, 'content').translateX)
403
+ : undefined;
404
+ // The overlay is a full-screen absolutely-positioned sibling BELOW content in paint order
405
+ // (see render-drawer.ts's drawerChildOrder) - for 'front' that's fine since content never
406
+ // moves, but for 'slide' content itself translates away by contentTranslateX, and without
407
+ // following it the overlay stays pinned full-screen. resolveDrawerSlotInterpolation's
408
+ // 'overlay' branch ties its translateX to the SAME range as content's for exactly this
409
+ // reason, so overlayOpacity and overlayTranslateX below share one resolved config.
410
+ const overlayInterpolation = animated
411
+ ? resolveDrawerSlotInterpolation(geometry, 'overlay')
412
+ : undefined;
413
+ const overlayOpacity = overlayInterpolation
414
+ ? progress.interpolate(overlayInterpolation.opacity)
415
+ : undefined;
416
+ const overlayTranslateX = overlayInterpolation
417
+ ? progress.interpolate(overlayInterpolation.translateX)
418
+ : undefined;
419
+
420
+ const focusedRoute = state.value.routes[state.value.index];
421
+ const focusedEntry = focusedRoute ? registry.get(focusedRoute.name) : undefined;
422
+ if (focusedRoute && !focusedEntry) {
423
+ dlog(`Drawer: no screen registered for route name "${focusedRoute.name}"`);
424
+ }
425
+
426
+ const content =
427
+ focusedEntry && focusedRoute
428
+ ? h(
429
+ NavigationScope,
430
+ {
431
+ value: {
432
+ route: focusedRoute,
433
+ navigation: handle,
434
+ emitter: emitterFor(focusedRoute.key),
435
+ parent: ambientScopeRef?.value,
436
+ },
437
+ },
438
+ // No route/navigation props: the screen reads both through composables off the
439
+ // NavigationScope provided just above (useRoute / useDrawerNavigation).
440
+ () => h(focusedEntry.component),
441
+ )
442
+ : null;
443
+
444
+ const descriptors: IDrawerDescriptorMap = {};
445
+ for (const route of state.value.routes) {
446
+ const entry = registry.get(route.name);
447
+ if (entry === undefined) continue;
448
+ descriptors[route.key] = {
449
+ options: resolveDrawerScreenOptions(entry, { route, navigation: handle }),
450
+ navigation: handle,
451
+ };
452
+ }
453
+
454
+ const drawerContent =
455
+ slots.drawerContent?.({ state: state.value, descriptors, navigation: handle }) ?? null;
456
+
457
+ const root = renderDrawer(
458
+ {
459
+ overlayColor: asString(attrs.overlayColor) ?? DRAWER_DEFAULT_OVERLAY_COLOR,
460
+ drawerStyle,
461
+ contentPassthrough: {},
462
+ overlayPassthrough: animated
463
+ ? {
464
+ pointerEvents: state.value.isOpen ? 'auto' : 'none',
465
+ onStartShouldSetResponder: () => true,
466
+ onResponderRelease: () => {
467
+ animateProgressTo(false);
468
+ dispatch({ type: 'closeDrawer' });
469
+ },
470
+ }
471
+ : {},
472
+ panelPassthrough: {},
473
+ },
474
+ options,
475
+ );
476
+
477
+ const order = drawerChildOrder(options);
478
+ const slotDescriptors = new Map<IDrawerSlot, IDescriptor>();
479
+ order.forEach((slot, index) => {
480
+ const descriptor = root.children[index];
481
+ if (typeof descriptor !== 'string') slotDescriptors.set(slot, descriptor);
482
+ });
483
+
484
+ const slotChildren: Record<IDrawerSlot, VNode[] | null> = {
485
+ content: content === null ? [] : [content],
486
+ overlay: null,
487
+ panel: drawerContent,
488
+ };
489
+ // Each animated style holds an AnimatedInterpolation node, not a plain number/color - it
490
+ // feeds only Animated.View's deliberately permissive `style?: unknown`, never the plain-
491
+ // IViewStyle branch below, so this stays untyped rather than widening IViewStyle.
492
+ const slotAnimatedStyle: Record<IDrawerSlot, unknown> = {
493
+ content:
494
+ contentTranslateX === undefined
495
+ ? undefined
496
+ : { transform: [{ translateX: contentTranslateX }] },
497
+ overlay:
498
+ overlayOpacity === undefined
499
+ ? undefined
500
+ : { opacity: overlayOpacity, transform: [{ translateX: overlayTranslateX }] },
501
+ panel:
502
+ panelTranslateX === undefined
503
+ ? undefined
504
+ : { transform: [{ translateX: panelTranslateX }] },
505
+ };
506
+
507
+ function renderSlot(slot: IDrawerSlot): VNode | null {
508
+ const descriptor = slotDescriptors.get(slot);
509
+ if (descriptor === undefined) return null;
510
+ const children = slotChildren[slot] ?? [];
511
+ const animatedStyle = slotAnimatedStyle[slot];
512
+ if (animatedStyle === undefined) {
513
+ return h(descriptor.type, { key: descriptor.key, ...descriptor.props }, children);
514
+ }
515
+ const style = [descriptor.props.style, animatedStyle];
516
+ return h(Animated.View, { key: descriptor.key, ...descriptor.props, style }, children);
517
+ }
518
+
519
+ const drawerChildren = order
520
+ .map(renderSlot)
521
+ .filter((element): element is VNode => element !== null);
522
+
523
+ return h(
524
+ 'symbiote-view',
525
+ { style: root.props.style, ...panResponder.panHandlers },
526
+ drawerChildren,
527
+ );
528
+ };
529
+ },
530
+ { name: 'Drawer', inheritAttrs: false },
531
+ );
532
+
533
+ export const Drawer = Object.assign(DrawerImpl, { Screen: DrawerScreen });
534
+
535
+ // --- Explicit gap list vs the real react-native-gesture-handler + react-native-reanimated
536
+ // @react-navigation/drawer (confirmed against its current docs, mirrored verbatim from the React
537
+ // twin - the gaps are architectural, not adapter-specific) ---
538
+ // 1. `configureGestureHandler` - a raw react-native-gesture-handler `Gesture` object escape
539
+ // hatch. No PanResponder equivalent exists; not ported.
540
+ // 2. Simultaneous/failure gesture RELATIONSHIPS (gesture-handler's declarative composition vs a
541
+ // nested ScrollView, another PanResponder, etc.) - PanResponder only offers negotiation via the
542
+ // should-set boolean gates used here (edge-start + dominant-axis), which is more prone to an
543
+ // accidental hijack of a nested horizontal ScrollView/Swiper than gesture-handler's system.
544
+ // 3. `useDrawerProgress` - a Reanimated SharedValue read on the UI thread. `progress` here is a
545
+ // JS-thread AnimatedValue; interpolating it for consumer-facing content animation works, but
546
+ // without native-driver wiring (gap noted above) it does not carry the same synchronous
547
+ // UI-thread guarantee under JS-thread load.
548
+ // 4. `hideStatusBarOnOpen` / `keyboardDismissMode` / `statusBarAnimation` / `overlayStyle` - not
549
+ // wired in this pass; straightforward additions once StatusBar/Keyboard module wiring is
550
+ // needed here (not a PanResponder/Animated limitation, just unscoped for v1).
@@ -0,0 +1,32 @@
1
+ // Drawer.Screen: a declarative marker, never rendered on its own - Drawer reads its props via a
2
+ // default-slot scan (see drawer.ts's collectRegistry) to build the static name -> {component,
3
+ // options} registry, then mounts the FOCUSED route's component. The Vue twin of
4
+ // react/drawer-screen.ts's DrawerScreen, mirroring tab-screen.ts's slot-scanning marker (Tab is
5
+ // the closer sibling - both are fixed-route-list/no-push navigators) and screen.ts's; see
6
+ // CLAUDE.md <third_party_rn_packages_are_react_only> - this and Drawer import nothing from
7
+ // react-native.
8
+
9
+ import { defineComponent } from '@vue/runtime-core';
10
+ import type { Component } from '@vue/runtime-core';
11
+ import type { IDrawerScreenOptions, IRoute, IDrawerNavigatorHandle } from '../core';
12
+
13
+ export type IDrawerScreenOptionsArgs = {
14
+ route: IRoute<unknown>;
15
+ navigation: IDrawerNavigatorHandle;
16
+ };
17
+
18
+ export type IDrawerScreenOptionsResolver = (
19
+ props: IDrawerScreenOptionsArgs,
20
+ ) => IDrawerScreenOptions;
21
+
22
+ export type IDrawerScreenProps = {
23
+ name: string;
24
+ component: Component;
25
+ options?: IDrawerScreenOptions | IDrawerScreenOptionsResolver;
26
+ initialParams?: unknown;
27
+ };
28
+
29
+ export const DrawerScreen = defineComponent<IDrawerScreenProps>(() => () => null, {
30
+ name: 'DrawerScreen',
31
+ inheritAttrs: false,
32
+ });
@@ -0,0 +1,70 @@
1
+ // @symbiote-native/navigation/vue: the Vue native-stack navigator over react-native-screens'
2
+ // native view primitives. Importing this barrel first registers the native views' ViewConfigs
3
+ // (../register, a side-effect import of the three codegen specs - never react-native-screens' own
4
+ // React components), then exposes Stack (with Stack.Screen attached) and the navigator handle.
5
+
6
+ import '../register';
7
+
8
+ export { Stack } from './stack';
9
+ export type { INavigatorHandle, IStackProps } from './stack';
10
+ export { Screen } from './screen';
11
+ export type {
12
+ IScreenOptionsArgs,
13
+ IScreenOptionsResolver,
14
+ IScreenProps,
15
+ IVueScreenOptions,
16
+ IVueSearchBarOptions,
17
+ } from './screen';
18
+ export type { IScreenOptions, IStackAnimation, IStackPresentation } from '../core';
19
+
20
+ export {
21
+ useNavigation,
22
+ useStackNavigation,
23
+ useTabNavigation,
24
+ useDrawerNavigation,
25
+ useRoute,
26
+ useIsFocused,
27
+ useFocusEffect,
28
+ useNavigationState,
29
+ } from './composables';
30
+ export type {
31
+ INavigationHandle,
32
+ IStackNavigationHandle,
33
+ ITabNavigationHandle,
34
+ IDrawerNavigationHandle,
35
+ } from './composables';
36
+ export type { INavigationScopeValue, IAnyNavigatorHandle } from './navigation-context';
37
+
38
+ export { useLinkingIntegration } from './linking';
39
+ export type { ILinkingConfig, IScreenLinkingConfig } from '../core';
40
+
41
+ // Tab: the bottom-tabs navigator, a PURE-JS UI (no react-native-screens views involved, so no
42
+ // extra ViewConfig registration is needed beyond the ../register import above).
43
+ export { Tab } from './tabs';
44
+ export type { ITabNavigatorHandle, ITabProps } from './tabs';
45
+ export { TabScreen } from './tab-screen';
46
+ export type {
47
+ ITabScreenOptionsArgs,
48
+ ITabScreenOptionsResolver,
49
+ ITabScreenProps,
50
+ } from './tab-screen';
51
+ export type { ITabOptions, ITabBarIcon } from '../core';
52
+
53
+ // Drawer: the swipeable drawer navigator, a PURE-JS UI (PanResponder + Animated, no
54
+ // react-native-screens views involved, so no extra ViewConfig registration is needed beyond the
55
+ // ../register import above). See drawer.ts's header for the feasibility note re:
56
+ // react-native-gesture-handler / react-native-reanimated parity gaps.
57
+ export { Drawer } from './drawer';
58
+ export type {
59
+ IDrawerContentSlotProps,
60
+ IDrawerNavigatorHandle,
61
+ IDrawerProps,
62
+ IDrawerDescriptorMap,
63
+ } from './drawer';
64
+ export { DrawerScreen } from './drawer-screen';
65
+ export type {
66
+ IDrawerScreenOptionsArgs,
67
+ IDrawerScreenOptionsResolver,
68
+ IDrawerScreenProps,
69
+ } from './drawer-screen';
70
+ export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition } from '../core';