diff --git a/packages/app-project/src/components/ProjectHeader/components/DropdownNav/DropdownNav.js b/packages/app-project/src/components/ProjectHeader/components/DropdownNav/DropdownNav.js index 598d6164b6..1667cc3117 100644 --- a/packages/app-project/src/components/ProjectHeader/components/DropdownNav/DropdownNav.js +++ b/packages/app-project/src/components/ProjectHeader/components/DropdownNav/DropdownNav.js @@ -6,6 +6,7 @@ import { bool, object, oneOfType, string } from 'prop-types' import { useState } from 'react' import styled, { css } from 'styled-components' import { useTranslation } from 'next-i18next' +import { useRouter } from 'next/router' import { useProjectNavigation } from '../../hooks' @@ -47,7 +48,7 @@ function DropdownNav({ className, margin = defaultMargin, organizationSlug = '', - organizationTitle = '', + organizationTitle = '' }) { const { t } = useTranslation('components') const navLinks = useProjectNavigation(adminMode) @@ -61,6 +62,32 @@ function DropdownNav({ setIsOpen(true) } + function NavItem({ navLink }) { + const router = useRouter() + let isCurrentPage + if (router?.asPath) { + const routerPath = router.asPath.split('/') + const hrefPath = navLink.href.split('/') + /* + The path arrays will be ['', owner, project, section, ...rest]. + The section is always the fourth item. + */ + isCurrentPage = routerPath[3] === hrefPath[3] + } + + return ( + + + + ) + } + const dropContent = ( - - <> - {navLinks.map(navLink => ( - - - - ))} - + + {navLinks.map(navLink => ( + + ))} {organizationTitle ? ( - + - + {t('ProjectHeader.organization')} - + {organizationTitle} - )} + } /> ) : null} @@ -160,7 +163,4 @@ DropdownNav.propTypes = { } export default DropdownNav -export { - DropdownNav, - StyledDropButton -} +// export { DropdownNav, StyledDropButton } diff --git a/packages/app-project/src/components/ProjectHeader/components/Nav/Nav.js b/packages/app-project/src/components/ProjectHeader/components/Nav/Nav.js index 337d5afa89..467a7e9f40 100644 --- a/packages/app-project/src/components/ProjectHeader/components/Nav/Nav.js +++ b/packages/app-project/src/components/ProjectHeader/components/Nav/Nav.js @@ -1,5 +1,6 @@ import { SpacedText } from '@zooniverse/react-components' import { Anchor, Box } from 'grommet' +import { useRouter } from 'next/router' import { bool } from 'prop-types' import styled, { css } from 'styled-components' import { useTranslation } from 'next-i18next' @@ -28,31 +29,50 @@ const StyledAnchor = styled(Anchor)` &[href]:hover { border-bottom-color: ${props.color}; } - &:not([href]) { + &[aria-current='page'] { cursor: default; border-bottom-color: ${props.color}; } `} ` -function Nav({ - adminMode = false, -}) { +function NavItem({ navLink }) { + const router = useRouter() + + let isCurrentPage + if (router?.isReady) { + const routerPath = router.asPath.split('/') + const hrefPath = navLink.href.split('/') + /* + Client-side routerPath will be ['', owner, project, section, ...rest]. + The link hrefPath will be ['', owner, project, section, ...rest]. + The section is always the fourth item in the array. + */ + isCurrentPage = routerPath[3] === hrefPath[3] + } + + return ( + + + + ) +} + +function Nav({ adminMode = false }) { const navLinks = useProjectNavigation(adminMode) const { t } = useTranslation('components') return ( {navLinks.map(navLink => ( - - - + ))} diff --git a/packages/app-project/src/screens/ProjectAboutPage/components/AboutDropdownNav/AboutDropdownNav.js b/packages/app-project/src/screens/ProjectAboutPage/components/AboutDropdownNav/AboutDropdownNav.js index e3fe48ab6d..4080990432 100644 --- a/packages/app-project/src/screens/ProjectAboutPage/components/AboutDropdownNav/AboutDropdownNav.js +++ b/packages/app-project/src/screens/ProjectAboutPage/components/AboutDropdownNav/AboutDropdownNav.js @@ -1,5 +1,5 @@ import { useState } from 'react' -import { arrayOf, object, string } from 'prop-types' +import { arrayOf, string } from 'prop-types' import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next' @@ -9,8 +9,7 @@ import { FormDown } from 'grommet-icons' import { SpacedText } from '@zooniverse/react-components' import AboutNavLink from '../AboutNavLink' -// this is a separate componenet specifically for testing with enzyme -export const AboutDropContent = ({ aboutNavLinks }) => { +const AboutDropContent = ({ aboutNavLinks }) => { const router = useRouter() const { owner, project } = router.query const baseUrl = `/${owner}/${project}/about` @@ -24,14 +23,12 @@ export const AboutDropContent = ({ aboutNavLinks }) => { href: `${baseUrl}/research`, text: t('About.PageHeading.title.research') }} - router={router} /> {aboutNavLinks.includes('results') && ( { href: `${baseUrl}/results`, text: t('About.PageHeading.title.results') }} - router={router} /> )} {aboutNavLinks.includes('education') && ( @@ -48,7 +44,6 @@ export const AboutDropContent = ({ aboutNavLinks }) => { href: `${baseUrl}/education`, text: t('About.PageHeading.title.education') }} - router={router} /> )} {aboutNavLinks.includes('faq') && ( @@ -57,14 +52,13 @@ export const AboutDropContent = ({ aboutNavLinks }) => { href: `${baseUrl}/faq`, text: t('About.PageHeading.title.faq') }} - router={router} /> )} ) } -const AboutDropdownNav = ({ aboutNavLinks, router }) => { +const AboutDropdownNav = ({ aboutNavLinks }) => { const [isOpen, setIsOpen] = useState(false) const handleOpen = () => setIsOpen(!isOpen) @@ -77,7 +71,7 @@ const AboutDropdownNav = ({ aboutNavLinks, router }) => { isOpen={isOpen} alignSelf='center' dropContent={ - + } onClose={handleOpen} onOpen={handleOpen} @@ -94,7 +88,6 @@ const AboutDropdownNav = ({ aboutNavLinks, router }) => { AboutDropdownNav.propTypes = { aboutNavLinks: arrayOf(string), - router: object } export default AboutDropdownNav diff --git a/packages/app-project/src/screens/ProjectAboutPage/components/AboutNavLink/AboutNavLink.js b/packages/app-project/src/screens/ProjectAboutPage/components/AboutNavLink/AboutNavLink.js index 069e23f642..75d1da6946 100644 --- a/packages/app-project/src/screens/ProjectAboutPage/components/AboutNavLink/AboutNavLink.js +++ b/packages/app-project/src/screens/ProjectAboutPage/components/AboutNavLink/AboutNavLink.js @@ -1,10 +1,10 @@ -import { string, object, shape } from 'prop-types' +import { Anchor, Box } from 'grommet' +import { useRouter } from 'next/router' +import { string, shape } from 'prop-types' import styled from 'styled-components' -import addQueryParams from '@helpers/addQueryParams' -/** Components */ +import addQueryParams from '@helpers/addQueryParams' import NavLink from '@shared/components/NavLink' -import { Anchor, Box } from 'grommet' const StyledAnchor = styled(Anchor)` &:hover { @@ -12,9 +12,10 @@ const StyledAnchor = styled(Anchor)` } ` -const AboutNavLink = ({ router, link }) => { +const AboutNavLink = ({ link }) => { const { href } = link - const isCurrentPage = router?.asPath === addQueryParams(href) + const router = useRouter() + const isCurrentPage = router?.isReady && router?.asPath === addQueryParams(href) return ( { pad={{ horizontal: '20px', vertical: '5px' }} > { @@ -18,14 +18,12 @@ const AboutSidebar = ({ aboutNavLinks }) => { href: `${baseUrl}/research`, text: t('About.PageHeading.title.research') }} - router={router} /> {aboutNavLinks.includes('results') && ( { href: `${baseUrl}/results`, text: t('About.PageHeading.title.results') }} - router={router} /> )} {aboutNavLinks.includes('education') && ( @@ -42,7 +39,6 @@ const AboutSidebar = ({ aboutNavLinks }) => { href: `${baseUrl}/education`, text: t('About.PageHeading.title.education') }} - router={router} /> )} {aboutNavLinks.includes('faq') && ( @@ -51,7 +47,6 @@ const AboutSidebar = ({ aboutNavLinks }) => { href: `${baseUrl}/faq`, text: t('About.PageHeading.title.faq') }} - router={router} /> )} @@ -60,7 +55,6 @@ const AboutSidebar = ({ aboutNavLinks }) => { AboutSidebar.propTypes = { aboutNavLinks: arrayOf(string), - router: object } export default AboutSidebar diff --git a/packages/app-project/src/shared/components/NavLink/NavLink.js b/packages/app-project/src/shared/components/NavLink/NavLink.js index b7ebc0300d..d406b8b540 100644 --- a/packages/app-project/src/shared/components/NavLink/NavLink.js +++ b/packages/app-project/src/shared/components/NavLink/NavLink.js @@ -1,7 +1,6 @@ import { SpacedText } from '@zooniverse/react-components' import { Anchor } from 'grommet' import Link from 'next/link' -import { withRouter } from 'next/router' import PropTypes from 'prop-types' import addQueryParams from '@helpers/addQueryParams' @@ -10,23 +9,15 @@ function NavLink ({ color, disabled = false, link, - router = {}, StyledAnchor = Anchor, StyledSpacedText = SpacedText, weight, ...anchorProps }) { const { href, text } = link - const isCurrentPage = router?.asPath === addQueryParams(href) const label = {text} - if (isCurrentPage) { - return ( - - ) - } - if (disabled) { // On the surface this may look odd, since you can't disable links // Sometimes we want to render anchors that look like buttons @@ -39,7 +30,7 @@ function NavLink ({ // We also do not wrap it with next.js's Link return } - + return ( NavLink', function () { render() }) - it('should not have a link', function () { - expect(screen.queryByRole('link')).to.be.null() + it('should have the correct link', function () { + expect(screen.getByRole('link').getAttribute('href')).to.equal(NavLinkMock.href) }) it('should have the correct text', function () {