1import { css } from '@emotion/react'; 2import { theme, typography, spacing } from '@expo/styleguide'; 3import NextLink from 'next/link'; 4import { useRouter } from 'next/router'; 5import * as React from 'react'; 6 7import stripVersionFromPath from '~/common/stripVersionFromPath'; 8import { NavigationRoute } from '~/types/common'; 9 10type SidebarLinkProps = React.PropsWithChildren<{ 11 info: NavigationRoute; 12}>; 13 14export const SidebarLink = ({ info, children }: SidebarLinkProps) => { 15 const { asPath, pathname } = useRouter(); 16 17 if (info.hidden) { 18 return null; 19 } 20 21 const checkSelection = () => { 22 // Special case for root url 23 if (info.name === 'Introduction') { 24 if (asPath.match(/\/versions\/[\w.]+\/$/) || asPath === '/versions/latest/') { 25 return true; 26 } 27 } 28 29 const linkUrl = stripVersionFromPath(info.as || info.href); 30 return linkUrl === stripVersionFromPath(pathname) || linkUrl === stripVersionFromPath(asPath); 31 }; 32 33 const isSelected = checkSelection(); 34 35 const customDataAttributes = isSelected 36 ? { 37 'data-sidebar-anchor-selected': true, 38 } 39 : {}; 40 41 return ( 42 <div css={STYLES_CONTAINER}> 43 <NextLink href={info.href as string} as={info.as || info.href} passHref> 44 <a {...customDataAttributes} css={[STYLES_LINK, isSelected && STYLES_LINK_ACTIVE]}> 45 {isSelected && <div css={STYLES_ACTIVE_BULLET} />} 46 {children} 47 </a> 48 </NextLink> 49 </div> 50 ); 51}; 52 53const STYLES_LINK = css` 54 ${typography.fontSizes[14]} 55 display: flex; 56 flex-direction: row; 57 text-decoration: none; 58 color: ${theme.text.secondary}; 59 transition: 50ms ease color; 60 align-items: flex-start; 61 padding-left: ${spacing[4] + spacing[0.5]}px; 62 63 &:hover { 64 color: ${theme.link.default}; 65 } 66`; 67 68const STYLES_LINK_ACTIVE = css` 69 font-family: ${typography.fontFaces.medium}; 70 color: ${theme.link.default}; 71 padding-left: 0; 72`; 73 74const STYLES_CONTAINER = css` 75 display: flex; 76 min-height: 32px; 77 align-items: center; 78 padding: ${spacing[1]}px; 79 padding-right: ${spacing[2]}px; 80`; 81 82const STYLES_ACTIVE_BULLET = css` 83 height: 6px; 84 width: 6px; 85 min-height: 6px; 86 min-width: 6px; 87 background-color: ${theme.link.default}; 88 border-radius: 100%; 89 margin: ${spacing[2]}px ${spacing[1.5]}px; 90`; 91