mirror of
https://github.com/ant-design/ant-design.git
synced 2026-02-18 15:22:28 +08:00
Compare commits
136 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
733d58deb1 | ||
|
|
84ee56f708 | ||
|
|
cb72cb2bbd | ||
|
|
e2998063e5 | ||
|
|
253b45eceb | ||
|
|
51ec7e39a3 | ||
|
|
b62b81958b | ||
|
|
9f2089c638 | ||
|
|
2d6a8b4c67 | ||
|
|
59de115d60 | ||
|
|
d47f9d212a | ||
|
|
9744ab6501 | ||
|
|
356ead5919 | ||
|
|
7232733134 | ||
|
|
84b072e585 | ||
|
|
08e39ba2e4 | ||
|
|
89e50e2994 | ||
|
|
92fa568f48 | ||
|
|
d447eeb26e | ||
|
|
4eefc49e8f | ||
|
|
787cd94125 | ||
|
|
a2d8659014 | ||
|
|
973305dc85 | ||
|
|
65063943f0 | ||
|
|
8b8021083e | ||
|
|
b15a2f2bfc | ||
|
|
470e8a8e0a | ||
|
|
c656603493 | ||
|
|
7af1cc616b | ||
|
|
eb218e80c6 | ||
|
|
c9f7f5d8e6 | ||
|
|
1f39811047 | ||
|
|
32b89e6d87 | ||
|
|
6da1ad1c67 | ||
|
|
c3cf0ded65 | ||
|
|
cf6e9c8b6e | ||
|
|
5ee92d3dc0 | ||
|
|
e2e3331ffe | ||
|
|
fec2132073 | ||
|
|
b87dbc91ae | ||
|
|
300ec22f33 | ||
|
|
766ae3b320 | ||
|
|
e2d7e689e5 | ||
|
|
4384984c38 | ||
|
|
3701f0a330 | ||
|
|
f0189fd36f | ||
|
|
d1d2400d2d | ||
|
|
8c60848d67 | ||
|
|
73adedbfab | ||
|
|
e6c4123a84 | ||
|
|
b96c10ae1b | ||
|
|
d3d3358ca7 | ||
|
|
0f06598bd8 | ||
|
|
b6b96d2d1d | ||
|
|
01264592a7 | ||
|
|
ddf70283ed | ||
|
|
06d78e663b | ||
|
|
8b1f79c1f5 | ||
|
|
313d534f2b | ||
|
|
0528d9ce42 | ||
|
|
419316e066 | ||
|
|
83f329eb24 | ||
|
|
6a53ed7ad0 | ||
|
|
8ef0a514bc | ||
|
|
4424dec28f | ||
|
|
eb205575a1 | ||
|
|
13c5801ac1 | ||
|
|
aa0a90fdd5 | ||
|
|
05f9362891 | ||
|
|
ab9edc3698 | ||
|
|
15982625b5 | ||
|
|
2f304d1e27 | ||
|
|
15c7e68149 | ||
|
|
88f363aa8e | ||
|
|
7b30c801cf | ||
|
|
cd87b4f59b | ||
|
|
0129115efb | ||
|
|
20f183cf6f | ||
|
|
2e9abf0097 | ||
|
|
4e9af18e76 | ||
|
|
97b7180616 | ||
|
|
68497323d5 | ||
|
|
af465eb0b1 | ||
|
|
7d27bedd9b | ||
|
|
8a75f60ce2 | ||
|
|
fd90c1b1cf | ||
|
|
3fa9d45dd5 | ||
|
|
6c7f161063 | ||
|
|
244ad743e3 | ||
|
|
5fc3618aad | ||
|
|
4d05229782 | ||
|
|
110c8b2e33 | ||
|
|
72c6fefc79 | ||
|
|
84b6bab8ab | ||
|
|
3b4809dede | ||
|
|
db17128186 | ||
|
|
ce43007de4 | ||
|
|
786dfc0339 | ||
|
|
c150885f5c | ||
|
|
6f6868f7d5 | ||
|
|
0dd5617205 | ||
|
|
ba5f9fe2f8 | ||
|
|
4020f658a8 | ||
|
|
97b89138ad | ||
|
|
d70de6c6e6 | ||
|
|
8567e55ed0 | ||
|
|
cc51d06117 | ||
|
|
9acde83991 | ||
|
|
5c2e6e3651 | ||
|
|
ed127e9418 | ||
|
|
2d237d0e93 | ||
|
|
ad7fdb01d5 | ||
|
|
27c942a00b | ||
|
|
9965d96259 | ||
|
|
9b72caf77e | ||
|
|
8026366676 | ||
|
|
c7f2760007 | ||
|
|
8a4a83ace7 | ||
|
|
1092660e0a | ||
|
|
d34ab00717 | ||
|
|
a09b9dd820 | ||
|
|
6a7945d2fd | ||
|
|
4cba8b85d5 | ||
|
|
53cbceb7db | ||
|
|
4621bd9f5e | ||
|
|
3062dc6aba | ||
|
|
6dcd6e2dc1 | ||
|
|
14f8279aea | ||
|
|
24a65de3c5 | ||
|
|
bb74803437 | ||
|
|
42c5a2fb21 | ||
|
|
34a7faa082 | ||
|
|
9680481546 | ||
|
|
f5c00a8607 | ||
|
|
a038583155 | ||
|
|
bd9444fa35 |
@@ -3,7 +3,8 @@
|
||||
(navigator.languages.includes('zh') || navigator.languages.includes('zh-CN')) &&
|
||||
/-cn\/?$/.test(window.location.pathname) &&
|
||||
!['ant-design.gitee.io', 'ant-design.antgroup.com'].includes(window.location.hostname) &&
|
||||
!window.location.host.includes('surge')
|
||||
!window.location.host.includes('surge') &&
|
||||
window.location.hostname !== 'localhost'
|
||||
) {
|
||||
const ANTD_DOT_NOT_SHOW_MIRROR_MODAL = 'ANT_DESIGN_DO_NOT_OPEN_MIRROR_MODAL';
|
||||
|
||||
|
||||
@@ -1,183 +0,0 @@
|
||||
import * as React from 'react';
|
||||
import { Button, Flex, Typography } from 'antd';
|
||||
import { createStyles, css, useTheme } from 'antd-style';
|
||||
import classNames from 'classnames';
|
||||
import { Link, useLocation } from 'dumi';
|
||||
|
||||
import useLocale from '../../../hooks/useLocale';
|
||||
import SiteContext from '../../../theme/slots/SiteContext';
|
||||
import * as utils from '../../../theme/utils';
|
||||
import GroupMaskLayer from './GroupMaskLayer';
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
slogan: '助力设计开发者「更灵活」地搭建出「更美」的产品,让用户「快乐工作」~',
|
||||
start: '开始使用',
|
||||
designLanguage: '设计语言',
|
||||
},
|
||||
en: {
|
||||
slogan:
|
||||
'Help designers/developers building beautiful products more flexible and working with happiness',
|
||||
start: 'Getting Started',
|
||||
designLanguage: 'Design Language',
|
||||
},
|
||||
};
|
||||
|
||||
const useStyle = () => {
|
||||
const { isMobile } = React.useContext(SiteContext);
|
||||
return createStyles(({ token }) => ({
|
||||
titleBase: css`
|
||||
h1& {
|
||||
font-family: AliPuHui, ${token.fontFamily};
|
||||
}
|
||||
`,
|
||||
title: isMobile
|
||||
? css`
|
||||
h1& {
|
||||
margin-bottom: ${token.margin}px;
|
||||
font-weight: normal;
|
||||
font-size: ${token.fontSizeHeading1 + 2}px;
|
||||
line-height: ${token.lineHeightHeading2};
|
||||
}
|
||||
`
|
||||
: css`
|
||||
h1& {
|
||||
margin-bottom: ${token.marginMD}px;
|
||||
font-weight: 900;
|
||||
font-size: 68px;
|
||||
}
|
||||
`,
|
||||
btnWrap: css`
|
||||
margin-bottom: ${token.marginXL}px;
|
||||
`,
|
||||
layer: css`
|
||||
text-align: center;
|
||||
padding-top: ${token.marginFar - 16}px;
|
||||
padding-bottom: ${token.marginFarSM}px;
|
||||
`,
|
||||
mobileBg: css`
|
||||
width: 100%;
|
||||
`,
|
||||
videoWrap: css`
|
||||
height: 320px;
|
||||
background-color: #77c6ff;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
`,
|
||||
video: css`
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
`,
|
||||
bg: css`
|
||||
flex: auto;
|
||||
background-repeat: repeat-x;
|
||||
background-size: auto 100%;
|
||||
`,
|
||||
bg1: css`
|
||||
background-image: url(https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*6d50SboraPIAAAAAAAAAAAAAARQnAQ);
|
||||
background-position: 100% 0;
|
||||
`,
|
||||
bg2: css`
|
||||
background-image: url(https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*8ILtRrQlVDMAAAAAAAAAAAAAARQnAQ);
|
||||
background-position: 0 0;
|
||||
margin-inline-start: -1px;
|
||||
`,
|
||||
logoWrap: css`
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
`,
|
||||
bgImg: css`
|
||||
position: absolute;
|
||||
width: 240px;
|
||||
`,
|
||||
}))();
|
||||
};
|
||||
|
||||
const Banner: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const [locale] = useLocale(locales);
|
||||
const { pathname, search } = useLocation();
|
||||
const token = useTheme();
|
||||
const { styles } = useStyle();
|
||||
const { isMobile } = React.useContext(SiteContext);
|
||||
const isZhCN = utils.isZhCN(pathname);
|
||||
return (
|
||||
<>
|
||||
{/* Banner Placeholder Motion */}
|
||||
{isMobile ? (
|
||||
<img
|
||||
className={styles.mobileBg}
|
||||
src="https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*JmlaR5oQn3MAAAAAAAAAAAAADrJ8AQ/original"
|
||||
alt=""
|
||||
/>
|
||||
) : (
|
||||
<div className={classNames(styles.videoWrap)}>
|
||||
<div className={classNames(styles.bg, styles.bg1)} />
|
||||
<video className={styles.video} autoPlay muted loop>
|
||||
<source
|
||||
type="video/webm"
|
||||
src="https://mdn.alipayobjects.com/huamei_iwk9zp/afts/file/A*uYT7SZwhJnUAAAAAAAAAAAAADgCCAQ"
|
||||
/>
|
||||
<source
|
||||
type="video/mp4"
|
||||
src="https://gw.alipayobjects.com/mdn/rms_08e378/afts/file/A*XYYNQJ3NbmMAAAAAAAAAAAAAARQnAQ"
|
||||
/>
|
||||
</video>
|
||||
<div className={classNames(styles.bg, styles.bg2)} />
|
||||
</div>
|
||||
)}
|
||||
{/* Logo */}
|
||||
<div className={styles.logoWrap}>
|
||||
{/* Image Bottom Right */}
|
||||
<img
|
||||
className={classNames(styles.bgImg)}
|
||||
style={{ right: 0, top: 240 }}
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/b3b8dc41-dce8-471f-9d81-9a0204f27d03.svg"
|
||||
alt="Ant Design"
|
||||
/>
|
||||
<GroupMaskLayer className={styles.layer}>
|
||||
{/* Image Left Top */}
|
||||
<img
|
||||
className={classNames(styles.bgImg)}
|
||||
style={{ left: isMobile ? -120 : 0, top: 0 }}
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/49f963db-b2a8-4f15-857a-270d771a1204.svg"
|
||||
alt="bg"
|
||||
/>
|
||||
{/* Image Right Top */}
|
||||
<img
|
||||
className={classNames(styles.bgImg)}
|
||||
style={{ right: isMobile ? 0 : 120, top: 0 }}
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/e152223c-bcae-4913-8938-54fda9efe330.svg"
|
||||
alt="bg"
|
||||
/>
|
||||
<Typography.Title level={1} className={classNames(styles.titleBase, styles.title)}>
|
||||
Ant Design 5.0
|
||||
</Typography.Title>
|
||||
<Typography.Paragraph
|
||||
style={{
|
||||
fontSize: isMobile ? token.fontSizeHeading5 - 2 : token.fontSizeHeading5,
|
||||
lineHeight: isMobile ? token.lineHeightSM : token.lineHeightHeading5,
|
||||
marginBottom: token.marginMD * 2,
|
||||
padding: isMobile ? `0 ${token.paddingLG + 2}px` : 0,
|
||||
}}
|
||||
>
|
||||
<div>{locale.slogan}</div>
|
||||
</Typography.Paragraph>
|
||||
<Flex gap="middle" className={styles.btnWrap}>
|
||||
<Link to={utils.getLocalizedPathname('/components/overview/', isZhCN, search)}>
|
||||
<Button size="large" type="primary">
|
||||
{locale.start}
|
||||
</Button>
|
||||
</Link>
|
||||
<Link to={utils.getLocalizedPathname('/docs/spec/introduce/', isZhCN, search)}>
|
||||
<Button size="large">{locale.designLanguage}</Button>
|
||||
</Link>
|
||||
</Flex>
|
||||
{children}
|
||||
</GroupMaskLayer>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Banner;
|
||||
@@ -36,12 +36,11 @@ const useStyle = createStyles(({ token, css }) => ({
|
||||
|
||||
export interface ColorPickerProps {
|
||||
id?: string;
|
||||
children?: React.ReactNode;
|
||||
value?: string | Color;
|
||||
onChange?: (value?: Color | string) => void;
|
||||
}
|
||||
|
||||
const DebouncedColorPicker: React.FC<ColorPickerProps> = (props) => {
|
||||
const DebouncedColorPicker: React.FC<React.PropsWithChildren<ColorPickerProps>> = (props) => {
|
||||
const { value: color, children, onChange } = props;
|
||||
const [value, setValue] = useState(color);
|
||||
|
||||
@@ -91,7 +90,7 @@ const ThemeColorPicker: React.FC<ColorPickerProps> = ({ value, onChange, id }) =
|
||||
}, [value]);
|
||||
|
||||
return (
|
||||
<Flex gap="large" align="center" wrap="wrap">
|
||||
<Flex gap="large" align="center" wrap>
|
||||
<Input
|
||||
value={typeof value === 'string' ? value : value?.toHexString()}
|
||||
onChange={(event) => onChange?.(event.target.value)}
|
||||
|
||||
@@ -84,7 +84,7 @@ const ThemePicker: React.FC<ThemePickerProps> = (props) => {
|
||||
const { styles } = useStyle();
|
||||
const [locale] = useLocale(locales);
|
||||
return (
|
||||
<Flex gap="large" wrap="wrap">
|
||||
<Flex gap="large" wrap>
|
||||
{(Object.keys(THEMES) as (keyof typeof THEMES)[]).map<React.ReactNode>((theme, index) => (
|
||||
<Flex vertical gap="small" justify="center" align="center" key={theme}>
|
||||
<label
|
||||
|
||||
@@ -3,11 +3,6 @@ import type { ColorInput } from '@ctrl/tinycolor';
|
||||
import { TinyColor } from '@ctrl/tinycolor';
|
||||
import { createStyles } from 'antd-style';
|
||||
|
||||
interface ColorChunkProps {
|
||||
children?: React.ReactNode;
|
||||
value?: ColorInput;
|
||||
}
|
||||
|
||||
const useStyle = createStyles(({ token, css }) => ({
|
||||
codeSpan: css`
|
||||
padding: 0.2em 0.4em;
|
||||
@@ -26,7 +21,11 @@ const useStyle = createStyles(({ token, css }) => ({
|
||||
`,
|
||||
}));
|
||||
|
||||
const ColorChunk: React.FC<ColorChunkProps> = (props) => {
|
||||
interface ColorChunkProps {
|
||||
value?: ColorInput;
|
||||
}
|
||||
|
||||
const ColorChunk: React.FC<React.PropsWithChildren<ColorChunkProps>> = (props) => {
|
||||
const { styles } = useStyle();
|
||||
const { value, children } = props;
|
||||
|
||||
|
||||
@@ -2,16 +2,20 @@
|
||||
* copied: https://github.com/arvinxx/dumi-theme-antd-style/tree/master/src/builtins/Container
|
||||
*/
|
||||
import * as React from 'react';
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import { Alert } from 'antd';
|
||||
|
||||
import useStyles from './style';
|
||||
|
||||
const Container: FC<{
|
||||
interface ContainerProps {
|
||||
type: 'info' | 'warning' | 'success' | 'error';
|
||||
title?: string;
|
||||
children: ReactNode;
|
||||
}> = ({ type, title, children }) => {
|
||||
}
|
||||
|
||||
const Container: React.FC<React.PropsWithChildren<ContainerProps>> = ({
|
||||
type,
|
||||
title,
|
||||
children,
|
||||
}) => {
|
||||
const { styles, cx } = useStyles();
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import { useIntl } from 'dumi';
|
||||
import { message } from 'antd';
|
||||
import { App } from 'antd';
|
||||
import CopyableIcon from './CopyableIcon';
|
||||
import type { ThemeType } from './index';
|
||||
import type { CategoriesKeys } from './fields';
|
||||
@@ -13,6 +13,7 @@ interface CategoryProps {
|
||||
}
|
||||
|
||||
const Category: React.FC<CategoryProps> = (props) => {
|
||||
const { message } = App.useApp();
|
||||
const { icons, title, newIcons, theme } = props;
|
||||
const intl = useIntl();
|
||||
const [justCopied, setJustCopied] = React.useState<string | null>(null);
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import React from 'react';
|
||||
import { Image } from 'antd';
|
||||
import classNames from 'classnames';
|
||||
import toArray from 'rc-util/lib/Children/toArray';
|
||||
import { Image } from 'antd';
|
||||
|
||||
interface ImagePreviewProps {
|
||||
children: React.ReactNode[];
|
||||
className?: string;
|
||||
/** Do not show padding & background */
|
||||
pure?: boolean;
|
||||
@@ -29,11 +28,22 @@ function isGoodBadImg(imgMeta: any): boolean {
|
||||
function isCompareImg(imgMeta: any): boolean {
|
||||
return isGoodBadImg(imgMeta) || imgMeta.inline;
|
||||
}
|
||||
const ImagePreview: React.FC<ImagePreviewProps> = (props) => {
|
||||
|
||||
interface MateType {
|
||||
className: string;
|
||||
alt: string;
|
||||
description: string;
|
||||
src: string;
|
||||
isGood: boolean;
|
||||
isBad: boolean;
|
||||
inline: boolean;
|
||||
}
|
||||
|
||||
const ImagePreview: React.FC<React.PropsWithChildren<ImagePreviewProps>> = (props) => {
|
||||
const { children, className: rootClassName, pure } = props;
|
||||
const imgs = toArray(children).filter((ele) => ele.type === 'img');
|
||||
|
||||
const imgsMeta = imgs.map((img) => {
|
||||
const imgsMeta = imgs.map<Partial<MateType>>((img) => {
|
||||
const { alt, description, src, className } = img.props;
|
||||
return {
|
||||
className,
|
||||
@@ -107,7 +117,7 @@ const ImagePreview: React.FC<ImagePreviewProps> = (props) => {
|
||||
<div className="preview-image-title">{coverMeta.alt}</div>
|
||||
<div
|
||||
className="preview-image-description"
|
||||
dangerouslySetInnerHTML={{ __html: coverMeta.description }}
|
||||
dangerouslySetInnerHTML={{ __html: coverMeta.description ?? '' }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -7,10 +7,13 @@ type LinkProps = Parameters<typeof Link>[0];
|
||||
|
||||
export interface LocaleLinkProps extends LinkProps {
|
||||
sourceType: 'a' | 'Link';
|
||||
children?: React.ReactNode;
|
||||
}
|
||||
|
||||
const LocaleLink: React.FC<LocaleLinkProps> = ({ sourceType, to, ...props }) => {
|
||||
const LocaleLink: React.FC<React.PropsWithChildren<LocaleLinkProps>> = ({
|
||||
sourceType,
|
||||
to,
|
||||
...props
|
||||
}) => {
|
||||
const Component = sourceType === 'a' ? 'a' : Link;
|
||||
|
||||
const [, localeType] = useLocale();
|
||||
|
||||
@@ -404,8 +404,7 @@ createRoot(document.getElementById('container')).render(<Demo />);
|
||||
dangerouslySetInnerHTML={{ __html: description }}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Flex wrap="wrap" gap="middle" className="code-box-actions">
|
||||
<Flex wrap gap="middle" className="code-box-actions">
|
||||
{showOnlineUrl && (
|
||||
<Tooltip title={<FormattedMessage id="app.demo.online" />}>
|
||||
<a
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import type { FC, ReactNode } from 'react';
|
||||
import React, { Suspense } from 'react';
|
||||
import { Skeleton } from 'antd';
|
||||
import { createStyles } from 'antd-style';
|
||||
@@ -42,13 +41,12 @@ const SandpackFallback = () => {
|
||||
};
|
||||
|
||||
interface SandpackProps {
|
||||
children?: ReactNode;
|
||||
dark?: boolean;
|
||||
autorun?: boolean;
|
||||
dependencies?: string;
|
||||
}
|
||||
|
||||
const Sandpack: FC<SandpackProps> = ({
|
||||
const Sandpack: React.FC<React.PropsWithChildren<SandpackProps>> = ({
|
||||
children,
|
||||
dark,
|
||||
dependencies: extraDeps,
|
||||
|
||||
@@ -11,14 +11,14 @@ const primaryMinBrightness = 70; // 主色推荐最小亮度
|
||||
|
||||
const locales = {
|
||||
cn: {
|
||||
saturation: (s: string) => `饱和度建议不低于${primaryMinSaturation}(现在${s})`,
|
||||
brightness: (b: string) => `亮度建议不低于${primaryMinBrightness}(现在${b})`,
|
||||
saturation: (s: string) => `饱和度建议不低于${primaryMinSaturation}(当前值 ${s})`,
|
||||
brightness: (b: string) => `亮度建议不低于${primaryMinBrightness}(当前值 ${b})`,
|
||||
},
|
||||
en: {
|
||||
saturation: (s: string) =>
|
||||
`Saturation is recommended not to be lower than ${primaryMinSaturation}(currently${s})`,
|
||||
`Saturation is recommended not to be lower than ${primaryMinSaturation} (currently ${s})`,
|
||||
brightness: (b: string) =>
|
||||
`Brightness is recommended not to be lower than ${primaryMinBrightness}(currently${b})`,
|
||||
`Brightness is recommended not to be lower than ${primaryMinBrightness} (currently ${b})`,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@ const ColorPaletteTool: React.FC = () => {
|
||||
text += locale.saturation((s * 100).toFixed(2));
|
||||
}
|
||||
if (b * 100 < primaryMinBrightness) {
|
||||
text += locale.brightness((s * 100).toFixed(2));
|
||||
text += locale.brightness((b * 100).toFixed(2));
|
||||
}
|
||||
}
|
||||
return <span className="color-palette-picker-validation">{text.trim()}</span>;
|
||||
|
||||
@@ -31,7 +31,7 @@ const useStyle = createStyles(({ token, css }) => ({
|
||||
history: css`
|
||||
position: absolute;
|
||||
top: 0;
|
||||
inset-inline-end: 0;
|
||||
inset-inline-end: ${token.marginXS}px;
|
||||
`,
|
||||
|
||||
li: css`
|
||||
|
||||
@@ -2,25 +2,22 @@ import React from 'react';
|
||||
import Icon from '@ant-design/icons';
|
||||
import type { DirectionType } from 'antd/es/config-provider';
|
||||
|
||||
const ltrD =
|
||||
'M448 64l512 0 0 128-128 0 0 768-128 0 0-768-128 0 0 768-128 0 0-448c-123.712 0-224-100.288-224-224s100.288-224 224-224zM64 448l256 224-256 224z';
|
||||
|
||||
const rtlD =
|
||||
'M256 64l512 0 0 128-128 0 0 768-128 0 0-768-128 0 0 768-128 0 0-448c-123.712 0-224-100.288-224-224s100.288-224 224-224zM960 896l-256-224 256-224z';
|
||||
|
||||
interface DirectionIconProps {
|
||||
className?: string;
|
||||
direction?: DirectionType;
|
||||
}
|
||||
|
||||
const DirectionSvg: React.FC<DirectionIconProps> = (props) => {
|
||||
const { direction } = props;
|
||||
return (
|
||||
<svg viewBox="0 0 1024 1024" fill="currentColor">
|
||||
<path d={direction === 'ltr' ? ltrD : rtlD} />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
const DirectionSvg: React.FC<DirectionIconProps> = ({ direction }) => (
|
||||
<svg
|
||||
viewBox="0 0 20 20"
|
||||
width="20"
|
||||
height="20"
|
||||
fill="currentColor"
|
||||
style={{ transform: `scaleX(${direction === 'ltr' ? '1' : '-1'})` }}
|
||||
>
|
||||
<path d="m14.6961816 11.6470802.0841184.0726198 2 2c.2662727.2662727.2904793.682876.0726198.9764816l-.0726198.0841184-2 2c-.2929.2929-.7677.2929-1.0606 0-.2662727-.2662727-.2904793-.682876-.0726198-.9764816l.0726198-.0841184.7196-.7197h-10.6893c-.41421 0-.75-.3358-.75-.75 0-.3796833.28215688-.6934889.64823019-.7431531l.10176981-.0068469h10.6893l-.7196-.7197c-.2929-.2929-.2929-.7677 0-1.0606.2662727-.2662727.682876-.2904793.9764816-.0726198zm-8.1961616-8.6470802c.30667 0 .58246.18671.69635.47146l3.00003 7.50004c.1538.3845-.0333.821-.41784.9749-.38459.1538-.82107-.0333-.9749-.4179l-.81142-2.0285h-2.98445l-.81142 2.0285c-.15383.3846-.59031.5717-.9749.4179-.38458-.1539-.57165-.5904-.41781-.9749l3-7.50004c.1139-.28475.38968-.47146.69636-.47146zm8.1961616 1.14705264.0841184.07261736 2 2c.2662727.26626364.2904793.68293223.0726198.97654222l-.0726198.08411778-2 2c-.2929.29289-.7677.29289-1.0606 0-.2662727-.26626364-.2904793-.68293223-.0726198-.97654222l.0726198-.08411778.7196-.7196675h-3.6893c-.4142 0-.75-.3357925-.75-.7500025 0-.3796925.2821653-.69348832.6482323-.74315087l.1017677-.00684663h3.6893l-.7196-.7196725c-.2929-.29289-.2929-.76777 0-1.06066.2662727-.26626364.682876-.29046942.9764816-.07261736zm-8.1961616 1.62238736-.89223 2.23056h1.78445z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const DirectionIcon: React.FC<DirectionIconProps> = (props) => (
|
||||
<Icon {...props} component={() => <DirectionSvg direction={props.direction} />} />
|
||||
|
||||
@@ -5,13 +5,14 @@ import nprogress from 'nprogress';
|
||||
|
||||
export interface LinkProps {
|
||||
to: string | { pathname?: string; search?: string; hash?: string };
|
||||
children?: React.ReactNode;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
onClick?: MouseEventHandler;
|
||||
}
|
||||
|
||||
const Link = forwardRef<HTMLAnchorElement, LinkProps>((props, ref) => {
|
||||
nprogress.configure({ showSpinner: false });
|
||||
|
||||
const Link = forwardRef<HTMLAnchorElement, React.PropsWithChildren<LinkProps>>((props, ref) => {
|
||||
const { to, children, ...rest } = props;
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const navigate = useNavigate();
|
||||
|
||||
@@ -1,77 +1,86 @@
|
||||
import { css, Global } from '@emotion/react';
|
||||
import React from 'react';
|
||||
import { css, Global } from '@emotion/react';
|
||||
import { useTheme } from 'antd-style';
|
||||
import { updateCSS } from 'rc-util/lib/Dom/dynamicCSS';
|
||||
|
||||
export default () => {
|
||||
const { anchorTop } = useTheme();
|
||||
|
||||
React.useInsertionEffect(() => {
|
||||
updateCSS(`@layer global, antd;`, 'site-global', {
|
||||
prepend: true,
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Global
|
||||
styles={css`
|
||||
body,
|
||||
div,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ul,
|
||||
ol,
|
||||
li,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
pre,
|
||||
code,
|
||||
form,
|
||||
fieldset,
|
||||
legend,
|
||||
input,
|
||||
textarea,
|
||||
p,
|
||||
blockquote,
|
||||
th,
|
||||
td,
|
||||
hr,
|
||||
button,
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
@layer global {
|
||||
body,
|
||||
div,
|
||||
dl,
|
||||
dt,
|
||||
dd,
|
||||
ul,
|
||||
ol,
|
||||
li,
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
pre,
|
||||
code,
|
||||
form,
|
||||
fieldset,
|
||||
legend,
|
||||
input,
|
||||
textarea,
|
||||
p,
|
||||
blockquote,
|
||||
th,
|
||||
td,
|
||||
hr,
|
||||
button,
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
menu,
|
||||
nav,
|
||||
section {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
list-style: none;
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
img {
|
||||
vertical-align: middle;
|
||||
border-style: none;
|
||||
}
|
||||
|
||||
[id] {
|
||||
scroll-margin-top: ${anchorTop}px;
|
||||
}
|
||||
[id] {
|
||||
scroll-margin-top: ${anchorTop}px;
|
||||
}
|
||||
|
||||
[data-prefers-color='dark'] {
|
||||
color-scheme: dark;
|
||||
}
|
||||
[data-prefers-color='dark'] {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
[data-prefers-color='light'] {
|
||||
color-scheme: light;
|
||||
}
|
||||
`}
|
||||
[data-prefers-color='light'] {
|
||||
color-scheme: light;
|
||||
}
|
||||
}
|
||||
`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -221,7 +221,8 @@ const RoutesPlugin = (api: IApi) => {
|
||||
const matchRegex = /<style data-type="antd-cssinjs">([\S\s]+?)<\/style>/;
|
||||
const matchList = file.content.match(matchRegex) || [];
|
||||
|
||||
let antdStyle = '';
|
||||
// Init to order the `@layer`
|
||||
let antdStyle = '@layer global, antd;';
|
||||
|
||||
matchList.forEach((text) => {
|
||||
file.content = file.content.replace(text, '');
|
||||
|
||||
@@ -8,7 +8,9 @@ import { useRouteMeta, useTabMeta } from 'dumi';
|
||||
const useStyle = createStyles(({ token, css }) => {
|
||||
const { antCls } = token;
|
||||
return {
|
||||
toc: css`
|
||||
anchorToc: css`
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: unset;
|
||||
${antCls}-anchor {
|
||||
${antCls}-anchor-link-title {
|
||||
font-size: ${token.fontSizeSM}px;
|
||||
@@ -120,8 +122,8 @@ const DocAnchor: React.FC<DocAnchorProps> = ({ showDebug, debugDemos = [] }) =>
|
||||
return (
|
||||
<section className={styles.tocWrapper}>
|
||||
<Anchor
|
||||
className={styles.toc}
|
||||
affix={false}
|
||||
className={styles.anchorToc}
|
||||
targetOffset={token.anchorTop}
|
||||
showInkInFixed
|
||||
items={anchorItems.map<AnchorLinkItemProps>(renderAnchorItem)}
|
||||
|
||||
@@ -5,10 +5,9 @@ import type { IntersectionObserverProps } from 'react-intersection-observer';
|
||||
|
||||
type InViewSuspenseProps = Pick<IntersectionObserverProps, 'delay'> & {
|
||||
fallback?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
};
|
||||
|
||||
const InViewSuspense: React.FC<InViewSuspenseProps> = ({
|
||||
const InViewSuspense: React.FC<React.PropsWithChildren<InViewSuspenseProps>> = ({
|
||||
children,
|
||||
fallback = <Skeleton.Input active size="small" />,
|
||||
delay = 200,
|
||||
|
||||
@@ -124,7 +124,7 @@ const HeaderNavigation: React.FC<NavigationProps> = (props) => {
|
||||
activeMenuItem = 'docs/resources';
|
||||
}
|
||||
|
||||
let additional: MenuProps['items'];
|
||||
let additional: MenuProps['items'] = [];
|
||||
|
||||
const additionalItems: MenuProps['items'] = [
|
||||
{
|
||||
@@ -215,50 +215,16 @@ const HeaderNavigation: React.FC<NavigationProps> = (props) => {
|
||||
},
|
||||
isZhCN
|
||||
? {
|
||||
key: 'mirror',
|
||||
label: (
|
||||
<a href="https://ant-design.antgroup.com" target="_blank" rel="noreferrer">
|
||||
国内镜像
|
||||
</a>
|
||||
),
|
||||
key: 'mirror',
|
||||
children: [
|
||||
{
|
||||
label: (
|
||||
<a href="https://ant-design.antgroup.com" target="_blank" rel="noreferrer">
|
||||
官方镜像
|
||||
</a>
|
||||
),
|
||||
icon: (
|
||||
<img
|
||||
alt="logo"
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg"
|
||||
width={16}
|
||||
style={{ verticalAlign: 'text-bottom' }}
|
||||
/>
|
||||
),
|
||||
key: 'antgroup',
|
||||
},
|
||||
{
|
||||
label: (
|
||||
<a href="https://ant-design.gitee.io" target="_blank" rel="noreferrer">
|
||||
Gitee 镜像
|
||||
</a>
|
||||
),
|
||||
icon: (
|
||||
<img
|
||||
alt="gitee"
|
||||
src="https://gw.alipayobjects.com/zos/bmw-prod/9e91e124-9bab-4113-b500-301412f6b370.svg"
|
||||
width={16}
|
||||
style={{ verticalAlign: 'text-bottom' }}
|
||||
/>
|
||||
),
|
||||
key: 'gitee',
|
||||
},
|
||||
],
|
||||
}
|
||||
: null,
|
||||
...(additional ?? []),
|
||||
];
|
||||
].filter(Boolean);
|
||||
|
||||
return (
|
||||
<Menu
|
||||
|
||||
@@ -54,12 +54,11 @@ const useStyle = createStyles(({ token, css }) => {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.nav-search-wrapper {
|
||||
display: flex;
|
||||
flex: auto;
|
||||
}
|
||||
|
||||
.dumi-default-search-bar {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
flex: auto;
|
||||
margin: 0;
|
||||
border-inline-start: 1px solid rgba(0, 0, 0, 0.06);
|
||||
|
||||
> svg {
|
||||
@@ -70,6 +69,7 @@ const useStyle = createStyles(({ token, css }) => {
|
||||
> input {
|
||||
height: 22px;
|
||||
border: 0;
|
||||
max-width: calc(100vw - 768px);
|
||||
|
||||
&:focus {
|
||||
box-shadow: none;
|
||||
@@ -85,6 +85,9 @@ const useStyle = createStyles(({ token, css }) => {
|
||||
background-color: rgba(150, 150, 150, 0.06);
|
||||
border-color: rgba(100, 100, 100, 0.2);
|
||||
border-radius: ${token.borderRadiusSM}px;
|
||||
position: static;
|
||||
top: unset;
|
||||
transform: unset;
|
||||
}
|
||||
|
||||
.dumi-default-search-popover {
|
||||
@@ -103,16 +106,15 @@ const useStyle = createStyles(({ token, css }) => {
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
column-gap: ${token.paddingSM}px;
|
||||
padding-inline-end: ${token.padding}px;
|
||||
|
||||
> * {
|
||||
flex: none;
|
||||
margin: 0;
|
||||
&:last-child {
|
||||
margin-inline-end: 40px;
|
||||
}
|
||||
}
|
||||
`,
|
||||
dataDirectionIcon: css`
|
||||
width: 16px;
|
||||
width: 20px;
|
||||
`,
|
||||
popoverMenu: {
|
||||
width: 300,
|
||||
@@ -405,11 +407,11 @@ const Header: React.FC = () => {
|
||||
<Col {...colProps[0]}>
|
||||
<Logo {...sharedProps} location={location} />
|
||||
</Col>
|
||||
<Col {...colProps[1]} className={styles.menuRow}>
|
||||
<div className="nav-search-wrapper">
|
||||
<Col {...colProps[1]}>
|
||||
<div className={styles.menuRow}>
|
||||
<DumiSearchBar />
|
||||
{!isMobile && menu}
|
||||
</div>
|
||||
{!isMobile && menu}
|
||||
</Col>
|
||||
</Row>
|
||||
</header>
|
||||
|
||||
@@ -40,7 +40,12 @@ export default defineConfig({
|
||||
},
|
||||
extraRehypePlugins: [rehypeAntd],
|
||||
extraRemarkPlugins: [remarkAntd],
|
||||
metas: [{ name: 'theme-color', content: '#1677ff' }],
|
||||
metas: [
|
||||
{ name: 'theme-color', content: '#1677ff' },
|
||||
{ name: 'build-time', content: Date.now().toString() },
|
||||
// https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables
|
||||
{ name: 'build-hash', content: process.env.GITHUB_SHA ?? 'unknown' },
|
||||
],
|
||||
analytics: {
|
||||
ga_v2: 'UA-72788897-1',
|
||||
},
|
||||
|
||||
3
.github/dependabot.yml
vendored
3
.github/dependabot.yml
vendored
@@ -9,7 +9,6 @@ updates:
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
versioning-strategy: increase
|
||||
groups:
|
||||
rc-component-patch:
|
||||
dependency-type: "production"
|
||||
@@ -28,6 +27,8 @@ updates:
|
||||
update-types: ["major"]
|
||||
ignore:
|
||||
- dependency-name: "@ant-design/cssinjs"
|
||||
- dependency-name: "dayjs"
|
||||
versions: ["1.x"]
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
|
||||
4
.github/workflows/mock-project-build.yml
vendored
4
.github/workflows/mock-project-build.yml
vendored
@@ -60,5 +60,9 @@ jobs:
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
notice-types: 'dingding'
|
||||
# Exit directly with non-zero to trigger the failure logic of ci-notice.
|
||||
ci: |
|
||||
echo "❌ CI Mock Project Build Failed"
|
||||
exit 1
|
||||
dingding-token: ${{ secrets.DINGDING_BOT_COLLABORATOR_TOKEN }}
|
||||
notice-title: 'CI Mock Project Build Failed'
|
||||
|
||||
1
.github/workflows/preview-build.yml
vendored
1
.github/workflows/preview-build.yml
vendored
@@ -73,7 +73,6 @@ jobs:
|
||||
id: site
|
||||
run: npm run site
|
||||
env:
|
||||
SITE_ENV: development
|
||||
NODE_OPTIONS: "--max_old_space_size=4096"
|
||||
|
||||
- name: upload site artifact
|
||||
|
||||
4
.github/workflows/size-limit.yml
vendored
4
.github/workflows/size-limit.yml
vendored
@@ -17,13 +17,15 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v1
|
||||
- name: size-limit
|
||||
uses: ant-design/size-limit-action@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
package_manager: yarn
|
||||
package_manager: bun
|
||||
build_script: dist
|
||||
env:
|
||||
NODE_OPTIONS: "--max_old_space_size=4096"
|
||||
PRODUCTION_ONLY: 1
|
||||
NO_DUP_CHECK: 1
|
||||
CI_JOB_NUMBER: 1
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -299,7 +299,7 @@ jobs:
|
||||
lib
|
||||
|
||||
- name: zip builds
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
if: github.repository == 'ant-design/ant-design' && github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
env:
|
||||
ALI_OSS_AK_ID: ${{ secrets.ALI_OSS_AK_ID }}
|
||||
ALI_OSS_AK_SECRET: ${{ secrets.ALI_OSS_AK_SECRET }}
|
||||
|
||||
@@ -54,5 +54,6 @@
|
||||
"5.14.0": ["https://github.com/ant-design/ant-design/issues/47354"],
|
||||
"5.15.0": ["https://github.com/ant-design/ant-design/pull/47504#issuecomment-1980459433"],
|
||||
">= 5.16.0 <= 5.16.1": ["https://github.com/ant-design/ant-design/issues/48200"],
|
||||
"5.16.3": ["https://github.com/ant-design/ant-design/issues/48568"]
|
||||
"5.16.3": ["https://github.com/ant-design/ant-design/issues/48568"],
|
||||
"5.17.1": ["https://github.com/ant-design/ant-design/issues/48913"]
|
||||
}
|
||||
|
||||
@@ -16,6 +16,84 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.17.3
|
||||
|
||||
`2024-05-19`
|
||||
|
||||
- 🐞 MISC: Fix some components throws `findDOMNode` warning in React 18.3.0. [#48958](https://github.com/ant-design/ant-design/pull/48958)
|
||||
- 🐞 Fix Button that `fontSize` token not works. [#48893](https://github.com/ant-design/ant-design/pull/48893) [@wanpan11](https://github.com/wanpan11)
|
||||
- 💄 Fix Pagination size-changer element style. [#48931](https://github.com/ant-design/ant-design/pull/48931) [@wanpan11](https://github.com/wanpan11)
|
||||
|
||||
## 5.17.2
|
||||
|
||||
`2024-05-14`
|
||||
|
||||
- 🐞 MISC: Fix `lib` bundle mistake deps on the `es` module which break the build progress. [#48914](https://github.com/ant-design/ant-design/pull/48914)
|
||||
|
||||
## 5.17.1
|
||||
|
||||
`2024-05-14`
|
||||
|
||||
- 🐞 Optimize the internal logic of the Form, fix the problem that antd takes too long time to build in Next.js. [react-component/async-validator#9](https://github.com/react-component/async-validator/pull/9)
|
||||
- 🐞 Fix visually not centered when Tooltip content is only one character. [#48890](https://github.com/ant-design/ant-design/pull/48890) [@kiner-tang](https://github.com/kiner-tang)
|
||||
- Button
|
||||
- 🐞 Fix hover and active styles not differentiating when Button `type="text"`and `type="danger"` are used together. [#48876](https://github.com/ant-design/ant-design/pull/48876) [@LonelySnowman](https://github.com/LonelySnowman)
|
||||
- Fix issue where some components throw findDOMNode warnings
|
||||
- 🐞 Fix Button throwing `findDOMNode` warning. [#48830](https://github.com/ant-design/ant-design/pull/48830) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 Fix Badge throwing `findDOMNode` warnings. [#48878](https://github.com/ant-design/ant-design/pull/48878) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 Fix Alert throwing `findDOMNode` warnings. [#48868](https://github.com/ant-design/ant-design/pull/48868) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 Fix FloatButton.BackTop throwing `findDOMNode` warnings. [#48865](https://github.com/ant-design/ant-design/pull/48865) [@wanpan11](https://github.com/wanpan11)
|
||||
- 💄 Add className to internal component Spin given by Drawer to prevent internal Spin styles from overriding user-passed Spin styles. [#48857](https://github.com/ant-design/ant-design/pull/48857) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 💄 Fix missing bottom border when Card `size="small"`. [#48787](https://github.com/ant-design/ant-design/pull/48787) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 Fix AutoComplete `tagRender` not working for maxTag and clicking on an edge triggering unexpected closure of the layer. [#48798](https://github.com/ant-design/ant-design/pull/48798)
|
||||
- RTL
|
||||
- 💄 Fix Button's missing icon order and margins under RTL. [#48821](https://github.com/ant-design/ant-design/pull/48821)
|
||||
- TypeScript
|
||||
- 🤖 Fix Cascader redundant generalization issue. [#48879](https://github.com/ant-design/ant-design/pull/48879) [@crazyair](https://github.com/crazyair)
|
||||
|
||||
## 5.17.0
|
||||
|
||||
`2024-05-03`
|
||||
|
||||
- 🔥🔥🔥 `@ant-design/cssinjs` StyleProvider supports configuring `layer` to unified downgrade CSS priority. After the downgrade, the style of antd will always be lower than the default CSS selector priority, so that users can override the style (please be sure to check the browser compatibility of [@layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer#browser_compatibility)), see [full documentation](https://ant.design/docs/react/compatible-style#layer-downgrade) for usage. [#48229](https://github.com/ant-design/ant-design/pull/48229)
|
||||
- 🆕 Carousel supports `arrows` to switching between slides now. [#48542](https://github.com/ant-design/ant-design/pull/48542)
|
||||
- Form
|
||||
- 🛠 Form move dependency from `async-validator` to `@rc-component/async-validator`, fix a bug that `transform` don't check it's return value type. [#48486](https://github.com/ant-design/ant-design/pull/48486) [@crazyair](https://github.com/crazyair)
|
||||
- 🆕 Form add `inlineMargin` token. [#48362](https://github.com/ant-design/ant-design/pull/48362) [@CooperHash](https://github.com/CooperHash)
|
||||
- 🐞 Fix Form `scrollToFirstError` cannot work on Upload. [#48211](https://github.com/ant-design/ant-design/pull/48211) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- Typography
|
||||
- 🆕 Typography.Paragraph could customize `tabIndex` prop for editable and copyable buttons. [#48567](https://github.com/ant-design/ant-design/pull/48567) [@nova1751](https://github.com/nova1751)
|
||||
- 🐞 Fix Typography `editable` will trigger focus unexpectedly on mounting. [#48741](https://github.com/ant-design/ant-design/pull/48741)
|
||||
- DatePicker
|
||||
- 🆕 DatePicker.RangePicker `showTime.disabledTime` supports `info.from` for customize time level limitation. [#48625](https://github.com/ant-design/ant-design/pull/48625)
|
||||
- 🐞 Fix DatePicker hover value flickering issue when closing panel. [#48734](https://github.com/ant-design/ant-design/pull/48734)
|
||||
- Drawer
|
||||
- 🆕 Drawer supports `loading` prop now. [#48563](https://github.com/ant-design/ant-design/pull/48563) [@Enigama](https://github.com/Enigama)
|
||||
- 🐞 Fix Drawer `classNames.wrapper` not working. [#48721](https://github.com/ant-design/ant-design/pull/48721) [@replygirl](https://github.com/replygirl)
|
||||
- Slider
|
||||
- 🐞 Fix Slider tooltip cannot be hidden when `tooltip={{ formatter: null }}`. [#48673](https://github.com/ant-design/ant-design/pull/48673) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 Slider tooltip should not display when `tooltip={{ open: false }}`. [#48708](https://github.com/ant-design/ant-design/pull/48708)
|
||||
- Button
|
||||
- 🆕 Button add `iconPosition` prop to specify icon position. [#47791](https://github.com/ant-design/ant-design/pull/47791) [@GeorgeHcc](https://github.com/GeorgeHcc)
|
||||
- 🆕 Button supports `autoInsertSpace` prop. [#48348](https://github.com/ant-design/ant-design/pull/48348) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 ConfigProvider supports `button.autoInsertSpace` prop and deprecated `autoInsertSpaceInButton` prop. [#48348](https://github.com/ant-design/ant-design/pull/48348) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 TreeSelect supports `onPopScroll` prop now. [#48636](https://github.com/ant-design/ant-design/pull/48636) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🆕 Tabs supports `more={{ .. }}` to customize more dropdown. [#48321](https://github.com/ant-design/ant-design/pull/48321) [@CooperHash](https://github.com/CooperHash)
|
||||
- 🆕 Flex `wrap` could be boolean type now. [#48391](https://github.com/ant-design/ant-design/pull/48391) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 Input.OTP supports `mask` prop. [#48257](https://github.com/ant-design/ant-design/pull/48257) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 Alert supports `id` and `ref` props. [#48336](https://github.com/ant-design/ant-design/pull/48336) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 Upload supports `ref.nativeElenent`. [#48210](https://github.com/ant-design/ant-design/pull/48210) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🐞 Fix List would not rerender when `grid` changed. [#48683](https://github.com/ant-design/ant-design/pull/48683) [@coderz-w](https://github.com/coderz-w)
|
||||
- 🐞 Fix QRCode size cannot fit it's container and remove default padding of `bordered={false}`. [#48194](https://github.com/ant-design/ant-design/pull/48194) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🐞 Fix Table shadow should be show when there are columns where `fixed={false}`. [#1113](https://github.com/react-component/table/pull/1113) [@linxianxi](https://github.com/linxianxi)
|
||||
- 🐞 Fix Progress tooltip wrong distance. [#48686](https://github.com/ant-design/ant-design/pull/48686)
|
||||
- 📖 Table add column-drag sorting demo. [#48434](https://github.com/ant-design/ant-design/pull/48434) [@GeorgeHcc](https://github.com/GeorgeHcc)
|
||||
- TypeScript
|
||||
- 🤖 Optimize Cascader typing. [#48420](https://github.com/ant-design/ant-design/pull/48420) [@crazyair](https://github.com/crazyair)
|
||||
- Locales
|
||||
- 🇯🇵 Fix missing Japanese locale translation. [#48704](https://github.com/ant-design/ant-design/pull/48704) [@edikurniawan-dev](https://github.com/edikurniawan-dev)
|
||||
- 🇮🇩 Fix missing Indonesian locale translation. [#48703](https://github.com/ant-design/ant-design/pull/48703) [@edikurniawan-dev](https://github.com/edikurniawan-dev)
|
||||
|
||||
## 5.16.5
|
||||
|
||||
`2024-04-28`
|
||||
@@ -78,8 +156,8 @@ tag: vVERSION
|
||||
- 💄 Fix Steps in compact theme not show the correct progress style. [#48251](https://github.com/ant-design/ant-design/pull/48251)
|
||||
- 💄 Refactor Tabs and wave-related components CSS duration values with `motionDurationSlow` Component Token. [#48311](https://github.com/ant-design/ant-design/pull/48311) [#48312](https://github.com/ant-design/ant-design/pull/48312) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🇯🇵 Add Transfer missing ja_JP translations. [#48411](https://github.com/ant-design/ant-design/pull/48411) [@Inshiku-Han](https://github.com/Inshiku-Han)
|
||||
- 🌐 Fix Picker ja-JP and ko-KR translations. [#48382](https://github.com/ant-design/ant-design/pull/48382) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🛠 Use constant instead of enumeration to reduce package size. [#48406](https://github.com/ant-design/ant-design/pull/48406) [@kiner-tang](https://github.com/kiner-tang)
|
||||
- 🇯🇵🇰🇷 Fix Picker ja-JP and ko-KR translations. [#48382](https://github.com/ant-design/ant-design/pull/48382) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 📦 Use constant instead of enumeration to reduce package size. [#48406](https://github.com/ant-design/ant-design/pull/48406) [@kiner-tang](https://github.com/kiner-tang)
|
||||
|
||||
## 5.16.1
|
||||
|
||||
|
||||
@@ -15,6 +15,84 @@ tag: vVERSION
|
||||
|
||||
---
|
||||
|
||||
## 5.17.3
|
||||
|
||||
`2024-05-19`
|
||||
|
||||
- 🐞 杂项:修复部分组件在 React 18.3.0 下警告 `findDOMNode` 的问题。[#48958](https://github.com/ant-design/ant-design/pull/48958)
|
||||
- 🐞 修复 Button 字体大小 token 无效的问题。[#48893](https://github.com/ant-design/ant-design/pull/48893) [@wanpan11](https://github.com/wanpan11)
|
||||
- 💄 修复 Pagination 组件跳转选择元素样式问题。[#48931](https://github.com/ant-design/ant-design/pull/48931) [@wanpan11](https://github.com/wanpan11)
|
||||
|
||||
## 5.17.2
|
||||
|
||||
`2024-05-14`
|
||||
|
||||
- 🐞 MISC: 修复 `lib` 产物错误引入 `es` 依赖导致构建错误的问题。[#48914](https://github.com/ant-design/ant-design/pull/48914)
|
||||
|
||||
## 5.17.1
|
||||
|
||||
`2024-05-14`
|
||||
|
||||
- 🐞 优化 Form 组件底层逻辑,修复了 antd 在 Next.js 中构建时间太长的问题。[react-component/async-validator#9](https://github.com/react-component/async-validator/pull/9)
|
||||
- 🐞 修复 Tooltip 内容只有一个字符时视觉不居中的问题。[#48890](https://github.com/ant-design/ant-design/pull/48890) [@kiner-tang](https://github.com/kiner-tang)
|
||||
- Button
|
||||
- 🐞 修复 Button `type="text"` 和`type="danger"` 同时使用时 hover 和 active 样式没有区分的问题。[#48876](https://github.com/ant-design/ant-design/pull/48876) [@LonelySnowman](https://github.com/LonelySnowman)
|
||||
- 修复部分组件抛出 findDOMNode 警告的问题
|
||||
- 🐞 修复 Button 抛出 `findDOMNode` 警告的问题。[#48830](https://github.com/ant-design/ant-design/pull/48830) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 修复 Badge 抛出 `findDOMNode` 警告的问题。[#48878](https://github.com/ant-design/ant-design/pull/48878) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 修复 Alert 抛出 `findDOMNode` 警告的问题。[#48868](https://github.com/ant-design/ant-design/pull/48868) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 修复 FloatButton.BackTop 抛出 `findDOMNode` 警告的问题。[#48865](https://github.com/ant-design/ant-design/pull/48865) [@wanpan11](https://github.com/wanpan11)
|
||||
- 💄 给 Drawer 的内部组件 Spin 添加 className,防止内部 Spin 样式覆盖用户传入的 Spin 样式。[#48857](https://github.com/ant-design/ant-design/pull/48857) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 💄 修复 Card `size="small"` 时下边框丢失的问题。[#48787](https://github.com/ant-design/ant-design/pull/48787) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🐞 AutoComplete 修复 `tagRender` 对 maxTag 无效的问题和点击边缘会触发弹层意外关闭的问题。[#48798](https://github.com/ant-design/ant-design/pull/48798)
|
||||
- RTL
|
||||
- 💄 修复 Button 在 RTL 下的图标顺序和边距缺失问题。[#48821](https://github.com/ant-design/ant-design/pull/48821)
|
||||
- TypeScript
|
||||
- 🤖 修复 Cascader 多余泛型问题。[#48879](https://github.com/ant-design/ant-design/pull/48879) [@crazyair](https://github.com/crazyair)
|
||||
|
||||
## 5.17.0
|
||||
|
||||
`2024-05-03`
|
||||
|
||||
- 🔥🔥🔥 `@ant-design/cssinjs` StyleProvider 支持配置 `layer` 统一降级 默认 CSS 优先级。经过降权后,antd 的样式将始终低于默认的 CSS 选择器优先级,以便于用户进行样式覆盖(请务必注意检查 [@layer](https://developer.mozilla.org/en-US/docs/Web/CSS/@layer#browser_compatibility) 浏览器兼容性),详情可见[文档](https://ant.design/docs/react/compatible-style-cn#layer-%E9%99%8D%E6%9D%83)。[#48229](https://github.com/ant-design/ant-design/pull/48229)
|
||||
- 🆕 Carousel 现在支持 `arrows` 来开启箭头切换功能。[#48542](https://github.com/ant-design/ant-design/pull/48542)
|
||||
- Form
|
||||
- 🛠 Form 依赖的 `async-validator` 替换为 `@rc-component/async-validator`,并修复 `transform` 没有自动检测返回值类型的问题。[#48486](https://github.com/ant-design/ant-design/pull/48486) [@crazyair](https://github.com/crazyair)
|
||||
- 🆕 Form 新增 `inlineMargin` token。[#48362](https://github.com/ant-design/ant-design/pull/48362) [@CooperHash](https://github.com/CooperHash)
|
||||
- 🐞 修复 Form 下出现错误时无法滚动到 Upload 组件的问题。[#48211](https://github.com/ant-design/ant-design/pull/48211) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- Typography
|
||||
- 🆕 Typography.Paragraph 的编辑、复制按钮允许修改 `tableIndex`。[#48567](https://github.com/ant-design/ant-design/pull/48567) [@nova1751](https://github.com/nova1751)
|
||||
- 🐞 修复 Typography 开启 `editable` 时会意外触发 focus 行为的问题。[#48741](https://github.com/ant-design/ant-design/pull/48741)
|
||||
- DatePicker
|
||||
- 🆕 DatePicker.RangePicker `showTime.disabledTime` 支持 `info.from` 以供时间维度的自定义限制能力。[#48625](https://github.com/ant-design/ant-design/pull/48625)
|
||||
- 🐞 修复 DatePicker 关闭时回填 hover 值闪烁的问题。[#48734](https://github.com/ant-design/ant-design/pull/48734)
|
||||
- Drawer
|
||||
- 🆕 Drawer 新增 `loading` 属性。[#48563](https://github.com/ant-design/ant-design/pull/48563) [@Enigama](https://github.com/Enigama)
|
||||
- 🐞 修复 Drawer 不支持 `classNames.wrapper` 的问题。[#48721](https://github.com/ant-design/ant-design/pull/48721) [@replygirl](https://github.com/replygirl)
|
||||
- Slider
|
||||
- 🐞 修复 Slider `tooltip={{ open: false }}` 时提示框未正确隐藏的问题。[#48708](https://github.com/ant-design/ant-design/pull/48708)
|
||||
- 🐞 修复 Slider `tooltip={{ formatter: null }}` 无法隐藏 Tooltip 的问题。[#48673](https://github.com/ant-design/ant-design/pull/48673) [@wanpan11](https://github.com/wanpan11)
|
||||
- Button
|
||||
- 🆕 Button 新增 `iconPosition` 以指定预置图标位置。[#47791](https://github.com/ant-design/ant-design/pull/47791) [@GeorgeHcc](https://github.com/GeorgeHcc)
|
||||
- 🆕 Button 组件支持 `autoInsertSpace` 属性,用来移除两个汉字之间的空格。[#48348](https://github.com/ant-design/ant-design/pull/48348) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 ConfigProvider 组件支持 `button.autoInsertSpace` 属性并废弃 `autoInsertSpaceInButton` 属性。[#48348](https://github.com/ant-design/ant-design/pull/48348) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 TreeSelect 支持 `onPopScroll` 属性。[#48636](https://github.com/ant-design/ant-design/pull/48636) [@wanpan11](https://github.com/wanpan11)
|
||||
- 🆕 Tabs 新增 `more={{ ... }}` 属性以支持自定义下拉菜单的属性。[#48321](https://github.com/ant-design/ant-design/pull/48321) [@CooperHash](https://github.com/CooperHash)
|
||||
- 🆕 Flex 组件 `wrap` 参数支持 boolean 类型。[#48391](https://github.com/ant-design/ant-design/pull/48391) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 Input.OTP 组件支持 `mask` 属性,以自定义遮罩字符。[#48257](https://github.com/ant-design/ant-design/pull/48257) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 Alert 组件支持 `id` 和 `ref` 属性。[#48336](https://github.com/ant-design/ant-design/pull/48336) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 Upload 组件 `ref.nativeElenent` 以支持访问原生元素。[#48210](https://github.com/ant-design/ant-design/pull/48210) [@Wxh16144](https://github.com/Wxh16144)
|
||||
- 🐞 修复 List `grid` 属性值更新后组件未重新渲染的问题。[#48683](https://github.com/ant-design/ant-design/pull/48683) [@coderz-w](https://github.com/coderz-w)
|
||||
- 🐞 修复 Progress tooltip 提示距离太近的问题。[#48686](https://github.com/ant-design/ant-design/pull/48686)
|
||||
- 🐞 修复 QRCode 无法自适应容器大小的问题并移除 `bordered={false}` 时的默认边距。[#48194](https://github.com/ant-design/ant-design/pull/48194) [@thinkasany](https://github.com/thinkasany)
|
||||
- 🐞 修复 Table 组件设置 `fixed={false}` 时的某些特殊情况下未正常显示投影的问题。[#1113](https://github.com/react-component/table/pull/1113) [@linxianxi](https://github.com/linxianxi)
|
||||
- 📖 添加 Table 表格列拖拽排序演示。[#48434](https://github.com/ant-design/ant-design/pull/48434) [@GeorgeHcc](https://github.com/GeorgeHcc)
|
||||
- TypeScript
|
||||
- 🤖 优化 Cascader 属性定义。[#48420](https://github.com/ant-design/ant-design/pull/48420) [@crazyair](https://github.com/crazyair)
|
||||
- 本地化
|
||||
- 🇯🇵 补充日语本地化文案。[#48704](https://github.com/ant-design/ant-design/pull/48704) [@edikurniawan-dev](https://github.com/edikurniawan-dev)
|
||||
- 🇮🇩 补充印尼语本地化文案。[#48703](https://github.com/ant-design/ant-design/pull/48703) [@edikurniawan-dev](https://github.com/edikurniawan-dev)
|
||||
|
||||
## 5.16.5
|
||||
|
||||
`2024-04-28`
|
||||
@@ -77,8 +155,8 @@ tag: vVERSION
|
||||
- 💄 修复 Steps 的进度样式在紧凑模式下不正确的问题。[#48251](https://github.com/ant-design/ant-design/pull/48251)
|
||||
- 💄 重构 Tabs 和波纹样式相关组件的 CSS 过渡时间值,替换为 `motionDurationSlow` Component Token。[#48311](https://github.com/ant-design/ant-design/pull/48311) [#48312](https://github.com/ant-design/ant-design/pull/48312) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🇯🇵 补充 Transfer 的 ja_JP 本地化文案。[#48411](https://github.com/ant-design/ant-design/pull/48411) [@Inshiku-Han](https://github.com/Inshiku-Han)
|
||||
- 🌐 修复 Picker 的 ja_JP 和 ko_KR 本地化文案。[#48382](https://github.com/ant-design/ant-design/pull/48382) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🛠 使用常量替代枚举减小包体积。[#48406](https://github.com/ant-design/ant-design/pull/48406) [@kiner-tang](https://github.com/kiner-tang)
|
||||
- 🇯🇵🇰🇷 修复 Picker 的 ja_JP 和 ko_KR 本地化文案。[#48382](https://github.com/ant-design/ant-design/pull/48382) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 📦 使用常量替代枚举减小包体积。[#48406](https://github.com/ant-design/ant-design/pull/48406) [@kiner-tang](https://github.com/kiner-tang)
|
||||
|
||||
## 5.16.1
|
||||
|
||||
@@ -101,7 +179,7 @@ tag: vVERSION
|
||||
- 🆕 Table 支持 `onScroll` 事件用于监听表单内容滚动。[#47986](https://github.com/ant-design/ant-design/pull/47986)
|
||||
- 🆕 Typography 省略支持展开和收起。[#47264](https://github.com/ant-design/ant-design/pull/47264) [@crazyair](https://github.com/crazyair)
|
||||
- 🆕 ConfigProvider 支持配置 FloatButton.Group 的 `closeIcon` 属性。[#47953](https://github.com/ant-design/ant-design/pull/47953) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🆕 Table 支持配置排序的 `showSorterTooltip.target` 属性.[#47409](https://github.com/ant-design/ant-design/pull/47409) [@Ke1sy](https://github.com/Ke1sy)
|
||||
- 🆕 Table 支持配置排序的 `showSorterTooltip.target` 属性。[#47409](https://github.com/ant-design/ant-design/pull/47409) [@Ke1sy](https://github.com/Ke1sy)
|
||||
- 🆕 Cascader 支持 `optionRender`。[#47727](https://github.com/ant-design/ant-design/pull/47727) [@crazyair](https://github.com/crazyair)
|
||||
- ⌨️ Popover 当 `trigger` 是 `focus` 或 `click` 时能被 ESC 按键所关闭。[#47928](https://github.com/ant-design/ant-design/pull/47928) [@CooperHash](https://github.com/CooperHash)
|
||||
- 🐞 修复 Button 图标位置居中问题。[#48178](https://github.com/ant-design/ant-design/pull/48178) [@momesana](https://github.com/momesana)
|
||||
|
||||
@@ -42,17 +42,6 @@
|
||||
[dumi-url]: https://github.com/umijs/dumi
|
||||
[github-issues-url]: https://new-issue.ant.design
|
||||
|
||||
<!-- Copy-paste in your Readme.md file -->
|
||||
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats?repo_id=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=dark" width="655" height="auto">
|
||||
<img alt="Performance Stats of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=light" width="655" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
<!-- Made with [OSS Insight](https://ossinsight.io/) -->
|
||||
|
||||
</div>
|
||||
|
||||
[](https://ant.design)
|
||||
@@ -166,16 +155,36 @@ $ npm start
|
||||
|
||||
## 🤝 参与共建 [](http://makeapullrequest.com)
|
||||
|
||||
<!-- Copy-paste in your Readme.md file -->
|
||||
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors?repo_id=34526884&limit=30" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors/thumbnail.png?repo_id=34526884&limit=30&image_size=auto&color_scheme=dark" width="655" height="auto">
|
||||
<img alt="Active Contributors of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors/thumbnail.png?repo_id=34526884&limit=30&image_size=auto&color_scheme=light" width="655" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
<!-- Made with [OSS Insight](https://ossinsight.io/) -->
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors?repo_id=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=dark" width="280">
|
||||
<img alt="Top Contributors of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=light" width="280">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats?repo_id=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=dark" width="655" height="auto">
|
||||
<img alt="Performance Stats of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=light" width="655" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-org-active-contributors?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884&image_size=2x3&color_scheme=dark" width="273" height="auto">
|
||||
<img alt="New participants of ant-design - past 28 days" src="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884&image_size=2x3&color_scheme=light" width="273" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
请参考[贡献指南](https://ant.design/docs/react/contributing-cn).
|
||||
|
||||
|
||||
56
README.md
56
README.md
@@ -50,18 +50,6 @@ An enterprise-class UI design language and React UI library.
|
||||
[dumi-image]: https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square
|
||||
[dumi-url]: https://github.com/umijs/dumi
|
||||
[github-issues-url]: https://new-issue.ant.design
|
||||
|
||||
<!-- Copy-paste in your Readme.md file -->
|
||||
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats?repo_id=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=dark" width="655" height="auto">
|
||||
<img alt="Performance Stats of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=light" width="655" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
<!-- Made with [OSS Insight](https://ossinsight.io/) -->
|
||||
|
||||
</div>
|
||||
|
||||
[](https://ant.design)
|
||||
@@ -158,22 +146,42 @@ Open your browser and visit http://127.0.0.1:8001 , see more at [Development](ht
|
||||
|
||||
## 🤝 Contributing [](http://makeapullrequest.com)
|
||||
|
||||
<!-- Copy-paste in your Readme.md file -->
|
||||
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors?repo_id=34526884&limit=30" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors/thumbnail.png?repo_id=34526884&limit=30&image_size=auto&color_scheme=dark" width="655" height="auto">
|
||||
<img alt="Active Contributors of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-recent-active-contributors/thumbnail.png?repo_id=34526884&limit=30&image_size=auto&color_scheme=light" width="655" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
<!-- Made with [OSS Insight](https://ossinsight.io/) -->
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors?repo_id=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=dark" width="280">
|
||||
<img alt="Top Contributors of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-recent-top-contributors/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=light" width="280">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
<td rowspan="2">
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats?repo_id=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=dark" width="655" height="auto">
|
||||
<img alt="Performance Stats of ant-design/ant-design - Last 28 days" src="https://next.ossinsight.io/widgets/official/compose-last-28-days-stats/thumbnail.png?repo_id=34526884&image_size=auto&color_scheme=light" width="655" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="https://next.ossinsight.io/widgets/official/compose-org-active-contributors?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884" target="_blank" style="display: block" align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884&image_size=2x3&color_scheme=dark" width="273" height="auto">
|
||||
<img alt="New participants of ant-design - past 28 days" src="https://next.ossinsight.io/widgets/official/compose-org-active-contributors/thumbnail.png?period=past_28_days&activity=new&owner_id=12101536&repo_ids=34526884&image_size=2x3&color_scheme=light" width="273" height="auto">
|
||||
</picture>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
Let's build a better antd together.
|
||||
|
||||
We welcome all contributions. Please read our [Contributing Guide](https://ant.design/docs/react/contributing) first. You can submit any ideas as [Pull Requests](https://github.com/ant-design/ant-design/pulls) or as [GitHub Issues](https://github.com/ant-design/ant-design/issues). If you'd like to improve code, check out the [Development Instructions](https://github.com/ant-design/ant-design/wiki/Development) and have a good time! :)
|
||||
We warmly invite contributions from everyone. Before you get started, please take a moment to review our [Contributing Guide](https://ant.design/docs/react/contributing). Feel free to share your ideas through [Pull Requests](https://github.com/ant-design/ant-design/pulls) or [GitHub Issues](https://github.com/ant-design/ant-design/issues). If you're interested in enhancing our codebase, explore the [Development Instructions](https://github.com/ant-design/ant-design/wiki/Development) and enjoy your coding journey! :)
|
||||
|
||||
If you are a collaborator, please follow our [Pull Request Principle](https://github.com/ant-design/ant-design/wiki/PR-principle) to create a Pull Request with our [Pull Request Template](https://github.com/ant-design/ant-design/wiki/PR-principle#pull-request-template).
|
||||
For collaborators, adhere to our [Pull Request Principle](https://github.com/ant-design/ant-design/wiki/PR-principle) and utilize our [Pull Request Template](https://github.com/ant-design/ant-design/wiki/PR-principle#pull-request-template) when creating a Pull Request.
|
||||
|
||||
[](https://issuehunt.io/repos/34526884)
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ describe('Wave component', () => {
|
||||
}
|
||||
|
||||
it('work', async () => {
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
const { container, unmount } = render(
|
||||
<Wave>
|
||||
<button type="button">button</button>
|
||||
@@ -95,6 +96,8 @@ describe('Wave component', () => {
|
||||
|
||||
expect(document.querySelector('.ant-wave')).toBeFalsy();
|
||||
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
|
||||
@@ -7,10 +7,11 @@ import * as React from 'react';
|
||||
import KeyCode from 'rc-util/lib/KeyCode';
|
||||
|
||||
interface TransButtonProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
onClick?: (e?: React.MouseEvent<HTMLDivElement>) => void;
|
||||
onClick?: (e?: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
||||
noStyle?: boolean;
|
||||
autoFocus?: boolean;
|
||||
disabled?: boolean;
|
||||
tabIndex?: number;
|
||||
}
|
||||
|
||||
const inlineStyle: React.CSSProperties = {
|
||||
@@ -37,7 +38,7 @@ const TransButton = React.forwardRef<HTMLDivElement, TransButtonProps>((props, r
|
||||
}
|
||||
};
|
||||
|
||||
const { style, noStyle, disabled, ...restProps } = props;
|
||||
const { style, noStyle, disabled, tabIndex = 0, ...restProps } = props;
|
||||
|
||||
let mergedStyle: React.CSSProperties = {};
|
||||
|
||||
@@ -59,7 +60,7 @@ const TransButton = React.forwardRef<HTMLDivElement, TransButtonProps>((props, r
|
||||
return (
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
tabIndex={tabIndex}
|
||||
ref={ref}
|
||||
{...restProps}
|
||||
onKeyDown={onKeyDown}
|
||||
|
||||
@@ -3,6 +3,7 @@ import classNames from 'classnames';
|
||||
import CSSMotion from 'rc-motion';
|
||||
import raf from 'rc-util/lib/raf';
|
||||
import { render, unmount } from 'rc-util/lib/React/render';
|
||||
import { composeRef } from 'rc-util/lib/ref';
|
||||
|
||||
import { TARGET_CLS } from './interface';
|
||||
import type { ShowWaveEffect } from './interface';
|
||||
@@ -20,7 +21,7 @@ export interface WaveEffectProps {
|
||||
|
||||
const WaveEffect: React.FC<WaveEffectProps> = (props) => {
|
||||
const { className, target, component } = props;
|
||||
const divRef = React.useRef<HTMLDivElement>(null);
|
||||
const divRef = React.useRef<HTMLDivElement | null>(null);
|
||||
|
||||
const [color, setWaveColor] = React.useState<string | null>(null);
|
||||
const [borderRadius, setBorderRadius] = React.useState<number[]>([]);
|
||||
@@ -125,16 +126,10 @@ const WaveEffect: React.FC<WaveEffectProps> = (props) => {
|
||||
return false;
|
||||
}}
|
||||
>
|
||||
{({ className: motionClassName }) => (
|
||||
{({ className: motionClassName }, ref) => (
|
||||
<div
|
||||
ref={divRef}
|
||||
className={classNames(
|
||||
className,
|
||||
{
|
||||
'wave-quick': isSmallComponent,
|
||||
},
|
||||
motionClassName,
|
||||
)}
|
||||
ref={composeRef(divRef, ref)}
|
||||
className={classNames(className, { 'wave-quick': isSmallComponent }, motionClassName)}
|
||||
style={waveStyle}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -7,6 +7,7 @@ import ExclamationCircleFilled from '@ant-design/icons/ExclamationCircleFilled';
|
||||
import InfoCircleFilled from '@ant-design/icons/InfoCircleFilled';
|
||||
import classNames from 'classnames';
|
||||
import CSSMotion from 'rc-motion';
|
||||
import { composeRef } from 'rc-util/lib/ref';
|
||||
import pickAttrs from 'rc-util/lib/pickAttrs';
|
||||
|
||||
import type { ClosableType } from '../_util/hooks/useClosable';
|
||||
@@ -15,6 +16,10 @@ import { devUseWarning } from '../_util/warning';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import useStyle from './style';
|
||||
|
||||
export interface AlertRef {
|
||||
nativeElement: HTMLDivElement;
|
||||
}
|
||||
|
||||
export interface AlertProps {
|
||||
/** Type of Alert styles, options:`success`, `info`, `warning`, `error` */
|
||||
type?: 'success' | 'info' | 'warning' | 'error';
|
||||
@@ -48,6 +53,8 @@ export interface AlertProps {
|
||||
onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
|
||||
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
|
||||
onClick?: React.MouseEventHandler<HTMLDivElement>;
|
||||
|
||||
id?: string;
|
||||
}
|
||||
|
||||
const iconMapFilled = {
|
||||
@@ -102,7 +109,7 @@ const CloseIconNode: React.FC<CloseIconProps> = (props) => {
|
||||
) : null;
|
||||
};
|
||||
|
||||
const Alert: React.FC<AlertProps> = (props) => {
|
||||
const Alert = React.forwardRef<AlertRef, AlertProps>((props, ref) => {
|
||||
const {
|
||||
description,
|
||||
prefixCls: customizePrefixCls,
|
||||
@@ -120,6 +127,7 @@ const Alert: React.FC<AlertProps> = (props) => {
|
||||
closeText,
|
||||
closeIcon,
|
||||
action,
|
||||
id,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
@@ -130,7 +138,12 @@ const Alert: React.FC<AlertProps> = (props) => {
|
||||
warning.deprecated(!closeText, 'closeText', 'closable.closeIcon');
|
||||
}
|
||||
|
||||
const ref = React.useRef<HTMLDivElement>(null);
|
||||
const internalRef = React.useRef<HTMLDivElement>(null);
|
||||
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
nativeElement: internalRef.current!,
|
||||
}));
|
||||
|
||||
const { getPrefixCls, direction, alert } = React.useContext(ConfigContext);
|
||||
const prefixCls = getPrefixCls('alert', customizePrefixCls);
|
||||
|
||||
@@ -222,9 +235,10 @@ const Alert: React.FC<AlertProps> = (props) => {
|
||||
onLeaveStart={(node) => ({ maxHeight: node.offsetHeight })}
|
||||
onLeaveEnd={afterClose}
|
||||
>
|
||||
{({ className: motionClassName, style: motionStyle }) => (
|
||||
{({ className: motionClassName, style: motionStyle }, setRef) => (
|
||||
<div
|
||||
ref={ref}
|
||||
id={id}
|
||||
ref={composeRef(internalRef, setRef)}
|
||||
data-show={!closed}
|
||||
className={classNames(alertCls, motionClassName)}
|
||||
style={{ ...alert?.style, ...style, ...motionStyle }}
|
||||
@@ -258,7 +272,7 @@ const Alert: React.FC<AlertProps> = (props) => {
|
||||
)}
|
||||
</CSSMotion>,
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
Alert.displayName = 'Alert';
|
||||
|
||||
@@ -6,6 +6,7 @@ interface ErrorBoundaryProps {
|
||||
message?: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
interface ErrorBoundaryStates {
|
||||
@@ -28,7 +29,7 @@ class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundarySta
|
||||
}
|
||||
|
||||
render() {
|
||||
const { message, description, children } = this.props;
|
||||
const { message, description, id, children } = this.props;
|
||||
const { error, info } = this.state;
|
||||
const componentStack = info && info.componentStack ? info.componentStack : null;
|
||||
const errorMessage = typeof message === 'undefined' ? (error || '').toString() : message;
|
||||
@@ -36,6 +37,7 @@ class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundarySta
|
||||
if (error) {
|
||||
return (
|
||||
<Alert
|
||||
id={id}
|
||||
type="error"
|
||||
message={errorMessage}
|
||||
description={
|
||||
|
||||
@@ -9,6 +9,7 @@ import { act, render, screen, waitFakeTimer } from '../../../tests/utils';
|
||||
import Button from '../../button';
|
||||
import Popconfirm from '../../popconfirm';
|
||||
import Tooltip from '../../tooltip';
|
||||
import type { AlertRef } from '../Alert';
|
||||
|
||||
const { ErrorBoundary } = Alert;
|
||||
|
||||
@@ -25,6 +26,7 @@ describe('Alert', () => {
|
||||
});
|
||||
|
||||
it('should show close button and could be closed', async () => {
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
const onClose = jest.fn();
|
||||
render(
|
||||
<Alert
|
||||
@@ -35,13 +37,14 @@ describe('Alert', () => {
|
||||
/>,
|
||||
);
|
||||
|
||||
await userEvent.click(screen.getByRole('button', { name: /close/i }));
|
||||
|
||||
act(() => {
|
||||
await act(async () => {
|
||||
await userEvent.click(screen.getByRole('button', { name: /close/i }));
|
||||
jest.runAllTimers();
|
||||
});
|
||||
|
||||
expect(onClose).toHaveBeenCalledTimes(1);
|
||||
expect(errSpy).not.toHaveBeenCalled();
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('custom action', () => {
|
||||
@@ -192,4 +195,13 @@ describe('Alert', () => {
|
||||
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should support id and ref', () => {
|
||||
const alertRef = React.createRef<AlertRef>();
|
||||
const { container } = render(<Alert id="test-id" ref={alertRef} />);
|
||||
const element = container.querySelector<HTMLDivElement>('#test-id');
|
||||
expect(element).toBeTruthy();
|
||||
expect(alertRef.current?.nativeElement).toBeTruthy();
|
||||
expect(alertRef.current?.nativeElement).toBe(element);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import type React from 'react';
|
||||
|
||||
import type { AlertProps } from './Alert';
|
||||
import InternalAlert from './Alert';
|
||||
import ErrorBoundary from './ErrorBoundary';
|
||||
|
||||
export type { AlertProps } from './Alert';
|
||||
|
||||
type CompoundedComponent = React.FC<AlertProps> & {
|
||||
type CompoundedComponent = typeof InternalAlert & {
|
||||
ErrorBoundary: typeof ErrorBoundary;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import { SmileOutlined } from '@ant-design/icons';
|
||||
import type { NotificationConfig } from 'antd/es/notification/interface';
|
||||
import ConfigProvider from 'antd/es/config-provider';
|
||||
|
||||
import App from '..';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
@@ -211,6 +212,16 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
describe('component', () => {
|
||||
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
afterEach(() => {
|
||||
errorSpy.mockReset();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
errorSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('replace', () => {
|
||||
const { container } = render(
|
||||
<App component="section">
|
||||
@@ -222,15 +233,25 @@ describe('App', () => {
|
||||
});
|
||||
|
||||
it('to false', () => {
|
||||
const warnSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
const { container } = render(
|
||||
<App component={false}>
|
||||
<p />
|
||||
</App>,
|
||||
);
|
||||
expect(warnSpy).not.toHaveBeenCalled();
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
expect(container.querySelector('.ant-app')).toBeFalsy();
|
||||
warnSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should warn if component is false and cssVarCls is not empty', () => {
|
||||
render(
|
||||
<ConfigProvider theme={{ cssVar: true }}>
|
||||
<App component={false} />
|
||||
</ConfigProvider>,
|
||||
);
|
||||
|
||||
expect(errorSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: App] When using cssVar, ensure `component` is assigned a valid React component string.',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,7 @@ tag: 5.1.0
|
||||
## When To Use
|
||||
|
||||
- Provide reset styles based on `.ant-app` element.
|
||||
- You could use static methods of `message/notification/Modal` form `useApp` without writing `contextHolder` manually.
|
||||
- You could use static methods of `message/notification/Modal` from `useApp` without writing `contextHolder` manually.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -131,10 +131,16 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| component | Config render element, if `false` will not create DOM node | ComponentType | div | 5.11.0 |
|
||||
| component | Config render element, if `false` will not create DOM node | ComponentType \| false | div | 5.11.0 |
|
||||
| message | Global config for Message | [MessageConfig](/components/message/#messageconfig) | - | 5.3.0 |
|
||||
| notification | Global config for Notification | [NotificationConfig](/components/notification/#notificationconfig) | - | 5.3.0 |
|
||||
|
||||
## Design Token
|
||||
|
||||
<ComponentTokenTable component="App"></ComponentTokenTable>
|
||||
|
||||
## FAQ
|
||||
|
||||
### CSS Var doesn't work inside `<App component={false}>`
|
||||
|
||||
Make sure the App `component` is a legit React component string, so when you're turning on CSS variables, there's a container to hold the CSS class name.
|
||||
|
||||
@@ -3,6 +3,7 @@ import React, { useContext } from 'react';
|
||||
import classNames from 'classnames';
|
||||
|
||||
import type { AnyObject, CustomComponent } from '../_util/type';
|
||||
import { devUseWarning } from '../_util/warning';
|
||||
import type { ConfigConsumerProps } from '../config-provider';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import useMessage from '../message/useMessage';
|
||||
@@ -64,6 +65,13 @@ const App: React.FC<AppProps> & { useApp: () => useAppProps } = (props) => {
|
||||
[messageApi, notificationApi, ModalApi],
|
||||
);
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/48802#issuecomment-2097813526
|
||||
devUseWarning('App')(
|
||||
!(cssVarCls && component === false),
|
||||
'usage',
|
||||
'When using cssVar, ensure `component` is assigned a valid React component string.',
|
||||
);
|
||||
|
||||
// ============================ Render ============================
|
||||
const Component = component === false ? React.Fragment : component;
|
||||
const rootProps: AppProps = {
|
||||
|
||||
@@ -132,10 +132,16 @@ export default () => {
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| component | 设置渲染元素,为 `false` 则不创建 DOM 节点 | ComponentType | div | 5.11.0 |
|
||||
| component | 设置渲染元素,为 `false` 则不创建 DOM 节点 | ComponentType \| false | div | 5.11.0 |
|
||||
| message | App 内 Message 的全局配置 | [MessageConfig](/components/message-cn/#messageconfig) | - | 5.3.0 |
|
||||
| notification | App 内 Notification 的全局配置 | [NotificationConfig](/components/notification-cn/#notificationconfig) | - | 5.3.0 |
|
||||
|
||||
## 主题变量(Design Token)
|
||||
|
||||
<ComponentTokenTable component="App"></ComponentTokenTable>
|
||||
|
||||
## FAQ
|
||||
|
||||
### CSS Var 在 `<App component={false}>` 内不起作用
|
||||
|
||||
请确保 App 的 `component` 是一个有效的 React 组件字符串,以便在启用 CSS 变量时,有一个容器来承载 CSS 类名。
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import { act, fireEvent, render } from '@testing-library/react';
|
||||
|
||||
import type { GetRef } from '../../_util/type';
|
||||
import mountTest from '../../../tests/shared/mountTest';
|
||||
import rtlTest from '../../../tests/shared/rtlTest';
|
||||
import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
|
||||
import Tooltip from '../../tooltip';
|
||||
import Badge from '../index';
|
||||
|
||||
@@ -26,19 +26,31 @@ describe('Badge', () => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
it('no strict warning', () => {
|
||||
it('no strict warning', async () => {
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
const { rerender } = render(
|
||||
<Badge dot>
|
||||
<span />
|
||||
</Badge>,
|
||||
);
|
||||
const Comp = () => {
|
||||
const [count, setCount] = React.useState<number | null>(9999);
|
||||
|
||||
rerender(
|
||||
<Badge>
|
||||
<span />
|
||||
</Badge>,
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<Badge count={count}>
|
||||
<span>Badge</span>
|
||||
</Badge>
|
||||
|
||||
<br />
|
||||
<br />
|
||||
<br />
|
||||
|
||||
<button type="button" onClick={() => setCount(null)}>
|
||||
click
|
||||
</button>
|
||||
</>
|
||||
);
|
||||
};
|
||||
const { container } = render(<Comp />);
|
||||
|
||||
fireEvent.click(container.querySelector('button')!);
|
||||
await waitFakeTimer();
|
||||
|
||||
expect(errSpy).not.toHaveBeenCalled();
|
||||
errSpy.mockRestore();
|
||||
|
||||
@@ -216,7 +216,7 @@ const InternalBadge = React.forwardRef<HTMLSpanElement, BadgeProps>((props, ref)
|
||||
motionAppear={false}
|
||||
motionDeadline={1000}
|
||||
>
|
||||
{({ className: motionClassName, ref: scrollNumberRef }) => {
|
||||
{({ className: motionClassName }) => {
|
||||
const scrollNumberPrefixCls = getPrefixCls(
|
||||
'scroll-number',
|
||||
customizeScrollNumberPrefixCls,
|
||||
@@ -255,7 +255,6 @@ const InternalBadge = React.forwardRef<HTMLSpanElement, BadgeProps>((props, ref)
|
||||
title={titleNode}
|
||||
style={scrollNumberStyle}
|
||||
key="scrollNumber"
|
||||
ref={scrollNumberRef}
|
||||
>
|
||||
{displayNode}
|
||||
</ScrollNumber>
|
||||
|
||||
@@ -252,59 +252,7 @@ exports[`renders components/breadcrumb/demo/component-token.tsx extend context c
|
||||
<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
|
||||
@@ -523,42 +471,7 @@ exports[`renders components/breadcrumb/demo/debug-routes.tsx extend context corr
|
||||
<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>
|
||||
/>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
@@ -758,59 +671,7 @@ exports[`renders components/breadcrumb/demo/overlay.tsx extend context correctly
|
||||
<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
|
||||
|
||||
@@ -3,6 +3,7 @@ import LoadingOutlined from '@ant-design/icons/LoadingOutlined';
|
||||
import classNames from 'classnames';
|
||||
import CSSMotion from 'rc-motion';
|
||||
|
||||
import type { ButtonProps } from './button';
|
||||
import IconWrapper from './IconWrapper';
|
||||
|
||||
type InnerLoadingIconProps = {
|
||||
@@ -10,27 +11,29 @@ type InnerLoadingIconProps = {
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
iconClassName?: string;
|
||||
};
|
||||
} & Pick<ButtonProps, 'iconPosition'>;
|
||||
|
||||
const InnerLoadingIcon = forwardRef<HTMLSpanElement, InnerLoadingIconProps>(
|
||||
({ prefixCls, className, style, iconClassName }, ref) => {
|
||||
const mergedIconCls = classNames(`${prefixCls}-loading-icon`, className);
|
||||
const InnerLoadingIcon = forwardRef<HTMLSpanElement, InnerLoadingIconProps>((props, ref) => {
|
||||
const { prefixCls, className, style, iconClassName, iconPosition = 'start' } = props;
|
||||
const mergedIconCls = classNames(className, {
|
||||
[`${prefixCls}-loading-icon-end`]: iconPosition === 'end',
|
||||
[`${prefixCls}-loading-icon`]: iconPosition === 'start',
|
||||
});
|
||||
|
||||
return (
|
||||
<IconWrapper prefixCls={prefixCls} className={mergedIconCls} style={style} ref={ref}>
|
||||
<LoadingOutlined className={iconClassName} />
|
||||
</IconWrapper>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<IconWrapper prefixCls={prefixCls} className={mergedIconCls} style={style} ref={ref}>
|
||||
<LoadingOutlined className={iconClassName} />
|
||||
</IconWrapper>
|
||||
);
|
||||
});
|
||||
|
||||
export interface LoadingIconProps {
|
||||
export type LoadingIconProps = {
|
||||
prefixCls: string;
|
||||
existIcon: boolean;
|
||||
loading?: boolean | object;
|
||||
className?: string;
|
||||
style?: React.CSSProperties;
|
||||
}
|
||||
} & Pick<ButtonProps, 'iconPosition'>;
|
||||
|
||||
const getCollapsedWidth = (): React.CSSProperties => ({
|
||||
width: 0,
|
||||
@@ -45,11 +48,18 @@ const getRealWidth = (node: HTMLElement): React.CSSProperties => ({
|
||||
});
|
||||
|
||||
const LoadingIcon: React.FC<LoadingIconProps> = (props) => {
|
||||
const { prefixCls, loading, existIcon, className, style } = props;
|
||||
const { prefixCls, loading, existIcon, className, style, iconPosition } = props;
|
||||
const visible = !!loading;
|
||||
|
||||
if (existIcon) {
|
||||
return <InnerLoadingIcon prefixCls={prefixCls} className={className} style={style} />;
|
||||
return (
|
||||
<InnerLoadingIcon
|
||||
prefixCls={prefixCls}
|
||||
className={className}
|
||||
style={style}
|
||||
iconPosition={iconPosition}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -73,6 +83,7 @@ const LoadingIcon: React.FC<LoadingIconProps> = (props) => {
|
||||
style={{ ...style, ...motionStyle }}
|
||||
ref={ref}
|
||||
iconClassName={motionCls}
|
||||
iconPosition={iconPosition}
|
||||
/>
|
||||
)}
|
||||
</CSSMotion>
|
||||
|
||||
@@ -1520,6 +1520,467 @@ exports[`renders components/button/demo/icon.tsx extend context correctly 1`] =
|
||||
|
||||
exports[`renders components/button/demo/icon.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/button/demo/icon-position.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small"
|
||||
>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-radio-group ant-radio-group-outline"
|
||||
>
|
||||
<label
|
||||
class="ant-radio-button-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio-button"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-button-input"
|
||||
type="radio"
|
||||
value="start"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-button-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
start
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio-button ant-radio-button-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-button-input"
|
||||
type="radio"
|
||||
value="end"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-button-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
end
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left ant-divider-plain"
|
||||
role="separator"
|
||||
>
|
||||
<span
|
||||
class="ant-divider-inner-text"
|
||||
>
|
||||
Preview
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-flex ant-flex-align-stretch ant-flex-gap-small ant-flex-vertical"
|
||||
>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-primary ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<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"
|
||||
>
|
||||
search
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
A
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-default ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<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"
|
||||
>
|
||||
search
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-default ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<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"
|
||||
>
|
||||
search
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-text"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-dashed ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<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"
|
||||
>
|
||||
search
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="ant-btn ant-btn-dashed"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<a
|
||||
class="ant-btn ant-btn-default ant-btn-icon-only"
|
||||
href="https://www.google.com"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary ant-btn-loading"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Loading
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-loading-icon-end"
|
||||
style="width: 0px; opacity: 0; transform: scale(0);"
|
||||
>
|
||||
<span
|
||||
aria-label="loading"
|
||||
class="anticon anticon-loading anticon-spin ant-btn-loading-icon-motion-appear ant-btn-loading-icon-motion-appear-start ant-btn-loading-icon-motion"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="loading"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders components/button/demo/icon-position.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/button/demo/legacy-group.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
@@ -2255,59 +2716,7 @@ exports[`renders components/button/demo/multiple.tsx extend context correctly 1`
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2315,6 +2724,31 @@ exports[`renders components/button/demo/multiple.tsx extend context correctly 1`
|
||||
|
||||
exports[`renders components/button/demo/multiple.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/button/demo/noSpace.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
确定
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
确 定
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/button/demo/noSpace.tsx extend context correctly 2`] = `[]`;
|
||||
|
||||
exports[`renders components/button/demo/size.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
|
||||
@@ -1345,6 +1345,388 @@ exports[`renders components/button/demo/icon.tsx correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/button/demo/icon-position.tsx correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
class="ant-space ant-space-horizontal ant-space-align-center ant-space-gap-row-small ant-space-gap-col-small"
|
||||
>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<div
|
||||
class="ant-radio-group ant-radio-group-outline"
|
||||
>
|
||||
<label
|
||||
class="ant-radio-button-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-radio-button"
|
||||
>
|
||||
<input
|
||||
class="ant-radio-button-input"
|
||||
type="radio"
|
||||
value="start"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-button-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
start
|
||||
</span>
|
||||
</label>
|
||||
<label
|
||||
class="ant-radio-button-wrapper ant-radio-button-wrapper-checked"
|
||||
>
|
||||
<span
|
||||
class="ant-radio-button ant-radio-button-checked"
|
||||
>
|
||||
<input
|
||||
checked=""
|
||||
class="ant-radio-button-input"
|
||||
type="radio"
|
||||
value="end"
|
||||
/>
|
||||
<span
|
||||
class="ant-radio-button-inner"
|
||||
/>
|
||||
</span>
|
||||
<span>
|
||||
end
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-divider ant-divider-horizontal ant-divider-with-text ant-divider-with-text-left ant-divider-plain"
|
||||
role="separator"
|
||||
>
|
||||
<span
|
||||
class="ant-divider-inner-text"
|
||||
>
|
||||
Preview
|
||||
</span>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-flex ant-flex-align-stretch ant-flex-gap-small ant-flex-vertical"
|
||||
>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-primary ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
A
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-default ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-default"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-small"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-default ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-text"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-circle ant-btn-dashed ant-btn-icon-only"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-dashed"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Search
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
<a
|
||||
class="ant-btn ant-btn-default ant-btn-icon-only"
|
||||
href="https://www.google.com"
|
||||
tabindex="0"
|
||||
>
|
||||
<span
|
||||
class="ant-btn-icon"
|
||||
>
|
||||
<span
|
||||
aria-label="search"
|
||||
class="anticon anticon-search"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="search"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M909.6 854.5L649.9 594.8C690.2 542.7 712 479 712 412c0-80.2-31.3-155.4-87.9-212.1-56.6-56.7-132-87.9-212.1-87.9s-155.5 31.3-212.1 87.9C143.2 256.5 112 331.8 112 412c0 80.1 31.3 155.5 87.9 212.1C256.5 680.8 331.8 712 412 712c67 0 130.6-21.8 182.7-62l259.7 259.6a8.2 8.2 0 0011.6 0l43.6-43.5a8.2 8.2 0 000-11.6zM570.4 570.4C528 612.7 471.8 636 412 636s-116-23.3-158.4-65.6C211.3 528 188 471.8 188 412s23.3-116.1 65.6-158.4C296 211.3 352.2 188 412 188s116.1 23.2 158.4 65.6S636 352.2 636 412s-23.3 116.1-65.6 158.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary ant-btn-loading"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Loading
|
||||
</span>
|
||||
<span
|
||||
class="ant-btn-icon ant-btn-loading-icon-end"
|
||||
>
|
||||
<span
|
||||
aria-label="loading"
|
||||
class="anticon anticon-loading anticon-spin"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
data-icon="loading"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="0 0 1024 1024"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders components/button/demo/legacy-group.tsx correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
@@ -1861,6 +2243,29 @@ exports[`renders components/button/demo/multiple.tsx correctly 1`] = `
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/button/demo/noSpace.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-flex ant-flex-wrap-wrap ant-flex-gap-middle"
|
||||
>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
确定
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
确 定
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders components/button/demo/size.tsx correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
|
||||
@@ -88,7 +88,7 @@ describe('Button', () => {
|
||||
});
|
||||
|
||||
it('renders Chinese characters correctly in HOC', () => {
|
||||
const Text = ({ children }: { children: React.ReactNode }) => <span>{children}</span>;
|
||||
const Text: React.FC<React.PropsWithChildren> = ({ children }) => <span>{children}</span>;
|
||||
const { container, rerender } = render(
|
||||
<Button>
|
||||
<Text>按钮</Text>
|
||||
@@ -441,4 +441,10 @@ describe('Button', () => {
|
||||
const { container } = render(<Button type={'' as any} />);
|
||||
expect(container.querySelector('.ant-btn-default')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should support autoInsertSpace', () => {
|
||||
const text = '确定';
|
||||
const { container } = render(<Button autoInsertSpace={false}>{text}</Button>);
|
||||
expect(container.querySelector<HTMLButtonElement>('button')?.textContent).toBe(text);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -24,6 +24,7 @@ export type LegacyButtonType = ButtonType | 'danger';
|
||||
export interface BaseButtonProps {
|
||||
type?: ButtonType;
|
||||
icon?: React.ReactNode;
|
||||
iconPosition?: 'start' | 'end';
|
||||
shape?: ButtonShape;
|
||||
size?: SizeType;
|
||||
disabled?: boolean;
|
||||
@@ -50,6 +51,7 @@ type MergedHTMLAttributes = Omit<
|
||||
export interface ButtonProps extends BaseButtonProps, MergedHTMLAttributes {
|
||||
href?: string;
|
||||
htmlType?: ButtonHTMLType;
|
||||
autoInsertSpace?: boolean;
|
||||
}
|
||||
|
||||
type LoadingConfigType = {
|
||||
@@ -90,12 +92,14 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
rootClassName,
|
||||
children,
|
||||
icon,
|
||||
iconPosition = 'start',
|
||||
ghost = false,
|
||||
block = false,
|
||||
// React does not recognize the `htmlType` prop on a DOM element. Here we pick it out of `rest`.
|
||||
htmlType = 'button',
|
||||
classNames: customClassNames,
|
||||
style: customStyle = {},
|
||||
autoInsertSpace,
|
||||
...rest
|
||||
} = props;
|
||||
|
||||
@@ -103,7 +107,10 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
// Compatible with original `type` behavior
|
||||
const mergedType = type || 'default';
|
||||
|
||||
const { getPrefixCls, autoInsertSpaceInButton, direction, button } = useContext(ConfigContext);
|
||||
const { getPrefixCls, direction, button } = useContext(ConfigContext);
|
||||
|
||||
const mergedInsertSpace = autoInsertSpace ?? button?.autoInsertSpace ?? true;
|
||||
|
||||
const prefixCls = getPrefixCls('btn', customizePrefixCls);
|
||||
|
||||
const [wrapCSSVar, hashId, cssVarCls] = useStyle(prefixCls);
|
||||
@@ -149,7 +156,7 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
|
||||
useEffect(() => {
|
||||
// FIXME: for HOC usage like <FormatMessage />
|
||||
if (!buttonRef || !(buttonRef as any).current || autoInsertSpaceInButton === false) {
|
||||
if (!buttonRef || !(buttonRef as any).current || !mergedInsertSpace) {
|
||||
return;
|
||||
}
|
||||
const buttonText = (buttonRef as any).current.textContent;
|
||||
@@ -188,7 +195,6 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
);
|
||||
}
|
||||
|
||||
const autoInsertSpace = autoInsertSpaceInButton !== false;
|
||||
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
|
||||
|
||||
const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined };
|
||||
@@ -212,7 +218,7 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
[`${prefixCls}-icon-only`]: !children && children !== 0 && !!iconType,
|
||||
[`${prefixCls}-background-ghost`]: ghost && !isUnBorderedButtonType(mergedType),
|
||||
[`${prefixCls}-loading`]: innerLoading,
|
||||
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && autoInsertSpace && !innerLoading,
|
||||
[`${prefixCls}-two-chinese-chars`]: hasTwoCNChar && mergedInsertSpace && !innerLoading,
|
||||
[`${prefixCls}-block`]: block,
|
||||
[`${prefixCls}-dangerous`]: !!danger,
|
||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||
@@ -225,7 +231,11 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
|
||||
const fullStyle: React.CSSProperties = { ...button?.style, ...customStyle };
|
||||
|
||||
const iconClasses = classNames(customClassNames?.icon, button?.classNames?.icon);
|
||||
const isIconPositionEnd = iconPosition === 'end' && children && children !== 0 && iconType;
|
||||
|
||||
const iconClasses = classNames(customClassNames?.icon, button?.classNames?.icon, {
|
||||
[`${prefixCls}-icon-end`]: isIconPositionEnd,
|
||||
});
|
||||
const iconStyle: React.CSSProperties = {
|
||||
...(styles?.icon || {}),
|
||||
...(button?.styles?.icon || {}),
|
||||
@@ -237,11 +247,29 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
{icon}
|
||||
</IconWrapper>
|
||||
) : (
|
||||
<LoadingIcon existIcon={!!icon} prefixCls={prefixCls} loading={!!innerLoading} />
|
||||
<LoadingIcon
|
||||
existIcon={!!icon}
|
||||
prefixCls={prefixCls}
|
||||
loading={!!innerLoading}
|
||||
iconPosition={iconPosition}
|
||||
/>
|
||||
);
|
||||
|
||||
const kids =
|
||||
children || children === 0 ? spaceChildren(children, needInserted && autoInsertSpace) : null;
|
||||
children || children === 0 ? spaceChildren(children, needInserted && mergedInsertSpace) : null;
|
||||
|
||||
const genButtonContent = (iconComponent: React.ReactNode, kidsComponent: React.ReactNode) =>
|
||||
iconPosition === 'start' ? (
|
||||
<>
|
||||
{iconComponent}
|
||||
{kidsComponent}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{kidsComponent}
|
||||
{iconComponent}
|
||||
</>
|
||||
);
|
||||
|
||||
if (linkButtonRestProps.href !== undefined) {
|
||||
return wrapCSSVar(
|
||||
@@ -256,8 +284,7 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
ref={buttonRef as React.Ref<HTMLAnchorElement>}
|
||||
tabIndex={mergedDisabled ? -1 : 0}
|
||||
>
|
||||
{iconNode}
|
||||
{kids}
|
||||
{genButtonContent(iconNode, kids)}
|
||||
</a>,
|
||||
);
|
||||
}
|
||||
@@ -272,8 +299,7 @@ const InternalCompoundedButton = React.forwardRef<
|
||||
disabled={mergedDisabled}
|
||||
ref={buttonRef as React.Ref<HTMLButtonElement>}
|
||||
>
|
||||
{iconNode}
|
||||
{kids}
|
||||
{genButtonContent(iconNode, kids)}
|
||||
|
||||
{/* Styles: compact */}
|
||||
{!!compactItemClassnames && <CompactCmp key="compact" prefixCls={prefixCls} />}
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Button, Flex } from 'antd';
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Flex gap="small" wrap="wrap">
|
||||
<Flex gap="small" wrap>
|
||||
<Button type="primary">Primary Button</Button>
|
||||
<Button>Default Button</Button>
|
||||
<Button type="dashed">Dashed Button</Button>
|
||||
|
||||
@@ -7,7 +7,7 @@ const Text2 = () => <span>部署</span>;
|
||||
const Text3 = () => <>Submit</>;
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Flex wrap="wrap" gap="small">
|
||||
<Flex wrap gap="small">
|
||||
<Button>
|
||||
<span>
|
||||
<span>部署</span>
|
||||
|
||||
@@ -24,12 +24,12 @@ const App: React.FC = () => (
|
||||
}}
|
||||
>
|
||||
<Flex gap="small" vertical>
|
||||
<Flex wrap="wrap" gap="small">
|
||||
<Flex wrap gap="small">
|
||||
<Button type="text">TEXT</Button>
|
||||
<Button type="primary">CONTAINED</Button>
|
||||
<Button>OUTLINED</Button>
|
||||
</Flex>
|
||||
<Flex wrap="wrap" gap="small">
|
||||
<Flex wrap gap="small">
|
||||
<Button type="text" disabled>
|
||||
TEXT
|
||||
</Button>
|
||||
@@ -38,7 +38,7 @@ const App: React.FC = () => (
|
||||
</Button>
|
||||
<Button disabled>OUTLINED</Button>
|
||||
</Flex>
|
||||
<Flex wrap="wrap" gap="small">
|
||||
<Flex wrap gap="small">
|
||||
<Button type="text" size="small">
|
||||
TEXT
|
||||
</Button>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Button, Flex } from 'antd';
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Flex wrap="wrap" gap="small">
|
||||
<Flex wrap gap="small">
|
||||
<Button type="primary" danger>
|
||||
Primary
|
||||
</Button>
|
||||
|
||||
@@ -19,7 +19,7 @@ const App: React.FC = () => {
|
||||
</Divider>
|
||||
<ConfigProvider componentSize={size}>
|
||||
<Flex gap="small" vertical>
|
||||
<Flex gap="small" wrap="wrap">
|
||||
<Flex gap="small" wrap>
|
||||
<Tooltip title="search">
|
||||
<Button type="primary" shape="circle" icon={<SearchOutlined />} />
|
||||
</Tooltip>
|
||||
@@ -34,7 +34,7 @@ const App: React.FC = () => {
|
||||
</Tooltip>
|
||||
<Button icon={<SearchOutlined />}>Search</Button>
|
||||
</Flex>
|
||||
<Flex gap="small" wrap="wrap">
|
||||
<Flex gap="small" wrap>
|
||||
<Tooltip title="search">
|
||||
<Button shape="circle" icon={<SearchOutlined />} />
|
||||
</Tooltip>
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import { Button, Flex } from 'antd';
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Flex wrap="wrap" gap="small" className="site-button-ghost-wrapper">
|
||||
<Flex wrap gap="small" className="site-button-ghost-wrapper">
|
||||
<Button type="primary" ghost>
|
||||
Primary
|
||||
</Button>
|
||||
|
||||
7
components/button/demo/icon-position.md
Normal file
7
components/button/demo/icon-position.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
通过设置 `iconPosition` 为 `start` 或 `end` 分别设置按钮图标的位置。
|
||||
|
||||
## en-US
|
||||
|
||||
Set the position of the button icon by setting `iconPosition` to `start` or `end` respectively.
|
||||
60
components/button/demo/icon-position.tsx
Normal file
60
components/button/demo/icon-position.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import React, { useState } from 'react';
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { Button, Divider, Flex, Radio, Space, Tooltip } from 'antd';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [position, setPosition] = useState<'start' | 'end'>('end');
|
||||
|
||||
return (
|
||||
<>
|
||||
<Space>
|
||||
<Radio.Group value={position} onChange={(e) => setPosition(e.target.value)}>
|
||||
<Radio.Button value="start">start</Radio.Button>
|
||||
<Radio.Button value="end">end</Radio.Button>
|
||||
</Radio.Group>
|
||||
</Space>
|
||||
<Divider orientation="left" plain>
|
||||
Preview
|
||||
</Divider>
|
||||
<Flex gap="small" vertical>
|
||||
<Flex wrap gap="small">
|
||||
<Tooltip title="search">
|
||||
<Button type="primary" shape="circle" icon={<SearchOutlined />} />
|
||||
</Tooltip>
|
||||
<Button type="primary" shape="circle">
|
||||
A
|
||||
</Button>
|
||||
<Button type="primary" icon={<SearchOutlined />} iconPosition={position}>
|
||||
Search
|
||||
</Button>
|
||||
<Tooltip title="search">
|
||||
<Button shape="circle" icon={<SearchOutlined />} />
|
||||
</Tooltip>
|
||||
<Button icon={<SearchOutlined />} iconPosition={position}>
|
||||
Search
|
||||
</Button>
|
||||
</Flex>
|
||||
<Flex wrap gap="small">
|
||||
<Tooltip title="search">
|
||||
<Button shape="circle" icon={<SearchOutlined />} />
|
||||
</Tooltip>
|
||||
<Button icon={<SearchOutlined />} type="text" iconPosition={position}>
|
||||
Search
|
||||
</Button>
|
||||
<Tooltip title="search">
|
||||
<Button type="dashed" shape="circle" icon={<SearchOutlined />} />
|
||||
</Tooltip>
|
||||
<Button type="dashed" icon={<SearchOutlined />} iconPosition={position}>
|
||||
Search
|
||||
</Button>
|
||||
<Button icon={<SearchOutlined />} href="https://www.google.com" iconPosition={position} />
|
||||
<Button type="primary" loading iconPosition={position}>
|
||||
Loading
|
||||
</Button>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -1,11 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
当需要在 `Button` 内嵌入 `Icon` 时,可以设置 `icon` 属性,或者直接在 `Button` 内使用 `Icon` 组件。
|
||||
|
||||
如果想控制 `Icon` 具体的位置,只能直接使用 `Icon` 组件,而非 `icon` 属性。
|
||||
可以通过 `icon `属性添加图标,并使用 `iconPosition` 调整图标的位置。
|
||||
|
||||
## en-US
|
||||
|
||||
`Button` components can contain an `Icon`. This is done by setting the `icon` property or placing an `Icon` component within the `Button`.
|
||||
|
||||
If you want specific control over the positioning and placement of the `Icon`, then that should be done by placing the `Icon` component within the `Button` rather than using the `icon` property.
|
||||
You can add an icon through the `icon` property and adjust the position of the icon using `iconPosition`.
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Button, Flex, Tooltip } from 'antd';
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Flex gap="small" vertical>
|
||||
<Flex wrap="wrap" gap="small">
|
||||
<Flex wrap gap="small">
|
||||
<Tooltip title="search">
|
||||
<Button type="primary" shape="circle" icon={<SearchOutlined />} />
|
||||
</Tooltip>
|
||||
@@ -19,7 +19,7 @@ const App: React.FC = () => (
|
||||
</Tooltip>
|
||||
<Button icon={<SearchOutlined />}>Search</Button>
|
||||
</Flex>
|
||||
<Flex wrap="wrap" gap="small">
|
||||
<Flex wrap gap="small">
|
||||
<Tooltip title="search">
|
||||
<Button shape="circle" icon={<SearchOutlined />} />
|
||||
</Tooltip>
|
||||
|
||||
@@ -23,7 +23,7 @@ const App: React.FC = () => {
|
||||
|
||||
return (
|
||||
<Flex gap="small" vertical>
|
||||
<Flex gap="small" align="center" wrap="wrap">
|
||||
<Flex gap="small" align="center" wrap>
|
||||
<Button type="primary" loading>
|
||||
Loading
|
||||
</Button>
|
||||
@@ -32,7 +32,7 @@ const App: React.FC = () => {
|
||||
</Button>
|
||||
<Button type="primary" icon={<PoweroffOutlined />} loading />
|
||||
</Flex>
|
||||
<Flex gap="small" wrap="wrap">
|
||||
<Flex gap="small" wrap>
|
||||
<Button type="primary" loading={loadings[0]} onClick={() => enterLoading(0)}>
|
||||
Click me!
|
||||
</Button>
|
||||
|
||||
7
components/button/demo/noSpace.md
Normal file
7
components/button/demo/noSpace.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
我们默认在两个汉字之间添加空格,可以通过设置 `autoInsertSpace` 为 `false` 关闭。
|
||||
|
||||
## en-US
|
||||
|
||||
We add a space between two Chinese characters by default, which can be removed by setting `autoInsertSpace` to `false`.
|
||||
15
components/button/demo/noSpace.tsx
Normal file
15
components/button/demo/noSpace.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import { Button, Flex } from 'antd';
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Flex gap="middle" wrap>
|
||||
<Button type="primary" autoInsertSpace={false}>
|
||||
确定
|
||||
</Button>
|
||||
<Button type="primary" autoInsertSpace>
|
||||
确定
|
||||
</Button>
|
||||
</Flex>
|
||||
);
|
||||
|
||||
export default App;
|
||||
@@ -18,7 +18,7 @@ const App: React.FC = () => {
|
||||
Preview
|
||||
</Divider>
|
||||
<Flex gap="small" align="flex-start" vertical>
|
||||
<Flex gap="small" wrap="wrap">
|
||||
<Flex gap="small" wrap>
|
||||
<Button type="primary" size={size}>
|
||||
Primary
|
||||
</Button>
|
||||
@@ -30,7 +30,7 @@ const App: React.FC = () => {
|
||||
<Button type="link" size={size}>
|
||||
Link
|
||||
</Button>
|
||||
<Flex gap="small" wrap="wrap">
|
||||
<Flex gap="small" wrap>
|
||||
<Button type="primary" icon={<DownloadOutlined />} size={size} />
|
||||
<Button type="primary" shape="circle" icon={<DownloadOutlined />} size={size} />
|
||||
<Button type="primary" shape="round" icon={<DownloadOutlined />} size={size} />
|
||||
|
||||
@@ -35,6 +35,7 @@ And 4 other properties additionally.
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/basic.tsx">Type</code>
|
||||
<code src="./demo/icon.tsx">Icon</code>
|
||||
<code src="./demo/icon-position.tsx" version="5.17.0">Icon Position</code>
|
||||
<code src="./demo/debug-icon.tsx" debug>Debug Icon</code>
|
||||
<code src="./demo/debug-block.tsx" debug>Debug Block</code>
|
||||
<code src="./demo/size.tsx">Size</code>
|
||||
@@ -57,6 +58,7 @@ Different button styles can be generated by setting Button properties. The recom
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| autoInsertSpace | We add a space between two Chinese characters by default, which can be removed by setting `autoInsertSpace` to `false`. | boolean | `true` | 5.17.0 |
|
||||
| block | Option to fit button width to its parent width | boolean | false | |
|
||||
| classNames | Semantic DOM class | [Record<SemanticDOM, string>](#semantic-dom) | - | 5.4.0 |
|
||||
| danger | Set the danger status of button | boolean | false | |
|
||||
@@ -65,13 +67,14 @@ Different button styles can be generated by setting Button properties. The recom
|
||||
| href | Redirect url of link button | string | - | |
|
||||
| htmlType | Set the original html `type` of `button`, see: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | |
|
||||
| icon | Set the icon component of button | ReactNode | - | |
|
||||
| iconPosition | Set the icon position of button | `start` \| `end` | `start` | 5.17.0 |
|
||||
| loading | Set the loading status of button | boolean \| { delay: number } | false | |
|
||||
| shape | Can be set button shape | `default` \| `circle` \| `round` | `default` | |
|
||||
| size | Set the size of button | `large` \| `middle` \| `small` | `middle` | |
|
||||
| styles | Semantic DOM style | [Record<SemanticDOM, CSSProperties>](#semantic-dom) | - | 5.4.0 |
|
||||
| target | Same as target attribute of a, works when href is specified | string | - | |
|
||||
| type | Set button type | `primary` \| `dashed` \| `link` \| `text` \| `default` | `default` | |
|
||||
| onClick | Set the handler to handle `click` event | (event: MouseEvent) => void | - | |
|
||||
| onClick | Set the handler to handle `click` event | (event: React.MouseEvent<HTMLElement, MouseEvent>) => void | - | |
|
||||
|
||||
It accepts all props which native buttons support.
|
||||
|
||||
@@ -95,18 +98,6 @@ If you don't need this feature, you can set `disabled` of `wave` in [ConfigProvi
|
||||
</ConfigProvider>
|
||||
```
|
||||
|
||||
### How to remove space between 2 chinese characters?
|
||||
|
||||
Following the Ant Design specification, we will add one space between if Button (exclude Text button and Link button) contains two Chinese characters only. If you don't need that, you can use [ConfigProvider](/components/config-provider/#api) to set `autoInsertSpaceInButton` as `false`.
|
||||
|
||||
```jsx
|
||||
<ConfigProvider autoInsertSpaceInButton={false}>
|
||||
<Button>按钮</Button>
|
||||
</ConfigProvider>
|
||||
```
|
||||
|
||||
<img src="https://gw.alipayobjects.com/zos/antfincdn/MY%26THAPZrW/38f06cb9-293a-4b42-b183-9f443e79ffea.png" width="100px" height="64px" style="box-shadow: none; margin: 0;" alt="Button with two Chinese characters" />
|
||||
|
||||
<style>
|
||||
.site-button-ghost-wrapper {
|
||||
padding: 16px;
|
||||
|
||||
@@ -37,11 +37,12 @@ group:
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
<code src="./demo/basic.tsx">按钮类型</code>
|
||||
<code src="./demo/icon.tsx">图标按钮</code>
|
||||
<code src="./demo/icon.tsx" >按钮图标</code>
|
||||
<code src="./demo/icon-position.tsx" version="5.17.0">按钮图标位置</code>
|
||||
<code src="./demo/debug-icon.tsx" debug>调试图标按钮</code>
|
||||
<code src="./demo/debug-block.tsx" debug>调试按钮block属性</code>
|
||||
<code src="./demo/size.tsx">按钮尺寸</code>
|
||||
<code src="./demo/disabled.tsx">不可用状态</code>
|
||||
<code src="./demo/disabled.tsx">不可用状态</code>
|
||||
<code src="./demo/loading.tsx">加载中状态</code>
|
||||
<code src="./demo/multiple.tsx">多个按钮组合</code>
|
||||
<code src="./demo/ghost.tsx">幽灵按钮</code>
|
||||
@@ -51,6 +52,7 @@ group:
|
||||
<code src="./demo/chinese-chars-loading.tsx" debug>加载中状态 bug 还原</code>
|
||||
<code src="./demo/component-token.tsx" debug>组件 Token</code>
|
||||
<code src="./demo/linear-gradient.tsx">渐变按钮</code>
|
||||
<code src="./demo/noSpace.tsx" version="5.17.0">移除两个汉字之间的空格</code>
|
||||
|
||||
## API
|
||||
|
||||
@@ -62,6 +64,7 @@ group:
|
||||
|
||||
| 属性 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| autoInsertSpace | 我们默认提供两个汉字之间的空格,可以设置 `autoInsertSpace` 为 `false` 关闭 | boolean | `true` | 5.17.0 |
|
||||
| block | 将按钮宽度调整为其父宽度的选项 | boolean | false | |
|
||||
| classNames | 语义化结构 class | [Record<SemanticDOM, string>](#semantic-dom) | - | 5.4.0 |
|
||||
| danger | 设置危险按钮 | boolean | false | |
|
||||
@@ -70,13 +73,14 @@ group:
|
||||
| href | 点击跳转的地址,指定此属性 button 的行为和 a 链接一致 | string | - | |
|
||||
| htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | |
|
||||
| icon | 设置按钮的图标组件 | ReactNode | - | |
|
||||
| iconPosition | 设置按钮图标组件的位置 | `start` \| `end` | `start` | 5.17.0 |
|
||||
| loading | 设置按钮载入状态 | boolean \| { delay: number } | false | |
|
||||
| shape | 设置按钮形状 | `default` \| `circle` \| `round` | `default` | |
|
||||
| size | 设置按钮大小 | `large` \| `middle` \| `small` | `middle` | |
|
||||
| styles | 语义化结构 style | [Record<SemanticDOM, CSSProperties>](#semantic-dom) | - | 5.4.0 |
|
||||
| target | 相当于 a 链接的 target 属性,href 存在时生效 | string | - | |
|
||||
| type | 设置按钮类型 | `primary` \| `dashed` \| `link` \| `text` \| `default` | `default` | |
|
||||
| onClick | 点击按钮时的回调 | (event: MouseEvent) => void | - | |
|
||||
| onClick | 点击按钮时的回调 | (event: React.MouseEvent<HTMLElement, MouseEvent>) => void | - | |
|
||||
|
||||
支持原生 button 的其他所有属性。
|
||||
|
||||
@@ -100,18 +104,6 @@ group:
|
||||
</ConfigProvider>
|
||||
```
|
||||
|
||||
### 如何移除两个汉字之间的空格?
|
||||
|
||||
根据 Ant Design 设计规范要求,我们会在按钮内(文本按钮和链接按钮除外)只有两个汉字时自动添加空格,如果你不需要这个特性,可以设置 [ConfigProvider](/components/config-provider-cn#api) 的 `autoInsertSpaceInButton` 为 `false`。
|
||||
|
||||
```jsx
|
||||
<ConfigProvider autoInsertSpaceInButton={false}>
|
||||
<Button>按钮</Button>
|
||||
</ConfigProvider>
|
||||
```
|
||||
|
||||
<img src="https://gw.alipayobjects.com/zos/antfincdn/MY%26THAPZrW/38f06cb9-293a-4b42-b183-9f443e79ffea.png" style="box-shadow: none; margin: 0" width="100px" height="64px" alt="移除两个汉字之间的空格" />
|
||||
|
||||
<style>
|
||||
.site-button-ghost-wrapper {
|
||||
padding: 16px;
|
||||
|
||||
@@ -13,7 +13,6 @@ export type { ComponentToken };
|
||||
// ============================== Shared ==============================
|
||||
const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSSObject => {
|
||||
const { componentCls, iconCls, fontWeight } = token;
|
||||
|
||||
return {
|
||||
[componentCls]: {
|
||||
outline: 'none',
|
||||
@@ -41,6 +40,10 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
|
||||
|
||||
[`${componentCls}-icon`]: {
|
||||
lineHeight: 0,
|
||||
// iconPosition in end
|
||||
[`&-end`]: {
|
||||
marginInlineStart: token.marginXS,
|
||||
},
|
||||
},
|
||||
|
||||
// Leave a space between icon and text.
|
||||
@@ -52,6 +55,9 @@ const genSharedButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token): CSS
|
||||
[`&${componentCls}-loading-icon, &:not(:last-child)`]: {
|
||||
marginInlineEnd: token.marginXS,
|
||||
},
|
||||
[`&${componentCls}-loading-icon-end`]: {
|
||||
marginInlineStart: token.marginXS,
|
||||
},
|
||||
},
|
||||
|
||||
'> a': {
|
||||
@@ -368,7 +374,7 @@ const genTextButtonStyle: GenerateStyle<ButtonToken, CSSObject> = (token) => ({
|
||||
},
|
||||
{
|
||||
color: token.colorErrorHover,
|
||||
background: token.colorErrorBg,
|
||||
background: token.colorErrorBgActive,
|
||||
},
|
||||
),
|
||||
},
|
||||
|
||||
@@ -82,6 +82,12 @@ const useStyle = createStyles(({ token, css, cx }) => {
|
||||
opacity: 0.8;
|
||||
}
|
||||
`,
|
||||
weekend: css`
|
||||
color: ${token.colorError};
|
||||
&.gray {
|
||||
opacity: .4
|
||||
}
|
||||
`,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -89,9 +95,11 @@ const App: React.FC = () => {
|
||||
const { styles } = useStyle({ test: true });
|
||||
|
||||
const [selectDate, setSelectDate] = React.useState<Dayjs>(dayjs());
|
||||
const [panelDateDate, setPanelDate] = React.useState<Dayjs>(dayjs());
|
||||
|
||||
const onPanelChange = (value: Dayjs, mode: CalendarProps<Dayjs>['mode']) => {
|
||||
console.log(value.format('YYYY-MM-DD'), mode);
|
||||
setPanelDate(value);
|
||||
};
|
||||
|
||||
const onDateChange: CalendarProps<Dayjs>['onSelect'] = (value, selectInfo) => {
|
||||
@@ -104,6 +112,7 @@ const App: React.FC = () => {
|
||||
const d = Lunar.fromDate(date.toDate());
|
||||
const lunar = d.getDayInChinese();
|
||||
const solarTerm = d.getJieQi();
|
||||
const isWeekend = date.day() === 6 || date.day() === 0;
|
||||
const h = HolidayUtil.getHoliday(date.get('year'), date.get('month') + 1, date.get('date'));
|
||||
const displayHoliday = h?.getTarget() === h?.getDay() ? h?.getName() : undefined;
|
||||
if (info.type === 'date') {
|
||||
@@ -115,7 +124,14 @@ const App: React.FC = () => {
|
||||
}),
|
||||
children: (
|
||||
<div className={styles.text}>
|
||||
{date.get('date')}
|
||||
<span
|
||||
className={classNames({
|
||||
[styles.weekend]: isWeekend,
|
||||
gray: !panelDateDate.isSame(date, 'month'),
|
||||
})}
|
||||
>
|
||||
{date.get('date')}
|
||||
</span>
|
||||
{info.type === 'date' && (
|
||||
<div className={styles.lunar}>{displayHoliday || solarTerm || lunar}</div>
|
||||
)}
|
||||
|
||||
@@ -364,7 +364,7 @@ const genCardStyle: GenerateStyle<CardToken> = (token): CSSObject => {
|
||||
},
|
||||
|
||||
[`${componentCls}-contain-tabs`]: {
|
||||
[`> ${componentCls}-head`]: {
|
||||
[`> div${componentCls}-head`]: {
|
||||
minHeight: 0,
|
||||
[`${componentCls}-head-title, ${componentCls}-extra`]: {
|
||||
paddingTop: cardHeadPadding,
|
||||
|
||||
@@ -1,5 +1,316 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders components/carousel/demo/arrows.tsx extend context correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
class="ant-carousel"
|
||||
>
|
||||
<div
|
||||
class="slick-slider slick-initialized"
|
||||
dir="ltr"
|
||||
>
|
||||
<button
|
||||
aria-label="prev"
|
||||
class="slick-arrow slick-prev slick-disabled"
|
||||
currentslide="0"
|
||||
data-role="none"
|
||||
slidecount="4"
|
||||
style="display: block;"
|
||||
type="button"
|
||||
/>
|
||||
<div
|
||||
class="slick-list"
|
||||
>
|
||||
<div
|
||||
class="slick-track"
|
||||
style="opacity: 1; transform: translate3d(0px, 0px, 0px);"
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
<button
|
||||
aria-label="next"
|
||||
class="slick-arrow slick-next"
|
||||
currentslide="0"
|
||||
data-role="none"
|
||||
slidecount="4"
|
||||
style="display: block;"
|
||||
type="button"
|
||||
/>
|
||||
<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>,
|
||||
<br />,
|
||||
<div
|
||||
class="ant-carousel ant-carousel-vertical"
|
||||
>
|
||||
<div
|
||||
class="slick-slider slick-vertical slick-initialized"
|
||||
dir="ltr"
|
||||
>
|
||||
<button
|
||||
aria-label="prev"
|
||||
class="slick-arrow slick-prev slick-disabled"
|
||||
currentslide="0"
|
||||
data-role="none"
|
||||
slidecount="4"
|
||||
style="display: block;"
|
||||
type="button"
|
||||
/>
|
||||
<div
|
||||
class="slick-list"
|
||||
style="height: 0px;"
|
||||
>
|
||||
<div
|
||||
class="slick-track"
|
||||
style="opacity: 1; transform: translate3d(0px, 0px, 0px);"
|
||||
>
|
||||
<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>
|
||||
</div>
|
||||
<button
|
||||
aria-label="next"
|
||||
class="slick-arrow slick-next"
|
||||
currentslide="0"
|
||||
data-role="none"
|
||||
slidecount="4"
|
||||
style="display: block;"
|
||||
type="button"
|
||||
/>
|
||||
<ul
|
||||
class="slick-dots slick-dots-left"
|
||||
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/arrows.tsx extend context correctly 2`] = `
|
||||
[
|
||||
"Warning: React does not recognize the \`%s\` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase \`%s\` instead. If you accidentally passed it from a parent component, remove it from the DOM element.%s",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders components/carousel/demo/autoplay.tsx extend context correctly 1`] = `
|
||||
<div
|
||||
class="ant-carousel"
|
||||
|
||||
@@ -1,5 +1,309 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders components/carousel/demo/arrows.tsx correctly 1`] = `
|
||||
Array [
|
||||
<div
|
||||
class="ant-carousel"
|
||||
>
|
||||
<div
|
||||
class="slick-slider slick-initialized"
|
||||
dir="ltr"
|
||||
>
|
||||
<button
|
||||
aria-label="prev"
|
||||
class="slick-arrow slick-prev slick-disabled"
|
||||
currentslide="0"
|
||||
data-role="none"
|
||||
slidecount="4"
|
||||
style="display:block"
|
||||
type="button"
|
||||
/>
|
||||
<div
|
||||
class="slick-list"
|
||||
>
|
||||
<div
|
||||
class="slick-track"
|
||||
style="width:400%;left:0%"
|
||||
>
|
||||
<div
|
||||
aria-hidden="false"
|
||||
class="slick-slide slick-active slick-current"
|
||||
data-index="0"
|
||||
style="outline:none;width:25%"
|
||||
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:25%"
|
||||
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:25%"
|
||||
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:25%"
|
||||
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>
|
||||
<button
|
||||
aria-label="next"
|
||||
class="slick-arrow slick-next"
|
||||
currentslide="0"
|
||||
data-role="none"
|
||||
slidecount="4"
|
||||
style="display:block"
|
||||
type="button"
|
||||
/>
|
||||
<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>,
|
||||
<br />,
|
||||
<div
|
||||
class="ant-carousel ant-carousel-vertical"
|
||||
>
|
||||
<div
|
||||
class="slick-slider slick-vertical slick-initialized"
|
||||
dir="ltr"
|
||||
>
|
||||
<button
|
||||
aria-label="prev"
|
||||
class="slick-arrow slick-prev slick-disabled"
|
||||
currentslide="0"
|
||||
data-role="none"
|
||||
slidecount="4"
|
||||
style="display:block"
|
||||
type="button"
|
||||
/>
|
||||
<div
|
||||
class="slick-list"
|
||||
>
|
||||
<div
|
||||
class="slick-track"
|
||||
style="width:400%;left:0%"
|
||||
>
|
||||
<div
|
||||
aria-hidden="false"
|
||||
class="slick-slide slick-active slick-current"
|
||||
data-index="0"
|
||||
style="outline:none;width:25%"
|
||||
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:25%"
|
||||
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:25%"
|
||||
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:25%"
|
||||
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>
|
||||
<button
|
||||
aria-label="next"
|
||||
class="slick-arrow slick-next"
|
||||
currentslide="0"
|
||||
data-role="none"
|
||||
slidecount="4"
|
||||
style="display:block"
|
||||
type="button"
|
||||
/>
|
||||
<ul
|
||||
class="slick-dots slick-dots-left"
|
||||
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/autoplay.tsx correctly 1`] = `
|
||||
<div
|
||||
class="ant-carousel"
|
||||
|
||||
7
components/carousel/demo/arrows.md
Normal file
7
components/carousel/demo/arrows.md
Normal file
@@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
显示切换箭头。
|
||||
|
||||
## en-US
|
||||
|
||||
Show the arrows for switching.
|
||||
47
components/carousel/demo/arrows.tsx
Normal file
47
components/carousel/demo/arrows.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import React from 'react';
|
||||
import { Carousel } from 'antd';
|
||||
|
||||
const contentStyle: React.CSSProperties = {
|
||||
margin: 0,
|
||||
height: '160px',
|
||||
color: '#fff',
|
||||
lineHeight: '160px',
|
||||
textAlign: 'center',
|
||||
background: '#364d79',
|
||||
};
|
||||
|
||||
const App: React.FC = () => (
|
||||
<>
|
||||
<Carousel arrows infinite={false}>
|
||||
<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>
|
||||
<br />
|
||||
<Carousel arrows dotPosition="left" infinite={false}>
|
||||
<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>
|
||||
</>
|
||||
);
|
||||
|
||||
export default App;
|
||||
@@ -22,6 +22,7 @@ demo:
|
||||
<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/arrows.tsx" version="5.17.0">Arrows for switching</code>
|
||||
<code src="./demo/component-token.tsx" debug>Component Token</code>
|
||||
|
||||
## API
|
||||
@@ -30,6 +31,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| arrows | Whether to show switch arrows | boolean | false | 5.17.0 |
|
||||
| autoplay | Whether to scroll automatically | boolean | false | |
|
||||
| autoplaySpeed | Delay between each auto scroll (in milliseconds) | number | 3000 | |
|
||||
| dotPosition | The position of the dots, which can be one of `top` `bottom` `left` `right` | string | `bottom` | |
|
||||
|
||||
@@ -35,6 +35,8 @@ const Carousel = React.forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
||||
const {
|
||||
dots = true,
|
||||
arrows = false,
|
||||
prevArrow = <button type="button" aria-label="prev" />,
|
||||
nextArrow = <button type="button" aria-label="next" />,
|
||||
draggable = false,
|
||||
waitForAnimate = false,
|
||||
dotPosition = 'bottom',
|
||||
@@ -115,6 +117,8 @@ const Carousel = React.forwardRef<CarouselRef, CarouselProps>((props, ref) => {
|
||||
dots={enableDots}
|
||||
dotsClass={dsClass}
|
||||
arrows={arrows}
|
||||
prevArrow={prevArrow}
|
||||
nextArrow={nextArrow}
|
||||
draggable={draggable}
|
||||
verticalSwiping={vertical}
|
||||
waitForAnimate={waitForAnimate}
|
||||
|
||||
@@ -23,6 +23,7 @@ demo:
|
||||
<code src="./demo/position.tsx">位置</code>
|
||||
<code src="./demo/autoplay.tsx">自动切换</code>
|
||||
<code src="./demo/fade.tsx">渐显</code>
|
||||
<code src="./demo/arrows.tsx" version="5.17.0">切换箭头</code>
|
||||
<code src="./demo/component-token.tsx" debug>组件 Token</code>
|
||||
|
||||
## API
|
||||
@@ -31,6 +32,7 @@ demo:
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| arrows | 是否显示箭头 | boolean | false | 5.17.0 |
|
||||
| autoplay | 是否自动切换 | boolean | false | |
|
||||
| autoplaySpeed | 自动切换的间隔(毫秒) | number | 3000 | |
|
||||
| dotPosition | 面板指示点位置,可选 `top` `bottom` `left` `right` | string | `bottom` | |
|
||||
|
||||
@@ -2,7 +2,7 @@ import { unit } from '@ant-design/cssinjs';
|
||||
|
||||
import { resetComponent } from '../../style';
|
||||
import type { FullToken, GenerateStyle, GetDefaultToken } from '../../theme/internal';
|
||||
import { genStyleHooks, mergeToken } from '../../theme/internal';
|
||||
import { genStyleHooks } from '../../theme/internal';
|
||||
|
||||
export interface ComponentToken {
|
||||
/**
|
||||
@@ -15,6 +15,16 @@ export interface ComponentToken {
|
||||
* @descEN Height of indicator
|
||||
*/
|
||||
dotHeight: number;
|
||||
/**
|
||||
* @desc 指示点之间的间距
|
||||
* @descEN gap between indicator
|
||||
*/
|
||||
dotGap: number;
|
||||
/**
|
||||
* @desc 指示点距离边缘的距离
|
||||
* @descEN dot offset to Carousel edge
|
||||
*/
|
||||
dotOffset: number;
|
||||
/** @deprecated Use `dotActiveWidth` instead. */
|
||||
dotWidthActive: number;
|
||||
/**
|
||||
@@ -22,19 +32,22 @@ export interface ComponentToken {
|
||||
* @descEN Width of active indicator
|
||||
*/
|
||||
dotActiveWidth: number;
|
||||
/**
|
||||
* @desc 切换箭头大小
|
||||
* @descEN Size of arrows
|
||||
*/
|
||||
arrowSize: number;
|
||||
/**
|
||||
* @desc 切换箭头边距
|
||||
* @descEN arrows offset to Carousel edge
|
||||
*/
|
||||
arrowOffset: number;
|
||||
}
|
||||
|
||||
interface CarouselToken extends FullToken<'Carousel'> {
|
||||
carouselArrowSize: string | number;
|
||||
carouselDotOffset: string | number;
|
||||
carouselDotInline: string | number;
|
||||
}
|
||||
interface CarouselToken extends FullToken<'Carousel'> {}
|
||||
|
||||
const genCarouselStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
const { componentCls, antCls, carouselArrowSize, carouselDotOffset, marginXXS } = token;
|
||||
const arrowOffset = token.calc(carouselArrowSize).mul(-1.25).equal();
|
||||
|
||||
const carouselDotMargin = marginXXS;
|
||||
const { componentCls, antCls } = token;
|
||||
|
||||
return {
|
||||
[componentCls]: {
|
||||
@@ -133,142 +146,176 @@ const genCarouselStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
display: 'block',
|
||||
height: 'auto',
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
'.slick-arrow.slick-hidden': {
|
||||
display: 'none',
|
||||
},
|
||||
const genArrowsStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
const { componentCls, motionDurationSlow, arrowSize, arrowOffset } = token;
|
||||
const arrowLength = token.calc(arrowSize).div(1.414).equal();
|
||||
|
||||
// Arrows
|
||||
'.slick-prev, .slick-next': {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
display: 'block',
|
||||
width: carouselArrowSize,
|
||||
height: carouselArrowSize,
|
||||
marginTop: token.calc(carouselArrowSize).mul(-1).div(2).equal(),
|
||||
padding: 0,
|
||||
color: 'transparent',
|
||||
fontSize: 0,
|
||||
lineHeight: 0,
|
||||
background: 'transparent',
|
||||
border: 0,
|
||||
outline: 'none',
|
||||
cursor: 'pointer',
|
||||
|
||||
'&:hover, &:focus': {
|
||||
color: 'transparent',
|
||||
return [
|
||||
{
|
||||
[componentCls]: {
|
||||
// Arrows
|
||||
'.slick-prev, .slick-next': {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
width: arrowSize,
|
||||
height: arrowSize,
|
||||
transform: 'translateY(-50%)',
|
||||
color: '#fff',
|
||||
opacity: 0.4,
|
||||
background: 'transparent',
|
||||
padding: 0,
|
||||
lineHeight: 0,
|
||||
border: 0,
|
||||
outline: 'none',
|
||||
cursor: 'pointer',
|
||||
zIndex: 1,
|
||||
transition: `opacity ${motionDurationSlow}`,
|
||||
|
||||
'&::before': {
|
||||
'&:hover, &:focus': {
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
|
||||
'&.slick-disabled::before': {
|
||||
opacity: 0.25,
|
||||
},
|
||||
},
|
||||
|
||||
'.slick-prev': {
|
||||
insetInlineStart: arrowOffset,
|
||||
|
||||
'&::before': {
|
||||
content: '"←"',
|
||||
},
|
||||
},
|
||||
|
||||
'.slick-next': {
|
||||
insetInlineEnd: arrowOffset,
|
||||
|
||||
'&::before': {
|
||||
content: '"→"',
|
||||
},
|
||||
},
|
||||
|
||||
// Dots
|
||||
'.slick-dots': {
|
||||
position: 'absolute',
|
||||
insetInlineEnd: 0,
|
||||
bottom: 0,
|
||||
insetInlineStart: 0,
|
||||
zIndex: 15,
|
||||
display: 'flex !important',
|
||||
justifyContent: 'center',
|
||||
paddingInlineStart: 0,
|
||||
margin: 0,
|
||||
listStyle: 'none',
|
||||
|
||||
'&-bottom': {
|
||||
bottom: carouselDotOffset,
|
||||
},
|
||||
|
||||
'&-top': {
|
||||
top: carouselDotOffset,
|
||||
bottom: 'auto',
|
||||
},
|
||||
|
||||
li: {
|
||||
position: 'relative',
|
||||
display: 'inline-block',
|
||||
flex: '0 1 auto',
|
||||
boxSizing: 'content-box',
|
||||
width: token.dotWidth,
|
||||
height: token.dotHeight,
|
||||
marginInline: carouselDotMargin,
|
||||
padding: 0,
|
||||
textAlign: 'center',
|
||||
textIndent: -999,
|
||||
verticalAlign: 'top',
|
||||
transition: `all ${token.motionDurationSlow}`,
|
||||
|
||||
button: {
|
||||
position: 'relative',
|
||||
display: 'block',
|
||||
width: '100%',
|
||||
height: token.dotHeight,
|
||||
padding: 0,
|
||||
color: 'transparent',
|
||||
fontSize: 0,
|
||||
background: token.colorBgContainer,
|
||||
border: 0,
|
||||
borderRadius: token.dotHeight,
|
||||
outline: 'none',
|
||||
cursor: 'pointer',
|
||||
opacity: 0.3,
|
||||
transition: `all ${token.motionDurationSlow}`,
|
||||
|
||||
'&: hover, &:focus': {
|
||||
opacity: 0.75,
|
||||
},
|
||||
|
||||
'&::after': {
|
||||
position: 'absolute',
|
||||
inset: token.calc(carouselDotMargin).mul(-1).equal(),
|
||||
content: '""',
|
||||
},
|
||||
'&.slick-disabled': {
|
||||
pointerEvents: 'none',
|
||||
opacity: 0,
|
||||
},
|
||||
|
||||
'&.slick-active': {
|
||||
width: token.dotActiveWidth,
|
||||
'&::after': {
|
||||
boxSizing: 'border-box',
|
||||
position: 'absolute',
|
||||
top: token.calc(arrowSize).sub(arrowLength).div(2).equal(),
|
||||
insetInlineStart: token.calc(arrowSize).sub(arrowLength).div(2).equal(),
|
||||
display: 'inline-block',
|
||||
width: arrowLength,
|
||||
height: arrowLength,
|
||||
border: `0 solid currentcolor`,
|
||||
borderInlineWidth: '2px 0',
|
||||
borderBlockWidth: '2px 0',
|
||||
borderRadius: 1,
|
||||
content: '""',
|
||||
},
|
||||
},
|
||||
|
||||
'& button': {
|
||||
background: token.colorBgContainer,
|
||||
opacity: 1,
|
||||
'.slick-prev': {
|
||||
insetInlineStart: arrowOffset,
|
||||
|
||||
'&::after': {
|
||||
transform: 'rotate(-45deg)',
|
||||
},
|
||||
},
|
||||
|
||||
'.slick-next': {
|
||||
insetInlineEnd: arrowOffset,
|
||||
|
||||
'&::after': {
|
||||
transform: 'rotate(135deg)',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
const genDotsStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
const {
|
||||
componentCls,
|
||||
dotOffset,
|
||||
dotWidth,
|
||||
dotHeight,
|
||||
dotGap,
|
||||
colorBgContainer,
|
||||
motionDurationSlow,
|
||||
} = token;
|
||||
return [
|
||||
{
|
||||
[componentCls]: {
|
||||
'.slick-dots': {
|
||||
position: 'absolute',
|
||||
insetInlineEnd: 0,
|
||||
bottom: 0,
|
||||
insetInlineStart: 0,
|
||||
zIndex: 15,
|
||||
display: 'flex !important',
|
||||
justifyContent: 'center',
|
||||
paddingInlineStart: 0,
|
||||
margin: 0,
|
||||
listStyle: 'none',
|
||||
|
||||
'&-bottom': {
|
||||
bottom: dotOffset,
|
||||
},
|
||||
|
||||
'&-top': {
|
||||
top: dotOffset,
|
||||
bottom: 'auto',
|
||||
},
|
||||
|
||||
li: {
|
||||
position: 'relative',
|
||||
display: 'inline-block',
|
||||
flex: '0 1 auto',
|
||||
boxSizing: 'content-box',
|
||||
width: dotWidth,
|
||||
height: dotHeight,
|
||||
marginInline: dotGap,
|
||||
padding: 0,
|
||||
textAlign: 'center',
|
||||
textIndent: -999,
|
||||
verticalAlign: 'top',
|
||||
transition: `all ${motionDurationSlow}`,
|
||||
|
||||
button: {
|
||||
position: 'relative',
|
||||
display: 'block',
|
||||
width: '100%',
|
||||
height: dotHeight,
|
||||
padding: 0,
|
||||
color: 'transparent',
|
||||
fontSize: 0,
|
||||
background: colorBgContainer,
|
||||
border: 0,
|
||||
borderRadius: dotHeight,
|
||||
outline: 'none',
|
||||
cursor: 'pointer',
|
||||
opacity: 0.2,
|
||||
transition: `all ${motionDurationSlow}`,
|
||||
|
||||
'&: hover, &:focus': {
|
||||
opacity: 0.75,
|
||||
},
|
||||
|
||||
'&::after': {
|
||||
position: 'absolute',
|
||||
inset: token.calc(dotGap).mul(-1).equal(),
|
||||
content: '""',
|
||||
},
|
||||
},
|
||||
|
||||
'&: hover, &:focus': {
|
||||
opacity: 1,
|
||||
'&.slick-active': {
|
||||
width: token.dotActiveWidth,
|
||||
|
||||
'& button': {
|
||||
background: colorBgContainer,
|
||||
opacity: 1,
|
||||
},
|
||||
|
||||
'&: hover, &:focus': {
|
||||
opacity: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
];
|
||||
};
|
||||
|
||||
const genCarouselVerticalStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
const { componentCls, carouselDotOffset, marginXXS } = token;
|
||||
const { componentCls, dotOffset, arrowOffset, marginXXS } = token;
|
||||
|
||||
const reverseSizeOfDot = {
|
||||
width: token.dotHeight,
|
||||
@@ -277,6 +324,26 @@ const genCarouselVerticalStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
|
||||
return {
|
||||
[`${componentCls}-vertical`]: {
|
||||
'.slick-prev, .slick-next': {
|
||||
insetInlineStart: '50%',
|
||||
marginBlockStart: 'unset',
|
||||
transform: 'translateX(-50%)',
|
||||
},
|
||||
'.slick-prev': {
|
||||
insetBlockStart: arrowOffset,
|
||||
insetInlineStart: '50%',
|
||||
|
||||
'&::after': {
|
||||
transform: 'rotate(45deg)',
|
||||
},
|
||||
},
|
||||
'.slick-next': {
|
||||
insetBlockStart: 'auto',
|
||||
insetBlockEnd: arrowOffset,
|
||||
'&::after': {
|
||||
transform: 'rotate(-135deg)',
|
||||
},
|
||||
},
|
||||
'.slick-dots': {
|
||||
top: '50%',
|
||||
bottom: 'auto',
|
||||
@@ -288,11 +355,11 @@ const genCarouselVerticalStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
|
||||
'&-left': {
|
||||
insetInlineEnd: 'auto',
|
||||
insetInlineStart: carouselDotOffset,
|
||||
insetInlineStart: dotOffset,
|
||||
},
|
||||
|
||||
'&-right': {
|
||||
insetInlineEnd: carouselDotOffset,
|
||||
insetInlineEnd: dotOffset,
|
||||
insetInlineStart: 'auto',
|
||||
},
|
||||
|
||||
@@ -343,12 +410,16 @@ const genCarouselRtlStyle: GenerateStyle<CarouselToken> = (token) => {
|
||||
];
|
||||
};
|
||||
|
||||
export const prepareComponentToken: GetDefaultToken<'Carousel'> = () => {
|
||||
export const prepareComponentToken: GetDefaultToken<'Carousel'> = (token) => {
|
||||
const dotActiveWidth = 24;
|
||||
|
||||
return {
|
||||
arrowSize: 16,
|
||||
arrowOffset: token.marginXS,
|
||||
dotWidth: 16,
|
||||
dotHeight: 3,
|
||||
dotGap: token.marginXXS,
|
||||
dotOffset: 12,
|
||||
dotWidthActive: dotActiveWidth,
|
||||
dotActiveWidth,
|
||||
};
|
||||
@@ -357,19 +428,13 @@ export const prepareComponentToken: GetDefaultToken<'Carousel'> = () => {
|
||||
// ============================== Export ==============================
|
||||
export default genStyleHooks(
|
||||
'Carousel',
|
||||
(token) => {
|
||||
const { controlHeightLG, controlHeightSM } = token;
|
||||
const carouselToken = mergeToken<CarouselToken>(token, {
|
||||
carouselArrowSize: token.calc(controlHeightLG).div(2).equal(),
|
||||
carouselDotOffset: token.calc(controlHeightSM).div(2).equal(),
|
||||
});
|
||||
|
||||
return [
|
||||
genCarouselStyle(carouselToken),
|
||||
genCarouselVerticalStyle(carouselToken),
|
||||
genCarouselRtlStyle(carouselToken),
|
||||
];
|
||||
},
|
||||
(token) => [
|
||||
genCarouselStyle(token),
|
||||
genArrowsStyle(token),
|
||||
genDotsStyle(token),
|
||||
genCarouselVerticalStyle(token),
|
||||
genCarouselRtlStyle(token),
|
||||
],
|
||||
prepareComponentToken,
|
||||
{
|
||||
deprecatedTokens: [['dotWidthActive', 'dotActiveWidth']],
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import * as React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import type { CascaderProps as RcCascaderProps } from 'rc-cascader';
|
||||
import { Panel } from 'rc-cascader';
|
||||
import type { PickType } from 'rc-cascader/lib/Panel';
|
||||
|
||||
import type { CascaderProps } from '.';
|
||||
import type { CascaderProps, DefaultOptionType } from '.';
|
||||
import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty';
|
||||
import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
|
||||
import useBase from './hooks/useBase';
|
||||
@@ -14,9 +15,23 @@ import usePanelStyle from './style/panel';
|
||||
|
||||
export type PanelPickType = Exclude<PickType, 'checkable'> | 'multiple' | 'rootClassName';
|
||||
|
||||
export type CascaderPanelProps = Pick<CascaderProps, PanelPickType>;
|
||||
export type CascaderPanelProps<
|
||||
OptionType extends DefaultOptionType = DefaultOptionType,
|
||||
ValueField extends keyof OptionType = keyof OptionType,
|
||||
Multiple extends boolean = false,
|
||||
> = Pick<CascaderProps<OptionType, ValueField, Multiple>, PanelPickType>;
|
||||
|
||||
const CascaderPanel: React.FC<CascaderPanelProps> = (props) => {
|
||||
export type CascaderPanelAutoProps<
|
||||
OptionType extends DefaultOptionType = DefaultOptionType,
|
||||
ValueField extends keyof OptionType = keyof OptionType,
|
||||
> =
|
||||
| CascaderPanelProps<OptionType, ValueField>
|
||||
| (CascaderPanelProps<OptionType, ValueField, true> & { multiple: true });
|
||||
|
||||
function CascaderPanel<
|
||||
OptionType extends DefaultOptionType = DefaultOptionType,
|
||||
ValueField extends keyof OptionType = keyof OptionType,
|
||||
>(props: CascaderPanelAutoProps<OptionType, ValueField>) {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
className,
|
||||
@@ -53,7 +68,7 @@ const CascaderPanel: React.FC<CascaderPanelProps> = (props) => {
|
||||
|
||||
return wrapCSSVar(
|
||||
<Panel
|
||||
{...props}
|
||||
{...(props as Pick<RcCascaderProps, PickType>)}
|
||||
checkable={checkable}
|
||||
prefixCls={cascaderPrefixCls}
|
||||
className={classNames(className, hashId, rootClassName, cssVarCls, rootCls)}
|
||||
@@ -63,6 +78,6 @@ const CascaderPanel: React.FC<CascaderPanelProps> = (props) => {
|
||||
loadingIcon={loadingIcon}
|
||||
/>,
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
export default CascaderPanel;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import type { SingleValueType } from 'rc-cascader/lib/Cascader';
|
||||
|
||||
import type { BaseOptionType, DefaultOptionType } from '..';
|
||||
import type { DefaultOptionType } from '..';
|
||||
import Cascader from '..';
|
||||
import { resetWarned } from '../../_util/warning';
|
||||
import excludeAllWarning from '../../../tests/shared/excludeWarning';
|
||||
@@ -71,11 +71,13 @@ const options = [
|
||||
},
|
||||
];
|
||||
|
||||
function filter<OptionType extends BaseOptionType = DefaultOptionType>(
|
||||
function filter<OptionType extends DefaultOptionType = DefaultOptionType>(
|
||||
inputValue: string,
|
||||
path: OptionType[],
|
||||
): boolean {
|
||||
return path.some((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()));
|
||||
return path.some((option) =>
|
||||
option.label?.toString().toLowerCase().includes(inputValue.toLowerCase()),
|
||||
);
|
||||
}
|
||||
|
||||
describe('Cascader', () => {
|
||||
@@ -183,7 +185,7 @@ describe('Cascader', () => {
|
||||
],
|
||||
},
|
||||
];
|
||||
function customFilter<OptionType extends BaseOptionType = DefaultOptionType>(
|
||||
function customFilter<OptionType extends DefaultOptionType = DefaultOptionType>(
|
||||
inputValue: string,
|
||||
path: OptionType[],
|
||||
): boolean {
|
||||
@@ -374,7 +376,7 @@ describe('Cascader', () => {
|
||||
{
|
||||
value: 'hangzhou',
|
||||
label: 'Hangzhou',
|
||||
children: null,
|
||||
children: null as any,
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -516,7 +518,7 @@ describe('Cascader', () => {
|
||||
|
||||
it('onChange works correctly when the label of fieldNames is the same as value', () => {
|
||||
const onChange = jest.fn();
|
||||
const sameNames = { label: 'label', value: 'label' };
|
||||
const sameNames = { label: 'label', value: 'label' } as const;
|
||||
const { container } = render(
|
||||
<Cascader options={options} onChange={onChange} showSearch fieldNames={sameNames} />,
|
||||
);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import type { BaseOptionType } from '..';
|
||||
import type { BaseOptionType, CascaderAutoProps } from '..';
|
||||
import Cascader from '..';
|
||||
import { render } from '../../../tests/utils';
|
||||
import type { CascaderPanelAutoProps } from '../Panel';
|
||||
|
||||
describe('Cascader.typescript', () => {
|
||||
it('options value', () => {
|
||||
@@ -80,16 +81,25 @@ describe('Cascader.typescript', () => {
|
||||
});
|
||||
|
||||
it('single onChange', () => {
|
||||
const { container } = render(
|
||||
<Cascader multiple={false} onChange={(values: (string | number)[]) => values} />,
|
||||
);
|
||||
const { container } = render(<Cascader multiple={false} onChange={(values) => values} />);
|
||||
expect(container).toBeTruthy();
|
||||
});
|
||||
|
||||
it('multiple onChange', () => {
|
||||
const { container } = render(
|
||||
<Cascader multiple onChange={(values: (string | number)[][]) => values} />,
|
||||
);
|
||||
const { container } = render(<Cascader multiple onChange={(values) => values} />);
|
||||
expect(container).toBeTruthy();
|
||||
});
|
||||
it('props', () => {
|
||||
const list: { props?: CascaderAutoProps }[] = [
|
||||
{ props: { multiple: true, onChange: (value) => value } },
|
||||
{ props: { multiple: false, onChange: (value) => value } },
|
||||
];
|
||||
expect(list).toBeTruthy();
|
||||
|
||||
const list2: { props?: CascaderPanelAutoProps }[] = [
|
||||
{ props: { multiple: true, onChange: (value) => value } },
|
||||
{ props: { multiple: false, onChange: (value) => value } },
|
||||
];
|
||||
expect(list2).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
interface Option {
|
||||
value: string | number;
|
||||
value: string;
|
||||
label: string;
|
||||
children?: Option[];
|
||||
}
|
||||
@@ -42,7 +43,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange = (value: (string | number)[]) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
@@ -43,7 +43,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
@@ -34,7 +34,7 @@ const options: Option[] = [
|
||||
const App: React.FC = () => {
|
||||
const [text, setText] = useState('Unselect');
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (_, selectedOptions) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (_, selectedOptions) => {
|
||||
setText(selectedOptions.map((o) => o.label).join(', '));
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
@@ -43,7 +43,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
@@ -45,7 +45,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
code: string;
|
||||
@@ -43,7 +43,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
@@ -43,7 +43,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { useState } from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
|
||||
interface Option {
|
||||
@@ -24,7 +25,7 @@ const optionLists: Option[] = [
|
||||
const App: React.FC = () => {
|
||||
const [options, setOptions] = useState<Option[]>(optionLists);
|
||||
|
||||
const onChange = (value: (string | number)[], selectedOptions: Option[]) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value, selectedOptions) => {
|
||||
console.log(value, selectedOptions);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { MultipleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string | number;
|
||||
@@ -44,7 +44,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: MultipleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option, 'value', true>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader, Flex } from 'antd';
|
||||
import type { MultipleCascaderProps, SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string | number;
|
||||
@@ -43,11 +43,11 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
const onMultipleChange: MultipleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onMultipleChange: CascaderProps<Option, 'value', true>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Cascader } from 'antd';
|
||||
import type { CascaderProps, GetProp } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
type DefaultOptionType = GetProp<CascaderProps, 'options'>[number];
|
||||
|
||||
@@ -52,7 +51,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value, selectedOptions) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value, selectedOptions) => {
|
||||
console.log(value, selectedOptions);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { MultipleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
const { SHOW_CHILD } = Cascader;
|
||||
|
||||
@@ -44,7 +44,7 @@ const options: Option[] = [
|
||||
];
|
||||
|
||||
const App: React.FC = () => {
|
||||
const onChange: MultipleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option, 'value', true>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
return (
|
||||
@@ -70,7 +70,7 @@ const App: React.FC = () => {
|
||||
onChange={onChange}
|
||||
multiple
|
||||
maxTagCount="responsive"
|
||||
defaultValue={['bamboo']}
|
||||
defaultValue={[['bamboo']]}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
@@ -43,7 +43,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { SmileOutlined } from '@ant-design/icons';
|
||||
import type { CascaderProps } from 'antd';
|
||||
import { Cascader } from 'antd';
|
||||
import type { SingleCascaderProps } from 'antd/es/cascader';
|
||||
|
||||
interface Option {
|
||||
value: string;
|
||||
@@ -44,7 +44,7 @@ const options: Option[] = [
|
||||
},
|
||||
];
|
||||
|
||||
const onChange: SingleCascaderProps<Option>['onChange'] = (value) => {
|
||||
const onChange: CascaderProps<Option>['onChange'] = (value) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ import type {
|
||||
BaseOptionType,
|
||||
DefaultOptionType,
|
||||
FieldNames,
|
||||
MultipleCascaderProps as RcMultipleCascaderProps,
|
||||
SingleCascaderProps as RcSingleCascaderProps,
|
||||
CascaderProps as RcCascaderProps,
|
||||
ShowSearchType,
|
||||
} from 'rc-cascader';
|
||||
import RcCascader from 'rc-cascader';
|
||||
@@ -105,51 +104,43 @@ const defaultSearchRender: ShowSearchType['render'] = (inputValue, path, prefixC
|
||||
return optionList;
|
||||
};
|
||||
|
||||
export type SingleCascaderProps<OptionType extends BaseOptionType = any> = Omit<
|
||||
RcSingleCascaderProps<OptionType>,
|
||||
'checkable' | 'options'
|
||||
> & {
|
||||
multiple?: false;
|
||||
};
|
||||
export type MultipleCascaderProps<OptionType extends BaseOptionType = any> = Omit<
|
||||
RcMultipleCascaderProps<OptionType>,
|
||||
'checkable' | 'options'
|
||||
> & {
|
||||
multiple: true;
|
||||
};
|
||||
export interface CascaderProps<
|
||||
OptionType extends DefaultOptionType = DefaultOptionType,
|
||||
ValueField extends keyof OptionType = keyof OptionType,
|
||||
Multiple extends boolean = false,
|
||||
> extends Omit<RcCascaderProps<OptionType, ValueField, Multiple>, 'checkable'> {
|
||||
multiple?: Multiple;
|
||||
size?: SizeType;
|
||||
/**
|
||||
* @deprecated `showArrow` is deprecated which will be removed in next major version. It will be a
|
||||
* default behavior, you can hide it by setting `suffixIcon` to null.
|
||||
*/
|
||||
showArrow?: boolean;
|
||||
disabled?: boolean;
|
||||
/** @deprecated Use `variant` instead. */
|
||||
bordered?: boolean;
|
||||
placement?: SelectCommonPlacement;
|
||||
suffixIcon?: React.ReactNode;
|
||||
options?: OptionType[];
|
||||
status?: InputStatus;
|
||||
autoClearSearchValue?: boolean;
|
||||
|
||||
type UnionCascaderProps<OptionType extends BaseOptionType> =
|
||||
| SingleCascaderProps<OptionType>
|
||||
| MultipleCascaderProps<OptionType>;
|
||||
|
||||
export type CascaderProps<DataNodeType extends BaseOptionType = any> =
|
||||
UnionCascaderProps<DataNodeType> & {
|
||||
multiple?: boolean;
|
||||
size?: SizeType;
|
||||
/**
|
||||
* @deprecated `showArrow` is deprecated which will be removed in next major version. It will be a
|
||||
* default behavior, you can hide it by setting `suffixIcon` to null.
|
||||
*/
|
||||
showArrow?: boolean;
|
||||
disabled?: boolean;
|
||||
/** @deprecated Use `variant` instead. */
|
||||
bordered?: boolean;
|
||||
placement?: SelectCommonPlacement;
|
||||
suffixIcon?: React.ReactNode;
|
||||
options?: DataNodeType[];
|
||||
status?: InputStatus;
|
||||
autoClearSearchValue?: boolean;
|
||||
|
||||
rootClassName?: string;
|
||||
popupClassName?: string;
|
||||
/** @deprecated Please use `popupClassName` instead */
|
||||
dropdownClassName?: string;
|
||||
/**
|
||||
* @since 5.13.0
|
||||
* @default "outlined"
|
||||
*/
|
||||
variant?: Variant;
|
||||
};
|
||||
rootClassName?: string;
|
||||
popupClassName?: string;
|
||||
/** @deprecated Please use `popupClassName` instead */
|
||||
dropdownClassName?: string;
|
||||
/**
|
||||
* @since 5.13.0
|
||||
* @default "outlined"
|
||||
*/
|
||||
variant?: Variant;
|
||||
}
|
||||
export type CascaderAutoProps<
|
||||
OptionType extends DefaultOptionType = DefaultOptionType,
|
||||
ValueField extends keyof OptionType = keyof OptionType,
|
||||
> =
|
||||
| CascaderProps<OptionType, ValueField>
|
||||
| (CascaderProps<OptionType, ValueField, true> & { multiple: true });
|
||||
|
||||
export interface CascaderRef {
|
||||
focus: () => void;
|
||||
@@ -360,8 +351,12 @@ const Cascader = React.forwardRef<CascaderRef, CascaderProps<any>>((props, ref)
|
||||
);
|
||||
|
||||
return wrapCascaderCSSVar(wrapSelectCSSVar(renderNode));
|
||||
}) as unknown as (<OptionType extends BaseOptionType | DefaultOptionType = DefaultOptionType>(
|
||||
props: React.PropsWithChildren<CascaderProps<OptionType>> & React.RefAttributes<CascaderRef>,
|
||||
}) as unknown as (<
|
||||
OptionType extends DefaultOptionType = DefaultOptionType,
|
||||
ValueField extends keyof OptionType = keyof OptionType,
|
||||
>(
|
||||
props: React.PropsWithChildren<CascaderAutoProps<OptionType, ValueField>> &
|
||||
React.RefAttributes<CascaderRef>,
|
||||
) => React.ReactElement) & {
|
||||
displayName: string;
|
||||
SHOW_PARENT: typeof SHOW_PARENT;
|
||||
|
||||
@@ -67,10 +67,11 @@ interface Option {
|
||||
|
||||
#### Checkbox
|
||||
|
||||
| Name | Description | Version |
|
||||
| ------- | ------------ | ------- |
|
||||
| blur() | Remove focus | |
|
||||
| focus() | Get focus | |
|
||||
| Name | Description | Version |
|
||||
| ------------- | ------------------------------------ | ------- |
|
||||
| blur() | Remove focus | |
|
||||
| focus() | Get focus | |
|
||||
| nativeElement | Returns the DOM node of the Checkbox | 5.17.3 |
|
||||
|
||||
## Design Token
|
||||
|
||||
|
||||
@@ -68,10 +68,11 @@ interface Option {
|
||||
|
||||
#### Checkbox
|
||||
|
||||
| 名称 | 描述 | 版本 |
|
||||
| ------- | -------- | ---- |
|
||||
| blur() | 移除焦点 | |
|
||||
| focus() | 获取焦点 | |
|
||||
| 名称 | 描述 | 版本 |
|
||||
| ------------- | ------------------------- | ------ |
|
||||
| blur() | 移除焦点 | |
|
||||
| focus() | 获取焦点 | |
|
||||
| nativeElement | 返回 Checkbox 的 DOM 节点 | 5.17.3 |
|
||||
|
||||
## 主题变量(Design Token)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## zh-CN
|
||||
|
||||
手风琴,每次只打开一个 tab。
|
||||
手风琴模式,始终只有一个面板处在激活状态。
|
||||
|
||||
## en-US
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| accordion | If true, Collapse renders as Accordion | boolean | false | |
|
||||
| activeKey | Key of the active panel | string\[] \| string <br/> number\[] \| number | No default value. In `accordion` mode, it's the key of the first panel | |
|
||||
| activeKey | Key of the active panel | string\[] \| string <br/> number\[] \| number | No default value. In [accordion mode](#components-collapse-demo-accordion), it's the key of the first panel | |
|
||||
| bordered | Toggles rendering of the border around the collapse block | boolean | true | |
|
||||
| collapsible | Specify whether the panels of children be collapsible or the trigger area of collapsible | `header` \| `icon` \| `disabled` | - | 4.9.0 |
|
||||
| defaultActiveKey | Key of the initial active panel | string\[] \| string <br/> number\[] \| number | - | |
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user