@symbiote-native/navigation 2.0.3 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/README.md +42 -12
  2. package/build/angular/drawer/index.js +29 -13
  3. package/build/angular/index.d.ts +4 -4
  4. package/build/angular/injectors/inject-navigation.js +1 -1
  5. package/build/angular/navigation-scope.directive.js +1 -1
  6. package/build/angular/search-bar-ref.directive.js +1 -1
  7. package/build/angular/stack/index.d.ts +2 -0
  8. package/build/angular/stack/index.js +43 -9
  9. package/build/angular/tabs/index.d.ts +1 -1
  10. package/build/angular/tabs/index.js +40 -13
  11. package/build/core/drawer-options/index.js +19 -5
  12. package/build/core/drawer-router-state/index.js +8 -2
  13. package/build/core/guards.js +3 -1
  14. package/build/core/header-bar-buttons.js +14 -4
  15. package/build/core/index.d.ts +6 -5
  16. package/build/core/index.js +7 -3
  17. package/build/core/navigator-state/index.js +12 -4
  18. package/build/core/render-drawer.js +4 -1
  19. package/build/core/render-stack.js +13 -4
  20. package/build/core/screen-options.js +1 -1
  21. package/build/core/search-bar-commands.js +1 -1
  22. package/build/core/stack-router-state/index.d.ts +2 -0
  23. package/build/core/stack-router-state/index.js +44 -0
  24. package/build/core/state-persistence/index.js +6 -2
  25. package/build/core/tab-router-state/index.d.ts +1 -0
  26. package/build/core/tab-router-state/index.js +27 -2
  27. package/build/react/drawer/index.js +59 -26
  28. package/build/react/index.d.ts +7 -7
  29. package/build/react/index.js +2 -2
  30. package/build/react/stack/index.js +47 -10
  31. package/build/react/tabs/index.js +36 -12
  32. package/build/solid/drawer/index.d.ts +22 -0
  33. package/build/solid/drawer/index.js +394 -0
  34. package/build/solid/drawer-screen-props.d.ts +13 -0
  35. package/build/solid/drawer-screen-props.js +2 -0
  36. package/build/solid/host.d.ts +2 -0
  37. package/build/solid/host.js +23 -0
  38. package/build/solid/index.d.ts +19 -0
  39. package/build/solid/index.js +24 -0
  40. package/build/solid/linking.d.ts +3 -0
  41. package/build/solid/linking.js +55 -0
  42. package/build/solid/navigation-context.d.ts +13 -0
  43. package/build/solid/navigation-context.js +37 -0
  44. package/build/solid/primitives/create-focus-effect.d.ts +1 -0
  45. package/build/solid/primitives/create-focus-effect.js +30 -0
  46. package/build/solid/primitives/create-is-focused.d.ts +2 -0
  47. package/build/solid/primitives/create-is-focused.js +31 -0
  48. package/build/solid/primitives/create-navigation-state.d.ts +3 -0
  49. package/build/solid/primitives/create-navigation-state.js +30 -0
  50. package/build/solid/primitives/index.d.ts +12 -0
  51. package/build/solid/primitives/index.js +8 -0
  52. package/build/solid/primitives/use-drawer-navigation.d.ts +5 -0
  53. package/build/solid/primitives/use-drawer-navigation.js +15 -0
  54. package/build/solid/primitives/use-navigation.d.ts +8 -0
  55. package/build/solid/primitives/use-navigation.js +23 -0
  56. package/build/solid/primitives/use-route.d.ts +3 -0
  57. package/build/solid/primitives/use-route.js +14 -0
  58. package/build/solid/primitives/use-stack-navigation.d.ts +5 -0
  59. package/build/solid/primitives/use-stack-navigation.js +19 -0
  60. package/build/solid/primitives/use-tab-navigation.d.ts +5 -0
  61. package/build/solid/primitives/use-tab-navigation.js +15 -0
  62. package/build/solid/screen-props.d.ts +19 -0
  63. package/build/solid/screen-props.js +9 -0
  64. package/build/solid/screen-registry.d.ts +31 -0
  65. package/build/solid/screen-registry.js +86 -0
  66. package/build/solid/screen.d.ts +6 -0
  67. package/build/solid/screen.js +69 -0
  68. package/build/solid/stack/index.d.ts +15 -0
  69. package/build/solid/stack/index.js +348 -0
  70. package/build/solid/tab-screen-props.d.ts +13 -0
  71. package/build/solid/tab-screen-props.js +3 -0
  72. package/build/solid/tabs/index.d.ts +14 -0
  73. package/build/solid/tabs/index.js +228 -0
  74. package/build/svelte/attachments.d.ts +5 -0
  75. package/build/svelte/attachments.js +61 -0
  76. package/build/svelte/descriptor-subtree.d.ts +3 -0
  77. package/build/svelte/descriptor-subtree.js +39 -0
  78. package/build/svelte/drawer/drawer-props.d.ts +14 -0
  79. package/build/svelte/drawer/drawer-props.js +3 -0
  80. package/build/svelte/drawer/index.d.ts +10 -0
  81. package/build/svelte/drawer/index.js +6 -0
  82. package/build/svelte/drawer/index.svelte +559 -0
  83. package/build/svelte/drawer/index.svelte.d.ts +10 -0
  84. package/build/svelte/drawer-screen-props.d.ts +13 -0
  85. package/build/svelte/drawer-screen-props.js +4 -0
  86. package/build/svelte/drawer-screen.svelte +25 -0
  87. package/build/svelte/drawer-screen.svelte.d.ts +4 -0
  88. package/build/svelte/index.d.ts +21 -0
  89. package/build/svelte/index.js +20 -0
  90. package/build/svelte/linking.svelte.d.ts +2 -0
  91. package/build/svelte/linking.svelte.js +55 -0
  92. package/build/svelte/navigation-context.d.ts +14 -0
  93. package/build/svelte/navigation-context.js +44 -0
  94. package/build/svelte/navigation-scope.svelte +27 -0
  95. package/build/svelte/navigation-scope.svelte.d.ts +9 -0
  96. package/build/svelte/registry-host.d.ts +1 -0
  97. package/build/svelte/registry-host.js +26 -0
  98. package/build/svelte/runes/index.d.ts +12 -0
  99. package/build/svelte/runes/index.js +12 -0
  100. package/build/svelte/runes/use-drawer-navigation.svelte.d.ts +6 -0
  101. package/build/svelte/runes/use-drawer-navigation.svelte.js +19 -0
  102. package/build/svelte/runes/use-focus-effect.svelte.d.ts +1 -0
  103. package/build/svelte/runes/use-focus-effect.svelte.js +31 -0
  104. package/build/svelte/runes/use-is-focused.svelte.d.ts +3 -0
  105. package/build/svelte/runes/use-is-focused.svelte.js +34 -0
  106. package/build/svelte/runes/use-navigation-state.svelte.d.ts +4 -0
  107. package/build/svelte/runes/use-navigation-state.svelte.js +39 -0
  108. package/build/svelte/runes/use-navigation.svelte.d.ts +9 -0
  109. package/build/svelte/runes/use-navigation.svelte.js +26 -0
  110. package/build/svelte/runes/use-route.svelte.d.ts +4 -0
  111. package/build/svelte/runes/use-route.svelte.js +12 -0
  112. package/build/svelte/runes/use-stack-navigation.svelte.d.ts +6 -0
  113. package/build/svelte/runes/use-stack-navigation.svelte.js +22 -0
  114. package/build/svelte/runes/use-tab-navigation.svelte.d.ts +6 -0
  115. package/build/svelte/runes/use-tab-navigation.svelte.js +19 -0
  116. package/build/svelte/screen-props.d.ts +21 -0
  117. package/build/svelte/screen-props.js +6 -0
  118. package/build/svelte/screen-registry.d.ts +17 -0
  119. package/build/svelte/screen-registry.js +57 -0
  120. package/build/svelte/screen.svelte +28 -0
  121. package/build/svelte/screen.svelte.d.ts +4 -0
  122. package/build/svelte/stack/index.d.ts +14 -0
  123. package/build/svelte/stack/index.js +7 -0
  124. package/build/svelte/stack/index.svelte +261 -0
  125. package/build/svelte/stack/index.svelte.d.ts +15 -0
  126. package/build/svelte/stack/stack-props.d.ts +20 -0
  127. package/build/svelte/stack/stack-props.js +4 -0
  128. package/build/svelte/stack/stack-screen.svelte +205 -0
  129. package/build/svelte/stack/stack-screen.svelte.d.ts +4 -0
  130. package/build/svelte/tab-screen-props.d.ts +13 -0
  131. package/build/svelte/tab-screen-props.js +4 -0
  132. package/build/svelte/tab-screen.svelte +26 -0
  133. package/build/svelte/tab-screen.svelte.d.ts +4 -0
  134. package/build/svelte/tabs/index.d.ts +8 -0
  135. package/build/svelte/tabs/index.js +6 -0
  136. package/build/svelte/tabs/index.svelte +269 -0
  137. package/build/svelte/tabs/index.svelte.d.ts +8 -0
  138. package/build/svelte/tabs/tab-props.d.ts +7 -0
  139. package/build/svelte/tabs/tab-props.js +3 -0
  140. package/build/vue/composables/use-navigation.js +5 -1
  141. package/build/vue/drawer/index.js +36 -13
  142. package/build/vue/index.d.ts +3 -3
  143. package/build/vue/navigation-context.js +1 -1
  144. package/build/vue/stack/index.js +43 -18
  145. package/build/vue/tabs/index.js +65 -39
  146. package/build-ngc/angular/drawer/index.js +40 -18
  147. package/build-ngc/angular/drawer/index.js.map +1 -1
  148. package/build-ngc/angular/drawer-screen.directive.js +3 -3
  149. package/build-ngc/angular/index.d.ts +4 -4
  150. package/build-ngc/angular/index.js.map +1 -1
  151. package/build-ngc/angular/injectors/inject-focus-effect.js.map +1 -1
  152. package/build-ngc/angular/injectors/inject-is-focused.js.map +1 -1
  153. package/build-ngc/angular/injectors/inject-navigation-state.js.map +1 -1
  154. package/build-ngc/angular/injectors/inject-navigation.js +1 -1
  155. package/build-ngc/angular/injectors/inject-navigation.js.map +1 -1
  156. package/build-ngc/angular/linking.js.map +1 -1
  157. package/build-ngc/angular/navigation-context.service.js +3 -3
  158. package/build-ngc/angular/navigation-context.service.js.map +1 -1
  159. package/build-ngc/angular/navigation-scope.directive.js +4 -4
  160. package/build-ngc/angular/navigation-scope.directive.js.map +1 -1
  161. package/build-ngc/angular/screen.directive.js +3 -3
  162. package/build-ngc/angular/screen.directive.js.map +1 -1
  163. package/build-ngc/angular/search-bar-ref.directive.js +4 -4
  164. package/build-ngc/angular/search-bar-ref.directive.js.map +1 -1
  165. package/build-ngc/angular/stack/index.d.ts +2 -0
  166. package/build-ngc/angular/stack/index.js +52 -14
  167. package/build-ngc/angular/stack/index.js.map +1 -1
  168. package/build-ngc/angular/tab-screen.directive.js +3 -3
  169. package/build-ngc/angular/tab-screen.directive.js.map +1 -1
  170. package/build-ngc/angular/tabs/index.d.ts +1 -1
  171. package/build-ngc/angular/tabs/index.js +43 -16
  172. package/build-ngc/angular/tabs/index.js.map +1 -1
  173. package/build-ngc/core/constants.js.map +1 -1
  174. package/build-ngc/core/drawer-options/index.js +19 -5
  175. package/build-ngc/core/drawer-options/index.js.map +1 -1
  176. package/build-ngc/core/drawer-router-state/index.js +8 -2
  177. package/build-ngc/core/drawer-router-state/index.js.map +1 -1
  178. package/build-ngc/core/guards.js +3 -1
  179. package/build-ngc/core/guards.js.map +1 -1
  180. package/build-ngc/core/header-bar-buttons.js +14 -4
  181. package/build-ngc/core/header-bar-buttons.js.map +1 -1
  182. package/build-ngc/core/index.d.ts +6 -5
  183. package/build-ngc/core/index.js +7 -3
  184. package/build-ngc/core/index.js.map +1 -1
  185. package/build-ngc/core/linking-config/index.js.map +1 -1
  186. package/build-ngc/core/navigation-events/index.js.map +1 -1
  187. package/build-ngc/core/navigator-handles/index.js.map +1 -1
  188. package/build-ngc/core/navigator-state/index.js +12 -4
  189. package/build-ngc/core/navigator-state/index.js.map +1 -1
  190. package/build-ngc/core/render-drawer.js +4 -1
  191. package/build-ngc/core/render-drawer.js.map +1 -1
  192. package/build-ngc/core/render-stack.js +13 -4
  193. package/build-ngc/core/render-stack.js.map +1 -1
  194. package/build-ngc/core/render-tabs.js.map +1 -1
  195. package/build-ngc/core/screen-options.js +1 -1
  196. package/build-ngc/core/screen-options.js.map +1 -1
  197. package/build-ngc/core/search-bar-commands.js +1 -1
  198. package/build-ngc/core/search-bar-commands.js.map +1 -1
  199. package/build-ngc/core/stack-router-state/index.d.ts +2 -0
  200. package/build-ngc/core/stack-router-state/index.js +45 -0
  201. package/build-ngc/core/stack-router-state/index.js.map +1 -0
  202. package/build-ngc/core/state-persistence/index.js +6 -2
  203. package/build-ngc/core/state-persistence/index.js.map +1 -1
  204. package/build-ngc/core/tab-router-state/index.d.ts +1 -0
  205. package/build-ngc/core/tab-router-state/index.js +27 -2
  206. package/build-ngc/core/tab-router-state/index.js.map +1 -1
  207. package/package.json +44 -16
  208. package/src/angular/drawer/index.ts +75 -29
  209. package/src/angular/index.ts +20 -4
  210. package/src/angular/injectors/inject-focus-effect.ts +8 -2
  211. package/src/angular/injectors/inject-is-focused.ts +6 -4
  212. package/src/angular/injectors/inject-navigation-state.ts +7 -4
  213. package/src/angular/injectors/inject-navigation.ts +12 -3
  214. package/src/angular/linking.ts +4 -1
  215. package/src/angular/navigation-context.service.ts +5 -2
  216. package/src/angular/navigation-scope.directive.ts +6 -2
  217. package/src/angular/screen.directive.ts +13 -3
  218. package/src/angular/search-bar-ref.directive.ts +10 -2
  219. package/src/angular/stack/index.ts +91 -24
  220. package/src/angular/tab-screen.directive.ts +3 -1
  221. package/src/angular/tabs/index.ts +54 -16
  222. package/src/core/constants.ts +6 -3
  223. package/src/core/drawer-options/index.ts +40 -13
  224. package/src/core/drawer-router-state/index.ts +11 -3
  225. package/src/core/guards.ts +3 -1
  226. package/src/core/header-bar-buttons.ts +41 -12
  227. package/src/core/index.ts +29 -5
  228. package/src/core/linking-config/index.ts +31 -10
  229. package/src/core/navigation-events/index.ts +8 -2
  230. package/src/core/navigator-handles/index.ts +8 -3
  231. package/src/core/navigator-props.ts +13 -4
  232. package/src/core/navigator-state/index.ts +24 -7
  233. package/src/core/render-drawer.ts +24 -9
  234. package/src/core/render-stack.ts +52 -13
  235. package/src/core/render-tabs.ts +24 -6
  236. package/src/core/screen-options.ts +15 -5
  237. package/src/core/search-bar-commands.ts +12 -3
  238. package/src/core/stack-router-state/index.ts +52 -0
  239. package/src/core/state-persistence/index.ts +13 -3
  240. package/src/core/tab-router-state/index.ts +35 -3
  241. package/src/react/drawer/index.ts +409 -330
  242. package/src/react/drawer-screen.ts +8 -2
  243. package/src/react/hooks/use-focus-effect.ts +8 -2
  244. package/src/react/hooks/use-is-focused.ts +6 -2
  245. package/src/react/hooks/use-navigation.ts +8 -2
  246. package/src/react/index.ts +37 -7
  247. package/src/react/linking.ts +4 -1
  248. package/src/react/navigation-context.ts +6 -2
  249. package/src/react/screen.ts +12 -3
  250. package/src/react/stack/index.ts +297 -220
  251. package/src/react/tab-screen.ts +3 -1
  252. package/src/react/tabs/index.ts +202 -139
  253. package/src/solid/drawer/index.ts +570 -0
  254. package/src/solid/drawer-screen-props.ts +24 -0
  255. package/src/solid/host.ts +29 -0
  256. package/src/solid/index.ts +87 -0
  257. package/src/solid/linking.ts +74 -0
  258. package/src/solid/navigation-context.ts +56 -0
  259. package/src/solid/primitives/create-focus-effect.ts +41 -0
  260. package/src/solid/primitives/create-is-focused.ts +41 -0
  261. package/src/solid/primitives/create-navigation-state.ts +44 -0
  262. package/src/solid/primitives/index.ts +12 -0
  263. package/src/solid/primitives/use-drawer-navigation.ts +25 -0
  264. package/src/solid/primitives/use-navigation.ts +44 -0
  265. package/src/solid/primitives/use-route.ts +18 -0
  266. package/src/solid/primitives/use-stack-navigation.ts +29 -0
  267. package/src/solid/primitives/use-tab-navigation.ts +25 -0
  268. package/src/solid/screen-props.ts +51 -0
  269. package/src/solid/screen-registry.ts +159 -0
  270. package/src/solid/screen.ts +80 -0
  271. package/src/solid/stack/index.ts +528 -0
  272. package/src/solid/tab-screen-props.ts +21 -0
  273. package/src/solid/tabs/index.ts +327 -0
  274. package/src/svelte/attachments.ts +70 -0
  275. package/src/svelte/descriptor-subtree.ts +51 -0
  276. package/src/svelte/drawer/drawer-props.ts +28 -0
  277. package/src/svelte/drawer/index.svelte +559 -0
  278. package/src/svelte/drawer/index.ts +10 -0
  279. package/src/svelte/drawer-screen-props.ts +26 -0
  280. package/src/svelte/drawer-screen.svelte +25 -0
  281. package/src/svelte/fabric-tree.test-helper.ts +95 -0
  282. package/src/svelte/index.ts +83 -0
  283. package/src/svelte/linking.svelte.ts +72 -0
  284. package/src/svelte/navigation-context.ts +62 -0
  285. package/src/svelte/navigation-scope.svelte +27 -0
  286. package/src/svelte/registry-host.ts +26 -0
  287. package/src/svelte/runes/index.ts +17 -0
  288. package/src/svelte/runes/use-drawer-navigation.svelte.ts +31 -0
  289. package/src/svelte/runes/use-focus-effect.svelte.ts +41 -0
  290. package/src/svelte/runes/use-is-focused.svelte.ts +38 -0
  291. package/src/svelte/runes/use-navigation-state.svelte.ts +48 -0
  292. package/src/svelte/runes/use-navigation.svelte.ts +49 -0
  293. package/src/svelte/runes/use-route.svelte.ts +16 -0
  294. package/src/svelte/runes/use-stack-navigation.svelte.ts +34 -0
  295. package/src/svelte/runes/use-tab-navigation.svelte.ts +29 -0
  296. package/src/svelte/screen-props.ts +50 -0
  297. package/src/svelte/screen-registry.ts +98 -0
  298. package/src/svelte/screen.svelte +28 -0
  299. package/src/svelte/stack/index.svelte +261 -0
  300. package/src/svelte/stack/index.ts +11 -0
  301. package/src/svelte/stack/stack-props.ts +31 -0
  302. package/src/svelte/stack/stack-screen.svelte +205 -0
  303. package/src/svelte/svelte-ambient.d.ts +6 -0
  304. package/src/svelte/svelte-compile.test-helper.ts +147 -0
  305. package/src/svelte/tab-screen-props.ts +22 -0
  306. package/src/svelte/tab-screen.svelte +26 -0
  307. package/src/svelte/tabs/index.svelte +269 -0
  308. package/src/svelte/tabs/index.ts +10 -0
  309. package/src/svelte/tabs/tab-props.ts +13 -0
  310. package/src/vue/composables/use-navigation-state.ts +7 -4
  311. package/src/vue/composables/use-navigation.ts +13 -3
  312. package/src/vue/drawer/index.ts +128 -41
  313. package/src/vue/drawer-screen.ts +12 -5
  314. package/src/vue/index.ts +15 -3
  315. package/src/vue/linking.ts +7 -2
  316. package/src/vue/navigation-context.ts +17 -5
  317. package/src/vue/screen.ts +7 -2
  318. package/src/vue/stack/index.ts +108 -43
  319. package/src/vue/tab-screen.ts +3 -1
  320. package/src/vue/tabs/index.ts +109 -68
@@ -0,0 +1,14 @@
1
+ export declare const Stack: import("svelte").Component<import("./stack-props").IStackProps, {
2
+ push: (name: string, params?: unknown) => void;
3
+ pop: (count?: number) => void;
4
+ popToTop: () => void;
5
+ popTo: (key: string) => void;
6
+ replace: (name: string, params?: unknown) => void;
7
+ setParams: (params: unknown, key?: string) => void;
8
+ reset: (nextState: import("../../core").INavigatorState) => void;
9
+ canGoBack: () => boolean;
10
+ }, ""> & {
11
+ Screen: import("svelte").Component<import("..").IScreenProps, {}, "">;
12
+ };
13
+ export type { INavigatorHandle } from '../../core';
14
+ export type { IStackProps } from './stack-props';
@@ -0,0 +1,7 @@
1
+ // `Stack.Screen` alongside the standalone `Screen` export, matching React's and Vue's barrels.
2
+ // A compiled Svelte component is an ordinary function object, so attaching the marker to it is
3
+ // the same Object.assign the other entries do - and `<Stack.Screen />` resolves through Svelte's
4
+ // member-expression component tags (verified against the real compiler).
5
+ import StackImpl from './index.svelte';
6
+ import Screen from '../screen.svelte';
7
+ export const Stack = Object.assign(StackImpl, { Screen });
@@ -0,0 +1,261 @@
1
+ <script lang="ts" module>
2
+ // Stack, the Svelte lifecycle half. The route-stack transitions (navigator-state) and the
3
+ // options/props folds (screen-options, render-stack) live in @symbiote-native/navigation core,
4
+ // shared verbatim with the React/Vue/Angular entries; here Svelte supplies the lifecycle -
5
+ // `$state.raw` for the pushed-route stack (its twin of useReducer: reassign from the same pure
6
+ // reducer), a module counter for route-key generation, `export function`s for the push/pop/
7
+ // replace navigator handle (Svelte's twin of Vue's expose(), reachable via `bind:this`) - plus
8
+ // the react-native-screens chrome per route (stack-screen.svelte). Pushing/popping a route is
9
+ // an ordinary child mount/unmount: RNSScreenStack diffs its RNSScreen children natively, so no
10
+ // imperative native command is needed here at all. Neither this nor the Screen marker imports
11
+ // react-native-screens' own React components (ScreenStack.tsx et al - hooks, crashes a
12
+ // non-React adapter); the native views are driven directly through the ViewConfig ../../register
13
+ // registers. See CLAUDE.md <third_party_rn_packages_are_react_only>.
14
+ //
15
+ // HOW SCREENS ARE DISCOVERED: not by reading `children`, which Svelte hands over as an opaque
16
+ // Snippet - the markers register themselves through the context collector (../screen-registry.ts)
17
+ // while the snippet renders, and the route list derives from that. The snippet is rendered
18
+ // inside a collapsed `symbiote-text` (../registry-host.ts) so whitespace between two markers
19
+ // can never become an illegal raw-text child of a native view.
20
+
21
+ // Route keys must be unique per Stack INSTANCE (Svelte has no useId); a module counter is the
22
+ // same mechanism the Angular entry uses.
23
+ let stackInstanceCounter = 0;
24
+
25
+ const STACK_ROOT_PROPS: Record<string, unknown> = { style: { flex: 1 } };
26
+ </script>
27
+
28
+ <script lang="ts">
29
+ import type { Component } from 'svelte';
30
+ import { dlog } from '@symbiote-native/engine';
31
+ import {
32
+ NAVIGATION_EVENT_STATE,
33
+ RNS_SCREEN_STACK_VIEW_NAME,
34
+ STACK_ON_FINISH_TRANSITIONING,
35
+ createInitialNavigatorState,
36
+ createNavigationEmitter,
37
+ navigatorReducer,
38
+ reconcileStackRoutes,
39
+ resolveStackProps,
40
+ } from '../../core';
41
+ import type {
42
+ INavigationEmitter,
43
+ INavigatorAction,
44
+ INavigatorHandle,
45
+ INavigatorState,
46
+ IRoute,
47
+ } from '../../core';
48
+ import { hostProps } from '../attachments';
49
+ import { getNavigationScope } from '../navigation-context';
50
+ import { SCREEN_REGISTRY_HOST_PROPS } from '../registry-host';
51
+ import {
52
+ setScreenCollector,
53
+ toRegistry,
54
+ withoutScreen,
55
+ } from '../screen-registry';
56
+ import type { IRegisteredScreen } from '../screen-registry';
57
+ import type { IScreenProps, ISvelteScreenOptions } from '../screen-props';
58
+ import StackScreen from './stack-screen.svelte';
59
+ import type { IStackProps } from './stack-props';
60
+
61
+ let { initialRouteName, screenOptions, children }: IStackProps = $props();
62
+
63
+ // Read BEFORE this Stack establishes its own per-screen NavigationScope - becomes the `parent`
64
+ // link a nested screen's useNavigation().getParent() walks (e.g. this Stack rendered as a Tab
65
+ // screen's content reaches that Tab via this value). undefined when this Stack is the nesting
66
+ // root. Kept as the BOX, not its unwrapped value, so every read below sees the current one.
67
+ const parentScope = getNavigationScope();
68
+
69
+ const routeIdPrefix = `stack-${(stackInstanceCounter += 1)}`;
70
+
71
+ // `$state.raw` + reassignment, never a mutated array: an entry holds a component reference (a
72
+ // plain function) behind live getters, and a deep reactive proxy would wrap both.
73
+ let screens = $state.raw<IRegisteredScreen<IScreenProps['options']>[]>([]);
74
+ setScreenCollector<IScreenProps['options']>({
75
+ kind: 'stack',
76
+ register: screen => {
77
+ screens = [...screens, screen];
78
+ },
79
+ unregister: screen => {
80
+ screens = withoutScreen(screens, screen);
81
+ },
82
+ });
83
+
84
+ const registry = $derived(toRegistry(screens));
85
+
86
+ let routeSequence = 0;
87
+ function createRoute(name: string, params: unknown): IRoute<unknown> {
88
+ routeSequence += 1;
89
+ return { key: `${routeIdPrefix}-${name}-${routeSequence}`, name, params };
90
+ }
91
+
92
+ // The pushed stack only exists once something has dispatched; until then the state derives from
93
+ // whatever the markers registered. `seededState` is a PLAIN local (not `$state`), so memoizing
94
+ // it inside the derivation below is not a state write during a derivation - it just makes the
95
+ // one route-key-allocating call happen exactly once, no matter how often the derivation re-runs
96
+ // as markers register.
97
+ let pushedState = $state.raw<INavigatorState | null>(null);
98
+ let seededState: INavigatorState | undefined;
99
+
100
+ function seedState(): INavigatorState {
101
+ if (seededState !== undefined) return seededState;
102
+ const startRouteName = initialRouteName ?? registry.keys().next().value;
103
+ if (startRouteName === undefined) {
104
+ dlog('Stack: no <Stack.Screen> children registered');
105
+ // Deliberately NOT memoized: markers may still be registering, and the next derivation run
106
+ // should get a real initial route rather than being stuck on this placeholder.
107
+ return createInitialNavigatorState({
108
+ key: routeIdPrefix,
109
+ name: '',
110
+ params: undefined,
111
+ });
112
+ }
113
+ seededState = createInitialNavigatorState(
114
+ createRoute(startRouteName, registry.get(startRouteName)?.initialParams),
115
+ );
116
+ return seededState;
117
+ }
118
+
119
+ // A `<Stack.Screen>` marker can unregister while its route is still in the pushed history (a
120
+ // marker behind an `{#if}`, a data-driven screen list), which would leave that entry with nothing
121
+ // for componentFor() to mount (reconcileStackRoutes' header). The reconciliation belongs in the
122
+ // derivation because it is PURE - it hands back the same state reference when nothing changed, so
123
+ // it writes no state and cannot re-trigger itself; `dispatch` below then persists the pruned
124
+ // history, since it reduces over this value rather than over `pushedState`.
125
+ const state = $derived(
126
+ reconcileStackRoutes(pushedState ?? seedState(), [...registry.keys()]),
127
+ );
128
+
129
+ function dispatch(action: INavigatorAction): void {
130
+ pushedState = navigatorReducer(state, action);
131
+ }
132
+
133
+ // One emitter per route.key, created lazily the first time a route is rendered and pruned once
134
+ // it is popped off the stack (the broadcast effect below).
135
+ const emitters = new Map<string, INavigationEmitter>();
136
+ function emitterFor(routeKey: string): INavigationEmitter {
137
+ let emitter = emitters.get(routeKey);
138
+ if (emitter === undefined) {
139
+ emitter = createNavigationEmitter();
140
+ emitters.set(routeKey, emitter);
141
+ }
142
+ return emitter;
143
+ }
144
+
145
+ export function push(name: string, params?: unknown): void {
146
+ dispatch({ type: 'push', route: createRoute(name, params) });
147
+ }
148
+ export function pop(count?: number): void {
149
+ dispatch({ type: 'pop', count });
150
+ }
151
+ export function popToTop(): void {
152
+ dispatch({ type: 'popToTop' });
153
+ }
154
+ export function popTo(key: string): void {
155
+ dispatch({ type: 'popTo', key });
156
+ }
157
+ export function replace(name: string, params?: unknown): void {
158
+ dispatch({ type: 'replace', route: createRoute(name, params) });
159
+ }
160
+ export function setParams(params: unknown, key?: string): void {
161
+ dispatch({ type: 'setParams', key, params });
162
+ }
163
+ export function reset(nextState: INavigatorState): void {
164
+ dispatch({ type: 'reset', state: nextState });
165
+ }
166
+ export function canGoBack(): boolean {
167
+ return state.routes.length > 1;
168
+ }
169
+
170
+ // The same handle, as a value, for everything that needs it INSIDE this component (the options
171
+ // fold's `navigation` argument, every route's NavigationScope). `bind:this` exposes the
172
+ // `export function`s above; this object is the internal twin of that surface.
173
+ const handle: INavigatorHandle = {
174
+ push,
175
+ pop,
176
+ popToTop,
177
+ popTo,
178
+ replace,
179
+ setParams,
180
+ reset,
181
+ canGoBack,
182
+ };
183
+
184
+ function popOne(): void {
185
+ dispatch({ type: 'pop', count: 1 });
186
+ }
187
+
188
+ // Broadcasts the router state to every still-live route's emitter (useNavigationState's source)
189
+ // after each commit, and prunes emitters for routes popped off the stack. Runs as an $effect
190
+ // rather than inline in the render path (Vue's shape), so the first broadcast lands AFTER the
191
+ // initial route's own screen has mounted and subscribed.
192
+ $effect(() => {
193
+ const current = state;
194
+ for (const route of current.routes) {
195
+ emitterFor(route.key).emit(NAVIGATION_EVENT_STATE, current);
196
+ }
197
+ for (const routeKey of [...emitters.keys()]) {
198
+ if (!current.routes.some(route => route.key === routeKey))
199
+ emitters.delete(routeKey);
200
+ }
201
+ });
202
+
203
+ // Investigation instrumentation (flicker-on-focus bug): STACK_ON_FINISH_TRANSITIONING is the
204
+ // native signal that the WHOLE push/pop animation has finished (as opposed to onAppear/
205
+ // onDisappear, which are per-screen) - logging it lets the per-screen appear/disappear
206
+ // timestamps be checked against the actual transition-complete moment. Kept behind DEBUG,
207
+ // never removed.
208
+ const stackProps = resolveStackProps({
209
+ passthrough: {
210
+ [STACK_ON_FINISH_TRANSITIONING]: () =>
211
+ dlog(`Stack: onFinishTransitioning at t=${Date.now()}`),
212
+ },
213
+ });
214
+
215
+ function optionsFor(route: IRoute<unknown>): ISvelteScreenOptions {
216
+ const entry = registry.get(route.name);
217
+ const own =
218
+ entry === undefined
219
+ ? undefined
220
+ : typeof entry.options === 'function'
221
+ ? entry.options({ route, navigation: handle })
222
+ : entry.options;
223
+ return { ...screenOptions, ...own };
224
+ }
225
+
226
+ function componentFor(route: IRoute<unknown>): Component | undefined {
227
+ const entry = registry.get(route.name);
228
+ if (entry === undefined) {
229
+ dlog(`Stack: no screen registered for route name "${route.name}"`);
230
+ return undefined;
231
+ }
232
+ return entry.component;
233
+ }
234
+ </script>
235
+
236
+ <symbiote-view p={STACK_ROOT_PROPS}>
237
+ <symbiote-text p={SCREEN_REGISTRY_HOST_PROPS}>
238
+ {@render children?.()}
239
+ </symbiote-text>
240
+ <svelte:element
241
+ this={RNS_SCREEN_STACK_VIEW_NAME}
242
+ {@attach hostProps(stackProps)}
243
+ >
244
+ {#each state.routes as route, index (route.key)}
245
+ {@const screenComponent = componentFor(route)}
246
+ {#if screenComponent !== undefined}
247
+ <StackScreen
248
+ {route}
249
+ {index}
250
+ routeCount={state.routes.length}
251
+ options={optionsFor(route)}
252
+ navigation={handle}
253
+ emitter={emitterFor(route.key)}
254
+ parentScope={parentScope?.current}
255
+ component={screenComponent}
256
+ onPopRequested={popOne}
257
+ />
258
+ {/if}
259
+ {/each}
260
+ </svelte:element>
261
+ </symbiote-view>
@@ -0,0 +1,15 @@
1
+ import type { Component } from 'svelte';
2
+ import type { INavigatorState } from '../../core';
3
+ import type { IStackProps } from './stack-props';
4
+ declare const Index: Component<IStackProps, {
5
+ push: (name: string, params?: unknown) => void;
6
+ pop: (count?: number) => void;
7
+ popToTop: () => void;
8
+ popTo: (key: string) => void;
9
+ replace: (name: string, params?: unknown) => void;
10
+ setParams: (params: unknown, key?: string) => void;
11
+ reset: (nextState: INavigatorState) => void;
12
+ canGoBack: () => boolean;
13
+ }, "">;
14
+ type Index = ReturnType<typeof Index>;
15
+ export default Index;
@@ -0,0 +1,20 @@
1
+ import type { Component, Snippet } from 'svelte';
2
+ import type { INavigationEmitter, INavigatorHandle, IRoute } from '../../core';
3
+ import type { INavigationScopeValue } from '../navigation-context';
4
+ import type { ISvelteScreenOptions } from '../screen-props';
5
+ export type IStackProps = {
6
+ initialRouteName?: string;
7
+ screenOptions?: ISvelteScreenOptions;
8
+ children?: Snippet;
9
+ };
10
+ export type IStackScreenProps = {
11
+ route: IRoute<unknown>;
12
+ index: number;
13
+ routeCount: number;
14
+ options: ISvelteScreenOptions;
15
+ navigation: INavigatorHandle;
16
+ emitter: INavigationEmitter;
17
+ parentScope: INavigationScopeValue | undefined;
18
+ component: Component;
19
+ onPopRequested: () => void;
20
+ };
@@ -0,0 +1,4 @@
1
+ // Stack's own public prop surface, and the internal per-route prop surface stack-screen.svelte
2
+ // takes. Both live in a plain `.ts` file for the tsc-cannot-see-a-`.svelte`-named-export reason
3
+ // ../screen-props.ts documents.
4
+ export {};
@@ -0,0 +1,205 @@
1
+ <script lang="ts" module>
2
+ import type { INavigatorPlatform } from '../../core';
3
+
4
+ // backTitleVisible defaults to `true` on both platforms per the codegen spec's own default
5
+ // (CT.WithDefault<boolean, 'true'>) - no ios/android divergence in v1 scope, so a single
6
+ // constant stands in for the per-platform injection point ISliderPlatform-style adapters use
7
+ // elsewhere.
8
+ const NAVIGATOR_PLATFORM: INavigatorPlatform = {
9
+ defaultHeaderBackTitleVisible: true,
10
+ };
11
+
12
+ // react-native-screens' RNSScreenStackHeaderConfig.mm requires every header child to be an
13
+ // RNSScreenStackHeaderSubview; `type: 'searchBar'` is how it knows which slot this one fills.
14
+ const HEADER_SUBVIEW_PROPS: Record<string, unknown> = { type: 'searchBar' };
15
+ </script>
16
+
17
+ <script lang="ts">
18
+ // One mounted route's native chrome. Split out of index.svelte so each route owns its own plan
19
+ // derivation and its own attachments, torn down by an ordinary component unmount when the route
20
+ // is popped - the Svelte equivalent of Vue's per-route render-loop closure.
21
+ //
22
+ // Every react-native-screens view here goes through `<svelte:element this={'RNSScreen'}>`
23
+ // rather than a literal tag: their Fabric names are capitalized and un-hyphenated, so a literal
24
+ // tag would parse as a COMPONENT reference in a Svelte template. Their props ride an
25
+ // `{@attach hostProps(...)}` attachment rather than an attribute, because a dynamic tag
26
+ // compiles through Svelte's generic setAttribute path and never the custom-element property-SET
27
+ // path the object bag depends on - see ../attachments.ts for the full reasoning.
28
+ //
29
+ // Whitespace between sibling tags in the per-route tree is inert: the shim drops a
30
+ // whitespace-only text node whose parent takes no raw text, so it never becomes an RCTRawText
31
+ // child of a react-native-screens view (dom-shim/text.ts, svelte-adapter-dom-shim skill §16b).
32
+ import { Platform, dlog } from '@symbiote-native/engine';
33
+ import {
34
+ NAVIGATION_EVENT_BLUR,
35
+ NAVIGATION_EVENT_FOCUS,
36
+ RNS_SCREEN_CONTENT_WRAPPER_VIEW_NAME,
37
+ RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME,
38
+ RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME,
39
+ RNS_SCREEN_STACK_VIEW_NAME,
40
+ RNS_SCREEN_VIEW_NAME,
41
+ RNS_SEARCH_BAR_VIEW_NAME,
42
+ SCREEN_ON_APPEAR,
43
+ SCREEN_ON_DISAPPEAR,
44
+ SCREEN_ON_DISMISSED,
45
+ SCREEN_ON_HEADER_BACK_BUTTON_CLICKED,
46
+ SCREEN_ON_WILL_APPEAR,
47
+ SCREEN_ON_WILL_DISAPPEAR,
48
+ buildSearchBarPassthrough,
49
+ resolveScreenRenderPlan,
50
+ } from '../../core';
51
+ import type { IScreenRenderPlan } from '../../core';
52
+ import { hostProps, searchBarRef } from '../attachments';
53
+ import NavigationScope from '../navigation-scope.svelte';
54
+ import type { INavigationScopeValue } from '../navigation-context';
55
+ import type { IStackScreenProps } from './stack-props';
56
+
57
+ let {
58
+ route,
59
+ index,
60
+ routeCount,
61
+ options,
62
+ navigation,
63
+ emitter,
64
+ parentScope,
65
+ // Destructured under a capitalized name because a Svelte template resolves a component tag
66
+ // only from a capitalized identifier.
67
+ component: ScreenComponent,
68
+ onPopRequested,
69
+ }: IStackScreenProps = $props();
70
+
71
+ const searchBarOptions = $derived(options.headerSearchBarOptions);
72
+
73
+ const plan = $derived.by<IScreenRenderPlan>(() =>
74
+ resolveScreenRenderPlan({
75
+ screenId: route.key,
76
+ index,
77
+ routeCount,
78
+ options,
79
+ platform: NAVIGATOR_PLATFORM,
80
+ isAndroid: Platform.OS === 'android',
81
+ screenPassthrough: {
82
+ [SCREEN_ON_DISMISSED]: onPopRequested,
83
+ [SCREEN_ON_HEADER_BACK_BUTTON_CLICKED]: onPopRequested,
84
+ // onAppear/onDisappear are the definitive visibility boundary (post-transition-
85
+ // animation), so 'focus'/'blur' fire exactly once per transition; onWillAppear/
86
+ // onWillDisappear fire BEFORE the animation runs, so wiring them to emit() too would
87
+ // double-invoke useFocusEffect per transition - they only get a debug log here.
88
+ [SCREEN_ON_WILL_APPEAR]: () =>
89
+ dlog(`Stack: route "${route.name}" will appear at t=${Date.now()}`),
90
+ [SCREEN_ON_APPEAR]: () => {
91
+ dlog(
92
+ `Stack: route "${route.name}" appeared (focus) at t=${Date.now()}`,
93
+ );
94
+ emitter.emit(NAVIGATION_EVENT_FOCUS);
95
+ },
96
+ [SCREEN_ON_WILL_DISAPPEAR]: () =>
97
+ dlog(
98
+ `Stack: route "${route.name}" will disappear at t=${Date.now()}`,
99
+ ),
100
+ [SCREEN_ON_DISAPPEAR]: () => {
101
+ dlog(
102
+ `Stack: route "${route.name}" disappeared (blur) at t=${Date.now()}`,
103
+ );
104
+ emitter.emit(NAVIGATION_EVENT_BLUR);
105
+ },
106
+ },
107
+ // The imperative SearchBarCommands ref rides its OWN attachment on the RNSSearchBar leaf
108
+ // below (../attachments.ts), never this passthrough map - same split Angular uses, so no
109
+ // `ref` key can leak through to Fabric as a real prop.
110
+ searchBarPassthrough: searchBarOptions
111
+ ? buildSearchBarPassthrough(searchBarOptions, message =>
112
+ dlog(`Stack: route "${route.name}" ${message}`),
113
+ )
114
+ : undefined,
115
+ }),
116
+ );
117
+
118
+ // Investigation instrumentation (flicker-on-focus bug): the actual timing/z-order-relevant
119
+ // values resolved onto the native RNSScreen, once per mounted route - rules a stackAnimation/
120
+ // transitionDuration mismatch against react-native-screens' own native default in or out. Kept
121
+ // behind DEBUG, never removed.
122
+ let hasLoggedScreenProps = false;
123
+ $effect(() => {
124
+ const screenProps = plan.screenProps;
125
+ if (hasLoggedScreenProps) return;
126
+ hasLoggedScreenProps = true;
127
+ dlog(
128
+ `Stack: route "${route.name}" resolved screen props ` +
129
+ `stackAnimation=${String(screenProps.stackAnimation)} ` +
130
+ `stackPresentation=${String(screenProps.stackPresentation)} ` +
131
+ `transitionDuration=${String(screenProps.transitionDuration)} ` +
132
+ `gestureEnabled=${String(screenProps.gestureEnabled)} at t=${Date.now()}`,
133
+ );
134
+ });
135
+
136
+ // A modal/formSheet screen has no UINavigationController of its own on iOS - nest an inner
137
+ // RNSScreenStack/RNSScreen purely to host the native header bar (see isHeaderInModal's comment
138
+ // in core/render-stack.ts). Skipping this leaves RNSScreenStackHeaderConfig with no navigation
139
+ // controller to attach to, so the header silently never renders. activityState mirrors the
140
+ // outer screen's own value - RNSScreen.mm treats an unset/inactive nested screen as not yet
141
+ // pushed, leaving it parked at its pre-push transition position.
142
+ const innerStackProps = $derived<Record<string, unknown>>({
143
+ style: plan.innerStackStyle,
144
+ });
145
+ const innerScreenProps = $derived<Record<string, unknown>>({
146
+ style: plan.innerScreenStyle,
147
+ activityState: plan.activityState,
148
+ });
149
+
150
+ const scopeValue = $derived<INavigationScopeValue>({
151
+ route,
152
+ navigation,
153
+ emitter,
154
+ parent: parentScope,
155
+ });
156
+ </script>
157
+
158
+ {#snippet chrome()}
159
+ <svelte:element
160
+ this={RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME}
161
+ {@attach hostProps(plan.headerConfig.props)}
162
+ >
163
+ {#if plan.searchBarProps !== undefined}
164
+ <svelte:element
165
+ this={RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME}
166
+ {@attach hostProps(HEADER_SUBVIEW_PROPS)}
167
+ >
168
+ <svelte:element
169
+ this={RNS_SEARCH_BAR_VIEW_NAME}
170
+ {@attach hostProps(plan.searchBarProps)}
171
+ {@attach searchBarRef(searchBarOptions?.ref)}
172
+ />
173
+ </svelte:element>
174
+ {/if}
175
+ </svelte:element>
176
+ <svelte:element
177
+ this={RNS_SCREEN_CONTENT_WRAPPER_VIEW_NAME}
178
+ {@attach hostProps(plan.contentWrapperProps)}
179
+ >
180
+ <NavigationScope value={scopeValue}>
181
+ <ScreenComponent />
182
+ </NavigationScope>
183
+ </svelte:element>
184
+ {/snippet}
185
+
186
+ <svelte:element
187
+ this={plan.screenViewName}
188
+ {@attach hostProps(plan.screenProps)}
189
+ >
190
+ {#if plan.inModal}
191
+ <svelte:element
192
+ this={RNS_SCREEN_STACK_VIEW_NAME}
193
+ {@attach hostProps(innerStackProps)}
194
+ >
195
+ <svelte:element
196
+ this={RNS_SCREEN_VIEW_NAME}
197
+ {@attach hostProps(innerScreenProps)}
198
+ >
199
+ {@render chrome()}
200
+ </svelte:element>
201
+ </svelte:element>
202
+ {:else}
203
+ {@render chrome()}
204
+ {/if}
205
+ </svelte:element>
@@ -0,0 +1,4 @@
1
+ import type { IStackScreenProps } from './stack-props';
2
+ declare const StackScreen: import("svelte").Component<IStackScreenProps, {}, "">;
3
+ type StackScreen = ReturnType<typeof StackScreen>;
4
+ export default StackScreen;
@@ -0,0 +1,13 @@
1
+ import type { Component } from 'svelte';
2
+ import type { IRoute, ITabNavigatorHandle, ITabOptions } from '../core';
3
+ export type ITabScreenOptionsArgs = {
4
+ route: IRoute<unknown>;
5
+ navigation: ITabNavigatorHandle;
6
+ };
7
+ export type ITabScreenOptionsResolver = (args: ITabScreenOptionsArgs) => ITabOptions;
8
+ export type ITabScreenProps = {
9
+ name: string;
10
+ component: Component;
11
+ options?: ITabOptions | ITabScreenOptionsResolver;
12
+ initialParams?: unknown;
13
+ };
@@ -0,0 +1,4 @@
1
+ // Tab.Screen's public prop surface - mirrors screen-props.ts minus the stack-only concepts (no
2
+ // push/pop lifecycle, no header search bar). Split out of `tab-screen.svelte` for the same
3
+ // tsc-cannot-see-a-`.svelte`-named-export reason screen-props.ts documents.
4
+ export {};
@@ -0,0 +1,26 @@
1
+ <script lang="ts">
2
+ // Tab.Screen: a declarative marker that paints nothing, registered through the same
3
+ // context-based collector Stack.Screen uses (screen-registry.ts). The `'tab'` kind tag is what
4
+ // stops it from silently registering with an ancestor Stack/Drawer when it is written in the
5
+ // wrong place. See CLAUDE.md <third_party_rn_packages_are_react_only> - this and Tab import
6
+ // nothing from react-native.
7
+ import { collectScreen } from './screen-registry';
8
+ import type { ITabScreenProps } from './tab-screen-props';
9
+
10
+ let { name, component, options, initialParams }: ITabScreenProps = $props();
11
+
12
+ collectScreen('tab', {
13
+ get name(): ITabScreenProps['name'] {
14
+ return name;
15
+ },
16
+ get component(): ITabScreenProps['component'] {
17
+ return component;
18
+ },
19
+ get options(): ITabScreenProps['options'] {
20
+ return options;
21
+ },
22
+ get initialParams(): unknown {
23
+ return initialParams;
24
+ },
25
+ });
26
+ </script>
@@ -0,0 +1,4 @@
1
+ import type { ITabScreenProps } from './tab-screen-props';
2
+ declare const TabScreen: import("svelte").Component<ITabScreenProps, {}, "">;
3
+ type TabScreen = ReturnType<typeof TabScreen>;
4
+ export default TabScreen;
@@ -0,0 +1,8 @@
1
+ export declare const Tab: import("svelte").Component<import("./tab-props").ITabProps, {
2
+ jumpTo: (name: string, params?: unknown) => void;
3
+ setParams: (params: unknown, key: string) => void;
4
+ }, ""> & {
5
+ Screen: import("svelte").Component<import("..").ITabScreenProps, {}, "">;
6
+ };
7
+ export type { ITabNavigatorHandle } from '../../core';
8
+ export type { ITabProps } from './tab-props';
@@ -0,0 +1,6 @@
1
+ // `Tab.Screen` alongside the standalone `TabScreen` export, matching React's and Vue's barrels -
2
+ // see ../stack/index.ts for why Object.assign is the right mechanism on a compiled Svelte
3
+ // component.
4
+ import TabImpl from './index.svelte';
5
+ import TabScreen from '../tab-screen.svelte';
6
+ export const Tab = Object.assign(TabImpl, { Screen: TabScreen });