@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
@@ -66,7 +66,12 @@ let tabInstanceCounter = 0;
66
66
  @Component({
67
67
  selector: 'Tab',
68
68
  standalone: true,
69
- imports: [NgComponentOutlet, NavigationScopeDirective, DescriptorOutlet, View],
69
+ imports: [
70
+ NgComponentOutlet,
71
+ NavigationScopeDirective,
72
+ DescriptorOutlet,
73
+ View,
74
+ ],
70
75
  changeDetection: ChangeDetectionStrategy.OnPush,
71
76
  template: `
72
77
  <View [style]="rootStyle">
@@ -101,7 +106,8 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
101
106
  // Keyed by name -> the LIVE TabScreenDirective instance - see stack.ts's matching comment for
102
107
  // why a snapshot copy would go stale on an in-place `[options]`/`[component]` change.
103
108
  private readonly registry = new Map<string, TabScreenDirective>();
104
- private tabScreenChildrenSubscription: { unsubscribe: () => void } | undefined;
109
+ private tabScreenChildrenSubscription:
110
+ { unsubscribe: () => void } | undefined;
105
111
 
106
112
  private readonly stateSignal = signal<ITabRouterState | undefined>(undefined);
107
113
  readonly state = this.stateSignal.asReadonly();
@@ -116,9 +122,10 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
116
122
 
117
123
  ngAfterContentInit(): void {
118
124
  this.syncRegistry();
119
- this.tabScreenChildrenSubscription = this.tabScreenChildren.changes.subscribe(() => {
120
- this.syncRegistry();
121
- });
125
+ this.tabScreenChildrenSubscription =
126
+ this.tabScreenChildren.changes.subscribe(() => {
127
+ this.syncRegistry();
128
+ });
122
129
  }
123
130
 
124
131
  ngOnDestroy(): void {
@@ -150,7 +157,8 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
150
157
  private syncRegistry(): void {
151
158
  this.rebuildRegistry();
152
159
  const routes = this.routesFromRegistry();
153
- if (routes.length === 0) dlog('Tab: no <ng-template symbioteTabScreen> children registered');
160
+ if (routes.length === 0)
161
+ dlog('Tab: no <ng-template symbioteTabScreen> children registered');
154
162
  const current = this.stateSignal();
155
163
  if (current !== undefined) {
156
164
  this.stateSignal.set(reconcileTabRoutes(current, routes));
@@ -168,9 +176,15 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
168
176
  this.stateSignal.set(tabRouterReducer(current, action));
169
177
  }
170
178
 
171
- private resolveTabOptions(entry: TabScreenDirective, route: IRoute<unknown>): ITabOptions {
179
+ private resolveTabOptions(
180
+ entry: TabScreenDirective,
181
+ route: IRoute<unknown>,
182
+ ): ITabOptions {
172
183
  const props: ITabScreenOptionsArgs = { route, navigation: this };
173
- const own = typeof entry.options === 'function' ? entry.options(props) : entry.options;
184
+ const own =
185
+ typeof entry.options === 'function'
186
+ ? entry.options(props)
187
+ : entry.options;
174
188
  return { ...this.screenOptions, ...own };
175
189
  }
176
190
 
@@ -207,8 +221,12 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
207
221
  focusedRouteEmitter(): INavigationEmitter {
208
222
  const key = this.focusedRoute()?.key;
209
223
  return untracked(() => {
210
- if (key === this.currentEmitterKey && this.currentEmitter) return this.currentEmitter;
211
- const { blurKey, focusKey } = diffFocusedRoute(this.currentEmitterKey, key);
224
+ if (key === this.currentEmitterKey && this.currentEmitter)
225
+ return this.currentEmitter;
226
+ const { blurKey, focusKey } = diffFocusedRoute(
227
+ this.currentEmitterKey,
228
+ key,
229
+ );
212
230
  if (blurKey !== undefined && this.currentEmitter) {
213
231
  dlog('Tab: previous route blurred');
214
232
  this.currentEmitter.emit(NAVIGATION_EVENT_BLUR);
@@ -257,12 +275,18 @@ export class Tab implements AfterContentInit, OnDestroy, ITabNavigatorHandle {
257
275
  });
258
276
 
259
277
  const focusedRoute = this.focusedRoute();
260
- const focusedEntry = focusedRoute ? this.registry.get(focusedRoute.name) : undefined;
278
+ const focusedEntry = focusedRoute
279
+ ? this.registry.get(focusedRoute.name)
280
+ : undefined;
261
281
  const focusedOptions =
262
282
  focusedEntry && focusedRoute
263
283
  ? this.resolveTabOptions(focusedEntry, focusedRoute)
264
284
  : this.screenOptions;
265
285
 
266
- return renderTabBar({ items, style: focusedOptions?.tabBarStyle, passthrough: {} });
286
+ return renderTabBar({
287
+ items,
288
+ style: focusedOptions?.tabBarStyle,
289
+ passthrough: {},
290
+ });
267
291
  }
268
292
  }
@@ -11,12 +11,14 @@ export const RNS_SCREEN_VIEW_NAME = 'RNSScreen';
11
11
  // render-stack.ts for why a formSheet/modal screen MUST use this different Fabric name.
12
12
  export const RNS_MODAL_SCREEN_VIEW_NAME = 'RNSModalScreen';
13
13
  export const RNS_SCREEN_STACK_VIEW_NAME = 'RNSScreenStack';
14
- export const RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME = 'RNSScreenStackHeaderConfig';
14
+ export const RNS_SCREEN_STACK_HEADER_CONFIG_VIEW_NAME =
15
+ 'RNSScreenStackHeaderConfig';
15
16
  // The header-subview leaf react-native-screens itself uses to host arbitrary framework children
16
17
  // (left/right/back/title/center/searchBar) inside the header. Registered here for ground-truth
17
18
  // parity, but unconsumed by any fold in v1 scope: renderHeaderConfig's Descriptor never takes
18
19
  // framework children (see render-stack.ts), so mounting a subview child is left to the adapter.
19
- export const RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME = 'RNSScreenStackHeaderSubview';
20
+ export const RNS_SCREEN_STACK_HEADER_SUBVIEW_VIEW_NAME =
21
+ 'RNSScreenStackHeaderSubview';
20
22
  export const RNS_SEARCH_BAR_VIEW_NAME = 'RNSSearchBar';
21
23
  // react-native-screens' own JS layer (ScreenStackItem -> DebugContainer -> ScreenContentWrapper)
22
24
  // ALWAYS wraps a screen's content in this native view, `collapsable: false` so Fabric can never
@@ -43,7 +45,8 @@ export const STACK_ON_FINISH_TRANSITIONING = 'onFinishTransitioning';
43
45
  // plain bar-button-item press, and a press on a (possibly nested) menu action of a 'menu'-type
44
46
  // bar-button item.
45
47
  export const HEADER_ON_PRESS_BAR_BUTTON_ITEM = 'onPressHeaderBarButtonItem';
46
- export const HEADER_ON_PRESS_BAR_BUTTON_MENU_ITEM = 'onPressHeaderBarButtonMenuItem';
48
+ export const HEADER_ON_PRESS_BAR_BUTTON_MENU_ITEM =
49
+ 'onPressHeaderBarButtonMenuItem';
47
50
 
48
51
  // RNSSearchBar event prop keys (all DirectEventHandler in the codegen spec). onClose/onOpen are
49
52
  // Android-only per the codegen spec's own comment.
@@ -7,7 +7,10 @@
7
7
  // PanResponder equivalent (see packages/navigation's README / the drawer feasibility note for the
8
8
  // full gap list).
9
9
 
10
- import type { IPanResponderGestureState, ISymbioteEvent } from '@symbiote-native/engine';
10
+ import type {
11
+ IPanResponderGestureState,
12
+ ISymbioteEvent,
13
+ } from '@symbiote-native/engine';
11
14
  import { isRecord } from '../guards';
12
15
  import type { IDrawerSlot } from '../render-drawer';
13
16
 
@@ -59,7 +62,9 @@ export function resolveDrawerType(options: IDrawerOptions): IDrawerType {
59
62
  return options.drawerType ?? DRAWER_DEFAULT_TYPE;
60
63
  }
61
64
 
62
- export function resolveDrawerPosition(options: IDrawerOptions): IDrawerPosition {
65
+ export function resolveDrawerPosition(
66
+ options: IDrawerOptions,
67
+ ): IDrawerPosition {
63
68
  return options.drawerPosition ?? DRAWER_DEFAULT_POSITION;
64
69
  }
65
70
 
@@ -90,7 +95,9 @@ export function isDrawerOverlayVisible(options: IDrawerOptions): boolean {
90
95
  // slide: panel AND content move together by the same delta, overlay fades in (content still
91
96
  // covers the panel partially as they slide in tandem, same as front visually at rest).
92
97
  // permanent: static, all zero (isDrawerAnimated() gates callers off this path already).
93
- export function resolveDrawerGeometry(options: IDrawerOptions): IDrawerGeometry {
98
+ export function resolveDrawerGeometry(
99
+ options: IDrawerOptions,
100
+ ): IDrawerGeometry {
94
101
  const width = resolveDrawerWidth(options);
95
102
  const type = resolveDrawerType(options);
96
103
  const sign = resolveDrawerPosition(options) === 'left' ? 1 : -1;
@@ -188,25 +195,37 @@ export function resolveDrawerSlotInterpolation(
188
195
  return {
189
196
  translateX: {
190
197
  inputRange: DRAWER_PROGRESS_INPUT_RANGE,
191
- outputRange: [geometry.contentTranslateXClosed, geometry.contentTranslateXOpen],
198
+ outputRange: [
199
+ geometry.contentTranslateXClosed,
200
+ geometry.contentTranslateXOpen,
201
+ ],
192
202
  },
193
203
  };
194
204
  case 'overlay':
195
205
  return {
196
206
  opacity: {
197
207
  inputRange: DRAWER_PROGRESS_INPUT_RANGE,
198
- outputRange: [geometry.overlayOpacityClosed, geometry.overlayOpacityOpen],
208
+ outputRange: [
209
+ geometry.overlayOpacityClosed,
210
+ geometry.overlayOpacityOpen,
211
+ ],
199
212
  },
200
213
  translateX: {
201
214
  inputRange: DRAWER_PROGRESS_INPUT_RANGE,
202
- outputRange: [geometry.contentTranslateXClosed, geometry.contentTranslateXOpen],
215
+ outputRange: [
216
+ geometry.contentTranslateXClosed,
217
+ geometry.contentTranslateXOpen,
218
+ ],
203
219
  },
204
220
  };
205
221
  case 'panel':
206
222
  return {
207
223
  translateX: {
208
224
  inputRange: DRAWER_PROGRESS_INPUT_RANGE,
209
- outputRange: [geometry.panelTranslateXClosed, geometry.panelTranslateXOpen],
225
+ outputRange: [
226
+ geometry.panelTranslateXClosed,
227
+ geometry.panelTranslateXOpen,
228
+ ],
210
229
  },
211
230
  };
212
231
  }
@@ -235,7 +254,9 @@ export function isSwipeStartInEdge(
235
254
  // ScrollView's way).
236
255
  const MOVE_CLAIM_THRESHOLD = 5;
237
256
 
238
- export function isHorizontalDrag(gestureState: IPanResponderGestureState): boolean {
257
+ export function isHorizontalDrag(
258
+ gestureState: IPanResponderGestureState,
259
+ ): boolean {
239
260
  return (
240
261
  Math.abs(gestureState.dx) > MOVE_CLAIM_THRESHOLD &&
241
262
  Math.abs(gestureState.dx) > Math.abs(gestureState.dy)
@@ -258,8 +279,10 @@ export function resolveSwipeIntent(
258
279
  // symmetrically for a right drawer's leftward drag).
259
280
  const signedDx = sign * gestureState.dx;
260
281
  const signedVx = sign * gestureState.vx;
261
- const minDistance = options.swipeMinDistance ?? DRAWER_DEFAULT_SWIPE_MIN_DISTANCE;
262
- const minVelocity = options.swipeMinVelocity ?? DRAWER_DEFAULT_SWIPE_MIN_VELOCITY;
282
+ const minDistance =
283
+ options.swipeMinDistance ?? DRAWER_DEFAULT_SWIPE_MIN_DISTANCE;
284
+ const minVelocity =
285
+ options.swipeMinVelocity ?? DRAWER_DEFAULT_SWIPE_MIN_VELOCITY;
263
286
 
264
287
  const pastDistance = Math.abs(signedDx) >= minDistance;
265
288
  const pastVelocity = Math.abs(signedVx) >= minVelocity;
@@ -276,7 +299,9 @@ export function clamp01(value: number): number {
276
299
  }
277
300
 
278
301
  function toFiniteNumber(value: unknown): number | undefined {
279
- return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
302
+ return typeof value === 'number' && Number.isFinite(value)
303
+ ? value
304
+ : undefined;
280
305
  }
281
306
 
282
307
  // The touch's real starting page-X, read off the raw event rather than gestureState.x0: the
@@ -293,7 +318,8 @@ export function startPageXOf(event: ISymbioteEvent): number | undefined {
293
318
  const direct = toFiniteNumber(nativeEvent.pageX);
294
319
  if (direct !== undefined) return direct;
295
320
  const touches = nativeEvent.touches;
296
- if (Array.isArray(touches) && isRecord(touches[0])) return toFiniteNumber(touches[0].pageX);
321
+ if (Array.isArray(touches) && isRecord(touches[0]))
322
+ return toFiniteNumber(touches[0].pageX);
297
323
  return undefined;
298
324
  }
299
325
 
@@ -323,7 +349,8 @@ export function shouldClaimDrawerSwipe(
323
349
  options: IDrawerOptions,
324
350
  phase: 'start' | 'move',
325
351
  ): boolean {
326
- if ((options.swipeEnabled ?? DRAWER_DEFAULT_SWIPE_ENABLED) === false) return false;
352
+ if ((options.swipeEnabled ?? DRAWER_DEFAULT_SWIPE_ENABLED) === false)
353
+ return false;
327
354
  if (!isDrawerAnimated(options)) return false;
328
355
  const startX = startPageXOf(event) ?? gestureState.x0;
329
356
  if (!isSwipeStartInEdge(startX, screenWidth, isOpen, options)) return false;
@@ -34,7 +34,11 @@ export function createInitialDrawerRouterState(
34
34
  return { routes, index: INITIAL_FOCUSED_INDEX, isOpen: false };
35
35
  }
36
36
  const index = routes.findIndex(route => route.name === initialRouteName);
37
- return { routes, index: index === -1 ? INITIAL_FOCUSED_INDEX : index, isOpen: false };
37
+ return {
38
+ routes,
39
+ index: index === -1 ? INITIAL_FOCUSED_INDEX : index,
40
+ isOpen: false,
41
+ };
38
42
  }
39
43
 
40
44
  // Mirrors @react-navigation/drawer's DrawerActions: jumpTo focuses a route by NAME (TabRouter's
@@ -49,7 +53,9 @@ export function drawerRouterReducer(
49
53
  case 'jumpTo': {
50
54
  const index = state.routes.findIndex(route => route.name === action.name);
51
55
  if (index === -1) return state;
52
- return index === state.index && !state.isOpen ? state : { ...state, index, isOpen: false };
56
+ return index === state.index && !state.isOpen
57
+ ? state
58
+ : { ...state, index, isOpen: false };
53
59
  }
54
60
 
55
61
  case 'openDrawer':
@@ -66,6 +72,8 @@ export function drawerRouterReducer(
66
72
  }
67
73
  }
68
74
 
69
- export function focusedDrawerRoute(state: IDrawerRouterState): IRouteEntry | undefined {
75
+ export function focusedDrawerRoute(
76
+ state: IDrawerRouterState,
77
+ ): IRouteEntry | undefined {
70
78
  return state.routes[state.index];
71
79
  }
@@ -19,5 +19,7 @@ export function isRecord(value: unknown): value is Record<string, unknown> {
19
19
  // navigator-state.ts (Stack) and tab-router-state.ts (Tabs) so the two reducers can't drift on
20
20
  // this rule independently.
21
21
  export function mergeParams(current: unknown, incoming: unknown): unknown {
22
- return isRecord(current) && isRecord(incoming) ? { ...current, ...incoming } : incoming;
22
+ return isRecord(current) && isRecord(incoming)
23
+ ? { ...current, ...incoming }
24
+ : incoming;
23
25
  }
@@ -21,7 +21,9 @@ import type {
21
21
  // time (both the structured `icon` field AND the flat native keys reach native - RNS's own
22
22
  // prepareHeaderBarButtonItems keeps both), and resolves image assets through the same resolver
23
23
  // the Image component uses.
24
- function prepareIcon(icon: IHeaderBarButtonIcon | undefined): Record<string, unknown> {
24
+ function prepareIcon(
25
+ icon: IHeaderBarButtonIcon | undefined,
26
+ ): Record<string, unknown> {
25
27
  if (!icon) return {};
26
28
  switch (icon.type) {
27
29
  case 'sfSymbol':
@@ -31,7 +33,9 @@ function prepareIcon(icon: IHeaderBarButtonIcon | undefined): Record<string, unk
31
33
  case 'imageSource':
32
34
  return { imageSource: imageStatics.resolveAssetSource(icon.imageSource) };
33
35
  case 'templateSource':
34
- return { templateSource: imageStatics.resolveAssetSource(icon.templateSource) };
36
+ return {
37
+ templateSource: imageStatics.resolveAssetSource(icon.templateSource),
38
+ };
35
39
  }
36
40
  }
37
41
 
@@ -40,7 +44,11 @@ type ISharedItem = IHeaderBarButtonItemAction | IHeaderBarButtonItemMenu;
40
44
  // The one id algorithm both the payload tagger (prepareMenuItems/prepareHeaderBarButtonItems)
41
45
  // and the dispatch-lookup builder (collectMenuHandlers/collectBarButtonHandlers) call - so a
42
46
  // change to the id scheme genuinely can't desync payload tagging from dispatch lookup.
43
- function buildMenuId(path: string, index: number, side: 'left' | 'right'): string {
47
+ function buildMenuId(
48
+ path: string,
49
+ index: number,
50
+ side: 'left' | 'right',
51
+ ): string {
44
52
  return `${path}-${index}-${side}`;
45
53
  }
46
54
 
@@ -54,18 +62,26 @@ function prepareTitleStyle(
54
62
  if (!titleStyle) return undefined;
55
63
  return {
56
64
  ...titleStyle,
57
- color: titleStyle.color === undefined ? undefined : processColor(titleStyle.color),
65
+ color:
66
+ titleStyle.color === undefined
67
+ ? undefined
68
+ : processColor(titleStyle.color),
58
69
  };
59
70
  }
60
71
 
61
- function prepareBadge(badge: ISharedItem['badge']): Record<string, unknown> | undefined {
72
+ function prepareBadge(
73
+ badge: ISharedItem['badge'],
74
+ ): Record<string, unknown> | undefined {
62
75
  if (!badge) return undefined;
63
76
  return {
64
77
  ...badge,
65
78
  style: badge.style
66
79
  ? {
67
80
  ...badge.style,
68
- color: badge.style.color === undefined ? undefined : processColor(badge.style.color),
81
+ color:
82
+ badge.style.color === undefined
83
+ ? undefined
84
+ : processColor(badge.style.color),
69
85
  backgroundColor:
70
86
  badge.style.backgroundColor === undefined
71
87
  ? undefined
@@ -81,7 +97,9 @@ function prepareBadge(badge: ISharedItem['badge']): Record<string, unknown> | un
81
97
  // headerRightBarButtonItems array it's nested in - not just the one bad field - so bar buttons and
82
98
  // menu actions never reached native at all, despite the buttonId/menuId dispatch wiring itself
83
99
  // being entirely correct.
84
- function excludeOnPress<T extends { onPress: unknown }>(item: T): Omit<T, 'onPress'> {
100
+ function excludeOnPress<T extends { onPress: unknown }>(
101
+ item: T,
102
+ ): Omit<T, 'onPress'> {
85
103
  const { onPress: _onPress, ...rest } = item;
86
104
  return rest;
87
105
  }
@@ -95,12 +113,15 @@ function prepareSharedFields(
95
113
  ...(item.type === 'button' ? excludeOnPress(item) : item),
96
114
  ...prepareIcon(item.icon),
97
115
  titleStyle: prepareTitleStyle(item.titleStyle),
98
- tintColor: item.tintColor === undefined ? undefined : processColor(item.tintColor),
116
+ tintColor:
117
+ item.tintColor === undefined ? undefined : processColor(item.tintColor),
99
118
  badge: prepareBadge(item.badge),
100
119
  };
101
120
  }
102
121
 
103
- type IMenuLike = { items: (IHeaderBarButtonMenuAction | IHeaderBarButtonSubmenu)[] };
122
+ type IMenuLike = {
123
+ items: (IHeaderBarButtonMenuAction | IHeaderBarButtonSubmenu)[];
124
+ };
104
125
 
105
126
  // Recursively tags every menu action with a `menuId` derived from its tree position
106
127
  // (`${path}-${index}-${side}`), mirroring RNS's own prepareMenu exactly - the id must match what
@@ -117,7 +138,11 @@ function prepareMenuItems<T extends IMenuLike>(
117
138
  const currentPath = path ? `${path}.${menuIndex}` : `${menuIndex}`;
118
139
  const icon = prepareIcon(menuItem.icon);
119
140
  if (menuItem.type === 'submenu') {
120
- return { ...menuItem, ...icon, ...prepareMenuItems(menuItem, index, side, currentPath) };
141
+ return {
142
+ ...menuItem,
143
+ ...icon,
144
+ ...prepareMenuItems(menuItem, index, side, currentPath),
145
+ };
121
146
  }
122
147
  return {
123
148
  ...excludeOnPress(menuItem),
@@ -139,7 +164,8 @@ export function prepareHeaderBarButtonItems(
139
164
  return items.map((item, index) => {
140
165
  if (item.type === 'spacing') return item;
141
166
  const prepared = prepareSharedFields(item);
142
- if (item.type === 'button') return { ...prepared, buttonId: buildButtonId(index, side) };
167
+ if (item.type === 'button')
168
+ return { ...prepared, buttonId: buildButtonId(index, side) };
143
169
  return { ...prepared, menu: prepareMenuItems(item.menu, index, side) };
144
170
  });
145
171
  }
@@ -176,7 +202,10 @@ function collectBarButtonHandlers(
176
202
  });
177
203
  }
178
204
 
179
- function readStringField(record: Record<string, unknown>, key: string): string | undefined {
205
+ function readStringField(
206
+ record: Record<string, unknown>,
207
+ key: string,
208
+ ): string | undefined {
180
209
  const value = record[key];
181
210
  return typeof value === 'string' ? value : undefined;
182
211
  }
package/src/core/index.ts CHANGED
@@ -14,7 +14,11 @@ export {
14
14
  computeActivityState,
15
15
  isTopRoute,
16
16
  } from './navigator-state';
17
- export type { IRoute, INavigatorState, INavigatorAction } from './navigator-state';
17
+ export type {
18
+ IRoute,
19
+ INavigatorState,
20
+ INavigatorAction,
21
+ } from './navigator-state';
18
22
 
19
23
  // Drops history entries whose `<Stack.Screen>` marker has unregistered - see
20
24
  // stack-router-state.ts's header for why the Stack's history needs this and the Tab's projection
@@ -50,7 +54,11 @@ export type {
50
54
  ISearchBarViewProps,
51
55
  } from './navigator-props';
52
56
 
53
- export { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView } from './screen-options';
57
+ export {
58
+ resolveHeaderConfigView,
59
+ resolveScreenView,
60
+ resolveSearchBarView,
61
+ } from './screen-options';
54
62
 
55
63
  export { buildSearchBarHandle } from './search-bar-commands';
56
64
  export type { ISearchBarCommands } from './search-bar-commands';
@@ -70,7 +78,10 @@ export {
70
78
  } from './render-stack';
71
79
  export type { IScreenRenderPlanInput, IScreenRenderPlan } from './render-stack';
72
80
 
73
- export { serializeNavigatorState, deserializeNavigatorState } from './state-persistence';
81
+ export {
82
+ serializeNavigatorState,
83
+ deserializeNavigatorState,
84
+ } from './state-persistence';
74
85
 
75
86
  export {
76
87
  createNavigationEmitter,
@@ -120,7 +131,10 @@ export {
120
131
  drawerRouterReducer,
121
132
  focusedDrawerRoute,
122
133
  } from './drawer-router-state';
123
- export type { IDrawerRouterState, IDrawerRouterAction } from './drawer-router-state';
134
+ export type {
135
+ IDrawerRouterState,
136
+ IDrawerRouterAction,
137
+ } from './drawer-router-state';
124
138
 
125
139
  export type {
126
140
  IDrawerType,
@@ -49,7 +49,9 @@ function normalizeSegment(segment: string): string {
49
49
  }
50
50
 
51
51
  function joinPath(parent: string, child: string): string {
52
- const parts = [normalizeSegment(parent), normalizeSegment(child)].filter(part => part.length > 0);
52
+ const parts = [normalizeSegment(parent), normalizeSegment(child)].filter(
53
+ part => part.length > 0,
54
+ );
53
55
  return parts.join('/');
54
56
  }
55
57
 
@@ -68,14 +70,17 @@ function flattenScreens(
68
70
  continue;
69
71
  }
70
72
 
71
- const nextParent = entry.path !== undefined ? joinPath(parentPath, entry.path) : parentPath;
73
+ const nextParent =
74
+ entry.path !== undefined ? joinPath(parentPath, entry.path) : parentPath;
72
75
 
73
76
  if (entry.screens !== undefined) {
74
77
  flattenScreens(entry.screens, nextParent, out);
75
78
  } else if (entry.path !== undefined) {
76
79
  out.push({ name, pattern: nextParent });
77
80
  } else {
78
- dlog(`linking-config: screen "${name}" has neither a path nor nested screens, skipping`);
81
+ dlog(
82
+ `linking-config: screen "${name}" has neither a path nor nested screens, skipping`,
83
+ );
79
84
  }
80
85
  }
81
86
  return out;
@@ -93,12 +98,16 @@ function segmentCount(pattern: string): number {
93
98
  // More static segments should win over a param that would also match (e.g. a literal
94
99
  // '/user/me' pattern over '/user/:id'), mirroring how react-navigation prefers exact matches.
95
100
  function bySpecificity(a: IFlatRoutePattern, b: IFlatRoutePattern): number {
96
- const dynamicDiff = dynamicSegmentCount(a.pattern) - dynamicSegmentCount(b.pattern);
101
+ const dynamicDiff =
102
+ dynamicSegmentCount(a.pattern) - dynamicSegmentCount(b.pattern);
97
103
  if (dynamicDiff !== 0) return dynamicDiff;
98
104
  return segmentCount(b.pattern) - segmentCount(a.pattern);
99
105
  }
100
106
 
101
- function matchPattern(pattern: string, pathname: string): Record<string, string> | null {
107
+ function matchPattern(
108
+ pattern: string,
109
+ pathname: string,
110
+ ): Record<string, string> | null {
102
111
  const patternSegments = pattern.length === 0 ? [] : pattern.split('/');
103
112
  const pathSegments = pathname.length === 0 ? [] : pathname.split('/');
104
113
  if (patternSegments.length !== pathSegments.length) return null;
@@ -127,7 +136,9 @@ function stripQueryAndHash(url: string): string {
127
136
  // neither applies - an unrecognized scheme/host, not "no route matched".
128
137
  function extractPathname(config: ILinkingConfig, url: string): string | null {
129
138
  const withoutQuery = stripQueryAndHash(url);
130
- const sortedPrefixes = [...config.prefixes].sort((a, b) => b.length - a.length);
139
+ const sortedPrefixes = [...config.prefixes].sort(
140
+ (a, b) => b.length - a.length,
141
+ );
131
142
  for (const prefix of sortedPrefixes) {
132
143
  if (withoutQuery.startsWith(prefix)) {
133
144
  return normalizeSegment(withoutQuery.slice(prefix.length));
@@ -137,14 +148,19 @@ function extractPathname(config: ILinkingConfig, url: string): string | null {
137
148
  return null;
138
149
  }
139
150
 
140
- export function resolveRouteFromUrl(config: ILinkingConfig, url: string): IRoute<unknown> | null {
151
+ export function resolveRouteFromUrl(
152
+ config: ILinkingConfig,
153
+ url: string,
154
+ ): IRoute<unknown> | null {
141
155
  const pathname = extractPathname(config, url);
142
156
  if (pathname === null) {
143
157
  dlog(`linking-config: url "${url}" matched no configured prefix`);
144
158
  return null;
145
159
  }
146
160
 
147
- const candidates = flattenScreens(config.config.screens, '', []).sort(bySpecificity);
161
+ const candidates = flattenScreens(config.config.screens, '', []).sort(
162
+ bySpecificity,
163
+ );
148
164
  for (const candidate of candidates) {
149
165
  const params = matchPattern(candidate.pattern, pathname);
150
166
  if (params !== null) {
@@ -159,7 +175,9 @@ export function resolveRouteFromUrl(config: ILinkingConfig, url: string): IRoute
159
175
  }
160
176
  }
161
177
 
162
- dlog(`linking-config: url "${url}" (path "${pathname}") matched no configured screen`);
178
+ dlog(
179
+ `linking-config: url "${url}" (path "${pathname}") matched no configured screen`,
180
+ );
163
181
  return null;
164
182
  }
165
183
 
@@ -182,7 +200,10 @@ function fillPattern(pattern: string, params: unknown): string | null {
182
200
  return segments.join('/');
183
201
  }
184
202
 
185
- export function resolveUrlFromRoute(config: ILinkingConfig, route: IRoute<unknown>): string | null {
203
+ export function resolveUrlFromRoute(
204
+ config: ILinkingConfig,
205
+ route: IRoute<unknown>,
206
+ ): string | null {
186
207
  const candidate = flattenScreens(config.config.screens, '', []).find(
187
208
  entry => entry.name === route.name,
188
209
  );
@@ -32,11 +32,17 @@ export type INavigationEventListener<TData = unknown> = (data: TData) => void;
32
32
 
33
33
  export type INavigationEmitter = {
34
34
  emit: (event: INavigationEventName, data?: unknown) => void;
35
- addListener: (event: INavigationEventName, listener: INavigationEventListener) => () => void;
35
+ addListener: (
36
+ event: INavigationEventName,
37
+ listener: INavigationEventListener,
38
+ ) => () => void;
36
39
  };
37
40
 
38
41
  export function createNavigationEmitter(): INavigationEmitter {
39
- const listenersByEvent = new Map<INavigationEventName, Set<INavigationEventListener>>();
42
+ const listenersByEvent = new Map<
43
+ INavigationEventName,
44
+ Set<INavigationEventListener>
45
+ >();
40
46
 
41
47
  function addListener(
42
48
  event: INavigationEventName,
@@ -44,9 +44,12 @@ export type IDrawerDescriptorMap = Record<
44
44
  // return this union since they don't know which navigator mounted the calling component; the
45
45
  // three guards below narrow it (used once, inside useStackNavigation/useTabNavigation/
46
46
  // useDrawerNavigation and their Vue/Angular equivalents) so app code never writes the guard itself.
47
- export type IAnyNavigatorHandle = INavigatorHandle | ITabNavigatorHandle | IDrawerNavigatorHandle;
47
+ export type IAnyNavigatorHandle =
48
+ INavigatorHandle | ITabNavigatorHandle | IDrawerNavigatorHandle;
48
49
 
49
- export function isStackNavigatorHandle(handle: IAnyNavigatorHandle): handle is INavigatorHandle {
50
+ export function isStackNavigatorHandle(
51
+ handle: IAnyNavigatorHandle,
52
+ ): handle is INavigatorHandle {
50
53
  return 'push' in handle;
51
54
  }
52
55
 
@@ -58,6 +61,8 @@ export function isDrawerNavigatorHandle(
58
61
 
59
62
  // jumpTo exists on both Tab and Drawer handles, so a Tab handle is a jumpTo-having handle that
60
63
  // isn't a Drawer handle (Drawer's own openDrawer/closeDrawer/toggleDrawer rule it out).
61
- export function isTabNavigatorHandle(handle: IAnyNavigatorHandle): handle is ITabNavigatorHandle {
64
+ export function isTabNavigatorHandle(
65
+ handle: IAnyNavigatorHandle,
66
+ ): handle is ITabNavigatorHandle {
62
67
  return 'jumpTo' in handle && !isDrawerNavigatorHandle(handle);
63
68
  }
@@ -51,8 +51,10 @@ export type IOptionalBooleanNativeProp = 'undefined' | 'false' | 'true';
51
51
  // mirrors react-native-screens' own ScreenProps['sheetAllowedDetents'] - a plain fraction array,
52
52
  // sorted ascending, or one of RNS's named presets; the fold to the native `sheetAllowedDetents:
53
53
  // number[]` array happens in screen-options.ts, replicating RNS's own resolveSheetAllowedDetents.
54
- export type ISheetAllowedDetents = number[] | 'fitToContents' | 'large' | 'medium' | 'all';
55
- export type ISheetLargestUndimmedDetent = number | 'last' | 'none' | 'all' | 'large' | 'medium';
54
+ export type ISheetAllowedDetents =
55
+ number[] | 'fitToContents' | 'large' | 'medium' | 'all';
56
+ export type ISheetLargestUndimmedDetent =
57
+ number | 'last' | 'none' | 'all' | 'large' | 'medium';
56
58
  export type ISheetInitialDetent = number | 'last';
57
59
 
58
60
  // A bar-button item's icon: SF Symbol / iOS asset-catalog name, or an image asset. Mirrors RNS's
@@ -143,13 +145,20 @@ export type IHeaderBarButtonItemMenu = ISharedHeaderBarButtonItem & {
143
145
  export type IHeaderBarButtonItemSpacing = { type: 'spacing'; spacing: number };
144
146
 
145
147
  export type IHeaderBarButtonItem =
146
- IHeaderBarButtonItemAction | IHeaderBarButtonItemMenu | IHeaderBarButtonItemSpacing;
148
+ | IHeaderBarButtonItemAction
149
+ | IHeaderBarButtonItemMenu
150
+ | IHeaderBarButtonItemSpacing;
147
151
 
148
152
  export type ISearchBarAutoCapitalize =
149
153
  'systemDefault' | 'none' | 'words' | 'sentences' | 'characters';
150
154
 
151
155
  export type ISearchBarPlacement =
152
- 'automatic' | 'inline' | 'stacked' | 'integrated' | 'integratedButton' | 'integratedCentered';
156
+ | 'automatic'
157
+ | 'inline'
158
+ | 'stacked'
159
+ | 'integrated'
160
+ | 'integratedButton'
161
+ | 'integratedCentered';
153
162
 
154
163
  // RNSSearchBar's full static config surface plus every event callback react-native-screens'
155
164
  // own SearchBarProps exposes (types.tsx): onChangeText/onSearchButtonPress carry the current