@symbiote-native/navigation 1.0.0 → 2.0.1
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 +159 -0
- package/package.json +14 -12
- package/build/angular/drawer/index.d.ts +0 -76
- package/build/angular/drawer/index.js +0 -508
- package/build/angular/drawer-screen.directive.d.ts +0 -14
- package/build/angular/drawer-screen.directive.js +0 -87
- package/build/angular/index.d.ts +0 -23
- package/build/angular/index.js +0 -22
- package/build/angular/injectors/index.d.ts +0 -13
- package/build/angular/injectors/index.js +0 -8
- package/build/angular/injectors/inject-drawer-navigation.d.ts +0 -4
- package/build/angular/injectors/inject-drawer-navigation.js +0 -12
- package/build/angular/injectors/inject-focus-effect.d.ts +0 -2
- package/build/angular/injectors/inject-focus-effect.js +0 -29
- package/build/angular/injectors/inject-is-focused.d.ts +0 -2
- package/build/angular/injectors/inject-is-focused.js +0 -20
- package/build/angular/injectors/inject-navigation-state.d.ts +0 -3
- package/build/angular/injectors/inject-navigation-state.js +0 -35
- package/build/angular/injectors/inject-navigation.d.ts +0 -7
- package/build/angular/injectors/inject-navigation.js +0 -16
- package/build/angular/injectors/inject-route.d.ts +0 -3
- package/build/angular/injectors/inject-route.js +0 -20
- package/build/angular/injectors/inject-stack-navigation.d.ts +0 -4
- package/build/angular/injectors/inject-stack-navigation.js +0 -15
- package/build/angular/injectors/inject-tab-navigation.d.ts +0 -4
- package/build/angular/injectors/inject-tab-navigation.js +0 -11
- package/build/angular/linking.d.ts +0 -3
- package/build/angular/linking.js +0 -43
- package/build/angular/navigation-context.service.d.ts +0 -13
- package/build/angular/navigation-context.service.js +0 -105
- package/build/angular/navigation-scope.directive.d.ts +0 -10
- package/build/angular/navigation-scope.directive.js +0 -90
- package/build/angular/screen.directive.d.ts +0 -22
- package/build/angular/screen.directive.js +0 -90
- package/build/angular/search-bar-ref.directive.d.ts +0 -10
- package/build/angular/search-bar-ref.directive.js +0 -88
- package/build/angular/stack/index.d.ts +0 -55
- package/build/angular/stack/index.js +0 -386
- package/build/angular/tab-screen.directive.d.ts +0 -14
- package/build/angular/tab-screen.directive.js +0 -87
- package/build/angular/tabs/index.d.ts +0 -42
- package/build/angular/tabs/index.js +0 -263
- package/build/core/constants.d.ts +0 -27
- package/build/core/constants.js +0 -61
- package/build/core/drawer-options/index.d.ts +0 -64
- package/build/core/drawer-options/index.js +0 -200
- package/build/core/drawer-router-state/index.d.ts +0 -21
- package/build/core/drawer-router-state/index.js +0 -40
- package/build/core/guards.d.ts +0 -2
- package/build/core/guards.js +0 -22
- package/build/core/header-bar-buttons.d.ts +0 -9
- package/build/core/header-bar-buttons.js +0 -163
- package/build/core/index.d.ts +0 -29
- package/build/core/index.js +0 -32
- package/build/core/linking-config/index.d.ts +0 -13
- package/build/core/linking-config/index.js +0 -171
- package/build/core/navigation-events/index.d.ts +0 -16
- package/build/core/navigation-events/index.js +0 -57
- package/build/core/navigator-handles/index.d.ts +0 -30
- package/build/core/navigator-handles/index.js +0 -15
- package/build/core/navigator-props.d.ts +0 -216
- package/build/core/navigator-props.js +0 -7
- package/build/core/navigator-state/index.d.ts +0 -36
- package/build/core/navigator-state/index.js +0 -81
- package/build/core/render-drawer.d.ts +0 -13
- package/build/core/render-drawer.js +0 -88
- package/build/core/render-stack.d.ts +0 -35
- package/build/core/render-stack.js +0 -294
- package/build/core/render-tabs.d.ts +0 -20
- package/build/core/render-tabs.js +0 -97
- package/build/core/screen-options.d.ts +0 -4
- package/build/core/screen-options.js +0 -133
- package/build/core/search-bar-commands.d.ts +0 -10
- package/build/core/search-bar-commands.js +0 -42
- package/build/core/state-persistence/index.d.ts +0 -3
- package/build/core/state-persistence/index.js +0 -23
- package/build/core/tab-options.d.ts +0 -13
- package/build/core/tab-options.js +0 -10
- package/build/core/tab-router-state/index.d.ts +0 -19
- package/build/core/tab-router-state/index.js +0 -51
- package/build/react/collect-registry.d.ts +0 -4
- package/build/react/collect-registry.js +0 -15
- package/build/react/drawer/index.d.ts +0 -29
- package/build/react/drawer/index.js +0 -277
- package/build/react/drawer-screen.d.ts +0 -14
- package/build/react/drawer-screen.js +0 -8
- package/build/react/hooks/index.d.ts +0 -12
- package/build/react/hooks/index.js +0 -8
- package/build/react/hooks/use-drawer-navigation.d.ts +0 -4
- package/build/react/hooks/use-drawer-navigation.js +0 -12
- package/build/react/hooks/use-focus-effect.d.ts +0 -2
- package/build/react/hooks/use-focus-effect.js +0 -29
- package/build/react/hooks/use-is-focused.d.ts +0 -1
- package/build/react/hooks/use-is-focused.js +0 -22
- package/build/react/hooks/use-navigation-state/index.d.ts +0 -2
- package/build/react/hooks/use-navigation-state/index.js +0 -39
- package/build/react/hooks/use-navigation.d.ts +0 -7
- package/build/react/hooks/use-navigation.js +0 -16
- package/build/react/hooks/use-route.d.ts +0 -2
- package/build/react/hooks/use-route.js +0 -8
- package/build/react/hooks/use-stack-navigation.d.ts +0 -4
- package/build/react/hooks/use-stack-navigation.js +0 -14
- package/build/react/hooks/use-tab-navigation.d.ts +0 -4
- package/build/react/hooks/use-tab-navigation.js +0 -12
- package/build/react/index.d.ts +0 -24
- package/build/react/index.js +0 -21
- package/build/react/linking.d.ts +0 -3
- package/build/react/linking.js +0 -47
- package/build/react/navigation-context.d.ts +0 -10
- package/build/react/navigation-context.js +0 -22
- package/build/react/screen.d.ts +0 -22
- package/build/react/screen.js +0 -7
- package/build/react/stack/index.d.ts +0 -13
- package/build/react/stack/index.js +0 -202
- package/build/react/tab-screen.d.ts +0 -15
- package/build/react/tab-screen.js +0 -8
- package/build/react/tabs/index.d.ts +0 -12
- package/build/react/tabs/index.js +0 -116
- package/build/register.d.ts +0 -7
- package/build/register.js +0 -58
- package/build/vue/composables/index.d.ts +0 -12
- package/build/vue/composables/index.js +0 -8
- package/build/vue/composables/use-drawer-navigation.d.ts +0 -5
- package/build/vue/composables/use-drawer-navigation.js +0 -15
- package/build/vue/composables/use-focus-effect.d.ts +0 -1
- package/build/vue/composables/use-focus-effect.js +0 -31
- package/build/vue/composables/use-is-focused.d.ts +0 -2
- package/build/vue/composables/use-is-focused.js +0 -28
- package/build/vue/composables/use-navigation-state.d.ts +0 -3
- package/build/vue/composables/use-navigation-state.js +0 -29
- package/build/vue/composables/use-navigation.d.ts +0 -8
- package/build/vue/composables/use-navigation.js +0 -13
- package/build/vue/composables/use-route.d.ts +0 -3
- package/build/vue/composables/use-route.js +0 -9
- package/build/vue/composables/use-stack-navigation.d.ts +0 -5
- package/build/vue/composables/use-stack-navigation.js +0 -18
- package/build/vue/composables/use-tab-navigation.d.ts +0 -5
- package/build/vue/composables/use-tab-navigation.js +0 -15
- package/build/vue/drawer/index.d.ts +0 -19
- package/build/vue/drawer/index.js +0 -390
- package/build/vue/drawer-screen.d.ts +0 -14
- package/build/vue/drawer-screen.js +0 -12
- package/build/vue/index.d.ts +0 -21
- package/build/vue/index.js +0 -19
- package/build/vue/linking.d.ts +0 -3
- package/build/vue/linking.js +0 -57
- package/build/vue/navigation-context.d.ts +0 -16
- package/build/vue/navigation-context.js +0 -65
- package/build/vue/screen.d.ts +0 -21
- package/build/vue/screen.js +0 -12
- package/build/vue/stack/index.d.ts +0 -9
- package/build/vue/stack/index.js +0 -279
- package/build/vue/tab-screen.d.ts +0 -14
- package/build/vue/tab-screen.js +0 -11
- package/build/vue/tabs/index.d.ts +0 -10
- package/build/vue/tabs/index.js +0 -209
- package/build-ngc/angular/drawer.d.ts +0 -79
- package/build-ngc/angular/drawer.js +0 -475
- package/build-ngc/angular/drawer.js.map +0 -1
- package/build-ngc/angular/stack.d.ts +0 -58
- package/build-ngc/angular/stack.js +0 -402
- package/build-ngc/angular/stack.js.map +0 -1
- package/build-ngc/angular/tabs.d.ts +0 -45
- package/build-ngc/angular/tabs.js +0 -231
- package/build-ngc/angular/tabs.js.map +0 -1
- package/build-ngc/core/drawer-options.d.ts +0 -64
- package/build-ngc/core/drawer-options.js +0 -201
- package/build-ngc/core/drawer-options.js.map +0 -1
- package/build-ngc/core/drawer-router-state.d.ts +0 -21
- package/build-ngc/core/drawer-router-state.js +0 -41
- package/build-ngc/core/drawer-router-state.js.map +0 -1
- package/build-ngc/core/href.d.ts +0 -16
- package/build-ngc/core/href.js +0 -55
- package/build-ngc/core/href.js.map +0 -1
- package/build-ngc/core/linking-config.d.ts +0 -13
- package/build-ngc/core/linking-config.js +0 -172
- package/build-ngc/core/linking-config.js.map +0 -1
- package/build-ngc/core/navigation-events.d.ts +0 -16
- package/build-ngc/core/navigation-events.js +0 -58
- package/build-ngc/core/navigation-events.js.map +0 -1
- package/build-ngc/core/navigator-handles.d.ts +0 -30
- package/build-ngc/core/navigator-handles.js +0 -16
- package/build-ngc/core/navigator-handles.js.map +0 -1
- package/build-ngc/core/navigator-state.d.ts +0 -36
- package/build-ngc/core/navigator-state.js +0 -82
- package/build-ngc/core/navigator-state.js.map +0 -1
- package/build-ngc/core/search-params.d.ts +0 -9
- package/build-ngc/core/search-params.js +0 -60
- package/build-ngc/core/search-params.js.map +0 -1
- package/build-ngc/core/state-persistence.d.ts +0 -3
- package/build-ngc/core/state-persistence.js +0 -24
- package/build-ngc/core/state-persistence.js.map +0 -1
- package/build-ngc/core/tab-router-state.d.ts +0 -19
- package/build-ngc/core/tab-router-state.js +0 -52
- package/build-ngc/core/tab-router-state.js.map +0 -1
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// useNavigation() returns a union (IAnyNavigatorHandle) since it doesn't know which navigator
|
|
2
|
-
// mounted the calling component. When a component genuinely knows it only ever renders under a
|
|
3
|
-
// Stack, this composable narrows that union ONCE, here, so call sites never write their own
|
|
4
|
-
// 'push' in navigation check. Vue twin of react/hooks/use-stack-navigation.ts.
|
|
5
|
-
import { computed } from '@vue/runtime-core';
|
|
6
|
-
import { isStackNavigatorHandle } from '../../core/index.js';
|
|
7
|
-
import { useNavigation } from './use-navigation.js';
|
|
8
|
-
export function useStackNavigation() {
|
|
9
|
-
const navigation = useNavigation();
|
|
10
|
-
return computed(() => {
|
|
11
|
-
const value = navigation.value;
|
|
12
|
-
if (!isStackNavigatorHandle(value)) {
|
|
13
|
-
throw new Error('useStackNavigation() was called from a component whose nearest navigator is not a Stack. ' +
|
|
14
|
-
'Use useNavigation() instead if this component can render under more than one navigator kind.');
|
|
15
|
-
}
|
|
16
|
-
return value;
|
|
17
|
-
});
|
|
18
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ComputedRef } from '@vue/runtime-core';
|
|
2
|
-
import type { ITabNavigatorHandle } from '../../core';
|
|
3
|
-
import type { INavigationHandle } from './use-navigation';
|
|
4
|
-
export type ITabNavigationHandle = ITabNavigatorHandle & Pick<INavigationHandle, 'addListener' | 'getParent'>;
|
|
5
|
-
export declare function useTabNavigation(): ComputedRef<ITabNavigationHandle>;
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// Twin of use-stack-navigation.ts, narrowing to a Tab handle instead.
|
|
2
|
-
import { computed } from '@vue/runtime-core';
|
|
3
|
-
import { isTabNavigatorHandle } from '../../core/index.js';
|
|
4
|
-
import { useNavigation } from './use-navigation.js';
|
|
5
|
-
export function useTabNavigation() {
|
|
6
|
-
const navigation = useNavigation();
|
|
7
|
-
return computed(() => {
|
|
8
|
-
const value = navigation.value;
|
|
9
|
-
if (!isTabNavigatorHandle(value)) {
|
|
10
|
-
throw new Error('useTabNavigation() was called from a component whose nearest navigator is not a Tab. ' +
|
|
11
|
-
'Use useNavigation() instead if this component can render under more than one navigator kind.');
|
|
12
|
-
}
|
|
13
|
-
return value;
|
|
14
|
-
});
|
|
15
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { IStyleProp, IViewStyle } from '@symbiote-native/engine';
|
|
2
|
-
import type { IDrawerDescriptorMap, IDrawerNavigatorHandle, IDrawerOptions, IDrawerRouterState } from '../../core';
|
|
3
|
-
import type { IDrawerScreenProps } from '../drawer-screen';
|
|
4
|
-
export type { IDrawerNavigatorHandle, IDrawerDescriptorMap } from '../../core';
|
|
5
|
-
export type IDrawerContentSlotProps = {
|
|
6
|
-
state: IDrawerRouterState;
|
|
7
|
-
descriptors: IDrawerDescriptorMap;
|
|
8
|
-
navigation: IDrawerNavigatorHandle;
|
|
9
|
-
};
|
|
10
|
-
export type IDrawerProps = IDrawerOptions & {
|
|
11
|
-
initialRouteName?: string;
|
|
12
|
-
drawerStyle?: IStyleProp<IViewStyle>;
|
|
13
|
-
};
|
|
14
|
-
export declare const Drawer: import("vue").DefineSetupFnComponent<IDrawerProps, {}, {}, IDrawerOptions & {
|
|
15
|
-
initialRouteName?: string;
|
|
16
|
-
drawerStyle?: IStyleProp<IViewStyle>;
|
|
17
|
-
} & {}, import("vue").PublicProps> & {
|
|
18
|
-
Screen: import("vue").DefineSetupFnComponent<IDrawerScreenProps, {}, {}, IDrawerScreenProps & {}, import("vue").PublicProps>;
|
|
19
|
-
};
|
|
@@ -1,390 +0,0 @@
|
|
|
1
|
-
// Drawer, the Vue lifecycle half. The open/closed + focused-route router (drawer-router-state)
|
|
2
|
-
// and the pure swipe/geometry math (drawer-options) live in @symbiote-native/navigation core,
|
|
3
|
-
// shared verbatim with the React/Angular adapters; here Vue supplies the lifecycle - a plain ref
|
|
4
|
-
// for the router (Vue's twin of useReducer), a PanResponder for the swipe gesture (built ONCE in
|
|
5
|
-
// setup, its callbacks reading options/window-width/isOpen LIVE off Vue's own reactive `attrs` /
|
|
6
|
-
// composable refs at gesture time - Vue's reactivity already gives every gesture callback the
|
|
7
|
-
// CURRENT value with no ref-mirroring dance, unlike React's useRef(value); value = X every
|
|
8
|
-
// render), an Animated.Value driving the slide/opacity transforms, and expose() for the
|
|
9
|
-
// open/close/toggle/jumpTo handle - mirroring tabs.ts's shape (Tab is the closer sibling: both are
|
|
10
|
-
// fixed-route-list, no-react-native-screens navigators; Stack's push/pop + native-screen bridging
|
|
11
|
-
// don't apply here).
|
|
12
|
-
//
|
|
13
|
-
// FEASIBILITY NOTE (see the drawer skill / PR description for the full writeup, mirrored from
|
|
14
|
-
// react/drawer.ts): the REAL @react-navigation/drawer is built on react-native-gesture-handler +
|
|
15
|
-
// react-native-reanimated, neither of which this codebase depends on. What's built here reaches
|
|
16
|
-
// the same swipe-to-open/close + front/back/slide/permanent behavior using only PanResponder +
|
|
17
|
-
// Animated (both already in @symbiote-native/engine), which is sufficient for a solid drawer but
|
|
18
|
-
// NOT byte-for-byte parity - see the explicit gap list at the bottom of this file (verbatim from
|
|
19
|
-
// the React twin - the gaps are architectural, not adapter-specific).
|
|
20
|
-
import { defineComponent, h, nextTick, onMounted, onUnmounted, shallowRef, useId, watch, } from '@vue/runtime-core';
|
|
21
|
-
import { Animated, PanResponder, normalizeVueAttrs, useWindowDimensions, } from '@symbiote-native/vue';
|
|
22
|
-
import { dlog } from '@symbiote-native/engine';
|
|
23
|
-
import { DRAWER_DEFAULT_OVERLAY_COLOR, NAVIGATION_EVENT_BLUR, NAVIGATION_EVENT_FOCUS, createInitialDrawerRouterState, createNavigationEmitter, diffFocusedRoute, drawerChildOrder, drawerRouterReducer, isDrawerAnimated, isRecord, renderDrawer, resolveDragProgress, resolveDrawerGeometry, resolveDrawerSlotInterpolation, resolveSwipeIntent, shouldClaimDrawerSwipe, } from '../../core/index.js';
|
|
24
|
-
import { NavigationScope, injectNavigationScope } from '../navigation-context.js';
|
|
25
|
-
import { DrawerScreen } from '../drawer-screen.js';
|
|
26
|
-
function asString(value) {
|
|
27
|
-
return typeof value === 'string' ? value : undefined;
|
|
28
|
-
}
|
|
29
|
-
function asNumber(value) {
|
|
30
|
-
return typeof value === 'number' ? value : undefined;
|
|
31
|
-
}
|
|
32
|
-
function asBoolean(value) {
|
|
33
|
-
return typeof value === 'boolean' ? value : undefined;
|
|
34
|
-
}
|
|
35
|
-
function isStyleProp(value) {
|
|
36
|
-
return isRecord(value);
|
|
37
|
-
}
|
|
38
|
-
const DRAWER_TYPES = ['front', 'back', 'slide', 'permanent'];
|
|
39
|
-
// .some() itself doesn't narrow `value`'s type back at the call site - the `value is IDrawerType`
|
|
40
|
-
// predicate on THIS function is what lets asDrawerType's ternary return `value` typed, mirroring
|
|
41
|
-
// Modal's isOrientation guard (adapters/vue/src/components/modal.ts).
|
|
42
|
-
function isDrawerType(value) {
|
|
43
|
-
return typeof value === 'string' && DRAWER_TYPES.some(type => type === value);
|
|
44
|
-
}
|
|
45
|
-
function asDrawerType(value) {
|
|
46
|
-
return isDrawerType(value) ? value : undefined;
|
|
47
|
-
}
|
|
48
|
-
const DRAWER_POSITIONS = ['left', 'right'];
|
|
49
|
-
function isDrawerPosition(value) {
|
|
50
|
-
return typeof value === 'string' && DRAWER_POSITIONS.some(position => position === value);
|
|
51
|
-
}
|
|
52
|
-
function asDrawerPosition(value) {
|
|
53
|
-
return isDrawerPosition(value) ? value : undefined;
|
|
54
|
-
}
|
|
55
|
-
function asComponent(value) {
|
|
56
|
-
if (typeof value === 'function')
|
|
57
|
-
return value;
|
|
58
|
-
return isRecord(value) ? value : undefined;
|
|
59
|
-
}
|
|
60
|
-
// IDrawerScreenOptions carries only `title`/`drawerLabel`, small enough for direct field guards -
|
|
61
|
-
// kept as a single cast-at-the-edge helper anyway for symmetry with stack.ts/tabs.ts's
|
|
62
|
-
// asScreenOptions/asTabOptions (same CLAUDE.md-sanctioned I/O-edge narrowing).
|
|
63
|
-
function asDrawerScreenOptions(value) {
|
|
64
|
-
return isRecord(value) ? value : undefined;
|
|
65
|
-
}
|
|
66
|
-
function asDrawerScreenOptionsOrResolver(value) {
|
|
67
|
-
if (typeof value === 'function')
|
|
68
|
-
return value;
|
|
69
|
-
return asDrawerScreenOptions(value);
|
|
70
|
-
}
|
|
71
|
-
function collectRegistry(vnodes) {
|
|
72
|
-
const registry = new Map();
|
|
73
|
-
for (const vnode of vnodes) {
|
|
74
|
-
if (vnode.type !== DrawerScreen || !isRecord(vnode.props))
|
|
75
|
-
continue;
|
|
76
|
-
const name = asString(vnode.props.name);
|
|
77
|
-
const component = asComponent(vnode.props.component);
|
|
78
|
-
if (name === undefined || component === undefined)
|
|
79
|
-
continue;
|
|
80
|
-
registry.set(name, {
|
|
81
|
-
component,
|
|
82
|
-
options: asDrawerScreenOptionsOrResolver(vnode.props.options),
|
|
83
|
-
initialParams: vnode.props.initialParams,
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
return registry;
|
|
87
|
-
}
|
|
88
|
-
function resolveDrawerScreenOptions(entry, screenComponentProps) {
|
|
89
|
-
if (typeof entry.options === 'function')
|
|
90
|
-
return entry.options(screenComponentProps);
|
|
91
|
-
return entry.options ?? {};
|
|
92
|
-
}
|
|
93
|
-
const DRAWER_SNAP_DURATION = 250;
|
|
94
|
-
const DrawerImpl = defineComponent((_props, { attrs: rawAttrs, slots, expose }) => {
|
|
95
|
-
const attrs = normalizeVueAttrs(rawAttrs);
|
|
96
|
-
// Read BEFORE this Drawer establishes its own per-screen NavigationScope below - becomes the
|
|
97
|
-
// `parent` link a nested screen's useNavigation().getParent() walks. undefined when this
|
|
98
|
-
// Drawer is the nesting root.
|
|
99
|
-
const ambientScopeRef = injectNavigationScope();
|
|
100
|
-
function currentOptions() {
|
|
101
|
-
return {
|
|
102
|
-
drawerType: asDrawerType(attrs.drawerType),
|
|
103
|
-
drawerPosition: asDrawerPosition(attrs.drawerPosition),
|
|
104
|
-
drawerWidth: asNumber(attrs.drawerWidth),
|
|
105
|
-
overlayColor: asString(attrs.overlayColor),
|
|
106
|
-
swipeEnabled: asBoolean(attrs.swipeEnabled),
|
|
107
|
-
swipeEdgeWidth: asNumber(attrs.swipeEdgeWidth),
|
|
108
|
-
swipeMinDistance: asNumber(attrs.swipeMinDistance),
|
|
109
|
-
swipeMinVelocity: asNumber(attrs.swipeMinVelocity),
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
let routeSequence = 0;
|
|
113
|
-
const routeIdPrefix = useId();
|
|
114
|
-
function buildRoutes(registry) {
|
|
115
|
-
return Array.from(registry.entries()).map(([name, entry]) => {
|
|
116
|
-
routeSequence += 1;
|
|
117
|
-
return {
|
|
118
|
-
key: `${routeIdPrefix}-${name}-${routeSequence}`,
|
|
119
|
-
name,
|
|
120
|
-
params: entry.initialParams,
|
|
121
|
-
};
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
const initialRegistry = collectRegistry(slots.default?.() ?? []);
|
|
125
|
-
const initialRoutes = buildRoutes(initialRegistry);
|
|
126
|
-
if (initialRoutes.length === 0)
|
|
127
|
-
dlog('Drawer: no <Drawer.Screen> children registered');
|
|
128
|
-
const state = shallowRef(createInitialDrawerRouterState(initialRoutes, asString(attrs.initialRouteName)));
|
|
129
|
-
function dispatch(action) {
|
|
130
|
-
state.value = drawerRouterReducer(state.value, action);
|
|
131
|
-
}
|
|
132
|
-
const windowDimensions = useWindowDimensions();
|
|
133
|
-
// progress: 0 closed -> 1 open, the single Animated.Value every slide/opacity transform below
|
|
134
|
-
// interpolates from. A plain `const` (not a ref): setup() runs once, so this needs no
|
|
135
|
-
// re-creation guard the way React's useRef(new Animated.Value(...)).current does.
|
|
136
|
-
const progress = new Animated.Value(state.value.isOpen ? 1 : 0);
|
|
137
|
-
// Where a drag STARTS from, in progress units. Always exactly 0 or 1: a gesture only ever
|
|
138
|
-
// begins at rest, since terminate/release always snap the value back to a resting state
|
|
139
|
-
// before another grant can fire.
|
|
140
|
-
let dragStartProgress = 0;
|
|
141
|
-
function animateProgressTo(open) {
|
|
142
|
-
dlog(`Drawer: animateProgressTo(open=${open}) starting at t=${Date.now()}`);
|
|
143
|
-
Animated.timing(progress, {
|
|
144
|
-
toValue: open ? 1 : 0,
|
|
145
|
-
duration: DRAWER_SNAP_DURATION,
|
|
146
|
-
// Native-driver wiring is deferred for v1 - see this file's header feasibility note. The
|
|
147
|
-
// JS timing loop still drives every frame, same as any other non-native-driven
|
|
148
|
-
// Animated.timing in this codebase.
|
|
149
|
-
useNativeDriver: false,
|
|
150
|
-
}).start();
|
|
151
|
-
}
|
|
152
|
-
const handle = {
|
|
153
|
-
openDrawer: () => {
|
|
154
|
-
dlog(`Drawer: openDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
|
|
155
|
-
animateProgressTo(true);
|
|
156
|
-
dispatch({ type: 'openDrawer' });
|
|
157
|
-
},
|
|
158
|
-
closeDrawer: () => {
|
|
159
|
-
dlog(`Drawer: closeDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
|
|
160
|
-
animateProgressTo(false);
|
|
161
|
-
dispatch({ type: 'closeDrawer' });
|
|
162
|
-
},
|
|
163
|
-
toggleDrawer: () => {
|
|
164
|
-
dlog(`Drawer: toggleDrawer() called, isOpen=${state.value.isOpen} at t=${Date.now()}`);
|
|
165
|
-
animateProgressTo(!state.value.isOpen);
|
|
166
|
-
dispatch({ type: 'toggleDrawer' });
|
|
167
|
-
},
|
|
168
|
-
jumpTo: (name) => {
|
|
169
|
-
// Captured BEFORE dispatch: unlike React's isOpenRef (only refreshed at the TOP of the
|
|
170
|
-
// next render, so it still holds the pre-dispatch value here since React batches the
|
|
171
|
-
// re-render asynchronously), this ref's `.value` mutates SYNCHRONOUSLY inside dispatch -
|
|
172
|
-
// reading it after dispatch would already see the reducer's own isOpen: false.
|
|
173
|
-
const wasOpen = state.value.isOpen;
|
|
174
|
-
dispatch({ type: 'jumpTo', name });
|
|
175
|
-
if (wasOpen)
|
|
176
|
-
animateProgressTo(false);
|
|
177
|
-
},
|
|
178
|
-
};
|
|
179
|
-
expose(handle);
|
|
180
|
-
const panResponder = PanResponder.create({
|
|
181
|
-
onStartShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, windowDimensions.value.width, state.value.isOpen, currentOptions(), 'start'),
|
|
182
|
-
onMoveShouldSetPanResponder: (event, gestureState) => shouldClaimDrawerSwipe(event, gestureState, windowDimensions.value.width, state.value.isOpen, currentOptions(), 'move'),
|
|
183
|
-
onPanResponderGrant: () => {
|
|
184
|
-
dlog('Drawer: gesture grant');
|
|
185
|
-
dragStartProgress = state.value.isOpen ? 1 : 0;
|
|
186
|
-
},
|
|
187
|
-
onPanResponderMove: (_event, gestureState) => {
|
|
188
|
-
progress.setValue(resolveDragProgress(gestureState, dragStartProgress, currentOptions()));
|
|
189
|
-
},
|
|
190
|
-
onPanResponderRelease: (_event, gestureState) => {
|
|
191
|
-
const intent = resolveSwipeIntent(gestureState, state.value.isOpen, currentOptions());
|
|
192
|
-
const open = intent === 'open';
|
|
193
|
-
dlog(`Drawer: gesture release -> ${open ? 'open' : 'close'}`);
|
|
194
|
-
animateProgressTo(open);
|
|
195
|
-
dispatch(open ? { type: 'openDrawer' } : { type: 'closeDrawer' });
|
|
196
|
-
},
|
|
197
|
-
onPanResponderTerminate: () => {
|
|
198
|
-
dlog('Drawer: gesture terminated, snapping back');
|
|
199
|
-
animateProgressTo(state.value.isOpen);
|
|
200
|
-
},
|
|
201
|
-
});
|
|
202
|
-
// Only the focused route's screen is ever mounted (like Tab, unlike Stack which keeps every
|
|
203
|
-
// pushed route alive). One emitter per route.key, created lazily and cached for the
|
|
204
|
-
// navigator's whole lifetime (mirrors stack.ts's own `emitters` map) - see tabs.ts's matching
|
|
205
|
-
// comment for why a stable per-key lookup, not a recreate-on-change scheme, is what actually
|
|
206
|
-
// avoids racing Vue's own render/mount cycle regardless of which watch `flush` timing is used.
|
|
207
|
-
function focusedKeyOf(current) {
|
|
208
|
-
return current.routes[current.index]?.key;
|
|
209
|
-
}
|
|
210
|
-
const emitters = new Map();
|
|
211
|
-
function emitterFor(routeKey) {
|
|
212
|
-
let emitter = emitters.get(routeKey);
|
|
213
|
-
if (emitter === undefined) {
|
|
214
|
-
emitter = createNavigationEmitter();
|
|
215
|
-
emitters.set(routeKey, emitter);
|
|
216
|
-
}
|
|
217
|
-
return emitter;
|
|
218
|
-
}
|
|
219
|
-
// Emitted from onMounted (NOT from inside the render closure below, which runs before the
|
|
220
|
-
// focused screen's own component ever mounts - an emit there always has zero subscribers).
|
|
221
|
-
let focusedRouteKey = focusedKeyOf(state.value);
|
|
222
|
-
onMounted(() => {
|
|
223
|
-
if (focusedRouteKey !== undefined) {
|
|
224
|
-
dlog(`Drawer: route "${focusedRouteKey}" focused at t=${Date.now()}`);
|
|
225
|
-
emitterFor(focusedRouteKey).emit(NAVIGATION_EVENT_FOCUS);
|
|
226
|
-
}
|
|
227
|
-
});
|
|
228
|
-
// The bookkeeping (which key is focused) updates immediately so the render closure below
|
|
229
|
-
// always reads the right route; the actual emit is deferred to nextTick(), which resolves
|
|
230
|
-
// only after the CURRENT flush cycle fully drains - including the newly-focused screen's own
|
|
231
|
-
// onMounted (subscribing its useIsFocused/useFocusEffect listeners). flush:'post' alone is
|
|
232
|
-
// NOT enough here: it only guarantees this callback runs after THIS component's own render
|
|
233
|
-
// effect, not after an arbitrary sibling post-flush job (a just-mounted child's onMounted)
|
|
234
|
-
// that may be queued after it in the same batch - nextTick is the one API that waits for the
|
|
235
|
-
// WHOLE cycle, not just this watcher's own slot in it.
|
|
236
|
-
watch(() => focusedKeyOf(state.value), nextKey => {
|
|
237
|
-
const { blurKey, focusKey } = diffFocusedRoute(focusedRouteKey, nextKey);
|
|
238
|
-
if (blurKey === undefined && focusKey === undefined)
|
|
239
|
-
return;
|
|
240
|
-
focusedRouteKey = nextKey;
|
|
241
|
-
nextTick(() => {
|
|
242
|
-
if (blurKey !== undefined) {
|
|
243
|
-
dlog(`Drawer: route "${blurKey}" blurred at t=${Date.now()}`);
|
|
244
|
-
emitterFor(blurKey).emit(NAVIGATION_EVENT_BLUR);
|
|
245
|
-
}
|
|
246
|
-
if (focusKey !== undefined) {
|
|
247
|
-
dlog(`Drawer: route "${focusKey}" focused at t=${Date.now()}`);
|
|
248
|
-
emitterFor(focusKey).emit(NAVIGATION_EVENT_FOCUS);
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
});
|
|
252
|
-
onUnmounted(() => {
|
|
253
|
-
if (focusedRouteKey !== undefined)
|
|
254
|
-
emitterFor(focusedRouteKey).emit(NAVIGATION_EVENT_BLUR);
|
|
255
|
-
});
|
|
256
|
-
return () => {
|
|
257
|
-
const registry = collectRegistry(slots.default?.() ?? []);
|
|
258
|
-
const options = currentOptions();
|
|
259
|
-
const drawerStyle = isStyleProp(attrs.drawerStyle) ? attrs.drawerStyle : undefined;
|
|
260
|
-
if (registry.size === 0)
|
|
261
|
-
dlog('Drawer: no <Drawer.Screen> children registered');
|
|
262
|
-
const animated = isDrawerAnimated(options);
|
|
263
|
-
const geometry = resolveDrawerGeometry(options);
|
|
264
|
-
const panelTranslateX = animated
|
|
265
|
-
? progress.interpolate(resolveDrawerSlotInterpolation(geometry, 'panel').translateX)
|
|
266
|
-
: undefined;
|
|
267
|
-
const contentTranslateX = animated
|
|
268
|
-
? progress.interpolate(resolveDrawerSlotInterpolation(geometry, 'content').translateX)
|
|
269
|
-
: undefined;
|
|
270
|
-
// The overlay is a full-screen absolutely-positioned sibling BELOW content in paint order
|
|
271
|
-
// (see render-drawer.ts's drawerChildOrder) - for 'front' that's fine since content never
|
|
272
|
-
// moves, but for 'slide' content itself translates away by contentTranslateX, and without
|
|
273
|
-
// following it the overlay stays pinned full-screen. resolveDrawerSlotInterpolation's
|
|
274
|
-
// 'overlay' branch ties its translateX to the SAME range as content's for exactly this
|
|
275
|
-
// reason, so overlayOpacity and overlayTranslateX below share one resolved config.
|
|
276
|
-
const overlayInterpolation = animated
|
|
277
|
-
? resolveDrawerSlotInterpolation(geometry, 'overlay')
|
|
278
|
-
: undefined;
|
|
279
|
-
const overlayOpacity = overlayInterpolation
|
|
280
|
-
? progress.interpolate(overlayInterpolation.opacity)
|
|
281
|
-
: undefined;
|
|
282
|
-
const overlayTranslateX = overlayInterpolation
|
|
283
|
-
? progress.interpolate(overlayInterpolation.translateX)
|
|
284
|
-
: undefined;
|
|
285
|
-
const focusedRoute = state.value.routes[state.value.index];
|
|
286
|
-
const focusedEntry = focusedRoute ? registry.get(focusedRoute.name) : undefined;
|
|
287
|
-
if (focusedRoute && !focusedEntry) {
|
|
288
|
-
dlog(`Drawer: no screen registered for route name "${focusedRoute.name}"`);
|
|
289
|
-
}
|
|
290
|
-
const content = focusedEntry && focusedRoute
|
|
291
|
-
? h(NavigationScope, {
|
|
292
|
-
value: {
|
|
293
|
-
route: focusedRoute,
|
|
294
|
-
navigation: handle,
|
|
295
|
-
emitter: emitterFor(focusedRoute.key),
|
|
296
|
-
parent: ambientScopeRef?.value,
|
|
297
|
-
},
|
|
298
|
-
},
|
|
299
|
-
// No route/navigation props: the screen reads both through composables off the
|
|
300
|
-
// NavigationScope provided just above (useRoute / useDrawerNavigation).
|
|
301
|
-
() => h(focusedEntry.component))
|
|
302
|
-
: null;
|
|
303
|
-
const descriptors = {};
|
|
304
|
-
for (const route of state.value.routes) {
|
|
305
|
-
const entry = registry.get(route.name);
|
|
306
|
-
if (entry === undefined)
|
|
307
|
-
continue;
|
|
308
|
-
descriptors[route.key] = {
|
|
309
|
-
options: resolveDrawerScreenOptions(entry, { route, navigation: handle }),
|
|
310
|
-
navigation: handle,
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
const drawerContent = slots.drawerContent?.({ state: state.value, descriptors, navigation: handle }) ?? null;
|
|
314
|
-
const root = renderDrawer({
|
|
315
|
-
overlayColor: asString(attrs.overlayColor) ?? DRAWER_DEFAULT_OVERLAY_COLOR,
|
|
316
|
-
drawerStyle,
|
|
317
|
-
contentPassthrough: {},
|
|
318
|
-
overlayPassthrough: animated
|
|
319
|
-
? {
|
|
320
|
-
pointerEvents: state.value.isOpen ? 'auto' : 'none',
|
|
321
|
-
onStartShouldSetResponder: () => true,
|
|
322
|
-
onResponderRelease: () => {
|
|
323
|
-
animateProgressTo(false);
|
|
324
|
-
dispatch({ type: 'closeDrawer' });
|
|
325
|
-
},
|
|
326
|
-
}
|
|
327
|
-
: {},
|
|
328
|
-
panelPassthrough: {},
|
|
329
|
-
}, options);
|
|
330
|
-
const order = drawerChildOrder(options);
|
|
331
|
-
const slotDescriptors = new Map();
|
|
332
|
-
order.forEach((slot, index) => {
|
|
333
|
-
const descriptor = root.children[index];
|
|
334
|
-
if (typeof descriptor !== 'string')
|
|
335
|
-
slotDescriptors.set(slot, descriptor);
|
|
336
|
-
});
|
|
337
|
-
const slotChildren = {
|
|
338
|
-
content: content === null ? [] : [content],
|
|
339
|
-
overlay: null,
|
|
340
|
-
panel: drawerContent,
|
|
341
|
-
};
|
|
342
|
-
// Each animated style holds an AnimatedInterpolation node, not a plain number/color - it
|
|
343
|
-
// feeds only Animated.View's deliberately permissive `style?: unknown`, never the plain-
|
|
344
|
-
// IViewStyle branch below, so this stays untyped rather than widening IViewStyle.
|
|
345
|
-
const slotAnimatedStyle = {
|
|
346
|
-
content: contentTranslateX === undefined
|
|
347
|
-
? undefined
|
|
348
|
-
: { transform: [{ translateX: contentTranslateX }] },
|
|
349
|
-
overlay: overlayOpacity === undefined
|
|
350
|
-
? undefined
|
|
351
|
-
: { opacity: overlayOpacity, transform: [{ translateX: overlayTranslateX }] },
|
|
352
|
-
panel: panelTranslateX === undefined
|
|
353
|
-
? undefined
|
|
354
|
-
: { transform: [{ translateX: panelTranslateX }] },
|
|
355
|
-
};
|
|
356
|
-
function renderSlot(slot) {
|
|
357
|
-
const descriptor = slotDescriptors.get(slot);
|
|
358
|
-
if (descriptor === undefined)
|
|
359
|
-
return null;
|
|
360
|
-
const children = slotChildren[slot] ?? [];
|
|
361
|
-
const animatedStyle = slotAnimatedStyle[slot];
|
|
362
|
-
if (animatedStyle === undefined) {
|
|
363
|
-
return h(descriptor.type, { key: descriptor.key, ...descriptor.props }, children);
|
|
364
|
-
}
|
|
365
|
-
const style = [descriptor.props.style, animatedStyle];
|
|
366
|
-
return h(Animated.View, { key: descriptor.key, ...descriptor.props, style }, children);
|
|
367
|
-
}
|
|
368
|
-
const drawerChildren = order
|
|
369
|
-
.map(renderSlot)
|
|
370
|
-
.filter((element) => element !== null);
|
|
371
|
-
return h('symbiote-view', { style: root.props.style, ...panResponder.panHandlers }, drawerChildren);
|
|
372
|
-
};
|
|
373
|
-
}, { name: 'Drawer', inheritAttrs: false });
|
|
374
|
-
export const Drawer = Object.assign(DrawerImpl, { Screen: DrawerScreen });
|
|
375
|
-
// --- Explicit gap list vs the real react-native-gesture-handler + react-native-reanimated
|
|
376
|
-
// @react-navigation/drawer (confirmed against its current docs, mirrored verbatim from the React
|
|
377
|
-
// twin - the gaps are architectural, not adapter-specific) ---
|
|
378
|
-
// 1. `configureGestureHandler` - a raw react-native-gesture-handler `Gesture` object escape
|
|
379
|
-
// hatch. No PanResponder equivalent exists; not ported.
|
|
380
|
-
// 2. Simultaneous/failure gesture RELATIONSHIPS (gesture-handler's declarative composition vs a
|
|
381
|
-
// nested ScrollView, another PanResponder, etc.) - PanResponder only offers negotiation via the
|
|
382
|
-
// should-set boolean gates used here (edge-start + dominant-axis), which is more prone to an
|
|
383
|
-
// accidental hijack of a nested horizontal ScrollView/Swiper than gesture-handler's system.
|
|
384
|
-
// 3. `useDrawerProgress` - a Reanimated SharedValue read on the UI thread. `progress` here is a
|
|
385
|
-
// JS-thread AnimatedValue; interpolating it for consumer-facing content animation works, but
|
|
386
|
-
// without native-driver wiring (gap noted above) it does not carry the same synchronous
|
|
387
|
-
// UI-thread guarantee under JS-thread load.
|
|
388
|
-
// 4. `hideStatusBarOnOpen` / `keyboardDismissMode` / `statusBarAnimation` / `overlayStyle` - not
|
|
389
|
-
// wired in this pass; straightforward additions once StatusBar/Keyboard module wiring is
|
|
390
|
-
// needed here (not a PanResponder/Animated limitation, just unscoped for v1).
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { Component } from '@vue/runtime-core';
|
|
2
|
-
import type { IDrawerScreenOptions, IRoute, IDrawerNavigatorHandle } from '../core';
|
|
3
|
-
export type IDrawerScreenOptionsArgs = {
|
|
4
|
-
route: IRoute<unknown>;
|
|
5
|
-
navigation: IDrawerNavigatorHandle;
|
|
6
|
-
};
|
|
7
|
-
export type IDrawerScreenOptionsResolver = (props: IDrawerScreenOptionsArgs) => IDrawerScreenOptions;
|
|
8
|
-
export type IDrawerScreenProps = {
|
|
9
|
-
name: string;
|
|
10
|
-
component: Component;
|
|
11
|
-
options?: IDrawerScreenOptions | IDrawerScreenOptionsResolver;
|
|
12
|
-
initialParams?: unknown;
|
|
13
|
-
};
|
|
14
|
-
export declare const DrawerScreen: import("vue").DefineSetupFnComponent<IDrawerScreenProps, {}, {}, IDrawerScreenProps & {}, import("vue").PublicProps>;
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
// Drawer.Screen: a declarative marker, never rendered on its own - Drawer reads its props via a
|
|
2
|
-
// default-slot scan (see drawer.ts's collectRegistry) to build the static name -> {component,
|
|
3
|
-
// options} registry, then mounts the FOCUSED route's component. The Vue twin of
|
|
4
|
-
// react/drawer-screen.ts's DrawerScreen, mirroring tab-screen.ts's slot-scanning marker (Tab is
|
|
5
|
-
// the closer sibling - both are fixed-route-list/no-push navigators) and screen.ts's; see
|
|
6
|
-
// CLAUDE.md <third_party_rn_packages_are_react_only> - this and Drawer import nothing from
|
|
7
|
-
// react-native.
|
|
8
|
-
import { defineComponent } from '@vue/runtime-core';
|
|
9
|
-
export const DrawerScreen = defineComponent(() => () => null, {
|
|
10
|
-
name: 'DrawerScreen',
|
|
11
|
-
inheritAttrs: false,
|
|
12
|
-
});
|
package/build/vue/index.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import '../register';
|
|
2
|
-
export { Stack } from './stack';
|
|
3
|
-
export type { INavigatorHandle, IStackProps } from './stack';
|
|
4
|
-
export { Screen } from './screen';
|
|
5
|
-
export type { IScreenOptionsArgs, IScreenOptionsResolver, IScreenProps, IVueScreenOptions, IVueSearchBarOptions, } from './screen';
|
|
6
|
-
export type { IScreenOptions, IStackAnimation, IStackPresentation } from '../core';
|
|
7
|
-
export { useNavigation, useStackNavigation, useTabNavigation, useDrawerNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './composables';
|
|
8
|
-
export type { INavigationHandle, IStackNavigationHandle, ITabNavigationHandle, IDrawerNavigationHandle, } from './composables';
|
|
9
|
-
export type { INavigationScopeValue, IAnyNavigatorHandle } from './navigation-context';
|
|
10
|
-
export { useLinkingIntegration } from './linking';
|
|
11
|
-
export type { ILinkingConfig, IScreenLinkingConfig } from '../core';
|
|
12
|
-
export { Tab } from './tabs';
|
|
13
|
-
export type { ITabNavigatorHandle, ITabProps } from './tabs';
|
|
14
|
-
export { TabScreen } from './tab-screen';
|
|
15
|
-
export type { ITabScreenOptionsArgs, ITabScreenOptionsResolver, ITabScreenProps, } from './tab-screen';
|
|
16
|
-
export type { ITabOptions, ITabBarIcon } from '../core';
|
|
17
|
-
export { Drawer } from './drawer';
|
|
18
|
-
export type { IDrawerContentSlotProps, IDrawerNavigatorHandle, IDrawerProps, IDrawerDescriptorMap, } from './drawer';
|
|
19
|
-
export { DrawerScreen } from './drawer-screen';
|
|
20
|
-
export type { IDrawerScreenOptionsArgs, IDrawerScreenOptionsResolver, IDrawerScreenProps, } from './drawer-screen';
|
|
21
|
-
export type { IDrawerOptions, IDrawerScreenOptions, IDrawerType, IDrawerPosition } from '../core';
|
package/build/vue/index.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
// @symbiote-native/navigation/vue: the Vue native-stack navigator over react-native-screens'
|
|
2
|
-
// native view primitives. Importing this barrel first registers the native views' ViewConfigs
|
|
3
|
-
// (../register, a side-effect import of the three codegen specs - never react-native-screens' own
|
|
4
|
-
// React components), then exposes Stack (with Stack.Screen attached) and the navigator handle.
|
|
5
|
-
import '../register';
|
|
6
|
-
export { Stack } from './stack/index.js';
|
|
7
|
-
export { Screen } from './screen.js';
|
|
8
|
-
export { useNavigation, useStackNavigation, useTabNavigation, useDrawerNavigation, useRoute, useIsFocused, useFocusEffect, useNavigationState, } from './composables/index.js';
|
|
9
|
-
export { useLinkingIntegration } from './linking.js';
|
|
10
|
-
// Tab: the bottom-tabs navigator, a PURE-JS UI (no react-native-screens views involved, so no
|
|
11
|
-
// extra ViewConfig registration is needed beyond the ../register import above).
|
|
12
|
-
export { Tab } from './tabs/index.js';
|
|
13
|
-
export { TabScreen } from './tab-screen.js';
|
|
14
|
-
// Drawer: the swipeable drawer navigator, a PURE-JS UI (PanResponder + Animated, no
|
|
15
|
-
// react-native-screens views involved, so no extra ViewConfig registration is needed beyond the
|
|
16
|
-
// ../register import above). See drawer.ts's header for the feasibility note re:
|
|
17
|
-
// react-native-gesture-handler / react-native-reanimated parity gaps.
|
|
18
|
-
export { Drawer } from './drawer/index.js';
|
|
19
|
-
export { DrawerScreen } from './drawer-screen.js';
|
package/build/vue/linking.d.ts
DELETED
package/build/vue/linking.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
// useLinkingIntegration: wires the framework-agnostic linking config (../core's
|
|
2
|
-
// resolveRouteFromUrl) onto an existing Stack's INavigatorHandle. Deliberately NOT called from
|
|
3
|
-
// inside stack.ts - app code owns the wiring, the same top-level-prop shape @react-navigation
|
|
4
|
-
// keeps `linking` in on NavigationContainer rather than baking it into the router itself.
|
|
5
|
-
//
|
|
6
|
-
// Vue-shape difference from React: React's twin takes the RESOLVED `navigatorHandle:
|
|
7
|
-
// INavigatorHandle` directly, because a React hook is called fresh on EVERY render with the
|
|
8
|
-
// caller's current value, and useImperativeHandle's ref assignment (a layout effect) is
|
|
9
|
-
// guaranteed to run before this hook's OWN mount effect, so `handleRef.current` is already
|
|
10
|
-
// populated by the time it's read. Vue's setup() runs exactly ONCE per component instance, so
|
|
11
|
-
// there is no "fresh call every render" to re-supply a resolved value, and a template/h() `ref`
|
|
12
|
-
// only resolves to Stack's expose()d handle AFTER mount - an eagerly-resolved argument evaluated
|
|
13
|
-
// at composable-call time (during setup, before mount) would be null. This composable therefore
|
|
14
|
-
// takes the Stack's `Ref<INavigatorHandle | null>` itself (the ref object, not its resolved
|
|
15
|
-
// value) and reads `.value` lazily inside onMounted - Vue's own onMounted hooks fire bottom-up
|
|
16
|
-
// (children before parents), giving the same "already populated" guarantee React's layout-effect
|
|
17
|
-
// ordering does.
|
|
18
|
-
import { onMounted, onUnmounted } from '@vue/runtime-core';
|
|
19
|
-
import { Linking, dlog } from '@symbiote-native/engine';
|
|
20
|
-
import { resolveRouteFromUrl } from '../core/index.js';
|
|
21
|
-
export function useLinkingIntegration(config, navigatorHandle) {
|
|
22
|
-
let cancelled = false;
|
|
23
|
-
let subscription;
|
|
24
|
-
function applyRoute(url, dispatch) {
|
|
25
|
-
const route = resolveRouteFromUrl(config, url);
|
|
26
|
-
if (route === null) {
|
|
27
|
-
dlog(`useLinkingIntegration: no route resolved for "${url}"`);
|
|
28
|
-
return;
|
|
29
|
-
}
|
|
30
|
-
dispatch(route.name, route.params);
|
|
31
|
-
}
|
|
32
|
-
onMounted(() => {
|
|
33
|
-
const handle = navigatorHandle.value;
|
|
34
|
-
if (handle === null) {
|
|
35
|
-
dlog('useLinkingIntegration: navigatorHandle is not yet available at mount time');
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
Linking.getInitialURL()
|
|
39
|
-
.then(url => {
|
|
40
|
-
if (cancelled || url === null)
|
|
41
|
-
return;
|
|
42
|
-
dlog(`useLinkingIntegration: initial URL "${url}"`);
|
|
43
|
-
applyRoute(url, handle.replace);
|
|
44
|
-
})
|
|
45
|
-
.catch((error) => {
|
|
46
|
-
dlog(`useLinkingIntegration: getInitialURL failed: ${String(error)}`);
|
|
47
|
-
});
|
|
48
|
-
subscription = Linking.addEventListener('url', (event) => {
|
|
49
|
-
dlog(`useLinkingIntegration: url event "${event.url}"`);
|
|
50
|
-
applyRoute(event.url, handle.push);
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
onUnmounted(() => {
|
|
54
|
-
cancelled = true;
|
|
55
|
-
subscription?.remove();
|
|
56
|
-
});
|
|
57
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { ShallowRef } from '@vue/runtime-core';
|
|
2
|
-
import type { INavigationEmitter, IRoute, IAnyNavigatorHandle } from '../core';
|
|
3
|
-
export type { IAnyNavigatorHandle };
|
|
4
|
-
export type INavigationScopeValue = {
|
|
5
|
-
route: IRoute<unknown>;
|
|
6
|
-
navigation: IAnyNavigatorHandle;
|
|
7
|
-
emitter: INavigationEmitter;
|
|
8
|
-
parent?: INavigationScopeValue;
|
|
9
|
-
};
|
|
10
|
-
export declare function injectNavigationScope(): ShallowRef<INavigationScopeValue> | undefined;
|
|
11
|
-
export declare function requireNavigationScope(hookName: string): ShallowRef<INavigationScopeValue>;
|
|
12
|
-
export declare const NavigationScope: import("vue").DefineSetupFnComponent<{
|
|
13
|
-
value: INavigationScopeValue;
|
|
14
|
-
}, {}, {}, {
|
|
15
|
-
value: INavigationScopeValue;
|
|
16
|
-
} & {}, import("vue").PublicProps>;
|