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