From 5aa20b99f370213c141b639bc613778d933a0dd1 Mon Sep 17 00:00:00 2001 From: Josefina Mancilla <32556167+jnm2377@users.noreply.github.com> Date: Tue, 19 May 2020 09:10:51 -0500 Subject: [PATCH] fix: left nav duplicate active selection and jumping scroll (#819) * v1.17.2 * v1.17.3 * fix: left nav is active bug and jumping scroll * fix: query selector classname * chore: add testing example * chore: comments * fix: update scollOffset name * fix: tweak hooks logic * fix: remove hook reference * fix: only set scroll top when it isn't defined * fix: remove nav context scroll function * fix: remove testing pages Co-authored-by: Vince Picone Co-authored-by: Scott Strubberg Co-authored-by: Vince Picone --- .../src/components/LeftNav/LeftNav.js | 28 +++++++++++++++++-- .../src/components/LeftNav/LeftNavItem.js | 10 +++---- .../src/util/context/NavContext.js | 8 +++++- 3 files changed, 37 insertions(+), 9 deletions(-) diff --git a/packages/gatsby-theme-carbon/src/components/LeftNav/LeftNav.js b/packages/gatsby-theme-carbon/src/components/LeftNav/LeftNav.js index 032062eb8..f96a360c3 100644 --- a/packages/gatsby-theme-carbon/src/components/LeftNav/LeftNav.js +++ b/packages/gatsby-theme-carbon/src/components/LeftNav/LeftNav.js @@ -1,4 +1,4 @@ -import React, { useContext } from 'react'; +import React, { useContext, useRef, useEffect } from 'react'; import classnames from 'classnames'; import { SideNav, SideNavItems } from 'carbon-components-react'; import { useNavItems } from './LeftNavItemProvider'; @@ -11,7 +11,28 @@ import LeftNavWrapper from './LeftNavWrapper'; import { sideNavDark } from './LeftNav.module.scss'; const LeftNav = (props) => { - const { leftNavIsOpen } = useContext(NavContext); + const { leftNavIsOpen, leftNavScrollTop, setLeftNavScrollTop } = useContext( + NavContext + ); + + const sideNavRef = useRef(); + const sideNavListRef = useRef(); + + useEffect(() => { + sideNavListRef.current = sideNavRef.current.querySelector('.sidenav-list'); + }, []); + + useEffect(() => { + sideNavListRef.current.addEventListener('scroll', (e) => { + setLeftNavScrollTop(e.target.scrollTop); + }); + }, [setLeftNavScrollTop]); + + useEffect(() => { + if (leftNavScrollTop >= 0 && !sideNavListRef?.current.scrollTop) { + sideNavListRef.current.scrollTop = leftNavScrollTop; + } + }, [leftNavScrollTop]); const navItems = useNavItems(); @@ -19,6 +40,7 @@ const LeftNav = (props) => { return ( { props.theme !== 'dark' && !props.homepage, })} > - + {navItems.map((item, i) => ( ))} diff --git a/packages/gatsby-theme-carbon/src/components/LeftNav/LeftNavItem.js b/packages/gatsby-theme-carbon/src/components/LeftNav/LeftNavItem.js index 324a13281..b83826d8f 100644 --- a/packages/gatsby-theme-carbon/src/components/LeftNav/LeftNavItem.js +++ b/packages/gatsby-theme-carbon/src/components/LeftNav/LeftNavItem.js @@ -16,7 +16,9 @@ import usePathprefix from '../../util/hooks/usePathprefix'; const LeftNavItem = (props) => { const { items, category } = props; const { toggleNavState } = useContext(NavContext); - const closeLeftNav = () => toggleNavState('leftNavIsOpen', 'close'); + const closeLeftNav = () => { + toggleNavState('leftNavIsOpen', 'close'); + }; const pathPrefix = usePathprefix(); return ( @@ -66,10 +68,8 @@ const LeftNavItem = (props) => { const SubNavItems = ({ items, pathname, onClick }) => items.map((item, i) => { const hasActiveTab = - item.path.split('/') > 3 - ? item.path.split('/')[3] === pathname.split('/')[3] - : item.path.split('/')[2] === pathname.split('/')[2]; - + `${item.path.split('/')[1]}/${item.path.split('/')[2]}` === + `${pathname.split('/')[1]}/${pathname.split('/')[2]}`; return ( { @@ -19,7 +20,7 @@ const reducer = (state, action) => { }; export const NavContextProvider = ({ children }) => { const [ - { leftNavIsOpen, searchIsOpen, switcherIsOpen }, + { leftNavIsOpen, searchIsOpen, switcherIsOpen, leftNavScrollOffset }, dispatch, ] = useReducer(reducer, { leftNavIsOpen: false, @@ -27,6 +28,8 @@ export const NavContextProvider = ({ children }) => { switcherIsOpen: false, }); + const [leftNavScrollTop, setLeftNavScrollTop] = useState(0); + const toggleNavState = (nav, type) => { dispatch({ nav, type }); }; @@ -40,6 +43,9 @@ export const NavContextProvider = ({ children }) => { toggleNavState, isManagingFocus, setIsManagingFocus, + leftNavScrollOffset, + leftNavScrollTop, + setLeftNavScrollTop, }; return {children};