import React, { useEffect, useMemo, type FC } from 'react'; import useLoading from '../../hooks/useLoading'; import useThemeConfig from '../../hooks/useThemeConfig'; import { HamburgerIcon } from '@chakra-ui/icons'; import { Box, Button, Container, Hide, HStack, Show, useColorMode, useColorModeValue, useDisclosure } from '@chakra-ui/react'; import animateScrollTo from 'animated-scroll-to'; import { Helmet, useLocation, useOutlet, useRouteMeta, useSidebarData } from 'dumi'; import SettingPanel from 'dumi/theme/builtins/SettingPanel'; import AnnouncementBar from 'dumi/theme/slots/AnnouncementBar'; import Content from 'dumi/theme/slots/Content'; import Features from 'dumi/theme/slots/Features'; import Footer from 'dumi/theme/slots/Footer'; import Header from 'dumi/theme/slots/Header'; import Hero from 'dumi/theme/slots/Hero'; import NavBar from 'dumi/theme/slots/Navbar'; import SideBar from 'dumi/theme/slots/Sidebar'; import Toc from 'dumi/theme/slots/Toc'; import { isUndefined } from '../../factory/tools'; import heroBackgroundDark from '../../media/hero-background-dark.jpg'; import heroBackground from '../../media/hero-background.jpg'; /** * @description cover default struct of dumi layout */ const DocLayout: FC = () => { const themeConfig = useThemeConfig(); const routeMeta = useRouteMeta(); const outlet = useOutlet(); const sidebar = useSidebarData(); const { hash } = useLocation(); const loading = useLoading(); const { colorMode } = useColorMode(); const sidebarMenuBg = useColorModeValue('whiteAlpha.800', 'gray.800'); const sidebarMenuBorderColor = useColorModeValue( 'transparent', 'whiteAlpha.400' ); const backgroundImage = useColorModeValue(heroBackground, heroBackgroundDark); const { isOpen, onOpen, onClose } = useDisclosure(); const navDisclosure = useDisclosure(); const helmetTitle = useMemo(() => { const { name, helmetIcon } = themeConfig; const { frontmatter } = routeMeta; return [name, helmetIcon, frontmatter?.title ?? name].join(' '); }, [themeConfig, routeMeta]); const helmetDescription = useMemo(() => { const { frontmatter } = routeMeta; const { description } = themeConfig; return frontmatter?.description ?? description; }, [routeMeta, themeConfig]); const { logo, keywords, author, thumbBackground, settingPanelVisible } = themeConfig; const docBackgroundImage = useMemo(() => { if (isUndefined(thumbBackground) || !thumbBackground) return ''; return typeof thumbBackground === 'string' ? thumbBackground : backgroundImage; }, [thumbBackground, backgroundImage]); // handle hash change or visit page hash after async chunk loaded useEffect(() => { const id = hash.replace('#', ''); if (id) { setTimeout(() => { const elm = document.getElementById(decodeURIComponent(id)); if (elm) { // animated-scroll-to instead of native scroll animateScrollTo(elm.offsetTop - 80, { maxDuration: 300 }); } }, 1); } }, [loading, hash]); return ( <> {logo && } {author && } {helmetTitle} {settingPanelVisible && ( )}
{sidebar && ( )} {outlet}