import * as React from 'react'; import { FormattedMessage, Link, useFullSidebarData, useLocation } from 'dumi'; import type { MenuProps } from 'antd'; import { Menu } from 'antd'; import { MenuOutlined } from '@ant-design/icons'; import { css } from '@emotion/react'; import { getEcosystemGroup } from './More'; import * as utils from '../../utils'; import type { SharedProps } from './interface'; import useSiteToken from '../../../hooks/useSiteToken'; import useLocale from '../../../hooks/useLocale'; // ============================= Theme ============================= const locales = { cn: { design: '设计', development: '研发', components: '组件', resources: '资源', blog: '博客', }, en: { design: 'Design', development: 'Development', components: 'Components', resources: 'Resources', blog: 'Blog', }, }; // ============================= Style ============================= const useStyle = () => { const { token } = useSiteToken(); const { antCls, iconCls, fontFamily, headerHeight, menuItemBorder, colorPrimary } = token; return { nav: css` height: 100%; font-size: 14px; font-family: Avenir, ${fontFamily}, sans-serif; border: 0; &${antCls}-menu-horizontal { border-bottom: none; & > ${antCls}-menu-item, & > ${antCls}-menu-submenu { min-width: (40px + 12px * 2); height: ${headerHeight}px; padding-right: 12px; padding-left: 12px; line-height: ${headerHeight}px; &::after { top: 0; right: 12px; bottom: auto; left: 12px; border-width: ${menuItemBorder}px; } } & ${antCls}-menu-submenu-title ${iconCls} { margin: 0; } & > ${antCls}-menu-item-selected { a { color: ${colorPrimary}; } } } & > ${antCls}-menu-item, & > ${antCls}-menu-submenu { text-align: center; } `, popoverMenuNav: css` ${antCls}-menu-item, ${antCls}-menu-submenu { text-align: left; } ${antCls}-menu-item-group-title { padding-left: 24px; } ${antCls}-menu-item-group-list { padding: 0 16px; } ${antCls}-menu-item, a { color: #333; } `, }; }; export interface NavigationProps extends SharedProps { isMobile: boolean; isClient: boolean; responsive: null | 'narrow' | 'crowded'; directionText: string; onLangChange: () => void; onDirectionChange: () => void; } export default ({ isZhCN, isClient, isMobile, responsive, directionText, onLangChange, onDirectionChange, }: NavigationProps) => { const { pathname, search } = useLocation(); const [locale] = useLocale(locales); const sidebarData = useFullSidebarData(); const blogList = sidebarData['/docs/blog']?.[0]?.children || []; const style = useStyle(); const menuMode = isMobile ? 'inline' : 'horizontal'; const module = pathname .split('/') .filter((path) => path) .slice(0, -1) .join('/'); let activeMenuItem = module || 'home'; if (pathname.startsWith('/changelog')) { activeMenuItem = 'docs/react'; } else if (pathname.startsWith('/docs/resources')) { activeMenuItem = 'docs/resources'; } let additional: MenuProps['items']; const additionalItems: MenuProps['items'] = [ { label: ( GitHub ), key: 'github', }, { label: , onClick: onLangChange, key: 'switch-lang', }, { label: directionText, onClick: onDirectionChange, key: 'switch-direction', }, ...getEcosystemGroup(), ]; if (isMobile) { additional = additionalItems; } else if (responsive === 'crowded') { additional = [ { label: , key: 'additional', children: [...additionalItems], }, ]; } const items: MenuProps['items'] = [ { label: ( {locale.design} ), key: 'docs/spec', }, { label: ( {locale.development} ), key: 'docs/react', }, { label: ( {locale.components} ), key: 'components', }, blogList.length ? { label: ( (a.frontmatter.date > b.frontmatter.date ? -1 : 1))[0].link, isZhCN, search, )} > {locale.blog} ), key: 'docs/blog', } : null, { label: ( {locale.resources} ), key: 'docs/resources', }, isZhCN && isClient && window.location.host !== 'ant-design.antgroup.com' && window.location.host !== 'ant-design.gitee.io' ? { label: '国内镜像', key: 'mirror', children: [ { label: 官方镜像, icon: ( logo ), key: 'antgroup', }, { label: Gitee 镜像, icon: ( gitee ), key: 'gitee', }, ], } : null, ...(additional ?? []), ]; return ( ); };