/**
* 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, {
type ComponentProps,
type ReactNode,
useEffect,
useMemo,
} from 'react';
import clsx from 'clsx';
import {
ThemeClassNames,
useThemeConfig,
usePrevious,
Collapsible,
useCollapsible,
} from '@docusaurus/theme-common';
import {isSamePath} from '@docusaurus/theme-common/internal';
import {
isActiveSidebarItem,
findFirstSidebarItemLink,
useDocSidebarItemsExpandedState,
useVisibleSidebarItems,
} from '@docusaurus/plugin-content-docs/client';
import Link from '@docusaurus/Link';
import {translate} from '@docusaurus/Translate';
import useIsBrowser from '@docusaurus/useIsBrowser';
import DocSidebarItems from '@theme/DocSidebarItems';
import DocSidebarItemLink from '@theme/DocSidebarItem/Link';
import type {Props} from '@theme/DocSidebarItem/Category';
import type {
PropSidebarItemCategory,
PropSidebarItemLink,
} from '@docusaurus/plugin-content-docs';
import styles from './styles.module.css';
// If we navigate to a category and it becomes active, it should automatically
// expand itself
function useAutoExpandActiveCategory({
isActive,
collapsed,
updateCollapsed,
activePath,
}: {
isActive: boolean;
collapsed: boolean;
updateCollapsed: (b: boolean) => void;
activePath: string;
}) {
const wasActive = usePrevious(isActive);
const previousActivePath = usePrevious(activePath);
useEffect(() => {
const justBecameActive = isActive && !wasActive;
const stillActiveButPathChanged =
isActive && wasActive && activePath !== previousActivePath;
if ((justBecameActive || stillActiveButPathChanged) && collapsed) {
updateCollapsed(false);
}
}, [
isActive,
wasActive,
collapsed,
updateCollapsed,
activePath,
previousActivePath,
]);
}
/**
* When a collapsible category has no link, we still link it to its first child
* during SSR as a temporary fallback. This allows to be able to navigate inside
* the category even when JS fails to load, is delayed or simply disabled
* React hydration becomes an optional progressive enhancement
* see https://github.com/facebookincubator/infima/issues/36#issuecomment-772543188
* see https://github.com/facebook/docusaurus/issues/3030
*/
function useCategoryHrefWithSSRFallback(
item: Props['item'],
): string | undefined {
const isBrowser = useIsBrowser();
return useMemo(() => {
if (item.href && !item.linkUnlisted) {
return item.href;
}
// In these cases, it's not necessary to render a fallback
// We skip the "findFirstCategoryLink" computation
if (isBrowser || !item.collapsible) {
return undefined;
}
return findFirstSidebarItemLink(item);
}, [item, isBrowser]);
}
function CollapseButton({
collapsed,
categoryLabel,
onClick,
}: {
collapsed: boolean;
categoryLabel: string;
onClick: ComponentProps<'button'>['onClick'];
}) {
return (
);
}
function CategoryLinkLabel({label}: {label: string}) {
return {label};
}
export default function DocSidebarItemCategory(props: Props): ReactNode {
const visibleChildren = useVisibleSidebarItems(
props.item.items,
props.activePath,
);
if (visibleChildren.length === 0) {
return