Merge branch 'next' into feat/masonry-v6

This commit is contained in:
afc163 2025-01-21 14:39:33 +08:00 committed by GitHub
commit 1cd065f767
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
616 changed files with 23711 additions and 7719 deletions

View File

@ -111,12 +111,14 @@ const SemanticPreview: React.FC<SemanticPreviewProps> = (props) => {
const targetElement = containerRef.current?.querySelector<HTMLElement>(`.${targetClassName}`);
const containerRect = containerRef.current?.getBoundingClientRect();
const targetRect = targetElement?.getBoundingClientRect();
setMarkPos([
(targetRect?.left || 0) - (containerRect?.left || 0),
(targetRect?.top || 0) - (containerRect?.top || 0),
targetRect?.width || 0,
targetRect?.height || 0,
]);
timerRef.current = setTimeout(() => {
setPositionMotion(true);
}, 10);

View File

@ -1,5 +1,5 @@
import { useEffect, useRef } from 'react';
import { removeCSS, updateCSS } from 'rc-util/lib/Dom/dynamicCSS';
import { removeCSS, updateCSS } from '@rc-component/util/lib/Dom/dynamicCSS';
import theme from '../../components/theme';

View File

@ -27,10 +27,10 @@ const { _InternalPanelDoNotUseOrYouWillBeFired: TourDoNotUseOrYouWillBeFired } =
const { _InternalPanelDoNotUseOrYouWillBeFired: FloatButtonDoNotUseOrYouWillBeFired } = FloatButton;
const SAMPLE_CONTENT_EN =
'Ant Design 5.0 use CSS-in-JS technology to provide dynamic & mix theme ability. And which use component level CSS-in-JS solution get your application a better performance.';
'Ant Design use CSS-in-JS technology to provide dynamic & mix theme ability. And which use component level CSS-in-JS solution get your application a better performance.';
const SAMPLE_CONTENT_CN =
'Ant Design 5.0 使用 CSS-in-JS 技术以提供动态与混合主题的能力。与此同时,我们使用组件级别的 CSS-in-JS 解决方案,让你的应用获得更好的性能。';
'Ant Design 使用 CSS-in-JS 技术以提供动态与混合主题的能力。与此同时,我们使用组件级别的 CSS-in-JS 解决方案,让你的应用获得更好的性能。';
const locales = {
cn: {
@ -158,7 +158,7 @@ const ComponentsList: React.FC = () => {
title: 'Modal',
type: 'update',
node: (
<ModalDoNotUseOrYouWillBeFired title="Ant Design 5.0" width={300}>
<ModalDoNotUseOrYouWillBeFired title="Ant Design" width={300}>
{locale.sampleContent}
</ModalDoNotUseOrYouWillBeFired>
),
@ -210,7 +210,7 @@ const ComponentsList: React.FC = () => {
type: 'new',
node: (
<TourDoNotUseOrYouWillBeFired
title="Ant Design 5.0"
title="Ant Design"
description={locale.tour}
style={{ width: isMobile ? 'auto' : 350 }}
current={3}
@ -255,7 +255,7 @@ const ComponentsList: React.FC = () => {
node: (
<Alert
style={{ width: 400 }}
message="Ant Design 5.0"
message="Ant Design"
description={locale.sampleContent}
closable={{ closeIcon: true, disabled: true }}
/>

View File

@ -28,7 +28,7 @@ const { _InternalPanelDoNotUseOrYouWillBeFired: InternalMessage } = message;
const locales = {
cn: {
range: '设置范围',
text: 'Ant Design 5.0 使用 CSS-in-JS 技术以提供动态与混合主题的能力。与此同时,我们使用组件级别的 CSS-in-JS 解决方案,让你的应用获得更好的性能。',
text: 'Ant Design 使用 CSS-in-JS 技术以提供动态与混合主题的能力。与此同时,我们使用组件级别的 CSS-in-JS 解决方案,让你的应用获得更好的性能。',
infoText: '信息内容展示',
dropdown: '下拉菜单',
finished: '已完成',
@ -45,11 +45,11 @@ const locales = {
dashed: '虚线按钮',
icon: '图标按钮',
hello: '你好Ant Design!',
release: 'Ant Design 5.0 正式发布!',
release: 'Ant Design 6.0 正式发布!',
},
en: {
range: 'Set Range',
text: 'Ant Design 5.0 use CSS-in-JS technology to provide dynamic & mix theme ability. And which use component level CSS-in-JS solution get your application a better performance.',
text: 'Ant Design use CSS-in-JS technology to provide dynamic & mix theme ability. And which use component level CSS-in-JS solution get your application a better performance.',
infoText: 'Info Text',
dropdown: 'Dropdown',
finished: 'Finished',
@ -66,7 +66,7 @@ const locales = {
dashed: 'Dashed',
icon: 'Icon',
hello: 'Hello, Ant Design!',
release: 'Ant Design 5.0 is released!',
release: 'Ant Design 6.0 is released!',
},
};
@ -109,7 +109,7 @@ const ComponentsBlock: React.FC = () => {
return (
<Tilt options={{ max: 20, glare: true, scale: 1 }} className={styles.holder}>
<ModalPanel title="Ant Design 5.0" width="100%">
<ModalPanel title="Ant Design" width="100%">
{locale.text}
</ModalPanel>
<Alert message={locale.infoText} type="info" />

View File

@ -156,7 +156,7 @@ const PreviewBanner: React.FC<Readonly<React.PropsWithChildren>> = (props) => {
</Suspense>
<div className={styles.mask} />
<Typography className={styles.typography}>
<h1>Ant Design 5.0</h1>
<h1>Ant Design</h1>
<p>{locale.slogan}</p>
</Typography>
<Flex gap="middle" className={styles.btnWrap}>

View File

@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { ColorPicker, Flex, Input } from 'antd';
import { createStyles } from 'antd-style';
import type { ColorPickerProps, GetProp } from 'antd';
import { createStyles } from 'antd-style';
import { generateColor } from 'antd/es/color-picker/util';
import classNames from 'classnames';
@ -61,7 +61,7 @@ const DebouncedColorPicker: React.FC<React.PropsWithChildren<ThemeColorPickerPro
<ColorPicker
value={value}
onChange={setValue}
presets={[{ label: 'PresetColors', colors: PRESET_COLORS }]}
presets={[{ label: 'PresetColors', key: 'PresetColors', colors: PRESET_COLORS }]}
>
{children}
</ColorPicker>

View File

@ -1,12 +1,12 @@
import * as React from 'react';
import { defaultAlgorithm, defaultTheme } from '@ant-design/compatible';
import { FastColor } from '@ant-design/fast-color';
import {
BellOutlined,
FolderOutlined,
HomeOutlined,
QuestionCircleOutlined,
} from '@ant-design/icons';
import { TinyColor } from '@ctrl/tinycolor';
import type { ColorPickerProps, GetProp, MenuProps, ThemeConfig } from 'antd';
import {
Breadcrumb,
@ -56,7 +56,7 @@ const TokenChecker: React.FC = () => {
const locales = {
cn: {
themeTitle: '定制主题,随心所欲',
themeDesc: 'Ant Design 5.0 开放更多样式算法,让你定制主题更简单',
themeDesc: 'Ant Design 开放更多样式算法,让你定制主题更简单',
customizeTheme: '定制主题',
myTheme: '我的主题',
@ -73,7 +73,7 @@ const locales = {
},
en: {
themeTitle: 'Flexible theme customization',
themeDesc: 'Ant Design 5.0 enable extendable algorithm, make custom theme easier',
themeDesc: 'Ant Design enable extendable algorithm, make custom theme easier',
customizeTheme: 'Customize Theme',
myTheme: 'My Theme',
@ -324,7 +324,7 @@ const ThemesInfo: Record<THEME, Partial<ThemeData>> = {
const normalize = (value: number) => value / 255;
function rgbToColorMatrix(color: string) {
const rgb = new TinyColor(color).toRgb();
const rgb = new FastColor(color).toRgb();
const { r, g, b } = rgb;
const invertValue = normalize(r) * 100;
@ -478,7 +478,7 @@ const Theme: React.FC = () => {
alt="antd logo"
/>
</div>
<h1>Ant Design 5.0</h1>
<h1>Ant Design</h1>
</div>
<Flex className={styles.menu} gap="middle">
<BellOutlined />

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import type { ColorInput } from '@ctrl/tinycolor';
import { TinyColor } from '@ctrl/tinycolor';
import { FastColor } from '@ant-design/fast-color';
import type { ColorInput } from '@ant-design/fast-color';
import { createStyles } from 'antd-style';
const useStyle = createStyles(({ token, css }) => ({
@ -22,7 +22,7 @@ const useStyle = createStyles(({ token, css }) => ({
}));
interface ColorChunkProps {
value?: ColorInput;
value: ColorInput;
}
const ColorChunk: React.FC<React.PropsWithChildren<ColorChunkProps>> = (props) => {
@ -30,7 +30,7 @@ const ColorChunk: React.FC<React.PropsWithChildren<ColorChunkProps>> = (props) =
const { value, children } = props;
const dotColor = React.useMemo(() => {
const _color = new TinyColor(value).toHex8String();
const _color = new FastColor(value).toHexString();
return _color.endsWith('ff') ? _color.slice(0, -2) : _color;
}, [value]);

View File

@ -154,7 +154,9 @@ const ComponentMeta: React.FC<ComponentMetaProps> = (props) => {
colon={false}
column={1}
style={{ marginTop: token.margin }}
labelStyle={{ paddingInlineEnd: token.padding, width: 56 }}
styles={{
label: { paddingInlineEnd: token.padding, width: 56 },
}}
items={
[
{

View File

@ -157,7 +157,7 @@ const SubTokenTable: React.FC<SubTokenTableProps> = (props) => {
{title}
<Popover
title={null}
overlayStyle={{ width: 400 }}
styles={{ root: { width: 400 } }}
content={
<Typography>
{/* <SourceCode lang="jsx">{code}</SourceCode> */}

View File

@ -1,7 +1,7 @@
import React from 'react';
import toArray from '@rc-component/util/lib/Children/toArray';
import { Image } from 'antd';
import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
interface ImagePreviewProps {
className?: string;

View File

@ -0,0 +1,80 @@
import React, { Suspense, useEffect, useState } from 'react';
import { Tooltip } from 'antd';
import { FormattedMessage } from 'dumi';
import { ping } from '../../utils';
let pingDeferrer: PromiseLike<boolean>;
const codeBlockJs =
'https://renderoffice.a' +
'lipay' +
'objects.com/p' +
'/yuyan/180020010001206410/parseFileData-v1.0.1.js';
function useShowCodeBlockButton() {
const [showCodeBlockButton, setShowCodeBlockButton] = useState(false);
useEffect(() => {
pingDeferrer ??= new Promise<boolean>((resolve) => {
ping((status) => {
if (status !== 'timeout' && status !== 'error') {
// Async insert `codeBlockJs` into body end
const script = document.createElement('script');
script.src = codeBlockJs;
script.async = true;
document.body.appendChild(script);
return resolve(true);
}
return resolve(false);
});
});
pingDeferrer.then(setShowCodeBlockButton);
}, []);
return showCodeBlockButton;
}
interface CodeBlockButtonProps {
title?: string;
dependencies: Record<PropertyKey, string>;
jsx: string;
}
const CodeBlockButton: React.FC<CodeBlockButtonProps> = ({ title, dependencies = {}, jsx }) => {
const showCodeBlockButton = useShowCodeBlockButton();
const codeBlockPrefillConfig = {
title: `${title} - antd@${dependencies.antd}`,
js: `${
/import React(\D*)from 'react';/.test(jsx) ? '' : `import React from 'react';\n`
}import { createRoot } from 'react-dom/client';\n${jsx.replace(
/export default/,
'const ComponentDemo =',
)}\n\ncreateRoot(mountNode).render(<ComponentDemo />);\n`,
css: '',
json: JSON.stringify({ name: 'antd-demo', dependencies }, null, 2),
};
return showCodeBlockButton ? (
<Tooltip title={<FormattedMessage id="app.demo.codeblock" />}>
<div className="code-box-code-action">
<img
alt="codeblock"
src="https://mdn.alipayobjects.com/huamei_wtld8u/afts/img/A*K8rjSJpTNQ8AAAAAAAAAAAAADhOIAQ/original"
className="code-box-codeblock"
onClick={() => {
openHituCodeBlock(JSON.stringify(codeBlockPrefillConfig));
}}
/>
</div>
</Tooltip>
) : null;
};
export default (props: CodeBlockButtonProps) => (
<Suspense>
<CodeBlockButton {...props} />
</Suspense>
);

View File

@ -16,11 +16,10 @@ import EditButton from '../../common/EditButton';
import CodePenIcon from '../../icons/CodePenIcon';
import CodeSandboxIcon from '../../icons/CodeSandboxIcon';
import ExternalLinkIcon from '../../icons/ExternalLinkIcon';
import RiddleIcon from '../../icons/RiddleIcon';
import DemoContext from '../../slots/DemoContext';
import type { SiteContextProps } from '../../slots/SiteContext';
import SiteContext from '../../slots/SiteContext';
import { ping } from '../../utils';
import CodeBlockButton from './CodeBlockButton';
import type { AntdPreviewerProps } from './Previewer';
const { ErrorBoundary } = Alert;
@ -39,27 +38,6 @@ const track = ({ type, demo }: { type: string; demo: string }) => {
window.gtag('event', 'demo', { event_category: type, event_label: demo });
};
let pingDeferrer: PromiseLike<boolean>;
function useShowRiddleButton() {
const [showRiddleButton, setShowRiddleButton] = useState(false);
useEffect(() => {
pingDeferrer ??= new Promise<boolean>((resolve) => {
ping((status) => {
if (status !== 'timeout' && status !== 'error') {
return resolve(true);
}
return resolve(false);
});
});
pingDeferrer.then(setShowRiddleButton);
}, []);
return showRiddleButton;
}
const useStyle = createStyles(({ token }) => {
const { borderRadius } = token;
return {
@ -98,7 +76,7 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
title,
description,
originDebug,
jsx,
jsx = '',
style,
compact,
background,
@ -117,7 +95,6 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
const entryName = 'index.tsx';
const entryCode = asset.dependencies[entryName].value;
const showRiddleButton = useShowRiddleButton();
const previewDemo = useRef<React.ReactNode>(null);
const demoContainer = useRef<HTMLElement>(null);
@ -127,11 +104,10 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
setSource: setLiveDemoSource,
} = useLiveDemo(asset.id, {
iframe: Boolean(iframe),
containerRef: demoContainer,
containerRef: demoContainer as React.RefObject<HTMLElement>,
});
const anchorRef = useRef<HTMLAnchorElement>(null);
const codeSandboxIconRef = useRef<HTMLFormElement>(null);
const riddleIconRef = useRef<HTMLFormElement>(null);
const codepenIconRef = useRef<HTMLFormElement>(null);
const [codeExpand, setCodeExpand] = useState<boolean>(false);
const { theme } = useContext<SiteContextProps>(SiteContext);
@ -278,18 +254,6 @@ const CodePreviewer: React.FC<AntdPreviewerProps> = (props) => {
js_pre_processor: 'typescript',
};
const riddlePrefillConfig = {
title: `${localizedTitle} - antd@${dependencies.antd}`,
js: `${
/import React(\D*)from 'react';/.test(jsx) ? '' : `import React from 'react';\n`
}import { createRoot } from 'react-dom/client';\n${jsx.replace(
/export default/,
'const ComponentDemo =',
)}\n\ncreateRoot(mountNode).render(<ComponentDemo />);\n`,
css: '',
json: JSON.stringify({ name: 'antd-demo', dependencies }, null, 2),
};
// Reorder source code
let parsedSourceCode = suffix === 'tsx' ? entryCode : jsx;
let importReactContent = "import React from 'react';";
@ -324,7 +288,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
main: 'index.js',
dependencies: {
...dependencies,
'rc-util': pkgDependencyList['rc-util'],
'@rc-component/util': pkgDependencyList['@rc-component/util'],
react: '^18.0.0',
'react-dom': '^18.0.0',
'react-scripts': '^5.0.0',
@ -440,24 +404,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
<CodeSandboxIcon className="code-box-codesandbox" />
</Tooltip>
</form>
{showRiddleButton ? (
<form
className="code-box-code-action"
action="//riddle.alibaba-inc.com/riddles/define"
method="POST"
target="_blank"
ref={riddleIconRef}
onClick={() => {
track({ type: 'riddle', demo: asset.id });
riddleIconRef.current?.submit();
}}
>
<input type="hidden" name="data" value={JSON.stringify(riddlePrefillConfig)} />
<Tooltip title={<FormattedMessage id="app.demo.riddle" />}>
<RiddleIcon className="code-box-riddle" />
</Tooltip>
</form>
) : null}
<CodeBlockButton title={localizedTitle} dependencies={dependencies} jsx={jsx} />
<Tooltip title={<FormattedMessage id="app.demo.stackblitz" />}>
<span
className="code-box-code-action"

View File

@ -7,6 +7,7 @@ import DesignPreviewer from './DesignPreviewer';
export interface AntdPreviewerProps extends IPreviewerProps {
originDebug?: IPreviewerProps['debug'];
jsx?: string;
}
const Previewer: React.FC<AntdPreviewerProps> = (props) => {

View File

@ -0,0 +1,91 @@
import React, { Suspense, useEffect, useRef, useState } from 'react';
import { Tooltip } from 'antd';
import { FormattedMessage } from 'dumi';
import type { IPreviewerProps } from 'dumi';
import RiddleIcon from '../../icons/RiddleIcon';
import { ping } from '../../utils';
let pingDeferrer: PromiseLike<boolean>;
function useShowRiddleButton() {
const [showRiddleButton, setShowRiddleButton] = useState(false);
useEffect(() => {
pingDeferrer ??= new Promise<boolean>((resolve) => {
ping((status) => {
if (status !== 'timeout' && status !== 'error') {
return resolve(true);
}
return resolve(false);
});
});
pingDeferrer.then(setShowRiddleButton);
}, []);
return showRiddleButton;
}
interface RiddleButtonProps {
title?: string;
dependencies: Record<PropertyKey, string>;
jsx: string;
track: ({
type,
demo,
}: {
type: string;
demo: string;
}) => void;
asset: IPreviewerProps['asset'];
}
const RiddleButton: React.FC<RiddleButtonProps> = ({
title,
dependencies = {},
jsx,
track,
asset,
}) => {
const riddleIconRef = useRef<HTMLFormElement>(null);
const showRiddleButton = useShowRiddleButton();
const riddlePrefillConfig = {
title: `${title} - antd@${dependencies.antd}`,
js: `${
/import React(\D*)from 'react';/.test(jsx) ? '' : `import React from 'react';\n`
}import { createRoot } from 'react-dom/client';\n${jsx.replace(
/export default/,
'const ComponentDemo =',
)}\n\ncreateRoot(mountNode).render(<ComponentDemo />);\n`,
css: '',
json: JSON.stringify({ name: 'antd-demo', dependencies }, null, 2),
};
return showRiddleButton ? (
<form
className="code-box-code-action"
action="//riddle.alibaba-inc.com/riddles/define"
method="POST"
target="_blank"
ref={riddleIconRef}
onClick={() => {
track({ type: 'riddle', demo: asset.id });
riddleIconRef.current?.submit();
}}
>
<input type="hidden" name="data" value={JSON.stringify(riddlePrefillConfig)} />
<Tooltip title={<FormattedMessage id="app.demo.riddle" />}>
<RiddleIcon className="code-box-riddle" />
</Tooltip>
</form>
) : null;
};
export default (props: RiddleButtonProps) => (
<Suspense>
<RiddleButton {...props} />
</Suspense>
);

View File

@ -1,6 +1,6 @@
// 用于 color.md 中的颜色对比
import React from 'react';
import { TinyColor } from '@ctrl/tinycolor';
import { FastColor } from '@ant-design/fast-color';
import { Flex, theme } from 'antd';
import { createStyles } from 'antd-style';
import tokenMeta from 'antd/es/version/token-meta.json';
@ -55,7 +55,7 @@ const useStyle = createStyles(({ token, css }) => {
});
function color2Rgba(color: string) {
return `#${new TinyColor(color).toHex8().toUpperCase()}`;
return `#${new FastColor(color).toHexString().toUpperCase()}`;
}
interface ColorCircleProps {

View File

@ -99,7 +99,7 @@ const TokenTable: FC<TokenTableProps> = ({ type }) => {
name: token,
desc: lang === 'cn' ? meta.desc : meta.descEn,
type: meta.type,
value: defaultToken[token],
value: defaultToken[token as keyof typeof defaultToken],
})),
[type, lang],
);

View File

@ -20,6 +20,7 @@ interface ChangelogInfo {
version: string;
changelog: string;
refs: string[];
contributors: string[];
releaseDate: string;
}
@ -160,14 +161,30 @@ const ParseChangelog: React.FC<{ changelog: string }> = (props) => {
return <span>{parsedChangelog}</span>;
};
const RefLinks: React.FC<{ refs: string[] }> = ({ refs }) => {
const RefLinks: React.FC<{ refs: string[]; contributors: string[] }> = ({ refs, contributors }) => {
const { styles } = useStyle();
return (
<>
{refs?.map((ref) => (
<a className={styles.linkRef} key={ref} href={ref} target="_blank" rel="noreferrer">
#{ref.match(/^.*\/(\d+)$/)?.[1]}
</a>
<React.Fragment key={ref}>
<a className={styles.linkRef} key={ref} href={ref} target="_blank" rel="noreferrer">
#{ref.match(/[^/]+$/)?.[0]}
</a>
</React.Fragment>
))}
{contributors?.map((contributor) => (
<React.Fragment key={contributor}>
<a
className={styles.linkRef}
key={contributor}
href={`https://github.com/${contributor}`}
target="_blank"
rel="noreferrer"
>
@{contributor}
</a>
</React.Fragment>
))}
</>
);
@ -178,7 +195,7 @@ const RenderChangelogList: React.FC<{ changelogList: ChangelogInfo[] }> = ({ cha
const { styles } = useStyle();
const len = changelogList.length;
for (let i = 0; i < len; i += 1) {
const { refs, changelog } = changelogList[i];
const { refs, changelog, contributors } = changelogList[i];
// Check if the next line is an image link and append it to the current line
if (i + 1 < len && changelogList[i + 1].changelog.trim().startsWith('<img')) {
const imgDom = new DOMParser().parseFromString(changelogList[i + 1].changelog, 'text/html');
@ -186,7 +203,7 @@ const RenderChangelogList: React.FC<{ changelogList: ChangelogInfo[] }> = ({ cha
elements.push(
<li key={i}>
<ParseChangelog changelog={changelog} />
<RefLinks refs={refs} />
<RefLinks refs={refs} contributors={contributors} />
<br />
<img
src={imgElement?.getAttribute('src') || ''}
@ -200,7 +217,7 @@ const RenderChangelogList: React.FC<{ changelogList: ChangelogInfo[] }> = ({ cha
elements.push(
<li key={i}>
<ParseChangelog changelog={changelog} />
<RefLinks refs={refs} />
<RefLinks refs={refs} contributors={contributors} />
</li>,
);
}

View File

@ -1,7 +1,7 @@
import React from 'react';
import { css, Global } from '@emotion/react';
import { updateCSS } from '@rc-component/util/lib/Dom/dynamicCSS';
import { useTheme } from 'antd-style';
import { updateCSS } from 'rc-util/lib/Dom/dynamicCSS';
export default () => {
const { anchorTop } = useTheme();

View File

@ -282,12 +282,13 @@ const GlobalDemoStyles: React.FC = () => {
cursor: pointer;
}
&-riddle {
width: 14px;
height: 14px;
&-codeblock {
width: 16px;
height: 16px;
overflow: hidden;
border: 0;
cursor: pointer;
max-width: 100% !important;
}
&-codesandbox {

View File

@ -1,5 +1,5 @@
import React from 'react';
import { TinyColor } from '@ctrl/tinycolor';
import { FastColor } from '@ant-design/fast-color';
import { css, Global } from '@emotion/react';
import { useTheme } from 'antd-style';
@ -410,7 +410,7 @@ const GlobalStyle: React.FC = () => {
background: ${demoGridColor};
&:nth-child(2n + 1) {
background: ${new TinyColor(demoGridColor).setAlpha(0.75).toHex8String()};
background: ${new FastColor(demoGridColor).setA(0.75).toHexString()};
}
}
@ -426,12 +426,12 @@ const GlobalStyle: React.FC = () => {
}
${antCls}-row .demo-col-1 {
background: ${new TinyColor(demoGridColor).setAlpha(0.75).toHexString()};
background: ${new FastColor(demoGridColor).setA(0.75).toHexString()};
}
${antCls}-row .demo-col-2,
.code-box-demo ${antCls}-row .demo-col-2 {
background: ${new TinyColor(demoGridColor).setAlpha(0.75).toHexString()};
background: ${new FastColor(demoGridColor).setA(0.75).toHexString()};
}
${antCls}-row .demo-col-3,
@ -442,7 +442,7 @@ const GlobalStyle: React.FC = () => {
${antCls}-row .demo-col-4,
.code-box-demo ${antCls}-row .demo-col-4 {
background: ${new TinyColor(demoGridColor).setAlpha(0.6).toHexString()};
background: ${new FastColor(demoGridColor).setA(0.6).toHexString()};
}
${antCls}-row .demo-col-5,

View File

@ -1,4 +1,5 @@
import React, { Suspense, useCallback, useEffect } from 'react';
import { Monitoring } from 'react-scan/monitoring';
import {
createCache,
extractStyle,
@ -12,7 +13,13 @@ import { getSandpackCssText } from '@codesandbox/sandpack-react';
import { theme as antdTheme, App } from 'antd';
import type { MappingAlgorithm } from 'antd';
import type { DirectionType, ThemeConfig } from 'antd/es/config-provider';
import { createSearchParams, useOutlet, useSearchParams, useServerInsertedHTML } from 'dumi';
import {
createSearchParams,
useOutlet,
useParams,
useSearchParams,
useServerInsertedHTML,
} from 'dumi';
import { DarkContext } from '../../hooks/useDark';
import useLayoutState from '../../hooks/useLayoutState';
@ -63,6 +70,7 @@ const getAlgorithm = (themes: ThemeName[] = []) =>
const GlobalLayout: React.FC = () => {
const outlet = useOutlet();
const { pathname } = useLocation();
const params = useParams();
const [searchParams, setSearchParams] = useSearchParams();
const [{ theme = [], direction, isMobile, bannerVisible = false }, setSiteState] =
useLayoutState<SiteState>({
@ -72,6 +80,9 @@ const GlobalLayout: React.FC = () => {
bannerVisible: false,
});
// TODO: This can be remove in v6
const useCssVar = searchParams.get('cssVar') !== 'false';
const updateSiteConfig = useCallback(
(props: SiteState) => {
setSiteState((prev) => ({ ...prev, ...props }));
@ -152,8 +163,8 @@ const GlobalLayout: React.FC = () => {
() => ({
algorithm: getAlgorithm(theme),
token: { motion: !theme.includes('motion-off') },
cssVar: true,
hashed: false,
cssVar: useCssVar,
hashed: !useCssVar,
}),
[theme],
);
@ -222,7 +233,17 @@ const GlobalLayout: React.FC = () => {
>
<SiteContext.Provider value={siteContextValue}>
<SiteThemeProvider theme={themeConfig}>
<HappyProvider disabled={!theme.includes('happy-work')}>{content}</HappyProvider>
<HappyProvider disabled={!theme.includes('happy-work')}>
{content}
<Monitoring
apiKey="GhrCCNrHZHXlf4P6E03ntrFwhRLxJL30" // Safe to expose publically
url="https://monitoring.react-scan.com/api/v1/ingest"
commit={process.env.COMMIT_HASH}
branch={process.env.BRANCH}
params={params as Record<string, string>}
path={pathname}
/>
</HappyProvider>
</SiteThemeProvider>
</SiteContext.Provider>
</StyleProvider>

View File

@ -35,7 +35,7 @@
"app.demo.codepen": "Open in CodePen",
"app.demo.codesandbox": "Open in CodeSandbox",
"app.demo.stackblitz": "Open in Stackblitz",
"app.demo.riddle": "Open in Riddle",
"app.demo.codeblock": "Open in Hitu",
"app.demo.separate": "Open in a new window",
"app.demo.online": "Online Address",
"app.home.introduce": "A design system for enterprise-level products. Create an efficient and enjoyable work experience.",

View File

@ -35,7 +35,7 @@
"app.demo.codepen": "在 CodePen 中打开",
"app.demo.codesandbox": "在 CodeSandbox 中打开",
"app.demo.stackblitz": "在 Stackblitz 中打开",
"app.demo.riddle": "在 Riddle 中打开",
"app.demo.codeblock": "在海兔中打开",
"app.demo.separate": "在新窗口打开",
"app.demo.online": "线上地址",
"app.home.introduce": "企业级产品设计体系,创造高效愉悦的工作体验",

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { removeCSS, updateCSS } from '@rc-component/util/lib/Dom/dynamicCSS';
import { createStyles } from 'antd-style';
import { removeCSS, updateCSS } from 'rc-util/lib/Dom/dynamicCSS';
import useLocale from '../../../hooks/useLocale';

View File

@ -13,7 +13,7 @@ import {
UsergroupAddOutlined,
ZhihuOutlined,
} from '@ant-design/icons';
import { TinyColor } from '@ctrl/tinycolor';
import { FastColor } from '@ant-design/fast-color';
import { createStyles } from 'antd-style';
import getAlphaColor from 'antd/es/theme/util/getAlphaColor';
import { FormattedMessage, Link } from 'dumi';
@ -37,7 +37,7 @@ const locales = {
const useStyle = () => {
const { isMobile } = useContext(SiteContext);
return createStyles(({ token, css }) => {
const background = new TinyColor(getAlphaColor('#f0f3fa', '#fff'))
const background = new FastColor(getAlphaColor('#f0f3fa', '#fff'))
.onBackground(token.colorBgContainer)
.toHexString();

View File

@ -357,7 +357,7 @@ const Header: React.FC = () => {
<header className={headerClassName}>
{isMobile && (
<Popover
overlayClassName={styles.popoverMenu}
classNames={{ root: styles.popoverMenu }}
placement="bottomRight"
content={menu}
trigger="click"

View File

@ -5,7 +5,7 @@ on:
- cron: "0 0 * * *" # Run at 00:00 every day
permissions:
issues: write # Need write permission to modify issue assignees
issues: write
jobs:
reminder_job:
@ -15,16 +15,18 @@ jobs:
uses: actions/github-script@v7
with:
script: |
const daysBeforeReminder = 14;
const daysBeforeReminder = 14;
let page = 1;
const perPage = 100;
const reminderSignature = "This issue has been inactive for more than 14 days";
while (true) {
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
assignee: '*', // Filter assigned issues
assignee: '*',
per_page: perPage,
page: page,
});
@ -53,16 +55,30 @@ jobs:
);
if (daysInactive >= daysBeforeReminder && !hasLinkedPR) {
const assigneesMentions = issue.assignees
.map(user => `@${user.login}`)
.join(' ');
await github.rest.issues.createComment({
// get issue comments
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: `${assigneesMentions} 这个 issue 已经超过 14 天没有更新或关联 PR。如果您仍在处理这个 issue请更新进度如果您无法继续处理请联系维护者重新分配。\n\nThis issue has been inactive for more than 14 days without any updates or linked PR. If you are still working on this issue, please provide a progress update. If you are unable to continue, please contact the maintainers for reassignment.`,
});
// check if reminder has been sent
const hasReminder = comments.some(comment =>
comment.body.includes(reminderSignature)
);
if (!hasReminder) {
const assigneesMentions = issue.assignees
.map(user => `@${user.login}`)
.join(' ');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issue.number,
body: `${assigneesMentions} 这个 issue 已经超过 14 天没有更新或关联 PR。如果您仍在处理这个 issue请更新进度如果您无法继续处理请联系维护者重新分配。\n\nThis issue has been inactive for more than 14 days without any updates or linked PR. If you are still working on this issue, please provide a progress update. If you are unable to continue, please contact the maintainers for reassignment.`,
});
}
}
}

View File

@ -117,7 +117,7 @@ jobs:
cd ..
- name: Upload to Release
uses: softprops/action-gh-release@7b4da11513bf3f43f9999e90eabced41ab8bb048 # v2.2.0
uses: softprops/action-gh-release@01570a1f39cb168c169c802c3bceb9e93fb10974 # v2.1.0
with:
fail_on_unmatched_files: true
files: website.tar.gz

View File

@ -5,6 +5,8 @@ const compileModules = [
'@ant-design',
'countup.js',
'.pnpm',
'@asamuzakjp/css-color',
'@rc-component',
];
const ignoreList = [];

View File

@ -74,5 +74,6 @@
"5.22.1": [
"https://github.com/ant-design/ant-design/issues/51420",
"https://github.com/ant-design/ant-design/issues/51430"
]
],
"5.22.6": ["https://github.com/ant-design/ant-design/issues/52124"]
}

View File

@ -15,6 +15,83 @@ tag: vVERSION
---
## 5.23.1
`2025-01-13`
- 🆕 Add Tree leaf node className for differentiate node type. [#52274](https://github.com/ant-design/ant-design/pull/52274) [@EmilyyyLiu](https://github.com/EmilyyyLiu)
- 🐞 Fix DatePicker switch buttons is not hidden when `superPrevIcon/superNextIcon/prevIcon/nextIcon` is null. [#52327](https://github.com/ant-design/ant-design/pull/52327) [@afc163](https://github.com/afc163)
- 🐞 Fix Select throws `error not a valid selector` in Jest tests. [#51844](https://github.com/ant-design/ant-design/pull/51844) [@renovate](https://github.com/renovate)
- 🐞 Fix Layout.Sider under ConfigProvider directly, the `theme` not working. [#52302](https://github.com/ant-design/ant-design/pull/52302) [@zombieJ](https://github.com/zombieJ)
- 🐞 Fix Splitter lost previous state when re-expanding. [#52222](https://github.com/ant-design/ant-design/pull/52222) [@jjlstruggle](https://github.com/jjlstruggle)
- 🐞 Fix Table unexpected row selections when set `checkStrictly` to false in tree mode. [#52338](https://github.com/ant-design/ant-design/pull/52338) [@LeeSSHH](https://github.com/LeeSSHH)
- Button
- 🐞 Fix Button alignment and icon centering by adjusting the icon size for icon-only Buttons. [#52353](https://github.com/ant-design/ant-design/pull/52353) [@afc163](https://github.com/afc163)
- 💄 Fix Button missing `box-shadow` style. [#52304](https://github.com/ant-design/ant-design/pull/52304) [@zombieJ](https://github.com/zombieJ)
- RTL
- 💄 Fix Collapse arrow direction in RTL mode. [#52374](https://github.com/ant-design/ant-design/pull/52374) [@aojunhao123](https://github.com/aojunhao123)
- 💄 Fix Layout.Sider arrow direction in RTL mode. [#52374](https://github.com/ant-design/ant-design/pull/52374) [@aojunhao123](https://github.com/aojunhao123)
## 5.23.0
`2025-01-06`
- 🔥 TreeSelect support `maxCount` to limit the maximum number of selections. [#51759](https://github.com/ant-design/ant-design/pull/51759) [@aojunhao123](https://github.com/aojunhao123)
- 🔥 Modal `width` support responsive size. [#51653](https://github.com/ant-design/ant-design/pull/51653) [@zombieJ](https://github.com/zombieJ)
- 🔥 Splitter support `lazy` mode. [#51557](https://github.com/ant-design/ant-design/pull/51557) [@OysterD3](https://github.com/OysterD3)
- Button
- 🔥 Button `color` support full color palette. [#51550](https://github.com/ant-design/ant-design/pull/51550) [@OysterD3](https://github.com/OysterD3)
<img width="520" alt="Button Colors" src="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*ApyYQpXQQfgAAAAAAAAAAAAADgCCAQ/original">
- 🆕 Button support `loading={{ icon: ReactNode }}` to customize loading icon. [#51758](https://github.com/ant-design/ant-design/pull/51758) [@zhangchao-wooc](https://github.com/zhangchao-wooc)
- Menu
- 🐞 Fix Menu `extra` font size and vertical align issue. [#52217](https://github.com/ant-design/ant-design/pull/52217) [@guoyunhe](https://github.com/guoyunhe)
- 🆕 Menu add token `subMenuItemSelectedColor` to resolve submenu title color being overrided by `itemSelectedColor`. [#52182](https://github.com/ant-design/ant-design/pull/52182) [@afc163](https://github.com/afc163)
- 🆕 Semantic Props
- 🆕 ConfigProvider support Empty semantic props `classNames` and `styles`. [#52208](https://github.com/ant-design/ant-design/pull/52208) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider support Popconfirm semantic props `classNames` and `styles`. [#52126](https://github.com/ant-design/ant-design/pull/52126) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider support Popover semantic props `classNames` and `styles`. [#52110](https://github.com/ant-design/ant-design/pull/52110) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider support Tooltip semantic props `classNames` and `styles`. [#51872](https://github.com/ant-design/ant-design/pull/51872) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider support Descriptions semantic props `classNames` and `styles`. [#52120](https://github.com/ant-design/ant-design/pull/52120) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider support Slider semantic props `classNames` and `styles`. [#52185](https://github.com/ant-design/ant-design/pull/52185) [@thinkasany](https://github.com/thinkasany)
- 🆕 Transfer support `showSearch` config `defaultValue` & `placeholder`. [#52125](https://github.com/ant-design/ant-design/pull/52125) [@EmilyyyLiu](https://github.com/EmilyyyLiu)
- 🆕 Calendar now supports `showWeek` prop. [#52072](https://github.com/ant-design/ant-design/pull/52072) [@afc163](https://github.com/afc163)
- 🆕 Mentions support `onPopupScroll` props. [#51858](https://github.com/ant-design/ant-design/pull/51858) [@OysterD3](https://github.com/OysterD3)
- 🆕 Card support `bodyPaddingSM`, `headerPaddingSM`, `bodyPadding`, `headerPadding` component token. [#51762](https://github.com/ant-design/ant-design/pull/51762) [@thinkasany](https://github.com/thinkasany)
- 🆕 ColorPicker `presets` support `key` prop. [#51794](https://github.com/ant-design/ant-design/pull/51794) [@li-jia-nan](https://github.com/li-jia-nan)
- 🆕 Cascader support `optionSelectedColor` token. [#51769](https://github.com/ant-design/ant-design/pull/51769) [@thinkasany](https://github.com/thinkasany)
- Tree
- 🛠 Refactor Tree part code to Function Component for React 19 perf preparing. [#52209](https://github.com/ant-design/ant-design/pull/52209) [@li-jia-nan](https://github.com/li-jia-nan)
- 💄 Optimize Tree `disabled` & `selected` node display style. [#52173](https://github.com/ant-design/ant-design/pull/52173) [@EmilyyyLiu](https://github.com/EmilyyyLiu)
- 🐞 Fix Slider crash when `tipFormatter` is undefined. [#52184](https://github.com/ant-design/ant-design/pull/52184) [@thinkasany](https://github.com/thinkasany)
- 🐞 Fix Layout.Sider `trigger` style not correct. [#46a8eff](https://github.com/ant-design/ant-design/commit/46a8eff) [@Wxh16144](https://github.com/Wxh16144)
- Table
- 🐞 Fix Table `fixedright` is not working in `expandable`. [#52176](https://github.com/ant-design/ant-design/pull/52176) [@afc163](https://github.com/afc163)
- 🐞 Fix Table sticky scrollbar not working in rtl direction. [#52176](https://github.com/ant-design/ant-design/pull/52176) [@afc163](https://github.com/afc163)
- 💄 Optimize Flex to always reset `margin` & `padding` for customize component. [#52170](https://github.com/ant-design/ant-design/pull/52170) [@li-jia-nan](https://github.com/li-jia-nan)
- 🐞 Fix DatePicker.RangePicker `needConfirm` sometime can switch panel without confirm. [#52102](https://github.com/ant-design/ant-design/pull/52102) [@Zyf665](https://github.com/Zyf665)
- 💄 Optimize Collapse focus styles and items border radius. [#52086](https://github.com/ant-design/ant-design/pull/52086) [@aojunhao123](https://github.com/aojunhao123)
- ⌨️ Add Radio.Group default `name` prop to improve a11y. [#52076](https://github.com/ant-design/ant-design/pull/52076) [@aojunhao123](https://github.com/aojunhao123)
- ⌨️ Input.Search add `type=search` by default. [#52083](https://github.com/ant-design/ant-design/pull/52083) [@Kaikiat1126](https://github.com/Kaikiat1126)
- ⌨️ Improve Tabs focus style for keyboard operation. [#52002](https://github.com/ant-design/ant-design/pull/52002) [@aojunhao123](https://github.com/aojunhao123)
- Segmented
- ⌨️ Optimize Segmented focus style to improve a11y. [#51934](https://github.com/ant-design/ant-design/pull/51934) [@aojunhao123](https://github.com/aojunhao123)
- ⌨️ Segmented support `name` prop to improve a11y. [#51725](https://github.com/ant-design/ant-design/pull/51725) [@thinkasany](https://github.com/thinkasany)
- 📦 MISC: Reduce bundle size by replacing `@ctrl/tinycolor` with `@ant-design/fast-color`. [#52190](https://github.com/ant-design/ant-design/pull/52190) [#52157](https://github.com/ant-design/ant-design/pull/52157) [@aojunhao123](https://github.com/aojunhao123)
- ⌨️ Adjust Input, InputNumber, Mentions, Textarea clear icon from `span` to `button` to improve a11y. [#52180](https://github.com/ant-design/ant-design/pull/52180) [@li-jia-nan](https://github.com/li-jia-nan)
- 🐞 MISC: Fix build error when using React 19. [#52168](https://github.com/ant-design/ant-design/pull/52168) [@zombieJ](https://github.com/zombieJ)
- TypeScript
- 🤖 Adjust Table `ref` type to React.Ref. [#52205](https://github.com/ant-design/ant-design/pull/52205) [@li-jia-nan](https://github.com/li-jia-nan)
- 🤖 Calendar export CalendarMode type. [#52160](https://github.com/ant-design/ant-design/pull/52160) [@Kaikiat1126](https://github.com/Kaikiat1126)
## 5.22.7
`2024-12-27`
- 🐞 Fix Button text and icon not align. [#52132](https://github.com/ant-design/ant-design/pull/52132) [@afc163](https://github.com/afc163)
- 🐞 Fix Button throws `reactRender is not a function` under React 19. [#52105](https://github.com/ant-design/ant-design/pull/52105) [@afc163](https://github.com/afc163)
- TypeScript
- 🤖 Fix Menu interface type error from external module. [#51715](https://github.com/ant-design/ant-design/pull/51715) [@msyavuz](https://github.com/msyavuz)
## 5.22.6
`2024-12-23`
@ -2025,7 +2102,7 @@ tag: vVERSION
- 💄 Adjust Select, TreeSelect, Cascader always show the `arrow` by default when multiple. [#41028](https://github.com/ant-design/ant-design/pull/41028)
- 🐞 Fix Form `Form.Item.useStatus` problem with sever-side-rendering. [#40977](https://github.com/ant-design/ant-design/pull/40977) [@AndyBoat](https://github.com/AndyBoat)
- 🐞 MISC: Fix arrow shape in some components. [#40971](https://github.com/ant-design/ant-design/pull/40971)
- 🐞 Fix Layout throw `React does not recognize the `suffixCls` prop on a DOM element` warning. [#40969](https://github.com/ant-design/ant-design/pull/40969)
- 🐞 Fix Layout throw "React does not recognize the `suffixCls` prop on a DOM element" warning. [#40969](https://github.com/ant-design/ant-design/pull/40969)
- 🐞 Fix Watermark that text will be displayed when the picture loads abnormally. [#40770](https://github.com/ant-design/ant-design/pull/40770) [@OriginRing](https://github.com/OriginRing)
- 🐞 Image support flip function in preview mode. Fix Image `fallback` when used in ssr. [#40660](https://github.com/ant-design/ant-design/pull/40660)
- 🐞 Fix Typography component is not centered in the Select component. [#40422](https://github.com/ant-design/ant-design/pull/40422) [@Yuiai01](https://github.com/Yuiai01)

View File

@ -15,6 +15,83 @@ tag: vVERSION
---
## 5.23.1
`2025-01-13`
- 🆕 新增 Tree 组件叶子节点的 className 用于区分节点类型。[#52274](https://github.com/ant-design/ant-design/pull/52274) [@EmilyyyLiu](https://github.com/EmilyyyLiu)
- 🐞 修复 DatePicker `superPrevIcon/superNextIcon/prevIcon/nextIcon` 设置为 null 时切换按钮依旧存在的问题。[#52327](https://github.com/ant-design/ant-design/pull/52327) [@afc163](https://github.com/afc163)
- 🐞 修复 Select 组件在 jest 测试中报错 `not a valid selector` 的问题。[#51844](https://github.com/ant-design/ant-design/pull/51844) [@renovate](https://github.com/renovate)
- 🐞 修复 Layout.Sider 直接嵌套在 ConfigProvider 下时,`theme` 配置无效的问题。[#52302](https://github.com/ant-design/ant-design/pull/52302) [@zombieJ](https://github.com/zombieJ)
- 🐞 修复 Splitter 二次展开时丢失上一次状态的问题。[#52222](https://github.com/ant-design/ant-design/pull/52222) [@jjlstruggle](https://github.com/jjlstruggle)
- 🐞 修复 Table 树形展示且设置 `checkStrictly` 为 false 时,某些行被错误选中的问题。[#52338](https://github.com/ant-design/ant-design/pull/52338) [@LeeSSHH](https://github.com/LeeSSHH)
- Button
- 🐞 调整 Button 纯图标的大小从而修复按钮对齐和图标居中问题。[#52353](https://github.com/ant-design/ant-design/pull/52353) [@afc163](https://github.com/afc163)
- 💄 修复 Button 丢失阴影样式的问题。[#52304](https://github.com/ant-design/ant-design/pull/52304) [@zombieJ](https://github.com/zombieJ)
- RTL
- 💄 修复 Collapse 在 RTL 模式下的箭头方向。[#52374](https://github.com/ant-design/ant-design/pull/52374) [@aojunhao123](https://github.com/aojunhao123)
- 💄 修复 Layout.Sider 在 RTL 模式下的箭头方向。[#52374](https://github.com/ant-design/ant-design/pull/52374) [@aojunhao123](https://github.com/aojunhao123)
## 5.23.0
`2025-01-06`
- 🔥 TreeSelect 新增 `maxCount` 属性以限制最大选择数量。[#51759](https://github.com/ant-design/ant-design/pull/51759) [@aojunhao123](https://github.com/aojunhao123)
- 🔥 Modal `width` 支持响应式尺寸。[#51653](https://github.com/ant-design/ant-design/pull/51653) [@zombieJ](https://github.com/zombieJ)
- 🔥 Splitter 增加 `lazy` 模式。[#51557](https://github.com/ant-design/ant-design/pull/51557) [@OysterD3](https://github.com/OysterD3)
- Button
- 🔥 Button `color` 属性支持完整色板。[#51550](https://github.com/ant-design/ant-design/pull/51550) [@OysterD3](https://github.com/OysterD3)
<img width="520" alt="Button Colors" src="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*ApyYQpXQQfgAAAAAAAAAAAAADgCCAQ/original">
- 🆕 Button 组件新增 `loading={{ icon: ReactNode }}` 以自定义加载图标。[#51758](https://github.com/ant-design/ant-design/pull/51758) [@zhangchao-wooc](https://github.com/zhangchao-wooc)
- Menu
- 🆕 Menu 新增 token `subMenuItemSelectedColor`,避免 `itemSelectedColor` 覆盖子菜单标题样式。[#52182](https://github.com/ant-design/ant-design/pull/52182) [@afc163](https://github.com/afc163)
- 🐞 修复 Menu `extra` 字体大小和垂直居中对齐问题。[#52217](https://github.com/ant-design/ant-design/pull/52217) [@guoyunhe](https://github.com/guoyunhe)
- 🆕 语义化
- 🆕 ConfigProvider 支持 Empty 组件语义化 `classNames``styles`。[#52208](https://github.com/ant-design/ant-design/pull/52208) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider 支持 Slider 组件语义化 `classNames``styles`。[#52185](https://github.com/ant-design/ant-design/pull/52185) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider 支持 Popconfirm 组件语义化 `classNames``styles`。[#52126](https://github.com/ant-design/ant-design/pull/52126) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider 支持 Popover 组件语义化 `classNames``styles`。[#52110](https://github.com/ant-design/ant-design/pull/52110) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider 支持 Tooltip 组件语义化 `classNames``styles`。[#51872](https://github.com/ant-design/ant-design/pull/51872) [@thinkasany](https://github.com/thinkasany)
- 🆕 ConfigProvider 支持 Descriptions 组件语义化 `classNames``styles`。[#52120](https://github.com/ant-design/ant-design/pull/52120) [@thinkasany](https://github.com/thinkasany)
- Tree
- 🛠 重构 Tree 部分代码为 Function Component 以为 React 19 做更好性能准备。[#52209](https://github.com/ant-design/ant-design/pull/52209) [@li-jia-nan](https://github.com/li-jia-nan)
- 💄 优化 Tree `disabled``selected` 节点状态下的颜色展示。[#52173](https://github.com/ant-design/ant-design/pull/52173) [@EmilyyyLiu](https://github.com/EmilyyyLiu)
- 🆕 Transfer 支持 `showSearch` 配置 `defaultValue``placeholder`。[#52125](https://github.com/ant-design/ant-design/pull/52125) [@EmilyyyLiu](https://github.com/EmilyyyLiu)
- 🆕 Calendar 支持 `showWeek` 属性用于显示周数列。[#52072](https://github.com/ant-design/ant-design/pull/52072) [@afc163](https://github.com/afc163)
- 🆕 Mentions 新增 `onPopupScroll` 属性。[#51858](https://github.com/ant-design/ant-design/pull/51858) [@OysterD3](https://github.com/OysterD3)
- 🆕 Card 增加 `bodyPaddingSM`、`headerPaddingSM`、`bodyPadding`、`headerPadding` 组件 token。[#51762](https://github.com/ant-design/ant-design/pull/51762) [@thinkasany](https://github.com/thinkasany)
- 🆕 ColorPicker `presets` 支持传入 `key`。[#51794](https://github.com/ant-design/ant-design/pull/51794) [@li-jia-nan](https://github.com/li-jia-nan)
- 🆕 Cascader 新增 `optionSelectedColor` token。[#51769](https://github.com/ant-design/ant-design/pull/51769) [@thinkasany](https://github.com/thinkasany)
- 🐞 修复 Layout.Sider `trigger` 样式不正确的问题。[#46a8eff](https://github.com/ant-design/ant-design/commit/46a8eff) [@Wxh16144](https://github.com/Wxh16144)
- Table
- 🐞 修复 Table `expandable` 中设置 `fixedright` 不生效的问题。[#52176](https://github.com/ant-design/ant-design/pull/52176) [@afc163](https://github.com/afc163)
- 🐞 修复 Table `sticky` 模式下水平固定滚动条在 rtl 模式下不生效的问题。[#52176](https://github.com/ant-design/ant-design/pull/52176) [@afc163](https://github.com/afc163)
- 💄 优化 Flex 使其在自定义渲染组件时总是重置 `margin`、`padding` 样式。[#52170](https://github.com/ant-design/ant-design/pull/52170) [@li-jia-nan](https://github.com/li-jia-nan)
- 🐞 修复 DatePicker.RangePicker `needConfirm` 模式偶尔在不确认仍然可以切换面板的问题。[#52102](https://github.com/ant-design/ant-design/pull/52102) [@Zyf665](https://github.com/Zyf665)
- 🐞 修复 Slider 当 `tipFormatter` 未定义时导致崩溃的问题。[#52184](https://github.com/ant-design/ant-design/pull/52184) [@thinkasany](https://github.com/thinkasany)
- 💄 优化 Collapse 聚焦样式以及折叠项圆角。[#52086](https://github.com/ant-design/ant-design/pull/52086) [@aojunhao123](https://github.com/aojunhao123)
- ⌨️ 为 Radio.Group 添加默认 `name` 属性以提升无障碍体验。[#52076](https://github.com/ant-design/ant-design/pull/52076) [@aojunhao123](https://github.com/aojunhao123)
- ⌨️ Input.Search 添加默认 `type=search` 类型。[#52083](https://github.com/ant-design/ant-design/pull/52083) [@Kaikiat1126](https://github.com/Kaikiat1126)
- ⌨️ 优化 Tabs 键盘操作时的焦点样式。[#52002](https://github.com/ant-design/ant-design/pull/52002) [@aojunhao123](https://github.com/aojunhao123)
- Segmented
- ⌨️ 优化 Segmented 聚焦样式以提升无障碍体验。[#51934](https://github.com/ant-design/ant-design/pull/51934) [@aojunhao123](https://github.com/aojunhao123)
- ⌨️ Segmented 支持 `name` 属性以提升无障碍体验。[#51725](https://github.com/ant-design/ant-design/pull/51725) [@thinkasany](https://github.com/thinkasany)
- 📦 MISC: 用 `@ant-design/fast-color` 替换 `@ctrl/tinycolor` 以降低打包体积。[#52190](https://github.com/ant-design/ant-design/pull/52190) [#52157](https://github.com/ant-design/ant-design/pull/52157) [@aojunhao123](https://github.com/aojunhao123)
- ⌨️ 调整 Input、InputNumber、Mentions、Textarea 组件清除图标从 `span` 元素更改为 `button` 元素,提高了可访问性和交互性。[#52180](https://github.com/ant-design/ant-design/pull/52180) [@li-jia-nan](https://github.com/li-jia-nan)
- 🐞 MISC: 修复 React 19 下构建报错的问题。[#52168](https://github.com/ant-design/ant-design/pull/52168) [@zombieJ](https://github.com/zombieJ)
- TypeScript
- 🤖 调整 Table `ref` 类型为 React.Ref。[#52205](https://github.com/ant-design/ant-design/pull/52205) [@li-jia-nan](https://github.com/li-jia-nan)
- 🤖 Calendar 导出 CalendarMode 类型。[#52160](https://github.com/ant-design/ant-design/pull/52160) [@Kaikiat1126](https://github.com/Kaikiat1126)
## 5.22.7
`2024-12-27`
- 🐞 修复 Button 文字和图标不对齐的问题。[#52132](https://github.com/ant-design/ant-design/pull/52132) [@afc163](https://github.com/afc163)
- 🐞 修复在 React 19 下点击 Button 时抛出 `reactRender is not a function` 错误的问题。[#52105](https://github.com/ant-design/ant-design/pull/52105) [@afc163](https://github.com/afc163)
- TypeScript
- 🤖 修复 Menu `component` 属性类型抛错。[#51715](https://github.com/ant-design/ant-design/pull/51715) [@msyavuz](https://github.com/msyavuz)
## 5.22.6
`2024-12-23`
@ -101,7 +178,7 @@ tag: vVERSION
- Form
- 🆕 Form.Item 支持隐藏 label。[#51524](https://github.com/ant-design/ant-design/pull/51524) [@crazyair](https://github.com/crazyair)
- 🐞 Form 移除了用于撑开 error 高度的 div将 errorDom 和 extraDom 用一个 div 包裹,并为该 div 设置了最小高度。[#51254](https://github.com/ant-design/ant-design/pull/51254) [@hongzzz](https://github.com/hongzzz)
- 🐞 Form 移除了用于撑开 error 高度的 div将 errorDom 和 extraDom 用一个 div 包裹,并为该 div 设置了最小高度。[#51254](https://github.com/ant-design/ant-design/pull/51254) [@hongzzz](https://github.com/hongzzz)
- 🐞 修复 Form 在字段触发 change 但是值没有变化时,`onValuesChange` 仍然会触发的问题。[#51437](https://github.com/ant-design/ant-design/pull/51437) [@crazyair](https://github.com/crazyair)
- 🆕 Form 支持在表单验证失败时scrollToFirstError 中的 focus 属性。[#51231](https://github.com/ant-design/ant-design/pull/51231) [@nathanlao](https://github.com/nathanlao)
- Table
@ -175,6 +252,7 @@ tag: vVERSION
- 💄 修改 Button `textHoverBg` 在悬浮状态下的背景色为 `colorFillTertiary`。[#51187](https://github.com/ant-design/ant-design/pull/51187) [@coding-ice](https://github.com/coding-ice)
- TypeScript
- 🤖 优化 Switch `eventHandler` 类型。[#51165](https://github.com/ant-design/ant-design/pull/51165) [@thinkasany](https://github.com/thinkasany)
## 5.21.3
`2024-10-09`
@ -223,17 +301,17 @@ tag: vVERSION
<img width="520" alt="Splitter" src="https://github.com/user-attachments/assets/25fc4e3c-1aa5-41bb-8f39-f34f7149e0f6">
- Button
- 🔥 Button 支持 `variant` 变体和 `color` 颜色属性,以支持更多组合样式。[#50051](https://github.com/ant-design/ant-design/pull/50051) [@coding-ice](https://github.com/coding-ice)
<img width="420" alt="Button" src="https://github.com/user-attachments/assets/cd5cb7fb-25e8-445f-b217-7fdd4ae0f9b4">
<img width="420" alt="Button" src="https://github.com/user-attachments/assets/cd5cb7fb-25e8-445f-b217-7fdd4ae0f9b4">
- 💄 Button 添加 `textColor`、`textHoverColor` 和 `textActiveColor` 三个 token。[#47870](https://github.com/ant-design/ant-design/pull/47870) [@madocto](https://github.com/madocto)
- FloatButton
- 🆕 FloatButton 组件支持 `placement` 属性,支持从四个方向弹出菜单。(实现方式改为 `position: absolute` + flex 布局,可能会对你现有的布局造成 breaking change请注意兼容[#50407](https://github.com/ant-design/ant-design/pull/50407) [@li-jia-nan](https://github.com/li-jia-nan)
<img width="300" alt="float button" src="https://github.com/user-attachments/assets/4b53c0f6-7bdd-4e2a-91cc-2fb804f6e6d3" />
<img width="300" alt="float button" src="https://github.com/user-attachments/assets/4b53c0f6-7bdd-4e2a-91cc-2fb804f6e6d3" />
- 💄 统一 FloatButton 和 FloatButton.Group 的按钮圆角。[#50513](https://github.com/ant-design/ant-design/pull/50513) [@Layouwen](https://github.com/Layouwen)
- 💄 FloatButton 组件的 `z-index` 加入 `useZIndex` 管理,兼容弹层类组件。[#50311](https://github.com/ant-design/ant-design/pull/50311) [@li-jia-nan](https://github.com/li-jia-nan)
- 🆕 FloatButton 支持传入 `htmlType` 属性。[#50892](https://github.com/ant-design/ant-design/pull/50892) [@li-jia-nan](https://github.com/li-jia-nan)
- Menu
- 🆕 Menu.Item 和 Dropdown 的 menu 支持 `extra` 属性。[#50431](https://github.com/ant-design/ant-design/pull/50431) [@coding-ice](https://github.com/coding-ice)
<img width="259" alt="menu extra" src="https://github.com/user-attachments/assets/fee57c43-b948-4f98-8a6b-0d94094a8a65">
<img width="259" alt="menu extra" src="https://github.com/user-attachments/assets/fee57c43-b948-4f98-8a6b-0d94094a8a65">
- 🐞 修复 Menu `popupStyle` 在 SubMenu 上失效的问题。[#50922](https://github.com/ant-design/ant-design/pull/50922) [@Wxh16144](https://github.com/Wxh16144)
- Table
- 🆕 Table 列支持配置 `minWidth` 属性。[#50416](https://github.com/ant-design/ant-design/pull/50416) [@linxianxi](https://github.com/linxianxi)
@ -2025,7 +2103,7 @@ tag: vVERSION
- 💄 调整 Select, TreeSelect, Cascader 在多选时总是默认显示下拉箭头。[#41028](https://github.com/ant-design/ant-design/pull/41028)
- 🐞 修复 Form 组件 `Form.Item.useStatus` 导致的服务端渲染问题。[#40977](https://github.com/ant-design/ant-design/pull/40977) [@AndyBoat](https://github.com/AndyBoat)
- 🐞 杂项:修复部分组件箭头形状问题。[#40971](https://github.com/ant-design/ant-design/pull/40971)
- 🐞 修复 Layout 报错 `React does not recognize the `suffixCls` prop on a DOM element` 的问题。[#40969](https://github.com/ant-design/ant-design/pull/40969)
- 🐞 修复 Layout 报错 "React does not recognize the `suffixCls` prop on a DOM element" 的问题。[#40969](https://github.com/ant-design/ant-design/pull/40969)
- 🐞 修复 Watermark 组件图片加载异常时的问题,默认展示文字。[#40770](https://github.com/ant-design/ant-design/pull/40770) [@OriginRing](https://github.com/OriginRing)
- 🐞 Image 预览新增图片翻转功能。并修复 Image `fallback` 在 ssr 下失效的问题。[#40660](https://github.com/ant-design/ant-design/pull/40660)
- 🐞 修复 Select 中使用 Typography 不居中的问题。[#40422](https://github.com/ant-design/ant-design/pull/40422) [@Yuiai01](https://github.com/Yuiai01)

View File

@ -8,7 +8,6 @@ exports[`antd exports modules correctly 1`] = `
"App",
"AutoComplete",
"Avatar",
"BackTop",
"Badge",
"Breadcrumb",
"Button",

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import useState from 'rc-util/lib/hooks/useState';
import useState from '@rc-component/util/lib/hooks/useState';
import Button from '../button';
import type { ButtonProps, LegacyButtonType } from '../button/button';

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import useMergedState from '@rc-component/util/lib/hooks/useMergedState';
import ConfigProvider, { ConfigContext } from '../config-provider';
import type { AnyObject } from './type';
@ -20,9 +20,10 @@ export interface BaseProps {
/* istanbul ignore next */
const genPurePanel = <ComponentProps extends BaseProps = BaseProps>(
Component: any,
defaultPrefixCls?: string,
getDropdownCls?: null | ((prefixCls: string) => string),
alignPropName?: 'align' | 'dropdownAlign' | 'popupAlign',
postProps?: (props: ComponentProps) => ComponentProps,
defaultPrefixCls?: string,
getDropdownCls?: (prefixCls: string) => string,
) => {
type WrapProps = ComponentProps & AnyObject;
@ -55,7 +56,6 @@ const genPurePanel = <ComponentProps extends BaseProps = BaseProps>(
? `.${getDropdownCls(prefixCls)}`
: `.${prefixCls}-dropdown`;
const popup = holderRef.current?.querySelector(dropdownCls);
if (popup) {
clearInterval(interval);
resizeObserver.observe(popup);
@ -83,6 +83,16 @@ const genPurePanel = <ComponentProps extends BaseProps = BaseProps>(
if (postProps) {
mergedProps = postProps(mergedProps);
}
if (alignPropName) {
Object.assign(mergedProps, {
[alignPropName]: {
overflow: {
adjustX: false,
adjustY: false,
},
},
});
}
const mergedStyle: React.CSSProperties = {
paddingBottom: popupHeight,
position: 'relative',

View File

@ -21,7 +21,7 @@ jest.mock('react-dom', () => {
return realReactDOM;
});
jest.mock('rc-util/lib/Dom/isVisible', () => {
jest.mock('@rc-component/util/lib/Dom/isVisible', () => {
const mockFn = () => (global as any).isVisible;
return mockFn;
});

View File

@ -4,17 +4,11 @@ import { PresetColors } from '../theme/interface';
type InverseColor = `${PresetColorKey}-inverse`;
const inverseColors = PresetColors.map<InverseColor>((color) => `${color}-inverse`);
export const PresetStatusColorTypes = [
'success',
'processing',
'error',
'default',
'warning',
] as const;
export const PresetStatusColors = ['success', 'processing', 'error', 'default', 'warning'] as const;
export type PresetColorType = PresetColorKey | InverseColor;
export type PresetStatusColorType = (typeof PresetStatusColorTypes)[number];
export type PresetStatusColorType = (typeof PresetStatusColors)[number];
/**
* determine if the color keyword belongs to the `Ant Design` {@link PresetColors}.
@ -30,5 +24,5 @@ export function isPresetColor(color?: any, includeInverse = true) {
}
export function isPresetStatusColor(color?: any): color is PresetStatusColorType {
return PresetStatusColorTypes.includes(color);
return PresetStatusColors.includes(color);
}

View File

@ -1,8 +1,8 @@
import type { ReactNode } from 'react';
import React from 'react';
import CloseOutlined from '@ant-design/icons/CloseOutlined';
import pickAttrs from '@rc-component/util/lib/pickAttrs';
import type { DialogProps } from 'rc-dialog';
import pickAttrs from 'rc-util/lib/pickAttrs';
export type ClosableType = DialogProps['closable'];

View File

@ -69,13 +69,13 @@ export default function useResponsiveObserver() {
return React.useMemo(() => {
const subscribers = new Map<number, SubscribeFunc>();
let subUid = -1;
let screens = {};
let screens: Partial<Record<Breakpoint, boolean>> = {};
return {
matchHandlers: {} as {
[prop: string]: {
mql: MediaQueryList;
listener: ((this: MediaQueryList, ev: MediaQueryListEvent) => any) | null;
listener: (this: MediaQueryList, ev: MediaQueryListEvent) => void;
};
},
dispatch(pointMap: ScreenMap) {
@ -84,7 +84,9 @@ export default function useResponsiveObserver() {
return subscribers.size >= 1;
},
subscribe(func: SubscribeFunc): number {
if (!subscribers.size) this.register();
if (!subscribers.size) {
this.register();
}
subUid += 1;
subscribers.set(subUid, func);
func(screens);
@ -92,7 +94,9 @@ export default function useResponsiveObserver() {
},
unsubscribe(paramToken: number) {
subscribers.delete(paramToken);
if (!subscribers.size) this.unregister();
if (!subscribers.size) {
this.unregister();
}
},
unregister() {
Object.keys(responsiveMap).forEach((screen) => {
@ -117,7 +121,6 @@ export default function useResponsiveObserver() {
mql,
listener,
};
listener(mql);
});
},
@ -129,7 +132,7 @@ export default function useResponsiveObserver() {
export const matchScreen = (screens: ScreenMap, screenSizes?: ScreenSizeMap) => {
if (screenSizes && typeof screenSizes === 'object') {
for (let i = 0; i < responsiveArray.length; i++) {
const breakpoint: Breakpoint = responsiveArray[i];
const breakpoint = responsiveArray[i];
if (screens[breakpoint] && screenSizes[breakpoint] !== undefined) {
return screenSizes[breakpoint];
}

View File

@ -1,4 +1,4 @@
import raf from 'rc-util/lib/raf';
import raf from '@rc-component/util/lib/raf';
import { easeInOutCubic } from './easings';
import getScroll, { isWindow } from './getScroll';

View File

@ -1,5 +1,5 @@
import canUseDom from 'rc-util/lib/Dom/canUseDom';
import { isStyleSupport } from 'rc-util/lib/Dom/styleChecker';
import canUseDom from '@rc-component/util/lib/Dom/canUseDom';
import { isStyleSupport } from '@rc-component/util/lib/Dom/styleChecker';
export const canUseDocElement = () => canUseDom() && window.document.documentElement;

View File

@ -1,4 +1,4 @@
import raf from 'rc-util/lib/raf';
import raf from '@rc-component/util/lib/raf';
function throttleByAnimationFrame<T extends any[]>(fn: (...args: T) => void) {
let requestId: number | null;

View File

@ -1,5 +1,6 @@
import * as React from 'react';
import rcWarning, { resetWarned as rcResetWarned } from 'rc-util/lib/warning';
import rcWarning, { resetWarned as rcResetWarned } from '@rc-component/util/lib/warning';
import { resetWarned as deprecatedRcResetWarned } from 'rc-util/lib/warning';
export function noop() {}
@ -8,6 +9,7 @@ let deprecatedWarnList: Record<string, string[]> | null = null;
export function resetWarned() {
deprecatedWarnList = null;
rcResetWarned();
deprecatedRcResetWarned();
}
type Warning = (valid: boolean, component: string, message?: string) => void;

View File

@ -1,8 +1,8 @@
import * as React from 'react';
import raf from '@rc-component/util/lib/raf';
import { composeRef } from '@rc-component/util/lib/ref';
import classNames from 'classnames';
import CSSMotion from 'rc-motion';
import raf from 'rc-util/lib/raf';
import { composeRef } from 'rc-util/lib/ref';
import { getReactRender, type UnmountType } from '../../config-provider/UnstableContext';
import { TARGET_CLS } from './interface';

View File

@ -1,7 +1,7 @@
import React, { useContext, useRef } from 'react';
import isVisible from '@rc-component/util/lib/Dom/isVisible';
import { composeRef, getNodeRef, supportRef } from '@rc-component/util/lib/ref';
import classNames from 'classnames';
import isVisible from 'rc-util/lib/Dom/isVisible';
import { composeRef, getNodeRef, supportRef } from 'rc-util/lib/ref';
import type { ConfigConsumerProps } from '../../config-provider';
import { ConfigContext } from '../../config-provider';

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import useEvent from 'rc-util/lib/hooks/useEvent';
import raf from 'rc-util/lib/raf';
import useEvent from '@rc-component/util/lib/hooks/useEvent';
import raf from '@rc-component/util/lib/raf';
import { ConfigContext } from '../../config-provider';
import useToken from '../../theme/useToken';

View File

@ -1,5 +1,5 @@
import * as React from 'react';
import { spyElementPrototype } from 'rc-util/lib/test/domHook';
import { spyElementPrototype } from '@rc-component/util/lib/test/domHook';
import demoTest, { rootPropsTest } from '../../../tests/shared/demoTest';

View File

@ -1,7 +1,7 @@
import React from 'react';
import omit from '@rc-component/util/lib/omit';
import classNames from 'classnames';
import ResizeObserver from 'rc-resize-observer';
import omit from 'rc-util/lib/omit';
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
import type { ConfigConsumerProps } from '../config-provider';

View File

@ -5,10 +5,10 @@ import CloseCircleFilled from '@ant-design/icons/CloseCircleFilled';
import CloseOutlined from '@ant-design/icons/CloseOutlined';
import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled';
import pickAttrs from '@rc-component/util/lib/pickAttrs';
import { composeRef } from '@rc-component/util/lib/ref';
import classNames from 'classnames';
import CSSMotion from 'rc-motion';
import pickAttrs from 'rc-util/lib/pickAttrs';
import { composeRef } from 'rc-util/lib/ref';
import type { ClosableType } from '../_util/hooks/useClosable';
import { replaceElement } from '../_util/reactNode';

View File

@ -1,6 +1,6 @@
import React from 'react';
import { resetWarned } from '@rc-component/util/lib/warning';
import userEvent from '@testing-library/user-event';
import { resetWarned } from 'rc-util/lib/warning';
import Alert from '..';
import { accessibilityTest } from '../../../tests/shared/accessibilityTest';

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import useEvent from '@rc-component/util/lib/hooks/useEvent';
import classNames from 'classnames';
import useEvent from 'rc-util/lib/hooks/useEvent';
import scrollIntoView from 'scroll-into-view-if-needed';
import getScroll from '../_util/getScroll';

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { resetWarned } from 'rc-util/lib/warning';
import { resetWarned } from '@rc-component/util/lib/warning';
import scrollIntoView from 'scroll-into-view-if-needed';
import Anchor from '..';

View File

@ -2,7 +2,6 @@ import React from 'react';
import userEvent from '@testing-library/user-event';
import AutoComplete from '..';
import { resetWarned } from '../../_util/warning';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { render, screen } from '../../../tests/utils';
@ -97,24 +96,4 @@ describe('AutoComplete', () => {
);
expect(screen.getByRole('combobox')).toHaveClass('custom');
});
it('deprecated dropdownClassName', () => {
resetWarned();
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const { container } = render(
<AutoComplete
dropdownClassName="legacy"
open
options={[{ label: 'little', value: 'little' }]}
searchValue="l"
/>,
);
expect(errSpy).toHaveBeenCalledWith(
'Warning: [antd: AutoComplete] `dropdownClassName` is deprecated. Please use `popupClassName` instead.',
);
expect(container.querySelector('.legacy')).toBeTruthy();
errSpy.mockRestore();
});
});

View File

@ -1,8 +1,8 @@
import * as React from 'react';
import toArray from '@rc-component/util/lib/Children/toArray';
import omit from '@rc-component/util/lib/omit';
import classNames from 'classnames';
import type { BaseSelectRef } from 'rc-select';
import toArray from 'rc-util/lib/Children/toArray';
import omit from 'rc-util/lib/omit';
import { useZIndex } from '../_util/hooks/useZIndex';
import genPurePanel from '../_util/PurePanel';
@ -38,8 +38,6 @@ export interface AutoCompleteProps<
dataSource?: DataSourceItemType[];
status?: InputStatus;
popupClassName?: string;
/** @deprecated Please use `popupClassName` instead */
dropdownClassName?: string;
/** @deprecated Please use `popupMatchSelectWidth` instead */
dropdownMatchSelectWidth?: boolean | number;
popupMatchSelectWidth?: boolean | number;
@ -53,14 +51,7 @@ const AutoComplete: React.ForwardRefRenderFunction<RefSelectProps, AutoCompleteP
props,
ref,
) => {
const {
prefixCls: customizePrefixCls,
className,
popupClassName,
dropdownClassName,
children,
dataSource,
} = props;
const { prefixCls: customizePrefixCls, className, popupClassName, children, dataSource } = props;
const childNodes: React.ReactElement[] = toArray(children);
// ============================= Input =============================
@ -120,8 +111,6 @@ const AutoComplete: React.ForwardRefRenderFunction<RefSelectProps, AutoCompleteP
'usage',
'You need to control style self instead of setting `size` when using customize input.',
);
warning.deprecated(!dropdownClassName, 'dropdownClassName', 'popupClassName');
}
const { getPrefixCls } = React.useContext<ConfigConsumerProps>(ConfigContext);
@ -135,9 +124,9 @@ const AutoComplete: React.ForwardRefRenderFunction<RefSelectProps, AutoCompleteP
<Select
ref={ref}
suffixIcon={null}
{...omit(props, ['dataSource', 'dropdownClassName'])}
{...omit(props, ['dataSource'])}
prefixCls={prefixCls}
popupClassName={popupClassName || dropdownClassName}
popupClassName={popupClassName}
dropdownStyle={{
...props.dropdownStyle,
zIndex,
@ -170,7 +159,7 @@ const RefAutoComplete = React.forwardRef<RefSelectProps, AutoCompleteProps>(
// We don't care debug panel
/* istanbul ignore next */
const PurePanel = genPurePanel(RefAutoComplete, undefined, undefined, (props: any) =>
const PurePanel = genPurePanel(RefAutoComplete, 'dropdownAlign', (props: any) =>
omit(props, ['visible']),
);

View File

@ -271,8 +271,8 @@ describe('Avatar Render', () => {
count: 2,
popover: {
placement: 'bottomRight',
overlayClassName: 'wanpan-111',
overlayStyle: { background: 'red' },
classNames: { root: 'wanpan-111' },
styles: { root: { background: 'red' } },
content: 'Avatar.Group',
open: true,
},

View File

@ -441,6 +441,7 @@ Array [
</span>
</span>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-circle"
style="color: rgb(245, 106, 0); background-color: rgb(253, 227, 207);"
>
@ -464,12 +465,14 @@ Array [
>
<div
class="ant-popover-inner"
id="test-id"
role="tooltip"
>
<div
class="ant-popover-inner-content"
>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-circle ant-avatar-icon"
style="background-color: rgb(135, 208, 104);"
>
@ -506,6 +509,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Ant User
@ -731,6 +735,7 @@ Array [
</span>
</a>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-circle ant-avatar-icon"
style="background-color: rgb(135, 208, 104);"
>
@ -767,6 +772,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Ant User
@ -824,6 +830,7 @@ Array [
</span>
</span>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-circle"
style="color: rgb(245, 106, 0); background-color: rgb(253, 227, 207);"
>
@ -847,12 +854,14 @@ Array [
>
<div
class="ant-popover-inner"
id="test-id"
role="tooltip"
>
<div
class="ant-popover-inner-content"
>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-circle ant-avatar-icon"
style="background-color: rgb(135, 208, 104);"
>
@ -889,6 +898,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Ant User
@ -950,6 +960,7 @@ Array [
</span>
</span>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-lg ant-avatar-circle"
style="color: rgb(245, 106, 0); background-color: rgb(253, 227, 207);"
>
@ -973,12 +984,14 @@ Array [
>
<div
class="ant-popover-inner"
id="test-id"
role="tooltip"
>
<div
class="ant-popover-inner-content"
>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon"
style="background-color: rgb(135, 208, 104);"
>
@ -1015,6 +1028,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Ant User
@ -1076,6 +1090,7 @@ Array [
</span>
</span>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-lg ant-avatar-circle"
style="color: rgb(245, 106, 0); background-color: rgb(253, 227, 207); cursor: pointer;"
>
@ -1099,12 +1114,14 @@ Array [
>
<div
class="ant-popover-inner"
id="test-id"
role="tooltip"
>
<div
class="ant-popover-inner-content"
>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-lg ant-avatar-circle ant-avatar-icon"
style="background-color: rgb(135, 208, 104);"
>
@ -1141,6 +1158,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Ant User

View File

@ -437,6 +437,7 @@ Array [
</span>
</span>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-circle"
style="color:#f56a00;background-color:#fde3cf"
>
@ -632,6 +633,7 @@ Array [
</span>
</a>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-circle ant-avatar-icon"
style="background-color:#87d068"
>
@ -706,6 +708,7 @@ Array [
</span>
</span>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-circle"
style="color:#f56a00;background-color:#fde3cf"
>
@ -743,6 +746,7 @@ Array [
</span>
</span>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-lg ant-avatar-circle"
style="color:#f56a00;background-color:#fde3cf"
>
@ -780,6 +784,7 @@ Array [
</span>
</span>
<span
aria-describedby="test-id"
class="ant-avatar ant-avatar-lg ant-avatar-circle"
style="color:#f56a00;background-color:#fde3cf;cursor:pointer"
>

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import { composeRef } from '@rc-component/util/lib/ref';
import classNames from 'classnames';
import ResizeObserver from 'rc-resize-observer';
import { composeRef } from 'rc-util/lib/ref';
import type { Breakpoint } from '../_util/responsiveObserver';
import { responsiveArray } from '../_util/responsiveObserver';

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import toArray from '@rc-component/util/lib/Children/toArray';
import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
import { cloneElement } from '../_util/reactNode';
import { devUseWarning } from '../_util/warning';
@ -121,7 +121,7 @@ const Group: React.FC<GroupProps> = (props) => {
const mergeProps = {
content: childrenHidden,
...max?.popover,
overlayClassName: classNames(`${groupPrefixCls}-popover`, max?.popover?.overlayClassName),
classNames: { root: classNames(`${groupPrefixCls}-popover`, max?.popover?.classNames?.root) },
placement: mergePopoverPlacement,
trigger: mergePopoverTrigger,
};

View File

@ -1,59 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders components/back-top/demo/basic.tsx extend context correctly 1`] = `
Array [
<div
class="ant-back-top"
/>,
Scroll down to see the bottom-right,
<strong
class="site-back-top-basic"
>
gray
</strong>,
button.,
]
`;
exports[`renders components/back-top/demo/basic.tsx extend context correctly 2`] = `
[
"Warning: [antd: BackTop] \`BackTop\` is deprecated. Please use \`FloatButton.BackTop\` instead.",
]
`;
exports[`renders components/back-top/demo/custom.tsx extend context correctly 1`] = `
<div
style="height: 600vh; padding: 8px;"
>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div
class="ant-back-top"
/>
</div>
`;
exports[`renders components/back-top/demo/custom.tsx extend context correctly 2`] = `
[
"Warning: [antd: BackTop] \`BackTop\` is deprecated. Please use \`FloatButton.BackTop\` instead.",
]
`;

View File

@ -1,47 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders components/back-top/demo/basic.tsx correctly 1`] = `
Array [
<div
class="ant-back-top"
/>,
Scroll down to see the bottom-right,
<strong
class="site-back-top-basic"
>
gray
</strong>,
button.,
]
`;
exports[`renders components/back-top/demo/custom.tsx correctly 1`] = `
<div
style="height:600vh;padding:8px"
>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div>
Scroll to bottom
</div>
<div
class="ant-back-top"
/>
</div>
`;

View File

@ -1,7 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`BackTop rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-back-top ant-back-top-rtl"
/>
`;

View File

@ -1,5 +0,0 @@
import accessibilityDemoTest from '../../../tests/shared/accessibilityTest';
describe('back-top demo a11y', () => {
accessibilityDemoTest('back-top');
});

View File

@ -1,3 +0,0 @@
import { extendTest } from '../../../tests/shared/demoTest';
extendTest('back-top');

View File

@ -1,3 +0,0 @@
import demoTest from '../../../tests/shared/demoTest';
demoTest('back-top');

View File

@ -1,55 +0,0 @@
import React from 'react';
import BackTop from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { fireEvent, render, waitFakeTimer } from '../../../tests/utils';
describe('BackTop', () => {
beforeEach(() => {
jest.useFakeTimers();
});
afterEach(() => {
jest.useRealTimers();
});
mountTest(BackTop);
rtlTest(BackTop);
it('should scroll to top after click it', async () => {
const { container } = render(<BackTop />);
const scrollToSpy = jest.spyOn(window, 'scrollTo').mockImplementation((_, y) => {
window.scrollY = y;
window.pageYOffset = y;
document.documentElement.scrollTop = y;
});
window.scrollTo(0, 400);
await waitFakeTimer();
expect(document.documentElement.scrollTop).toBe(400);
fireEvent.click(container.querySelector<HTMLDivElement>('.ant-back-top')!);
await waitFakeTimer();
expect(document.documentElement.scrollTop).toBe(0);
scrollToSpy.mockRestore();
});
it('support onClick', () => {
const onClick = jest.fn();
const { container } = render(<BackTop onClick={onClick} visibilityHeight={0} />);
fireEvent.click(container.querySelector<HTMLDivElement>('.ant-back-top')!);
expect(onClick).toHaveBeenCalled();
});
it('invalid target', () => {
const onClick = jest.fn();
const { container } = render(<BackTop onClick={onClick} target={undefined} />);
fireEvent.click(container.querySelector<HTMLDivElement>('.ant-back-top')!);
expect(onClick).toHaveBeenCalled();
});
it('should console Error', () => {
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
render(<BackTop />);
expect(errSpy).toHaveBeenCalledWith(
'Warning: [antd: BackTop] `BackTop` is deprecated. Please use `FloatButton.BackTop` instead.',
);
errSpy.mockRestore();
});
});

View File

@ -1,13 +0,0 @@
## zh-CN
最简单的用法。
## en-US
The most basic usage.
```css
.site-back-top-basic {
color: rgba(64, 64, 64, 0.6);
}
```

View File

@ -1,13 +0,0 @@
import React from 'react';
import { BackTop } from 'antd';
const App: React.FC = () => (
<>
<BackTop />
Scroll down to see the bottom-right
<strong className="site-back-top-basic"> gray </strong>
button.
</>
);
export default App;

View File

@ -1,11 +0,0 @@
## zh-CN
可以自定义回到顶部按钮的样式,限制宽高:`40px * 40px`。
> 注意:`BackTop` 需要一个可接受 `onClick` 事件的元素作为 `children`。 如果您直接将文本作为子项放置,则该组件将无法正常运行。
## en-US
You can customize the style of the button, just note the size limit: no more than `40px * 40px`.
> Note: `BackTop` expects a element could accept `onClick` property as children. If you put a text directly as children the component will not function properly.

View File

@ -1,30 +0,0 @@
import React from 'react';
import { BackTop } from 'antd';
const style: React.CSSProperties = {
height: 40,
width: 40,
lineHeight: '40px',
borderRadius: 4,
backgroundColor: '#1088e9',
color: '#fff',
textAlign: 'center',
fontSize: 14,
};
const App: React.FC = () => (
<div style={{ height: '600vh', padding: 8 }}>
<div>Scroll to bottom</div>
<div>Scroll to bottom</div>
<div>Scroll to bottom</div>
<div>Scroll to bottom</div>
<div>Scroll to bottom</div>
<div>Scroll to bottom</div>
<div>Scroll to bottom</div>
<BackTop>
<div style={style}>UP</div>
</BackTop>
</div>
);
export default App;

View File

@ -1,128 +0,0 @@
import * as React from 'react';
import VerticalAlignTopOutlined from '@ant-design/icons/VerticalAlignTopOutlined';
import classNames from 'classnames';
import CSSMotion from 'rc-motion';
import omit from 'rc-util/lib/omit';
import getScroll from '../_util/getScroll';
import { cloneElement } from '../_util/reactNode';
import scrollTo from '../_util/scrollTo';
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
import { devUseWarning } from '../_util/warning';
import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import useStyle from './style';
export interface BackTopProps {
visibilityHeight?: number;
onClick?: React.MouseEventHandler<HTMLElement>;
target?: () => HTMLElement | Window | Document;
prefixCls?: string;
children?: React.ReactNode;
className?: string;
rootClassName?: string;
style?: React.CSSProperties;
duration?: number;
}
const BackTop: React.FC<BackTopProps> = (props) => {
const {
prefixCls: customizePrefixCls,
className,
rootClassName,
visibilityHeight = 400,
target,
onClick,
duration = 450,
} = props;
const [visible, setVisible] = React.useState<boolean>(visibilityHeight === 0);
const ref = React.useRef<HTMLDivElement>(null);
const getDefaultTarget = (): HTMLElement | Document | Window =>
ref.current?.ownerDocument || window;
const handleScroll = throttleByAnimationFrame(
(e: React.UIEvent<HTMLElement, UIEvent> | { target: any }) => {
const scrollTop = getScroll(e.target);
setVisible(scrollTop >= visibilityHeight);
},
);
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('BackTop');
warning.deprecated(false, 'BackTop', 'FloatButton.BackTop');
}
React.useEffect(() => {
const getTarget = target || getDefaultTarget;
const container = getTarget();
handleScroll({ target: container });
container?.addEventListener('scroll', handleScroll);
return () => {
handleScroll.cancel();
container?.removeEventListener('scroll', handleScroll);
};
}, [target]);
const scrollToTop = (e: React.MouseEvent<HTMLDivElement>) => {
scrollTo(0, { getContainer: target || getDefaultTarget, duration });
onClick?.(e);
};
const { getPrefixCls, direction } = React.useContext<ConfigConsumerProps>(ConfigContext);
const prefixCls = getPrefixCls('back-top', customizePrefixCls);
const rootPrefixCls = getPrefixCls();
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
const classString = classNames(
hashId,
cssVarCls,
prefixCls,
{
[`${prefixCls}-rtl`]: direction === 'rtl',
},
className,
rootClassName,
);
// fix https://fb.me/react-unknown-prop
const divProps = omit(props, [
'prefixCls',
'className',
'rootClassName',
'children',
'visibilityHeight',
'target',
]);
const defaultElement = (
<div className={`${prefixCls}-content`}>
<div className={`${prefixCls}-icon`}>
<VerticalAlignTopOutlined />
</div>
</div>
);
return wrapCSSVar(
<div {...divProps} className={classString} onClick={scrollToTop} ref={ref}>
<CSSMotion visible={visible} motionName={`${rootPrefixCls}-fade`}>
{({ className: motionClassName }) =>
cloneElement(props.children || defaultElement, ({ className: cloneCls }) => ({
className: classNames(motionClassName, cloneCls),
}))
}
</CSSMotion>
</div>,
);
};
if (process.env.NODE_ENV !== 'production') {
BackTop.displayName = 'BackTop';
}
export default BackTop;

View File

@ -1,158 +0,0 @@
import { unit } from '@ant-design/cssinjs';
import type { CSSObject } from '@ant-design/cssinjs';
import { resetComponent } from '../../style';
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
import { genStyleHooks, mergeToken } from '../../theme/internal';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
/**
* @desc z-index
* @descEN z-index of popup
*/
zIndexPopup: number;
}
type BackTopToken = FullToken<'BackTop'> & {
/**
* @desc BackTop
* @descEN Background color of BackTop
*/
backTopBackground: string;
/**
* @desc BackTop
* @descEN Text color of BackTop
*/
backTopColor: string;
/**
* @desc BackTop
* @descEN Hover background color of BackTop
*/
backTopHoverBackground: string;
/**
* @desc BackTop
* @descEN Font size of BackTop
*/
backTopFontSize: number;
/**
* @desc BackTop
* @descEN Size of BackTop
*/
backTopSize: number;
// Position
/**
* @desc BackTop
* @descEN Bottom offset of BackTop
*/
backTopBlockEnd: number | string;
/**
* @desc BackTop
* @descEN Right offset of BackTop
*/
backTopInlineEnd: number | string;
/**
* @desc BackTop
* @descEN Right offset of BackTop on medium screens
*/
backTopInlineEndMD: number | string;
/**
* @desc BackTop
* @descEN Right offset of BackTop on small screens
*/
backTopInlineEndXS: number | string;
};
// ============================== Shared ==============================
const genSharedBackTopStyle: GenerateStyle<BackTopToken, CSSObject> = (token): CSSObject => {
const { componentCls, backTopFontSize, backTopSize, zIndexPopup } = token;
return {
[componentCls]: {
...resetComponent(token),
position: 'fixed',
insetInlineEnd: token.backTopInlineEnd,
insetBlockEnd: token.backTopBlockEnd,
zIndex: zIndexPopup,
width: 40,
height: 40,
cursor: 'pointer',
'&:empty': {
display: 'none',
},
[`${componentCls}-content`]: {
width: backTopSize,
height: backTopSize,
overflow: 'hidden',
color: token.backTopColor,
textAlign: 'center',
backgroundColor: token.backTopBackground,
borderRadius: backTopSize,
transition: `all ${token.motionDurationMid}`,
'&:hover': {
backgroundColor: token.backTopHoverBackground,
transition: `all ${token.motionDurationMid}`,
},
},
// change to .backtop .backtop-icon
[`${componentCls}-icon`]: {
fontSize: backTopFontSize,
lineHeight: unit(backTopSize),
},
},
};
};
const genMediaBackTopStyle: GenerateStyle<BackTopToken> = (token): CSSObject => {
const { componentCls, screenMD, screenXS, backTopInlineEndMD, backTopInlineEndXS } = token;
return {
[`@media (max-width: ${unit(screenMD)})`]: {
[componentCls]: {
insetInlineEnd: backTopInlineEndMD,
},
},
[`@media (max-width: ${unit(screenXS)})`]: {
[componentCls]: {
insetInlineEnd: backTopInlineEndXS,
},
},
};
};
export const prepareComponentToken: GetDefaultToken<'BackTop'> = (token) => ({
zIndexPopup: token.zIndexBase + 10,
});
// ============================== Export ==============================
export default genStyleHooks(
'BackTop',
(token) => {
const {
fontSizeHeading3,
colorTextDescription,
colorTextLightSolid,
colorText,
controlHeightLG,
calc,
} = token;
const backTopToken = mergeToken<BackTopToken>(token, {
backTopBackground: colorTextDescription,
backTopColor: colorTextLightSolid,
backTopHoverBackground: colorText,
backTopFontSize: fontSizeHeading3,
backTopSize: controlHeightLG,
backTopBlockEnd: calc(controlHeightLG).mul(1.25).equal(),
backTopInlineEnd: calc(controlHeightLG).mul(2.5).equal(),
backTopInlineEndMD: calc(controlHeightLG).mul(1.5).equal(),
backTopInlineEndXS: calc(controlHeightLG).mul(0.5).equal(),
});
return [genSharedBackTopStyle(backTopToken), genMediaBackTopStyle(backTopToken)];
},
prepareComponentToken,
);

View File

@ -9,6 +9,8 @@ import useStyle from './style/ribbon';
type RibbonPlacement = 'start' | 'end';
type SemanticName = 'root' | 'content' | 'indicator';
export interface RibbonProps {
className?: string;
prefixCls?: string;
@ -18,6 +20,8 @@ export interface RibbonProps {
children?: React.ReactNode;
placement?: RibbonPlacement;
rootClassName?: string;
classNames?: Partial<Record<SemanticName, string>>;
styles?: Partial<Record<SemanticName, React.CSSProperties>>;
}
const Ribbon: React.FC<RibbonProps> = (props) => {
@ -30,8 +34,10 @@ const Ribbon: React.FC<RibbonProps> = (props) => {
text,
placement = 'end',
rootClassName,
styles,
classNames: ribbonClassNames,
} = props;
const { getPrefixCls, direction } = React.useContext(ConfigContext);
const { getPrefixCls, direction, ribbon } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('ribbon', customizePrefixCls);
const wrapperCls = `${prefixCls}-wrapper`;
@ -46,6 +52,9 @@ const Ribbon: React.FC<RibbonProps> = (props) => {
[`${prefixCls}-color-${color}`]: colorInPreset,
},
className,
ribbon?.className,
ribbon?.classNames?.indicator,
ribbonClassNames?.indicator,
);
const colorStyle: React.CSSProperties = {};
@ -55,10 +64,38 @@ const Ribbon: React.FC<RibbonProps> = (props) => {
cornerColorStyle.color = color;
}
return wrapCSSVar(
<div className={classNames(wrapperCls, rootClassName, hashId, cssVarCls)}>
<div
className={classNames(
wrapperCls,
rootClassName,
hashId,
cssVarCls,
ribbonClassNames?.root,
ribbon?.classNames?.root,
)}
style={{ ...ribbon?.styles?.root, ...styles?.root }}
>
{children}
<div className={classNames(ribbonCls, hashId)} style={{ ...colorStyle, ...style }}>
<span className={`${prefixCls}-text`}>{text}</span>
<div
className={classNames(ribbonCls, hashId)}
style={{
...colorStyle,
...ribbon?.styles?.indicator,
...ribbon?.style,
...styles?.indicator,
...style,
}}
>
<span
className={classNames(
`${prefixCls}-content`,
ribbonClassNames?.content,
ribbon?.classNames?.content,
)}
style={{ ...ribbon?.styles?.content, ...styles?.content }}
>
{text}
</span>
<div className={`${prefixCls}-corner`} style={cornerColorStyle} />
</div>
</div>,

View File

@ -2315,7 +2315,7 @@ exports[`renders components/badge/demo/ribbon.tsx extend context correctly 1`] =
class="ant-ribbon ant-ribbon-placement-end"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2357,7 +2357,7 @@ exports[`renders components/badge/demo/ribbon.tsx extend context correctly 1`] =
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-pink"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2399,7 +2399,7 @@ exports[`renders components/badge/demo/ribbon.tsx extend context correctly 1`] =
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-red"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2441,7 +2441,7 @@ exports[`renders components/badge/demo/ribbon.tsx extend context correctly 1`] =
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-cyan"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2483,7 +2483,7 @@ exports[`renders components/badge/demo/ribbon.tsx extend context correctly 1`] =
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-green"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2525,7 +2525,7 @@ exports[`renders components/badge/demo/ribbon.tsx extend context correctly 1`] =
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-purple"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2567,7 +2567,7 @@ exports[`renders components/badge/demo/ribbon.tsx extend context correctly 1`] =
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-volcano"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2609,7 +2609,7 @@ exports[`renders components/badge/demo/ribbon.tsx extend context correctly 1`] =
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-magenta"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2648,7 +2648,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx extend context correctly
class="ant-ribbon ant-ribbon-placement-end"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>
@ -2677,7 +2677,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx extend context correctly
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-purple"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>
@ -2707,7 +2707,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx extend context correctly
style="background: rgb(45, 183, 245);"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>
@ -2738,7 +2738,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx extend context correctly
style="background: rgb(45, 183, 245);"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>
@ -2769,7 +2769,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx extend context correctly
style="background: rgb(45, 183, 245);"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>

View File

@ -2294,7 +2294,7 @@ exports[`renders components/badge/demo/ribbon.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2336,7 +2336,7 @@ exports[`renders components/badge/demo/ribbon.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-pink"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2378,7 +2378,7 @@ exports[`renders components/badge/demo/ribbon.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-red"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2420,7 +2420,7 @@ exports[`renders components/badge/demo/ribbon.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-cyan"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2462,7 +2462,7 @@ exports[`renders components/badge/demo/ribbon.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-green"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2504,7 +2504,7 @@ exports[`renders components/badge/demo/ribbon.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-purple"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2546,7 +2546,7 @@ exports[`renders components/badge/demo/ribbon.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-volcano"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2588,7 +2588,7 @@ exports[`renders components/badge/demo/ribbon.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-magenta"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
Hippies
</span>
@ -2625,7 +2625,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>
@ -2654,7 +2654,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx correctly 1`] = `
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-color-purple"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>
@ -2684,7 +2684,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx correctly 1`] = `
style="background:#2db7f5"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>
@ -2715,7 +2715,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx correctly 1`] = `
style="background:#2db7f5"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>
@ -2746,7 +2746,7 @@ exports[`renders components/badge/demo/ribbon-debug.tsx correctly 1`] = `
style="background:#2db7f5"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
>
啦啦啦啦
</span>

View File

@ -8,7 +8,7 @@ exports[`Ribbon rtl render component should be rendered correctly in RTL directi
class="ant-ribbon ant-ribbon-placement-end ant-ribbon-rtl"
>
<span
class="ant-ribbon-text"
class="ant-ribbon-content"
/>
<div
class="ant-ribbon-corner"

View File

@ -80,4 +80,37 @@ describe('Ribbon', () => {
expect(container.querySelectorAll('.cool').length).toEqual(1);
});
});
it('should apply custom styles to Badge.Ribbon', () => {
const customClassNames = {
root: 'custom-root',
indicator: 'custom-indicator',
content: 'custom-content',
};
const customStyles = {
root: { color: 'red' },
indicator: { color: 'green' },
content: { color: 'yellow' },
};
const { container } = render(
<Badge.Ribbon text="Hippies" color="pink" classNames={customClassNames} styles={customStyles}>
<div>and raises the spyglass.</div>
</Badge.Ribbon>,
);
const rootElement = container.querySelector('.ant-ribbon-wrapper') as HTMLElement;
const indicatorElement = container.querySelector('.ant-ribbon') as HTMLElement;
const contentElement = container.querySelector('.ant-ribbon-content') as HTMLElement;
// check classNames
expect(rootElement.classList).toContain('custom-root');
expect(indicatorElement.classList).toContain('custom-indicator');
expect(contentElement.classList).toContain('custom-content');
// check styles
expect(rootElement.style.color).toBe('red');
expect(indicatorElement.style.color).toBe('green');
expect(contentElement.style.color).toBe('yellow');
});
});

View File

@ -0,0 +1,47 @@
import React from 'react';
import { Badge, Card } from 'antd';
import SemanticPreview from '../../../.dumi/components/SemanticPreview';
import useLocale from '../../../.dumi/hooks/useLocale';
const locales = {
cn: {
root: '根节点',
indicator: '指示器节点',
content: '文本节点',
},
en: {
root: 'Root element',
indicator: 'Indicator element',
content: 'Text element',
},
};
const BlockList = (props: any) => {
return (
<div style={{ width: '100%' }}>
<Badge.Ribbon {...props} text="Hippies" color="pink">
<Card title="Pushes open the window" size="small">
and raises the spyglass.
</Card>
</Badge.Ribbon>
</div>
);
};
const App: React.FC = () => {
const [locale] = useLocale(locales);
return (
<SemanticPreview
semantics={[
{ name: 'root', desc: locale.root, version: '6.0.0' },
{ name: 'indicator', desc: locale.indicator, version: '6.0.0' },
{ name: 'content', desc: locale.content, version: '6.0.0' },
]}
>
<BlockList />
</SemanticPreview>
);
};
export default App;

View File

@ -64,8 +64,14 @@ Common props ref[Common props](/docs/react/common-props)
## Semantic DOM
### Badge
<code src="./demo/_semantic.tsx" simplify="true"></code>
### Badge.Ribbon
<code src="./demo/_semantic_ribbon.tsx" simplify="true"></code>
## Design Token
<ComponentTokenTable component="Badge"></ComponentTokenTable>

View File

@ -65,8 +65,14 @@ group: 数据展示
## Semantic DOM
### Badge
<code src="./demo/_semantic.tsx" simplify="true"></code>
### Badge.Ribbon
<code src="./demo/_semantic_ribbon.tsx" simplify="true"></code>
## 主题变量Design Token
<ComponentTokenTable component="Badge"></ComponentTokenTable>

View File

@ -33,7 +33,7 @@ const genRibbonStyle: GenerateStyle<BadgeToken> = (token) => {
whiteSpace: 'nowrap',
backgroundColor: token.colorPrimary,
borderRadius: token.borderRadiusSM,
[`${ribbonPrefixCls}-text`]: {
[`${ribbonPrefixCls}-content`]: {
color: token.badgeTextColor,
},
[`${ribbonPrefixCls}-corner`]: {

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import toArray from '@rc-component/util/lib/Children/toArray';
import pickAttrs from '@rc-component/util/lib/pickAttrs';
import classNames from 'classnames';
import toArray from 'rc-util/lib/Children/toArray';
import pickAttrs from 'rc-util/lib/pickAttrs';
import { cloneElement } from '../_util/reactNode';
import type { AnyObject } from '../_util/type';
@ -29,8 +29,6 @@ export interface BreadcrumbItemType {
/** @deprecated Please use `title` instead */
breadcrumbName?: string;
menu?: BreadcrumbItemProps['menu'];
/** @deprecated Please use `menu` instead */
overlay?: React.ReactNode;
className?: string;
dropdownProps?: DropdownProps;
onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLSpanElement>;
@ -141,7 +139,6 @@ const Breadcrumb = <T extends AnyObject = AnyObject>(props: BreadcrumbProps<T>)
key,
type,
menu,
overlay,
onClick,
className: itemClassName,
separator: itemSeparator,
@ -164,8 +161,6 @@ const Breadcrumb = <T extends AnyObject = AnyObject>(props: BreadcrumbProps<T>)
if (menu) {
itemProps.menu = menu;
} else if (overlay) {
itemProps.overlay = overlay as any;
}
let { href } = item;

View File

@ -1,7 +1,5 @@
import * as React from 'react';
import DownOutlined from '@ant-design/icons/DownOutlined';
import { devUseWarning } from '../_util/warning';
import { ConfigContext } from '../config-provider';
import type { DropdownProps } from '../dropdown/dropdown';
import Dropdown from '../dropdown/dropdown';
@ -33,24 +31,14 @@ export interface BreadcrumbItemProps extends SeparatorType {
onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLSpanElement>;
className?: string;
children?: React.ReactNode;
// Deprecated
/** @deprecated Please use `menu` instead */
overlay?: DropdownProps['overlay'];
}
export const InternalBreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) => {
const { prefixCls, separator = '/', children, menu, overlay, dropdownProps, href } = props;
// Warning for deprecated usage
if (process.env.NODE_ENV !== 'production') {
const warning = devUseWarning('Breadcrumb.Item');
warning.deprecated(!('overlay' in props), 'overlay', 'menu');
}
const { prefixCls, separator = '/', children, menu, dropdownProps, href } = props;
/** If overlay is have Wrap a Dropdown */
const renderBreadcrumbNode = (breadcrumbItem: React.ReactNode) => {
if (menu || overlay) {
if (menu) {
const mergeDropDownProps: DropdownProps = {
...dropdownProps,
};
@ -73,8 +61,6 @@ export const InternalBreadcrumbItem: React.FC<BreadcrumbItemProps> = (props) =>
};
}),
};
} else if (overlay) {
mergeDropDownProps.overlay = overlay;
}
return (

View File

@ -1,6 +1,4 @@
import React from 'react';
import { resetWarned } from '../../_util/warning';
import { accessibilityTest } from '../../../tests/shared/accessibilityTest';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
@ -67,39 +65,6 @@ describe('Breadcrumb', () => {
expect(asFragment().firstChild).toMatchSnapshot();
});
describe('overlay deprecation warning set', () => {
it('legacy jsx', () => {
resetWarned();
render(
<Breadcrumb>
<Breadcrumb.Item overlay={<div>menu</div>}>
<a href="">General</a>
</Breadcrumb.Item>
</Breadcrumb>,
);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Breadcrumb.Item] `overlay` is deprecated. Please use `menu` instead.',
);
});
it('items', () => {
resetWarned();
render(
<Breadcrumb
items={[
{
overlay: <div>menu</div>,
title: 'General',
},
]}
/>,
);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Breadcrumb.Item] `overlay` is deprecated. Please use `menu` instead.',
);
});
});
it('Breadcrumb.Item deprecation warning', () => {
render(
<Breadcrumb>
@ -122,33 +87,6 @@ describe('Breadcrumb', () => {
);
});
// https://github.com/ant-design/ant-design/issues/40204
it('wrong overlay deprecation warning in Dropdown', () => {
const menuItems = [
{
key: '1',
label: (
<a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">
General
</a>
),
},
];
render(
<Breadcrumb
items={[
{
menu: { items: menuItems },
title: <a href="">General</a>,
},
]}
/>,
);
expect(errorSpy).not.toHaveBeenCalledWith(
'Warning: [antd: Dropdown] `overlay` is deprecated. Please use `menu` instead.',
);
});
// https://github.com/ant-design/ant-design/issues/5015
it('should allow Breadcrumb.Item is null or undefined', () => {
const { asFragment } = render(
@ -325,20 +263,6 @@ describe('Breadcrumb', () => {
expect(container.firstChild).toMatchSnapshot();
});
it('should console Error when `overlay` in props', () => {
resetWarned();
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
render(
<Breadcrumb>
<Breadcrumb.Item overlay={<div>test</div>} />
</Breadcrumb>,
);
expect(errSpy).toHaveBeenCalledWith(
'Warning: [antd: Breadcrumb.Item] `overlay` is deprecated. Please use `menu` instead.',
);
errSpy.mockRestore();
});
it('should not console Error when `overlay` not in props', () => {
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
render(<Breadcrumb items={[{ path: '/', title: 'Test' }]} />);

View File

@ -144,6 +144,7 @@ exports[`renders components/breadcrumb/demo/component-token.tsx extend context c
tabindex="0"
>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-1"
role="menuitem"
@ -174,11 +175,13 @@ exports[`renders components/breadcrumb/demo/component-token.tsx extend context c
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-2"
role="menuitem"
@ -209,11 +212,13 @@ exports[`renders components/breadcrumb/demo/component-token.tsx extend context c
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-3"
role="menuitem"
@ -244,6 +249,7 @@ exports[`renders components/breadcrumb/demo/component-token.tsx extend context c
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
@ -402,6 +408,7 @@ exports[`renders components/breadcrumb/demo/debug-routes.tsx extend context corr
tabindex="0"
>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-0"
role="menuitem"
@ -430,11 +437,13 @@ exports[`renders components/breadcrumb/demo/debug-routes.tsx extend context corr
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-1"
role="menuitem"
@ -463,6 +472,7 @@ exports[`renders components/breadcrumb/demo/debug-routes.tsx extend context corr
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
@ -563,6 +573,7 @@ exports[`renders components/breadcrumb/demo/overlay.tsx extend context correctly
tabindex="0"
>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-1"
role="menuitem"
@ -593,11 +604,13 @@ exports[`renders components/breadcrumb/demo/overlay.tsx extend context correctly
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-2"
role="menuitem"
@ -628,11 +641,13 @@ exports[`renders components/breadcrumb/demo/overlay.tsx extend context correctly
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-3"
role="menuitem"
@ -663,6 +678,7 @@ exports[`renders components/breadcrumb/demo/overlay.tsx extend context correctly
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import pickAttrs from '@rc-component/util/lib/pickAttrs';
import classNames from 'classnames';
import pickAttrs from 'rc-util/lib/pickAttrs';
import type { BreadcrumbProps, InternalRouteType, ItemType } from './Breadcrumb';

View File

@ -23,7 +23,7 @@ const InnerLoadingIcon = forwardRef<HTMLSpanElement, InnerLoadingIconProps>((pro
);
});
export type LoadingIconProps = {
export type DefaultLoadingIconProps = {
prefixCls: string;
existIcon: boolean;
loading?: boolean | object;
@ -44,7 +44,7 @@ const getRealWidth = (node: HTMLElement): React.CSSProperties => ({
transform: 'scale(1)',
});
const LoadingIcon: React.FC<LoadingIconProps> = (props) => {
const DefaultLoadingIcon: React.FC<DefaultLoadingIconProps> = (props) => {
const { prefixCls, loading, existIcon, className, style, mount } = props;
const visible = !!loading;
@ -84,4 +84,4 @@ const LoadingIcon: React.FC<LoadingIconProps> = (props) => {
);
};
export default LoadingIcon;
export default DefaultLoadingIcon;

View File

@ -492,6 +492,162 @@ exports[`renders components/button/demo/color-variant.tsx extend context correct
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-solid ant-btn-sm"
type="button"
>
<span>
Solid
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-outlined ant-btn-sm"
type="button"
>
<span>
Outlined
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-dashed ant-btn-sm"
type="button"
>
<span>
Dashed
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-filled ant-btn-sm"
type="button"
>
<span>
Filled
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-text ant-btn-sm"
type="button"
>
<span>
Text
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-link ant-btn-sm"
type="button"
>
<span>
Link
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-solid ant-btn-sm"
type="button"
>
<span>
Solid
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-outlined ant-btn-sm"
type="button"
>
<span>
Outlined
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-dashed ant-btn-sm"
type="button"
>
<span>
Dashed
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-filled ant-btn-sm"
type="button"
>
<span>
Filled
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-text ant-btn-sm"
type="button"
>
<span>
Text
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-link ant-btn-sm"
type="button"
>
<span>
Link
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-solid ant-btn-sm"
type="button"
>
<span>
Solid
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-outlined ant-btn-sm"
type="button"
>
<span>
Outlined
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-dashed ant-btn-sm"
type="button"
>
<span>
Dashed
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-filled ant-btn-sm"
type="button"
>
<span>
Filled
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-text ant-btn-sm"
type="button"
>
<span>
Text
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-link ant-btn-sm"
type="button"
>
<span>
Link
</span>
</button>
</div>
</div>
`;
@ -743,6 +899,7 @@ Array [
<input
checked=""
class="ant-radio-button-input"
name="test-id"
type="radio"
value="large"
/>
@ -750,7 +907,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Large
</span>
</label>
@ -762,6 +921,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="default"
/>
@ -769,7 +929,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Default
</span>
</label>
@ -781,6 +943,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="small"
/>
@ -788,7 +951,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Small
</span>
</label>
@ -810,6 +975,7 @@ Array [
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -850,6 +1016,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -896,6 +1063,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -936,6 +1104,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -978,6 +1147,7 @@ Array [
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -1018,6 +1188,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -1056,6 +1227,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-dashed ant-btn-color-default ant-btn-variant-dashed ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -1096,6 +1268,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -1242,6 +1415,236 @@ Array [
</span>
</button>
</div>
<div
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center ant-divider-plain"
role="separator"
>
<span
class="ant-divider-inner-text"
>
👇🏻 https://github.com/ant-design/ant-design/issues/52124 👇🏻
</span>
</div>
<div>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
style="height: 60px;"
type="button"
>
<span>
without icon
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
style="height: 60px;"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</span>
<span>
with icon
</span>
</button>
</div>
<div
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center ant-divider-plain"
role="separator"
>
<span
class="ant-divider-inner-text"
>
👇🏻 https://github.com/ant-design/ant-design/issues/51380 👇🏻
</span>
</div>
<div>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only"
type="button"
>
<span
class="ant-btn-icon"
>
<svg
class="my-class-name"
fill="none"
height="1em"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 3h7a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-7m0-18H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7m0-18v18"
/>
</svg>
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
type="button"
>
<span
class="ant-btn-icon"
>
<svg
fill="none"
height="1em"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 3h7a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-7m0-18H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7m0-18v18"
/>
</svg>
</span>
<span>
custom icon
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</span>
<span>
with icon
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
type="button"
>
<span>
without icon
</span>
</button>
<span
class="ant-input-group-wrapper ant-input-group-wrapper-lg ant-input-group-wrapper-outlined ant-input-search ant-input-search-large"
style="width: 100px;"
>
<span
class="ant-input-wrapper ant-input-group"
>
<input
class="ant-input ant-input-lg ant-input-outlined"
type="search"
value=""
/>
<span
class="ant-input-group-addon"
>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only ant-input-search-button"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</span>
</button>
</span>
</span>
</span>
</div>
<div
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center ant-divider-plain"
role="separator"
@ -1598,6 +2001,7 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-icon-only"
type="button"
>
@ -1638,6 +2042,7 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -1684,6 +2089,7 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-icon-only"
type="button"
>
@ -1724,6 +2130,7 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -1766,6 +2173,7 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-icon-only"
type="button"
>
@ -1806,6 +2214,7 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -1844,6 +2253,7 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-dashed ant-btn-color-default ant-btn-variant-dashed ant-btn-icon-only"
type="button"
>
@ -1884,6 +2294,7 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -1976,6 +2387,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="start"
/>
@ -1983,7 +2395,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
start
</span>
</label>
@ -1996,6 +2410,7 @@ Array [
<input
checked=""
class="ant-radio-button-input"
name="test-id"
type="radio"
value="end"
/>
@ -2003,7 +2418,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
end
</span>
</label>
@ -2027,6 +2444,7 @@ Array [
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-icon-only"
type="button"
>
@ -2067,6 +2485,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -2113,6 +2532,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-icon-only"
type="button"
>
@ -2153,6 +2573,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -2195,6 +2616,7 @@ Array [
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-icon-only"
type="button"
>
@ -2235,6 +2657,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -2273,6 +2696,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-dashed ant-btn-color-default ant-btn-variant-dashed ant-btn-icon-only"
type="button"
>
@ -2313,6 +2737,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
search
@ -2440,6 +2865,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-sm ant-btn-icon-only"
disabled=""
type="button"
@ -2481,6 +2907,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Tooltip
@ -2488,6 +2915,7 @@ Array [
</div>
</div>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-sm ant-btn-icon-only"
type="button"
>
@ -2528,6 +2956,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Tooltip
@ -2556,6 +2985,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-icon-only"
disabled=""
type="button"
@ -2597,6 +3027,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Tooltip
@ -2604,6 +3035,7 @@ Array [
</div>
</div>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-icon-only"
type="button"
>
@ -2644,6 +3076,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Tooltip
@ -2672,6 +3105,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-lg ant-btn-icon-only"
disabled=""
type="button"
@ -2713,6 +3147,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Tooltip
@ -2720,6 +3155,7 @@ Array [
</div>
</div>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -2760,6 +3196,7 @@ Array [
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
>
Tooltip
@ -2925,6 +3362,37 @@ exports[`renders components/button/demo/loading.tsx extend context correctly 1`]
</span>
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-loading"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="sync"
class="anticon anticon-sync anticon-spin"
role="img"
>
<svg
aria-hidden="true"
data-icon="sync"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M168 504.2c1-43.7 10-86.1 26.9-126 17.3-41 42.1-77.7 73.7-109.4S337 212.3 378 195c42.4-17.9 87.4-27 133.9-27s91.5 9.1 133.8 27A341.5 341.5 0 01755 268.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.7 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c0-6.7-7.7-10.5-12.9-6.3l-56.4 44.1C765.8 155.1 646.2 92 511.8 92 282.7 92 96.3 275.6 92 503.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8zm756 7.8h-60c-4.4 0-7.9 3.5-8 7.8-1 43.7-10 86.1-26.9 126-17.3 41-42.1 77.8-73.7 109.4A342.45 342.45 0 01512.1 856a342.24 342.24 0 01-243.2-100.8c-9.9-9.9-19.2-20.4-27.8-31.4l60.2-47a8 8 0 00-3-14.1l-175.7-43c-5-1.2-9.9 2.6-9.9 7.7l-.7 181c0 6.7 7.7 10.5 12.9 6.3l56.4-44.1C258.2 868.9 377.8 932 512.2 932c229.2 0 415.5-183.7 419.8-411.8a8 8 0 00-8-8.2z"
/>
</svg>
</span>
</span>
<span>
Loading Icon
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
@ -3004,6 +3472,37 @@ exports[`renders components/button/demo/loading.tsx extend context correctly 1`]
</span>
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="poweroff"
class="anticon anticon-poweroff"
role="img"
>
<svg
aria-hidden="true"
data-icon="poweroff"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M705.6 124.9a8 8 0 00-11.6 7.2v64.2c0 5.5 2.9 10.6 7.5 13.6a352.2 352.2 0 0162.2 49.8c32.7 32.8 58.4 70.9 76.3 113.3a355 355 0 0127.9 138.7c0 48.1-9.4 94.8-27.9 138.7a355.92 355.92 0 01-76.3 113.3 353.06 353.06 0 01-113.2 76.4c-43.8 18.6-90.5 28-138.5 28s-94.7-9.4-138.5-28a353.06 353.06 0 01-113.2-76.4A355.92 355.92 0 01184 650.4a355 355 0 01-27.9-138.7c0-48.1 9.4-94.8 27.9-138.7 17.9-42.4 43.6-80.5 76.3-113.3 19-19 39.8-35.6 62.2-49.8 4.7-2.9 7.5-8.1 7.5-13.6V132c0-6-6.3-9.8-11.6-7.2C178.5 195.2 82 339.3 80 506.3 77.2 745.1 272.5 943.5 511.2 944c239 .5 432.8-193.3 432.8-432.4 0-169.2-97-315.7-238.4-386.7zM480 560h64c4.4 0 8-3.6 8-8V88c0-4.4-3.6-8-8-8h-64c-4.4 0-8 3.6-8 8v464c0 4.4 3.6 8 8 8z"
/>
</svg>
</span>
</span>
<span>
Loading Icon
</span>
</button>
</div>
</div>
`;
@ -3080,6 +3579,7 @@ exports[`renders components/button/demo/multiple.tsx extend context correctly 1`
tabindex="0"
>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-1"
role="menuitem"
@ -3104,11 +3604,13 @@ exports[`renders components/button/demo/multiple.tsx extend context correctly 1`
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-2"
role="menuitem"
@ -3133,11 +3635,13 @@ exports[`renders components/button/demo/multiple.tsx extend context correctly 1`
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
</div>
<li
aria-describedby="test-id"
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-3"
role="menuitem"
@ -3162,6 +3666,7 @@ exports[`renders components/button/demo/multiple.tsx extend context correctly 1`
>
<div
class="ant-tooltip-inner"
id="test-id"
role="tooltip"
/>
</div>
@ -3192,6 +3697,7 @@ Array [
<input
checked=""
class="ant-radio-button-input"
name="test-id"
type="radio"
value="large"
/>
@ -3199,7 +3705,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Large
</span>
</label>
@ -3211,6 +3719,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="default"
/>
@ -3218,7 +3727,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Default
</span>
</label>
@ -3230,6 +3741,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="small"
/>
@ -3237,7 +3749,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Small
</span>
</label>

View File

@ -484,6 +484,162 @@ exports[`renders components/button/demo/color-variant.tsx correctly 1`] = `
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-solid ant-btn-sm"
type="button"
>
<span>
Solid
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-outlined ant-btn-sm"
type="button"
>
<span>
Outlined
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-dashed ant-btn-sm"
type="button"
>
<span>
Dashed
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-filled ant-btn-sm"
type="button"
>
<span>
Filled
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-text ant-btn-sm"
type="button"
>
<span>
Text
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-pink ant-btn-variant-link ant-btn-sm"
type="button"
>
<span>
Link
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-solid ant-btn-sm"
type="button"
>
<span>
Solid
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-outlined ant-btn-sm"
type="button"
>
<span>
Outlined
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-dashed ant-btn-sm"
type="button"
>
<span>
Dashed
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-filled ant-btn-sm"
type="button"
>
<span>
Filled
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-text ant-btn-sm"
type="button"
>
<span>
Text
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-purple ant-btn-variant-link ant-btn-sm"
type="button"
>
<span>
Link
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-solid ant-btn-sm"
type="button"
>
<span>
Solid
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-outlined ant-btn-sm"
type="button"
>
<span>
Outlined
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-dashed ant-btn-sm"
type="button"
>
<span>
Dashed
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-filled ant-btn-sm"
type="button"
>
<span>
Filled
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-text ant-btn-sm"
type="button"
>
<span>
Text
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-cyan ant-btn-variant-link ant-btn-sm"
type="button"
>
<span>
Link
</span>
</button>
</div>
</div>
`;
@ -727,6 +883,7 @@ Array [
<input
checked=""
class="ant-radio-button-input"
name="test-id"
type="radio"
value="large"
/>
@ -734,7 +891,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Large
</span>
</label>
@ -746,6 +905,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="default"
/>
@ -753,7 +913,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Default
</span>
</label>
@ -765,6 +927,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="small"
/>
@ -772,7 +935,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Small
</span>
</label>
@ -794,6 +959,7 @@ Array [
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -861,6 +1027,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -924,6 +1091,7 @@ Array [
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -983,6 +1151,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-dashed ant-btn-color-default ant-btn-variant-dashed ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -1150,6 +1319,236 @@ Array [
</span>
</button>
</div>
<div
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center ant-divider-plain"
role="separator"
>
<span
class="ant-divider-inner-text"
>
👇🏻 https://github.com/ant-design/ant-design/issues/52124 👇🏻
</span>
</div>
<div>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
style="height:60px"
type="button"
>
<span>
without icon
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
style="height:60px"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</span>
<span>
with icon
</span>
</button>
</div>
<div
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center ant-divider-plain"
role="separator"
>
<span
class="ant-divider-inner-text"
>
👇🏻 https://github.com/ant-design/ant-design/issues/51380 👇🏻
</span>
</div>
<div>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only"
type="button"
>
<span
class="ant-btn-icon"
>
<svg
class="my-class-name"
fill="none"
height="1em"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 3h7a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-7m0-18H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7m0-18v18"
/>
</svg>
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
type="button"
>
<span
class="ant-btn-icon"
>
<svg
fill="none"
height="1em"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
width="1em"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M12 3h7a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-7m0-18H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7m0-18v18"
/>
</svg>
</span>
<span>
custom icon
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</span>
<span>
with icon
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg"
type="button"
>
<span>
without icon
</span>
</button>
<span
class="ant-input-group-wrapper ant-input-group-wrapper-lg ant-input-group-wrapper-outlined ant-input-search ant-input-search-large"
style="width:100px"
>
<span
class="ant-input-wrapper ant-input-group"
>
<input
class="ant-input ant-input-lg ant-input-outlined"
type="search"
value=""
/>
<span
class="ant-input-group-addon"
>
<button
class="ant-btn ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-lg ant-btn-icon-only ant-input-search-button"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="search"
class="anticon anticon-search"
role="img"
>
<svg
aria-hidden="true"
data-icon="search"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
/>
</svg>
</span>
</span>
</button>
</span>
</span>
</span>
</div>
<div
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-center ant-divider-plain"
role="separator"
@ -1500,6 +1899,7 @@ exports[`renders components/button/demo/icon.tsx correctly 1`] = `
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-icon-only"
type="button"
>
@ -1567,6 +1967,7 @@ exports[`renders components/button/demo/icon.tsx correctly 1`] = `
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-icon-only"
type="button"
>
@ -1630,6 +2031,7 @@ exports[`renders components/button/demo/icon.tsx correctly 1`] = `
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-icon-only"
type="button"
>
@ -1689,6 +2091,7 @@ exports[`renders components/button/demo/icon.tsx correctly 1`] = `
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-dashed ant-btn-color-default ant-btn-variant-dashed ant-btn-icon-only"
type="button"
>
@ -1800,6 +2203,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="start"
/>
@ -1807,7 +2211,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
start
</span>
</label>
@ -1820,6 +2226,7 @@ Array [
<input
checked=""
class="ant-radio-button-input"
name="test-id"
type="radio"
value="end"
/>
@ -1827,7 +2234,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
end
</span>
</label>
@ -1851,6 +2260,7 @@ Array [
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-icon-only"
type="button"
>
@ -1918,6 +2328,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-icon-only"
type="button"
>
@ -1981,6 +2392,7 @@ Array [
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-default ant-btn-color-default ant-btn-variant-outlined ant-btn-icon-only"
type="button"
>
@ -2040,6 +2452,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-circle ant-btn-dashed ant-btn-color-default ant-btn-variant-dashed ant-btn-icon-only"
type="button"
>
@ -2186,6 +2599,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-sm ant-btn-icon-only"
disabled=""
type="button"
@ -2215,6 +2629,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-sm ant-btn-icon-only"
type="button"
>
@ -2264,6 +2679,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-icon-only"
disabled=""
type="button"
@ -2293,6 +2709,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-icon-only"
type="button"
>
@ -2342,6 +2759,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-lg ant-btn-icon-only"
disabled=""
type="button"
@ -2371,6 +2789,7 @@ Array [
</span>
</button>
<button
aria-describedby="test-id"
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-lg ant-btn-icon-only"
type="button"
>
@ -2553,6 +2972,37 @@ exports[`renders components/button/demo/loading.tsx correctly 1`] = `
</span>
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid ant-btn-loading"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="sync"
class="anticon anticon-sync anticon-spin"
role="img"
>
<svg
aria-hidden="true"
data-icon="sync"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M168 504.2c1-43.7 10-86.1 26.9-126 17.3-41 42.1-77.7 73.7-109.4S337 212.3 378 195c42.4-17.9 87.4-27 133.9-27s91.5 9.1 133.8 27A341.5 341.5 0 01755 268.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.7 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c0-6.7-7.7-10.5-12.9-6.3l-56.4 44.1C765.8 155.1 646.2 92 511.8 92 282.7 92 96.3 275.6 92 503.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8zm756 7.8h-60c-4.4 0-7.9 3.5-8 7.8-1 43.7-10 86.1-26.9 126-17.3 41-42.1 77.8-73.7 109.4A342.45 342.45 0 01512.1 856a342.24 342.24 0 01-243.2-100.8c-9.9-9.9-19.2-20.4-27.8-31.4l60.2-47a8 8 0 00-3-14.1l-175.7-43c-5-1.2-9.9 2.6-9.9 7.7l-.7 181c0 6.7 7.7 10.5 12.9 6.3l56.4-44.1C258.2 868.9 377.8 932 512.2 932c229.2 0 415.5-183.7 419.8-411.8a8 8 0 00-8-8.2z"
/>
</svg>
</span>
</span>
<span>
Loading Icon
</span>
</button>
</div>
<div
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
@ -2632,6 +3082,37 @@ exports[`renders components/button/demo/loading.tsx correctly 1`] = `
</span>
</span>
</button>
<button
class="ant-btn ant-btn-primary ant-btn-color-primary ant-btn-variant-solid"
type="button"
>
<span
class="ant-btn-icon"
>
<span
aria-label="poweroff"
class="anticon anticon-poweroff"
role="img"
>
<svg
aria-hidden="true"
data-icon="poweroff"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M705.6 124.9a8 8 0 00-11.6 7.2v64.2c0 5.5 2.9 10.6 7.5 13.6a352.2 352.2 0 0162.2 49.8c32.7 32.8 58.4 70.9 76.3 113.3a355 355 0 0127.9 138.7c0 48.1-9.4 94.8-27.9 138.7a355.92 355.92 0 01-76.3 113.3 353.06 353.06 0 01-113.2 76.4c-43.8 18.6-90.5 28-138.5 28s-94.7-9.4-138.5-28a353.06 353.06 0 01-113.2-76.4A355.92 355.92 0 01184 650.4a355 355 0 01-27.9-138.7c0-48.1 9.4-94.8 27.9-138.7 17.9-42.4 43.6-80.5 76.3-113.3 19-19 39.8-35.6 62.2-49.8 4.7-2.9 7.5-8.1 7.5-13.6V132c0-6-6.3-9.8-11.6-7.2C178.5 195.2 82 339.3 80 506.3 77.2 745.1 272.5 943.5 511.2 944c239 .5 432.8-193.3 432.8-432.4 0-169.2-97-315.7-238.4-386.7zM480 560h64c4.4 0 8-3.6 8-8V88c0-4.4-3.6-8-8-8h-64c-4.4 0-8 3.6-8 8v464c0 4.4 3.6 8 8 8z"
/>
</svg>
</span>
</span>
<span>
Loading Icon
</span>
</button>
</div>
</div>
`;
@ -2713,6 +3194,7 @@ Array [
<input
checked=""
class="ant-radio-button-input"
name="test-id"
type="radio"
value="large"
/>
@ -2720,7 +3202,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Large
</span>
</label>
@ -2732,6 +3216,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="default"
/>
@ -2739,7 +3224,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Default
</span>
</label>
@ -2751,6 +3238,7 @@ Array [
>
<input
class="ant-radio-button-input"
name="test-id"
type="radio"
value="small"
/>
@ -2758,7 +3246,9 @@ Array [
class="ant-radio-button-inner"
/>
</span>
<span>
<span
class="ant-radio-button-label"
>
Small
</span>
</label>

View File

@ -1,14 +1,15 @@
import React, { Suspense, useRef, useState } from 'react';
import { SearchOutlined } from '@ant-design/icons';
import { resetWarned } from 'rc-util/lib/warning';
import { resetWarned } from '@rc-component/util/lib/warning';
import Button from '..';
import Button, { _ButtonVariantTypes } from '..';
import type { GetRef } from '../../_util/type';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
import ConfigProvider from '../../config-provider';
import theme from '../../theme';
import { PresetColors } from '../../theme/interface';
import type { BaseButtonProps } from '../button';
describe('Button', () => {
@ -475,6 +476,20 @@ describe('Button', () => {
});
});
it('should render preset colors and variants correctly', () => {
PresetColors.forEach((color) => {
_ButtonVariantTypes.forEach((variant) => {
const { container } = render(
<Button color={color} variant={variant}>
{color}
</Button>,
);
expect(container.firstChild).toHaveClass(`ant-btn-color-${color}`);
expect(container.firstChild).toHaveClass(`ant-btn-variant-${variant}`);
});
});
});
it('autoFocus should work', () => {
const { container } = render(<Button autoFocus>button</Button>);

View File

@ -16,7 +16,7 @@ jest.mock('react-dom', () => {
return realReactDOM;
});
jest.mock('rc-util/lib/Dom/isVisible', () => {
jest.mock('@rc-component/util/lib/Dom/isVisible', () => {
const mockFn = () => true;
return mockFn;
});

View File

@ -1,7 +1,7 @@
import React, { Children, useContext, useEffect, useMemo, useRef, useState } from 'react';
import omit from '@rc-component/util/lib/omit';
import { useComposeRef } from '@rc-component/util/lib/ref';
import classNames from 'classnames';
import omit from 'rc-util/lib/omit';
import { useComposeRef } from 'rc-util/lib/ref';
import { devUseWarning } from '../_util/warning';
import Wave from '../_util/wave';
@ -19,8 +19,8 @@ import type {
ButtonVariantType,
} from './buttonHelpers';
import { isTwoCNChar, isUnBorderedButtonVariant, spaceChildren } from './buttonHelpers';
import DefaultLoadingIcon from './DefaultLoadingIcon';
import IconWrapper from './IconWrapper';
import LoadingIcon from './LoadingIcon';
import useStyle from './style';
import Compact from './style/compact';
@ -35,7 +35,7 @@ export interface BaseButtonProps {
shape?: ButtonShape;
size?: SizeType;
disabled?: boolean;
loading?: boolean | { delay?: number };
loading?: boolean | { delay?: number; icon?: React.ReactNode };
prefixCls?: string;
className?: string;
rootClassName?: string;
@ -310,8 +310,12 @@ const InternalCompoundedButton = React.forwardRef<
<IconWrapper prefixCls={prefixCls} className={iconClasses} style={iconStyle}>
{icon}
</IconWrapper>
) : typeof loading === 'object' && loading.icon ? (
<IconWrapper prefixCls={prefixCls} className={iconClasses} style={iconStyle}>
{loading.icon}
</IconWrapper>
) : (
<LoadingIcon
<DefaultLoadingIcon
existIcon={!!icon}
prefixCls={prefixCls}
loading={innerLoading}

View File

@ -1,6 +1,7 @@
import React from 'react';
import { cloneElement, isFragment } from '../_util/reactNode';
import { PresetColors } from '../theme/interface';
import type { BaseButtonProps, LegacyButtonType } from './button';
const rxTwoCNChar = /^[\u4E00-\u9FA5]{2}$/;
@ -106,5 +107,6 @@ export const _ButtonVariantTypes = [
] as const;
export type ButtonVariantType = (typeof _ButtonVariantTypes)[number];
export const _ButtonColorTypes = ['default', 'primary', 'danger'] as const;
export const _ButtonColorTypes = ['default', 'primary', 'danger', ...PresetColors] as const;
export type ButtonColorType = (typeof _ButtonColorTypes)[number];

View File

@ -68,6 +68,66 @@ const App: React.FC = () => {
Link
</Button>
</Flex>
<Flex gap="small" wrap>
<Button color="pink" variant="solid">
Solid
</Button>
<Button color="pink" variant="outlined">
Outlined
</Button>
<Button color="pink" variant="dashed">
Dashed
</Button>
<Button color="pink" variant="filled">
Filled
</Button>
<Button color="pink" variant="text">
Text
</Button>
<Button color="pink" variant="link">
Link
</Button>
</Flex>
<Flex gap="small" wrap>
<Button color="purple" variant="solid">
Solid
</Button>
<Button color="purple" variant="outlined">
Outlined
</Button>
<Button color="purple" variant="dashed">
Dashed
</Button>
<Button color="purple" variant="filled">
Filled
</Button>
<Button color="purple" variant="text">
Text
</Button>
<Button color="purple" variant="link">
Link
</Button>
</Flex>
<Flex gap="small" wrap>
<Button color="cyan" variant="solid">
Solid
</Button>
<Button color="cyan" variant="outlined">
Outlined
</Button>
<Button color="cyan" variant="dashed">
Dashed
</Button>
<Button color="cyan" variant="filled">
Filled
</Button>
<Button color="cyan" variant="text">
Text
</Button>
<Button color="cyan" variant="link">
Link
</Button>
</Flex>
</Flex>
</ConfigProvider>
);

View File

@ -54,7 +54,7 @@ const App: React.FC = () => {
<Flex vertical gap="small">
{/* link color */}
<Flex gap="small">
<ConfigProvider theme={{ token: { colorPrimary: 'red' } }}>
<ConfigProvider theme={{ token: { colorLink: '#FF0000' } }}>
<Button type="link">Link Button</Button>
</ConfigProvider>
<Button type="link">Link Button</Button>

View File

@ -1,7 +1,8 @@
import React from 'react';
import { MinusSquareOutlined, SearchOutlined } from '@ant-design/icons';
import { Button, ConfigProvider, Divider, Flex, Radio, Tooltip } from 'antd';
import { Button, ConfigProvider, Divider, Flex, Radio, Tooltip, Input } from 'antd';
import type { ConfigProviderProps } from 'antd';
import { FiColumns } from 'react-icons/fi';
type SizeType = ConfigProviderProps['componentSize'];
@ -63,6 +64,35 @@ const App: React.FC = () => {
<Button>without icon</Button>
<Button icon={<SearchOutlined />}>with icon</Button>
</div>
<Divider plain>👇🏻 https://github.com/ant-design/ant-design/issues/52124 👇🏻</Divider>
<div>
<Button
style={{
height: 60,
}}
>
without icon
</Button>
<Button
icon={<SearchOutlined />}
style={{
height: 60,
}}
>
with icon
</Button>
</div>
<Divider plain>👇🏻 https://github.com/ant-design/ant-design/issues/51380 👇🏻</Divider>
<div>
<Button size="large" icon={<FiColumns className="my-class-name" />} />
<Button size="large" icon={<FiColumns />}>
custom icon
</Button>
<Button icon={<SearchOutlined />} />
<Button icon={<SearchOutlined />}>with icon</Button>
<Button size="large">without icon</Button>
<Input.Search style={{ width: 100 }} />
</div>
<Divider plain>👇🏻 https://github.com/ant-design/ant-design/issues/51380 👇🏻</Divider>
<Flex
gap="small"

View File

@ -1,7 +1,7 @@
## zh-CN
添加 `loading` 属性即可让按钮处于加载状态,最后三个按钮演示点击后进入加载状态。
添加 `loading` 属性即可让按钮处于加载状态,`loading.icon` 可以自定义加载图标,最后三个按钮演示点击后进入加载状态。
## en-US
A loading indicator can be added to a button by setting the `loading` property on the `Button`.
A loading indicator can be added to a button by setting the `loading` property on the `Button`. The `loading.icon` can be used to customize the loading icon.

View File

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { PoweroffOutlined } from '@ant-design/icons';
import { PoweroffOutlined, SyncOutlined } from '@ant-design/icons';
import { Button, Flex } from 'antd';
const App: React.FC = () => {
@ -31,6 +31,9 @@ const App: React.FC = () => {
Loading
</Button>
<Button type="primary" icon={<PoweroffOutlined />} loading />
<Button type="primary" loading={{ icon: <SyncOutlined spin /> }}>
Loading Icon
</Button>
</Flex>
<Flex gap="small" wrap>
<Button type="primary" loading={loadings[0]} onClick={() => enterLoading(0)}>
@ -58,6 +61,14 @@ const App: React.FC = () => {
loading={loadings[3]}
onClick={() => enterLoading(3)}
/>
<Button
type="primary"
icon={<PoweroffOutlined />}
loading={loadings[3] && { icon: <SyncOutlined spin /> }}
onClick={() => enterLoading(3)}
>
Loading Icon
</Button>
</Flex>
</Flex>
);

View File

@ -63,7 +63,7 @@ Different button styles generated by setting Button properties. The recommended
| autoInsertSpace | We add a space between two Chinese characters by default, which removed by setting `autoInsertSpace` to `false`. | boolean | `true` | 5.17.0 |
| block | Option to fit button width to its parent width | boolean | false | |
| classNames | Semantic DOM class | [Record<SemanticDOM, string>](#semantic-dom) | - | 5.4.0 |
| color | Set button color | `default` \| `primary` \| `danger` | - | 5.21.0 |
| color | Set button color | `default` \| `primary` \| `danger` \| [PresetColors](#presetcolors) | - | `default`, `primary` and `danger`: 5.21.0, `PresetColors`: 5.23.0 |
| danger | Syntactic sugar. Set the danger status of button. will follow `color` if provided | boolean | false | |
| disabled | Disabled state of button | boolean | false | |
| ghost | Make background transparent and invert text and border colors | boolean | false | |
@ -71,7 +71,7 @@ Different button styles generated by setting Button properties. The recommended
| htmlType | Set the original html `type` of `button`, see: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#type) | `submit` \| `reset` \| `button` | `button` | |
| icon | Set the icon component of button | ReactNode | - | |
| iconPosition | Set the icon position of button | `start` \| `end` | `start` | 5.17.0 |
| loading | Set the loading status of button | boolean \| { delay: number } | false | |
| loading | Set the loading status of button | boolean \| { delay: number, icon: ReactNode } | false | icon: 5.23.0 |
| shape | Can be used to set button shape | `default` \| `circle` \| `round` | `default` | |
| size | Set the size of button | `large` \| `middle` \| `small` | `middle` | |
| styles | Semantic DOM style | [Record<SemanticDOM, CSSProperties>](#semantic-dom) | - | 5.4.0 |
@ -82,6 +82,10 @@ Different button styles generated by setting Button properties. The recommended
It accepts all props which native buttons support.
### PresetColors
> type PresetColors = 'blue' | 'purple' | 'cyan' | 'green' | 'magenta' | 'pink' | 'red' | 'orange' | 'yellow' | 'volcano' | 'geekblue' | 'lime' | 'gold';
## Semantic DOM
<code src="./demo/_semantic.tsx" simplify="true"></code>

Some files were not shown because too many files have changed in this diff Show More