1import { css } from '@emotion/react';
2import { mergeClasses, theme, typography } from '@expo/styleguide';
3import { borderRadius, spacing } from '@expo/styleguide-base';
4import { ArrowUpRightIcon } from '@expo/styleguide-icons';
5import type { ComponentType, HTMLAttributes } from 'react';
6
7import { A } from '../Text';
8
9type SidebarSingleEntryProps = {
10  href: string;
11  title: string;
12  Icon: ComponentType<HTMLAttributes<SVGSVGElement>>;
13  isActive?: boolean;
14  isExternal?: boolean;
15  secondary?: boolean;
16};
17
18export const SidebarSingleEntry = ({
19  href,
20  title,
21  Icon,
22  isActive = false,
23  isExternal = false,
24  secondary = false,
25}: SidebarSingleEntryProps) => {
26  return (
27    <A
28      href={href}
29      css={[containerStyle, secondary && secondaryContainerStyle, isActive && activeContainerStyle]}
30      isStyled>
31      <span
32        css={[
33          iconWrapperStyle,
34          secondary && secondaryIconWrapperStyle,
35          isActive && activeIconWrapperStyle,
36        ]}>
37        <Icon
38          className={mergeClasses(
39            'icon-sm',
40            isActive ? 'text-palette-blue11' : 'text-icon-secondary'
41          )}
42        />
43      </span>
44      {title}
45      {isExternal && <ArrowUpRightIcon className="icon-sm text-icon-secondary ml-auto" />}
46    </A>
47  );
48};
49
50const containerStyle = css({
51  ...typography.fontSizes[14],
52  minHeight: 38,
53  lineHeight: '100%',
54  padding: `${spacing[1]}px ${spacing[1]}px`,
55  color: theme.text.secondary,
56  cursor: 'pointer',
57  display: 'flex',
58  alignItems: 'center',
59  userSelect: 'none',
60  transition: 'color 150ms, opacity 150ms',
61  textDecoration: 'none',
62  borderRadius: borderRadius.md,
63  fontWeight: 500,
64  gap: spacing[2.5],
65
66  '&:hover': {
67    color: theme.text.default,
68    opacity: 1,
69  },
70});
71
72const secondaryContainerStyle = css({
73  fontWeight: 400,
74
75  '&:hover': {
76    color: theme.text.secondary,
77    opacity: 0.8,
78  },
79});
80
81const activeContainerStyle = css({
82  color: theme.text.link,
83
84  '&:hover': {
85    color: theme.text.link,
86  },
87});
88
89const iconWrapperStyle = css({
90  display: 'flex',
91  backgroundColor: theme.background.element,
92  width: spacing[6],
93  height: spacing[6],
94  borderRadius: borderRadius.sm,
95  alignItems: 'center',
96  justifyContent: 'center',
97});
98
99const activeIconWrapperStyle = css({
100  backgroundColor: theme.palette.blue4,
101});
102
103const secondaryIconWrapperStyle = css({
104  backgroundColor: 'transparent',
105});
106