mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 02:59:58 +08:00
commit
5d376aefb1
@ -115,8 +115,14 @@ const useMenu = (options: UseMenuOptions = {}): [MenuProps['items'], string] =>
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const list = group.children || [];
|
||||
// 如果有 date 字段,我们就对其进行排序
|
||||
if (list.every((info) => info?.frontmatter?.date)) {
|
||||
list.sort((a, b) => (a.frontmatter.date > b.frontmatter.date ? -1 : 1));
|
||||
}
|
||||
|
||||
result.push(
|
||||
...(group.children?.map((item) => ({
|
||||
...list.map((item) => ({
|
||||
label: (
|
||||
<Link to={`${item.link}${search}`}>
|
||||
{before}
|
||||
@ -125,7 +131,7 @@ const useMenu = (options: UseMenuOptions = {}): [MenuProps['items'], string] =>
|
||||
</Link>
|
||||
),
|
||||
key: item.link.replace(/(-cn$)/g, ''),
|
||||
})) ?? []),
|
||||
})),
|
||||
);
|
||||
}
|
||||
return result;
|
||||
|
@ -1,21 +1,140 @@
|
||||
import React, { useState } from 'react';
|
||||
import { ThemeEditor } from 'antd-token-previewer';
|
||||
import { ConfigProvider } from 'antd';
|
||||
import React, { useEffect } from 'react';
|
||||
import { enUS, ThemeEditor, zhCN } from 'antd-token-previewer';
|
||||
import { Button, ConfigProvider, message, Modal, Typography } from 'antd';
|
||||
import type { ThemeConfig } from 'antd/es/config-provider/context';
|
||||
import { Helmet } from 'dumi';
|
||||
import { css } from '@emotion/react';
|
||||
import CopyToClipboard from 'react-copy-to-clipboard';
|
||||
import { CopyOutlined } from '@ant-design/icons';
|
||||
import useLocale from '../../hooks/useLocale';
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
title: '主题编辑器',
|
||||
save: '保存',
|
||||
reset: '重置',
|
||||
export: '导出',
|
||||
exportDesc: '将下面的 JSON 对象复制到 ConfigProvider 的 theme 属性中即可。',
|
||||
saveSuccessfully: '保存成功',
|
||||
},
|
||||
en: {
|
||||
title: 'Theme Editor',
|
||||
save: 'Save',
|
||||
reset: 'Reset',
|
||||
export: 'Export',
|
||||
exportDesc: 'Copy the following JSON object to the theme prop of ConfigProvider.',
|
||||
saveSuccessfully: 'Saved successfully',
|
||||
},
|
||||
};
|
||||
|
||||
const useStyle = () => ({
|
||||
header: css({
|
||||
display: 'flex',
|
||||
height: 56,
|
||||
alignItems: 'center',
|
||||
padding: '0 24px',
|
||||
justifyContent: 'space-between',
|
||||
borderBottom: '1px solid #F0F0F0',
|
||||
}),
|
||||
});
|
||||
|
||||
const ANT_DESIGN_V5_THEME_EDITOR_THEME = 'ant-design-v5-theme-editor-theme';
|
||||
|
||||
const CustomTheme = () => {
|
||||
const [theme, setTheme] = useState<ThemeConfig>({});
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const [modalApi, modalContextHolder] = Modal.useModal();
|
||||
const [locale, lang] = useLocale(locales);
|
||||
|
||||
const [theme, setTheme] = React.useState<ThemeConfig>({});
|
||||
|
||||
useEffect(() => {
|
||||
const storedConfig = localStorage.getItem(ANT_DESIGN_V5_THEME_EDITOR_THEME);
|
||||
if (storedConfig) {
|
||||
setTheme(() => JSON.parse(storedConfig));
|
||||
}
|
||||
}, []);
|
||||
|
||||
const styles = useStyle();
|
||||
|
||||
const handleSave = () => {
|
||||
localStorage.setItem(ANT_DESIGN_V5_THEME_EDITOR_THEME, JSON.stringify(theme));
|
||||
messageApi.success(locale.saveSuccessfully);
|
||||
};
|
||||
|
||||
const onCopy = (text: string, result: boolean) => {
|
||||
if (result) {
|
||||
messageApi.success('Copy theme config successfully!');
|
||||
} else {
|
||||
messageApi.error('Copy failed, please try again.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleOutput = () => {
|
||||
modalApi.info({
|
||||
title: locale.export,
|
||||
width: 600,
|
||||
content: (
|
||||
<div>
|
||||
<div style={{ color: 'rgba(0,0,0,0.65)' }}>{locale.exportDesc}</div>
|
||||
<pre
|
||||
style={{
|
||||
padding: 12,
|
||||
background: '#f5f5f5',
|
||||
borderRadius: 4,
|
||||
marginTop: 12,
|
||||
position: 'relative',
|
||||
}}
|
||||
>
|
||||
<CopyToClipboard text={JSON.stringify(theme, null, 2)} onCopy={onCopy}>
|
||||
<Button
|
||||
type="text"
|
||||
icon={<CopyOutlined />}
|
||||
style={{ position: 'absolute', right: 8, top: 8 }}
|
||||
/>
|
||||
</CopyToClipboard>
|
||||
{JSON.stringify(theme, null, 2)}
|
||||
</pre>
|
||||
</div>
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
setTheme({});
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Helmet>
|
||||
<title>{`${locale.title} - Ant Design`}</title>
|
||||
<meta property="og:title" content={`${locale.title} - Ant Design`} />
|
||||
</Helmet>
|
||||
{contextHolder}
|
||||
{modalContextHolder}
|
||||
<ConfigProvider theme={{ inherit: false }}>
|
||||
<div css={styles.header}>
|
||||
<Typography.Title level={5} style={{ margin: 0 }}>
|
||||
{locale.title}
|
||||
</Typography.Title>
|
||||
<div>
|
||||
<Button onClick={handleOutput} style={{ marginRight: 8 }}>
|
||||
{locale.export}
|
||||
</Button>
|
||||
<Button onClick={handleReset} style={{ marginRight: 8 }}>
|
||||
{locale.reset}
|
||||
</Button>
|
||||
<Button type="primary" onClick={handleSave}>
|
||||
{locale.save}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<ThemeEditor
|
||||
theme={{ name: 'Custom Theme', key: 'test', config: theme }}
|
||||
simple
|
||||
style={{ height: 'calc(100vh - 64px)' }}
|
||||
style={{ height: 'calc(100vh - 64px - 56px)' }}
|
||||
onThemeChange={(newTheme) => {
|
||||
setTheme(newTheme.config);
|
||||
}}
|
||||
locale={lang === 'cn' ? zhCN : enUS}
|
||||
/>
|
||||
</ConfigProvider>
|
||||
</div>
|
||||
|
50
.dumi/theme/builtins/ColorChunk/index.tsx
Normal file
50
.dumi/theme/builtins/ColorChunk/index.tsx
Normal file
@ -0,0 +1,50 @@
|
||||
import * as React from 'react';
|
||||
import { TinyColor, type ColorInput } from '@ctrl/tinycolor';
|
||||
import { css } from '@emotion/react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
interface ColorChunkProps {
|
||||
children?: React.ReactNode;
|
||||
color?: ColorInput;
|
||||
}
|
||||
|
||||
const useStyle = () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
return {
|
||||
codeSpan: css`
|
||||
padding: 0.2em 0.4em;
|
||||
font-size: 0.9em;
|
||||
background: ${token.siteMarkdownCodeBg};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
font-family: monospace;
|
||||
`,
|
||||
dot: css`
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: ${token.borderRadiusSM}px;
|
||||
margin-right: 4px;
|
||||
border: 1px solid ${token.colorSplit};
|
||||
`,
|
||||
};
|
||||
};
|
||||
|
||||
const ColorChunk: React.FC<ColorChunkProps> = (props) => {
|
||||
const styles = useStyle();
|
||||
const { color, children } = props;
|
||||
|
||||
const dotColor = React.useMemo(() => {
|
||||
const _color = new TinyColor(color).toHex8String();
|
||||
return _color.endsWith('ff') ? _color.slice(0, -2) : _color;
|
||||
}, [color]);
|
||||
|
||||
return (
|
||||
<span css={styles.codeSpan}>
|
||||
<span css={styles.dot} style={{ backgroundColor: dotColor }} />
|
||||
{children ?? dotColor}
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default ColorChunk;
|
@ -2,28 +2,39 @@ import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import { Modal, Carousel } from 'antd';
|
||||
|
||||
function isGood(className) {
|
||||
function isGood(className: string): boolean {
|
||||
return /\bgood\b/i.test(className);
|
||||
}
|
||||
|
||||
function isBad(className) {
|
||||
function isBad(className: string): boolean {
|
||||
return /\bbad\b/i.test(className);
|
||||
}
|
||||
|
||||
function isInline(className) {
|
||||
function isInline(className: string): boolean {
|
||||
return /\binline\b/i.test(className);
|
||||
}
|
||||
|
||||
function PreviewImageBox({
|
||||
cover,
|
||||
coverMeta,
|
||||
imgs,
|
||||
style,
|
||||
previewVisible,
|
||||
comparable,
|
||||
onClick,
|
||||
onCancel,
|
||||
}) {
|
||||
function isGoodBadImg(imgMeta: any): boolean {
|
||||
return imgMeta.isGood || imgMeta.isBad;
|
||||
}
|
||||
|
||||
function isCompareImg(imgMeta: any): boolean {
|
||||
return isGoodBadImg(imgMeta) || imgMeta.inline;
|
||||
}
|
||||
|
||||
interface PreviewImageBoxProps {
|
||||
coverMeta: any;
|
||||
cover: React.ReactNode;
|
||||
imgs: React.ReactNode[];
|
||||
style: React.CSSProperties;
|
||||
previewVisible: boolean;
|
||||
comparable: boolean;
|
||||
onClick: () => void;
|
||||
onCancel: () => void;
|
||||
}
|
||||
|
||||
const PreviewImageBox: React.FC<PreviewImageBoxProps> = (props) => {
|
||||
const { cover, coverMeta, imgs, style, previewVisible, comparable, onClick, onCancel } = props;
|
||||
const onlyOneImg = comparable || imgs.length === 1;
|
||||
const imageWrapperClassName = classNames('preview-image-wrapper', {
|
||||
good: coverMeta.isGood,
|
||||
@ -58,30 +69,27 @@ function PreviewImageBox({
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface ImagePreviewProps {
|
||||
imgs: any[];
|
||||
}
|
||||
|
||||
function isGoodBadImg(imgMeta) {
|
||||
return imgMeta.isGood || imgMeta.isBad;
|
||||
interface ImagePreviewStates {
|
||||
previewVisible?: Record<PropertyKey, boolean>;
|
||||
}
|
||||
|
||||
function isCompareImg(imgMeta) {
|
||||
return isGoodBadImg(imgMeta) || imgMeta.inline;
|
||||
}
|
||||
|
||||
export default class ImagePreview extends React.Component {
|
||||
constructor(props) {
|
||||
class ImagePreview extends React.Component<ImagePreviewProps, ImagePreviewStates> {
|
||||
constructor(props: ImagePreviewProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
previewVisible: {},
|
||||
};
|
||||
}
|
||||
|
||||
handleClick = (index) => {
|
||||
handleClick = (index: number) => {
|
||||
this.setState({
|
||||
previewVisible: {
|
||||
[index]: true,
|
||||
},
|
||||
previewVisible: { [index]: true },
|
||||
});
|
||||
};
|
||||
|
||||
@ -107,7 +115,7 @@ export default class ImagePreview extends React.Component {
|
||||
};
|
||||
});
|
||||
|
||||
const imagesList = imgsMeta.map((meta, index) => {
|
||||
const imagesList = imgsMeta.map<React.ReactNode>((meta, index) => {
|
||||
const metaCopy = { ...meta };
|
||||
delete metaCopy.description;
|
||||
delete metaCopy.isGood;
|
||||
@ -125,7 +133,9 @@ export default class ImagePreview extends React.Component {
|
||||
(imgs.length === 2 && imgsMeta.every(isCompareImg)) ||
|
||||
(imgs.length >= 2 && imgsMeta.every(isGoodBadImg));
|
||||
|
||||
const style = comparable ? { width: `${(100 / imgs.length).toFixed(3)}%` } : null;
|
||||
const style: React.CSSProperties = comparable
|
||||
? { width: `${(100 / imgs.length).toFixed(3)}%` }
|
||||
: {};
|
||||
|
||||
const hasCarousel = imgs.length > 1 && !comparable;
|
||||
const previewClassName = classNames({
|
||||
@ -140,20 +150,19 @@ export default class ImagePreview extends React.Component {
|
||||
if (!comparable && index !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<PreviewImageBox
|
||||
key={index}
|
||||
style={style}
|
||||
comparable={comparable}
|
||||
previewVisible={!!this.state.previewVisible[index]}
|
||||
previewVisible={!!this.state.previewVisible?.[index]}
|
||||
cover={imagesList[index]}
|
||||
coverMeta={imgsMeta[index]}
|
||||
imgs={imagesList}
|
||||
onCancel={this.handleCancel}
|
||||
onClick={() => {
|
||||
this.handleClick(index);
|
||||
}}
|
||||
onCancel={this.handleCancel}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@ -161,3 +170,5 @@ export default class ImagePreview extends React.Component {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ImagePreview;
|
@ -1,10 +1,9 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
// @ts-ignore
|
||||
import JsonML from 'jsonml.js/lib/utils';
|
||||
// @ts-ignore
|
||||
import toReactComponent from 'jsonml-to-react-element';
|
||||
import Prism from 'prismjs';
|
||||
import { useLocation, useIntl, type IPreviewerProps } from 'dumi';
|
||||
import 'prismjs/components/prism-typescript';
|
||||
import { useLocation, useSearchParams, useIntl, type IPreviewerProps } from 'dumi';
|
||||
import { ping } from '../../utils';
|
||||
|
||||
let pingDeferrer: PromiseLike<boolean>;
|
||||
@ -37,6 +36,7 @@ export default function fromDumiProps<P extends object>(
|
||||
const hoc = function DumiPropsAntdPreviewer(props: IPreviewerProps) {
|
||||
const showRiddleButton = useShowRiddleButton();
|
||||
const location = useLocation();
|
||||
const [searchParams] = useSearchParams();
|
||||
const { asset, children, demoUrl, expand, description = '', ...meta } = props;
|
||||
const intl = useIntl();
|
||||
const entryCode = asset.dependencies['index.tsx'].value;
|
||||
@ -75,9 +75,13 @@ export default function fromDumiProps<P extends object>(
|
||||
},
|
||||
intl: { locale: intl.locale },
|
||||
showRiddleButton,
|
||||
sourceCodes: {
|
||||
jsx: meta.jsx,
|
||||
tsx: entryCode,
|
||||
},
|
||||
highlightedCodes: {
|
||||
jsx: Prism.highlight(meta.jsx, Prism.languages.javascript, 'jsx'),
|
||||
tsx: Prism.highlight(entryCode, Prism.languages.javascript, 'tsx'),
|
||||
tsx: Prism.highlight(entryCode, Prism.languages.typescript, 'tsx'),
|
||||
},
|
||||
style: meta.style,
|
||||
location,
|
||||
@ -85,8 +89,7 @@ export default function fromDumiProps<P extends object>(
|
||||
expand,
|
||||
// FIXME: confirm is there has any case?
|
||||
highlightedStyle: '',
|
||||
// FIXME: dumi support usePrefersColor
|
||||
theme: 'light',
|
||||
theme: searchParams.get('theme'),
|
||||
} as P;
|
||||
|
||||
return <WrappedComponent {...transformedProps} />;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* eslint jsx-a11y/no-noninteractive-element-interactions: 0 */
|
||||
import { CheckOutlined, SnippetsOutlined, ThunderboltOutlined } from '@ant-design/icons';
|
||||
import stackblitzSdk from '@stackblitz/sdk';
|
||||
import type { Project } from '@stackblitz/sdk';
|
||||
import { Alert, Badge, Tooltip, Space } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import LZString from 'lz-string';
|
||||
@ -16,26 +17,55 @@ import CodeSandboxIcon from '../../common/CodeSandboxIcon';
|
||||
import RiddleIcon from '../../common/RiddleIcon';
|
||||
import ExternalLinkIcon from '../../common/ExternalLinkIcon';
|
||||
import fromDumiProps from './fromDumiProps';
|
||||
import { version } from '../../../../package.json';
|
||||
|
||||
const { ErrorBoundary } = Alert;
|
||||
|
||||
function compress(string) {
|
||||
function compress(string: string): string {
|
||||
return LZString.compressToBase64(string)
|
||||
.replace(/\+/g, '-') // Convert '+' to '-'
|
||||
.replace(/\//g, '_') // Convert '/' to '_'
|
||||
.replace(/=+$/, ''); // Remove ending '='
|
||||
}
|
||||
|
||||
class Demo extends React.Component {
|
||||
iframeRef = React.createRef();
|
||||
interface DemoProps {
|
||||
meta: any;
|
||||
src: string;
|
||||
content: string;
|
||||
preview: (react: typeof React, reactDOM: typeof ReactDOM) => React.ReactNode;
|
||||
highlightedCodes: Record<PropertyKey, string>;
|
||||
style: string;
|
||||
highlightedStyle: string;
|
||||
expand: boolean;
|
||||
intl: any;
|
||||
theme: string;
|
||||
sourceCodes: Record<'jsx' | 'tsx', string>;
|
||||
location: Location;
|
||||
showRiddleButton: boolean;
|
||||
utils?: any;
|
||||
}
|
||||
|
||||
codeSandboxIconRef = React.createRef();
|
||||
interface DemoState {
|
||||
codeType?: string;
|
||||
copied?: boolean;
|
||||
codeExpand?: boolean;
|
||||
copyTooltipOpen?: boolean | string;
|
||||
}
|
||||
|
||||
riddleIconRef = React.createRef();
|
||||
class Demo extends React.Component<DemoProps, DemoState> {
|
||||
liveDemo: any;
|
||||
|
||||
codepenIconRef = React.createRef();
|
||||
iframeRef = React.createRef<HTMLIFrameElement>();
|
||||
|
||||
state = {
|
||||
anchorRef = React.createRef<HTMLAnchorElement>();
|
||||
|
||||
codeSandboxIconRef = React.createRef<HTMLFormElement>();
|
||||
|
||||
riddleIconRef = React.createRef<HTMLFormElement>();
|
||||
|
||||
codepenIconRef = React.createRef<HTMLFormElement>();
|
||||
|
||||
state: DemoState = {
|
||||
codeExpand: false,
|
||||
copied: false,
|
||||
copyTooltipOpen: false,
|
||||
@ -45,11 +75,11 @@ class Demo extends React.Component {
|
||||
componentDidMount() {
|
||||
const { meta, location } = this.props;
|
||||
if (meta.id === location.hash.slice(1)) {
|
||||
this.anchor.click();
|
||||
this.anchorRef.current?.click();
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
shouldComponentUpdate(nextProps: DemoProps, nextState: DemoState) {
|
||||
const { codeExpand, copied, copyTooltipOpen, codeType } = this.state;
|
||||
const { expand, theme, showRiddleButton } = this.props;
|
||||
return (
|
||||
@ -62,55 +92,31 @@ class Demo extends React.Component {
|
||||
);
|
||||
}
|
||||
|
||||
getSourceCode() {
|
||||
const { highlightedCodes } = this.props;
|
||||
const { codeType } = this.state;
|
||||
if (typeof document !== 'undefined') {
|
||||
const div = document.createElement('div');
|
||||
const divJSX = document.createElement('div');
|
||||
div.innerHTML = highlightedCodes[codeType] || highlightedCodes.jsx;
|
||||
divJSX.innerHTML = highlightedCodes.jsx;
|
||||
return [divJSX.textContent, div.textContent];
|
||||
}
|
||||
return ['', ''];
|
||||
}
|
||||
getSourceCode = (): [string, string] => {
|
||||
const { sourceCodes } = this.props;
|
||||
return [sourceCodes.jsx, sourceCodes.tsx];
|
||||
};
|
||||
|
||||
handleCodeExpand = (demo) => {
|
||||
handleCodeExpand = (demo: string) => {
|
||||
const { codeExpand } = this.state;
|
||||
this.setState({ codeExpand: !codeExpand });
|
||||
this.track({
|
||||
type: 'expand',
|
||||
demo,
|
||||
});
|
||||
this.track({ type: 'expand', demo });
|
||||
};
|
||||
|
||||
saveAnchor = (anchor) => {
|
||||
this.anchor = anchor;
|
||||
};
|
||||
|
||||
handleCodeCopied = (demo) => {
|
||||
handleCodeCopied = (demo: string) => {
|
||||
this.setState({ copied: true });
|
||||
this.track({
|
||||
type: 'copy',
|
||||
demo,
|
||||
});
|
||||
this.track({ type: 'copy', demo });
|
||||
};
|
||||
|
||||
onCopyTooltipOpenChange = (open) => {
|
||||
onCopyTooltipOpenChange = (open: boolean) => {
|
||||
if (open) {
|
||||
this.setState({
|
||||
copyTooltipOpen: open,
|
||||
copied: false,
|
||||
});
|
||||
this.setState({ copyTooltipOpen: open, copied: false });
|
||||
return;
|
||||
}
|
||||
this.setState({
|
||||
copyTooltipOpen: open,
|
||||
});
|
||||
this.setState({ copyTooltipOpen: open });
|
||||
};
|
||||
|
||||
// eslint-disable-next-line class-methods-use-this
|
||||
track({ type, demo }) {
|
||||
track = ({ type, demo }: { type: string; demo: string }) => {
|
||||
if (!window.gtag) {
|
||||
return;
|
||||
}
|
||||
@ -118,7 +124,7 @@ class Demo extends React.Component {
|
||||
event_category: type,
|
||||
event_label: demo,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { state } = this;
|
||||
@ -142,7 +148,6 @@ class Demo extends React.Component {
|
||||
<BrowserFrame>
|
||||
<iframe
|
||||
ref={this.iframeRef}
|
||||
onLoad={this.handleIframeReady}
|
||||
src={src}
|
||||
height={meta.iframe}
|
||||
title="demo"
|
||||
@ -191,7 +196,7 @@ class Demo extends React.Component {
|
||||
const [sourceCode, sourceCodeTyped] = this.getSourceCode();
|
||||
const suffix = codeType === 'tsx' ? 'tsx' : 'js';
|
||||
|
||||
const dependencies = sourceCode.split('\n').reduce(
|
||||
const dependencies: Record<PropertyKey, string> = sourceCode.split('\n').reduce(
|
||||
(acc, line) => {
|
||||
const matches = line.match(/import .+? from '(.+)';$/);
|
||||
if (matches && matches[1] && !line.includes('antd')) {
|
||||
@ -204,8 +209,7 @@ class Demo extends React.Component {
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
// eslint-disable-next-line no-undef
|
||||
{ antd: antdReproduceVersion },
|
||||
{ antd: version },
|
||||
);
|
||||
|
||||
dependencies['@ant-design/icons'] = 'latest';
|
||||
@ -237,15 +241,14 @@ class Demo extends React.Component {
|
||||
)}\n\ncreateRoot(mountNode).render(<ComponentDemo />);\n`,
|
||||
editors: '001',
|
||||
css: '',
|
||||
// eslint-disable-next-line no-undef
|
||||
js_external: [
|
||||
'react@18/umd/react.development.js',
|
||||
'react-dom@18/umd/react-dom.development.js',
|
||||
// eslint-disable-next-line no-undef
|
||||
`antd@${antdReproduceVersion}/dist/antd-with-locales.js`,
|
||||
'dayjs@1/dayjs.min.js',
|
||||
`antd@${version}/dist/antd-with-locales.js`,
|
||||
`@ant-design/icons/dist/index.umd.js`,
|
||||
'react-router-dom/umd/react-router-dom.min.js',
|
||||
'react-router@3.x/umd/ReactRouter.min.js',
|
||||
'react-router-dom/dist/umd/react-router-dom.production.min.js',
|
||||
'react-router/dist/umd/react-router.production.min.js',
|
||||
]
|
||||
.map((url) => `https://unpkg.com/${url}`)
|
||||
.join(';'),
|
||||
@ -332,10 +335,11 @@ createRoot(document.getElementById('container')).render(<Demo />);
|
||||
},
|
||||
},
|
||||
};
|
||||
const stackblitzPrefillConfig = {
|
||||
const stackblitzPrefillConfig: Project = {
|
||||
title: `${localizedTitle} - antd@${dependencies.antd}`,
|
||||
template: 'create-react-app',
|
||||
dependencies,
|
||||
description: '',
|
||||
files: {
|
||||
'index.css': indexCssContent,
|
||||
[`index.${suffix}`]: indexJsContent,
|
||||
@ -343,6 +347,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
|
||||
'index.html': html,
|
||||
},
|
||||
};
|
||||
|
||||
if (suffix === 'tsx') {
|
||||
stackblitzPrefillConfig.files['tsconfig.json'] = tsconfig;
|
||||
}
|
||||
@ -358,7 +363,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
|
||||
<section className="code-box-meta markdown">
|
||||
<div className="code-box-title">
|
||||
<Tooltip title={meta.debug ? <FormattedMessage id="app.demo.debug" /> : ''}>
|
||||
<a href={`#${meta.id}`} ref={this.saveAnchor}>
|
||||
<a href={`#${meta.id}`} ref={this.anchorRef}>
|
||||
{localizedTitle}
|
||||
</a>
|
||||
</Tooltip>
|
||||
@ -407,24 +412,22 @@ createRoot(document.getElementById('container')).render(<Demo />);
|
||||
<CodeSandboxIcon className="code-box-codesandbox" />
|
||||
</Tooltip>
|
||||
</form>
|
||||
{sourceCode && (
|
||||
<form
|
||||
className="code-box-code-action"
|
||||
action="https://codepen.io/pen/define"
|
||||
method="POST"
|
||||
target="_blank"
|
||||
ref={this.codepenIconRef}
|
||||
onClick={() => {
|
||||
this.track({ type: 'codepen', demo: meta.id });
|
||||
this.codepenIconRef.current.submit();
|
||||
}}
|
||||
>
|
||||
<input type="hidden" name="data" value={JSON.stringify(codepenPrefillConfig)} />
|
||||
<Tooltip title={<FormattedMessage id="app.demo.codepen" />}>
|
||||
<CodePenIcon className="code-box-codepen" />
|
||||
</Tooltip>
|
||||
</form>
|
||||
)}
|
||||
<form
|
||||
className="code-box-code-action"
|
||||
action="https://codepen.io/pen/define"
|
||||
method="POST"
|
||||
target="_blank"
|
||||
ref={this.codepenIconRef}
|
||||
onClick={() => {
|
||||
this.track({ type: 'codepen', demo: meta.id });
|
||||
this.codepenIconRef.current?.submit();
|
||||
}}
|
||||
>
|
||||
<input type="hidden" name="data" value={JSON.stringify(codepenPrefillConfig)} />
|
||||
<Tooltip title={<FormattedMessage id="app.demo.codepen" />}>
|
||||
<CodePenIcon className="code-box-codepen" />
|
||||
</Tooltip>
|
||||
</form>
|
||||
<Tooltip title={<FormattedMessage id="app.demo.stackblitz" />}>
|
||||
<span
|
||||
className="code-box-code-action"
|
||||
@ -440,7 +443,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
|
||||
</Tooltip>
|
||||
<CopyToClipboard text={sourceCodeTyped} onCopy={() => this.handleCodeCopied(meta.id)}>
|
||||
<Tooltip
|
||||
open={copyTooltipOpen}
|
||||
open={copyTooltipOpen as boolean}
|
||||
onOpenChange={this.onCopyTooltipOpenChange}
|
||||
title={<FormattedMessage id={`app.demo.${copied ? 'copied' : 'copy'}`} />}
|
||||
>
|
||||
@ -485,8 +488,8 @@ createRoot(document.getElementById('container')).render(<Demo />);
|
||||
</section>
|
||||
<section className={highlightClass} key="code">
|
||||
<CodePreview
|
||||
toReactComponent={props.utils.toReactComponent}
|
||||
codes={highlightedCodes}
|
||||
toReactComponent={props.utils?.toReactComponent}
|
||||
onCodeTypeChange={(type) => this.setState({ codeType: type })}
|
||||
/>
|
||||
{highlightedStyle ? (
|
@ -9,6 +9,7 @@ import type { TableProps } from 'antd';
|
||||
import { css } from '@emotion/react';
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
import ColorChunk from '../ColorChunk';
|
||||
|
||||
type TokenTableProps = {
|
||||
type: 'seed' | 'map' | 'alias';
|
||||
@ -78,25 +79,15 @@ const TokenTable: FC<TokenTableProps> = ({ type }) => {
|
||||
{
|
||||
title: locale.value,
|
||||
key: 'value',
|
||||
render: (_, record) => (
|
||||
<span style={{ display: 'inline-flex', alignItems: 'center' }}>
|
||||
{typeof record.value === 'string' &&
|
||||
(record.value.startsWith('#') || record.value.startsWith('rgb')) && (
|
||||
<span
|
||||
style={{
|
||||
background: record.value,
|
||||
display: 'inline-block',
|
||||
width: 6,
|
||||
height: 6,
|
||||
borderRadius: '50%',
|
||||
boxShadow: 'inset 0 0 0 1px rgba(0, 0, 0, 0.06)',
|
||||
marginRight: 4,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{typeof record.value !== 'string' ? JSON.stringify(record.value) : record.value}
|
||||
</span>
|
||||
),
|
||||
render: (_, record) => {
|
||||
const isColor =
|
||||
typeof record.value === 'string' &&
|
||||
(record.value.startsWith('#') || record.value.startsWith('rgb'));
|
||||
if (isColor) {
|
||||
return <ColorChunk color={record.value}>{record.value}</ColorChunk>;
|
||||
}
|
||||
return typeof record.value !== 'string' ? JSON.stringify(record.value) : record.value;
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -4,7 +4,7 @@ import Icon from '@ant-design/icons';
|
||||
const ThemeIcon: React.FC<{ className?: string }> = (props) => {
|
||||
const SVGIcon = React.useCallback(
|
||||
() => (
|
||||
<svg width={21} height={21} viewBox="0 0 21 21" fill="currentColor" {...props}>
|
||||
<svg width={20} height={20} viewBox="0 0 24 24" fill="currentColor" {...props}>
|
||||
<g fillRule="evenodd">
|
||||
<g fillRule="nonzero">
|
||||
<path d="M7.02 3.635l12.518 12.518a1.863 1.863 0 010 2.635l-1.317 1.318a1.863 1.863 0 01-2.635 0L3.068 7.588A2.795 2.795 0 117.02 3.635zm2.09 14.428a.932.932 0 110 1.864.932.932 0 010-1.864zm-.043-9.747L7.75 9.635l9.154 9.153 1.318-1.317-9.154-9.155zM3.52 12.473c.514 0 .931.417.931.931v.932h.932a.932.932 0 110 1.864h-.932v.931a.932.932 0 01-1.863 0l-.001-.931h-.93a.932.932 0 010-1.864h.93v-.932c0-.514.418-.931.933-.931zm15.374-3.727a1.398 1.398 0 110 2.795 1.398 1.398 0 010-2.795zM4.385 4.953a.932.932 0 000 1.317l2.046 2.047L7.75 7 5.703 4.953a.932.932 0 00-1.318 0zM14.701.36a.932.932 0 01.931.932v.931h.932a.932.932 0 010 1.864h-.933l.001.932a.932.932 0 11-1.863 0l-.001-.932h-.93a.932.932 0 110-1.864h.93v-.931a.932.932 0 01.933-.932z" />
|
||||
|
@ -1,68 +1,51 @@
|
||||
import React from 'react';
|
||||
import { FloatButton, theme } from 'antd';
|
||||
import { FloatButton } from 'antd';
|
||||
import { FormattedMessage } from 'dumi';
|
||||
import { DarkTheme, Light, CompactTheme } from 'antd-token-previewer/es/icons';
|
||||
import ThemeIcon from './ThemeIcon';
|
||||
|
||||
const { defaultAlgorithm, darkAlgorithm, compactAlgorithm } = theme;
|
||||
export type ThemeName = 'light' | 'dark' | 'compact';
|
||||
|
||||
export type ThemeSwitchProps = {
|
||||
value: typeof defaultAlgorithm[];
|
||||
onChange: (value: typeof defaultAlgorithm[]) => void;
|
||||
value?: ThemeName[];
|
||||
onChange: (value: ThemeName[]) => void;
|
||||
};
|
||||
|
||||
const ThemeSwitch: React.FC<ThemeSwitchProps> = ({ value, onChange }) => {
|
||||
const handleLightSwitch = () => {
|
||||
let newValue = [...value];
|
||||
if (value.includes(darkAlgorithm)) {
|
||||
newValue = newValue.filter((item) => item !== darkAlgorithm);
|
||||
}
|
||||
if (!value.includes(defaultAlgorithm)) {
|
||||
newValue.unshift(defaultAlgorithm);
|
||||
}
|
||||
onChange(newValue);
|
||||
};
|
||||
|
||||
const handleDarkSwitch = () => {
|
||||
let newValue = [...value];
|
||||
if (value.includes(defaultAlgorithm)) {
|
||||
newValue = newValue.filter((item) => item !== defaultAlgorithm);
|
||||
}
|
||||
if (!value.includes(darkAlgorithm)) {
|
||||
newValue.push(darkAlgorithm);
|
||||
}
|
||||
onChange(newValue);
|
||||
};
|
||||
|
||||
const handleCompactSwitch = () => {
|
||||
if (value.includes(compactAlgorithm)) {
|
||||
onChange(value.filter((item) => item !== compactAlgorithm));
|
||||
} else {
|
||||
onChange([...value, compactAlgorithm]);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<FloatButton.Group trigger="click" icon={<ThemeIcon />}>
|
||||
<FloatButton
|
||||
icon={<Light />}
|
||||
type={value.includes(defaultAlgorithm) ? 'primary' : 'default'}
|
||||
onClick={handleLightSwitch}
|
||||
tooltip="Light"
|
||||
/>
|
||||
<FloatButton
|
||||
icon={<DarkTheme />}
|
||||
type={value.includes(darkAlgorithm) ? 'primary' : 'default'}
|
||||
onClick={handleDarkSwitch}
|
||||
tooltip="Dark"
|
||||
/>
|
||||
<FloatButton
|
||||
icon={<CompactTheme />}
|
||||
type={value.includes(compactAlgorithm) ? 'primary' : 'default'}
|
||||
onClick={handleCompactSwitch}
|
||||
tooltip="Compact"
|
||||
/>
|
||||
</FloatButton.Group>
|
||||
);
|
||||
};
|
||||
const ThemeSwitch: React.FC<ThemeSwitchProps> = ({ value, onChange }) => (
|
||||
<FloatButton.Group trigger="click" icon={<ThemeIcon />}>
|
||||
<FloatButton
|
||||
icon={<Light />}
|
||||
type={!value.includes('dark') ? 'primary' : 'default'}
|
||||
onClick={() => {
|
||||
if (value.includes('dark')) {
|
||||
onChange(value.filter((theme) => theme !== 'dark'));
|
||||
}
|
||||
}}
|
||||
tooltip={<FormattedMessage id="app.theme.switch.default" />}
|
||||
/>
|
||||
<FloatButton
|
||||
icon={<DarkTheme />}
|
||||
type={value.includes('dark') ? 'primary' : 'default'}
|
||||
onClick={() => {
|
||||
if (!value.includes('dark')) {
|
||||
onChange([...value, 'dark']);
|
||||
}
|
||||
}}
|
||||
tooltip={<FormattedMessage id="app.theme.switch.dark" />}
|
||||
/>
|
||||
<FloatButton
|
||||
icon={<CompactTheme />}
|
||||
type={value.includes('compact') ? 'primary' : 'default'}
|
||||
onClick={() => {
|
||||
if (value.includes('compact')) {
|
||||
onChange(value.filter((theme) => theme !== 'compact'));
|
||||
} else {
|
||||
onChange([...value, 'compact']);
|
||||
}
|
||||
}}
|
||||
tooltip={<FormattedMessage id="app.theme.switch.compact" />}
|
||||
/>
|
||||
</FloatButton.Group>
|
||||
);
|
||||
|
||||
export default ThemeSwitch;
|
||||
|
62
.dumi/theme/common/styles/BrowserMockup.tsx
Normal file
62
.dumi/theme/common/styles/BrowserMockup.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
|
||||
export default () => (
|
||||
<Global
|
||||
styles={css`
|
||||
/* Browser mockup code
|
||||
* Contribute: https://gist.github.com/jarthod/8719db9fef8deb937f4f
|
||||
* Live example: https://updown.io
|
||||
*/
|
||||
|
||||
.browser-mockup {
|
||||
position: relative;
|
||||
border-top: 2em solid rgba(230, 230, 230, 0.7);
|
||||
border-radius: 3px 3px 0 0;
|
||||
box-shadow: 0 0.1em 0.5em 0 rgba(0, 0, 0, 0.28);
|
||||
}
|
||||
|
||||
.browser-mockup::before {
|
||||
position: absolute;
|
||||
top: -1.25em;
|
||||
left: 1em;
|
||||
display: block;
|
||||
width: 0.5em;
|
||||
height: 0.5em;
|
||||
background-color: #f44;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 0 2px #f44, 1.5em 0 0 2px #9b3, 3em 0 0 2px #fb5;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.browser-mockup.with-tab::after {
|
||||
position: absolute;
|
||||
top: -2em;
|
||||
left: 5.5em;
|
||||
display: block;
|
||||
width: 20%;
|
||||
height: 0;
|
||||
border-right: 0.8em solid transparent;
|
||||
border-bottom: 2em solid white;
|
||||
border-left: 0.8em solid transparent;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.browser-mockup.with-url::after {
|
||||
position: absolute;
|
||||
top: -1.6em;
|
||||
left: 5.5em;
|
||||
display: block;
|
||||
width: ~'calc(100% - 6em)';
|
||||
height: 1.2em;
|
||||
background-color: white;
|
||||
border-radius: 2px;
|
||||
content: '';
|
||||
}
|
||||
|
||||
.browser-mockup > * {
|
||||
display: block;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
60
.dumi/theme/common/styles/Common.tsx
Normal file
60
.dumi/theme/common/styles/Common.tsx
Normal file
@ -0,0 +1,60 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
|
||||
export default () => (
|
||||
<Global
|
||||
styles={css`
|
||||
body,
|
||||
div,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ul,
|
||||
ol,
|
||||
li,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
pre,
|
||||
code,
|
||||
form,
|
||||
fieldset,
|
||||
legend,
|
||||
input,
|
||||
textarea,
|
||||
p,
|
||||
blockquote,
|
||||
th,
|
||||
td,
|
||||
hr,
|
||||
button,
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
375
.dumi/theme/common/styles/Demo.tsx
Normal file
375
.dumi/theme/common/styles/Demo.tsx
Normal file
@ -0,0 +1,375 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
const { antCls, iconCls } = token;
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
.code-boxes-col-1-1 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.code-boxes-col-2-1 {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.code-box {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
margin: 0 0 16px;
|
||||
overflow: hidden;
|
||||
border: 1px solid ${token.colorSplit};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
transition: all 0.2s;
|
||||
|
||||
.code-box-title {
|
||||
&,
|
||||
a {
|
||||
color: ${token.colorText} !important;
|
||||
background: ${token.colorBgContainer};
|
||||
}
|
||||
}
|
||||
|
||||
&,
|
||||
.code-box-demo {
|
||||
background-color: ${token.colorBgContainer};
|
||||
}
|
||||
|
||||
.markdown {
|
||||
pre {
|
||||
margin: 0.5em 0;
|
||||
padding: 6px 12px;
|
||||
}
|
||||
|
||||
pre code {
|
||||
margin: 0;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
&:target {
|
||||
border: 1px solid ${token.colorPrimary};
|
||||
}
|
||||
|
||||
&-expand-trigger {
|
||||
position: relative;
|
||||
margin-left: 12px;
|
||||
color: #3b4357;
|
||||
font-size: 20px;
|
||||
cursor: pointer;
|
||||
opacity: 0.75;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
${antCls}-row-rtl & {
|
||||
margin-right: 8px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
position: absolute;
|
||||
top: -14px;
|
||||
margin-left: 16px;
|
||||
padding: 1px 8px;
|
||||
color: #777;
|
||||
background: ${token.colorBgContainer};
|
||||
border-radius: ${token.borderRadius}px ${token.borderRadius}px 0 0;
|
||||
transition: background-color 0.4s;
|
||||
|
||||
${antCls}-row-rtl & {
|
||||
margin-right: 16px;
|
||||
margin-left: 0;
|
||||
border-radius: ${token.borderRadius}px 0 0 ${token.borderRadius}px;
|
||||
}
|
||||
|
||||
a,
|
||||
a:hover {
|
||||
color: ${token.colorText};
|
||||
font-weight: 500;
|
||||
font-size: ${token.fontSize}px;
|
||||
}
|
||||
}
|
||||
|
||||
&-description {
|
||||
padding: 18px 24px 12px;
|
||||
}
|
||||
|
||||
a.edit-button {
|
||||
position: absolute;
|
||||
top: 7px;
|
||||
right: -16px;
|
||||
padding-right: 6px;
|
||||
font-size: 12px;
|
||||
text-decoration: none;
|
||||
background: inherit;
|
||||
transform: scale(0.9);
|
||||
|
||||
${iconCls} {
|
||||
color: ${token.colorTextSecondary};
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorText};
|
||||
}
|
||||
}
|
||||
|
||||
${antCls}-row${antCls}-row-rtl & {
|
||||
right: auto;
|
||||
left: -22px;
|
||||
margin-right: 0;
|
||||
padding-right: 8px;
|
||||
padding-left: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
&-demo {
|
||||
padding: 42px 24px 50px;
|
||||
color: ${token.colorText};
|
||||
border-bottom: 1px solid ${token.colorSplit};
|
||||
}
|
||||
|
||||
iframe {
|
||||
width: 100%;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
&-meta {
|
||||
&.markdown {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
font-size: ${token.fontSize}px;
|
||||
border-radius: 0 0 ${token.borderRadius}px ${token.borderRadius}px;
|
||||
transition: background-color 0.4s;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
h4,
|
||||
section& p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
> p {
|
||||
width: 100%;
|
||||
margin: 0.5em 0;
|
||||
padding-right: 25px;
|
||||
font-size: 12px;
|
||||
word-break: break-word;
|
||||
|
||||
${antCls}-row-rtl & {
|
||||
padding-right: 0;
|
||||
padding-left: 25px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.expand &-meta {
|
||||
border-bottom: 1px dashed ${token.colorSplit};
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.code-expand-icon {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.code-expand-icon-show,
|
||||
.code-expand-icon-hide {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
transition: all 0.4s;
|
||||
user-select: none;
|
||||
|
||||
${antCls}-row-rtl & {
|
||||
right: 0;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.code-expand-icon-show {
|
||||
opacity: 0.55;
|
||||
pointer-events: auto;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.code-expand-icon${antCls}-tooltip-open .code-expand-icon-show {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.code-expand-icon-hide {
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.highlight-wrapper {
|
||||
display: none;
|
||||
overflow: auto;
|
||||
border-radius: 0 0 ${token.borderRadius}px ${token.borderRadius}px;
|
||||
|
||||
&-expand {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.highlight {
|
||||
position: relative;
|
||||
|
||||
pre {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: ${token.colorBgContainer};
|
||||
}
|
||||
|
||||
&:not(:first-child) {
|
||||
border-top: 1px dashed ${token.colorSplit};
|
||||
}
|
||||
}
|
||||
|
||||
&-actions {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 12px 0;
|
||||
border-top: 1px dashed ${token.colorSplit};
|
||||
opacity: 0.7;
|
||||
transition: opacity 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&-actions &-code-action {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
color: ${token.colorTextSecondary};
|
||||
cursor: pointer;
|
||||
transition: all 0.24s;
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorText};
|
||||
}
|
||||
|
||||
${iconCls} {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&-code-copy {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
background: ${token.colorBgContainer};
|
||||
cursor: pointer;
|
||||
transition: transform 0.24s;
|
||||
|
||||
&${iconCls}-check {
|
||||
color: ${token['green-6']} !important;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
&-codepen {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-riddle {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&-codesandbox {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
overflow: hidden;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.highlight-wrapper:hover &-code-copy,
|
||||
.highlight-wrapper:hover &-codepen,
|
||||
.highlight-wrapper:hover &-codesandbox,
|
||||
.highlight-wrapper:hover &-riddle {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
pre {
|
||||
width: auto;
|
||||
margin: 0;
|
||||
|
||||
code {
|
||||
background: ${token.colorBgContainer};
|
||||
border: none;
|
||||
box-shadow: unset;
|
||||
}
|
||||
}
|
||||
|
||||
&-debug {
|
||||
border-color: ${token['purple-3']};
|
||||
}
|
||||
|
||||
&-debug &-title a {
|
||||
color: ${token['purple-6']};
|
||||
}
|
||||
}
|
||||
|
||||
.demo-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.all-code-box-controls {
|
||||
position: absolute;
|
||||
top: -32px;
|
||||
inset-inline-end: 0;
|
||||
}
|
||||
|
||||
${antCls}-row-rtl {
|
||||
#components-tooltip-demo-placement,
|
||||
#components-popover-demo-placement,
|
||||
#components-popconfirm-demo-placement {
|
||||
.code-box-demo {
|
||||
direction: ltr;
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
43
.dumi/theme/common/styles/HeadingAnchor.tsx
Normal file
43
.dumi/theme/common/styles/HeadingAnchor.tsx
Normal file
@ -0,0 +1,43 @@
|
||||
import React from 'react';
|
||||
import { css, Global } from '@emotion/react';
|
||||
|
||||
export default () => (
|
||||
<Global
|
||||
styles={css`
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
> a[aria-hidden]:first-child {
|
||||
float: left;
|
||||
width: 20px;
|
||||
padding-inline-end: 4px;
|
||||
margin-inline-start: -24px;
|
||||
// hide phantom blank node
|
||||
font-size: 0;
|
||||
text-align: right;
|
||||
line-height: inherit;
|
||||
|
||||
[data-direction='rtl'] & {
|
||||
float: right;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
> .icon-link::before {
|
||||
content: '#';
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(:hover) > a[aria-hidden]:first-child > .icon-link {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
157
.dumi/theme/common/styles/Highlight.tsx
Normal file
157
.dumi/theme/common/styles/Highlight.tsx
Normal file
@ -0,0 +1,157 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
/**
|
||||
* prism.js default theme for JavaScript, CSS and HTML
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
padding: 16px 32px;
|
||||
color: ${token.colorText};
|
||||
font-size: ${token.fontSize}px;
|
||||
font-family: 'Lucida Console', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
line-height: 2;
|
||||
white-space: pre;
|
||||
background: white;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-radius: ${token.borderRadius}px;
|
||||
}
|
||||
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
color: black;
|
||||
font-family: 'Lucida Console', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
|
||||
line-height: 1.5;
|
||||
direction: ltr;
|
||||
white-space: pre;
|
||||
text-align: left;
|
||||
word-wrap: normal;
|
||||
word-break: normal;
|
||||
word-spacing: normal;
|
||||
tab-size: 4;
|
||||
hyphens: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
code[class*='css'] {
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
pre[class*='language-'] ::selection,
|
||||
code[class*='language-'] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*='language-'] {
|
||||
margin: 16px 0;
|
||||
padding: 12px 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*='language-'] {
|
||||
padding: 0.1em;
|
||||
white-space: normal;
|
||||
border-radius: 0.3em;
|
||||
}
|
||||
|
||||
.token.comment,
|
||||
.token.prolog,
|
||||
.token.doctype,
|
||||
.token.cdata {
|
||||
color: slategray;
|
||||
}
|
||||
|
||||
.token.punctuation {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.markdown {
|
||||
.token.property,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.number,
|
||||
.token.constant,
|
||||
.token.symbol,
|
||||
.token.deleted {
|
||||
color: #f81d22;
|
||||
}
|
||||
|
||||
.token.selector,
|
||||
.token.attr-name,
|
||||
.token.string,
|
||||
.token.char,
|
||||
.token.builtin,
|
||||
.token.inserted {
|
||||
color: #0b8235;
|
||||
}
|
||||
|
||||
.token.operator,
|
||||
.token.entity,
|
||||
.token.url,
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #0b8235;
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.attr-value,
|
||||
.token.keyword {
|
||||
color: #008dff;
|
||||
}
|
||||
|
||||
.token.function {
|
||||
color: #f81d22;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
.token.important,
|
||||
.token.variable {
|
||||
color: #e90;
|
||||
}
|
||||
|
||||
.token.important,
|
||||
.token.bold {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.token.entity {
|
||||
cursor: help;
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
111
.dumi/theme/common/styles/Icon.tsx
Normal file
111
.dumi/theme/common/styles/Icon.tsx
Normal file
@ -0,0 +1,111 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
const { antCls, iconCls } = token;
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
ul.anticons-list {
|
||||
margin: 10px 0;
|
||||
overflow: hidden;
|
||||
direction: ltr;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 16.66%;
|
||||
height: 100px;
|
||||
margin: 3px 0;
|
||||
padding: 10px 0 0;
|
||||
overflow: hidden;
|
||||
color: #555;
|
||||
text-align: center;
|
||||
list-style: none;
|
||||
background-color: inherit;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out;
|
||||
|
||||
.rtl & {
|
||||
margin: 3px 0;
|
||||
padding: 10px 0 0;
|
||||
}
|
||||
|
||||
${iconCls} {
|
||||
margin: 12px 0 8px;
|
||||
font-size: 36px;
|
||||
transition: transform 0.3s ease-in-out;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.anticon-class {
|
||||
display: block;
|
||||
font-family: 'Lucida Console', Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono',
|
||||
monospace;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
transform: scale(0.83);
|
||||
|
||||
${antCls}-badge {
|
||||
transition: color 0.3s ease-in-out;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #fff;
|
||||
background-color: ${token.colorPrimary};
|
||||
|
||||
${iconCls} {
|
||||
transform: scale(1.4);
|
||||
}
|
||||
|
||||
${antCls}-badge {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
&.TwoTone:hover {
|
||||
background-color: #8ecafe;
|
||||
}
|
||||
|
||||
&.copied:hover {
|
||||
color: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
background: #1677ff;
|
||||
line-height: 110px;
|
||||
text-align: center;
|
||||
opacity: 0;
|
||||
transition: all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
|
||||
content: 'Copied!';
|
||||
}
|
||||
|
||||
&.copied::after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.copied-code {
|
||||
padding: 2px 4px;
|
||||
font-size: 12px;
|
||||
background: #f5f5f5;
|
||||
border-radius: 2px;
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
72
.dumi/theme/common/styles/IconPickSearcher.tsx
Normal file
72
.dumi/theme/common/styles/IconPickSearcher.tsx
Normal file
@ -0,0 +1,72 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
const { iconCls } = token;
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
.icon-pic-searcher {
|
||||
display: inline-block;
|
||||
margin: 0 8px;
|
||||
|
||||
.icon-pic-btn {
|
||||
color: ${token.colorIcon};
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorIconHover};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-pic-preview {
|
||||
width: 66px;
|
||||
height: 66px;
|
||||
margin-top: 10px;
|
||||
padding: 8px;
|
||||
text-align: center;
|
||||
border: 1px solid ${token.colorBorder};
|
||||
border-radius: 4px;
|
||||
|
||||
> img {
|
||||
max-width: 50px;
|
||||
max-height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-pic-search-result {
|
||||
min-height: 50px;
|
||||
padding: 0 10px;
|
||||
|
||||
> .result-tip {
|
||||
padding: 10px 0;
|
||||
color: ${token.colorTextSecondary};
|
||||
}
|
||||
|
||||
> table {
|
||||
width: 100%;
|
||||
|
||||
.col-icon {
|
||||
width: 80px;
|
||||
padding: 10px 0;
|
||||
|
||||
> ${iconCls} {
|
||||
font-size: 30px;
|
||||
|
||||
:hover {
|
||||
color: ${token.colorLinkHover};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
568
.dumi/theme/common/styles/Markdown.tsx
Normal file
568
.dumi/theme/common/styles/Markdown.tsx
Normal file
@ -0,0 +1,568 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
const { antCls } = token;
|
||||
|
||||
const demoGridColor = token.colorPrimary;
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
.markdown {
|
||||
color: ${token.colorText};
|
||||
font-size: 14px;
|
||||
line-height: 2;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
max-width: calc(100% - 32px);
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.markdown p > img {
|
||||
margin: 34px 0;
|
||||
box-shadow: 0 8px 20px rgba(143, 168, 191, 0.35);
|
||||
}
|
||||
|
||||
.markdown p > img.markdown-inline-image {
|
||||
margin: 0;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
margin-top: 8px;
|
||||
margin-bottom: 20px;
|
||||
color: ${token.colorTextHeading};
|
||||
font-weight: 500;
|
||||
font-size: 30px;
|
||||
font-family: Avenir, ${token.fontFamily}, sans-serif;
|
||||
line-height: 38px;
|
||||
|
||||
.subtitle {
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 24px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
clear: both;
|
||||
margin: 1.6em 0 0.6em;
|
||||
color: ${token.colorTextHeading};
|
||||
font-weight: 500;
|
||||
font-family: Avenir, ${token.fontFamily}, sans-serif;
|
||||
}
|
||||
|
||||
.markdown h3 {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.markdown h4 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.markdown h5 {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.markdown h6 {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
clear: both;
|
||||
height: 1px;
|
||||
margin: 24px 0;
|
||||
background: ${token.colorSplit};
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.markdown p,
|
||||
.markdown pre {
|
||||
margin: 1em 0;
|
||||
|
||||
${antCls}-row-rtl & {
|
||||
direction: rtl;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown ul > li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
list-style-type: circle;
|
||||
|
||||
.rtl & {
|
||||
margin-right: 20px;
|
||||
margin-left: 0;
|
||||
padding-right: 4px;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown ol > li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
list-style-type: decimal;
|
||||
|
||||
${antCls}-row-rtl & {
|
||||
margin-right: 20px;
|
||||
margin-left: 0;
|
||||
padding-right: 4px;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown ul > li > p,
|
||||
.markdown ol > li > p {
|
||||
margin: 0.2em 0;
|
||||
}
|
||||
|
||||
.markdown code {
|
||||
margin: 0 1px;
|
||||
padding: 0.2em 0.4em;
|
||||
font-size: 0.9em;
|
||||
background: ${token.siteMarkdownCodeBg};
|
||||
border: 1px solid ${token.colorSplit};
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.markdown pre {
|
||||
font-family: ${token.codeFamily};
|
||||
background: ${token.siteMarkdownCodeBg};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
}
|
||||
|
||||
.markdown pre code {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
color: ${token.colorText};
|
||||
font-size: ${Math.max(token.fontSize - 1, 12)}px;
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
background: #f5f5f5;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.markdown strong,
|
||||
.markdown b {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.markdown .dumi-default-source-code {
|
||||
margin: 1em 0;
|
||||
background-color: ${token.siteMarkdownCodeBg};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
> pre.prism-code {
|
||||
padding: 12px 20px;
|
||||
font-size: 13px;
|
||||
line-height: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown .dumi-default-table-content > table,
|
||||
.markdown > table {
|
||||
width: 100%;
|
||||
margin: 8px 0 16px;
|
||||
direction: ltr;
|
||||
empty-cells: show;
|
||||
border: 1px solid ${token.colorSplit};
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
.markdown .dumi-default-table-content,
|
||||
.markdown {
|
||||
> table th {
|
||||
color: #5c6b77;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
background: rgba(0, 0, 0, 0.02);
|
||||
}
|
||||
}
|
||||
|
||||
.markdown .dumi-default-table-content,
|
||||
.markdown {
|
||||
> table th,
|
||||
> table td {
|
||||
padding: 16px 24px;
|
||||
text-align: left;
|
||||
border: 1px solid ${token.colorSplit};
|
||||
}
|
||||
}
|
||||
|
||||
.markdown table td > a:not(:last-child) {
|
||||
margin-right: 0 !important;
|
||||
|
||||
&::after {
|
||||
position: relative !important;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
margin: 1em 0;
|
||||
padding-left: 0.8em;
|
||||
color: ${token.colorTextSecondary};
|
||||
font-size: 90%;
|
||||
border-left: 4px solid ${token.colorSplit};
|
||||
|
||||
.rtl & {
|
||||
padding-right: 0.8em;
|
||||
padding-left: 0;
|
||||
border-right: 4px solid ${token.colorSplit};
|
||||
border-left: none;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.markdown .anchor {
|
||||
margin-left: 8px;
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s;
|
||||
|
||||
.rtl & {
|
||||
margin-right: 8px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.markdown .waiting {
|
||||
color: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.markdown a.edit-button {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
text-decoration: none;
|
||||
|
||||
.rtl & {
|
||||
margin-right: 8px;
|
||||
margin-left: 0;
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
${antCls}icon {
|
||||
display: block;
|
||||
color: ${token.colorTextSecondary};
|
||||
font-size: 16px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
color: ${token.colorText};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.markdown h1:hover .anchor,
|
||||
.markdown h2:hover .anchor,
|
||||
.markdown h3:hover .anchor,
|
||||
.markdown h4:hover .anchor,
|
||||
.markdown h5:hover .anchor,
|
||||
.markdown h6:hover .anchor {
|
||||
display: inline-block;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.markdown > br,
|
||||
.markdown > p > br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.markdown .dumi-default-table {
|
||||
.component-api-table {
|
||||
display: block;
|
||||
|
||||
td {
|
||||
&:first-child {
|
||||
width: 18%;
|
||||
color: #595959;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 55%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 22%;
|
||||
color: ${token['magenta-7']};
|
||||
font-size: ${Math.max(token.fontSize - 1, 12)}px;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
font-size: ${Math.max(token.fontSize - 1, 12)}px;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 8%;
|
||||
font-size: ${Math.max(token.fontSize - 1, 12)}px;
|
||||
}
|
||||
|
||||
&:nth-last-child(3):first-child {
|
||||
width: 38%;
|
||||
}
|
||||
|
||||
&:nth-last-child(3):first-child ~ td:nth-last-child(2) {
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.markdown .dumi-default-table {
|
||||
table {
|
||||
margin: 0;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
font-size: ${Math.max(token.fontSize - 1, 12)}px;
|
||||
font-family: ${token.codeFamily};
|
||||
line-height: ${token.lineHeight};
|
||||
border: 0;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 12px;
|
||||
border-color: ${token.colorSplit};
|
||||
border-width: 1px 0;
|
||||
|
||||
&:first-child {
|
||||
border-left: 1px solid ${token.colorSplit};
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-right: 1px solid ${token.colorSplit};
|
||||
}
|
||||
}
|
||||
|
||||
th {
|
||||
padding-top: 14px;
|
||||
border-width: 1px 0 2px;
|
||||
}
|
||||
|
||||
tbody tr {
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
background: rgba(60, 90, 100, 0.04);
|
||||
}
|
||||
}
|
||||
|
||||
td {
|
||||
&:first-child {
|
||||
min-width: 58px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
margin: 12px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-demo,
|
||||
[id^='components-grid-demo-'] {
|
||||
.demo-row,
|
||||
.code-box-demo .demo-row {
|
||||
margin-bottom: 8px;
|
||||
overflow: hidden;
|
||||
background-image: linear-gradient(
|
||||
90deg,
|
||||
#f5f5f5 4.16666667%,
|
||||
transparent 4.16666667%,
|
||||
transparent 8.33333333%,
|
||||
#f5f5f5 8.33333333%,
|
||||
#f5f5f5 12.5%,
|
||||
transparent 12.5%,
|
||||
transparent 16.66666667%,
|
||||
#f5f5f5 16.66666667%,
|
||||
#f5f5f5 20.83333333%,
|
||||
transparent 20.83333333%,
|
||||
transparent 25%,
|
||||
#f5f5f5 25%,
|
||||
#f5f5f5 29.16666667%,
|
||||
transparent 29.16666667%,
|
||||
transparent 33.33333333%,
|
||||
#f5f5f5 33.33333333%,
|
||||
#f5f5f5 37.5%,
|
||||
transparent 37.5%,
|
||||
transparent 41.66666667%,
|
||||
#f5f5f5 41.66666667%,
|
||||
#f5f5f5 45.83333333%,
|
||||
transparent 45.83333333%,
|
||||
transparent 50%,
|
||||
#f5f5f5 50%,
|
||||
#f5f5f5 54.16666667%,
|
||||
transparent 54.16666667%,
|
||||
transparent 58.33333333%,
|
||||
#f5f5f5 58.33333333%,
|
||||
#f5f5f5 62.5%,
|
||||
transparent 62.5%,
|
||||
transparent 66.66666667%,
|
||||
#f5f5f5 66.66666667%,
|
||||
#f5f5f5 70.83333333%,
|
||||
transparent 70.83333333%,
|
||||
transparent 75%,
|
||||
#f5f5f5 75%,
|
||||
#f5f5f5 79.16666667%,
|
||||
transparent 79.16666667%,
|
||||
transparent 83.33333333%,
|
||||
#f5f5f5 83.33333333%,
|
||||
#f5f5f5 87.5%,
|
||||
transparent 87.5%,
|
||||
transparent 91.66666667%,
|
||||
#f5f5f5 91.66666667%,
|
||||
#f5f5f5 95.83333333%,
|
||||
transparent 95.83333333%
|
||||
);
|
||||
}
|
||||
|
||||
${antCls}-row > div,
|
||||
.code-box-demo ${antCls}-row > div {
|
||||
min-height: 30px;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.code-box-demo ${antCls}-row > div:not(.gutter-row) {
|
||||
padding: 16px 0;
|
||||
background: ${demoGridColor};
|
||||
|
||||
&:nth-child(2n + 1) {
|
||||
background: ${new TinyColor(demoGridColor).setAlpha(0.75).toHex8String()};
|
||||
}
|
||||
}
|
||||
|
||||
${antCls}-row .demo-col,
|
||||
.code-box-demo ${antCls}-row .demo-col {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
padding: 30px 0;
|
||||
color: ${token.colorWhite};
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
border: none;
|
||||
}
|
||||
|
||||
${antCls}-row .demo-col-1 {
|
||||
background: ${new TinyColor(demoGridColor).setAlpha(0.75).toHexString()};
|
||||
}
|
||||
|
||||
${antCls}-row .demo-col-2,
|
||||
.code-box-demo ${antCls}-row .demo-col-2 {
|
||||
background: ${new TinyColor(demoGridColor).setAlpha(0.75).toHexString()};
|
||||
}
|
||||
|
||||
${antCls}-row .demo-col-3,
|
||||
.code-box-demo ${antCls}-row .demo-col-3 {
|
||||
color: #999;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
${antCls}-row .demo-col-4,
|
||||
.code-box-demo ${antCls}-row .demo-col-4 {
|
||||
background: ${new TinyColor(demoGridColor).setAlpha(0.6).toHexString()};
|
||||
}
|
||||
|
||||
${antCls}-row .demo-col-5,
|
||||
.code-box-demo ${antCls}-row .demo-col-5 {
|
||||
color: #999;
|
||||
background: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.code-box-demo .height-100 {
|
||||
height: 100px;
|
||||
line-height: 100px;
|
||||
}
|
||||
|
||||
.code-box-demo .height-50 {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
.code-box-demo .height-120 {
|
||||
height: 120px;
|
||||
line-height: 120px;
|
||||
}
|
||||
|
||||
.code-box-demo .height-80 {
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
[id='components-grid-demo-playground'],
|
||||
[id='components-grid-demo-gutter'] {
|
||||
> .code-box-demo ${antCls}-row > div {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// For Changelog
|
||||
.markdown ul${antCls}-timeline {
|
||||
line-height: 2;
|
||||
|
||||
li${antCls}-timeline-item {
|
||||
margin: 0;
|
||||
padding: 0 0 30px;
|
||||
list-style: none;
|
||||
|
||||
${antCls}-timeline-item-content {
|
||||
position: relative;
|
||||
top: -14px;
|
||||
padding-left: 32px;
|
||||
font-size: 14px;
|
||||
|
||||
> h2 {
|
||||
margin-top: 0;
|
||||
padding-top: 4px;
|
||||
direction: ltr;
|
||||
|
||||
span {
|
||||
${antCls}-row-rtl & {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li${antCls}-timeline-item:first-child {
|
||||
margin-top: 40px;
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
27
.dumi/theme/common/styles/NProgress.tsx
Normal file
27
.dumi/theme/common/styles/NProgress.tsx
Normal file
@ -0,0 +1,27 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
#nprogress {
|
||||
.bar {
|
||||
background: ${token.colorPrimary};
|
||||
}
|
||||
|
||||
.peg {
|
||||
box-shadow: 0 0 10px ${token.colorPrimary}, 0 0 5px ${token.colorPrimary};
|
||||
}
|
||||
|
||||
.spinner-icon {
|
||||
border-top-color: ${token.colorPrimary};
|
||||
border-left-color: ${token.colorPrimary};
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
244
.dumi/theme/common/styles/PreviewImage.tsx
Normal file
244
.dumi/theme/common/styles/PreviewImage.tsx
Normal file
@ -0,0 +1,244 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
.preview-image-boxes {
|
||||
display: flex;
|
||||
float: right;
|
||||
clear: both;
|
||||
width: 496px;
|
||||
margin: 0 0 70px 64px;
|
||||
|
||||
&-with-carousel {
|
||||
width: 420px;
|
||||
|
||||
.preview-image-box img {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-row-rtl & {
|
||||
float: left;
|
||||
margin: 0 64px 70px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-image-boxes + .preview-image-boxes {
|
||||
margin-top: -35px;
|
||||
}
|
||||
|
||||
.preview-image-box {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.preview-image-box + .preview-image-box {
|
||||
margin-left: 24px;
|
||||
|
||||
.ant-row-rtl & {
|
||||
margin-right: 24px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-image-wrapper {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
text-align: center;
|
||||
background: #f2f4f5;
|
||||
}
|
||||
|
||||
.preview-image-wrapper.video {
|
||||
display: block;
|
||||
padding: 0;
|
||||
background: 0;
|
||||
}
|
||||
|
||||
.preview-image-wrapper video {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
||||
+ svg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-image-wrapper.good::after {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background: ${token.colorPrimary};
|
||||
content: '';
|
||||
}
|
||||
|
||||
.preview-image-wrapper.bad::after {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
background: ${token.colorError};
|
||||
content: '';
|
||||
}
|
||||
|
||||
.preview-image-title {
|
||||
margin-top: 20px;
|
||||
color: ${token.colorText};
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.preview-image-description {
|
||||
margin-top: 2px;
|
||||
color: ${token.colorTextSecondary};
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.preview-image-description hr {
|
||||
margin: 2px 0;
|
||||
background: none;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.preview-image-box img {
|
||||
max-width: 100%;
|
||||
padding: 12px;
|
||||
background: ${token.colorBgContainer};
|
||||
border-radius: ${token.borderRadius}px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
&.no-padding {
|
||||
padding: 0;
|
||||
background: none;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-image-boxes.preview-image-boxes-with-carousel img {
|
||||
padding: 0;
|
||||
box-shadow: 0 1px 0 0 #ddd, 0 3px 0 0 ${token.colorBgContainer}, 0 4px 0 0 #ddd,
|
||||
0 6px 0 0 ${token.colorBgContainer}, 0 7px 0 0 #ddd;
|
||||
}
|
||||
|
||||
.preview-image-box img:hover {
|
||||
box-shadow: 1px 1px 6px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.preview-img {
|
||||
float: right;
|
||||
clear: both;
|
||||
max-width: 496px !important;
|
||||
margin: 0 0 70px 64px;
|
||||
padding: 16px;
|
||||
background-color: #f2f4f5;
|
||||
}
|
||||
|
||||
.image-modal {
|
||||
text-align: center;
|
||||
|
||||
&-container {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ant-carousel {
|
||||
.slick-slider {
|
||||
padding-bottom: 24px;
|
||||
|
||||
img {
|
||||
display: inline;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.slick-dots {
|
||||
bottom: 4px;
|
||||
|
||||
li button {
|
||||
background: #888;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.image-modal-single.slick-slider {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.image-modal-single .slick-dots {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.transition-video-player,
|
||||
.motion-video-min {
|
||||
float: right;
|
||||
width: 600px;
|
||||
padding: 0 0 70px 20px;
|
||||
|
||||
.preview-image-wrapper {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ant-row-rtl & {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
.motion-video-min {
|
||||
width: 390px;
|
||||
}
|
||||
|
||||
.motion-principle-wrapper {
|
||||
width: 100%;
|
||||
max-width: 900px;
|
||||
margin: 48px 0 24px;
|
||||
}
|
||||
|
||||
.principle-wrapper {
|
||||
width: 100%;
|
||||
|
||||
.principle {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
min-height: 180px;
|
||||
margin-right: 12.5%;
|
||||
margin-bottom: 24px;
|
||||
padding: 24px;
|
||||
font-size: 24px;
|
||||
text-align: center;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 4px;
|
||||
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
h4 {
|
||||
margin: 16px 0 8px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
63
.dumi/theme/common/styles/Reset.tsx
Normal file
63
.dumi/theme/common/styles/Reset.tsx
Normal file
@ -0,0 +1,63 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
@font-face {
|
||||
font-weight: normal;
|
||||
font-family: PuHuiTi;
|
||||
src: url('//at.alicdn.com/t/webfont_6e11e43nfj.woff2') format('woff2'),
|
||||
url('//at.alicdn.com/t/webfont_6e11e43nfj.woff') format('woff'),
|
||||
/* chrome、firefox */ url('//at.alicdn.com/t/webfont_6e11e43nfj.ttf')
|
||||
format('truetype'); /* chrome、firefox、opera、Safari, Android, iOS 4.2+ */
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-weight: bold;
|
||||
font-family: PuHuiTi;
|
||||
src: url('//at.alicdn.com/t/webfont_exesdog9toj.woff2') format('woff2'),
|
||||
url('//at.alicdn.com/t/webfont_exesdog9toj.woff') format('woff'),
|
||||
/* chrome、firefox */ url('//at.alicdn.com/t/webfont_exesdog9toj.ttf')
|
||||
format('truetype'); /* chrome、firefox、opera、Safari, Android, iOS 4.2+ */
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
// 组件丰富,选用自如定制主题随心所欲设计语言与研发框架1234567890 QWERTYUIOPLKJHGFDSAZXCVBNM,.mnbvcxzasdfghjklpoiuytrewq
|
||||
/* CDN 服务仅供平台体验和调试使用,平台不承诺服务的稳定性,企业客户需下载字体包自行发布使用并做好备份。 */
|
||||
@font-face {
|
||||
font-weight: 900;
|
||||
font-family: 'AliPuHui';
|
||||
src: url('//at.alicdn.com/wf/webfont/exMpJIukiCms/Gsw2PSKrftc1yNWMNlXgw.woff2')
|
||||
format('woff2'),
|
||||
url('//at.alicdn.com/wf/webfont/exMpJIukiCms/vtu73by4O2gEBcvBuLgeu.woff')
|
||||
format('woff');
|
||||
font-display: swap;
|
||||
}
|
||||
|
||||
html {
|
||||
direction: initial;
|
||||
|
||||
&.rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
overflow-x: hidden;
|
||||
color: ${token.colorText};
|
||||
font-size: ${token.fontSize}px;
|
||||
font-family: ${token.fontFamily};
|
||||
line-height: ${token.lineHeight};
|
||||
background: ${token.colorBgContainer};
|
||||
transition: background 1s cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
341
.dumi/theme/common/styles/Responsive.tsx
Normal file
341
.dumi/theme/common/styles/Responsive.tsx
Normal file
@ -0,0 +1,341 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import useSiteToken from '../../../hooks/useSiteToken';
|
||||
|
||||
export default () => {
|
||||
const { token } = useSiteToken();
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
.nav-phone-icon {
|
||||
position: absolute;
|
||||
top: 25px;
|
||||
right: 30px;
|
||||
z-index: 1;
|
||||
display: none;
|
||||
width: 16px;
|
||||
height: 22px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: ${token.screenLG}px) {
|
||||
.code-boxes-col-2-1,
|
||||
.code-boxes-col-1-1 {
|
||||
float: none;
|
||||
width: 100%;
|
||||
max-width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 767.99px) {
|
||||
.preview-image-boxes {
|
||||
float: none;
|
||||
width: 100%;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.preview-image-box {
|
||||
width: 100%;
|
||||
margin: 10px 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.image-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.version {
|
||||
display: block;
|
||||
margin: 29px auto 16px;
|
||||
}
|
||||
|
||||
.toc {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nav-phone-icon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.main {
|
||||
height: calc(100% - 86px);
|
||||
}
|
||||
|
||||
.aside-container {
|
||||
float: none;
|
||||
width: auto;
|
||||
padding-bottom: 30px;
|
||||
border-right: 0;
|
||||
}
|
||||
|
||||
.ant-row-rtl {
|
||||
margin-right: 0;
|
||||
margin-left: 0;
|
||||
padding-right: 16px;
|
||||
padding-left: 16px;
|
||||
|
||||
> .markdown > * {
|
||||
width: 100% !important;
|
||||
}
|
||||
}
|
||||
|
||||
.main-wrapper {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.prev-next-nav {
|
||||
width: ~'calc(100% - 32px)';
|
||||
margin-left: 16px;
|
||||
|
||||
.ant-row-rtl & {
|
||||
margin-right: 16px;
|
||||
margin-left: 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.drawer {
|
||||
.ant-menu-inline .ant-menu-item::after,
|
||||
.ant-menu-vertical .ant-menu-item::after {
|
||||
right: auto;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** home 区块 **/
|
||||
.home-page-wrapper {
|
||||
.page {
|
||||
h2 {
|
||||
margin: 80px auto 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.parallax-bg {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.banner {
|
||||
display: block;
|
||||
height: 632px;
|
||||
|
||||
&-bg-wrapper {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.img-wrapper,
|
||||
.text-wrapper {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
min-width: unset;
|
||||
max-width: unset;
|
||||
margin: auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.img-wrapper {
|
||||
position: initial;
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
|
||||
svg {
|
||||
width: 100%;
|
||||
max-width: 260px;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.text-wrapper {
|
||||
min-height: 200px;
|
||||
margin-top: 32px;
|
||||
padding: 0;
|
||||
|
||||
h1 {
|
||||
display: none;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #314659;
|
||||
font-size: 14px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.banner-btns {
|
||||
display: block;
|
||||
min-width: 100%;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
|
||||
.banner-btn {
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.banner-promote {
|
||||
min-width: 100%;
|
||||
margin-top: 32px;
|
||||
|
||||
.ant-divider {
|
||||
display: none;
|
||||
}
|
||||
|
||||
a {
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
|
||||
img {
|
||||
width: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page1 {
|
||||
min-height: 1300px;
|
||||
|
||||
.ant-row {
|
||||
margin: 24px auto 64px;
|
||||
|
||||
> div {
|
||||
margin-bottom: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page2 {
|
||||
min-height: 840px;
|
||||
background: ${token.colorBgContainer};
|
||||
|
||||
&-content {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
&-components {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-product {
|
||||
min-height: auto;
|
||||
padding: 0 16px;
|
||||
|
||||
.product-block {
|
||||
margin-bottom: 34px;
|
||||
padding-bottom: 35px;
|
||||
border-bottom: 1px solid ${token.colorSplit};
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 32px;
|
||||
border-bottom: none;
|
||||
|
||||
.block-text-wrapper {
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.block-image-wrapper {
|
||||
height: 88px;
|
||||
|
||||
img {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.block-text-wrapper {
|
||||
padding-bottom: 0;
|
||||
border-bottom: none;
|
||||
|
||||
h4 {
|
||||
margin-bottom: 4px;
|
||||
font-size: 18px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
a {
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.components-button-wrapper {
|
||||
margin-top: 16px;
|
||||
font-size: 12px;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
a.more-mobile-react,
|
||||
a.more-mobile-angular {
|
||||
margin-top: 0;
|
||||
color: ${token.colorLink};
|
||||
}
|
||||
|
||||
a.more-mobile-react:hover,
|
||||
a.more-mobile-angular:hover {
|
||||
color: #40a9ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page3 {
|
||||
min-height: 688px;
|
||||
background: url('https://gw.alipayobjects.com/zos/rmsportal/qICoJIqqQRMeRGhPHBBS.svg')
|
||||
no-repeat;
|
||||
background-size: cover;
|
||||
|
||||
.ant-row {
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.page3-block {
|
||||
margin-bottom: 32px;
|
||||
padding: 24px;
|
||||
background: ${token.colorBgContainer};
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 8px 16px rgba(174, 185, 193, 0.3);
|
||||
|
||||
&:nth-child(2) {
|
||||
.page3-img-wrapper img {
|
||||
display: block;
|
||||
width: 70%;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.page3-img-wrapper {
|
||||
width: 20%;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.page3-text-wrapper {
|
||||
width: 80%;
|
||||
max-width: initial;
|
||||
margin: 0;
|
||||
padding-left: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
12
.dumi/theme/common/styles/index.ts
Normal file
12
.dumi/theme/common/styles/index.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export { default as HeadingAnchor } from './HeadingAnchor';
|
||||
export { default as Reset } from './Reset';
|
||||
export { default as Common } from './Common';
|
||||
export { default as Markdown } from './Markdown';
|
||||
export { default as Highlight } from './Highlight';
|
||||
export { default as Demo } from './Demo';
|
||||
export { default as Icon } from './Icon';
|
||||
export { default as IconPickSearcher } from './IconPickSearcher';
|
||||
export { default as BrowserMockup } from './BrowserMockup';
|
||||
export { default as Responsive } from './Responsive';
|
||||
export { default as NProgress } from './NProgress';
|
||||
export { default as PreviewImage } from './PreviewImage';
|
@ -1,9 +1,9 @@
|
||||
import React, { startTransition, useLayoutEffect } from 'react';
|
||||
import { useOutlet } from 'dumi';
|
||||
import React from 'react';
|
||||
import { useOutlet, useSearchParams } from 'dumi';
|
||||
import { ConfigProvider, theme as antdTheme } from 'antd';
|
||||
import type { ThemeConfig } from 'antd/es/config-provider/context';
|
||||
import { createCache, StyleProvider } from '@ant-design/cssinjs';
|
||||
import ThemeSwitch from '../common/ThemeSwitch';
|
||||
import type { ThemeName } from '../common/ThemeSwitch';
|
||||
import useLocation from '../../hooks/useLocation';
|
||||
|
||||
const styleCache = createCache();
|
||||
@ -11,77 +11,39 @@ if (typeof global !== 'undefined') {
|
||||
(global as any).styleCache = styleCache;
|
||||
}
|
||||
|
||||
const ANT_DESIGN_SITE_THEME = 'antd-site-theme';
|
||||
|
||||
const getAlgorithm = (theme: string) => {
|
||||
if (theme === 'dark') {
|
||||
return antdTheme.darkAlgorithm;
|
||||
}
|
||||
if (theme === 'compact') {
|
||||
return antdTheme.compactAlgorithm;
|
||||
}
|
||||
return antdTheme.defaultAlgorithm;
|
||||
};
|
||||
|
||||
const getThemeString = (algorithm: typeof antdTheme.defaultAlgorithm) => {
|
||||
if (algorithm === antdTheme.darkAlgorithm) {
|
||||
return 'dark';
|
||||
}
|
||||
if (algorithm === antdTheme.compactAlgorithm) {
|
||||
return 'compact';
|
||||
}
|
||||
return 'light';
|
||||
};
|
||||
const getAlgorithm = (themes: ThemeName[]) =>
|
||||
(themes || []).map((theme) => {
|
||||
if (theme === 'dark') {
|
||||
return antdTheme.darkAlgorithm;
|
||||
}
|
||||
if (theme === 'compact') {
|
||||
return antdTheme.compactAlgorithm;
|
||||
}
|
||||
return antdTheme.defaultAlgorithm;
|
||||
});
|
||||
|
||||
const GlobalLayout: React.FC = () => {
|
||||
const outlet = useOutlet();
|
||||
const { pathname } = useLocation();
|
||||
|
||||
const [theme, setTheme] = React.useState<ThemeConfig>({
|
||||
algorithm: [antdTheme.defaultAlgorithm],
|
||||
});
|
||||
|
||||
const handleThemeChange = (newTheme: ThemeConfig, ignoreAlgorithm: boolean = true) => {
|
||||
const nextTheme = { ...newTheme };
|
||||
if (ignoreAlgorithm) {
|
||||
nextTheme.algorithm = theme.algorithm;
|
||||
}
|
||||
setTheme(nextTheme);
|
||||
localStorage.setItem(
|
||||
ANT_DESIGN_SITE_THEME,
|
||||
JSON.stringify(nextTheme, (key, value) => {
|
||||
if (key === 'algorithm') {
|
||||
return Array.isArray(value) ? value.map((item) => getThemeString(item)) : ['light'];
|
||||
}
|
||||
return value;
|
||||
}),
|
||||
);
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const theme = searchParams.getAll('theme') as unknown as ThemeName[];
|
||||
const handleThemeChange = (value: ThemeName[]) => {
|
||||
setSearchParams({
|
||||
...searchParams,
|
||||
theme: value,
|
||||
});
|
||||
};
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const localTheme = localStorage.getItem(ANT_DESIGN_SITE_THEME);
|
||||
if (localTheme) {
|
||||
const themeConfig = JSON.parse(localTheme);
|
||||
if (themeConfig.algorithm) {
|
||||
themeConfig.algorithm = themeConfig.algorithm.map((item: string) => getAlgorithm(item));
|
||||
} else {
|
||||
themeConfig.algorithm = [antdTheme.defaultAlgorithm];
|
||||
}
|
||||
startTransition(() => {
|
||||
setTheme(themeConfig);
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<StyleProvider cache={styleCache}>
|
||||
<ConfigProvider theme={theme}>
|
||||
<ConfigProvider
|
||||
theme={{
|
||||
algorithm: getAlgorithm(theme),
|
||||
}}
|
||||
>
|
||||
{outlet}
|
||||
{!pathname.startsWith('/~demos') && (
|
||||
<ThemeSwitch
|
||||
value={theme.algorithm as []}
|
||||
onChange={(value) => handleThemeChange({ ...theme, algorithm: value }, false)}
|
||||
/>
|
||||
<ThemeSwitch value={theme} onChange={handleThemeChange} />
|
||||
)}
|
||||
</ConfigProvider>
|
||||
</StyleProvider>
|
||||
|
@ -1,8 +1,10 @@
|
||||
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 { Col, Typography, Avatar, Tooltip, Affix, Anchor, Space } from 'antd';
|
||||
import { CalendarOutlined } from '@ant-design/icons';
|
||||
import ContributorsList from '@qixian.cs/github-contributors-list';
|
||||
import DayJS from 'dayjs';
|
||||
import { css } from '@emotion/react';
|
||||
import classNames from 'classnames';
|
||||
import Footer from '../Footer';
|
||||
@ -183,6 +185,25 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
/>
|
||||
)}
|
||||
</Typography.Title>
|
||||
|
||||
{/* 添加作者、时间等信息 */}
|
||||
{meta.frontmatter.date || meta.frontmatter.author ? (
|
||||
<Typography.Paragraph style={{ opacity: 0.65 }}>
|
||||
<Space>
|
||||
{meta.frontmatter.date && (
|
||||
<span>
|
||||
<CalendarOutlined /> {DayJS(meta.frontmatter.date).format('YYYY-MM-DD')}
|
||||
</span>
|
||||
)}
|
||||
{meta.frontmatter.author && (
|
||||
<Typography.Link href={`https://github.com/${meta.frontmatter.author}`}>
|
||||
@{meta.frontmatter.author}
|
||||
</Typography.Link>
|
||||
)}
|
||||
</Space>
|
||||
</Typography.Paragraph>
|
||||
) : null}
|
||||
|
||||
{children}
|
||||
{meta.frontmatter.filename && (
|
||||
<ContributorsList
|
||||
|
@ -206,7 +206,13 @@ export default ({
|
||||
blogList.length
|
||||
? {
|
||||
label: (
|
||||
<Link to={utils.getLocalizedPathname(blogList[0].link, isZhCN, search)}>
|
||||
<Link
|
||||
to={utils.getLocalizedPathname(
|
||||
blogList.sort((a, b) => (a.frontmatter.date > b.frontmatter.date ? -1 : 1))[0].link,
|
||||
isZhCN,
|
||||
search,
|
||||
)}
|
||||
>
|
||||
{locale.blog}
|
||||
</Link>
|
||||
),
|
||||
|
@ -1,3 +1 @@
|
||||
import 'react-github-button/assets/style.css';
|
||||
import 'docsearch.js/dist/cdn/docsearch.css';
|
||||
import 'rc-footer/assets/index.css';
|
||||
|
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
7
.github/PULL_REQUEST_TEMPLATE.md
vendored
@ -1,14 +1,9 @@
|
||||
<!--
|
||||
First of all, thank you for your contribution! 😄
|
||||
|
||||
For requesting to pull a new feature or bugfix, please send it from a feature/bugfix branch based on the `master` branch.
|
||||
|
||||
Before submitting your pull request, please make sure the checklist below is confirmed.
|
||||
|
||||
Your pull requests will be merged after one of the collaborators approve.
|
||||
|
||||
Thank you!
|
||||
|
||||
-->
|
||||
|
||||
[[中文版模板 / Chinese template](https://github.com/ant-design/ant-design/blob/master/.github/PULL_REQUEST_TEMPLATE/pr_cn.md)]
|
||||
@ -29,12 +24,14 @@ Thank you!
|
||||
- [ ] Code style optimization
|
||||
- [ ] Test Case
|
||||
- [ ] Branch merge
|
||||
- [ ] Workflow
|
||||
- [ ] Other (about what?)
|
||||
|
||||
### 🔗 Related issue link
|
||||
|
||||
<!--
|
||||
1. Put the related issue or discussion links here.
|
||||
2. close #xxxx or fix #xxxx for instance.
|
||||
-->
|
||||
|
||||
### 💡 Background and solution
|
||||
|
4
.github/workflows/issue-open-check.yml
vendored
4
.github/workflows/issue-open-check.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
actions: 'check-issue'
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
# 格式如:'x1,x2' or 'x1,x2/y1,y2' 最多支持 2 个数组
|
||||
title-includes: '官网,网站,国内,镜像,mobile ant design,mobile.ant.design,ant design,ant design pro,pro.ant.design/挂了,挂掉了,无法访问,不能访问,访问不了,出问题,打不开,登不上,can not open,cannot open,can not be reached'
|
||||
title-includes: '官网,网站,国内,镜像,mobile ant design,mobile.ant.design,ant design,ant design pro,pro.ant.design/挂了,挂掉了,无法访问,不能访问,访问速度,访问慢,访问不了,出问题,打不开,登不上,can not open,cannot open,can not be reached'
|
||||
|
||||
- name: deal website
|
||||
if: steps.checkid.outputs.check-result == 'true'
|
||||
@ -49,7 +49,7 @@ jobs:
|
||||
actions: 'create-comment,close-issue'
|
||||
issue-number: ${{ github.event.issue.number }}
|
||||
body: |
|
||||
Ant Design 系列官网由于某些众所周知的原因无法访问,建议翻墙或访问国内镜像站点。
|
||||
如果你无法访问 Ant Design 官网,可以先点此[downforeveryoneorjustme.com/ant.design](https://downforeveryoneorjustme.com/ant.design) 检查网站是不是挂了,如果没挂,可以尝试翻墙或访问国内镜像站点。
|
||||
|
||||
## 官网
|
||||
* Ant Design: https://ant.design
|
||||
|
5
.github/workflows/pr-open-check.yml
vendored
5
.github/workflows/pr-open-check.yml
vendored
@ -39,11 +39,10 @@ jobs:
|
||||
- Write with a **developer-oriented perspective** and **narrative method**, without describing the details of the repair
|
||||
- **Describing the problem and the impact on the developer**
|
||||
- **describing the user-first site problem**, not your solution
|
||||
- Refer: https://ant.design/changelog#4.9.0
|
||||
|
||||
- Refer: https://4x.ant.design/changelog#4.9.0
|
||||
- 🚨 请填写 PR 中的 changelog
|
||||
- 请用**面向开发者的角度**和**叙述方式撰写**,不描述修复细节
|
||||
- **描述问题和对开发者的影响**
|
||||
- **描述用户第一现场的问题**,而非你的解决方式
|
||||
- 参考:https://ant.design/changelog-cn#4.9.0
|
||||
- 参考:https://4x.ant.design/changelog-cn#4.9.0
|
||||
skip-title-start: 'docs, chore, test, ci'
|
||||
|
6
.github/workflows/release-helper.yml
vendored
6
.github/workflows/release-helper.yml
vendored
@ -23,10 +23,11 @@ jobs:
|
||||
- name: release antd
|
||||
uses: actions-cool/release-helper@v2
|
||||
with:
|
||||
triger: 'tag'
|
||||
trigger: 'tag'
|
||||
changelogs: 'CHANGELOG.en-US.md, CHANGELOG.zh-CN.md'
|
||||
branch: 'master, 4.x-stable'
|
||||
tag: '5*, 4*'
|
||||
latest: '5*'
|
||||
dingding-token: ${{ secrets.DINGDING_BOT_TOKEN }} ${{ secrets.DINGDING_BOT_COLLABORATOR_TOKEN }} ${{ secrets.DINGDING_BOT_MAINTAINER_TOKEN }}
|
||||
dingding-msg: 'CHANGELOG.zh-CN.md'
|
||||
msg-title: '# Ant Design {{v}} 发布日志'
|
||||
@ -38,10 +39,11 @@ jobs:
|
||||
- name: notice bigfish
|
||||
uses: actions-cool/release-helper@v2
|
||||
with:
|
||||
triger: 'tag'
|
||||
trigger: 'tag'
|
||||
changelogs: 'CHANGELOG.en-US.md, CHANGELOG.zh-CN.md'
|
||||
branch: 'master, 4.x-stable'
|
||||
tag: '5*, 4*'
|
||||
latest: '5*'
|
||||
dingding-token: ${{ secrets.DINGDING_BOT_BIGFISH_TOKEN }} ${{ secrets.DINGDING_BOT_YUNFENGDIE_TOKEN }}
|
||||
dingding-msg: 'CHANGELOG.zh-CN.md'
|
||||
dingding-delay-minute: 10
|
||||
|
26
.github/workflows/site-deploy.yml
vendored
26
.github/workflows/site-deploy.yml
vendored
@ -1,8 +1,11 @@
|
||||
# When publish a release. This workflow will trigger and deploy to site.
|
||||
# When pushing a tag. this workflow will trigger site deployment and fixed version address comments
|
||||
|
||||
name: Deploy website
|
||||
on:
|
||||
create
|
||||
push:
|
||||
tags:
|
||||
- '5.*'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@ -10,7 +13,7 @@ permissions:
|
||||
jobs:
|
||||
setup:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.ref_type == 'tag' && (contains(github.event.ref, '-') == false)
|
||||
if: startsWith(github.ref, 'refs/tags/') && (contains(github.ref_name, '-') == false)
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v3
|
||||
@ -63,9 +66,24 @@ jobs:
|
||||
- name: build
|
||||
run: npm run predeploy
|
||||
|
||||
- name: deploy
|
||||
- name: Get version
|
||||
id: publish-version
|
||||
run: echo "VERSION=$(echo ${{ github.ref_name }} | sed 's/\./-/g')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./_site
|
||||
force_orphan: true
|
||||
|
||||
- name: Deploy to Surge (with TAG)
|
||||
run: |
|
||||
export DEPLOY_DOMAIN=ant-design-${{ steps.publish-version.outputs.VERSION }}.surge.sh
|
||||
npx surge --project ./_site --domain $DEPLOY_DOMAIN --token ${{ secrets.SURGE_TOKEN }}
|
||||
|
||||
- name: Create Commit Comment
|
||||
uses: peter-evans/commit-comment@v1
|
||||
with:
|
||||
body: |
|
||||
Doc site for this release: https://ant-design-${{ steps.publish-version.outputs.VERSION }}.surge.sh
|
||||
|
3
.jest.js
3
.jest.js
@ -25,7 +25,7 @@ const transformIgnorePatterns = [
|
||||
];
|
||||
|
||||
function getTestRegex(libDir) {
|
||||
if (libDir === 'dist') {
|
||||
if (['dist', 'lib', 'es'].includes(libDir)) {
|
||||
return 'demo\\.test\\.(j|t)s$';
|
||||
}
|
||||
return '.*\\.test\\.(j|t)sx?$';
|
||||
@ -72,4 +72,5 @@ module.exports = {
|
||||
url: 'http://localhost',
|
||||
},
|
||||
// bail: true,
|
||||
maxWorkers: '50%',
|
||||
};
|
||||
|
@ -15,6 +15,25 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 5.0.5
|
||||
|
||||
`2022-12-08`
|
||||
|
||||
- 🐞 Fix button hover style in Space.Compact. [#39157](https://github.com/ant-design/ant-design/pull/39157) [@foryuki](https://github.com/foryuki)
|
||||
- 🐞 Fix Tabs active bar missing sometimes in windows Chrome. [#39352](https://github.com/ant-design/ant-design/pull/39352) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🐞 Fix Divider `horizontal` align issue in flex layout. [#39339](https://github.com/ant-design/ant-design/pull/39339)
|
||||
- 🐞 Fix Popover width in rtl mode. [#39311](https://github.com/ant-design/ant-design/pull/39311)
|
||||
- 🐞 Fix Popconfirm padding style issue when `wireframe` is `true`. [#39313](https://github.com/ant-design/ant-design/pull/39313) [@MadCcc](https://github.com/MadCcc)
|
||||
- 💄 Fix Select search input with white space style issue. [#39299](https://github.com/ant-design/ant-design/pull/39299) [@MadCcc](https://github.com/MadCcc)
|
||||
- 💄 Fix Tree missing selection style. [#39292](https://github.com/ant-design/ant-design/pull/39292)
|
||||
- 🐞 Fix FloatButton content not align when customize size. [#39282](https://github.com/ant-design/ant-design/pull/39282) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🐞 Fix RangePicker cell hover style. [#39266](https://github.com/ant-design/ant-design/pull/39266)
|
||||
- 💄 Optimize Button style under Space.Compact. [#39241](https://github.com/ant-design/ant-design/pull/39241) [@foryuki](https://github.com/foryuki)
|
||||
- 🌐 Fix `vi_VN` i18n mistake. [#39279](https://github.com/ant-design/ant-design/pull/39279) [@nghiepdev](https://github.com/nghiepdev)
|
||||
- 🌐 Fix `he_IL` i18n mistake. [#39280](https://github.com/ant-design/ant-design/pull/39280) [@Ran-Sagy](https://github.com/Ran-Sagy)
|
||||
- TypeScript
|
||||
- 🤖 Optimize Anchor `onClick` event definition. [#39305](https://github.com/ant-design/ant-design/pull/39305) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
|
||||
## 5.0.4
|
||||
|
||||
`2022-12-05`
|
||||
|
@ -15,6 +15,25 @@ timeline: true
|
||||
|
||||
---
|
||||
|
||||
## 5.0.5
|
||||
|
||||
`2022-12-08`
|
||||
|
||||
- 🐞 修复 Space.Compact 下 Button hover 样式问题。[#39157](https://github.com/ant-design/ant-design/pull/39157) [@foryuki](https://github.com/foryuki)
|
||||
- 🐞 修复 Tabs 在 windows Chrome 下高亮条有时候会丢失的问题。[#39352](https://github.com/ant-design/ant-design/pull/39352) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🐞 修复 Divider `horizontal` 在 flex 布局下的对齐问题。[#39339](https://github.com/ant-design/ant-design/pull/39339)
|
||||
- 🐞 修复 Popover 在 rtl 模式下宽度异常的问题。[#39311](https://github.com/ant-design/ant-design/pull/39311)
|
||||
- 🐞 修复 Popconfirm 组件 token 配置线框化后边框坍缩的样式问题。[#39313](https://github.com/ant-design/ant-design/pull/39313) [@MadCcc](https://github.com/MadCcc)
|
||||
- 💄 修复 Select 组件搜索框会出现空白区域的样式问题。[#39299](https://github.com/ant-design/ant-design/pull/39299) [@MadCcc](https://github.com/MadCcc)
|
||||
- 💄 修复 Tree 丢失选中样式的问题。[#39292](https://github.com/ant-design/ant-design/pull/39292)
|
||||
- 🐞 修复 FloatButton 自定义尺寸时,内容不居中的问题。[#39282](https://github.com/ant-design/ant-design/pull/39282) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🐞 修复 RangePicker 日期 hover 样式。[#39266](https://github.com/ant-design/ant-design/pull/39266)
|
||||
- 💄 优化 Button 在 Space.Compact 下的 Hover 样式。[#39241](https://github.com/ant-design/ant-design/pull/39241) [@foryuki](https://github.com/foryuki)
|
||||
- 🌐 修正 `vi_VN` 国际化描述。[#39279](https://github.com/ant-design/ant-design/pull/39279) [@nghiepdev](https://github.com/nghiepdev)
|
||||
- 🌐 修正 `he_IL` 国际化描述。[#39280](https://github.com/ant-design/ant-design/pull/39280) [@Ran-Sagy](https://github.com/Ran-Sagy)
|
||||
- TypeScript
|
||||
- 🤖 优化 Anchor `onClick` 的事件类型定义。[#39305](https://github.com/ant-design/ant-design/pull/39305) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
|
||||
## 5.0.4
|
||||
|
||||
`2022-12-05`
|
||||
|
@ -81,6 +81,7 @@ const genBaseStyle: GenerateStyle<CascaderToken> = (token) => {
|
||||
flexGrow: 1,
|
||||
minWidth: token.controlItemWidth,
|
||||
height: token.dropdownHeight,
|
||||
margin: 0,
|
||||
padding: token.paddingXXS,
|
||||
overflow: 'auto',
|
||||
verticalAlign: 'top',
|
||||
|
@ -53,16 +53,12 @@ const FloatButton: React.ForwardRefRenderFunction<
|
||||
[prefixCls, description, icon, type],
|
||||
);
|
||||
|
||||
const buttonNode = tooltip ? (
|
||||
const buttonNode = (
|
||||
<Tooltip title={tooltip} placement="left">
|
||||
<div className={`${prefixCls}-body`}>
|
||||
<Content {...contentProps} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
) : (
|
||||
<div className={`${prefixCls}-body`}>
|
||||
<Content {...contentProps} />
|
||||
</div>
|
||||
);
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
|
@ -64,6 +64,28 @@ exports[`renders ./components/float-button/demo/basic.tsx extend context correct
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
`;
|
||||
|
||||
@ -110,6 +132,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>,
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
|
||||
@ -129,6 +173,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>,
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
|
||||
@ -171,6 +237,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>,
|
||||
]
|
||||
`;
|
||||
@ -219,6 +307,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
|
||||
@ -255,6 +365,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>,
|
||||
<div
|
||||
@ -299,6 +431,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
|
||||
@ -335,6 +489,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
|
||||
@ -371,6 +547,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>,
|
||||
]
|
||||
@ -415,6 +613,28 @@ exports[`renders ./components/float-button/demo/group-menu.tsx extend context co
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
@ -458,6 +678,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-pure ant-float-btn-default ant-float-btn-circle"
|
||||
@ -494,6 +736,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-pure ant-float-btn-primary ant-float-btn-square"
|
||||
@ -538,6 +802,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<div
|
||||
class="ant-float-btn-group ant-float-btn-pure ant-float-btn-group-square ant-float-btn-group-square-shadow"
|
||||
@ -580,6 +866,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
|
||||
@ -616,6 +924,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-square"
|
||||
@ -652,6 +982,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
@ -698,6 +1050,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
|
||||
@ -734,6 +1108,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
|
||||
@ -770,6 +1166,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
@ -807,6 +1225,28 @@ exports[`renders ./components/float-button/demo/render-panel.tsx extend context
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@ -893,6 +1333,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>,
|
||||
]
|
||||
`;
|
||||
@ -1003,6 +1465,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>,
|
||||
<button
|
||||
class="ant-float-btn ant-float-btn-default ant-float-btn-circle"
|
||||
@ -1043,6 +1527,28 @@ Array [
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="ant-tooltip"
|
||||
style="opacity:0"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-content"
|
||||
>
|
||||
<div
|
||||
class="ant-tooltip-arrow"
|
||||
>
|
||||
<span
|
||||
class="ant-tooltip-arrow-content"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="ant-tooltip-inner"
|
||||
role="tooltip"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>,
|
||||
]
|
||||
`;
|
||||
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import FloatButton from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { fireEvent, render } from '../../../tests/utils';
|
||||
import { fireEvent, render, waitFakeTimer } from '../../../tests/utils';
|
||||
|
||||
describe('FloatButton', () => {
|
||||
mountTest(FloatButton);
|
||||
@ -51,4 +51,15 @@ describe('FloatButton', () => {
|
||||
);
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('tooltip should support number `0`', async () => {
|
||||
jest.useFakeTimers();
|
||||
const { container } = render(<FloatButton tooltip={0} />);
|
||||
fireEvent.mouseEnter(container.querySelector<HTMLDivElement>('.ant-float-btn-body')!);
|
||||
await waitFakeTimer();
|
||||
const element = container.querySelector('.ant-tooltip')?.querySelector('.ant-tooltip-inner');
|
||||
expect(element?.textContent).toBe('0');
|
||||
jest.clearAllTimers();
|
||||
jest.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
@ -46,7 +46,7 @@ exports[`renders ./components/input/demo/addon.tsx extend context correctly 1`]
|
||||
class="ant-input-group-addon"
|
||||
>
|
||||
<div
|
||||
class="ant-select select-before ant-select-single ant-select-show-arrow"
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
@ -196,7 +196,7 @@ exports[`renders ./components/input/demo/addon.tsx extend context correctly 1`]
|
||||
class="ant-input-group-addon"
|
||||
>
|
||||
<div
|
||||
class="ant-select select-after ant-select-single ant-select-show-arrow"
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
|
@ -46,7 +46,7 @@ exports[`renders ./components/input/demo/addon.tsx correctly 1`] = `
|
||||
class="ant-input-group-addon"
|
||||
>
|
||||
<div
|
||||
class="ant-select select-before ant-select-single ant-select-show-arrow"
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
@ -114,7 +114,7 @@ exports[`renders ./components/input/demo/addon.tsx correctly 1`] = `
|
||||
class="ant-input-group-addon"
|
||||
>
|
||||
<div
|
||||
class="ant-select select-after ant-select-single ant-select-show-arrow"
|
||||
class="ant-select ant-select-single ant-select-show-arrow"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
|
@ -5,21 +5,3 @@
|
||||
## en-US
|
||||
|
||||
Using pre & post tabs example.
|
||||
|
||||
```css
|
||||
.select-before {
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.select-after {
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
[data-theme='compact'] .select-before {
|
||||
width: 71px;
|
||||
}
|
||||
|
||||
[data-theme='compact'] .select-after {
|
||||
width: 65px;
|
||||
}
|
||||
```
|
||||
|
@ -5,13 +5,13 @@ import { Cascader, Input, Select, Space } from 'antd';
|
||||
const { Option } = Select;
|
||||
|
||||
const selectBefore = (
|
||||
<Select defaultValue="http://" className="select-before">
|
||||
<Select defaultValue="http://">
|
||||
<Option value="http://">http://</Option>
|
||||
<Option value="https://">https://</Option>
|
||||
</Select>
|
||||
);
|
||||
const selectAfter = (
|
||||
<Select defaultValue=".com" className="select-after">
|
||||
<Select defaultValue=".com">
|
||||
<Option value=".com">.com</Option>
|
||||
<Option value=".jp">.jp</Option>
|
||||
<Option value=".cn">.cn</Option>
|
||||
|
@ -11,6 +11,7 @@ export type InputToken<T extends GlobalToken = FullToken<'Input'>> = T & {
|
||||
inputPaddingVerticalLG: number;
|
||||
inputPaddingVerticalSM: number;
|
||||
inputPaddingHorizontal: number;
|
||||
inputPaddingHorizontalLG: number;
|
||||
inputPaddingHorizontalSM: number;
|
||||
inputBorderHoverColor: string;
|
||||
inputBorderActiveColor: string;
|
||||
@ -58,14 +59,14 @@ export const genDisabledStyle = (token: InputToken): CSSObject => ({
|
||||
const genInputLargeStyle = (token: InputToken): CSSObject => {
|
||||
const {
|
||||
inputPaddingVerticalLG,
|
||||
inputPaddingHorizontal,
|
||||
fontSizeLG,
|
||||
lineHeightLG,
|
||||
borderRadiusLG,
|
||||
inputPaddingHorizontalLG,
|
||||
} = token;
|
||||
|
||||
return {
|
||||
padding: `${inputPaddingVerticalLG}px ${inputPaddingHorizontal}px`,
|
||||
padding: `${inputPaddingVerticalLG}px ${inputPaddingHorizontalLG}px`,
|
||||
fontSize: fontSizeLG,
|
||||
lineHeight: lineHeightLG,
|
||||
borderRadius: borderRadiusLG,
|
||||
@ -860,8 +861,9 @@ export function initInputToken<T extends GlobalToken = GlobalToken>(token: T): I
|
||||
token.lineWidth,
|
||||
0,
|
||||
),
|
||||
inputPaddingHorizontal: token.controlPaddingHorizontal - token.lineWidth,
|
||||
inputPaddingHorizontalSM: token.controlPaddingHorizontalSM - token.lineWidth,
|
||||
inputPaddingHorizontal: token.paddingSM - token.lineWidth,
|
||||
inputPaddingHorizontalSM: token.paddingXS - token.lineWidth,
|
||||
inputPaddingHorizontalLG: token.controlPaddingHorizontal - token.lineWidth,
|
||||
inputBorderHoverColor: token.colorPrimaryHover,
|
||||
inputBorderActiveColor: token.colorPrimaryHover,
|
||||
});
|
||||
|
@ -167,7 +167,7 @@ export default genComponentStyleHook(
|
||||
const combinedToken = mergeToken<MessageToken>(token, {
|
||||
messageNoticeContentPadding: `${
|
||||
(token.controlHeightLG - token.fontSize * token.lineHeight) / 2
|
||||
}px ${token.paddingContentVertical}px`,
|
||||
}px ${token.paddingSM}px`,
|
||||
});
|
||||
return [genMessageStyle(combinedToken)];
|
||||
},
|
||||
|
@ -16,7 +16,7 @@ Radio.
|
||||
|
||||
## Examples
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<code src="./demo/basic.tsx">Basic</code>
|
||||
<code src="./demo/disabled.tsx">disabled</code>
|
||||
<code src="./demo/radiogroup.tsx">Radio Group</code>
|
||||
@ -28,6 +28,7 @@ Radio.
|
||||
<code src="./demo/radiobutton-solid.tsx">Solid radio button</code>
|
||||
<code src="./demo/badge.tsx" debug>Badge style</code>
|
||||
<code src="./demo/wireframe.tsx" debug>Wireframe</code>
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
## API
|
||||
|
||||
|
@ -17,7 +17,7 @@ demo:
|
||||
|
||||
## 代码演示
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<!-- prettier-ignore-start -->
|
||||
<code src="./demo/basic.tsx">基本</code>
|
||||
<code src="./demo/disabled.tsx">不可用</code>
|
||||
<code src="./demo/radiogroup.tsx">单选组合</code>
|
||||
@ -29,25 +29,28 @@ demo:
|
||||
<code src="./demo/radiobutton-solid.tsx">填底的按钮样式</code>
|
||||
<code src="./demo/badge.tsx" debug>测试 Badge 的样式</code>
|
||||
<code src="./demo/wireframe.tsx" debug>线框风格</code>
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
## API
|
||||
|
||||
### Radio/Radio.Button
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| -------------- | --------------------------------- | ------- | ------ |
|
||||
| autoFocus | 自动获取焦点 | boolean | false |
|
||||
| checked | 指定当前是否选中 | boolean | false |
|
||||
| defaultChecked | 初始是否选中 | boolean | false |
|
||||
| disabled | 禁用 Radio | boolean | false |
|
||||
| value | 根据 value 进行比较,判断是否选中 | any | - |
|
||||
<!-- prettier-ignore -->
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| autoFocus | 自动获取焦点 | boolean | false |
|
||||
| checked | 指定当前是否选中 | boolean | false |
|
||||
| defaultChecked | 初始是否选中 | boolean | false |
|
||||
| disabled | 禁用 Radio | boolean | false |
|
||||
| value | 根据 value 进行比较,判断是否选中 | any | - |
|
||||
|
||||
### RadioGroup
|
||||
### Radio.Group
|
||||
|
||||
单选框组合,用于包裹一组 `Radio`。
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 | |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
<!-- prettier-ignore -->
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| buttonStyle | RadioButton 的风格样式,目前有描边和填色两种风格 | `outline` \| `solid` | `outline` | | |
|
||||
| defaultValue | 默认选中的值 | any | - | | |
|
||||
| disabled | 禁选所有子单选器 | boolean | false | | |
|
||||
|
@ -497,6 +497,7 @@ export default genComponentStyleHook('Radio', (token) => {
|
||||
colorPrimary,
|
||||
marginXS,
|
||||
controlOutlineWidth,
|
||||
colorTextLightSolid,
|
||||
wireframe,
|
||||
} = token;
|
||||
|
||||
@ -528,7 +529,7 @@ export default genComponentStyleHook('Radio', (token) => {
|
||||
radioDotDisabledSize,
|
||||
radioCheckedColor,
|
||||
radioDotDisabledColor: colorTextDisabled,
|
||||
radioSolidCheckedColor: colorBgContainer,
|
||||
radioSolidCheckedColor: colorTextLightSolid,
|
||||
radioButtonBg: colorBgContainer,
|
||||
radioButtonCheckedBg: colorBgContainer,
|
||||
radioButtonColor,
|
||||
|
@ -329,7 +329,7 @@ export default genComponentStyleHook(
|
||||
(token, { rootPrefixCls }) => {
|
||||
const selectToken: SelectToken = mergeToken<SelectToken>(token, {
|
||||
rootPrefixCls,
|
||||
inputPaddingHorizontalBase: token.controlPaddingHorizontal - 1,
|
||||
inputPaddingHorizontalBase: token.paddingSM - 1,
|
||||
});
|
||||
|
||||
return [genSelectStyle(selectToken)];
|
||||
|
@ -111,7 +111,7 @@ const genBaseStyle: GenerateStyle<SliderToken> = (token) => {
|
||||
insetInlineStart: 0,
|
||||
width: token.handleSize,
|
||||
height: token.handleSize,
|
||||
backgroundColor: token.colorBgContainer,
|
||||
backgroundColor: token.colorBgElevated,
|
||||
boxShadow: `0 0 0 ${token.handleLineWidth}px ${token.colorPrimaryBorder}`,
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
@ -177,8 +177,8 @@ const genBaseStyle: GenerateStyle<SliderToken> = (token) => {
|
||||
position: 'absolute',
|
||||
width: dotSize,
|
||||
height: dotSize,
|
||||
backgroundColor: token.colorBgContainer,
|
||||
border: `${token.handleLineWidth}px solid ${token.colorSplit}`,
|
||||
backgroundColor: token.colorBgElevated,
|
||||
border: `${token.handleLineWidth}px solid ${token.colorBorderSecondary}`,
|
||||
borderRadius: '50%',
|
||||
cursor: 'pointer',
|
||||
transition: `border-color ${token.motionDurationSlow}`,
|
||||
@ -202,14 +202,14 @@ const genBaseStyle: GenerateStyle<SliderToken> = (token) => {
|
||||
[`
|
||||
${componentCls}-dot
|
||||
`]: {
|
||||
backgroundColor: token.colorBgContainer,
|
||||
backgroundColor: token.colorBgElevated,
|
||||
borderColor: token.colorTextDisabled,
|
||||
boxShadow: 'none',
|
||||
cursor: 'not-allowed',
|
||||
},
|
||||
|
||||
[`${componentCls}-handle::after`]: {
|
||||
backgroundColor: token.colorBgContainer,
|
||||
backgroundColor: token.colorBgElevated,
|
||||
cursor: 'not-allowed',
|
||||
width: token.handleSize,
|
||||
height: token.handleSize,
|
||||
@ -335,7 +335,7 @@ export default genComponentStyleHook(
|
||||
railSize: 4,
|
||||
handleSize: controlSize,
|
||||
handleSizeHover: controlSizeHover,
|
||||
dotSize: (controlSize / 3) * 2,
|
||||
dotSize: 8,
|
||||
handleLineWidth,
|
||||
handleLineWidthHover,
|
||||
};
|
||||
|
@ -124,7 +124,7 @@ const columns = [
|
||||
| scroll | Whether the table can be scrollable, [config](#scroll) | object | - | |
|
||||
| showHeader | Whether to show table header | boolean | true | |
|
||||
| showSorterTooltip | The header show next sorter direction tooltip. It will be set as the property of Tooltip if its type is object | boolean \| [Tooltip props](/components/tooltip/#API) | true | |
|
||||
| size | Size of table | `default` \| `middle` \| `small` | `default` | |
|
||||
| size | Size of table | `large` \| `middle` \| `small` | `large` | |
|
||||
| sortDirections | Supported sort way, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | |
|
||||
| sticky | Set sticky header and scroll bar | boolean \| `{offsetHeader?: number, offsetScroll?: number, getContainer?: () => HTMLElement}` | - | 4.6.0 (getContainer: 4.7.0) |
|
||||
| summary | Summary content | (currentData) => ReactNode | - | |
|
||||
|
@ -125,7 +125,7 @@ const columns = [
|
||||
| scroll | 表格是否可滚动,也可以指定滚动区域的宽、高,[配置项](#scroll) | object | - | |
|
||||
| showHeader | 是否显示表头 | boolean | true | |
|
||||
| showSorterTooltip | 表头是否显示下一次排序的 tooltip 提示。当参数类型为对象时,将被设置为 Tooltip 的属性 | boolean \| [Tooltip props](/components/tooltip/) | true | |
|
||||
| size | 表格大小 | `default` \| `middle` \| `small` | default | |
|
||||
| size | 表格大小 | `large` \| `middle` \| `small` | `large` | |
|
||||
| sortDirections | 支持的排序方式,取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | |
|
||||
| sticky | 设置粘性头部和滚动条 | boolean \| `{offsetHeader?: number, offsetScroll?: number, getContainer?: () => HTMLElement}` | - | 4.6.0 (getContainer: 4.7.0) |
|
||||
| summary | 总结栏 | (currentData) => ReactNode | - | |
|
||||
|
@ -48,58 +48,12 @@ export interface AliasToken extends MapToken {
|
||||
colorErrorOutline: string;
|
||||
|
||||
// Font
|
||||
fontSizeSM: number;
|
||||
fontSize: number;
|
||||
fontSizeLG: number;
|
||||
fontSizeXL: number;
|
||||
/** Operation icon in Select, Cascader, etc. icon fontSize. Normal is same as fontSizeSM */
|
||||
fontSizeIcon: number;
|
||||
|
||||
/**
|
||||
* @nameZH 一级标题字号
|
||||
* @desc H1 标签所使用的字号
|
||||
* @default 38
|
||||
*/
|
||||
fontSizeHeading1: number;
|
||||
/**
|
||||
* @nameZH 二级标题字号
|
||||
* @desc h2 标签所使用的字号
|
||||
* @default 30
|
||||
*/
|
||||
fontSizeHeading2: number;
|
||||
/**
|
||||
* @nameZH 三级标题字号
|
||||
* @desc h3 标签使用的字号
|
||||
* @default 24
|
||||
*/
|
||||
fontSizeHeading3: number;
|
||||
/**
|
||||
* @nameZH 四级标题字号
|
||||
* @desc h4 标签使用的字号
|
||||
* @default 20
|
||||
*/
|
||||
fontSizeHeading4: number;
|
||||
/**
|
||||
* @nameZH 五级标题字号
|
||||
* @desc h5 标签使用的字号
|
||||
* @default 16
|
||||
*/
|
||||
fontSizeHeading5: number;
|
||||
|
||||
/** For heading like h1, h2, h3 or option selected item */
|
||||
fontWeightStrong: number;
|
||||
|
||||
// LineHeight
|
||||
lineHeight: number;
|
||||
lineHeightLG: number;
|
||||
lineHeightSM: number;
|
||||
|
||||
lineHeightHeading1: number;
|
||||
lineHeightHeading2: number;
|
||||
lineHeightHeading3: number;
|
||||
lineHeightHeading4: number;
|
||||
lineHeightHeading5: number;
|
||||
|
||||
// Control
|
||||
controlOutlineWidth: number;
|
||||
controlItemBgHover: string; // Note. It also is a color
|
||||
|
@ -18,7 +18,7 @@ export type {
|
||||
CommonMapToken,
|
||||
HeightMapToken,
|
||||
SizeMapToken,
|
||||
FontSizeMapToken,
|
||||
FontMapToken,
|
||||
StyleMapToken,
|
||||
} from './maps';
|
||||
export type { AliasToken } from './alias';
|
||||
|
49
components/theme/interface/maps/font.ts
Normal file
49
components/theme/interface/maps/font.ts
Normal file
@ -0,0 +1,49 @@
|
||||
export interface FontMapToken {
|
||||
// Font Size
|
||||
fontSizeSM: number;
|
||||
fontSize: number;
|
||||
fontSizeLG: number;
|
||||
fontSizeXL: number;
|
||||
|
||||
/**
|
||||
* @nameZH 一级标题字号
|
||||
* @desc H1 标签所使用的字号
|
||||
* @default 38
|
||||
*/
|
||||
fontSizeHeading1: number;
|
||||
/**
|
||||
* @nameZH 二级标题字号
|
||||
* @desc h2 标签所使用的字号
|
||||
* @default 30
|
||||
*/
|
||||
fontSizeHeading2: number;
|
||||
/**
|
||||
* @nameZH 三级标题字号
|
||||
* @desc h3 标签使用的字号
|
||||
* @default 24
|
||||
*/
|
||||
fontSizeHeading3: number;
|
||||
/**
|
||||
* @nameZH 四级标题字号
|
||||
* @desc h4 标签使用的字号
|
||||
* @default 20
|
||||
*/
|
||||
fontSizeHeading4: number;
|
||||
/**
|
||||
* @nameZH 五级标题字号
|
||||
* @desc h5 标签使用的字号
|
||||
* @default 16
|
||||
*/
|
||||
fontSizeHeading5: number;
|
||||
|
||||
// LineHeight
|
||||
lineHeight: number;
|
||||
lineHeightLG: number;
|
||||
lineHeightSM: number;
|
||||
|
||||
lineHeightHeading1: number;
|
||||
lineHeightHeading2: number;
|
||||
lineHeightHeading3: number;
|
||||
lineHeightHeading4: number;
|
||||
lineHeightHeading5: number;
|
||||
}
|
@ -1,14 +1,16 @@
|
||||
import type { ColorPalettes } from '../presetColors';
|
||||
import type { SeedToken } from '../seeds';
|
||||
import type { SizeMapToken, HeightMapToken, FontSizeMapToken } from './size';
|
||||
import type { SizeMapToken, HeightMapToken } from './size';
|
||||
import type { ColorMapToken } from './colors';
|
||||
import type { StyleMapToken } from './style';
|
||||
import type { FontMapToken } from './font';
|
||||
|
||||
export * from './colors';
|
||||
export * from './style';
|
||||
export * from './size';
|
||||
export * from './font';
|
||||
|
||||
export interface CommonMapToken extends FontSizeMapToken, StyleMapToken {
|
||||
export interface CommonMapToken extends StyleMapToken {
|
||||
// Motion
|
||||
motionDurationFast: string;
|
||||
motionDurationMid: string;
|
||||
@ -27,4 +29,5 @@ export interface MapToken
|
||||
SizeMapToken,
|
||||
HeightMapToken,
|
||||
StyleMapToken,
|
||||
FontMapToken,
|
||||
CommonMapToken {}
|
||||
|
@ -53,15 +53,3 @@ export interface HeightMapToken {
|
||||
/** @internal */
|
||||
controlHeightLG: number;
|
||||
}
|
||||
|
||||
// Font
|
||||
export interface FontSizeMapToken {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
fontSizes: number[];
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
lineHeights: number[];
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ export interface SeedToken extends PresetColorType {
|
||||
|
||||
/**
|
||||
* @nameZH 信息色
|
||||
* @nameEN Info Color
|
||||
* @desc 用于表示操作信息的 Token 序列,如 Alert 、Tag、 Progress 等组件都有用到该组梯度变量。
|
||||
* @descEN Used to represent the operation information of the Token sequence, such as Alert, Tag, Progress, and other components use these map tokens.
|
||||
*/
|
||||
@ -73,6 +74,7 @@ export interface SeedToken extends PresetColorType {
|
||||
|
||||
/**
|
||||
* @nameZH 默认字号
|
||||
* @nameEN Default Font Size
|
||||
* @desc 设计系统中使用最广泛的字体大小,文本梯度也将基于该字号进行派生。
|
||||
* @default 14
|
||||
*/
|
||||
@ -232,7 +234,8 @@ export interface SeedToken extends PresetColorType {
|
||||
// ---------- Style ---------- //
|
||||
|
||||
/**
|
||||
* @nameZH 线框化
|
||||
* @nameZH 线框风格
|
||||
* @nameEN Wireframe Style
|
||||
* @desc 用于将组件的视觉效果变为线框化,如果需要使用 V4 的效果,需要开启配置项
|
||||
* @default false
|
||||
*/
|
||||
|
@ -1,15 +1,14 @@
|
||||
import type { DerivativeFunc } from '@ant-design/cssinjs';
|
||||
import genControlHeight from '../shared/genControlHeight';
|
||||
import type { SeedToken, MapToken } from '../../interface';
|
||||
import type { MapToken, SeedToken } from '../../interface';
|
||||
import defaultAlgorithm from '../default';
|
||||
import genCompactSizeMapToken from './genCompactSizeMapToken';
|
||||
import getFontSizes from '../shared/genFontSizes';
|
||||
import genFontMapToken from '../shared/genFontMapToken';
|
||||
|
||||
const derivative: DerivativeFunc<SeedToken, MapToken> = (token, mapToken) => {
|
||||
const mergedMapToken = mapToken ?? defaultAlgorithm(token);
|
||||
|
||||
const fontSize = mergedMapToken.fontSizes[0]; // Smaller size font-size as base
|
||||
const fontSizes = getFontSizes(fontSize);
|
||||
const fontSize = mergedMapToken.fontSizeSM; // Smaller size font-size as base
|
||||
const controlHeight = mergedMapToken.controlHeight - 4;
|
||||
|
||||
return {
|
||||
@ -17,8 +16,7 @@ const derivative: DerivativeFunc<SeedToken, MapToken> = (token, mapToken) => {
|
||||
...genCompactSizeMapToken(mapToken ?? token),
|
||||
|
||||
// font
|
||||
fontSizes: fontSizes.map((fs) => fs.size),
|
||||
lineHeights: fontSizes.map((fs) => fs.lineHeight),
|
||||
...genFontMapToken(fontSize),
|
||||
|
||||
// controlHeight
|
||||
controlHeight,
|
||||
|
@ -6,6 +6,7 @@ import { defaultPresetColors } from '../seed';
|
||||
import genColorMapToken from '../shared/genColorMapToken';
|
||||
import genCommonMapToken from '../shared/genCommonMapToken';
|
||||
import { generateColorPalettes, generateNeutralColorPalettes } from './colors';
|
||||
import genFontMapToken from '../shared/genFontMapToken';
|
||||
|
||||
export default function derivative(token: SeedToken): MapToken {
|
||||
const colorPalettes = Object.keys(defaultPresetColors)
|
||||
@ -33,6 +34,8 @@ export default function derivative(token: SeedToken): MapToken {
|
||||
generateColorPalettes,
|
||||
generateNeutralColorPalettes,
|
||||
}),
|
||||
// Font
|
||||
...genFontMapToken(token.fontSize),
|
||||
// Size
|
||||
...genSizeMapToken(token),
|
||||
// Height
|
||||
|
@ -1,11 +1,8 @@
|
||||
import type { CommonMapToken, SeedToken } from '../../interface';
|
||||
import genFontSizes from './genFontSizes';
|
||||
import genRadius from './genRadius';
|
||||
|
||||
export default function genCommonMapToken(token: SeedToken): CommonMapToken {
|
||||
const { motionUnit, motionBase, fontSize, borderRadius, lineWidth } = token;
|
||||
|
||||
const fontSizes = genFontSizes(fontSize);
|
||||
const { motionUnit, motionBase, borderRadius, lineWidth } = token;
|
||||
|
||||
return {
|
||||
// motion
|
||||
@ -13,10 +10,6 @@ export default function genCommonMapToken(token: SeedToken): CommonMapToken {
|
||||
motionDurationMid: `${(motionBase + motionUnit * 2).toFixed(1)}s`,
|
||||
motionDurationSlow: `${(motionBase + motionUnit * 3).toFixed(1)}s`,
|
||||
|
||||
// font
|
||||
fontSizes: fontSizes.map((fs) => fs.size),
|
||||
lineHeights: fontSizes.map((fs) => fs.lineHeight),
|
||||
|
||||
// line
|
||||
lineWidthBold: lineWidth + 1,
|
||||
|
||||
|
33
components/theme/themes/shared/genFontMapToken.ts
Normal file
33
components/theme/themes/shared/genFontMapToken.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import type { FontMapToken } from '../../interface';
|
||||
import genFontSizes from './genFontSizes';
|
||||
|
||||
const genFontMapToken = (fontSize: number): FontMapToken => {
|
||||
const fontSizePairs = genFontSizes(fontSize);
|
||||
const fontSizes = fontSizePairs.map((pair) => pair.size);
|
||||
const lineHeights = fontSizePairs.map((pair) => pair.lineHeight);
|
||||
|
||||
return {
|
||||
fontSizeSM: fontSizes[0],
|
||||
fontSize: fontSizes[1],
|
||||
fontSizeLG: fontSizes[2],
|
||||
fontSizeXL: fontSizes[3],
|
||||
|
||||
fontSizeHeading1: fontSizes[6],
|
||||
fontSizeHeading2: fontSizes[5],
|
||||
fontSizeHeading3: fontSizes[4],
|
||||
fontSizeHeading4: fontSizes[3],
|
||||
fontSizeHeading5: fontSizes[2],
|
||||
|
||||
lineHeight: lineHeights[1],
|
||||
lineHeightLG: lineHeights[2],
|
||||
lineHeightSM: lineHeights[0],
|
||||
|
||||
lineHeightHeading1: lineHeights[6],
|
||||
lineHeightHeading2: lineHeights[5],
|
||||
lineHeightHeading3: lineHeights[4],
|
||||
lineHeightHeading4: lineHeights[3],
|
||||
lineHeightHeading5: lineHeights[2],
|
||||
};
|
||||
};
|
||||
|
||||
export default genFontMapToken;
|
@ -24,7 +24,6 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
|
||||
...overrideTokens,
|
||||
};
|
||||
|
||||
const { fontSizes, lineHeights } = mergedToken;
|
||||
const screenXS = 480;
|
||||
const screenSM = 576;
|
||||
const screenMD = 768;
|
||||
@ -32,8 +31,6 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
|
||||
const screenXL = 1200;
|
||||
const screenXXL = 1600;
|
||||
|
||||
const fontSizeSM = fontSizes[0];
|
||||
|
||||
// Generate alias token
|
||||
const aliasToken: AliasToken = {
|
||||
...mergedToken,
|
||||
@ -70,26 +67,7 @@ export default function formatToken(derivativeToken: RawMergedToken): AliasToken
|
||||
colorWarningOutline: getAlphaColor(mergedToken.colorWarningBg, mergedToken.colorBgContainer),
|
||||
|
||||
// Font
|
||||
fontSizeSM,
|
||||
fontSize: fontSizes[1],
|
||||
fontSizeLG: fontSizes[2],
|
||||
fontSizeXL: fontSizes[3],
|
||||
fontSizeHeading1: fontSizes[6],
|
||||
fontSizeHeading2: fontSizes[5],
|
||||
fontSizeHeading3: fontSizes[4],
|
||||
fontSizeHeading4: fontSizes[3],
|
||||
fontSizeHeading5: fontSizes[2],
|
||||
fontSizeIcon: fontSizeSM,
|
||||
|
||||
lineHeight: lineHeights[1],
|
||||
lineHeightLG: lineHeights[2],
|
||||
lineHeightSM: lineHeights[0],
|
||||
|
||||
lineHeightHeading1: lineHeights[6],
|
||||
lineHeightHeading2: lineHeights[5],
|
||||
lineHeightHeading3: lineHeights[4],
|
||||
lineHeightHeading4: lineHeights[3],
|
||||
lineHeightHeading5: lineHeights[2],
|
||||
fontSizeIcon: mergedToken.fontSizeSM,
|
||||
|
||||
// Control
|
||||
lineWidth: mergedToken.lineWidth,
|
||||
|
@ -1,6 +1,7 @@
|
||||
---
|
||||
order: 0
|
||||
title: Component-level CSS-in-JS
|
||||
date: 2022-11-25
|
||||
author: MadCcc
|
||||
---
|
||||
|
||||
On November 18, 2022, we released Ant Design 5.0. At the same time, Ant Design's unique CSS-in-JS solution was brought into everyone's view. Through this solution, Ant Design achieves higher performance than other CSS-in-JS libraries, but at the cost of sacrificing its flexibility for free use in applications. So we call it a "component-level" CSS-in-JS solution. <a name="W668Z"></a>
|
||||
|
@ -1,10 +1,9 @@
|
||||
---
|
||||
order: 0
|
||||
title: 组件级别的 CSS-in-JS
|
||||
date: 2022-11-25
|
||||
author: MadCcc
|
||||
---
|
||||
|
||||
`2022-11-25`
|
||||
|
||||
在 2022 年 11 月 18 日,我们发布了 Ant Design 5.0 的正式版本,同时带入大家视野中的还有 Ant Design 独特的 CSS-in-JS 方案。通过这个方案,Ant Design 获得了相较于其他 CSS-in-JS 库更高的性能,但代价则是牺牲了其在应用中自由使用的灵活性。所以我们把它称为“组件级”的 CSS-in-JS 方案。
|
||||
|
||||
## CSS-in-JS 的困境
|
||||
|
113
docs/blog/getContainer.en-US.md
Normal file
113
docs/blog/getContainer.en-US.md
Normal file
@ -0,0 +1,113 @@
|
||||
---
|
||||
title: Some change on getContainer
|
||||
date: 2022-12-08
|
||||
author: zombieJ
|
||||
---
|
||||
|
||||
We often encounter the need for pop-up elements when developing, such as the Select drop-down box, or the Modal component. When it is directly rendered under the current node, it may be clipped by the `overflow: hidden` of the parent node:
|
||||
|
||||
![Overflow](https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*Noh-TYJ0BdcAAAAAAAAAAAAADrJ8AQ/original)
|
||||
|
||||
Therefore we render it under `body` by default in Ant Design, but this will bring new problems. Since they are not under the same container, when the user scrolls the screen, they will find that the popup layer does not follow the scrolling:
|
||||
|
||||
![Scroll](https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*d44KQqkTX90AAAAAAAAAAAAADrJ8AQ/original)
|
||||
|
||||
To solve this problem, we provide the `getContainer` property, which allows users to customize the rendered container. The `getContainer` method will be called when the component is mounted, returning a container node, and the component will be rendered under this node through `createPortal`.
|
||||
|
||||
```tsx
|
||||
// Fake Code. Just for Demo
|
||||
const PopupWrapper = () => {
|
||||
const eleRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
// It's much complex with timing in real world. You can view the source for more detail:
|
||||
// https://github.com/react-component/portal/blob/master/src/Portal.tsx
|
||||
const container: HTMLElement = getContainer(eleRef.current);
|
||||
|
||||
// ...
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div ref={eleRef}>
|
||||
{...}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// Fake Code. Just for Demo
|
||||
const defaultGetContainer = () => {
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
return div;
|
||||
};
|
||||
|
||||
const SomeComponent = ({ getContainer = defaultGetContainer }) => (
|
||||
<PopupWrapper getContainer={getContainer} />
|
||||
);
|
||||
```
|
||||
|
||||
For the time being, we don’t pay attention to `getContainer`’s need to dynamically switch the mount node (in fact, it has not been able to switch for a long time in the past), only from the perspective of React 18, it has encountered some problems.
|
||||
|
||||
## React 18 Concurrent Mode
|
||||
|
||||
In React 18, effects may fire multiple times. In order to prevent inadvertently breaking the developer's behavior, it has also been adjusted accordingly under [StrictMode](https://reactjs.org/docs/strict-mode.html):
|
||||
|
||||
> - React mounts the component.
|
||||
> - Layout effects are created.
|
||||
> - Effect effects are created.
|
||||
> - React simulates effects being destroyed on a mounted component.
|
||||
> - Layout effects are destroyed.
|
||||
> - Effects are destroyed.
|
||||
> - React simulates effects being re-created on a mounted component.
|
||||
> - Layout effects are created
|
||||
> - Effect setup code runs
|
||||
|
||||
The simple understanding is that under StrictMode, even if your deps contains empty objects, the effect will still be triggered multiple times. When switching to React 18 StrictMode, we will find that there will be a pair of mount nodes in the HTML, and the previous one is empty:
|
||||
|
||||
```html
|
||||
<body>
|
||||
<div id="root">...</div>
|
||||
|
||||
<!-- Empty -->
|
||||
<div className="sample-holder"></div>
|
||||
|
||||
<!-- Real in use -->
|
||||
<div className="sample-holder">
|
||||
<div className="ant-component-wrapper">...</div>
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
Therefore, we adjusted the call implementation, and the default `getContainer` is also managed through state to ensure that the nodes generated by the previous effect will be cleaned up in StrictMode:
|
||||
|
||||
```tsx
|
||||
// Fake Code. Just for Demo
|
||||
const SomeComponent = ({ getContainer }) => {
|
||||
const [myContainer, setMyContainer] = React.useState<HTMLElement | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (getContainer) {
|
||||
setMyContainer(getContainer());
|
||||
return;
|
||||
}
|
||||
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
setMyContainer(div);
|
||||
|
||||
return () => {
|
||||
document.body.removeChild(div);
|
||||
};
|
||||
}, [getContainer]);
|
||||
|
||||
return <PopupWrapper getContainer={() => myContainer} />;
|
||||
};
|
||||
```
|
||||
|
||||
After putting `getContainer` into effect management, we can manage nodes in a way that is more in line with the React life cycle, and we can also clean up when `getContainer` changes. So as to support the scenario of dynamically changing `getContainer` (although I personally doubt the universality of this usage scenario).
|
||||
|
||||
## Finally
|
||||
|
||||
Due to the fix that `getContainer` does not support dynamic changes, it also introduces a potential breaking change at the same time. If the developer customizes `getContainer` to create a new dom node every time, it will cause an infinite loop because of the continuous execution of the effect, resulting in the continuous creation of nodes. If you use this method and encounter problems, you need to pay attention to check.
|
113
docs/blog/getContainer.zh-CN.md
Normal file
113
docs/blog/getContainer.zh-CN.md
Normal file
@ -0,0 +1,113 @@
|
||||
---
|
||||
title: getContainer 的一些变化
|
||||
date: 2022-12-08
|
||||
author: zombieJ
|
||||
---
|
||||
|
||||
在网页开发中,我们时长会遇到弹出元素的需求,比如 Select 的下拉框、或者是 Modal 组件。直接将其渲染到当前节点下时,可能会被父节点的 `overflow: hidden` 裁剪掉:
|
||||
|
||||
![Overflow](https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*Noh-TYJ0BdcAAAAAAAAAAAAADrJ8AQ/original)
|
||||
|
||||
因而在 Ant Design 中,我们默认将其渲染到 `body` 下,但是这又会带来新的问题。由于不在同一个容器下,当用户滚动屏幕时会发现弹出层并未跟随滚动:
|
||||
|
||||
![Scroll](https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*d44KQqkTX90AAAAAAAAAAAAADrJ8AQ/original)
|
||||
|
||||
为了解决这个问题,我们提供了 `getContainer` 属性,让用户可以自定义渲染的容器。`getContainer` 方法会在组件挂载时调用,返回一个容器节点,组件会通过 `createPortal` 渲染到这个节点下。
|
||||
|
||||
```tsx
|
||||
// Fake Code. Just for Demo
|
||||
const PopupWrapper = () => {
|
||||
const eleRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
// It's much complex with timing in real world. You can view the source for more detail:
|
||||
// https://github.com/react-component/portal/blob/master/src/Portal.tsx
|
||||
const container: HTMLElement = getContainer(eleRef.current);
|
||||
|
||||
// ...
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div ref={eleRef}>
|
||||
{...}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
```tsx
|
||||
// Fake Code. Just for Demo
|
||||
const defaultGetContainer = () => {
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
return div;
|
||||
};
|
||||
|
||||
const SomeComponent = ({ getContainer = defaultGetContainer }) => (
|
||||
<PopupWrapper getContainer={getContainer} />
|
||||
);
|
||||
```
|
||||
|
||||
我们暂时不关注 `getContainer` 需要动态切换挂载节点的需求(其实在过去很长时间它的确也无法切换),仅仅从 React 18 看,它遇到了一些问题。
|
||||
|
||||
## React 18 Concurrent Mode
|
||||
|
||||
React 18 中,effect 可能会多次触发。为了防止不经意间破坏开发者的行为,在 [StrictMode](https://reactjs.org/docs/strict-mode.html) 下它也做了相应的调整:
|
||||
|
||||
> - React mounts the component.
|
||||
> - Layout effects are created.
|
||||
> - Effect effects are created.
|
||||
> - React simulates effects being destroyed on a mounted component.
|
||||
> - Layout effects are destroyed.
|
||||
> - Effects are destroyed.
|
||||
> - React simulates effects being re-created on a mounted component.
|
||||
> - Layout effects are created
|
||||
> - Effect setup code runs
|
||||
|
||||
简单理解就是 StrictMode 下,即便你的 deps 里是空对象,effect 仍然会多次触发。在切换为 React 18 StrictMode 的时候,我们会发现在 HTML 中会成对出现挂载节点,同时前一个是空的:
|
||||
|
||||
```html
|
||||
<body>
|
||||
<div id="root">...</div>
|
||||
|
||||
<!-- Empty -->
|
||||
<div className="sample-holder"></div>
|
||||
|
||||
<!-- Real in use -->
|
||||
<div className="sample-holder">
|
||||
<div className="ant-component-wrapper">...</div>
|
||||
</div>
|
||||
</body>
|
||||
```
|
||||
|
||||
因而我们调整了调用实现,默认的 `getContainer` 也通过 state 进行管理,确保在 StrictMode 下会清理前一个 effect 生成的节点:
|
||||
|
||||
```tsx
|
||||
// Fake Code. Just for Demo
|
||||
const SomeComponent = ({ getContainer }) => {
|
||||
const [myContainer, setMyContainer] = React.useState<HTMLElement | null>(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (getContainer) {
|
||||
setMyContainer(getContainer());
|
||||
return;
|
||||
}
|
||||
|
||||
const div = document.createElement('div');
|
||||
document.body.appendChild(div);
|
||||
setMyContainer(div);
|
||||
|
||||
return () => {
|
||||
document.body.removeChild(div);
|
||||
};
|
||||
}, [getContainer]);
|
||||
|
||||
return <PopupWrapper getContainer={() => myContainer} />;
|
||||
};
|
||||
```
|
||||
|
||||
将 `getContainer` 放入 effect 管理后,我们可以更符合 React 生命周期的方式去管理节点,同时也可以在 `getContainer` 变化时进行清理。从而支持动态改变 `getContainer` 的场景(虽然我个人比较怀疑这种使用场景的普遍性)。
|
||||
|
||||
## 最后
|
||||
|
||||
由于修复了 `getContainer` 不支持动态改变的问题,它也引入了一个潜在的 breaking change。开发者如果自定义 `getContainer` 每次都是创建新的 dom 节点时,它就会因为 effect 不断执行,导致节点不断创建而死循环。如果你使用了这种方式并且遇到了问题,需要注意检查。
|
@ -39,7 +39,7 @@ const App: React.FC = () => (
|
||||
export default App;
|
||||
```
|
||||
|
||||
You will get a theme with primary color <div style="display: inline-block; width: 16px; height: 16px; border-radius: 4px; background: #00b96b; vertical-align: text-bottom;"></div> `#00b96b`. And we can see the change in Button:
|
||||
You will get a theme with primary color <ColorChunk color="#00b96b" /></ColorChunk>. And we can see the change in Button:
|
||||
|
||||
![themed button](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*CbF_RJfKEiwAAAAAAAAAAAAAARQnAQ)
|
||||
|
||||
@ -90,7 +90,7 @@ const App: React.FC = () => (
|
||||
export default App;
|
||||
```
|
||||
|
||||
In this way, we changed the primary color of Radio to <div style="display: inline-block; width: 16px; height: 16px; border-radius: 4px; background: #00b96b; vertical-align: text-bottom;"></div> `#00b96b`, and Checkbox is not affected.
|
||||
In this way, we changed the primary color of Radio to <ColorChunk color="#00b96b" /></ColorChunk>, and Checkbox is not affected.
|
||||
|
||||
![component token](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*EMY0QrHFDjsAAAAAAAAAAAAAARQnAQ)
|
||||
|
||||
|
@ -39,7 +39,7 @@ const App: React.FC = () => (
|
||||
export default App;
|
||||
```
|
||||
|
||||
这将会得到一个以 <div style="display: inline-block; width: 16px; height: 16px; border-radius: 4px; background: #00b96b; vertical-align: text-bottom;"></div> `#00b96b` 为主色的主题,以 Button 组件为例可以看到相应的变化:
|
||||
这将会得到一个以 <ColorChunk color="#00b96b" /></ColorChunk> 为主色的主题,以 Button 组件为例可以看到相应的变化:
|
||||
|
||||
![themed button](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*CbF_RJfKEiwAAAAAAAAAAAAAARQnAQ)
|
||||
|
||||
@ -90,7 +90,7 @@ const App: React.FC = () => (
|
||||
export default App;
|
||||
```
|
||||
|
||||
通过这种方式,我们可以仅将 Radio 组件的主色改为 <div style="display: inline-block; width: 16px; height: 16px; border-radius: 4px; background: #00b96b; vertical-align: text-bottom;"></div> `#00b96b`,而不会影响其他组件。
|
||||
通过这种方式,我们可以仅将 Radio 组件的主色改为 <ColorChunk color="#00b96b" /></ColorChunk> 而不会影响其他组件。
|
||||
|
||||
![component token](https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*EMY0QrHFDjsAAAAAAAAAAAAAARQnAQ)
|
||||
|
||||
|
@ -14,7 +14,7 @@ This document will help you upgrade from antd `4.x` version to antd `5.x` versio
|
||||
### Design specification
|
||||
|
||||
- Basic rounded corner adjustment, changed from `2px` to four layers of radius, which are `2px` `4px` `6px` and `8px`. For example, radius of default Button is modified from `2px` to `6px`.
|
||||
- Primary color adjustment, changed from <div style="display: inline-block; width: 16px; height: 16px; border-radius: 4px; background: #1890ff; vertical-align: text-bottom;"></div> `#1890ff` to <div style="display: inline-block; width: 16px; height: 16px; border-radius: 4px; background: #1677ff; vertical-align: text-bottom;"></div> `#1677ff`.
|
||||
- Primary color adjustment, changed from <ColorChunk color="#1890ff" /></ColorChunk> to <ColorChunk color="#1677ff" /></ColorChunk>.
|
||||
- Global shadow optimization, adjusted from three layers of shadows to two layers, which are used in common components (Card .e.g) and popup components (Dropdown .e.g).
|
||||
- Overall reduction in wireframe usage.
|
||||
|
||||
@ -207,6 +207,15 @@ const v4Token = convertLegacyToken(mapToken);
|
||||
}
|
||||
```
|
||||
|
||||
Ant then remove antd less reference in your less file:
|
||||
|
||||
```diff
|
||||
// Your less file
|
||||
-- @import (reference) '~antd/es/style/themes/index';
|
||||
or
|
||||
-- @import '~antd/es/style/some-other-less-file-ref';
|
||||
```
|
||||
|
||||
### Remove babel-plugin-import
|
||||
|
||||
Remove `babel-plugin-import` from package.json and modify `.babelrc`:
|
||||
|
@ -14,7 +14,7 @@ title: 从 v4 到 v5
|
||||
### 设计规范调整
|
||||
|
||||
- 基础圆角调整,由统一的 `2px` 改为四级圆角,分别为 `2px` `4px` `6px` `8px`,分别应用于不同场景,比如默认尺寸的 Button 的圆角调整为了 `6px`。
|
||||
- 主色调整,由 <div style="display: inline-block; width: 16px; height: 16px; border-radius: 4px; background: #1890ff; vertical-align: text-bottom;"></div> `#1890ff` 改为 <div style="display: inline-block; width: 16px; height: 16px; border-radius: 4px; background: #1677ff; vertical-align: text-bottom;"></div> `#1677ff`。
|
||||
- 主色调整,由 <ColorChunk color="#1890ff" /></ColorChunk> 改为 <ColorChunk color="#1677ff" /></ColorChunk>。
|
||||
- 整体阴影调整,由原本的三级阴影调整为两级,分别用于常驻页面的组件(如 Card)和交互反馈(如 Dropdown)。
|
||||
- 部分组件内间距调整。
|
||||
- 整体去线框化。
|
||||
@ -199,6 +199,15 @@ const v4Token = convertLegacyToken(mapToken);
|
||||
}
|
||||
```
|
||||
|
||||
同时移除对 antd less 文件的直接引用:
|
||||
|
||||
```diff
|
||||
// Your less file
|
||||
-- @import (reference) '~antd/es/style/themes/index';
|
||||
or
|
||||
-- @import '~antd/es/style/some-other-less-file-ref';
|
||||
```
|
||||
|
||||
### 移除 babel-plugin-import
|
||||
|
||||
从 package.json 中移除 `babel-plugin-import`,并从 `.babelrc` 移除该插件:
|
||||
|
18
package.json
18
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "5.0.4",
|
||||
"version": "5.0.5",
|
||||
"description": "An enterprise-class UI design language and React components implementation",
|
||||
"title": "Ant Design",
|
||||
"keywords": [
|
||||
@ -158,11 +158,8 @@
|
||||
"shallowequal": "^1.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design/bisheng-plugin": "^3.3.0-alpha.4",
|
||||
"@ant-design/hitu": "^0.0.0-alpha.13",
|
||||
"@ant-design/tools": "^16.1.0-alpha.2",
|
||||
"@babel/eslint-plugin": "^7.19.1",
|
||||
"@docsearch/css": "^3.0.0",
|
||||
"@emotion/babel-preset-css-prop": "^11.10.0",
|
||||
"@emotion/css": "^11.10.5",
|
||||
"@emotion/react": "^11.10.4",
|
||||
@ -178,7 +175,7 @@
|
||||
"@types/jest": "^29.0.0",
|
||||
"@types/jest-axe": "^3.5.3",
|
||||
"@types/jest-environment-puppeteer": "^5.0.0",
|
||||
"@types/jest-image-snapshot": "^5.1.0",
|
||||
"@types/jest-image-snapshot": "^6.1.0",
|
||||
"@types/jquery": "^3.5.14",
|
||||
"@types/lodash": "^4.14.139",
|
||||
"@types/prismjs": "^1.26.0",
|
||||
@ -199,19 +196,14 @@
|
||||
"antd-img-crop": "^4.2.8",
|
||||
"antd-token-previewer": "^1.1.0-6",
|
||||
"array-move": "^4.0.0",
|
||||
"babel-plugin-add-react-displayname": "^0.0.5",
|
||||
"bundlesize2": "^0.0.31",
|
||||
"chalk": "^4.0.0",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"concurrently": "^7.0.0",
|
||||
"cross-env": "^7.0.0",
|
||||
"css-minimizer-webpack-plugin": "^1.3.0",
|
||||
"dekko": "^0.2.1",
|
||||
"docsearch-react-fork": "^0.0.0-alpha.0",
|
||||
"docsearch.js": "^2.6.3",
|
||||
"dumi": "^2.0.2",
|
||||
"duplicate-package-checker-webpack-plugin": "^3.0.0",
|
||||
"enquire-js": "^0.2.1",
|
||||
"esbuild-loader": "^2.13.1",
|
||||
"eslint": "^8.0.0",
|
||||
"eslint-config-airbnb": "^19.0.0",
|
||||
@ -228,7 +220,6 @@
|
||||
"fast-glob": "^3.2.11",
|
||||
"fetch-jsonp": "^1.1.3",
|
||||
"fs-extra": "^11.0.0",
|
||||
"full-icu": "^1.3.0",
|
||||
"gh-pages": "^4.0.0",
|
||||
"glob": "^8.0.1",
|
||||
"highlight.js": "^11.5.0",
|
||||
@ -237,9 +228,7 @@
|
||||
"identity-obj-proxy": "^3.0.0",
|
||||
"immer": "^9.0.1",
|
||||
"immutability-helper": "^3.0.0",
|
||||
"increase-memory-limit": "^1.0.7",
|
||||
"inquirer": "^9.1.2",
|
||||
"intersection-observer": "^0.12.0",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"jest": "^29.0.0",
|
||||
"jest-axe": "^7.0.0",
|
||||
@ -275,7 +264,6 @@
|
||||
"react-dom": "^18.0.0",
|
||||
"react-draggable": "^4.4.3",
|
||||
"react-fast-marquee": "^1.2.1",
|
||||
"react-github-button": "^0.1.11",
|
||||
"react-highlight-words": "^0.18.0",
|
||||
"react-infinite-scroll-component": "^6.1.0",
|
||||
"react-resizable": "^3.0.1",
|
||||
@ -286,7 +274,7 @@
|
||||
"remark-cli": "^11.0.0",
|
||||
"remark-lint": "^9.0.0",
|
||||
"remark-preset-lint-recommended": "^6.0.0",
|
||||
"rome": "^10.0.1",
|
||||
"rome": "^11.0.0",
|
||||
"semver": "^7.3.5",
|
||||
"simple-git": "^3.0.0",
|
||||
"size-limit": "^8.1.0",
|
||||
|
@ -11,19 +11,19 @@ const getTokenList = (list, source) =>
|
||||
desc:
|
||||
item.comment?.blockTags
|
||||
?.find((tag) => tag.tag === '@desc')
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '-',
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '',
|
||||
descEn:
|
||||
item.comment?.blockTags
|
||||
?.find((tag) => tag.tag === '@descEN')
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '-',
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '',
|
||||
name:
|
||||
item.comment?.blockTags
|
||||
?.find((tag) => tag.tag === '@nameZH')
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '-',
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '',
|
||||
nameEn:
|
||||
item.comment?.blockTags
|
||||
?.find((tag) => tag.tag === '@nameEN')
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '-',
|
||||
?.content.reduce((result, str) => result.concat(str.text), '') || '',
|
||||
}));
|
||||
|
||||
function main() {
|
||||
|
@ -21,6 +21,7 @@ const DEPRECIATED_VERSION = {
|
||||
'https://github.com/ant-design/ant-design/issues/37931',
|
||||
],
|
||||
'4.24.0': ['https://github.com/ant-design/ant-design/issues/38371'],
|
||||
'5.0.4': ['https://github.com/ant-design/ant-design/issues/39284'],
|
||||
};
|
||||
|
||||
function matchDeprecated(version) {
|
||||
|
19
typings/custom-typings.d.ts
vendored
19
typings/custom-typings.d.ts
vendored
@ -8,14 +8,6 @@ declare module '*.svg' {
|
||||
export default src;
|
||||
}
|
||||
|
||||
declare module 'bisheng/collect';
|
||||
|
||||
declare module 'bisheng/router';
|
||||
|
||||
declare module 'react-github-button';
|
||||
|
||||
declare module 'jsonml.js/*';
|
||||
|
||||
declare module 'rc-pagination/*';
|
||||
|
||||
declare module 'rc-util*';
|
||||
@ -24,17 +16,10 @@ declare module 'rc-checkbox';
|
||||
|
||||
declare module 'rc-rate';
|
||||
|
||||
declare module 'jsonml.js/*';
|
||||
|
||||
declare module '*.json' {
|
||||
const value: any;
|
||||
export const version: string;
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module 'docsearch-react-fork/style/modal';
|
||||
|
||||
declare module 'docsearch-react-fork/modal' {
|
||||
import { DocSearchModal as value } from 'docsearch-react-fork';
|
||||
export const DocSearchModal = value;
|
||||
}
|
||||
|
||||
declare module 'docsearch.js';
|
||||
|
Loading…
Reference in New Issue
Block a user