1import { css } from '@emotion/react';
2import { borderRadius, breakpoints, shadows, spacing, theme } from '@expo/styleguide';
3
4import { Icon } from './Icon';
5
6import { A, CALLOUT, RawH4 } from '~/ui/components/Text';
7
8type GridItemProps = React.PropsWithChildren<{
9  title: string;
10  image?: string;
11  href?: string;
12  protocol: string[];
13}>;
14
15export const GridItem = ({
16  title,
17  image,
18  protocol = [],
19  href = `#${title.toLowerCase().replaceAll(' ', '-')}`,
20}: GridItemProps) => (
21  <A href={href} css={itemStyle} isStyled>
22    <Icon title={title} image={image} />
23    <RawH4 css={titleStyle}>{title}</RawH4>
24    {(protocol || []).length && (
25      <CALLOUT theme="secondary" css={protocolStyle}>
26        {protocol.join(' | ')}
27      </CALLOUT>
28    )}
29  </A>
30);
31
32const protocolStyle = css({
33  opacity: 0,
34  transform: `translateY(4px)`,
35  transitionProperty: 'all',
36  transitionDuration: '0.15s',
37  textAlign: 'center',
38});
39
40const titleStyle = css({
41  marginTop: spacing[2],
42  textAlign: 'center',
43});
44
45const itemStyle = css({
46  display: 'flex',
47  flexDirection: 'column',
48  justifyContent: 'center',
49  alignItems: 'center',
50  padding: spacing[6],
51  gap: spacing[2],
52  textDecoration: 'none',
53  borderRadius: borderRadius.sm,
54  transition: 'box-shadow 0.15s ease 0s, transform 0.15s ease 0s',
55  boxShadow: shadows.xs,
56  border: `1px solid ${theme.border.default}`,
57
58  ':hover': {
59    boxShadow: shadows.md,
60    transform: 'scale(1.05)',
61
62    p: {
63      opacity: 0.75,
64      transform: 'translateY(0)',
65    },
66  },
67
68  [`@media screen and (max-width: ${(breakpoints.medium + breakpoints.large) / 2}px)`]: {
69    p: {
70      opacity: 0.75,
71    },
72  },
73});
74