import React, { HTMLProps, useCallback } from 'react'
import ReactGA from 'react-ga'
import { Link } from 'react-router-dom'
import styled, { keyframes } from 'styled-components'
import { darken } from 'polished'
import { ArrowLeft, X, ExternalLink as LinkIconFeather, Trash } from 'react-feather'
export const ButtonText = styled.button`
outline: none;
border: none;
font-size: inherit;
padding: 0;
margin: 0;
background: none;
cursor: pointer;
:hover {
opacity: 0.7;
}
:focus {
text-decoration: underline;
}
`
export const Button = styled.button.attrs<{ warning: boolean }, { backgroundColor: string }>(({ warning, theme }) => ({
backgroundColor: warning ? theme.red1 : theme.primary1,
}))`
padding: 1rem 2rem 1rem 2rem;
border-radius: 3rem;
cursor: pointer;
user-select: none;
font-size: 1rem;
border: none;
outline: none;
background-color: ${({ backgroundColor }) => backgroundColor};
color: ${({ theme }) => theme.white};
width: 100%;
:hover,
:focus {
background-color: ${({ backgroundColor }) => darken(0.05, backgroundColor)};
}
:active {
background-color: ${({ backgroundColor }) => darken(0.1, backgroundColor)};
}
:disabled {
background-color: ${({ theme }) => theme.bg1};
color: ${({ theme }) => theme.text4};
cursor: auto;
}
`
export const CloseIcon = styled(X)<{ onClick: () => void }>`
cursor: pointer;
`
// for wrapper react feather icons
export const IconWrapper = styled.div<{ stroke?: string; size?: string; marginRight?: string; marginLeft?: string }>`
display: flex;
align-items: center;
justify-content: center;
width: ${({ size }) => size ?? '20px'};
height: ${({ size }) => size ?? '20px'};
margin-right: ${({ marginRight }) => marginRight ?? 0};
margin-left: ${({ marginLeft }) => marginLeft ?? 0};
& > * {
stroke: ${({ theme, stroke }) => stroke ?? theme.blue1};
}
`
// A button that triggers some onClick result, but looks like a link.
export const LinkStyledButton = styled.button<{ disabled?: boolean }>`
border: none;
text-decoration: none;
background: none;
cursor: ${({ disabled }) => (disabled ? 'default' : 'pointer')};
color: ${({ theme, disabled }) => (disabled ? theme.text2 : theme.primary1)};
font-weight: 500;
:hover {
text-decoration: ${({ disabled }) => (disabled ? null : 'underline')};
}
:focus {
outline: none;
text-decoration: ${({ disabled }) => (disabled ? null : 'underline')};
}
:active {
text-decoration: none;
}
`
// An internal link from the react-router-dom library that is correctly styled
export const StyledInternalLink = styled(Link)`
text-decoration: none;
cursor: pointer;
color: ${({ theme }) => theme.primary1};
font-weight: 500;
:hover {
text-decoration: underline;
}
:focus {
outline: none;
text-decoration: underline;
}
:active {
text-decoration: none;
}
`
const StyledLink = styled.a`
text-decoration: none;
cursor: pointer;
color: ${({ theme }) => theme.primary1};
font-weight: 500;
:hover {
text-decoration: underline;
}
:focus {
outline: none;
text-decoration: underline;
}
:active {
text-decoration: none;
}
`
const LinkIconWrapper = styled.a`
text-decoration: none;
cursor: pointer;
align-items: center;
justify-content: center;
display: flex;
:hover {
text-decoration: none;
opacity: 0.7;
}
:focus {
outline: none;
text-decoration: none;
}
:active {
text-decoration: none;
}
`
export const LinkIcon = styled(LinkIconFeather)`
height: 16px;
width: 18px;
margin-left: 10px;
stroke: ${({ theme }) => theme.blue1};
`
export const TrashIcon = styled(Trash)`
height: 16px;
width: 18px;
margin-left: 10px;
stroke: ${({ theme }) => theme.text3};
cursor: pointer;
align-items: center;
justify-content: center;
display: flex;
:hover {
opacity: 0.7;
}
`
const rotateImg = keyframes`
0% {
transform: perspective(1000px) rotateY(0deg);
}
100% {
transform: perspective(1000px) rotateY(360deg);
}
`
export const UniTokenAnimated = styled.img`
animation: ${rotateImg} 5s cubic-bezier(0.83, 0, 0.17, 1) infinite;
padding: 2rem 0 0 0;
filter: drop-shadow(0px 2px 4px rgba(0, 0, 0, 0.15));
`
/**
* Outbound link that handles firing google analytics events
*/
export function ExternalLink({
target = '_blank',
href,
rel = 'noopener noreferrer',
...rest
}: Omit, 'as' | 'ref' | 'onClick'> & { href: string }) {
const handleClick = useCallback(
(event: React.MouseEvent) => {
// don't prevent default, don't redirect if it's a new tab
if (target === '_blank' || event.ctrlKey || event.metaKey) {
ReactGA.outboundLink({ label: href }, () => {
console.debug('Fired outbound link event', href)
})
} else {
event.preventDefault()
// send a ReactGA event and then trigger a location change
ReactGA.outboundLink({ label: href }, () => {
window.location.href = href
})
}
},
[href, target]
)
return
}
export function ExternalLinkIcon({
target = '_blank',
href,
rel = 'noopener noreferrer',
...rest
}: Omit, 'as' | 'ref' | 'onClick'> & { href: string }) {
const handleClick = useCallback(
(event: React.MouseEvent) => {
// don't prevent default, don't redirect if it's a new tab
if (target === '_blank' || event.ctrlKey || event.metaKey) {
ReactGA.outboundLink({ label: href }, () => {
console.debug('Fired outbound link event', href)
})
} else {
event.preventDefault()
// send a ReactGA event and then trigger a location change
ReactGA.outboundLink({ label: href }, () => {
window.location.href = href
})
}
},
[href, target]
)
return (
)
}
const rotate = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`
export const Spinner = styled.img`
animation: 2s ${rotate} linear infinite;
width: 16px;
height: 16px;
`
const BackArrowLink = styled(StyledInternalLink)`
color: ${({ theme }) => theme.text1};
`
export function BackArrow({ to }: { to: string }) {
return (
)
}
export const CustomLightSpinner = styled(Spinner)<{ size: string }>`
height: ${({ size }) => size};
width: ${({ size }) => size};
`
export const HideSmall = styled.span`
${({ theme }) => theme.mediaWidth.upToSmall`
display: none;
`};
`
export const HideExtraSmall = styled.span`
${({ theme }) => theme.mediaWidth.upToExtraSmall`
display: none;
`};
`
export const SmallOnly = styled.span`
display: none;
${({ theme }) => theme.mediaWidth.upToSmall`
display: block;
`};
`
export const ExtraSmallOnly = styled.span`
display: none;
${({ theme }) => theme.mediaWidth.upToExtraSmall`
display: block;
`};
`
// --- Link for GUNI POOLS ---
export const GlobalLink = styled(ExternalLink)`
color: ${({ theme }) => theme.blue3};
:hover {
text-decoration: underline;
}
:focus {
outline: none;
text-decoration: underline;
}
:active {
text-decoration: none;
}
`