UNPKG

@alauda/doom

Version:

Doctor Doom making docs.

119 lines (118 loc) 4.76 kB
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; import { isProduction, NoSSR, useSite, withBase } from '@rspress/core/runtime'; import {} from '@rspress/shared'; import virtual from 'doom-@global-virtual'; import { noop } from 'es-toolkit'; import { useEffect, useMemo, useState } from 'react'; import { createPortal } from 'react-dom'; import { base } from 'virtual-runtime-config'; import { parse } from 'yaml'; import { ACP_BASE, getPdfName, getUnversionedVersion, isExplicitlyUnversioned, } from '../../shared/index.js'; import { NavMenuGroup } from './NavMenuGroup.js'; import { NavMenuSingleItem } from './NavMenuSingleItem.js'; import { useLang, useTranslation } from '@alauda/doom/runtime'; const getNavMenu = () => { if (typeof document === 'undefined') { return null; } return document.querySelector('.rspress-nav-menu'); }; const LEGACY_VERSIONS = ['v3.18.1', 'v3.18.0', 'v3.16', 'v3.14']; const LEGACY_NAV_ITEMS = LEGACY_VERSIONS.map((v) => ({ text: v, link: `https://docs.alauda.io/document/release-notes?version=${v}`, })); const ALLOWED_LEGACY_DOMAINS = new Set(['docs.alauda.cn', 'docs.alauda.io']); if (!isProduction()) { ALLOWED_LEGACY_DOMAINS.add('localhost'); } const VersionsNav_ = () => { const { site } = useSite(); const lang = useLang(); const t = useTranslation(); const siteTitle = site.originalTitle ?? site.title; const downloadLink = useMemo(() => { if (!virtual.download) { return; } return withBase(getPdfName(lang, virtual.userBase, siteTitle)); }, [lang, siteTitle]); const [versionsBase, version] = useMemo(() => { const unversionedVersion = getUnversionedVersion(virtual.version); if (!unversionedVersion) { return []; } return [ isExplicitlyUnversioned(virtual.version) ? undefined : base.slice(0, -unversionedVersion.length - 1), unversionedVersion, ]; }, []); const [navMenu, setNavMenu] = useState(getNavMenu); const [versions, setVersions] = useState(version ? [version] : []); useEffect(() => { const fetchVersions = async () => { if (versionsBase == null) { if (!version) { return; } } else { const res = await fetch(`${isProduction() ? versionsBase : base}/versions.yaml`); if (!res.ok) { return; } const text = await res.text(); const versions = parse(text); if (version && !versions.includes(version)) { versions.unshift(version); } setVersions(versions); } setNavMenu(getNavMenu); }; void fetchVersions().catch(noop); }, [version, versionsBase]); // hack way to detect nav menu recreation on theme change useEffect(() => { if (!navMenu) { return; } const observer = new MutationObserver((mutations) => { if (mutations.some((m) => m.removedNodes.length)) { setNavMenu(getNavMenu); } }); const newNavMenu = getNavMenu(); if (newNavMenu !== navMenu) { // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect setNavMenu(newNavMenu); } else if (navMenu.parentNode) { observer.observe(navMenu.parentNode, { childList: true }); } return () => { observer.disconnect(); }; }, [navMenu]); const navItems = useMemo(() => { const versionItems = versions.map((v) => versionsBase == null ? { text: v, items: [] } : { text: v, link: `${versionsBase}/${v}/`, activeMatch: v }); if (versionsBase != null && ALLOWED_LEGACY_DOMAINS.has(location.hostname) && virtual.userBase === ACP_BASE) { versionItems.push(...LEGACY_NAV_ITEMS); } return versionItems; }, [versionsBase, versions]); let finalNavMenu; if ((!navItems.length && !virtual.download) || !(finalNavMenu = getNavMenu())) { return; } return createPortal(_jsxs(_Fragment, { children: [downloadLink && (_jsx(NavMenuSingleItem, { text: t('download_pdf'), link: downloadLink, download: true })), !navItems.length || (_jsx(NavMenuGroup, { text: version, base: versionsBase, items: navItems, pathname: base }))] }), finalNavMenu); }; export const VersionsNav = () => (_jsx(NoSSR, { children: _jsx(VersionsNav_, {}) })); export default VersionsNav;