Add theme toggle and footer (#400)

This commit is contained in:
Callil Capuozzo 2019-08-07 14:58:29 -04:00 committed by Noah Zinsmeister
parent 80da6e0ff6
commit c28884f44b
8 changed files with 251 additions and 1832 deletions

@ -24,6 +24,7 @@
"react-router-dom": "^5.0.0",
"react-scripts": "^3.0.1",
"react-spring": "^8.0.20",
"react-toggle": "^4.0.2",
"styled-components": "^4.2.0",
"web3-react": "^5.0.4"
},

@ -14,7 +14,7 @@ const SummaryWrapper = styled.div`
`
const Details = styled.div`
background-color: ${({ theme }) => theme.doveGray};
background-color: ${({ theme }) => theme.concreteGray};
padding: 1.5rem;
border-radius: 1rem;
font-size: 0.75rem;

@ -0,0 +1,120 @@
import React from 'react'
import styled from 'styled-components'
import { Link } from '../../theme'
import { darken } from 'polished'
import { useDarkModeManager } from '../../contexts/LocalStorage'
import Toggle from 'react-toggle'
import { transparentize } from 'polished'
import 'react-toggle/style.css'
const FooterFrame = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
`
const FooterElement = styled.div`
margin: 1.25rem;
display: flex;
min-width: 0;
display: flex;
align-items: center;
`
const Title = styled.div`
display: flex;
align-items: center;
color: ${({ theme }) => theme.uniswapPink};
:hover {
cursor: pointer;
}
#link {
text-decoration-color: ${({ theme }) => theme.uniswapPink};
}
#title {
display: inline;
font-size: 0.825rem;
margin-right: 12px;
font-weight: 400;
color: ${({ theme }) => theme.uniswapPink};
:hover {
color: ${({ theme }) => darken(0.2, theme.uniswapPink)};
}
}
`
const EmojiToggle = styled.span`
position: relative;
font-size: 15px;
font-family: 'Arial sans-serif';
`
const ToggleComponent = styled(Toggle)`
margin-right: 24px;
.react-toggle-track {
background-color: ${({ theme }) => theme.inputBackground} !important;
border: 1px solid ${({ theme }) => theme.concreteGray};
}
.react-toggle-track-x {
line-height: unset;
bottom: auto;
right: 14px;
}
.react-toggle-track-check {
line-height: unset;
bottom: auto;
left: 7px;
}
&&& .react-toggle-thumb {
background-color: ${({ theme }) => theme.inputBackground};
box-shadow: 0 4px 8px 0 ${({ theme }) => transparentize(0.93, theme.royalBlue)};
border: 1px solid ${({ theme }) => theme.mercuryGray};
border-color: ${({ theme }) => theme.mercuryGray} !important;
/* border: none; */
top: 2px;
left: ${({ defaultChecked }) => (defaultChecked ? '28px' : '2px')};
}
`
function ToggleIcon(props) {
return (
<EmojiToggle role="img" aria-label="sun">
{props.content}
</EmojiToggle>
)
}
export default function Footer() {
const [isDark, toggleDarkMode] = useDarkModeManager()
return (
<FooterFrame>
<FooterElement>
<Title>
<Link id="link" href="https://uniswap.io/">
<h1 id="title">About</h1>
</Link>
<Link id="link" href="https://docs.uniswap.io/">
<h1 id="title">Docs</h1>
</Link>
<Link id="link" href="https://github.com/Uniswap">
<h1 id="title">Code</h1>
</Link>
</Title>
</FooterElement>
<ToggleComponent
defaultChecked={!isDark}
icons={{ checked: <ToggleIcon content="☀️" />, unchecked: <ToggleIcon content="🌙️" /> }}
onChange={toggleDarkMode}
/>
</FooterFrame>
)
}

@ -4,12 +4,29 @@ import styled from 'styled-components'
import { Link } from '../../theme'
import Web3Status from '../Web3Status'
import { darken } from 'polished'
import { useDarkModeManager } from '../../contexts/LocalStorage'
const HeaderFrame = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
`
const HeaderElement = styled.div`
margin: 1.25rem;
display: flex;
min-width: 0;
display: flex;
align-items: center;
`
const Nod = styled.span`
transform: rotate(0deg);
transition: transform 150ms ease-out;
:hover {
transform: rotate(-10deg);
}
`
const Title = styled.div`
@ -20,19 +37,8 @@ const Title = styled.div`
cursor: pointer;
}
#image {
font-size: 1.5rem;
margin-right: 1rem;
transform: rotate(0deg);
transition: transform 150ms ease-out;
:hover {
transform: rotate(-10deg);
}
}
#link {
text-decoration-color: ${({ theme }) => theme.wisteriaPurple};
text-decoration-color: ${({ theme }) => theme.UniswapPink};
}
#title {
@ -47,25 +53,25 @@ const Title = styled.div`
`
export default function Header() {
const [, toggleDarkMode] = useDarkModeManager()
return (
<>
<HeaderFrame>
<HeaderElement>
<Title>
<span onClick={toggleDarkMode} id="image" role="img" aria-label="Unicorn Emoji">
🦄
</span>
<Nod>
<Link id="link" href="https://uniswap.io">
<span role="img" aria-label="unicorn">
🦄{' '}
</span>
</Link>
</Nod>
<Link id="link" href="https://uniswap.io">
<h1 id="title">Uniswap</h1>
</Link>
</Title>
</HeaderElement>
<HeaderElement>
<Web3Status />
</HeaderElement>
</>
</HeaderFrame>
)
}

@ -87,6 +87,8 @@ const Popup = styled(Flex)`
padding: 0.6rem 1rem;
line-height: 150%;
background: ${({ theme }) => theme.inputBackground};
border: 1px solid ${({ theme }) => theme.mercuryGray};
border-radius: 8px;
animation: ${fadeIn} 0.15s linear;

@ -4,6 +4,8 @@ import { BrowserRouter, Redirect, Route, Switch } from 'react-router-dom'
import Web3ReactManager from '../components/Web3ReactManager'
import Header from '../components/Header'
import Footer from '../components/Footer'
import NavigationTabs from '../components/NavigationTabs'
import { isAddress } from '../utils'
@ -11,83 +13,102 @@ const Swap = lazy(() => import('./Swap'))
const Send = lazy(() => import('./Send'))
const Pool = lazy(() => import('./Pool'))
const AppWrapper = styled.div`
display: flex;
flex-flow: column;
align-items: flex-start;
height: 100vh;
`
const HeaderWrapper = styled.div`
${({ theme }) => theme.flexRowNoWrap}
width: 100%;
justify-content: space-between;
`
const FooterWrapper = styled.div`
width: 100%;
min-height: 30px;
align-self: flex-end;
`
const BodyWrapper = styled.div`
${({ theme }) => theme.flexRowNoWrap}
display: flex;
flex-direction: column;
width: 100%;
justify-content: center;
flex-grow: 1;
flex-basis: 0;
justify-content: flex-start;
align-items: center;
flex: 1;
overflow: auto;
`
const Body = styled.div`
width: 35rem;
margin: 1.25rem;
max-width: 35rem;
width: 90%;
/* margin: 0 1.25rem 1.25rem 1.25rem; */
`
export default function App() {
return (
<>
<Suspense fallback={null}>
<HeaderWrapper>
<Header />
</HeaderWrapper>
<BodyWrapper>
<Body>
<Web3ReactManager>
<BrowserRouter>
<NavigationTabs />
{/* this Suspense is for route code-splitting */}
<Suspense fallback={null}>
<Switch>
<Route exact strict path="/swap" component={Swap} />
<Route
exact
strict
path="/swap/:tokenAddress?"
render={({ match }) => {
if (isAddress(match.params.tokenAddress)) {
return <Swap initialCurrency={isAddress(match.params.tokenAddress)} />
} else {
return <Redirect to={{ pathname: '/swap' }} />
}
}}
/>
<Route exact strict path="/send" component={Send} />
<Route
exact
strict
path="/send/:tokenAddress?"
render={({ match }) => {
if (isAddress(match.params.tokenAddress)) {
return <Send initialCurrency={isAddress(match.params.tokenAddress)} />
} else {
return <Redirect to={{ pathname: '/send' }} />
}
}}
/>
<Route
path={[
'/add-liquidity',
'/remove-liquidity',
'/create-exchange',
'/create-exchange/:tokenAddress?'
]}
component={Pool}
/>
<Redirect to="/swap" />
</Switch>
</Suspense>
</BrowserRouter>
</Web3ReactManager>
</Body>
</BodyWrapper>
<AppWrapper>
<HeaderWrapper>
<Header />
</HeaderWrapper>
<BodyWrapper>
<Body>
<Web3ReactManager>
<BrowserRouter>
<NavigationTabs />
{/* this Suspense is for route code-splitting */}
<Suspense fallback={null}>
<Switch>
<Route exact strict path="/swap" component={Swap} />
<Route
exact
strict
path="/swap/:tokenAddress?"
render={({ match }) => {
if (isAddress(match.params.tokenAddress)) {
return <Swap initialCurrency={isAddress(match.params.tokenAddress)} />
} else {
return <Redirect to={{ pathname: '/swap' }} />
}
}}
/>
<Route exact strict path="/send" component={Send} />
<Route
exact
strict
path="/send/:tokenAddress?"
render={({ match }) => {
if (isAddress(match.params.tokenAddress)) {
return <Send initialCurrency={isAddress(match.params.tokenAddress)} />
} else {
return <Redirect to={{ pathname: '/send' }} />
}
}}
/>
<Route
path={[
'/add-liquidity',
'/remove-liquidity',
'/create-exchange',
'/create-exchange/:tokenAddress?'
]}
component={Pool}
/>
<Redirect to="/swap" />
</Switch>
</Suspense>
</BrowserRouter>
</Web3ReactManager>
</Body>
</BodyWrapper>
<FooterWrapper>
<Footer />
</FooterWrapper>
</AppWrapper>
</Suspense>
</>
)

@ -93,8 +93,17 @@ export const GlobalStyle = createGlobalStyle`
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
body > div {
height: 100%;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
html {
font-size: 16px;
font-variant: none;

1760
yarn.lock

File diff suppressed because it is too large Load Diff