Browse Source

Merge branch 'master' into PeachScript-patch-1

PeachScript-patch-1
afc163 1 year ago
committed by GitHub
parent
commit
fa001145fa
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      .dumi/pages/index/components/Theme/ColorPicker.tsx
  2. 4
      .dumi/pages/index/components/Theme/index.tsx
  3. 62
      .dumi/theme/builtins/InstallDependencies/index.tsx
  4. 36
      .dumi/theme/builtins/InstallDependencies/npm.tsx
  5. 40
      .dumi/theme/builtins/InstallDependencies/pnpm.tsx
  6. 38
      .dumi/theme/builtins/InstallDependencies/yarn.tsx
  7. 10
      .dumi/theme/common/PrevAndNext.tsx
  8. 2
      .dumi/theme/common/styles/BrowserMockup.tsx
  9. 16
      .dumi/theme/common/styles/Markdown.tsx
  10. 2
      .dumi/theme/common/styles/Reset.tsx
  11. 2
      .dumi/theme/common/styles/Responsive.tsx
  12. 188
      .dumi/theme/slots/Content/ColumnCard.tsx
  13. 7
      .dumi/theme/slots/Content/index.tsx
  14. 9
      .dumi/theme/slots/Header/index.tsx
  15. 10
      .dumi/theme/slots/Sidebar/index.tsx
  16. 7
      .eslintrc.js
  17. 12
      .github/workflows/site-deploy.yml
  18. 17
      CHANGELOG.en-US.md
  19. 17
      CHANGELOG.zh-CN.md
  20. 4
      README.md
  21. 2
      components/app/demo/basic.md
  22. 5
      components/app/index.en-US.md
  23. 9
      components/breadcrumb/Breadcrumb.tsx
  24. 22
      components/breadcrumb/__tests__/Breadcrumb.test.tsx
  25. 2
      components/breadcrumb/demo/overlay.tsx
  26. 2
      components/breadcrumb/useItemRender.tsx
  27. 4
      components/button/button.tsx
  28. 2
      components/cascader/index.tsx
  29. 5
      components/checkbox/Checkbox.tsx
  30. 2
      components/checkbox/Group.tsx
  31. 2
      components/config-provider/index.en-US.md
  32. 2
      components/config-provider/index.tsx
  33. 2
      components/date-picker/generatePicker/generateRangePicker.tsx
  34. 2
      components/date-picker/generatePicker/generateSinglePicker.tsx
  35. 4
      components/date-picker/index.zh-CN.md
  36. 15
      components/dropdown/__tests__/dropdown-button.test.tsx
  37. 3
      components/dropdown/dropdown.tsx
  38. 1
      components/float-button/__tests__/__snapshots__/demo-extend.test.ts.snap
  39. 1
      components/float-button/__tests__/__snapshots__/demo.test.ts.snap
  40. 2
      components/float-button/demo/controlled.tsx
  41. 5
      components/form/Form.tsx
  42. 4
      components/form/context.tsx
  43. 7
      components/form/validateMessagesContext.tsx
  44. 242
      components/input-number/__tests__/__snapshots__/demo-extend.test.ts.snap
  45. 242
      components/input-number/__tests__/__snapshots__/demo.test.tsx.snap
  46. 39
      components/input-number/__tests__/addon.test.tsx
  47. 17
      components/input-number/demo/addon.tsx
  48. 3
      components/input-number/index.tsx
  49. 22
      components/input-number/style/index.ts
  50. 2
      components/input/Input.tsx
  51. 2
      components/input/Search.tsx
  52. 127
      components/input/__tests__/__snapshots__/demo-extend.test.ts.snap
  53. 127
      components/input/__tests__/__snapshots__/demo.test.tsx.snap
  54. 4
      components/input/demo/group.tsx
  55. 11
      components/input/style/index.ts
  56. 16
      components/menu/OverrideContext.tsx
  57. 4
      components/progress/demo/segment.md
  58. 2
      components/progress/index.en-US.md
  59. 2
      components/progress/index.zh-CN.md
  60. 2
      components/progress/progress.tsx
  61. 18
      components/progress/utils.ts
  62. 1
      components/radio/group.tsx
  63. 6
      components/select/index.en-US.md
  64. 2
      components/select/index.tsx
  65. 6
      components/select/index.zh-CN.md
  66. 4
      components/select/style/dropdown.tsx
  67. 5
      components/select/style/index.tsx
  68. 7
      components/slider/SliderTooltip.tsx
  69. 2
      components/space/Compact.tsx
  70. 32
      components/space/__tests__/__snapshots__/demo-extend.test.ts.snap
  71. 26
      components/space/__tests__/__snapshots__/demo.test.tsx.snap
  72. 37
      components/space/__tests__/space-compact.test.tsx
  73. 2
      components/table/__tests__/Table.filter.test.tsx
  74. 19
      components/table/hooks/useFilter/FilterWrapper.tsx
  75. 2
      components/table/index.en-US.md
  76. 2
      components/table/index.zh-CN.md
  77. 30
      components/transfer/__tests__/index.test.tsx
  78. 6
      components/transfer/hooks/useSelection.ts
  79. 2
      components/tree-select/index.tsx
  80. 2
      components/tree/index.en-US.md
  81. 2
      components/tree/index.zh-CN.md
  82. 11
      components/upload/Dragger.tsx
  83. 37
      components/upload/Upload.tsx
  84. 7
      components/upload/UploadList/ListItem.tsx
  85. 15
      components/upload/UploadList/index.tsx
  86. 7
      components/upload/__tests__/upload.test.tsx
  87. 1
      docs/blog/why-not-static.en-US.md
  88. 1
      docs/blog/why-not-static.zh-CN.md
  89. 54
      docs/react/contributing.en-US.md
  90. 54
      docs/react/contributing.zh-CN.md
  91. 4
      docs/react/customize-theme.en-US.md
  92. 4
      docs/react/customize-theme.zh-CN.md
  93. 31
      docs/react/getting-started.en-US.md
  94. 25
      docs/react/getting-started.zh-CN.md
  95. 26
      docs/react/introduce.en-US.md
  96. 24
      docs/react/introduce.zh-CN.md
  97. 12
      docs/react/migrate-less-variables.en-US.md
  98. 12
      docs/react/migrate-less-variables.zh-CN.md
  99. 41
      docs/react/use-with-create-react-app.en-US.md
  100. 41
      docs/react/use-with-create-react-app.zh-CN.md

8
.dumi/pages/index/components/Theme/ColorPicker.tsx

@ -19,7 +19,7 @@ const useStyle = () => {
transition: all ${token.motionDurationFast};
display: inline-block;
& > input[type="radio"] {
& > input[type='radio'] {
width: 0;
height: 0;
opacity: 0;
@ -138,7 +138,11 @@ export default function ThemeColorPicker({ value, onChange }: RadiusPickerProps)
if (picker) {
colorNode = (
<DebouncedColorPicker value={value || ''} onChange={onChange}>
<DebouncedColorPicker
key={`colorpicker-${value}`}
value={value || ''}
onChange={onChange}
>
{colorNode}
</DebouncedColorPicker>
);

4
.dumi/pages/index/components/Theme/index.tsx

@ -377,8 +377,8 @@ export default function Theme() {
},
Menu: isLight
? {
colorItemBg: 'transparent',
colorSubItemBg: 'transparent',
itemBg: 'transparent',
subMenuItemBg: 'transparent',
colorActiveBarWidth: 0,
}
: {

62
.dumi/theme/builtins/InstallDependencies/index.tsx

@ -1,3 +1,4 @@
import type { TabsProps } from 'antd';
import { Tabs } from 'antd';
import SourceCode from 'dumi/theme-default/builtins/SourceCode';
import React from 'react';
@ -11,46 +12,51 @@ interface InstallProps {
pnpm?: string;
}
const npmLabel = (
<span className="snippet-label">
<NpmLogo />
npm
</span>
);
const pnpmLabel = (
<span className="snippet-label">
<PnpmLogo />
pnpm
</span>
);
const yarnLabel = (
<span className="snippet-label">
<YarnLogo />
yarn
</span>
);
const InstallDependencies: React.FC<InstallProps> = (props) => {
const { npm, yarn, pnpm } = props;
return (
<Tabs
className="antd-site-snippet"
defaultActiveKey="npm"
items={[
const items = React.useMemo<TabsProps['items']>(
() =>
[
{
key: 'npm',
children: <SourceCode lang="bash">{npm}</SourceCode>,
label: (
<div className="snippet-label">
<NpmLogo />
<span>npm</span>
</div>
),
children: npm ? <SourceCode lang="bash">{npm}</SourceCode> : null,
label: npmLabel,
},
{
key: 'yarn',
children: <SourceCode lang="bash">{yarn}</SourceCode>,
label: (
<div className="snippet-label">
<YarnLogo />
<span>yarn</span>
</div>
),
children: yarn ? <SourceCode lang="bash">{yarn}</SourceCode> : null,
label: yarnLabel,
},
{
key: 'pnpm',
children: <SourceCode lang="bash">{pnpm}</SourceCode>,
label: (
<div className="snippet-label">
<PnpmLogo />
<span>pnpm</span>
</div>
),
children: pnpm ? <SourceCode lang="bash">{pnpm}</SourceCode> : null,
label: pnpmLabel,
},
]}
/>
].filter((item) => item.children),
[npm, yarn, pnpm],
);
return <Tabs className="antd-site-snippet" defaultActiveKey="npm" items={items} />;
};
export default InstallDependencies;

36
.dumi/theme/builtins/InstallDependencies/npm.tsx

@ -1,17 +1,27 @@
import React from 'react';
const NpmIcon: React.FC = () => (
<svg
fill="#E53E3E"
focusable="false"
height="1em"
stroke="#E53E3E"
strokeWidth="0"
viewBox="0 0 16 16"
width="1em"
>
<path d="M0 0v16h16v-16h-16zM13 13h-2v-8h-3v8h-5v-10h10v10z" />
</svg>
);
interface IconProps {
className?: string;
style?: React.CSSProperties;
}
const NpmIcon: React.FC<IconProps> = (props) => {
const { className, style } = props;
return (
<svg
className={className}
style={style}
fill="#E53E3E"
focusable="false"
height="1em"
stroke="#E53E3E"
strokeWidth="0"
viewBox="0 0 16 16"
width="1em"
>
<path d="M0 0v16h16v-16h-16zM13 13h-2v-8h-3v8h-5v-10h10v10z" />
</svg>
);
};
export default NpmIcon;

40
.dumi/theme/builtins/InstallDependencies/pnpm.tsx

@ -1,19 +1,29 @@
import React from 'react';
const PnpmIcon: React.FC = () => (
<svg
aria-hidden="true"
fill="#F69220"
focusable="false"
height="1em"
role="img"
stroke="#F69220"
strokeWidth="0"
viewBox="0 0 24 24"
width="1em"
>
<path d="M0 0v7.5h7.5V0zm8.25 0v7.5h7.498V0zm8.25 0v7.5H24V0zM8.25 8.25v7.5h7.498v-7.5zm8.25 0v7.5H24v-7.5zM0 16.5V24h7.5v-7.5zm8.25 0V24h7.498v-7.5zm8.25 0V24H24v-7.5z" />
</svg>
);
interface IconProps {
className?: string;
style?: React.CSSProperties;
}
const PnpmIcon: React.FC<IconProps> = (props) => {
const { className, style } = props;
return (
<svg
className={className}
style={style}
aria-hidden="true"
fill="#F69220"
focusable="false"
height="1em"
role="img"
stroke="#F69220"
strokeWidth="0"
viewBox="0 0 24 24"
width="1em"
>
<path d="M0 0v7.5h7.5V0zm8.25 0v7.5h7.498V0zm8.25 0v7.5H24V0zM8.25 8.25v7.5h7.498v-7.5zm8.25 0v7.5H24v-7.5zM0 16.5V24h7.5v-7.5zm8.25 0V24h7.498v-7.5zm8.25 0V24H24v-7.5z" />
</svg>
);
};
export default PnpmIcon;

38
.dumi/theme/builtins/InstallDependencies/yarn.tsx

@ -1,18 +1,28 @@
import React from 'react';
const YarnIcon: React.FC = () => (
<svg
aria-hidden="true"
fill="#2C8EBB"
focusable="false"
height="1em"
stroke="#2C8EBB"
strokeWidth="0"
viewBox="0 0 496 512"
width="1em"
>
<path d="M393.9 345.2c-39 9.3-48.4 32.1-104 47.4 0 0-2.7 4-10.4 5.8-13.4 3.3-63.9 6-68.5 6.1-12.4.1-19.9-3.2-22-8.2-6.4-15.3 9.2-22 9.2-22-8.1-5-9-9.9-9.8-8.1-2.4 5.8-3.6 20.1-10.1 26.5-8.8 8.9-25.5 5.9-35.3.8-10.8-5.7.8-19.2.8-19.2s-5.8 3.4-10.5-3.6c-6-9.3-17.1-37.3 11.5-62-1.3-10.1-4.6-53.7 40.6-85.6 0 0-20.6-22.8-12.9-43.3 5-13.4 7-13.3 8.6-13.9 5.7-2.2 11.3-4.6 15.4-9.1 20.6-22.2 46.8-18 46.8-18s12.4-37.8 23.9-30.4c3.5 2.3 16.3 30.6 16.3 30.6s13.6-7.9 15.1-5c8.2 16 9.2 46.5 5.6 65.1-6.1 30.6-21.4 47.1-27.6 57.5-1.4 2.4 16.5 10 27.8 41.3 10.4 28.6 1.1 52.7 2.8 55.3.8 1.4 13.7.8 36.4-13.2 12.8-7.9 28.1-16.9 45.4-17 16.7-.5 17.6 19.2 4.9 22.2zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-79.3 75.2c-1.7-13.6-13.2-23-28-22.8-22 .3-40.5 11.7-52.8 19.2-4.8 3-8.9 5.2-12.4 6.8 3.1-44.5-22.5-73.1-28.7-79.4 7.8-11.3 18.4-27.8 23.4-53.2 4.3-21.7 3-55.5-6.9-74.5-1.6-3.1-7.4-11.2-21-7.4-9.7-20-13-22.1-15.6-23.8-1.1-.7-23.6-16.4-41.4 28-12.2.9-31.3 5.3-47.5 22.8-2 2.2-5.9 3.8-10.1 5.4h.1c-8.4 3-12.3 9.9-16.9 22.3-6.5 17.4.2 34.6 6.8 45.7-17.8 15.9-37 39.8-35.7 82.5-34 36-11.8 73-5.6 79.6-1.6 11.1 3.7 19.4 12 23.8 12.6 6.7 30.3 9.6 43.9 2.8 4.9 5.2 13.8 10.1 30 10.1 6.8 0 58-2.9 72.6-6.5 6.8-1.6 11.5-4.5 14.6-7.1 9.8-3.1 36.8-12.3 62.2-28.7 18-11.7 24.2-14.2 37.6-17.4 12.9-3.2 21-15.1 19.4-28.2z" />
</svg>
);
interface IconProps {
className?: string;
style?: React.CSSProperties;
}
const YarnIcon: React.FC<IconProps> = (props) => {
const { className, style } = props;
return (
<svg
className={className}
style={style}
aria-hidden="true"
fill="#2C8EBB"
focusable="false"
height="1em"
stroke="#2C8EBB"
strokeWidth="0"
viewBox="0 0 496 512"
width="1em"
>
<path d="M393.9 345.2c-39 9.3-48.4 32.1-104 47.4 0 0-2.7 4-10.4 5.8-13.4 3.3-63.9 6-68.5 6.1-12.4.1-19.9-3.2-22-8.2-6.4-15.3 9.2-22 9.2-22-8.1-5-9-9.9-9.8-8.1-2.4 5.8-3.6 20.1-10.1 26.5-8.8 8.9-25.5 5.9-35.3.8-10.8-5.7.8-19.2.8-19.2s-5.8 3.4-10.5-3.6c-6-9.3-17.1-37.3 11.5-62-1.3-10.1-4.6-53.7 40.6-85.6 0 0-20.6-22.8-12.9-43.3 5-13.4 7-13.3 8.6-13.9 5.7-2.2 11.3-4.6 15.4-9.1 20.6-22.2 46.8-18 46.8-18s12.4-37.8 23.9-30.4c3.5 2.3 16.3 30.6 16.3 30.6s13.6-7.9 15.1-5c8.2 16 9.2 46.5 5.6 65.1-6.1 30.6-21.4 47.1-27.6 57.5-1.4 2.4 16.5 10 27.8 41.3 10.4 28.6 1.1 52.7 2.8 55.3.8 1.4 13.7.8 36.4-13.2 12.8-7.9 28.1-16.9 45.4-17 16.7-.5 17.6 19.2 4.9 22.2zM496 256c0 136.9-111.1 248-248 248S0 392.9 0 256 111.1 8 248 8s248 111.1 248 248zm-79.3 75.2c-1.7-13.6-13.2-23-28-22.8-22 .3-40.5 11.7-52.8 19.2-4.8 3-8.9 5.2-12.4 6.8 3.1-44.5-22.5-73.1-28.7-79.4 7.8-11.3 18.4-27.8 23.4-53.2 4.3-21.7 3-55.5-6.9-74.5-1.6-3.1-7.4-11.2-21-7.4-9.7-20-13-22.1-15.6-23.8-1.1-.7-23.6-16.4-41.4 28-12.2.9-31.3 5.3-47.5 22.8-2 2.2-5.9 3.8-10.1 5.4h.1c-8.4 3-12.3 9.9-16.9 22.3-6.5 17.4.2 34.6 6.8 45.7-17.8 15.9-37 39.8-35.7 82.5-34 36-11.8 73-5.6 79.6-1.6 11.1 3.7 19.4 12 23.8 12.6 6.7 30.3 9.6 43.9 2.8 4.9 5.2 13.8 10.1 30 10.1 6.8 0 58-2.9 72.6-6.5 6.8-1.6 11.5-4.5 14.6-7.1 9.8-3.1 36.8-12.3 62.2-28.7 18-11.7 24.2-14.2 37.6-17.4 12.9-3.2 21-15.1 19.4-28.2z" />
</svg>
);
};
export default YarnIcon;

10
.dumi/theme/common/PrevAndNext.tsx

@ -37,7 +37,10 @@ const useStyle = createStyles(({ token }) => {
`,
prevNav: css`
text-align: start;
display: flex;
justify-content: flex-start;
align-items: center;
.footer-nav-icon-after {
display: none;
}
@ -57,7 +60,10 @@ const useStyle = createStyles(({ token }) => {
`,
nextNav: css`
text-align: end;
display: flex;
justify-content: flex-end;
align-items: center;
.footer-nav-icon-before {
display: none;
}

2
.dumi/theme/common/styles/BrowserMockup.tsx

@ -47,7 +47,7 @@ export default () => (
top: -1.6em;
left: 5.5em;
display: block;
width: ~'calc(100% - 6em)';
width: calc(100% - 6em);
height: 1.2em;
background-color: white;
border-radius: 2px;

16
.dumi/theme/common/styles/Markdown.tsx

@ -180,15 +180,25 @@ const GlobalStyle: React.FC = () => {
line-height: 2;
}
}
.pic-plus {
& > * {
display: inline-block !important;
vertical-align: middle;
}
span {
margin: 0 20px;
color: #aaa;
font-size: 30px;
}
}
.antd-site-snippet {
.ant-tabs-tab {
.snippet-label {
display: flex;
align-items: center;
justify-content: center;
span {
margin-inline-start: 8px;
svg {
margin-inline-end: 8px;
}
}
}

2
.dumi/theme/common/styles/Reset.tsx

@ -53,7 +53,7 @@ export default () => {
font-family: ${token.fontFamily};
line-height: ${token.lineHeight};
background: ${token.colorBgContainer};
transition: background 1s cubic-bezier(0.075, 0.82, 0.165, 1);
transition: background-color 1s cubic-bezier(0.075, 0.82, 0.165, 1);
}
`}
/>

2
.dumi/theme/common/styles/Responsive.tsx

@ -87,7 +87,7 @@ export default () => {
}
.prev-next-nav {
width: ~'calc(100% - 32px)';
width: calc(100% - 32px);
margin-left: 16px;
.ant-row-rtl & {

188
.dumi/theme/slots/Content/ColumnCard.tsx

@ -0,0 +1,188 @@
import { RightOutlined, YuqueOutlined, ZhihuOutlined } from '@ant-design/icons';
import { css } from '@emotion/react';
import { Button, Card, Divider } from 'antd';
import React from 'react';
import useLocale from '../../../hooks/useLocale';
import useSiteToken from '../../../hooks/useSiteToken';
const ANTD_IMG_URL =
'https://picx.zhimg.com/v2-3b2bca09c2771e7a82a81562e806be4d.jpg?source=d16d100b';
const useStyle = () => {
const { token } = useSiteToken();
return {
card: css`
width: 100%;
margin: 40px 0;
transition: all 0.2s;
background-color: ${token.colorFillQuaternary};
`,
bigTitle: css`
font-size: 16px;
color: #121212;
margin-bottom: 24px;
font-weight: 600;
`,
cardBody: css`
display: flex;
justify-content: space-between;
align-items: center;
`,
left: css`
display: flex;
justify-content: flex-start;
align-items: center;
img {
width: 200px;
margin-right: 24px;
overflow: hidden;
border-radius: 8px;
}
`,
title: css`
color: #444;
font-size: 16px;
font-weight: 600;
`,
subTitle: css`
display: flex;
justify-content: flex-start;
align-items: center;
color: #646464;
font-size: 14px;
font-weight: 400;
margin-top: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.logo {
font-size: 24px;
&.zhihu-logo {
color: #056de8;
}
&.yuque-logo {
color: #00b96b;
}
}
.arrowIcon {
margin: 0 8px;
color: #8a8f8d;
font-size: 12px;
}
.zl-btn {
display: flex;
align-items: center;
justify-content: center;
padding: 0;
color: #646464;
}
`,
btn: css`
display: flex;
justify-content: center;
align-items: center;
`,
};
};
const locales = {
cn: {
bigTitle: '文章被以下专栏收录:',
zhiHu: '一个 UI 设计体系',
yuQue: 'Ant Design 官方专栏',
buttonText: '我有想法,去参与讨论',
},
en: {
bigTitle: 'Articles are included in the column:',
zhiHu: 'A UI design system',
yuQue: 'Ant Design official column',
buttonText: 'Go to discuss',
},
};
interface Props {
zhihuLink?: string;
yuqueLink?: string;
}
const ColumnCard: React.FC<Props> = ({ zhihuLink, yuqueLink }) => {
const [locale] = useLocale(locales);
const { card, bigTitle, cardBody, left, title, subTitle, btn } = useStyle();
if (!zhihuLink && !yuqueLink) {
return null;
}
return (
<Card css={card} bordered={false}>
<h3 css={bigTitle}>{locale.bigTitle}</h3>
{zhihuLink && (
<div css={cardBody}>
<div css={left}>
<img src={ANTD_IMG_URL} alt="antd" />
<div>
<p css={title}>Ant Design</p>
<div css={subTitle}>
<ZhihuOutlined className="logo zhihu-logo" />
<RightOutlined className="arrowIcon" />
<Button
target="_blank"
href="https://www.zhihu.com/column/c_1564262000561106944"
className="zl-btn"
type="link"
>
{locale.zhiHu}
</Button>
</div>
</div>
</div>
<Button
type="primary"
css={btn}
icon={<ZhihuOutlined style={{ fontSize: 15 }} />}
ghost
target="_blank"
href={zhihuLink}
>
{locale.buttonText}
</Button>
</div>
)}
{yuqueLink && (
<>
<Divider />
<div css={cardBody}>
<div css={left}>
<img src={ANTD_IMG_URL} alt="antd" />
<div>
<p css={title}>Ant Design</p>
<div css={subTitle}>
<YuqueOutlined className="logo yuque-logo" />
<RightOutlined className="arrowIcon" />
<Button
target="_blank"
href="https://www.yuque.com/ant-design/ant-design"
className="zl-btn"
type="link"
>
{locale.yuQue}
</Button>
</div>
</div>
</div>
<Button
type="primary"
css={btn}
icon={<YuqueOutlined style={{ fontSize: 15 }} />}
ghost
target="_blank"
href={yuqueLink}
>
{locale.buttonText}
</Button>
</div>
</>
)}
</Card>
);
};
export default ColumnCard;

7
.dumi/theme/slots/Content/index.tsx

@ -16,6 +16,7 @@ import type { DemoContextProps } from '../DemoContext';
import DemoContext from '../DemoContext';
import Footer from '../Footer';
import SiteContext from '../SiteContext';
import ColumnCard from './ColumnCard';
const useStyle = () => {
const { token } = useSiteToken();
@ -272,6 +273,12 @@ const Content: React.FC<{ children: ReactNode }> = ({ children }) => {
) : null}
{!meta.frontmatter.__autoDescription && meta.frontmatter.description}
{children}
{(meta.frontmatter?.zhihu_url || meta.frontmatter?.yuque_url) && (
<ColumnCard
zhihuLink={meta.frontmatter.zhihu_url}
yuqueLink={meta.frontmatter.yuque_url}
/>
)}
{meta.frontmatter.filename && (
<ContributorsList
repo="ant-design"

9
.dumi/theme/slots/Header/index.tsx

@ -213,11 +213,12 @@ const Header: React.FC = () => {
.replace(/\/$/, '');
return;
}
// Mirror url must have `/`, we add this for compatible
const urlObj = new URL(currentUrl.replace(window.location.origin, url));
urlObj.pathname = `${urlObj.pathname.replace(/\/$/, '')}/`;
window.location.href = urlObj.href;
if (urlObj.host.includes('antgroup')) {
window.location.href = `${urlObj.href.replace(/\/$/, '')}/`;
}
window.location.href = urlObj.href.replace(/\/$/, '');
}, []);
const onLangChange = useCallback(() => {
@ -297,7 +298,7 @@ const Header: React.FC = () => {
defaultValue={pkg.version}
onChange={handleVersionChange}
dropdownStyle={getDropdownStyle}
dropdownMatchSelectWidth={false}
popupMatchSelectWidth={false}
getPopupContainer={(trigger) => trigger.parentNode}
options={versionOptions}
/>,

10
.dumi/theme/slots/Sidebar/index.tsx

@ -1,11 +1,11 @@
import React, { useContext } from 'react';
import { useSidebarData } from 'dumi';
import { css } from '@emotion/react';
import { Col, ConfigProvider, Menu } from 'antd';
import { useSidebarData } from 'dumi';
import MobileMenu from 'rc-drawer';
import { css } from '@emotion/react';
import SiteContext from '../SiteContext';
import React, { useContext } from 'react';
import useMenu from '../../../hooks/useMenu';
import useSiteToken from '../../../hooks/useSiteToken';
import SiteContext from '../SiteContext';
const useStyle = () => {
const { token } = useSiteToken();
@ -134,7 +134,7 @@ const Sidebar: React.FC = () => {
} = useSiteToken();
const menuChild = (
<ConfigProvider theme={{ components: { Menu: { colorItemBg: colorBgContainer } } }}>
<ConfigProvider theme={{ components: { Menu: { itemBg: colorBgContainer } } }}>
<Menu
items={menuItems}
inlineIndent={30}

7
.eslintrc.js

@ -119,6 +119,13 @@ module.exports = {
'react/no-danger': 0,
},
},
{
files: ['**/*.json'],
rules: {
'no-unused-expressions': 0,
'comma-dangle': 0,
},
},
],
rules: {
'react/jsx-one-expression-per-line': 0,

12
.github/workflows/site-deploy.yml

@ -69,11 +69,14 @@ jobs:
- name: build site
run: npm run predeploy
env:
NODE_OPTIONS: "--max_old_space_size=4096"
- name: build dist and bundle analyzer report
run: npm run dist
env:
ANALYZER: 1
NODE_OPTIONS: "--max_old_space_size=4096"
- name: Get version
id: publish-version
@ -86,6 +89,15 @@ jobs:
publish_dir: ./_site
force_orphan: true
# Since force_orphan will not trigger Sync to Gitee, we need to force run it here
- name: Sync to Gitee
uses: wearerequired/git-mirror-action@v1
env:
SSH_PRIVATE_KEY: ${{ secrets.GITEE_SSH_PRIVATE_KEY }}
with:
source-repo: 'git@github.com:ant-design/ant-design.git'
destination-repo: 'git@gitee.com:ant-design/ant-design.git'
- name: Deploy to Surge (with TAG)
run: |
export DEPLOY_DOMAIN=ant-design-${{ steps.publish-version.outputs.VERSION }}.surge.sh

17
CHANGELOG.en-US.md

@ -15,6 +15,23 @@ timeline: true
---
## 5.6.2
`2023-06-19`
- 🐞 Fix Dropdown with `autoFocus` not work as expect. [#43002](https://github.com/ant-design/ant-design/pull/43002) [@Yuiai01](https://github.com/Yuiai01)
- 🐞 Fix InputNumber with `prefix` abnormal height under Form.Item of `hasFeedBack`. [#43049](https://github.com/ant-design/ant-design/pull/43049)
- 💄 Fix Input and InputNumber disabled style with addons. [#42974](https://github.com/ant-design/ant-design/pull/42974) [@kampiu](https://github.com/kampiu)
- 🐞 Fix Upload trigger extra `onChange` event when upload the file exceeds `maxCount`. [#43034](https://github.com/ant-design/ant-design/pull/43034)
- 🐞 Fix export bundle size always contain `rc-field-form` even not use it. [#43023](https://github.com/ant-design/ant-design/pull/43023)
- 🐞 Fix DatePicker `disabledTime` sometime can select disabled option. [#42991](https://github.com/ant-design/ant-design/pull/42991) [@linxianxi](https://github.com/linxianxi)
- 📖 Add FloatButton controlled demo and patch related warning info. [#42835](https://github.com/ant-design/ant-design/pull/42835) [@poyiding](https://github.com/poyiding)
- 🐞 Fix Button with `disabled` still can interactive with sub component. [#42949](https://github.com/ant-design/ant-design/pull/42949) [@kiner-tang](https://github.com/kiner-tang)
- 🐞 Drawer add max width to avoid exceed in small screen. [#42914](https://github.com/ant-design/ant-design/pull/42914) [@amir2mi](https://github.com/amir2mi)
- 🐞 Fix Table `preserveSelectedRowKeys` not working when `checkStrictly` configured. [#42784](https://github.com/ant-design/ant-design/pull/42784) [@linxianxi](https://github.com/linxianxi)
- 🐞 Fix Transfer select count not sync when dynamic update data. [#42785](https://github.com/ant-design/ant-design/pull/42785) [@BoyYangzai](https://github.com/BoyYangzai)
- 🐞 Fix Radio.Button `title` not work and update typescript definition. [#43012](https://github.com/ant-design/ant-design/pull/43012) [@linxianxi](https://github.com/linxianxi)
## 5.6.1
`2023-06-07`

17
CHANGELOG.zh-CN.md

@ -15,6 +15,23 @@ timeline: true
---
## 5.6.2
`2023-06-19`
- 🐞 修复 Dropdown 配置 `autoFocus` 无效的问题。[#43002](https://github.com/ant-design/ant-design/pull/43002) [@Yuiai01](https://github.com/Yuiai01)
- 🐞 修复 InputNumber 设置 `prefix` 在 Form.Item `hasFeedBack` 内高度异常的问题。[#43049](https://github.com/ant-design/ant-design/pull/43049)
- 💄 修复 Input 和 InputNumber 禁用状态样式。[#42974](https://github.com/ant-design/ant-design/pull/42974) [@kampiu](https://github.com/kampiu)
- 🐞 修复 Upload 配置 `maxCount` 后,上传超出范围的文件仍然会触发 `onChange` 事件的问题。[#43034](https://github.com/ant-design/ant-design/pull/43034)
- 🐞 修复打包时即便没有使用 `rc-field-form` 包仍然会包含它的问题。[#43023](https://github.com/ant-design/ant-design/pull/43023)
- 🐞 修复 DatePicker 动态设置 `disabledTime` 时值不正确的问题。[#42991](https://github.com/ant-design/ant-design/pull/42991) [@linxianxi](https://github.com/linxianxi)
- 📖 补充 FloatButton 受控实例,并添加对应的 warning 提示。[#42835](https://github.com/ant-design/ant-design/pull/42835) [@poyiding](https://github.com/poyiding)
- 🐞 修复 Button 禁用时子节点仍然可以交互的问题。[#42949](https://github.com/ant-design/ant-design/pull/42949) [@kiner-tang](https://github.com/kiner-tang)
- 🐞 Drawer 添加最大宽度以防止在小屏幕下超出的问题。[#42914](https://github.com/ant-design/ant-design/pull/42914) [@amir2mi](https://github.com/amir2mi)
- 🐞 修复 Table 设置 `checkStrictly` 时,`preserveSelectedRowKeys` 无效的问题。[#42784](https://github.com/ant-design/ant-design/pull/42784) [@linxianxi](https://github.com/linxianxi)
- 🐞 修复 Transfer 在动态变更数据时,展示的选中数不同步的问题。[#42785](https://github.com/ant-design/ant-design/pull/42785) [@BoyYangzai](https://github.com/BoyYangzai)
- 🐞 修复 Radio.Button `title` 属性不生效,并补齐对应定义。[#43012](https://github.com/ant-design/ant-design/pull/43012) [@linxianxi](https://github.com/linxianxi)
## 5.6.1
`2023-06-07`

4
README.md

@ -34,8 +34,8 @@ An enterprise-class UI design language and React UI library.
[unpkg-js-url]: https://unpkg.com/browse/antd/dist/antd.min.js
[bundlephobia-image]: https://badgen.net/bundlephobia/minzip/antd?style=flat-square
[bundlephobia-url]: https://bundlephobia.com/package/antd
[issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square
[issues-helper-url]: https://github.com/actions-cool/issues-helper
[issues-helper-image]: https://img.shields.io/badge/using-actions--cool-blue?style=flat-square
[issues-helper-url]: https://github.com/actions-cool
[renovate-image]: https://img.shields.io/badge/renovate-enabled-brightgreen.svg?style=flat-square
[renovate-dashboard-url]: https://github.com/ant-design/ant-design/issues/32498
[dumi-image]: https://img.shields.io/badge/docs%20by-dumi-blue?style=flat-square

2
components/app/demo/basic.md

@ -1,6 +1,6 @@
## zh-CN
获取 `message`, `notification`, `modal` 静态方法。
获取 `message`、`notification`、`modal` 静态方法。
## en-US

5
components/app/index.en-US.md

@ -8,11 +8,12 @@ demo:
cols: 2
---
New App Component which provide global style & static function replacement.
Application wrapper for some global usages.
## When To Use
Static function in React 18 concurrent mode will not well support. In v5, we recommend to use hooks for the static replacement. But it will make user manual work on define this.
- Provide reset styles based on `.ant-app` element.
- You could use static methods of `message/notification/Modal` form `useApp` without put `contextHolder` mannully.
## Examples

9
components/breadcrumb/Breadcrumb.tsx

@ -9,6 +9,7 @@ import type { BreadcrumbItemProps } from './BreadcrumbItem';
import BreadcrumbItem, { InternalBreadcrumbItem } from './BreadcrumbItem';
import BreadcrumbSeparator from './BreadcrumbSeparator';
import type { DropdownProps } from '../dropdown';
import useStyle from './style';
import useItemRender from './useItemRender';
import useItems from './useItems';
@ -30,6 +31,7 @@ export interface BreadcrumbItemType {
/** @deprecated Please use `menu` instead */
overlay?: React.ReactNode;
className?: string;
dropdownProps?: DropdownProps;
onClick?: React.MouseEventHandler<HTMLAnchorElement | HTMLSpanElement>;
/** @deprecated Please use `menu` instead */
@ -123,6 +125,7 @@ const Breadcrumb = (props: BreadcrumbProps) => {
onClick,
className: itemClassName,
separator: itemSeparator,
dropdownProps,
} = item;
const mergedPath = getPath(params, path);
@ -145,10 +148,6 @@ const Breadcrumb = (props: BreadcrumbProps) => {
itemProps.overlay = overlay as any;
}
if (itemClassName) {
itemProps.className = itemClassName;
}
let { href } = item;
if (paths.length && mergedPath !== undefined) {
href = `#/${paths.join('/')}`;
@ -162,6 +161,8 @@ const Breadcrumb = (props: BreadcrumbProps) => {
data: true,
aria: true,
})}
className={itemClassName}
dropdownProps={dropdownProps}
href={href}
separator={isLastItem ? '' : separator}
onClick={onClick}

22
components/breadcrumb/__tests__/Breadcrumb.test.tsx

@ -362,4 +362,26 @@ describe('Breadcrumb', () => {
it('Breadcrumb.Item menu type', () => {
expect(<Breadcrumb.Item menu={{ selectable: true }} />).toBeTruthy();
});
it('dropdownProps in items should be worked', () => {
render(
<Breadcrumb
items={[
{
title: 'test',
menu: {
items: [
{
key: '1',
label: 'label',
},
],
},
dropdownProps: { open: true },
},
]}
/>,
);
expect(document.querySelector('.ant-dropdown')).toBeTruthy();
});
});

2
components/breadcrumb/demo/overlay.tsx

@ -1,5 +1,5 @@
import React from 'react';
import { Breadcrumb } from 'antd';
import React from 'react';
const menuItems = [
{

2
components/breadcrumb/useItemRender.tsx

@ -11,7 +11,7 @@ type ItemRender = NonNullable<BreadcrumbProps['itemRender']>;
type InternalItemRenderParams = AddParameters<ItemRender, [href?: string]>;
function getBreadcrumbName(route: InternalRouteType, params: any) {
if (route.title === undefined) {
if (route.title === undefined || route.title === null) {
return null;
}
const paramsKeys = Object.keys(params).join('|');

4
components/button/button.tsx

@ -55,7 +55,7 @@ export interface BaseButtonProps {
export type AnchorButtonProps = {
href: string;
target?: string;
target?: React.HTMLAttributeAnchorTarget;
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
} & BaseButtonProps &
Omit<React.AnchorHTMLAttributes<HTMLAnchorElement | HTMLButtonElement>, 'type' | 'onClick'>;
@ -210,7 +210,7 @@ const InternalButton: React.ForwardRefRenderFunction<
const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined };
const sizeFullname = useSize((ctxSize) => compactSize ?? groupSize ?? customizeSize ?? ctxSize);
const sizeFullname = useSize((ctxSize) => customizeSize ?? compactSize ?? groupSize ?? ctxSize);
const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : '';

2
components/cascader/index.tsx

@ -229,7 +229,7 @@ const Cascader = React.forwardRef((props: CascaderProps<any>, ref: React.Ref<Cas
}, [showSearch]);
// ===================== Size ======================
const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx);
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);

5
components/checkbox/Checkbox.tsx

@ -2,11 +2,11 @@ import classNames from 'classnames';
import type { CheckboxRef } from 'rc-checkbox';
import RcCheckbox from 'rc-checkbox';
import * as React from 'react';
import warning from '../_util/warning';
import { ConfigContext } from '../config-provider';
import DisabledContext from '../config-provider/DisabledContext';
import { FormItemInputContext } from '../form/context';
import warning from '../_util/warning';
import { GroupContext } from './Group';
import DisabledContext from '../config-provider/DisabledContext';
import useStyle from './style';
@ -18,6 +18,7 @@ export interface AbstractCheckboxProps<T> {
checked?: boolean;
style?: React.CSSProperties;
disabled?: boolean;
title?: string;
onChange?: (e: T) => void;
onClick?: React.MouseEventHandler<HTMLElement>;
onMouseEnter?: React.MouseEventHandler<HTMLElement>;

2
components/checkbox/Group.tsx

@ -14,6 +14,7 @@ export interface CheckboxOptionType {
value: CheckboxValueType;
style?: React.CSSProperties;
disabled?: boolean;
title?: string;
onChange?: (e: CheckboxChangeEvent) => void;
}
@ -132,6 +133,7 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
onChange={option.onChange}
className={`${groupPrefixCls}-item`}
style={option.style}
title={option.title}
>
{option.label}
</Checkbox>

2
components/config-provider/index.en-US.md

@ -97,7 +97,7 @@ const {
} = ConfigProvider.useConfig();
```
| 返回值 | 说明 | 类型 | 默认值 | 版本 |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| componentDisabled | antd component disabled state | boolean | - | 5.3.0 |
| componentSize | antd component size state | `small` \| `middle` \| `large` | - | 5.3.0 |

2
components/config-provider/index.tsx

@ -7,8 +7,8 @@ import type { ReactElement } from 'react';
import * as React from 'react';
import type { Options } from 'scroll-into-view-if-needed';
import warning from '../_util/warning';
import { ValidateMessagesContext } from '../form/context';
import type { RequiredMark } from '../form/Form';
import ValidateMessagesContext from '../form/validateMessagesContext';
import type { Locale } from '../locale';
import LocaleProvider, { ANT_MARK } from '../locale';
import type { LocaleContextProps } from '../locale/context';

2
components/date-picker/generatePicker/generateRangePicker.tsx

@ -78,7 +78,7 @@ export default function generateRangePicker<DateType>(generateConfig: GenerateCo
}
// ===================== Size =====================
const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx);
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);

2
components/date-picker/generatePicker/generateSinglePicker.tsx

@ -103,7 +103,7 @@ export default function generatePicker<DateType>(generateConfig: GenerateConfig<
}
// ===================== Size =====================
const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx);
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);

4
components/date-picker/index.zh-CN.md

@ -106,8 +106,8 @@ import locale from 'antd/locale/zh_CN';
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
| style | 自定义输入框样式 | CSSProperties | {} | |
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| superNextIcon | 自定义 `<<` 切换图标 | ReactNode | - | 4.17.0 |
| superPrevIcon | 自定义 `>>` 切换图标 | ReactNode | - | 4.17.0 |
| superNextIcon | 自定义 `>>` 切换图标 | ReactNode | - | 4.17.0 |
| superPrevIcon | 自定义 `<<` 切换图标 | ReactNode | - | 4.17.0 |
| onOpenChange | 弹出日历和关闭日历的回调 | function(open) | - | |
| onPanelChange | 日历面板切换的回调 | function(value, mode) | - | |

15
components/dropdown/__tests__/dropdown-button.test.tsx

@ -1,7 +1,7 @@
import React from 'react';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { render } from '../../../tests/utils';
import { render, waitFakeTimer } from '../../../tests/utils';
import type { DropdownProps } from '../dropdown';
import DropdownButton from '../dropdown-button';
@ -156,4 +156,17 @@ describe('DropdownButton', () => {
render(<DropdownButton open dropdownRender={dropdownRender} />);
expect(dropdownRender).toHaveBeenCalled();
});
it('should support focus menu when set autoFocus', async () => {
jest.useFakeTimers();
const items = [
{
label: 'foo',
key: '1',
},
];
const { container } = render(<DropdownButton open autoFocus menu={{ items }} />);
await waitFakeTimer();
expect(container.querySelector('.ant-dropdown-menu-item-active')).toBeTruthy();
});
});

3
components/dropdown/dropdown.tsx

@ -14,7 +14,6 @@ import { ConfigContext } from '../config-provider';
import type { MenuProps } from '../menu';
import Menu from '../menu';
import { OverrideProvider } from '../menu/OverrideContext';
import { NoCompactStyle } from '../space/Compact';
import theme from '../theme';
import useStyle from './style';
@ -274,7 +273,7 @@ const Dropdown: CompoundedComponent = (props) => {
);
}}
>
<NoCompactStyle>{overlayNode}</NoCompactStyle>
{overlayNode}
</OverrideProvider>
);
};

1
components/float-button/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -855,6 +855,7 @@ Array [
aria-checked="true"
class="ant-switch ant-switch-checked"
role="switch"
style="margin: 16px;"
type="button"
>
<div

1
components/float-button/__tests__/__snapshots__/demo.test.ts.snap

@ -645,6 +645,7 @@ Array [
aria-checked="true"
class="ant-switch ant-switch-checked"
role="switch"
style="margin:16px"
type="button"
>
<div

2
components/float-button/demo/controlled.tsx

@ -20,7 +20,7 @@ const App: React.FC = () => {
<FloatButton />
<FloatButton icon={<CommentOutlined />} />
</FloatButton.Group>
<Switch onChange={onChange} checked={open} />
<Switch onChange={onChange} checked={open} style={{ margin: 16 }} />
</>
);
};

5
components/form/Form.tsx

@ -12,11 +12,12 @@ import { SizeContextProvider } from '../config-provider/SizeContext';
import useSize from '../config-provider/hooks/useSize';
import type { ColProps } from '../grid/col';
import type { FormContextProps } from './context';
import { FormContext, FormProvider, ValidateMessagesContext } from './context';
import { FormContext, FormProvider } from './context';
import useForm, { type FormInstance } from './hooks/useForm';
import useFormWarning from './hooks/useFormWarning';
import type { FormLabelAlign } from './interface';
import useStyle from './style';
import ValidateMessagesContext from './validateMessagesContext';
export type RequiredMark = boolean | 'optional';
export type FormLayout = 'horizontal' | 'inline' | 'vertical';
@ -186,6 +187,6 @@ const Form = React.forwardRef<FormInstance, FormProps>(InternalForm) as <Values
props: React.PropsWithChildren<FormProps<Values>> & { ref?: React.Ref<FormInstance<Values>> },
) => React.ReactElement;
export { useForm, List, type FormInstance, useWatch };
export { List, useForm, useWatch, type FormInstance };
export default Form;

4
components/form/context.tsx

@ -1,6 +1,6 @@
import { FormProvider as RcFormProvider } from 'rc-field-form';
import type { FormProviderProps as RcFormProviderProps } from 'rc-field-form/lib/FormContext';
import type { Meta, ValidateMessages } from 'rc-field-form/lib/interface';
import type { Meta } from 'rc-field-form/lib/interface';
import omit from 'rc-util/lib/omit';
import type { FC, PropsWithChildren, ReactNode } from 'react';
import * as React from 'react';
@ -92,5 +92,3 @@ export const NoFormStyle: FC<NoFormStyleProps> = ({ children, status, override }
</FormItemInputContext.Provider>
);
};
export const ValidateMessagesContext = React.createContext<ValidateMessages | undefined>(undefined);

7
components/form/validateMessagesContext.tsx

@ -0,0 +1,7 @@
import type { ValidateMessages } from 'rc-field-form/lib/interface';
import { createContext } from 'react';
// ZombieJ: We export single file here since
// ConfigProvider use this which will make loop deps
// to import whole `rc-field-form`
export default createContext<ValidateMessages | undefined>(undefined);

242
components/input-number/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -626,6 +626,7 @@ exports[`renders components/input-number/demo/addon.tsx extend context correctly
</div>
<div
class="ant-space-item"
style="margin-bottom: 8px;"
>
<div
class="ant-input-number-group-wrapper"
@ -846,6 +847,247 @@ exports[`renders components/input-number/demo/addon.tsx extend context correctly
</div>
</div>
</div>
<div
class="ant-space-item"
style="margin-bottom: 8px;"
>
<div
class="ant-input-number-group-wrapper"
>
<div
class="ant-input-number-wrapper ant-input-number-group ant-input-number-wrapper-disabled"
>
<div
class="ant-input-number-group-addon"
>
+
</div>
<div
class="ant-input-number ant-input-number-disabled"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
aria-valuenow="100"
autocomplete="off"
class="ant-input-number-input"
disabled=""
role="spinbutton"
step="1"
value="100"
/>
</div>
</div>
<div
class="ant-input-number-group-addon"
>
<span
aria-label="setting"
class="anticon anticon-setting"
role="img"
>
<svg
aria-hidden="true"
data-icon="setting"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
/>
</svg>
</span>
</div>
</div>
</div>
</div>
<div
class="ant-space-item"
>
<div
class="ant-input-number-group-wrapper"
>
<div
class="ant-input-number-wrapper ant-input-number-group ant-input-number-wrapper-disabled"
>
<div
class="ant-input-number-group-addon"
>
+
</div>
<div
class="ant-input-number-affix-wrapper ant-input-number-affix-wrapper-disabled"
disabled=""
>
<span
class="ant-input-number-prefix"
>
¥
</span>
<div
class="ant-input-number ant-input-number-disabled"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
aria-valuenow="100"
autocomplete="off"
class="ant-input-number-input"
disabled=""
role="spinbutton"
step="1"
value="100"
/>
</div>
</div>
</div>
<div
class="ant-input-number-group-addon"
>
<span
aria-label="setting"
class="anticon anticon-setting"
role="img"
>
<svg
aria-hidden="true"
data-icon="setting"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
/>
</svg>
</span>
</div>
</div>
</div>
</div>
</div>
`;

242
components/input-number/__tests__/__snapshots__/demo.test.tsx.snap

@ -430,6 +430,7 @@ exports[`renders components/input-number/demo/addon.tsx correctly 1`] = `
</div>
<div
class="ant-space-item"
style="margin-bottom:8px"
>
<div
class="ant-input-number-group-wrapper"
@ -577,6 +578,247 @@ exports[`renders components/input-number/demo/addon.tsx correctly 1`] = `
</div>
</div>
</div>
<div
class="ant-space-item"
style="margin-bottom:8px"
>
<div
class="ant-input-number-group-wrapper"
>
<div
class="ant-input-number-wrapper ant-input-number-group ant-input-number-wrapper-disabled"
>
<div
class="ant-input-number-group-addon"
>
+
</div>
<div
class="ant-input-number ant-input-number-disabled"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
aria-valuenow="100"
autocomplete="off"
class="ant-input-number-input"
disabled=""
role="spinbutton"
step="1"
value="100"
/>
</div>
</div>
<div
class="ant-input-number-group-addon"
>
<span
aria-label="setting"
class="anticon anticon-setting"
role="img"
>
<svg
aria-hidden="true"
data-icon="setting"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
/>
</svg>
</span>
</div>
</div>
</div>
</div>
<div
class="ant-space-item"
>
<div
class="ant-input-number-group-wrapper"
>
<div
class="ant-input-number-wrapper ant-input-number-group ant-input-number-wrapper-disabled"
>
<div
class="ant-input-number-group-addon"
>
+
</div>
<div
class="ant-input-number-affix-wrapper ant-input-number-affix-wrapper-disabled"
disabled=""
>
<span
class="ant-input-number-prefix"
>
¥
</span>
<div
class="ant-input-number ant-input-number-disabled"
>
<div
class="ant-input-number-handler-wrap"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
aria-valuenow="100"
autocomplete="off"
class="ant-input-number-input"
disabled=""
role="spinbutton"
step="1"
value="100"
/>
</div>
</div>
</div>
<div
class="ant-input-number-group-addon"
>
<span
aria-label="setting"
class="anticon anticon-setting"
role="img"
>
<svg
aria-hidden="true"
data-icon="setting"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z"
/>
</svg>
</span>
</div>
</div>
</div>
</div>
</div>
`;

39
components/input-number/__tests__/addon.test.tsx

@ -0,0 +1,39 @@
import React from 'react';
import InputNumber from '..';
import { render } from '../../../tests/utils';
describe('addon', () => {
it('disabled status when prefix is active', () => {
const { container } = render(<InputNumber prefix="¥" defaultValue={100} disabled controls />);
expect(container.querySelector('.ant-input-number-affix-wrapper-disabled')).toBeInTheDocument();
});
it('disabled status when addon is active', () => {
const { container } = render(
<InputNumber
prefix="¥"
addonBefore="Before"
addonAfter="After"
defaultValue={100}
disabled
controls
/>,
);
expect(container.querySelector('.ant-input-number-wrapper-disabled')).toBeInTheDocument();
});
it('disabled status when prefix and addon is active', () => {
const { container } = render(
<InputNumber
prefix="¥"
addonBefore="Before"
addonAfter="After"
defaultValue={100}
disabled
controls
/>,
);
expect(container.querySelector('.ant-input-number-wrapper-disabled')).toBeInTheDocument();
expect(container.querySelector('.ant-input-number-affix-wrapper-disabled')).toBeInTheDocument();
});
});

17
components/input-number/demo/addon.tsx

@ -1,6 +1,6 @@
import React from 'react';
import { SettingOutlined } from '@ant-design/icons';
import { Cascader, InputNumber, Select, Space } from 'antd';
import React from 'react';
const { Option } = Select;
@ -28,6 +28,21 @@ const App: React.FC = () => (
addonBefore={<Cascader placeholder="cascader" style={{ width: 150 }} />}
defaultValue={100}
/>
<InputNumber
addonBefore="+"
addonAfter={<SettingOutlined />}
defaultValue={100}
disabled
controls
/>
<InputNumber
prefix="¥"
addonBefore="+"
addonAfter={<SettingOutlined />}
defaultValue={100}
disabled
controls
/>
</Space>
);

3
components/input-number/index.tsx

@ -87,7 +87,7 @@ const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>((props,
} = React.useContext(FormItemInputContext);
const mergedStatus = getMergedStatus(contextStatus, customStatus);
const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx);
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
const hasPrefix = prefix != null || hasFeedback;
const hasAddon = !!(addonBefore || addonAfter);
@ -179,6 +179,7 @@ const InputNumber = React.forwardRef<HTMLInputElement, InputNumberProps>((props,
const mergedWrapperClassName = classNames(`${prefixCls}-wrapper`, wrapperClassName, hashId, {
[`${wrapperClassName}-rtl`]: direction === 'rtl',
[`${prefixCls}-wrapper-disabled`]: mergedDisabled,
});
const mergedGroupClassName = classNames(

22
components/input-number/style/index.ts

@ -99,13 +99,6 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
...genActiveStyle(token),
},
'&-disabled': {
...genDisabledStyle(token),
[`${componentCls}-input`]: {
cursor: 'not-allowed',
},
},
// ===================== Out Of Range =====================
'&-out-of-range': {
[`${componentCls}-input-wrap`]: {
@ -140,9 +133,17 @@ const genInputNumberStyles: GenerateStyle<InputNumberToken> = (token: InputNumbe
borderRadius: borderRadiusSM,
},
},
[`${componentCls}-wrapper-disabled > ${componentCls}-group-addon`]: {
...genDisabledStyle(token),
},
},
},
[`&-disabled ${componentCls}-input`]: {
cursor: 'not-allowed',
},
[componentCls]: {
'&-input': {
...resetComponent(token),
@ -338,10 +339,8 @@ const genAffixWrapperStyles: GenerateStyle<InputNumberToken> = (token: InputNumb
zIndex: 1,
},
'&-disabled': {
[`${componentCls}[disabled]`]: {
background: 'transparent',
},
[`&-disabled > ${componentCls}-disabled`]: {
background: 'transparent',
},
[`> div${componentCls}`]: {
@ -359,6 +358,7 @@ const genAffixWrapperStyles: GenerateStyle<InputNumberToken> = (token: InputNumb
},
'&::before': {
display: 'inline-block',
width: 0,
visibility: 'hidden',
content: '"\\a0"',

2
components/input/Input.tsx

@ -97,7 +97,7 @@ const Input = forwardRef<InputRef, InputProps>((props, ref) => {
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
// ===================== Size =====================
const mergedSize = useSize((ctx) => compactSize ?? customSize ?? ctx);
const mergedSize = useSize((ctx) => customSize ?? compactSize ?? ctx);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);

2
components/input/Search.tsx

@ -49,7 +49,7 @@ const Search = React.forwardRef<InputRef, SearchProps>((props, ref) => {
const inputPrefixCls = getPrefixCls('input', customizeInputPrefixCls);
const { compactSize } = useCompactItemContext(prefixCls, direction);
const size = useSize((ctx) => compactSize ?? customizeSize ?? ctx);
const size = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
const inputRef = React.useRef<InputRef>(null);

127
components/input/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -5194,7 +5194,7 @@ exports[`renders components/input/demo/compact-style.tsx extend context correctl
class="ant-space-compact"
>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item ant-input-compact-first-item ant-input-compact-last-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item ant-input-compact-first-item ant-input-compact-last-item"
>
<span
class="ant-input-wrapper ant-input-group"
@ -6356,76 +6356,85 @@ exports[`renders components/input/demo/group.tsx extend context correctly 1`] =
value="input content"
/>
<div
class="ant-input-number"
class="ant-input-number-affix-wrapper"
>
<span
class="ant-input-number-prefix"
>
@
</span>
<div
class="ant-input-number-handler-wrap"
class="ant-input-number"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
<div
class="ant-input-number-handler-wrap"
>
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
</span>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
</div>
</div>
</span>

127
components/input/__tests__/__snapshots__/demo.test.tsx.snap

@ -1412,7 +1412,7 @@ exports[`renders components/input/demo/compact-style.tsx correctly 1`] = `
class="ant-space-compact"
>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item ant-input-compact-first-item ant-input-compact-last-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item ant-input-compact-first-item ant-input-compact-last-item"
>
<span
class="ant-input-wrapper ant-input-group"
@ -2312,76 +2312,85 @@ exports[`renders components/input/demo/group.tsx correctly 1`] = `
value="input content"
/>
<div
class="ant-input-number"
class="ant-input-number-affix-wrapper"
>
<span
class="ant-input-number-prefix"
>
@
</span>
<div
class="ant-input-number-handler-wrap"
class="ant-input-number"
>
<span
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
<div
class="ant-input-number-handler-wrap"
>
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
aria-disabled="false"
aria-label="Increase Value"
class="ant-input-number-handler ant-input-number-handler-up"
role="button"
unselectable="on"
>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span
aria-label="up"
class="anticon anticon-up ant-input-number-handler-up-inner"
role="img"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
<svg
aria-hidden="true"
data-icon="up"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"
/>
</svg>
</span>
</span>
</span>
<span
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
aria-disabled="false"
aria-label="Decrease Value"
class="ant-input-number-handler ant-input-number-handler-down"
role="button"
unselectable="on"
>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span
aria-label="down"
class="anticon anticon-down ant-input-number-handler-down-inner"
role="img"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
<svg
aria-hidden="true"
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</span>
</span>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
<div
class="ant-input-number-input-wrap"
>
<input
autocomplete="off"
class="ant-input-number-input"
role="spinbutton"
step="1"
value=""
/>
</div>
</div>
</div>
</span>

4
components/input/demo/group.tsx

@ -1,4 +1,3 @@
import React from 'react';
import { CopyOutlined } from '@ant-design/icons';
import {
AutoComplete,
@ -12,6 +11,7 @@ import {
Select,
Tooltip,
} from 'antd';
import React from 'react';
const { Option } = Select;
@ -102,7 +102,7 @@ const App: React.FC = () => (
<Option value="Option2">Option2</Option>
</Select>
<Input style={{ width: '50%' }} defaultValue="input content" />
<InputNumber />
<InputNumber prefix="@" />
</Input.Group>
<br />
<Input.Group compact>

11
components/input/style/index.ts

@ -412,11 +412,11 @@ export const genInputGroupStyle = (token: InputToken): CSSObject => {
borderRadius: 0,
},
[`& > ${componentCls}-affix-wrapper`]: {
display: 'inline-flex',
},
[`& > ${antCls}-picker-range`]: {
[`
& > ${componentCls}-affix-wrapper,
& > ${componentCls}-number-affix-wrapper,
& > ${antCls}-picker-range
`]: {
display: 'inline-flex',
},
@ -620,6 +620,7 @@ const genAffixStyle: GenerateStyle<InputToken> = (token: InputToken) => {
},
'&::before': {
display: 'inline-block',
width: 0,
visibility: 'hidden',
content: '"\\a0"',

16
components/menu/OverrideContext.tsx

@ -1,4 +1,5 @@
import * as React from 'react';
import { NoCompactStyle } from '../space/Compact';
import type { MenuProps } from './menu';
// Used for Dropdown only
@ -14,9 +15,10 @@ export interface OverrideContextProps {
const OverrideContext = React.createContext<OverrideContextProps | null>(null);
/** @internal Only used for Dropdown component. Do not use this in your production. */
export const OverrideProvider: React.FC<OverrideContextProps & { children: React.ReactNode }> = (
props,
) => {
export const OverrideProvider = React.forwardRef<
HTMLElement,
OverrideContextProps & { children: React.ReactNode }
>((props, ref) => {
const { children, ...restProps } = props;
const override = React.useContext(OverrideContext);
@ -32,8 +34,12 @@ export const OverrideProvider: React.FC<OverrideContextProps & { children: React
],
);
return <OverrideContext.Provider value={context}>{children}</OverrideContext.Provider>;
};
return (
<OverrideContext.Provider value={context}>
<NoCompactStyle>{React.cloneElement(children as React.ReactElement, { ref })}</NoCompactStyle>
</OverrideContext.Provider>
);
});
/** @internal Only used for Dropdown component. Do not use this in your production. */
export default OverrideContext;

4
components/progress/demo/segment.md

@ -1,7 +1,7 @@
## zh-CN
标准的进度条。`type="circle|dashboard"` 时不支持分段颜色
分段展示进度,可以用于细化进度语义
## en-US
A standard progress bar. Doesn't support trail color when `type="circle|dashboard"`.
Show several parts of progress with different status.

2
components/progress/index.en-US.md

@ -50,7 +50,7 @@ Properties that shared by all types.
| success | Configs of successfully progress bar | { percent: number, strokeColor: string } | - | - |
| trailColor | The color of unfilled part | string | - | - |
| type | To set the type, options: `line` `circle` `dashboard` | string | `line` |
| size | Progress size | number \| \[number, number] \| "small" \| "default" | "default" | v5.3.0 |
| size | Progress size | number \| \[number \| string, number] \| "small" \| "default" | "default" | v5.3.0 |
### `type="line"`

2
components/progress/index.zh-CN.md

@ -51,7 +51,7 @@ demo:
| success | 成功进度条相关配置 | { percent: number, strokeColor: string } | - | - |
| trailColor | 未完成的分段的颜色 | string | - | - |
| type | 类型,可选 `line` `circle` `dashboard` | string | `line` | - |
| size | 进度条的尺寸 | number \| \[number, number] \| "small" \| "default" | "default" | v5.3.0 |
| size | 进度条的尺寸 | number \| \[number \| string, number] \| "small" \| "default" | "default" | v5.3.0 |
### `type="line"`

2
components/progress/progress.tsx

@ -50,7 +50,7 @@ export interface ProgressProps extends ProgressAriaProps {
style?: React.CSSProperties;
gapDegree?: number;
gapPosition?: 'top' | 'bottom' | 'left' | 'right';
size?: number | [number, number] | ProgressSize;
size?: number | [number | string, number] | ProgressSize;
steps?: number;
/** @deprecated Use `success` instead */
successPercent?: number;

18
components/progress/utils.ts

@ -1,7 +1,7 @@
import { presetPrimaryColors } from '@ant-design/colors';
import warning from '../_util/warning';
import type { CircleProps } from './Circle';
import type { ProgressProps } from './progress';
import warning from '../_util/warning';
export function validProgress(progress?: number) {
if (!progress || progress < 0) {
@ -35,10 +35,10 @@ export const getPercentage = ({ percent, success, successPercent }: ProgressProp
return [realSuccessPercent, validProgress(validProgress(percent) - realSuccessPercent)];
};
export const getStrokeColor = ({ success = {}, strokeColor }: Partial<CircleProps>): (
| string
| Record<PropertyKey, string>
)[] => {
export const getStrokeColor = ({
success = {},
strokeColor,
}: Partial<CircleProps>): (string | Record<PropertyKey, string>)[] => {
const { strokeColor: successColor } = success;
return [successColor || presetPrimaryColors.green, strokeColor || null!];
};
@ -62,7 +62,7 @@ export const getSize = (
} else if (typeof size === 'number') {
[width, height] = [size, size];
} else {
[width = 14, height = 8] = size;
[width = 14, height = 8] = size as [number, number];
}
width *= steps;
} else if (type === 'line') {
@ -72,7 +72,7 @@ export const getSize = (
} else if (typeof size === 'number') {
[width, height] = [size, size];
} else {
[width = -1, height = 8] = size;
[width = -1, height = 8] = size as [number, number];
}
} else if (type === 'circle' || type === 'dashboard') {
if (typeof size === 'string' || typeof size === 'undefined') {
@ -88,8 +88,8 @@ export const getSize = (
);
}
width = size[0] ?? size[1] ?? 120;
height = size[0] ?? size[1] ?? 120;
width = (size[0] ?? size[1] ?? 120) as number;
height = (size[0] ?? size[1] ?? 120) as number;
}
}
return [width, height];

1
components/radio/group.tsx

@ -76,6 +76,7 @@ const RadioGroup = React.forwardRef<HTMLDivElement, RadioGroupProps>((props, ref
disabled={option.disabled || disabled}
value={option.value}
checked={value === option.value}
title={option.title}
style={option.style}
>
{option.label}

6
components/select/index.en-US.md

@ -47,12 +47,6 @@ Select component to select value from options.
## API
```tsx
<Select>
<Option value="lucy">lucy</Option>
</Select>
```
### Select props
| Property | Description | Type | Default | Version |

2
components/select/index.tsx

@ -175,7 +175,7 @@ const InternalSelect = <
hashId,
);
const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx);
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);

6
components/select/index.zh-CN.md

@ -48,12 +48,6 @@ demo:
## API
```tsx
<Select>
<Option value="lucy">lucy</Option>
</Select>
```
### Select props
| 参数 | 说明 | 类型 | 默认值 | 版本 |

4
components/select/style/dropdown.tsx

@ -104,10 +104,6 @@ const genSingleStyle: GenerateStyle<SelectToken> = (token) => {
'&-content': {
flex: 'auto',
...textEllipsis,
'> *': {
...textEllipsis,
},
},
'&-state': {

5
components/select/style/index.tsx

@ -144,11 +144,6 @@ const genBaseStyle: GenerateStyle<SelectToken> = (token) => {
flex: 1,
fontWeight: 'normal',
...textEllipsis,
'> *': {
lineHeight: 'inherit',
...textEllipsis,
},
},
// ======================= Placeholder =======================

7
components/slider/SliderTooltip.tsx

@ -1,3 +1,4 @@
import type { SliderRef } from 'rc-slider/lib/Slider';
import raf from 'rc-util/lib/raf';
import { composeRef } from 'rc-util/lib/ref';
import * as React from 'react';
@ -5,7 +6,7 @@ import { useRef } from 'react';
import type { TooltipProps } from '../tooltip';
import Tooltip from '../tooltip';
const SliderTooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
const SliderTooltip = React.forwardRef<SliderRef, TooltipProps>((props, ref) => {
const { open } = props;
const innerRef = useRef<any>(null);
@ -36,4 +37,8 @@ const SliderTooltip = React.forwardRef<unknown, TooltipProps>((props, ref) => {
return <Tooltip ref={composeRef(innerRef, ref)} {...props} />;
});
if (process.env.NODE_ENV !== 'production') {
SliderTooltip.displayName = 'SliderTooltip';
}
export default SliderTooltip;

2
components/space/Compact.tsx

@ -78,7 +78,7 @@ const Compact: React.FC<SpaceCompactProps> = (props) => {
...restProps
} = props;
const mergedSize = useSize((ctx) => size ?? ctx ?? 'middle');
const mergedSize = useSize((ctx) => size ?? ctx);
const prefixCls = getPrefixCls('space-compact', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(prefixCls);

32
components/space/__tests__/__snapshots__/demo-extend.test.ts.snap

@ -871,7 +871,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
class="ant-space-compact ant-space-compact-block"
>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item ant-input-compact-first-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item ant-input-compact-first-item"
style="width: 30%;"
>
<span
@ -917,7 +917,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
</span>
</span>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item"
style="width: 50%;"
>
<span
@ -996,7 +996,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
</span>
</span>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item ant-input-compact-last-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item ant-input-compact-last-item"
style="width: 20%;"
>
<span
@ -1279,7 +1279,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
value="input content"
/>
<div
class="ant-picker ant-picker-middle ant-picker-compact-item ant-picker-compact-last-item"
class="ant-picker ant-picker-compact-item ant-picker-compact-last-item"
style="width: 50%;"
>
<div
@ -1880,7 +1880,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
class="ant-space-compact ant-space-compact-block"
>
<div
class="ant-picker ant-picker-range ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item"
class="ant-picker ant-picker-range ant-picker-compact-item ant-picker-compact-first-item"
style="width: 70%;"
>
<div
@ -3088,7 +3088,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
value="input content"
/>
<div
class="ant-picker ant-picker-range ant-picker-middle ant-picker-compact-item ant-picker-compact-last-item"
class="ant-picker ant-picker-range ant-picker-compact-item ant-picker-compact-last-item"
style="width: 70%;"
>
<div
@ -4981,7 +4981,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
class="ant-space-compact ant-space-compact-block"
>
<div
class="ant-picker ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item"
class="ant-picker ant-picker-compact-item ant-picker-compact-first-item"
style="width: 70%;"
>
<div
@ -6375,7 +6375,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
class="ant-picker-ok"
>
<button
class="ant-btn ant-btn-primary ant-btn-compact-item ant-btn-compact-first-item"
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-compact-item ant-btn-compact-first-item"
disabled=""
type="button"
>
@ -6544,7 +6544,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
class="ant-space-compact ant-space-compact-block"
>
<div
class="ant-picker ant-picker-range ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item"
class="ant-picker ant-picker-range ant-picker-compact-item ant-picker-compact-first-item"
>
<div
class="ant-picker-input ant-picker-input-active"
@ -7985,7 +7985,7 @@ exports[`renders components/space/demo/compact.tsx extend context correctly 1`]
class="ant-picker-ok"
>
<button
class="ant-btn ant-btn-primary ant-btn-compact-item ant-btn-compact-first-item"
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-compact-item ant-btn-compact-first-item"
disabled=""
type="button"
>
@ -10034,7 +10034,7 @@ exports[`renders components/space/demo/compact-debug.tsx extend context correctl
class="ant-space-compact"
>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item ant-input-compact-first-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item ant-input-compact-first-item"
>
<span
class="ant-input-wrapper ant-input-group"
@ -10079,7 +10079,7 @@ exports[`renders components/space/demo/compact-debug.tsx extend context correctl
</span>
</span>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item"
>
<span
class="ant-input-wrapper ant-input-group"
@ -11772,7 +11772,7 @@ exports[`renders components/space/demo/compact-debug.tsx extend context correctl
class="ant-space-compact"
>
<div
class="ant-picker ant-picker-range ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item ant-picker-compact-last-item"
class="ant-picker ant-picker-range ant-picker-compact-item ant-picker-compact-first-item ant-picker-compact-last-item"
style="width: 70%;"
>
<div
@ -13497,7 +13497,7 @@ Array [
class="ant-space-compact"
>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item"
style="width: 110px;"
>
<span
@ -13599,7 +13599,7 @@ Array [
class="ant-space-compact"
>
<div
class="ant-picker ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item"
class="ant-picker ant-picker-compact-item ant-picker-compact-first-item"
>
<div
class="ant-picker-input"
@ -14992,7 +14992,7 @@ Array [
class="ant-picker-ok"
>
<button
class="ant-btn ant-btn-primary ant-btn-compact-item ant-btn-compact-first-item"
class="ant-btn ant-btn-primary ant-btn-sm ant-btn-compact-item ant-btn-compact-first-item"
disabled=""
type="button"
>

26
components/space/__tests__/__snapshots__/demo.test.tsx.snap

@ -594,7 +594,7 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-space-compact ant-space-compact-block"
>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item ant-input-compact-first-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item ant-input-compact-first-item"
style="width:30%"
>
<span
@ -640,7 +640,7 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
</span>
</span>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item"
style="width:50%"
>
<span
@ -719,7 +719,7 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
</span>
</span>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item ant-input-compact-last-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item ant-input-compact-last-item"
style="width:20%"
>
<span
@ -921,7 +921,7 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
value="input content"
/>
<div
class="ant-picker ant-picker-middle ant-picker-compact-item ant-picker-compact-last-item"
class="ant-picker ant-picker-compact-item ant-picker-compact-last-item"
style="width:50%"
>
<div
@ -966,7 +966,7 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-space-compact ant-space-compact-block"
>
<div
class="ant-picker ant-picker-range ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item"
class="ant-picker ant-picker-range ant-picker-compact-item ant-picker-compact-first-item"
style="width:70%"
>
<div
@ -1073,7 +1073,7 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
value="input content"
/>
<div
class="ant-picker ant-picker-range ant-picker-middle ant-picker-compact-item ant-picker-compact-last-item"
class="ant-picker ant-picker-range ant-picker-compact-item ant-picker-compact-last-item"
style="width:70%"
>
<div
@ -1469,7 +1469,7 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-space-compact ant-space-compact-block"
>
<div
class="ant-picker ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item"
class="ant-picker ant-picker-compact-item ant-picker-compact-first-item"
style="width:70%"
>
<div
@ -1576,7 +1576,7 @@ exports[`renders components/space/demo/compact.tsx correctly 1`] = `
class="ant-space-compact ant-space-compact-block"
>
<div
class="ant-picker ant-picker-range ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item"
class="ant-picker ant-picker-range ant-picker-compact-item ant-picker-compact-first-item"
>
<div
class="ant-picker-input ant-picker-input-active"
@ -2636,7 +2636,7 @@ exports[`renders components/space/demo/compact-debug.tsx correctly 1`] = `
class="ant-space-compact"
>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item ant-input-compact-first-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item ant-input-compact-first-item"
>
<span
class="ant-input-wrapper ant-input-group"
@ -2681,7 +2681,7 @@ exports[`renders components/space/demo/compact-debug.tsx correctly 1`] = `
</span>
</span>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item"
>
<span
class="ant-input-wrapper ant-input-group"
@ -3280,7 +3280,7 @@ exports[`renders components/space/demo/compact-debug.tsx correctly 1`] = `
class="ant-space-compact"
>
<div
class="ant-picker ant-picker-range ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item ant-picker-compact-last-item"
class="ant-picker ant-picker-range ant-picker-compact-item ant-picker-compact-first-item ant-picker-compact-last-item"
style="width:70%"
>
<div
@ -3734,7 +3734,7 @@ Array [
class="ant-space-compact"
>
<span
class="ant-input-group-wrapper ant-input-search ant-input-search-middle ant-input-compact-item"
class="ant-input-group-wrapper ant-input-search ant-input-compact-item"
style="width:110px"
>
<span
@ -3836,7 +3836,7 @@ Array [
class="ant-space-compact"
>
<div
class="ant-picker ant-picker-middle ant-picker-compact-item ant-picker-compact-first-item"
class="ant-picker ant-picker-compact-item ant-picker-compact-first-item"
>
<div
class="ant-picker-input"

37
components/space/__tests__/space-compact.test.tsx

@ -12,6 +12,7 @@ import DatePicker from '../../date-picker';
import Drawer from '../../drawer';
import Dropdown from '../../dropdown';
import Input from '../../input';
import InputNumber from '../../input-number';
import Modal from '../../modal';
import Select from '../../select';
import TimePicker from '../../time-picker';
@ -156,6 +157,42 @@ describe('Space.Compact', () => {
expect(container.querySelector('.ant-input')?.classList.contains('ant-input-sm')).toBe(true);
expect(container.querySelector('.ant-btn')?.classList.contains('ant-btn-sm')).toBe(true);
});
it('component size has a higher priority than Compact', () => {
const { container } = render(
<Space.Compact size="middle">
<Input size="small" />
<Select size="small" />
<Button size="small">Submit</Button>
<InputNumber size="small" />
<DatePicker size="small" />
<DatePicker.RangePicker size="small" />
<Cascader size="small" />
<TreeSelect size="small" />
<Input.Search size="small" />
</Space.Compact>,
);
expect(container.querySelector('.ant-input')?.classList.contains('ant-input-sm')).toBe(true);
expect(container.querySelector('.ant-select')?.classList.contains('ant-select-sm')).toBe(true);
expect(container.querySelector('.ant-btn')?.classList.contains('ant-btn-sm')).toBe(true);
expect(
container.querySelector('.ant-input-number')?.classList.contains('ant-input-number-sm'),
).toBe(true);
expect(container.querySelector('.ant-picker')?.classList.contains('ant-picker-small')).toBe(
true,
);
expect(
container.querySelector('.ant-picker-range')?.classList.contains('ant-picker-small'),
).toBe(true);
expect(container.querySelector('.ant-cascader')?.classList.contains('ant-select-sm')).toBe(
true,
);
expect(container.querySelector('.ant-tree-select')?.classList.contains('ant-select-sm')).toBe(
true,
);
expect(
container.querySelector('.ant-input-search')?.classList.contains('ant-input-search-small'),
).toBe(true);
});
it('direction=vertical', () => {
const { container } = render(

2
components/table/__tests__/Table.filter.test.tsx

@ -134,6 +134,8 @@ describe('Table.filter', () => {
});
it('renders empty menu correctly', () => {
resetWarned();
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const { container } = render(
createTable({

19
components/table/hooks/useFilter/FilterWrapper.tsx

@ -13,10 +13,21 @@ const onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event) => {
}
};
const FilterDropdownMenuWrapper: React.FC<FilterDropdownMenuWrapperProps> = (props) => (
<div className={props.className} onClick={(e) => e.stopPropagation()} onKeyDown={onKeyDown}>
{props.children}
</div>
const FilterDropdownMenuWrapper = React.forwardRef<HTMLDivElement, FilterDropdownMenuWrapperProps>(
(props, ref) => (
<div
className={props.className}
onClick={(e) => e.stopPropagation()}
onKeyDown={onKeyDown}
ref={ref}
>
{props.children}
</div>
),
);
if (process.env.NODE_ENV !== 'production') {
FilterDropdownMenuWrapper.displayName = 'FilterDropdownMenuWrapper';
}
export default FilterDropdownMenuWrapper;

2
components/table/index.en-US.md

@ -192,7 +192,7 @@ One of the Table `columns` prop for describing the table's columns, Column has t
| shouldCellUpdate | Control cell render logic | (record, prevRecord) => boolean | - | 4.3.0 |
| showSorterTooltip | If header show next sorter direction tooltip, override `showSorterTooltip` in table | boolean \| [Tooltip props](/components/tooltip/) | true | |
| sortDirections | Supported sort way, override `sortDirections` in `Table`, could be `ascend`, `descend` | Array | \[`ascend`, `descend`] | |
| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | function \| boolean | - | |
| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | function \| boolean \| { compare: function: multiple: number } | - | |
| sortOrder | Order of sorted values: `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | |
| sortIcon | Customized sort icon | (props: { sortOrder }) => ReactNode | - | 5.6.0 |
| title | Title of this column | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | |

2
components/table/index.zh-CN.md

@ -194,7 +194,7 @@ const columns = [
| shouldCellUpdate | 自定义单元格渲染时机 | (record, prevRecord) => boolean | - | 4.3.0 |
| showSorterTooltip | 表头显示下一次排序的 tooltip 提示, 覆盖 table 中 `showSorterTooltip` | boolean \| [Tooltip props](/components/tooltip-cn/#api) | true | |
| sortDirections | 支持的排序方式,覆盖 `Table``sortDirections`, 取值为 `ascend` `descend` | Array | \[`ascend`, `descend`] | |
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | function \| boolean | - | |
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | function \| boolean \| { compare: function: multiple: number } | - | |
| sortOrder | 排序的受控属性,外界可用此控制列的排序,可设置为 `ascend` `descend` `null` | `ascend` \| `descend` \| null | - | |
| sortIcon | 自定义 sort 图标 | (props: { sortOrder }) => ReactNode | - | 5.6.0 |
| title | 列头显示文字(函数用法 `3.10.0` 后支持) | ReactNode \| ({ sortOrder, sortColumn, filters }) => ReactNode | - | |

30
components/transfer/__tests__/index.test.tsx

@ -496,10 +496,32 @@ describe('Transfer', () => {
expect(onScroll).toHaveBeenLastCalledWith('right', expect.anything());
});
it('should support rowKey is function', () => {
expect(() => {
render(<Transfer {...listCommonProps} rowKey={(record) => record.key} />);
}).not.toThrow();
it('support rowKey', () => {
const onSelectChange = jest.fn();
const Demo = () => {
const [selectedKeys, setSelectedKeys] = useState<string[]>([]);
return (
<Transfer
{...listCommonProps}
selectedKeys={selectedKeys}
rowKey={(record) => `key_${record.key}`}
onSelectChange={(keys) => {
onSelectChange(keys);
setSelectedKeys(keys);
}}
/>
);
};
const { container } = render(<Demo />);
fireEvent.click(container.querySelector('.ant-transfer-list-content input')!);
expect(onSelectChange).toHaveBeenCalledWith(['key_a']);
expect(
container.querySelector<HTMLInputElement>('.ant-transfer-list-content input')!.checked,
).toBeTruthy();
});
it('should support render value and label in item', () => {

6
components/transfer/hooks/useSelection.ts

@ -7,6 +7,10 @@ function filterKeys(keys: string[], dataKeys: Set<string>) {
return keys.length === filteredKeys.length ? keys : filteredKeys;
}
function flattenKeys(keys: Set<string>) {
return Array.from(keys).join(';');
}
export default function useSelection<T extends { key: string }>(
leftDataSource: T[],
rightDataSource: T[],
@ -44,7 +48,7 @@ export default function useSelection<T extends { key: string }>(
React.useEffect(() => {
setSourceSelectedKeys(filterKeys(sourceSelectedKeys, leftKeys));
setTargetSelectedKeys(filterKeys(targetSelectedKeys, rightKeys));
}, [leftKeys, rightKeys]);
}, [flattenKeys(leftKeys), flattenKeys(rightKeys)]);
return [
// Keys

2
components/tree-select/index.tsx

@ -206,7 +206,7 @@ const InternalTreeSelect = <
const mergedBuiltinPlacements = useBuiltinPlacements(builtinPlacements, popupOverflow);
const mergedSize = useSize((ctx) => compactSize ?? customizeSize ?? ctx);
const mergedSize = useSize((ctx) => customizeSize ?? compactSize ?? ctx);
// ===================== Disabled =====================
const disabled = React.useContext(DisabledContext);

2
components/tree/index.en-US.md

@ -61,7 +61,7 @@ Almost anything can be represented in a tree structure. Examples include directo
| rootClassName | ClassName on the root element | string | - | 4.20.0 |
| rootStyle | Style on the root element | CSSProperties | - | 4.20.0 |
| selectable | Whether can be selected | boolean | true | |
| selectedKeys | (Controlled) Specifies the keys of the selected treeNodes | string\[] | - | |
| selectedKeys | (Controlled) Specifies the keys of the selected treeNodes, multiple selection needs to set `multiple` to true | string\[] | - | |
| showIcon | Shows the icon before a TreeNode's title. There is no default style; you must set a custom style for it if set to true | boolean | false | |
| showLine | Shows a connecting line | boolean \| {showLeafIcon: boolean \| ReactNode \| ((props: AntTreeNodeProps) => ReactNode)} | false | |
| switcherIcon | Customize collapse/expand icon of tree node | ReactNode \| ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.20.0 |

2
components/tree/index.zh-CN.md

@ -63,7 +63,7 @@ demo:
| rootClassName | 添加在 Tree 最外层的 className | string | - | 4.20.0 |
| rootStyle | 添加在 Tree 最外层的 style | CSSProperties | - | 4.20.0 |
| selectable | 是否可选中 | boolean | true | |
| selectedKeys | (受控)设置选中的树节点 | string\[] | - | |
| selectedKeys | (受控)设置选中的树节点,多选需设置 `multiple` 为 true | string\[] | - | |
| showIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true,需要自行定义图标相关样式 | boolean | false | |
| showLine | 是否展示连接线 | boolean \| {showLeafIcon: boolean \| ReactNode \| ((props: AntTreeNodeProps) => ReactNode)} | false | |
| switcherIcon | 自定义树节点的展开/折叠图标 | ReactNode \| ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.20.0 |

11
components/upload/Dragger.tsx

@ -1,12 +1,15 @@
import * as React from 'react';
import type { UploadProps } from './interface';
import type { UploadRef } from './Upload';
import Upload from './Upload';
import type { UploadProps } from './interface';
export type DraggerProps = UploadProps & { height?: number };
const Dragger = React.forwardRef<unknown, DraggerProps>(({ style, height, ...restProps }, ref) => (
<Upload ref={ref} {...restProps} type="drag" style={{ ...style, height }} />
));
const Dragger = React.forwardRef<UploadRef, DraggerProps>(
({ style, height, ...restProps }, ref) => (
<Upload ref={ref} {...restProps} type="drag" style={{ ...style, height }} />
),
);
if (process.env.NODE_ENV !== 'production') {
Dragger.displayName = 'Dragger';

37
components/upload/Upload.tsx

@ -4,11 +4,12 @@ import RcUpload from 'rc-upload';
import useMergedState from 'rc-util/lib/hooks/useMergedState';
import * as React from 'react';
import { flushSync } from 'react-dom';
import warning from '../_util/warning';
import { ConfigContext } from '../config-provider';
import DisabledContext from '../config-provider/DisabledContext';
import defaultLocale from '../locale/en_US';
import { useLocale } from '../locale';
import warning from '../_util/warning';
import defaultLocale from '../locale/en_US';
import UploadList from './UploadList';
import type {
RcFile,
ShowUploadListInterface,
@ -16,16 +17,23 @@ import type {
UploadFile,
UploadProps,
} from './interface';
import UploadList from './UploadList';
import { file2Obj, getFileItem, removeFileItem, updateFileList } from './utils';
import useStyle from './style';
import { file2Obj, getFileItem, removeFileItem, updateFileList } from './utils';
export const LIST_IGNORE = `__LIST_IGNORE_${Date.now()}__`;
export type { UploadProps };
const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (props, ref) => {
export interface UploadRef<T = any> {
onBatchStart: RcUploadProps['onBatchStart'];
onSuccess: (response: any, file: RcFile, xhr: any) => void;
onProgress: (e: { percent: number }, file: RcFile) => void;
onError: (error: Error, response: any, file: RcFile) => void;
fileList: UploadFile<T>[];
upload: RcUpload | null;
}
const InternalUpload: React.ForwardRefRenderFunction<UploadRef, UploadProps> = (props, ref) => {
const {
fileList,
defaultFileList,
@ -99,10 +107,13 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
) => {
let cloneList = [...changedFileList];
let exceedMaxCount = false;
// Cut to match count
if (maxCount === 1) {
cloneList = cloneList.slice(-1);
} else if (maxCount) {
exceedMaxCount = true;
cloneList = cloneList.slice(0, maxCount);
}
@ -121,9 +132,15 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
changeInfo.event = event;
}
flushSync(() => {
onChange?.(changeInfo);
});
if (
!exceedMaxCount ||
// We should ignore event if current file is exceed `maxCount`
cloneList.some((f) => f.uid === file.uid)
) {
flushSync(() => {
onChange?.(changeInfo);
});
}
};
const mergedBeforeUpload = async (file: RcFile, fileListArgs: RcFile[]) => {
@ -461,7 +478,7 @@ const InternalUpload: React.ForwardRefRenderFunction<unknown, UploadProps> = (pr
);
};
const Upload = React.forwardRef<unknown, UploadProps>(InternalUpload);
const Upload = React.forwardRef<UploadRef, UploadProps>(InternalUpload);
if (process.env.NODE_ENV !== 'production') {
Upload.displayName = 'Upload';

7
components/upload/UploadList/ListItem.tsx

@ -82,15 +82,12 @@ const ListItem = React.forwardRef(
// Delay to show the progress bar
const [showProgress, setShowProgress] = React.useState(false);
const progressRafRef = React.useRef<NodeJS.Timer | null>(null);
React.useEffect(() => {
progressRafRef.current = setTimeout(() => {
const timer = setTimeout(() => {
setShowProgress(true);
}, 300);
return () => {
if (progressRafRef.current) {
clearTimeout(progressRafRef.current);
}
clearTimeout(timer);
};
}, []);

15
components/upload/UploadList/index.tsx

@ -6,17 +6,22 @@ import classNames from 'classnames';
import type { CSSMotionListProps } from 'rc-motion';
import CSSMotion, { CSSMotionList } from 'rc-motion';
import * as React from 'react';
import type { ButtonProps } from '../../button';
import Button from '../../button';
import { ConfigContext } from '../../config-provider';
import useForceUpdate from '../../_util/hooks/useForceUpdate';
import initCollapseMotion from '../../_util/motion';
import { cloneElement, isValidElement } from '../../_util/reactNode';
import type { ButtonProps } from '../../button';
import Button from '../../button';
import { ConfigContext } from '../../config-provider';
import type { InternalUploadFile, UploadFile, UploadListProps } from '../interface';
import { isImageUrl, previewImage } from '../utils';
import ListItem from './ListItem';
const InternalUploadList: React.ForwardRefRenderFunction<unknown, UploadListProps> = (
interface UploadListRef {
handlePreview: (file: UploadFile, e?: React.SyntheticEvent<HTMLElement>) => void;
handleDownload: (file: UploadFile) => void;
}
const InternalUploadList: React.ForwardRefRenderFunction<UploadListRef, UploadListProps> = (
props,
ref,
) => {
@ -254,7 +259,7 @@ const InternalUploadList: React.ForwardRefRenderFunction<unknown, UploadListProp
);
};
const UploadList = React.forwardRef<unknown, UploadListProps>(InternalUploadList);
const UploadList = React.forwardRef<UploadListRef, UploadListProps>(InternalUploadList);
if (process.env.NODE_ENV !== 'production') {
UploadList.displayName = 'UploadList';

7
components/upload/__tests__/upload.test.tsx

@ -480,7 +480,7 @@ describe('Upload', () => {
// Delay return true for remove
await waitFakeTimer();
await act(async () => {
await removePromise(true);
removePromise(true);
});
expect(onChange).toHaveBeenCalled();
@ -771,6 +771,11 @@ describe('Upload', () => {
name: 'foo.png',
}),
]);
// Only trigger for file in `maxCount`
onChange.mock.calls.forEach((args) => {
expect(args[0].file.name).toBe('foo.png');
});
});
});

1
docs/blog/why-not-static.en-US.md

@ -2,6 +2,7 @@
title: Pain of static methods
date: 2023-04-26
author: zombieJ
zhihu_url: https://zhuanlan.zhihu.com/p/633333904
---
> `message.success` is working well, why do you warn me to use hooks? antd is getting worse and worse, goodbye!

1
docs/blog/why-not-static.zh-CN.md

@ -2,6 +2,7 @@
title: 静态方法之痛
date: 2023-04-26
author: zombieJ
zhihu_url: https://zhuanlan.zhihu.com/p/633333904
---
> `message.success` 用的好好的为什么要 warning 我去用 hooks?antd 越做越垃圾,走好不送!

54
docs/react/contributing.en-US.md

@ -49,12 +49,12 @@ The core team is monitoring for pull requests. We will review your pull request
**Before submitting a pull request**, please make sure the following is done:
1. Fork the repository and create your branch from the [correct branch](#branch-organization).
1. Run `npm install` in the repository root.
1. If you've fixed a bug or added code that should be tested, add tests!
1. Ensure the test suite passes (npm run test). Tip: `npm test -- --watch TestName` is helpful in development.
1. Run `npm test -- -u` to update the [jest snapshots](https://jestjs.io/docs/snapshot-testing) and commit these changes as well (if there are any updates).
1. Ensure the UI change passes `npm run test-image`,Run `npm run test-image -- -u` to update UI snapshots and commit these changes as well (if there are any updates), **UI test base on [Docker](https://docs.docker.com/get-docker/), need download the corresponding installation according to the platform**
1. Make sure your code lints (npm run lint). Tip: Lint runs automatically when you `git commit` (Use [Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)).
2. Run `npm install` in the repository root.
3. If you've fixed a bug or added code that should be tested, add tests!
4. Ensure the test suite passes (npm run test). Tip: `npm test -- --watch TestName` is helpful in development.
5. Run `npm test -- -u` to update the [jest snapshots](https://jestjs.io/docs/snapshot-testing) and commit these changes as well (if there are any updates).
6. Ensure the UI change passes `npm run test-image`,Run `npm run test-image -- -u` to update UI snapshots and commit these changes as well (if there are any updates), **UI test base on [Docker](https://docs.docker.com/get-docker/), need download the corresponding installation according to the platform**
7. Make sure your code lints (npm run lint). Tip: Lint runs automatically when you `git commit` (Use [Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks)).
Sending a Pull Request to [react-component](https://github.com/react-component/):
@ -62,19 +62,41 @@ Since antd's components are based on react-component, sometimes you may need to
## Development Workflow
Before you can start you must run the following command to enable [corepack](https://nodejs.org/api/corepack.html)。
`npm` or `yarn` are recommended as package management tools.
```bash
corepack enable
```
After you clone the antd code and use following commands to install dependencies:
After cloning antd, run `npm install` to fetch its dependencies. Then, you can run several commands:
<InstallDependencies npm='$ npm install' yarn='$ yarn'></InstallDependencies>
1. `npm start` runs Ant Design website locally.
1. `npm run lint` checks the code style.
1. `npm test` runs the complete test suite. (Make sure the `NODE_ENV` environment variable is unset, or it may causing some problems.)
1. `npm run compile` compiles TypeScript code to the `lib` and `es` directory.
1. `npm run dist` creates UMD build of antd.
You can also run the following common commands:
### Run locally
Runs Ant Design website locally.
<InstallDependencies npm='$ npm start' yarn='$ yarn start'></InstallDependencies>
### Checks the code style
<InstallDependencies npm='$ npm run lint' yarn='$ yarn lint'></InstallDependencies>
### Run test
runs the complete test suite. (Make sure the `NODE_ENV` environment variable is unset, or it may causing some problems.)
<InstallDependencies npm='$ npm test' yarn='$ yarn test'></InstallDependencies>
### Compile
compiles TypeScript code to the `lib` and `es` directory.
<InstallDependencies npm='$ npm run compile' yarn='$ yarn compile'></InstallDependencies>
### Build
creates UMD build of antd.
<InstallDependencies npm='$ npm run dist' yarn='$ yarn dist'></InstallDependencies>
## Development Tools

54
docs/react/contributing.zh-CN.md

@ -49,12 +49,12 @@ Ant Design 团队会关注所有的 pull request,我们会 review 以及合并
**在你发送 Pull Request 之前**,请确认你是按照下面的步骤来做的:
1. 基于 [正确的分支](#分支管理) 做修改。
1. 在项目根目录下运行了 `npm install`
1. 如果你修复了一个 bug 或者新增了一个功能,请确保写了相应的测试,这很重要。
1. 确认所有的测试都是通过的 `npm run test`。 小贴士:开发过程中可以用 `npm test -- --watch TestName` 来运行指定的测试。
1. 运行 `npm test -- -u` 来更新 [jest snapshot](https://jestjs.io/zh-Hans/docs/snapshot-testing) 并且把这些更新也提交上来(如果有的话)。
1. 确认所有的 UI 改动通过 `npm run test-image`,可以运行 `npm run test-image -- -u` 更新 UI 快照并且把这些更新也提交上来(如果有的话),**UI 测试基于 [Docker](https://docs.docker.com/get-docker/),根据平台下载对应的安装程序。**
1. 确保你的代码通过了 lint 检查 `npm run lint`. 小贴士: Lint 会在你 `git commit` 的时候自动运行(通过[Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks))。
2. 在项目根目录下运行了 `npm install`
3. 如果你修复了一个 bug 或者新增了一个功能,请确保写了相应的测试,这很重要。
4. 确认所有的测试都是通过的 `npm run test`。 小贴士:开发过程中可以用 `npm test -- --watch TestName` 来运行指定的测试。
5. 运行 `npm test -- -u` 来更新 [jest snapshot](https://jestjs.io/zh-Hans/docs/snapshot-testing) 并且把这些更新也提交上来(如果有的话)。
6. 确认所有的 UI 改动通过 `npm run test-image`,可以运行 `npm run test-image -- -u` 更新 UI 快照并且把这些更新也提交上来(如果有的话),**UI 测试基于 [Docker](https://docs.docker.com/get-docker/),根据平台下载对应的安装程序。**
7. 确保你的代码通过了 lint 检查 `npm run lint`. 小贴士: Lint 会在你 `git commit` 的时候自动运行(通过[Git Hooks](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks))。
给 [react-component](https://github.com/react-component/) 发送 pull request:
@ -62,19 +62,41 @@ Ant Design 团队会关注所有的 pull request,我们会 review 以及合并
## 开发流程
在开始之前,请先执行下面的命令启用 [corepack](https://nodejs.org/api/corepack.html)。
推荐使用 `npm``yarn` 作为包管理工具
```bash
corepack enable
```
在你 clone 了 antd 的代码并且使用
在你 clone 了 antd 的代码并且使用 `npm install` 安装完依赖后,你还可以运行下面几个常用的命令:
<InstallDependencies npm='$ npm install' yarn='$ yarn'></InstallDependencies>
1. `npm start` 在本地运行 Ant Design 的网站。
2. `npm run lint` 检查代码风格。
3. `npm test` 运行测试。(在运行测试前请确保 `NODE_ENV` 环境变量没有被设定,否则可能会引发一些问题)
4. `npm run compile` 编译 TypeScript 代码到 lib 和 es 目录。
5. `npm run dist` 构建 antd 的 UMD 版本到 dist 目录。
安装完依赖后,你还可以运行下面几个常用的命令:
### 本地运行
在本地运行 Ant Design 的网站。
<InstallDependencies npm='$ npm start' yarn='$ yarn start'></InstallDependencies>
### 代码风格检测
<InstallDependencies npm='$ npm run lint' yarn='$ yarn lint'></InstallDependencies>
### 运行测试用例
运行测试。(在运行测试前请确保 `NODE_ENV` 环境变量没有被设定,否则可能会引发一些问题)
<InstallDependencies npm='$ npm test' yarn='$ yarn test'></InstallDependencies>
### 编译
编译 TypeScript 代码到 lib 和 es 目录。
<InstallDependencies npm='$ npm run compile' yarn='$ yarn compile'></InstallDependencies>
### 构建
构建 antd 的 UMD 版本到 dist 目录。
<InstallDependencies npm='$ npm run dist' yarn='$ yarn dist'></InstallDependencies>
## 配套开发工具

4
docs/react/customize-theme.en-US.md

@ -425,8 +425,8 @@ Then, you just need to import this file into the `pages/_app.tsx` file:
```tsx
import { StyleProvider } from '@ant-design/cssinjs';
import type { AppProps } from 'next/app';
import '../public/antd.min.css';
import '../styles/globals.css'; // add this line
import '../public/antd.min.css'; // add this line
import '../styles/globals.css';
export default function App({ Component, pageProps }: AppProps) {
return (

4
docs/react/customize-theme.zh-CN.md

@ -421,8 +421,8 @@ fs.writeFileSync(outputPath, css);
```tsx
import { StyleProvider } from '@ant-design/cssinjs';
import type { AppProps } from 'next/app';
import '../public/antd.min.css';
import '../styles/globals.css'; // 添加这行
import '../public/antd.min.css'; // 添加这行
import '../styles/globals.css';
export default function App({ Component, pageProps }: AppProps) {
return (

31
docs/react/getting-started.en-US.md

@ -3,11 +3,11 @@ order: 2
title: Getting Started
---
Ant Design React is dedicated to providing a **good development experience** for programmers. Before starting, it is recommended to learn [React](https://reactjs.org) and [ES2015](http://babeljs.io/docs/learn-es2015/) first, and correctly install and configure [Node.js](https://nodejs.org/) v8 or above.
Ant Design React is dedicated to providing a **good development experience** for programmers. Before starting, it is recommended to learn [React](https://react.dev) first, and correctly install and configure [Node.js](https://nodejs.org/) v16 or above.
The official guide also assumes that you have intermediate knowledge about HTML, CSS, and JavaScript, and React. If you are just starting to learn front-end or React, it may not be the best idea to use the UI framework as your first step.
Finally, if you are working in a local development environment, please refer to [Install and Initialization](/docs/react/use-with-create-react-app#install-and-initialization) section of "Use in create-react-app".
Finally, if you are working in a local development environment, please refer to [Use with create-react-app](/docs/react/use-with-create-react-app).
---
@ -27,25 +27,25 @@ Follow the steps below to play around with Ant Design yourself:
### 1. Create a codesandbox
Visit http://u.ant.design/codesandbox-repro to create a codesandbox -- don't forget to press the save button as well to create a new instance.
Visit https://u.ant.design/codesandbox-repro to create a codesandbox -- don't forget to press the save button as well to create a new instance.
### 2. Use and modify an antd component
Replace the contents of `index.js` with the following code. As you can see, there is no difference between antd's components and typical React components.
If you have already set things up by following the [Install and Initialization](/docs/react/use-with-create-react-app#install-and-initialization) section of "Use in create-react-app", replace the content of `/src/index.js` as follows:
If you have already set things up by following the [Use with create-react-app](/docs/react/use-with-create-react-app), replace the content of `/src/index.js` as follows:
```jsx
import React, { useState } from 'react';
import { render } from 'react-dom';
import { createRoot } from 'react-dom/client';
import { DatePicker, message } from 'antd';
import 'antd/dist/reset.css';
import './index.css';
const App = () => {
const [date, setDate] = useState(null);
const [messageApi, contextHolder] = message.useMessage();
const handleChange = (value) => {
message.info(`Selected Date: ${value ? value.format('YYYY-MM-DD') : 'None'}`);
messageApi.info(`Selected Date: ${value ? value.format('YYYY-MM-DD') : 'None'}`);
setDate(value);
};
return (
@ -54,11 +54,12 @@ const App = () => {
<div style={{ marginTop: 16 }}>
Selected Date: {date ? date.format('YYYY-MM-DD') : 'None'}
</div>
{contextHolder}
</div>
);
};
render(<App />, document.getElementById('root'));
createRoot(document.getElementById('root')).render(<App />);
```
### 3. Explore more components
@ -92,15 +93,13 @@ OK! Now that you know the basics of using antd components, you are welcome to ex
During actual real-world project development, you will most likely need a development workflow consisting of `compile/build/deploy/lint/debug/` deployment. You can read the following documents on the subject or use the following scaffolds and examples provided below:
- [Ant Design Pro](http://pro.ant.design/)
- [antd-admin](https://github.com/zuiidea/antd-admin)
- [d2-admin](https://github.com/d2-projects/d2-admin)
- [Use in Next](https://github.com/ant-design/create-next-app-antd)
- More scaffolds at [Scaffold Market](http://scaffold.ant.design/)
- [Ant Design Pro](https://pro.ant.design/)
- [create-next-app](https://github.com/ant-design/create-next-app-antd)
- More scaffolds at [Scaffold Market](https://scaffold.ant.design/)
## Test with Jest
If you use `create-react-app` follow the instructions [here](/docs/react/use-with-create-react-app#test-with-jest) instead.
If you use `create-react-app` follow the instructions [here](/docs/react/use-with-create-react-app) instead.
Jest does not support `esm` modules, and Ant Design uses them. In order to test your Ant Design application with Jest you have to add the following to your Jest config :
@ -114,6 +113,6 @@ Jest does not support `esm` modules, and Ant Design uses them. In order to test
## Customize your Workflow
If you want to customize your workflow, we recommend using [webpack](http://webpack.github.io/) to build and debug code. You can try out plenty of [boilerplates](https://github.com/enaqx/awesome-react#react-tools) available in the React ecosystem.
If you want to customize your workflow, we recommend using [webpack](https://webpack.js.org) to build and debug code. You can try out plenty of [boilerplates](https://github.com/enaqx/awesome-react#react-tools) available in the React ecosystem.
There are also some [scaffolds](http://scaffold.ant.design/) which have already been integrated into antd, so you can try and start with one of these and even contribute.
There are also some [scaffolds](https://scaffold.ant.design/) which have already been integrated into antd, so you can try and start with one of these and even contribute.

25
docs/react/getting-started.zh-CN.md

@ -5,7 +5,7 @@ title: 快速上手
Ant Design React 致力于提供给程序员**愉悦**的开发体验。
> 在开始之前,推荐先学习 [React](http://reactjs.org) 和 [ES2015](http://babeljs.io/docs/learn-es2015/),并正确安装和配置了 [Node.js](https://nodejs.org/) v8 或以上。官方指南假设你已了解关于 HTML、CSS 和 JavaScript 的中级知识,并且已经完全掌握了 React 全家桶的正确开发方式。如果你刚开始学习前端或者 React,将 UI 框架作为你的第一步可能不是最好的主意。
> 在开始之前,推荐先学习 [React](https://react.dev),并正确安装和配置了 [Node.js](https://nodejs.org/) v16 或以上。官方指南假设你已了解关于 HTML、CSS 和 JavaScript 的中级知识,并且已经完全掌握了 React 全家桶的正确开发方式。如果你刚开始学习前端或者 React,将 UI 框架作为你的第一步可能不是最好的主意。
---
@ -23,7 +23,7 @@ Ant Design React 致力于提供给程序员**愉悦**的开发体验。
### 1. 创建一个 codesandbox
访问 http://u.ant.design/codesandbox-repro 创建一个 codesandbox 的在线示例,别忘了保存以创建一个新的实例。
访问 https://u.ant.design/codesandbox-repro 创建一个 codesandbox 的在线示例,别忘了保存以创建一个新的实例。
### 2. 使用组件
@ -31,21 +31,21 @@ Ant Design React 致力于提供给程序员**愉悦**的开发体验。
```jsx
import React, { useState } from 'react';
import { render } from 'react-dom';
import { createRoot } from 'react-dom/client';
import { ConfigProvider, DatePicker, message } from 'antd';
// 由于 antd 组件的默认文案是英文,所以需要修改为中文
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
import zhCN from 'antd/locale/zh_CN';
import 'antd/dist/reset.css';
import './index.css';
dayjs.locale('zh-cn');
const App = () => {
const [date, setDate] = useState(null);
const [messageApi, contextHolder] = message.useMessage();
const handleChange = (value) => {
message.info(`您选择的日期是: ${value ? value.format('YYYY年MM月DD日') : '未选择'}`);
messageApi.info(`您选择的日期是: ${value ? value.format('YYYY年MM月DD日') : '未选择'}`);
setDate(value);
};
return (
@ -56,11 +56,12 @@ const App = () => {
当前日期:{date ? date.format('YYYY年MM月DD日') : '未选择'}
</div>
</div>
{contextHolder}
</ConfigProvider>
);
};
render(<App />, document.getElementById('root'));
createRoot(document.getElementById('root')).render(<App />);
```
### 3. 探索更多组件用法
@ -94,11 +95,9 @@ render(<App />, document.getElementById('root'));
实际项目开发中,你会需要构建、调试、代理、打包部署等一系列工程化的需求。您可以阅读后面的文档或者使用以下脚手架和范例:
- [Ant Design Pro](http://pro.ant.design/)
- [antd-admin](https://github.com/zuiidea/antd-admin)
- [d2-admin](https://github.com/d2-projects/d2-admin)
- [Use in Next](https://github.com/ant-design/create-next-app-antd)
- 更多脚手架可以查看 [脚手架市场](http://scaffold.ant.design/)
- [Ant Design Pro](https://pro.ant.design/)
- [create-next-app](https://github.com/ant-design/create-next-app-antd)
- 更多脚手架可以查看 [脚手架市场](https://scaffold.ant.design/)
## 按需加载
@ -106,6 +105,6 @@ render(<App />, document.getElementById('root'));
## 自行构建
如果想自己维护工作流,我们推荐使用 [webpack](https://webpack.github.io/) 进行构建和调试,可以使用 React 生态圈中的 [各种脚手架](https://github.com/enaqx/awesome-react#react-tools) 进行开发。
如果想自己维护工作流,我们推荐使用 [webpack](https://webpack.js.org) 进行构建和调试,可以使用 React 生态圈中的 [各种脚手架](https://github.com/enaqx/awesome-react#react-tools) 进行开发。
目前社区也有很多基于 antd 定制的 [React 脚手架](http://scaffold.ant.design/),欢迎进行试用和贡献。
目前社区也有很多基于 antd 定制的 [React 脚手架](https://scaffold.ant.design/),欢迎进行试用和贡献。

26
docs/react/introduce.en-US.md

@ -8,21 +8,9 @@ Following the Ant Design specification, we developed a React UI library `antd` t
<div class="pic-plus">
<img width="150" src="https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg" />
<span>+</span>
<img width="160" src="https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg" />
<img width="160" src="https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg" />
</div>
<style>
.pic-plus > * {
display: inline-block !important;
vertical-align: middle;
}
.pic-plus span {
margin: 0 20px;
color: #aaa;
font-size: 30px;
}
</style>
---
## ✨ Features
@ -56,17 +44,11 @@ You can subscribe to this feed for new version notifications: https://github.com
## Installation
### Using npm or yarn
**We recommend using npm or yarn to install**, it not only makes development easier, but also allow you to take advantage of the rich ecosystem of Javascript packages and tooling.
### Using npm or yarn or pnpm
```bash
$ npm install antd
```
**We recommend using [npm](https://www.npmjs.com/) or [yarn](https://github.com/yarnpkg/yarn/) or [pnpm](https://pnpm.io/) to install**, it not only makes development easier, but also allow you to take advantage of the rich ecosystem of Javascript packages and tooling.
```bash
$ yarn add antd
```
<InstallDependencies npm='$ npm install antd --save' yarn='$ yarn add antd' pnpm='$ pnpm install antd --save'></InstallDependencies>
If you are in a bad network environment, you can try other registries and tools like [cnpm](https://github.com/cnpm/cnpm).

24
docs/react/introduce.zh-CN.md

@ -11,18 +11,6 @@ title: Ant Design of React
<img width="160" src="https://gw.alipayobjects.com/zos/antfincdn/aPkFc8Sj7n/method-draw-image.svg"/>
</div>
<style>
.pic-plus > * {
display: inline-block !important;
vertical-align: middle;
}
.pic-plus span {
margin: 0 20px;
color: #aaa;
font-size: 30px;
}
</style>
---
## ✨ 特性
@ -56,17 +44,11 @@ title: Ant Design of React
## 安装
### 使用 npm 或 yarn 安装
**我们推荐使用 npm 或 yarn 的方式进行开发**,不仅可在开发环境轻松调试,也可放心地在生产环境打包部署使用,享受整个生态圈和工具链带来的诸多好处。
### 使用 npm 或 yarn 或 pnpm 安装
```bash
$ npm install antd --save
```
**我们推荐使用 [npm](https://www.npmjs.com/) 或 [yarn](https://github.com/yarnpkg/yarn/) 或 [pnpm](https://pnpm.io/zh/) 的方式进行开发**,不仅可在开发环境轻松调试,也可放心地在生产环境打包部署使用,享受整个生态圈和工具链带来的诸多好处。
```bash
$ yarn add antd
```
<InstallDependencies npm='$ npm install antd --save' yarn='$ yarn add antd' pnpm='$ pnpm install antd --save'></InstallDependencies>
如果你的网络环境不佳,推荐使用 [cnpm](https://github.com/cnpm/cnpm)。

12
docs/react/migrate-less-variables.en-US.md

@ -42,7 +42,7 @@ export default App;
<!-- ### Alert -->
## Anchor
### Anchor
<!-- prettier-ignore -->
| Less variables | Component Token | Note |
@ -89,7 +89,7 @@ export default App;
<!-- ### Button -->
## Calendar
### Calendar
<!-- prettier-ignore -->
| Less variables | Component Token | Note |
@ -127,7 +127,7 @@ export default App;
| `@card-head-tabs-margin-bottom` | `tabsMarginBottom` | - |
| `@card-head-extra-color` | `extraColor` | - |
## Carousel
### Carousel
<!-- prettier-ignore -->
| Less variables | Component Token | Note |
@ -140,7 +140,7 @@ export default App;
<!-- ### Checkbox -->
## Checkbox
### Checkbox
<!-- prettier-ignore -->
| Less variables | Component Token | Note |
@ -344,7 +344,7 @@ export default App;
| `@radio-disabled-button-checked-color` | `buttonCheckdColorDisabled` | - |
| `@radio-wrapper-margin-right` | `wrapperMarginInlineEnd` | - |
## Rate
### Rate
<!-- prettier-ignore -->
| Less variables | Component Token | Note |
@ -464,7 +464,7 @@ export default App;
| `@tabs-card-gutter` | `cardGutter` | - |
| `@tabs-card-tab-active-border-top` | - | Deprecated |
## Tag
### Tag
<!-- prettier-ignore -->
| Less variables | Component Token | Note |

12
docs/react/migrate-less-variables.zh-CN.md

@ -42,7 +42,7 @@ export default App;
<!-- ### Alert 警告提示 -->
## Anchor 锚点
### Anchor 锚点
<!-- prettier-ignore -->
| Less 变量 | Component Token | 备注 |
@ -89,7 +89,7 @@ export default App;
<!-- ### Button 按钮 -->
## Calendar 日历
### Calendar 日历
<!-- prettier-ignore -->
| Less 变量 | Component Token | 备注 |
@ -138,7 +138,7 @@ export default App;
<!-- ### Cascader 级联选择 -->
## Checkbox 多选框
### Checkbox 多选框
<!-- prettier-ignore -->
| Less 变量 | Component Token | 备注 |
@ -320,7 +320,7 @@ Mentions 提及
<!-- ### Progress 进度条 -->
## Radio 单选框
### Radio 单选框
<!-- prettier-ignore -->
| less 变量 | Component Token | 备注 |
@ -342,7 +342,7 @@ Mentions 提及
| `@radio-disabled-button-checked-color` | `buttonCheckdColorDisabled` | - |
| `@radio-wrapper-margin-right` | `wrapperMarginInlineEnd` | - |
## Rate 评分
### Rate 评分
<!-- prettier-ignore -->
| less 变量 | Component Token | 备注 |
@ -461,7 +461,7 @@ Mentions 提及
| `@tabs-card-gutter` | `cardGutter` | - |
| `@tabs-card-tab-active-border-top` | - | 已废弃 |
## Tag 标签
### Tag 标签
<!-- prettier-ignore -->
| less 变量 | Component Token | 备注 |

41
docs/react/use-with-create-react-app.en-US.md

@ -3,13 +3,15 @@ order: 4
title: Usage with create-react-app
---
[create-react-app](https://create-react-app.dev/) is one of the best React application development tools, This article will try to use `create-react-app` to create a project, and introduce antd.
[create-react-app](https://create-react-app.dev/) is one of the best React application development tools, This article will try to use `create-react-app` to create a `TypeScript` project, and introduce antd.
> We build `antd` based on latest stable version of TypeScript (`>=5.0.0`), please make sure your project dependency matches it.
## Install and Initialization
Before all start, you may need install [yarn](https://github.com/yarnpkg/yarn/) or [pnpm](https://pnpm.io/).
<InstallDependencies npm='$ npx create-react-app antd-demo' yarn='$ yarn create react-app antd-demo' pnpm='$ pnpm create react-app antd-demo'></InstallDependencies>
<InstallDependencies npm='$ npx create-react-app antd-demo --template typescript' yarn='$ yarn create react-app antd-demo --template typescript' pnpm='$ pnpm create react-app antd-demo --template typescript'></InstallDependencies>
The tool will create and initialize environment and dependencies automatically, please try config your proxy setting or use another npm registry if any network errors happen during it.
@ -17,7 +19,7 @@ Then we go inside project and start it.
```bash
$ cd antd-demo
$ yarn start
$ npm run start
```
Open the browser at http://localhost:3000/. It renders a header saying `Welcome to React` on the page.
@ -42,19 +44,17 @@ Below is the default directory structure.
└── yarn.lock
```
Now we install `antd` from yarn or npm.
Now we install `antd` from yarn or npm or pnpm.
```bash
$ yarn add antd
```
<InstallDependencies npm='$ npm install antd --save' yarn='$ yarn add antd' pnpm='$ pnpm install antd --save'></InstallDependencies>
Modify `src/App.js`, import Button component from `antd`.
```jsx
```tsx
import { Button } from 'antd';
import React from 'react';
const App = () => (
const App: React.FC = () => (
<div className="App">
<Button type="primary">Button</Button>
</div>
@ -65,4 +65,27 @@ export default App;
OK, you should now see a blue primary button displayed on the page. Next you can choose any components of `antd` to develop your application. Visit other workflows of `create-react-app` at its [User Guide](https://create-react-app.dev/docs/getting-started).
### Customize Theme
Ref to the [Customize Theme documentation](/docs/react/customize-theme). Modify theme with ConfigProvider:
```tsx
import { ConfigProvider } from 'antd';
import React from 'react';
const App: React.FC = () => (
<ConfigProvider theme={{ token: { colorPrimary: '#00b96b' } }}>
<MyApp />
</ConfigProvider>
);
export default App;
```
`antd` is written in TypeScript with complete definitions, try out and enjoy the property suggestion and typing check.
![](https://gw.alipayobjects.com/zos/antfincdn/26L5vPoLug/8d7da796-175e-40af-8eea-e7031ba09f9f.png)
> Don't install `@types/antd`.
We are successfully running antd components now, go build your own application!

41
docs/react/use-with-create-react-app.zh-CN.md

@ -3,13 +3,15 @@ order: 4
title: 在 create-react-app 中使用
---
[create-react-app](https://create-react-app.dev/) 是业界最优秀的 React 应用开发工具之一,本文会尝试使用 `create-react-app` 创建一个项目,并引入 antd。
[create-react-app](https://create-react-app.dev/) 是业界最优秀的 React 应用开发工具之一,本文会尝试使用 `create-react-app` 创建一个 `TypeScript` 项目,并引入 antd。
> `antd` 基于最新稳定版本的 TypeScript(`>=5.0.0`),请确保项目中使用匹配的版本。
## 安装和初始化
在开始之前,你可能需要安装 [yarn](https://github.com/yarnpkg/yarn/) 或者 [pnpm](https://pnpm.io/zh/)。
<InstallDependencies npm='$ npx create-react-app antd-demo' yarn='$ yarn create react-app antd-demo' pnpm='$ pnpm create react-app antd-demo'></InstallDependencies>
<InstallDependencies npm='$ npx create-react-app antd-demo --template typescript' yarn='$ yarn create react-app antd-demo --template typescript' pnpm='$ pnpm create react-app antd-demo --template typescript'></InstallDependencies>
工具会自动初始化一个脚手架并安装 React 项目的各种必要依赖,如果在过程中出现网络问题,请尝试配置代理或使用其他 npm registry。
@ -17,7 +19,7 @@ title: 在 create-react-app 中使用
```bash
$ cd antd-demo
$ yarn start
$ npm run start
```
此时浏览器会访问 http://localhost:3000/ ,看到 `Welcome to React` 的界面就算成功了。
@ -42,19 +44,17 @@ $ yarn start
└── yarn.lock
```
现在从 yarn 或 npm 安装并引入 antd。
现在从 yarn 或 npm 或 pnpm 安装并引入 antd。
```bash
$ yarn add antd
```
<InstallDependencies npm='$ npm install antd --save' yarn='$ yarn add antd' pnpm='$ pnpm install antd --save'></InstallDependencies>
修改 `src/App.js`,引入 antd 的按钮组件。
```jsx
```tsx
import { Button } from 'antd';
import React from 'react';
const App = () => (
const App: React.FC = () => (
<div className="App">
<Button type="primary">Button</Button>
</div>
@ -65,4 +65,27 @@ export default App;
好了,现在你应该能看到页面上已经有了 antd 的蓝色按钮组件,接下来就可以继续选用其他组件开发应用了。其他开发流程你可以参考 create-react-app 的[官方文档](https://create-react-app.dev/docs/getting-started)。
### 自定义主题
参考 [配置主题](/docs/react/customize-theme),通过 ConfigProvider 进行主题配置:
```tsx
import { ConfigProvider } from 'antd';
import React from 'react';
const App: React.FC = () => (
<ConfigProvider theme={{ token: { colorPrimary: '#00b96b' } }}>
<MyApp />
</ConfigProvider>
);
export default App;
```
`antd` 使用 TypeScript 书写并提供了完整的定义,你可以享受组件属性输入建议和定义检查的功能。
![](https://gw.alipayobjects.com/zos/antfincdn/26L5vPoLug/8d7da796-175e-40af-8eea-e7031ba09f9f.png)
> 注意不要安装 `@types/antd`
我们现在已经把 antd 组件成功运行起来了,开始开发你的应用吧!

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

Loading…
Cancel
Save