@symbiote-native/navigation 2.1.0 → 3.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 (237) hide show
  1. package/README.md +89 -14
  2. package/build/angular/drawer/index.js +23 -9
  3. package/build/angular/index.d.ts +4 -4
  4. package/build/angular/index.js +1 -1
  5. package/build/angular/injectors/inject-navigation.js +1 -1
  6. package/build/angular/navigation-scope.directive.js +1 -1
  7. package/build/angular/search-bar-ref.directive.js +1 -1
  8. package/build/angular/stack/index.js +20 -6
  9. package/build/angular/tabs/index.js +21 -7
  10. package/build/core/drawer-options/index.js +19 -5
  11. package/build/core/drawer-router-state/index.js +8 -2
  12. package/build/core/guards.js +3 -1
  13. package/build/core/header-bar-buttons.js +14 -4
  14. package/build/core/index.d.ts +4 -4
  15. package/build/core/index.js +2 -2
  16. package/build/core/navigator-state/index.js +12 -4
  17. package/build/core/render-drawer.js +4 -1
  18. package/build/core/render-stack.js +13 -4
  19. package/build/core/screen-options.js +1 -1
  20. package/build/core/search-bar-commands.js +1 -1
  21. package/build/core/state-persistence/index.js +6 -2
  22. package/build/core/tab-router-state/index.js +8 -2
  23. package/build/react/drawer/index.js +36 -13
  24. package/build/react/index.d.ts +7 -7
  25. package/build/react/index.js +3 -3
  26. package/build/react/stack/index.js +34 -8
  27. package/build/react/tabs/index.js +14 -4
  28. package/build/solid/drawer/index.d.ts +22 -0
  29. package/build/solid/drawer/index.js +394 -0
  30. package/build/solid/drawer-screen-props.d.ts +13 -0
  31. package/build/solid/drawer-screen-props.js +2 -0
  32. package/build/solid/host.d.ts +2 -0
  33. package/build/solid/host.js +23 -0
  34. package/build/solid/index.d.ts +19 -0
  35. package/build/solid/index.js +24 -0
  36. package/build/solid/linking.d.ts +3 -0
  37. package/build/solid/linking.js +55 -0
  38. package/build/solid/navigation-context.d.ts +13 -0
  39. package/build/solid/navigation-context.js +37 -0
  40. package/build/solid/primitives/create-focus-effect.d.ts +1 -0
  41. package/build/solid/primitives/create-focus-effect.js +30 -0
  42. package/build/solid/primitives/create-is-focused.d.ts +2 -0
  43. package/build/solid/primitives/create-is-focused.js +31 -0
  44. package/build/solid/primitives/create-navigation-state.d.ts +3 -0
  45. package/build/solid/primitives/create-navigation-state.js +30 -0
  46. package/build/solid/primitives/index.d.ts +12 -0
  47. package/build/solid/primitives/index.js +8 -0
  48. package/build/solid/primitives/use-drawer-navigation.d.ts +5 -0
  49. package/build/solid/primitives/use-drawer-navigation.js +15 -0
  50. package/build/solid/primitives/use-navigation.d.ts +8 -0
  51. package/build/solid/primitives/use-navigation.js +23 -0
  52. package/build/solid/primitives/use-route.d.ts +3 -0
  53. package/build/solid/primitives/use-route.js +14 -0
  54. package/build/solid/primitives/use-stack-navigation.d.ts +5 -0
  55. package/build/solid/primitives/use-stack-navigation.js +19 -0
  56. package/build/solid/primitives/use-tab-navigation.d.ts +5 -0
  57. package/build/solid/primitives/use-tab-navigation.js +15 -0
  58. package/build/solid/screen-props.d.ts +19 -0
  59. package/build/solid/screen-props.js +9 -0
  60. package/build/solid/screen-registry.d.ts +31 -0
  61. package/build/solid/screen-registry.js +86 -0
  62. package/build/solid/screen.d.ts +6 -0
  63. package/build/solid/screen.js +69 -0
  64. package/build/solid/stack/index.d.ts +15 -0
  65. package/build/solid/stack/index.js +348 -0
  66. package/build/solid/tab-screen-props.d.ts +13 -0
  67. package/build/solid/tab-screen-props.js +3 -0
  68. package/build/solid/tabs/index.d.ts +14 -0
  69. package/build/solid/tabs/index.js +228 -0
  70. package/build/svelte/descriptor-subtree.js +3 -1
  71. package/build/svelte/drawer/index.svelte +163 -25
  72. package/build/svelte/drawer-screen.svelte +2 -1
  73. package/build/svelte/index.d.ts +3 -3
  74. package/build/svelte/index.js +1 -1
  75. package/build/svelte/navigation-scope.svelte +4 -1
  76. package/build/svelte/runes/use-navigation.svelte.js +5 -1
  77. package/build/svelte/stack/index.svelte +43 -6
  78. package/build/svelte/stack/stack-screen.svelte +66 -9
  79. package/build/svelte/tabs/index.svelte +42 -20
  80. package/build/vue/composables/use-navigation.js +5 -1
  81. package/build/vue/drawer/index.js +30 -8
  82. package/build/vue/index.d.ts +3 -3
  83. package/build/vue/index.js +1 -1
  84. package/build/vue/navigation-context.js +1 -1
  85. package/build/vue/stack/index.js +17 -6
  86. package/build/vue/tabs/index.js +18 -5
  87. package/build-ngc/angular/drawer/index.js +31 -11
  88. package/build-ngc/angular/drawer/index.js.map +1 -1
  89. package/build-ngc/angular/index.d.ts +4 -4
  90. package/build-ngc/angular/index.js.map +1 -1
  91. package/build-ngc/angular/injectors/inject-focus-effect.js.map +1 -1
  92. package/build-ngc/angular/injectors/inject-is-focused.js.map +1 -1
  93. package/build-ngc/angular/injectors/inject-navigation-state.js.map +1 -1
  94. package/build-ngc/angular/injectors/inject-navigation.js +1 -1
  95. package/build-ngc/angular/injectors/inject-navigation.js.map +1 -1
  96. package/build-ngc/angular/linking.js.map +1 -1
  97. package/build-ngc/angular/navigation-context.service.js.map +1 -1
  98. package/build-ngc/angular/navigation-scope.directive.js +1 -1
  99. package/build-ngc/angular/navigation-scope.directive.js.map +1 -1
  100. package/build-ngc/angular/screen.directive.js.map +1 -1
  101. package/build-ngc/angular/search-bar-ref.directive.js +1 -1
  102. package/build-ngc/angular/search-bar-ref.directive.js.map +1 -1
  103. package/build-ngc/angular/stack/index.js +26 -8
  104. package/build-ngc/angular/stack/index.js.map +1 -1
  105. package/build-ngc/angular/tab-screen.directive.js.map +1 -1
  106. package/build-ngc/angular/tabs/index.js +21 -7
  107. package/build-ngc/angular/tabs/index.js.map +1 -1
  108. package/build-ngc/core/constants.js.map +1 -1
  109. package/build-ngc/core/drawer-options/index.js +19 -5
  110. package/build-ngc/core/drawer-options/index.js.map +1 -1
  111. package/build-ngc/core/drawer-router-state/index.js +8 -2
  112. package/build-ngc/core/drawer-router-state/index.js.map +1 -1
  113. package/build-ngc/core/guards.js +3 -1
  114. package/build-ngc/core/guards.js.map +1 -1
  115. package/build-ngc/core/header-bar-buttons.js +14 -4
  116. package/build-ngc/core/header-bar-buttons.js.map +1 -1
  117. package/build-ngc/core/index.d.ts +4 -4
  118. package/build-ngc/core/index.js +2 -2
  119. package/build-ngc/core/index.js.map +1 -1
  120. package/build-ngc/core/linking-config/index.js.map +1 -1
  121. package/build-ngc/core/navigation-events/index.js.map +1 -1
  122. package/build-ngc/core/navigator-handles/index.js.map +1 -1
  123. package/build-ngc/core/navigator-state/index.js +12 -4
  124. package/build-ngc/core/navigator-state/index.js.map +1 -1
  125. package/build-ngc/core/render-drawer.js +4 -1
  126. package/build-ngc/core/render-drawer.js.map +1 -1
  127. package/build-ngc/core/render-stack.js +13 -4
  128. package/build-ngc/core/render-stack.js.map +1 -1
  129. package/build-ngc/core/render-tabs.js.map +1 -1
  130. package/build-ngc/core/screen-options.js +1 -1
  131. package/build-ngc/core/screen-options.js.map +1 -1
  132. package/build-ngc/core/search-bar-commands.js +1 -1
  133. package/build-ngc/core/search-bar-commands.js.map +1 -1
  134. package/build-ngc/core/stack-router-state/index.js.map +1 -1
  135. package/build-ngc/core/state-persistence/index.js +6 -2
  136. package/build-ngc/core/state-persistence/index.js.map +1 -1
  137. package/build-ngc/core/tab-router-state/index.js +8 -2
  138. package/build-ngc/core/tab-router-state/index.js.map +1 -1
  139. package/package.json +40 -15
  140. package/src/angular/drawer/index.ts +69 -25
  141. package/src/angular/index.ts +20 -4
  142. package/src/angular/injectors/inject-focus-effect.ts +8 -2
  143. package/src/angular/injectors/inject-is-focused.ts +6 -4
  144. package/src/angular/injectors/inject-navigation-state.ts +7 -4
  145. package/src/angular/injectors/inject-navigation.ts +12 -3
  146. package/src/angular/linking.ts +4 -1
  147. package/src/angular/navigation-context.service.ts +5 -2
  148. package/src/angular/navigation-scope.directive.ts +6 -2
  149. package/src/angular/screen.directive.ts +13 -3
  150. package/src/angular/search-bar-ref.directive.ts +10 -2
  151. package/src/angular/stack/index.ts +68 -22
  152. package/src/angular/tab-screen.directive.ts +3 -1
  153. package/src/angular/tabs/index.ts +36 -12
  154. package/src/core/constants.ts +6 -3
  155. package/src/core/drawer-options/index.ts +40 -13
  156. package/src/core/drawer-router-state/index.ts +11 -3
  157. package/src/core/guards.ts +3 -1
  158. package/src/core/header-bar-buttons.ts +41 -12
  159. package/src/core/index.ts +18 -4
  160. package/src/core/linking-config/index.ts +31 -10
  161. package/src/core/navigation-events/index.ts +8 -2
  162. package/src/core/navigator-handles/index.ts +8 -3
  163. package/src/core/navigator-props.ts +13 -4
  164. package/src/core/navigator-state/index.ts +24 -7
  165. package/src/core/render-drawer.ts +24 -9
  166. package/src/core/render-stack.ts +52 -13
  167. package/src/core/render-tabs.ts +24 -6
  168. package/src/core/screen-options.ts +15 -5
  169. package/src/core/search-bar-commands.ts +12 -3
  170. package/src/core/stack-router-state/index.ts +5 -2
  171. package/src/core/state-persistence/index.ts +13 -3
  172. package/src/core/tab-router-state/index.ts +10 -3
  173. package/src/react/drawer/index.ts +408 -344
  174. package/src/react/drawer-screen.ts +8 -2
  175. package/src/react/hooks/use-focus-effect.ts +8 -2
  176. package/src/react/hooks/use-is-focused.ts +6 -2
  177. package/src/react/hooks/use-navigation.ts +8 -2
  178. package/src/react/index.ts +37 -7
  179. package/src/react/linking.ts +4 -1
  180. package/src/react/navigation-context.ts +6 -2
  181. package/src/react/screen.ts +12 -3
  182. package/src/react/stack/index.ts +294 -231
  183. package/src/react/tab-screen.ts +3 -1
  184. package/src/react/tabs/index.ts +188 -158
  185. package/src/solid/drawer/index.ts +570 -0
  186. package/src/solid/drawer-screen-props.ts +24 -0
  187. package/src/solid/host.ts +29 -0
  188. package/src/solid/index.ts +87 -0
  189. package/src/solid/linking.ts +74 -0
  190. package/src/solid/navigation-context.ts +56 -0
  191. package/src/solid/primitives/create-focus-effect.ts +41 -0
  192. package/src/solid/primitives/create-is-focused.ts +41 -0
  193. package/src/solid/primitives/create-navigation-state.ts +44 -0
  194. package/src/solid/primitives/index.ts +12 -0
  195. package/src/solid/primitives/use-drawer-navigation.ts +25 -0
  196. package/src/solid/primitives/use-navigation.ts +44 -0
  197. package/src/solid/primitives/use-route.ts +18 -0
  198. package/src/solid/primitives/use-stack-navigation.ts +29 -0
  199. package/src/solid/primitives/use-tab-navigation.ts +25 -0
  200. package/src/solid/screen-props.ts +51 -0
  201. package/src/solid/screen-registry.ts +159 -0
  202. package/src/solid/screen.ts +80 -0
  203. package/src/solid/stack/index.ts +528 -0
  204. package/src/solid/tab-screen-props.ts +21 -0
  205. package/src/solid/tabs/index.ts +327 -0
  206. package/src/svelte/attachments.ts +3 -1
  207. package/src/svelte/descriptor-subtree.ts +3 -1
  208. package/src/svelte/drawer/index.svelte +163 -25
  209. package/src/svelte/drawer-screen-props.ts +8 -2
  210. package/src/svelte/drawer-screen.svelte +2 -1
  211. package/src/svelte/fabric-tree.test-helper.ts +37 -3
  212. package/src/svelte/index.ts +15 -3
  213. package/src/svelte/linking.svelte.ts +11 -5
  214. package/src/svelte/navigation-scope.svelte +4 -1
  215. package/src/svelte/runes/use-drawer-navigation.svelte.ts +3 -1
  216. package/src/svelte/runes/use-focus-effect.svelte.ts +8 -2
  217. package/src/svelte/runes/use-navigation-state.svelte.ts +3 -1
  218. package/src/svelte/runes/use-navigation.svelte.ts +13 -3
  219. package/src/svelte/runes/use-stack-navigation.svelte.ts +3 -1
  220. package/src/svelte/screen-props.ts +7 -2
  221. package/src/svelte/screen-registry.ts +9 -3
  222. package/src/svelte/stack/index.svelte +43 -6
  223. package/src/svelte/stack/stack-screen.svelte +66 -9
  224. package/src/svelte/svelte-compile.test-helper.ts +16 -12
  225. package/src/svelte/tab-screen-props.ts +3 -1
  226. package/src/svelte/tabs/index.svelte +42 -20
  227. package/src/vue/composables/use-navigation-state.ts +7 -4
  228. package/src/vue/composables/use-navigation.ts +13 -3
  229. package/src/vue/drawer/index.ts +122 -36
  230. package/src/vue/drawer-screen.ts +12 -5
  231. package/src/vue/index.ts +15 -3
  232. package/src/vue/linking.ts +7 -2
  233. package/src/vue/navigation-context.ts +17 -5
  234. package/src/vue/screen.ts +7 -2
  235. package/src/vue/stack/index.ts +82 -34
  236. package/src/vue/tab-screen.ts +3 -1
  237. package/src/vue/tabs/index.ts +51 -13
@@ -26,10 +26,13 @@ export function useNavigationState<TResult>(
26
26
  let unsubscribe: (() => void) | undefined;
27
27
 
28
28
  onMounted(() => {
29
- unsubscribe = scope.value.emitter.addListener(NAVIGATION_EVENT_STATE, (state: unknown) => {
30
- if (!isNavigatorState(state)) return;
31
- result.value = selector(state);
32
- });
29
+ unsubscribe = scope.value.emitter.addListener(
30
+ NAVIGATION_EVENT_STATE,
31
+ (state: unknown) => {
32
+ if (!isNavigatorState(state)) return;
33
+ result.value = selector(state);
34
+ },
35
+ );
33
36
  });
34
37
 
35
38
  onUnmounted(() => unsubscribe?.());
@@ -5,12 +5,18 @@
5
5
 
6
6
  import { computed } from '@vue/runtime-core';
7
7
  import type { ComputedRef } from '@vue/runtime-core';
8
- import type { INavigationEventListener, INavigationEventName } from '../../core';
8
+ import type {
9
+ INavigationEventListener,
10
+ INavigationEventName,
11
+ } from '../../core';
9
12
  import { requireNavigationScope } from '../navigation-context';
10
13
  import type { IAnyNavigatorHandle } from '../navigation-context';
11
14
 
12
15
  export type INavigationHandle = IAnyNavigatorHandle & {
13
- addListener: (event: INavigationEventName, listener: INavigationEventListener) => () => void;
16
+ addListener: (
17
+ event: INavigationEventName,
18
+ listener: INavigationEventListener,
19
+ ) => () => void;
14
20
  // Walks exactly ONE hop up the scope's `parent` chain to the enclosing navigator's handle -
15
21
  // e.g. a Tab screen nested inside a Stack screen calling getParent() to push a new Stack route.
16
22
  // Callers narrow the union themselves ('push' in parent, etc.). Deliberately NOT
@@ -25,6 +31,10 @@ export function useNavigation(): ComputedRef<INavigationHandle> {
25
31
  const scope = requireNavigationScope('useNavigation');
26
32
  return computed(() => {
27
33
  const { navigation, emitter, parent } = scope.value;
28
- return { ...navigation, addListener: emitter.addListener, getParent: () => parent?.navigation };
34
+ return {
35
+ ...navigation,
36
+ addListener: emitter.addListener,
37
+ getParent: () => parent?.navigation,
38
+ };
29
39
  });
30
40
  }
@@ -35,7 +35,10 @@ import {
35
35
  normalizeVueAttrs,
36
36
  useWindowDimensions,
37
37
  } from '@symbiote-native/vue';
38
- import type { IPanResponderGestureState, ISymbioteEvent } from '@symbiote-native/vue';
38
+ import type {
39
+ IPanResponderGestureState,
40
+ ISymbioteEvent,
41
+ } from '@symbiote-native/vue';
39
42
  import type { IDescriptor } from '@symbiote-native/components';
40
43
  import { dlog } from '@symbiote-native/engine';
41
44
  import type { IStyleProp, IViewStyle } from '@symbiote-native/engine';
@@ -71,7 +74,10 @@ import type {
71
74
  } from '../../core';
72
75
  import { NavigationScope, injectNavigationScope } from '../navigation-context';
73
76
  import { DrawerScreen } from '../drawer-screen';
74
- import type { IDrawerScreenOptionsArgs, IDrawerScreenProps } from '../drawer-screen';
77
+ import type {
78
+ IDrawerScreenOptionsArgs,
79
+ IDrawerScreenProps,
80
+ } from '../drawer-screen';
75
81
 
76
82
  export type { IDrawerNavigatorHandle, IDrawerDescriptorMap } from '../../core';
77
83
 
@@ -113,7 +119,12 @@ function isStyleProp(value: unknown): value is IStyleProp<IViewStyle> {
113
119
  return isRecord(value);
114
120
  }
115
121
 
116
- const DRAWER_TYPES: ReadonlyArray<IDrawerType> = ['front', 'back', 'slide', 'permanent'];
122
+ const DRAWER_TYPES: ReadonlyArray<IDrawerType> = [
123
+ 'front',
124
+ 'back',
125
+ 'slide',
126
+ 'permanent',
127
+ ];
117
128
  // .some() itself doesn't narrow `value`'s type back at the call site - the `value is IDrawerType`
118
129
  // predicate on THIS function is what lets asDrawerType's ternary return `value` typed, mirroring
119
130
  // Modal's isOrientation guard (adapters/vue/src/components/modal.ts).
@@ -126,30 +137,45 @@ function asDrawerType(value: unknown): IDrawerType | undefined {
126
137
 
127
138
  const DRAWER_POSITIONS: ReadonlyArray<IDrawerPosition> = ['left', 'right'];
128
139
  function isDrawerPosition(value: unknown): value is IDrawerPosition {
129
- return typeof value === 'string' && DRAWER_POSITIONS.some(position => position === value);
140
+ return (
141
+ typeof value === 'string' &&
142
+ DRAWER_POSITIONS.some(position => position === value)
143
+ );
130
144
  }
131
145
  function asDrawerPosition(value: unknown): IDrawerPosition | undefined {
132
146
  return isDrawerPosition(value) ? value : undefined;
133
147
  }
134
148
 
135
- function asComponent(value: unknown): IDrawerScreenProps['component'] | undefined {
136
- if (typeof value === 'function') return value as IDrawerScreenProps['component'];
137
- return isRecord(value) ? (value as IDrawerScreenProps['component']) : undefined;
149
+ function asComponent(
150
+ value: unknown,
151
+ ): IDrawerScreenProps['component'] | undefined {
152
+ if (typeof value === 'function')
153
+ return value as IDrawerScreenProps['component'];
154
+ return isRecord(value)
155
+ ? (value as IDrawerScreenProps['component'])
156
+ : undefined;
138
157
  }
139
158
 
140
159
  // IDrawerScreenOptions carries only `title`/`drawerLabel`, small enough for direct field guards -
141
160
  // kept as a single cast-at-the-edge helper anyway for symmetry with stack.ts/tabs.ts's
142
161
  // asScreenOptions/asTabOptions (same CLAUDE.md-sanctioned I/O-edge narrowing).
143
- function asDrawerScreenOptions(value: unknown): IDrawerScreenOptions | undefined {
162
+ function asDrawerScreenOptions(
163
+ value: unknown,
164
+ ): IDrawerScreenOptions | undefined {
144
165
  return isRecord(value) ? (value as IDrawerScreenOptions) : undefined;
145
166
  }
146
167
 
147
- function asDrawerScreenOptionsOrResolver(value: unknown): IDrawerScreenProps['options'] {
148
- if (typeof value === 'function') return value as IDrawerScreenProps['options'];
168
+ function asDrawerScreenOptionsOrResolver(
169
+ value: unknown,
170
+ ): IDrawerScreenProps['options'] {
171
+ if (typeof value === 'function')
172
+ return value as IDrawerScreenProps['options'];
149
173
  return asDrawerScreenOptions(value);
150
174
  }
151
175
 
152
- function collectRegistry(vnodes: readonly VNode[]): Map<string, IDrawerRegistryEntry> {
176
+ function collectRegistry(
177
+ vnodes: readonly VNode[],
178
+ ): Map<string, IDrawerRegistryEntry> {
153
179
  const registry = new Map<string, IDrawerRegistryEntry>();
154
180
  for (const vnode of vnodes) {
155
181
  if (vnode.type !== DrawerScreen || !isRecord(vnode.props)) continue;
@@ -169,7 +195,8 @@ function resolveDrawerScreenOptions(
169
195
  entry: IDrawerRegistryEntry,
170
196
  screenComponentProps: IDrawerScreenOptionsArgs,
171
197
  ): IDrawerScreenOptions {
172
- if (typeof entry.options === 'function') return entry.options(screenComponentProps);
198
+ if (typeof entry.options === 'function')
199
+ return entry.options(screenComponentProps);
173
200
  return entry.options ?? {};
174
201
  }
175
202
 
@@ -200,7 +227,9 @@ const DrawerImpl = defineComponent<IDrawerProps>(
200
227
  let routeSequence = 0;
201
228
  const routeIdPrefix = useId();
202
229
 
203
- function buildRoutes(registry: Map<string, IDrawerRegistryEntry>): IRoute<unknown>[] {
230
+ function buildRoutes(
231
+ registry: Map<string, IDrawerRegistryEntry>,
232
+ ): IRoute<unknown>[] {
204
233
  return Array.from(registry.entries()).map(([name, entry]) => {
205
234
  routeSequence += 1;
206
235
  return {
@@ -213,10 +242,14 @@ const DrawerImpl = defineComponent<IDrawerProps>(
213
242
 
214
243
  const initialRegistry = collectRegistry(slots.default?.() ?? []);
215
244
  const initialRoutes = buildRoutes(initialRegistry);
216
- if (initialRoutes.length === 0) dlog('Drawer: no <Drawer.Screen> children registered');
245
+ if (initialRoutes.length === 0)
246
+ dlog('Drawer: no <Drawer.Screen> children registered');
217
247
 
218
248
  const state = shallowRef(
219
- createInitialDrawerRouterState(initialRoutes, asString(attrs.initialRouteName)),
249
+ createInitialDrawerRouterState(
250
+ initialRoutes,
251
+ asString(attrs.initialRouteName),
252
+ ),
220
253
  );
221
254
 
222
255
  function dispatch(action: Parameters<typeof drawerRouterReducer>[1]): void {
@@ -235,7 +268,9 @@ const DrawerImpl = defineComponent<IDrawerProps>(
235
268
  let dragStartProgress = 0;
236
269
 
237
270
  function animateProgressTo(open: boolean): void {
238
- dlog(`Drawer: animateProgressTo(open=${open}) starting at t=${Date.now()}`);
271
+ dlog(
272
+ `Drawer: animateProgressTo(open=${open}) starting at t=${Date.now()}`,
273
+ );
239
274
  Animated.timing(progress, {
240
275
  toValue: open ? 1 : 0,
241
276
  duration: DRAWER_SNAP_DURATION,
@@ -248,17 +283,23 @@ const DrawerImpl = defineComponent<IDrawerProps>(
248
283
 
249
284
  const handle: IDrawerNavigatorHandle = {
250
285
  openDrawer: () => {
251
- dlog(`Drawer: openDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
286
+ dlog(
287
+ `Drawer: openDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`,
288
+ );
252
289
  animateProgressTo(true);
253
290
  dispatch({ type: 'openDrawer' });
254
291
  },
255
292
  closeDrawer: () => {
256
- dlog(`Drawer: closeDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
293
+ dlog(
294
+ `Drawer: closeDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`,
295
+ );
257
296
  animateProgressTo(false);
258
297
  dispatch({ type: 'closeDrawer' });
259
298
  },
260
299
  toggleDrawer: () => {
261
- dlog(`Drawer: toggleDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
300
+ dlog(
301
+ `Drawer: toggleDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`,
302
+ );
262
303
  animateProgressTo(!state.value.isOpen);
263
304
  dispatch({ type: 'toggleDrawer' });
264
305
  },
@@ -308,13 +349,23 @@ const DrawerImpl = defineComponent<IDrawerProps>(
308
349
  _event: ISymbioteEvent,
309
350
  gestureState: IPanResponderGestureState,
310
351
  ): void => {
311
- progress.setValue(resolveDragProgress(gestureState, dragStartProgress, currentOptions()));
352
+ progress.setValue(
353
+ resolveDragProgress(
354
+ gestureState,
355
+ dragStartProgress,
356
+ currentOptions(),
357
+ ),
358
+ );
312
359
  },
313
360
  onPanResponderRelease: (
314
361
  _event: ISymbioteEvent,
315
362
  gestureState: IPanResponderGestureState,
316
363
  ): void => {
317
- const intent = resolveSwipeIntent(gestureState, state.value.isOpen, currentOptions());
364
+ const intent = resolveSwipeIntent(
365
+ gestureState,
366
+ state.value.isOpen,
367
+ currentOptions(),
368
+ );
318
369
  const open = intent === 'open';
319
370
  dlog(`Drawer: gesture release -> ${open ? 'open' : 'close'}`);
320
371
  animateProgressTo(open);
@@ -367,7 +418,10 @@ const DrawerImpl = defineComponent<IDrawerProps>(
367
418
  watch(
368
419
  () => focusedKeyOf(state.value),
369
420
  nextKey => {
370
- const { blurKey, focusKey } = diffFocusedRoute(focusedRouteKey, nextKey);
421
+ const { blurKey, focusKey } = diffFocusedRoute(
422
+ focusedRouteKey,
423
+ nextKey,
424
+ );
371
425
  if (blurKey === undefined && focusKey === undefined) return;
372
426
  focusedRouteKey = nextKey;
373
427
  nextTick(() => {
@@ -383,24 +437,32 @@ const DrawerImpl = defineComponent<IDrawerProps>(
383
437
  },
384
438
  );
385
439
  onUnmounted(() => {
386
- if (focusedRouteKey !== undefined) emitterFor(focusedRouteKey).emit(NAVIGATION_EVENT_BLUR);
440
+ if (focusedRouteKey !== undefined)
441
+ emitterFor(focusedRouteKey).emit(NAVIGATION_EVENT_BLUR);
387
442
  });
388
443
 
389
444
  return () => {
390
445
  const registry = collectRegistry(slots.default?.() ?? []);
391
446
  const options = currentOptions();
392
- const drawerStyle = isStyleProp(attrs.drawerStyle) ? attrs.drawerStyle : undefined;
447
+ const drawerStyle = isStyleProp(attrs.drawerStyle)
448
+ ? attrs.drawerStyle
449
+ : undefined;
393
450
 
394
- if (registry.size === 0) dlog('Drawer: no <Drawer.Screen> children registered');
451
+ if (registry.size === 0)
452
+ dlog('Drawer: no <Drawer.Screen> children registered');
395
453
 
396
454
  const animated = isDrawerAnimated(options);
397
455
  const geometry = resolveDrawerGeometry(options);
398
456
 
399
457
  const panelTranslateX = animated
400
- ? progress.interpolate(resolveDrawerSlotInterpolation(geometry, 'panel').translateX)
458
+ ? progress.interpolate(
459
+ resolveDrawerSlotInterpolation(geometry, 'panel').translateX,
460
+ )
401
461
  : undefined;
402
462
  const contentTranslateX = animated
403
- ? progress.interpolate(resolveDrawerSlotInterpolation(geometry, 'content').translateX)
463
+ ? progress.interpolate(
464
+ resolveDrawerSlotInterpolation(geometry, 'content').translateX,
465
+ )
404
466
  : undefined;
405
467
  // The overlay is a full-screen absolutely-positioned sibling BELOW content in paint order
406
468
  // (see render-drawer.ts's drawerChildOrder) - for 'front' that's fine since content never
@@ -419,9 +481,13 @@ const DrawerImpl = defineComponent<IDrawerProps>(
419
481
  : undefined;
420
482
 
421
483
  const focusedRoute = state.value.routes[state.value.index];
422
- const focusedEntry = focusedRoute ? registry.get(focusedRoute.name) : undefined;
484
+ const focusedEntry = focusedRoute
485
+ ? registry.get(focusedRoute.name)
486
+ : undefined;
423
487
  if (focusedRoute && !focusedEntry) {
424
- dlog(`Drawer: no screen registered for route name "${focusedRoute.name}"`);
488
+ dlog(
489
+ `Drawer: no screen registered for route name "${focusedRoute.name}"`,
490
+ );
425
491
  }
426
492
 
427
493
  const content =
@@ -447,17 +513,25 @@ const DrawerImpl = defineComponent<IDrawerProps>(
447
513
  const entry = registry.get(route.name);
448
514
  if (entry === undefined) continue;
449
515
  descriptors[route.key] = {
450
- options: resolveDrawerScreenOptions(entry, { route, navigation: handle }),
516
+ options: resolveDrawerScreenOptions(entry, {
517
+ route,
518
+ navigation: handle,
519
+ }),
451
520
  navigation: handle,
452
521
  };
453
522
  }
454
523
 
455
524
  const drawerContent =
456
- slots.drawerContent?.({ state: state.value, descriptors, navigation: handle }) ?? null;
525
+ slots.drawerContent?.({
526
+ state: state.value,
527
+ descriptors,
528
+ navigation: handle,
529
+ }) ?? null;
457
530
 
458
531
  const root = renderDrawer(
459
532
  {
460
- overlayColor: asString(attrs.overlayColor) ?? DRAWER_DEFAULT_OVERLAY_COLOR,
533
+ overlayColor:
534
+ asString(attrs.overlayColor) ?? DRAWER_DEFAULT_OVERLAY_COLOR,
461
535
  drawerStyle,
462
536
  contentPassthrough: {},
463
537
  overlayPassthrough: animated
@@ -479,7 +553,8 @@ const DrawerImpl = defineComponent<IDrawerProps>(
479
553
  const slotDescriptors = new Map<IDrawerSlot, IDescriptor>();
480
554
  order.forEach((slot, index) => {
481
555
  const descriptor = root.children[index];
482
- if (typeof descriptor !== 'string') slotDescriptors.set(slot, descriptor);
556
+ if (typeof descriptor !== 'string')
557
+ slotDescriptors.set(slot, descriptor);
483
558
  });
484
559
 
485
560
  const slotChildren: Record<IDrawerSlot, VNode[] | null> = {
@@ -498,7 +573,10 @@ const DrawerImpl = defineComponent<IDrawerProps>(
498
573
  overlay:
499
574
  overlayOpacity === undefined
500
575
  ? undefined
501
- : { opacity: overlayOpacity, transform: [{ translateX: overlayTranslateX }] },
576
+ : {
577
+ opacity: overlayOpacity,
578
+ transform: [{ translateX: overlayTranslateX }],
579
+ },
502
580
  panel:
503
581
  panelTranslateX === undefined
504
582
  ? undefined
@@ -511,10 +589,18 @@ const DrawerImpl = defineComponent<IDrawerProps>(
511
589
  const children = slotChildren[slot] ?? [];
512
590
  const animatedStyle = slotAnimatedStyle[slot];
513
591
  if (animatedStyle === undefined) {
514
- return h(descriptor.type, { key: descriptor.key, ...descriptor.props }, children);
592
+ return h(
593
+ descriptor.type,
594
+ { key: descriptor.key, ...descriptor.props },
595
+ children,
596
+ );
515
597
  }
516
598
  const style = [descriptor.props.style, animatedStyle];
517
- return h(Animated.View, { key: descriptor.key, ...descriptor.props, style }, children);
599
+ return h(
600
+ Animated.View,
601
+ { key: descriptor.key, ...descriptor.props, style },
602
+ children,
603
+ );
518
604
  }
519
605
 
520
606
  const drawerChildren = order
@@ -8,7 +8,11 @@
8
8
 
9
9
  import { defineComponent } from '@vue/runtime-core';
10
10
  import type { Component } from '@vue/runtime-core';
11
- import type { IDrawerScreenOptions, IRoute, IDrawerNavigatorHandle } from '../core';
11
+ import type {
12
+ IDrawerScreenOptions,
13
+ IRoute,
14
+ IDrawerNavigatorHandle,
15
+ } from '../core';
12
16
 
13
17
  export type IDrawerScreenOptionsArgs = {
14
18
  route: IRoute<unknown>;
@@ -26,7 +30,10 @@ export type IDrawerScreenProps = {
26
30
  initialParams?: unknown;
27
31
  };
28
32
 
29
- export const DrawerScreen = defineComponent<IDrawerScreenProps>(() => () => null, {
30
- name: 'DrawerScreen',
31
- inheritAttrs: false,
32
- });
33
+ export const DrawerScreen = defineComponent<IDrawerScreenProps>(
34
+ () => () => null,
35
+ {
36
+ name: 'DrawerScreen',
37
+ inheritAttrs: false,
38
+ },
39
+ );
package/src/vue/index.ts CHANGED
@@ -15,7 +15,11 @@ export type {
15
15
  IVueScreenOptions,
16
16
  IVueSearchBarOptions,
17
17
  } from './screen';
18
- export type { IScreenOptions, IStackAnimation, IStackPresentation } from '../core';
18
+ export type {
19
+ IScreenOptions,
20
+ IStackAnimation,
21
+ IStackPresentation,
22
+ } from '../core';
19
23
 
20
24
  export {
21
25
  useNavigation,
@@ -33,7 +37,10 @@ export type {
33
37
  ITabNavigationHandle,
34
38
  IDrawerNavigationHandle,
35
39
  } from './composables';
36
- export type { INavigationScopeValue, IAnyNavigatorHandle } from './navigation-context';
40
+ export type {
41
+ INavigationScopeValue,
42
+ IAnyNavigatorHandle,
43
+ } from './navigation-context';
37
44
 
38
45
  export { useLinkingIntegration } from './linking';
39
46
  export type { ILinkingConfig, IScreenLinkingConfig } from '../core';
@@ -67,4 +74,9 @@ export type {
67
74
  IDrawerScreenOptionsResolver,
68
75
  IDrawerScreenProps,
69
76
  } from './drawer-screen';
70
- export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition } from '../core';
77
+ export type {
78
+ IDrawerOptions,
79
+ IDrawerScreenOptions,
80
+ IDrawerType,
81
+ IDrawerPosition,
82
+ } from '../core';
@@ -30,7 +30,10 @@ export function useLinkingIntegration(
30
30
  let cancelled = false;
31
31
  let subscription: IEventSubscription | undefined;
32
32
 
33
- function applyRoute(url: string, dispatch: (name: string, params?: unknown) => void): void {
33
+ function applyRoute(
34
+ url: string,
35
+ dispatch: (name: string, params?: unknown) => void,
36
+ ): void {
34
37
  const route = resolveRouteFromUrl(config, url);
35
38
  if (route === null) {
36
39
  dlog(`useLinkingIntegration: no route resolved for "${url}"`);
@@ -42,7 +45,9 @@ export function useLinkingIntegration(
42
45
  onMounted(() => {
43
46
  const handle = navigatorHandle.value;
44
47
  if (handle === null) {
45
- dlog('useLinkingIntegration: navigatorHandle is not yet available at mount time');
48
+ dlog(
49
+ 'useLinkingIntegration: navigatorHandle is not yet available at mount time',
50
+ );
46
51
  return;
47
52
  }
48
53
 
@@ -27,7 +27,12 @@
27
27
  // screen nested inside e.g. a Stack-screen-renders-a-Tab composition reach the enclosing Stack via
28
28
  // useNavigation().getParent().
29
29
 
30
- import { defineComponent, inject, provide, shallowRef } from '@vue/runtime-core';
30
+ import {
31
+ defineComponent,
32
+ inject,
33
+ provide,
34
+ shallowRef,
35
+ } from '@vue/runtime-core';
31
36
  import type { InjectionKey, ShallowRef } from '@vue/runtime-core';
32
37
  import type { INavigationEmitter, IRoute, IAnyNavigatorHandle } from '../core';
33
38
  export type { IAnyNavigatorHandle };
@@ -44,7 +49,9 @@ const NAVIGATION_SCOPE_KEY: InjectionKey<ShallowRef<INavigationScopeValue>> =
44
49
 
45
50
  // The setter half of the pair - writes the CURRENT route's scope onto the shared key. Called only
46
51
  // from NavigationScope's own setup below (never directly by app code).
47
- function provideNavigationScope(value: ShallowRef<INavigationScopeValue>): void {
52
+ function provideNavigationScope(
53
+ value: ShallowRef<INavigationScopeValue>,
54
+ ): void {
48
55
  provide(NAVIGATION_SCOPE_KEY, value);
49
56
  }
50
57
 
@@ -52,7 +59,8 @@ function provideNavigationScope(value: ShallowRef<INavigationScopeValue>): void
52
59
  // (stack.ts/tabs.ts/drawer.ts, reading the AMBIENT/parent scope on their own mount) calls this
53
60
  // directly; undefined simply means "no ancestor NavigationScope", which is a legitimate state (the
54
61
  // nesting root) rather than an error - callers that require one throw their own message.
55
- export function injectNavigationScope(): ShallowRef<INavigationScopeValue> | undefined {
62
+ export function injectNavigationScope():
63
+ ShallowRef<INavigationScopeValue> | undefined {
56
64
  return inject(NAVIGATION_SCOPE_KEY, undefined);
57
65
  }
58
66
 
@@ -60,7 +68,9 @@ export function injectNavigationScope(): ShallowRef<INavigationScopeValue> | und
60
68
  // useIsFocused, useFocusEffect, useNavigationState) - they all called injectNavigationScope() and
61
69
  // threw the same shaped error, differing only in which hook name the message names. Centralized
62
70
  // here so a wording change lands once instead of five times.
63
- export function requireNavigationScope(hookName: string): ShallowRef<INavigationScopeValue> {
71
+ export function requireNavigationScope(
72
+ hookName: string,
73
+ ): ShallowRef<INavigationScopeValue> {
64
74
  const scope = injectNavigationScope();
65
75
  if (scope === undefined) {
66
76
  throw new Error(
@@ -74,7 +84,9 @@ export function requireNavigationScope(hookName: string): ShallowRef<INavigation
74
84
  // declaration here, not stylistic - without it Vue would route the incoming `value` into `attrs`
75
85
  // instead of a tracked reactive `props` field, and the render closure's refresh below would
76
86
  // silently keep re-reading a stale initial snapshot.
77
- export const NavigationScope = defineComponent<{ value: INavigationScopeValue }>(
87
+ export const NavigationScope = defineComponent<{
88
+ value: INavigationScopeValue;
89
+ }>(
78
90
  (props, { slots }) => {
79
91
  const current = shallowRef(props.value);
80
92
  provideNavigationScope(current);
package/src/vue/screen.ts CHANGED
@@ -25,7 +25,10 @@ export type IVueSearchBarOptions = ISearchBarOptions & {
25
25
  ref?: Ref<ISearchBarCommands | null>;
26
26
  };
27
27
 
28
- export type IVueScreenOptions = Omit<IScreenOptions, 'headerSearchBarOptions'> & {
28
+ export type IVueScreenOptions = Omit<
29
+ IScreenOptions,
30
+ 'headerSearchBarOptions'
31
+ > & {
29
32
  headerSearchBarOptions?: IVueSearchBarOptions;
30
33
  };
31
34
 
@@ -37,7 +40,9 @@ export type IScreenOptionsArgs = {
37
40
  navigation: INavigatorHandle;
38
41
  };
39
42
 
40
- export type IScreenOptionsResolver = (args: IScreenOptionsArgs) => IVueScreenOptions;
43
+ export type IScreenOptionsResolver = (
44
+ args: IScreenOptionsArgs,
45
+ ) => IVueScreenOptions;
41
46
 
42
47
  export type IScreenProps = {
43
48
  name: string;