1import { css } from '@emotion/react'; 2import { theme, typography } from '@expo/styleguide'; 3import * as React from 'react'; 4 5import { PageApiVersionContext } from '~/providers/page-api-version'; 6import { usePageMetadata } from '~/providers/page-metadata'; 7import { Terminal } from '~/ui/components/Snippet'; 8 9const STYLES_P = css` 10 line-height: 1.8rem; 11 margin-top: 1.4rem; 12 margin-bottom: 1.4rem; 13 color: ${theme.text.default}; 14`; 15 16const STYLES_BOLD = css` 17 font-family: ${typography.fontFaces.medium}; 18 font-weight: 400; 19 text-decoration: none; 20 color: ${theme.link.default}; 21 :hover { 22 text-decoration: underline; 23 } 24`; 25const STYLES_LINK = css` 26 text-decoration: none; 27 color: ${theme.link.default}; 28 :hover { 29 text-decoration: underline; 30 } 31`; 32 33type InstallSectionProps = React.PropsWithChildren<{ 34 packageName: string; 35 hideBareInstructions?: boolean; 36 cmd?: string[]; 37 href?: string; 38}>; 39 40const getPackageLink = (packageNames: string) => 41 `https://github.com/expo/expo/tree/main/packages/${packageNames.split(' ')[0]}`; 42 43function getInstallCmd(packageName: string) { 44 return `$ npx expo install ${packageName}`; 45} 46 47const InstallSection = ({ 48 packageName, 49 hideBareInstructions = false, 50 cmd = [getInstallCmd(packageName)], 51 href = getPackageLink(packageName), 52}: InstallSectionProps) => { 53 const { sourceCodeUrl } = usePageMetadata(); 54 const { version } = React.useContext(PageApiVersionContext); 55 56 // Recommend just `expo install` for SDK 43, 44, and 45. 57 // TODO: remove this when we drop SDK 45 from docs 58 if (version.startsWith('v43') || version.startsWith('v44') || version.startsWith('v45')) { 59 if (cmd[0] === getInstallCmd(packageName)) { 60 cmd[0] = cmd[0].replace('npx expo', 'expo'); 61 } 62 } 63 64 return ( 65 <> 66 <Terminal cmd={cmd} /> 67 {hideBareInstructions ? null : ( 68 <p css={STYLES_P}> 69 If you're installing this in a{' '} 70 <a css={STYLES_LINK} href="/introduction/managed-vs-bare/#bare-workflow"> 71 bare React Native app 72 </a> 73 , you should also follow{' '} 74 <a css={STYLES_BOLD} href={sourceCodeUrl ?? href}> 75 these additional installation instructions 76 </a> 77 . 78 </p> 79 )} 80 </> 81 ); 82}; 83 84export default InstallSection; 85 86export const APIInstallSection = (props: InstallSectionProps) => { 87 const { packageName } = usePageMetadata(); 88 return <InstallSection {...props} packageName={props.packageName ?? packageName} />; 89}; 90