expo-router 5.2.0-canary-20250729-d8899ae → 6.0.0-beta.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/_ctx.android.js +1 -1
- package/_ctx.ios.js +1 -1
- package/_ctx.web.js +1 -1
- package/assets/modal.module.css +12 -3
- package/build/ExpoRoot.d.ts.map +1 -1
- package/build/ExpoRoot.js +12 -2
- package/build/ExpoRoot.js.map +1 -1
- package/build/Route.d.ts +9 -0
- package/build/Route.d.ts.map +1 -1
- package/build/Route.js.map +1 -1
- package/build/constants.d.ts +2 -0
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +3 -1
- package/build/constants.js.map +1 -1
- package/build/doctor/index.d.ts +1 -1
- package/build/doctor/index.d.ts.map +1 -1
- package/build/doctor/index.js +4 -1
- package/build/doctor/index.js.map +1 -1
- package/build/exports.d.ts +2 -2
- package/build/exports.d.ts.map +1 -1
- package/build/exports.js +6 -6
- package/build/exports.js.map +1 -1
- package/build/fork/native-stack/createNativeStackNavigator.d.ts +2 -2
- package/build/fork/native-stack/createNativeStackNavigator.d.ts.map +1 -1
- package/build/fork/native-stack/createNativeStackNavigator.js +82 -2
- package/build/fork/native-stack/createNativeStackNavigator.js.map +1 -1
- package/build/fork/useLinking.js +2 -2
- package/build/fork/useLinking.js.map +1 -1
- package/build/getLinkingConfig.d.ts +29 -2
- package/build/getLinkingConfig.d.ts.map +1 -1
- package/build/getLinkingConfig.js +35 -4
- package/build/getLinkingConfig.js.map +1 -1
- package/build/getRoutesCore.d.ts +1 -0
- package/build/getRoutesCore.d.ts.map +1 -1
- package/build/getRoutesCore.js +60 -0
- package/build/getRoutesCore.js.map +1 -1
- package/build/getServerManifest.d.ts +20 -1
- package/build/getServerManifest.d.ts.map +1 -1
- package/build/getServerManifest.js +8 -1
- package/build/getServerManifest.js.map +1 -1
- package/build/global-state/routeInfo.d.ts.map +1 -1
- package/build/global-state/routeInfo.js +12 -1
- package/build/global-state/routeInfo.js.map +1 -1
- package/build/global-state/router-store.d.ts.map +1 -1
- package/build/global-state/router-store.js +4 -0
- package/build/global-state/router-store.js.map +1 -1
- package/build/global-state/routing.d.ts +29 -1
- package/build/global-state/routing.d.ts.map +1 -1
- package/build/global-state/routing.js +78 -42
- package/build/global-state/routing.js.map +1 -1
- package/build/global-state/utils.d.ts +4 -0
- package/build/global-state/utils.d.ts.map +1 -0
- package/build/global-state/utils.js +29 -0
- package/build/global-state/utils.js.map +1 -0
- package/build/hooks.d.ts +1 -1
- package/build/hooks.d.ts.map +1 -1
- package/build/hooks.js +9 -4
- package/build/hooks.js.map +1 -1
- package/build/layouts/DrawerClient.d.ts +2 -2
- package/build/layouts/Stack.web.d.ts +1 -1
- package/build/layouts/Stack.web.d.ts.map +1 -1
- package/build/layouts/Stack.web.js +3 -3
- package/build/layouts/Stack.web.js.map +1 -1
- package/build/layouts/StackClient.d.ts +2 -2
- package/build/layouts/StackClient.d.ts.map +1 -1
- package/build/layouts/StackClient.js +18 -14
- package/build/layouts/StackClient.js.map +1 -1
- package/build/layouts/TabsClient.d.ts +3 -3
- package/build/layouts/withLayoutContext.d.ts.map +1 -1
- package/build/layouts/withLayoutContext.js +13 -0
- package/build/layouts/withLayoutContext.js.map +1 -1
- package/build/link/ExpoLink.d.ts.map +1 -1
- package/build/link/ExpoLink.js +3 -2
- package/build/link/ExpoLink.js.map +1 -1
- package/build/link/InternalLinkPreviewContext.d.ts +6 -0
- package/build/link/InternalLinkPreviewContext.d.ts.map +1 -0
- package/build/link/InternalLinkPreviewContext.js +6 -0
- package/build/link/InternalLinkPreviewContext.js.map +1 -0
- package/build/link/Link.d.ts +2 -67
- package/build/link/Link.d.ts.map +1 -1
- package/build/link/Link.js +5 -70
- package/build/link/Link.js.map +1 -1
- package/build/link/LinkWithPreview.d.ts +1 -46
- package/build/link/LinkWithPreview.d.ts.map +1 -1
- package/build/link/LinkWithPreview.js +30 -114
- package/build/link/LinkWithPreview.js.map +1 -1
- package/build/link/elements.d.ts +174 -0
- package/build/link/elements.d.ts.map +1 -0
- package/build/link/elements.js +172 -0
- package/build/link/elements.js.map +1 -0
- package/build/link/preview/HrefPreview.d.ts +1 -1
- package/build/link/preview/HrefPreview.d.ts.map +1 -1
- package/build/link/preview/HrefPreview.js +61 -7
- package/build/link/preview/HrefPreview.js.map +1 -1
- package/build/link/preview/LinkPreviewContext.d.ts +3 -2
- package/build/link/preview/LinkPreviewContext.d.ts.map +1 -1
- package/build/link/preview/LinkPreviewContext.js +3 -2
- package/build/link/preview/LinkPreviewContext.js.map +1 -1
- package/build/link/preview/native.d.ts +14 -6
- package/build/link/preview/native.d.ts.map +1 -1
- package/build/link/preview/native.js.map +1 -1
- package/build/link/preview/useNextScreenId.d.ts +8 -1
- package/build/link/preview/useNextScreenId.d.ts.map +1 -1
- package/build/link/preview/useNextScreenId.js +36 -32
- package/build/link/preview/useNextScreenId.js.map +1 -1
- package/build/link/preview/utils.d.ts +12 -0
- package/build/link/preview/utils.d.ts.map +1 -0
- package/build/link/preview/utils.js +66 -0
- package/build/link/preview/utils.js.map +1 -0
- package/build/modal/Modal.js +1 -1
- package/build/modal/Modal.js.map +1 -1
- package/build/modal/ModalsRenderer.js +1 -1
- package/build/modal/ModalsRenderer.js.map +1 -1
- package/build/modal/ModalsRenderer.web.js +4 -4
- package/build/modal/ModalsRenderer.web.js.map +1 -1
- package/build/modal/web/{ModalStack.web.d.ts → ModalStack.d.ts} +1 -1
- package/build/modal/web/ModalStack.d.ts.map +1 -0
- package/build/modal/web/{ModalStack.web.js → ModalStack.js} +5 -5
- package/build/modal/web/ModalStack.js.map +1 -0
- package/build/modal/web/{ModalStackRouteDrawer.web.d.ts → ModalStackRouteDrawer.d.ts} +1 -1
- package/build/modal/web/ModalStackRouteDrawer.d.ts.map +1 -0
- package/build/modal/web/{ModalStackRouteDrawer.web.js → ModalStackRouteDrawer.js} +1 -2
- package/build/modal/web/ModalStackRouteDrawer.js.map +1 -0
- package/build/modal/web/{TransparentModalStackRouteDrawer.web.d.ts → TransparentModalStackRouteDrawer.d.ts} +1 -1
- package/build/modal/web/TransparentModalStackRouteDrawer.d.ts.map +1 -0
- package/build/modal/web/{TransparentModalStackRouteDrawer.web.js → TransparentModalStackRouteDrawer.js} +1 -1
- package/build/modal/web/TransparentModalStackRouteDrawer.js.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.d.ts +17 -0
- package/build/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.d.ts.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.js +27 -0
- package/build/native-tabs/NativeBottomTabs/NativeBottomTabsNavigator.js.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeBottomTabsRouter.d.ts +3 -0
- package/build/native-tabs/NativeBottomTabs/NativeBottomTabsRouter.d.ts.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeBottomTabsRouter.js +65 -0
- package/build/native-tabs/NativeBottomTabs/NativeBottomTabsRouter.js.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabTrigger.d.ts +47 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabTrigger.d.ts.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabTrigger.js +153 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabTrigger.js.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabs.d.ts +24 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabs.d.ts.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabs.js +27 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabs.js.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabsView.d.ts +4 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabsView.d.ts.map +1 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabsView.js +116 -0
- package/build/native-tabs/NativeBottomTabs/NativeTabsView.js.map +1 -0
- package/build/native-tabs/NativeBottomTabs/types.d.ts +166 -0
- package/build/native-tabs/NativeBottomTabs/types.d.ts.map +1 -0
- package/build/native-tabs/NativeBottomTabs/types.js +3 -0
- package/build/native-tabs/NativeBottomTabs/types.js.map +1 -0
- package/build/native-tabs/NativeBottomTabs/utils.d.ts +7 -0
- package/build/native-tabs/NativeBottomTabs/utils.d.ts.map +1 -0
- package/build/native-tabs/NativeBottomTabs/utils.js +21 -0
- package/build/native-tabs/NativeBottomTabs/utils.js.map +1 -0
- package/build/native-tabs/common/elements.d.ts +74 -0
- package/build/native-tabs/common/elements.d.ts.map +1 -0
- package/build/native-tabs/common/elements.js +21 -0
- package/build/native-tabs/common/elements.js.map +1 -0
- package/build/native-tabs/index.d.ts +5 -0
- package/build/native-tabs/index.d.ts.map +1 -0
- package/build/native-tabs/index.js +23 -0
- package/build/native-tabs/index.js.map +1 -0
- package/build/routes-manifest.d.ts +42 -0
- package/build/routes-manifest.d.ts.map +1 -1
- package/build/routes-manifest.js.map +1 -1
- package/build/rsc/middleware.d.ts +1 -1
- package/build/rsc/middleware.d.ts.map +1 -1
- package/build/rsc/middleware.js.map +1 -1
- package/build/testing-library/mock-config.d.ts +18 -0
- package/build/testing-library/mock-config.d.ts.map +1 -1
- package/build/testing-library/mock-config.js +4 -1
- package/build/testing-library/mock-config.js.map +1 -1
- package/build/ui/common.d.ts.map +1 -1
- package/build/ui/common.js +7 -6
- package/build/ui/common.js.map +1 -1
- package/build/useNavigation.d.ts.map +1 -1
- package/build/useNavigation.js +8 -5
- package/build/useNavigation.js.map +1 -1
- package/build/views/NoSSR.d.ts +5 -0
- package/build/views/NoSSR.d.ts.map +1 -0
- package/build/views/NoSSR.js +22 -0
- package/build/views/NoSSR.js.map +1 -0
- package/build/views/Screen.d.ts.map +1 -1
- package/build/views/Screen.js +4 -1
- package/build/views/Screen.js.map +1 -1
- package/build/views/Sitemap.d.ts.map +1 -1
- package/build/views/Sitemap.js +113 -10
- package/build/views/Sitemap.js.map +1 -1
- package/build/views/Unmatched.d.ts.map +1 -1
- package/build/views/Unmatched.js +14 -4
- package/build/views/Unmatched.js.map +1 -1
- package/ios/ExpoHead.podspec +10 -1
- package/ios/LinkPreview/LinkPreviewNativeActionView.swift +159 -21
- package/ios/LinkPreview/LinkPreviewNativeModule.swift +44 -6
- package/ios/LinkPreview/LinkPreviewNativeNavigation.h +37 -11
- package/ios/LinkPreview/LinkPreviewNativeNavigation.mm +110 -87
- package/ios/LinkPreview/LinkPreviewNativeNavigation.swift +136 -0
- package/ios/LinkPreview/LinkPreviewNativePreviewView.swift +0 -1
- package/ios/LinkPreview/LinkPreviewNativeTriggerView.swift +1 -1
- package/ios/LinkPreview/LinkPreviewNativeView.swift +72 -71
- package/package.json +42 -10
- package/plugin/build/index.d.ts +2 -0
- package/plugin/options.json +5 -0
- package/plugin/src/index.ts +2 -0
- package/plugin/tsconfig.tsbuildinfo +1 -0
- package/server.d.ts +2 -1
- package/unstable-native-tabs.d.ts +1 -0
- package/unstable-native-tabs.js +1 -0
- package/build/modal/web/ModalStack.web.d.ts.map +0 -1
- package/build/modal/web/ModalStack.web.js.map +0 -1
- package/build/modal/web/ModalStackRouteDrawer.web.d.ts.map +0 -1
- package/build/modal/web/ModalStackRouteDrawer.web.js.map +0 -1
- package/build/modal/web/TransparentModalStackRouteDrawer.web.d.ts.map +0 -1
- package/build/modal/web/TransparentModalStackRouteDrawer.web.js.map +0 -1
package/build/link/Link.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":";;;AAAA,yCAAsC;AACtC,
|
|
1
|
+
{"version":3,"file":"Link.js","sourceRoot":"","sources":["../../src/link/Link.tsx"],"names":[],"mappings":";;;AAAA,yCAAsC;AACtC,yCAAgF;AAChF,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,IAAI,EAAE,mBAAQ;IACd,OAAO,EAAE,sBAAW;IACpB,OAAO,EAAE,sBAAW;IACpB,UAAU,EAAE,yBAAc;CAC3B,CACF,CAAC;AAKF,uCAAqD;AAA5C,oGAAA,QAAQ,OAAA","sourcesContent":["import { ExpoLink } from './ExpoLink';\nimport { LinkMenu, LinkMenuAction, LinkPreview, LinkTrigger } from './elements';\nimport { resolveHref } from './href';\nimport type { 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 Menu: LinkMenu,\n Trigger: LinkTrigger,\n Preview: LinkPreview,\n MenuAction: LinkMenuAction,\n }\n);\n\nexport type LinkComponent = typeof Link;\n\nexport { LinkProps, WebAnchorProps };\nexport { Redirect, RedirectProps } from './Redirect';\n"]}
|
|
@@ -1,49 +1,4 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import type { SFSymbol } from 'sf-symbols-typescript';
|
|
1
|
+
import React from 'react';
|
|
3
2
|
import { LinkProps } from './useLinkHooks';
|
|
4
3
|
export declare function LinkWithPreview({ children, ...rest }: LinkProps): React.JSX.Element;
|
|
5
|
-
interface LinkMenuActionProps {
|
|
6
|
-
/**
|
|
7
|
-
* The title of the menu item.
|
|
8
|
-
*/
|
|
9
|
-
title: string;
|
|
10
|
-
/**
|
|
11
|
-
* Optional SF Symbol displayed alongside the menu item.
|
|
12
|
-
*/
|
|
13
|
-
icon?: SFSymbol;
|
|
14
|
-
onPress: () => void;
|
|
15
|
-
}
|
|
16
|
-
export declare function LinkMenuAction(_: LinkMenuActionProps): null;
|
|
17
|
-
export interface LinkMenuProps {
|
|
18
|
-
/**
|
|
19
|
-
* The title of the menu item
|
|
20
|
-
*/
|
|
21
|
-
title?: string;
|
|
22
|
-
/**
|
|
23
|
-
* Optional SF Symbol displayed alongside the menu item.
|
|
24
|
-
*/
|
|
25
|
-
icon?: string;
|
|
26
|
-
children: ReactElement<LinkMenuActionProps> | ReactElement<LinkMenuActionProps>[];
|
|
27
|
-
}
|
|
28
|
-
export declare const LinkMenu: FC<LinkMenuProps>;
|
|
29
|
-
interface LinkPreviewProps {
|
|
30
|
-
/**
|
|
31
|
-
* Sets the preferred width of the preview.
|
|
32
|
-
* If not set, full width of the screen will be used.
|
|
33
|
-
*
|
|
34
|
-
* This is only **preferred** width, the actual width may be different
|
|
35
|
-
*/
|
|
36
|
-
width?: number;
|
|
37
|
-
/**
|
|
38
|
-
* Sets the preferred height of the preview.
|
|
39
|
-
* If not set, full height of the screen will be used.
|
|
40
|
-
*
|
|
41
|
-
* This is only **preferred** height, the actual height may be different
|
|
42
|
-
*/
|
|
43
|
-
height?: number;
|
|
44
|
-
children?: React.ReactNode;
|
|
45
|
-
}
|
|
46
|
-
export declare function LinkPreview({ children, width, height }: LinkPreviewProps): React.JSX.Element | null;
|
|
47
|
-
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;
|
|
48
|
-
export {};
|
|
49
4
|
//# sourceMappingURL=LinkWithPreview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LinkWithPreview.d.ts","sourceRoot":"","sources":["../../src/link/LinkWithPreview.tsx"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"LinkWithPreview.d.ts","sourceRoot":"","sources":["../../src/link/LinkWithPreview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAON,MAAM,OAAO,CAAC;AAUf,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAK3C,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,EAAE,SAAS,qBAuH/D"}
|
|
@@ -34,25 +34,21 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
};
|
|
35
35
|
})();
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
-
exports.LinkMenu = void 0;
|
|
38
37
|
exports.LinkWithPreview = LinkWithPreview;
|
|
39
|
-
exports.LinkMenuAction = LinkMenuAction;
|
|
40
|
-
exports.LinkPreview = LinkPreview;
|
|
41
|
-
exports.LinkTrigger = LinkTrigger;
|
|
42
38
|
const react_1 = __importStar(require("react"));
|
|
39
|
+
const react_native_1 = require("react-native");
|
|
43
40
|
const hooks_1 = require("../hooks");
|
|
44
41
|
const BaseExpoRouterLink_1 = require("./BaseExpoRouterLink");
|
|
45
|
-
const
|
|
42
|
+
const InternalLinkPreviewContext_1 = require("./InternalLinkPreviewContext");
|
|
43
|
+
const elements_1 = require("./elements");
|
|
46
44
|
const LinkPreviewContext_1 = require("./preview/LinkPreviewContext");
|
|
47
45
|
const native_1 = require("./preview/native");
|
|
48
46
|
const useNextScreenId_1 = require("./preview/useNextScreenId");
|
|
49
47
|
const url_1 = require("../utils/url");
|
|
50
|
-
const
|
|
51
|
-
const Slot_1 = require("../ui/Slot");
|
|
52
|
-
const InternalLinkPreviewContext = (0, react_1.createContext)(undefined);
|
|
48
|
+
const isPad = react_native_1.Platform.OS === 'ios' && react_native_1.Platform.isPad;
|
|
53
49
|
function LinkWithPreview({ children, ...rest }) {
|
|
54
50
|
const router = (0, hooks_1.useRouter)();
|
|
55
|
-
const {
|
|
51
|
+
const { setOpenPreviewKey } = (0, LinkPreviewContext_1.useLinkPreviewContext)();
|
|
56
52
|
const [isCurrentPreviewOpen, setIsCurrenPreviewOpen] = (0, react_1.useState)(false);
|
|
57
53
|
const hrefWithoutQuery = String(rest.href).split('?')[0];
|
|
58
54
|
const prevHrefWithoutQuery = (0, react_1.useRef)(hrefWithoutQuery);
|
|
@@ -66,7 +62,7 @@ function LinkWithPreview({ children, ...rest }) {
|
|
|
66
62
|
prevHrefWithoutQuery.current = hrefWithoutQuery;
|
|
67
63
|
}
|
|
68
64
|
}, [hrefWithoutQuery]);
|
|
69
|
-
const [nextScreenId,
|
|
65
|
+
const [{ nextScreenId, tabPath }, prefetch] = (0, useNextScreenId_1.useNextScreenId)();
|
|
70
66
|
(0, react_1.useEffect)(() => {
|
|
71
67
|
if ((0, url_1.shouldLinkExternally)(String(rest.href))) {
|
|
72
68
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -85,10 +81,10 @@ function LinkWithPreview({ children, ...rest }) {
|
|
|
85
81
|
}
|
|
86
82
|
}
|
|
87
83
|
}, [rest.href, rest.replace]);
|
|
88
|
-
const triggerElement = react_1.default.useMemo(() => getFirstChildOfType(children, LinkTrigger), [children]);
|
|
89
|
-
const menuElement = react_1.default.useMemo(() => getFirstChildOfType(children,
|
|
90
|
-
const previewElement = react_1.default.useMemo(() => getFirstChildOfType(children, LinkPreview), [children]);
|
|
91
|
-
if (previewElement && !triggerElement) {
|
|
84
|
+
const triggerElement = react_1.default.useMemo(() => getFirstChildOfType(children, elements_1.LinkTrigger), [children]);
|
|
85
|
+
const menuElement = react_1.default.useMemo(() => getFirstChildOfType(children, elements_1.LinkMenu), [children]);
|
|
86
|
+
const previewElement = react_1.default.useMemo(() => getFirstChildOfType(children, elements_1.LinkPreview), [children]);
|
|
87
|
+
if ((previewElement || menuElement) && !triggerElement) {
|
|
92
88
|
if (process.env.NODE_ENV !== 'production') {
|
|
93
89
|
throw new Error('When you use Link.Preview, you must use Link.Trigger to specify the trigger element.');
|
|
94
90
|
}
|
|
@@ -96,127 +92,47 @@ function LinkWithPreview({ children, ...rest }) {
|
|
|
96
92
|
console.warn('When you use Link.Preview, you must use Link.Trigger to specify the trigger element.');
|
|
97
93
|
}
|
|
98
94
|
}
|
|
99
|
-
const trigger = react_1.default.useMemo(() => triggerElement ?? <LinkTrigger>{children}</LinkTrigger>, [triggerElement, children]);
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
: {}, [menuElement]);
|
|
103
|
-
const preview = react_1.default.useMemo(() => previewElement ?? <LinkPreview />, [previewElement, rest.href]);
|
|
95
|
+
const trigger = react_1.default.useMemo(() => triggerElement ?? <elements_1.LinkTrigger>{children}</elements_1.LinkTrigger>, [triggerElement, children]);
|
|
96
|
+
const highlightBorderRadius = triggerElement?.props.highlightBorderRadius;
|
|
97
|
+
const preview = react_1.default.useMemo(() => previewElement ?? null, [previewElement, rest.href]);
|
|
104
98
|
const isPreviewTapped = (0, react_1.useRef)(false);
|
|
99
|
+
const tabPathValue = (0, react_1.useMemo)(() => ({
|
|
100
|
+
path: tabPath,
|
|
101
|
+
}), [tabPath]);
|
|
105
102
|
if ((0, url_1.shouldLinkExternally)(String(rest.href)) || rest.replace) {
|
|
106
103
|
return <BaseExpoRouterLink_1.BaseExpoRouterLink children={children} {...rest}/>;
|
|
107
104
|
}
|
|
108
|
-
return (<native_1.NativeLinkPreview nextScreenId={nextScreenId}
|
|
109
|
-
actionsHandlers[id]?.();
|
|
110
|
-
}} onWillPreviewOpen={() => {
|
|
105
|
+
return (<native_1.NativeLinkPreview nextScreenId={isPad ? undefined : nextScreenId} tabPath={isPad ? undefined : tabPathValue} onWillPreviewOpen={() => {
|
|
111
106
|
isPreviewTapped.current = false;
|
|
112
|
-
|
|
113
|
-
setIsPreviewOpen(true);
|
|
107
|
+
prefetch(rest.href);
|
|
114
108
|
setIsCurrenPreviewOpen(true);
|
|
115
|
-
}} onDidPreviewOpen={() => {
|
|
116
|
-
updateNextScreenId(rest.href);
|
|
117
109
|
}} onPreviewWillClose={() => {
|
|
110
|
+
setIsCurrenPreviewOpen(false);
|
|
118
111
|
// When preview was not tapped, then we need to enable the screen stack animation
|
|
119
|
-
// Otherwise
|
|
120
|
-
if (!isPreviewTapped.current) {
|
|
121
|
-
|
|
122
|
-
setIsPreviewOpen(false);
|
|
112
|
+
// Otherwise this will happen in StackNavigator, when new screen is opened
|
|
113
|
+
if (!isPreviewTapped.current || isPad) {
|
|
114
|
+
setOpenPreviewKey(undefined);
|
|
123
115
|
}
|
|
124
116
|
}} onPreviewDidClose={() => {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
if (isPreviewTapped.current) {
|
|
128
|
-
setIsCurrenPreviewOpen(false);
|
|
129
|
-
setIsPreviewOpen(false);
|
|
117
|
+
if (isPreviewTapped.current && isPad) {
|
|
118
|
+
router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });
|
|
130
119
|
}
|
|
131
120
|
}} onPreviewTapped={() => {
|
|
132
121
|
isPreviewTapped.current = true;
|
|
133
|
-
|
|
122
|
+
if (!isPad) {
|
|
123
|
+
router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });
|
|
124
|
+
}
|
|
134
125
|
}}>
|
|
135
|
-
<InternalLinkPreviewContext value={{ isVisible: isCurrentPreviewOpen, href: rest.href }}>
|
|
136
|
-
<native_1.NativeLinkPreviewTrigger>
|
|
126
|
+
<InternalLinkPreviewContext_1.InternalLinkPreviewContext value={{ isVisible: isCurrentPreviewOpen, href: rest.href }}>
|
|
127
|
+
<native_1.NativeLinkPreviewTrigger style={{ borderRadius: highlightBorderRadius }}>
|
|
137
128
|
<BaseExpoRouterLink_1.BaseExpoRouterLink {...rest} children={trigger} ref={rest.ref}/>
|
|
138
129
|
</native_1.NativeLinkPreviewTrigger>
|
|
139
130
|
{preview}
|
|
140
131
|
{menuElement}
|
|
141
|
-
</InternalLinkPreviewContext>
|
|
132
|
+
</InternalLinkPreviewContext_1.InternalLinkPreviewContext>
|
|
142
133
|
</native_1.NativeLinkPreview>);
|
|
143
134
|
}
|
|
144
|
-
function LinkMenuAction(_) {
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
const LinkMenu = (props) => {
|
|
148
|
-
if ((0, PreviewRouteContext_1.useIsPreview)() || process.env.EXPO_OS !== 'ios' || !(0, react_1.use)(InternalLinkPreviewContext)) {
|
|
149
|
-
return null;
|
|
150
|
-
}
|
|
151
|
-
return convertActionsToNativeElements(convertChildrenArrayToActions([(0, react_1.createElement)(exports.LinkMenu, props, props.children)]));
|
|
152
|
-
};
|
|
153
|
-
exports.LinkMenu = LinkMenu;
|
|
154
|
-
function convertActionsToNativeElements(actions) {
|
|
155
|
-
return actions.map(({ children, onPress, ...props }) => (<native_1.NativeLinkPreviewAction {...props} key={props.id} children={convertActionsToNativeElements(children)}/>));
|
|
156
|
-
}
|
|
157
|
-
function LinkPreview({ children, width, height }) {
|
|
158
|
-
const internalPreviewContext = (0, react_1.use)(InternalLinkPreviewContext);
|
|
159
|
-
if ((0, PreviewRouteContext_1.useIsPreview)() || process.env.EXPO_OS !== 'ios' || !internalPreviewContext) {
|
|
160
|
-
return null;
|
|
161
|
-
}
|
|
162
|
-
const { isVisible, href } = internalPreviewContext;
|
|
163
|
-
const contentSize = {
|
|
164
|
-
width: width ?? 0,
|
|
165
|
-
height: height ?? 0,
|
|
166
|
-
};
|
|
167
|
-
let content;
|
|
168
|
-
if (children) {
|
|
169
|
-
content = isVisible ? children : null;
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
content = isVisible ? <HrefPreview_1.HrefPreview href={href}/> : null;
|
|
173
|
-
}
|
|
174
|
-
return (<native_1.NativeLinkPreviewContent style={{
|
|
175
|
-
/* Setting default background here, so that the preview is not transparent */
|
|
176
|
-
backgroundColor: '#fff',
|
|
177
|
-
}} preferredContentSize={contentSize}>
|
|
178
|
-
{content}
|
|
179
|
-
</native_1.NativeLinkPreviewContent>);
|
|
180
|
-
}
|
|
181
|
-
function LinkTrigger(props) {
|
|
182
|
-
if (react_1.default.Children.count(props.children) > 1 || !(0, react_1.isValidElement)(props.children)) {
|
|
183
|
-
// If onPress is passed, this means that Link passed props to this component.
|
|
184
|
-
// We can assume that asChild is used, so we throw an error, because link will not work in this case.
|
|
185
|
-
if (props && typeof props === 'object' && 'onPress' in props) {
|
|
186
|
-
throw new Error('When using Link.Trigger in an asChild Link, you must pass a single child element that will emit onPress event.');
|
|
187
|
-
}
|
|
188
|
-
return props.children;
|
|
189
|
-
}
|
|
190
|
-
return <Slot_1.Slot {...props}/>;
|
|
191
|
-
}
|
|
192
135
|
function getFirstChildOfType(children, type) {
|
|
193
136
|
return react_1.default.Children.toArray(children).find((child) => (0, react_1.isValidElement)(child) && child.type === type);
|
|
194
137
|
}
|
|
195
|
-
function convertActionsToActionsHandlers(items) {
|
|
196
|
-
return flattenActions(items ?? []).reduce((acc, item) => ({
|
|
197
|
-
...acc,
|
|
198
|
-
[item.id]: item.onPress,
|
|
199
|
-
}), {});
|
|
200
|
-
}
|
|
201
|
-
function flattenActions(actions) {
|
|
202
|
-
return actions.reduce((acc, action) => {
|
|
203
|
-
if (action.children.length > 0) {
|
|
204
|
-
return [...acc, action, ...flattenActions(action.children)];
|
|
205
|
-
}
|
|
206
|
-
return [...acc, action];
|
|
207
|
-
}, []);
|
|
208
|
-
}
|
|
209
|
-
function convertChildrenArrayToActions(children, parentId = '') {
|
|
210
|
-
return children
|
|
211
|
-
.filter((item) => (0, react_1.isValidElement)(item) && (item.type === LinkMenuAction || item.type === exports.LinkMenu))
|
|
212
|
-
.map((child, index) => ({
|
|
213
|
-
id: `${parentId}${child.props.title}-${index}`,
|
|
214
|
-
title: child.props.title ?? '',
|
|
215
|
-
onPress: 'onPress' in child.props ? child.props.onPress : () => { },
|
|
216
|
-
icon: child.props.icon,
|
|
217
|
-
children: 'children' in child.props
|
|
218
|
-
? convertChildrenArrayToActions(react_1.default.Children.toArray(child.props.children), `${parentId}${child.props.title}-${index}`)
|
|
219
|
-
: [],
|
|
220
|
-
}));
|
|
221
|
-
}
|
|
222
138
|
//# sourceMappingURL=LinkWithPreview.js.map
|
|
@@ -1 +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 createElement,\n isValidElement,\n use,\n useEffect,\n useRef,\n useState,\n type FC,\n type PropsWithChildren,\n type ReactElement,\n} from 'react';\nimport type { SFSymbol } from 'sf-symbols-typescript';\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 type NativeLinkPreviewActionProps,\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 menuElement\n ? convertActionsToActionsHandlers(convertChildrenArrayToActions([menuElement]))\n : {},\n [menuElement]\n );\n const preview = React.useMemo(\n () => previewElement ?? <LinkPreview />,\n [previewElement, rest.href]\n );\n\n const isPreviewTapped = useRef(false);\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 isPreviewTapped.current = false;\n router.prefetch(rest.href);\n setIsPreviewOpen(true);\n setIsCurrenPreviewOpen(true);\n }}\n onDidPreviewOpen={() => {\n updateNextScreenId(rest.href);\n }}\n onPreviewWillClose={() => {\n // When preview was not tapped, then we need to enable the screen stack animation\n // Otherwise a quick user could tap another link before onDidPreviewClose is called\n if (!isPreviewTapped.current) {\n setIsCurrenPreviewOpen(false);\n setIsPreviewOpen(false);\n }\n }}\n onPreviewDidClose={() => {\n // If preview was tapped we need to enable the screen stack animation\n // For other cases we did it in onPreviewWillClose\n if (isPreviewTapped.current) {\n setIsCurrenPreviewOpen(false);\n setIsPreviewOpen(false);\n }\n }}\n onPreviewTapped={() => {\n isPreviewTapped.current = true;\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 LinkMenuActionProps {\n /**\n * The title of the menu item.\n */\n title: string;\n /**\n * Optional SF Symbol displayed alongside the menu item.\n */\n icon?: SFSymbol;\n onPress: () => void;\n}\n\nexport function LinkMenuAction(_: LinkMenuActionProps) {\n return null;\n}\n\nexport interface LinkMenuProps {\n /**\n * The title of the menu item\n */\n title?: string;\n /**\n * Optional SF Symbol displayed alongside the menu item.\n */\n icon?: string;\n children: ReactElement<LinkMenuActionProps> | ReactElement<LinkMenuActionProps>[];\n}\n\nexport const LinkMenu: FC<LinkMenuProps> = (props) => {\n if (useIsPreview() || process.env.EXPO_OS !== 'ios' || !use(InternalLinkPreviewContext)) {\n return null;\n }\n return convertActionsToNativeElements(\n convertChildrenArrayToActions([createElement(LinkMenu, props, props.children)])\n );\n};\n\nfunction convertActionsToNativeElements(actions: ConvertChildrenArrayToActionsReturnType) {\n return actions.map(({ children, onPress, ...props }) => (\n <NativeLinkPreviewAction\n {...props}\n key={props.id}\n children={convertActionsToNativeElements(children)}\n />\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() || process.env.EXPO_OS !== 'ios' || !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: ConvertChildrenArrayToActionsReturnType | undefined\n) {\n return flattenActions(items ?? []).reduce(\n (acc, item) => ({\n ...acc,\n [item.id]: item.onPress,\n }),\n {} as Record<string, () => void>\n );\n}\n\nfunction flattenActions(\n actions: ConvertChildrenArrayToActionsReturnType\n): ConvertChildrenArrayToActionsReturnType {\n return actions.reduce((acc, action) => {\n if (action.children.length > 0) {\n return [...acc, action, ...flattenActions(action.children)];\n }\n return [...acc, action];\n }, [] as ConvertChildrenArrayToActionsReturnType);\n}\n\ntype ConvertChildrenArrayToActionsReturnType = (Omit<NativeLinkPreviewActionProps, 'children'> & {\n onPress: () => void;\n children: ConvertChildrenArrayToActionsReturnType;\n})[];\n\nfunction convertChildrenArrayToActions(\n children: ReturnType<typeof React.Children.toArray>,\n parentId: string = ''\n): ConvertChildrenArrayToActionsReturnType {\n return children\n .filter(\n (item): item is ReactElement<LinkMenuActionProps | LinkMenuProps> =>\n isValidElement(item) && (item.type === LinkMenuAction || item.type === LinkMenu)\n )\n .map((child, index) => ({\n id: `${parentId}${child.props.title}-${index}`,\n title: child.props.title ?? '',\n onPress: 'onPress' in child.props ? child.props.onPress : () => {},\n icon: child.props.icon,\n children:\n 'children' in child.props\n ? convertChildrenArrayToActions(\n React.Children.toArray(child.props.children),\n `${parentId}${child.props.title}-${index}`\n )\n : [],\n }));\n}\n"]}
|
|
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 isValidElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n} from 'react';\nimport { Platform } from 'react-native';\n\nimport { useRouter } from '../hooks';\nimport { BaseExpoRouterLink } from './BaseExpoRouterLink';\nimport { InternalLinkPreviewContext } from './InternalLinkPreviewContext';\nimport { LinkMenu, LinkPreview, LinkTrigger } from './elements';\nimport { useLinkPreviewContext } from './preview/LinkPreviewContext';\nimport { NativeLinkPreview, NativeLinkPreviewTrigger } from './preview/native';\nimport { useNextScreenId } from './preview/useNextScreenId';\nimport { LinkProps } from './useLinkHooks';\nimport { shouldLinkExternally } from '../utils/url';\n\nconst isPad = Platform.OS === 'ios' && Platform.isPad;\n\nexport function LinkWithPreview({ children, ...rest }: LinkProps) {\n const router = useRouter();\n const { setOpenPreviewKey } = 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, tabPath }, prefetch] = 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 || menuElement) && !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 const highlightBorderRadius = triggerElement?.props.highlightBorderRadius;\n\n const preview = React.useMemo(() => previewElement ?? null, [previewElement, rest.href]);\n\n const isPreviewTapped = useRef(false);\n\n const tabPathValue = useMemo(\n () => ({\n path: tabPath,\n }),\n [tabPath]\n );\n\n if (shouldLinkExternally(String(rest.href)) || rest.replace) {\n return <BaseExpoRouterLink children={children} {...rest} />;\n }\n\n return (\n <NativeLinkPreview\n nextScreenId={isPad ? undefined : nextScreenId}\n tabPath={isPad ? undefined : tabPathValue}\n onWillPreviewOpen={() => {\n isPreviewTapped.current = false;\n prefetch(rest.href);\n setIsCurrenPreviewOpen(true);\n }}\n onPreviewWillClose={() => {\n setIsCurrenPreviewOpen(false);\n // When preview was not tapped, then we need to enable the screen stack animation\n // Otherwise this will happen in StackNavigator, when new screen is opened\n if (!isPreviewTapped.current || isPad) {\n setOpenPreviewKey(undefined);\n }\n }}\n onPreviewDidClose={() => {\n if (isPreviewTapped.current && isPad) {\n router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });\n }\n }}\n onPreviewTapped={() => {\n isPreviewTapped.current = true;\n if (!isPad) {\n router.navigate(rest.href, { __internal__PreviewKey: nextScreenId });\n }\n }}>\n <InternalLinkPreviewContext value={{ isVisible: isCurrentPreviewOpen, href: rest.href }}>\n <NativeLinkPreviewTrigger style={{ borderRadius: highlightBorderRadius }}>\n <BaseExpoRouterLink {...rest} children={trigger} ref={rest.ref} />\n </NativeLinkPreviewTrigger>\n {preview}\n {menuElement}\n </InternalLinkPreviewContext>\n </NativeLinkPreview>\n );\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"]}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import React, { type PropsWithChildren, type ReactElement } from 'react';
|
|
2
|
+
import type { SFSymbol } from 'sf-symbols-typescript';
|
|
3
|
+
export interface LinkMenuActionProps {
|
|
4
|
+
/**
|
|
5
|
+
* The title of the menu item.
|
|
6
|
+
*/
|
|
7
|
+
title: string;
|
|
8
|
+
/**
|
|
9
|
+
* Optional SF Symbol displayed alongside the menu item.
|
|
10
|
+
*/
|
|
11
|
+
icon?: SFSymbol;
|
|
12
|
+
/**
|
|
13
|
+
* If `true`, the menu item will be disabled and not selectable.
|
|
14
|
+
*
|
|
15
|
+
* @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/disabled) for more information.
|
|
16
|
+
*/
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* If `true`, the menu item will be displayed as destructive.
|
|
20
|
+
*
|
|
21
|
+
* @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/destructive) for more information.
|
|
22
|
+
*/
|
|
23
|
+
destructive?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* If `true`, the menu will be kept presented after the action is selected.
|
|
26
|
+
*
|
|
27
|
+
* This is marked as unstable, because when action is selected it will recreate the menu,
|
|
28
|
+
* which will close all opened submenus and reset the scroll position.
|
|
29
|
+
*
|
|
30
|
+
* @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenuelement/attributes/keepsmenupresented) for more information.
|
|
31
|
+
*/
|
|
32
|
+
unstable_keepPresented?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* If `true`, the menu item will be displayed as selected.
|
|
35
|
+
*/
|
|
36
|
+
isOn?: boolean;
|
|
37
|
+
onPress: () => void;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* This component renders a context menu action for a link.
|
|
41
|
+
* It should only be used as a child of `Link.Menu` or `LinkMenu`.
|
|
42
|
+
*
|
|
43
|
+
* > **Note**: You can use the alias `Link.MenuAction` for this component.
|
|
44
|
+
*
|
|
45
|
+
* @platform ios
|
|
46
|
+
*/
|
|
47
|
+
export declare function LinkMenuAction(props: LinkMenuActionProps): React.JSX.Element | null;
|
|
48
|
+
export interface LinkMenuProps {
|
|
49
|
+
/**
|
|
50
|
+
* The title of the menu item
|
|
51
|
+
*/
|
|
52
|
+
title?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Optional SF Symbol displayed alongside the menu item.
|
|
55
|
+
*/
|
|
56
|
+
icon?: string;
|
|
57
|
+
/**
|
|
58
|
+
* If `true`, the menu will be displayed as a palette.
|
|
59
|
+
* This means that the menu will be displayed as one row
|
|
60
|
+
*
|
|
61
|
+
* @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayaspalette) for more information.
|
|
62
|
+
*/
|
|
63
|
+
displayAsPalette?: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* If `true`, the menu will be displayed inline.
|
|
66
|
+
* This means that the menu will not be collapsed
|
|
67
|
+
*
|
|
68
|
+
* @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/displayinline) for more information.
|
|
69
|
+
*/
|
|
70
|
+
displayInline?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* If `true`, the menu item will be displayed as destructive.
|
|
73
|
+
*
|
|
74
|
+
* @see [Apple documentation](https://developer.apple.com/documentation/uikit/uimenu/options-swift.struct/destructive) for more information.
|
|
75
|
+
*/
|
|
76
|
+
destructive?: boolean;
|
|
77
|
+
children: ReactElement<LinkMenuActionProps> | ReactElement<LinkMenuActionProps>[];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Groups context menu actions for a link.
|
|
81
|
+
*
|
|
82
|
+
* If multiple `Link.Menu` components are used within a single `Link`, only the first will be rendered.
|
|
83
|
+
* Only `Link.MenuAction` and `LinkMenuAction` components are allowed as children.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* <Link.Menu>
|
|
88
|
+
* <Link.MenuAction title="Action 1" onPress={() => {}} />
|
|
89
|
+
* <Link.MenuAction title="Action 2" onPress={() => {}} />
|
|
90
|
+
* </Link.Menu>
|
|
91
|
+
* ```
|
|
92
|
+
*
|
|
93
|
+
* > **Note**: You can use the alias `Link.Menu` for this component.
|
|
94
|
+
*
|
|
95
|
+
* @platform ios
|
|
96
|
+
*/
|
|
97
|
+
export declare const LinkMenu: React.FC<LinkMenuProps>;
|
|
98
|
+
export interface LinkPreviewProps {
|
|
99
|
+
/**
|
|
100
|
+
* Sets the preferred width of the preview.
|
|
101
|
+
* If not set, full width of the screen will be used.
|
|
102
|
+
*
|
|
103
|
+
* This is only **preferred** width, the actual width may be different
|
|
104
|
+
*/
|
|
105
|
+
width?: number;
|
|
106
|
+
/**
|
|
107
|
+
* Sets the preferred height of the preview.
|
|
108
|
+
* If not set, full height of the screen will be used.
|
|
109
|
+
*
|
|
110
|
+
* This is only **preferred** height, the actual height may be different
|
|
111
|
+
*/
|
|
112
|
+
height?: number;
|
|
113
|
+
children?: React.ReactNode;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* A component used to render and customize the link preview.
|
|
117
|
+
*
|
|
118
|
+
* If `Link.Preview` is used without any props, it will render a preview of the `href` passed to the `Link`.
|
|
119
|
+
*
|
|
120
|
+
* If multiple `Link.Preview` components are used within a single `Link`, only the first one will be rendered.
|
|
121
|
+
*
|
|
122
|
+
* To customize the preview, you can pass custom content as children.
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```tsx
|
|
126
|
+
* <Link href="/about">
|
|
127
|
+
* <Link.Preview>
|
|
128
|
+
* <Text>Custom Preview Content</Text>
|
|
129
|
+
* </Link.Trigger>
|
|
130
|
+
* </Link>
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* ```tsx
|
|
135
|
+
* <Link href="/about">
|
|
136
|
+
* <Link.Preview />
|
|
137
|
+
* </Link>
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* > **Note**: You can use the alias `Link.Preview` for this component.
|
|
141
|
+
*
|
|
142
|
+
* @platform ios
|
|
143
|
+
*/
|
|
144
|
+
export declare function LinkPreview(props: LinkPreviewProps): React.JSX.Element | null;
|
|
145
|
+
export interface LinkTriggerProps extends PropsWithChildren {
|
|
146
|
+
/**
|
|
147
|
+
* Sets the corner radius of the highlight — the element that appears during a long press,
|
|
148
|
+
* before the preview shows, and beside the context menu if no preview is displayed.
|
|
149
|
+
*
|
|
150
|
+
* @platform ios
|
|
151
|
+
*/
|
|
152
|
+
highlightBorderRadius?: number;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Serves as the trigger for a link.
|
|
156
|
+
* The content inside this component will be rendered as part of the base link.
|
|
157
|
+
*
|
|
158
|
+
* If multiple `Link.Trigger` components are used within a single `Link`, only the first will be rendered.
|
|
159
|
+
*
|
|
160
|
+
* @example
|
|
161
|
+
* ```tsx
|
|
162
|
+
* <Link href="/about">
|
|
163
|
+
* <Link.Trigger>
|
|
164
|
+
* Trigger
|
|
165
|
+
* </Link.Trigger>
|
|
166
|
+
* </Link>
|
|
167
|
+
* ```
|
|
168
|
+
*
|
|
169
|
+
* > **Note**: You can use the alias `Link.Trigger` for this component.
|
|
170
|
+
*
|
|
171
|
+
* @platform ios
|
|
172
|
+
*/
|
|
173
|
+
export declare function LinkTrigger(props: LinkTriggerProps): 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;
|
|
174
|
+
//# sourceMappingURL=elements.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"elements.d.ts","sourceRoot":"","sources":["../../src/link/elements.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAuB,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,OAAO,CAAC;AAC9F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAQtD,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;OAOG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,4BAYxD;AAED,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,YAAY,CAAC,mBAAmB,CAAC,GAAG,YAAY,CAAC,mBAAmB,CAAC,EAAE,CAAC;CACnF;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAe5C,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B;;;;;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;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,4BA4BlD;AAED,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,mSAYlD"}
|