-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WEB-4242] Mobile navigation fixes #2486
Changes from all commits
85883ce
4264dc1
00cbd8d
c4dd183
851beea
57e319a
ea494aa
a3f6d8c
0183e2d
043b691
a4544c1
c373b3e
54dcb88
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import React, { useState, useEffect, useContext } from 'react'; | ||
import React, { useContext } from 'react'; | ||
import { useLocation } from '@reach/router'; | ||
import Icon from '@ably/ui/core/Icon'; | ||
import AblyHeader from '@ably/ui/core/Header'; | ||
import { SearchBar } from '../SearchBar'; | ||
|
@@ -10,7 +11,7 @@ type HeaderProps = { | |
}; | ||
|
||
const Header: React.FC<HeaderProps> = ({ searchBar = true }) => { | ||
const [showMenu, setShowMenu] = useState(false); | ||
const location = useLocation(); | ||
const userContext = useContext(UserContext); | ||
const sessionState = { | ||
...userContext.sessionState, | ||
|
@@ -33,30 +34,6 @@ const Header: React.FC<HeaderProps> = ({ searchBar = true }) => { | |
// } | ||
// }; | ||
|
||
useEffect(() => { | ||
const handleResize = () => { | ||
if (window.innerWidth >= 1040) { | ||
setShowMenu(false); | ||
} | ||
}; | ||
|
||
window.addEventListener('resize', handleResize); | ||
return () => window.removeEventListener('resize', handleResize); | ||
}, []); | ||
|
||
useEffect(() => { | ||
if (showMenu) { | ||
document.body.classList.add('overflow-hidden'); | ||
} else { | ||
document.body.classList.remove('overflow-hidden'); | ||
} | ||
|
||
// Cleanup on unmount | ||
return () => { | ||
document.body.classList.remove('overflow-hidden'); | ||
}; | ||
}, [showMenu]); | ||
|
||
return ( | ||
<AblyHeader | ||
// TODO: reenable when examples are ready to be released | ||
|
@@ -86,7 +63,7 @@ const Header: React.FC<HeaderProps> = ({ searchBar = true }) => { | |
mobileNav={<LeftSidebar inHeader key="nav-mobile-documentation-tab" />} | ||
searchButton={ | ||
<button | ||
className="cursor-pointer focus-base rounded" | ||
className="cursor-pointer focus-base rounded px-0 pt-4 text-neutral-1300 dark:text-neutral-000" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🍎 overrides button colouring with its own blue, how thoughtful |
||
aria-label="Toggle search" | ||
onClick={() => { | ||
const searchContainer = document.querySelector('#inkeep-search > div'); | ||
|
@@ -125,6 +102,7 @@ const Header: React.FC<HeaderProps> = ({ searchBar = true }) => { | |
]} | ||
sessionState={sessionState} | ||
logoHref="/docs" | ||
location={location} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Piping this in instructs the header menu to close when it changes. |
||
/> | ||
); | ||
}; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import { useMemo, useState, useEffect, useRef } from 'react'; | ||
import { useLocation } from '@reach/router'; | ||
import { navigate, useLocation } from '@reach/router'; | ||
import cn from '@ably/ui/core/utils/cn'; | ||
import Accordion from '@ably/ui/core/Accordion'; | ||
import Icon from '@ably/ui/core/Icon'; | ||
|
@@ -130,6 +130,26 @@ const constructProductNavData = ( | |
return { | ||
name: product.name, | ||
icon: activePageTree[0]?.page.name === product.name ? product.icon.open : product.icon.closed, | ||
onClick: () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When a top-level accordion item is clicked, then it tries to bring the header row into view if it isn't visible - this happens after the opening animation has concluded, to ensure that the |
||
// When a product is clicked, find and scroll to any open accordion element | ||
if (typeof document !== 'undefined') { | ||
// Use setTimeout to ensure the DOM has updated after the click and animation has completed | ||
setTimeout(() => { | ||
const targetAccordion = window.innerWidth >= 1040 ? 'left-nav' : 'mobile-nav'; | ||
const menuContainer = document.getElementById(targetAccordion); | ||
const openAccordion: HTMLElement | null = menuContainer | ||
? menuContainer.querySelector('[data-state="open"] > button') | ||
: null; | ||
|
||
if (openAccordion) { | ||
menuContainer?.scrollTo({ | ||
top: openAccordion.offsetTop, | ||
behavior: 'smooth', | ||
}); | ||
} | ||
}, 200); | ||
} | ||
}, | ||
content: ( | ||
<div key={product.name} className="flex flex-col gap-20 px-16 pt-12"> | ||
{product.showJumpLink ? ( | ||
|
@@ -163,6 +183,18 @@ const constructProductNavData = ( | |
}; | ||
}); | ||
|
||
// Add a Home entry at the start of navData if inHeader is true | ||
if (inHeader) { | ||
navData.unshift({ | ||
name: 'Home', | ||
content: null, | ||
onClick: () => { | ||
navigate('/docs'); | ||
}, | ||
interactive: false, | ||
}); | ||
} | ||
|
||
return navData; | ||
}; | ||
|
||
|
@@ -192,29 +224,18 @@ const LeftSidebar = ({ inHeader = false }: LeftSidebarProps) => { | |
); | ||
|
||
return ( | ||
<> | ||
{inHeader ? ( | ||
<a | ||
href="/docs" | ||
aria-label="Home" | ||
className="flex w-full items-center focus-base text-neutral-1000 dark:text-neutral-300 hover:text-neutral-1100 active:text-neutral-1000 transition-colors h-40 ui-text-menu1 font-bold px-16 mt-16" | ||
> | ||
Home | ||
</a> | ||
) : null} | ||
<Accordion | ||
ref={sidebarRef} | ||
className={cn( | ||
!inHeader && [sidebarAlignmentClasses, 'hidden md:block md:-mx-16'], | ||
'overflow-y-auto', | ||
hasScrollbar ? 'md:pr-8' : 'md:pr-16', | ||
)} | ||
style={sidebarAlignmentStyles} | ||
id="left-nav" | ||
data={productNavData} | ||
{...commonAccordionOptions(null, activePage.tree[0]?.index, true, inHeader)} | ||
/> | ||
</> | ||
<Accordion | ||
ref={sidebarRef} | ||
className={cn( | ||
!inHeader && [sidebarAlignmentClasses, 'hidden md:block md:-mx-16'], | ||
'overflow-y-auto', | ||
hasScrollbar ? 'md:pr-8' : 'md:pr-16', | ||
)} | ||
style={sidebarAlignmentStyles} | ||
id={inHeader ? 'mobile-nav' : 'left-nav'} | ||
data={productNavData} | ||
{...commonAccordionOptions(null, activePage.tree[0]?.index, true, inHeader)} | ||
/> | ||
); | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This now lives in ably-ui and was left behind after the back-merge