import React, { useEffect, useRef, useState, } from 'react'; import { DevidedPagePath } from '@growi/core/dist/models'; import { pagePathUtils } from '@growi/core/dist/utils'; import dynamic from 'next/dynamic'; import Sticky from 'react-stickynode'; import { useIsNotFound } from '~/stores/page'; import { usePageControlsX, useCurrentProductNavWidth, useSidebarMode, } from '~/stores/ui'; import LinkedPagePath from '../../../models/linked-page-path'; import { PagePathHierarchicalLink } from '../PagePathHierarchicalLink'; import { CollapsedParentsDropdown } from '../PagePathHierarchicalLink/CollapsedParentsDropdown'; import styles from './PagePathNav.module.scss'; const { isTrashPage } = pagePathUtils; type Props = { pagePath: string, pageId?: string | null, isWipPage?: boolean, isSingleLineMode?: boolean, isCollapseParents?: boolean, formerLinkClassName?: string, latterLinkClassName?: string, maxWidth?: number, } const CopyDropdown = dynamic(() => import('../CopyDropdown').then(mod => mod.CopyDropdown), { ssr: false }); const Separator = ({ className }: {className?: string}): JSX.Element => { return /; }; export const PagePathNav = (props: Props): JSX.Element => { const { pageId, pagePath, isWipPage, isSingleLineMode, isCollapseParents, formerLinkClassName, latterLinkClassName, maxWidth, } = props; const dPagePath = new DevidedPagePath(pagePath, false, true); const { data: isNotFound } = useIsNotFound(); const isInTrash = isTrashPage(pagePath); let formerLink; let latterLink; // one line if (dPagePath.isRoot || dPagePath.isFormerRoot || (!isCollapseParents && isSingleLineMode)) { const linkedPagePath = new LinkedPagePath(pagePath); latterLink = ; } // collapse parents else if (isCollapseParents) { const linkedPagePathFormer = new LinkedPagePath(dPagePath.former); const linkedPagePathLatter = new LinkedPagePath(dPagePath.latter); latterLink = ( <> ); } // two line else { const linkedPagePathFormer = new LinkedPagePath(dPagePath.former); const linkedPagePathLatter = new LinkedPagePath(dPagePath.latter); formerLink = ( <> ); latterLink = ( ); } const copyDropdownId = `copydropdown-${pageId}`; return (
{formerLink}

{latterLink}

{ pageId != null && !isNotFound && (
{ isWipPage && ( WIP )} content_paste
) }
); }; PagePathNav.displayName = 'PagePathNav'; type PagePathNavStickyProps = Omit; export const PagePathNavSticky = (props: PagePathNavStickyProps): JSX.Element => { const { data: pageControlsX } = usePageControlsX(); const { data: sidebarWidth } = useCurrentProductNavWidth(); const { data: sidebarMode } = useSidebarMode(); const pagePathNavRef = useRef(null); const [navMaxWidth, setNavMaxWidth] = useState(); useEffect(() => { if (pageControlsX == null || pagePathNavRef.current == null || sidebarWidth == null) { return; } setNavMaxWidth(pageControlsX - pagePathNavRef.current.getBoundingClientRect().x - 10); }, [pageControlsX, pagePathNavRef, sidebarWidth]); useEffect(() => { // wait for the end of the animation of the opening and closing of the sidebar const timeout = setTimeout(() => { if (pageControlsX == null || pagePathNavRef.current == null || sidebarMode == null) { return; } setNavMaxWidth(pageControlsX - pagePathNavRef.current.getBoundingClientRect().x - 10); }, 200); return () => { clearTimeout(timeout); }; }, [pageControlsX, pagePathNavRef, sidebarMode]); return ( // Controlling pointer-events // 1. disable pointer-events with 'pe-none'
{({ status }) => { const isCollapseParents = status === Sticky.STATUS_FIXED; return ( // Controlling pointer-events // 2. enable pointer-events with 'pe-auto' only against the children // which width is minimized by 'd-inline-block' //
); }}
); }; PagePathNavSticky.displayName = 'PagePathNavSticky';