mirror of
https://github.com/ant-design/ant-design.git
synced 2025-01-18 14:13:37 +08:00
Merge remote-tracking branch 'origin/feature' into fix/datePicker
This commit is contained in:
commit
852394c198
@ -1,10 +1,10 @@
|
||||
import type { ReactNode } from 'react';
|
||||
import React, { useMemo } from 'react';
|
||||
import type { MenuProps } from 'antd';
|
||||
import { useFullSidebarData, useSidebarData } from 'dumi';
|
||||
import { Tag, theme } from 'antd';
|
||||
import useLocation from './useLocation';
|
||||
import { useFullSidebarData, useSidebarData } from 'dumi';
|
||||
import type { ReactNode } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import Link from '../theme/common/Link';
|
||||
import useLocation from './useLocation';
|
||||
|
||||
export type UseMenuOptions = {
|
||||
before?: ReactNode;
|
||||
|
@ -1,18 +1,24 @@
|
||||
import type { FC } from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
import { ConfigContext } from 'antd/es/config-provider';
|
||||
import { ConfigProvider, theme as antdTheme } from 'antd';
|
||||
import type { ThemeProviderProps } from 'antd-style';
|
||||
import { ThemeProvider } from 'antd-style';
|
||||
import { theme } from 'antd';
|
||||
import type { FC } from 'react';
|
||||
import React, { useContext } from 'react';
|
||||
|
||||
const SiteThemeProvider: FC<ThemeProviderProps> = ({ children, ...rest }) => {
|
||||
const { getPrefixCls, iconPrefixCls } = useContext(ConfigContext);
|
||||
const SiteThemeProvider: FC<ThemeProviderProps> = ({ children, theme, ...rest }) => {
|
||||
const { getPrefixCls, iconPrefixCls } = useContext(ConfigProvider.ConfigContext);
|
||||
const rootPrefixCls = getPrefixCls();
|
||||
const { token } = theme.useToken();
|
||||
const { token } = antdTheme.useToken();
|
||||
|
||||
React.useEffect(() => {
|
||||
ConfigProvider.config({
|
||||
theme,
|
||||
});
|
||||
}, [theme]);
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
{...rest}
|
||||
theme={theme}
|
||||
customToken={{
|
||||
headerHeight: 64,
|
||||
menuItemBorder: 2,
|
||||
|
@ -1,8 +1,7 @@
|
||||
/* eslint-disable class-methods-use-this */
|
||||
import KeyCode from 'rc-util/lib/KeyCode';
|
||||
import React from 'react';
|
||||
import { waitFakeTimer, render, fireEvent } from '../../../tests/utils';
|
||||
import getDataOrAriaProps from '../getDataOrAriaProps';
|
||||
import { fireEvent, render, waitFakeTimer } from '../../../tests/utils';
|
||||
import { isStyleSupport } from '../styleChecker';
|
||||
import throttleByAnimationFrame from '../throttleByAnimationFrame';
|
||||
import TransButton from '../transButton';
|
||||
@ -46,57 +45,6 @@ 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>();
|
||||
|
@ -1,11 +0,0 @@
|
||||
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;
|
||||
}, {});
|
||||
}
|
@ -5,11 +5,11 @@ 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 { ConfigContext } from '../config-provider';
|
||||
import getDataOrAriaProps from '../_util/getDataOrAriaProps';
|
||||
import { replaceElement } from '../_util/reactNode';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import ErrorBoundary from './ErrorBoundary';
|
||||
|
||||
// CSSINJS
|
||||
@ -117,7 +117,7 @@ const Alert: CompoundedComponent = ({
|
||||
}) => {
|
||||
const [closed, setClosed] = React.useState(false);
|
||||
|
||||
const ref = React.useRef<HTMLElement>();
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
const { getPrefixCls, direction } = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('alert', customizePrefixCls);
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
@ -157,7 +157,10 @@ const Alert: CompoundedComponent = ({
|
||||
hashId,
|
||||
);
|
||||
|
||||
const dataOrAriaProps = getDataOrAriaProps(props);
|
||||
const dataOrAriaProps = pickAttrs(props, {
|
||||
aria: true,
|
||||
data: true,
|
||||
});
|
||||
|
||||
return wrapSSR(
|
||||
<CSSMotion
|
||||
|
@ -79,6 +79,85 @@ 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"
|
||||
|
@ -78,6 +78,84 @@ 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"
|
||||
|
7
components/anchor/demo/component-token.md
Normal file
7
components/anchor/demo/component-token.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
Component Token Debug.
|
||||
|
||||
## en-US
|
||||
|
||||
Component Token Debug
|
46
components/anchor/demo/component-token.tsx
Normal file
46
components/anchor/demo/component-token.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
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>
|
||||
);
|
@ -30,6 +30,7 @@ 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
|
||||
|
||||
|
@ -31,6 +31,7 @@ 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
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
import { resetComponent, textEllipsis } from '../../style';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { resetComponent, textEllipsis } from '../../style';
|
||||
|
||||
export interface ComponentToken {}
|
||||
export interface ComponentToken {
|
||||
linkPaddingBlock: number;
|
||||
linkPaddingInlineStart: number;
|
||||
}
|
||||
|
||||
interface AnchorToken extends FullToken<'Anchor'> {
|
||||
holderOffsetBlock: number;
|
||||
anchorPaddingBlock: number;
|
||||
anchorPaddingBlockSecondary: number;
|
||||
anchorPaddingInline: number;
|
||||
anchorBallSize: number;
|
||||
anchorTitleBlock: number;
|
||||
}
|
||||
@ -34,16 +35,14 @@ const genSharedAnchorStyle: GenerateStyle<AnchorToken> = (token): CSSObject => {
|
||||
// delete overflow: auto
|
||||
// overflow: 'auto',
|
||||
|
||||
backgroundColor: 'transparent',
|
||||
|
||||
[componentCls]: {
|
||||
...resetComponent(token),
|
||||
position: 'relative',
|
||||
paddingInlineStart: lineWidthBold,
|
||||
|
||||
[`${componentCls}-link`]: {
|
||||
paddingBlock: token.anchorPaddingBlock,
|
||||
paddingInline: `${token.anchorPaddingInline}px 0`,
|
||||
paddingBlock: token.linkPaddingBlock,
|
||||
paddingInline: `${token.linkPaddingInlineStart}px 0`,
|
||||
|
||||
'&-title': {
|
||||
...textEllipsis,
|
||||
@ -152,16 +151,21 @@ const genSharedAnchorHorizontalStyle: GenerateStyle<AnchorToken> = (token): CSSO
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default genComponentStyleHook('Anchor', (token) => {
|
||||
const { fontSize, fontSizeLG, padding, paddingXXS } = token;
|
||||
export default genComponentStyleHook(
|
||||
'Anchor',
|
||||
(token) => {
|
||||
const { fontSize, fontSizeLG, paddingXXS } = token;
|
||||
|
||||
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)];
|
||||
});
|
||||
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,
|
||||
}),
|
||||
);
|
||||
|
@ -342,6 +342,243 @@ 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
|
||||
|
@ -342,6 +342,154 @@ 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
|
||||
|
7
components/avatar/demo/comonent-token.md
Normal file
7
components/avatar/demo/comonent-token.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
Component Token Debug.
|
||||
|
||||
## en-US
|
||||
|
||||
Component Token Debug
|
51
components/avatar/demo/component-token.tsx
Normal file
51
components/avatar/demo/component-token.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
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;
|
@ -23,6 +23,7 @@ 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
|
||||
|
||||
|
@ -28,6 +28,7 @@ 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
|
||||
|
||||
|
@ -1,23 +1,24 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
import { resetComponent } from '../../style';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { resetComponent } from '../../style';
|
||||
|
||||
export interface ComponentToken {}
|
||||
export interface ComponentToken {
|
||||
containerSize: number;
|
||||
containerSizeLG: number;
|
||||
containerSizeSM: number;
|
||||
textFontSize: number;
|
||||
textFontSizeLG: number;
|
||||
textFontSizeSM: number;
|
||||
groupSpace: number;
|
||||
groupOverlapping: number;
|
||||
groupBorderColor: string;
|
||||
}
|
||||
|
||||
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) => {
|
||||
@ -27,12 +28,12 @@ const genBaseStyle: GenerateStyle<AvatarToken> = (token) => {
|
||||
iconCls,
|
||||
avatarBg,
|
||||
avatarColor,
|
||||
avatarSizeBase,
|
||||
avatarSizeLG,
|
||||
avatarSizeSM,
|
||||
avatarFontSizeBase,
|
||||
avatarFontSizeLG,
|
||||
avatarFontSizeSM,
|
||||
containerSize,
|
||||
containerSizeLG,
|
||||
containerSizeSM,
|
||||
textFontSize,
|
||||
textFontSizeLG,
|
||||
textFontSizeSM,
|
||||
borderRadius,
|
||||
borderRadiusLG,
|
||||
borderRadiusSM,
|
||||
@ -89,14 +90,14 @@ const genBaseStyle: GenerateStyle<AvatarToken> = (token) => {
|
||||
display: 'block',
|
||||
},
|
||||
|
||||
...avatarSizeStyle(avatarSizeBase, avatarFontSizeBase, borderRadius),
|
||||
...avatarSizeStyle(containerSize, textFontSize, borderRadius),
|
||||
|
||||
[`&-lg`]: {
|
||||
...avatarSizeStyle(avatarSizeLG, avatarFontSizeLG, borderRadiusLG),
|
||||
...avatarSizeStyle(containerSizeLG, textFontSizeLG, borderRadiusLG),
|
||||
},
|
||||
|
||||
[`&-sm`]: {
|
||||
...avatarSizeStyle(avatarSizeSM, avatarFontSizeSM, borderRadiusSM),
|
||||
...avatarSizeStyle(containerSizeSM, textFontSizeSM, borderRadiusSM),
|
||||
},
|
||||
|
||||
'> img': {
|
||||
@ -110,55 +111,65 @@ const genBaseStyle: GenerateStyle<AvatarToken> = (token) => {
|
||||
};
|
||||
|
||||
const genGroupStyle: GenerateStyle<AvatarToken> = (token) => {
|
||||
const { componentCls, avatarGroupBorderColor, avatarGroupSpace } = token;
|
||||
const { componentCls, groupBorderColor, groupOverlapping, groupSpace } = token;
|
||||
|
||||
return {
|
||||
[`${componentCls}-group`]: {
|
||||
display: 'inline-flex',
|
||||
|
||||
[`${componentCls}`]: {
|
||||
borderColor: avatarGroupBorderColor,
|
||||
borderColor: groupBorderColor,
|
||||
},
|
||||
|
||||
[`> *:not(:first-child)`]: {
|
||||
marginInlineStart: avatarGroupSpace,
|
||||
marginInlineStart: groupOverlapping,
|
||||
},
|
||||
},
|
||||
[`${componentCls}-group-popover`]: {
|
||||
[`${componentCls} + ${componentCls}`]: {
|
||||
marginInlineStart: groupSpace,
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export default genComponentStyleHook('Avatar', (token) => {
|
||||
const {
|
||||
colorTextLightSolid,
|
||||
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,
|
||||
|
||||
controlHeight,
|
||||
controlHeightLG,
|
||||
controlHeightSM,
|
||||
fontSize,
|
||||
fontSizeLG,
|
||||
fontSizeXL,
|
||||
fontSizeHeading3,
|
||||
|
||||
fontSize,
|
||||
fontSizeLG,
|
||||
fontSizeXL,
|
||||
fontSizeHeading3,
|
||||
marginXS,
|
||||
marginXXS,
|
||||
colorBorderBg,
|
||||
} = token;
|
||||
return {
|
||||
containerSize: controlHeight,
|
||||
containerSizeLG: controlHeightLG,
|
||||
containerSizeSM: controlHeightSM,
|
||||
|
||||
marginXS,
|
||||
colorBorderBg,
|
||||
colorTextPlaceholder,
|
||||
} = token;
|
||||
textFontSize: Math.round((fontSizeLG + fontSizeXL) / 2),
|
||||
textFontSizeLG: fontSizeHeading3,
|
||||
textFontSizeSM: fontSize,
|
||||
|
||||
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)];
|
||||
});
|
||||
groupSpace: marginXXS,
|
||||
groupOverlapping: -marginXS,
|
||||
groupBorderColor: colorBorderBg,
|
||||
};
|
||||
},
|
||||
);
|
||||
|
@ -63,6 +63,333 @@ 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"
|
||||
>
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
>
|
||||
<a
|
||||
href=""
|
||||
>
|
||||
Application Center
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-hidden="true"
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
>
|
||||
</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"
|
||||
>
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-breadcrumb-link"
|
||||
href=""
|
||||
>
|
||||
Application Center
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-hidden="true"
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
>
|
||||
</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"
|
||||
>
|
||||
>
|
||||
</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"
|
||||
|
@ -63,6 +63,160 @@ 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"
|
||||
>
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<span
|
||||
class="ant-breadcrumb-link"
|
||||
>
|
||||
<a
|
||||
href=""
|
||||
>
|
||||
Application Center
|
||||
</a>
|
||||
</span>
|
||||
</li>
|
||||
<li
|
||||
aria-hidden="true"
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
>
|
||||
</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"
|
||||
>
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="ant-breadcrumb-link"
|
||||
href=""
|
||||
>
|
||||
Application Center
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-hidden="true"
|
||||
class="ant-breadcrumb-separator"
|
||||
>
|
||||
>
|
||||
</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"
|
||||
>
|
||||
>
|
||||
</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"
|
||||
|
7
components/breadcrumb/demo/component-token.md
Normal file
7
components/breadcrumb/demo/component-token.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
Component Token Debug.
|
||||
|
||||
## en-US
|
||||
|
||||
Component Token Debug.
|
80
components/breadcrumb/demo/component-token.tsx
Normal file
80
components/breadcrumb/demo/component-token.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
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>
|
||||
);
|
@ -42,6 +42,7 @@ 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
|
||||
|
||||
|
@ -43,6 +43,7 @@ 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
|
||||
|
||||
|
@ -1,30 +1,31 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
import { genFocusStyle, resetComponent } from '../../style';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { genFocusStyle, resetComponent } from '../../style';
|
||||
|
||||
interface BreadcrumbToken extends FullToken<'Breadcrumb'> {
|
||||
breadcrumbBaseColor: string;
|
||||
breadcrumbFontSize: number;
|
||||
breadcrumbIconFontSize: number;
|
||||
breadcrumbLinkColor: string;
|
||||
breadcrumbLinkColorHover: string;
|
||||
breadcrumbLastItemColor: string;
|
||||
breadcrumbSeparatorMargin: number;
|
||||
breadcrumbSeparatorColor: string;
|
||||
export interface ComponentToken {
|
||||
itemColor: string;
|
||||
iconFontSize: number;
|
||||
linkColor: string;
|
||||
linkHoverColor: string;
|
||||
lastItemColor: string;
|
||||
separatorMargin: number;
|
||||
separatorColor: string;
|
||||
}
|
||||
|
||||
interface BreadcrumbToken extends FullToken<'Breadcrumb'> {}
|
||||
|
||||
const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) => {
|
||||
const { componentCls, iconCls } = token;
|
||||
|
||||
return {
|
||||
[componentCls]: {
|
||||
...resetComponent(token),
|
||||
color: token.breadcrumbBaseColor,
|
||||
fontSize: token.breadcrumbFontSize,
|
||||
color: token.itemColor,
|
||||
fontSize: token.fontSize,
|
||||
|
||||
[iconCls]: {
|
||||
fontSize: token.breadcrumbIconFontSize,
|
||||
fontSize: token.iconFontSize,
|
||||
},
|
||||
|
||||
ol: {
|
||||
@ -36,7 +37,7 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
|
||||
},
|
||||
|
||||
a: {
|
||||
color: token.breadcrumbLinkColor,
|
||||
color: token.linkColor,
|
||||
transition: `color ${token.motionDurationMid}`,
|
||||
padding: `0 ${token.paddingXXS}px`,
|
||||
borderRadius: token.borderRadiusSM,
|
||||
@ -45,7 +46,7 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
|
||||
marginInline: -token.marginXXS,
|
||||
|
||||
'&:hover': {
|
||||
color: token.breadcrumbLinkColorHover,
|
||||
color: token.linkHoverColor,
|
||||
backgroundColor: token.colorBgTextHover,
|
||||
},
|
||||
|
||||
@ -53,12 +54,12 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
|
||||
},
|
||||
|
||||
[`li:last-child`]: {
|
||||
color: token.breadcrumbLastItemColor,
|
||||
color: token.lastItemColor,
|
||||
},
|
||||
|
||||
[`${componentCls}-separator`]: {
|
||||
marginInline: token.breadcrumbSeparatorMargin,
|
||||
color: token.breadcrumbSeparatorColor,
|
||||
marginInline: token.separatorMargin,
|
||||
color: token.separatorColor,
|
||||
},
|
||||
|
||||
[`${componentCls}-link`]: {
|
||||
@ -83,11 +84,11 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
|
||||
},
|
||||
|
||||
'&:hover': {
|
||||
color: token.breadcrumbLinkColorHover,
|
||||
color: token.linkHoverColor,
|
||||
backgroundColor: token.colorBgTextHover,
|
||||
|
||||
a: {
|
||||
color: token.breadcrumbLinkColorHover,
|
||||
color: token.linkHoverColor,
|
||||
},
|
||||
},
|
||||
|
||||
@ -107,17 +108,19 @@ const genBreadcrumbStyle: GenerateStyle<BreadcrumbToken, CSSObject> = (token) =>
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
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)];
|
||||
});
|
||||
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,
|
||||
}),
|
||||
);
|
||||
|
@ -18,12 +18,12 @@ import DisabledContext from '../config-provider/DisabledContext';
|
||||
import type { SizeType } from '../config-provider/SizeContext';
|
||||
import useSize from '../config-provider/hooks/useSize';
|
||||
import { useCompactItemContext } from '../space/Compact';
|
||||
import IconWrapper from './IconWrapper';
|
||||
import LoadingIcon from './LoadingIcon';
|
||||
import Group, { GroupSizeContext } from './button-group';
|
||||
import type { ButtonHTMLType, ButtonShape, ButtonType } from './buttonHelpers';
|
||||
import { isTwoCNChar, isUnBorderedButtonType, spaceChildren } from './buttonHelpers';
|
||||
import useStyle from './style';
|
||||
import IconWrapper from './IconWrapper';
|
||||
|
||||
export type LegacyButtonType = ButtonType | 'danger';
|
||||
|
||||
@ -121,10 +121,11 @@ 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 } = useContext(ConfigContext);
|
||||
const { getPrefixCls, autoInsertSpaceInButton, direction, button } = useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('btn', customizePrefixCls);
|
||||
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
@ -238,11 +239,17 @@ 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={customClassNames?.icon} style={styles?.icon}>
|
||||
<IconWrapper prefixCls={prefixCls} className={iconClasses} style={iconStyle}>
|
||||
{icon}
|
||||
</IconWrapper>
|
||||
) : (
|
||||
@ -257,6 +264,7 @@ const InternalButton: React.ForwardRefRenderFunction<
|
||||
<a
|
||||
{...linkButtonRestProps}
|
||||
className={classes}
|
||||
style={fullStyle}
|
||||
onClick={handleClick}
|
||||
ref={buttonRef as React.Ref<HTMLAnchorElement>}
|
||||
>
|
||||
@ -271,6 +279,7 @@ const InternalButton: React.ForwardRefRenderFunction<
|
||||
{...(rest as NativeButtonProps)}
|
||||
type={htmlType}
|
||||
className={classes}
|
||||
style={fullStyle}
|
||||
onClick={handleClick}
|
||||
disabled={mergedDisabled}
|
||||
ref={buttonRef as React.Ref<HTMLButtonElement>}
|
||||
|
@ -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 } from './generateCalendar';
|
||||
import type { CalendarMode, SelectInfo } 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) => void;
|
||||
onChange: (date: DateType, source: SelectInfo['source']) => void;
|
||||
onModeChange: (mode: CalendarMode) => void;
|
||||
}
|
||||
function CalendarHeader<DateType>(props: CalendarHeaderProps<DateType>) {
|
||||
@ -165,7 +165,6 @@ function CalendarHeader<DateType>(props: CalendarHeaderProps<DateType>) {
|
||||
|
||||
const sharedProps = {
|
||||
...props,
|
||||
onChange,
|
||||
fullscreen,
|
||||
divRef,
|
||||
};
|
||||
@ -173,8 +172,20 @@ function CalendarHeader<DateType>(props: CalendarHeaderProps<DateType>) {
|
||||
return (
|
||||
<div className={`${prefixCls}-header`} ref={divRef}>
|
||||
<FormItemInputContext.Provider value={mergedFormItemInputContext}>
|
||||
<YearSelect {...sharedProps} />
|
||||
{mode === 'month' && <MonthSelect {...sharedProps} />}
|
||||
<YearSelect
|
||||
{...sharedProps}
|
||||
onChange={(v) => {
|
||||
onChange(v, 'year');
|
||||
}}
|
||||
/>
|
||||
{mode === 'month' && (
|
||||
<MonthSelect
|
||||
{...sharedProps}
|
||||
onChange={(v) => {
|
||||
onChange(v, 'month');
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</FormItemInputContext.Provider>
|
||||
<ModeSwitch {...sharedProps} onModeChange={onModeChange} />
|
||||
</div>
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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());
|
||||
expect(onSelect).toHaveBeenCalledWith(expect.anything(), { source: 'date' });
|
||||
|
||||
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));
|
||||
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(3), 'year');
|
||||
});
|
||||
|
||||
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));
|
||||
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(10), 'year');
|
||||
});
|
||||
|
||||
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));
|
||||
expect(onValueChange).toHaveBeenCalledWith(value.year(2019).month(2), 'year');
|
||||
});
|
||||
|
||||
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));
|
||||
expect(onValueChange).toHaveBeenCalledWith(value.month(10), 'month');
|
||||
});
|
||||
|
||||
it('onTypeChange should work correctly', () => {
|
||||
|
99
components/calendar/__tests__/select.test.tsx
Normal file
99
components/calendar/__tests__/select.test.tsx
Normal file
@ -0,0 +1,99 @@
|
||||
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' });
|
||||
});
|
||||
});
|
7
components/calendar/demo/component-token.md
Normal file
7
components/calendar/demo/component-token.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
Component Token Debug.
|
||||
|
||||
## en-US
|
||||
|
||||
Component Token Debug.
|
29
components/calendar/demo/component-token.tsx
Normal file
29
components/calendar/demo/component-token.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
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>
|
||||
);
|
||||
};
|
@ -1,12 +1,12 @@
|
||||
import classNames from 'classnames';
|
||||
import { PickerPanel as RCPickerPanel } from 'rc-picker';
|
||||
import type { GenerateConfig } from 'rc-picker/lib/generate';
|
||||
import type { CellRenderInfo } from 'rc-picker/lib/interface';
|
||||
import type {
|
||||
PickerPanelBaseProps as RCPickerPanelBaseProps,
|
||||
PickerPanelDateProps as RCPickerPanelDateProps,
|
||||
PickerPanelTimeProps as RCPickerPanelTimeProps,
|
||||
} from 'rc-picker/lib/PickerPanel';
|
||||
import type { GenerateConfig } from 'rc-picker/lib/generate';
|
||||
import type { CellRenderInfo } from 'rc-picker/lib/interface';
|
||||
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
||||
import * as React from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
@ -14,8 +14,8 @@ import { useLocale } from '../locale';
|
||||
import CalendarHeader from './Header';
|
||||
import enUS from './locale/en_US';
|
||||
|
||||
import useStyle from './style';
|
||||
import warning from '../_util/warning';
|
||||
import useStyle from './style';
|
||||
|
||||
type InjectDefaultProps<Props> = Omit<
|
||||
Props,
|
||||
@ -43,6 +43,10 @@ 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;
|
||||
@ -68,7 +72,7 @@ export interface CalendarProps<DateType> {
|
||||
fullscreen?: boolean;
|
||||
onChange?: (date: DateType) => void;
|
||||
onPanelChange?: (date: DateType, mode: CalendarMode) => void;
|
||||
onSelect?: (date: DateType) => void;
|
||||
onSelect?: (date: DateType, selectInfo: SelectInfo) => void;
|
||||
}
|
||||
|
||||
function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
|
||||
@ -198,10 +202,10 @@ function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
|
||||
triggerPanelChange(mergedValue, newMode);
|
||||
};
|
||||
|
||||
const onInternalSelect = (date: DateType) => {
|
||||
const onInternalSelect = (date: DateType, source: SelectInfo['source']) => {
|
||||
triggerChange(date);
|
||||
|
||||
onSelect?.(date);
|
||||
onSelect?.(date, { source });
|
||||
};
|
||||
|
||||
// ====================== Locale ======================
|
||||
@ -310,7 +314,9 @@ function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
|
||||
headerRender({
|
||||
value: mergedValue,
|
||||
type: mergedMode,
|
||||
onChange: onInternalSelect,
|
||||
onChange: (nextDate) => {
|
||||
onInternalSelect(nextDate, 'customize');
|
||||
},
|
||||
onTypeChange: triggerModeChange,
|
||||
})
|
||||
) : (
|
||||
@ -332,7 +338,9 @@ function generateCalendar<DateType>(generateConfig: GenerateConfig<DateType>) {
|
||||
locale={contextLocale?.lang}
|
||||
generateConfig={generateConfig}
|
||||
cellRender={mergedCellRender}
|
||||
onSelect={onInternalSelect}
|
||||
onSelect={(nextDate) => {
|
||||
onInternalSelect(nextDate, panelMode);
|
||||
}}
|
||||
mode={panelMode}
|
||||
picker={panelMode}
|
||||
disabledDate={mergedDisabledDate}
|
||||
|
@ -20,6 +20,7 @@ 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
|
||||
|
||||
@ -55,7 +56,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 | function(date: Dayjs) | - | |
|
||||
| onSelect | Callback for when a date is selected, include source info | function(date: Dayjs, info: { source: 'year' \| 'month' \| 'date' \| 'customize' }) | - | `info`: 5.6.0 |
|
||||
|
||||
## Design Token
|
||||
|
||||
@ -74,3 +75,17 @@ 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);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
@ -21,6 +21,7 @@ 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
|
||||
|
||||
@ -60,7 +61,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) | - | |
|
||||
| onSelect | 选择日期回调,包含来源信息 | function(date: Dayjs, info: { source: 'year' \| 'month' \| 'date' \| 'customize' }) | - | `info`: 5.6.0 |
|
||||
|
||||
## Design Token
|
||||
|
||||
@ -79,3 +80,17 @@ 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);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
@ -1,9 +1,9 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
import { resetComponent } from '../../style';
|
||||
import type { PickerPanelToken } from '../../date-picker/style';
|
||||
import { genPanelStyle, initPickerPanelToken } from '../../date-picker/style';
|
||||
import type { InputToken } from '../../input/style';
|
||||
import { initInputToken } from '../../input/style';
|
||||
import { resetComponent } from '../../style';
|
||||
import type { FullToken } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
|
||||
@ -11,26 +11,25 @@ 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, calendarFullBg, calendarFullPanelBg, calendarItemActiveBg } =
|
||||
token;
|
||||
const { calendarCls, componentCls, fullBg, fullPanelBg, itemActiveBg } = token;
|
||||
return {
|
||||
[calendarCls]: {
|
||||
...genPanelStyle(token),
|
||||
...resetComponent(token),
|
||||
background: calendarFullBg,
|
||||
background: fullBg,
|
||||
'&-rtl': {
|
||||
direction: 'rtl',
|
||||
},
|
||||
@ -52,7 +51,7 @@ export const genCalendarStyles = (token: CalendarToken): CSSObject => {
|
||||
},
|
||||
},
|
||||
[`${calendarCls} ${componentCls}-panel`]: {
|
||||
background: calendarFullPanelBg,
|
||||
background: fullPanelBg,
|
||||
border: 0,
|
||||
borderTop: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
|
||||
borderRadius: 0,
|
||||
@ -92,7 +91,7 @@ export const genCalendarStyles = (token: CalendarToken): CSSObject => {
|
||||
display: 'block',
|
||||
width: '100%',
|
||||
textAlign: 'end',
|
||||
background: calendarFullBg,
|
||||
background: fullBg,
|
||||
border: 0,
|
||||
[`${componentCls}-body`]: {
|
||||
'th, td': {
|
||||
@ -121,7 +120,7 @@ export const genCalendarStyles = (token: CalendarToken): CSSObject => {
|
||||
// >>> Selected
|
||||
[`&-in-view${componentCls}-cell-selected`]: {
|
||||
[`${calendarCls}-date, ${calendarCls}-date-today`]: {
|
||||
background: calendarItemActiveBg,
|
||||
background: itemActiveBg,
|
||||
},
|
||||
},
|
||||
'&-selected, &-selected:hover': {
|
||||
@ -198,9 +197,6 @@ 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:
|
||||
@ -210,9 +206,12 @@ export default genComponentStyleHook(
|
||||
|
||||
return [genCalendarStyles(calendarToken)];
|
||||
},
|
||||
{
|
||||
(token) => ({
|
||||
fullBg: token.colorBgContainer,
|
||||
fullPanelBg: token.colorBgContainer,
|
||||
itemActiveBg: token.controlItemBgActive,
|
||||
yearControlWidth: 80,
|
||||
monthControlWidth: 70,
|
||||
miniContentHeight: 256,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
@ -1,4 +1,5 @@
|
||||
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';
|
||||
@ -12,10 +13,11 @@ import useStyle from './style';
|
||||
export type CardType = 'inner';
|
||||
export type CardSize = 'default' | 'small';
|
||||
|
||||
export interface CardTabListType {
|
||||
export interface CardTabListType extends Omit<Tab, 'label'> {
|
||||
key: string;
|
||||
tab: React.ReactNode;
|
||||
disabled?: boolean;
|
||||
/** @deprecated Please use `label` instead */
|
||||
tab?: React.ReactNode;
|
||||
label?: React.ReactNode;
|
||||
}
|
||||
|
||||
export interface CardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
||||
@ -123,10 +125,9 @@ const Card = React.forwardRef<HTMLDivElement, CardProps>((props, ref) => {
|
||||
{...extraProps}
|
||||
className={`${prefixCls}-head-tabs`}
|
||||
onChange={onTabChange}
|
||||
items={tabList.map((item) => ({
|
||||
label: item.tab,
|
||||
key: item.key,
|
||||
disabled: item.disabled ?? false,
|
||||
items={tabList.map(({ tab, ...item }) => ({
|
||||
label: tab,
|
||||
...item,
|
||||
}))}
|
||||
/>
|
||||
) : null;
|
||||
|
@ -130,6 +130,284 @@ 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"
|
||||
@ -771,7 +1049,6 @@ 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"
|
||||
@ -787,7 +1064,6 @@ 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"
|
||||
@ -913,7 +1189,6 @@ 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"
|
||||
@ -929,7 +1204,6 @@ 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"
|
||||
@ -945,7 +1219,6 @@ 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"
|
||||
|
@ -130,6 +130,261 @@ 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"
|
||||
@ -770,7 +1025,6 @@ Array [
|
||||
data-node-key="tab1"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-btn"
|
||||
role="tab"
|
||||
@ -784,7 +1038,6 @@ Array [
|
||||
data-node-key="tab2"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class="ant-tabs-tab-btn"
|
||||
role="tab"
|
||||
@ -889,7 +1142,6 @@ Array [
|
||||
data-node-key="article"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class="ant-tabs-tab-btn"
|
||||
role="tab"
|
||||
@ -903,7 +1155,6 @@ Array [
|
||||
data-node-key="app"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="true"
|
||||
class="ant-tabs-tab-btn"
|
||||
role="tab"
|
||||
@ -917,7 +1168,6 @@ Array [
|
||||
data-node-key="project"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
aria-selected="false"
|
||||
class="ant-tabs-tab-btn"
|
||||
role="tab"
|
||||
|
@ -1,5 +1,268 @@
|
||||
// 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"
|
||||
|
@ -1,11 +1,11 @@
|
||||
import React from 'react';
|
||||
import '@testing-library/jest-dom';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { screen, render } from '../../../tests/utils';
|
||||
import { render, screen } from '../../../tests/utils';
|
||||
import Button from '../../button/index';
|
||||
import Card from '../index';
|
||||
import '@testing-library/jest-dom';
|
||||
|
||||
describe('Card', () => {
|
||||
mountTest(Card);
|
||||
@ -112,7 +112,7 @@ describe('Card', () => {
|
||||
tab: 'tab',
|
||||
},
|
||||
]}
|
||||
size='small'
|
||||
size="small"
|
||||
>
|
||||
<p>Card content</p>
|
||||
</Card>,
|
||||
@ -131,4 +131,36 @@ 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();
|
||||
});
|
||||
});
|
||||
|
7
components/card/demo/component-token.md
Normal file
7
components/card/demo/component-token.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
Component Token Debug.
|
||||
|
||||
## en-US
|
||||
|
||||
Component Token Debug.
|
52
components/card/demo/component-token.tsx
Normal file
52
components/card/demo/component-token.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
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>
|
||||
);
|
@ -20,15 +20,15 @@ const contentList: Record<string, React.ReactNode> = {
|
||||
const tabListNoTitle = [
|
||||
{
|
||||
key: 'article',
|
||||
tab: 'article',
|
||||
label: 'article',
|
||||
},
|
||||
{
|
||||
key: 'app',
|
||||
tab: 'app',
|
||||
label: 'app',
|
||||
},
|
||||
{
|
||||
key: 'project',
|
||||
tab: 'project',
|
||||
label: 'project',
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -25,6 +25,7 @@ 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
|
||||
|
||||
@ -48,7 +49,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 | Array<{key: string, tab: ReactNode}> | - | |
|
||||
| tabList | List of TabPane's head | [TabItemType](/components/tabs#tabitemtype)[] | - | |
|
||||
| tabProps | [Tabs](/components/tabs/#tabs) | - | - | |
|
||||
| title | Card title | ReactNode | - | |
|
||||
| type | Card style type, can be set to `inner` or not set | string | - | |
|
||||
|
@ -26,6 +26,7 @@ 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
|
||||
|
||||
@ -49,7 +50,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 | 页签标题列表 | Array<{key: string, tab: ReactNode}> | - | |
|
||||
| tabList | 页签标题列表 | [TabItemType](/components/tabs#tabitemtype)[] | - | |
|
||||
| tabProps | [Tabs](/components/tabs-cn#tabs) | - | - | |
|
||||
| title | 卡片标题 | ReactNode | - | |
|
||||
| type | 卡片类型,可设置为 `inner` 或 不设置 | string | - | |
|
||||
|
@ -1,20 +1,26 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
|
||||
import { clearFix, resetComponent, textEllipsis } from '../../style';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { clearFix, resetComponent, textEllipsis } from '../../style';
|
||||
|
||||
export interface ComponentToken {}
|
||||
export interface ComponentToken {
|
||||
headerBg: string;
|
||||
headerFontSize: number;
|
||||
headerFontSizeSM: number;
|
||||
headerHeight: number;
|
||||
headerHeightSM: number;
|
||||
actionsBg: string;
|
||||
actionsLiMargin: string;
|
||||
tabsMarginBottom: number;
|
||||
extraColor: string;
|
||||
}
|
||||
|
||||
interface CardToken extends FullToken<'Card'> {
|
||||
cardHeadHeight: number;
|
||||
cardHeadHeightSM: number;
|
||||
cardShadow: string;
|
||||
cardHeadPadding: number;
|
||||
cardPaddingSM: number;
|
||||
cardPaddingBase: number;
|
||||
cardHeadTabsMarginBottom: number;
|
||||
cardActionsLiMargin: string;
|
||||
cardActionsIconSize: number;
|
||||
}
|
||||
|
||||
@ -22,19 +28,19 @@ interface CardToken extends FullToken<'Card'> {
|
||||
|
||||
// ============================== Head ==============================
|
||||
const genCardHeadStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
const { antCls, componentCls, cardHeadHeight, cardPaddingBase, cardHeadTabsMarginBottom } = token;
|
||||
const { antCls, componentCls, headerHeight, cardPaddingBase, tabsMarginBottom } = token;
|
||||
|
||||
return {
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
flexDirection: 'column',
|
||||
minHeight: cardHeadHeight,
|
||||
minHeight: headerHeight,
|
||||
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.fontSizeLG,
|
||||
background: 'transparent',
|
||||
fontSize: token.headerFontSize,
|
||||
background: token.headerBg,
|
||||
borderBottom: `${token.lineWidth}px ${token.lineType} ${token.colorBorderSecondary}`,
|
||||
borderRadius: `${token.borderRadiusLG}px ${token.borderRadiusLG}px 0 0`,
|
||||
|
||||
@ -63,7 +69,7 @@ const genCardHeadStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
|
||||
[`${antCls}-tabs-top`]: {
|
||||
clear: 'both',
|
||||
marginBottom: cardHeadTabsMarginBottom,
|
||||
marginBottom: tabsMarginBottom,
|
||||
color: token.colorText,
|
||||
fontWeight: 'normal',
|
||||
fontSize: token.fontSize,
|
||||
@ -102,20 +108,26 @@ const genCardGridStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
|
||||
// ============================== Actions ==============================
|
||||
const genCardActionsStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
const { componentCls, iconCls, cardActionsLiMargin, cardActionsIconSize, colorBorderSecondary } =
|
||||
token;
|
||||
const {
|
||||
componentCls,
|
||||
iconCls,
|
||||
actionsLiMargin,
|
||||
cardActionsIconSize,
|
||||
colorBorderSecondary,
|
||||
actionsBg,
|
||||
} = token;
|
||||
return {
|
||||
margin: 0,
|
||||
padding: 0,
|
||||
listStyle: 'none',
|
||||
background: token.colorBgContainer,
|
||||
background: actionsBg,
|
||||
borderTop: `${token.lineWidth}px ${token.lineType} ${colorBorderSecondary}`,
|
||||
display: 'flex',
|
||||
borderRadius: `0 0 ${token.borderRadiusLG}px ${token.borderRadiusLG}px `,
|
||||
...clearFix(),
|
||||
|
||||
'& > li': {
|
||||
margin: cardActionsLiMargin,
|
||||
margin: actionsLiMargin,
|
||||
color: token.colorTextDescription,
|
||||
textAlign: 'center',
|
||||
|
||||
@ -231,6 +243,7 @@ const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
colorBorderSecondary,
|
||||
boxShadowTertiary,
|
||||
cardPaddingBase,
|
||||
extraColor,
|
||||
} = token;
|
||||
|
||||
return {
|
||||
@ -250,7 +263,7 @@ const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
[`${componentCls}-extra`]: {
|
||||
// https://stackoverflow.com/a/22429853/3040605
|
||||
marginInlineStart: 'auto',
|
||||
color: '',
|
||||
color: extraColor,
|
||||
fontWeight: 'normal',
|
||||
fontSize: token.fontSize,
|
||||
},
|
||||
@ -332,14 +345,14 @@ const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
|
||||
// ============================== Size ==============================
|
||||
const genCardSizeStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
const { componentCls, cardPaddingSM, cardHeadHeightSM } = token;
|
||||
const { componentCls, cardPaddingSM, headerHeightSM, headerFontSizeSM } = token;
|
||||
|
||||
return {
|
||||
[`${componentCls}-small`]: {
|
||||
[`> ${componentCls}-head`]: {
|
||||
minHeight: cardHeadHeightSM,
|
||||
minHeight: headerHeightSM,
|
||||
padding: `0 ${cardPaddingSM}px`,
|
||||
fontSize: token.fontSize,
|
||||
fontSize: headerFontSizeSM,
|
||||
|
||||
[`> ${componentCls}-head-wrapper`]: {
|
||||
[`> ${componentCls}-extra`]: {
|
||||
@ -355,7 +368,7 @@ const genCardSizeStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
[`${componentCls}-small${componentCls}-contain-tabs`]: {
|
||||
[`> ${componentCls}-head`]: {
|
||||
[`${componentCls}-head-title, ${componentCls}-extra`]: {
|
||||
minHeight: cardHeadHeightSM,
|
||||
minHeight: headerHeightSM,
|
||||
paddingTop: 0,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
@ -366,24 +379,34 @@ const genCardSizeStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
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.
|
||||
});
|
||||
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.
|
||||
});
|
||||
|
||||
return [
|
||||
// Style
|
||||
genCardStyle(cardToken),
|
||||
return [
|
||||
// Style
|
||||
genCardStyle(cardToken),
|
||||
|
||||
// Size
|
||||
genCardSizeStyle(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,
|
||||
}),
|
||||
);
|
||||
|
@ -468,6 +468,240 @@ 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"
|
||||
|
@ -468,6 +468,240 @@ 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"
|
||||
|
7
components/carousel/demo/component-token.md
Normal file
7
components/carousel/demo/component-token.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
Component Token Debug.
|
||||
|
||||
## en-US
|
||||
|
||||
Component Token Debug.
|
41
components/carousel/demo/component-token.tsx
Normal file
41
components/carousel/demo/component-token.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
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>
|
||||
);
|
@ -23,6 +23,7 @@ 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
|
||||
|
||||
|
@ -24,6 +24,7 @@ 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
|
||||
|
||||
|
@ -1,11 +1,13 @@
|
||||
import { resetComponent } from '../../style';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { resetComponent } from '../../style';
|
||||
|
||||
export interface ComponentToken {
|
||||
dotWidth: number;
|
||||
dotHeight: number;
|
||||
/** @deprecated Use `dotActiveWidth` instead. */
|
||||
dotWidthActive: number;
|
||||
dotActiveWidth: number;
|
||||
}
|
||||
|
||||
interface CarouselToken extends FullToken<'Carousel'> {
|
||||
@ -233,7 +235,7 @@ const genCarouselStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
},
|
||||
|
||||
'&.slick-active': {
|
||||
width: token.dotWidthActive,
|
||||
width: token.dotActiveWidth,
|
||||
|
||||
'& button': {
|
||||
background: token.colorBgContainer,
|
||||
@ -342,9 +344,17 @@ export default genComponentStyleHook(
|
||||
genCarouselRtlStyle(carouselToken),
|
||||
];
|
||||
},
|
||||
() => {
|
||||
const dotActiveWidth = 24;
|
||||
|
||||
return {
|
||||
dotWidth: 16,
|
||||
dotHeight: 3,
|
||||
dotWidthActive: dotActiveWidth,
|
||||
dotActiveWidth,
|
||||
};
|
||||
},
|
||||
{
|
||||
dotWidth: 16,
|
||||
dotHeight: 3,
|
||||
dotWidthActive: 24,
|
||||
deprecatedTokens: [['dotWidthActive', 'dotActiveWidth']],
|
||||
},
|
||||
);
|
||||
|
@ -5,9 +5,9 @@ import { fireEvent, render } from '../../../tests/utils';
|
||||
import Collapse from '../../collapse';
|
||||
import Input from '../../input';
|
||||
import Table from '../../table';
|
||||
import Checkbox from '../index';
|
||||
import type { CheckboxValueType } from '../Group';
|
||||
import type { CheckboxGroupProps } from '../index';
|
||||
import Checkbox from '../index';
|
||||
|
||||
describe('CheckboxGroup', () => {
|
||||
mountTest(Checkbox.Group);
|
||||
@ -167,13 +167,20 @@ describe('CheckboxGroup', () => {
|
||||
it('should work when checkbox is wrapped by other components', () => {
|
||||
const { container } = render(
|
||||
<Checkbox.Group>
|
||||
<Collapse bordered={false}>
|
||||
<Collapse.Panel key="test panel" header="test panel">
|
||||
<div>
|
||||
<Checkbox value="1">item</Checkbox>
|
||||
</div>
|
||||
</Collapse.Panel>
|
||||
</Collapse>
|
||||
<Collapse
|
||||
items={[
|
||||
{
|
||||
key: 'test panel',
|
||||
label: 'test panel',
|
||||
children: (
|
||||
<div>
|
||||
<Checkbox value="1">item</Checkbox>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
bordered={false}
|
||||
/>
|
||||
</Checkbox.Group>,
|
||||
);
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
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';
|
||||
@ -20,6 +21,7 @@ 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;
|
||||
/** 手风琴效果 */
|
||||
@ -36,6 +38,9 @@ export interface CollapseProps {
|
||||
ghost?: boolean;
|
||||
size?: SizeType;
|
||||
collapsible?: CollapsibleType;
|
||||
/**
|
||||
* @deprecated use `items` instead
|
||||
*/
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
@ -125,7 +130,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: CollapseProps & { key: React.Key } = {
|
||||
const childProps: Omit<CollapseProps, 'items'> & { key: React.Key } = {
|
||||
...omit(child.props, ['disabled']),
|
||||
key,
|
||||
collapsible: collapsible ?? (disabled ? 'disabled' : undefined),
|
||||
|
@ -1,8 +1,8 @@
|
||||
import classNames from 'classnames';
|
||||
import RcCollapse from 'rc-collapse';
|
||||
import * as React from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import warning from '../_util/warning';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
|
||||
export type CollapsibleType = 'header' | 'icon' | 'disabled';
|
||||
|
||||
@ -21,6 +21,7 @@ export interface CollapsePanelProps {
|
||||
collapsible?: CollapsibleType;
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((props, ref) => {
|
||||
warning(
|
||||
!('disabled' in props),
|
||||
|
@ -1420,7 +1420,7 @@ exports[`renders components/collapse/demo/noarrow.tsx extend context correctly 1
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-no-arrow"
|
||||
class="ant-collapse-item"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
|
@ -1339,7 +1339,7 @@ exports[`renders components/collapse/demo/noarrow.tsx correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="ant-collapse-item ant-collapse-no-arrow"
|
||||
class="ant-collapse-item"
|
||||
>
|
||||
<div
|
||||
aria-disabled="false"
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CollapseProps } from 'antd';
|
||||
import { Collapse } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import React from 'react';
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
@ -9,18 +8,24 @@ const text = `
|
||||
it can be found as a welcome guest in many households across the world.
|
||||
`;
|
||||
|
||||
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>
|
||||
);
|
||||
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} />;
|
||||
|
||||
export default App;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CollapseProps } from 'antd';
|
||||
import { Collapse } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import React from 'react';
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
@ -9,24 +8,30 @@ const text = `
|
||||
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 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>
|
||||
);
|
||||
return <Collapse items={items} defaultActiveKey={['1']} onChange={onChange} />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CollapseProps } from 'antd';
|
||||
import { Collapse } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import React from 'react';
|
||||
|
||||
const text = (
|
||||
<p style={{ paddingLeft: 24 }}>
|
||||
@ -10,18 +9,24 @@ const text = (
|
||||
</p>
|
||||
);
|
||||
|
||||
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>
|
||||
);
|
||||
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']} />;
|
||||
|
||||
export default App;
|
||||
|
@ -1,7 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Collapse, Space } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import React from 'react';
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
@ -11,21 +9,38 @@ const text = `
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Space direction="vertical">
|
||||
<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>
|
||||
<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>,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Space>
|
||||
);
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React from 'react';
|
||||
import { CaretRightOutlined } from '@ant-design/icons';
|
||||
import type { CollapseProps } from 'antd';
|
||||
import { Collapse, theme } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import type { CSSProperties } from 'react';
|
||||
import React from 'react';
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
@ -10,6 +10,27 @@ const text = `
|
||||
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();
|
||||
|
||||
@ -26,17 +47,8 @@ const App: React.FC = () => {
|
||||
defaultActiveKey={['1']}
|
||||
expandIcon={({ isActive }) => <CaretRightOutlined rotate={isActive ? 90 : 0} />}
|
||||
style={{ background: token.colorBgContainer }}
|
||||
>
|
||||
<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>
|
||||
items={getItems(panelStyle)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
import React, { useState } from 'react';
|
||||
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,23 +33,35 @@ 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}
|
||||
>
|
||||
<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>
|
||||
items={items}
|
||||
/>
|
||||
<br />
|
||||
<span>Expand Icon Position: </span>
|
||||
<Select value={expandIconPosition} style={{ margin: '0 8px' }} onChange={onPositionChange}>
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CollapseProps } from 'antd';
|
||||
import { Collapse } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import React from 'react';
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
@ -9,18 +8,24 @@ const text = `
|
||||
it can be found as a welcome guest in many households across the world.
|
||||
`;
|
||||
|
||||
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>
|
||||
);
|
||||
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} />;
|
||||
|
||||
export default App;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CollapseProps } from 'antd';
|
||||
import { Collapse } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import React from 'react';
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
@ -9,28 +8,38 @@ const text = `
|
||||
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}>
|
||||
<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>
|
||||
);
|
||||
return <Collapse onChange={onChange} items={items} />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CollapseProps } from 'antd';
|
||||
import { Collapse } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import React from 'react';
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
@ -9,21 +8,26 @@ const text = `
|
||||
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}>
|
||||
<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>
|
||||
);
|
||||
return <Collapse defaultActiveKey={['1']} onChange={onChange} items={items} />;
|
||||
};
|
||||
|
||||
export default App;
|
||||
|
@ -1,7 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Collapse, Divider } from 'antd';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
import React from 'react';
|
||||
|
||||
const text = `
|
||||
A dog is a type of domesticated animal.
|
||||
@ -12,23 +10,19 @@ const text = `
|
||||
const App: React.FC = () => (
|
||||
<>
|
||||
<Divider orientation="left">Default Size</Divider>
|
||||
<Collapse>
|
||||
<Panel header="This is default size panel header" key="1">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
<Collapse
|
||||
items={[{ key: '1', label: 'This is default size panel header', children: <p>{text}</p> }]}
|
||||
/>
|
||||
<Divider orientation="left">Small Size</Divider>
|
||||
<Collapse size="small">
|
||||
<Panel header="This is small size panel header" key="1">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
<Collapse
|
||||
size="small"
|
||||
items={[{ key: '1', label: 'This is small size panel header', children: <p>{text}</p> }]}
|
||||
/>
|
||||
<Divider orientation="left">Large Size</Divider>
|
||||
<Collapse size="large">
|
||||
<Panel header="This is large size panel header" key="1">
|
||||
<p>{text}</p>
|
||||
</Panel>
|
||||
</Collapse>
|
||||
<Collapse
|
||||
size="large"
|
||||
items={[{ key: '1', label: 'This is large size panel header', children: <p>{text}</p> }]}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
|
@ -13,6 +13,49 @@ 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 -->
|
||||
@ -44,9 +87,12 @@ A content area which can be collapsed and expanded.
|
||||
| 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=">= 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) |
|
||||
|
@ -14,6 +14,49 @@ 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 -->
|
||||
@ -45,9 +88,12 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*sir-TK0HkWcAAA
|
||||
| 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=">= 5.6.0 请使用 items 方式配置面板."></Alert>
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| collapsible | 是否可折叠或指定可折叠触发区域 | `header` \| `icon` \| `disabled` | - | 4.9.0 (icon: 4.24.0) |
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { resetComponent, resetIcon } from '../../style';
|
||||
import { genCollapseMotion } from '../../style/motion';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { resetComponent, resetIcon } from '../../style';
|
||||
|
||||
export interface ComponentToken {}
|
||||
|
||||
@ -39,6 +39,7 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
|
||||
marginSM,
|
||||
paddingSM,
|
||||
paddingLG,
|
||||
paddingXS,
|
||||
motionDurationSlow,
|
||||
fontSizeIcon,
|
||||
} = token;
|
||||
@ -73,6 +74,7 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
|
||||
flexWrap: 'nowrap',
|
||||
alignItems: 'flex-start',
|
||||
padding: collapseHeaderPadding,
|
||||
paddingInlineStart: paddingSM,
|
||||
color: colorTextHeading,
|
||||
lineHeight,
|
||||
cursor: 'pointer',
|
||||
@ -92,6 +94,8 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
paddingInlineEnd: marginSM,
|
||||
// Arrow offset
|
||||
marginInlineStart: padding - paddingSM,
|
||||
},
|
||||
|
||||
[`${componentCls}-arrow`]: {
|
||||
@ -125,12 +129,6 @@ export const genBaseStyle: GenerateStyle<CollapseToken> = (token) => {
|
||||
cursor: 'pointer',
|
||||
},
|
||||
},
|
||||
|
||||
[`&${componentCls}-no-arrow`]: {
|
||||
[`> ${componentCls}-header`]: {
|
||||
paddingInlineStart: paddingSM,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[`${componentCls}-content`]: {
|
||||
@ -151,6 +149,12 @@ 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,
|
||||
@ -164,9 +168,12 @@ 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`]: {
|
||||
|
@ -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, useEffect, useRef, useState } from 'react';
|
||||
import React, { useContext, useRef, useState } from 'react';
|
||||
import genPurePanel from '../_util/PurePanel';
|
||||
import type { ConfigConsumerProps } from '../config-provider/context';
|
||||
import { ConfigContext } from '../config-provider/context';
|
||||
@ -44,6 +44,7 @@ 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'];
|
||||
}
|
||||
@ -71,6 +72,7 @@ const ColorPicker: CompoundedComponent = (props) => {
|
||||
styles,
|
||||
onFormatChange,
|
||||
onChange,
|
||||
onClear,
|
||||
onOpenChange,
|
||||
getPopupContainer,
|
||||
autoAdjustOverflow = true,
|
||||
@ -121,8 +123,9 @@ const ColorPicker: CompoundedComponent = (props) => {
|
||||
onChange?.(color, color.toHexString());
|
||||
};
|
||||
|
||||
const handleClear = (clear: boolean) => {
|
||||
setColorCleared(clear);
|
||||
const handleClear = () => {
|
||||
setColorCleared(true);
|
||||
onClear?.();
|
||||
};
|
||||
|
||||
const handleChangeComplete = () => {
|
||||
@ -150,12 +153,6 @@ const ColorPicker: CompoundedComponent = (props) => {
|
||||
onFormatChange,
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (colorCleared) {
|
||||
setPopupOpen(false);
|
||||
}
|
||||
}, [colorCleared]);
|
||||
|
||||
return wrapSSR(
|
||||
<Popover
|
||||
style={styles?.popup}
|
||||
|
@ -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?: (clear?: boolean) => void;
|
||||
onClear?: () => void;
|
||||
}
|
||||
|
||||
const ColorPickerPanel: FC<ColorPickerPanelProps> = (props) => {
|
||||
@ -36,7 +36,7 @@ const ColorPickerPanel: FC<ColorPickerPanelProps> = (props) => {
|
||||
value={color}
|
||||
onChange={(clearColor) => {
|
||||
onChange?.(clearColor);
|
||||
onClear?.(true);
|
||||
onClear?.();
|
||||
}}
|
||||
{...injectProps}
|
||||
/>
|
||||
|
@ -102,16 +102,16 @@ describe('ColorPicker', () => {
|
||||
expect(container.querySelector('.ant-color-picker')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('Should allowClear work', async () => {
|
||||
const { container } = render(<ColorPicker allowClear />);
|
||||
it('Should allowClear and onClear work', async () => {
|
||||
const onClear = jest.fn();
|
||||
const { container } = render(<ColorPicker allowClear onClear={onClear} />);
|
||||
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,12 +119,6 @@ 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' },
|
||||
});
|
||||
|
@ -3,14 +3,13 @@ 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;
|
||||
@ -48,36 +47,39 @@ 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>
|
||||
{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>
|
||||
<Collapse defaultActiveKey={activeKeys} ghost items={items} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -37,19 +37,20 @@ 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
|
||||
|
||||
|
@ -38,19 +38,20 @@ 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
|
||||
|
||||
|
@ -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"
|
||||
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -19007,11 +19007,8 @@ 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>
|
||||
@ -19134,7 +19131,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"
|
||||
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -19153,11 +19150,8 @@ 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>
|
||||
@ -19285,7 +19279,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"
|
||||
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-disabled config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -19305,11 +19299,8 @@ 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>
|
||||
@ -19432,7 +19423,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"
|
||||
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"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -19452,11 +19443,8 @@ 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>
|
||||
@ -19584,7 +19572,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"
|
||||
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -19603,11 +19591,8 @@ 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>
|
||||
@ -19730,7 +19715,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"
|
||||
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -19749,11 +19734,8 @@ 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>
|
||||
@ -19881,7 +19863,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"
|
||||
class="config-select config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -19900,11 +19882,8 @@ 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>
|
||||
@ -20027,7 +20006,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"
|
||||
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -20046,11 +20025,8 @@ 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>
|
||||
@ -20178,7 +20154,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"
|
||||
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -20197,11 +20173,8 @@ 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>
|
||||
@ -20324,7 +20297,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"
|
||||
class="config-select config-select-sm config-pagination-options-size-changer config-select-single config-select-show-arrow config-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="config-select-selector"
|
||||
@ -20343,11 +20316,8 @@ 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>
|
||||
@ -20475,7 +20445,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"
|
||||
class="ant-select ant-pagination-options-size-changer ant-select-single ant-select-show-arrow ant-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
@ -20494,11 +20464,8 @@ 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>
|
||||
@ -20621,7 +20588,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"
|
||||
class="ant-select ant-select-sm ant-pagination-options-size-changer ant-select-single ant-select-show-arrow ant-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
@ -20640,11 +20607,8 @@ 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>
|
||||
@ -20772,7 +20736,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"
|
||||
class="ant-select prefix-Pagination-options-size-changer ant-select-single ant-select-show-arrow ant-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
@ -20791,11 +20755,8 @@ 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>
|
||||
@ -20918,7 +20879,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"
|
||||
class="ant-select ant-select-sm prefix-Pagination-options-size-changer ant-select-single ant-select-show-arrow ant-select-show-search"
|
||||
>
|
||||
<div
|
||||
class="ant-select-selector"
|
||||
@ -20937,11 +20898,8 @@ 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>
|
||||
|
53
components/config-provider/__tests__/button.test.tsx
Normal file
53
components/config-provider/__tests__/button.test.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
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);
|
||||
});
|
||||
});
|
@ -6,8 +6,9 @@ import mountTest from '../../../tests/shared/mountTest';
|
||||
import { fireEvent, render } from '../../../tests/utils';
|
||||
import Button from '../../button';
|
||||
import Input from '../../input';
|
||||
import Table from '../../table';
|
||||
import Select from '../../select';
|
||||
import Space from '../../space';
|
||||
import Table from '../../table';
|
||||
|
||||
describe('ConfigProvider', () => {
|
||||
mountTest(() => (
|
||||
@ -123,4 +124,78 @@ 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;');
|
||||
});
|
||||
});
|
||||
|
@ -9,4 +9,27 @@ 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: {} });
|
||||
});
|
||||
});
|
||||
|
@ -49,7 +49,9 @@ describe('ConfigProvider.Theme', () => {
|
||||
expect(canUseDom()).toBeFalsy();
|
||||
|
||||
ConfigProvider.config({
|
||||
theme: {},
|
||||
theme: {
|
||||
infoColor: 'red',
|
||||
},
|
||||
});
|
||||
|
||||
expect(errorSpy).toHaveBeenCalledWith(
|
||||
|
@ -1,11 +1,13 @@
|
||||
import * as React from 'react';
|
||||
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 { RenderEmptyHandler } from './defaultRenderEmpty';
|
||||
import type { SizeType } from './SizeContext';
|
||||
import type { RenderEmptyHandler } from './defaultRenderEmpty';
|
||||
|
||||
export const defaultIconPrefixCls = 'anticon';
|
||||
|
||||
@ -34,6 +36,15 @@ 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 {
|
||||
@ -58,6 +69,10 @@ 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;
|
||||
@ -71,6 +86,7 @@ export interface ConfigConsumerProps {
|
||||
select?: {
|
||||
showSearch?: boolean;
|
||||
};
|
||||
button?: ButtonConfig;
|
||||
}
|
||||
|
||||
const defaultGetPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {
|
||||
|
@ -63,21 +63,26 @@ 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 `size`, ref [Space](/components/space) | { size: `small` \| `middle` \| `large` \| `number` } | - | 4.1.0 |
|
||||
| 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 |
|
||||
| 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() `4.13.0+`
|
||||
### ConfigProvider.config()
|
||||
|
||||
Setting `Modal`、`Message`、`Notification` rootPrefixCls.
|
||||
Setting `Modal`、`Message`、`Notification` static config. Not work on hooks.
|
||||
|
||||
```ts
|
||||
ConfigProvider.config({
|
||||
prefixCls: 'ant', // 4.13.0+
|
||||
iconPrefixCls: 'anticon', // 4.17.0+
|
||||
prefixCls: 'ant',
|
||||
iconPrefixCls: 'anticon',
|
||||
|
||||
// 5.6.0+
|
||||
// Please use hooks version first
|
||||
theme: { token: { colorPrimary: 'red' } },
|
||||
});
|
||||
```
|
||||
|
||||
|
@ -14,9 +14,11 @@ 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,
|
||||
@ -86,6 +88,7 @@ const PASSED_PROPS: Exclude<keyof ConfigConsumerProps, 'rootPrefixCls' | 'getPre
|
||||
'pagination',
|
||||
'form',
|
||||
'select',
|
||||
'button',
|
||||
];
|
||||
|
||||
export interface ConfigProviderProps {
|
||||
@ -121,6 +124,10 @@ 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 */
|
||||
@ -128,6 +135,7 @@ export interface ConfigProviderProps {
|
||||
popupMatchSelectWidth?: boolean;
|
||||
popupOverflow?: PopupOverflow;
|
||||
theme?: ThemeConfig;
|
||||
button?: ButtonConfig;
|
||||
}
|
||||
|
||||
interface ProviderChildrenProps extends ConfigProviderProps {
|
||||
@ -138,6 +146,7 @@ interface ProviderChildrenProps extends ConfigProviderProps {
|
||||
export const defaultPrefixCls = 'ant';
|
||||
let globalPrefixCls: string;
|
||||
let globalIconPrefixCls: string;
|
||||
let globalTheme: ThemeConfig;
|
||||
|
||||
function getGlobalPrefixCls() {
|
||||
return globalPrefixCls || defaultPrefixCls;
|
||||
@ -147,11 +156,15 @@ 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 }) => {
|
||||
}: Pick<ConfigProviderProps, 'prefixCls' | 'iconPrefixCls'> & { theme?: Theme | ThemeConfig }) => {
|
||||
if (prefixCls !== undefined) {
|
||||
globalPrefixCls = prefixCls;
|
||||
}
|
||||
@ -160,7 +173,16 @@ const setGlobalConfig = ({
|
||||
}
|
||||
|
||||
if (theme) {
|
||||
registerTheme(getGlobalPrefixCls(), 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;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -179,6 +201,7 @@ export const globalConfig = () => ({
|
||||
// Fallback to default prefixCls
|
||||
return getGlobalPrefixCls();
|
||||
},
|
||||
getTheme: () => globalTheme,
|
||||
});
|
||||
|
||||
const ProviderChildren: React.FC<ProviderChildrenProps> = (props) => {
|
||||
|
@ -64,21 +64,26 @@ 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 的 `size`,参考 [Space](/components/space-cn) | { size: `small` \| `middle` \| `large` \| `number` } | - | 4.1.0 |
|
||||
| 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 |
|
||||
| theme | 设置主题,参考 [定制主题](/docs/react/customize-theme-cn) | - | - | 5.0.0 |
|
||||
| virtual | 设置 `false` 时关闭虚拟滚动 | boolean | - | 4.3.0 |
|
||||
|
||||
### ConfigProvider.config() `4.13.0+`
|
||||
### ConfigProvider.config()
|
||||
|
||||
设置 `Modal`、`Message`、`Notification` rootPrefixCls。
|
||||
设置 `Modal`、`Message`、`Notification` 静态方法配置,只会对非 hooks 的静态方法调用生效。
|
||||
|
||||
```ts
|
||||
ConfigProvider.config({
|
||||
prefixCls: 'ant', // 4.13.0+
|
||||
iconPrefixCls: 'anticon', // 4.17.0+
|
||||
prefixCls: 'ant',
|
||||
iconPrefixCls: 'anticon',
|
||||
|
||||
// 5.6.0+
|
||||
// 请优先考虑使用 hooks 版本
|
||||
theme: { token: { colorPrimary: 'red' } },
|
||||
});
|
||||
```
|
||||
|
||||
|
@ -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,4 +295,21 @@ 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);
|
||||
});
|
||||
});
|
||||
|
@ -30,7 +30,20 @@
|
||||
"previousCentury": "Last century",
|
||||
"nextCentury": "Next century",
|
||||
"shortWeekDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
|
||||
"shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
|
||||
"shortMonths": [
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec"
|
||||
]
|
||||
},
|
||||
"timePickerLocale": {
|
||||
"placeholder": "Select time"
|
||||
|
@ -385,6 +385,427 @@ 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
|
||||
|
@ -353,6 +353,395 @@ 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
|
||||
|
7
components/descriptions/demo/component-token.md
Normal file
7
components/descriptions/demo/component-token.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
Component Token Debug.
|
||||
|
||||
## en-US
|
||||
|
||||
Component Token Debug.
|
73
components/descriptions/demo/component-token.tsx
Normal file
73
components/descriptions/demo/component-token.tsx
Normal file
@ -0,0 +1,73 @@
|
||||
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;
|
@ -23,6 +23,7 @@ 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
|
||||
|
||||
|
@ -24,6 +24,7 @@ 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
|
||||
|
||||
|
@ -1,28 +1,23 @@
|
||||
import type { CSSObject } from '@ant-design/cssinjs';
|
||||
import { resetComponent, textEllipsis } from '../../style';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { resetComponent, textEllipsis } from '../../style';
|
||||
|
||||
interface DescriptionsToken extends FullToken<'Descriptions'> {
|
||||
descriptionsTitleMarginBottom: number;
|
||||
descriptionsExtraColor: string;
|
||||
descriptionItemPaddingBottom: number;
|
||||
descriptionsDefaultPadding: string;
|
||||
descriptionsBg: string;
|
||||
descriptionsMiddlePadding: string;
|
||||
descriptionsSmallPadding: string;
|
||||
descriptionsItemLabelColonMarginRight: number;
|
||||
descriptionsItemLabelColonMarginLeft: number;
|
||||
/** 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'> {}
|
||||
|
||||
const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
|
||||
const {
|
||||
componentCls,
|
||||
descriptionsSmallPadding,
|
||||
descriptionsDefaultPadding,
|
||||
descriptionsMiddlePadding,
|
||||
descriptionsBg,
|
||||
} = token;
|
||||
const { componentCls, labelBg } = token;
|
||||
return {
|
||||
[`&${componentCls}-bordered`]: {
|
||||
[`${componentCls}-view`]: {
|
||||
@ -33,7 +28,7 @@ const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
|
||||
},
|
||||
},
|
||||
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
|
||||
padding: descriptionsDefaultPadding,
|
||||
padding: `${token.padding}px ${token.paddingLG}px`,
|
||||
borderInlineEnd: `${token.lineWidth}px ${token.lineType} ${token.colorSplit}`,
|
||||
'&:last-child': {
|
||||
borderInlineEnd: 'none',
|
||||
@ -41,7 +36,7 @@ const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
|
||||
},
|
||||
[`${componentCls}-item-label`]: {
|
||||
color: token.colorTextSecondary,
|
||||
backgroundColor: descriptionsBg,
|
||||
backgroundColor: labelBg,
|
||||
'&::after': {
|
||||
display: 'none',
|
||||
},
|
||||
@ -54,26 +49,26 @@ const genBorderedStyle = (token: DescriptionsToken): CSSObject => {
|
||||
},
|
||||
[`&${componentCls}-middle`]: {
|
||||
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
|
||||
padding: descriptionsMiddlePadding,
|
||||
padding: `${token.paddingSM}px ${token.paddingLG}px`,
|
||||
},
|
||||
},
|
||||
[`&${componentCls}-small`]: {
|
||||
[`${componentCls}-item-label, ${componentCls}-item-content`]: {
|
||||
padding: descriptionsSmallPadding,
|
||||
padding: `${token.paddingXS}px ${token.padding}px`,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: DescriptionsToken) => {
|
||||
const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token) => {
|
||||
const {
|
||||
componentCls,
|
||||
descriptionsExtraColor,
|
||||
descriptionItemPaddingBottom,
|
||||
descriptionsItemLabelColonMarginRight,
|
||||
descriptionsItemLabelColonMarginLeft,
|
||||
descriptionsTitleMarginBottom,
|
||||
extraColor,
|
||||
itemPaddingBottom,
|
||||
colonMarginRight,
|
||||
colonMarginLeft,
|
||||
titleMarginBottom,
|
||||
} = token;
|
||||
return {
|
||||
[componentCls]: {
|
||||
@ -85,7 +80,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: Descripti
|
||||
[`${componentCls}-header`]: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
marginBottom: descriptionsTitleMarginBottom,
|
||||
marginBottom: titleMarginBottom,
|
||||
},
|
||||
[`${componentCls}-title`]: {
|
||||
...textEllipsis,
|
||||
@ -97,7 +92,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: Descripti
|
||||
},
|
||||
[`${componentCls}-extra`]: {
|
||||
marginInlineStart: 'auto',
|
||||
color: descriptionsExtraColor,
|
||||
color: extraColor,
|
||||
fontSize: token.fontSize,
|
||||
},
|
||||
[`${componentCls}-view`]: {
|
||||
@ -110,7 +105,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: Descripti
|
||||
},
|
||||
[`${componentCls}-row`]: {
|
||||
'> th, > td': {
|
||||
paddingBottom: descriptionItemPaddingBottom,
|
||||
paddingBottom: itemPaddingBottom,
|
||||
},
|
||||
'&:last-child': {
|
||||
borderBottom: 'none',
|
||||
@ -127,7 +122,7 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: Descripti
|
||||
content: '":"',
|
||||
position: 'relative',
|
||||
top: -0.5, // magic for position
|
||||
marginInline: `${descriptionsItemLabelColonMarginLeft}px ${descriptionsItemLabelColonMarginRight}px`,
|
||||
marginInline: `${colonMarginLeft}px ${colonMarginRight}px`,
|
||||
},
|
||||
|
||||
[`&${componentCls}-item-no-colon::after`]: {
|
||||
@ -182,28 +177,18 @@ const genDescriptionStyles: GenerateStyle<DescriptionsToken> = (token: Descripti
|
||||
};
|
||||
};
|
||||
// ============================== Export ==============================
|
||||
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)];
|
||||
});
|
||||
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,
|
||||
}),
|
||||
);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import classNames from 'classnames';
|
||||
import * as React from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import warning from '../_util/warning';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
|
||||
import useStyle from './style';
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user