tachybase_todo/.dumi/theme/layout.tsx

118 lines
4.0 KiB
TypeScript
Raw Normal View History

import React, { useContext, useState, useEffect } from 'react';
import type { IRouteComponentProps } from '@umijs/types';
import { context, Link } from 'dumi/theme';
import Navbar from './components/Navbar';
import SideMenu from './components/SideMenu';
import SlugList from './components/SlugList';
import SearchBar from './components/SearchBar';
import './style/layout.less';
const Hero = hero => (
<>
<div className="__dumi-default-layout-hero">
{hero.image && <img src={hero.image} />}
<h1>{hero.title}</h1>
<div dangerouslySetInnerHTML={{ __html: hero.desc }} />
{hero.actions &&
hero.actions.map(action => (
<Link to={action.link} key={action.text}>
<button type="button">{action.text}</button>
</Link>
))}
</div>
</>
);
const Features = features => (
<div className="__dumi-default-layout-features">
{features.map(feat => (
<dl key={feat.title} style={{ backgroundImage: feat.icon ? `url(${feat.icon})` : undefined }}>
{feat.link ? (
<Link to={feat.link}>
<dt>{feat.title}</dt>
</Link>
) : (
<dt>{feat.title}</dt>
)}
<dd dangerouslySetInnerHTML={{ __html: feat.desc }} />
</dl>
))}
</div>
);
const Layout: React.FC<IRouteComponentProps> = ({ children, location }) => {
const {
config: { mode, repository },
meta,
locale,
} = useContext(context);
const { url: repoUrl, branch, platform } = repository;
const [menuCollapsed, setMenuCollapsed] = useState<boolean>(true);
const isSiteMode = mode === 'site';
const showHero = isSiteMode && meta.hero;
const showFeatures = isSiteMode && meta.features;
const showSideMenu = meta.sidemenu !== false && !showHero && !showFeatures && !meta.gapless;
const showSlugs =
!showHero &&
!showFeatures &&
Boolean(meta.slugs?.length) &&
(meta.toc === 'content' || meta.toc === undefined) &&
!meta.gapless;
const isCN = /^zh|cn$/i.test(locale);
const updatedTimeIns = new Date(meta.updatedTime);
const updatedTime: any = `${updatedTimeIns.toLocaleDateString([], { hour12: false })} ${updatedTimeIns.toLocaleTimeString([], { hour12: false })}`;
const repoPlatform =
{ github: 'GitHub', gitlab: 'GitLab' }[
(repoUrl || '').match(/(github|gitlab)/)?.[1] || 'nothing'
] || platform;
return (
<div
className="__dumi-default-layout"
data-route={location.pathname}
data-show-sidemenu={String(showSideMenu)}
data-show-slugs={String(showSlugs)}
data-site-mode={isSiteMode}
data-gapless={String(!!meta.gapless)}
onClick={() => {
if (menuCollapsed) return;
setMenuCollapsed(true);
}}
>
<Navbar
location={location}
navPrefix={<SearchBar />}
onMobileMenuClick={ev => {
setMenuCollapsed(val => !val);
ev.stopPropagation();
}}
/>
<SideMenu mobileMenuCollapsed={menuCollapsed} location={location} />
{showSlugs && <SlugList slugs={meta.slugs} className="__dumi-default-layout-toc" />}
{showHero && Hero(meta.hero)}
{showFeatures && Features(meta.features)}
<div className="__dumi-default-layout-content">
{children}
{!showHero && !showFeatures && meta.filePath && !meta.gapless && (
<div className="__dumi-default-layout-footer-meta">
{repoPlatform && (
<Link to={`${repoUrl}/edit/${branch}/${meta.filePath}`}>
{isCN ? `${repoPlatform} 上编辑此页` : `Edit this doc on ${repoPlatform}`}
</Link>
)}
<span data-updated-text={isCN ? '最后更新时间:' : 'Last update: '}>{updatedTime}</span>
</div>
)}
{(showHero || showFeatures) && meta.footer && (
<div
className="__dumi-default-layout-footer"
dangerouslySetInnerHTML={{ __html: meta.footer }}
/>
)}
</div>
</div>
);
};
export default Layout;