import React, { ReactNode, type FC, useMemo, useState, useLayoutEffect, useContext } from 'react'; import { useIntl, useRouteMeta } from 'dumi'; import Footer from 'dumi/theme/slots/Footer'; import { Col, Typography, Avatar, Tooltip, Affix, Anchor } from 'antd'; import EditButton from '../../common/EditButton'; import { FormattedMessage } from 'dumi'; import useLocation from '../../../hooks/useLocation'; import ContributorsList from '@qixian.cs/github-contributors-list'; import useSiteToken from '../../../hooks/useSiteToken'; import { css } from '@emotion/react'; import PrevAndNext from '../../common/PrevAndNext'; import DemoContext, { DemoContextProps } from '../DemoContext'; import classNames from 'classnames'; import SiteContext from '../SiteContext'; const useStyle = () => { const { token } = useSiteToken(); const { antCls } = token; return { contributorsList: css` display: flex; flex-wrap: wrap; margin-top: 120px !important; a, ${antCls}-avatar + ${antCls}-avatar { margin-bottom: 8px; margin-inline-end: 8px; } `, toc: css` ${antCls}-anchor { ${antCls}-anchor-link-title { font-size: 12px; } ${antCls}-anchor-ink-ball { left: 0; width: ${token.lineWidthBold}px; height: ${token.fontSizeSM * token.lineHeightSM}px; margin-top: ${token.marginXXS}px; background-color: ${token.colorPrimary}; border: none; transform: translateY(-50%); } } `, tocWrapper: css` position: absolute; top: 8px; right: 0; width: 160px; margin: 12px 0; padding: 8px 8px 8px 4px; backdrop-filter: blur(8px); border-radius: ${token.borderRadius}px; box-sizing: border-box; .toc-debug { color: ${token['purple-6']}; &:hover { color: ${token['purple-5']}; } } > div { box-sizing: border-box; width: 100%; max-height: calc(100vh - 40px); margin: 0 auto; overflow: auto; padding-inline: 4px; } &.rtl { right: auto; left: 20px; } @media only screen and (max-width: ${token.screenLG}px) { display: none; } `, articleWrapper: css` padding: 0 170px 32px 64px; &.rtl { padding: 0 64px 144px 170px; } @media only screen and (max-width: ${token.screenLG}px) { &, &.rtl { padding-right: 48px; padding-left: 48px; } } `, }; }; type AnchorItem = { id: string; title: string; children?: AnchorItem[]; }; const Content: FC<{ children: ReactNode }> = ({ children }) => { const meta = useRouteMeta(); const { pathname } = useLocation(); const { formatMessage } = useIntl(); const styles = useStyle(); const { direction } = useContext(SiteContext); const [showDebug, setShowDebug] = useState(false); const [debugDemos, setDebugDemos] = useState([]); useLayoutEffect(() => { setShowDebug(process.env.NODE_ENV === 'development'); }, []); const contextValue = useMemo( () => ({ showDebug, setShowDebug, debugDemos, setDebugDemos }), [showDebug, debugDemos], ); const anchorItems = useMemo(() => { return meta.toc.reduce((result, item) => { if (item.depth === 2) { result.push({ ...item }); } else if (item.depth === 3) { const parent = result[result.length - 1]; if (parent) { parent.children = parent.children || []; parent.children.push({ ...item }); } } return result; }, []); }, [meta.toc]); const isRTL = direction === 'rtl'; return (
{anchorItems.map((item) => ( {item.children ?.filter((child) => showDebug || !debugDemos.includes(child.id)) .map((child) => ( {child.title} } key={child.id} /> ))} ))}
{meta.frontmatter.title} {meta.frontmatter.subtitle && ( {meta.frontmatter.subtitle} )} {!pathname.startsWith('/components/overview') && ( } filename={meta.frontmatter.filename} /> )} {children} loading ? ( ) : ( item && ( {item.username} ) ) } repo="ant-design" owner="ant-design" />