From e1f42c47517cee898db90890bd668a9d7cdab74e Mon Sep 17 00:00:00 2001 From: Tore Brede <Tore.Brede@uib.no> Date: Sat, 11 Sep 2021 14:58:38 +0200 Subject: [PATCH] GREG-41: Updating link component --- frontend/src/App.tsx | 11 +-- frontend/src/components/link/index.tsx | 113 +++++++++++++++++++++---- 2 files changed, 103 insertions(+), 21 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 719320ed..fd3e451f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -72,11 +72,12 @@ const App = () => { API reachable? {apiHealth} </p> - <Link to='test' external={false}>Test</Link> - <Link to='test2' external={true}>Test2</Link> - </header> - </div> - </Suspense> + <Link to='test@example.org' mail={true}>Mail link</Link> + <Link to='test4' external={false} underline={true} noExternalIcon={true}>Internal link</Link> + <Link to='test6' external={true} underline={false} noUnderline={true}>External link</Link> + <Link to='test5' external={false} noUnderline={true}>Another internal link</Link> + </header> + </div> ) } diff --git a/frontend/src/components/link/index.tsx b/frontend/src/components/link/index.tsx index 65a9e8e0..139bd527 100644 --- a/frontend/src/components/link/index.tsx +++ b/frontend/src/components/link/index.tsx @@ -1,25 +1,106 @@ -import styled from 'styled-components/macro' +import styled, {css, DefaultTheme} from 'styled-components/macro' -interface LinkProps { - children?: React.ReactNode - external?: boolean - to?: string +interface IStyledLink { + theme: DefaultTheme + external?: boolean + underline?: boolean + marginRight?: boolean + inheritColor?: boolean + noUnderline?: boolean } -const StyledLink = styled.a<LinkProps>` - background: ${(props) => props.external ? 'green' : 'red'}; + +interface ILink { + to: string + external?: boolean + children?: React.ReactNode + marginRight?: boolean + noExternalIcon?: boolean + mail?: boolean + inheritColor?: boolean + underline?: boolean + noUnderline?: boolean +} + +const externalLinkIcon = ( + <svg width="15.3" height="12.6" viewBox="0 0 17 14"> + <g fill="#0F748D" fillRule="evenodd"> + <path + d="M13.044 8.157h-.607a.3.3 0 0 0-.218.082.276.276 0 0 0-.085.208v2.907c0 .4-.148.742-.445 1.027a1.493 1.493 0 0 1-1.072.427H2.73c-.417 0-.774-.143-1.071-.427a1.371 1.371 0 0 1-.446-1.027V3.796c0-.4.149-.742.446-1.026a1.493 1.493 0 0 1 1.071-.427h6.674a.302.302 0 0 0 .218-.082.277.277 0 0 0 .085-.209v-.581a.277.277 0 0 0-.085-.21.302.302 0 0 0-.218-.08H2.73c-.752 0-1.395.255-1.93.767-.533.511-.8 1.128-.8 1.848v7.558c0 .721.267 1.337.801 1.849a2.689 2.689 0 0 0 1.93.768h7.886c.752 0 1.395-.256 1.93-.768.534-.512.8-1.128.8-1.849V8.448a.276.276 0 0 0-.085-.21.302.302 0 0 0-.218-.081z"/> + <path + d="M16.807.19a.596.596 0 0 0-.426-.173h-4.854a.596.596 0 0 0-.426.173.548.548 0 0 0-.18.409c0 .157.06.294.18.409l1.668 1.598-6.18 5.923a.281.281 0 0 0-.095.21c0 .078.031.148.094.208L7.67 9.983a.306.306 0 0 0 .436 0l6.18-5.923 1.67 1.599c.12.115.262.172.426.172a.596.596 0 0 0 .426-.172.547.547 0 0 0 .18-.409V.599a.548.548 0 0 0-.18-.409z"/> + </g> + </svg> +); + +const ExternalIcon = styled.span` + margin-left: 1.2rem; + position: relative; + top: 1px; + zIndex: -1; +` + +const baseInputStyles = css<IStyledLink>` + display: inline-flex; + align-items: center; + + color: ${props => props.external ? props.theme.linkExternalColor : props.theme.linkInternalColor}; + + ${props => props.marginRight ? "margin-right: 3rem;" : ""} + ${props => props.inheritColor ? "color: inherit;" : ""} + ${props => props.underline ? "text-decoration: underline;" : ""} + ${props => props.noUnderline ? ":hover { text-decoration: none };" : ""} ` -export function Link(props: LinkProps) { +const StyledLink = styled.a<IStyledLink>` + ${baseInputStyles} +` +// TODO Put back when routes are set up +// const StyledRouterLink = styled(RouterLink)` +// ${baseInputStyles}; +// ` + +export default function Link(props: ILink) { + const {children, external, to, noExternalIcon, mail} = props + + if (mail) { + return ( + <StyledLink href={`mailto:${to}`} {...props}> + {children} + </StyledLink> + ); + } + + if (external) { + const urlRegex = /^((http|https):\/\/)/; + const href = urlRegex.test(to) ? to : `//${to}`; + + return ( + <StyledLink + href={href} + target="_blank" + rel="noopener noreferrer" + {...props} + > + {children} + {!noExternalIcon && ( + <ExternalIcon>{externalLinkIcon}</ExternalIcon> + )} + </StyledLink> + ); + } + + // TODO Use StyledRouterLink for internal links when routes are set up + // return ( + // <StyledRouterLink {...props}> + // {children} + // </StyledRouterLink> + // ) - if (props.external) { return ( - <StyledLink href={props.to} {...props} /> + <StyledLink {...props}> + {children} + </StyledLink> ) - } - - return ( - <StyledLink href={props.to} {...props} /> - ) -} \ No newline at end of file +} -- GitLab