@symbiote-native/navigation 2.0.3 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -12
- package/build/angular/drawer/index.js +29 -13
- package/build/angular/index.d.ts +4 -4
- package/build/angular/injectors/inject-navigation.js +1 -1
- package/build/angular/navigation-scope.directive.js +1 -1
- package/build/angular/search-bar-ref.directive.js +1 -1
- package/build/angular/stack/index.d.ts +2 -0
- package/build/angular/stack/index.js +43 -9
- package/build/angular/tabs/index.d.ts +1 -1
- package/build/angular/tabs/index.js +40 -13
- package/build/core/drawer-options/index.js +19 -5
- package/build/core/drawer-router-state/index.js +8 -2
- package/build/core/guards.js +3 -1
- package/build/core/header-bar-buttons.js +14 -4
- package/build/core/index.d.ts +6 -5
- package/build/core/index.js +7 -3
- package/build/core/navigator-state/index.js +12 -4
- package/build/core/render-drawer.js +4 -1
- package/build/core/render-stack.js +13 -4
- package/build/core/screen-options.js +1 -1
- package/build/core/search-bar-commands.js +1 -1
- package/build/core/stack-router-state/index.d.ts +2 -0
- package/build/core/stack-router-state/index.js +44 -0
- package/build/core/state-persistence/index.js +6 -2
- package/build/core/tab-router-state/index.d.ts +1 -0
- package/build/core/tab-router-state/index.js +27 -2
- package/build/react/drawer/index.js +59 -26
- package/build/react/index.d.ts +7 -7
- package/build/react/index.js +2 -2
- package/build/react/stack/index.js +47 -10
- package/build/react/tabs/index.js +36 -12
- package/build/solid/drawer/index.d.ts +22 -0
- package/build/solid/drawer/index.js +394 -0
- package/build/solid/drawer-screen-props.d.ts +13 -0
- package/build/solid/drawer-screen-props.js +2 -0
- package/build/solid/host.d.ts +2 -0
- package/build/solid/host.js +23 -0
- package/build/solid/index.d.ts +19 -0
- package/build/solid/index.js +24 -0
- package/build/solid/linking.d.ts +3 -0
- package/build/solid/linking.js +55 -0
- package/build/solid/navigation-context.d.ts +13 -0
- package/build/solid/navigation-context.js +37 -0
- package/build/solid/primitives/create-focus-effect.d.ts +1 -0
- package/build/solid/primitives/create-focus-effect.js +30 -0
- package/build/solid/primitives/create-is-focused.d.ts +2 -0
- package/build/solid/primitives/create-is-focused.js +31 -0
- package/build/solid/primitives/create-navigation-state.d.ts +3 -0
- package/build/solid/primitives/create-navigation-state.js +30 -0
- package/build/solid/primitives/index.d.ts +12 -0
- package/build/solid/primitives/index.js +8 -0
- package/build/solid/primitives/use-drawer-navigation.d.ts +5 -0
- package/build/solid/primitives/use-drawer-navigation.js +15 -0
- package/build/solid/primitives/use-navigation.d.ts +8 -0
- package/build/solid/primitives/use-navigation.js +23 -0
- package/build/solid/primitives/use-route.d.ts +3 -0
- package/build/solid/primitives/use-route.js +14 -0
- package/build/solid/primitives/use-stack-navigation.d.ts +5 -0
- package/build/solid/primitives/use-stack-navigation.js +19 -0
- package/build/solid/primitives/use-tab-navigation.d.ts +5 -0
- package/build/solid/primitives/use-tab-navigation.js +15 -0
- package/build/solid/screen-props.d.ts +19 -0
- package/build/solid/screen-props.js +9 -0
- package/build/solid/screen-registry.d.ts +31 -0
- package/build/solid/screen-registry.js +86 -0
- package/build/solid/screen.d.ts +6 -0
- package/build/solid/screen.js +69 -0
- package/build/solid/stack/index.d.ts +15 -0
- package/build/solid/stack/index.js +348 -0
- package/build/solid/tab-screen-props.d.ts +13 -0
- package/build/solid/tab-screen-props.js +3 -0
- package/build/solid/tabs/index.d.ts +14 -0
- package/build/solid/tabs/index.js +228 -0
- package/build/svelte/attachments.d.ts +5 -0
- package/build/svelte/attachments.js +61 -0
- package/build/svelte/descriptor-subtree.d.ts +3 -0
- package/build/svelte/descriptor-subtree.js +39 -0
- package/build/svelte/drawer/drawer-props.d.ts +14 -0
- package/build/svelte/drawer/drawer-props.js +3 -0
- package/build/svelte/drawer/index.d.ts +10 -0
- package/build/svelte/drawer/index.js +6 -0
- package/build/svelte/drawer/index.svelte +559 -0
- package/build/svelte/drawer/index.svelte.d.ts +10 -0
- package/build/svelte/drawer-screen-props.d.ts +13 -0
- package/build/svelte/drawer-screen-props.js +4 -0
- package/build/svelte/drawer-screen.svelte +25 -0
- package/build/svelte/drawer-screen.svelte.d.ts +4 -0
- package/build/svelte/index.d.ts +21 -0
- package/build/svelte/index.js +20 -0
- package/build/svelte/linking.svelte.d.ts +2 -0
- package/build/svelte/linking.svelte.js +55 -0
- package/build/svelte/navigation-context.d.ts +14 -0
- package/build/svelte/navigation-context.js +44 -0
- package/build/svelte/navigation-scope.svelte +27 -0
- package/build/svelte/navigation-scope.svelte.d.ts +9 -0
- package/build/svelte/registry-host.d.ts +1 -0
- package/build/svelte/registry-host.js +26 -0
- package/build/svelte/runes/index.d.ts +12 -0
- package/build/svelte/runes/index.js +12 -0
- package/build/svelte/runes/use-drawer-navigation.svelte.d.ts +6 -0
- package/build/svelte/runes/use-drawer-navigation.svelte.js +19 -0
- package/build/svelte/runes/use-focus-effect.svelte.d.ts +1 -0
- package/build/svelte/runes/use-focus-effect.svelte.js +31 -0
- package/build/svelte/runes/use-is-focused.svelte.d.ts +3 -0
- package/build/svelte/runes/use-is-focused.svelte.js +34 -0
- package/build/svelte/runes/use-navigation-state.svelte.d.ts +4 -0
- package/build/svelte/runes/use-navigation-state.svelte.js +39 -0
- package/build/svelte/runes/use-navigation.svelte.d.ts +9 -0
- package/build/svelte/runes/use-navigation.svelte.js +26 -0
- package/build/svelte/runes/use-route.svelte.d.ts +4 -0
- package/build/svelte/runes/use-route.svelte.js +12 -0
- package/build/svelte/runes/use-stack-navigation.svelte.d.ts +6 -0
- package/build/svelte/runes/use-stack-navigation.svelte.js +22 -0
- package/build/svelte/runes/use-tab-navigation.svelte.d.ts +6 -0
- package/build/svelte/runes/use-tab-navigation.svelte.js +19 -0
- package/build/svelte/screen-props.d.ts +21 -0
- package/build/svelte/screen-props.js +6 -0
- package/build/svelte/screen-registry.d.ts +17 -0
- package/build/svelte/screen-registry.js +57 -0
- package/build/svelte/screen.svelte +28 -0
- package/build/svelte/screen.svelte.d.ts +4 -0
- package/build/svelte/stack/index.d.ts +14 -0
- package/build/svelte/stack/index.js +7 -0
- package/build/svelte/stack/index.svelte +261 -0
- package/build/svelte/stack/index.svelte.d.ts +15 -0
- package/build/svelte/stack/stack-props.d.ts +20 -0
- package/build/svelte/stack/stack-props.js +4 -0
- package/build/svelte/stack/stack-screen.svelte +205 -0
- package/build/svelte/stack/stack-screen.svelte.d.ts +4 -0
- package/build/svelte/tab-screen-props.d.ts +13 -0
- package/build/svelte/tab-screen-props.js +4 -0
- package/build/svelte/tab-screen.svelte +26 -0
- package/build/svelte/tab-screen.svelte.d.ts +4 -0
- package/build/svelte/tabs/index.d.ts +8 -0
- package/build/svelte/tabs/index.js +6 -0
- package/build/svelte/tabs/index.svelte +269 -0
- package/build/svelte/tabs/index.svelte.d.ts +8 -0
- package/build/svelte/tabs/tab-props.d.ts +7 -0
- package/build/svelte/tabs/tab-props.js +3 -0
- package/build/vue/composables/use-navigation.js +5 -1
- package/build/vue/drawer/index.js +36 -13
- package/build/vue/index.d.ts +3 -3
- package/build/vue/navigation-context.js +1 -1
- package/build/vue/stack/index.js +43 -18
- package/build/vue/tabs/index.js +65 -39
- package/build-ngc/angular/drawer/index.js +40 -18
- package/build-ngc/angular/drawer/index.js.map +1 -1
- package/build-ngc/angular/drawer-screen.directive.js +3 -3
- package/build-ngc/angular/index.d.ts +4 -4
- package/build-ngc/angular/index.js.map +1 -1
- package/build-ngc/angular/injectors/inject-focus-effect.js.map +1 -1
- package/build-ngc/angular/injectors/inject-is-focused.js.map +1 -1
- package/build-ngc/angular/injectors/inject-navigation-state.js.map +1 -1
- package/build-ngc/angular/injectors/inject-navigation.js +1 -1
- package/build-ngc/angular/injectors/inject-navigation.js.map +1 -1
- package/build-ngc/angular/linking.js.map +1 -1
- package/build-ngc/angular/navigation-context.service.js +3 -3
- package/build-ngc/angular/navigation-context.service.js.map +1 -1
- package/build-ngc/angular/navigation-scope.directive.js +4 -4
- package/build-ngc/angular/navigation-scope.directive.js.map +1 -1
- package/build-ngc/angular/screen.directive.js +3 -3
- package/build-ngc/angular/screen.directive.js.map +1 -1
- package/build-ngc/angular/search-bar-ref.directive.js +4 -4
- package/build-ngc/angular/search-bar-ref.directive.js.map +1 -1
- package/build-ngc/angular/stack/index.d.ts +2 -0
- package/build-ngc/angular/stack/index.js +52 -14
- package/build-ngc/angular/stack/index.js.map +1 -1
- package/build-ngc/angular/tab-screen.directive.js +3 -3
- package/build-ngc/angular/tab-screen.directive.js.map +1 -1
- package/build-ngc/angular/tabs/index.d.ts +1 -1
- package/build-ngc/angular/tabs/index.js +43 -16
- package/build-ngc/angular/tabs/index.js.map +1 -1
- package/build-ngc/core/constants.js.map +1 -1
- package/build-ngc/core/drawer-options/index.js +19 -5
- package/build-ngc/core/drawer-options/index.js.map +1 -1
- package/build-ngc/core/drawer-router-state/index.js +8 -2
- package/build-ngc/core/drawer-router-state/index.js.map +1 -1
- package/build-ngc/core/guards.js +3 -1
- package/build-ngc/core/guards.js.map +1 -1
- package/build-ngc/core/header-bar-buttons.js +14 -4
- package/build-ngc/core/header-bar-buttons.js.map +1 -1
- package/build-ngc/core/index.d.ts +6 -5
- package/build-ngc/core/index.js +7 -3
- package/build-ngc/core/index.js.map +1 -1
- package/build-ngc/core/linking-config/index.js.map +1 -1
- package/build-ngc/core/navigation-events/index.js.map +1 -1
- package/build-ngc/core/navigator-handles/index.js.map +1 -1
- package/build-ngc/core/navigator-state/index.js +12 -4
- package/build-ngc/core/navigator-state/index.js.map +1 -1
- package/build-ngc/core/render-drawer.js +4 -1
- package/build-ngc/core/render-drawer.js.map +1 -1
- package/build-ngc/core/render-stack.js +13 -4
- package/build-ngc/core/render-stack.js.map +1 -1
- package/build-ngc/core/render-tabs.js.map +1 -1
- package/build-ngc/core/screen-options.js +1 -1
- package/build-ngc/core/screen-options.js.map +1 -1
- package/build-ngc/core/search-bar-commands.js +1 -1
- package/build-ngc/core/search-bar-commands.js.map +1 -1
- package/build-ngc/core/stack-router-state/index.d.ts +2 -0
- package/build-ngc/core/stack-router-state/index.js +45 -0
- package/build-ngc/core/stack-router-state/index.js.map +1 -0
- package/build-ngc/core/state-persistence/index.js +6 -2
- package/build-ngc/core/state-persistence/index.js.map +1 -1
- package/build-ngc/core/tab-router-state/index.d.ts +1 -0
- package/build-ngc/core/tab-router-state/index.js +27 -2
- package/build-ngc/core/tab-router-state/index.js.map +1 -1
- package/package.json +44 -16
- package/src/angular/drawer/index.ts +75 -29
- package/src/angular/index.ts +20 -4
- package/src/angular/injectors/inject-focus-effect.ts +8 -2
- package/src/angular/injectors/inject-is-focused.ts +6 -4
- package/src/angular/injectors/inject-navigation-state.ts +7 -4
- package/src/angular/injectors/inject-navigation.ts +12 -3
- package/src/angular/linking.ts +4 -1
- package/src/angular/navigation-context.service.ts +5 -2
- package/src/angular/navigation-scope.directive.ts +6 -2
- package/src/angular/screen.directive.ts +13 -3
- package/src/angular/search-bar-ref.directive.ts +10 -2
- package/src/angular/stack/index.ts +91 -24
- package/src/angular/tab-screen.directive.ts +3 -1
- package/src/angular/tabs/index.ts +54 -16
- package/src/core/constants.ts +6 -3
- package/src/core/drawer-options/index.ts +40 -13
- package/src/core/drawer-router-state/index.ts +11 -3
- package/src/core/guards.ts +3 -1
- package/src/core/header-bar-buttons.ts +41 -12
- package/src/core/index.ts +29 -5
- package/src/core/linking-config/index.ts +31 -10
- package/src/core/navigation-events/index.ts +8 -2
- package/src/core/navigator-handles/index.ts +8 -3
- package/src/core/navigator-props.ts +13 -4
- package/src/core/navigator-state/index.ts +24 -7
- package/src/core/render-drawer.ts +24 -9
- package/src/core/render-stack.ts +52 -13
- package/src/core/render-tabs.ts +24 -6
- package/src/core/screen-options.ts +15 -5
- package/src/core/search-bar-commands.ts +12 -3
- package/src/core/stack-router-state/index.ts +52 -0
- package/src/core/state-persistence/index.ts +13 -3
- package/src/core/tab-router-state/index.ts +35 -3
- package/src/react/drawer/index.ts +409 -330
- package/src/react/drawer-screen.ts +8 -2
- package/src/react/hooks/use-focus-effect.ts +8 -2
- package/src/react/hooks/use-is-focused.ts +6 -2
- package/src/react/hooks/use-navigation.ts +8 -2
- package/src/react/index.ts +37 -7
- package/src/react/linking.ts +4 -1
- package/src/react/navigation-context.ts +6 -2
- package/src/react/screen.ts +12 -3
- package/src/react/stack/index.ts +297 -220
- package/src/react/tab-screen.ts +3 -1
- package/src/react/tabs/index.ts +202 -139
- package/src/solid/drawer/index.ts +570 -0
- package/src/solid/drawer-screen-props.ts +24 -0
- package/src/solid/host.ts +29 -0
- package/src/solid/index.ts +87 -0
- package/src/solid/linking.ts +74 -0
- package/src/solid/navigation-context.ts +56 -0
- package/src/solid/primitives/create-focus-effect.ts +41 -0
- package/src/solid/primitives/create-is-focused.ts +41 -0
- package/src/solid/primitives/create-navigation-state.ts +44 -0
- package/src/solid/primitives/index.ts +12 -0
- package/src/solid/primitives/use-drawer-navigation.ts +25 -0
- package/src/solid/primitives/use-navigation.ts +44 -0
- package/src/solid/primitives/use-route.ts +18 -0
- package/src/solid/primitives/use-stack-navigation.ts +29 -0
- package/src/solid/primitives/use-tab-navigation.ts +25 -0
- package/src/solid/screen-props.ts +51 -0
- package/src/solid/screen-registry.ts +159 -0
- package/src/solid/screen.ts +80 -0
- package/src/solid/stack/index.ts +528 -0
- package/src/solid/tab-screen-props.ts +21 -0
- package/src/solid/tabs/index.ts +327 -0
- package/src/svelte/attachments.ts +70 -0
- package/src/svelte/descriptor-subtree.ts +51 -0
- package/src/svelte/drawer/drawer-props.ts +28 -0
- package/src/svelte/drawer/index.svelte +559 -0
- package/src/svelte/drawer/index.ts +10 -0
- package/src/svelte/drawer-screen-props.ts +26 -0
- package/src/svelte/drawer-screen.svelte +25 -0
- package/src/svelte/fabric-tree.test-helper.ts +95 -0
- package/src/svelte/index.ts +83 -0
- package/src/svelte/linking.svelte.ts +72 -0
- package/src/svelte/navigation-context.ts +62 -0
- package/src/svelte/navigation-scope.svelte +27 -0
- package/src/svelte/registry-host.ts +26 -0
- package/src/svelte/runes/index.ts +17 -0
- package/src/svelte/runes/use-drawer-navigation.svelte.ts +31 -0
- package/src/svelte/runes/use-focus-effect.svelte.ts +41 -0
- package/src/svelte/runes/use-is-focused.svelte.ts +38 -0
- package/src/svelte/runes/use-navigation-state.svelte.ts +48 -0
- package/src/svelte/runes/use-navigation.svelte.ts +49 -0
- package/src/svelte/runes/use-route.svelte.ts +16 -0
- package/src/svelte/runes/use-stack-navigation.svelte.ts +34 -0
- package/src/svelte/runes/use-tab-navigation.svelte.ts +29 -0
- package/src/svelte/screen-props.ts +50 -0
- package/src/svelte/screen-registry.ts +98 -0
- package/src/svelte/screen.svelte +28 -0
- package/src/svelte/stack/index.svelte +261 -0
- package/src/svelte/stack/index.ts +11 -0
- package/src/svelte/stack/stack-props.ts +31 -0
- package/src/svelte/stack/stack-screen.svelte +205 -0
- package/src/svelte/svelte-ambient.d.ts +6 -0
- package/src/svelte/svelte-compile.test-helper.ts +147 -0
- package/src/svelte/tab-screen-props.ts +22 -0
- package/src/svelte/tab-screen.svelte +26 -0
- package/src/svelte/tabs/index.svelte +269 -0
- package/src/svelte/tabs/index.ts +10 -0
- package/src/svelte/tabs/tab-props.ts +13 -0
- package/src/vue/composables/use-navigation-state.ts +7 -4
- package/src/vue/composables/use-navigation.ts +13 -3
- package/src/vue/drawer/index.ts +128 -41
- package/src/vue/drawer-screen.ts +12 -5
- package/src/vue/index.ts +15 -3
- package/src/vue/linking.ts +7 -2
- package/src/vue/navigation-context.ts +17 -5
- package/src/vue/screen.ts +7 -2
- package/src/vue/stack/index.ts +108 -43
- package/src/vue/tab-screen.ts +3 -1
- package/src/vue/tabs/index.ts +109 -68
package/build/core/index.d.ts
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
export * from './constants';
|
|
2
2
|
export { createInitialNavigatorState, navigatorReducer, computeActivityState, isTopRoute, } from './navigator-state';
|
|
3
|
-
export type { IRoute, INavigatorState, INavigatorAction } from './navigator-state';
|
|
3
|
+
export type { IRoute, INavigatorState, INavigatorAction, } from './navigator-state';
|
|
4
|
+
export { reconcileStackRoutes } from './stack-router-state';
|
|
4
5
|
export type { IStackAnimation, IStackPresentation, IHeaderBackButtonDisplayMode, IHeaderUserInterfaceStyle, IOptionalBooleanNativeProp, ISheetAllowedDetents, ISheetLargestUndimmedDetent, ISheetInitialDetent, IHeaderBarButtonIcon, IHeaderBarButtonItemBadge, IHeaderBarButtonItemAction, IHeaderBarButtonMenuAction, IHeaderBarButtonSubmenu, IHeaderBarButtonItemMenu, IHeaderBarButtonItemSpacing, IHeaderBarButtonItem, ISearchBarAutoCapitalize, ISearchBarPlacement, ISearchBarOptions, IScreenOrientation, IScreenOptions, INavigatorPlatform, IScreenViewProps, IHeaderConfigViewProps, IStackViewProps, ISearchBarViewProps, } from './navigator-props';
|
|
5
|
-
export { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView } from './screen-options';
|
|
6
|
+
export { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView, } from './screen-options';
|
|
6
7
|
export { buildSearchBarHandle } from './search-bar-commands';
|
|
7
8
|
export type { ISearchBarCommands } from './search-bar-commands';
|
|
8
9
|
export { resolveScreenProps, resolveStackProps, renderHeaderConfig, resolveSearchBarProps, resolveScreenContentWrapperStyle, resolveScreenViewName, isHeaderInModal, resolveHeaderInModalStackStyle, resolveHeaderInModalScreenStyle, buildSearchBarPassthrough, resolveScreenRenderPlan, } from './render-stack';
|
|
9
10
|
export type { IScreenRenderPlanInput, IScreenRenderPlan } from './render-stack';
|
|
10
|
-
export { serializeNavigatorState, deserializeNavigatorState } from './state-persistence';
|
|
11
|
+
export { serializeNavigatorState, deserializeNavigatorState, } from './state-persistence';
|
|
11
12
|
export { createNavigationEmitter, diffFocusedRoute, NAVIGATION_EVENT_FOCUS, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_STATE, NAVIGATION_EVENT_BEFORE_REMOVE, } from './navigation-events';
|
|
12
13
|
export type { INavigationEmitter, INavigationEventListener, INavigationEventName, IFocusTransition, } from './navigation-events';
|
|
13
14
|
export { isRecord } from './guards';
|
|
14
|
-
export { createInitialTabState, tabRouterReducer, isFocusedRoute } from './tab-router-state';
|
|
15
|
+
export { createInitialTabState, tabRouterReducer, reconcileTabRoutes, isFocusedRoute, } from './tab-router-state';
|
|
15
16
|
export type { ITabRouterState, ITabRouterAction } from './tab-router-state';
|
|
16
17
|
export type { ITabBarIcon, ITabOptions } from './tab-options';
|
|
17
18
|
export { renderTabBarItem, renderTabBar } from './render-tabs';
|
|
@@ -19,7 +20,7 @@ export type { ITabBarItemView, ITabBarViewProps } from './render-tabs';
|
|
|
19
20
|
export { resolveRouteFromUrl, resolveUrlFromRoute } from './linking-config';
|
|
20
21
|
export type { ILinkingConfig, IScreenLinkingConfig } from './linking-config';
|
|
21
22
|
export { createInitialDrawerRouterState, drawerRouterReducer, focusedDrawerRoute, } from './drawer-router-state';
|
|
22
|
-
export type { IDrawerRouterState, IDrawerRouterAction } from './drawer-router-state';
|
|
23
|
+
export type { IDrawerRouterState, IDrawerRouterAction, } from './drawer-router-state';
|
|
23
24
|
export type { IDrawerType, IDrawerPosition, IDrawerOptions, IDrawerScreenOptions, IDrawerGeometry, ISwipeIntent, } from './drawer-options';
|
|
24
25
|
export { DRAWER_DEFAULT_TYPE, DRAWER_DEFAULT_POSITION, DRAWER_DEFAULT_WIDTH, DRAWER_DEFAULT_OVERLAY_COLOR, DRAWER_DEFAULT_SWIPE_ENABLED, DRAWER_DEFAULT_SWIPE_EDGE_WIDTH, DRAWER_DEFAULT_SWIPE_MIN_DISTANCE, DRAWER_DEFAULT_SWIPE_MIN_VELOCITY, resolveDrawerType, resolveDrawerPosition, resolveDrawerWidth, isDrawerAnimated, isDrawerOverlayVisible, resolveDrawerGeometry, isSwipeStartInEdge, isHorizontalDrag, resolveSwipeIntent, clamp01, startPageXOf, resolveDragProgress, shouldClaimDrawerSwipe, resolveDrawerSlotInterpolation, } from './drawer-options';
|
|
25
26
|
export type { IDrawerInterpolationRange, IDrawerContentSlotInterpolation, IDrawerOverlaySlotInterpolation, IDrawerPanelSlotInterpolation, } from './drawer-options';
|
package/build/core/index.js
CHANGED
|
@@ -7,10 +7,14 @@
|
|
|
7
7
|
// the descriptor bridge.
|
|
8
8
|
export * from './constants.js';
|
|
9
9
|
export { createInitialNavigatorState, navigatorReducer, computeActivityState, isTopRoute, } from './navigator-state/index.js';
|
|
10
|
-
|
|
10
|
+
// Drops history entries whose `<Stack.Screen>` marker has unregistered - see
|
|
11
|
+
// stack-router-state.ts's header for why the Stack's history needs this and the Tab's projection
|
|
12
|
+
// does not.
|
|
13
|
+
export { reconcileStackRoutes } from './stack-router-state/index.js';
|
|
14
|
+
export { resolveHeaderConfigView, resolveScreenView, resolveSearchBarView, } from './screen-options.js';
|
|
11
15
|
export { buildSearchBarHandle } from './search-bar-commands.js';
|
|
12
16
|
export { resolveScreenProps, resolveStackProps, renderHeaderConfig, resolveSearchBarProps, resolveScreenContentWrapperStyle, resolveScreenViewName, isHeaderInModal, resolveHeaderInModalStackStyle, resolveHeaderInModalScreenStyle, buildSearchBarPassthrough, resolveScreenRenderPlan, } from './render-stack.js';
|
|
13
|
-
export { serializeNavigatorState, deserializeNavigatorState } from './state-persistence/index.js';
|
|
17
|
+
export { serializeNavigatorState, deserializeNavigatorState, } from './state-persistence/index.js';
|
|
14
18
|
export { createNavigationEmitter, diffFocusedRoute, NAVIGATION_EVENT_FOCUS, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_STATE, NAVIGATION_EVENT_BEFORE_REMOVE, } from './navigation-events/index.js';
|
|
15
19
|
// Runtime guards shared across core (and re-exported for adapters narrowing their own untyped
|
|
16
20
|
// inputs - vnode props, gesture/event data, persisted JSON) - see guards.ts's header for which
|
|
@@ -18,7 +22,7 @@ export { createNavigationEmitter, diffFocusedRoute, NAVIGATION_EVENT_FOCUS, NAVI
|
|
|
18
22
|
export { isRecord } from './guards.js';
|
|
19
23
|
// Bottom-tabs navigator: a FOCUSED-INDEX router (not a stack - see tab-router-state.ts) driving
|
|
20
24
|
// a pure-JS tab bar render, framework-agnostic and shared verbatim by every adapter.
|
|
21
|
-
export { createInitialTabState, tabRouterReducer, isFocusedRoute } from './tab-router-state/index.js';
|
|
25
|
+
export { createInitialTabState, tabRouterReducer, reconcileTabRoutes, isFocusedRoute, } from './tab-router-state/index.js';
|
|
22
26
|
export { renderTabBarItem, renderTabBar } from './render-tabs.js';
|
|
23
27
|
// Linking config: resolves a URL to a route (and back), the piece @react-navigation's
|
|
24
28
|
// NavigationContainer `linking` prop provides on top of the framework-agnostic Linking module.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// in its router, minus the React-specific action-creator/linking machinery. Route identity
|
|
4
4
|
// (`key`) is generated by the CALLER (the adapter, via React's useId or an equivalent) - the
|
|
5
5
|
// reducer never invents identity itself, so it stays a pure (state, action) => state function.
|
|
6
|
-
import { SCREEN_ACTIVITY_STATE_FOCUSED, SCREEN_ACTIVITY_STATE_INACTIVE } from '../constants.js';
|
|
6
|
+
import { SCREEN_ACTIVITY_STATE_FOCUSED, SCREEN_ACTIVITY_STATE_INACTIVE, } from '../constants.js';
|
|
7
7
|
import { mergeParams } from '../guards.js';
|
|
8
8
|
export function createInitialNavigatorState(initialRoute) {
|
|
9
9
|
return { routes: [initialRoute] };
|
|
@@ -22,7 +22,9 @@ export function navigatorReducer(state, action) {
|
|
|
22
22
|
return { routes: state.routes.slice(0, nextLength) };
|
|
23
23
|
}
|
|
24
24
|
case 'popToTop':
|
|
25
|
-
return state.routes.length <= 1
|
|
25
|
+
return state.routes.length <= 1
|
|
26
|
+
? state
|
|
27
|
+
: { routes: state.routes.slice(0, 1) };
|
|
26
28
|
case 'popTo': {
|
|
27
29
|
const index = state.routes.findIndex(route => route.key === action.key);
|
|
28
30
|
if (index === -1)
|
|
@@ -51,7 +53,11 @@ export function navigatorReducer(state, action) {
|
|
|
51
53
|
params: mergeParams(target.params, action.params),
|
|
52
54
|
};
|
|
53
55
|
return {
|
|
54
|
-
routes: [
|
|
56
|
+
routes: [
|
|
57
|
+
...state.routes.slice(0, index),
|
|
58
|
+
nextRoute,
|
|
59
|
+
...state.routes.slice(index + 1),
|
|
60
|
+
],
|
|
55
61
|
};
|
|
56
62
|
}
|
|
57
63
|
// Mirrors @react-navigation's CommonActions.reset / BaseRouter's RESET handler: the payload
|
|
@@ -74,7 +80,9 @@ export function navigatorReducer(state, action) {
|
|
|
74
80
|
// exceeds routesLength - 1, this formula never produces a decrease across a push or pop.
|
|
75
81
|
export function computeActivityState(index, routesLength) {
|
|
76
82
|
const focusedIndex = routesLength - 1;
|
|
77
|
-
return index > focusedIndex
|
|
83
|
+
return index > focusedIndex
|
|
84
|
+
? SCREEN_ACTIVITY_STATE_INACTIVE
|
|
85
|
+
: SCREEN_ACTIVITY_STATE_FOCUSED;
|
|
78
86
|
}
|
|
79
87
|
export function isTopRoute(index, routesLength) {
|
|
80
88
|
return index === routesLength - 1;
|
|
@@ -69,7 +69,10 @@ function panelBaseStyle(options) {
|
|
|
69
69
|
export function renderDrawer(view, options) {
|
|
70
70
|
const type = resolveDrawerType(options);
|
|
71
71
|
const content = el('symbiote-view', { ...view.contentPassthrough, style: CONTENT_STYLE }, []);
|
|
72
|
-
const panel = el('symbiote-view', {
|
|
72
|
+
const panel = el('symbiote-view', {
|
|
73
|
+
...view.panelPassthrough,
|
|
74
|
+
style: [panelBaseStyle(options), view.drawerStyle],
|
|
75
|
+
}, []);
|
|
73
76
|
const slots = { content, panel };
|
|
74
77
|
if (isDrawerOverlayVisible(options)) {
|
|
75
78
|
slots.overlay = el('symbiote-view', {
|
|
@@ -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
|
|
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' &&
|
|
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 = {
|
|
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
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// StackRouter: the registry-reconciliation half (framework-agnostic, zero render). A Stack's route
|
|
2
|
+
// list is navigation HISTORY, not a projection of the registered `<Stack.Screen>` markers the way a
|
|
3
|
+
// Tab's is (tab-router-state) - it seeds exactly one route and grows only through push/replace. So
|
|
4
|
+
// a marker that unregisters while its route still sits in the history (a marker behind an `{#if}`,
|
|
5
|
+
// a data-driven screen list) leaves behind an entry nothing can render: the route stays, the
|
|
6
|
+
// adapter's componentFor() finds no screen, and the user is parked on a blank RNSScreen with no
|
|
7
|
+
// way to tell what happened. Mirrors @react-navigation/routers' StackRouter.getStateForRouteNames-
|
|
8
|
+
// Change, which filters those routes out of the history and pulls the focused index back into
|
|
9
|
+
// range.
|
|
10
|
+
//
|
|
11
|
+
// Deliberately NOT a navigatorReducer action: this is not something a caller dispatches, it is a
|
|
12
|
+
// reaction to the registry changing underneath an unchanged history, and each adapter observes
|
|
13
|
+
// that change through its own lifecycle. Keeping it a separate pure function lets every adapter
|
|
14
|
+
// wire it its own way without teaching the reducer about a registry it has never seen.
|
|
15
|
+
// The contract, and the two places it deliberately parts from upstream:
|
|
16
|
+
//
|
|
17
|
+
// - SURVIVORS KEEP THEIR IDENTITY. A stack route's key is COUNTER-derived (every adapter's
|
|
18
|
+
// createRoute increments a per-navigator sequence), not name-derived like a tab route's, so
|
|
19
|
+
// re-deriving the list from the registry would hand every survivor a brand-new key and remount
|
|
20
|
+
// live screens. Only the phantom entries go; every other route object passes through by
|
|
21
|
+
// reference, params included.
|
|
22
|
+
//
|
|
23
|
+
// - THE FOCUSED ROUTE IS THE TOP ONE. This state carries no `index` field: the focused route is
|
|
24
|
+
// always the last one (see computeActivityState's comment for why no route can outrank it), so
|
|
25
|
+
// upstream's `index: Math.min(state.index, routes.length - 1)` degenerates here to "the last
|
|
26
|
+
// survivor". Dropping the FOCUSED route therefore lands the user on the nearest still-registered
|
|
27
|
+
// route beneath it - where a pop() would have left them - rather than on nothing.
|
|
28
|
+
//
|
|
29
|
+
// - THE ROUTE LIST IS NEVER EMPTIED. `routes.length - 1` IS the focused index, so an empty list
|
|
30
|
+
// means no focused route at all - the blank screen this function exists to prevent. When nothing
|
|
31
|
+
// in the history survives (every marker gone, or the whole screen set swapped for new names) the
|
|
32
|
+
// state is returned UNCHANGED. Upstream instead pushes a freshly nanoid()-keyed route for
|
|
33
|
+
// initialRouteName; we cannot, because minting a route key belongs to the caller here
|
|
34
|
+
// (navigator-state.ts's header) and a derivation that mints one would allocate a new key on every
|
|
35
|
+
// re-run. Unchanged is also the right answer for the usual cause of a momentarily empty registry
|
|
36
|
+
// - markers unregistering and re-registering across a re-render - since the next run reconciles
|
|
37
|
+
// for real.
|
|
38
|
+
export function reconcileStackRoutes(state, registeredNames) {
|
|
39
|
+
const routes = state.routes.filter(route => registeredNames.includes(route.name));
|
|
40
|
+
// filter preserves order, so an unchanged length means nothing was dropped.
|
|
41
|
+
if (routes.length === state.routes.length || routes.length === 0)
|
|
42
|
+
return state;
|
|
43
|
+
return { routes };
|
|
44
|
+
}
|
|
@@ -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) &&
|
|
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) &&
|
|
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;
|
|
@@ -15,5 +15,6 @@ export type ITabRouterAction = {
|
|
|
15
15
|
params: unknown;
|
|
16
16
|
};
|
|
17
17
|
export declare function createInitialTabState(routes: readonly IRouteEntry[], initialRouteName?: string): ITabRouterState;
|
|
18
|
+
export declare function reconcileTabRoutes(state: ITabRouterState, nextRoutes: readonly IRouteEntry[]): ITabRouterState;
|
|
18
19
|
export declare function tabRouterReducer(state: ITabRouterState, action: ITabRouterAction): ITabRouterState;
|
|
19
20
|
export declare function isFocusedRoute(index: number, focusedIndex: number): boolean;
|
|
@@ -14,6 +14,25 @@ export function createInitialTabState(routes, initialRouteName) {
|
|
|
14
14
|
const index = routes.findIndex(route => route.name === initialRouteName);
|
|
15
15
|
return { routes, index: index === -1 ? INITIAL_FOCUSED_INDEX : index };
|
|
16
16
|
}
|
|
17
|
+
// A screen marker can appear or disappear after mount (a marker behind an `{#if}`, a data-driven
|
|
18
|
+
// screen list), so a navigator's route list has to follow its registry instead of staying frozen
|
|
19
|
+
// at whatever createInitialTabState saw first. Mirrors TabRouter.getStateForRouteNamesChange:
|
|
20
|
+
// membership and order come from `nextRoutes`, but a route that survives keeps its IDENTITY (its
|
|
21
|
+
// key) and everything jumpTo/setParams accumulated onto its params - only genuinely new names
|
|
22
|
+
// take their entry from `nextRoutes`. Focus follows the previously focused route's NAME, so an
|
|
23
|
+
// unrelated screen disappearing never moves the user; when the focused route is the one that
|
|
24
|
+
// disappeared, focus falls back to the first route, the same landing spot every unresolvable
|
|
25
|
+
// focus gets here (createInitialTabState's own fallback).
|
|
26
|
+
export function reconcileTabRoutes(state, nextRoutes) {
|
|
27
|
+
const routes = nextRoutes.map(next => state.routes.find(route => route.name === next.name) ?? next);
|
|
28
|
+
const isUnchanged = routes.length === state.routes.length &&
|
|
29
|
+
routes.every((route, at) => route === state.routes[at]);
|
|
30
|
+
if (isUnchanged)
|
|
31
|
+
return state;
|
|
32
|
+
const focusedName = state.routes[state.index]?.name;
|
|
33
|
+
const index = routes.findIndex(route => route.name === focusedName);
|
|
34
|
+
return { routes, index: index === -1 ? INITIAL_FOCUSED_INDEX : index };
|
|
35
|
+
}
|
|
17
36
|
// jumpTo moves the focused index to an existing route by name and optionally merges params
|
|
18
37
|
// (navigation.jumpTo(name, params) - the tab-actions doc's own signature); it never adds,
|
|
19
38
|
// removes, or reorders routes (mirrors TabRouter: JUMP_TO is a no-op when the target name isn't
|
|
@@ -30,7 +49,10 @@ export function tabRouterReducer(state, action) {
|
|
|
30
49
|
}
|
|
31
50
|
const target = state.routes[index];
|
|
32
51
|
const routes = state.routes.slice();
|
|
33
|
-
routes[index] = {
|
|
52
|
+
routes[index] = {
|
|
53
|
+
...target,
|
|
54
|
+
params: mergeParams(target.params, action.params),
|
|
55
|
+
};
|
|
34
56
|
return { ...state, index, routes };
|
|
35
57
|
}
|
|
36
58
|
case 'setParams': {
|
|
@@ -39,7 +61,10 @@ export function tabRouterReducer(state, action) {
|
|
|
39
61
|
return state;
|
|
40
62
|
const target = state.routes[index];
|
|
41
63
|
const routes = state.routes.slice();
|
|
42
|
-
routes[index] = {
|
|
64
|
+
routes[index] = {
|
|
65
|
+
...target,
|
|
66
|
+
params: mergeParams(target.params, action.params),
|
|
67
|
+
};
|
|
43
68
|
return { ...state, routes };
|
|
44
69
|
}
|
|
45
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'
|
|
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;
|
|
@@ -71,8 +73,10 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
|
|
|
71
73
|
optionsRef.current = options;
|
|
72
74
|
const screenWidthRef = useRef(screenWidth);
|
|
73
75
|
screenWidthRef.current = screenWidth;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
// The whole router state, not just its isOpen bit: jumpTo below has to re-run the reducer to
|
|
77
|
+
// learn what the dispatch actually produced, and that needs the routes too.
|
|
78
|
+
const stateRef = useRef(state);
|
|
79
|
+
stateRef.current = state;
|
|
76
80
|
const animateProgressTo = useCallback((open) => {
|
|
77
81
|
// Investigation instrumentation (Drawer openDrawer-no-op / toggleDrawer-no-animation bug):
|
|
78
82
|
// every imperative caller (openDrawer/closeDrawer/toggleDrawer/jumpTo) funnels through here,
|
|
@@ -92,40 +96,48 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
|
|
|
92
96
|
}, [progress]);
|
|
93
97
|
const handle = useMemo(() => ({
|
|
94
98
|
openDrawer: () => {
|
|
95
|
-
dlog(`Drawer: openDrawer() called, isOpen=${
|
|
99
|
+
dlog(`Drawer: openDrawer() called, isOpen=${stateRef.current.isOpen} at t=${Date.now()}`);
|
|
96
100
|
animateProgressTo(true);
|
|
97
101
|
dispatch({ type: 'openDrawer' });
|
|
98
102
|
},
|
|
99
103
|
closeDrawer: () => {
|
|
100
|
-
dlog(`Drawer: closeDrawer() called, isOpen=${
|
|
104
|
+
dlog(`Drawer: closeDrawer() called, isOpen=${stateRef.current.isOpen} at t=${Date.now()}`);
|
|
101
105
|
animateProgressTo(false);
|
|
102
106
|
dispatch({ type: 'closeDrawer' });
|
|
103
107
|
},
|
|
104
108
|
toggleDrawer: () => {
|
|
105
|
-
dlog(`Drawer: toggleDrawer() called, isOpen=${
|
|
106
|
-
animateProgressTo(!
|
|
109
|
+
dlog(`Drawer: toggleDrawer() called, isOpen=${stateRef.current.isOpen} at t=${Date.now()}`);
|
|
110
|
+
animateProgressTo(!stateRef.current.isOpen);
|
|
107
111
|
dispatch({ type: 'toggleDrawer' });
|
|
108
112
|
},
|
|
109
113
|
jumpTo: (name) => {
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
// An unregistered name is a documented reducer no-op that hands the SAME state back, so
|
|
115
|
+
// animating off `isOpen` alone would slide the panel shut while the router still says
|
|
116
|
+
// open. useReducer's dispatch is async - stateRef only catches up on the next render - so
|
|
117
|
+
// the reducer (a pure function) is re-run here to learn what the dispatch produces, and
|
|
118
|
+
// the animation runs only on a genuine open -> closed transition.
|
|
119
|
+
const action = { type: 'jumpTo', name };
|
|
120
|
+
const current = stateRef.current;
|
|
121
|
+
const next = drawerRouterReducer(current, action);
|
|
122
|
+
dispatch(action);
|
|
123
|
+
if (current.isOpen && !next.isOpen)
|
|
112
124
|
animateProgressTo(false);
|
|
113
125
|
},
|
|
114
126
|
}), [animateProgressTo]);
|
|
115
127
|
useImperativeHandle(forwardedRef, () => handle, [handle]);
|
|
116
128
|
const panResponder = useRef(PanResponder.create({
|
|
117
|
-
onStartShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, screenWidthRef.current,
|
|
118
|
-
onMoveShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, screenWidthRef.current,
|
|
129
|
+
onStartShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, screenWidthRef.current, stateRef.current.isOpen, optionsRef.current, 'start'),
|
|
130
|
+
onMoveShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, screenWidthRef.current, stateRef.current.isOpen, optionsRef.current, 'move'),
|
|
119
131
|
onPanResponderGrant: () => {
|
|
120
132
|
dlog('Drawer: gesture grant');
|
|
121
|
-
dragStartProgress.current =
|
|
133
|
+
dragStartProgress.current = stateRef.current.isOpen ? 1 : 0;
|
|
122
134
|
},
|
|
123
135
|
onPanResponderMove: (_event, gestureState) => {
|
|
124
136
|
const nextProgress = resolveDragProgress(gestureState, dragStartProgress.current, optionsRef.current);
|
|
125
137
|
progress.setValue(nextProgress);
|
|
126
138
|
},
|
|
127
139
|
onPanResponderRelease: (_event, gestureState) => {
|
|
128
|
-
const intent = resolveSwipeIntent(gestureState,
|
|
140
|
+
const intent = resolveSwipeIntent(gestureState, stateRef.current.isOpen, optionsRef.current);
|
|
129
141
|
const open = intent === 'open';
|
|
130
142
|
dlog(`Drawer: gesture release -> ${open ? 'open' : 'close'}`);
|
|
131
143
|
animateProgressTo(open);
|
|
@@ -133,17 +145,29 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
|
|
|
133
145
|
},
|
|
134
146
|
onPanResponderTerminate: () => {
|
|
135
147
|
dlog('Drawer: gesture terminated, snapping back');
|
|
136
|
-
animateProgressTo(
|
|
148
|
+
animateProgressTo(stateRef.current.isOpen);
|
|
137
149
|
},
|
|
138
150
|
})).current;
|
|
139
151
|
const animated = isDrawerAnimated(options);
|
|
140
152
|
const geometry = useMemo(() => resolveDrawerGeometry(options), [options.drawerType, options.drawerPosition, options.drawerWidth]);
|
|
141
|
-
const panelSlot = animated
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
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;
|
|
147
171
|
// The overlay is a full-screen absolutely-positioned sibling BELOW content in paint order
|
|
148
172
|
// (see render-drawer.ts's drawerChildOrder) - for 'front' that's fine since content never moves,
|
|
149
173
|
// but for 'slide' content itself translates away by contentTranslateX, and without following it
|
|
@@ -151,9 +175,13 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
|
|
|
151
175
|
// underneath instead of just the content sliver it's meant to dim. Tying overlay to the SAME
|
|
152
176
|
// translateX as content keeps it registered exactly under content, wherever content actually is
|
|
153
177
|
// (resolveDrawerSlotInterpolation's 'overlay' overload returns that same content delta).
|
|
154
|
-
const overlayTranslateX = overlaySlot
|
|
178
|
+
const overlayTranslateX = overlaySlot
|
|
179
|
+
? progress.interpolate(overlaySlot.translateX)
|
|
180
|
+
: undefined;
|
|
155
181
|
const focusedRoute = state.routes[state.index];
|
|
156
|
-
const focusedEntry = focusedRoute
|
|
182
|
+
const focusedEntry = focusedRoute
|
|
183
|
+
? registry.get(focusedRoute.name)
|
|
184
|
+
: undefined;
|
|
157
185
|
if (focusedRoute && !focusedEntry) {
|
|
158
186
|
dlog(`Drawer: no screen registered for route name "${focusedRoute.name}"`);
|
|
159
187
|
}
|
|
@@ -240,8 +268,13 @@ const DrawerImpl = forwardRef((props, forwardedRef) => {
|
|
|
240
268
|
: { transform: [{ translateX: contentTranslateX }] },
|
|
241
269
|
overlay: overlayOpacity === undefined
|
|
242
270
|
? undefined
|
|
243
|
-
: {
|
|
244
|
-
|
|
271
|
+
: {
|
|
272
|
+
opacity: overlayOpacity,
|
|
273
|
+
transform: [{ translateX: overlayTranslateX }],
|
|
274
|
+
},
|
|
275
|
+
panel: panelTranslateX === undefined
|
|
276
|
+
? undefined
|
|
277
|
+
: { transform: [{ translateX: panelTranslateX }] },
|
|
245
278
|
};
|
|
246
279
|
function renderSlot(slot) {
|
|
247
280
|
const descriptor = slots.get(slot);
|
package/build/react/index.d.ts
CHANGED
|
@@ -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';
|
package/build/react/index.js
CHANGED
|
@@ -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
|