expo-router 5.2.0-canary-20250613-b29d676-2 → 5.2.0-canary-20250701-6a945c5

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.
Files changed (130) hide show
  1. package/build/ExpoRoot.d.ts.map +1 -1
  2. package/build/ExpoRoot.js +13 -7
  3. package/build/ExpoRoot.js.map +1 -1
  4. package/build/exports.d.ts +2 -0
  5. package/build/exports.d.ts.map +1 -1
  6. package/build/exports.js +5 -1
  7. package/build/exports.js.map +1 -1
  8. package/build/fork/getStateFromPath-forks.d.ts.map +1 -1
  9. package/build/fork/getStateFromPath-forks.js +4 -1
  10. package/build/fork/getStateFromPath-forks.js.map +1 -1
  11. package/build/getRoutes.d.ts +1 -1
  12. package/build/getRoutes.d.ts.map +1 -1
  13. package/build/getRoutes.js +14 -6
  14. package/build/getRoutes.js.map +1 -1
  15. package/build/getRoutesCore.d.ts +7 -2
  16. package/build/getRoutesCore.d.ts.map +1 -1
  17. package/build/getRoutesCore.js +86 -58
  18. package/build/getRoutesCore.js.map +1 -1
  19. package/build/getRoutesRedirects.d.ts +2 -2
  20. package/build/getRoutesRedirects.d.ts.map +1 -1
  21. package/build/getRoutesRedirects.js +18 -24
  22. package/build/getRoutesRedirects.js.map +1 -1
  23. package/build/getRoutesSSR.d.ts +1 -1
  24. package/build/getRoutesSSR.d.ts.map +1 -1
  25. package/build/getRoutesSSR.js +2 -3
  26. package/build/getRoutesSSR.js.map +1 -1
  27. package/build/global-state/router-store.d.ts +52 -1
  28. package/build/global-state/router-store.d.ts.map +1 -1
  29. package/build/global-state/router-store.js +22 -1
  30. package/build/global-state/router-store.js.map +1 -1
  31. package/build/global-state/routing.d.ts +1 -0
  32. package/build/global-state/routing.d.ts.map +1 -1
  33. package/build/global-state/routing.js +3 -2
  34. package/build/global-state/routing.js.map +1 -1
  35. package/build/global-state/storeContext.d.ts +50 -0
  36. package/build/global-state/storeContext.d.ts.map +1 -1
  37. package/build/hooks.d.ts.map +1 -1
  38. package/build/hooks.js +33 -1
  39. package/build/hooks.js.map +1 -1
  40. package/build/layouts/StackClient.d.ts.map +1 -1
  41. package/build/layouts/StackClient.js +39 -2
  42. package/build/layouts/StackClient.js.map +1 -1
  43. package/build/link/BaseExpoRouterLink.d.ts +3 -0
  44. package/build/link/BaseExpoRouterLink.d.ts.map +1 -0
  45. package/build/link/BaseExpoRouterLink.js +63 -0
  46. package/build/link/BaseExpoRouterLink.js.map +1 -0
  47. package/build/link/ExpoLink.d.ts +3 -0
  48. package/build/link/ExpoLink.d.ts.map +1 -0
  49. package/build/link/ExpoLink.js +23 -0
  50. package/build/link/ExpoLink.js.map +1 -0
  51. package/build/link/Link.d.ts +63 -78
  52. package/build/link/Link.d.ts.map +1 -1
  53. package/build/link/Link.js +81 -99
  54. package/build/link/Link.js.map +1 -1
  55. package/build/link/LinkWithPreview.d.ts +36 -0
  56. package/build/link/LinkWithPreview.d.ts.map +1 -0
  57. package/build/link/LinkWithPreview.js +192 -0
  58. package/build/link/LinkWithPreview.js.map +1 -0
  59. package/build/link/Redirect.d.ts +58 -0
  60. package/build/link/Redirect.d.ts.map +1 -0
  61. package/build/link/Redirect.js +46 -0
  62. package/build/link/Redirect.js.map +1 -0
  63. package/build/link/preview/HrefPreview.d.ts +5 -0
  64. package/build/link/preview/HrefPreview.d.ts.map +1 -0
  65. package/build/link/preview/HrefPreview.js +99 -0
  66. package/build/link/preview/HrefPreview.js.map +1 -0
  67. package/build/link/preview/LinkPreviewContext.d.ts +7 -0
  68. package/build/link/preview/LinkPreviewContext.d.ts.map +1 -0
  69. package/build/link/preview/LinkPreviewContext.js +21 -0
  70. package/build/link/preview/LinkPreviewContext.js.map +1 -0
  71. package/build/link/preview/PreviewRouteContext.d.ts +22 -0
  72. package/build/link/preview/PreviewRouteContext.d.ts.map +1 -0
  73. package/build/link/preview/PreviewRouteContext.js +28 -0
  74. package/build/link/preview/PreviewRouteContext.js.map +1 -0
  75. package/build/link/preview/native.d.ts +31 -0
  76. package/build/link/preview/native.d.ts.map +1 -0
  77. package/build/link/preview/native.js +53 -0
  78. package/build/link/preview/native.js.map +1 -0
  79. package/build/link/preview/useNextScreenId.d.ts +3 -0
  80. package/build/link/preview/useNextScreenId.d.ts.map +1 -0
  81. package/build/link/preview/useNextScreenId.js +42 -0
  82. package/build/link/preview/useNextScreenId.js.map +1 -0
  83. package/build/link/useLinkHooks.d.ts +3 -2
  84. package/build/link/useLinkHooks.d.ts.map +1 -1
  85. package/build/link/useLinkHooks.js +1 -0
  86. package/build/link/useLinkHooks.js.map +1 -1
  87. package/build/modal/Modal.d.ts +82 -0
  88. package/build/modal/Modal.d.ts.map +1 -0
  89. package/build/modal/Modal.js +82 -0
  90. package/build/modal/Modal.js.map +1 -0
  91. package/build/modal/ModalComponent.d.ts +7 -0
  92. package/build/modal/ModalComponent.d.ts.map +1 -0
  93. package/build/modal/ModalComponent.js +10 -0
  94. package/build/modal/ModalComponent.js.map +1 -0
  95. package/build/modal/ModalContext.d.ts +22 -0
  96. package/build/modal/ModalContext.d.ts.map +1 -0
  97. package/build/modal/ModalContext.js +150 -0
  98. package/build/modal/ModalContext.js.map +1 -0
  99. package/build/typed-routes/generate.js +1 -1
  100. package/build/typed-routes/generate.js.map +1 -1
  101. package/build/useFocusEffect.d.ts.map +1 -1
  102. package/build/useFocusEffect.js +5 -3
  103. package/build/useFocusEffect.js.map +1 -1
  104. package/build/useScreens.js +1 -1
  105. package/build/useScreens.js.map +1 -1
  106. package/build/utils/stack.d.ts +5 -0
  107. package/build/utils/stack.d.ts.map +1 -0
  108. package/build/utils/stack.js +10 -0
  109. package/build/utils/stack.js.map +1 -0
  110. package/build/views/Screen.d.ts.map +1 -1
  111. package/build/views/Screen.js +13 -40
  112. package/build/views/Screen.js.map +1 -1
  113. package/build/views/Unmatched.d.ts.map +1 -1
  114. package/build/views/Unmatched.js +9 -3
  115. package/build/views/Unmatched.js.map +1 -1
  116. package/build/views/useSafeLayoutEffect.d.ts +3 -0
  117. package/build/views/useSafeLayoutEffect.d.ts.map +1 -0
  118. package/build/views/useSafeLayoutEffect.js +6 -0
  119. package/build/views/useSafeLayoutEffect.js.map +1 -0
  120. package/expo-module.config.json +1 -1
  121. package/ios/ExpoHead.podspec +1 -1
  122. package/ios/LinkPreview/LinkPreviewNativeActionView.swift +12 -0
  123. package/ios/LinkPreview/LinkPreviewNativeModule.swift +50 -0
  124. package/ios/LinkPreview/LinkPreviewNativeNavigation.h +18 -0
  125. package/ios/LinkPreview/LinkPreviewNativeNavigation.mm +108 -0
  126. package/ios/LinkPreview/LinkPreviewNativePreviewView.swift +15 -0
  127. package/ios/LinkPreview/LinkPreviewNativeTriggerView.swift +9 -0
  128. package/ios/LinkPreview/LinkPreviewNativeView.swift +193 -0
  129. package/package.json +6 -6
  130. package/plugin/options.json +29 -1
@@ -1,57 +1,10 @@
1
1
  "use strict";
2
- 'use client';
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
2
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.Link = void 0;
8
- exports.Redirect = Redirect;
9
- // Fork of @react-navigation/native Link.tsx with `href` and `replace` support added and
10
- // `to` / `action` support removed.
11
- const react_1 = require("react");
12
- const react_native_1 = require("react-native");
3
+ exports.Redirect = exports.Link = void 0;
4
+ const ExpoLink_1 = require("./ExpoLink");
5
+ const LinkWithPreview_1 = require("./LinkWithPreview");
13
6
  const href_1 = require("./href");
14
- const useLinkToPathProps_1 = __importDefault(require("./useLinkToPathProps"));
15
- const hooks_1 = require("../hooks");
16
- const useFocusEffect_1 = require("../useFocusEffect");
17
- const useLinkHooks_1 = require("./useLinkHooks");
18
- const Prefetch_1 = require("../Prefetch");
19
- const Slot_1 = require("../ui/Slot");
20
- /**
21
- * Redirects to the `href` as soon as the component is mounted.
22
- *
23
- * @example
24
- * ```tsx
25
- * import { View, Text } from 'react-native';
26
- * import { Redirect } from 'expo-router';
27
- *
28
- * export default function Page() {
29
- * const { user } = useAuth();
30
- *
31
- * if (!user) {
32
- * return <Redirect href="/login" />;
33
- * }
34
- *
35
- * return (
36
- * <View>
37
- * <Text>Welcome Back!</Text>
38
- * </View>
39
- * );
40
- * }
41
- * ```
42
- */
43
- function Redirect({ href, relativeToDirectory, withAnchor }) {
44
- const router = (0, hooks_1.useRouter)();
45
- (0, useFocusEffect_1.useFocusEffect)(() => {
46
- try {
47
- router.replace(href, { relativeToDirectory, withAnchor });
48
- }
49
- catch (error) {
50
- console.error(error);
51
- }
52
- });
53
- return null;
54
- }
7
+ exports.Link = Object.assign(
55
8
  /**
56
9
  * Component that renders a link using [`href`](#href) to another route.
57
10
  * By default, it accepts children and wraps them in a `<Text>` component.
@@ -78,52 +31,81 @@ function Redirect({ href, relativeToDirectory, withAnchor }) {
78
31
  *}
79
32
  * ```
80
33
  */
81
- exports.Link = (0, react_1.forwardRef)(ExpoRouterLink);
82
- exports.Link.resolveHref = href_1.resolveHref;
83
- function ExpoRouterLink({ href, replace, push, dismissTo,
84
- // TODO: This does not prevent default on the anchor tag.
85
- relativeToDirectory, asChild, rel, target, download, withAnchor, dangerouslySingular: singular, prefetch, ...rest }, ref) {
86
- // Mutate the style prop to add the className on web.
87
- const style = (0, useLinkHooks_1.useInteropClassName)(rest);
88
- // If not passing asChild, we need to forward the props to the anchor tag using React Native Web's `hrefAttrs`.
89
- const hrefAttrs = (0, useLinkHooks_1.useHrefAttrs)({ asChild, rel, target, download });
90
- const resolvedHref = (0, react_1.useMemo)(() => {
91
- if (href == null) {
92
- throw new Error('Link: href is required');
93
- }
94
- return (0, href_1.resolveHref)(href);
95
- }, [href]);
96
- let event;
97
- if (push)
98
- event = 'PUSH';
99
- if (replace)
100
- event = 'REPLACE';
101
- if (dismissTo)
102
- event = 'POP_TO';
103
- const props = (0, useLinkToPathProps_1.default)({
104
- href: resolvedHref,
105
- event,
106
- relativeToDirectory,
107
- withAnchor,
108
- dangerouslySingular: singular,
109
- });
110
- const onPress = (e) => {
111
- if ('onPress' in rest) {
112
- rest.onPress?.(e);
113
- }
114
- props.onPress(e);
115
- };
116
- const Component = asChild ? Slot_1.Slot : react_native_1.Text;
117
- // Avoid using createElement directly, favoring JSX, to allow tools like NativeWind to perform custom JSX handling on native.
118
- const element = (<Component ref={ref} {...props} {...hrefAttrs} {...rest} style={style} {...react_native_1.Platform.select({
119
- web: {
120
- onClick: onPress,
121
- },
122
- default: { onPress },
123
- })}/>);
124
- return prefetch ? (<>
125
- <Prefetch_1.Prefetch href={href}/>
126
- {element}
127
- </>) : (element);
128
- }
34
+ function Link(props) {
35
+ // Re-exporting ExpoLink here so that Link.* can be used in server components.
36
+ return <ExpoLink_1.ExpoLink {...props}/>;
37
+ }, {
38
+ resolveHref: href_1.resolveHref,
39
+ /**
40
+ * A component used to group context menu actions for a link.
41
+ *
42
+ * If multiple `Link.Menu` components are used within a single `Link`, only the first one will be rendered.
43
+ * Only `Link.MenuAction` components are allowed as children of `Link.Menu`.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * <Link.Menu>
48
+ * <Link.MenuAction title="Action 1" onPress={()=>{}} />
49
+ * <Link.MenuAction title="Action 2" onPress={()=>{}} />
50
+ * </Link.Menu>
51
+ * ```
52
+ *
53
+ * @platform ios
54
+ */
55
+ Menu: LinkWithPreview_1.LinkMenu,
56
+ /**
57
+ * A component used as a link trigger. The content of this component will be rendered in the base link.
58
+ *
59
+ * If multiple `Link.Trigger` components are used within a single `Link`, only the first one will be rendered.
60
+ *
61
+ * @example
62
+ * ```tsx
63
+ * <Link href="/about">
64
+ * <Link.Trigger>
65
+ * Trigger
66
+ * </Link.Trigger>
67
+ * </Link>
68
+ * ```
69
+ *
70
+ * @platform ios
71
+ */
72
+ Trigger: LinkWithPreview_1.LinkTrigger,
73
+ /**
74
+ * A component used to render and customize the link preview.
75
+ *
76
+ * If `Link.Preview` is used without any props, it will render a preview of the `href` passed to the `Link`.
77
+ *
78
+ * If multiple `Link.Preview` components are used within a single `Link`, only the first one will be rendered.
79
+ *
80
+ * To customize the preview, you can pass custom content as children.
81
+ *
82
+ * @example
83
+ * ```tsx
84
+ * <Link href="/about">
85
+ * <Link.Preview>
86
+ * <Text>Custom Preview Content</Text>
87
+ * </Link.Trigger>
88
+ * </Link>
89
+ * ```
90
+ *
91
+ * @example
92
+ * ```tsx
93
+ * <Link href="/about">
94
+ * <Link.Preview />
95
+ * </Link>
96
+ * ```
97
+ *
98
+ * @platform ios
99
+ */
100
+ Preview: LinkWithPreview_1.LinkPreview,
101
+ /**
102
+ * A component used to render a context menu action for a link.
103
+ * This component should only be used as a child of `Link.Menu`.
104
+ *
105
+ * @platform ios
106
+ */
107
+ MenuAction: LinkWithPreview_1.LinkMenuAction,
108
+ });
109
+ var Redirect_1 = require("./Redirect");
110
+ Object.defineProperty(exports, "Redirect", { enumerable: true, get: function () { return Redirect_1.Redirect; } });
129
111
  //# sourceMappingURL=Link.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n// Fork of @react-navigation/native Link.tsx with `href` and `replace` support added and\n// `to` / `action` support removed.\nimport { PropsWithChildren, forwardRef, useMemo, MouseEvent, ForwardedRef, JSX } from 'react';\nimport { Text, GestureResponderEvent, Platform } from 'react-native';\n\nimport { resolveHref } from './href';\nimport useLinkToPathProps from './useLinkToPathProps';\nimport { useRouter } from '../hooks';\nimport { Href } from '../types';\nimport { useFocusEffect } from '../useFocusEffect';\nimport { useInteropClassName, useHrefAttrs, LinkProps, WebAnchorProps } from './useLinkHooks';\nimport { Prefetch } from '../Prefetch';\nimport { Slot } from '../ui/Slot';\n\nexport interface LinkComponent {\n (props: PropsWithChildren<LinkProps>): JSX.Element;\n /** Helper method to resolve an Href object into a string. */\n resolveHref: (href: Href) => string;\n}\n\nexport type RedirectProps = {\n /**\n * The path of the route to navigate to. It can either be:\n * - **string**: A full path like `/profile/settings` or a relative path like `../settings`.\n * - **object**: An object with a `pathname` and optional `params`. The `pathname` can be\n * a full path like `/profile/settings` or a relative path like `../settings`. The\n * params can be an object of key-value pairs.\n *\n * @example\n * ```tsx Dynamic\n * import { Redirect } from 'expo-router';\n *\n * export default function RedirectToAbout() {\n * return (\n * <Redirect href=\"/about\">About</Link>\n * );\n *}\n * ```\n */\n href: Href;\n\n /**\n * Relative URL references are either relative to the directory or the document.\n * By default, relative paths are relative to the document.\n *\n * @see [Resolving relative references in Mozilla's documentation](https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references).\n */\n relativeToDirectory?: boolean;\n\n /**\n * Replaces the initial screen with the current route.\n */\n withAnchor?: boolean;\n};\n\n/**\n * Redirects to the `href` as soon as the component is mounted.\n *\n * @example\n * ```tsx\n * import { View, Text } from 'react-native';\n * import { Redirect } from 'expo-router';\n *\n * export default function Page() {\n * const { user } = useAuth();\n *\n * if (!user) {\n * return <Redirect href=\"/login\" />;\n * }\n *\n * return (\n * <View>\n * <Text>Welcome Back!</Text>\n * </View>\n * );\n * }\n * ```\n */\nexport function Redirect({ href, relativeToDirectory, withAnchor }: RedirectProps) {\n const router = useRouter();\n useFocusEffect(() => {\n try {\n router.replace(href, { relativeToDirectory, withAnchor });\n } catch (error) {\n console.error(error);\n }\n });\n return null;\n}\n\n/**\n * Component that renders a link using [`href`](#href) to another route.\n * By default, it accepts children and wraps them in a `<Text>` component.\n *\n * Uses an anchor tag (`<a>`) on web and performs a client-side navigation to preserve\n * the state of the website and navigate faster. The web-only attributes such as `target`,\n * `rel`, and `download` are supported and passed to the anchor tag on web. See\n * [`WebAnchorProps`](#webanchorprops) for more details.\n *\n * > **Note**: Client-side navigation works with both single-page apps,\n * and [static-rendering](/router/reference/static-rendering/).\n *\n * @example\n * ```tsx\n * import { Link } from 'expo-router';\n * import { View } from 'react-native';\n *\n * export default function Route() {\n * return (\n * <View>\n * <Link href=\"/about\">About</Link>\n * </View>\n * );\n *}\n * ```\n */\nexport const Link = forwardRef(ExpoRouterLink) as unknown as LinkComponent;\n\nLink.resolveHref = resolveHref;\n\nfunction ExpoRouterLink(\n {\n href,\n replace,\n push,\n dismissTo,\n // TODO: This does not prevent default on the anchor tag.\n relativeToDirectory,\n asChild,\n rel,\n target,\n download,\n withAnchor,\n dangerouslySingular: singular,\n prefetch,\n ...rest\n }: LinkProps,\n ref: ForwardedRef<Text>\n) {\n // Mutate the style prop to add the className on web.\n const style = useInteropClassName(rest);\n\n // If not passing asChild, we need to forward the props to the anchor tag using React Native Web's `hrefAttrs`.\n const hrefAttrs = useHrefAttrs({ asChild, rel, target, download });\n\n const resolvedHref = useMemo(() => {\n if (href == null) {\n throw new Error('Link: href is required');\n }\n return resolveHref(href);\n }, [href]);\n\n let event;\n if (push) event = 'PUSH';\n if (replace) event = 'REPLACE';\n if (dismissTo) event = 'POP_TO';\n\n const props = useLinkToPathProps({\n href: resolvedHref,\n event,\n relativeToDirectory,\n withAnchor,\n dangerouslySingular: singular,\n });\n\n const onPress = (e: MouseEvent<HTMLAnchorElement> | GestureResponderEvent) => {\n if ('onPress' in rest) {\n rest.onPress?.(e);\n }\n props.onPress(e);\n };\n\n const Component = asChild ? Slot : Text;\n\n // Avoid using createElement directly, favoring JSX, to allow tools like NativeWind to perform custom JSX handling on native.\n const element = (\n <Component\n ref={ref}\n {...props}\n {...hrefAttrs}\n {...rest}\n style={style}\n {...Platform.select({\n web: {\n onClick: onPress,\n } as any,\n default: { onPress },\n })}\n />\n );\n\n return prefetch ? (\n <>\n <Prefetch href={href} />\n {element}\n </>\n ) : (\n element\n );\n}\n\nexport { LinkProps, WebAnchorProps };\n"]}
1
+ {"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":";;;AAAA,yCAAsC;AACtC,uDAAuF;AACvF,iCAAqC;AAGxB,QAAA,IAAI,GAAG,MAAM,CAAC,MAAM;AAC/B;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,SAAS,IAAI,CAAC,KAAgB;IAC5B,8EAA8E;IAC9E,OAAO,CAAC,mBAAQ,CAAC,IAAI,KAAK,CAAC,EAAG,CAAC;AACjC,CAAC,EACD;IACE,WAAW,EAAX,kBAAW;IACX;;;;;;;;;;;;;;;OAeG;IACH,IAAI,EAAE,0BAAQ;IACd;;;;;;;;;;;;;;;OAeG;IACH,OAAO,EAAE,6BAAW;IACpB;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,OAAO,EAAE,6BAAW;IACpB;;;;;OAKG;IACH,UAAU,EAAE,gCAAc;CAC3B,CACF,CAAC;AAKF,uCAAqD;AAA5C,oGAAA,QAAQ,OAAA","sourcesContent":["import { ExpoLink } from './ExpoLink';\nimport { LinkMenu, LinkMenuAction, LinkPreview, LinkTrigger } from './LinkWithPreview';\nimport { resolveHref } from './href';\nimport { LinkProps, WebAnchorProps } from './useLinkHooks';\n\nexport const Link = Object.assign(\n /**\n * Component that renders a link using [`href`](#href) to another route.\n * By default, it accepts children and wraps them in a `<Text>` component.\n *\n * Uses an anchor tag (`<a>`) on web and performs a client-side navigation to preserve\n * the state of the website and navigate faster. The web-only attributes such as `target`,\n * `rel`, and `download` are supported and passed to the anchor tag on web. See\n * [`WebAnchorProps`](#webanchorprops) for more details.\n *\n * > **Note**: Client-side navigation works with both single-page apps,\n * and [static-rendering](/router/reference/static-rendering/).\n *\n * @example\n * ```tsx\n * import { Link } from 'expo-router';\n * import { View } from 'react-native';\n *\n * export default function Route() {\n * return (\n * <View>\n * <Link href=\"/about\">About</Link>\n * </View>\n * );\n *}\n * ```\n */\n function Link(props: LinkProps) {\n // Re-exporting ExpoLink here so that Link.* can be used in server components.\n return <ExpoLink {...props} />;\n },\n {\n resolveHref,\n /**\n * A component used to group context menu actions for a link.\n *\n * If multiple `Link.Menu` components are used within a single `Link`, only the first one will be rendered.\n * Only `Link.MenuAction` components are allowed as children of `Link.Menu`.\n *\n * @example\n * ```tsx\n * <Link.Menu>\n * <Link.MenuAction title=\"Action 1\" onPress={()=>{}} />\n * <Link.MenuAction title=\"Action 2\" onPress={()=>{}} />\n * </Link.Menu>\n * ```\n *\n * @platform ios\n */\n Menu: LinkMenu,\n /**\n * A component used as a link trigger. The content of this component will be rendered in the base link.\n *\n * If multiple `Link.Trigger` components are used within a single `Link`, only the first one will be rendered.\n *\n * @example\n * ```tsx\n * <Link href=\"/about\">\n * <Link.Trigger>\n * Trigger\n * </Link.Trigger>\n * </Link>\n * ```\n *\n * @platform ios\n */\n Trigger: LinkTrigger,\n /**\n * A component used to render and customize the link preview.\n *\n * If `Link.Preview` is used without any props, it will render a preview of the `href` passed to the `Link`.\n *\n * If multiple `Link.Preview` components are used within a single `Link`, only the first one will be rendered.\n *\n * To customize the preview, you can pass custom content as children.\n *\n * @example\n * ```tsx\n * <Link href=\"/about\">\n * <Link.Preview>\n * <Text>Custom Preview Content</Text>\n * </Link.Trigger>\n * </Link>\n * ```\n *\n * @example\n * ```tsx\n * <Link href=\"/about\">\n * <Link.Preview />\n * </Link>\n * ```\n *\n * @platform ios\n */\n Preview: LinkPreview,\n /**\n * A component used to render a context menu action for a link.\n * This component should only be used as a child of `Link.Menu`.\n *\n * @platform ios\n */\n MenuAction: LinkMenuAction,\n }\n);\n\nexport type LinkComponent = typeof Link;\n\nexport { LinkProps, WebAnchorProps };\nexport { Redirect, RedirectProps } from './Redirect';\n"]}
@@ -0,0 +1,36 @@
1
+ import React, { type PropsWithChildren, type ReactElement } from 'react';
2
+ import { LinkProps } from './useLinkHooks';
3
+ export declare function LinkWithPreview({ children, ...rest }: LinkProps): React.JSX.Element;
4
+ interface LinkMenuAction {
5
+ /**
6
+ * The title of the menu item.
7
+ */
8
+ title: string;
9
+ onPress: () => void;
10
+ }
11
+ export declare function LinkMenuAction(_: LinkMenuAction): null;
12
+ interface LinkMenuProps {
13
+ children: ReactElement<LinkMenuAction> | ReactElement<LinkMenuAction>[];
14
+ }
15
+ export declare function LinkMenu({ children }: LinkMenuProps): React.JSX.Element[] | null;
16
+ interface LinkPreviewProps {
17
+ /**
18
+ * Sets the preferred width of the preview.
19
+ * If not set, full width of the screen will be used.
20
+ *
21
+ * This is only **preferred** width, the actual width may be different
22
+ */
23
+ width?: number;
24
+ /**
25
+ * Sets the preferred height of the preview.
26
+ * If not set, full height of the screen will be used.
27
+ *
28
+ * This is only **preferred** height, the actual height may be different
29
+ */
30
+ height?: number;
31
+ children?: React.ReactNode;
32
+ }
33
+ export declare function LinkPreview({ children, width, height }: LinkPreviewProps): React.JSX.Element | null;
34
+ export declare function LinkTrigger(props: PropsWithChildren): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | React.JSX.Element | null | undefined;
35
+ export {};
36
+ //# sourceMappingURL=LinkWithPreview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkWithPreview.d.ts","sourceRoot":"","sources":["../../src/link/LinkWithPreview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAOZ,KAAK,iBAAiB,EACtB,KAAK,YAAY,EAClB,MAAM,OAAO,CAAC;AAaf,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAS3C,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,qBAgH/D;AAED,UAAU,cAAc;IACtB;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,QAE/C;AACD,UAAU,aAAa;IACrB,QAAQ,EAAE,YAAY,CAAC,cAAc,CAAC,GAAG,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;CACzE;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE,aAAa,8BAOnD;AAED,UAAU,gBAAgB;IACxB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,gBAAgB,4BA2BxE;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,iBAAiB,mSAYnD"}
@@ -0,0 +1,192 @@
1
+ "use strict";
2
+ 'use client';
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.LinkWithPreview = LinkWithPreview;
38
+ exports.LinkMenuAction = LinkMenuAction;
39
+ exports.LinkMenu = LinkMenu;
40
+ exports.LinkPreview = LinkPreview;
41
+ exports.LinkTrigger = LinkTrigger;
42
+ const react_1 = __importStar(require("react"));
43
+ const hooks_1 = require("../hooks");
44
+ const BaseExpoRouterLink_1 = require("./BaseExpoRouterLink");
45
+ const HrefPreview_1 = require("./preview/HrefPreview");
46
+ const LinkPreviewContext_1 = require("./preview/LinkPreviewContext");
47
+ const native_1 = require("./preview/native");
48
+ const useNextScreenId_1 = require("./preview/useNextScreenId");
49
+ const url_1 = require("../utils/url");
50
+ const PreviewRouteContext_1 = require("./preview/PreviewRouteContext");
51
+ const Slot_1 = require("../ui/Slot");
52
+ const InternalLinkPreviewContext = (0, react_1.createContext)(undefined);
53
+ function LinkWithPreview({ children, ...rest }) {
54
+ const router = (0, hooks_1.useRouter)();
55
+ const { setIsPreviewOpen } = (0, LinkPreviewContext_1.useLinkPreviewContext)();
56
+ const [isCurrentPreviewOpen, setIsCurrenPreviewOpen] = (0, react_1.useState)(false);
57
+ const hrefWithoutQuery = String(rest.href).split('?')[0];
58
+ const prevHrefWithoutQuery = (0, react_1.useRef)(hrefWithoutQuery);
59
+ (0, react_1.useEffect)(() => {
60
+ if (isCurrentPreviewOpen) {
61
+ if (prevHrefWithoutQuery.current !== hrefWithoutQuery) {
62
+ throw new Error('Link does not support changing the href prop after the preview has been opened. Please ensure that the href prop is stable and does not change between renders.');
63
+ }
64
+ }
65
+ else {
66
+ prevHrefWithoutQuery.current = hrefWithoutQuery;
67
+ }
68
+ }, [hrefWithoutQuery]);
69
+ const [nextScreenId, updateNextScreenId] = (0, useNextScreenId_1.useNextScreenId)();
70
+ (0, react_1.useEffect)(() => {
71
+ if ((0, url_1.shouldLinkExternally)(String(rest.href))) {
72
+ if (process.env.NODE_ENV !== 'production') {
73
+ throw new Error('External links previews are not supported');
74
+ }
75
+ else {
76
+ console.warn('External links previews are not supported');
77
+ }
78
+ }
79
+ if (rest.replace) {
80
+ if (process.env.NODE_ENV !== 'production') {
81
+ throw new Error('Using replace links with preview is not supported');
82
+ }
83
+ else {
84
+ console.warn('Using replace links with preview is not supported');
85
+ }
86
+ }
87
+ }, [rest.href, rest.replace]);
88
+ const triggerElement = react_1.default.useMemo(() => getFirstChildOfType(children, LinkTrigger), [children]);
89
+ const menuElement = react_1.default.useMemo(() => getFirstChildOfType(children, LinkMenu), [children]);
90
+ const previewElement = react_1.default.useMemo(() => getFirstChildOfType(children, LinkPreview), [children]);
91
+ if (previewElement && !triggerElement) {
92
+ if (process.env.NODE_ENV !== 'production') {
93
+ throw new Error('When you use Link.Preview, you must use Link.Trigger to specify the trigger element.');
94
+ }
95
+ else {
96
+ console.warn('When you use Link.Preview, you must use Link.Trigger to specify the trigger element.');
97
+ }
98
+ }
99
+ const trigger = react_1.default.useMemo(() => triggerElement ?? <LinkTrigger>{children}</LinkTrigger>, [triggerElement, children]);
100
+ const actionsHandlers = react_1.default.useMemo(() => convertActionsToActionsHandlers(convertChildrenArrayToActions(react_1.default.Children.toArray(menuElement?.props.children))), [menuElement]);
101
+ const preview = react_1.default.useMemo(() => previewElement ?? <LinkPreview />, [previewElement, rest.href]);
102
+ if ((0, url_1.shouldLinkExternally)(String(rest.href)) || rest.replace) {
103
+ return <BaseExpoRouterLink_1.BaseExpoRouterLink children={children} {...rest}/>;
104
+ }
105
+ return (<native_1.NativeLinkPreview nextScreenId={nextScreenId} onActionSelected={({ nativeEvent: { id } }) => {
106
+ actionsHandlers[id]?.();
107
+ }} onWillPreviewOpen={() => {
108
+ router.prefetch(rest.href);
109
+ setIsPreviewOpen(true);
110
+ setIsCurrenPreviewOpen(true);
111
+ }} onDidPreviewOpen={() => {
112
+ updateNextScreenId(rest.href);
113
+ }} onPreviewDidClose={() => {
114
+ setIsPreviewOpen(false);
115
+ setIsCurrenPreviewOpen(false);
116
+ }} onPreviewTapped={() => {
117
+ router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });
118
+ }}>
119
+ <InternalLinkPreviewContext value={{ isVisible: isCurrentPreviewOpen, href: rest.href }}>
120
+ <native_1.NativeLinkPreviewTrigger>
121
+ <BaseExpoRouterLink_1.BaseExpoRouterLink {...rest} children={trigger} ref={rest.ref}/>
122
+ </native_1.NativeLinkPreviewTrigger>
123
+ {preview}
124
+ {menuElement}
125
+ </InternalLinkPreviewContext>
126
+ </native_1.NativeLinkPreview>);
127
+ }
128
+ function LinkMenuAction(_) {
129
+ return null;
130
+ }
131
+ function LinkMenu({ children }) {
132
+ if ((0, PreviewRouteContext_1.useIsPreview)() || !(0, react_1.use)(InternalLinkPreviewContext)) {
133
+ return null;
134
+ }
135
+ return convertChildrenArrayToActions(react_1.default.Children.toArray(children)).map((action) => {
136
+ return <native_1.NativeLinkPreviewAction key={action.id} title={action.title} id={action.id}/>;
137
+ });
138
+ }
139
+ function LinkPreview({ children, width, height }) {
140
+ const internalPreviewContext = (0, react_1.use)(InternalLinkPreviewContext);
141
+ if ((0, PreviewRouteContext_1.useIsPreview)() || !internalPreviewContext) {
142
+ return null;
143
+ }
144
+ const { isVisible, href } = internalPreviewContext;
145
+ const contentSize = {
146
+ width: width ?? 0,
147
+ height: height ?? 0,
148
+ };
149
+ let content;
150
+ if (children) {
151
+ content = isVisible ? children : null;
152
+ }
153
+ else {
154
+ content = isVisible ? <HrefPreview_1.HrefPreview href={href}/> : null;
155
+ }
156
+ return (<native_1.NativeLinkPreviewContent style={{
157
+ /* Setting default background here, so that the preview is not transparent */
158
+ backgroundColor: '#fff',
159
+ }} preferredContentSize={contentSize}>
160
+ {content}
161
+ </native_1.NativeLinkPreviewContent>);
162
+ }
163
+ function LinkTrigger(props) {
164
+ if (react_1.default.Children.count(props.children) > 1 || !(0, react_1.isValidElement)(props.children)) {
165
+ // If onPress is passed, this means that Link passed props to this component.
166
+ // We can assume that asChild is used, so we throw an error, because link will not work in this case.
167
+ if (props && typeof props === 'object' && 'onPress' in props) {
168
+ throw new Error('When using Link.Trigger in an asChild Link, you must pass a single child element that will emit onPress event.');
169
+ }
170
+ return props.children;
171
+ }
172
+ return <Slot_1.Slot {...props}/>;
173
+ }
174
+ function getFirstChildOfType(children, type) {
175
+ return react_1.default.Children.toArray(children).find((child) => (0, react_1.isValidElement)(child) && child.type === type);
176
+ }
177
+ function convertActionsToActionsHandlers(items) {
178
+ return (items ?? []).reduce((acc, item) => ({
179
+ ...acc,
180
+ [item.id]: item.onPress,
181
+ }), {});
182
+ }
183
+ function convertChildrenArrayToActions(children) {
184
+ return children
185
+ .filter((item) => (0, react_1.isValidElement)(item) && item.type === LinkMenuAction)
186
+ .map((child, index) => ({
187
+ id: `${child.props.title}-${index}`,
188
+ title: child.props.title,
189
+ onPress: child.props.onPress,
190
+ }));
191
+ }
192
+ //# sourceMappingURL=LinkWithPreview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LinkWithPreview.js","sourceRoot":"","sources":["../../src/link/LinkWithPreview.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport React, {\n createContext,\n isValidElement,\n use,\n useEffect,\n useRef,\n useState,\n type PropsWithChildren,\n type ReactElement,\n} from 'react';\n\nimport { useRouter } from '../hooks';\nimport { BaseExpoRouterLink } from './BaseExpoRouterLink';\nimport { HrefPreview } from './preview/HrefPreview';\nimport { useLinkPreviewContext } from './preview/LinkPreviewContext';\nimport {\n NativeLinkPreview,\n NativeLinkPreviewAction,\n NativeLinkPreviewContent,\n NativeLinkPreviewTrigger,\n} from './preview/native';\nimport { useNextScreenId } from './preview/useNextScreenId';\nimport { LinkProps } from './useLinkHooks';\nimport { shouldLinkExternally } from '../utils/url';\nimport { useIsPreview } from './preview/PreviewRouteContext';\nimport { Slot } from '../ui/Slot';\n\nconst InternalLinkPreviewContext = createContext<\n { isVisible: boolean; href: LinkProps['href'] } | undefined\n>(undefined);\n\nexport function LinkWithPreview({ children, ...rest }: LinkProps) {\n const router = useRouter();\n const { setIsPreviewOpen } = useLinkPreviewContext();\n const [isCurrentPreviewOpen, setIsCurrenPreviewOpen] = useState(false);\n\n const hrefWithoutQuery = String(rest.href).split('?')[0];\n const prevHrefWithoutQuery = useRef(hrefWithoutQuery);\n\n useEffect(() => {\n if (isCurrentPreviewOpen) {\n if (prevHrefWithoutQuery.current !== hrefWithoutQuery) {\n throw new Error(\n 'Link does not support changing the href prop after the preview has been opened. Please ensure that the href prop is stable and does not change between renders.'\n );\n }\n } else {\n prevHrefWithoutQuery.current = hrefWithoutQuery;\n }\n }, [hrefWithoutQuery]);\n\n const [nextScreenId, updateNextScreenId] = useNextScreenId();\n\n useEffect(() => {\n if (shouldLinkExternally(String(rest.href))) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('External links previews are not supported');\n } else {\n console.warn('External links previews are not supported');\n }\n }\n if (rest.replace) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error('Using replace links with preview is not supported');\n } else {\n console.warn('Using replace links with preview is not supported');\n }\n }\n }, [rest.href, rest.replace]);\n\n const triggerElement = React.useMemo(\n () => getFirstChildOfType(children, LinkTrigger),\n [children]\n );\n const menuElement = React.useMemo(() => getFirstChildOfType(children, LinkMenu), [children]);\n const previewElement = React.useMemo(\n () => getFirstChildOfType(children, LinkPreview),\n [children]\n );\n\n if (previewElement && !triggerElement) {\n if (process.env.NODE_ENV !== 'production') {\n throw new Error(\n 'When you use Link.Preview, you must use Link.Trigger to specify the trigger element.'\n );\n } else {\n console.warn(\n 'When you use Link.Preview, you must use Link.Trigger to specify the trigger element.'\n );\n }\n }\n\n const trigger = React.useMemo(\n () => triggerElement ?? <LinkTrigger>{children}</LinkTrigger>,\n [triggerElement, children]\n );\n\n const actionsHandlers = React.useMemo(\n () =>\n convertActionsToActionsHandlers(\n convertChildrenArrayToActions(React.Children.toArray(menuElement?.props.children))\n ),\n [menuElement]\n );\n const preview = React.useMemo(\n () => previewElement ?? <LinkPreview />,\n [previewElement, rest.href]\n );\n\n if (shouldLinkExternally(String(rest.href)) || rest.replace) {\n return <BaseExpoRouterLink children={children} {...rest} />;\n }\n\n return (\n <NativeLinkPreview\n nextScreenId={nextScreenId}\n onActionSelected={({ nativeEvent: { id } }) => {\n actionsHandlers[id]?.();\n }}\n onWillPreviewOpen={() => {\n router.prefetch(rest.href);\n setIsPreviewOpen(true);\n setIsCurrenPreviewOpen(true);\n }}\n onDidPreviewOpen={() => {\n updateNextScreenId(rest.href);\n }}\n onPreviewDidClose={() => {\n setIsPreviewOpen(false);\n setIsCurrenPreviewOpen(false);\n }}\n onPreviewTapped={() => {\n router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });\n }}>\n <InternalLinkPreviewContext value={{ isVisible: isCurrentPreviewOpen, href: rest.href }}>\n <NativeLinkPreviewTrigger>\n <BaseExpoRouterLink {...rest} children={trigger} ref={rest.ref} />\n </NativeLinkPreviewTrigger>\n {preview}\n {menuElement}\n </InternalLinkPreviewContext>\n </NativeLinkPreview>\n );\n}\n\ninterface LinkMenuAction {\n /**\n * The title of the menu item.\n */\n title: string;\n onPress: () => void;\n}\n\nexport function LinkMenuAction(_: LinkMenuAction) {\n return null;\n}\ninterface LinkMenuProps {\n children: ReactElement<LinkMenuAction> | ReactElement<LinkMenuAction>[];\n}\n\nexport function LinkMenu({ children }: LinkMenuProps) {\n if (useIsPreview() || !use(InternalLinkPreviewContext)) {\n return null;\n }\n return convertChildrenArrayToActions(React.Children.toArray(children)).map((action) => {\n return <NativeLinkPreviewAction key={action.id} title={action.title} id={action.id} />;\n });\n}\n\ninterface LinkPreviewProps {\n /**\n * Sets the preferred width of the preview.\n * If not set, full width of the screen will be used.\n *\n * This is only **preferred** width, the actual width may be different\n */\n width?: number;\n\n /**\n * Sets the preferred height of the preview.\n * If not set, full height of the screen will be used.\n *\n * This is only **preferred** height, the actual height may be different\n */\n height?: number;\n children?: React.ReactNode;\n}\n\nexport function LinkPreview({ children, width, height }: LinkPreviewProps) {\n const internalPreviewContext = use(InternalLinkPreviewContext);\n if (useIsPreview() || !internalPreviewContext) {\n return null;\n }\n const { isVisible, href } = internalPreviewContext;\n const contentSize = {\n width: width ?? 0,\n height: height ?? 0,\n };\n let content: React.ReactNode;\n if (children) {\n content = isVisible ? children : null;\n } else {\n content = isVisible ? <HrefPreview href={href} /> : null;\n }\n\n return (\n <NativeLinkPreviewContent\n style={{\n /* Setting default background here, so that the preview is not transparent */\n backgroundColor: '#fff',\n }}\n preferredContentSize={contentSize}>\n {content}\n </NativeLinkPreviewContent>\n );\n}\n\nexport function LinkTrigger(props: PropsWithChildren) {\n if (React.Children.count(props.children) > 1 || !isValidElement(props.children)) {\n // If onPress is passed, this means that Link passed props to this component.\n // We can assume that asChild is used, so we throw an error, because link will not work in this case.\n if (props && typeof props === 'object' && 'onPress' in props) {\n throw new Error(\n 'When using Link.Trigger in an asChild Link, you must pass a single child element that will emit onPress event.'\n );\n }\n return props.children;\n }\n return <Slot {...props} />;\n}\n\nfunction getFirstChildOfType<PropsT>(\n children: React.ReactNode | React.ReactNode[],\n type: (props: PropsT) => unknown\n) {\n return React.Children.toArray(children).find(\n (child): child is ReactElement<PropsT> => isValidElement(child) && child.type === type\n );\n}\n\nfunction convertActionsToActionsHandlers(\n items: { id: string; title: string; onPress: () => void }[] | undefined\n) {\n return (items ?? []).reduce(\n (acc, item) => ({\n ...acc,\n [item.id]: item.onPress,\n }),\n {} as Record<string, () => void>\n );\n}\n\nfunction convertChildrenArrayToActions(children: ReturnType<typeof React.Children.toArray>) {\n return children\n .filter(\n (item): item is ReactElement<LinkMenuAction> =>\n isValidElement(item) && item.type === LinkMenuAction\n )\n .map((child, index) => ({\n id: `${child.props.title}-${index}`,\n title: child.props.title,\n onPress: child.props.onPress,\n }));\n}\n"]}
@@ -0,0 +1,58 @@
1
+ import type { Href } from '../types';
2
+ export type RedirectProps = {
3
+ /**
4
+ * The path of the route to navigate to. It can either be:
5
+ * - **string**: A full path like `/profile/settings` or a relative path like `../settings`.
6
+ * - **object**: An object with a `pathname` and optional `params`. The `pathname` can be
7
+ * a full path like `/profile/settings` or a relative path like `../settings`. The
8
+ * params can be an object of key-value pairs.
9
+ *
10
+ * @example
11
+ * ```tsx Dynamic
12
+ * import { Redirect } from 'expo-router';
13
+ *
14
+ * export default function RedirectToAbout() {
15
+ * return (
16
+ * <Redirect href="/about" />
17
+ * );
18
+ *}
19
+ * ```
20
+ */
21
+ href: Href;
22
+ /**
23
+ * Relative URL references are either relative to the directory or the document.
24
+ * By default, relative paths are relative to the document.
25
+ *
26
+ * @see [Resolving relative references in Mozilla's documentation](https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references).
27
+ */
28
+ relativeToDirectory?: boolean;
29
+ /**
30
+ * Replaces the initial screen with the current route.
31
+ */
32
+ withAnchor?: boolean;
33
+ };
34
+ /**
35
+ * Redirects to the `href` as soon as the component is mounted.
36
+ *
37
+ * @example
38
+ * ```tsx
39
+ * import { View, Text } from 'react-native';
40
+ * import { Redirect } from 'expo-router';
41
+ *
42
+ * export default function Page() {
43
+ * const { user } = useAuth();
44
+ *
45
+ * if (!user) {
46
+ * return <Redirect href="/login" />;
47
+ * }
48
+ *
49
+ * return (
50
+ * <View>
51
+ * <Text>Welcome Back!</Text>
52
+ * </View>
53
+ * );
54
+ * }
55
+ * ```
56
+ */
57
+ export declare function Redirect({ href, relativeToDirectory, withAnchor }: RedirectProps): null;
58
+ //# sourceMappingURL=Redirect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Redirect.d.ts","sourceRoot":"","sources":["../../src/link/Redirect.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAIrC,MAAM,MAAM,aAAa,GAAG;IAC1B;;;;;;;;;;;;;;;;;OAiBG;IACH,IAAI,EAAE,IAAI,CAAC;IAEX;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAE,EAAE,aAAa,QAahF"}
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Redirect = Redirect;
5
+ const hooks_1 = require("../hooks");
6
+ const useFocusEffect_1 = require("../useFocusEffect");
7
+ const PreviewRouteContext_1 = require("./preview/PreviewRouteContext");
8
+ /**
9
+ * Redirects to the `href` as soon as the component is mounted.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { View, Text } from 'react-native';
14
+ * import { Redirect } from 'expo-router';
15
+ *
16
+ * export default function Page() {
17
+ * const { user } = useAuth();
18
+ *
19
+ * if (!user) {
20
+ * return <Redirect href="/login" />;
21
+ * }
22
+ *
23
+ * return (
24
+ * <View>
25
+ * <Text>Welcome Back!</Text>
26
+ * </View>
27
+ * );
28
+ * }
29
+ * ```
30
+ */
31
+ function Redirect({ href, relativeToDirectory, withAnchor }) {
32
+ const router = (0, hooks_1.useRouter)();
33
+ const isPreview = (0, PreviewRouteContext_1.useIsPreview)();
34
+ (0, useFocusEffect_1.useFocusEffect)(() => {
35
+ if (!isPreview) {
36
+ try {
37
+ router.replace(href, { relativeToDirectory, withAnchor });
38
+ }
39
+ catch (error) {
40
+ console.error(error);
41
+ }
42
+ }
43
+ });
44
+ return null;
45
+ }
46
+ //# sourceMappingURL=Redirect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Redirect.js","sourceRoot":"","sources":["../../src/link/Redirect.tsx"],"names":[],"mappings":";AAAA,YAAY,CAAC;;AAiEb,4BAaC;AA5ED,oCAAqC;AAErC,sDAAmD;AACnD,uEAA6D;AAqC7D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,SAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,mBAAmB,EAAE,UAAU,EAAiB;IAC/E,MAAM,MAAM,GAAG,IAAA,iBAAS,GAAE,CAAC;IAC3B,MAAM,SAAS,GAAG,IAAA,kCAAY,GAAE,CAAC;IACjC,IAAA,+BAAc,EAAC,GAAG,EAAE;QAClB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,IAAI,CAAC;gBACH,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,mBAAmB,EAAE,UAAU,EAAE,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["'use client';\n\nimport { useRouter } from '../hooks';\nimport type { Href } from '../types';\nimport { useFocusEffect } from '../useFocusEffect';\nimport { useIsPreview } from './preview/PreviewRouteContext';\n\nexport type RedirectProps = {\n /**\n * The path of the route to navigate to. It can either be:\n * - **string**: A full path like `/profile/settings` or a relative path like `../settings`.\n * - **object**: An object with a `pathname` and optional `params`. The `pathname` can be\n * a full path like `/profile/settings` or a relative path like `../settings`. The\n * params can be an object of key-value pairs.\n *\n * @example\n * ```tsx Dynamic\n * import { Redirect } from 'expo-router';\n *\n * export default function RedirectToAbout() {\n * return (\n * <Redirect href=\"/about\" />\n * );\n *}\n * ```\n */\n href: Href;\n\n /**\n * Relative URL references are either relative to the directory or the document.\n * By default, relative paths are relative to the document.\n *\n * @see [Resolving relative references in Mozilla's documentation](https://developer.mozilla.org/en-US/docs/Web/API/URL_API/Resolving_relative_references).\n */\n relativeToDirectory?: boolean;\n\n /**\n * Replaces the initial screen with the current route.\n */\n withAnchor?: boolean;\n};\n\n/**\n * Redirects to the `href` as soon as the component is mounted.\n *\n * @example\n * ```tsx\n * import { View, Text } from 'react-native';\n * import { Redirect } from 'expo-router';\n *\n * export default function Page() {\n * const { user } = useAuth();\n *\n * if (!user) {\n * return <Redirect href=\"/login\" />;\n * }\n *\n * return (\n * <View>\n * <Text>Welcome Back!</Text>\n * </View>\n * );\n * }\n * ```\n */\nexport function Redirect({ href, relativeToDirectory, withAnchor }: RedirectProps) {\n const router = useRouter();\n const isPreview = useIsPreview();\n useFocusEffect(() => {\n if (!isPreview) {\n try {\n router.replace(href, { relativeToDirectory, withAnchor });\n } catch (error) {\n console.error(error);\n }\n }\n });\n return null;\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { Href } from '../../types';
2
+ export declare function HrefPreview({ href }: {
3
+ href: Href;
4
+ }): import("react").JSX.Element | null;
5
+ //# sourceMappingURL=HrefPreview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HrefPreview.d.ts","sourceRoot":"","sources":["../../../src/link/preview/HrefPreview.tsx"],"names":[],"mappings":"AAYA,OAAO,EAAE,IAAI,EAAuB,MAAM,aAAa,CAAC;AAMxD,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,sCA+BnD"}