UNPKG

1.97 kBTypeScriptView Raw
1import {
2 getPathFromState,
3 NavigationHelpers,
4 NavigationHelpersContext,
5 NavigationProp,
6 ParamListBase,
7} from '@react-navigation/core';
8import * as React from 'react';
9
10import LinkingContext from './LinkingContext';
11
12type NavigationObject =
13 | NavigationHelpers<ParamListBase>
14 | NavigationProp<ParamListBase>;
15
16type MinimalState = {
17 index: number;
18 routes: { name: string; params?: object; state?: MinimalState }[];
19};
20
21const getRootStateForNavigate = (
22 navigation: NavigationObject,
23 state: MinimalState
24): MinimalState => {
25 const parent = navigation.getParent();
26
27 if (parent) {
28 const parentState = parent.getState();
29
30 return getRootStateForNavigate(parent, {
31 index: 0,
32 routes: [
33 {
34 ...parentState.routes[parentState.index],
35 state: state,
36 },
37 ],
38 });
39 }
40
41 return state;
42};
43
44/**
45 * Build destination link for a navigate action.
46 * Useful for showing anchor tags on the web for buttons that perform navigation.
47 */
48export default function useLinkBuilder() {
49 const navigation = React.useContext(NavigationHelpersContext);
50 const linking = React.useContext(LinkingContext);
51
52 const buildLink = React.useCallback(
53 (name: string, params?: object) => {
54 const { options } = linking;
55
56 if (options?.enabled === false) {
57 return undefined;
58 }
59
60 const state = navigation
61 ? getRootStateForNavigate(navigation, {
62 index: 0,
63 routes: [{ name, params }],
64 })
65 : // If we couldn't find a navigation object in context, we're at root
66 // So we'll construct a basic state object to use
67 {
68 index: 0,
69 routes: [{ name, params }],
70 };
71
72 const path = options?.getPathFromState
73 ? options.getPathFromState(state, options?.config)
74 : getPathFromState(state, options?.config);
75
76 return path;
77 },
78 [linking, navigation]
79 );
80
81 return buildLink;
82}