import * as WebBrowser from "expo-web-browser"; import { WebBrowserPresentationStyle } from "expo-web-browser"; import type { ComponentProps, FunctionComponent, ReactNode } from "react"; import { Linking } from "react-native"; import type { GestureResponderEvent } from "react-native"; import { useColorVariable } from "../core/useColorToken"; import type { ExternalOpenLinkBehavior } from "./ExternalLink.shared"; export interface ExternalLinkRequiredComponentProps { onPress?: (event: GestureResponderEvent) => Promise | void; } const useOpenExternalLink = () => { const textSharp = useColorVariable("text-sharp"); const bgSurface = useColorVariable("bg-surface"); return async (href: string, openLinkBehavior: ExternalOpenLinkBehavior) => { switch (openLinkBehavior.native) { case "webBrowser": { return WebBrowser.openBrowserAsync(href, { controlsColor: textSharp, dismissButtonStyle: "close", presentationStyle: WebBrowserPresentationStyle.PAGE_SHEET, toolbarColor: bgSurface, secondaryToolbarColor: bgSurface, readerMode: false, enableBarCollapsing: false, showTitle: true, enableDefaultShareMenuItem: true, }); } case "linking": { return Linking.openURL(href); } default: { throw new Error( `Unsupported openLinkBehavior.native: ${openLinkBehavior.native as string}`, ); } } }; }; export interface ExternalLinkProps> { as: C; href: string; onPress?: (event: GestureResponderEvent) => void; openLinkBehavior: ExternalOpenLinkBehavior; } type ExternalLinkSpreadProps> = Omit< ComponentProps, keyof ExternalLinkProps >; export function ExternalLink>({ as: C, href, openLinkBehavior, onPress, ...props }: ExternalLinkProps & ExternalLinkSpreadProps): ReactNode { const openExternalLink = useOpenExternalLink(); const handlePress: ExternalLinkRequiredComponentProps["onPress"] = (e) => { if (onPress) { onPress(e); if (e?.defaultPrevented) return; } if (!href) return; return openExternalLink(href, openLinkBehavior); }; return ; }