UNPKG

3.27 kBJavaScriptView Raw
1import { getPathFromState, NavigationContainerRefContext, NavigationHelpersContext } from '@react-navigation/core';
2import * as React from 'react';
3import { Platform } from 'react-native';
4import LinkingContext from './LinkingContext';
5import useLinkTo from './useLinkTo';
6
7const getStateFromParams = params => {
8 if (params !== null && params !== void 0 && params.state) {
9 return params.state;
10 }
11
12 if (params !== null && params !== void 0 && params.screen) {
13 return {
14 routes: [{
15 name: params.screen,
16 params: params.params,
17 // @ts-expect-error
18 state: params.screen ? getStateFromParams(params.params) : undefined
19 }]
20 };
21 }
22
23 return undefined;
24};
25/**
26 * Hook to get props for an anchor tag so it can work with in page navigation.
27 *
28 * @param props.to Absolute path to screen (e.g. `/feeds/hot`).
29 * @param props.action Optional action to use for in-page navigation. By default, the path is parsed to an action based on linking config.
30 */
31
32
33export default function useLinkProps(_ref) {
34 var _options$getPathFromS;
35
36 let {
37 to,
38 action
39 } = _ref;
40 const root = React.useContext(NavigationContainerRefContext);
41 const navigation = React.useContext(NavigationHelpersContext);
42 const {
43 options
44 } = React.useContext(LinkingContext);
45 const linkTo = useLinkTo();
46
47 const onPress = e => {
48 var _e$currentTarget;
49
50 let shouldHandle = false;
51
52 if (Platform.OS !== 'web' || !e) {
53 shouldHandle = e ? !e.defaultPrevented : true;
54 } else if (!e.defaultPrevented && // onPress prevented default
55 // @ts-expect-error: these properties exist on web, but not in React Native
56 !(e.metaKey || e.altKey || e.ctrlKey || e.shiftKey) && ( // ignore clicks with modifier keys
57 // @ts-expect-error: these properties exist on web, but not in React Native
58 e.button == null || e.button === 0) && // ignore everything but left clicks
59 // @ts-expect-error: these properties exist on web, but not in React Native
60 [undefined, null, '', 'self'].includes((_e$currentTarget = e.currentTarget) === null || _e$currentTarget === void 0 ? void 0 : _e$currentTarget.target) // let browser handle "target=_blank" etc.
61 ) {
62 e.preventDefault();
63 shouldHandle = true;
64 }
65
66 if (shouldHandle) {
67 if (action) {
68 if (navigation) {
69 navigation.dispatch(action);
70 } else if (root) {
71 root.dispatch(action);
72 } else {
73 throw new Error("Couldn't find a navigation object. Is your component inside NavigationContainer?");
74 }
75 } else {
76 linkTo(to);
77 }
78 }
79 };
80
81 const getPathFromStateHelper = (_options$getPathFromS = options === null || options === void 0 ? void 0 : options.getPathFromState) !== null && _options$getPathFromS !== void 0 ? _options$getPathFromS : getPathFromState;
82 const href = typeof to === 'string' ? to : getPathFromStateHelper({
83 routes: [{
84 name: to.screen,
85 // @ts-expect-error
86 params: to.params,
87 // @ts-expect-error
88 state: getStateFromParams(to.params)
89 }]
90 }, options === null || options === void 0 ? void 0 : options.config);
91 return {
92 href,
93 accessibilityRole: 'link',
94 onPress
95 };
96}
97//# sourceMappingURL=useLinkProps.js.map
\No newline at end of file