-
-
Notifications
You must be signed in to change notification settings - Fork 437
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add the new navbar and refactor the sidebar #109
Changes from 10 commits
283b22a
27ef848
8aaf806
9424e8b
c6be883
a2c73ec
4dcef97
5afb593
d038838
cddc75b
2d4b2cc
2b805d3
570d1e4
f2eac0c
9c34064
912a395
c142736
baea209
0a25303
c4c8670
5c7b4ec
8dc4760
7404612
b04d1ce
654e42e
4665c72
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,27 +1,65 @@ | ||
import React from 'react' | ||
import React, { Component } from 'react' | ||
import Head from './SeoHead' | ||
import Navbar from './Navbar' | ||
import Nav from './Nav' | ||
import { Container, Content, Title } from './Layout' | ||
|
||
const DocsLayout = ({ children, title="", description="" }) => ( | ||
<Container> | ||
|
||
<Head | ||
title={`styled-components${title ? `: ${title}` : ''}`} | ||
description={description}> | ||
<meta name="robots" content="noodp" /> | ||
</Head> | ||
class DocsLayout extends Component { | ||
state = { | ||
isSideFolded: true | ||
} | ||
|
||
<Navbar /> | ||
static defaultProps = { | ||
title: '', | ||
description: '', | ||
} | ||
|
||
<Content> | ||
<Title> | ||
{title} | ||
</Title> | ||
onSideFold = () => { | ||
let isSideFolded = !this.state.isSideFolded | ||
if(!isSideFolded) { | ||
document.body.classList.add('sticky') | ||
} else { | ||
document.body.classList.remove('sticky') | ||
} | ||
this.setState({ | ||
isSideFolded: isSideFolded | ||
}) | ||
} | ||
|
||
onRouteChange = () => { | ||
this.setState({ isSideFolded: true }) | ||
} | ||
|
||
render() { | ||
const { children, title, description } = this.props | ||
const { isSideFolded } = this.state | ||
|
||
return ( | ||
<Container> | ||
|
||
<Head | ||
title={`styled-components${title ? `: ${title}` : ''}`} | ||
description={description}> | ||
<meta name="robots" content="noodp" /> | ||
</Head> | ||
|
||
<Nav | ||
isSideFolded={isSideFolded} | ||
onSideFold={this.onSideFold} | ||
onRouteChange={this.onRouteChange} | ||
/> | ||
|
||
<Content moveRight={!isSideFolded}> | ||
<Title> | ||
{title} | ||
</Title> | ||
|
||
{children} | ||
</Content> | ||
</Container> | ||
) | ||
} | ||
} | ||
|
||
{children} | ||
</Content> | ||
</Container> | ||
) | ||
|
||
export default DocsLayout |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,24 @@ | ||
import styled, { css } from 'styled-components' | ||
|
||
import rem from '../../utils/rem' | ||
import { mobile } from '../../utils/media' | ||
|
||
const Logo = styled.div` | ||
display: inline-block; | ||
width: 100%; | ||
height: 100%; | ||
|
||
vertical-align: middle; | ||
box-sizing: border-box; | ||
|
||
background-image: url(/static/logo.png); | ||
background-size: contain; | ||
background-position: center; | ||
background-size: contain; | ||
|
||
${mobile(css` | ||
${p => p.compact ? css` | ||
background-image: url(/static/icon.png); | ||
background-position: center; | ||
width: ${rem(70)}; | ||
height: ${rem(70)}; | ||
`)} | ||
width: ${rem(100)}; | ||
height: ${rem(30)}; | ||
` : css` | ||
background-image: url(/static/nav-logo.png); | ||
width: ${rem(164)}; | ||
height: ${rem(40)}; | ||
`} | ||
` | ||
|
||
export default Logo |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import React, { PureComponent } from 'react' | ||
import styled, { css } from 'styled-components' | ||
|
||
import rem from '../../utils/rem' | ||
import { navbarHeight } from '../../utils/sizes' | ||
import { paleGrey } from '../../utils/colors' | ||
import { mobile } from '../../utils/media' | ||
import Link from '../Link' | ||
import NavLinks from './NavLinks' | ||
import Social from './Social' | ||
import Search from './Search' | ||
import Logo from './Logo' | ||
import NavSeparator from './NavSeparator' | ||
import NavButton from './NavButton' | ||
|
||
const Wrapper = styled.div` | ||
display: none; | ||
|
||
${mobile(css` | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
height: ${rem(navbarHeight)}; | ||
`)} | ||
` | ||
|
||
const SecondaryMenu = styled.div` | ||
position: absolute; | ||
top: ${rem(navbarHeight)}; | ||
left: 0; | ||
right: 0; | ||
|
||
${p => p.open ? css` | ||
height: ${rem(navbarHeight)}; | ||
` : css` | ||
height: 0; | ||
`} | ||
|
||
display: flex; | ||
flex-wrap: nowrap; | ||
align-items: center; | ||
justify-content: space-between; | ||
padding: 0 ${rem(20)}; | ||
transition: height 0.1s; | ||
|
||
-webkit-user-select: none; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! |
||
-webkit-overflow-scrolling: touch; | ||
overflow-x: scroll; | ||
overflow-y: hidden; | ||
|
||
background: ${paleGrey}; | ||
color: #868686; | ||
` | ||
|
||
const LogoLink = styled(Link).attrs({ | ||
unstyled: true, | ||
href: '/', | ||
})` | ||
display: inline-block; | ||
vertical-align: center; | ||
margin-right: ${rem(35)}; | ||
` | ||
|
||
const ArrowWrapper = styled.div` | ||
transition: transform 0.1s; | ||
|
||
${p => p.rotate && css` | ||
transform-origin: 50% 55%; | ||
transform: rotate(180deg); | ||
`} | ||
` | ||
|
||
const PaddedSocial = styled(Social)` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not too happy about wrapping the It goes against the container -> structural -> presentational components order There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You're totally right. I didn't think of this before |
||
padding-right: ${rem(20)}; | ||
` | ||
|
||
const CloseIcon = () => ( | ||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" xmlnsXlink="http://www.w3.org/1999/xlink"> | ||
<title>close</title> | ||
<use fill="#FFF" xlinkHref="#close" transform="translate(1 1)" /> | ||
<defs> | ||
<path id="close" d="M-.7.7l13 13 1.4-1.4-13-13L-.7.7zm13-1.4l-13 13 1.4 1.4 13-13-1.4-1.4z"/> | ||
</defs> | ||
</svg> | ||
) | ||
|
||
const FoldIcon = () => ( | ||
<svg xmlns="http://www.w3.org/2000/svg" width="17" height="14" xmlnsXlink="http://www.w3.org/1999/xlink"> | ||
<title>fold</title> | ||
<use fill="#FFF" xlinkHref="#fold" transform="translate(0 1)"/> | ||
<defs> | ||
<path id="fold" d="M0 1h17v-2H0v2zm17 4H0v2h17V5zM0 13h17v-2H0v2z"/> | ||
</defs> | ||
</svg> | ||
) | ||
|
||
const ArrowIcon = props => ( | ||
<ArrowWrapper {...props}> | ||
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="8" xmlnsXlink="http://www.w3.org/1999/xlink"> | ||
<title>arrow down</title> | ||
<use fill="#FFF" xlinkHref="#menuArrow" transform="translate(1 1)"/> | ||
<defs> | ||
<path id="menuArrow" d="M5 5l-.7.7.7.7.7-.7L5 5zM9.3-.7l-5 5 1.4 1.4 5-5L9.3-.7zm-3.6 5l-5-5L-.7.7l5 5 1.4-1.4z"/> | ||
</defs> | ||
</svg> | ||
</ArrowWrapper> | ||
) | ||
|
||
class MobileNavbar extends PureComponent { | ||
state = { | ||
isMenuOpen: false, | ||
} | ||
|
||
render() { | ||
const { isMenuOpen } = this.state | ||
const { isFolded, onFold } = this.props | ||
|
||
return ( | ||
<Wrapper> | ||
<NavButton | ||
active={!isFolded} | ||
onClick={onFold} | ||
> | ||
{isFolded ? <FoldIcon /> : <CloseIcon />} | ||
</NavButton> | ||
|
||
<LogoLink> | ||
<Logo compact /> | ||
</LogoLink> | ||
|
||
<NavButton | ||
onClick={this.toggleMenu} | ||
active={isMenuOpen} | ||
> | ||
<ArrowIcon rotate={isMenuOpen} /> | ||
</NavButton> | ||
|
||
<SecondaryMenu open={isMenuOpen}> | ||
<NavLinks /> | ||
<NavSeparator /> | ||
<Search /> | ||
<NavSeparator /> | ||
<PaddedSocial /> | ||
</SecondaryMenu> | ||
</Wrapper> | ||
) | ||
} | ||
|
||
toggleMenu = () => { | ||
this.setState({ isMenuOpen: !this.state.isMenuOpen }) | ||
} | ||
} | ||
|
||
export default MobileNavbar |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import styled, { css } from 'styled-components' | ||
|
||
import rem from '../../utils/rem' | ||
import { navbarHeight } from '../../utils/sizes' | ||
import { resetInput } from '../../utils/form' | ||
|
||
const NavButton = styled.button` | ||
${resetInput} | ||
|
||
flex: 0 0 auto; | ||
min-width: ${rem(navbarHeight)}; | ||
height: ${rem(navbarHeight)}; | ||
text-align: center; | ||
vertical-align: middle; | ||
cursor: pointer; | ||
|
||
${p => p.active && css` | ||
background: rgba(0, 0, 0, 0.07); | ||
`} | ||
|
||
&:focus { | ||
border: ${rem(2)} solid currentColor; | ||
border-radius: ${rem(2)}; | ||
} | ||
|
||
svg { | ||
display: inline-block; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd much rather have this be placed with the SVGs themselves. Surely we can choose an abstraction component for them instead of just chugging them into There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
|
||
path { | ||
fill: currentColor; | ||
} | ||
} | ||
` | ||
|
||
export default NavButton |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import React from 'react' | ||
import styled from 'styled-components' | ||
|
||
import rem from '../../utils/rem' | ||
import { navbarHeight } from '../../utils/sizes' | ||
import NavSeparator from './NavSeparator' | ||
import Link from '../Link' | ||
|
||
const Wrapper = styled.nav` | ||
display: flex; | ||
align-items: center; | ||
flex: 0 0 auto; | ||
` | ||
|
||
const NavLink = styled(Link).attrs({ | ||
unstyled: true, | ||
})` | ||
flex: 0 0 auto; | ||
display: inline-block; | ||
line-height: ${rem(navbarHeight)}; | ||
transition: opacity 200ms, transfrom 200ms; | ||
cursor: pointer; | ||
|
||
letter-spacing: ${rem(.4)} | ||
color: currentColor; | ||
|
||
&:hover, | ||
&:focus { | ||
opacity: 0.8; | ||
} | ||
|
||
&:active { | ||
transform: scale(0.95); | ||
opacity: 0.6; | ||
} | ||
` | ||
|
||
const NavLinks = () => ( | ||
<Wrapper> | ||
<NavLink>Concepts</NavLink> | ||
<NavSeparator /> | ||
<NavLink>Try it out</NavLink> | ||
<NavSeparator /> | ||
<NavLink>Documentation</NavLink> | ||
</Wrapper> | ||
) | ||
|
||
export default NavLinks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small nit, can you remove the variable above? Also it won't need to be a
let
. We generally use theconst
beforelet
conventionThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, you're right, I forgot to refactor the old code here. Sorry!