docs: improve site experience (#53954)

This commit is contained in:
afc163 2025-05-31 00:17:21 +08:00 committed by GitHub
parent 53d3661f5e
commit 0b4d2498b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 157 additions and 86 deletions

View File

@ -18,3 +18,119 @@ html {
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: #eaeaea transparent; scrollbar-color: #eaeaea transparent;
} }
.rc-footer {
position: relative;
clear: both;
color: rgba(255, 255, 255, 0.4);
font-size: 14px;
line-height: 1.5;
background-color: #000;
}
.rc-footer a {
color: rgba(255, 255, 255, 0.9);
text-decoration: none;
transition: all 0.3s;
}
.rc-footer a:hover {
color: #40a9ff;
}
.rc-footer-container {
width: 100%;
max-width: 1200px;
margin: auto;
padding: 80px 0 20px;
}
.rc-footer-columns {
display: flex;
justify-content: space-around;
}
.rc-footer-column {
margin-bottom: 60px;
}
.rc-footer-column h2 {
position: relative;
margin: 0 auto;
color: #fff;
font-weight: 500;
font-size: 16px;
}
.rc-footer-column-icon {
position: relative;
top: -1px;
display: inline-block;
width: 22px;
text-align: center;
vertical-align: middle;
margin-inline-end: 0.5em;
}
.rc-footer-column-icon > span,
.rc-footer-column-icon > svg,
.rc-footer-column-icon img {
display: block;
width: 100%;
}
.rc-footer-item {
margin: 12px 0;
}
.rc-footer-item-icon {
position: relative;
top: -1px;
display: inline-block;
width: 16px;
text-align: center;
vertical-align: middle;
margin-inline-end: 0.4em;
}
.rc-footer-item-icon > span,
.rc-footer-item-icon > svg,
.rc-footer-item-icon img {
display: block;
width: 100%;
}
.rc-footer-item-separator {
margin: 0 0.3em;
}
.rc-footer-bottom-container {
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: 16px 0;
font-size: 16px;
line-height: 32px;
text-align: center;
border-top: 1px solid rgba(255, 255, 255, 0.25);
}
.rc-footer-light {
color: rgba(0, 0, 0, 0.85);
background-color: transparent;
}
.rc-footer-light h2,
.rc-footer-light a {
color: rgba(0, 0, 0, 0.85);
}
.rc-footer-light .rc-footer-bottom-container {
border-top-color: #e8e8e8;
}
.rc-footer-light .rc-footer-item-separator,
.rc-footer-light .rc-footer-item-description {
color: rgba(0, 0, 0, 0.45);
}
@media only screen and (max-width: 767.99px) {
.rc-footer {
text-align: center;
}
.rc-footer-container {
padding: 40px 0;
}
.rc-footer-columns {
display: block;
}
.rc-footer-column {
display: block;
margin-bottom: 40px;
}
.rc-footer-column:last-child {
margin-bottom: 0;
}
}

View File

@ -19,25 +19,23 @@ const Container: React.FC<React.PropsWithChildren<ContainerProps>> = ({
const { styles, cx } = useStyles(); const { styles, cx } = useStyles();
return ( return (
<div data-type={type} className={styles.container}> <Alert
<Alert showIcon
showIcon type={type}
type={type} message={title || type.toUpperCase()}
message={title || type.toUpperCase()} description={
description={ <div
<div className={cx(
className={cx( styles.desc,
styles.desc, // 为了让 markdown 的样式生效,需要在这里添加一个额外的 class
// 为了让 markdown 的样式生效,需要在这里添加一个额外的 class 'markdown',
'markdown', )}
)} >
> {children}
{children} </div>
</div> }
} className={styles.alert}
className={styles.alert} />
/>
</div>
); );
}; };

View File

@ -1,11 +1,8 @@
import { createStyles } from 'antd-style'; import { createStyles } from 'antd-style';
const useStyles = createStyles(({ token, prefixCls, css }) => ({ const useStyles = createStyles(({ prefixCls, css }) => ({
container: css`
margin: ${token.marginXS}px 0;
`,
alert: css` alert: css`
padding: 12px 16px;
.${prefixCls}-alert-message { .${prefixCls}-alert-message {
font-weight: bold; font-weight: bold;
} }

View File

@ -14,8 +14,6 @@ import GlobalStyles from '../../common/GlobalStyles';
import Header from '../../slots/Header'; import Header from '../../slots/Header';
import SiteContext from '../../slots/SiteContext'; import SiteContext from '../../slots/SiteContext';
import '../../static/style';
import IndexLayout from '../IndexLayout'; import IndexLayout from '../IndexLayout';
import ResourceLayout from '../ResourceLayout'; import ResourceLayout from '../ResourceLayout';
import SidebarLayout from '../SidebarLayout'; import SidebarLayout from '../SidebarLayout';

View File

@ -1,24 +0,0 @@
import React, { Suspense } from 'react';
import { Skeleton } from 'antd';
import { InView } from 'react-intersection-observer';
import type { IntersectionObserverProps } from 'react-intersection-observer';
type InViewSuspenseProps = Pick<IntersectionObserverProps, 'delay'> & {
fallback?: React.ReactNode;
};
const InViewSuspense: React.FC<React.PropsWithChildren<InViewSuspenseProps>> = ({
children,
fallback = <Skeleton.Input active size="small" />,
delay = 200,
}) => (
<InView triggerOnce delay={delay}>
{({ inView, ref }) => (
<div ref={ref}>
<Suspense fallback={fallback}>{inView ? children : <span />}</Suspense>
</div>
)}
</InView>
);
export default InViewSuspense;

View File

@ -1,4 +1,4 @@
import React, { useLayoutEffect, useMemo, useState } from 'react'; import React, { Suspense, useLayoutEffect, useMemo, useState } from 'react';
import { Col, Flex, FloatButton, Skeleton, Space, Typography } from 'antd'; import { Col, Flex, FloatButton, Skeleton, Space, Typography } from 'antd';
import classNames from 'classnames'; import classNames from 'classnames';
import { FormattedMessage, useRouteMeta } from 'dumi'; import { FormattedMessage, useRouteMeta } from 'dumi';
@ -9,16 +9,13 @@ import ComponentMeta from '../../builtins/ComponentMeta';
import type { DemoContextProps } from '../DemoContext'; import type { DemoContextProps } from '../DemoContext';
import DemoContext from '../DemoContext'; import DemoContext from '../DemoContext';
import SiteContext from '../SiteContext'; import SiteContext from '../SiteContext';
import { useStyle } from './DocAnchor'; import DocAnchor, { useStyle } from './DocAnchor';
import InViewSuspense from './InViewSuspense'; import Contributors from './Contributors';
import ColumnCard from './ColumnCard';
const Contributors = React.lazy(() => import('./Contributors')); import DocMeta from './DocMeta';
const ColumnCard = React.lazy(() => import('./ColumnCard')); import Footer from '../Footer';
const DocAnchor = React.lazy(() => import('./DocAnchor')); import PrevAndNext from '../../common/PrevAndNext';
const DocMeta = React.lazy(() => import('./DocMeta')); import EditButton from '../../common/EditButton';
const Footer = React.lazy(() => import('../Footer'));
const PrevAndNext = React.lazy(() => import('../../common/PrevAndNext'));
const EditButton = React.lazy(() => import('../../common/EditButton'));
const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 6 }) => const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 6 }) =>
Array.from({ length: num }).map<React.ReactNode>((_, i) => ( Array.from({ length: num }).map<React.ReactNode>((_, i) => (
@ -54,9 +51,7 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
return ( return (
<DemoContext value={contextValue}> <DemoContext value={contextValue}>
<Col xxl={20} xl={19} lg={18} md={18} sm={24} xs={24}> <Col xxl={20} xl={19} lg={18} md={18} sm={24} xs={24}>
<InViewSuspense fallback={null}> <DocAnchor showDebug={showDebug} debugDemos={debugDemos} />
<DocAnchor showDebug={showDebug} debugDemos={debugDemos} />
</InViewSuspense>
<article className={classNames(styles.articleWrapper, { rtl: isRTL })}> <article className={classNames(styles.articleWrapper, { rtl: isRTL })}>
{meta.frontmatter?.title ? ( {meta.frontmatter?.title ? (
<Flex justify="space-between"> <Flex justify="space-between">
@ -65,20 +60,16 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
<span>{meta.frontmatter?.title}</span> <span>{meta.frontmatter?.title}</span>
<span>{meta.frontmatter?.subtitle}</span> <span>{meta.frontmatter?.subtitle}</span>
{!pathname.startsWith('/components/overview') && ( {!pathname.startsWith('/components/overview') && (
<InViewSuspense fallback={null}> <EditButton
<EditButton title={<FormattedMessage id="app.content.edit-page" />}
title={<FormattedMessage id="app.content.edit-page" />} filename={meta.frontmatter.filename}
filename={meta.frontmatter.filename} />
/>
</InViewSuspense>
)} )}
</Space> </Space>
</Typography.Title> </Typography.Title>
</Flex> </Flex>
) : null} ) : null}
<InViewSuspense fallback={null}> <DocMeta />
<DocMeta />
</InViewSuspense>
{!meta.frontmatter.__autoDescription && meta.frontmatter.description} {!meta.frontmatter.__autoDescription && meta.frontmatter.description}
{/* Import Info */} {/* Import Info */}
@ -96,22 +87,18 @@ const Content: React.FC<React.PropsWithChildren> = ({ children }) => {
{children} {children}
<FloatButton.BackTop /> <FloatButton.BackTop />
</div> </div>
<InViewSuspense fallback={null}> <ColumnCard
<ColumnCard zhihuLink={meta.frontmatter.zhihu_url}
zhihuLink={meta.frontmatter.zhihu_url} yuqueLink={meta.frontmatter.yuque_url}
yuqueLink={meta.frontmatter.yuque_url} juejinLink={meta.frontmatter.juejin_url}
juejinLink={meta.frontmatter.juejin_url} />
/>
</InViewSuspense>
<div style={{ marginTop: 120 }}> <div style={{ marginTop: 120 }}>
<InViewSuspense fallback={<AvatarPlaceholder />}> <Suspense fallback={<AvatarPlaceholder />}>
<Contributors filename={meta.frontmatter.filename} /> <Contributors filename={meta.frontmatter.filename} />
</InViewSuspense> </Suspense>
</div> </div>
</article> </article>
<InViewSuspense fallback={null}> <PrevAndNext rtl={isRTL} />
<PrevAndNext rtl={isRTL} />
</InViewSuspense>
<Footer /> <Footer />
</Col> </Col>
</DemoContext> </DemoContext>

View File

@ -1 +0,0 @@
import 'rc-footer/assets/index.css';