@symbiote-native/navigation 2.1.0 → 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 (234) hide show
  1. package/README.md +42 -12
  2. package/build/angular/drawer/index.js +23 -9
  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.js +20 -6
  8. package/build/angular/tabs/index.js +21 -7
  9. package/build/core/drawer-options/index.js +19 -5
  10. package/build/core/drawer-router-state/index.js +8 -2
  11. package/build/core/guards.js +3 -1
  12. package/build/core/header-bar-buttons.js +14 -4
  13. package/build/core/index.d.ts +4 -4
  14. package/build/core/index.js +2 -2
  15. package/build/core/navigator-state/index.js +12 -4
  16. package/build/core/render-drawer.js +4 -1
  17. package/build/core/render-stack.js +13 -4
  18. package/build/core/screen-options.js +1 -1
  19. package/build/core/search-bar-commands.js +1 -1
  20. package/build/core/state-persistence/index.js +6 -2
  21. package/build/core/tab-router-state/index.js +8 -2
  22. package/build/react/drawer/index.js +36 -13
  23. package/build/react/index.d.ts +7 -7
  24. package/build/react/index.js +2 -2
  25. package/build/react/stack/index.js +34 -8
  26. package/build/react/tabs/index.js +14 -4
  27. package/build/solid/drawer/index.d.ts +22 -0
  28. package/build/solid/drawer/index.js +394 -0
  29. package/build/solid/drawer-screen-props.d.ts +13 -0
  30. package/build/solid/drawer-screen-props.js +2 -0
  31. package/build/solid/host.d.ts +2 -0
  32. package/build/solid/host.js +23 -0
  33. package/build/solid/index.d.ts +19 -0
  34. package/build/solid/index.js +24 -0
  35. package/build/solid/linking.d.ts +3 -0
  36. package/build/solid/linking.js +55 -0
  37. package/build/solid/navigation-context.d.ts +13 -0
  38. package/build/solid/navigation-context.js +37 -0
  39. package/build/solid/primitives/create-focus-effect.d.ts +1 -0
  40. package/build/solid/primitives/create-focus-effect.js +30 -0
  41. package/build/solid/primitives/create-is-focused.d.ts +2 -0
  42. package/build/solid/primitives/create-is-focused.js +31 -0
  43. package/build/solid/primitives/create-navigation-state.d.ts +3 -0
  44. package/build/solid/primitives/create-navigation-state.js +30 -0
  45. package/build/solid/primitives/index.d.ts +12 -0
  46. package/build/solid/primitives/index.js +8 -0
  47. package/build/solid/primitives/use-drawer-navigation.d.ts +5 -0
  48. package/build/solid/primitives/use-drawer-navigation.js +15 -0
  49. package/build/solid/primitives/use-navigation.d.ts +8 -0
  50. package/build/solid/primitives/use-navigation.js +23 -0
  51. package/build/solid/primitives/use-route.d.ts +3 -0
  52. package/build/solid/primitives/use-route.js +14 -0
  53. package/build/solid/primitives/use-stack-navigation.d.ts +5 -0
  54. package/build/solid/primitives/use-stack-navigation.js +19 -0
  55. package/build/solid/primitives/use-tab-navigation.d.ts +5 -0
  56. package/build/solid/primitives/use-tab-navigation.js +15 -0
  57. package/build/solid/screen-props.d.ts +19 -0
  58. package/build/solid/screen-props.js +9 -0
  59. package/build/solid/screen-registry.d.ts +31 -0
  60. package/build/solid/screen-registry.js +86 -0
  61. package/build/solid/screen.d.ts +6 -0
  62. package/build/solid/screen.js +69 -0
  63. package/build/solid/stack/index.d.ts +15 -0
  64. package/build/solid/stack/index.js +348 -0
  65. package/build/solid/tab-screen-props.d.ts +13 -0
  66. package/build/solid/tab-screen-props.js +3 -0
  67. package/build/solid/tabs/index.d.ts +14 -0
  68. package/build/solid/tabs/index.js +228 -0
  69. package/build/svelte/descriptor-subtree.js +3 -1
  70. package/build/svelte/drawer/index.svelte +163 -25
  71. package/build/svelte/drawer-screen.svelte +2 -1
  72. package/build/svelte/index.d.ts +3 -3
  73. package/build/svelte/navigation-scope.svelte +4 -1
  74. package/build/svelte/runes/use-navigation.svelte.js +5 -1
  75. package/build/svelte/stack/index.svelte +43 -6
  76. package/build/svelte/stack/stack-screen.svelte +66 -9
  77. package/build/svelte/tabs/index.svelte +42 -20
  78. package/build/vue/composables/use-navigation.js +5 -1
  79. package/build/vue/drawer/index.js +30 -8
  80. package/build/vue/index.d.ts +3 -3
  81. package/build/vue/navigation-context.js +1 -1
  82. package/build/vue/stack/index.js +17 -6
  83. package/build/vue/tabs/index.js +18 -5
  84. package/build-ngc/angular/drawer/index.js +31 -11
  85. package/build-ngc/angular/drawer/index.js.map +1 -1
  86. package/build-ngc/angular/index.d.ts +4 -4
  87. package/build-ngc/angular/index.js.map +1 -1
  88. package/build-ngc/angular/injectors/inject-focus-effect.js.map +1 -1
  89. package/build-ngc/angular/injectors/inject-is-focused.js.map +1 -1
  90. package/build-ngc/angular/injectors/inject-navigation-state.js.map +1 -1
  91. package/build-ngc/angular/injectors/inject-navigation.js +1 -1
  92. package/build-ngc/angular/injectors/inject-navigation.js.map +1 -1
  93. package/build-ngc/angular/linking.js.map +1 -1
  94. package/build-ngc/angular/navigation-context.service.js.map +1 -1
  95. package/build-ngc/angular/navigation-scope.directive.js +1 -1
  96. package/build-ngc/angular/navigation-scope.directive.js.map +1 -1
  97. package/build-ngc/angular/screen.directive.js.map +1 -1
  98. package/build-ngc/angular/search-bar-ref.directive.js +1 -1
  99. package/build-ngc/angular/search-bar-ref.directive.js.map +1 -1
  100. package/build-ngc/angular/stack/index.js +26 -8
  101. package/build-ngc/angular/stack/index.js.map +1 -1
  102. package/build-ngc/angular/tab-screen.directive.js.map +1 -1
  103. package/build-ngc/angular/tabs/index.js +21 -7
  104. package/build-ngc/angular/tabs/index.js.map +1 -1
  105. package/build-ngc/core/constants.js.map +1 -1
  106. package/build-ngc/core/drawer-options/index.js +19 -5
  107. package/build-ngc/core/drawer-options/index.js.map +1 -1
  108. package/build-ngc/core/drawer-router-state/index.js +8 -2
  109. package/build-ngc/core/drawer-router-state/index.js.map +1 -1
  110. package/build-ngc/core/guards.js +3 -1
  111. package/build-ngc/core/guards.js.map +1 -1
  112. package/build-ngc/core/header-bar-buttons.js +14 -4
  113. package/build-ngc/core/header-bar-buttons.js.map +1 -1
  114. package/build-ngc/core/index.d.ts +4 -4
  115. package/build-ngc/core/index.js +2 -2
  116. package/build-ngc/core/index.js.map +1 -1
  117. package/build-ngc/core/linking-config/index.js.map +1 -1
  118. package/build-ngc/core/navigation-events/index.js.map +1 -1
  119. package/build-ngc/core/navigator-handles/index.js.map +1 -1
  120. package/build-ngc/core/navigator-state/index.js +12 -4
  121. package/build-ngc/core/navigator-state/index.js.map +1 -1
  122. package/build-ngc/core/render-drawer.js +4 -1
  123. package/build-ngc/core/render-drawer.js.map +1 -1
  124. package/build-ngc/core/render-stack.js +13 -4
  125. package/build-ngc/core/render-stack.js.map +1 -1
  126. package/build-ngc/core/render-tabs.js.map +1 -1
  127. package/build-ngc/core/screen-options.js +1 -1
  128. package/build-ngc/core/screen-options.js.map +1 -1
  129. package/build-ngc/core/search-bar-commands.js +1 -1
  130. package/build-ngc/core/search-bar-commands.js.map +1 -1
  131. package/build-ngc/core/stack-router-state/index.js.map +1 -1
  132. package/build-ngc/core/state-persistence/index.js +6 -2
  133. package/build-ngc/core/state-persistence/index.js.map +1 -1
  134. package/build-ngc/core/tab-router-state/index.js +8 -2
  135. package/build-ngc/core/tab-router-state/index.js.map +1 -1
  136. package/package.json +23 -9
  137. package/src/angular/drawer/index.ts +69 -25
  138. package/src/angular/index.ts +20 -4
  139. package/src/angular/injectors/inject-focus-effect.ts +8 -2
  140. package/src/angular/injectors/inject-is-focused.ts +6 -4
  141. package/src/angular/injectors/inject-navigation-state.ts +7 -4
  142. package/src/angular/injectors/inject-navigation.ts +12 -3
  143. package/src/angular/linking.ts +4 -1
  144. package/src/angular/navigation-context.service.ts +5 -2
  145. package/src/angular/navigation-scope.directive.ts +6 -2
  146. package/src/angular/screen.directive.ts +13 -3
  147. package/src/angular/search-bar-ref.directive.ts +10 -2
  148. package/src/angular/stack/index.ts +68 -22
  149. package/src/angular/tab-screen.directive.ts +3 -1
  150. package/src/angular/tabs/index.ts +36 -12
  151. package/src/core/constants.ts +6 -3
  152. package/src/core/drawer-options/index.ts +40 -13
  153. package/src/core/drawer-router-state/index.ts +11 -3
  154. package/src/core/guards.ts +3 -1
  155. package/src/core/header-bar-buttons.ts +41 -12
  156. package/src/core/index.ts +18 -4
  157. package/src/core/linking-config/index.ts +31 -10
  158. package/src/core/navigation-events/index.ts +8 -2
  159. package/src/core/navigator-handles/index.ts +8 -3
  160. package/src/core/navigator-props.ts +13 -4
  161. package/src/core/navigator-state/index.ts +24 -7
  162. package/src/core/render-drawer.ts +24 -9
  163. package/src/core/render-stack.ts +52 -13
  164. package/src/core/render-tabs.ts +24 -6
  165. package/src/core/screen-options.ts +15 -5
  166. package/src/core/search-bar-commands.ts +12 -3
  167. package/src/core/stack-router-state/index.ts +5 -2
  168. package/src/core/state-persistence/index.ts +13 -3
  169. package/src/core/tab-router-state/index.ts +10 -3
  170. package/src/react/drawer/index.ts +408 -344
  171. package/src/react/drawer-screen.ts +8 -2
  172. package/src/react/hooks/use-focus-effect.ts +8 -2
  173. package/src/react/hooks/use-is-focused.ts +6 -2
  174. package/src/react/hooks/use-navigation.ts +8 -2
  175. package/src/react/index.ts +37 -7
  176. package/src/react/linking.ts +4 -1
  177. package/src/react/navigation-context.ts +6 -2
  178. package/src/react/screen.ts +12 -3
  179. package/src/react/stack/index.ts +294 -231
  180. package/src/react/tab-screen.ts +3 -1
  181. package/src/react/tabs/index.ts +188 -158
  182. package/src/solid/drawer/index.ts +570 -0
  183. package/src/solid/drawer-screen-props.ts +24 -0
  184. package/src/solid/host.ts +29 -0
  185. package/src/solid/index.ts +87 -0
  186. package/src/solid/linking.ts +74 -0
  187. package/src/solid/navigation-context.ts +56 -0
  188. package/src/solid/primitives/create-focus-effect.ts +41 -0
  189. package/src/solid/primitives/create-is-focused.ts +41 -0
  190. package/src/solid/primitives/create-navigation-state.ts +44 -0
  191. package/src/solid/primitives/index.ts +12 -0
  192. package/src/solid/primitives/use-drawer-navigation.ts +25 -0
  193. package/src/solid/primitives/use-navigation.ts +44 -0
  194. package/src/solid/primitives/use-route.ts +18 -0
  195. package/src/solid/primitives/use-stack-navigation.ts +29 -0
  196. package/src/solid/primitives/use-tab-navigation.ts +25 -0
  197. package/src/solid/screen-props.ts +51 -0
  198. package/src/solid/screen-registry.ts +159 -0
  199. package/src/solid/screen.ts +80 -0
  200. package/src/solid/stack/index.ts +528 -0
  201. package/src/solid/tab-screen-props.ts +21 -0
  202. package/src/solid/tabs/index.ts +327 -0
  203. package/src/svelte/attachments.ts +3 -1
  204. package/src/svelte/descriptor-subtree.ts +3 -1
  205. package/src/svelte/drawer/index.svelte +163 -25
  206. package/src/svelte/drawer-screen-props.ts +8 -2
  207. package/src/svelte/drawer-screen.svelte +2 -1
  208. package/src/svelte/fabric-tree.test-helper.ts +37 -3
  209. package/src/svelte/index.ts +15 -3
  210. package/src/svelte/linking.svelte.ts +11 -5
  211. package/src/svelte/navigation-scope.svelte +4 -1
  212. package/src/svelte/runes/use-drawer-navigation.svelte.ts +3 -1
  213. package/src/svelte/runes/use-focus-effect.svelte.ts +8 -2
  214. package/src/svelte/runes/use-navigation-state.svelte.ts +3 -1
  215. package/src/svelte/runes/use-navigation.svelte.ts +13 -3
  216. package/src/svelte/runes/use-stack-navigation.svelte.ts +3 -1
  217. package/src/svelte/screen-props.ts +7 -2
  218. package/src/svelte/screen-registry.ts +9 -3
  219. package/src/svelte/stack/index.svelte +43 -6
  220. package/src/svelte/stack/stack-screen.svelte +66 -9
  221. package/src/svelte/svelte-compile.test-helper.ts +16 -12
  222. package/src/svelte/tab-screen-props.ts +3 -1
  223. package/src/svelte/tabs/index.svelte +42 -20
  224. package/src/vue/composables/use-navigation-state.ts +7 -4
  225. package/src/vue/composables/use-navigation.ts +13 -3
  226. package/src/vue/drawer/index.ts +122 -36
  227. package/src/vue/drawer-screen.ts +12 -5
  228. package/src/vue/index.ts +15 -3
  229. package/src/vue/linking.ts +7 -2
  230. package/src/vue/navigation-context.ts +17 -5
  231. package/src/vue/screen.ts +7 -2
  232. package/src/vue/stack/index.ts +82 -34
  233. package/src/vue/tab-screen.ts +3 -1
  234. package/src/vue/tabs/index.ts +51 -13
@@ -11,7 +11,7 @@
11
11
  import { el } from '@symbiote-native/components';
12
12
  import { HEADER_ON_PRESS_BAR_BUTTON_ITEM, HEADER_ON_PRESS_BAR_BUTTON_MENU_ITEM, RNS_MODAL_SCREEN_VIEW_NAME, RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME, RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME, RNS_SCREEN_VIEW_NAME, RNS_SEARCH_BAR_VIEW_NAME, SEARCH_BAR_ON_BLUR, SEARCH_BAR_ON_CANCEL_BUTTON_PRESS, SEARCH_BAR_ON_CHANGE_TEXT, SEARCH_BAR_ON_CLOSE, SEARCH_BAR_ON_FOCUS, SEARCH_BAR_ON_OPEN, SEARCH_BAR_ON_SEARCH_BUTTON_PRESS, STACK_DEFAULT_ANIMATION, STACK_DEFAULT_PRESENTATION, } from './constants.js';
13
13
  import { computeActivityState } from './navigator-state/index.js';
14
- import { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView } from './screen-options.js';
14
+ import { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView, } from './screen-options.js';
15
15
  // Mirrors react-native-screens' ScreenStackItem.tsx (getPositioningStyle): a formSheet's content
16
16
  // wrapper does not get `flex: 1`. RNSScreen.mm's updateBounds pushes the sheet's live native size
17
17
  // into Fabric's shadow state on every frame of a detent drag, and a `bottom: 0`-pinned wrapper
@@ -65,7 +65,9 @@ export function resolveScreenViewName(stackPresentation, isAndroid) {
65
65
  stackPresentation === 'push' ||
66
66
  stackPresentation === 'containedModal' ||
67
67
  stackPresentation === 'containedTransparentModal';
68
- return isPlainPresentation ? RNS_SCREEN_VIEW_NAME : RNS_MODAL_SCREEN_VIEW_NAME;
68
+ return isPlainPresentation
69
+ ? RNS_SCREEN_VIEW_NAME
70
+ : RNS_MODAL_SCREEN_VIEW_NAME;
69
71
  }
70
72
  export function resolveScreenContentWrapperStyle(stackPresentation, headerHidden, headerTranslucent, isAndroid) {
71
73
  let baseStyles;
@@ -96,13 +98,20 @@ export function resolveScreenContentWrapperStyle(stackPresentation, headerHidden
96
98
  export function isHeaderInModal(stackPresentation, headerHidden, isAndroid) {
97
99
  if (isAndroid)
98
100
  return false;
99
- return (stackPresentation ?? STACK_DEFAULT_PRESENTATION) !== 'push' && !headerHidden;
101
+ return ((stackPresentation ?? STACK_DEFAULT_PRESENTATION) !== 'push' &&
102
+ !headerHidden);
100
103
  }
101
104
  // Inner-modal wrapper styles for isHeaderInModal: the inner RNSScreenStack fills its outer
102
105
  // RNSScreen, and the inner RNSScreen fills the stack absolutely on all four edges. This mirrors
103
106
  // react-native-screens' own `styles.container` / `StyleSheet.absoluteFill` for this exact pair.
104
107
  const HEADER_IN_MODAL_STACK_STYLE = { flex: 1 };
105
- const HEADER_IN_MODAL_SCREEN_STYLE = { position: 'absolute', top: 0, start: 0, end: 0, bottom: 0 };
108
+ const HEADER_IN_MODAL_SCREEN_STYLE = {
109
+ position: 'absolute',
110
+ top: 0,
111
+ start: 0,
112
+ end: 0,
113
+ bottom: 0,
114
+ };
106
115
  export function resolveHeaderInModalStackStyle() {
107
116
  return HEADER_IN_MODAL_STACK_STYLE;
108
117
  }
@@ -7,7 +7,7 @@
7
7
  // The header bar-button payload+dispatch cluster (id-tagging, onPress lookup) lives in
8
8
  // header-bar-buttons.ts - self-contained, consumed here only as a black box by
9
9
  // resolveHeaderConfigView.
10
- import { buildHeaderBarButtonDispatch, prepareHeaderBarButtonItems } from './header-bar-buttons.js';
10
+ import { buildHeaderBarButtonDispatch, prepareHeaderBarButtonItems, } from './header-bar-buttons.js';
11
11
  // These sentinels must be kept in sync with react-native-screens' native side - they are RNS's
12
12
  // own compat values for the 'fitToContents'/'large'/'medium'/'all' legacy presets, replicated
13
13
  // here because we drive RNSScreen directly (no react-native-screens JS component in the path).
@@ -5,7 +5,7 @@
5
5
  // buildScrollViewHandle exactly (same lazy-getter shape); the adapter supplies the node getter
6
6
  // and its own framework-specific ref field (see react/screen.ts's IReactSearchBarOptions - the
7
7
  // ref itself is per-adapter, same split as IPressableProps).
8
- import { dispatchViewCommand, dlog } from '@symbiote-native/engine';
8
+ import { dispatchViewCommand, dlog, } from '@symbiote-native/engine';
9
9
  // dispatchViewCommand itself dlogs a "node not committed" skip; this null case (the ref never
10
10
  // attached to a live RNSSearchBar at all - e.g. the header's search bar isn't mounted, or a
11
11
  // stale handle outlived its screen) was the one unlogged gap, silently indistinguishable from
@@ -7,10 +7,14 @@ import { isRecord } from '../guards.js';
7
7
  // params: undefined}`, and JSON.stringify drops undefined-valued keys - a JSON round trip of a
8
8
  // perfectly valid route legitimately arrives here without a `params` key at all.
9
9
  function isRoute(value) {
10
- return isRecord(value) && typeof value.key === 'string' && typeof value.name === 'string';
10
+ return (isRecord(value) &&
11
+ typeof value.key === 'string' &&
12
+ typeof value.name === 'string');
11
13
  }
12
14
  function isNavigatorState(value) {
13
- return isRecord(value) && Array.isArray(value.routes) && value.routes.every(isRoute);
15
+ return (isRecord(value) &&
16
+ Array.isArray(value.routes) &&
17
+ value.routes.every(isRoute));
14
18
  }
15
19
  export function serializeNavigatorState(state) {
16
20
  return state;
@@ -49,7 +49,10 @@ export function tabRouterReducer(state, action) {
49
49
  }
50
50
  const target = state.routes[index];
51
51
  const routes = state.routes.slice();
52
- routes[index] = { ...target, params: mergeParams(target.params, action.params) };
52
+ routes[index] = {
53
+ ...target,
54
+ params: mergeParams(target.params, action.params),
55
+ };
53
56
  return { ...state, index, routes };
54
57
  }
55
58
  case 'setParams': {
@@ -58,7 +61,10 @@ export function tabRouterReducer(state, action) {
58
61
  return state;
59
62
  const target = state.routes[index];
60
63
  const routes = state.routes.slice();
61
- routes[index] = { ...target, params: mergeParams(target.params, action.params) };
64
+ routes[index] = {
65
+ ...target,
66
+ params: mergeParams(target.params, action.params),
67
+ };
62
68
  return { ...state, routes };
63
69
  }
64
70
  default:
@@ -15,8 +15,8 @@
15
15
  // @symbiote-native/engine), which is sufficient for a solid drawer but NOT byte-for-byte parity -
16
16
  // see the explicit gap list at the bottom of this file.
17
17
  import { createElement, forwardRef, isValidElement, useCallback, useContext, useEffect, useId, useImperativeHandle, useMemo, useReducer, useRef, } from 'react';
18
- import { Animated, PanResponder, useWindowDimensions } from '@symbiote-native/react';
19
- import { dlog } from '@symbiote-native/engine';
18
+ import { Animated, PanResponder, useWindowDimensions, } from '@symbiote-native/react';
19
+ import { dlog, } from '@symbiote-native/engine';
20
20
  import { DRAWER_DEFAULT_OVERLAY_COLOR, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_FOCUS, createInitialDrawerRouterState, createNavigationEmitter, drawerChildOrder, drawerRouterReducer, isDrawerAnimated, renderDrawer, resolveDragProgress, resolveDrawerGeometry, resolveDrawerSlotInterpolation, resolveSwipeIntent, shouldClaimDrawerSwipe, } from '../../core/index.js';
21
21
  import { collectRegistry } from '../collect-registry.js';
22
22
  import { NavigationContext } from '../navigation-context.js';
@@ -25,7 +25,9 @@ function isDrawerScreenElement(child) {
25
25
  return isValidElement(child) && child.type === DrawerScreen;
26
26
  }
27
27
  function resolveDrawerScreenOptions(entry, optionsArgs, screenOptions) {
28
- const own = typeof entry.options === 'function' ? entry.options(optionsArgs) : entry.options;
28
+ const own = typeof entry.options === 'function'
29
+ ? entry.options(optionsArgs)
30
+ : entry.options;
29
31
  return { ...screenOptions, ...own };
30
32
  }
31
33
  const DRAWER_SNAP_DURATION = 250;
@@ -148,12 +150,24 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
148
150
  })).current;
149
151
  const animated = isDrawerAnimated(options);
150
152
  const geometry = useMemo(() => resolveDrawerGeometry(options), [options.drawerType, options.drawerPosition, options.drawerWidth]);
151
- const panelSlot = animated ? resolveDrawerSlotInterpolation(geometry, 'panel') : undefined;
152
- const contentSlot = animated ? resolveDrawerSlotInterpolation(geometry, 'content') : undefined;
153
- const overlaySlot = animated ? resolveDrawerSlotInterpolation(geometry, 'overlay') : undefined;
154
- const panelTranslateX = panelSlot ? progress.interpolate(panelSlot.translateX) : undefined;
155
- const contentTranslateX = contentSlot ? progress.interpolate(contentSlot.translateX) : undefined;
156
- const overlayOpacity = overlaySlot ? progress.interpolate(overlaySlot.opacity) : undefined;
153
+ const panelSlot = animated
154
+ ? resolveDrawerSlotInterpolation(geometry, 'panel')
155
+ : undefined;
156
+ const contentSlot = animated
157
+ ? resolveDrawerSlotInterpolation(geometry, 'content')
158
+ : undefined;
159
+ const overlaySlot = animated
160
+ ? resolveDrawerSlotInterpolation(geometry, 'overlay')
161
+ : undefined;
162
+ const panelTranslateX = panelSlot
163
+ ? progress.interpolate(panelSlot.translateX)
164
+ : undefined;
165
+ const contentTranslateX = contentSlot
166
+ ? progress.interpolate(contentSlot.translateX)
167
+ : undefined;
168
+ const overlayOpacity = overlaySlot
169
+ ? progress.interpolate(overlaySlot.opacity)
170
+ : undefined;
157
171
  // The overlay is a full-screen absolutely-positioned sibling BELOW content in paint order
158
172
  // (see render-drawer.ts's drawerChildOrder) - for 'front' that's fine since content never moves,
159
173
  // but for 'slide' content itself translates away by contentTranslateX, and without following it
@@ -161,9 +175,13 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
161
175
  // underneath instead of just the content sliver it's meant to dim. Tying overlay to the SAME
162
176
  // translateX as content keeps it registered exactly under content, wherever content actually is
163
177
  // (resolveDrawerSlotInterpolation's 'overlay' overload returns that same content delta).
164
- const overlayTranslateX = overlaySlot ? progress.interpolate(overlaySlot.translateX) : undefined;
178
+ const overlayTranslateX = overlaySlot
179
+ ? progress.interpolate(overlaySlot.translateX)
180
+ : undefined;
165
181
  const focusedRoute = state.routes[state.index];
166
- const focusedEntry = focusedRoute ? registry.get(focusedRoute.name) : undefined;
182
+ const focusedEntry = focusedRoute
183
+ ? registry.get(focusedRoute.name)
184
+ : undefined;
167
185
  if (focusedRoute && !focusedEntry) {
168
186
  dlog(`Drawer: no screen registered for route name "${focusedRoute.name}"`);
169
187
  }
@@ -250,8 +268,13 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
250
268
  : { transform: [{ translateX: contentTranslateX }] },
251
269
  overlay: overlayOpacity === undefined
252
270
  ? undefined
253
- : { opacity: overlayOpacity, transform: [{ translateX: overlayTranslateX }] },
254
- panel: panelTranslateX === undefined ? undefined : { transform: [{ translateX: panelTranslateX }] },
271
+ : {
272
+ opacity: overlayOpacity,
273
+ transform: [{ translateX: overlayTranslateX }],
274
+ },
275
+ panel: panelTranslateX === undefined
276
+ ? undefined
277
+ : { transform: [{ translateX: panelTranslateX }] },
255
278
  };
256
279
  function renderSlot(slot) {
257
280
  const descriptor = slots.get(slot);
@@ -2,14 +2,14 @@ import '../register';
2
2
  export { Stack } from './stack';
3
3
  export type { INavigatorHandle, IStackProps } from './stack';
4
4
  export { Screen } from './screen';
5
- export type { IScreenOptionsArgs, IScreenOptionsResolver, IScreenProps } from './screen';
6
- export type { IScreenOptions, IStackAnimation, IStackPresentation } from '../core';
7
- export { useNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState } from './hooks';
5
+ export type { IScreenOptionsArgs, IScreenOptionsResolver, IScreenProps, } from './screen';
6
+ export type { IScreenOptions, IStackAnimation, IStackPresentation, } from '../core';
7
+ export { useNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './hooks';
8
8
  export type { INavigationHandle } from './hooks';
9
- export { useStackNavigation, useTabNavigation, useDrawerNavigation } from './hooks';
9
+ export { useStackNavigation, useTabNavigation, useDrawerNavigation, } from './hooks';
10
10
  export type { IStackNavigationHandle, ITabNavigationHandle, IDrawerNavigationHandle, } from './hooks';
11
11
  export { NavigationContext } from './navigation-context';
12
- export type { INavigationContextValue, IAnyNavigatorHandle } from './navigation-context';
12
+ export type { INavigationContextValue, IAnyNavigatorHandle, } from './navigation-context';
13
13
  export { useLinkingIntegration } from './linking';
14
14
  export type { ILinkingConfig, IScreenLinkingConfig } from '../core';
15
15
  export { Tab } from './tabs';
@@ -18,7 +18,7 @@ export { TabScreen } from './tab-screen';
18
18
  export type { ITabScreenOptionsArgs, ITabScreenOptionsResolver, ITabScreenProps, } from './tab-screen';
19
19
  export type { ITabOptions, ITabBarIcon } from '../core';
20
20
  export { Drawer } from './drawer';
21
- export type { IDrawerNavigatorHandle, IDrawerProps, IDrawerDescriptorMap } from './drawer';
21
+ export type { IDrawerNavigatorHandle, IDrawerProps, IDrawerDescriptorMap, } from './drawer';
22
22
  export { DrawerScreen } from './drawer-screen';
23
23
  export type { IDrawerScreenOptionsArgs, IDrawerScreenOptionsResolver, IDrawerScreenProps, } from './drawer-screen';
24
- export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition } from '../core';
24
+ export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition, } from '../core';
@@ -5,8 +5,8 @@
5
5
  import '../register';
6
6
  export { Stack } from './stack/index.js';
7
7
  export { Screen } from './screen.js';
8
- export { useNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState } from './hooks/index.js';
9
- export { useStackNavigation, useTabNavigation, useDrawerNavigation } from './hooks/index.js';
8
+ export { useNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './hooks/index.js';
9
+ export { useStackNavigation, useTabNavigation, useDrawerNavigation, } from './hooks/index.js';
10
10
  export { NavigationContext } from './navigation-context.js';
11
11
  export { useLinkingIntegration } from './linking.js';
12
12
  // Tab: the bottom-tabs navigator, a PURE-JS UI (no react-native-screens views involved, so no
@@ -18,12 +18,16 @@ import { Screen } from '../screen.js';
18
18
  // backTitleVisible defaults to `true` on both platforms per the codegen spec's own default
19
19
  // (CT.WithDefault<boolean, 'true'>) - no ios/android divergence in v1 scope, so a single constant
20
20
  // stands in for the per-platform injection point ISliderPlatform-style adapters use elsewhere.
21
- const NAVIGATOR_PLATFORM = { defaultHeaderBackTitleVisible: true };
21
+ const NAVIGATOR_PLATFORM = {
22
+ defaultHeaderBackTitleVisible: true,
23
+ };
22
24
  function isScreenElement(child) {
23
25
  return isValidElement(child) && child.type === Screen;
24
26
  }
25
27
  function resolveScreenOptions(entry, optionsArgs, screenOptions) {
26
- const own = typeof entry.options === 'function' ? entry.options(optionsArgs) : entry.options;
28
+ const own = typeof entry.options === 'function'
29
+ ? entry.options(optionsArgs)
30
+ : entry.options;
27
31
  return { ...screenOptions, ...own };
28
32
  }
29
33
  const StackImpl = forwardRef((props, forwardedRef) => {
@@ -51,14 +55,22 @@ const StackImpl = forwardRef((props, forwardedRef) => {
51
55
  }, [emitters]);
52
56
  const createRoute = useCallback((name, params) => {
53
57
  routeSequence.current += 1;
54
- return { key: `${routeIdPrefix}-${name}-${routeSequence.current}`, name, params };
58
+ return {
59
+ key: `${routeIdPrefix}-${name}-${routeSequence.current}`,
60
+ name,
61
+ params,
62
+ };
55
63
  }, [routeIdPrefix]);
56
64
  const registeredNames = useMemo(() => [...registry.keys()], [registry]);
57
65
  const [dispatchedState, dispatch] = useReducer(navigatorReducer, undefined, () => {
58
66
  const initialRouteName = props.initialRouteName ?? registry.keys().next().value;
59
67
  if (initialRouteName === undefined) {
60
68
  dlog('Stack: no <Stack.Screen> children registered');
61
- return createInitialNavigatorState({ key: routeIdPrefix, name: '', params: undefined });
69
+ return createInitialNavigatorState({
70
+ key: routeIdPrefix,
71
+ name: '',
72
+ params: undefined,
73
+ });
62
74
  }
63
75
  return createInitialNavigatorState(createRoute(initialRouteName, registry.get(initialRouteName)?.initialParams));
64
76
  });
@@ -112,7 +124,10 @@ const StackImpl = forwardRef((props, forwardedRef) => {
112
124
  dlog(`Stack: no screen registered for route name "${route.name}"`);
113
125
  return null;
114
126
  }
115
- const screenOptionsArgs = { route, navigation: handle };
127
+ const screenOptionsArgs = {
128
+ route,
129
+ navigation: handle,
130
+ };
116
131
  const mergedOptions = resolveScreenOptions(entry, screenOptionsArgs, props.screenOptions);
117
132
  const activityState = computeActivityState(index, state.routes.length);
118
133
  // Investigation instrumentation (flicker-on-focus bug): fires on EVERY Stack render, not just
@@ -166,7 +181,8 @@ const StackImpl = forwardRef((props, forwardedRef) => {
166
181
  const appRef = searchBarOptions.ref;
167
182
  if (!appRef)
168
183
  return;
169
- appRef.current = node === null ? null : buildSearchBarHandle(() => node);
184
+ appRef.current =
185
+ node === null ? null : buildSearchBarHandle(() => node);
170
186
  },
171
187
  }
172
188
  : undefined,
@@ -188,7 +204,14 @@ const StackImpl = forwardRef((props, forwardedRef) => {
188
204
  // sizing (see RNS_SCREEN_CONTENT_WRAPPER_VIEW_NAME's comment in core/constants.ts). A
189
205
  // `push` screen doesn't need it, but a `formSheet` one is otherwise left with no content
190
206
  // ever attached natively.
191
- const content = createElement(RNS_SCREEN_CONTENT_WRAPPER_VIEW_NAME, plan.contentWrapperProps, createElement(NavigationContext.Provider, { value: { route, navigation: handle, emitter: routeEmitter, parent: ambientContext } }, createElement(entry.component)));
207
+ const content = createElement(RNS_SCREEN_CONTENT_WRAPPER_VIEW_NAME, plan.contentWrapperProps, createElement(NavigationContext.Provider, {
208
+ value: {
209
+ route,
210
+ navigation: handle,
211
+ emitter: routeEmitter,
212
+ parent: ambientContext,
213
+ },
214
+ }, createElement(entry.component)));
192
215
  // react-native-screens' own Screen.tsx swaps in a DIFFERENT Fabric component
193
216
  // ('RNSModalScreen') for a modally-presented screen - its native updateLayoutMetrics: relies on
194
217
  // this exact class to know it must NOT apply Yoga's computed frame (see resolveScreenViewName's
@@ -205,7 +228,10 @@ const StackImpl = forwardRef((props, forwardedRef) => {
205
228
  // RNSScreen.mm treats an unset/inactive nested screen as not yet pushed, leaving it
206
229
  // parked at its pre-push transition position (off past the bottom edge) instead of
207
230
  // its real, presented frame.
208
- { style: plan.innerScreenStyle, activityState: plan.activityState }, descriptorToReact(plan.headerConfig), content)))
231
+ {
232
+ style: plan.innerScreenStyle,
233
+ activityState: plan.activityState,
234
+ }, descriptorToReact(plan.headerConfig), content)))
209
235
  : createElement(plan.screenViewName, { key: route.key, ...plan.screenProps }, descriptorToReact(plan.headerConfig), content);
210
236
  });
211
237
  return createElement(RNS_SCREEN_STACK_VIEW_NAME, stackProps, ...children);
@@ -17,7 +17,9 @@ function isTabScreenElement(child) {
17
17
  return isValidElement(child) && child.type === TabScreen;
18
18
  }
19
19
  function resolveTabOptions(entry, optionsArgs, screenOptions) {
20
- const own = typeof entry.options === 'function' ? entry.options(optionsArgs) : entry.options;
20
+ const own = typeof entry.options === 'function'
21
+ ? entry.options(optionsArgs)
22
+ : entry.options;
21
23
  return { ...screenOptions, ...own };
22
24
  }
23
25
  const TAB_CONTENT_STYLE = { flex: 1 };
@@ -41,7 +43,9 @@ const TabImpl = forwardRef((props, forwardedRef) => {
41
43
  // than staying frozen at whatever the first render saw. `null` means no marker had registered
42
44
  // yet: seeding an empty list would resolve initialRouteName against nothing and lose it, so the
43
45
  // state stays derived until either a marker arrives or something dispatches.
44
- const [storedState, setStoredState] = useState(() => routes.length === 0 ? null : createInitialTabState(routes, props.initialRouteName));
46
+ const [storedState, setStoredState] = useState(() => routes.length === 0
47
+ ? null
48
+ : createInitialTabState(routes, props.initialRouteName));
45
49
  const resolveState = useCallback((stored) => stored === null
46
50
  ? createInitialTabState(routes, props.initialRouteName)
47
51
  : reconcileTabRoutes(stored, routes), [routes, props.initialRouteName]);
@@ -84,11 +88,17 @@ const TabImpl = forwardRef((props, forwardedRef) => {
84
88
  },
85
89
  };
86
90
  });
87
- const focusedEntry = focusedRoute ? registry.get(focusedRoute.name) : undefined;
91
+ const focusedEntry = focusedRoute
92
+ ? registry.get(focusedRoute.name)
93
+ : undefined;
88
94
  const focusedOptions = focusedEntry && focusedRoute
89
95
  ? resolveTabOptions(focusedEntry, { route: focusedRoute, navigation: handle }, props.screenOptions)
90
96
  : props.screenOptions;
91
- const tabBar = descriptorToReact(renderTabBar({ items, style: focusedOptions?.tabBarStyle, passthrough: {} }));
97
+ const tabBar = descriptorToReact(renderTabBar({
98
+ items,
99
+ style: focusedOptions?.tabBarStyle,
100
+ passthrough: {},
101
+ }));
92
102
  // Only the focused route's screen is ever mounted (unlike Stack, which keeps every pushed route
93
103
  // alive), so a fresh emitter per focus change is sufficient - no per-route emitter map to prune,
94
104
  // because the previous screen's whole subtree (and any listeners it registered) is torn down by
@@ -0,0 +1,22 @@
1
+ import type { Accessor } from 'solid-js';
2
+ import type { JSX } from '@symbiote-native/solid/jsx-runtime';
3
+ import type { IStyleProp, IViewStyle } from '@symbiote-native/engine';
4
+ import type { IDrawerDescriptorMap, IDrawerNavigatorHandle, IDrawerOptions, IDrawerRouterState } from '../../core';
5
+ import { DrawerScreen } from '../screen';
6
+ export type { IDrawerNavigatorHandle, IDrawerDescriptorMap } from '../../core';
7
+ export type IDrawerContentSlotProps = {
8
+ state: IDrawerRouterState;
9
+ descriptors: IDrawerDescriptorMap;
10
+ navigation: IDrawerNavigatorHandle;
11
+ };
12
+ export type IDrawerProps = IDrawerOptions & {
13
+ initialRouteName?: string;
14
+ drawerStyle?: IStyleProp<IViewStyle>;
15
+ drawerContent?: (props: Accessor<IDrawerContentSlotProps>) => JSX.Element;
16
+ ref?: (handle: IDrawerNavigatorHandle) => void;
17
+ children?: JSX.Element;
18
+ };
19
+ declare function DrawerImpl(props: IDrawerProps): JSX.Element;
20
+ export declare const Drawer: typeof DrawerImpl & {
21
+ Screen: typeof DrawerScreen;
22
+ };