From 47bfd74297b8b22d56c17b58604cb52c38ef7b78 Mon Sep 17 00:00:00 2001 From: TheoryOfNekomata Date: Sun, 29 Nov 2020 12:59:21 +0800 Subject: [PATCH] Improve tablet layout, add sidebar animation Make the sidebar not occupy the whole screen width. Also add transitions for sidebar opening/closing. --- src/components/Navbar/Navbar.tsx | 178 +++++++++++++----- .../PrimaryNavItem/PrimaryNavItem.tsx | 1 + .../SecondaryNavItem/SecondaryNavItem.tsx | 78 +++++--- src/pages/notes.tsx | 26 ++- 4 files changed, 195 insertions(+), 88 deletions(-) diff --git a/src/components/Navbar/Navbar.tsx b/src/components/Navbar/Navbar.tsx index 194b28b..fd8bdfe 100644 --- a/src/components/Navbar/Navbar.tsx +++ b/src/components/Navbar/Navbar.tsx @@ -1,7 +1,8 @@ import * as React from 'react' -import styled from 'styled-components' +import styled, { createGlobalStyle } from 'styled-components' import SecondaryNavItem from '../SecondaryNavItem/SecondaryNavItem' import PrimaryNavItem from '../PrimaryNavItem/PrimaryNavItem' +import Link from 'next/link' const Base = styled('aside')({ width: 360, @@ -59,9 +60,37 @@ const PrimaryNavItemGroup = styled('div')({ }) const SecondaryNavItems = styled('nav')({ + width: '100%', + height: '100%', + position: 'fixed', + top: 0, + left: 0, + paddingBottom: '4rem', + boxSizing: 'border-box', + pointerEvents: 'none', + '@media (min-width: 1080px)': { + position: 'relative', + top: 'auto', + left: 'auto', + flex: 'auto', + width: 'auto', + paddingBottom: 0, + pointerEvents: 'initial', + }, +}) + +const SecondaryNavItemsFg = styled('div')({ height: '100%', - position: 'relative', backgroundColor: 'var(--color-bg)', + width: 360, + position: 'absolute', + top: 0, + left: -360, + paddingBottom: '4rem', + boxSizing: 'border-box', + transitionProperty: 'left', + transitionDuration: '350ms', + transitionTimingFunction: 'ease-out', '::before': { content: "''", display: 'block', @@ -73,27 +102,34 @@ const SecondaryNavItems = styled('nav')({ backgroundColor: 'black', opacity: 0.03125, }, - '@media (min-width: 1080px)': { - flex: 'auto', - }, -}) - -const VisibleSecondaryNavItems = styled(SecondaryNavItems)({ - position: 'fixed', - top: 0, - left: 0, - width: '100%', - paddingBottom: '4rem', - boxSizing: 'border-box', '@media (min-width: 1080px)': { position: 'relative', top: 'auto', left: 'auto', + flex: 'auto', width: 'auto', paddingBottom: 0, }, }) +const SecondaryNavItemsBg = styled('a')({ + opacity: 0, + transitionProperty: 'opacity', + transitionDuration: '350ms', + transitionTimingFunction: 'ease-out', + '::before': { + content: "''", + display: 'block', + top: 0, + left: 0, + width: '100%', + height: '100%', + position: 'absolute', + backgroundColor: 'black', + opacity: 0.75, + }, +}) + const SecondaryNavItemsOverflow = styled('div')({ overflow: 'auto', width: '100%', @@ -116,15 +152,40 @@ const NavbarContainer = styled('div')({ maxWidth: 360, }) +const SecondaryVisibleDummy = styled('div')({ + display: 'none', +}) + +const Visible = createGlobalStyle({ + [`div + ${SecondaryNavItems}`]: { + pointerEvents: 'initial', + }, + [`div + ${SecondaryNavItems} ${SecondaryNavItemsFg}`]: { + left: 0, + }, + [`div + ${SecondaryNavItems} ${SecondaryNavItemsBg}`]: { + opacity: 1, + }, + '@media (min-width: 1080px)': { + [`div + ${SecondaryNavItems} ${SecondaryNavItemsFg}`]: { + left: 'auto', + }, + [`div + ${SecondaryNavItems} ${SecondaryNavItemsBg}`]: { + opacity: 0, + }, + } +}) + const Navbar = ({ + closeHref, secondaryVisible, primaryItemsStart = [], primaryItemsEnd = [], secondaryItemsHeader = [], secondaryItems = [], -}) => { - const SecondaryNavItemsComponent = secondaryVisible ? VisibleSecondaryNavItems : SecondaryNavItems - return ( +}) => ( + + @@ -165,42 +226,57 @@ const Navbar = ({ } - - - { - secondaryItemsHeader.map(i => ( - - )) - } - { - secondaryItems.map(i => ( - - )) - } - - + { + secondaryVisible + && ( + + ) + } + + + + + + + { + secondaryItemsHeader.map(i => ( + + )) + } + { + secondaryItems.map(i => ( + + )) + } + + + - ) -} + +) export default Navbar diff --git a/src/components/PrimaryNavItem/PrimaryNavItem.tsx b/src/components/PrimaryNavItem/PrimaryNavItem.tsx index c53ff4d..b3a34c3 100644 --- a/src/components/PrimaryNavItem/PrimaryNavItem.tsx +++ b/src/components/PrimaryNavItem/PrimaryNavItem.tsx @@ -89,6 +89,7 @@ const PrimaryNavItem: React.FC = ({ = ({ href={href} replace={replace} passHref + shallow > - - - - { - iconName - && ( - - ) - } - - 0 ? 1 : 0.5, }} - > + + { + iconName + && ( + + ) + } + + + 0 ? 1 : 0.5, }} + > + {title.length > 0 ? title : '(untitled)'} - - + + { subtitle && ( @@ -153,7 +173,7 @@ const SecondaryNavItem: React.FC = ({ ) } - + { diff --git a/src/pages/notes.tsx b/src/pages/notes.tsx index a9d929a..c292e54 100644 --- a/src/pages/notes.tsx +++ b/src/pages/notes.tsx @@ -91,6 +91,19 @@ const Notes = ({ id: idProp }) => { key !== 'navbar') + .reduce( + (theQuery, [key, value]) => ({ + ...theQuery, + [key]: value, + }), + {} + ), + }} secondaryVisible={Boolean(router.query.navbar)} primaryItemsStart={[ { @@ -213,14 +226,11 @@ const Notes = ({ id: idProp }) => { replace: true, title: n.title.trim(), subtitle: ( - - {'Last updated '} - - + ), actions: [ {