Link.js (1625B)
1 // @flow 2 import React from 'react'; 3 import {useHistory, useRouteMatch} from 'react-router'; 4 import styled, {type StyledComponent} from 'styled-components'; 5 import theme from 'styled-theming'; 6 7 import {colors} from '../Theme/colors'; 8 9 const linkColor = theme('mode', { 10 light: colors.linkDark, 11 dark: colors.linkLight, 12 }); 13 14 const linkHoverColor = theme('mode', { 15 light: colors.brown, 16 dark: colors.orange, 17 }); 18 19 type LinkProps = { 20 to: string, 21 children: React$Node, 22 rel?: string, 23 }; 24 25 const LinkBase: StyledComponent<{isCurrentRoute?: boolean}, {}, {}> = styled.a` 26 color: ${({isCurrentRoute}) => (isCurrentRoute ? linkHoverColor : linkColor)}; 27 cursor: pointer; 28 text-decoration: underline solid 29 ${({isCurrentRoute}) => (isCurrentRoute ? linkHoverColor : linkColor)} 0.5px; 30 31 &:hover { 32 color: ${linkHoverColor}; 33 text-decoration: underline solid ${linkHoverColor} 2px; 34 } 35 `; 36 37 const Link = ({children, to, rel, ...props}: LinkProps) => { 38 const history = useHistory(); 39 40 Link.goTo = (to: string) => { 41 history.push(to); 42 }; 43 44 const isExternal = to[0] !== '/'; 45 if (isExternal) { 46 return ( 47 <LinkBase 48 {...props} 49 target="_blank" 50 rel={rel ? rel : 'noopener noreferrer'} 51 href={to} 52 > 53 {children} 54 </LinkBase> 55 ); 56 } 57 58 const {isExact = false} = useRouteMatch(to) || {}; 59 const handleClick = e => { 60 e.preventDefault(); 61 history.push(to); 62 }; 63 64 return ( 65 <LinkBase 66 {...props} 67 href={to} 68 onClick={handleClick} 69 isCurrentRoute={isExact} 70 > 71 {children} 72 </LinkBase> 73 ); 74 }; 75 76 export default Link;