mirror of
https://github.com/Snigdha-OS/documentation.git
synced 2025-09-18 20:54:56 +02:00
153 lines
4.7 KiB
JavaScript
153 lines
4.7 KiB
JavaScript
/**
|
|
* 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 React, {useState, useRef, useEffect} from 'react';
|
|
import clsx from 'clsx';
|
|
import {
|
|
isRegexpStringMatch,
|
|
useCollapsible,
|
|
Collapsible,
|
|
} from '@docusaurus/theme-common';
|
|
import {isSamePath, useLocalPathname} from '@docusaurus/theme-common/internal';
|
|
import NavbarNavLink from '@theme/NavbarItem/NavbarNavLink';
|
|
import NavbarItem from '@theme/NavbarItem';
|
|
import styles from './styles.module.css';
|
|
function isItemActive(item, localPathname) {
|
|
if (isSamePath(item.to, localPathname)) {
|
|
return true;
|
|
}
|
|
if (isRegexpStringMatch(item.activeBaseRegex, localPathname)) {
|
|
return true;
|
|
}
|
|
if (item.activeBasePath && localPathname.startsWith(item.activeBasePath)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
function containsActiveItems(items, localPathname) {
|
|
return items.some((item) => isItemActive(item, localPathname));
|
|
}
|
|
function DropdownNavbarItemDesktop({
|
|
items,
|
|
position,
|
|
className,
|
|
onClick,
|
|
...props
|
|
}) {
|
|
const dropdownRef = useRef(null);
|
|
const [showDropdown, setShowDropdown] = useState(false);
|
|
useEffect(() => {
|
|
const handleClickOutside = (event) => {
|
|
if (!dropdownRef.current || dropdownRef.current.contains(event.target)) {
|
|
return;
|
|
}
|
|
setShowDropdown(false);
|
|
};
|
|
document.addEventListener('mousedown', handleClickOutside);
|
|
document.addEventListener('touchstart', handleClickOutside);
|
|
document.addEventListener('focusin', handleClickOutside);
|
|
return () => {
|
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
document.removeEventListener('touchstart', handleClickOutside);
|
|
document.removeEventListener('focusin', handleClickOutside);
|
|
};
|
|
}, [dropdownRef]);
|
|
return (
|
|
<div
|
|
ref={dropdownRef}
|
|
className={clsx('navbar__item', 'dropdown', 'dropdown--hoverable', {
|
|
'dropdown--right': position === 'right',
|
|
'dropdown--show': showDropdown,
|
|
})}>
|
|
<NavbarNavLink
|
|
aria-haspopup="true"
|
|
aria-expanded={showDropdown}
|
|
role="button"
|
|
// # hash permits to make the <a> tag focusable in case no link target
|
|
// See https://github.com/facebook/docusaurus/pull/6003
|
|
// There's probably a better solution though...
|
|
href={props.to ? undefined : '#'}
|
|
className={clsx('navbar__link', className)}
|
|
{...props}
|
|
onClick={props.to ? undefined : (e) => e.preventDefault()}
|
|
onKeyDown={(e) => {
|
|
if (e.key === 'Enter') {
|
|
e.preventDefault();
|
|
setShowDropdown(!showDropdown);
|
|
}
|
|
}}>
|
|
{props.children ?? props.label}
|
|
</NavbarNavLink>
|
|
<ul className="dropdown__menu">
|
|
{items.map((childItemProps, i) => (
|
|
<NavbarItem
|
|
isDropdownItem
|
|
activeClassName="dropdown__link--active"
|
|
{...childItemProps}
|
|
key={i}
|
|
/>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
);
|
|
}
|
|
function DropdownNavbarItemMobile({
|
|
items,
|
|
className,
|
|
position, // Need to destructure position from props so that it doesn't get passed on.
|
|
onClick,
|
|
...props
|
|
}) {
|
|
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, setCollapsed]);
|
|
return (
|
|
<li
|
|
className={clsx('menu__list-item', {
|
|
'menu__list-item--collapsed': collapsed,
|
|
})}>
|
|
<NavbarNavLink
|
|
role="button"
|
|
className={clsx(
|
|
styles.dropdownNavbarItemMobile,
|
|
'menu__link menu__link--sublist menu__link--sublist-caret',
|
|
className,
|
|
)}
|
|
{...props}
|
|
onClick={(e) => {
|
|
e.preventDefault();
|
|
toggleCollapsed();
|
|
}}>
|
|
{props.children ?? props.label}
|
|
</NavbarNavLink>
|
|
<Collapsible lazy as="ul" className="menu__list" collapsed={collapsed}>
|
|
{items.map((childItemProps, i) => (
|
|
<NavbarItem
|
|
mobile
|
|
isDropdownItem
|
|
onClick={onClick}
|
|
activeClassName="menu__link--active"
|
|
{...childItemProps}
|
|
key={i}
|
|
/>
|
|
))}
|
|
</Collapsible>
|
|
</li>
|
|
);
|
|
}
|
|
export default function DropdownNavbarItem({mobile = false, ...props}) {
|
|
const Comp = mobile ? DropdownNavbarItemMobile : DropdownNavbarItemDesktop;
|
|
return <Comp {...props} />;
|
|
}
|