refactor(v2): mobile dropdown navbar: expand when subitem become active (#5168)

This commit is contained in:
Sébastien Lorber 2021-07-14 19:42:47 +02:00 committed by GitHub
parent 007e901354
commit 818fb3956b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 5 deletions

View file

@ -7,21 +7,49 @@
import React, {useState, useRef, useEffect} from 'react';
import clsx from 'clsx';
import {useLocation} from '@docusaurus/router';
import {
isSamePath,
useCollapsible,
Collapsible,
useLocalPathname,
} from '@docusaurus/theme-common';
import type {
DesktopOrMobileNavBarItemProps,
Props,
} from '@theme/NavbarItem/DropdownNavbarItem';
import type {LinkLikeNavbarItemProps} from '@theme/NavbarItem';
import {NavLink} from '@theme/NavbarItem/DefaultNavbarItem';
import NavbarItem from '@theme/NavbarItem';
const dropdownLinkActiveClass = 'dropdown__link--active';
function isItemActive(
item: LinkLikeNavbarItemProps,
localPathname: string,
): boolean {
if (isSamePath(item.to, localPathname)) {
return true;
}
if (
item.activeBaseRegex &&
new RegExp(item.activeBaseRegex).test(localPathname)
) {
return true;
}
if (item.activeBasePath && localPathname.startsWith(item.activeBasePath)) {
return true;
}
return false;
}
function containsActiveItems(
items: readonly LinkLikeNavbarItemProps[],
localPathname: string,
): boolean {
return items.some((item) => isItemActive(item, localPathname));
}
function DropdownNavbarItemDesktop({
items,
position,
@ -102,12 +130,20 @@ function DropdownNavbarItemMobile({
position: _position, // Need to destructure position from props so that it doesn't get passed on.
...props
}: DesktopOrMobileNavBarItemProps) {
const {pathname} = useLocation();
const {collapsed, toggleCollapsed} = useCollapsible({
initialState: () =>
!items?.some((item) => isSamePath(item.to, pathname)) ?? true,
const localPathname = useLocalPathname();
const containsActive = containsActiveItems(items, localPathname);
const {collapsed, toggleCollapsed, setCollapsed} = useCollapsible({
initialState: () => !containsActive,
});
// Expand/collapse if any item active after a navigation
useEffect(() => {
if (containsActive) {
setCollapsed(!containsActive);
}
}, [localPathname, containsActive]);
return (
<li
className={clsx('menu__list-item', {

View file

@ -63,3 +63,5 @@ export {
AnnouncementBarProvider,
useAnnouncementBar,
} from './utils/announcementBarUtils';
export {useLocalPathname} from './utils/useLocalPathname';

View file

@ -0,0 +1,20 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import {useLocation} from '@docusaurus/router';
// Get the pathname of current route, without the optional site baseUrl
// - /docs/myDoc => /docs/myDoc
// - /baseUrl/docs/myDoc => /docs/myDoc
export function useLocalPathname(): string {
const {
siteConfig: {baseUrl},
} = useDocusaurusContext();
const {pathname} = useLocation();
return pathname.replace(baseUrl, '/');
}