Skip to content

Commit

Permalink
feat: floating navigation for smaller screens (#190)
Browse files Browse the repository at this point in the history
* fix: quoting issue on post closes #189

* feat: add floating navigation option #171

* fix: style tuning and linting

* feat: style tuning for nav item #171

* feat: menu icon tuning #171
  • Loading branch information
ajfisher committed Feb 17, 2024
1 parent 09ac50c commit b2ba447
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 67 deletions.
2 changes: 1 addition & 1 deletion site/src/components/article.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ const StyledAttribution = styled.section`
padding: calc(0.25 * var(--gutter)) 0;
background: var(--light-bg-tint);
border-bottom: 0.4rem solid var(--light-base);
margin-bottom: var(--gutter);
@media only screen and ${device.large} {
border-radius: 0.2rem;
border-bottom: none;
border-top: 0.4rem solid var(--light-base);
margin-bottom: var(--gutter);
}
& h4 {
Expand Down
4 changes: 2 additions & 2 deletions site/src/components/devices.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

const size = {
small: '401px',
medium: '501px',
large: '751px',
medium: '601px',
large: '821px',
wide: '1051px'
};

Expand Down
12 changes: 7 additions & 5 deletions site/src/components/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const ListItems = styled.ul`
padding: 0;
margin: 0 var(--gutter) !important;
@media only screen and ${device.large} {
@media only screen and ${device.medium} {
display: flex;
flex-direction: row;
flex-wrap: wrap;
Expand All @@ -28,11 +28,11 @@ const Item = styled.li`
width: 100%;
height: min-content;
@media only screen and ${device.large} {
width: 47%;
@media only screen and ${device.medium} {
width: 49%;
}
@media only screen and ${device.wide} {
@media only screen and ${device.large} {
width: 45%;
}
`;
Expand Down Expand Up @@ -141,6 +141,8 @@ export const PostListItem = ({title, image, position, excerpt, date,
// work out if we should say An 8 minute or A 7 seven minute
const a_an = ([8,11,18].includes(rounded_time)) ? 'An' : 'A';

const reading_time = `${a_an} ${rounded_time} minute read (${humanised_words} words).`;

return (
<Item>
<ImageLink $position={position}>
Expand All @@ -153,7 +155,7 @@ export const PostListItem = ({title, image, position, excerpt, date,
{ excerpt.length > 0 &&
<p>{excerpt}</p>
}
<p>{a_an} {rounded_time} minute read ({humanised_words} words)</p>
<p>{reading_time}</p>
</Item>
);
};
Expand Down
220 changes: 164 additions & 56 deletions site/src/components/nav.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { useState } from 'react';
import styled from 'styled-components';

import { Link } from 'gatsby';
Expand All @@ -7,54 +7,139 @@ import { OutboundLink } from 'gatsby-plugin-google-analytics';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faTwitter, faInstagram, faGithub, faLinkedin } from '@fortawesome/free-brands-svg-icons';
import { faEnvelope } from '@fortawesome/free-regular-svg-icons';
import { faBars } from '@fortawesome/free-solid-svg-icons';

import { device } from './devices';

const Navigation = styled.nav`
const NavButton = styled.button`
padding: 0 var(--gutter);
display: inline-block;
z-index: 3; // place above content
transform: ${({ isOpen }) => isOpen ? 'rotate(90deg)' : 'none'};
position: fixed;
top: calc(0.5 * var(--gutter));
right: calc(0.5 * var(--gutter));
padding: calc(0.5 * var(--gutter));
border: none;
background-color: transparent;
font-size: 3rem;
color: var(--base);
transition: all 0.8s ease;
@media only screen and ${device.large} {
padding: 0;
display: none;
}
&:hover {
color: var(--dark-text-colour);
}
`;

const NavMenuOverlay = styled.div`
// this puts in the overlay to darken the rest of the page
// in order to focus the nav drawer
display: ${({ isOpen }) => isOpen ? 'block' : 'none'};
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
z-index: 1;
@media only screen and ${device.large} {
display: none;
}
`;

const NavDrawer = styled.nav`
display: flex;
flex-direction: column;
position: fixed;
z-index: 2;
top: 0;
right: ${({ isOpen }) => isOpen ? '0' : '-100%'};
height: 100%;
width: 75vw;
padding: var(--gutter);
background: var(--light-text-colour);
transition: right 0.5s ease-in-out;
@media only screen and ${device.medium} {
width: 60vw;
}
& ul {
margin: 0 0 var(--gutter) 0;
@media only screen and ${device.large} {
display: none;
}
`;

const MainNavigation = styled.nav`
display: none;
@media only screen and ${device.large} {
display: block;
padding: 0;
list-style-type: none;
}
@media only screen and ${device.large} {
margin: 0;
}
`;

& li {
font-size: 3.5rem;
line-height: 4rem;
margin: 0;
const NavItems = styled.ul`
@media only screen and ${device.large} {
font-size: 2.8rem;
line-height: inherit;
}
margin: 0;
padding: 0;
list-style-type: none;
& li {
font-size: 3rem;
line-height: 5rem;
margin: 0;
@media only screen and ${device.medium} {
font-size: 3.5rem;
line-height: 4.8rem;
}
& li:first-child {
margin-top: 0;
@media only screen and ${device.large} {
font-size: 2.8rem;
line-height: 3.5rem;
}
}
& li:first-child {
margin-top: 0;
}
& li.icons {
font-size: 4.2rem;
line-height: 6rem;
& li.icons {
@media only screen and ${device.medium} {
font-size: 5rem;
}
@media only screen and ${device.large} {
font-size: 4rem;
}
@media only screen and ${device.large} {
font-size: 3.5rem;
}
& a {
padding-right: calc(var(--gutter));
@media only screen and ${device.wide} {
font-size: 4rem;
}
@media only screen and ${device.large} {
padding-right: calc(0.5 * var(--gutter));
}
& a {
padding-right: calc(var(--gutter));
@media only screen and ${device.large} {
padding-right: calc(0.5 * var(--gutter));
}
}
}
Expand All @@ -74,35 +159,58 @@ const Navigation = styled.nav`
}
`;

const Nav = ({children}) => {
const Navigation = () => {

return (
<NavItems>
<li><Link to="/">Home</Link></li>
<li><Link to="/blog/">Article archive</Link></li>
<li><Link to="/who/">Who is @ajfisher</Link></li>
<li><Link to="/colophon/">Colophon</Link></li>
<li><Link to="/dis-everything/">Disclaimer & Disclosure</Link></li>
<li className="icons">
<OutboundLink title="@ajfisher on Github" href="https://github.com/ajfisher" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faGithub}/>
</OutboundLink>
<OutboundLink title="@ajfisher on Instagram" href="https://instagram.com/andrewjfisher" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faInstagram}/>
</OutboundLink>
<OutboundLink title="Send ajfisher an email" href="mailto:ajfisher.td@gmail.com" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faEnvelope}/>
</OutboundLink>
<OutboundLink title="@ajfisher on Twitter" href="https://twitter.com/ajfisher" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faTwitter}/>
</OutboundLink>
<OutboundLink title="@ajfisher on LinkedIn" href="https://www.linkedin.com/in/andrewfisher/" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faLinkedin}/>
</OutboundLink>
</li>
</NavItems>
);
}


const Nav = () => {

const [isOpen, setIsOpen] = useState(false);

const toggleMenu = () => {
setIsOpen(!isOpen);
};

return (
<Navigation>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/blog/">Article archive</Link></li>
<li><Link to="/who/">Who is @ajfisher</Link></li>
<li><Link to="/colophon/">Colophon</Link></li>
<li><Link to="/dis-everything/">Disclaimer & Disclosure</Link></li>
<li className="icons">
<OutboundLink title="@ajfisher on Github" href="https://github.com/ajfisher" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faGithub}/>
</OutboundLink>
<OutboundLink title="@ajfisher on Instagram" href="https://instagram.com/andrewjfisher" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faInstagram}/>
</OutboundLink>
<OutboundLink title="Send ajfisher an email" href="mailto:ajfisher.td@gmail.com" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faEnvelope}/>
</OutboundLink>
<OutboundLink title="@ajfisher on Twitter" href="https://twitter.com/ajfisher" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faTwitter}/>
</OutboundLink>
<OutboundLink title="@ajfisher on LinkedIn" href="https://www.linkedin.com/in/andrewfisher/" target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={faLinkedin}/>
</OutboundLink>
</li>
</ul>
</Navigation>
<>
<NavButton onClick={toggleMenu} isOpen={isOpen}>
<FontAwesomeIcon icon={faBars}/>
</NavButton>
<NavMenuOverlay isOpen={isOpen} onClick={toggleMenu}/>
<NavDrawer isOpen={isOpen}>
<Navigation/>
</NavDrawer>
<MainNavigation>
<Navigation/>
</MainNavigation>
</>
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ batteries laying around so it was a fairly straight forward process to get it
all up and running.

> Minecraft is a lot of fun, especially when you play with friends. Minecraft
servers are great but they aren’t very portable and rely on a good Internet
connection. What about if you could take your own portable server with you -
say to the park - and it will fit inside a lunchbox?
> servers are great but they aren’t very portable and rely on a good Internet
> connection. What about if you could take your own portable server with you -
> say to the park - and it will fit inside a lunchbox?
The build process for this is published over at Packt
[Building a portable minecraft server for LAN parties in the park](https://www.packtpub.com/books/content/building-portable-minecraft-server-lan-parties-park)
Expand Down

0 comments on commit b2ba447

Please sign in to comment.