1import { css } from '@emotion/react'; 2import { 3 borderRadius, 4 spacing, 5 theme, 6 ArrowRightIcon, 7 iconSize, 8 shadows, 9 ArrowUpRightIcon, 10 breakpoints, 11} from '@expo/styleguide'; 12import type { IconProps } from '@expo/styleguide/dist/types'; 13import React, { ComponentType, PropsWithChildren, ReactNode } from 'react'; 14 15import { A, DEMI, P } from '~/ui/components/Text'; 16 17type BoxLinkProps = PropsWithChildren<{ 18 title: string; 19 description: string | ReactNode; 20 href?: string; 21 testID?: string; 22 Icon?: ComponentType<IconProps>; 23}>; 24 25export function BoxLink({ title, description, href, testID, Icon }: BoxLinkProps) { 26 const isExternal = Boolean(href && href.startsWith('http')); 27 const ArrowIcon = isExternal ? ArrowUpRightIcon : ArrowRightIcon; 28 return ( 29 <A href={href} css={tileContainerStyle} data-testid={testID} openInNewTab={isExternal} isStyled> 30 <div css={tileContentWrapperStyle}> 31 {Icon && ( 32 <div css={tileIconBackgroundStyle}> 33 <Icon width={iconSize.md} /> 34 </div> 35 )} 36 <div> 37 <DEMI>{title}</DEMI> 38 <P>{description}</P> 39 </div> 40 </div> 41 <ArrowIcon css={arrowIconStyle} color={theme.icon.secondary} /> 42 </A> 43 ); 44} 45 46const tileContainerStyle = css({ 47 display: 'flex', 48 flexDirection: 'row', 49 justifyContent: 'space-between', 50 border: `1px solid ${theme.border.default}`, 51 borderRadius: borderRadius.md, 52 padding: `${spacing[3]}px ${spacing[4]}px`, 53 marginBottom: spacing[3], 54 55 ':hover': { 56 boxShadow: shadows.xs, 57 }, 58}); 59 60const tileContentWrapperStyle = css({ 61 display: 'flex', 62 flexDirection: 'row', 63 gap: spacing[4], 64}); 65 66const tileIconBackgroundStyle = css({ 67 display: 'flex', 68 backgroundColor: theme.background.element, 69 borderRadius: borderRadius.md, 70 alignSelf: 'center', 71 alignItems: 'center', 72 justifyContent: 'center', 73 minWidth: 36, 74 height: 36, 75 76 [`@media screen and (max-width: ${(breakpoints.medium + breakpoints.large) / 2}px)`]: { 77 alignSelf: 'flex-start', 78 }, 79}); 80 81const arrowIconStyle = css({ 82 alignSelf: 'center', 83 alignContent: 'flex-end', 84 minWidth: iconSize.md, 85 marginLeft: spacing[3], 86}); 87