1import { css } from '@emotion/react'; 2import { shadows, theme, typography } from '@expo/styleguide'; 3import { borderRadius, breakpoints, palette, spacing } from '@expo/styleguide-base'; 4import { ArrowRightIcon, ArrowUpRightIcon } from '@expo/styleguide-icons'; 5import { PropsWithChildren } from 'react'; 6import { Col, ColProps } from 'react-grid-system'; 7 8import { A, P } from '~/ui/components/Text'; 9 10const CustomCol = ({ children, sm, md, lg, xl, xxl }: PropsWithChildren<ColProps>) => ( 11 <> 12 <Col css={cellWrapperStyle} sm={sm} md={md} lg={lg} xl={xl} xxl={xxl}> 13 {children} 14 </Col> 15 <div css={mobileCellWrapperStyle}>{children}</div> 16 </> 17); 18 19export const GridCell = ({ 20 children, 21 sm, 22 md, 23 lg, 24 xl, 25 xxl, 26 className, 27}: PropsWithChildren<ColProps>) => ( 28 <CustomCol css={cellWrapperStyle} sm={sm} md={md} lg={lg} xl={xl} xxl={xxl}> 29 <div css={cellStyle} className={className}> 30 {children} 31 </div> 32 </CustomCol> 33); 34 35type APIGridCellProps = ColProps & { 36 icon?: string | JSX.Element; 37 title?: string; 38 link?: string; 39}; 40 41export const APIGridCell = ({ 42 icon, 43 title, 44 link, 45 className, 46 sm = 6, 47 md = 6, 48 lg = 6, 49 xl = 3, 50}: APIGridCellProps) => ( 51 <CustomCol css={cellWrapperStyle} md={md} sm={sm} lg={lg} xl={xl}> 52 <A href={link} css={[cellStyle, cellAPIStyle, cellHoverStyle]} className={className} isStyled> 53 <div css={cellIconWrapperStyle}>{icon}</div> 54 <div css={cellTitleWrapperStyle}> 55 {title} 56 <ArrowRightIcon className="text-icon-secondary" /> 57 </div> 58 </A> 59 </CustomCol> 60); 61 62type CommunityGridCellProps = APIGridCellProps & { 63 description?: string; 64 iconBackground?: string; 65}; 66 67export const CommunityGridCell = ({ 68 icon, 69 iconBackground = palette.light.gray11, 70 title, 71 link, 72 description, 73 className, 74 md = 6, 75}: CommunityGridCellProps) => ( 76 <CustomCol css={cellWrapperStyle} md={md}> 77 <A 78 href={link} 79 css={[cellStyle, cellCommunityStyle, cellCommunityHoverStyle]} 80 className={className} 81 isStyled> 82 <div css={[cellCommunityIconWrapperStyle, css({ backgroundColor: iconBackground })]}> 83 {icon} 84 </div> 85 <div css={cellCommunityContentStyle}> 86 <span css={cellCommunityTitleStyle}>{title}</span> 87 <P css={cellCommunityDescriptionStyle}>{description}</P> 88 </div> 89 <ArrowUpRightIcon className="text-icon-secondary self-center ml-1.5" /> 90 </A> 91 </CustomCol> 92); 93 94const cellWrapperStyle = css` 95 padding-left: 0 !important; 96 padding-right: 0 !important; 97 98 @media screen and (max-width: ${breakpoints.medium}px) { 99 display: none; 100 } 101`; 102 103const mobileCellWrapperStyle = css({ 104 width: '100%', 105 106 [`@media screen and (min-width: ${breakpoints.medium}px)`]: { 107 display: 'none', 108 }, 109}); 110 111const cellHoverStyle = css` 112 & { 113 transition: box-shadow 200ms; 114 115 svg { 116 transition: transform 200ms; 117 } 118 } 119 120 &:hover { 121 box-shadow: ${shadows.sm}; 122 123 svg { 124 transform: scale(1.05); 125 } 126 127 svg[role='img'] { 128 transform: none; 129 } 130 } 131`; 132 133const cellStyle = css({ 134 margin: spacing[4], 135 padding: spacing[8], 136 minHeight: 200, 137 overflow: 'hidden', 138 position: 'relative', 139 borderWidth: 1, 140 borderStyle: 'solid', 141 borderColor: theme.border.default, 142 borderRadius: borderRadius.lg, 143 144 h2: { 145 marginTop: 0, 146 marginBottom: 0, 147 }, 148 149 h3: { 150 marginTop: 0, 151 }, 152}); 153 154const cellAPIStyle = css({ 155 display: 'block', 156 backgroundColor: theme.background.subtle, 157 padding: 0, 158 overflow: 'hidden', 159 textDecoration: 'none', 160}); 161 162const cellIconWrapperStyle = css({ 163 display: 'flex', 164 minHeight: 136, 165 justifyContent: 'space-around', 166 alignItems: 'center', 167}); 168 169const cellTitleWrapperStyle = css({ 170 ...typography.fontSizes[15], 171 display: 'flex', 172 justifyContent: 'space-between', 173 backgroundColor: theme.background.default, 174 padding: spacing[4], 175 textDecoration: 'none', 176 fontWeight: 500, 177 lineHeight: '30px', 178 color: theme.text.default, 179 alignItems: 'center', 180}); 181 182const cellCommunityStyle = css({ 183 display: 'flex', 184 minHeight: 'unset', 185 padding: spacing[4], 186 margin: `${spacing[3]}px ${spacing[4]}px`, 187 flexDirection: 'row', 188 textDecoration: 'none', 189}); 190 191const cellCommunityIconWrapperStyle = css({ 192 height: 48, 193 width: 48, 194 minWidth: 48, 195 display: 'flex', 196 justifyContent: 'center', 197 alignItems: 'center', 198 borderRadius: borderRadius.lg, 199 marginRight: spacing[3], 200}); 201 202const cellCommunityContentStyle = css({ 203 flexGrow: 1, 204}); 205 206const cellCommunityTitleStyle = css({ 207 ...typography.fontSizes[16], 208 fontWeight: 500, 209 color: theme.text.default, 210 textDecoration: 'none', 211 marginBottom: spacing[2], 212}); 213 214const cellCommunityDescriptionStyle = css({ 215 ...typography.fontSizes[14], 216 color: theme.text.secondary, 217}); 218 219const cellCommunityHoverStyle = css` 220 & { 221 transition: box-shadow 200ms; 222 223 svg { 224 transition: transform 200ms; 225 } 226 } 227 228 &:hover { 229 box-shadow: ${shadows.sm}; 230 231 svg { 232 transform: scale(1.075); 233 } 234 } 235`; 236