Skip to content

Commit

Permalink
fix: close mobile nav on blur of nav list
Browse files Browse the repository at this point in the history
  • Loading branch information
SatyamSetia committed Nov 1, 2023
1 parent 2911aba commit 0dcc3e5
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 20 deletions.
13 changes: 6 additions & 7 deletions components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import styles from "./Header.module.css"

export interface IHeaderProps {
handleNavClick: () => void
showNavMobile: boolean
isNavMobileOpen: boolean
}

export const Header = ({ handleNavClick, showNavMobile }: IHeaderProps) => {
export const Header = ({ handleNavClick, isNavMobileOpen }: IHeaderProps) => {
return (
<>
<header>
Expand All @@ -21,12 +21,11 @@ export const Header = ({ handleNavClick, showNavMobile }: IHeaderProps) => {
className={styles.hamburgerBtn}
onClick={handleNavClick}
aria-label="Navigation menu"
aria-expanded={showNavMobile}>
{!showNavMobile && (
<IoMenuSharp size="1.5rem" aria-hidden="true" />
)}
{showNavMobile && (
aria-expanded={isNavMobileOpen}>
{isNavMobileOpen ? (
<IoCloseSharp size="1.5rem" aria-hidden="true" />
) : (
<IoMenuSharp size="1.5rem" aria-hidden="true" />
)}
</button>
</div>
Expand Down
15 changes: 9 additions & 6 deletions components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,25 @@ interface ILayoutProps {
}

export const Layout = ({ activeNavLink, children }: ILayoutProps) => {
const [showNavMobile, setShowNavMobile] = useState<boolean>(false)
const [isNavMobileOpen, setIsNavMobileOpen] = useState<boolean>(false)

const handleNavClick = () => {
setShowNavMobile((prevState) => !prevState)
const toggleNavMobileOpen = () => {
setIsNavMobileOpen((prevState) => !prevState)
}

return (
<>
<SkipLink />
<Header handleNavClick={handleNavClick} showNavMobile={showNavMobile} />
<Header
handleNavClick={toggleNavMobileOpen}
isNavMobileOpen={isNavMobileOpen}
/>
<div className={styles.layoutContainer}>
<NavPrimary activeNavLink={activeNavLink} />
{showNavMobile && (
{isNavMobileOpen && (
<NavPrimaryMobile
activeNavLink={activeNavLink}
handleNavClick={handleNavClick}
closeNavMobile={toggleNavMobileOpen} // since, closeNavMobile prop can only be called when <NavPrimaryMobile /> is in open state so, toggleNavMobileOpen handler can be used for closing nav mobile.
/>
)}
<div className={styles.columnContainer}>
Expand Down
5 changes: 4 additions & 1 deletion components/Nav/NavItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import { IPage } from "../../data/pages"
export interface INavItemProps {
page: IPage
activeNavLink: string
isLastNavItem?: boolean
handleNavClick?: () => void
}

export const NavItem = ({
page,
activeNavLink,
isLastNavItem = false,
handleNavClick,
}: INavItemProps) => {
const isLinkActive = activeNavLink === page.href
Expand All @@ -19,7 +21,8 @@ export const NavItem = ({
<Link href={page.href}>
<a
onClick={handleNavClick}
aria-current={isLinkActive ? "page" : false}>
aria-current={isLinkActive ? "page" : false}
data-last-nav-item={isLastNavItem}>
{page.name}
</a>
</Link>
Expand Down
17 changes: 13 additions & 4 deletions components/Nav/NavPrimaryMobile.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,34 @@
import { FocusEvent, useCallback } from "react"
import { NavItem } from "./NavItem"
import { pages } from "../../data/pages"
import styles from "./NavPrimary.module.css"

export interface INavProps {
activeNavLink: string
handleNavClick: () => void
closeNavMobile: () => void
}

export const NavPrimaryMobile = ({
activeNavLink,
handleNavClick,
closeNavMobile,
}: INavProps) => {
const handleNavBlur = useCallback((event: FocusEvent<HTMLAnchorElement>) => {
const isLastNavItem = /true/i.test(event.target.dataset?.lastNavItem ?? "")
if (isLastNavItem) closeNavMobile()
}, [])
return (
<nav aria-label="Primary" className={styles.navPrimaryMobile}>
<nav
aria-label="Primary"
className={styles.navPrimaryMobile}
onBlur={handleNavBlur}>
<ul className={styles.navList}>
{pages.map((page, index) => (
<NavItem
key={page.name + index}
page={page}
activeNavLink={activeNavLink}
handleNavClick={handleNavClick}
handleNavClick={closeNavMobile}
isLastNavItem={pages.length === index + 1}
/>
))}
</ul>
Expand Down
2 changes: 1 addition & 1 deletion stories/Header.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ export const DesktopHeader = Template.bind({})
DesktopHeader.args = {
headerTitle: "Page Title",
handleNavClick: () => true,
showNavMobile: false,
isNavMobileOpen: false,
// eslint-disable-next-line @typescript-eslint/naming-convention
} as IHeaderProps
2 changes: 1 addition & 1 deletion stories/NavPrimaryMobile.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ export const MobilePrimaryNav = Template.bind({})

MobilePrimaryNav.args = {
activeNavLink: "/",
handleNavClick: () => true,
closeNavMobile: () => true,
// eslint-disable-next-line @typescript-eslint/naming-convention
} as INavProps

0 comments on commit 0dcc3e5

Please sign in to comment.