This post will go over the responsive menu experience I built for this website. Instead of the typical hambuger style drawer navigation for mobile, I wanted the site to feel more "app-like" with navigation tabs at the bottom of the viewport.
Let's start by building out the tabs for mobile navigation by creating a new component called NavbarBottom.js in the src/components folder.
import React, { Component } from 'react'
import { Link } from 'gatsby'
import {
Icon,
Menu,
Responsive
} from 'semantic-ui-react'
export default class NavbarBottom extends Component {
render() {
return (
<Responsive as={Menu} icon='labeled' fluid widths={4} fixed='bottom' maxWidth={Responsive.onlyTablet.maxWidth}>
<Menu.Item as={Link} activeClassName='active' to='/'>
<Icon name='home' />
Home
</Menu.Item>
<Menu.Item as={Link} activeClassName='active' to='portfolio'>
<Icon name='folder open' />
Portfolio
</Menu.Item>
<Menu.Item as={Link} activeClassName='active' to='blog'>
<Icon name='file alternate' />
Blog
</Menu.Item>
<Menu.Item as={Link} activeClassName='active' to='contact'>
<Icon name='paper plane' />
Contact
</Menu.Item>
</Responsive>
)
}
}
With the <Responsive>
SUIR component we can manipulate when this component is visible to the user. In this case, I wanted the navigation tabs to show up for smartphone and tablet devices. This was done by setting maxWidth={Responsive.onlyTablet.maxWidth}
. The cool thing about this is this component will not be included in the DOM at larger device widths which avoid the redundancy of having two menus present in the DOM that are manipulated with CSS display/visibility rules. I also really like how SUIR allows you to pass in any SUIR component into another. For example, passing <Menu>
into the <Responsive>
'as' prop. This works especially well when passing the the Gatsby <Link>
component into the the <Menu.Item>
to retain all the benefits of using Gatsby Link.
Note: Offset the page by the height of the tabbed menu
Add some css to offset the height of the tabbed menu or else it will cover up some of the bottom of the page.
Now lets create the navigation menu that will be displayed on viewports larger than the tablet breakpoint. Create a new component in src/components called Navbar.js.
A few details about the UI functionality before we begin:
Note to self: break this up into sections with animated gifs
import React, { Component } from 'react'
import { Link, withPrefix } from 'gatsby'
import {
Container,
Icon,
Menu,
Responsive,
Visibility
} from 'semantic-ui-react'
const menuStyle = {
border: 'none',
borderRadius: 0,
boxShadow: 'none',
marginBottom: '1em',
backgroundColor: 'transparent',
transition: 'box-shadow 0.5s ease, padding 0.5s ease',
}
const fixedMenuStyle = {
backgroundColor: '#fff',
border: '1px solid #ddd',
boxShadow: '0px 3px 5px rgba(0, 0, 0, 0.2)',
}
export default class Navbar extends Component {
state = {
menuFixed: false,
}
stickTopMenu = () => this.setState({ menuFixed: true })
unStickTopMenu = () => this.setState({ menuFixed: false })
handleOnUpdate = (e, { width }) => this.setState({ width })
render() {
const { menuFixed, width } = this.state
const menuWidths = width >= Responsive.onlyTablet.maxWidth ? null : 1
const isHomepage = typeof window !== 'undefined' && window.location.pathname === withPrefix("/");
return (
<Visibility
onBottomPassed={this.stickTopMenu}
onBottomVisible={this.unStickTopMenu}
offset={[0, -50]}
once={false}
>
<Responsive as={Menu}
borderless
inverted={menuFixed || !isHomepage ? false : true}
fixed={'top'}
style={menuFixed ? fixedMenuStyle : menuStyle}
fireOnMount
onUpdate={this.handleOnUpdate}
widths={menuWidths}
>
<Container text >
<Menu.Item header as={Link} to='/'>
<Icon name='terminal' />
CHRIS JAEGER
</Menu.Item>
<Responsive as={Menu.Menu} position='right' {...Responsive.onlyComputer}>
<Menu.Item as={Link} activeClassName='active' to='blog'>BLOG</Menu.Item>
<Menu.Item as={Link} activeClassName='active' to='portfolio'>PORTFOLIO</Menu.Item>
<Menu.Item as={Link} activeClassName='active' to='contact'>CONTACT</Menu.Item>
</Responsive>
</Container>
</Responsive>
</Visibility>
)
}
}
no results when searching for semantic ui responsive menu icon center This can help people with that.