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