Revert "Merge remote-tracking branch 'origin/feature' into fix/datePicker"

This reverts commit 852394c198, reversing
changes made to d661c7b009.
This commit is contained in:
jrr997 2023-06-04 14:40:58 +08:00
parent 852394c198
commit 1471235e67
257 changed files with 5839 additions and 29621 deletions

View File

@ -1,24 +1,18 @@
import { ConfigProvider, theme as antdTheme } from 'antd';
import { theme } from 'antd';
import type { ThemeProviderProps } from 'antd-style';
import { ThemeProvider } from 'antd-style';
import { ConfigContext } from 'antd/es/config-provider';
import type { FC } from 'react';
import React, { useContext } from 'react';
import { useContext } from 'react';
const SiteThemeProvider: FC<ThemeProviderProps> = ({ children, theme, ...rest }) => {
const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext);
const SiteThemeProvider: FC<ThemeProviderProps> = ({ children, ...rest }) => {
const { getPrefixCls, iconPrefixCls } = useContext(ConfigContext);
const rootPrefixCls = getPrefixCls();
const { token } = antdTheme.useToken();
React.useEffect(() => {
ConfigProvider.config({
theme,
});
}, [theme]);
const { token } = theme.useToken();
return (
<ThemeProvider
{...rest}
theme={theme}
customToken={{
headerHeight: 64,
menuItemBorder: 2,

View File

@ -2,6 +2,7 @@
import KeyCode from 'rc-util/lib/KeyCode';
import React from 'react';
import { fireEvent, render, waitFakeTimer } from '../../../tests/utils';
import getDataOrAriaProps from '../getDataOrAriaProps';
import { isStyleSupport } from '../styleChecker';
import throttleByAnimationFrame from '../throttleByAnimationFrame';
import TransButton from '../transButton';
@ -45,6 +46,57 @@ describe('Test utils function', () => {
});
});
describe('getDataOrAriaProps', () => {
it('returns all data-* properties from an object', () => {
const props = {
onClick: () => {},
isOpen: true,
'data-test': 'test-id',
'data-id': 1234,
};
const results = getDataOrAriaProps(props);
expect(results).toEqual({
'data-test': 'test-id',
'data-id': 1234,
});
});
it('does not return data-__ properties from an object', () => {
const props = {
onClick: () => {},
isOpen: true,
'data-__test': 'test-id',
'data-__id': 1234,
};
const results = getDataOrAriaProps(props);
expect(results).toEqual({});
});
it('returns all aria-* properties from an object', () => {
const props = {
onClick: () => {},
isOpen: true,
'aria-labelledby': 'label-id',
'aria-label': 'some-label',
};
const results = getDataOrAriaProps(props);
expect(results).toEqual({
'aria-labelledby': 'label-id',
'aria-label': 'some-label',
});
});
it('returns role property from an object', () => {
const props = {
onClick: () => {},
isOpen: true,
role: 'search',
};
const results = getDataOrAriaProps(props);
expect(results).toEqual({ role: 'search' });
});
});
describe('TransButton', () => {
it('can be focus/blur', () => {
const ref = React.createRef<HTMLDivElement>();

View File

@ -0,0 +1,11 @@
export default function getDataOrAriaProps(props: any) {
return Object.keys(props).reduce((prev: any, key: string) => {
if (
(key.startsWith('data-') || key.startsWith('aria-') || key === 'role') &&
!key.startsWith('data-__')
) {
prev[key] = props[key];
}
return prev;
}, {});
}

View File

@ -5,9 +5,9 @@ import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled';
import classNames from 'classnames';
import CSSMotion from 'rc-motion';
import pickAttrs from 'rc-util/lib/pickAttrs';
import type { ReactElement } from 'react';
import * as React from 'react';
import getDataOrAriaProps from '../_util/getDataOrAriaProps';
import { replaceElement } from '../_util/reactNode';
import { ConfigContext } from '../config-provider';
import ErrorBoundary from './ErrorBoundary';
@ -117,7 +117,7 @@ const Alert: CompoundedComponent = ({
}) => {
const [closed, setClosed] = React.useState(false);
const ref = React.useRef<HTMLDivElement>(null);
const ref = React.useRef<HTMLElement>();
const { getPrefixCls, direction } = React.useContext(ConfigContext);
const prefixCls = getPrefixCls('alert', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
@ -157,10 +157,7 @@ const Alert: CompoundedComponent = ({
hashId,
);
const dataOrAriaProps = pickAttrs(props, {
aria: true,
data: true,
});
const dataOrAriaProps = getDataOrAriaProps(props);
return wrapSSR(
<CSSMotion

View File

@ -79,85 +79,6 @@ exports[`renders components/anchor/demo/basic.tsx extend context correctly 1`] =
</div>
`;
exports[`renders components/anchor/demo/component-token.tsx extend context correctly 1`] = `
<div
class="ant-row"
>
<div
class="ant-col ant-col-16"
>
<div
id="part-1"
style="height: 100vh; background: rgba(255, 0, 0, 0.02);"
/>
<div
id="part-2"
style="height: 100vh; background: rgba(0, 255, 0, 0.02);"
/>
<div
id="part-3"
style="height: 100vh; background: rgba(0, 0, 255, 0.02);"
/>
</div>
<div
class="ant-col ant-col-8"
>
<div>
<div
class=""
>
<div
class="ant-anchor-wrapper"
style="max-height: 100vh;"
>
<div
class="ant-anchor"
>
<span
class="ant-anchor-ink ant-anchor-ink-visible"
style="top: 0px; height: 0px;"
/>
<div
class="ant-anchor-link ant-anchor-link-active"
>
<a
class="ant-anchor-link-title ant-anchor-link-title-active"
href="#part-1"
title="Part 1"
>
Part 1
</a>
</div>
<div
class="ant-anchor-link"
>
<a
class="ant-anchor-link-title"
href="#part-2"
title="Part 2"
>
Part 2
</a>
</div>
<div
class="ant-anchor-link"
>
<a
class="ant-anchor-link-title"
href="#part-3"
title="Part 3"
>
Part 3
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`renders components/anchor/demo/customizeHighlight.tsx extend context correctly 1`] = `
<div
class="ant-anchor-wrapper"

View File

@ -78,84 +78,6 @@ exports[`renders components/anchor/demo/basic.tsx correctly 1`] = `
</div>
`;
exports[`renders components/anchor/demo/component-token.tsx correctly 1`] = `
<div
class="ant-row"
>
<div
class="ant-col ant-col-16"
>
<div
id="part-1"
style="height:100vh;background:rgba(255,0,0,0.02)"
/>
<div
id="part-2"
style="height:100vh;background:rgba(0,255,0,0.02)"
/>
<div
id="part-3"
style="height:100vh;background:rgba(0,0,255,0.02)"
/>
</div>
<div
class="ant-col ant-col-8"
>
<div>
<div
class=""
>
<div
class="ant-anchor-wrapper"
style="max-height:100vh"
>
<div
class="ant-anchor"
>
<span
class="ant-anchor-ink"
/>
<div
class="ant-anchor-link"
>
<a
class="ant-anchor-link-title"
href="#part-1"
title="Part 1"
>
Part 1
</a>
</div>
<div
class="ant-anchor-link"
>
<a
class="ant-anchor-link-title"
href="#part-2"
title="Part 2"
>
Part 2
</a>
</div>
<div
class="ant-anchor-link"
>
<a
class="ant-anchor-link-title"
href="#part-3"
title="Part 3"
>
Part 3
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
exports[`renders components/anchor/demo/customizeHighlight.tsx correctly 1`] = `
<div
class="ant-anchor-wrapper"

View File

@ -1,7 +0,0 @@
## zh-CN
Component Token Debug.
## en-US
Component Token Debug

View File

@ -1,46 +0,0 @@
import { Anchor, Col, ConfigProvider, Row } from 'antd';
import React from 'react';
/** Test usage. Do not use in your production. */
export default () => (
<ConfigProvider
theme={{
components: {
Anchor: {
linkPaddingBlock: 100,
linkPaddingInlineStart: 50,
},
},
}}
>
<Row>
<Col span={16}>
<div id="part-1" style={{ height: '100vh', background: 'rgba(255,0,0,0.02)' }} />
<div id="part-2" style={{ height: '100vh', background: 'rgba(0,255,0,0.02)' }} />
<div id="part-3" style={{ height: '100vh', background: 'rgba(0,0,255,0.02)' }} />
</Col>
<Col span={8}>
<Anchor
items={[
{
key: 'part-1',
href: '#part-1',
title: 'Part 1',
},
{
key: 'part-2',
href: '#part-2',
title: 'Part 2',
},
{
key: 'part-3',
href: '#part-3',
title: 'Part 3',
},
]}
/>
</Col>
</Row>
</ConfigProvider>
);

View File

@ -30,7 +30,6 @@ For displaying anchor hyperlinks on page and jumping between them.
<code src="./demo/targetOffset.tsx" iframe="200">Set Anchor scroll offset</code>
<code src="./demo/onChange.tsx">Listening for anchor link change</code>
<code src="./demo/legacy-anchor.tsx" debug>Deprecated JSX demo</code>
<code src="./demo/component-token.tsx" debug>Component Token</code>
## API

View File

@ -31,7 +31,6 @@ group:
<code src="./demo/targetOffset.tsx" iframe="200">设置锚点滚动偏移量</code>
<code src="./demo/onChange.tsx">监听锚点链接改变</code>
<code src="./demo/legacy-anchor.tsx" debug>废弃的 JSX 示例</code>
<code src="./demo/component-token.tsx" debug>组件 Token</code>
## API

View File

@ -3,14 +3,13 @@ import { resetComponent, textEllipsis } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
export interface ComponentToken {
linkPaddingBlock: number;
linkPaddingInlineStart: number;
}
export interface ComponentToken {}
interface AnchorToken extends FullToken<'Anchor'> {
holderOffsetBlock: number;
anchorPaddingBlock: number;
anchorPaddingBlockSecondary: number;
anchorPaddingInline: number;
anchorBallSize: number;
anchorTitleBlock: number;
}
@ -35,14 +34,16 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
// delete overflow: auto
// overflow: 'auto',
backgroundColor: 'transparent',
[componentCls]: {
...resetComponent(token),
position: 'relative',
paddingInlineStart: lineWidthBold,
[`${componentCls}-link`]: {
paddingBlock: token.linkPaddingBlock,
paddingInline: `${token.linkPaddingInlineStart}px 0`,
paddingBlock: token.anchorPaddingBlock,
paddingInline: `${token.anchorPaddingInline}px 0`,
'&-title': {
...textEllipsis,
@ -151,21 +152,16 @@ const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = (token): CSSO
};
// ============================== Export ==============================
export default genComponentStyleHook(
'Anchor',
(token) => {
const { fontSize, fontSizeLG, paddingXXS } = token;
export default genComponentStyleHook('Anchor', (token) => {
const { fontSize, fontSizeLG, padding, paddingXXS } = token;
const anchorToken = mergeToken<AnchorToken>(token, {
holderOffsetBlock: paddingXXS,
anchorPaddingBlockSecondary: paddingXXS / 2,
anchorTitleBlock: (fontSize / 14) * 3,
anchorBallSize: fontSizeLG / 2,
});
return [genSharedAnchorStyle(anchorToken), genSharedAnchorHorizontalStyle(anchorToken)];
},
(token) => ({
linkPaddingBlock: token.paddingXXS,
linkPaddingInlineStart: token.padding,
}),
);
const anchorToken = mergeToken<AnchorToken>(token, {
holderOffsetBlock: paddingXXS,
anchorPaddingBlock: paddingXXS,
anchorPaddingBlockSecondary: paddingXXS / 2,
anchorPaddingInline: padding,
anchorTitleBlock: (fontSize / 14) * 3,
anchorBallSize: fontSizeLG / 2,
});
return [genSharedAnchorStyle(anchorToken), genSharedAnchorHorizontalStyle(anchorToken)];
});

View File

@ -342,243 +342,6 @@ exports[`renders components/avatar/demo/basic.tsx extend context correctly 1`] =
</div>
`;
exports[`renders components/avatar/demo/component-token.tsx extend context correctly 1`] = `
Array [
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
>
<span
class="ant-avatar ant-avatar-circle ant-avatar-image"
>
<img
src="http://abc.com/not-exist.jpg"
/>
</span>
</div>
</div>,
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
>
<div
class="ant-avatar-group"
>
<span
class="ant-avatar ant-avatar-circle ant-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel&key=2"
/>
</span>
<span
class="ant-avatar ant-avatar-circle"
style="background-color: rgb(245, 106, 0);"
>
<span
class="ant-avatar-string"
style="transform: scale(1) translateX(-50%);"
>
K
</span>
</span>
<span
class="ant-avatar ant-avatar-circle"
style="color: rgb(245, 106, 0); background-color: rgb(253, 227, 207);"
>
<span
class="ant-avatar-string"
style="transform: scale(1) translateX(-50%);"
>
+2
</span>
</span>
<div
class="ant-popover ant-zoom-big-appear ant-zoom-big-appear-prepare ant-zoom-big ant-avatar-group-popover ant-popover-placement-top"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-popover-arrow"
style="position: absolute; bottom: 0px; left: 0px;"
/>
<div
class="ant-popover-content"
>
<div
class="ant-popover-inner"
role="tooltip"
>
<div
class="ant-popover-inner-content"
>
<span
class="ant-avatar ant-avatar-circle ant-avatar-icon"
style="background-color: rgb(135, 208, 104);"
>
<span
aria-label="user"
class="anticon anticon-user"
role="img"
>
<svg
aria-hidden="true"
data-icon="user"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</span>
</span>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-tooltip-placement-top"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; bottom: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
>
Ant User
</div>
</div>
</div>
<span
class="ant-avatar ant-avatar-circle ant-avatar-icon"
style="background-color: rgb(24, 144, 255);"
>
<span
aria-label="ant-design"
class="anticon anticon-ant-design"
role="img"
>
<svg
aria-hidden="true"
data-icon="ant-design"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M716.3 313.8c19-18.9 19-49.7 0-68.6l-69.9-69.9.1.1c-18.5-18.5-50.3-50.3-95.3-95.2-21.2-20.7-55.5-20.5-76.5.5L80.9 474.2a53.84 53.84 0 000 76.4L474.6 944a54.14 54.14 0 0076.5 0l165.1-165c19-18.9 19-49.7 0-68.6a48.7 48.7 0 00-68.7 0l-125 125.2c-5.2 5.2-13.3 5.2-18.5 0L189.5 521.4c-5.2-5.2-5.2-13.3 0-18.5l314.4-314.2c.4-.4.9-.7 1.3-1.1 5.2-4.1 12.4-3.7 17.2 1.1l125.2 125.1c19 19 49.8 19 68.7 0zM408.6 514.4a106.3 106.2 0 10212.6 0 106.3 106.2 0 10-212.6 0zm536.2-38.6L821.9 353.5c-19-18.9-49.8-18.9-68.7.1a48.4 48.4 0 000 68.6l83 82.9c5.2 5.2 5.2 13.3 0 18.5l-81.8 81.7a48.4 48.4 0 000 68.6 48.7 48.7 0 0068.7 0l121.8-121.7a53.93 53.93 0 00-.1-76.4z"
/>
</svg>
</span>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>,
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
style="margin-right: 8px;"
>
<span
class="ant-badge"
>
<span
class="ant-avatar ant-avatar-square ant-avatar-icon"
>
<span
aria-label="user"
class="anticon anticon-user"
role="img"
>
<svg
aria-hidden="true"
data-icon="user"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</span>
</span>
<sup
class="ant-scroll-number ant-badge-count"
data-show="true"
title="1"
>
<span
class="ant-scroll-number-only"
style="transition: none;"
>
<span
class="ant-scroll-number-only-unit current"
>
1
</span>
</span>
</sup>
</span>
</div>
<div
class="ant-space-item"
>
<span
class="ant-badge"
>
<span
class="ant-avatar ant-avatar-square ant-avatar-icon"
>
<span
aria-label="user"
class="anticon anticon-user"
role="img"
>
<svg
aria-hidden="true"
data-icon="user"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</span>
</span>
<sup
class="ant-scroll-number ant-badge-dot"
data-show="true"
/>
</span>
</div>
</div>,
]
`;
exports[`renders components/avatar/demo/dynamic.tsx extend context correctly 1`] = `
Array [
<span

View File

@ -342,154 +342,6 @@ exports[`renders components/avatar/demo/basic.tsx correctly 1`] = `
</div>
`;
exports[`renders components/avatar/demo/component-token.tsx correctly 1`] = `
Array [
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
>
<span
class="ant-avatar ant-avatar-circle ant-avatar-image"
>
<img
src="http://abc.com/not-exist.jpg"
/>
</span>
</div>
</div>,
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
>
<div
class="ant-avatar-group"
>
<span
class="ant-avatar ant-avatar-circle ant-avatar-image"
>
<img
src="https://xsgames.co/randomusers/avatar.php?g=pixel&key=2"
/>
</span>
<span
class="ant-avatar ant-avatar-circle"
style="background-color:#f56a00"
>
<span
class="ant-avatar-string"
style="opacity:0"
>
K
</span>
</span>
<span
class="ant-avatar ant-avatar-circle"
style="color:#f56a00;background-color:#fde3cf"
>
<span
class="ant-avatar-string"
style="opacity:0"
>
+2
</span>
</span>
</div>
</div>
</div>,
<div
class="ant-space ant-space-horizontal ant-space-align-center"
>
<div
class="ant-space-item"
style="margin-right:8px"
>
<span
class="ant-badge"
>
<span
class="ant-avatar ant-avatar-square ant-avatar-icon"
>
<span
aria-label="user"
class="anticon anticon-user"
role="img"
>
<svg
aria-hidden="true"
data-icon="user"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</span>
</span>
<sup
class="ant-scroll-number ant-badge-count"
data-show="true"
title="1"
>
<span
class="ant-scroll-number-only"
style="transition:none"
>
<span
class="ant-scroll-number-only-unit current"
>
1
</span>
</span>
</sup>
</span>
</div>
<div
class="ant-space-item"
>
<span
class="ant-badge"
>
<span
class="ant-avatar ant-avatar-square ant-avatar-icon"
>
<span
aria-label="user"
class="anticon anticon-user"
role="img"
>
<svg
aria-hidden="true"
data-icon="user"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</span>
</span>
<sup
class="ant-scroll-number ant-badge-dot"
data-show="true"
/>
</span>
</div>
</div>,
]
`;
exports[`renders components/avatar/demo/dynamic.tsx correctly 1`] = `
Array [
<span

View File

@ -1,7 +0,0 @@
## zh-CN
Component Token Debug.
## en-US
Component Token Debug

View File

@ -1,51 +0,0 @@
import { AntDesignOutlined, UserOutlined } from '@ant-design/icons';
import { Avatar, Badge, ConfigProvider, Space, Tooltip } from 'antd';
import React from 'react';
const App: React.FC = () => (
<ConfigProvider
theme={{
components: {
Avatar: {
containerSize: 60,
containerSizeLG: 30,
containerSizeSM: 16,
textFontSize: 18,
textFontSizeLG: 28,
textFontSizeSM: 12,
borderRadius: 10,
groupOverlapping: -10,
groupBorderColor: '#eee',
},
},
}}
>
<Space>
<Avatar shape="circle" src="http://abc.com/not-exist.jpg">
A
</Avatar>
</Space>
<Space>
<Avatar.Group maxCount={2} maxStyle={{ color: '#f56a00', backgroundColor: '#fde3cf' }}>
<Avatar src="https://xsgames.co/randomusers/avatar.php?g=pixel&key=2" />
<Avatar style={{ backgroundColor: '#f56a00' }}>K</Avatar>
<Tooltip title="Ant User" placement="top">
<Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} />
</Tooltip>
<Avatar style={{ backgroundColor: '#1890ff' }} icon={<AntDesignOutlined />} />
</Avatar.Group>
</Space>
<Space>
<Badge count={1}>
<Avatar shape="square" icon={<UserOutlined />} />
</Badge>
<Badge dot>
<Avatar shape="square" icon={<UserOutlined />} />
</Badge>
</Space>
</ConfigProvider>
);
export default App;

View File

@ -23,7 +23,6 @@ Avatars can be used to represent people or objects. It supports images, `Icon`s,
<code src="./demo/toggle-debug.tsx" debug>Calculate text style when hiding</code>
<code src="./demo/responsive.tsx">Responsive Size</code>
<code src="./demo/fallback.tsx" debug>Fallback</code>
<code src="./demo/component-token.tsx" debug>Component Token</code>
## API

View File

@ -28,7 +28,6 @@ group:
<code src="./demo/toggle-debug.tsx" debug>隐藏情况下计算字符对齐</code>
<code src="./demo/responsive.tsx">响应式尺寸</code>
<code src="./demo/fallback.tsx" debug>图片不存在时</code>
<code src="./demo/component-token.tsx" debug>组件 Token</code>
## API

View File

@ -3,22 +3,21 @@ import { resetComponent } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
export interface ComponentToken {
containerSize: number;
containerSizeLG: number;
containerSizeSM: number;
textFontSize: number;
textFontSizeLG: number;
textFontSizeSM: number;
groupSpace: number;
groupOverlapping: number;
groupBorderColor: string;
}
export interface ComponentToken {}
type AvatarToken = FullToken<'Avatar'> & {
avatarBgColor: string;
avatarBg: string;
avatarColor: string;
avatarSizeBase: number;
avatarSizeLG: number;
avatarSizeSM: number;
avatarFontSizeBase: number;
avatarFontSizeLG: number;
avatarFontSizeSM: number;
avatarGroupOverlapping: number;
avatarGroupSpace: number;
avatarGroupBorderColor: string;
avatarBgColor: string;
};
const genBaseStyle: GenerateStyle<AvatarToken> = (token) => {
@ -28,12 +27,12 @@ const genBaseStyle: GenerateStyle<AvatarToken> = (token) => {
iconCls,
avatarBg,
avatarColor,
containerSize,
containerSizeLG,
containerSizeSM,
textFontSize,
textFontSizeLG,
textFontSizeSM,
avatarSizeBase,
avatarSizeLG,
avatarSizeSM,
avatarFontSizeBase,
avatarFontSizeLG,
avatarFontSizeSM,
borderRadius,
borderRadiusLG,
borderRadiusSM,
@ -90,14 +89,14 @@ const genBaseStyle: GenerateStyle<AvatarToken> = (token) => {
display: 'block',
},
...avatarSizeStyle(containerSize, textFontSize, borderRadius),
...avatarSizeStyle(avatarSizeBase, avatarFontSizeBase, borderRadius),
[`&-lg`]: {
...avatarSizeStyle(containerSizeLG, textFontSizeLG, borderRadiusLG),
...avatarSizeStyle(avatarSizeLG, avatarFontSizeLG, borderRadiusLG),
},
[`&-sm`]: {
...avatarSizeStyle(containerSizeSM, textFontSizeSM, borderRadiusSM),
...avatarSizeStyle(avatarSizeSM, avatarFontSizeSM, borderRadiusSM),
},
'> img': {
@ -111,65 +110,55 @@ const genBaseStyle: GenerateStyle<AvatarToken> = (token) => {
};
const genGroupStyle: GenerateStyle<AvatarToken> = (token) => {
const { componentCls, groupBorderColor, groupOverlapping, groupSpace } = token;
const { componentCls, avatarGroupBorderColor, avatarGroupSpace } = token;
return {
[`${componentCls}-group`]: {
display: 'inline-flex',
[`${componentCls}`]: {
borderColor: groupBorderColor,
borderColor: avatarGroupBorderColor,
},
[`> *:not(:first-child)`]: {
marginInlineStart: groupOverlapping,
},
},
[`${componentCls}-group-popover`]: {
[`${componentCls} + ${componentCls}`]: {
marginInlineStart: groupSpace,
marginInlineStart: avatarGroupSpace,
},
},
};
};
export default genComponentStyleHook(
'Avatar',
(token) => {
const { colorTextLightSolid, colorTextPlaceholder } = token;
const avatarToken = mergeToken<AvatarToken>(token, {
avatarBg: colorTextPlaceholder,
avatarColor: colorTextLightSolid,
});
return [genBaseStyle(avatarToken), genGroupStyle(avatarToken)];
},
(token) => {
const {
controlHeight,
controlHeightLG,
controlHeightSM,
export default genComponentStyleHook('Avatar', (token) => {
const {
colorTextLightSolid,
fontSize,
fontSizeLG,
fontSizeXL,
fontSizeHeading3,
controlHeight,
controlHeightLG,
controlHeightSM,
marginXS,
marginXXS,
colorBorderBg,
} = token;
return {
containerSize: controlHeight,
containerSizeLG: controlHeightLG,
containerSizeSM: controlHeightSM,
fontSize,
fontSizeLG,
fontSizeXL,
fontSizeHeading3,
textFontSize: Math.round((fontSizeLG + fontSizeXL) / 2),
textFontSizeLG: fontSizeHeading3,
textFontSizeSM: fontSize,
marginXS,
colorBorderBg,
colorTextPlaceholder,
} = token;
groupSpace: marginXXS,
groupOverlapping: -marginXS,
groupBorderColor: colorBorderBg,
};
},
);
const avatarToken = mergeToken<AvatarToken>(token, {
avatarBg: colorTextPlaceholder,
avatarColor: colorTextLightSolid,
avatarSizeBase: controlHeight,
avatarSizeLG: controlHeightLG,
avatarSizeSM: controlHeightSM,
avatarFontSizeBase: Math.round((fontSizeLG + fontSizeXL) / 2),
avatarFontSizeLG: fontSizeHeading3,
avatarFontSizeSM: fontSize,
avatarGroupSpace: -marginXS,
avatarGroupBorderColor: colorBorderBg,
});
return [genBaseStyle(avatarToken), genGroupStyle(avatarToken)];
});

View File

@ -63,333 +63,6 @@ exports[`renders components/breadcrumb/demo/basic.tsx extend context correctly 1
</nav>
`;
exports[`renders components/breadcrumb/demo/component-token.tsx extend context correctly 1`] = `
<nav
class="ant-breadcrumb"
>
<ol>
<li>
<span
class="ant-breadcrumb-link"
>
Home
</span>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<span
class="ant-breadcrumb-link"
>
<a
href=""
>
Application Center
</a>
</span>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<span
class="ant-dropdown-trigger ant-breadcrumb-overlay-link"
>
<span
class="ant-breadcrumb-link"
>
<a
href=""
>
General
</a>
</span>
<span
aria-label="down"
class="anticon anticon-down"
role="img"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
<div
class="ant-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-dropdown-placement-bottom"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
class="ant-dropdown-menu ant-dropdown-menu-root ant-dropdown-menu-vertical ant-dropdown-menu-light"
data-menu-list="true"
role="menu"
tabindex="0"
>
<li
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-1"
role="menuitem"
tabindex="-1"
>
<span
class="ant-dropdown-menu-title-content"
>
<a
href="http://www.alipay.com/"
rel="noopener noreferrer"
target="_blank"
>
General
</a>
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-2"
role="menuitem"
tabindex="-1"
>
<span
class="ant-dropdown-menu-title-content"
>
<a
href="http://www.taobao.com/"
rel="noopener noreferrer"
target="_blank"
>
Layout
</a>
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<li
class="ant-dropdown-menu-item ant-dropdown-menu-item-only-child"
data-menu-id="rc-menu-uuid-test-3"
role="menuitem"
tabindex="-1"
>
<span
class="ant-dropdown-menu-title-content"
>
<a
href="http://www.tmall.com/"
rel="noopener noreferrer"
target="_blank"
>
Navigation
</a>
</span>
</li>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</ul>
<div
aria-hidden="true"
style="display: none;"
>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
<div
class="ant-tooltip ant-zoom-big-fast-appear ant-zoom-big-fast-appear-prepare ant-zoom-big-fast ant-dropdown-menu-inline-collapsed-tooltip ant-tooltip-placement-right"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<div
class="ant-tooltip-arrow"
style="position: absolute; top: 0px; left: 0px;"
/>
<div
class="ant-tooltip-content"
>
<div
class="ant-tooltip-inner"
role="tooltip"
/>
</div>
</div>
</div>
</div>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<a
class="ant-breadcrumb-link"
href=""
>
Application Center
</a>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<a
class="ant-breadcrumb-link"
href=""
>
<span
aria-label="home"
class="anticon anticon-home"
role="img"
>
<svg
aria-hidden="true"
data-icon="home"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M946.5 505L560.1 118.8l-25.9-25.9a31.5 31.5 0 00-44.4 0L77.5 505a63.9 63.9 0 00-18.8 46c.4 35.2 29.7 63.3 64.9 63.3h42.5V940h691.8V614.3h43.4c17.1 0 33.2-6.7 45.3-18.8a63.6 63.6 0 0018.7-45.3c0-17-6.7-33.1-18.8-45.2zM568 868H456V664h112v204zm217.9-325.7V868H632V640c0-22.1-17.9-40-40-40H432c-22.1 0-40 17.9-40 40v228H238.1V542.3h-96l370-369.7 23.1 23.1L882 542.3h-96.1z"
/>
</svg>
</span>
</a>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<a
class="ant-breadcrumb-link"
href=""
>
<span
aria-label="user"
class="anticon anticon-user"
role="img"
>
<svg
aria-hidden="true"
data-icon="user"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</span>
<span>
Application List
</span>
</a>
</li>
</ol>
</nav>
`;
exports[`renders components/breadcrumb/demo/debug-routes.tsx extend context correctly 1`] = `
<nav
class="ant-breadcrumb"

View File

@ -63,160 +63,6 @@ exports[`renders components/breadcrumb/demo/basic.tsx correctly 1`] = `
</nav>
`;
exports[`renders components/breadcrumb/demo/component-token.tsx correctly 1`] = `
<nav
class="ant-breadcrumb"
>
<ol>
<li>
<span
class="ant-breadcrumb-link"
>
Home
</span>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<span
class="ant-breadcrumb-link"
>
<a
href=""
>
Application Center
</a>
</span>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<span
class="ant-dropdown-trigger ant-breadcrumb-overlay-link"
>
<span
class="ant-breadcrumb-link"
>
<a
href=""
>
General
</a>
</span>
<span
aria-label="down"
class="anticon anticon-down"
role="img"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<a
class="ant-breadcrumb-link"
href=""
>
Application Center
</a>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<a
class="ant-breadcrumb-link"
href=""
>
<span
aria-label="home"
class="anticon anticon-home"
role="img"
>
<svg
aria-hidden="true"
data-icon="home"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M946.5 505L560.1 118.8l-25.9-25.9a31.5 31.5 0 00-44.4 0L77.5 505a63.9 63.9 0 00-18.8 46c.4 35.2 29.7 63.3 64.9 63.3h42.5V940h691.8V614.3h43.4c17.1 0 33.2-6.7 45.3-18.8a63.6 63.6 0 0018.7-45.3c0-17-6.7-33.1-18.8-45.2zM568 868H456V664h112v204zm217.9-325.7V868H632V640c0-22.1-17.9-40-40-40H432c-22.1 0-40 17.9-40 40v228H238.1V542.3h-96l370-369.7 23.1 23.1L882 542.3h-96.1z"
/>
</svg>
</span>
</a>
</li>
<li
aria-hidden="true"
class="ant-breadcrumb-separator"
>
&gt;
</li>
<li>
<a
class="ant-breadcrumb-link"
href=""
>
<span
aria-label="user"
class="anticon anticon-user"
role="img"
>
<svg
aria-hidden="true"
data-icon="user"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</span>
<span>
Application List
</span>
</a>
</li>
</ol>
</nav>
`;
exports[`renders components/breadcrumb/demo/debug-routes.tsx correctly 1`] = `
<nav
class="ant-breadcrumb"

View File

@ -1,7 +0,0 @@
## zh-CN
Component Token Debug.
## en-US
Component Token Debug.

View File

@ -1,80 +0,0 @@
import { HomeOutlined, UserOutlined } from '@ant-design/icons';
import { Breadcrumb, ConfigProvider } from 'antd';
import React from 'react';
const menuItems = [
{
key: '1',
label: (
<a target="_blank" rel="noopener noreferrer" href="http://www.alipay.com/">
General
</a>
),
},
{
key: '2',
label: (
<a target="_blank" rel="noopener noreferrer" href="http://www.taobao.com/">
Layout
</a>
),
},
{
key: '3',
label: (
<a target="_blank" rel="noopener noreferrer" href="http://www.tmall.com/">
Navigation
</a>
),
},
];
export default () => (
<ConfigProvider
theme={{
components: {
Breadcrumb: {
itemColor: '#b02121',
lastItemColor: '#0f3a88',
iconFontSize: 28,
linkColor: '#979a42',
linkHoverColor: '#9450c0',
separatorColor: '#b41b60',
separatorMargin: 22,
},
},
}}
>
<Breadcrumb
separator=">"
items={[
{
title: 'Home',
},
{
title: <a href="">Application Center</a>,
},
{
title: <a href="">General</a>,
menu: { items: menuItems },
},
{
title: 'Application Center',
href: '',
},
{
href: '',
title: <HomeOutlined />,
},
{
href: '',
title: (
<>
<UserOutlined />
<span>Application List</span>
</>
),
},
]}
/>
</ConfigProvider>
);

View File

@ -42,7 +42,6 @@ return <Breadcrumb routes={[{ breadcrumbName: 'sample' }]} />;
<code src="./demo/overlay.tsx">Bread crumbs with drop down menu</code>
<code src="./demo/separator-component.tsx">Configuring the Separator Independently</code>
<code src="./demo/debug-routes.tsx">Debug Routes</code>
<code src="./demo/component-token.tsx" debug>Component Token</code>
## API

View File

@ -43,7 +43,6 @@ return <Breadcrumb routes={[{ breadcrumbName: 'sample' }]} />;
<code src="./demo/overlay.tsx">带下拉菜单的面包屑</code>
<code src="./demo/separator-component.tsx">独立的分隔符</code>
<code src="./demo/debug-routes.tsx">Debug Routes</code>
<code src="./demo/component-token.tsx" debug>组件 Token</code>
## API

View File

@ -3,29 +3,28 @@ import { genFocusStyle, resetComponent } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
export interface ComponentToken {
itemColor: string;
iconFontSize: number;
linkColor: string;
linkHoverColor: string;
lastItemColor: string;
separatorMargin: number;
separatorColor: string;
interface BreadcrumbToken extends FullToken<'Breadcrumb'> {
breadcrumbBaseColor: string;
breadcrumbFontSize: number;
breadcrumbIconFontSize: number;
breadcrumbLinkColor: string;
breadcrumbLinkColorHover: string;
breadcrumbLastItemColor: string;
breadcrumbSeparatorMargin: number;
breadcrumbSeparatorColor: string;
}
interface BreadcrumbToken extends FullToken<'Breadcrumb'> {}
const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) => {
const { componentCls, iconCls } = token;
return {
[componentCls]: {
...resetComponent(token),
color: token.itemColor,
fontSize: token.fontSize,
color: token.breadcrumbBaseColor,
fontSize: token.breadcrumbFontSize,
[iconCls]: {
fontSize: token.iconFontSize,
fontSize: token.breadcrumbIconFontSize,
},
ol: {
@ -37,7 +36,7 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
},
a: {
color: token.linkColor,
color: token.breadcrumbLinkColor,
transition: `color ${token.motionDurationMid}`,
padding: `0 ${token.paddingXXS}px`,
borderRadius: token.borderRadiusSM,
@ -46,7 +45,7 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
marginInline: -token.marginXXS,
'&:hover': {
color: token.linkHoverColor,
color: token.breadcrumbLinkColorHover,
backgroundColor: token.colorBgTextHover,
},
@ -54,12 +53,12 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
},
[`li:last-child`]: {
color: token.lastItemColor,
color: token.breadcrumbLastItemColor,
},
[`${componentCls}-separator`]: {
marginInline: token.separatorMargin,
color: token.separatorColor,
marginInline: token.breadcrumbSeparatorMargin,
color: token.breadcrumbSeparatorColor,
},
[`${componentCls}-link`]: {
@ -84,11 +83,11 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
},
'&:hover': {
color: token.linkHoverColor,
color: token.breadcrumbLinkColorHover,
backgroundColor: token.colorBgTextHover,
a: {
color: token.linkHoverColor,
color: token.breadcrumbLinkColorHover,
},
},
@ -108,19 +107,17 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
};
// ============================== Export ==============================
export default genComponentStyleHook(
'Breadcrumb',
(token) => {
const BreadcrumbToken = mergeToken<BreadcrumbToken>(token, {});
return [genBreadcrumbStyle(BreadcrumbToken)];
},
(token) => ({
itemColor: token.colorTextDescription,
lastItemColor: token.colorText,
iconFontSize: token.fontSize,
linkColor: token.colorTextDescription,
linkHoverColor: token.colorText,
separatorColor: token.colorTextDescription,
separatorMargin: token.marginXS,
}),
);
export default genComponentStyleHook('Breadcrumb', (token) => {
const BreadcrumbToken = mergeToken<BreadcrumbToken>(token, {
breadcrumbBaseColor: token.colorTextDescription,
breadcrumbFontSize: token.fontSize,
breadcrumbIconFontSize: token.fontSize,
breadcrumbLinkColor: token.colorTextDescription,
breadcrumbLinkColorHover: token.colorText,
breadcrumbLastItemColor: token.colorText,
breadcrumbSeparatorMargin: token.marginXS,
breadcrumbSeparatorColor: token.colorTextDescription,
});
return [genBreadcrumbStyle(BreadcrumbToken)];
});

View File

@ -121,11 +121,10 @@ const InternalButton: React.ForwardRefRenderFunction<
// React does not recognize the `htmlType` prop on a DOM element. Here we pick it out of `rest`.
htmlType = 'button',
classNames: customClassNames,
style: customStyle = {},
...rest
} = props;
const { getPrefixCls, autoInsertSpaceInButton, direction, button } = useContext(ConfigContext);
const { getPrefixCls, autoInsertSpaceInButton, direction } = useContext(ConfigContext);
const prefixCls = getPrefixCls('btn', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);
@ -239,17 +238,11 @@ const InternalButton: React.ForwardRefRenderFunction<
compactItemClassnames,
className,
rootClassName,
button?.className,
);
const fullStyle = { ...button?.style, ...customStyle };
const iconClasses = classNames(customClassNames?.icon, button?.classNames?.icon);
const iconStyle = { ...(styles?.icon || {}), ...(button?.styles?.icon || {}) };
const iconNode =
icon && !innerLoading ? (
<IconWrapper prefixCls={prefixCls} className={iconClasses} style={iconStyle}>
<IconWrapper prefixCls={prefixCls} className={customClassNames?.icon} style={styles?.icon}>
{icon}
</IconWrapper>
) : (
@ -264,7 +257,6 @@ const InternalButton: React.ForwardRefRenderFunction<
<a
{...linkButtonRestProps}
className={classes}
style={fullStyle}
onClick={handleClick}
ref={buttonRef as React.Ref<HTMLAnchorElement>}
>
@ -279,7 +271,6 @@ const InternalButton: React.ForwardRefRenderFunction<
{...(rest as NativeButtonProps)}
type={htmlType}
className={classes}
style={fullStyle}
onClick={handleClick}
disabled={mergedDisabled}
ref={buttonRef as React.Ref<HTMLButtonElement>}

View File

@ -5,7 +5,7 @@ import { useContext, useMemo } from 'react';
import { FormItemInputContext } from '../form/context';
import { Button, Group } from '../radio';
import Select from '../select';
import type { CalendarMode, SelectInfo } from './generateCalendar';
import type { CalendarMode } from './generateCalendar';
const YearSelectOffset = 10;
const YearSelectTotal = 20;
@ -147,7 +147,7 @@ export interface CalendarHeaderProps<DateType> {
locale: Locale;
mode: CalendarMode;
fullscreen: boolean;
onChange: (date: DateType, source: SelectInfo['source']) => void;
onChange: (date: DateType) => void;
onModeChange: (mode: CalendarMode) => void;
}
function CalendarHeader<DateType>(props: CalendarHeaderProps<DateType>) {
@ -165,6 +165,7 @@ function CalendarHeader<DateType>(props: CalendarHeaderProps<DateType>) {
const sharedProps = {
...props,
onChange,
fullscreen,
divRef,
};
@ -172,20 +173,8 @@ function CalendarHeader<DateType>(props: CalendarHeaderProps<DateType>) {
return (
<div className={`${prefixCls}-header`} ref={divRef}>
<FormItemInputContext.Provider value={mergedFormItemInputContext}>
<YearSelect
{...sharedProps}
onChange={(v) => {
onChange(v, 'year');
}}
/>
{mode === 'month' && (
<MonthSelect
{...sharedProps}
onChange={(v) => {
onChange(v, 'month');
}}
/>
)}
<YearSelect {...sharedProps} />
{mode === 'month' && <MonthSelect {...sharedProps} />}
</FormItemInputContext.Provider>
<ModeSwitch {...sharedProps} onModeChange={onModeChange} />
</div>

File diff suppressed because it is too large Load Diff

View File

@ -76,7 +76,7 @@ describe('Calendar', () => {
const { container } = render(<Calendar onSelect={onSelect} onChange={onChange} />);
fireEvent.click(container.querySelector('.ant-picker-cell')!);
expect(onSelect).toHaveBeenCalledWith(expect.anything(), { source: 'date' });
expect(onSelect).toHaveBeenCalledWith(expect.anything());
const value = onSelect.mock.calls[0][0];
expect(Dayjs.isDayjs(value)).toBe(true);
@ -270,7 +270,7 @@ describe('Calendar', () => {
const end = Dayjs('2019-11-01');
const onValueChange = jest.fn();
createWrapper(start, end, value, onValueChange);
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(3), 'year');
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(3));
});
it('if start.month > value.month, set value.month to start.month', () => {
@ -279,7 +279,7 @@ describe('Calendar', () => {
const end = Dayjs('2019-03-01');
const onValueChange = jest.fn();
createWrapper(start, end, value, onValueChange);
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(10), 'year');
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(10));
});
it('if change year and month > end month, set value.month to end.month', () => {
@ -302,7 +302,7 @@ describe('Calendar', () => {
fireEvent.click(
Array.from(wrapper.container.querySelectorAll('.ant-select-item-option')).at(-1)!,
);
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(2), 'year');
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(2));
});
it('onMonthChange should work correctly', () => {
@ -324,7 +324,7 @@ describe('Calendar', () => {
);
openSelect(wrapper.container, '.ant-picker-calendar-month-select');
clickSelectItem(wrapper.container);
expect(onValueChange).toHaveBeenCalledWith(value.month(10), 'month');
expect(onValueChange).toHaveBeenCalledWith(value.month(10));
});
it('onTypeChange should work correctly', () => {

View File

@ -1,99 +0,0 @@
import Dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import MockDate from 'mockdate';
import { resetWarned } from 'rc-util/lib/warning';
import React from 'react';
import Calendar from '..';
import { fireEvent, render, waitFakeTimer } from '../../../tests/utils';
describe('Calendar.onSelect', () => {
beforeAll(() => {
MockDate.set(Dayjs('2000-01-01').valueOf());
});
beforeEach(() => {
resetWarned();
jest.useFakeTimers();
jest.clearAllTimers();
});
afterEach(() => {
jest.useRealTimers();
});
it('source of year select', async () => {
const onSelect = jest.fn();
const { container } = render(<Calendar onSelect={onSelect} />);
fireEvent.mouseDown(container.querySelector('.ant-select-selector')!);
await waitFakeTimer();
fireEvent.click(container.querySelector('.ant-select-item-option')!);
await waitFakeTimer();
expect(onSelect).toHaveBeenCalledWith(expect.anything(), { source: 'year' });
});
it('source of month select', async () => {
const onSelect = jest.fn();
const { container } = render(<Calendar onSelect={onSelect} />);
fireEvent.mouseDown(container.querySelectorAll('.ant-select-selector')[1]!);
await waitFakeTimer();
fireEvent.click(container.querySelector('.ant-select-item-option')!);
await waitFakeTimer();
expect(onSelect).toHaveBeenCalledWith(expect.anything(), { source: 'month' });
});
it('source of customize', async () => {
const onSelect = jest.fn();
const { container } = render(
<Calendar
onSelect={onSelect}
headerRender={({ onChange }) => (
<button
className="bamboo"
type="button"
onClick={() => {
onChange(Dayjs('1999-01-01'));
}}
>
Trigger
</button>
)}
/>,
);
fireEvent.click(container.querySelector('.bamboo')!);
await waitFakeTimer();
expect(onSelect).toHaveBeenCalledWith(expect.anything(), { source: 'customize' });
});
it('source of date', () => {
const onSelect = jest.fn();
const { container } = render(<Calendar onSelect={onSelect} />);
fireEvent.click(container.querySelector('.ant-picker-cell')!);
expect(onSelect).toHaveBeenCalledWith(expect.anything(), { source: 'date' });
});
it('source of date with month panel', async () => {
const onSelect = jest.fn();
const onPanelChange = jest.fn();
const { container } = render(<Calendar onSelect={onSelect} onPanelChange={onPanelChange} />);
// Default is month radio
fireEvent.click(container.querySelector('.ant-picker-cell')!);
expect(onSelect).toHaveBeenCalledWith(expect.anything(), { source: 'date' });
// Click year radio
fireEvent.click(container.querySelectorAll('.ant-radio-button-input')[1]!);
expect(onPanelChange).toHaveBeenCalledWith(expect.anything(), 'year');
fireEvent.click(container.querySelector('.ant-picker-cell')!);
expect(onSelect).toHaveBeenCalledWith(expect.anything(), { source: 'month' });
});
});

View File

@ -1,7 +0,0 @@
## zh-CN
Component Token Debug.
## en-US
Component Token Debug.

View File

@ -1,29 +0,0 @@
import { Calendar, ConfigProvider } from 'antd';
import type { CalendarMode } from 'antd/es/calendar/generateCalendar';
import type { Dayjs } from 'dayjs';
import React from 'react';
/** Test usage. Do not use in your production. */
export default () => {
const onPanelChange = (value: Dayjs, mode: CalendarMode) => {
console.log(value.format('YYYY-MM-DD'), mode);
};
return (
<ConfigProvider
theme={{
components: {
Calendar: {
fullBg: 'red',
fullPanelBg: 'green',
itemActiveBg: 'black',
},
},
}}
>
<Calendar onPanelChange={onPanelChange} />
<br />
<Calendar onPanelChange={onPanelChange} fullscreen={false} />
</ConfigProvider>
);
};

View File

@ -43,10 +43,6 @@ export type HeaderRender<DateType> = (config: {
onTypeChange: (type: CalendarMode) => void;
}) => React.ReactNode;
export interface SelectInfo {
source: 'year' | 'month' | 'date' | 'customize';
}
export interface CalendarProps<DateType> {
prefixCls?: string;
className?: string;
@ -72,7 +68,7 @@ export interface CalendarProps<DateType> {
fullscreen?: boolean;
onChange?: (date: DateType) => void;
onPanelChange?: (date: DateType, mode: CalendarMode) => void;
onSelect?: (date: DateType, selectInfo: SelectInfo) => void;
onSelect?: (date: DateType) => void;
}
function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
@ -202,10 +198,10 @@ function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
triggerPanelChange(mergedValue, newMode);
};
const onInternalSelect = (date: DateType, source: SelectInfo['source']) => {
const onInternalSelect = (date: DateType) => {
triggerChange(date);
onSelect?.(date, { source });
onSelect?.(date);
};
// ====================== Locale ======================
@ -314,9 +310,7 @@ function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
headerRender({
value: mergedValue,
type: mergedMode,
onChange: (nextDate) => {
onInternalSelect(nextDate, 'customize');
},
onChange: onInternalSelect,
onTypeChange: triggerModeChange,
})
) : (
@ -338,9 +332,7 @@ function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
locale={contextLocale?.lang}
generateConfig={generateConfig}
cellRender={mergedCellRender}
onSelect={(nextDate) => {
onInternalSelect(nextDate, panelMode);
}}
onSelect={onInternalSelect}
mode={panelMode}
picker={panelMode}
disabledDate={mergedDisabledDate}

View File

@ -20,7 +20,6 @@ When data is in the form of dates, such as schedules, timetables, prices calenda
<code src="./demo/card.tsx" clientOnly>Card</code>
<code src="./demo/select.tsx" clientOnly>Selectable Calendar</code>
<code src="./demo/customize-header.tsx" clientOnly>Customize Header</code>
<code src="./demo/component-token.tsx" debug>Component Token</code>
## API
@ -56,7 +55,7 @@ When data is in the form of dates, such as schedules, timetables, prices calenda
| value | The current selected date | [dayjs](https://day.js.org/) | - | |
| onChange | Callback for when date changes | function(date: Dayjs) | - | |
| onPanelChange | Callback for when panel changes | function(date: Dayjs, mode: string) | - | |
| onSelect | Callback for when a date is selected, include source info | function(date: Dayjs, info: { source: 'year' \| 'month' \| 'date' \| 'customize' }) | - | `info`: 5.6.0 |
| onSelect | Callback for when a date is selected | function(date: Dayjs | - | |
## Design Token
@ -75,17 +74,3 @@ See [How to set locale for date-related components](/components/date-picker/#loc
### Date-related components locale is not working?
See FAQ [Date-related-components-locale-is-not-working?](/docs/react/faq#date-related-components-locale-is-not-working)
### How to get date from panel click?
`onSelect` provide `info.source` to help on this:
```tsx
<Calendar
onSelect={(date, { source }) => {
if (source === 'date') {
console.log('Panel Select:', source);
}
}}
/>
```

View File

@ -21,7 +21,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*-p-wQLik200AAA
<code src="./demo/card.tsx" clientOnly>卡片模式</code>
<code src="./demo/select.tsx" clientOnly>选择功能</code>
<code src="./demo/customize-header.tsx" clientOnly>自定义头部</code>
<code src="./demo/component-token.tsx" debug>组件 Token</code>
## API
@ -61,7 +60,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*-p-wQLik200AAA
| value | 展示日期 | [dayjs](https://day.js.org/) | - | |
| onChange | 日期变化回调 | function(date: Dayjs) | - | |
| onPanelChange | 日期面板变化回调 | function(date: Dayjs, mode: string) | - | |
| onSelect | 选择日期回调,包含来源信息 | function(date: Dayjs, info: { source: 'year' \| 'month' \| 'date' \| 'customize' }) | - | `info`: 5.6.0 |
| onSelect | 点击选择日期回调 | function(date: Dayjs | - | |
## Design Token
@ -80,17 +79,3 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*-p-wQLik200AAA
### 为什么时间类组件的国际化 locale 设置不生效?
参考 FAQ [为什么时间类组件的国际化 locale 设置不生效?](/docs/react/faq#为什么时间类组件的国际化-locale-设置不生效)。
### 如何仅获取来自面板点击的日期?
`onSelect` 事件提供额外的来源信息,你可以通过 `info.source` 来判断来源:
```tsx
<Calendar
onSelect={(date, { source }) => {
if (source === 'date') {
console.log('Panel Select:', source);
}
}}
/>
```

View File

@ -11,25 +11,26 @@ export interface ComponentToken {
yearControlWidth: number;
monthControlWidth: number;
miniContentHeight: number;
fullBg: string;
fullPanelBg: string;
itemActiveBg: string;
}
interface CalendarToken extends InputToken<FullToken<'Calendar'>>, PickerPanelToken {
calendarCls: string;
calendarFullBg: string;
calendarFullPanelBg: string;
calendarItemActiveBg: string;
dateValueHeight: number;
weekHeight: number;
dateContentHeight: number;
}
export const genCalendarStyles = (token: CalendarToken): CSSObject => {
const { calendarCls, componentCls, fullBg, fullPanelBg, itemActiveBg } = token;
const { calendarCls, componentCls, calendarFullBg, calendarFullPanelBg, calendarItemActiveBg } =
token;
return {
[calendarCls]: {
...genPanelStyle(token),
...resetComponent(token),
background: fullBg,
background: calendarFullBg,
'&-rtl': {
direction: 'rtl',
},
@ -51,7 +52,7 @@ export const genCalendarStyles = (token: CalendarToken): CSSObject => {
},
},
[`${calendarCls} ${componentCls}-panel`]: {
background: fullPanelBg,
background: calendarFullPanelBg,
border: 0,
borderTop: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
borderRadius: 0,
@ -91,7 +92,7 @@ export const genCalendarStyles = (token: CalendarToken): CSSObject => {
display: 'block',
width: '100%',
textAlign: 'end',
background: fullBg,
background: calendarFullBg,
border: 0,
[`${componentCls}-body`]: {
'th, td': {
@ -120,7 +121,7 @@ export const genCalendarStyles = (token: CalendarToken): CSSObject => {
// >>> Selected
[`&-in-view${componentCls}-cell-selected`]: {
[`${calendarCls}-date, ${calendarCls}-date-today`]: {
background: itemActiveBg,
background: calendarItemActiveBg,
},
},
'&-selected, &-selected:hover': {
@ -197,6 +198,9 @@ export default genComponentStyleHook(
{
calendarCls,
pickerCellInnerCls: `${token.componentCls}-cell-inner`,
calendarFullBg: token.colorBgContainer,
calendarFullPanelBg: token.colorBgContainer,
calendarItemActiveBg: token.controlItemBgActive,
dateValueHeight: token.controlHeightSM,
weekHeight: token.controlHeightSM * 0.75,
dateContentHeight:
@ -206,12 +210,9 @@ export default genComponentStyleHook(
return [genCalendarStyles(calendarToken)];
},
(token) => ({
fullBg: token.colorBgContainer,
fullPanelBg: token.colorBgContainer,
itemActiveBg: token.controlItemBgActive,
{
yearControlWidth: 80,
monthControlWidth: 70,
miniContentHeight: 256,
}),
},
);

View File

@ -1,5 +1,4 @@
import classNames from 'classnames';
import type { Tab } from 'rc-tabs/lib/interface';
import omit from 'rc-util/lib/omit';
import * as React from 'react';
import { ConfigContext } from '../config-provider';
@ -13,11 +12,10 @@ import useStyle from './style';
export type CardType = 'inner';
export type CardSize = 'default' | 'small';
export interface CardTabListType extends Omit<Tab, 'label'> {
export interface CardTabListType {
key: string;
/** @deprecated Please use `label` instead */
tab?: React.ReactNode;
label?: React.ReactNode;
tab: React.ReactNode;
disabled?: boolean;
}
export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
@ -125,9 +123,10 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>((props, ref) => {
{...extraProps}
className={`${prefixCls}-head-tabs`}
onChange={onTabChange}
items={tabList.map(({ tab, ...item }) => ({
label: tab,
...item,
items={tabList.map((item) => ({
label: item.tab,
key: item.key,
disabled: item.disabled ?? false,
}))}
/>
) : null;

View File

@ -130,284 +130,6 @@ exports[`renders components/card/demo/border-less.tsx extend context correctly 1
</div>
`;
exports[`renders components/card/demo/component-token.tsx extend context correctly 1`] = `
Array [
<div
class="ant-card ant-card-bordered ant-card-contain-tabs"
>
<div
class="ant-card-head"
>
<div
class="ant-card-head-wrapper"
>
<div
class="ant-card-head-title"
>
Card title
</div>
<div
class="ant-card-extra"
>
More
</div>
</div>
<div
class="ant-tabs ant-tabs-top ant-tabs-large ant-card-head-tabs"
>
<div
class="ant-tabs-nav"
role="tablist"
>
<div
class="ant-tabs-nav-wrap"
>
<div
class="ant-tabs-nav-list"
style="transform: translate(0px, 0px);"
>
<div
class="ant-tabs-tab ant-tabs-tab-active"
data-node-key="tab1"
>
<div
aria-controls="rc-tabs-test-panel-tab1"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-tab1"
role="tab"
tabindex="0"
>
tab1
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="tab2"
>
<div
aria-controls="rc-tabs-test-panel-tab2"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-tab2"
role="tab"
tabindex="0"
>
tab2
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
>
<button
aria-controls="rc-tabs-test-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
class="ant-tabs-nav-more"
id="rc-tabs-test-more"
style="visibility: hidden; order: 1;"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
<div
class="ant-tabs-dropdown ant-slide-up-appear ant-slide-up-appear-prepare ant-slide-up ant-tabs-dropdown-placement-bottomLeft"
style="--arrow-x: 0px; --arrow-y: 0px; left: -1000vw; top: -1000vh; box-sizing: border-box;"
>
<ul
aria-label="expanded dropdown"
class="ant-tabs-dropdown-menu ant-tabs-dropdown-menu-root ant-tabs-dropdown-menu-vertical"
data-menu-list="true"
id="rc-tabs-test-more-popup"
role="listbox"
tabindex="-1"
/>
<div
aria-hidden="true"
style="display: none;"
/>
</div>
</div>
</div>
<div
class="ant-tabs-content-holder"
>
<div
class="ant-tabs-content ant-tabs-content-top"
>
<div
aria-hidden="false"
aria-labelledby="rc-tabs-test-tab-tab1"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
id="rc-tabs-test-panel-tab1"
role="tabpanel"
tabindex="0"
/>
</div>
</div>
</div>
</div>
<div
class="ant-card-body"
>
<p>
Card content
</p>
<p>
Card content
</p>
<p>
Card content
</p>
</div>
<ul
class="ant-card-actions"
>
<li
style="width: 33.333333333333336%;"
>
<span>
<span
aria-label="setting"
class="anticon anticon-setting"
role="img"
>
<svg
aria-hidden="true"
data-icon="setting"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
/>
</svg>
</span>
</span>
</li>
<li
style="width: 33.333333333333336%;"
>
<span>
<span
aria-label="edit"
class="anticon anticon-edit"
role="img"
>
<svg
aria-hidden="true"
data-icon="edit"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M257.7 752c2 0 4-.2 6-.5L431.9 722c2-.4 3.9-1.3 5.3-2.8l423.9-423.9a9.96 9.96 0 000-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2a33.5 33.5 0 009.4 29.8c6.6 6.4 14.9 9.9 23.8 9.9zm67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z"
/>
</svg>
</span>
</span>
</li>
<li
style="width: 33.333333333333336%;"
>
<span>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</span>
</li>
</ul>
</div>,
<div
class="ant-card ant-card-bordered ant-card-small"
style="width: 300px;"
>
<div
class="ant-card-head"
>
<div
class="ant-card-head-wrapper"
>
<div
class="ant-card-head-title"
>
Small size card
</div>
<div
class="ant-card-extra"
>
<a
href="#"
>
More
</a>
</div>
</div>
</div>
<div
class="ant-card-body"
>
<p>
Card content
</p>
<p>
Card content
</p>
<p>
Card content
</p>
</div>
</div>,
]
`;
exports[`renders components/card/demo/flexible-content.tsx extend context correctly 1`] = `
<div
class="ant-card ant-card-bordered ant-card-hoverable"
@ -1049,6 +771,7 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-tab1"
aria-disabled="false"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-tab1"
@ -1064,6 +787,7 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-tab2"
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-tab2"
@ -1189,6 +913,7 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-article"
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-article"
@ -1204,6 +929,7 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-app"
aria-disabled="false"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-app"
@ -1219,6 +945,7 @@ Array [
>
<div
aria-controls="rc-tabs-test-panel-project"
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-project"

View File

@ -130,261 +130,6 @@ exports[`renders components/card/demo/border-less.tsx correctly 1`] = `
</div>
`;
exports[`renders components/card/demo/component-token.tsx correctly 1`] = `
Array [
<div
class="ant-card ant-card-bordered ant-card-contain-tabs"
>
<div
class="ant-card-head"
>
<div
class="ant-card-head-wrapper"
>
<div
class="ant-card-head-title"
>
Card title
</div>
<div
class="ant-card-extra"
>
More
</div>
</div>
<div
class="ant-tabs ant-tabs-top ant-tabs-large ant-card-head-tabs"
>
<div
class="ant-tabs-nav"
role="tablist"
>
<div
class="ant-tabs-nav-wrap"
>
<div
class="ant-tabs-nav-list"
style="transform:translate(0px, 0px)"
>
<div
class="ant-tabs-tab ant-tabs-tab-active"
data-node-key="tab1"
>
<div
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
tab1
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="tab2"
>
<div
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
tabindex="0"
>
tab2
</div>
</div>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
>
<button
aria-controls="null-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
class="ant-tabs-nav-more"
id="null-more"
style="visibility:hidden;order:1"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
</div>
</div>
<div
class="ant-tabs-content-holder"
>
<div
class="ant-tabs-content ant-tabs-content-top"
>
<div
aria-hidden="false"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
role="tabpanel"
tabindex="0"
/>
</div>
</div>
</div>
</div>
<div
class="ant-card-body"
>
<p>
Card content
</p>
<p>
Card content
</p>
<p>
Card content
</p>
</div>
<ul
class="ant-card-actions"
>
<li
style="width:33.333333333333336%"
>
<span>
<span
aria-label="setting"
class="anticon anticon-setting"
role="img"
>
<svg
aria-hidden="true"
data-icon="setting"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
/>
</svg>
</span>
</span>
</li>
<li
style="width:33.333333333333336%"
>
<span>
<span
aria-label="edit"
class="anticon anticon-edit"
role="img"
>
<svg
aria-hidden="true"
data-icon="edit"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M257.7 752c2 0 4-.2 6-.5L431.9 722c2-.4 3.9-1.3 5.3-2.8l423.9-423.9a9.96 9.96 0 000-14.1L694.9 114.9c-1.9-1.9-4.4-2.9-7.1-2.9s-5.2 1-7.1 2.9L256.8 538.8c-1.5 1.5-2.4 3.3-2.8 5.3l-29.5 168.2a33.5 33.5 0 009.4 29.8c6.6 6.4 14.9 9.9 23.8 9.9zm67.4-174.4L687.8 215l73.3 73.3-362.7 362.6-88.9 15.7 15.6-89zM880 836H144c-17.7 0-32 14.3-32 32v36c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-36c0-17.7-14.3-32-32-32z"
/>
</svg>
</span>
</span>
</li>
<li
style="width:33.333333333333336%"
>
<span>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</span>
</li>
</ul>
</div>,
<div
class="ant-card ant-card-bordered ant-card-small"
style="width:300px"
>
<div
class="ant-card-head"
>
<div
class="ant-card-head-wrapper"
>
<div
class="ant-card-head-title"
>
Small size card
</div>
<div
class="ant-card-extra"
>
<a
href="#"
>
More
</a>
</div>
</div>
</div>
<div
class="ant-card-body"
>
<p>
Card content
</p>
<p>
Card content
</p>
<p>
Card content
</p>
</div>
</div>,
]
`;
exports[`renders components/card/demo/flexible-content.tsx correctly 1`] = `
<div
class="ant-card ant-card-bordered ant-card-hoverable"
@ -1025,6 +770,7 @@ Array [
data-node-key="tab1"
>
<div
aria-disabled="false"
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
@ -1038,6 +784,7 @@ Array [
data-node-key="tab2"
>
<div
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
@ -1142,6 +889,7 @@ Array [
data-node-key="article"
>
<div
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"
@ -1155,6 +903,7 @@ Array [
data-node-key="app"
>
<div
aria-disabled="false"
aria-selected="true"
class="ant-tabs-tab-btn"
role="tab"
@ -1168,6 +917,7 @@ Array [
data-node-key="project"
>
<div
aria-disabled="false"
aria-selected="false"
class="ant-tabs-tab-btn"
role="tab"

View File

@ -1,268 +1,5 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Card correct pass tabList props 1`] = `
<div
class="ant-card ant-card-bordered ant-card-contain-tabs"
>
<div
class="ant-card-head"
>
<div
class="ant-card-head-wrapper"
/>
<div
class="ant-tabs ant-tabs-top ant-tabs-editable ant-tabs-large ant-tabs-card ant-tabs-editable-card ant-card-head-tabs"
>
<div
class="ant-tabs-nav"
role="tablist"
>
<div
class="ant-tabs-nav-wrap"
>
<div
class="ant-tabs-nav-list"
style="transform: translate(0px, 0px);"
>
<div
class="ant-tabs-tab ant-tabs-tab-with-remove ant-tabs-tab-active"
data-node-key="basic"
>
<div
aria-controls="rc-tabs-test-panel-basic"
aria-selected="true"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-basic"
role="tab"
tabindex="0"
>
Basic
</div>
<button
aria-label="remove"
class="ant-tabs-tab-remove"
tabindex="0"
type="button"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/>
</svg>
</span>
</button>
</div>
<div
class="ant-tabs-tab ant-tabs-tab-with-remove"
data-node-key="deprecated"
>
<div
aria-controls="rc-tabs-test-panel-deprecated"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-deprecated"
role="tab"
tabindex="0"
>
Deprecated
</div>
<button
aria-label="remove"
class="ant-tabs-tab-remove"
tabindex="0"
type="button"
>
<span
aria-label="close"
class="anticon anticon-close"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/>
</svg>
</span>
</button>
</div>
<div
class="ant-tabs-tab ant-tabs-tab-disabled"
data-node-key="disabled"
>
<div
aria-controls="rc-tabs-test-panel-disabled"
aria-disabled="true"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-disabled"
role="tab"
>
Disabled
</div>
</div>
<div
class="ant-tabs-tab"
data-node-key="notClosable"
>
<div
aria-controls="rc-tabs-test-panel-notClosable"
aria-selected="false"
class="ant-tabs-tab-btn"
id="rc-tabs-test-tab-notClosable"
role="tab"
tabindex="0"
>
NotClosable
</div>
</div>
<button
aria-label="Add tab"
class="ant-tabs-nav-add"
type="button"
>
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
>
<svg
aria-hidden="true"
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs>
<style />
</defs>
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
</button>
<div
class="ant-tabs-ink-bar ant-tabs-ink-bar-animated"
/>
</div>
</div>
<div
class="ant-tabs-nav-operations ant-tabs-nav-operations-hidden"
>
<button
aria-controls="rc-tabs-test-more-popup"
aria-expanded="false"
aria-haspopup="listbox"
aria-hidden="true"
class="ant-tabs-nav-more"
id="rc-tabs-test-more"
style="visibility: hidden; order: 1;"
tabindex="-1"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<svg
aria-hidden="true"
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
<button
aria-label="Add tab"
class="ant-tabs-nav-add"
type="button"
>
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
>
<svg
aria-hidden="true"
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs>
<style />
</defs>
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
</button>
</div>
</div>
<div
class="ant-tabs-content-holder"
>
<div
class="ant-tabs-content ant-tabs-content-top"
>
<div
aria-hidden="false"
aria-labelledby="rc-tabs-test-tab-basic"
class="ant-tabs-tabpane ant-tabs-tabpane-active"
id="rc-tabs-test-panel-basic"
role="tabpanel"
tabindex="0"
/>
</div>
</div>
</div>
</div>
<div
class="ant-card-body"
/>
</div>
`;
exports[`Card rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-card ant-card-bordered ant-card-rtl"

View File

@ -131,36 +131,4 @@ describe('Card', () => {
expect(cardRef.current).toHaveClass('ant-card');
});
it('correct pass tabList props', () => {
const { container } = render(
<Card
tabList={[
{
label: 'Basic',
key: 'basic',
},
{
tab: 'Deprecated',
key: 'deprecated',
},
{
tab: 'Disabled',
key: 'disabled',
disabled: true,
},
{
tab: 'NotClosable',
key: 'notClosable',
closable: false,
},
]}
tabProps={{
type: 'editable-card',
}}
/>,
);
expect(container.firstChild).toMatchSnapshot();
});
});

View File

@ -1,7 +0,0 @@
## zh-CN
Component Token Debug.
## en-US
Component Token Debug.

View File

@ -1,52 +0,0 @@
import { EditOutlined, EllipsisOutlined, SettingOutlined } from '@ant-design/icons';
import { Card, ConfigProvider } from 'antd';
import React from 'react';
export default () => (
<ConfigProvider
theme={{
components: {
Card: {
headerBg: '#e6f4ff',
headerFontSize: 20,
headerFontSizeSM: 20,
headerHeight: 60,
headerHeightSM: 60,
actionsBg: '#e6f4ff',
actionsLiMargin: `2px 0`,
tabsMarginBottom: 0,
extraColor: 'rgba(0,0,0,0.25)',
},
},
}}
>
<Card
title="Card title"
actions={[
<SettingOutlined key="setting" />,
<EditOutlined key="edit" />,
<EllipsisOutlined key="ellipsis" />,
]}
extra="More"
tabList={[
{
key: 'tab1',
label: 'tab1',
},
{
key: 'tab2',
label: 'tab2',
},
]}
>
<p>Card content</p>
<p>Card content</p>
<p>Card content</p>
</Card>
<Card size="small" title="Small size card" extra={<a href="#">More</a>} style={{ width: 300 }}>
<p>Card content</p>
<p>Card content</p>
<p>Card content</p>
</Card>
</ConfigProvider>
);

View File

@ -20,15 +20,15 @@ const contentList: Record<string, React.ReactNode> = {
const tabListNoTitle = [
{
key: 'article',
label: 'article',
tab: 'article',
},
{
key: 'app',
label: 'app',
tab: 'app',
},
{
key: 'project',
label: 'project',
tab: 'project',
},
];

View File

@ -25,7 +25,6 @@ A card can be used to display content related to a single subject. The content c
<code src="./demo/inner.tsx">Inner card</code>
<code src="./demo/tabs.tsx">With tabs</code>
<code src="./demo/meta.tsx">Support more content configuration</code>
<code src="./demo/component-token.tsx" debug>Component Token</code>
## API
@ -49,7 +48,7 @@ A card can be used to display content related to a single subject. The content c
| loading | Shows a loading indicator while the contents of the card are being fetched | boolean | false | |
| size | Size of card | `default` \| `small` | `default` | |
| tabBarExtraContent | Extra content in tab bar | ReactNode | - | |
| tabList | List of TabPane's head | [TabItemType](/components/tabs#tabitemtype)[] | - | |
| tabList | List of TabPane's head | Array&lt;{key: string, tab: ReactNode}> | - | |
| tabProps | [Tabs](/components/tabs/#tabs) | - | - | |
| title | Card title | ReactNode | - | |
| type | Card style type, can be set to `inner` or not set | string | - | |

View File

@ -26,7 +26,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*a-8zR6rrupgAAA
<code src="./demo/inner.tsx">内部卡片</code>
<code src="./demo/tabs.tsx">带页签的卡片</code>
<code src="./demo/meta.tsx">支持更多内容配置</code>
<code src="./demo/component-token.tsx" debug>组件 Token</code>
## API
@ -50,7 +49,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*a-8zR6rrupgAAA
| loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位 | boolean | false | |
| size | card 的尺寸 | `default` \| `small` | `default` | |
| tabBarExtraContent | tab bar 上额外的元素 | ReactNode | - | |
| tabList | 页签标题列表 | [TabItemType](/components/tabs#tabitemtype)[] | - | |
| tabList | 页签标题列表 | Array&lt;{key: string, tab: ReactNode}> | - | |
| tabProps | [Tabs](/components/tabs-cn#tabs) | - | - | |
| title | 卡片标题 | ReactNode | - | |
| type | 卡片类型,可设置为 `inner` 或 不设置 | string | - | |

View File

@ -4,23 +4,17 @@ import { clearFix, resetComponent, textEllipsis } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
export interface ComponentToken {
headerBg: string;
headerFontSize: number;
headerFontSizeSM: number;
headerHeight: number;
headerHeightSM: number;
actionsBg: string;
actionsLiMargin: string;
tabsMarginBottom: number;
extraColor: string;
}
export interface ComponentToken {}
interface CardToken extends FullToken<'Card'> {
cardHeadHeight: number;
cardHeadHeightSM: number;
cardShadow: string;
cardHeadPadding: number;
cardPaddingSM: number;
cardPaddingBase: number;
cardHeadTabsMarginBottom: number;
cardActionsLiMargin: string;
cardActionsIconSize: number;
}
@ -28,19 +22,19 @@ interface CardToken extends FullToken<'Card'> {
// ============================== Head ==============================
const genCardHeadStyle: GenerateStyle<CardToken> = (token): CSSObject => {
const { antCls, componentCls, headerHeight, cardPaddingBase, tabsMarginBottom } = token;
const { antCls, componentCls, cardHeadHeight, cardPaddingBase, cardHeadTabsMarginBottom } = token;
return {
display: 'flex',
justifyContent: 'center',
flexDirection: 'column',
minHeight: headerHeight,
minHeight: cardHeadHeight,
marginBottom: -1, // Fix card grid overflow bug: https://gw.alipayobjects.com/zos/rmsportal/XonYxBikwpgbqIQBeuhk.png
padding: `0 ${cardPaddingBase}px`,
color: token.colorTextHeading,
fontWeight: token.fontWeightStrong,
fontSize: token.headerFontSize,
background: token.headerBg,
fontSize: token.fontSizeLG,
background: 'transparent',
borderBottom: `${token.lineWidth}px ${token.lineType} ${token.colorBorderSecondary}`,
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`,
@ -69,7 +63,7 @@ const genCardHeadStyle: GenerateStyle<CardToken> = (token): CSSObject => {
[`${antCls}-tabs-top`]: {
clear: 'both',
marginBottom: tabsMarginBottom,
marginBottom: cardHeadTabsMarginBottom,
color: token.colorText,
fontWeight: 'normal',
fontSize: token.fontSize,
@ -108,26 +102,20 @@ const genCardGridStyle: GenerateStyle<CardToken> = (token): CSSObject => {
// ============================== Actions ==============================
const genCardActionsStyle: GenerateStyle<CardToken> = (token): CSSObject => {
const {
componentCls,
iconCls,
actionsLiMargin,
cardActionsIconSize,
colorBorderSecondary,
actionsBg,
} = token;
const { componentCls, iconCls, cardActionsLiMargin, cardActionsIconSize, colorBorderSecondary } =
token;
return {
margin: 0,
padding: 0,
listStyle: 'none',
background: actionsBg,
background: token.colorBgContainer,
borderTop: `${token.lineWidth}px ${token.lineType} ${colorBorderSecondary}`,
display: 'flex',
borderRadius: `0 0 ${token.borderRadiusLG}px ${token.borderRadiusLG}px `,
...clearFix(),
'& > li': {
margin: actionsLiMargin,
margin: cardActionsLiMargin,
color: token.colorTextDescription,
textAlign: 'center',
@ -243,7 +231,6 @@ const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
colorBorderSecondary,
boxShadowTertiary,
cardPaddingBase,
extraColor,
} = token;
return {
@ -263,7 +250,7 @@ const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
[`${componentCls}-extra`]: {
// https://stackoverflow.com/a/22429853/3040605
marginInlineStart: 'auto',
color: extraColor,
color: '',
fontWeight: 'normal',
fontSize: token.fontSize,
},
@ -345,14 +332,14 @@ const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
// ============================== Size ==============================
const genCardSizeStyle: GenerateStyle<CardToken> = (token): CSSObject => {
const { componentCls, cardPaddingSM, headerHeightSM, headerFontSizeSM } = token;
const { componentCls, cardPaddingSM, cardHeadHeightSM } = token;
return {
[`${componentCls}-small`]: {
[`> ${componentCls}-head`]: {
minHeight: headerHeightSM,
minHeight: cardHeadHeightSM,
padding: `0 ${cardPaddingSM}px`,
fontSize: headerFontSizeSM,
fontSize: token.fontSize,
[`> ${componentCls}-head-wrapper`]: {
[`> ${componentCls}-extra`]: {
@ -368,7 +355,7 @@ const genCardSizeStyle: GenerateStyle<CardToken> = (token): CSSObject => {
[`${componentCls}-small${componentCls}-contain-tabs`]: {
[`> ${componentCls}-head`]: {
[`${componentCls}-head-title, ${componentCls}-extra`]: {
minHeight: headerHeightSM,
minHeight: cardHeadHeightSM,
paddingTop: 0,
display: 'flex',
alignItems: 'center',
@ -379,34 +366,24 @@ const genCardSizeStyle: GenerateStyle<CardToken> = (token): CSSObject => {
};
// ============================== Export ==============================
export default genComponentStyleHook(
'Card',
(token) => {
const cardToken = mergeToken<CardToken>(token, {
cardShadow: token.boxShadowCard,
cardHeadPadding: token.padding,
cardPaddingBase: token.paddingLG,
cardActionsIconSize: token.fontSize,
cardPaddingSM: 12, // Fixed padding.
});
export default genComponentStyleHook('Card', (token) => {
const cardToken = mergeToken<CardToken>(token, {
cardShadow: token.boxShadowCard,
cardHeadHeight: token.fontSizeLG * token.lineHeightLG + token.padding * 2,
cardHeadHeightSM: token.fontSize * token.lineHeight + token.paddingXS * 2,
cardHeadPadding: token.padding,
cardPaddingBase: token.paddingLG,
cardHeadTabsMarginBottom: -token.padding - token.lineWidth,
cardActionsLiMargin: `${token.paddingSM}px 0`,
cardActionsIconSize: token.fontSize,
cardPaddingSM: 12, // Fixed padding.
});
return [
// Style
genCardStyle(cardToken),
return [
// Style
genCardStyle(cardToken),
// Size
genCardSizeStyle(cardToken),
];
},
(token) => ({
headerBg: 'transparent',
headerFontSize: token.fontSizeLG,
headerFontSizeSM: token.fontSize,
headerHeight: token.fontSizeLG * token.lineHeightLG + token.padding * 2,
headerHeightSM: token.fontSize * token.lineHeight + token.paddingXS * 2,
actionsBg: token.colorBgContainer,
actionsLiMargin: `${token.paddingSM}px 0`,
tabsMarginBottom: -token.padding - token.lineWidth,
extraColor: token.colorText,
}),
);
// Size
genCardSizeStyle(cardToken),
];
});

View File

@ -468,240 +468,6 @@ exports[`renders components/carousel/demo/basic.tsx extend context correctly 1`]
</div>
`;
exports[`renders components/carousel/demo/component-token.tsx extend context correctly 1`] = `
<div
class="ant-carousel"
>
<div
class="slick-slider slick-initialized"
dir="ltr"
>
<div
class="slick-list"
>
<div
class="slick-track"
style="opacity: 1; transform: translate3d(0px, 0px, 0px);"
>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="-1"
style="width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
4
</h3>
</div>
</div>
</div>
<div
aria-hidden="false"
class="slick-slide slick-active slick-current"
data-index="0"
style="outline: none; width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
1
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide"
data-index="1"
style="outline: none; width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
2
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide"
data-index="2"
style="outline: none; width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
3
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide"
data-index="3"
style="outline: none; width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
4
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="4"
style="width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
1
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="5"
style="width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
2
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="6"
style="width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
3
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="7"
style="width: 0px;"
tabindex="-1"
>
<div>
<div
style="width: 100%; display: inline-block;"
tabindex="-1"
>
<h3
style="margin: 0px; height: 160px; color: rgb(255, 255, 255); line-height: 160px; text-align: center; background: rgb(54, 77, 121);"
>
4
</h3>
</div>
</div>
</div>
</div>
</div>
<ul
class="slick-dots slick-dots-bottom"
style="display: block;"
>
<li
class="slick-active"
>
<button>
1
</button>
</li>
<li
class=""
>
<button>
2
</button>
</li>
<li
class=""
>
<button>
3
</button>
</li>
<li
class=""
>
<button>
4
</button>
</li>
</ul>
</div>
</div>
`;
exports[`renders components/carousel/demo/fade.tsx extend context correctly 1`] = `
<div
class="ant-carousel"

View File

@ -468,240 +468,6 @@ exports[`renders components/carousel/demo/basic.tsx correctly 1`] = `
</div>
`;
exports[`renders components/carousel/demo/component-token.tsx correctly 1`] = `
<div
class="ant-carousel"
>
<div
class="slick-slider slick-initialized"
dir="ltr"
>
<div
class="slick-list"
>
<div
class="slick-track"
style="width:900%;left:-100%"
>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="-1"
style="width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
4
</h3>
</div>
</div>
</div>
<div
aria-hidden="false"
class="slick-slide slick-active slick-current"
data-index="0"
style="outline:none;width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
1
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide"
data-index="1"
style="outline:none;width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
2
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide"
data-index="2"
style="outline:none;width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
3
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide"
data-index="3"
style="outline:none;width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
4
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="4"
style="width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
1
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="5"
style="width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
2
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="6"
style="width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
3
</h3>
</div>
</div>
</div>
<div
aria-hidden="true"
class="slick-slide slick-cloned"
data-index="7"
style="width:11.11111111111111%"
tabindex="-1"
>
<div>
<div
style="width:100%;display:inline-block"
tabindex="-1"
>
<h3
style="margin:0;height:160px;color:#fff;line-height:160px;text-align:center;background:#364d79"
>
4
</h3>
</div>
</div>
</div>
</div>
</div>
<ul
class="slick-dots slick-dots-bottom"
style="display:block"
>
<li
class="slick-active"
>
<button>
1
</button>
</li>
<li
class=""
>
<button>
2
</button>
</li>
<li
class=""
>
<button>
3
</button>
</li>
<li
class=""
>
<button>
4
</button>
</li>
</ul>
</div>
</div>
`;
exports[`renders components/carousel/demo/fade.tsx correctly 1`] = `
<div
class="ant-carousel"

View File

@ -1,7 +0,0 @@
## zh-CN
Component Token Debug.
## en-US
Component Token Debug.

View File

@ -1,41 +0,0 @@
import { Carousel, ConfigProvider } from 'antd';
import React from 'react';
/** Test usage. Do not use in your production. */
const contentStyle: React.CSSProperties = {
margin: 0,
height: '160px',
color: '#fff',
lineHeight: '160px',
textAlign: 'center',
background: '#364d79',
};
export default () => (
<ConfigProvider
theme={{
components: {
Carousel: {
dotWidth: 50,
dotHeight: 50,
dotActiveWidth: 80,
},
},
}}
>
<Carousel>
<div>
<h3 style={contentStyle}>1</h3>
</div>
<div>
<h3 style={contentStyle}>2</h3>
</div>
<div>
<h3 style={contentStyle}>3</h3>
</div>
<div>
<h3 style={contentStyle}>4</h3>
</div>
</Carousel>
</ConfigProvider>
);

View File

@ -23,7 +23,6 @@ A carousel component. Scales with its container.
<code src="./demo/position.tsx">Position</code>
<code src="./demo/autoplay.tsx">Scroll automatically</code>
<code src="./demo/fade.tsx">Fade in</code>
<code src="./demo/component-token.tsx" debug>Component Token</code>
## API

View File

@ -24,7 +24,6 @@ demo:
<code src="./demo/position.tsx">位置</code>
<code src="./demo/autoplay.tsx">自动切换</code>
<code src="./demo/fade.tsx">渐显</code>
<code src="./demo/component-token.tsx" debug>组件 Token</code>
## API

View File

@ -5,9 +5,7 @@ import { genComponentStyleHook, mergeToken } from '../../theme/internal';
export interface ComponentToken {
dotWidth: number;
dotHeight: number;
/** @deprecated Use `dotActiveWidth` instead. */
dotWidthActive: number;
dotActiveWidth: number;
}
interface CarouselToken extends FullToken<'Carousel'> {
@ -235,7 +233,7 @@ const genCarouselStyle: GenerateStyle<CarouselToken> = (token) => {
},
'&.slick-active': {
width: token.dotActiveWidth,
width: token.dotWidthActive,
'& button': {
background: token.colorBgContainer,
@ -344,17 +342,9 @@ export default genComponentStyleHook(
genCarouselRtlStyle(carouselToken),
];
},
() => {
const dotActiveWidth = 24;
return {
dotWidth: 16,
dotHeight: 3,
dotWidthActive: dotActiveWidth,
dotActiveWidth,
};
},
{
deprecatedTokens: [['dotWidthActive', 'dotActiveWidth']],
dotWidth: 16,
dotHeight: 3,
dotWidthActive: 24,
},
);

View File

@ -167,20 +167,13 @@ describe('CheckboxGroup', () => {
it('should work when checkbox is wrapped by other components', () => {
const { container } = render(
<Checkbox.Group>
<Collapse
items={[
{
key: 'test panel',
label: 'test panel',
children: (
<div>
<Checkbox value="1">item</Checkbox>
</div>
),
},
]}
bordered={false}
/>
<Collapse bordered={false}>
<Collapse.Panel key="test panel" header="test panel">
<div>
<Checkbox value="1">item</Checkbox>
</div>
</Collapse.Panel>
</Collapse>
</Checkbox.Group>,
);

View File

@ -1,6 +1,5 @@
import RightOutlined from '@ant-design/icons/RightOutlined';
import classNames from 'classnames';
import type { CollapseProps as RcCollapseProps } from 'rc-collapse';
import RcCollapse from 'rc-collapse';
import type { CSSMotionProps } from 'rc-motion';
import toArray from 'rc-util/lib/Children/toArray';
@ -21,7 +20,6 @@ type ExpandIconPositionLegacy = 'left' | 'right';
export type ExpandIconPosition = 'start' | 'end' | ExpandIconPositionLegacy | undefined;
export interface CollapseProps {
items: RcCollapseProps['items'];
activeKey?: Array<string | number> | string | number;
defaultActiveKey?: Array<string | number> | string | number;
/** 手风琴效果 */
@ -38,9 +36,6 @@ export interface CollapseProps {
ghost?: boolean;
size?: SizeType;
collapsible?: CollapsibleType;
/**
* @deprecated use `items` instead
*/
children?: React.ReactNode;
}
@ -130,7 +125,7 @@ const Collapse = React.forwardRef<HTMLDivElement, CollapseProps>((props, ref) =>
if (child.props?.disabled) {
const key = child.key ?? String(index);
const { disabled, collapsible } = child.props;
const childProps: Omit<CollapseProps, 'items'> & { key: React.Key } = {
const childProps: CollapseProps & { key: React.Key } = {
...omit(child.props, ['disabled']),
key,
collapsible: collapsible ?? (disabled ? 'disabled' : undefined),

View File

@ -21,7 +21,6 @@ export interface CollapsePanelProps {
collapsible?: CollapsibleType;
children?: React.ReactNode;
}
const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((props, ref) => {
warning(
!('disabled' in props),

View File

@ -1420,7 +1420,7 @@ exports[`renders components/collapse/demo/noarrow.tsx extend context correctly 1
</div>
</div>
<div
class="ant-collapse-item"
class="ant-collapse-item ant-collapse-no-arrow"
>
<div
aria-disabled="false"

View File

@ -1339,7 +1339,7 @@ exports[`renders components/collapse/demo/noarrow.tsx correctly 1`] = `
</div>
</div>
<div
class="ant-collapse-item"
class="ant-collapse-item ant-collapse-no-arrow"
>
<div
aria-disabled="false"

View File

@ -1,31 +1,26 @@
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';
import React from 'react';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header 1',
children: <p>{text}</p>,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
},
];
const App: React.FC = () => <Collapse accordion items={items} />;
const App: React.FC = () => (
<Collapse accordion>
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>
);
export default App;

View File

@ -1,37 +1,32 @@
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';
import React from 'react';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header 1',
children: <p>{text}</p>,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
},
];
const App: React.FC = () => {
const onChange = (key: string | string[]) => {
console.log(key);
};
return <Collapse items={items} defaultActiveKey={['1']} onChange={onChange} />;
return (
<Collapse defaultActiveKey={['1']} onChange={onChange}>
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>
);
};
export default App;

View File

@ -1,7 +1,8 @@
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';
import React from 'react';
const { Panel } = Collapse;
const text = (
<p style={{ paddingLeft: 24 }}>
A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found
@ -9,24 +10,18 @@ const text = (
</p>
);
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header 1',
children: text,
},
{
key: '2',
label: 'This is panel header 2',
children: text,
},
{
key: '3',
label: 'This is panel header 3',
children: text,
},
];
const App: React.FC = () => <Collapse items={items} bordered={false} defaultActiveKey={['1']} />;
const App: React.FC = () => (
<Collapse bordered={false} defaultActiveKey={['1']}>
<Panel header="This is panel header 1" key="1">
{text}
</Panel>
<Panel header="This is panel header 2" key="2">
{text}
</Panel>
<Panel header="This is panel header 3" key="3">
{text}
</Panel>
</Collapse>
);
export default App;

View File

@ -1,6 +1,8 @@
import { Collapse, Space } from 'antd';
import React from 'react';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
@ -9,38 +11,21 @@ const text = `
const App: React.FC = () => (
<Space direction="vertical">
<Collapse
collapsible="header"
defaultActiveKey={['1']}
items={[
{
key: '1',
label: 'This panel can only be collapsed by clicking text',
children: <p>{text}</p>,
},
]}
/>
<Collapse
collapsible="icon"
defaultActiveKey={['1']}
items={[
{
key: '1',
label: 'This panel can only be collapsed by clicking icon',
children: <p>{text}</p>,
},
]}
/>
<Collapse
collapsible="disabled"
items={[
{
key: '1',
label: "This panel can't be collapsed",
children: <p>{text}</p>,
},
]}
/>
<Collapse collapsible="header" defaultActiveKey={['1']}>
<Panel header="This panel can only be collapsed by clicking text" key="1">
<p>{text}</p>
</Panel>
</Collapse>
<Collapse collapsible="icon" defaultActiveKey={['1']}>
<Panel header="This panel can only be collapsed by clicking icon" key="1">
<p>{text}</p>
</Panel>
</Collapse>
<Collapse collapsible="disabled">
<Panel header="This panel can't be collapsed" key="1">
<p>{text}</p>
</Panel>
</Collapse>
</Space>
);

View File

@ -1,36 +1,15 @@
import { CaretRightOutlined } from '@ant-design/icons';
import type { CollapseProps } from 'antd';
import { Collapse, theme } from 'antd';
import type { CSSProperties } from 'react';
import React from 'react';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const getItems: (panelStyle: CSSProperties) => CollapseProps['items'] = (panelStyle) => [
{
key: '1',
label: 'This is panel header 1',
children: <p>{text}</p>,
style: panelStyle,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
style: panelStyle,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
style: panelStyle,
},
];
const App: React.FC = () => {
const { token } = theme.useToken();
@ -47,8 +26,17 @@ const App: React.FC = () => {
defaultActiveKey={['1']}
expandIcon={({ isActive }) => <CaretRightOutlined rotate={isActive ? 90 : 0} />}
style={{ background: token.colorBgContainer }}
items={getItems(panelStyle)}
/>
>
<Panel header="This is panel header 1" key="1" style={panelStyle}>
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2" style={panelStyle}>
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3" style={panelStyle}>
<p>{text}</p>
</Panel>
</Collapse>
);
};

View File

@ -1,8 +1,8 @@
import { SettingOutlined } from '@ant-design/icons';
import type { CollapseProps } from 'antd';
import { Collapse, Select } from 'antd';
import React, { useState } from 'react';
const { Panel } = Collapse;
const { Option } = Select;
const text = `
@ -33,35 +33,23 @@ const App: React.FC = () => {
/>
);
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header 1',
children: <div>{text}</div>,
extra: genExtra(),
},
{
key: '2',
label: 'This is panel header 2',
children: <div>{text}</div>,
extra: genExtra(),
},
{
key: '3',
label: 'This is panel header 3',
children: <div>{text}</div>,
extra: genExtra(),
},
];
return (
<>
<Collapse
defaultActiveKey={['1']}
onChange={onChange}
expandIconPosition={expandIconPosition}
items={items}
/>
>
<Panel header="This is panel header 1" key="1" extra={genExtra()}>
<div>{text}</div>
</Panel>
<Panel header="This is panel header 2" key="2" extra={genExtra()}>
<div>{text}</div>
</Panel>
<Panel header="This is panel header 3" key="3" extra={genExtra()}>
<div>{text}</div>
</Panel>
</Collapse>
<br />
<span>Expand Icon Position: </span>
<Select value={expandIconPosition} style={{ margin: '0 8px' }} onChange={onPositionChange}>

View File

@ -1,31 +1,26 @@
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';
import React from 'react';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header 1',
children: <p>{text}</p>,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
},
];
const App: React.FC = () => <Collapse defaultActiveKey={['1']} ghost items={items} />;
const App: React.FC = () => (
<Collapse defaultActiveKey={['1']} ghost>
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>
);
export default App;

View File

@ -1,45 +1,36 @@
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';
import React from 'react';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const itemsNest: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel nest panel',
children: <p>{text}</p>,
},
];
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header 1',
children: <Collapse defaultActiveKey="1" items={itemsNest} />,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
},
];
const App: React.FC = () => {
const onChange = (key: string | string[]) => {
console.log(key);
};
return <Collapse onChange={onChange} items={items} />;
return (
<Collapse onChange={onChange}>
<Panel header="This is panel header 1" key="1">
<Collapse defaultActiveKey="1">
<Panel header="This is panel nest panel" key="1">
<p>{text}</p>
</Panel>
</Collapse>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>
);
};
export default App;

View File

@ -1,33 +1,29 @@
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';
import React from 'react';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header with arrow icon',
children: <p>{text}</p>,
},
{
key: '2',
label: 'This is panel header with no arrow icon',
children: <p>{text}</p>,
showArrow: false,
},
];
const App: React.FC = () => {
const onChange = (key: string | string[]) => {
console.log(key);
};
return <Collapse defaultActiveKey={['1']} onChange={onChange} items={items} />;
return (
<Collapse defaultActiveKey={['1']} onChange={onChange}>
<Panel header="This is panel header with arrow icon" key="1">
<p>{text}</p>
</Panel>
<Panel showArrow={false} header="This is panel header with no arrow icon" key="2">
<p>{text}</p>
</Panel>
</Collapse>
);
};
export default App;

View File

@ -1,6 +1,8 @@
import { Collapse, Divider } from 'antd';
import React from 'react';
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
@ -10,19 +12,23 @@ const text = `
const App: React.FC = () => (
<>
<Divider orientation="left">Default Size</Divider>
<Collapse
items={[{ key: '1', label: 'This is default size panel header', children: <p>{text}</p> }]}
/>
<Collapse>
<Panel header="This is default size panel header" key="1">
<p>{text}</p>
</Panel>
</Collapse>
<Divider orientation="left">Small Size</Divider>
<Collapse
size="small"
items={[{ key: '1', label: 'This is small size panel header', children: <p>{text}</p> }]}
/>
<Collapse size="small">
<Panel header="This is small size panel header" key="1">
<p>{text}</p>
</Panel>
</Collapse>
<Divider orientation="left">Large Size</Divider>
<Collapse
size="large"
items={[{ key: '1', label: 'This is large size panel header', children: <p>{text}</p> }]}
/>
<Collapse size="large">
<Panel header="This is large size panel header" key="1">
<p>{text}</p>
</Panel>
</Collapse>
</>
);

View File

@ -13,49 +13,6 @@ A content area which can be collapsed and expanded.
- Can be used to group or hide complex regions to keep the page clean.
- `Accordion` is a special kind of `Collapse`, which allows only one panel to be expanded at a time.
```tsx | pure
// works when >= 5.6.0, recommended ✅
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header 1',
children: <p>{text}</p>,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
},
];
<Collapse items={items} defaultActiveKey={['1']} />;
// works when <5.6.0 , deprecated when >=5.6.0 🙅🏻‍♀️
<Collapse defaultActiveKey={['1']} onChange={onChange}>
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>;
```
## Examples
<!-- prettier-ignore -->
@ -87,12 +44,9 @@ const items: CollapseProps['items'] = [
| ghost | Make the collapse borderless and its background transparent | boolean | false | 4.4.0 |
| size | Set the size of collapse | `large` \| `middle` \| `small` | `middle` | 5.2.0 |
| onChange | Callback function executed when active panel is changed | function | - | |
| items | collapse items content | [ItemType](https://github.com/react-component/collapse/blob/27250ca5415faab16db412b9bff2c131bb4f32fc/src/interface.ts#L6) | - | 5.6.0 |
### Collapse.Panel
<Alert message="&gt;= 5.6.0 configure the panel by `items`."></Alert>
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| collapsible | Specify whether the panel be collapsible or the trigger area of collapsible | `header` \| `icon` \| `disabled` | - | 4.9.0 (icon: 4.24.0) |

View File

@ -14,49 +14,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sir-TK0HkWcAAA
- 对复杂区域进行分组和隐藏,保持页面的整洁。
- `手风琴` 是一种特殊的折叠面板,只允许单个内容区域展开。
```tsx | pure
// >= 5.6.0 可用,推荐的写法 ✅
const text = `
A dog is a type of domesticated animal.
Known for its loyalty and faithfulness,
it can be found as a welcome guest in many households across the world.
`;
const items: CollapseProps['items'] = [
{
key: '1',
label: 'This is panel header 1',
children: <p>{text}</p>,
},
{
key: '2',
label: 'This is panel header 2',
children: <p>{text}</p>,
},
{
key: '3',
label: 'This is panel header 3',
children: <p>{text}</p>,
},
];
<Collapse items={items} defaultActiveKey={['1']} />;
// <5.6.0 可用>=5.6.0 时不推荐 🙅🏻‍♀️
<Collapse defaultActiveKey={['1']} onChange={onChange}>
<Panel header="This is panel header 1" key="1">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 2" key="2">
<p>{text}</p>
</Panel>
<Panel header="This is panel header 3" key="3">
<p>{text}</p>
</Panel>
</Collapse>;
```
## 代码演示
<!-- prettier-ignore -->
@ -88,12 +45,9 @@ const items: CollapseProps['items'] = [
| ghost | 使折叠面板透明且无边框 | boolean | false | 4.4.0 |
| size | 设置折叠面板大小 | `large` \| `middle` \| `small` | `middle` | 5.2.0 |
| onChange | 切换面板的回调 | function | - | |
| items | 折叠项目内容 | [ItemType](https://github.com/react-component/collapse/blob/27250ca5415faab16db412b9bff2c131bb4f32fc/src/interface.ts#L6) | - | 5.6.0 |
### Collapse.Panel
<Alert message="&gt;= 5.6.0 请使用 items 方式配置面板."></Alert>
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| collapsible | 是否可折叠或指定可折叠触发区域 | `header` \| `icon` \| `disabled` | - | 4.9.0 (icon: 4.24.0) |

View File

@ -39,7 +39,6 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
marginSM,
paddingSM,
paddingLG,
paddingXS,
motionDurationSlow,
fontSizeIcon,
} = token;
@ -74,7 +73,6 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
flexWrap: 'nowrap',
alignItems: 'flex-start',
padding: collapseHeaderPadding,
paddingInlineStart: paddingSM,
color: colorTextHeading,
lineHeight,
cursor: 'pointer',
@ -94,8 +92,6 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
display: 'flex',
alignItems: 'center',
paddingInlineEnd: marginSM,
// Arrow offset
marginInlineStart: padding - paddingSM,
},
[`${componentCls}-arrow`]: {
@ -129,6 +125,12 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
cursor: 'pointer',
},
},
[`&${componentCls}-no-arrow`]: {
[`> ${componentCls}-header`]: {
paddingInlineStart: paddingSM,
},
},
},
[`${componentCls}-content`]: {
@ -149,12 +151,6 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
[`> ${componentCls}-item`]: {
[`> ${componentCls}-header`]: {
padding: collapseHeaderPaddingSM,
paddingInlineStart: paddingXS,
[`> ${componentCls}-expand-icon`]: {
// Arrow offset
marginInlineStart: paddingSM - paddingXS,
},
},
[`> ${componentCls}-content > ${componentCls}-content-box`]: {
padding: paddingSM,
@ -168,12 +164,9 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
[`> ${componentCls}-header`]: {
padding: collapseHeaderPaddingLG,
paddingInlineStart: padding,
[`> ${componentCls}-expand-icon`]: {
height: fontSizeLG * lineHeight,
// Arrow offset
marginInlineStart: paddingLG - padding,
},
},
[`> ${componentCls}-content > ${componentCls}-content-box`]: {

View File

@ -5,7 +5,7 @@ import type {
import classNames from 'classnames';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import type { CSSProperties } from 'react';
import React, { useContext, useRef, useState } from 'react';
import React, { useContext, useEffect, useRef, useState } from 'react';
import genPurePanel from '../_util/PurePanel';
import type { ConfigConsumerProps } from '../config-provider/context';
import { ConfigContext } from '../config-provider/context';
@ -44,7 +44,6 @@ export interface ColorPickerProps
onOpenChange?: (open: boolean) => void;
onFormatChange?: (format: ColorFormat) => void;
onChange?: (value: Color, hex: string) => void;
onClear?: () => void;
getPopupContainer?: PopoverProps['getPopupContainer'];
autoAdjustOverflow?: PopoverProps['autoAdjustOverflow'];
}
@ -72,7 +71,6 @@ const ColorPicker: CompoundedComponent = (props) => {
styles,
onFormatChange,
onChange,
onClear,
onOpenChange,
getPopupContainer,
autoAdjustOverflow = true,
@ -123,9 +121,8 @@ const ColorPicker: CompoundedComponent = (props) => {
onChange?.(color, color.toHexString());
};
const handleClear = () => {
setColorCleared(true);
onClear?.();
const handleClear = (clear: boolean) => {
setColorCleared(clear);
};
const handleChangeComplete = () => {
@ -153,6 +150,12 @@ const ColorPicker: CompoundedComponent = (props) => {
onFormatChange,
};
useEffect(() => {
if (colorCleared) {
setPopupOpen(false);
}
}, [colorCleared]);
return wrapSSR(
<Popover
style={styles?.popup}

View File

@ -12,7 +12,7 @@ import type { ColorPickerBaseProps } from './interface';
interface ColorPickerPanelProps extends ColorPickerBaseProps {
onChange?: (value?: Color, type?: HsbaColorType, pickColor?: boolean) => void;
onChangeComplete?: (type?: HsbaColorType) => void;
onClear?: () => void;
onClear?: (clear?: boolean) => void;
}
const ColorPickerPanel: FC<ColorPickerPanelProps> = (props) => {
@ -36,7 +36,7 @@ const ColorPickerPanel: FC<ColorPickerPanelProps> = (props) => {
value={color}
onChange={(clearColor) => {
onChange?.(clearColor);
onClear?.();
onClear?.(true);
}}
{...injectProps}
/>

View File

@ -102,16 +102,16 @@ describe('ColorPicker', () => {
expect(container.querySelector('.ant-color-picker')).toBeFalsy();
});
it('Should allowClear and onClear work', async () => {
const onClear = jest.fn();
const { container } = render(<ColorPicker allowClear onClear={onClear} />);
it('Should allowClear work', async () => {
const { container } = render(<ColorPicker allowClear />);
fireEvent.click(container.querySelector('.ant-color-picker-trigger')!);
await waitFakeTimer();
expect(container.querySelector('.ant-popover-hidden')).toBeFalsy();
expect(container.querySelector('.ant-color-picker-clear')).toBeTruthy();
fireEvent.click(container.querySelector('.ant-color-picker-clear')!);
expect(onClear).toHaveBeenCalledTimes(1);
await waitFakeTimer();
expect(container.querySelector('.ant-popover-hidden')).toBeTruthy();
expect(
container.querySelector('.ant-color-picker-alpha-input input')?.getAttribute('value'),
).toEqual('0%');
@ -119,6 +119,12 @@ describe('ColorPicker', () => {
container.querySelector('.ant-color-picker-trigger .ant-color-picker-clear'),
).toBeTruthy();
fireEvent.click(container.querySelector('.ant-color-picker-trigger')!);
await waitFakeTimer();
expect(
container.querySelector('.ant-color-picker-alpha-input input')?.getAttribute('value'),
).toEqual('0%');
fireEvent.change(container.querySelector('.ant-color-picker-hex-input input')!, {
target: { value: '#273B57' },
});

View File

@ -3,13 +3,14 @@ import classNames from 'classnames';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import type { FC } from 'react';
import React, { useMemo } from 'react';
import type { CollapseProps } from '../../collapse';
import Collapse from '../../collapse';
import { useLocale } from '../../locale';
import type { Color } from '../color';
import type { ColorPickerBaseProps, PresetsItem } from '../interface';
import { generateColor } from '../util';
const { Panel } = Collapse;
interface ColorPresetsProps extends Pick<ColorPickerBaseProps, 'prefixCls'> {
presets: PresetsItem[];
value?: Color;
@ -47,39 +48,36 @@ const ColorPresets: FC<ColorPresetsProps> = ({ prefixCls, presets, value: color,
onChange?.(colorValue);
};
const items: CollapseProps['items'] = useMemo(
() =>
presetsValue.map((preset) => ({
key: `panel-${preset.label}`,
label: <div className={`${colorPresetsPrefixCls}-label`}>{preset?.label}</div>,
children: (
<div className={`${colorPresetsPrefixCls}-items`}>
{Array.isArray(preset?.colors) && preset.colors?.length > 0 ? (
preset.colors.map((presetColor: Color) => (
<ColorBlock
key={`preset-${presetColor.toHexString()}`}
color={generateColor(presetColor).toRgbString()}
prefixCls={prefixCls}
className={classNames(`${colorPresetsPrefixCls}-color`, {
[`${colorPresetsPrefixCls}-color-checked`]:
presetColor.toHexString() === color?.toHexString(),
[`${colorPresetsPrefixCls}-color-bright`]: isBright(presetColor),
})}
onClick={() => handleClick(presetColor)}
/>
))
) : (
<span className={`${colorPresetsPrefixCls}-empty`}>{locale.presetEmpty}</span>
)}
</div>
),
})),
[],
);
return (
<div className={colorPresetsPrefixCls}>
<Collapse defaultActiveKey={activeKeys} ghost items={items} />
<Collapse defaultActiveKey={activeKeys} ghost>
{presetsValue.map((preset) => (
<Panel
header={<div className={`${colorPresetsPrefixCls}-label`}>{preset?.label}</div>}
key={`panel-${preset?.label}`}
>
<div className={`${colorPresetsPrefixCls}-items`}>
{Array.isArray(preset?.colors) && preset.colors?.length > 0 ? (
preset.colors.map((presetColor: Color) => (
<ColorBlock
key={`preset-${presetColor.toHexString()}`}
color={generateColor(presetColor).toRgbString()}
prefixCls={prefixCls}
className={classNames(`${colorPresetsPrefixCls}-color`, {
[`${colorPresetsPrefixCls}-color-checked`]:
presetColor.toHexString() === color?.toHexString(),
[`${colorPresetsPrefixCls}-color-bright`]: isBright(presetColor),
})}
onClick={() => handleClick(presetColor)}
/>
))
) : (
<span className={`${colorPresetsPrefixCls}-empty`}>{locale.presetEmpty}</span>
)}
</div>
</Panel>
))}
</Collapse>
</div>
);
};

View File

@ -37,20 +37,19 @@ Used when the user needs to customize the color selection.
| Property | Description | Type | Default |
| :-- | :-- | :-- | :-- |
| format | Format of color | `rgb` \| `hex` \| `hsb` | `hex` |
| onFormatChange | Callback when `format` is changed | `(format: 'hex' \| 'rgb' \| 'hsb') => void` | - |
| value | Value of color | string \| `Color` | - |
| defaultValue | Default value of color | string \| `Color` | - |
| onChange | Callback when `value` is changed | `(value: Color, hex: string) => void` | - |
| allowClear | Allow clearing color selected | boolean | false |
| presets | Preset colors | `{ label: ReactNode, colors: Array<string \| Color> }[]` | - |
| children | Trigger of ColorPicker | React.ReactNode | - |
| trigger | ColorPicker trigger mode | `hover` \| `click` | `click` |
| open | Whether to show popup | boolean | - |
| onOpenChange | Callback when `open` is changed | `(open: boolean) => void` | - |
| disabled | Disable ColorPicker | boolean | - |
| placement | Placement of popup | `top` \| `topLeft` \| `topRight` \| `bottom` \| `bottomLeft` \| `bottomRight` | `bottomLeft` |
| arrow | Configuration for popup arrow | `boolean \| { pointAtCenter: boolean }` | `true` | - |
| onChange | Callback when `value` is changed | `(value: Color, hex: string) => void` | - |
| onFormatChange | Callback when `format` is changed | `(format: 'hex' \| 'rgb' \| 'hsb') => void` | - |
| onOpenChange | Callback when `open` is changed | `(open: boolean) => void` | - |
| onClear | Called when clear | `() => void` | - |
### Color

View File

@ -38,20 +38,19 @@ group:
| 参数 | 说明 | 类型 | 默认值 |
| :-- | :-- | :-- | :-- |
| format | 颜色格式 | `rgb` \| `hex` \| `hsb` | `hex` |
| onFormatChange | 颜色格式变化的回调 | `(format: 'hex' \| 'rgb' \| 'hsb') => void` | - |
| value | 颜色的值 | string \| `Color` | - |
| defaultValue | 颜色默认的值 | string \| `Color` | - |
| onChange | 颜色变化的回调 | `(value: Color, hex: string) => void` | - |
| allowClear | 允许清除选择的颜色 | boolean | false |
| presets | 预设的颜色 | `{ label: ReactNode, colors: Array<string \| Color> }[]` | - |
| children | 颜色选择器的触发器 | React.ReactNode | - |
| trigger | 颜色选择器的触发模式 | `hover` \| `click` | `click` |
| open | 是否显示弹出窗口 | boolean | - |
| onOpenChange | 当 `open` 被改变时的回调 | `(open: boolean) => void` | - |
| disabled | 禁用颜色选择器 | boolean | - |
| placement | 弹出窗口的位置 | `top` \| `topLeft` \| `topRight` \| `bottom` \| `bottomLeft` \| `bottomRight` | `bottomLeft` |
| arrow | 配置弹出的箭头 | `boolean \| { pointAtCenter: boolean }` | `true` | - |
| onChange | 颜色变化的回调 | `(value: Color, hex: string) => void` | - |
| onFormatChange | 颜色格式变化的回调 | `(format: 'hex' \| 'rgb' \| 'hsb') => void` | - |
| onOpenChange | 当 `open` 被改变时的回调 | `(open: boolean) => void` | - |
| onClear | 清除的回调 | `() => void` | - |
### Color

View File

@ -18988,7 +18988,7 @@ exports[`ConfigProvider components Pagination configProvider 1`] = `
>
<div
aria-label="Page Size"
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow"
>
<div
class="config-select-selector"
@ -19007,8 +19007,11 @@ exports[`ConfigProvider components Pagination configProvider 1`] = `
autocomplete="off"
class="config-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -19131,7 +19134,7 @@ exports[`ConfigProvider components Pagination configProvider 1`] = `
>
<div
aria-label="Page Size"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow"
>
<div
class="config-select-selector"
@ -19150,8 +19153,11 @@ exports[`ConfigProvider components Pagination configProvider 1`] = `
autocomplete="off"
class="config-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -19279,7 +19285,7 @@ exports[`ConfigProvider components Pagination configProvider componentDisabled 1
>
<div
aria-label="Page Size"
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-disabled config-select-show-search"
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-disabled"
>
<div
class="config-select-selector"
@ -19299,8 +19305,11 @@ exports[`ConfigProvider components Pagination configProvider componentDisabled 1
class="config-select-selection-search-input"
disabled=""
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -19423,7 +19432,7 @@ exports[`ConfigProvider components Pagination configProvider componentDisabled 1
>
<div
aria-label="Page Size"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-disabled config-select-show-search"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-disabled"
>
<div
class="config-select-selector"
@ -19443,8 +19452,11 @@ exports[`ConfigProvider components Pagination configProvider componentDisabled 1
class="config-select-selection-search-input"
disabled=""
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -19572,7 +19584,7 @@ exports[`ConfigProvider components Pagination configProvider componentSize large
>
<div
aria-label="Page Size"
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow"
>
<div
class="config-select-selector"
@ -19591,8 +19603,11 @@ exports[`ConfigProvider components Pagination configProvider componentSize large
autocomplete="off"
class="config-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -19715,7 +19730,7 @@ exports[`ConfigProvider components Pagination configProvider componentSize large
>
<div
aria-label="Page Size"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow"
>
<div
class="config-select-selector"
@ -19734,8 +19749,11 @@ exports[`ConfigProvider components Pagination configProvider componentSize large
autocomplete="off"
class="config-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -19863,7 +19881,7 @@ exports[`ConfigProvider components Pagination configProvider componentSize middl
>
<div
aria-label="Page Size"
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow"
>
<div
class="config-select-selector"
@ -19882,8 +19900,11 @@ exports[`ConfigProvider components Pagination configProvider componentSize middl
autocomplete="off"
class="config-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -20006,7 +20027,7 @@ exports[`ConfigProvider components Pagination configProvider componentSize middl
>
<div
aria-label="Page Size"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow"
>
<div
class="config-select-selector"
@ -20025,8 +20046,11 @@ exports[`ConfigProvider components Pagination configProvider componentSize middl
autocomplete="off"
class="config-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -20154,7 +20178,7 @@ exports[`ConfigProvider components Pagination configProvider componentSize small
>
<div
aria-label="Page Size"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow"
>
<div
class="config-select-selector"
@ -20173,8 +20197,11 @@ exports[`ConfigProvider components Pagination configProvider componentSize small
autocomplete="off"
class="config-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -20297,7 +20324,7 @@ exports[`ConfigProvider components Pagination configProvider componentSize small
>
<div
aria-label="Page Size"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow"
>
<div
class="config-select-selector"
@ -20316,8 +20343,11 @@ exports[`ConfigProvider components Pagination configProvider componentSize small
autocomplete="off"
class="config-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -20445,7 +20475,7 @@ exports[`ConfigProvider components Pagination normal 1`] = `
>
<div
aria-label="Page Size"
class="ant-select ant-pagination-options-size-changer ant-select-single ant-select-show-arrow ant-select-show-search"
class="ant-select ant-pagination-options-size-changer ant-select-single ant-select-show-arrow"
>
<div
class="ant-select-selector"
@ -20464,8 +20494,11 @@ exports[`ConfigProvider components Pagination normal 1`] = `
autocomplete="off"
class="ant-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -20588,7 +20621,7 @@ exports[`ConfigProvider components Pagination normal 1`] = `
>
<div
aria-label="Page Size"
class="ant-select ant-select-sm ant-pagination-options-size-changer ant-select-single ant-select-show-arrow ant-select-show-search"
class="ant-select ant-select-sm ant-pagination-options-size-changer ant-select-single ant-select-show-arrow"
>
<div
class="ant-select-selector"
@ -20607,8 +20640,11 @@ exports[`ConfigProvider components Pagination normal 1`] = `
autocomplete="off"
class="ant-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -20736,7 +20772,7 @@ exports[`ConfigProvider components Pagination prefixCls 1`] = `
>
<div
aria-label="Page Size"
class="ant-select prefix-Pagination-options-size-changer ant-select-single ant-select-show-arrow ant-select-show-search"
class="ant-select prefix-Pagination-options-size-changer ant-select-single ant-select-show-arrow"
>
<div
class="ant-select-selector"
@ -20755,8 +20791,11 @@ exports[`ConfigProvider components Pagination prefixCls 1`] = `
autocomplete="off"
class="ant-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>
@ -20879,7 +20918,7 @@ exports[`ConfigProvider components Pagination prefixCls 1`] = `
>
<div
aria-label="Page Size"
class="ant-select ant-select-sm prefix-Pagination-options-size-changer ant-select-single ant-select-show-arrow ant-select-show-search"
class="ant-select ant-select-sm prefix-Pagination-options-size-changer ant-select-single ant-select-show-arrow"
>
<div
class="ant-select-selector"
@ -20898,8 +20937,11 @@ exports[`ConfigProvider components Pagination prefixCls 1`] = `
autocomplete="off"
class="ant-select-selection-search-input"
id="rc_select_TEST_OR_SSR"
readonly=""
role="combobox"
style="opacity: 0;"
type="search"
unselectable="on"
value=""
/>
</span>

View File

@ -1,53 +0,0 @@
import { SearchOutlined } from '@ant-design/icons';
import Button from 'antd/es/button';
import React from 'react';
import ConfigProvider from '..';
import { render } from '../../../tests/utils';
describe('ConfigProvider.button', () => {
beforeEach(() => {
(global as any).triggerProps = null;
});
it('ConfigProvider button style', () => {
const { container } = render(
<ConfigProvider>
<Button style={{ fontSize: '14px' }} />
</ConfigProvider>,
);
const item = container.querySelector('button') as HTMLElement;
expect(getComputedStyle(item)?.fontSize).toBe('14px');
});
it('ConfigProvider button className', () => {
const { container } = render(
<ConfigProvider>
<Button className="custom-class" />
</ConfigProvider>,
);
expect(container.querySelector('button')?.className.includes('custom-class')).toBe(true);
});
it('ConfigProvider button styles', () => {
const { container } = render(
<ConfigProvider button={{ styles: { icon: { color: '#333' } } }}>
<Button icon={<SearchOutlined />} />
</ConfigProvider>,
);
const item = container.querySelector('.ant-btn-icon') as HTMLElement;
expect(getComputedStyle(item)?.fontSize).toBe('14px');
});
it('ConfigProvider button classNames', () => {
const { container } = render(
<ConfigProvider button={{ classNames: { icon: 'icon-custom-class' } }}>
<Button icon={<SearchOutlined />} />
</ConfigProvider>,
);
expect(container.querySelector('.ant-btn-icon')?.className.includes('custom-class')).toBe(true);
});
});

View File

@ -7,7 +7,6 @@ import { fireEvent, render } from '../../../tests/utils';
import Button from '../../button';
import Input from '../../input';
import Select from '../../select';
import Space from '../../space';
import Table from '../../table';
describe('ConfigProvider', () => {
@ -124,78 +123,4 @@ describe('ConfigProvider', () => {
expect(rendered).toBeTruthy();
expect(cacheRenderEmpty).toBeFalsy();
});
it('Should Space classNames works', () => {
const { container } = render(
<ConfigProvider
space={{
classNames: {
item: 'test-classNames',
},
}}
>
<Space>
<span>Text1</span>
<span>Text2</span>
</Space>
</ConfigProvider>,
);
expect(container.querySelector('.ant-space-item.test-classNames')).toBeTruthy();
});
it('Should Space className works', () => {
const { container } = render(
<ConfigProvider
space={{
className: 'test-classNames',
}}
>
<Space>
<span>Text1</span>
<span>Text2</span>
</Space>
</ConfigProvider>,
);
expect(container.querySelector('.ant-space.test-classNames')).toBeTruthy();
});
it('Should Space styles works', () => {
const { container } = render(
<ConfigProvider
space={{
styles: {
item: {
color: 'red',
},
},
}}
>
<Space>
<span>Text1</span>
<span>Text2</span>
</Space>
</ConfigProvider>,
);
expect(container.querySelector('.ant-space-item')?.getAttribute('style')).toEqual(
'margin-right: 8px; color: red;',
);
});
it('Should Space style works', () => {
const { container } = render(
<ConfigProvider
space={{
style: {
color: 'red',
},
}}
>
<Space>
<span>Text1</span>
<span>Text2</span>
</Space>
</ConfigProvider>,
);
expect(container.querySelector('.ant-space')?.getAttribute('style')).toEqual('color: red;');
});
});

View File

@ -9,27 +9,4 @@ describe('ConfigProvider.config', () => {
});
expect(globalConfig().getRootPrefixCls()).toEqual('light');
});
it('theme', () => {
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
expect(globalConfig().getTheme()).toBeFalsy();
ConfigProvider.config({
theme: {
infoColor: 'red',
},
});
expect(errSpy).toHaveBeenCalledWith(
'Warning: [antd: ConfigProvider] `config` of css variable theme is not work in v5. Please use new `theme` config instead.',
);
ConfigProvider.config({
theme: {
token: {},
},
});
expect(globalConfig().getTheme()).toEqual({ token: {} });
});
});

View File

@ -49,9 +49,7 @@ describe('ConfigProvider.Theme', () => {
expect(canUseDom()).toBeFalsy();
ConfigProvider.config({
theme: {
infoColor: 'red',
},
theme: {},
});
expect(errorSpy).toHaveBeenCalledWith(

View File

@ -1,10 +1,8 @@
import type { DerivativeFunc } from '@ant-design/cssinjs';
import * as React from 'react';
import type { Options } from 'scroll-into-view-if-needed';
import type { ButtonProps } from '../button';
import type { RequiredMark } from '../form/Form';
import type { Locale } from '../locale';
import type { SpaceProps } from '../space';
import type { AliasToken, MapToken, OverrideToken, SeedToken } from '../theme/interface';
import type { SizeType } from './SizeContext';
import type { RenderEmptyHandler } from './defaultRenderEmpty';
@ -36,15 +34,6 @@ export interface ThemeConfig {
inherit?: boolean;
}
interface componentStyleConfig {
className?: string;
style?: React.CSSProperties;
classNames?: ButtonProps['classNames'];
styles?: ButtonProps['styles'];
}
export interface ButtonConfig extends componentStyleConfig {}
export type PopupOverflow = 'viewport' | 'scroll';
export interface ConfigConsumerProps {
@ -69,10 +58,6 @@ export interface ConfigConsumerProps {
direction?: DirectionType;
space?: {
size?: SizeType | number;
className?: SpaceProps['className'];
classNames?: SpaceProps['classNames'];
style?: SpaceProps['style'];
styles?: SpaceProps['styles'];
};
virtual?: boolean;
popupMatchSelectWidth?: boolean;
@ -86,7 +71,6 @@ export interface ConfigConsumerProps {
select?: {
showSearch?: boolean;
};
button?: ButtonConfig;
}
const defaultGetPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {

View File

@ -63,26 +63,21 @@ Some components use dynamic style to support wave effect. You can config `csp` p
| iconPrefixCls | Set icon prefix className | string | `anticon` | 4.11.0 |
| input | Set Input common props | { autoComplete?: string } | - | 4.2.0 |
| select | Set Select common props | { showSearch?: boolean } | - | |
| button | Set Select common props | { className?: string, style?: React.CSSProperties, classNames?: { icon: string }, styles?: { icon: React.CSSProperties } } | - | 5.6.0 |
| locale | Language package setting, you can find the packages in [antd/locale](http://unpkg.com/antd/locale/) | object | - | |
| prefixCls | Set prefix className | string | `ant` | |
| renderEmpty | Set empty content of components. Ref [Empty](/components/empty/) | function(componentName: string): ReactNode | - | |
| space | Set Space common props, ref [Space](/components/space) | { size: `small` \| `middle` \| `large` \| `number`, className?: string, style?: React.CSSProperties, classNames?: { item: string }, styles?: { item: React.CSSProperties } } | - | 5.6.0 |
| space | Set Space `size`, ref [Space](/components/space) | { size: `small` \| `middle` \| `large` \| `number` } | - | 4.1.0 |
| theme | Set theme, ref [Customize Theme](/docs/react/customize-theme) | - | - | 5.0.0 |
| virtual | Disable virtual scroll when set to `false` | boolean | - | 4.3.0 |
### ConfigProvider.config()
### ConfigProvider.config() `4.13.0+`
Setting `Modal`、`Message`、`Notification` static config. Not work on hooks.
Setting `Modal`、`Message`、`Notification` rootPrefixCls.
```ts
ConfigProvider.config({
prefixCls: 'ant',
iconPrefixCls: 'anticon',
// 5.6.0+
// Please use hooks version first
theme: { token: { colorPrimary: 'red' } },
prefixCls: 'ant', // 4.13.0+
iconPrefixCls: 'anticon', // 4.17.0+
});
```

View File

@ -14,11 +14,9 @@ import LocaleProvider, { ANT_MARK } from '../locale';
import type { LocaleContextProps } from '../locale/context';
import LocaleContext from '../locale/context';
import defaultLocale from '../locale/en_US';
import type { SpaceProps } from '../space';
import { DesignTokenContext } from '../theme/internal';
import defaultSeedToken from '../theme/themes/seed';
import type {
ButtonConfig,
ConfigConsumerProps,
CSPConfig,
DirectionType,
@ -88,7 +86,6 @@ const PASSED_PROPS: Exclude<keyof ConfigConsumerProps, 'rootPrefixCls' | 'getPre
'pagination',
'form',
'select',
'button',
];
export interface ConfigProviderProps {
@ -124,10 +121,6 @@ export interface ConfigProviderProps {
direction?: DirectionType;
space?: {
size?: SizeType | number;
className?: SpaceProps['className'];
classNames?: SpaceProps['classNames'];
style?: SpaceProps['style'];
styles?: SpaceProps['styles'];
};
virtual?: boolean;
/** @deprecated Please use `popupMatchSelectWidth` instead */
@ -135,7 +128,6 @@ export interface ConfigProviderProps {
popupMatchSelectWidth?: boolean;
popupOverflow?: PopupOverflow;
theme?: ThemeConfig;
button?: ButtonConfig;
}
interface ProviderChildrenProps extends ConfigProviderProps {
@ -146,7 +138,6 @@ interface ProviderChildrenProps extends ConfigProviderProps {
export const defaultPrefixCls = 'ant';
let globalPrefixCls: string;
let globalIconPrefixCls: string;
let globalTheme: ThemeConfig;
function getGlobalPrefixCls() {
return globalPrefixCls || defaultPrefixCls;
@ -156,15 +147,11 @@ function getGlobalIconPrefixCls() {
return globalIconPrefixCls || defaultIconPrefixCls;
}
function isLegacyTheme(theme: Theme | ThemeConfig): theme is Theme {
return Object.keys(theme).some((key) => key.endsWith('Color'));
}
const setGlobalConfig = ({
prefixCls,
iconPrefixCls,
theme,
}: Pick<ConfigProviderProps, 'prefixCls' | 'iconPrefixCls'> & { theme?: Theme | ThemeConfig }) => {
}: Pick<ConfigProviderProps, 'prefixCls' | 'iconPrefixCls'> & { theme?: Theme }) => {
if (prefixCls !== undefined) {
globalPrefixCls = prefixCls;
}
@ -173,16 +160,7 @@ const setGlobalConfig = ({
}
if (theme) {
if (isLegacyTheme(theme)) {
warning(
false,
'ConfigProvider',
'`config` of css variable theme is not work in v5. Please use new `theme` config instead.',
);
registerTheme(getGlobalPrefixCls(), theme);
} else {
globalTheme = theme;
}
registerTheme(getGlobalPrefixCls(), theme);
}
};
@ -201,7 +179,6 @@ export const globalConfig = () => ({
// Fallback to default prefixCls
return getGlobalPrefixCls();
},
getTheme: () => globalTheme,
});
const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {

View File

@ -64,26 +64,21 @@ export default Demo;
| iconPrefixCls | 设置图标统一样式前缀 | string | `anticon` | 4.11.0 |
| input | 设置 Input 组件的通用属性 | { autoComplete?: string } | - | 4.2.0 |
| select | 设置 Select 组件的通用属性 | { showSearch?: boolean } | - | |
| button | 设置 Button 组件的通用属性 | { className?: string, style?: React.CSSProperties, classNames?: { icon: string }, styles?: { icon: React.CSSProperties } } | - | 5.6.0 |
| locale | 语言包配置,语言包可到 [antd/locale](http://unpkg.com/antd/locale/) 目录下寻找 | object | - | |
| prefixCls | 设置统一样式前缀 | string | `ant` | |
| renderEmpty | 自定义组件空状态。参考 [空状态](/components/empty-cn) | function(componentName: string): ReactNode | - | |
| space | 设置 Space 的通用属性,参考 [Space](/components/space-cn) | { size: `small` \| `middle` \| `large` \| `number`, className?: string, style?: React.CSSProperties, classNames?: { item: string }, styles?: { item: React.CSSProperties } } | - | 5.6.0 |
| space | 设置 Space 的 `size`,参考 [Space](/components/space-cn) | { size: `small` \| `middle` \| `large` \| `number` } | - | 4.1.0 |
| theme | 设置主题,参考 [定制主题](/docs/react/customize-theme-cn) | - | - | 5.0.0 |
| virtual | 设置 `false` 时关闭虚拟滚动 | boolean | - | 4.3.0 |
### ConfigProvider.config()
### ConfigProvider.config() `4.13.0+`
设置 `Modal`、`Message`、`Notification` 静态方法配置,只会对非 hooks 的静态方法调用生效
设置 `Modal`、`Message`、`Notification` rootPrefixCls
```ts
ConfigProvider.config({
prefixCls: 'ant',
iconPrefixCls: 'anticon',
// 5.6.0+
// 请优先考虑使用 hooks 版本
theme: { token: { colorPrimary: 'red' } },
prefixCls: 'ant', // 4.13.0+
iconPrefixCls: 'anticon', // 4.17.0+
});
```

View File

@ -1,9 +1,9 @@
import type { TriggerProps } from '@rc-component/trigger';
import dayjs from 'dayjs';
import 'dayjs/locale/mk'; // to test local in 'prop locale should works' test case
import customParseFormat from 'dayjs/plugin/customParseFormat';
import MockDate from 'mockdate';
import dayJsGenerateConfig from 'rc-picker/lib/generate/dayjs';
import type { TriggerProps } from 'rc-trigger';
import React from 'react';
import DatePicker from '..';
import focusTest from '../../../tests/shared/focusTest';
@ -295,21 +295,4 @@ describe('DatePicker', () => {
const { container } = render(<MyDatePicker />);
expect(container.firstChild).toMatchSnapshot();
});
it('kk:mm format', () => {
const { container } = render(
<DatePicker defaultValue={dayjs()} format="kk:mm" showTime open />,
);
expect(container.querySelectorAll('.ant-picker-time-panel-column').length).toBe(2);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[0]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(24);
expect(
container
.querySelectorAll('.ant-picker-time-panel-column')?.[1]
.querySelectorAll('.ant-picker-time-panel-cell').length,
).toBe(60);
});
});

View File

@ -385,427 +385,6 @@ exports[`renders components/descriptions/demo/border.tsx extend context correctl
</div>
`;
exports[`renders components/descriptions/demo/component-token.tsx extend context correctly 1`] = `
<div>
<div
class="ant-radio-group ant-radio-group-outline"
>
<label
class="ant-radio-wrapper ant-radio-wrapper-checked"
>
<span
class="ant-radio ant-radio-checked"
>
<input
checked=""
class="ant-radio-input"
type="radio"
value="default"
/>
<span
class="ant-radio-inner"
/>
</span>
<span>
default
</span>
</label>
<label
class="ant-radio-wrapper"
>
<span
class="ant-radio"
>
<input
class="ant-radio-input"
type="radio"
value="middle"
/>
<span
class="ant-radio-inner"
/>
</span>
<span>
middle
</span>
</label>
<label
class="ant-radio-wrapper"
>
<span
class="ant-radio"
>
<input
class="ant-radio-input"
type="radio"
value="small"
/>
<span
class="ant-radio-inner"
/>
</span>
<span>
small
</span>
</label>
</div>
<br />
<br />
<div
class="ant-descriptions ant-descriptions-bordered"
>
<div
class="ant-descriptions-header"
>
<div
class="ant-descriptions-title"
>
Custom Size
</div>
<div
class="ant-descriptions-extra"
>
<div>
extra color: blue
</div>
</div>
</div>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Product
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Cloud Database
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Billing
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Prepaid
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
time
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
18:00:00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Amount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$80.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Discount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$20.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Official
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$60.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Config Info
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Data disk type: MongoDB
<br />
Database version: 3.4
<br />
Package: dds.mongo.mid
<br />
Storage space: 10 GB
<br />
Replication factor: 3
<br />
Region: East China 1
<br />
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<br />
<br />
<div
class="ant-descriptions"
>
<div
class="ant-descriptions-header"
>
<div
class="ant-descriptions-title"
>
Custom Size
</div>
<div
class="ant-descriptions-extra"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Edit
</span>
</button>
</div>
</div>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Product
</span>
<span
class="ant-descriptions-item-content"
>
Cloud Database
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Billing
</span>
<span
class="ant-descriptions-item-content"
>
Prepaid
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
time
</span>
<span
class="ant-descriptions-item-content"
>
18:00:00
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Amount
</span>
<span
class="ant-descriptions-item-content"
>
$80.00
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Discount
</span>
<span
class="ant-descriptions-item-content"
>
$20.00
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Official
</span>
<span
class="ant-descriptions-item-content"
>
$60.00
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
`;
exports[`renders components/descriptions/demo/responsive.tsx extend context correctly 1`] = `
<div>
<div

View File

@ -353,395 +353,6 @@ exports[`renders components/descriptions/demo/border.tsx correctly 1`] = `
</div>
`;
exports[`renders components/descriptions/demo/component-token.tsx correctly 1`] = `
<div>
<div
class="ant-radio-group ant-radio-group-outline"
>
<label
class="ant-radio-wrapper ant-radio-wrapper-checked"
>
<span
class="ant-radio ant-radio-checked"
>
<input
checked=""
class="ant-radio-input"
type="radio"
value="default"
/>
<span
class="ant-radio-inner"
/>
</span>
<span>
default
</span>
</label>
<label
class="ant-radio-wrapper"
>
<span
class="ant-radio"
>
<input
class="ant-radio-input"
type="radio"
value="middle"
/>
<span
class="ant-radio-inner"
/>
</span>
<span>
middle
</span>
</label>
<label
class="ant-radio-wrapper"
>
<span
class="ant-radio"
>
<input
class="ant-radio-input"
type="radio"
value="small"
/>
<span
class="ant-radio-inner"
/>
</span>
<span>
small
</span>
</label>
</div>
<br />
<br />
<div
class="ant-descriptions ant-descriptions-bordered"
>
<div
class="ant-descriptions-header"
>
<div
class="ant-descriptions-title"
>
Custom Size
</div>
<div
class="ant-descriptions-extra"
>
<div>
extra color: blue
</div>
</div>
</div>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Product
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Cloud Database
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Billing
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
Prepaid
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
time
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
18:00:00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Amount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$80.00
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Discount
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$20.00
</span>
</td>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Official
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="1"
>
<span>
$60.00
</span>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<th
class="ant-descriptions-item-label"
colspan="1"
>
<span>
Config Info
</span>
</th>
<td
class="ant-descriptions-item-content"
colspan="5"
>
<span>
Data disk type: MongoDB
<br />
Database version: 3.4
<br />
Package: dds.mongo.mid
<br />
Storage space: 10 GB
<br />
Replication factor: 3
<br />
Region: East China 1
<br />
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<br />
<br />
<div
class="ant-descriptions"
>
<div
class="ant-descriptions-header"
>
<div
class="ant-descriptions-title"
>
Custom Size
</div>
<div
class="ant-descriptions-extra"
>
<button
class="ant-btn ant-btn-primary"
type="button"
>
<span>
Edit
</span>
</button>
</div>
</div>
<div
class="ant-descriptions-view"
>
<table>
<tbody>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Product
</span>
<span
class="ant-descriptions-item-content"
>
Cloud Database
</span>
</div>
</td>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Billing
</span>
<span
class="ant-descriptions-item-content"
>
Prepaid
</span>
</div>
</td>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
time
</span>
<span
class="ant-descriptions-item-content"
>
18:00:00
</span>
</div>
</td>
</tr>
<tr
class="ant-descriptions-row"
>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Amount
</span>
<span
class="ant-descriptions-item-content"
>
$80.00
</span>
</div>
</td>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Discount
</span>
<span
class="ant-descriptions-item-content"
>
$20.00
</span>
</div>
</td>
<td
class="ant-descriptions-item"
colspan="1"
>
<div
class="ant-descriptions-item-container"
>
<span
class="ant-descriptions-item-label"
>
Official
</span>
<span
class="ant-descriptions-item-content"
>
$60.00
</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
`;
exports[`renders components/descriptions/demo/responsive.tsx correctly 1`] = `
<div>
<div

View File

@ -1,7 +0,0 @@
## zh-CN
Component Token Debug.
## en-US
Component Token Debug.

View File

@ -1,73 +0,0 @@
import type { RadioChangeEvent } from 'antd';
import { Button, ConfigProvider, Descriptions, Radio } from 'antd';
import React, { useState } from 'react';
const App: React.FC = () => {
const [size, setSize] = useState<'default' | 'middle' | 'small'>('default');
const onChange = (e: RadioChangeEvent) => {
console.log('size checked', e.target.value);
setSize(e.target.value);
};
return (
<ConfigProvider
theme={{
components: {
Descriptions: {
labelBg: 'red',
titleMarginBottom: 2,
itemPaddingBottom: 8,
colonMarginRight: 10,
colonMarginLeft: 20,
extraColor: 'blue',
},
},
}}
>
<div>
<Radio.Group onChange={onChange} value={size}>
<Radio value="default">default</Radio>
<Radio value="middle">middle</Radio>
<Radio value="small">small</Radio>
</Radio.Group>
<br />
<br />
<Descriptions bordered title="Custom Size" size={size} extra={<div>extra color: blue</div>}>
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
<Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
<Descriptions.Item label="time">18:00:00</Descriptions.Item>
<Descriptions.Item label="Amount">$80.00</Descriptions.Item>
<Descriptions.Item label="Discount">$20.00</Descriptions.Item>
<Descriptions.Item label="Official">$60.00</Descriptions.Item>
<Descriptions.Item label="Config Info">
Data disk type: MongoDB
<br />
Database version: 3.4
<br />
Package: dds.mongo.mid
<br />
Storage space: 10 GB
<br />
Replication factor: 3
<br />
Region: East China 1
<br />
</Descriptions.Item>
</Descriptions>
<br />
<br />
<Descriptions title="Custom Size" size={size} extra={<Button type="primary">Edit</Button>}>
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
<Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
<Descriptions.Item label="time">18:00:00</Descriptions.Item>
<Descriptions.Item label="Amount">$80.00</Descriptions.Item>
<Descriptions.Item label="Discount">$20.00</Descriptions.Item>
<Descriptions.Item label="Official">$60.00</Descriptions.Item>
</Descriptions>
</div>
</ConfigProvider>
);
};
export default App;

View File

@ -23,7 +23,6 @@ Commonly displayed on the details page.
<code src="./demo/vertical.tsx">Vertical</code>
<code src="./demo/vertical-border.tsx">Vertical border</code>
<code src="./demo/style.tsx" debug>Customize label & wrapper style</code>
<code src="./demo/component-token.tsx" debug>Component Token</code>
## API

View File

@ -24,7 +24,6 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*d27AQJrowGAAAA
<code src="./demo/vertical.tsx">垂直</code>
<code src="./demo/vertical-border.tsx">垂直带边框的</code>
<code src="./demo/style.tsx" debug>自定义 label & wrapper 样式</code>
<code src="./demo/component-token.tsx" debug>组件 Token</code>
## API

View File

@ -3,21 +3,26 @@ import { resetComponent, textEllipsis } from '../../style';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
/** Component only token. Which will handle additional calculation of alias token */
export interface ComponentToken {
// Component token here
labelBg: string;
titleMarginBottom: number;
itemPaddingBottom: number;
colonMarginRight: number;
colonMarginLeft: number;
extraColor: string;
interface DescriptionsToken extends FullToken<'Descriptions'> {
descriptionsTitleMarginBottom: number;
descriptionsExtraColor: string;
descriptionItemPaddingBottom: number;
descriptionsDefaultPadding: string;
descriptionsBg: string;
descriptionsMiddlePadding: string;
descriptionsSmallPadding: string;
descriptionsItemLabelColonMarginRight: number;
descriptionsItemLabelColonMarginLeft: number;
}
interface DescriptionsToken extends FullToken<'Descriptions'> {}
const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
const { componentCls, labelBg } = token;
const {
componentCls,
descriptionsSmallPadding,
descriptionsDefaultPadding,
descriptionsMiddlePadding,
descriptionsBg,
} = token;
return {
[`&${componentCls}-bordered`]: {
[`${componentCls}-view`]: {
@ -28,7 +33,7 @@ const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
},
},
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
padding: `${token.padding}px ${token.paddingLG}px`,
padding: descriptionsDefaultPadding,
borderInlineEnd: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
'&:last-child': {
borderInlineEnd: 'none',
@ -36,7 +41,7 @@ const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
},
[`${componentCls}-item-label`]: {
color: token.colorTextSecondary,
backgroundColor: labelBg,
backgroundColor: descriptionsBg,
'&::after': {
display: 'none',
},
@ -49,26 +54,26 @@ const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
},
[`&${componentCls}-middle`]: {
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
padding: `${token.paddingSM}px ${token.paddingLG}px`,
padding: descriptionsMiddlePadding,
},
},
[`&${componentCls}-small`]: {
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
padding: `${token.paddingXS}px ${token.padding}px`,
padding: descriptionsSmallPadding,
},
},
},
};
};
const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: DescriptionsToken) => {
const {
componentCls,
extraColor,
itemPaddingBottom,
colonMarginRight,
colonMarginLeft,
titleMarginBottom,
descriptionsExtraColor,
descriptionItemPaddingBottom,
descriptionsItemLabelColonMarginRight,
descriptionsItemLabelColonMarginLeft,
descriptionsTitleMarginBottom,
} = token;
return {
[componentCls]: {
@ -80,7 +85,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
[`${componentCls}-header`]: {
display: 'flex',
alignItems: 'center',
marginBottom: titleMarginBottom,
marginBottom: descriptionsTitleMarginBottom,
},
[`${componentCls}-title`]: {
...textEllipsis,
@ -92,7 +97,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
},
[`${componentCls}-extra`]: {
marginInlineStart: 'auto',
color: extraColor,
color: descriptionsExtraColor,
fontSize: token.fontSize,
},
[`${componentCls}-view`]: {
@ -105,7 +110,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
},
[`${componentCls}-row`]: {
'> th, > td': {
paddingBottom: itemPaddingBottom,
paddingBottom: descriptionItemPaddingBottom,
},
'&:last-child': {
borderBottom: 'none',
@ -122,7 +127,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
content: '":"',
position: 'relative',
top: -0.5, // magic for position
marginInline: `${colonMarginLeft}px ${colonMarginRight}px`,
marginInline: `${descriptionsItemLabelColonMarginLeft}px ${descriptionsItemLabelColonMarginRight}px`,
},
[`&${componentCls}-item-no-colon::after`]: {
@ -177,18 +182,28 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
};
};
// ============================== Export ==============================
export default genComponentStyleHook(
'Descriptions',
(token) => {
const descriptionToken = mergeToken<DescriptionsToken>(token, {});
return [genDescriptionStyles(descriptionToken)];
},
(token) => ({
labelBg: token.colorFillAlter,
titleMarginBottom: token.fontSizeSM * token.lineHeightSM,
itemPaddingBottom: token.padding,
colonMarginRight: token.marginXS,
colonMarginLeft: token.marginXXS / 2,
extraColor: token.colorText,
}),
);
export default genComponentStyleHook('Descriptions', (token) => {
const descriptionsBg = token.colorFillAlter;
const descriptionsTitleMarginBottom = token.fontSizeSM * token.lineHeightSM;
const descriptionsExtraColor = token.colorText;
const descriptionsSmallPadding = `${token.paddingXS}px ${token.padding}px`;
const descriptionsDefaultPadding = `${token.padding}px ${token.paddingLG}px`;
const descriptionsMiddlePadding = `${token.paddingSM}px ${token.paddingLG}px`;
const descriptionItemPaddingBottom = token.padding;
const descriptionsItemLabelColonMarginRight = token.marginXS;
const descriptionsItemLabelColonMarginLeft = token.marginXXS / 2;
const descriptionToken = mergeToken<DescriptionsToken>(token, {
descriptionsBg,
descriptionsTitleMarginBottom,
descriptionsExtraColor,
descriptionItemPaddingBottom,
descriptionsSmallPadding,
descriptionsDefaultPadding,
descriptionsMiddlePadding,
descriptionsItemLabelColonMarginRight,
descriptionsItemLabelColonMarginLeft,
});
return [genDescriptionStyles(descriptionToken)];
});

View File

@ -20288,7 +20288,6 @@ exports[`renders components/form/demo/validate-other.tsx extend context correctl
>
<ul
class="ant-rate"
id="validate_other_rate"
role="radiogroup"
tabindex="0"
>

View File

@ -9168,7 +9168,6 @@ exports[`renders components/form/demo/validate-other.tsx correctly 1`] = `
>
<ul
class="ant-rate"
id="validate_other_rate"
role="radiogroup"
tabindex="0"
>

View File

@ -41,87 +41,6 @@ exports[`renders components/image/demo/basic.tsx extend context correctly 1`] =
</div>
`;
exports[`renders components/image/demo/component-token.tsx extend context correctly 1`] = `
Array [
<div
class="ant-image"
style="width: 150px;"
>
<img
class="ant-image-img"
src="https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg"
width="150"
/>
<div
class="ant-image-mask"
>
<div
class="ant-image-mask-info"
>
<span
aria-label="eye"
class="anticon anticon-eye"
role="img"
>
<svg
aria-hidden="true"
data-icon="eye"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
/>
</svg>
</span>
Preview
</div>
</div>
</div>,
<div
class="ant-image"
style="width: 150px;"
>
<img
class="ant-image-img"
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
width="150"
/>
<div
class="ant-image-mask"
>
<div
class="ant-image-mask-info"
>
<span
aria-label="eye"
class="anticon anticon-eye"
role="img"
>
<svg
aria-hidden="true"
data-icon="eye"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
/>
</svg>
</span>
Preview
</div>
</div>
</div>,
]
`;
exports[`renders components/image/demo/controlled-preview.tsx extend context correctly 1`] = `
Array [
<div>

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