Menu at a coffee shop displaying various drinks and their price. In the background, there is a statue of a pigeon looking at us.

Menu

Implementation

  • Steal a hamburger SVG from a Tailwind CSS tutorial
  • Steal some Tailwind CSS code from the navigation component example as well as from the tutorial
  • To control things when the pop-up menu is open or closed, using a MenuProvider—fun!

MenuProvider

  • Defining
1import * as React from 'react'
2import { useState } from 'react'
3
4export const MenuContext = React.createContext()
5
6export const MenuProvider = ({ children }) => {
7 const [menuOpen, setMenuOpen] = useState(false)
8
9 return (
10 <MenuContext.Provider value={{ menuOpen, setMenuOpen }}>
11 {children}
12 </MenuContext.Provider>
13 )
14}
  • Using
1import { useContext } from 'react'
2import { MenuContext } from '../components'
3
4export const Header = ({ siteTitle }) => {
5 const { menuOpen, setMenuOpen } = useContext(MenuContext)
6 // At this point, you can use menuOpen and setMenuOpen!
7 //...
8}

Using Props with twin.macro Styled-component

ContentWrapper - the styled component

  • The mt-40 is going to have to be constantly updated if new menu items are added.
  • Added menuShift because for the landing pages and posts, it looks nice going over the picture.
1// menuOpen is passed from the main component
2// it can then be used to add more tailwind styles as needed
3const ContentWrapper = styled.div(({ menuOpen, menuShift }) => [
4 tw`p-4 mx-4 mt-6 bg-container rounded-lg shadow-lg`,
5 menuOpen && menuShift && tw`mt-40`,
6])

Content - the main component

1export const Content = ({ children }) => {
2 const { menuOpen } = useContext(MenuContext)
3 // Pass in a prop called menuOpen to the styled component
4 // I tried <ContentWrapper menuOpen> but that didn't work
5 return (
6 <ContentWrapper menuOpen={menuOpen} menuShift={menuShift}>
7 {children}
8 </ContentWrapper>
9 )
10}

Scroll Bar Fun

When the scroll bar is not needed and then becomes needed, the menus and dark toggle fidget about. There was some CSS code in the html element from the original layout.css that I did not bring over which fixed this.

  • overflow-y: scroll;

Menu Design

Using the normal primary color (teal for light, orange for dark) did not look good for the menus. Created opposite colors for the theme. —primary is Sharks Teal, —opposite is Sharks Orange for light and vice versa for dark. This is how I had it in a mock-up and I think I like how it it looks. It does make me think the opposite color (secondary if you will) could be used more in the site.

Popup Menu

Originally, the idea was to have the theme toggle go away on a popup menu. However, I just realized now (as 2021 just started!) that this would make it impossible for mobile users to toggle the theme. I added the button as a flex container…a first for me. I thought to myself, why can't it be done? And it was done!

Button as Flex

I used spans for the text and icon but I probably could have used paragraphs, still, span sang to me for this. After all, these are just bits of the button.

1return (
2 <div className='hover:bg-opposite'>
3 <button
4 type='button'
5 onClick={() => {
6 setTheme(theme === 'light' ? 'dark' : 'light')
7 }}
8 className='sm:inline sm:ml-2 flex justify-between items-center w-full pr-6'
9 >
10 <span className='block sm:hidden px-2 py-1 font-semibold rounded hover:bg-opposite'>
11 {' '}
12 Toggle Theme{' '}
13 </span>
14 <span className='block'>{`${theme === 'light' ? '🌙' : '🌞'}`}</span>
15 </button>
16 </div>
17)

With this done, the button looks rather like any other menu item and reaches across the whole screen. A little padding on the right and the icon lines up pretty well with the menu button.

Final Tweaks

After getting the mobile dark mode toggle in the menu looking perfect, it looked poor for the desktop. That took some tweaking and remembering that top padding and margins both do nothing when an element is inline! (ugh!)

Attributions

Photo by Croissant (@getcroissant) on Unsplash

Built with Gatsby from 2020 thru 2024 (and beyond?!)