import { Link04Icon } from '@expo/styleguide-icons'; import React, { PropsWithChildren } from 'react'; import { SnippetHeader } from '../Snippet/SnippetHeader'; import { RuntimePopup } from './RuntimePopup'; type ProtocolType = 'expo-go' | 'custom' | 'web'; const mapping: { name: string; id: ProtocolType }[] = [ { name: 'Expo Go', id: 'expo-go' }, { name: 'Custom', id: 'custom' }, { name: 'Web', id: 'web' }, ]; const SharedContext = React.createContext<{ type: ProtocolType; setType: (type: ProtocolType) => void; } | null>(null); /** * Wraps a group of route urls and shares the preference. */ export function RouteUrlGroup({ children }: { children: React.ReactNode }) { const [type, setType] = React.useState('custom'); return {children}; } function getProtocol(type: ProtocolType) { return { 'expo-go': 'exp://127.0.0.1:8081/--/', web: 'acme.dev/', custom: 'acme://' }[type]; } export const RouteUrl = (props: PropsWithChildren) => { const context = React.useContext(SharedContext); const [type, setType] = React.useState('custom'); if (context) { return ; } return ; }; const RouteUrlInner = ({ children, type, setType, }: PropsWithChildren<{ type: ProtocolType; setType: (type: ProtocolType) => void }>) => { const protocol = getProtocol(type); const childrenString = React.useMemo( () => React.Children.map(children, child => { // return strings if (typeof child === 'string') { return child; } return null; }) ?.filter(Boolean) .join('') .trim() || '/', [children] ); const [parsedProtocol, inputUrl] = React.useMemo<[string, string]>(() => { if (type === 'custom') { if (childrenString === '/') { // remove last slash return [protocol.replace(/\/$/, ''), childrenString]; } else { // ensure no starting slashes return [protocol, childrenString.replace(/^\/+/, '')]; } } // remove last slash return [protocol.replace(/\/$/, ''), childrenString]; }, [type, childrenString, protocol]); return ( {parsedProtocol} {inputUrl} } Icon={Link04Icon}> setType(value)} /> ); };