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