chore: lint (#39102)

* chore: enable tsc for demos

* chore: site lint

* chore: fix lint
This commit is contained in:
MadCcc 2022-11-30 11:05:41 +08:00 committed by GitHub
parent 02e2104b45
commit ffbb19e090
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 276 additions and 281 deletions

View File

@ -1,4 +1,3 @@
import * as React from 'react';
import { useLocale as useDumiLocale } from 'dumi';
export interface LocaleMap<Key extends string> {

View File

@ -1,5 +1,6 @@
import React, { ReactNode, useMemo } from 'react';
import { MenuProps } from 'antd';
import type { ReactNode } from 'react';
import React, { useMemo } from 'react';
import type { MenuProps } from 'antd';
import { Link, useFullSidebarData, useSidebarData } from 'dumi';
import useLocation from './useLocation';
@ -115,7 +116,7 @@ const useMenu = (options: UseMenuOptions = {}): [MenuProps['items'], string] =>
}
} else {
result.push(
...group.children?.map((item) => ({
...(group.children?.map((item) => ({
label: (
<Link to={`${item.link}${search}`}>
{before}
@ -124,7 +125,7 @@ const useMenu = (options: UseMenuOptions = {}): [MenuProps['items'], string] =>
</Link>
),
key: item.link.replace(/(-cn$)/g, ''),
})),
})) ?? []),
);
}
return result;

View File

@ -1 +1,3 @@
export { default } from '../index/index';
import Homepage from '../index/index';
export default Homepage;

View File

@ -1,9 +1,9 @@
import * as React from 'react';
import { Button, Space, Typography } from 'antd';
import { Link, useLocation } from 'dumi';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import { GroupMask } from './Group';
import { Link, useLocation } from 'dumi';
import * as utils from '../../../theme/utils';
const locales = {
@ -25,7 +25,7 @@ export interface BannerProps {
}
export default function Banner({ children }: BannerProps) {
const [locale, lang] = useLocale(locales);
const [locale] = useLocale(locales);
const { pathname, search } = useLocation();
const { token } = useSiteToken();
@ -82,6 +82,7 @@ export default function Banner({ children }: BannerProps) {
<img
style={{ position: 'absolute', right: 0, top: 240, width: 240 }}
src="https://gw.alipayobjects.com/zos/bmw-prod/b3b8dc41-dce8-471f-9d81-9a0204f27d03.svg"
alt="Ant Design"
/>
<GroupMask
@ -95,11 +96,13 @@ export default function Banner({ children }: BannerProps) {
<img
style={{ position: 'absolute', left: 0, top: 0, width: 240 }}
src="https://gw.alipayobjects.com/zos/bmw-prod/49f963db-b2a8-4f15-857a-270d771a1204.svg"
alt="bg"
/>
{/* Image Left Top */}
<img
style={{ position: 'absolute', right: 120, top: 0, width: 240 }}
src="https://gw.alipayobjects.com/zos/bmw-prod/e152223c-bcae-4913-8938-54fda9efe330.svg"
alt="bg"
/>
<Typography.Title

View File

@ -1,8 +1,8 @@
import * as React from 'react';
import { Skeleton, Typography } from 'antd';
import { css } from '@emotion/react';
import type { Extra, Icon } from './util';
import useSiteToken from '../../../hooks/useSiteToken';
import { Col, Row, Card, Typography, Skeleton } from 'antd';
import { css } from '@emotion/react';
const useStyle = () => {
const { token } = useSiteToken();
@ -52,20 +52,20 @@ export default function BannerRecommends({ extras = [], icons = [] }: BannerReco
textAlign: 'start',
}}
>
{first3.map((extra, index) => {
{first3.map((extra) => {
if (!extra) {
return <Skeleton key={index} />;
return <Skeleton key={extra.title} />;
}
const icon = icons.find((icon) => icon.name === extra.source);
const icon = icons.find((i) => i.name === extra.source);
return (
<a key={index} href={extra.href} target="_blank" css={style.card}>
<a key={extra.title} href={extra.href} target="_blank" css={style.card} rel="noreferrer">
<Typography.Title level={5}>{extra.title}</Typography.Title>
<Typography.Paragraph type="secondary" style={{ flex: 'auto' }}>
{extra.description}
</Typography.Paragraph>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<Typography.Text>{extra.date}</Typography.Text>
{icon && <img src={icon.href} style={{ height: token.fontSize }} />}
{icon && <img src={icon.href} style={{ height: token.fontSize }} alt="banner" />}
</div>
</a>
);

View File

@ -1,4 +1,4 @@
import useSiteToken from '../../../hooks/useSiteToken';
/* eslint-disable react/jsx-pascal-case */
import React from 'react';
import {
Space,
@ -14,6 +14,7 @@ import {
import dayjs from 'dayjs';
import { CustomerServiceOutlined, QuestionCircleOutlined, SyncOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import useSiteToken from '../../../hooks/useSiteToken';
import useLocale from '../../../hooks/useLocale';
const SAMPLE_CONTENT_EN =

View File

@ -1,9 +1,9 @@
import useSiteToken from '../../../hooks/useSiteToken';
import { Col, Row, Typography } from 'antd';
import React from 'react';
import { css } from '@emotion/react';
import useLocale from '../../../hooks/useLocale';
import { Link, useLocation } from 'dumi';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import * as utils from '../../../theme/utils';
const SECONDARY_LIST = [
@ -150,7 +150,7 @@ export default function DesignFramework() {
return (
<Col key={index} span={8}>
<a css={style.cardMini} target="_blank" href={url}>
<a css={style.cardMini} target="_blank" href={url} rel="noreferrer">
<img alt={title} src={img} style={{ transform: `scale(${imgScale})` }} />
<Typography.Title

View File

@ -58,7 +58,7 @@ export default function Group(props: GroupProps) {
boxSizing: 'border-box',
paddingInline: token.marginXXL,
};
let childNode = (
const childNode = (
<>
<div style={{ textAlign: 'center' }}>
<Typography.Title

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import { Row, Col, Typography } from 'antd';
import type { Recommendation } from './util';
import { css } from '@emotion/react';
import type { Recommendation } from './util';
import useSiteToken from '../../../hooks/useSiteToken';
const useStyle = () => {

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import useSiteToken from '../../../../hooks/useSiteToken';
import { COLOR_IMAGES, DEFAULT_COLOR, getClosetColor } from './colorUtil';
import { COLOR_IMAGES, getClosetColor } from './colorUtil';
export interface BackgroundImageProps {
colorPrimary?: string;
@ -38,6 +38,7 @@ export default function BackgroundImage({ colorPrimary, isLight }: BackgroundIma
objectPosition: 'right top',
}}
src={url}
alt=""
/>
);
})}

View File

@ -1,10 +1,12 @@
import useSiteToken from '../../../../hooks/useSiteToken';
import { Input, Space, Popover } from 'antd';
import React, { FC, useEffect, useState } from 'react';
import type { FC } from 'react';
import React, { useEffect, useState } from 'react';
import { css } from '@emotion/react';
import { TinyColor } from '@ctrl/tinycolor';
import type { ColorPanelProps } from 'antd-token-previewer/es/ColorPanel';
import ColorPanel from 'antd-token-previewer/es/ColorPanel';
import { PRESET_COLORS } from './colorUtil';
import ColorPanel, { ColorPanelProps } from 'antd-token-previewer/es/ColorPanel';
import useSiteToken from '../../../../hooks/useSiteToken';
const useStyle = () => {
const { token } = useSiteToken();
@ -109,10 +111,7 @@ export default function ColorPicker({ value, onChange }: RadiusPickerProps) {
key={color}
overlayInnerStyle={{ padding: 0 }}
content={
<DebouncedColorPanel
color={value || ''}
onChange={(color) => onChange?.(color)}
/>
<DebouncedColorPanel color={value || ''} onChange={(c) => onChange?.(c)} />
}
trigger="click"
showArrow={false}

View File

@ -85,6 +85,7 @@ export default function ThemePicker({ value, onChange }: ThemePickerProps) {
onClick={() => {
onChange?.(theme);
}}
alt=""
/>
</div>
<span>{locale[theme as keyof typeof locale]}</span>

View File

@ -52,9 +52,9 @@ export function getClosetColor(colorPrimary?: string | null) {
const distance = COLOR_IMAGES.map(({ color }) => {
const colorObj = new TinyColor(color).toRgb();
const dist = Math.sqrt(
Math.pow(colorObj.r - colorPrimaryRGB.r, 2) +
Math.pow(colorObj.g - colorPrimaryRGB.g, 2) +
Math.pow(colorObj.b - colorPrimaryRGB.b, 2),
(colorObj.r - colorPrimaryRGB.r) ** 2 +
(colorObj.g - colorPrimaryRGB.g) ** 2 +
(colorObj.b - colorPrimaryRGB.b) ** 2,
);
return { color, dist };

View File

@ -2,33 +2,34 @@ import * as React from 'react';
import { css } from '@emotion/react';
import { TinyColor } from '@ctrl/tinycolor';
import {
HomeOutlined,
FolderOutlined,
BellOutlined,
FolderOutlined,
HomeOutlined,
QuestionCircleOutlined,
} from '@ant-design/icons';
import useLocale from '../../../../hooks/useLocale';
import useSiteToken from '../../../../hooks/useSiteToken';
import type { MenuProps } from 'antd';
import {
Typography,
Breadcrumb,
Button,
Card,
ConfigProvider,
Form,
Layout,
Menu,
Breadcrumb,
MenuProps,
Space,
ConfigProvider,
Card,
Form,
Radio,
Space,
theme,
Button,
Typography,
} from 'antd';
import ThemePicker, { THEME } from './ThemePicker';
import useLocale from '../../../../hooks/useLocale';
import useSiteToken from '../../../../hooks/useSiteToken';
import type { THEME } from './ThemePicker';
import ThemePicker from './ThemePicker';
import ColorPicker from './ColorPicker';
import RadiusPicker from './RadiusPicker';
import Group from '../Group';
import BackgroundImage from './BackgroundImage';
import { getClosetColor, DEFAULT_COLOR, getAvatarURL, PINK_COLOR } from './colorUtil';
import { DEFAULT_COLOR, getAvatarURL, getClosetColor, PINK_COLOR } from './colorUtil';
const { Header, Content, Sider } = Layout;
@ -179,10 +180,6 @@ const useStyle = () => {
};
};
interface PickerProps {
title: React.ReactNode;
}
// ========================== Menu Config ==========================
const subMenuItems: MenuProps['items'] = [
{
@ -403,6 +400,7 @@ export default function Theme() {
? undefined
: `drop-shadow(30px 0 0 ${logoColor})`,
}}
alt=""
/>
</div>
<h1>Ant Design 5.0</h1>
@ -517,6 +515,7 @@ export default function Theme() {
height: 500,
}}
src="https://gw.alipayobjects.com/zos/bmw-prod/bd71b0c6-f93a-4e52-9c8a-f01a9b8fe22b.svg"
alt=""
/>
{/* Image Right Bottom */}
<img
@ -528,6 +527,7 @@ export default function Theme() {
height: 287,
}}
src="https://gw.alipayobjects.com/zos/bmw-prod/84ad805a-74cb-4916-b7ba-9cdc2bdec23a.svg"
alt=""
/>
</div>
@ -542,11 +542,13 @@ export default function Theme() {
<img
style={{ ...posStyle, left: 0, top: -100, height: 500 }}
src="https://gw.alipayobjects.com/zos/bmw-prod/a213184a-f212-4afb-beec-1e8b36bb4b8a.svg"
alt=""
/>
{/* Image Right Bottom */}
<img
style={{ ...posStyle, right: 0, bottom: -100, height: 287 }}
src="https://gw.alipayobjects.com/zos/bmw-prod/bb74a2fb-bff1-4d0d-8c2d-2ade0cd9bb0d.svg"
alt=""
/>
</div>

View File

@ -1,29 +1,14 @@
import React from 'react';
import { useLocale as useDumiLocale } from 'dumi';
import { css } from '@emotion/react';
import { ConfigProvider } from 'antd';
import useLocale from '../../hooks/useLocale';
import Banner from './components/Banner';
import Group from './components/Group';
import { useSiteData } from './components/util';
import useSiteToken from '../../hooks/useSiteToken';
import Theme from './components/Theme';
import BannerRecommends from './components/BannerRecommends';
import ComponentsList from './components/ComponentsList';
import DesignFramework from './components/DesignFramework';
import { ConfigProvider } from 'antd';
const useStyle = () => {
const { token } = useSiteToken();
return {
container: css`
// padding: 0 116px;
// background: url(https://gw.alipayobjects.com/zos/bmw-prod/5741382d-cc22-4ede-b962-aea287a1d1a1/l4nq43o8_w2646_h1580.png);
// background-size: 20% 10%;
`,
};
};
const locales = {
cn: {
@ -47,9 +32,7 @@ const Homepage: React.FC = () => {
const { id: localeId } = useDumiLocale();
const localeStr = localeId === 'zh-CN' ? 'cn' : 'en';
const [siteData, loading] = useSiteData();
const style = useStyle();
const [siteData] = useSiteData();
return (
<ConfigProvider theme={{ algorithm: undefined }}>
@ -58,7 +41,7 @@ const Homepage: React.FC = () => {
<BannerRecommends extras={siteData?.extras?.[localeStr]} icons={siteData?.icons} />
</Banner>
<div css={style.container}>
<div>
<Theme />
<Group
background="#fff"
@ -79,6 +62,7 @@ const Homepage: React.FC = () => {
<img
style={{ position: 'absolute', left: 0, top: -50, height: 160 }}
src="https://gw.alipayobjects.com/zos/bmw-prod/ba37a413-28e6-4be4-b1c5-01be1a0ebb1c.svg"
alt=""
/>
</>
}

View File

@ -1 +1,3 @@
export { default } from '../theme-editor/index';
import ThemeEditor from '../theme-editor';
export default ThemeEditor;

View File

@ -1,20 +1,9 @@
import React, { useState } from 'react';
import { ThemeEditor } from 'antd-token-previewer';
import { useState } from 'react';
import useLocale from '../../hooks/useLocale';
import { ConfigProvider } from 'antd';
import { ThemeConfig } from 'antd/es/config-provider/context';
const locales = {
cn: {
title: '主题编辑器',
},
en: {
title: 'Theme Editor',
},
};
import type { ThemeConfig } from 'antd/es/config-provider/context';
const CustomTheme = () => {
const [locale] = useLocale(locales);
const [theme, setTheme] = useState<ThemeConfig>({});
return (

View File

@ -6,7 +6,7 @@ import { type HastRoot, type UnifiedTransformer, unistUtilVisit } from 'dumi';
*/
function rehypeAntd(): UnifiedTransformer<HastRoot> {
return (tree, vFile) => {
const filename = (vFile.data.frontmatter as any).filename;
const { filename } = vFile.data.frontmatter as any;
unistUtilVisit.visit(tree, 'element', (node) => {
if (node.tagName === 'DumiDemoGrid') {

View File

@ -1,8 +1,8 @@
import React from 'react';
const APITable: React.FC = () => {
const APITable: React.FC = () => (
// TODO: implement api table, depend on the new markdown data structure passed
return <>API Table</>;
};
<>API Table</>
);
export default APITable;

View File

@ -1,8 +1,10 @@
import { Alert, AlertProps } from 'antd';
import React, { FC } from 'react';
import type { AlertProps } from 'antd';
import { Alert } from 'antd';
import type { FC } from 'react';
import React from 'react';
const MdAlert: FC<AlertProps> = ({ style, ...props }) => {
return <Alert {...props} style={{ margin: '24px 0', ...style }} />;
};
const MdAlert: FC<AlertProps> = ({ style, ...props }) => (
<Alert {...props} style={{ margin: '24px 0', ...style }} />
);
export default MdAlert;

View File

@ -1,11 +1,11 @@
import React, { useState, memo, useMemo } from 'react';
import { Link, useRouteMeta, useIntl, useSidebarData, Helmet } from 'dumi';
import React, { memo, useMemo, useState } from 'react';
import { Link, useIntl, useSidebarData } from 'dumi';
import { css } from '@emotion/react';
import debounce from 'lodash/debounce';
import { Input, Divider, Row, Col, Card, Typography, Tag, Space } from 'antd';
import { Card, Col, Divider, Input, Row, Space, Tag, Typography } from 'antd';
import { SearchOutlined } from '@ant-design/icons';
import proComponentsList from './ProComponentsList';
import type { Component } from './ProComponentsList';
import proComponentsList from './ProComponentsList';
import useSiteToken from '../../../hooks/useSiteToken';
const useStyle = () => {
@ -80,11 +80,9 @@ const { Title } = Typography;
const Overview: React.FC = () => {
const style = useStyle();
const meta = useRouteMeta();
const data = useSidebarData();
const { locale, formatMessage } = useIntl();
const documentTitle = `${meta.frontmatter.title} - Ant Design`;
const [search, setSearch] = useState<string>('');
@ -96,11 +94,11 @@ const Overview: React.FC = () => {
}
};
const groups = useMemo<{ title: string; children: Component[] }[]>(() => {
return data
const groups = useMemo<{ title: string; children: Component[] }[]>(
() =>
data
.filter((item) => item.title)
.map<{ title: string; children: Component[] }>((item) => {
return {
.map<{ title: string; children: Component[] }>((item) => ({
title: item.title!,
children: item.children.map((child) => ({
title: child.frontmatter.title,
@ -108,8 +106,7 @@ const Overview: React.FC = () => {
cover: child.frontmatter.cover,
link: child.link,
})),
};
})
}))
.concat([
{
title: locale === 'zh-CN' ? '重型组件' : 'Others',
@ -118,8 +115,9 @@ const Overview: React.FC = () => {
? proComponentsList
: proComponentsList.map((component) => ({ ...component, subtitle: '' })),
},
]);
}, [data, locale]);
]),
[data, locale],
);
return (
<section className="markdown" ref={sectionRef}>

View File

@ -1,4 +1,4 @@
import React, { useContext, useLayoutEffect, useState } from 'react';
import React, { useContext, useState } from 'react';
import { DumiDemoGrid, FormattedMessage } from 'dumi';
import { Tooltip } from 'antd';
import { BugFilled, BugOutlined, CodeFilled, CodeOutlined } from '@ant-design/icons';
@ -55,7 +55,7 @@ const DemoWrapper: typeof DumiDemoGrid = ({ items }) => {
</Tooltip>
</span>
{/* FIXME: find a new way instead of `key` to trigger re-render */}
<DumiDemoGrid items={filteredItems} key={expandAll + '' + showDebug} />
<DumiDemoGrid items={filteredItems} key={`${expandAll}${showDebug}`} />
</div>
);
};

View File

@ -5,10 +5,8 @@ import JsonML from 'jsonml.js/lib/utils';
import toReactComponent from 'jsonml-to-react-element';
// @ts-ignore
import Prism from 'prismjs';
import { useLocation } from 'dumi';
import { useIntl, type IPreviewerProps } from 'dumi';
import { useLocation, useIntl, type IPreviewerProps } from 'dumi';
import { ping } from '../../utils';
import sylvanas from 'sylvanas';
let pingDeferrer: PromiseLike<boolean>;
@ -56,13 +54,11 @@ export default function fromDumiProps<P extends object>(
toReactComponent(jsonML: any) {
return toReactComponent(jsonML, [
[
function (node: any) {
return JsonML.isElement(node) && JsonML.getTagName(node) === 'pre';
},
function (node: any, index: any) {
(node: any) => JsonML.isElement(node) && JsonML.getTagName(node) === 'pre',
(node: any, index: any) => {
// @ts-ignore
// ref: https://github.com/benjycui/bisheng/blob/master/packages/bisheng/src/bisheng-plugin-highlight/lib/browser.js#L7
var attr = JsonML.getAttributes(node);
const attr = JsonML.getAttributes(node);
return React.createElement(
'pre',
{

View File

@ -120,13 +120,6 @@ class Demo extends React.Component {
});
}
handleIframeReady = () => {
const { theme, setIframeTheme } = this.props;
if (this.iframeRef.current) {
// setIframeTheme(this.iframeRef.current, theme);
}
};
render() {
const { state } = this;
const { props } = this;
@ -167,7 +160,7 @@ class Demo extends React.Component {
});
const localizedTitle = meta.title[locale] || meta.title;
const localizeIntro = content[locale] || content;
const introChildren = <div dangerouslySetInnerHTML={{ __html: localizeIntro }}></div>;
const introChildren = <div dangerouslySetInnerHTML={{ __html: localizeIntro }} />;
const highlightClass = classNames('highlight-wrapper', {
'highlight-wrapper-expand': codeExpand,
@ -458,7 +451,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
</Tooltip>
</CopyToClipboard>
<Tooltip title={<FormattedMessage id="app.demo.separate" />}>
<a className="code-box-code-action" target="_blank" rel="noreferer" href={src}>
<a className="code-box-code-action" target="_blank" rel="noreferrer" href={src}>
<ExternalLinkIcon className="code-box-separate" />
</a>
</Tooltip>

View File

@ -3,9 +3,9 @@ import * as React from 'react';
import dayjs from 'dayjs';
import { FormattedMessage, useIntl } from 'dumi';
import { Tabs, Skeleton, Avatar, Divider, Empty } from 'antd';
import { css } from '@emotion/react';
import { useSiteData } from '../../../pages/index/components/util';
import type { Article, Authors } from '../../../pages/index/components/util';
import { css } from '@emotion/react';
import useSiteToken from '../../../hooks/useSiteToken';
const useStyle = () => {

View File

@ -86,7 +86,7 @@ const ResourceCard: React.FC<ResourceCardProps> = ({ resource }) => {
return (
<Col xs={24} sm={12} md={8} lg={6} style={{ padding: 12 }}>
<a css={styles.card} target="_blank" href={src}>
<a css={styles.card} target="_blank" href={src} rel="noreferrer">
<img
css={styles.image}
src={cover}
@ -105,14 +105,12 @@ export type ResourceCardsProps = {
resources: Resource[];
};
const ResourceCards: React.FC<ResourceCardsProps> = ({ resources }) => {
return (
const ResourceCards: React.FC<ResourceCardsProps> = ({ resources }) => (
<Row style={{ margin: '-12px -12px 0 -12px' }}>
{resources.map((item) => (
<ResourceCard resource={item} key={item.title} />
))}
</Row>
);
};
);
export default ResourceCards;

View File

@ -1,10 +1,14 @@
import React, { FC, useMemo } from 'react';
import type { FC } from 'react';
import React, { useMemo } from 'react';
/* eslint import/no-unresolved: 0 */
// @ts-ignore
import tokenMeta from 'antd/es/version/token-meta.json';
import { getDesignToken } from 'antd-token-previewer';
import { Table, TableProps, Tag } from 'antd';
import type { TableProps } from 'antd';
import { Table } from 'antd';
import { css } from '@emotion/react';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import { css } from '@emotion/react';
type TokenTableProps = {
type: 'seed' | 'map' | 'alias';
@ -89,7 +93,7 @@ const TokenTable: FC<TokenTableProps> = ({ type }) => {
boxShadow: 'inset 0 0 0 1px rgba(0, 0, 0, 0.06)',
marginRight: 4,
}}
></span>
/>
)}
{typeof record.value !== 'string' ? JSON.stringify(record.value) : record.value}
</span>
@ -97,16 +101,16 @@ const TokenTable: FC<TokenTableProps> = ({ type }) => {
},
];
const data = useMemo<TokenData[]>(() => {
return tokenMeta[type].map((token) => {
return {
const data = useMemo<TokenData[]>(
() =>
tokenMeta[type].map((token) => ({
name: token.name,
desc: lang === 'cn' ? token.desc : token.descEn,
type: token.type,
value: (defaultToken as any)[token.name],
};
});
}, [type, lang]);
})),
[type, lang],
);
return <Table dataSource={data} columns={columns} pagination={false} bordered />;
};

View File

@ -1,3 +1,4 @@
import React from 'react';
import { Global, css } from '@emotion/react';
import useSiteToken from '../../../hooks/useSiteToken';

View File

@ -6,7 +6,7 @@ const CommonHelmet = () => {
const [title, description] = useMemo(() => {
const helmetTitle = `${meta.frontmatter.subtitle || ''} ${meta.frontmatter.title} - Ant Design`;
let helmetDescription = meta.frontmatter.description;
const helmetDescription = meta.frontmatter.description;
return [helmetTitle, helmetDescription];
}, [meta]);

View File

@ -1,8 +1,8 @@
import React from 'react';
import { Global, css } from '@emotion/react';
import useSiteToken from '../../hooks/useSiteToken';
import { TinyColor } from '@ctrl/tinycolor';
import ColorStyle from '../common/Color/ColorStyle';
import useSiteToken from '../../hooks/useSiteToken';
import ColorStyle from './Color/ColorStyle';
const GlobalStyles = () => {
const { token } = useSiteToken();

View File

@ -1,10 +1,11 @@
import React, { ReactElement, useMemo } from 'react';
import type { ReactElement } from 'react';
import React, { useMemo } from 'react';
import { ClassNames, css } from '@emotion/react';
import useSiteToken from '../../hooks/useSiteToken';
import { Menu, MenuProps, Typography } from 'antd';
import useMenu from '../../hooks/useMenu';
import { MenuItemType } from 'antd/es/menu/hooks/useItems';
import type { MenuProps } from 'antd';
import type { MenuItemType } from 'antd/es/menu/hooks/useItems';
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
import useMenu from '../../hooks/useMenu';
import useSiteToken from '../../hooks/useSiteToken';
const useStyle = () => {
const { token } = useSiteToken();
@ -114,9 +115,10 @@ const PrevAndNext = () => {
activeMenuItemIndex = i;
}
});
const prev = flatMenu[activeMenuItemIndex - 1];
const next = flatMenu[activeMenuItemIndex + 1];
return [prev as MenuItemType, next as MenuItemType];
return [
flatMenu[activeMenuItemIndex - 1] as MenuItemType,
flatMenu[activeMenuItemIndex + 1] as MenuItemType,
];
}, [menuItems, selectedKey]);
return (

View File

@ -1,7 +1,8 @@
import React, { FC } from 'react';
import type { FC } from 'react';
import React from 'react';
import { FloatButton, theme } from 'antd';
import ThemeIcon from './ThemeIcon';
import { DarkTheme, Light, CompactTheme } from 'antd-token-previewer/es/icons';
import ThemeIcon from './ThemeIcon';
const { defaultAlgorithm, darkAlgorithm, compactAlgorithm } = theme;

View File

@ -1,17 +1,18 @@
import React, { useEffect, useMemo, useRef, useLayoutEffect } from 'react';
import React, { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
import 'dayjs/locale/zh-cn';
import dayjs from 'dayjs';
import { useOutlet, useSearchParams, Helmet } from 'dumi';
import Header from 'dumi/theme/slots/Header';
import Footer from 'dumi/theme/slots/Footer';
import { Helmet, useOutlet, useSearchParams } from 'dumi';
import '../../static/style';
import useLocation from '../../../hooks/useLocation';
import SiteContext from '../../slots/SiteContext';
import ConfigProvider, { DirectionType } from 'antd/es/config-provider';
import type { DirectionType } from 'antd/es/config-provider';
import ConfigProvider from 'antd/es/config-provider';
import classNames from 'classnames';
import useLocale from '../../../hooks/useLocale';
import zhCN from 'antd/es/locale/zh_CN';
import { createCache, StyleProvider } from '@ant-design/cssinjs';
import Header from '../../slots/Header';
import Footer from '../../slots/Footer';
import useLocale from '../../../hooks/useLocale';
import SiteContext from '../../slots/SiteContext';
import useLocation from '../../../hooks/useLocation';
import ResourceLayout from '../ResourceLayout';
import GlobalStyles from '../../common/GlobalStyles';
import SidebarLayout from '../SidebarLayout';
@ -94,9 +95,9 @@ const DocLayout: React.FC = () => {
}
}, [location]);
const changeDirection = (direction: DirectionType): void => {
setDirection(direction);
if (direction === 'ltr') {
const changeDirection = (dir: DirectionType): void => {
setDirection(dir);
if (dir === 'ltr') {
searchParams.delete('direction');
} else {
searchParams.set('direction', 'rtl');
@ -115,17 +116,27 @@ const DocLayout: React.FC = () => {
<Footer />
</>
);
} else if (pathname.startsWith('/docs/resource')) {
}
if (pathname.startsWith('/docs/resource')) {
return <ResourceLayout>{outlet}</ResourceLayout>;
} else if (pathname.startsWith('/theme-editor')) {
return <>{outlet}</>;
}
if (pathname.startsWith('/theme-editor')) {
return outlet;
}
return <SidebarLayout>{outlet}</SidebarLayout>;
}, [pathname, outlet]);
const siteContextValue = useMemo(
() => ({
isMobile,
direction,
}),
[isMobile, direction],
);
return (
<StyleProvider cache={styleCache}>
<SiteContext.Provider value={{ isMobile, direction }}>
<SiteContext.Provider value={siteContextValue}>
<Helmet encodeSpecialCharacters={false}>
<html
lang={lang}

View File

@ -1,8 +1,9 @@
import React, { useLayoutEffect } from 'react';
import { useOutlet } from 'dumi';
import { ConfigProvider, theme as antdTheme } from 'antd';
import { ThemeConfig } from 'antd/es/config-provider/context';
import ThemeContext, { ThemeContextProps } from '../slots/ThemeContext';
import type { ThemeConfig } from 'antd/es/config-provider/context';
import type { ThemeContextProps } from '../slots/ThemeContext';
import ThemeContext from '../slots/ThemeContext';
import ThemeSwitch from '../common/ThemeSwitch';
import useLocation from '../../hooks/useLocation';

View File

@ -1,10 +1,9 @@
import * as React from 'react';
import classNames from 'classnames';
import throttle from 'lodash/throttle';
import { Tabs } from 'antd';
import { css } from '@emotion/react';
import scrollTo from '../../../../components/_util/scrollTo';
import useSiteToken from '../../../hooks/useSiteToken';
import { css } from '@emotion/react';
const useStyle = () => {
const { token } = useSiteToken();

View File

@ -1,8 +1,9 @@
import React, { FC, PropsWithChildren } from 'react';
import type { FC, PropsWithChildren } from 'react';
import React from 'react';
import { useRouteMeta, FormattedMessage } from 'dumi';
import Footer from 'dumi/theme/slots/Footer';
import { Layout, Typography, ConfigProvider } from 'antd';
import { css } from '@emotion/react';
import Footer from '../../slots/Footer';
import AffixTabs from './AffixTabs';
import EditButton from '../../common/EditButton';
import useSiteToken from '../../../hooks/useSiteToken';

View File

@ -1,16 +1,15 @@
import React, { FC, PropsWithChildren } from 'react';
import type { FC, PropsWithChildren } from 'react';
import React from 'react';
import Sidebar from '../../slots/Sidebar';
import Content from '../../slots/Content';
import CommonHelmet from '../../common/CommonHelmet';
const SidebarLayout: FC<PropsWithChildren<{}>> = ({ children }) => {
return (
const SidebarLayout: FC<PropsWithChildren<{}>> = ({ children }) => (
<main style={{ display: 'flex', marginTop: 40 }}>
<CommonHelmet />
<Sidebar />
<Content>{children}</Content>
</main>
);
};
);
export default SidebarLayout;

View File

@ -81,7 +81,7 @@ const RoutesPlugin = (api: IApi) => {
let styles = '';
// extract all emotion style tags from body
file.content = file.content.replace(/<style data-emotion[\s\S\n]+?<\/style>/g, (s) => {
file.content = file.content.replace(/<style data-emotion[\S\s]+?<\/style>/g, (s) => {
styles += s;
return '';

View File

@ -1,16 +1,17 @@
import React, { ReactNode, useMemo, useState, useLayoutEffect, useContext } from 'react';
import { useIntl, useRouteMeta } from 'dumi';
import Footer from 'dumi/theme/slots/Footer';
import type { ReactNode } from 'react';
import React, { useMemo, useState, useLayoutEffect, useContext } from 'react';
import { useIntl, useRouteMeta, FormattedMessage } from 'dumi';
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 Footer from '../Footer';
import EditButton from '../../common/EditButton';
import useLocation from '../../../hooks/useLocation';
import useSiteToken from '../../../hooks/useSiteToken';
import PrevAndNext from '../../common/PrevAndNext';
import type { DemoContextProps } from '../DemoContext';
import DemoContext from '../DemoContext';
import SiteContext from '../SiteContext';
const useStyle = () => {
@ -120,8 +121,9 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
[showDebug, debugDemos],
);
const anchorItems = useMemo(() => {
return meta.toc.reduce<AnchorItem[]>((result, item) => {
const anchorItems = useMemo(
() =>
meta.toc.reduce<AnchorItem[]>((result, item) => {
if (item.depth === 2) {
result.push({ ...item });
} else if (item.depth === 3) {
@ -132,8 +134,9 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
}
}
return result;
}, []);
}, [meta.toc]);
}, []),
[meta.toc],
);
const isRTL = direction === 'rtl';

View File

@ -17,12 +17,12 @@ import {
ZhihuOutlined,
YuqueFilled,
} from '@ant-design/icons';
import useLocation from '../../../hooks/useLocation';
import { css } from '@emotion/react';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import { TinyColor } from '@ctrl/tinycolor';
import getAlphaColor from 'antd/es/theme/util/getAlphaColor';
import useLocation from '../../../hooks/useLocation';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
import AdditionalInfo from './AdditionalInfo';
const locales = {

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import { Link, useLocation } from 'dumi';
import * as utils from '../../utils';
import { css } from '@emotion/react';
import * as utils from '../../utils';
import useSiteToken from '../../../hooks/useSiteToken';
const useStyle = () => {

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import type { MenuProps } from 'antd';
import { Dropdown, Menu, Button } from 'antd';
import { Button, Dropdown } from 'antd';
import { FormattedMessage } from 'dumi';
import { DownOutlined } from '@ant-design/icons';
import type { SharedProps } from './interface';

View File

@ -1,15 +1,15 @@
import * as React from 'react';
import classNames from 'classnames';
import { Link, useLocation, FormattedMessage, useFullSidebarData } from 'dumi';
import { MenuProps, Tooltip } from 'antd';
import { MenuOutlined } from '@ant-design/icons';
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';
import { css } from '@emotion/react';
// ============================= Theme =============================
const locales = {

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import { Button, Tooltip } from 'antd';
import useSiteToken from '../../../hooks/useSiteToken';
import { Tooltip } from 'antd';
import { css } from '@emotion/react';
import useSiteToken from '../../../hooks/useSiteToken';
export interface LangBtnProps {
label1: React.ReactNode;
@ -110,13 +110,8 @@ export default function LangBtn({
let node = (
<button onClick={onClick} css={[style.btn]} key="lang-button">
<div className="btn-inner">
{pure ? (
value === 1 ? (
label1
) : (
label2
)
) : (
{pure && (value === 1 ? label1 : label2)}
{!pure && (
<div style={{ position: 'relative', width: BASE_SIZE, height: BASE_SIZE }}>
<span
style={{

View File

@ -1,21 +1,19 @@
import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
import { FormattedMessage, useIntl } from 'dumi';
import { useLocation } from 'dumi';
import DumiSearchBar from 'dumi/theme-default/slots/SearchBar';
import classNames from 'classnames';
import { Col, Modal, Popover, Row, Select, Typography } from 'antd';
import { MenuOutlined, GithubOutlined } from '@ant-design/icons';
import { GithubOutlined, MenuOutlined } from '@ant-design/icons';
import type { DirectionType } from 'antd/es/config-provider';
import { ClassNames, css } from '@emotion/react';
import * as utils from '../../utils';
import { getThemeConfig, ping } from '../../utils';
import packageJson from '../../../../package.json';
import Logo from './Logo';
import More from './More';
import Navigation from './Navigation';
import Github from './Github';
import type { SiteContextProps } from '../SiteContext';
import SiteContext from '../SiteContext';
import { useLocation, useNavigate } from 'dumi';
import { ClassNames, css } from '@emotion/react';
import useSiteToken from '../../../hooks/useSiteToken';
import useLocale from '../../../hooks/useLocale';
import SwitchBtn from './SwitchBtn';
@ -135,18 +133,6 @@ export interface HeaderProps {
changeDirection: (direction: DirectionType) => void;
}
let docsearch: any;
const triggerDocSearchImport = () => {
if (docsearch) {
return Promise.resolve();
}
// @ts-ignore
return import('docsearch.js').then((ds) => {
docsearch = ds.default;
});
};
const V5_NOTIFICATION = 'antd@4.0.0-notification-sent';
const SHOULD_OPEN_ANT_DESIGN_MIRROR_MODAL = 'ANT_DESIGN_DO_NOT_OPEN_MIRROR_MODAL';
@ -166,7 +152,6 @@ interface HeaderState {
// ================================= Header =================================
const Header: React.FC<HeaderProps> = (props) => {
const intl = useIntl();
const { changeDirection } = props;
const [isClient, setIsClient] = React.useState(false);
const [locale, lang] = useLocale(locales);
@ -207,7 +192,6 @@ const Header: React.FC<HeaderProps> = (props) => {
const pingTimer = useRef<NodeJS.Timeout | null>(null);
const location = useLocation();
const { pathname, search } = location;
const navigate = useNavigate();
const style = useStyle();
@ -217,9 +201,6 @@ const Header: React.FC<HeaderProps> = (props) => {
const onWindowResize = useCallback(() => {
setHeaderState((prev) => ({ ...prev, windowWidth: window.innerWidth }));
}, []);
const onTriggerSearching = useCallback((searching: boolean) => {
setHeaderState((prev) => ({ ...prev, searching }));
}, []);
const handleShowMenu = useCallback(() => {
setHeaderState((prev) => ({ ...prev, menuVisible: true }));
}, []);
@ -358,6 +339,7 @@ const Header: React.FC<HeaderProps> = (props) => {
let menu: (React.ReactElement | null)[] = [
navigationNode,
<Popover
key="version"
open={!!notify}
title={locale.title}
content={
@ -422,24 +404,28 @@ const Header: React.FC<HeaderProps> = (props) => {
onClick={onDirectionChange}
value={direction === 'rtl' ? 2 : 1}
label1={
<img src="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*6k0CTJA-HxUAAAAAAAAAAAAADrJ8AQ/original" />
<img
src="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*6k0CTJA-HxUAAAAAAAAAAAAADrJ8AQ/original"
alt="direction"
/>
}
tooltip1="LTR"
label2={
<img src="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*SZoaQqm2hwsAAAAAAAAAAAAADrJ8AQ/original" />
<img
src="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*SZoaQqm2hwsAAAAAAAAAAAAADrJ8AQ/original"
alt="LTR"
/>
}
tooltip2="RTL"
pure
/>,
<a href="https://github.com/ant-design/ant-design" target="_blank">
<SwitchBtn
<a
key="github"
value={1}
label1={<GithubOutlined />}
tooltip1="Github"
label2={null}
pure
/>
href="https://github.com/ant-design/ant-design"
target="_blank"
rel="noreferrer"
>
<SwitchBtn value={1} label1={<GithubOutlined />} tooltip1="Github" label2={null} pure />
</a>,
];
@ -460,9 +446,9 @@ const Header: React.FC<HeaderProps> = (props) => {
<header css={style.header} className={headerClassName}>
{isMobile && (
<ClassNames>
{({ css }) => (
{({ css: cssFn }) => (
<Popover
overlayClassName={css(style.popoverMenu)}
overlayClassName={cssFn(style.popoverMenu)}
placement="bottomRight"
content={menu}
trigger="click"

View File

@ -2,10 +2,10 @@ import React, { useContext } from 'react';
import { useSidebarData } from 'dumi';
import { Affix, Col, Menu } from 'antd';
import MobileMenu from 'rc-drawer';
import { css } from '@emotion/react';
import SiteContext from '../SiteContext';
import useMenu from '../../../hooks/useMenu';
import useSiteToken from '../../../hooks/useSiteToken';
import { css } from '@emotion/react';
const useStyle = () => {
const { token } = useSiteToken();

View File

@ -1,5 +1,5 @@
import { createContext } from 'react';
import { ThemeConfig } from 'antd/es/config-provider/context';
import type { ThemeConfig } from 'antd/es/config-provider/context';
export type ThemeContextProps = {
theme: ThemeConfig;

View File

@ -3,6 +3,8 @@
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "@emotion/react",
"esModuleInterop": true,
"resolveJsonModule": true,
"baseUrl": "../",
"paths": {
"@@/*": [".dumi/tmp/*"],

View File

@ -11,6 +11,8 @@ lib/**/*
locale
server
.dumi/tmp
.dumi/tmp-production
!.dumi/
node_modules
_site
dist

View File

@ -98,6 +98,22 @@ module.exports = {
'react/no-access-state-in-setstate': 0,
},
},
{
files: ['.dumi/**/*.ts', '.dumi/**/*.tsx', '.dumi/**/*.js', '.dumi/**/*.jsx'],
rules: {
'import/no-extraneous-dependencies': 0,
'no-console': 0,
'compat/compat': 0,
'react/no-unstable-nested-components': 0,
'jsx-a11y/control-has-associated-label': 0,
'class-methods-use-this': 0,
'react/no-access-state-in-setstate': 0,
'react/no-unknown-property': ['error', { ignore: ['css'] }],
'react/no-array-index-key': 0,
'react/button-has-type': 0,
'react/no-danger': 0,
},
},
],
rules: {
'react/jsx-one-expression-per-line': 0,

View File

@ -1,3 +1,4 @@
// @ts-nocheck
import React from 'react';
import { PoweroffOutlined } from '@ant-design/icons';
import { Button, Space } from 'antd';

View File

@ -4,14 +4,14 @@ import type {
TourStepProps as RCTourStepProps,
} from '@rc-component/tour';
export type TourProps = Omit<RCTourProps, 'renderPanel'> & {
export interface TourProps extends Omit<RCTourProps, 'renderPanel'> {
steps?: TourStepProps[];
className?: string;
prefixCls?: string;
current?: number;
stepRender?: (current: number, total: number) => ReactNode;
type?: 'default' | 'primary'; // default 类型,影响底色与文字颜色
};
}
export interface TourStepProps extends RCTourStepProps {
cover?: ReactNode; // 展示的图片或者视频

View File

@ -23,5 +23,5 @@
"skipLibCheck": true,
"stripInternal": true
},
"exclude": ["node_modules", "lib", "es", "components/*/demo"]
"exclude": ["node_modules", "lib", "es"]
}