Skip to content

Commit

Permalink
🎉 add scrollTo when expanding SiteNavigationToggle on mobile
Browse files Browse the repository at this point in the history
  • Loading branch information
ikesau committed Feb 19, 2025
1 parent 14cf231 commit c14269b
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
10 changes: 8 additions & 2 deletions site/SiteMobileMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react"
import { useRef, useState } from "react"
import { CategoryWithEntries } from "@ourworldindata/utils"
import classnames from "classnames"
import { SiteNavigationToggle } from "./SiteNavigationToggle.js"
Expand All @@ -21,6 +21,8 @@ export const SiteMobileMenu = ({
const [activeCategory, setActiveCategory] =
useState<CategoryWithEntries | null>(null)

const menuRef = useRef<HTMLDivElement>(null)

const toggleCategory = (category: CategoryWithEntries) => {
if (activeCategory === category) {
setActiveCategory(null)
Expand All @@ -30,7 +32,7 @@ export const SiteMobileMenu = ({
}

return (
<div className={classnames("SiteMobileMenu", className)}>
<div ref={menuRef} className={classnames("SiteMobileMenu", className)}>
<ul>
<li>
<span className="section__header">Browse by topic</span>
Expand Down Expand Up @@ -69,6 +71,8 @@ export const SiteMobileMenu = ({
dropdown={<SiteResources />}
withCaret={true}
className="SiteNavigationToggle--lvl1"
shouldScrollIntoView
menuRef={menuRef}
>
Resources
</SiteNavigationToggle>
Expand All @@ -85,6 +89,8 @@ export const SiteMobileMenu = ({
dropdown={<SiteAbout />}
withCaret={true}
className="SiteNavigationToggle--lvl1"
shouldScrollIntoView
menuRef={menuRef}
>
About
</SiteNavigationToggle>
Expand Down
19 changes: 19 additions & 0 deletions site/SiteNavigationToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export const SiteNavigationToggle = ({
withCaret = false,
dropdown,
className,
shouldScrollIntoView = false,
menuRef,
}: {
ariaLabel: string
children: React.ReactNode
Expand All @@ -19,7 +21,24 @@ export const SiteNavigationToggle = ({
withCaret?: boolean
dropdown?: React.ReactNode
className?: string
shouldScrollIntoView?: boolean
menuRef?: React.RefObject<HTMLDivElement>
}) => {
React.useLayoutEffect(() => {
if (shouldScrollIntoView && isActive && menuRef?.current) {
const menuBottomOffset =
menuRef.current.getBoundingClientRect().bottom

// put bottom of the menu at the bottom of the viewport if it's offscreen
if (menuBottomOffset > window.innerHeight) {
window.scrollTo({
top: menuBottomOffset - window.innerHeight + window.scrollY,
behavior: "smooth",
})
}
}
}, [shouldScrollIntoView, menuRef, isActive])

return (
<div
className={cx("SiteNavigationToggle", className, {
Expand Down

0 comments on commit c14269b

Please sign in to comment.