@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,390 @@
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
+ import { defineComponent, h, nextTick, onMounted, onUnmounted, shallowRef, useId, watch, } from '@vue/runtime-core';
21
+ import { Animated, PanResponder, normalizeVueAttrs, useWindowDimensions, } from '@symbiote-native/vue';
22
+ import { dlog } from '@symbiote-native/engine';
23
+ import { DRAWER_DEFAULT_OVERLAY_COLOR, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_FOCUS, createInitialDrawerRouterState, createNavigationEmitter, diffFocusedRoute, drawerChildOrder, drawerRouterReducer, isDrawerAnimated, isRecord, renderDrawer, resolveDragProgress, resolveDrawerGeometry, resolveDrawerSlotInterpolation, resolveSwipeIntent, shouldClaimDrawerSwipe, } from '../../core/index.js';
24
+ import { NavigationScope, injectNavigationScope } from '../navigation-context.js';
25
+ import { DrawerScreen } from '../drawer-screen.js';
26
+ function asString(value) {
27
+ return typeof value === 'string' ? value : undefined;
28
+ }
29
+ function asNumber(value) {
30
+ return typeof value === 'number' ? value : undefined;
31
+ }
32
+ function asBoolean(value) {
33
+ return typeof value === 'boolean' ? value : undefined;
34
+ }
35
+ function isStyleProp(value) {
36
+ return isRecord(value);
37
+ }
38
+ const DRAWER_TYPES = ['front', 'back', 'slide', 'permanent'];
39
+ // .some() itself doesn't narrow `value`'s type back at the call site - the `value is IDrawerType`
40
+ // predicate on THIS function is what lets asDrawerType's ternary return `value` typed, mirroring
41
+ // Modal's isOrientation guard (adapters/vue/src/components/modal.ts).
42
+ function isDrawerType(value) {
43
+ return typeof value === 'string' && DRAWER_TYPES.some(type => type === value);
44
+ }
45
+ function asDrawerType(value) {
46
+ return isDrawerType(value) ? value : undefined;
47
+ }
48
+ const DRAWER_POSITIONS = ['left', 'right'];
49
+ function isDrawerPosition(value) {
50
+ return typeof value === 'string' && DRAWER_POSITIONS.some(position => position === value);
51
+ }
52
+ function asDrawerPosition(value) {
53
+ return isDrawerPosition(value) ? value : undefined;
54
+ }
55
+ function asComponent(value) {
56
+ if (typeof value === 'function')
57
+ return value;
58
+ return isRecord(value) ? value : undefined;
59
+ }
60
+ // IDrawerScreenOptions carries only `title`/`drawerLabel`, small enough for direct field guards -
61
+ // kept as a single cast-at-the-edge helper anyway for symmetry with stack.ts/tabs.ts's
62
+ // asScreenOptions/asTabOptions (same CLAUDE.md-sanctioned I/O-edge narrowing).
63
+ function asDrawerScreenOptions(value) {
64
+ return isRecord(value) ? value : undefined;
65
+ }
66
+ function asDrawerScreenOptionsOrResolver(value) {
67
+ if (typeof value === 'function')
68
+ return value;
69
+ return asDrawerScreenOptions(value);
70
+ }
71
+ function collectRegistry(vnodes) {
72
+ const registry = new Map();
73
+ for (const vnode of vnodes) {
74
+ if (vnode.type !== DrawerScreen || !isRecord(vnode.props))
75
+ continue;
76
+ const name = asString(vnode.props.name);
77
+ const component = asComponent(vnode.props.component);
78
+ if (name === undefined || component === undefined)
79
+ continue;
80
+ registry.set(name, {
81
+ component,
82
+ options: asDrawerScreenOptionsOrResolver(vnode.props.options),
83
+ initialParams: vnode.props.initialParams,
84
+ });
85
+ }
86
+ return registry;
87
+ }
88
+ function resolveDrawerScreenOptions(entry, screenComponentProps) {
89
+ if (typeof entry.options === 'function')
90
+ return entry.options(screenComponentProps);
91
+ return entry.options ?? {};
92
+ }
93
+ const DRAWER_SNAP_DURATION = 250;
94
+ const DrawerImpl = defineComponent((_props, { attrs: rawAttrs, slots, expose }) => {
95
+ const attrs = normalizeVueAttrs(rawAttrs);
96
+ // Read BEFORE this Drawer establishes its own per-screen NavigationScope below - becomes the
97
+ // `parent` link a nested screen's useNavigation().getParent() walks. undefined when this
98
+ // Drawer is the nesting root.
99
+ const ambientScopeRef = injectNavigationScope();
100
+ function currentOptions() {
101
+ return {
102
+ drawerType: asDrawerType(attrs.drawerType),
103
+ drawerPosition: asDrawerPosition(attrs.drawerPosition),
104
+ drawerWidth: asNumber(attrs.drawerWidth),
105
+ overlayColor: asString(attrs.overlayColor),
106
+ swipeEnabled: asBoolean(attrs.swipeEnabled),
107
+ swipeEdgeWidth: asNumber(attrs.swipeEdgeWidth),
108
+ swipeMinDistance: asNumber(attrs.swipeMinDistance),
109
+ swipeMinVelocity: asNumber(attrs.swipeMinVelocity),
110
+ };
111
+ }
112
+ let routeSequence = 0;
113
+ const routeIdPrefix = useId();
114
+ function buildRoutes(registry) {
115
+ return Array.from(registry.entries()).map(([name, entry]) => {
116
+ routeSequence += 1;
117
+ return {
118
+ key: `${routeIdPrefix}-${name}-${routeSequence}`,
119
+ name,
120
+ params: entry.initialParams,
121
+ };
122
+ });
123
+ }
124
+ const initialRegistry = collectRegistry(slots.default?.() ?? []);
125
+ const initialRoutes = buildRoutes(initialRegistry);
126
+ if (initialRoutes.length === 0)
127
+ dlog('Drawer: no <Drawer.Screen> children registered');
128
+ const state = shallowRef(createInitialDrawerRouterState(initialRoutes, asString(attrs.initialRouteName)));
129
+ function dispatch(action) {
130
+ state.value = drawerRouterReducer(state.value, action);
131
+ }
132
+ const windowDimensions = useWindowDimensions();
133
+ // progress: 0 closed -> 1 open, the single Animated.Value every slide/opacity transform below
134
+ // interpolates from. A plain `const` (not a ref): setup() runs once, so this needs no
135
+ // re-creation guard the way React's useRef(new Animated.Value(...)).current does.
136
+ const progress = new Animated.Value(state.value.isOpen ? 1 : 0);
137
+ // Where a drag STARTS from, in progress units. Always exactly 0 or 1: a gesture only ever
138
+ // begins at rest, since terminate/release always snap the value back to a resting state
139
+ // before another grant can fire.
140
+ let dragStartProgress = 0;
141
+ function animateProgressTo(open) {
142
+ dlog(`Drawer: animateProgressTo(open=${open}) starting at t=${Date.now()}`);
143
+ Animated.timing(progress, {
144
+ toValue: open ? 1 : 0,
145
+ duration: DRAWER_SNAP_DURATION,
146
+ // Native-driver wiring is deferred for v1 - see this file's header feasibility note. The
147
+ // JS timing loop still drives every frame, same as any other non-native-driven
148
+ // Animated.timing in this codebase.
149
+ useNativeDriver: false,
150
+ }).start();
151
+ }
152
+ const handle = {
153
+ openDrawer: () => {
154
+ dlog(`Drawer: openDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
155
+ animateProgressTo(true);
156
+ dispatch({ type: 'openDrawer' });
157
+ },
158
+ closeDrawer: () => {
159
+ dlog(`Drawer: closeDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
160
+ animateProgressTo(false);
161
+ dispatch({ type: 'closeDrawer' });
162
+ },
163
+ toggleDrawer: () => {
164
+ dlog(`Drawer: toggleDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
165
+ animateProgressTo(!state.value.isOpen);
166
+ dispatch({ type: 'toggleDrawer' });
167
+ },
168
+ jumpTo: (name) => {
169
+ // Captured BEFORE dispatch: unlike React's isOpenRef (only refreshed at the TOP of the
170
+ // next render, so it still holds the pre-dispatch value here since React batches the
171
+ // re-render asynchronously), this ref's `.value` mutates SYNCHRONOUSLY inside dispatch -
172
+ // reading it after dispatch would already see the reducer's own isOpen: false.
173
+ const wasOpen = state.value.isOpen;
174
+ dispatch({ type: 'jumpTo', name });
175
+ if (wasOpen)
176
+ animateProgressTo(false);
177
+ },
178
+ };
179
+ expose(handle);
180
+ const panResponder = PanResponder.create({
181
+ onStartShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, windowDimensions.value.width, state.value.isOpen, currentOptions(), 'start'),
182
+ onMoveShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, windowDimensions.value.width, state.value.isOpen, currentOptions(), 'move'),
183
+ onPanResponderGrant: () => {
184
+ dlog('Drawer: gesture grant');
185
+ dragStartProgress = state.value.isOpen ? 1 : 0;
186
+ },
187
+ onPanResponderMove: (_event, gestureState) => {
188
+ progress.setValue(resolveDragProgress(gestureState, dragStartProgress, currentOptions()));
189
+ },
190
+ onPanResponderRelease: (_event, gestureState) => {
191
+ const intent = resolveSwipeIntent(gestureState, state.value.isOpen, currentOptions());
192
+ const open = intent === 'open';
193
+ dlog(`Drawer: gesture release -> ${open ? 'open' : 'close'}`);
194
+ animateProgressTo(open);
195
+ dispatch(open ? { type: 'openDrawer' } : { type: 'closeDrawer' });
196
+ },
197
+ onPanResponderTerminate: () => {
198
+ dlog('Drawer: gesture terminated, snapping back');
199
+ animateProgressTo(state.value.isOpen);
200
+ },
201
+ });
202
+ // Only the focused route's screen is ever mounted (like Tab, unlike Stack which keeps every
203
+ // pushed route alive). One emitter per route.key, created lazily and cached for the
204
+ // navigator's whole lifetime (mirrors stack.ts's own `emitters` map) - see tabs.ts's matching
205
+ // comment for why a stable per-key lookup, not a recreate-on-change scheme, is what actually
206
+ // avoids racing Vue's own render/mount cycle regardless of which watch `flush` timing is used.
207
+ function focusedKeyOf(current) {
208
+ return current.routes[current.index]?.key;
209
+ }
210
+ const emitters = new Map();
211
+ function emitterFor(routeKey) {
212
+ let emitter = emitters.get(routeKey);
213
+ if (emitter === undefined) {
214
+ emitter = createNavigationEmitter();
215
+ emitters.set(routeKey, emitter);
216
+ }
217
+ return emitter;
218
+ }
219
+ // Emitted from onMounted (NOT from inside the render closure below, which runs before the
220
+ // focused screen's own component ever mounts - an emit there always has zero subscribers).
221
+ let focusedRouteKey = focusedKeyOf(state.value);
222
+ onMounted(() => {
223
+ if (focusedRouteKey !== undefined) {
224
+ dlog(`Drawer: route "${focusedRouteKey}" focused at t=${Date.now()}`);
225
+ emitterFor(focusedRouteKey).emit(NAVIGATION_EVENT_FOCUS);
226
+ }
227
+ });
228
+ // The bookkeeping (which key is focused) updates immediately so the render closure below
229
+ // always reads the right route; the actual emit is deferred to nextTick(), which resolves
230
+ // only after the CURRENT flush cycle fully drains - including the newly-focused screen's own
231
+ // onMounted (subscribing its useIsFocused/useFocusEffect listeners). flush:'post' alone is
232
+ // NOT enough here: it only guarantees this callback runs after THIS component's own render
233
+ // effect, not after an arbitrary sibling post-flush job (a just-mounted child's onMounted)
234
+ // that may be queued after it in the same batch - nextTick is the one API that waits for the
235
+ // WHOLE cycle, not just this watcher's own slot in it.
236
+ watch(() => focusedKeyOf(state.value), nextKey => {
237
+ const { blurKey, focusKey } = diffFocusedRoute(focusedRouteKey, nextKey);
238
+ if (blurKey === undefined && focusKey === undefined)
239
+ return;
240
+ focusedRouteKey = nextKey;
241
+ nextTick(() => {
242
+ if (blurKey !== undefined) {
243
+ dlog(`Drawer: route "${blurKey}" blurred at t=${Date.now()}`);
244
+ emitterFor(blurKey).emit(NAVIGATION_EVENT_BLUR);
245
+ }
246
+ if (focusKey !== undefined) {
247
+ dlog(`Drawer: route "${focusKey}" focused at t=${Date.now()}`);
248
+ emitterFor(focusKey).emit(NAVIGATION_EVENT_FOCUS);
249
+ }
250
+ });
251
+ });
252
+ onUnmounted(() => {
253
+ if (focusedRouteKey !== undefined)
254
+ emitterFor(focusedRouteKey).emit(NAVIGATION_EVENT_BLUR);
255
+ });
256
+ return () => {
257
+ const registry = collectRegistry(slots.default?.() ?? []);
258
+ const options = currentOptions();
259
+ const drawerStyle = isStyleProp(attrs.drawerStyle) ? attrs.drawerStyle : undefined;
260
+ if (registry.size === 0)
261
+ dlog('Drawer: no <Drawer.Screen> children registered');
262
+ const animated = isDrawerAnimated(options);
263
+ const geometry = resolveDrawerGeometry(options);
264
+ const panelTranslateX = animated
265
+ ? progress.interpolate(resolveDrawerSlotInterpolation(geometry, 'panel').translateX)
266
+ : undefined;
267
+ const contentTranslateX = animated
268
+ ? progress.interpolate(resolveDrawerSlotInterpolation(geometry, 'content').translateX)
269
+ : undefined;
270
+ // The overlay is a full-screen absolutely-positioned sibling BELOW content in paint order
271
+ // (see render-drawer.ts's drawerChildOrder) - for 'front' that's fine since content never
272
+ // moves, but for 'slide' content itself translates away by contentTranslateX, and without
273
+ // following it the overlay stays pinned full-screen. resolveDrawerSlotInterpolation's
274
+ // 'overlay' branch ties its translateX to the SAME range as content's for exactly this
275
+ // reason, so overlayOpacity and overlayTranslateX below share one resolved config.
276
+ const overlayInterpolation = animated
277
+ ? resolveDrawerSlotInterpolation(geometry, 'overlay')
278
+ : undefined;
279
+ const overlayOpacity = overlayInterpolation
280
+ ? progress.interpolate(overlayInterpolation.opacity)
281
+ : undefined;
282
+ const overlayTranslateX = overlayInterpolation
283
+ ? progress.interpolate(overlayInterpolation.translateX)
284
+ : undefined;
285
+ const focusedRoute = state.value.routes[state.value.index];
286
+ const focusedEntry = focusedRoute ? registry.get(focusedRoute.name) : undefined;
287
+ if (focusedRoute && !focusedEntry) {
288
+ dlog(`Drawer: no screen registered for route name "${focusedRoute.name}"`);
289
+ }
290
+ const content = focusedEntry && focusedRoute
291
+ ? h(NavigationScope, {
292
+ value: {
293
+ route: focusedRoute,
294
+ navigation: handle,
295
+ emitter: emitterFor(focusedRoute.key),
296
+ parent: ambientScopeRef?.value,
297
+ },
298
+ },
299
+ // No route/navigation props: the screen reads both through composables off the
300
+ // NavigationScope provided just above (useRoute / useDrawerNavigation).
301
+ () => h(focusedEntry.component))
302
+ : null;
303
+ const descriptors = {};
304
+ for (const route of state.value.routes) {
305
+ const entry = registry.get(route.name);
306
+ if (entry === undefined)
307
+ continue;
308
+ descriptors[route.key] = {
309
+ options: resolveDrawerScreenOptions(entry, { route, navigation: handle }),
310
+ navigation: handle,
311
+ };
312
+ }
313
+ const drawerContent = slots.drawerContent?.({ state: state.value, descriptors, navigation: handle }) ?? null;
314
+ const root = renderDrawer({
315
+ overlayColor: asString(attrs.overlayColor) ?? DRAWER_DEFAULT_OVERLAY_COLOR,
316
+ drawerStyle,
317
+ contentPassthrough: {},
318
+ overlayPassthrough: animated
319
+ ? {
320
+ pointerEvents: state.value.isOpen ? 'auto' : 'none',
321
+ onStartShouldSetResponder: () => true,
322
+ onResponderRelease: () => {
323
+ animateProgressTo(false);
324
+ dispatch({ type: 'closeDrawer' });
325
+ },
326
+ }
327
+ : {},
328
+ panelPassthrough: {},
329
+ }, options);
330
+ const order = drawerChildOrder(options);
331
+ const slotDescriptors = new Map();
332
+ order.forEach((slot, index) => {
333
+ const descriptor = root.children[index];
334
+ if (typeof descriptor !== 'string')
335
+ slotDescriptors.set(slot, descriptor);
336
+ });
337
+ const slotChildren = {
338
+ content: content === null ? [] : [content],
339
+ overlay: null,
340
+ panel: drawerContent,
341
+ };
342
+ // Each animated style holds an AnimatedInterpolation node, not a plain number/color - it
343
+ // feeds only Animated.View's deliberately permissive `style?: unknown`, never the plain-
344
+ // IViewStyle branch below, so this stays untyped rather than widening IViewStyle.
345
+ const slotAnimatedStyle = {
346
+ content: contentTranslateX === undefined
347
+ ? undefined
348
+ : { transform: [{ translateX: contentTranslateX }] },
349
+ overlay: overlayOpacity === undefined
350
+ ? undefined
351
+ : { opacity: overlayOpacity, transform: [{ translateX: overlayTranslateX }] },
352
+ panel: panelTranslateX === undefined
353
+ ? undefined
354
+ : { transform: [{ translateX: panelTranslateX }] },
355
+ };
356
+ function renderSlot(slot) {
357
+ const descriptor = slotDescriptors.get(slot);
358
+ if (descriptor === undefined)
359
+ return null;
360
+ const children = slotChildren[slot] ?? [];
361
+ const animatedStyle = slotAnimatedStyle[slot];
362
+ if (animatedStyle === undefined) {
363
+ return h(descriptor.type, { key: descriptor.key, ...descriptor.props }, children);
364
+ }
365
+ const style = [descriptor.props.style, animatedStyle];
366
+ return h(Animated.View, { key: descriptor.key, ...descriptor.props, style }, children);
367
+ }
368
+ const drawerChildren = order
369
+ .map(renderSlot)
370
+ .filter((element) => element !== null);
371
+ return h('symbiote-view', { style: root.props.style, ...panResponder.panHandlers }, drawerChildren);
372
+ };
373
+ }, { name: 'Drawer', inheritAttrs: false });
374
+ export const Drawer = Object.assign(DrawerImpl, { Screen: DrawerScreen });
375
+ // --- Explicit gap list vs the real react-native-gesture-handler + react-native-reanimated
376
+ // @react-navigation/drawer (confirmed against its current docs, mirrored verbatim from the React
377
+ // twin - the gaps are architectural, not adapter-specific) ---
378
+ // 1. `configureGestureHandler` - a raw react-native-gesture-handler `Gesture` object escape
379
+ // hatch. No PanResponder equivalent exists; not ported.
380
+ // 2. Simultaneous/failure gesture RELATIONSHIPS (gesture-handler's declarative composition vs a
381
+ // nested ScrollView, another PanResponder, etc.) - PanResponder only offers negotiation via the
382
+ // should-set boolean gates used here (edge-start + dominant-axis), which is more prone to an
383
+ // accidental hijack of a nested horizontal ScrollView/Swiper than gesture-handler's system.
384
+ // 3. `useDrawerProgress` - a Reanimated SharedValue read on the UI thread. `progress` here is a
385
+ // JS-thread AnimatedValue; interpolating it for consumer-facing content animation works, but
386
+ // without native-driver wiring (gap noted above) it does not carry the same synchronous
387
+ // UI-thread guarantee under JS-thread load.
388
+ // 4. `hideStatusBarOnOpen` / `keyboardDismissMode` / `statusBarAnimation` / `overlayStyle` - not
389
+ // wired in this pass; straightforward additions once StatusBar/Keyboard module wiring is
390
+ // needed here (not a PanResponder/Animated limitation, just unscoped for v1).
@@ -0,0 +1,14 @@
1
+ import type { Component } from '@vue/runtime-core';
2
+ import type { IDrawerScreenOptions, IRoute, IDrawerNavigatorHandle } from '../core';
3
+ export type IDrawerScreenOptionsArgs = {
4
+ route: IRoute<unknown>;
5
+ navigation: IDrawerNavigatorHandle;
6
+ };
7
+ export type IDrawerScreenOptionsResolver = (props: IDrawerScreenOptionsArgs) => IDrawerScreenOptions;
8
+ export type IDrawerScreenProps = {
9
+ name: string;
10
+ component: Component;
11
+ options?: IDrawerScreenOptions | IDrawerScreenOptionsResolver;
12
+ initialParams?: unknown;
13
+ };
14
+ export declare const DrawerScreen: import("vue").DefineSetupFnComponent<IDrawerScreenProps, {}, {}, IDrawerScreenProps & {}, import("vue").PublicProps>;
@@ -0,0 +1,12 @@
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
+ import { defineComponent } from '@vue/runtime-core';
9
+ export const DrawerScreen = defineComponent(() => () => null, {
10
+ name: 'DrawerScreen',
11
+ inheritAttrs: false,
12
+ });
@@ -0,0 +1,21 @@
1
+ import '../register';
2
+ export { Stack } from './stack';
3
+ export type { INavigatorHandle, IStackProps } from './stack';
4
+ export { Screen } from './screen';
5
+ export type { IScreenOptionsArgs, IScreenOptionsResolver, IScreenProps, IVueScreenOptions, IVueSearchBarOptions, } from './screen';
6
+ export type { IScreenOptions, IStackAnimation, IStackPresentation } from '../core';
7
+ export { useNavigation, useStackNavigation, useTabNavigation, useDrawerNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './composables';
8
+ export type { INavigationHandle, IStackNavigationHandle, ITabNavigationHandle, IDrawerNavigationHandle, } from './composables';
9
+ export type { INavigationScopeValue, IAnyNavigatorHandle } from './navigation-context';
10
+ export { useLinkingIntegration } from './linking';
11
+ export type { ILinkingConfig, IScreenLinkingConfig } from '../core';
12
+ export { Tab } from './tabs';
13
+ export type { ITabNavigatorHandle, ITabProps } from './tabs';
14
+ export { TabScreen } from './tab-screen';
15
+ export type { ITabScreenOptionsArgs, ITabScreenOptionsResolver, ITabScreenProps, } from './tab-screen';
16
+ export type { ITabOptions, ITabBarIcon } from '../core';
17
+ export { Drawer } from './drawer';
18
+ export type { IDrawerContentSlotProps, IDrawerNavigatorHandle, IDrawerProps, IDrawerDescriptorMap, } from './drawer';
19
+ export { DrawerScreen } from './drawer-screen';
20
+ export type { IDrawerScreenOptionsArgs, IDrawerScreenOptionsResolver, IDrawerScreenProps, } from './drawer-screen';
21
+ export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition } from '../core';
@@ -0,0 +1,19 @@
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
+ import '../register';
6
+ export { Stack } from './stack/index.js';
7
+ export { Screen } from './screen.js';
8
+ export { useNavigation, useStackNavigation, useTabNavigation, useDrawerNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './composables/index.js';
9
+ export { useLinkingIntegration } from './linking.js';
10
+ // Tab: the bottom-tabs navigator, a PURE-JS UI (no react-native-screens views involved, so no
11
+ // extra ViewConfig registration is needed beyond the ../register import above).
12
+ export { Tab } from './tabs/index.js';
13
+ export { TabScreen } from './tab-screen.js';
14
+ // Drawer: the swipeable drawer navigator, a PURE-JS UI (PanResponder + Animated, no
15
+ // react-native-screens views involved, so no extra ViewConfig registration is needed beyond the
16
+ // ../register import above). See drawer.ts's header for the feasibility note re:
17
+ // react-native-gesture-handler / react-native-reanimated parity gaps.
18
+ export { Drawer } from './drawer/index.js';
19
+ export { DrawerScreen } from './drawer-screen.js';
@@ -0,0 +1,3 @@
1
+ import type { Ref } from '@vue/runtime-core';
2
+ import type { ILinkingConfig, INavigatorHandle } from '../core';
3
+ export declare function useLinkingIntegration(config: ILinkingConfig, navigatorHandle: Ref<INavigatorHandle | null>): void;
@@ -0,0 +1,57 @@
1
+ // useLinkingIntegration: wires the framework-agnostic linking config (../core's
2
+ // resolveRouteFromUrl) onto an existing Stack's INavigatorHandle. Deliberately NOT called from
3
+ // inside stack.ts - app code owns the wiring, the same top-level-prop shape @react-navigation
4
+ // keeps `linking` in on NavigationContainer rather than baking it into the router itself.
5
+ //
6
+ // Vue-shape difference from React: React's twin takes the RESOLVED `navigatorHandle:
7
+ // INavigatorHandle` directly, because a React hook is called fresh on EVERY render with the
8
+ // caller's current value, and useImperativeHandle's ref assignment (a layout effect) is
9
+ // guaranteed to run before this hook's OWN mount effect, so `handleRef.current` is already
10
+ // populated by the time it's read. Vue's setup() runs exactly ONCE per component instance, so
11
+ // there is no "fresh call every render" to re-supply a resolved value, and a template/h() `ref`
12
+ // only resolves to Stack's expose()d handle AFTER mount - an eagerly-resolved argument evaluated
13
+ // at composable-call time (during setup, before mount) would be null. This composable therefore
14
+ // takes the Stack's `Ref<INavigatorHandle | null>` itself (the ref object, not its resolved
15
+ // value) and reads `.value` lazily inside onMounted - Vue's own onMounted hooks fire bottom-up
16
+ // (children before parents), giving the same "already populated" guarantee React's layout-effect
17
+ // ordering does.
18
+ import { onMounted, onUnmounted } from '@vue/runtime-core';
19
+ import { Linking, dlog } from '@symbiote-native/engine';
20
+ import { resolveRouteFromUrl } from '../core/index.js';
21
+ export function useLinkingIntegration(config, navigatorHandle) {
22
+ let cancelled = false;
23
+ let subscription;
24
+ function applyRoute(url, dispatch) {
25
+ const route = resolveRouteFromUrl(config, url);
26
+ if (route === null) {
27
+ dlog(`useLinkingIntegration: no route resolved for "${url}"`);
28
+ return;
29
+ }
30
+ dispatch(route.name, route.params);
31
+ }
32
+ onMounted(() => {
33
+ const handle = navigatorHandle.value;
34
+ if (handle === null) {
35
+ dlog('useLinkingIntegration: navigatorHandle is not yet available at mount time');
36
+ return;
37
+ }
38
+ Linking.getInitialURL()
39
+ .then(url => {
40
+ if (cancelled || url === null)
41
+ return;
42
+ dlog(`useLinkingIntegration: initial URL "${url}"`);
43
+ applyRoute(url, handle.replace);
44
+ })
45
+ .catch((error) => {
46
+ dlog(`useLinkingIntegration: getInitialURL failed: ${String(error)}`);
47
+ });
48
+ subscription = Linking.addEventListener('url', (event) => {
49
+ dlog(`useLinkingIntegration: url event "${event.url}"`);
50
+ applyRoute(event.url, handle.push);
51
+ });
52
+ });
53
+ onUnmounted(() => {
54
+ cancelled = true;
55
+ subscription?.remove();
56
+ });
57
+ }
@@ -0,0 +1,16 @@
1
+ import type { ShallowRef } from '@vue/runtime-core';
2
+ import type { INavigationEmitter, IRoute, IAnyNavigatorHandle } from '../core';
3
+ export type { IAnyNavigatorHandle };
4
+ export type INavigationScopeValue = {
5
+ route: IRoute<unknown>;
6
+ navigation: IAnyNavigatorHandle;
7
+ emitter: INavigationEmitter;
8
+ parent?: INavigationScopeValue;
9
+ };
10
+ export declare function injectNavigationScope(): ShallowRef<INavigationScopeValue> | undefined;
11
+ export declare function requireNavigationScope(hookName: string): ShallowRef<INavigationScopeValue>;
12
+ export declare const NavigationScope: import("vue").DefineSetupFnComponent<{
13
+ value: INavigationScopeValue;
14
+ }, {}, {}, {
15
+ value: INavigationScopeValue;
16
+ } & {}, import("vue").PublicProps>;
@@ -0,0 +1,65 @@
1
+ // The lifecycle half of the framework-agnostic emitter (../core/navigation-events): Vue has no
2
+ // "Context" concept the way React does. The equivalent here is a plain provide/inject
3
+ // getter/setter pair over one shared InjectionKey (mirrors this codebase's own pd-widgets
4
+ // convention: `provideX(value)` writes, `injectX()` reads and throws if nothing was provided), so
5
+ // a screen's subtree can read its own route, navigator handle, and per-route emitter without
6
+ // prop-drilling - the Vue twin of react/navigation-context.ts's React Context, collapsed into one
7
+ // key the same way (a symbiote screen only ever needs its OWN route, no per-navigator
8
+ // param-list generics in v1 scope, see screen.ts).
9
+ //
10
+ // Vue's provide() must run once, synchronously, inside a component's OWN setup(). Unlike React,
11
+ // which re-creates a fresh `<Context.Provider value={...}>` element (and therefore a fresh value)
12
+ // on every render loop iteration, Vue's provide/inject is scoped to the component INSTANCE, not to
13
+ // a render-time position. Stack/Tab/Drawer keep every mounted route's screen alive as a SEPARATE
14
+ // sibling subtree (Stack keeps every pushed route mounted; see stack.ts), and each one needs its
15
+ // OWN distinct provided value (its own route/emitter) invisible to its siblings - that is an
16
+ // inherent property of any hierarchical dependency-injection scheme, provide/inject included, not
17
+ // a React artifact. NavigationScope is the small setup-boundary component that gives each route
18
+ // subtree its own instance to call provideNavigationScope from: stack.ts/tabs.ts/drawer.ts's
19
+ // render loop mounts ONE NavigationScope per route (keyed by route.key, exactly like React's
20
+ // per-route `<NavigationContext.Provider>`), and that instance's setup() calls the setter ONCE,
21
+ // refreshed from the latest `value` prop on every one of ITS OWN re-renders - consumers read
22
+ // `.value` off the injected ref, so a later change (e.g. setParams producing a new route object
23
+ // for the same key) still reaches them reactively.
24
+ //
25
+ // `parent` threads the ambient value a navigator read on ITS OWN mount (undefined at the root)
26
+ // into the value it provides to its own screens, forming a linked list - this is what lets a
27
+ // screen nested inside e.g. a Stack-screen-renders-a-Tab composition reach the enclosing Stack via
28
+ // useNavigation().getParent().
29
+ import { defineComponent, inject, provide, shallowRef } from '@vue/runtime-core';
30
+ const NAVIGATION_SCOPE_KEY = Symbol('navigation-scope');
31
+ // The setter half of the pair - writes the CURRENT route's scope onto the shared key. Called only
32
+ // from NavigationScope's own setup below (never directly by app code).
33
+ function provideNavigationScope(value) {
34
+ provide(NAVIGATION_SCOPE_KEY, value);
35
+ }
36
+ // The getter half of the pair - every composable in ./composables and every navigator
37
+ // (stack.ts/tabs.ts/drawer.ts, reading the AMBIENT/parent scope on their own mount) calls this
38
+ // directly; undefined simply means "no ancestor NavigationScope", which is a legitimate state (the
39
+ // nesting root) rather than an error - callers that require one throw their own message.
40
+ export function injectNavigationScope() {
41
+ return inject(NAVIGATION_SCOPE_KEY, undefined);
42
+ }
43
+ // The "throw if missing" half every composable in ./composables needs (useNavigation, useRoute,
44
+ // useIsFocused, useFocusEffect, useNavigationState) - they all called injectNavigationScope() and
45
+ // threw the same shaped error, differing only in which hook name the message names. Centralized
46
+ // here so a wording change lands once instead of five times.
47
+ export function requireNavigationScope(hookName) {
48
+ const scope = injectNavigationScope();
49
+ if (scope === undefined) {
50
+ throw new Error(`${hookName} must be used within a screen rendered by <Stack>, <Tab>, or <Drawer>`);
51
+ }
52
+ return scope;
53
+ }
54
+ // The setup-boundary component described above. `props: ['value']` is a REQUIRED runtime
55
+ // declaration here, not stylistic - without it Vue would route the incoming `value` into `attrs`
56
+ // instead of a tracked reactive `props` field, and the render closure's refresh below would
57
+ // silently keep re-reading a stale initial snapshot.
58
+ export const NavigationScope = defineComponent((props, { slots }) => {
59
+ const current = shallowRef(props.value);
60
+ provideNavigationScope(current);
61
+ return () => {
62
+ current.value = props.value;
63
+ return slots.default?.() ?? null;
64
+ };
65
+ }, { name: 'NavigationScope', props: ['value'] });
@@ -0,0 +1,21 @@
1
+ import type { Component, Ref } from '@vue/runtime-core';
2
+ import type { IRoute } from '../core';
3
+ import type { ISearchBarCommands, ISearchBarOptions, IScreenOptions, INavigatorHandle } from '../core';
4
+ export type IVueSearchBarOptions = ISearchBarOptions & {
5
+ ref?: Ref<ISearchBarCommands | null>;
6
+ };
7
+ export type IVueScreenOptions = Omit<IScreenOptions, 'headerSearchBarOptions'> & {
8
+ headerSearchBarOptions?: IVueSearchBarOptions;
9
+ };
10
+ export type IScreenOptionsArgs = {
11
+ route: IRoute<unknown>;
12
+ navigation: INavigatorHandle;
13
+ };
14
+ export type IScreenOptionsResolver = (args: IScreenOptionsArgs) => IVueScreenOptions;
15
+ export type IScreenProps = {
16
+ name: string;
17
+ component: Component;
18
+ options?: IVueScreenOptions | IScreenOptionsResolver;
19
+ initialParams?: unknown;
20
+ };
21
+ export declare const Screen: import("vue").DefineSetupFnComponent<IScreenProps, {}, {}, IScreenProps & {}, import("vue").PublicProps>;
@@ -0,0 +1,12 @@
1
+ // Stack.Screen: a declarative marker, never rendered on its own - Stack reads its props via a
2
+ // default-slot scan (see stack.ts's collectRegistry) to build the static name -> {component,
3
+ // options} registry, then mounts the registered component itself for each pushed route. The Vue
4
+ // twin of react/screen.ts's Screen, using the slot-scanning pattern real Vue component libraries
5
+ // use for this exact declarative-marker-child shape (Element Plus's `<el-collapse-item>`, Ant
6
+ // Design Vue's `<a-menu-item>`): the parent inspects `vnode.type === Screen` and reads
7
+ // `vnode.props` directly, so Screen's own setup() never actually runs.
8
+ import { defineComponent } from '@vue/runtime-core';
9
+ export const Screen = defineComponent(() => () => null, {
10
+ name: 'Screen',
11
+ inheritAttrs: false,
12
+ });