1import { css } from '@emotion/react'; 2import { borderRadius, palette, shadows, spacing, theme, typography } from '@expo/styleguide'; 3import React, { PropsWithChildren } from 'react'; 4import { Col, ColProps } from 'react-grid-system'; 5 6import { P } from '~/ui/components/Text'; 7 8export type GridCellProps = ColProps & { 9 style?: object; 10}; 11 12export const GridCell = ({ 13 children, 14 sm, 15 md, 16 lg, 17 xl, 18 xxl, 19 style, 20 css, 21}: PropsWithChildren<GridCellProps>) => ( 22 <Col css={[cellWrapperStyle, css]} sm={sm} md={md} lg={lg} xl={xl} xxl={xxl}> 23 <div css={cellStyle} style={style}> 24 {children} 25 </div> 26 </Col> 27); 28 29type APIGridCellProps = GridCellProps & { 30 icon?: string | JSX.Element; 31 title?: string; 32 link?: string; 33}; 34 35export const APIGridCell = ({ 36 icon, 37 title, 38 link, 39 style, 40 sm = 6, 41 md = 6, 42 lg = 6, 43 xl = 3, 44}: APIGridCellProps) => ( 45 <Col css={cellWrapperStyle} md={md} sm={sm} lg={lg} xl={xl}> 46 <a href={link} css={[cellStyle, cellAPIStyle, cellHoverStyle]} style={style}> 47 <div css={cellIconWrapperStyle}>{icon}</div> 48 <div css={cellTitleWrapperStyle}> 49 {title} 50 <span css={cellTitleArrow}>{'->'}</span> 51 </div> 52 </a> 53 </Col> 54); 55 56type CommunityGridCellProps = APIGridCellProps & { 57 description?: string; 58 iconBackground?: string; 59}; 60 61export const CommunityGridCell = ({ 62 icon, 63 iconBackground = palette.light.gray['800'], 64 title, 65 link, 66 description, 67 style, 68 md = 6, 69}: CommunityGridCellProps) => ( 70 <Col css={cellWrapperStyle} md={md}> 71 <a href={link} css={[cellStyle, cellCommunityStyle, cellHoverStyle]} style={style}> 72 <div css={[cellCommunityIconWrapperStyle, css({ backgroundColor: iconBackground })]}> 73 {icon} 74 </div> 75 <div> 76 <span css={cellCommunityTitleStyle}>{title}</span> 77 <P css={cellCommunityDescriptionStyle}>{description}</P> 78 </div> 79 </a> 80 </Col> 81); 82 83const cellWrapperStyle = css` 84 padding-left: 0 !important; 85 padding-right: 0 !important; 86`; 87 88const cellHoverStyle = css` 89 & { 90 transition: box-shadow 200ms; 91 } 92 93 &:hover { 94 box-shadow: ${shadows.tiny}; 95 } 96`; 97 98const cellStyle = css({ 99 margin: spacing[4], 100 padding: spacing[8], 101 minHeight: 200, 102 overflow: 'hidden', 103 position: 'relative', 104 borderWidth: 1, 105 borderStyle: 'solid', 106 borderColor: theme.border.default, 107 borderRadius: borderRadius.large, 108}); 109 110const cellAPIStyle = css({ 111 display: 'block', 112 backgroundColor: theme.background.secondary, 113 padding: 0, 114 overflow: 'hidden', 115 textDecoration: 'none', 116}); 117 118const cellIconWrapperStyle = css({ 119 display: 'flex', 120 minHeight: 136, 121 justifyContent: 'space-around', 122 alignItems: 'center', 123}); 124 125const cellTitleWrapperStyle = css({ 126 ...typography.fontSizes[15], 127 display: 'flex', 128 justifyContent: 'space-between', 129 backgroundColor: theme.background.default, 130 padding: spacing[4], 131 textDecoration: 'none', 132 fontFamily: typography.fontStacks.medium, 133 lineHeight: '30px', 134 color: theme.text.default, 135}); 136 137const cellTitleArrow = css({ 138 ...typography.fontSizes[18], 139 float: 'right', 140 color: theme.icon.secondary, 141 letterSpacing: 0, 142}); 143 144const cellCommunityStyle = css({ 145 display: 'flex', 146 minHeight: 'auto', 147 padding: spacing[4], 148 margin: `${spacing[3]}px ${spacing[4]}px`, 149 flexDirection: 'row', 150 textDecoration: 'none', 151}); 152 153const cellCommunityIconWrapperStyle = css({ 154 height: 32, 155 width: 32, 156 minWidth: 32, 157 display: 'flex', 158 justifyContent: 'center', 159 alignItems: 'center', 160 borderRadius: borderRadius.large, 161 marginRight: spacing[3], 162}); 163 164const cellCommunityTitleStyle = css({ 165 ...typography.fontSizes[16], 166 fontFamily: typography.fontStacks.medium, 167 color: theme.text.default, 168 textDecoration: 'none', 169 marginBottom: spacing[2], 170}); 171 172const cellCommunityDescriptionStyle = css({ 173 ...typography.fontSizes[14], 174 color: theme.text.secondary, 175}); 176