chore: auto merge branches (#46501)

chore: merge master into feature
This commit is contained in:
github-actions[bot] 2023-12-18 04:31:30 +00:00 committed by GitHub
commit a8fc2ec3f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 491 additions and 297 deletions

View File

@ -1,13 +1,26 @@
import { RightOutlined, LinkOutlined, QuestionCircleOutlined } from '@ant-design/icons'; import React, { useMemo, useState } from 'react';
import { LinkOutlined, QuestionCircleOutlined, RightOutlined } from '@ant-design/icons';
import { ConfigProvider, Popover, Table, Typography } from 'antd';
import { createStyles, css, useTheme } from 'antd-style'; import { createStyles, css, useTheme } from 'antd-style';
import { getDesignToken } from 'antd-token-previewer'; import { getDesignToken } from 'antd-token-previewer';
import React, { useMemo, useState } from 'react';
import tokenMeta from 'antd/es/version/token-meta.json'; import tokenMeta from 'antd/es/version/token-meta.json';
import tokenData from 'antd/es/version/token.json'; import tokenData from 'antd/es/version/token.json';
import { ConfigProvider, Table, Popover, Typography } from 'antd';
import useLocale from '../../../hooks/useLocale'; import useLocale from '../../../hooks/useLocale';
import { useColumns } from '../TokenTable'; import { useColumns } from '../TokenTable';
const compare = (token1: string, token2: string) => {
const hasColor1 = token1.toLowerCase().includes('color');
const hasColor2 = token2.toLowerCase().includes('color');
if (hasColor1 && !hasColor2) {
return -1;
}
if (!hasColor1 && hasColor2) {
return 1;
}
return token1 < token2 ? -1 : 1;
};
const defaultToken = getDesignToken(); const defaultToken = getDesignToken();
const locales = { const locales = {
@ -18,6 +31,8 @@ const locales = {
value: '默认值', value: '默认值',
componentToken: '组件 Token', componentToken: '组件 Token',
globalToken: '全局 Token', globalToken: '全局 Token',
componentComment: '这里是你的组件 token',
globalComment: '这里是你的全局 token',
help: '如何定制?', help: '如何定制?',
customizeTokenLink: '/docs/react/customize-theme-cn#修改主题变量', customizeTokenLink: '/docs/react/customize-theme-cn#修改主题变量',
customizeComponentTokenLink: '/docs/react/customize-theme-cn#修改组件变量', customizeComponentTokenLink: '/docs/react/customize-theme-cn#修改组件变量',
@ -29,6 +44,8 @@ const locales = {
value: 'Default Value', value: 'Default Value',
componentToken: 'Component Token', componentToken: 'Component Token',
globalToken: 'Global Token', globalToken: 'Global Token',
componentComment: 'here is your component tokens',
globalComment: 'here is your global tokens',
help: 'How to use?', help: 'How to use?',
customizeTokenLink: '/docs/react/customize-theme#customize-design-token', customizeTokenLink: '/docs/react/customize-theme#customize-design-token',
customizeComponentTokenLink: 'docs/react/customize-theme#customize-component-token', customizeComponentTokenLink: 'docs/react/customize-theme#customize-component-token',
@ -46,13 +63,13 @@ const useStyle = createStyles(() => ({
`, `,
arrowIcon: css` arrowIcon: css`
font-size: 16px; font-size: 16px;
margin-right: 8px; margin-inline-end: 8px;
& svg { & svg {
transition: all 0.3s; transition: all 0.3s;
} }
`, `,
help: css` help: css`
margin-left: 8px; margin-inline-start: 8px;
font-size: 12px; font-size: 12px;
font-weight: normal; font-weight: normal;
color: #999; color: #999;
@ -69,16 +86,14 @@ interface SubTokenTableProps {
helpLink: string; helpLink: string;
tokens: string[]; tokens: string[];
component?: string; component?: string;
comment?: {
componentComment?: string;
globalComment?: string;
};
} }
const SubTokenTable: React.FC<SubTokenTableProps> = ({ const SubTokenTable: React.FC<SubTokenTableProps> = (props) => {
defaultOpen, const { defaultOpen, tokens, title, helpText, helpLink, component, comment } = props;
tokens,
title,
helpText,
helpLink,
component,
}) => {
const [, lang] = useLocale(locales); const [, lang] = useLocale(locales);
const token = useTheme(); const token = useTheme();
const columns = useColumns(); const columns = useColumns();
@ -92,24 +107,7 @@ const SubTokenTable: React.FC<SubTokenTableProps> = ({
} }
const data = tokens const data = tokens
.sort( .sort(component ? undefined : compare)
component
? undefined
: (token1, token2) => {
const hasColor1 = token1.toLowerCase().includes('color');
const hasColor2 = token2.toLowerCase().includes('color');
if (hasColor1 && !hasColor2) {
return -1;
}
if (!hasColor1 && hasColor2) {
return 1;
}
return token1 < token2 ? -1 : 1;
},
)
.map((name) => { .map((name) => {
const meta = component const meta = component
? tokenMeta.components[component].find((item) => item.token === name) ? tokenMeta.components[component].find((item) => item.token === name)
@ -133,7 +131,7 @@ const SubTokenTable: React.FC<SubTokenTableProps> = ({
theme={{ theme={{
components: { components: {
${component}: { ${component}: {
/* here is your component tokens */ /* ${comment?.componentComment} */
}, },
}, },
}} }}
@ -143,7 +141,7 @@ const SubTokenTable: React.FC<SubTokenTableProps> = ({
: `<ConfigProvider : `<ConfigProvider
theme={{ theme={{
token: { token: {
/* here is your global tokens */ /* ${comment?.globalComment} */
}, },
}} }}
> >
@ -161,16 +159,17 @@ const SubTokenTable: React.FC<SubTokenTableProps> = ({
popupStyle={{ width: 400 }} popupStyle={{ width: 400 }}
content={ content={
<Typography> <Typography>
{/* <SourceCode lang="jsx">{code}</SourceCode> */}
<pre style={{ fontSize: 12 }}>{code}</pre> <pre style={{ fontSize: 12 }}>{code}</pre>
<a href={helpLink} target="_blank" rel="noreferrer"> <a href={helpLink} target="_blank" rel="noreferrer">
<LinkOutlined style={{ marginRight: 4 }} /> <LinkOutlined style={{ marginInlineEnd: 4 }} />
{helpText} {helpText}
</a> </a>
</Typography> </Typography>
} }
> >
<span className={styles.help}> <span className={styles.help}>
<QuestionCircleOutlined style={{ marginRight: 3 }} /> <QuestionCircleOutlined style={{ marginInlineEnd: 4 }} />
{helpText} {helpText}
</span> </span>
</Popover> </Popover>
@ -217,12 +216,16 @@ const ComponentTokenTable: React.FC<ComponentTokenTableProps> = ({ component })
<> <>
{tokenMeta.components[component] && ( {tokenMeta.components[component] && (
<SubTokenTable <SubTokenTable
defaultOpen
title={locale.componentToken} title={locale.componentToken}
helpText={locale.help} helpText={locale.help}
helpLink={locale.customizeTokenLink} helpLink={locale.customizeTokenLink}
tokens={tokenMeta.components[component].map((item) => item.token)} tokens={tokenMeta.components[component].map((item) => item.token)}
component={component} component={component}
defaultOpen comment={{
componentComment: locale.componentComment,
globalComment: locale.globalComment,
}}
/> />
)} )}
<SubTokenTable <SubTokenTable
@ -230,6 +233,10 @@ const ComponentTokenTable: React.FC<ComponentTokenTableProps> = ({ component })
helpText={locale.help} helpText={locale.help}
helpLink={locale.customizeComponentTokenLink} helpLink={locale.customizeComponentTokenLink}
tokens={mergedGlobalTokens} tokens={mergedGlobalTokens}
comment={{
componentComment: locale.componentComment,
globalComment: locale.globalComment,
}}
/> />
</> </>
); );

View File

@ -0,0 +1,39 @@
/**
* copied: https://github.com/arvinxx/dumi-theme-antd-style/tree/master/src/builtins/Container
*/
import * as React from 'react';
import { Alert } from 'antd';
import { type FC, type ReactNode } from 'react';
import useStyles from './style';
const Container: FC<{
type: 'info' | 'warning' | 'success' | 'error';
title?: string;
children: ReactNode;
}> = ({ type, title, children }) => {
const { styles, cx } = useStyles();
return (
<div data-type={type} className={styles.container}>
<Alert
showIcon
type={type}
message={title || type.toUpperCase()}
description={
<div
className={cx(
styles.desc,
// 为了让 markdown 的样式生效,需要在这里添加一个额外的 class
'markdown',
)}
>
{children}
</div>
}
className={styles.alert}
/>
</div>
);
};
export default Container;

View File

@ -0,0 +1,22 @@
import { createStyles } from 'antd-style';
const useStyles = createStyles(({ prefixCls, css }) => ({
container: css`
margin: 8px 0;
`,
alert: css`
.${prefixCls}-alert-message {
font-weight: bold;
}
`,
/* 使用 `&&` 加一点点权重 */
desc: css`
&& p {
margin: 0;
}
`,
}));
export default useStyles;

View File

@ -0,0 +1,38 @@
import React from 'react';
import { Avatar, Skeleton, Tooltip } from 'antd';
const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 3 }) => (
<li>
{Array.from({ length: num }).map((_, i) => (
<Skeleton.Avatar size="small" active key={i} style={{ marginLeft: i === 0 ? 0 : -8 }} />
))}
</li>
);
interface ContributorAvatarProps {
username?: string;
url?: string;
loading?: boolean;
}
const ContributorAvatar: React.FC<ContributorAvatarProps> = ({ username, url, loading }) => {
if (loading) {
return <AvatarPlaceholder />;
}
if (username?.includes('github-actions')) {
return null;
}
return (
<Tooltip title={username}>
<li>
<a href={`https://github.com/${username}`} target="_blank" rel="noopener noreferrer">
<Avatar size="small" src={url} alt={username}>
{username}
</Avatar>
</a>
</li>
</Tooltip>
);
};
export default ContributorAvatar;

View File

@ -0,0 +1,82 @@
import React, { useContext } from 'react';
import classNames from 'classnames';
import { useIntl } from 'dumi';
import { createStyles } from 'antd-style';
import ContributorsList from '@qixian.cs/github-contributors-list';
import ContributorAvatar from './ContributorAvatar';
import SiteContext from '../SiteContext';
const useStyle = createStyles(({ token, css }) => {
const { antCls } = token;
return {
contributorsList: css`
margin-top: 120px !important;
`,
listMobile: css`
margin: 1em 0 !important;
`,
title: css`
font-size: 12px;
opacity: 0.45;
`,
list: css`
display: flex;
flex-wrap: wrap;
clear: both;
li {
height: 24px;
}
li,
${antCls}-avatar + ${antCls}-avatar {
transition: all ${token.motionDurationSlow};
margin-inline-end: -8px;
}
&:hover {
li,
${antCls}-avatar {
margin-inline-end: 0;
}
}
`,
};
});
interface ContributorsProps {
filename?: string;
}
const Contributors: React.FC<ContributorsProps> = ({ filename }) => {
const { formatMessage } = useIntl();
const { styles } = useStyle();
const { isMobile } = useContext(SiteContext);
if (!filename) {
return null;
}
return (
<div className={classNames(styles.contributorsList, { [styles.listMobile]: isMobile })}>
<div className={styles.title}>{formatMessage({ id: 'app.content.contributors' })}</div>
<ContributorsList
cache
repo="ant-design"
owner="ant-design"
fileName={filename}
className={styles.list}
renderItem={(item, loading) => (
<ContributorAvatar
key={item?.username}
username={item?.username}
url={item?.url}
loading={loading}
/>
)}
/>
</div>
);
};
export default Contributors;

View File

@ -0,0 +1,137 @@
import React, { useMemo } from 'react';
import classNames from 'classnames';
import { Anchor } from 'antd';
import { createStyles, useTheme } from 'antd-style';
import { useRouteMeta, useTabMeta } from 'dumi';
const useStyle = createStyles(({ token, css }) => {
const { antCls } = token;
return {
toc: css`
${antCls}-anchor {
${antCls}-anchor-link-title {
font-size: 12px;
}
}
`,
tocWrapper: css`
position: fixed;
top: ${token.headerHeight + token.contentMarginTop}px;
inset-inline-end: 0;
width: 160px;
margin: 0 0 12px 0;
padding: 8px 0;
padding-inline: 4px 8px;
backdrop-filter: blur(8px);
border-radius: ${token.borderRadius}px;
box-sizing: border-box;
z-index: 1000;
.toc-debug {
color: ${token.purple6};
&:hover {
color: ${token.purple5};
}
}
> div {
box-sizing: border-box;
width: 100%;
max-height: calc(100vh - 40px) !important;
margin: 0 auto;
overflow: auto;
padding-inline: 4px;
}
@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: 0 48px;
}
}
`,
};
});
interface DocAnchorProps {
showDebug?: boolean;
debugDemos?: string[];
}
type AnchorItem = {
id: string;
title: string;
children?: AnchorItem[];
};
const DocAnchor: React.FC<DocAnchorProps> = ({ showDebug, debugDemos = [] }) => {
const { styles } = useStyle();
const token = useTheme();
const meta = useRouteMeta();
const tab = useTabMeta();
const renderAnchorItem = (item: AnchorItem) => ({
href: `#${item.id}`,
title: item.title,
key: item.id,
children: item.children
?.filter((child) => showDebug || !debugDemos.includes(child.id))
.map((child) => ({
key: child.id,
href: `#${child.id}`,
title: (
<span className={classNames(debugDemos.includes(child.id) && 'toc-debug')}>
{child?.title}
</span>
),
})),
});
const anchorItems = useMemo(
() =>
(tab?.toc || meta.toc).reduce<AnchorItem[]>((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;
}, []),
[tab?.toc, meta.toc],
);
if (!meta.frontmatter.toc) {
return null;
}
return (
<section className={styles.tocWrapper}>
<Anchor
className={styles.toc}
affix={false}
targetOffset={token.anchorTop}
showInkInFixed
items={anchorItems.map(renderAnchorItem)}
/>
</section>
);
};
export default DocAnchor;

View File

@ -0,0 +1,79 @@
import React, { useState, useLayoutEffect, useMemo } from 'react';
import { Typography, Space, Skeleton, Avatar } from 'antd';
import { useRouteMeta } from 'dumi';
import DayJS from 'dayjs';
import { CalendarOutlined } from '@ant-design/icons';
const AuthorAvatar: React.FC<{ name: string; avatar: string }> = ({ name, avatar }) => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
useLayoutEffect(() => {
const img = new Image();
img.src = avatar;
img.onload = () => setLoading(false);
img.onerror = () => setError(true);
}, []);
if (error) {
return null;
}
if (loading) {
return <Skeleton.Avatar size="small" active />;
}
return (
<Avatar size="small" src={avatar} alt={name}>
{name}
</Avatar>
);
};
const DocMeta: React.FC<{}> = () => {
const meta = useRouteMeta();
const mergedAuthorInfos = useMemo(() => {
const { author } = meta.frontmatter;
if (!author) {
return [];
}
if (typeof author === 'string') {
return author.split(',').map((item) => ({
name: item,
avatar: `https://github.com/${item}.png`,
}));
}
if (Array.isArray(author)) {
return author;
}
return [];
}, [meta.frontmatter.author]);
if (!meta.frontmatter.date && !meta.frontmatter.author) {
return null;
}
return (
<Typography.Paragraph>
<Space>
{meta.frontmatter.date && (
<span style={{ opacity: 0.65 }}>
<CalendarOutlined /> {DayJS(meta.frontmatter.date).format('YYYY-MM-DD')}
</span>
)}
{mergedAuthorInfos.map((info) => (
<a
href={`https://github.com/${info.name}`}
target="_blank"
rel="noopener noreferrer"
key={info.name}
>
<Space size={3}>
<AuthorAvatar name={info.name} avatar={info.avatar} />
<span style={{ opacity: 0.65 }}>@{info.name}</span>
</Space>
</a>
))}
</Space>
</Typography.Paragraph>
);
};
export default DocMeta;

View File

@ -1,94 +1,26 @@
import { CalendarOutlined } from '@ant-design/icons';
import { createStyles, useTheme } from 'antd-style';
import ContributorsList from '@qixian.cs/github-contributors-list';
import classNames from 'classnames'; import classNames from 'classnames';
import DayJS from 'dayjs'; import { FormattedMessage, useRouteMeta } from 'dumi';
import { FormattedMessage, useIntl, useRouteMeta, useTabMeta } from 'dumi';
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import React, { useContext, useLayoutEffect, useMemo, useState } from 'react'; import React, { Suspense, useContext, useLayoutEffect, useMemo } from 'react';
import { Anchor, Avatar, Col, Skeleton, Space, Tooltip, Typography } from 'antd'; import { Col, Space, Typography, Skeleton } from 'antd';
import { createStyles } from 'antd-style';
import useLayoutState from '../../../hooks/useLayoutState'; import useLayoutState from '../../../hooks/useLayoutState';
import useLocation from '../../../hooks/useLocation'; import useLocation from '../../../hooks/useLocation';
import EditButton from '../../common/EditButton';
import PrevAndNext from '../../common/PrevAndNext';
import ComponentChangelog from '../../common/ComponentChangelog';
import type { DemoContextProps } from '../DemoContext'; import type { DemoContextProps } from '../DemoContext';
import DemoContext from '../DemoContext'; import DemoContext from '../DemoContext';
import Footer from '../Footer';
import SiteContext from '../SiteContext'; import SiteContext from '../SiteContext';
import ColumnCard from './ColumnCard';
const useStyle = createStyles(({ token, css }) => { const Contributors = React.lazy(() => import('./Contributors'));
const { antCls } = token; const ColumnCard = React.lazy(() => import('./ColumnCard'));
const DocAnchor = React.lazy(() => import('./DocAnchor'));
const DocMeta = React.lazy(() => import('./DocMeta'));
const Footer = React.lazy(() => import('../Footer'));
const PrevAndNext = React.lazy(() => import('../../common/PrevAndNext'));
const ComponentChangelog = React.lazy(() => import('../../common/ComponentChangelog'));
const EditButton = React.lazy(() => import('../../common/EditButton'));
return { const useStyle = createStyles(({ token, css }) => ({
contributorsList: css` articleWrapper: css`
display: flex;
flex-wrap: wrap;
margin-top: 120px !important;
clear: both;
li {
height: 24px;
}
li,
${antCls}-avatar + ${antCls}-avatar {
transition: all ${token.motionDurationSlow};
margin-inline-end: -8px;
}
&:hover {
li,
${antCls}-avatar {
margin-inline-end: 0;
}
}
`,
listMobile: css`
margin: 1em 0 !important;
`,
toc: css`
${antCls}-anchor {
${antCls}-anchor-link-title {
font-size: 12px;
}
}
`,
tocWrapper: css`
position: fixed;
top: ${token.headerHeight + token.contentMarginTop}px;
inset-inline-end: 0;
width: 160px;
margin: 0 0 12px 0;
padding: 8px 0;
padding-inline: 4px 8px;
backdrop-filter: blur(8px);
border-radius: ${token.borderRadius}px;
box-sizing: border-box;
z-index: 1000;
.toc-debug {
color: ${token.purple6};
&:hover {
color: ${token.purple5};
}
}
> div {
box-sizing: border-box;
width: 100%;
max-height: calc(100vh - 40px) !important;
margin: 0 auto;
overflow: auto;
padding-inline: 4px;
}
@media only screen and (max-width: ${token.screenLG}px) {
display: none;
}
`,
articleWrapper: css`
padding: 0 170px 32px 64px; padding: 0 170px 32px 64px;
&.rtl { &.rtl {
@ -102,53 +34,13 @@ const useStyle = createStyles(({ token, css }) => {
} }
} }
`, `,
}; }));
});
type AnchorItem = {
id: string;
title: string;
children?: AnchorItem[];
};
const AvatarPlaceholder: React.FC<{ num?: number }> = ({ num = 3 }) => (
<li>
{Array.from({ length: num }).map((_, i) => (
<Skeleton.Avatar size="small" active key={i} style={{ marginLeft: i === 0 ? 0 : -8 }} />
))}
</li>
);
const AuthorAvatar: React.FC<{ name: string; avatar: string }> = ({ name, avatar }) => {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
useLayoutEffect(() => {
const img = new Image();
img.src = avatar;
img.onload = () => setLoading(false);
img.onerror = () => setError(true);
}, []);
if (error) {
return null;
}
if (loading) {
return <Skeleton.Avatar size="small" active />;
}
return (
<Avatar size="small" src={avatar} alt={name}>
{name}
</Avatar>
);
};
const Content: React.FC<{ children: ReactNode }> = ({ children }) => { const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
const meta = useRouteMeta(); const meta = useRouteMeta();
const tab = useTabMeta();
const { pathname, hash } = useLocation(); const { pathname, hash } = useLocation();
const { formatMessage } = useIntl(); const { direction } = useContext(SiteContext);
const { styles } = useStyle(); const { styles } = useStyle();
const token = useTheme();
const { direction, isMobile } = useContext(SiteContext);
const [showDebug, setShowDebug] = useLayoutState(false); const [showDebug, setShowDebug] = useLayoutState(false);
const debugDemos = useMemo( const debugDemos = useMemo(
@ -167,71 +59,14 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
[showDebug, debugDemos], [showDebug, debugDemos],
); );
const anchorItems = useMemo(
() =>
(tab?.toc || meta.toc).reduce<AnchorItem[]>((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;
}, []),
[tab?.toc, meta.toc],
);
const isRTL = direction === 'rtl'; const isRTL = direction === 'rtl';
const mergedAuthorInfos = useMemo(() => {
const { author } = meta.frontmatter;
if (!author) {
return [];
}
if (typeof author === 'string') {
return author.split(',').map((item) => ({
name: item,
avatar: `https://github.com/${item}.png`,
}));
}
if (Array.isArray(author)) {
return author;
}
return [];
}, [meta.frontmatter.author]);
return ( return (
<DemoContext.Provider value={contextValue}> <DemoContext.Provider 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}>
{!!meta.frontmatter.toc && ( <Suspense fallback={<Skeleton.Input active size="small" />}>
<section className={styles.tocWrapper}> <DocAnchor showDebug={showDebug} debugDemos={debugDemos} />
<Anchor </Suspense>
className={styles.toc}
affix={false}
targetOffset={token.anchorTop}
showInkInFixed
items={anchorItems.map((item) => ({
href: `#${item.id}`,
title: item.title,
key: item.id,
children: item.children
?.filter((child) => showDebug || !debugDemos.includes(child.id))
.map((child) => ({
key: child.id,
href: `#${child.id}`,
title: (
<span className={classNames(debugDemos.includes(child.id) && 'toc-debug')}>
{child?.title}
</span>
),
})),
}))}
/>
</section>
)}
<article className={classNames(styles.articleWrapper, { rtl: isRTL })}> <article className={classNames(styles.articleWrapper, { rtl: isRTL })}>
{meta.frontmatter?.title ? ( {meta.frontmatter?.title ? (
<Typography.Title style={{ fontSize: 30, position: 'relative' }}> <Typography.Title style={{ fontSize: 30, position: 'relative' }}>
@ -240,90 +75,43 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
{meta.frontmatter?.subtitle} {meta.frontmatter?.subtitle}
{!pathname.startsWith('/components/overview') && ( {!pathname.startsWith('/components/overview') && (
<EditButton <Suspense fallback={null}>
title={<FormattedMessage id="app.content.edit-page" />} <EditButton
filename={meta.frontmatter.filename} title={<FormattedMessage id="app.content.edit-page" />}
/> filename={meta.frontmatter.filename}
/>
</Suspense>
)} )}
</Space> </Space>
{pathname.startsWith('/components/') && <ComponentChangelog pathname={pathname} />} {pathname.startsWith('/components/') && (
<Suspense fallback={null}>
<ComponentChangelog pathname={pathname} />
</Suspense>
)}
</Typography.Title> </Typography.Title>
) : null} ) : null}
{/* 添加作者、时间等信息 */} <Suspense fallback={<Skeleton.Input active size="small" />}>
{meta.frontmatter.date || meta.frontmatter.author ? ( <DocMeta />
<Typography.Paragraph> </Suspense>
<Space>
{meta.frontmatter.date && (
<span style={{ opacity: 0.65 }}>
<CalendarOutlined /> {DayJS(meta.frontmatter.date).format('YYYY-MM-DD')}
</span>
)}
{mergedAuthorInfos.map((info) => (
<a
href={`https://github.com/${info.name}`}
target="_blank"
rel="noopener noreferrer"
key={info.name}
>
<Space size={3}>
<AuthorAvatar name={info.name} avatar={info.avatar} />
<span style={{ opacity: 0.65 }}>@{info.name}</span>
</Space>
</a>
))}
</Space>
</Typography.Paragraph>
) : null}
{!meta.frontmatter.__autoDescription && meta.frontmatter.description} {!meta.frontmatter.__autoDescription && meta.frontmatter.description}
<div style={{ minHeight: 'calc(100vh - 64px)' }}>{children}</div> <div style={{ minHeight: 'calc(100vh - 64px)' }}>{children}</div>
{(meta.frontmatter?.zhihu_url || <Suspense fallback={<Skeleton.Input active size="small" />}>
meta.frontmatter?.yuque_url ||
meta.frontmatter?.juejin_url) && (
<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}
/> />
)} </Suspense>
{meta.frontmatter.filename && ( <Suspense fallback={<Skeleton.Input active size="small" />}>
<ContributorsList <Contributors filename={meta.frontmatter.filename} />
cache </Suspense>
repo="ant-design"
owner="ant-design"
className={classNames(styles.contributorsList, { [styles.listMobile]: isMobile })}
fileName={meta.frontmatter.filename}
renderItem={(item, loading) => {
if (!item || loading) {
return <AvatarPlaceholder />;
}
if (item.username?.includes('github-actions')) {
return null;
}
return (
<Tooltip
mouseEnterDelay={0.3}
title={`${formatMessage({ id: 'app.content.contributors' })}: ${item.username}`}
key={item.username}
>
<li>
<a
href={`https://github.com/${item.username}`}
target="_blank"
rel="noopener noreferrer"
>
<Avatar size="small" src={item.url} alt={item.username}>
{item.username}
</Avatar>
</a>
</li>
</Tooltip>
);
}}
/>
)}
</article> </article>
<PrevAndNext rtl={isRTL} /> <Suspense fallback={<Skeleton.Input active size="small" />}>
<Footer /> <PrevAndNext rtl={isRTL} />
</Suspense>
<Suspense fallback={null}>
<Footer />
</Suspense>
</Col> </Col>
</DemoContext.Provider> </DemoContext.Provider>
); );

View File

@ -223,9 +223,11 @@ const Header: React.FC = () => {
// Mirror url must have `/`, we add this for compatible // Mirror url must have `/`, we add this for compatible
const urlObj = new URL(currentUrl.replace(window.location.origin, url)); const urlObj = new URL(currentUrl.replace(window.location.origin, url));
if (urlObj.host.includes('antgroup')) { if (urlObj.host.includes('antgroup')) {
window.location.href = `${urlObj.href.replace(/\/$/, '')}/`; urlObj.pathname = `${urlObj.pathname.replace(/\/$/, '')}/`;
window.location.href = urlObj.toString();
} else {
window.location.href = urlObj.href.replace(/\/$/, '');
} }
window.location.href = urlObj.href.replace(/\/$/, '');
}, []); }, []);
const onLangChange = useCallback(() => { const onLangChange = useCallback(() => {

View File

@ -7,7 +7,7 @@
name: 👀 Visual Regression Diff Start name: 👀 Visual Regression Diff Start
on: on:
pull_request: pull_request_target:
branches: [master, feature] branches: [master, feature]
types: [opened, synchronize, reopened] types: [opened, synchronize, reopened]

View File

@ -5,7 +5,7 @@ import { genPresetColor, genSubStyleComponent } from '../../theme/internal';
// ============================== Preset ============================== // ============================== Preset ==============================
const genPresetStyle = (token: TagToken) => const genPresetStyle = (token: TagToken) =>
genPresetColor(token, (colorKey, { textColor, lightBorderColor, lightColor, darkColor }) => ({ genPresetColor(token, (colorKey, { textColor, lightBorderColor, lightColor, darkColor }) => ({
[`${token.componentCls}-${colorKey}`]: { [`${token.componentCls}${token.componentCls}-${colorKey}`]: {
color: textColor, color: textColor,
background: lightColor, background: lightColor,
borderColor: lightBorderColor, borderColor: lightBorderColor,

View File

@ -15,7 +15,7 @@ const genTagStatusStyle = (
): CSSInterpolation => { ): CSSInterpolation => {
const capitalizedCssVariableType = capitalize<CssVariableType>(cssVariableType); const capitalizedCssVariableType = capitalize<CssVariableType>(cssVariableType);
return { return {
[`${token.componentCls}-${status}`]: { [`${token.componentCls}${token.componentCls}-${status}`]: {
color: token[`color${cssVariableType}`], color: token[`color${cssVariableType}`],
background: token[`color${capitalizedCssVariableType}Bg`], background: token[`color${capitalizedCssVariableType}Bg`],
borderColor: token[`color${capitalizedCssVariableType}Border`], borderColor: token[`color${capitalizedCssVariableType}Border`],