Merge pull request #38536 from ant-design/next-merge-master

chore: Next merge master
This commit is contained in:
二货爱吃白萝卜 2022-11-13 15:30:37 +08:00 committed by GitHub
commit 64c06e193c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
57 changed files with 762 additions and 252 deletions

View File

@ -7,7 +7,7 @@ version: 2.1
jobs:
test-argos-ci:
docker:
- image: cimg/node:16.18.0-browsers
- image: cimg/node:16.18.1-browsers
steps:
- checkout
- run:

21
.github/workflows/codeball.yml vendored Normal file
View File

@ -0,0 +1,21 @@
name: Codeball
on:
pull_request: {}
pull_request_review_comment:
types: [created, edited]
jobs:
codeball_job:
runs-on: ubuntu-latest
name: Codeball
steps:
# Run Codeball on all new Pull Requests and Review Comments! 🚀
# For customizations and more documentation, see https://github.com/sturdy-dev/codeball-action
- name: Codeball
uses: sturdy-dev/codeball-action@v2
with:
# Settings for "Codeball Approver"
approvePullRequests: "false"
labelPullRequestsWhenApproved: "true"
labelPullRequestsWhenReviewNeeded: "true"
failJobsWhenReviewNeeded: "false"

View File

@ -34,7 +34,18 @@ jobs:
prettier: true
prerelease-filter: '-, a, b, A, B'
- name: release bigfish
- name: notice next
uses: actions-cool/release-helper@v2
with:
triger: 'tag'
dingding-token: ${{ secrets.DINGDING_BOT_V5_PRE_TOKEN }}
msg-title: '# Ant Design {{v}} 发布日志'
msg-poster: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*zx7LTI_ECSAAAAAAAAAAAABkARQnAQ'
msg-footer: '💬 前往 [**Ant Design Releases**]({{url}}) 查看更新日志'
prerelease-filter: '-, a, b, A, B'
prerelease-notice: true
- name: notice bigfish
uses: actions-cool/release-helper@v2
with:
triger: 'tag'

1
.husky/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
_

View File

@ -1,4 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no-install pretty-quick --staged
npx --no-install lint-staged

View File

@ -12,8 +12,8 @@ const compileModules = [
const ignoreList = [];
// cnpm use `_` as prefix
['', '_'].forEach(prefix => {
compileModules.forEach(module => {
['', '_'].forEach((prefix) => {
compileModules.forEach((module) => {
ignoreList.push(`${prefix}${module}`);
});
});
@ -71,5 +71,5 @@ module.exports = {
testEnvironmentOptions: {
url: 'http://localhost',
},
bail: true,
// bail: true,
};

View File

@ -15,5 +15,5 @@ module.exports = {
testRegex: 'node\\.test\\.(j|t)sx$',
testEnvironment: 'node',
transformIgnorePatterns,
bail: true,
// bail: true,
};

View File

@ -15,6 +15,29 @@ timeline: true
---
## 4.24.2
`2022-11-12`
- Image
- 💄 Image preview controls enter animation should not be zooming out. [#36456](https://github.com/ant-design/ant-design/pull/36456)
- 🐞 Fix Image preview not showing error images. [#38112](https://github.com/ant-design/ant-design/pull/38112)
- Typography
- 🐞 Fix Typography.Text `tooltip` do not display in List. [#38431](https://github.com/ant-design/ant-design/pull/38431) [@crazyair](https://github.com/crazyair)
- 🐞 Fix Typography.Paragraph flash issue in some situations. [#38439](https://github.com/ant-design/ant-design/pull/38439) [@tinyfind](https://github.com/tinyfind)
- 🐞 Fix Menu SubMenu flick when collapse it. [#36636](https://github.com/ant-design/ant-design/issues/36636) [@JarvisArt](https://github.com/JarvisArt)
- 🐞 Fix RangePicker that `onBlur` gets triggered when selecting dates. [#38411](https://github.com/ant-design/ant-design/pull/38411) [@kiner-tang](https://github.com/kiner-tang)
- 🐞 Result should hide icon when it is falsy. [#38488](https://github.com/ant-design/ant-design/pull/38488)
- 🐞 Fix Dropdown.Button throws `overlay is deprecated` warning. [#38446](https://github.com/ant-design/ant-design/pull/38446) [@li-jia-nan](https://github.com/li-jia-nan)
- 🛎 Improve error message about multiple Form.Item children. [#38038](https://github.com/ant-design/ant-design/pull/38038) [@cincodenada](https://github.com/cincodenada)
- 🛠 Resolve Tree circular import issue. [#38421](https://github.com/ant-design/ant-design/pull/38421) [@KotoriK](https://github.com/KotoriK)
- 🐞 Fix Affix shake issue when switching visible. [#38410](https://github.com/ant-design/ant-design/pull/38410) [@imoctopus](https://github.com/imoctopus)
- 🐞 Fix Pagination `simple` mode should support `showTotal` property. [#38399](https://github.com/ant-design/ant-design/pull/38399)
- 🐞 Fix Modal.confirm buttons should not be interactive when modal is hiding. [#38400](https://github.com/ant-design/ant-design/pull/38400)
- 🐞 Fix Radio.Group style problem using in Drawer `extra`. [#38385](https://github.com/ant-design/ant-design/pull/38385)
- ⌨️ Fix Table `aria-label` contains `[object Object]`. [#38389](https://github.com/ant-design/ant-design/pull/38389) [@kiner-tang](https://github.com/kiner-tang)
- ⌨️ Adds role progressbar to Progress component. [#38447](https://github.com/ant-design/ant-design/pull/38447) [@kpustakhod](https://github.com/kpustakhod)
## 4.24.1
`2022-11-04`

View File

@ -15,6 +15,29 @@ timeline: true
---
## 4.24.2
`2022-11-12`
- Image
- 💄 优化 Image 预览图片的工具栏显示动画的效果,现在工具条不再用缩放动画进场。[#36456](https://github.com/ant-design/ant-design/pull/36456)
- 🐞 修复 Image 预览图片没有展现错误图片的问题。[#38112](https://github.com/ant-design/ant-design/pull/38112)
- Typography
- 🐞 修复 Typography.Paragraph 在宽度较短时可能出现闪动的问题。[#38439](https://github.com/ant-design/ant-design/pull/38439) [@tinyfind](https://github.com/tinyfind)
- 🐞 修复一个 Typography.Text 在 List 内 tooltip 不显示的问题。[#38431](https://github.com/ant-design/ant-design/pull/38431) [@crazyair](https://github.com/crazyair)
- 🐞 修复 Menu 收起时 SubMenu 闪动的问题。[#36636](https://github.com/ant-design/ant-design/issues/36636) [@JarvisArt](https://github.com/JarvisArt)
- 🐞 修复 RangePicker 选择日期过程中触发 `onBlur` 的问题。[#38411](https://github.com/ant-design/ant-design/pull/38411) [@kiner-tang](https://github.com/kiner-tang)
- 🐞 修复 Result `icon``null` 时图标没有隐藏的问题。[#38488](https://github.com/ant-design/ant-design/pull/38488)
- 🐞 修复 Dropdown.Button 出现 `overlay is deprecated` 警告的问题。[#38446](https://github.com/ant-design/ant-design/pull/38446) [@li-jia-nan](https://github.com/li-jia-nan)
- 🛎 优化 Form 的相关控制台提示的表述。[#38038](https://github.com/ant-design/ant-design/pull/38038) [@cincodenada](https://github.com/cincodenada)
- 🛠 修复 Tree 模块循环导入的问题。[#38421](https://github.com/ant-design/ant-design/pull/38421) [@KotoriK](https://github.com/KotoriK)
- 🐞 修复当 Affix 隐藏切换到显示时会出现抖动。[#38410](https://github.com/ant-design/ant-design/pull/38410) [@imoctopus](https://github.com/imoctopus)
- 🐞 修复 Pagination `showTotal` 属性在 `simple` 模式下不生效的问题。[#38399](https://github.com/ant-design/ant-design/pull/38399)
- 🐞 修复 Modal.confirm 关闭中确认按钮依旧可能被触发的问题。[#38400](https://github.com/ant-design/ant-design/pull/38400)
- 🐞 修复在 Drawer `extra` 中使用 Radio.Group 的样式问题。[#38385](https://github.com/ant-design/ant-design/pull/38385)
- ⌨️ 修复 Table 组件 `aria-label` 出现 `[object Object]` 的问题。[#38389](https://github.com/ant-design/ant-design/pull/38389) [@kiner-tang](https://github.com/kiner-tang)
- ⌨️ Progress 组件增加 `role="progressbar"` 。[#38447](https://github.com/ant-design/ant-design/pull/38447) [@kpustakhod](https://github.com/kpustakhod)
## 4.24.1
`2022-11-04`

View File

@ -118,7 +118,7 @@ describe('Test utils function', () => {
});
});
it('delayRaf', done => {
it('delayRaf', (done) => {
jest.useRealTimers();
let bamboo = false;
@ -152,7 +152,7 @@ describe('Test utils function', () => {
describe('TransButton', () => {
it('can be focus/blur', () => {
const ref = React.createRef<any>();
const ref = React.createRef<HTMLDivElement>();
render(<TransButton ref={ref}>TransButton</TransButton>);
expect(typeof ref.current?.focus).toBe('function');
expect(typeof ref.current?.blur).toBe('function');

View File

@ -3,6 +3,7 @@ import mountTest from '../../../tests/shared/mountTest';
import { render, waitFakeTimer, fireEvent, act } from '../../../tests/utils';
import ConfigProvider from '../../config-provider';
import Wave from '../wave';
import type { InternalWave } from '../wave';
describe('Wave component', () => {
mountTest(Wave);
@ -194,7 +195,7 @@ describe('Wave component', () => {
});
it('bindAnimationEvent should return when node is null', () => {
const ref = React.createRef<any>();
const ref = React.createRef<InternalWave>();
render(
<Wave ref={ref}>
<button type="button" disabled>
@ -206,7 +207,7 @@ describe('Wave component', () => {
});
it('bindAnimationEvent.onClick should return when children is hidden', () => {
const ref = React.createRef<any>();
const ref = React.createRef<InternalWave>();
render(
<Wave ref={ref}>
<button type="button" style={{ display: 'none' }}>
@ -218,7 +219,7 @@ describe('Wave component', () => {
});
it('bindAnimationEvent.onClick should return when children is input', () => {
const ref = React.createRef<any>();
const ref = React.createRef<InternalWave>();
render(
<Wave ref={ref}>
<input />

View File

@ -9,9 +9,8 @@ export const getRenderPropValue = (
return null;
}
const isRenderFunction = typeof propValue === 'function';
if (isRenderFunction) {
return (propValue as RenderFunction)();
if (typeof propValue === 'function') {
return propValue();
}
return propValue;

View File

@ -1,7 +1,7 @@
import * as React from 'react';
import useForceUpdate from './useForceUpdate';
type UseSyncStateProps<T> = [() => T, (newValue: T) => void];
type UseSyncStateProps<T> = readonly [() => T, (newValue: T) => void];
export default function useSyncState<T>(initialValue: T): UseSyncStateProps<T> {
const ref = React.useRef<T>(initialValue);
@ -14,5 +14,5 @@ export default function useSyncState<T>(initialValue: T): UseSyncStateProps<T> {
// re-render
forceUpdate();
},
];
] as const;
}

View File

@ -24,7 +24,7 @@ function getValidateContainer(nodeRoot: Node): Element {
}
return Array.from(nodeRoot.childNodes).find(
ele => ele?.nodeType === Node.ELEMENT_NODE,
(ele) => ele?.nodeType === Node.ELEMENT_NODE,
) as Element;
}
@ -70,7 +70,7 @@ export interface WaveProps {
children?: React.ReactNode;
}
class InternalWave extends React.Component<WaveProps> {
export class InternalWave extends React.Component<WaveProps> {
static contextType = ConfigContext;
private instance?: {
@ -135,9 +135,7 @@ class InternalWave extends React.Component<WaveProps> {
styleForPseudo = updateCSS(
`
[${getPrefixCls('')}-click-animating-without-extra-node='true']::after, .${getPrefixCls(
'',
)}-click-animating-node {
[${getPrefixCls('')}-click-animating-without-extra-node='true']::after, .${getPrefixCls('')}-click-animating-node {
--antd-wave-shadow-color: ${waveColor};
}`,
'antd-wave',
@ -147,7 +145,7 @@ class InternalWave extends React.Component<WaveProps> {
if (insertExtraNode) {
node.appendChild(extraNode);
}
['transition', 'animation'].forEach(name => {
['transition', 'animation'].forEach((name) => {
node.addEventListener(`${name}start`, this.onTransitionStart);
node.addEventListener(`${name}end`, this.onTransitionEnd);
});
@ -180,7 +178,7 @@ class InternalWave extends React.Component<WaveProps> {
: `${getPrefixCls('')}-click-animating-without-extra-node`;
}
bindAnimationEvent = (node: HTMLElement) => {
bindAnimationEvent = (node?: HTMLElement) => {
if (
!node ||
!node.getAttribute ||
@ -230,7 +228,7 @@ class InternalWave extends React.Component<WaveProps> {
if (insertExtraNode && this.extraNode && node.contains(this.extraNode)) {
node.removeChild(this.extraNode);
}
['transition', 'animation'].forEach(name => {
['transition', 'animation'].forEach((name) => {
node.removeEventListener(`${name}start`, this.onTransitionStart);
node.removeEventListener(`${name}end`, this.onTransitionEnd);
});

View File

@ -31,38 +31,38 @@ group:
<code src="./demo/uncertain-category.tsx">查询模式 - 不确定类目</code>
<code src="./demo/status.tsx">自定义状态</code>
<code src="./demo/form-debug.tsx" debug>在 Form 中 Debug</code>
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
<code src="./demo/render-panel.tsx" debug>\_InternalPanelDoNotUseOrYouWillBeFired</code>
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| allowClear | 支持清除 | boolean | false | |
| autoFocus | 自动获取焦点 | boolean | false | |
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
| children (自动完成的数据源) | 自动完成的数据源 | React.ReactElement&lt;OptionProps> \| Array&lt;React.ReactElement&lt;OptionProps>> | - | |
| children (自定义输入框) | 自定义输入框 | HTMLInputElement \| HTMLTextAreaElement \| React.ReactElement&lt;InputProps> | &lt;Input /> | |
| defaultActiveFirstOption | 是否默认高亮第一个选项 | boolean | true | |
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
| defaultValue | 指定默认选中的条目 | string | - | |
| disabled | 是否禁用 | boolean | false | |
| popupClassName | 下拉菜单的 className 属性 | string | - | 4.23.0 |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | |
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 true反之则返回 false | boolean \| function(inputValue, option) | true | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | - | |
| open | 是否展开下拉菜单 | boolean | - | |
| options | 数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能 | { label, value }\[] | - | |
| placeholder | 输入框提示 | string | - | |
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
| value | 指定当前选中的条目 | string | - | |
| onBlur | 失去焦点时的回调 | function() | - | |
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
| onFocus | 获得焦点时的回调 | function() | - | |
| onSearch | 搜索补全项的时候调用 | function(value) | - | |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | - | |
| onClear | 清除内容时回调 | function | - | 4.6.0 |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------- | ------ |
| allowClear | 支持清除 | boolean | false | |
| autoFocus | 自动获取焦点 | boolean | false | |
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
| children (自动完成的数据源) | 自动完成的数据源 | React.ReactElement&lt;OptionProps> \| Array&lt;React.ReactElement&lt;OptionProps>> | - | |
| children (自定义输入框) | 自定义输入框 | HTMLInputElement \| HTMLTextAreaElement \| React.ReactElement&lt;InputProps> | &lt;Input /> | |
| defaultActiveFirstOption | 是否默认高亮第一个选项 | boolean | true | |
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
| defaultValue | 指定默认选中的条目 | string | - | |
| disabled | 是否禁用 | boolean | false | |
| popupClassName | 下拉菜单的 className 属性 | string | - | 4.23.0 |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | |
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 true反之则返回 false | boolean \| function(inputValue, option) | true | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | - | |
| open | 是否展开下拉菜单 | boolean | - | |
| options | 数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能 | { label, value }\[] | - | |
| placeholder | 输入框提示 | string | - | |
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
| value | 指定当前选中的条目 | string | - | |
| onBlur | 失去焦点时的回调 | function() | - | |
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
| onFocus | 获得焦点时的回调 | function() | - | |
| onSearch | 搜索补全项的时候调用 | function(value) | - | |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | - | |
| onClear | 清除内容时回调 | function | - | 4.6.0 |
## 方法

View File

@ -71,11 +71,11 @@ const ScrollNumber: React.FC<ScrollNumberProps> = ({
};
}
if (children) {
return cloneElement(children, oriProps => ({
return cloneElement(children, (oriProps) => ({
className: classNames(`${prefixCls}-custom-component`, oriProps?.className, motionClassName),
}));
}
return React.createElement(component as any, newProps, numberNodes);
return React.createElement(component, newProps, numberNodes);
};
export default ScrollNumber;

View File

@ -38,18 +38,18 @@ demo:
| defaultChecked | 初始是否选中 | boolean | false | |
| disabled | 失效状态 | boolean | false | |
| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false | |
| onChange | 变化时回调函数 | function(e:Event) | - | |
| onChange | 变化时回调函数 | function(e:Event) | - | |
#### Checkbox Group
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| defaultValue | 默认选中的选项 | string\[] | \[] | |
| disabled | 整组失效 | boolean | false | |
| name | CheckboxGroup 下所有 `input[type="checkbox"]``name` 属性 | string | - | |
| options | 指定可选项 | string\[] \| number\[] \| Option\[] | \[] | |
| value | 指定选中的选项 | string\[] | \[] | |
| onChange | 变化时回调函数 | function(checkedValue) | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------------ | ------------------------------------------------------------ | ----------------------------------- | ------ | ---- |
| defaultValue | 默认选中的选项 | string\[] | \[] | |
| disabled | 整组失效 | boolean | false | |
| name | CheckboxGroup 下所有 `input[type="checkbox"]``name` 属性 | string | - | |
| options | 指定可选项 | string\[] \| number\[] \| Option\[] | \[] | |
| value | 指定选中的选项 | string\[] | \[] | |
| onChange | 变化时回调函数 | function(checkedValue) | - | |
##### Option

View File

@ -21778,6 +21778,7 @@ exports[`ConfigProvider components Popover prefixCls 1`] = `
exports[`ConfigProvider components Progress configProvider 1`] = `
<div
class="config-progress config-progress-line config-progress-status-normal config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
@ -21803,6 +21804,7 @@ exports[`ConfigProvider components Progress configProvider 1`] = `
exports[`ConfigProvider components Progress configProvider componentDisabled 1`] = `
<div
class="config-progress config-progress-line config-progress-status-normal config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
@ -21828,6 +21830,7 @@ exports[`ConfigProvider components Progress configProvider componentDisabled 1`]
exports[`ConfigProvider components Progress configProvider componentSize large 1`] = `
<div
class="config-progress config-progress-line config-progress-status-normal config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
@ -21853,6 +21856,7 @@ exports[`ConfigProvider components Progress configProvider componentSize large 1
exports[`ConfigProvider components Progress configProvider componentSize middle 1`] = `
<div
class="config-progress config-progress-line config-progress-status-normal config-progress-show-info config-progress-default"
role="progressbar"
>
<div
class="config-progress-outer"
@ -21878,6 +21882,7 @@ exports[`ConfigProvider components Progress configProvider componentSize middle
exports[`ConfigProvider components Progress configProvider virtual and dropdownMatchSelectWidth 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -21903,6 +21908,7 @@ exports[`ConfigProvider components Progress configProvider virtual and dropdownM
exports[`ConfigProvider components Progress normal 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -21928,6 +21934,7 @@ exports[`ConfigProvider components Progress normal 1`] = `
exports[`ConfigProvider components Progress prefixCls 1`] = `
<div
class="prefix-Progress prefix-Progress-line prefix-Progress-status-normal prefix-Progress-show-info prefix-Progress-default"
role="progressbar"
>
<div
class="prefix-Progress-outer"

View File

@ -2,6 +2,7 @@ import React from 'react';
import { act } from 'react-dom/test-utils';
import ConfigProvider from '..';
import { render } from '../../../tests/utils';
import type { FormInstance } from '../../form';
import Form from '../../form';
import zhCN from '../../locale/zh_CN';
@ -16,7 +17,7 @@ describe('ConfigProvider.Form', () => {
describe('form validateMessages', () => {
const renderComponent = ({ validateMessages }: { validateMessages?: any }) => {
const formRef = React.createRef<any>();
const formRef = React.createRef<FormInstance>();
const { container } = render(
<ConfigProvider locale={zhCN} form={{ validateMessages }}>
<Form ref={formRef} initialValues={{ age: 18 }}>

View File

@ -14,7 +14,7 @@ dayjs.extend(customParseFormat);
const { RangePicker } = DatePicker;
describe('RangePicker', () => {
focusTest(RangePicker, { refFocus: true });
focusTest(RangePicker, { refFocus: true, blurDelay: 110 });
beforeEach(() => {
setMockDate();
@ -66,7 +66,7 @@ describe('RangePicker', () => {
<RangePicker
value={this.state.value}
mode={['month', 'month']}
onPanelChange={value => {
onPanelChange={(value) => {
this.setState({ value });
rangePickerValue = value as any;
}}

View File

@ -14,7 +14,7 @@ jest.mock('../dropdown', () => {
const MockedDropdown: React.FC<DropdownProps> & {
Button: typeof ActualDropdownComponent.Button;
} = props => {
} = (props) => {
dropdownProps = props;
const { children, ...restProps } = props;
return h.createElement(ActualDropdownComponent, { ...restProps }, children);
@ -131,4 +131,18 @@ describe('DropdownButton', () => {
'ant-btn',
);
});
it('should console Error then `overlay` in props', () => {
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
render(<DropdownButton overlay={<div>test</div>} />);
expect(errSpy).toHaveBeenCalledWith(
'Warning: [antd: Dropdown] `overlay` is deprecated. Please use `menu` instead.',
);
errSpy.mockRestore();
});
it('should not console Error then `overlay` not in props', () => {
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
render(<DropdownButton />);
expect(errSpy).not.toHaveBeenCalled();
errSpy.mockRestore();
});
});

View File

@ -33,7 +33,7 @@ interface DropdownButtonInterface extends React.FC<DropdownButtonProps> {
__ANT_BUTTON: boolean;
}
const DropdownButton: DropdownButtonInterface = props => {
const DropdownButton: DropdownButtonInterface = (props) => {
const {
getPopupContainer: getContextPopupContainer,
getPrefixCls,
@ -81,7 +81,6 @@ const DropdownButton: DropdownButtonInterface = props => {
arrow,
autoFocus,
align,
overlay,
disabled,
trigger: disabled ? [] : trigger,
onOpenChange,
@ -92,10 +91,15 @@ const DropdownButton: DropdownButtonInterface = props => {
overlayStyle,
destroyPopupOnHide,
};
const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction);
const classes = classNames(buttonPrefixCls, compactItemClassnames, className, hashId);
if ('overlay' in props) {
dropdownProps.overlay = overlay;
}
if ('open' in props) {
dropdownProps.open = open;
}

View File

@ -86,7 +86,7 @@ interface DropdownInterface extends React.FC<DropdownProps> {
_InternalPanelDoNotUseOrYouWillBeFired: typeof WrapPurePanel;
}
const Dropdown: DropdownInterface = props => {
const Dropdown: DropdownInterface = (props) => {
const {
getPopupContainer: getContextPopupContainer,
getPrefixCls,
@ -233,7 +233,7 @@ const Dropdown: DropdownInterface = props => {
if (menu?.items) {
overlayNode = <Menu {...menu} />;
} else if (typeof overlay === 'function') {
overlayNode = (overlay as OverlayFunc)();
overlayNode = overlay();
} else {
overlayNode = overlay;
}
@ -296,7 +296,7 @@ const Dropdown: DropdownInterface = props => {
Dropdown.Button = DropdownButton;
// We don't care debug panel
const PurePanel = genPurePanel(Dropdown, 'dropdown', prefixCls => prefixCls);
const PurePanel = genPurePanel(Dropdown, 'dropdown', (prefixCls) => prefixCls);
/* istanbul ignore next */
const WrapPurePanel = (props: DropdownProps) => (

View File

@ -1,5 +1,238 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Image Default Group preview props 1`] = `
<body>
<div>
<div
class="ant-image"
>
<img
class="ant-image-img"
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
/>
<div
class="ant-image-mask"
>
<div
class="ant-image-mask-info"
>
<span
aria-label="eye"
class="anticon anticon-eye"
role="img"
>
<svg
aria-hidden="true"
data-icon="eye"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3a60.3 60.3 0 000 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766zm-4-430c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"
/>
</svg>
</span>
Preview
</div>
</div>
</div>
</div>
<div>
<div
class="ant-image-preview-root"
>
<div
class="ant-image-preview-mask ant-fade-appear ant-fade-appear-start ant-fade"
/>
<div
class="ant-image-preview-wrap"
tabindex="-1"
>
<div
aria-modal="true"
class="ant-image-preview ant-zoom-appear ant-zoom-appear-prepare ant-zoom"
role="dialog"
>
<div
aria-hidden="true"
style="width: 0px; height: 0px; overflow: hidden; outline: none;"
tabindex="0"
/>
<div
class="ant-image-preview-content"
>
<div
class="ant-image-preview-body"
>
<div
class="ant-image-preview-img-wrapper"
style="transform: translate3d(0px, 0px, 0);"
>
<img
class="ant-image-preview-img"
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
style="transform: scale3d(1, 1, 1) rotate(0deg);"
/>
</div>
</div>
</div>
<div
aria-hidden="true"
style="width: 0px; height: 0px; overflow: hidden; outline: none;"
tabindex="0"
/>
</div>
</div>
</div>
</div>
<div>
<div
class="ant-image-preview-operations-wrapper ant-fade-appear ant-fade-appear-start ant-fade"
>
<ul
class="ant-image-preview-operations"
>
<li
class="ant-image-preview-operations-progress"
>
1 / 1
</li>
<li
class="ant-image-preview-operations-operation ant-image-preview-operations-operation-close"
>
<span
aria-label="close"
class="anticon anticon-close ant-image-preview-operations-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="close"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M563.8 512l262.5-312.9c4.4-5.2.7-13.1-6.1-13.1h-79.8c-4.7 0-9.2 2.1-12.3 5.7L511.6 449.8 295.1 191.7c-3-3.6-7.5-5.7-12.3-5.7H203c-6.8 0-10.5 7.9-6.1 13.1L459.4 512 196.9 824.9A7.95 7.95 0 00203 838h79.8c4.7 0 9.2-2.1 12.3-5.7l216.5-258.1 216.5 258.1c3 3.6 7.5 5.7 12.3 5.7h79.8c6.8 0 10.5-7.9 6.1-13.1L563.8 512z"
/>
</svg>
</span>
</li>
<li
class="ant-image-preview-operations-operation ant-image-preview-operations-operation-zoomIn"
>
<span
aria-label="zoom-in"
class="anticon anticon-zoom-in ant-image-preview-operations-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="zoom-in"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M637 443H519V309c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v134H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h118v134c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V519h118c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8zm284 424L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z"
/>
</svg>
</span>
</li>
<li
class="ant-image-preview-operations-operation ant-image-preview-operations-operation-zoomOut ant-image-preview-operations-operation-disabled"
>
<span
aria-label="zoom-out"
class="anticon anticon-zoom-out ant-image-preview-operations-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="zoom-out"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M637 443H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h312c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8zm284 424L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z"
/>
</svg>
</span>
</li>
<li
class="ant-image-preview-operations-operation ant-image-preview-operations-operation-rotateRight"
>
<span
aria-label="rotate-right"
class="anticon anticon-rotate-right ant-image-preview-operations-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="rotate-right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs>
<style />
</defs>
<path
d="M480.5 251.2c13-1.6 25.9-2.4 38.8-2.5v63.9c0 6.5 7.5 10.1 12.6 6.1L660 217.6c4-3.2 4-9.2 0-12.3l-128-101c-5.1-4-12.6-.4-12.6 6.1l-.2 64c-118.6.5-235.8 53.4-314.6 154.2A399.75 399.75 0 00123.5 631h74.9c-.9-5.3-1.7-10.7-2.4-16.1-5.1-42.1-2.1-84.1 8.9-124.8 11.4-42.2 31-81.1 58.1-115.8 27.2-34.7 60.3-63.2 98.4-84.3 37-20.6 76.9-33.6 119.1-38.8z"
/>
<path
d="M880 418H352c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32zm-44 402H396V494h440v326z"
/>
</svg>
</span>
</li>
<li
class="ant-image-preview-operations-operation ant-image-preview-operations-operation-rotateLeft"
>
<span
aria-label="rotate-left"
class="anticon anticon-rotate-left ant-image-preview-operations-icon"
role="img"
>
<svg
aria-hidden="true"
data-icon="rotate-left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs>
<style />
</defs>
<path
d="M672 418H144c-17.7 0-32 14.3-32 32v414c0 17.7 14.3 32 32 32h528c17.7 0 32-14.3 32-32V450c0-17.7-14.3-32-32-32zm-44 402H188V494h440v326z"
/>
<path
d="M819.3 328.5c-78.8-100.7-196-153.6-314.6-154.2l-.2-64c0-6.5-7.6-10.1-12.6-6.1l-128 101c-4 3.1-3.9 9.1 0 12.3L492 318.6c5.1 4 12.7.4 12.6-6.1v-63.9c12.9.1 25.9.9 38.8 2.5 42.1 5.2 82.1 18.2 119 38.7 38.1 21.2 71.2 49.7 98.4 84.3 27.1 34.7 46.7 73.7 58.1 115.8a325.95 325.95 0 016.5 140.9h74.9c14.8-103.6-11.3-213-81-302.3z"
/>
</svg>
</span>
</li>
</ul>
</div>
</div>
</body>
`;
exports[`Image rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-image"

View File

@ -47,6 +47,7 @@ describe('Image', () => {
expect(baseElement.querySelector('.ant-image-preview-mask')).toHaveClass('ant-fade');
expect(baseElement.querySelector('.ant-image-preview')).toHaveClass('ant-zoom');
expect(baseElement).toMatchSnapshot();
});
it('Customize preview props', () => {
const { container, baseElement } = render(

View File

@ -3,6 +3,7 @@ import React from 'react';
import Input from '..';
import { fireEvent, render } from '../../../tests/utils';
import type { InputRef } from '../Input';
import type { TextAreaRef } from '../TextArea';
const { TextArea } = Input;
@ -49,7 +50,7 @@ describe('Input.Focus', () => {
});
it('all', () => {
const ref = React.createRef<any>();
const ref = React.createRef<TextAreaRef>();
render(<TextArea ref={ref} defaultValue="light" />);
ref.current!.focus({ cursor: 'all' });

View File

@ -5,10 +5,10 @@ export default function useRemovePasswordTimeout(
inputRef: React.RefObject<InputRef>,
triggerOnMount?: boolean,
) {
const removePasswordTimeoutRef = useRef<number[]>([]);
const removePasswordTimeoutRef = useRef<NodeJS.Timer[]>([]);
const removePasswordTimeout = () => {
removePasswordTimeoutRef.current.push(
window.setTimeout(() => {
setTimeout(() => {
if (
inputRef.current?.input &&
inputRef.current?.input.getAttribute('type') === 'password' &&
@ -25,7 +25,12 @@ export default function useRemovePasswordTimeout(
removePasswordTimeout();
}
return () => removePasswordTimeoutRef.current.forEach(item => window.clearTimeout(item));
return () =>
removePasswordTimeoutRef.current.forEach((timer) => {
if (timer) {
clearTimeout(timer);
}
});
}, []);
return removePasswordTimeout;

View File

@ -317,12 +317,12 @@ describe('Sider', () => {
).toBeTruthy();
});
['Layout', 'Header', 'Footer', 'Sider'].forEach(tag => {
(['Layout', 'Header', 'Footer', 'Sider'] as const).forEach((tag) => {
const ComponentMap = { Layout, Header, Footer, Sider };
it(`should get ${tag} element from ref`, () => {
const ref = React.createRef<any>();
const ref = React.createRef<HTMLDivElement>();
const onSelect = jest.fn();
const Component = ComponentMap[tag as keyof typeof ComponentMap];
const Component = ComponentMap[tag];
render(
<Component onSelect={onSelect} ref={ref}>
{tag}

View File

@ -1,6 +1,6 @@
import React from 'react';
import React, { useEffect } from 'react';
import List from '..';
import { render } from '../../../tests/utils';
import { pureRender, render } from '../../../tests/utils';
import ConfigProvider from '../../config-provider';
describe('List Item Layout', () => {
@ -22,7 +22,7 @@ describe('List Item Layout', () => {
const { container: wrapper } = render(
<List
dataSource={data}
renderItem={item => (
renderItem={(item) => (
<List.Item key={item.title}>
I am <span>ant</span> design list item
</List.Item>
@ -38,7 +38,7 @@ describe('List Item Layout', () => {
const { container: wrapper } = render(
<List
dataSource={data}
renderItem={item => (
renderItem={(item) => (
<List.Item key={item.title}>
<List.Item.Meta
title={<a href={item.href}>{item.title}</a>}
@ -58,7 +58,7 @@ describe('List Item Layout', () => {
<List
itemLayout="vertical"
dataSource={data}
renderItem={item => (
renderItem={(item) => (
<List.Item key={item.title} extra={item.extra}>
<List.Item.Meta
title={<a href={item.href}>{item.title}</a>}
@ -78,7 +78,7 @@ describe('List Item Layout', () => {
<List
itemLayout="vertical"
dataSource={data}
renderItem={item => (
renderItem={(item) => (
<List.Item key={item.title}>
<List.Item.Meta
title={<a href={item.href}>{item.title}</a>}
@ -97,7 +97,7 @@ describe('List Item Layout', () => {
const { container: wrapper } = render(
<List
dataSource={data}
renderItem={item => (
renderItem={(item) => (
<List.Item
key={item.title}
actions={[<a key="action">Action</a>]}
@ -119,7 +119,7 @@ describe('List Item Layout', () => {
<ConfigProvider direction="rtl">
<List
dataSource={data}
renderItem={item => (
renderItem={(item) => (
<List.Item
key={item.title}
actions={[<a key="action">Action</a>]}
@ -156,7 +156,7 @@ describe('List Item Layout', () => {
<List
dataSource={dataWithId}
rowKey="id"
renderItem={item => <List.Item>{item.title}</List.Item>}
renderItem={(item) => <List.Item>{item.title}</List.Item>}
/>,
);
expect(wrapper.firstChild).toMatchSnapshot();
@ -180,8 +180,8 @@ describe('List Item Layout', () => {
const { container: wrapper } = render(
<List
dataSource={dataWithId}
rowKey={item => item.id}
renderItem={item => <List.Item>{item.title}</List.Item>}
rowKey={(item) => item.id}
renderItem={(item) => <List.Item>{item.title}</List.Item>}
/>,
);
expect(wrapper.firstChild).toMatchSnapshot();
@ -204,4 +204,30 @@ describe('List Item Layout', () => {
);
expect(ref.current).toHaveClass('ant-col');
});
it('react key', () => {
const loadId: number[] = [];
const Demo = ({ id }: { id: number }) => {
useEffect(() => {
loadId.push(id);
}, []);
return <div>{id}</div>;
};
const getDom = (id = 1) => (
<List
dataSource={[{ id, title: `ant design` }]}
rowKey={(item) => item.id}
renderItem={(item) => (
<List.Item>
<Demo id={item.id} />
</List.Item>
)}
/>
);
const { rerender } = pureRender(getDom(1));
rerender(getDom(3));
rerender(getDom(5));
expect(loadId).toEqual([1, 3, 5]);
});
});

View File

@ -108,8 +108,6 @@ function List<T>({
total: 0,
};
const listItemsKeys: { [index: number]: React.Key } = {};
const triggerPaginationEvent = (eventName: string) => (page: number, pageSize: number) => {
setPaginationCurrent(page);
setPaginationSize(pageSize);
@ -139,9 +137,7 @@ function List<T>({
key = `list-item-${index}`;
}
listItemsKeys[index] = key;
return renderItem(item, index);
return <React.Fragment key={key}>{renderItem(item, index)}</React.Fragment>;
};
const isSomethingAfterLastItem = () => !!(loadMore || pagination || footer);
@ -226,7 +222,7 @@ function List<T>({
}
}
const needResponsive = Object.keys(grid || {}).some(key =>
const needResponsive = Object.keys(grid || {}).some((key) =>
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].includes(key),
);
const screens = useBreakpoint(needResponsive);
@ -257,13 +253,14 @@ function List<T>({
let childrenContent = isLoading && <div style={{ minHeight: 53 }} />;
if (splitDataSource.length > 0) {
const items = splitDataSource.map((item: T, index: number) => renderInnerItem(item, index));
const childrenList = React.Children.map(items, (child: React.ReactNode, index: number) => (
<div key={listItemsKeys[index]} style={colStyle}>
{child}
</div>
));
childrenContent = grid ? (
<Row gutter={grid.gutter}>{childrenList}</Row>
<Row gutter={grid.gutter}>
{React.Children.map(items, (child) => (
<div key={child?.key} style={colStyle}>
{child}
</div>
))}
</Row>
) : (
<ul className={`${prefixCls}-items`}>{items}</ul>
);

View File

@ -28,7 +28,7 @@ const ElementsHolder = React.memo(
);
export default function useModal(): [Omit<ModalStaticFunctions, 'warn'>, React.ReactElement] {
const holderRef = React.useRef<ElementsHolderRef>(null as any);
const holderRef = React.useRef<ElementsHolderRef>(null);
// ========================== Effect ==========================
const [actionQueue, setActionQueue] = React.useState<(() => void)[]>([]);
@ -36,7 +36,7 @@ export default function useModal(): [Omit<ModalStaticFunctions, 'warn'>, React.R
React.useEffect(() => {
if (actionQueue.length) {
const cloneQueue = [...actionQueue];
cloneQueue.forEach(action => {
cloneQueue.forEach((action) => {
action();
});
@ -52,14 +52,14 @@ export default function useModal(): [Omit<ModalStaticFunctions, 'warn'>, React.R
const modalRef = React.createRef<HookModalRef>();
let closeFunc: Function;
let closeFunc: Function | undefined;
const modal = (
<HookModal
key={`modal-${uuid}`}
config={withFunc(config)}
ref={modalRef}
afterClose={() => {
closeFunc();
closeFunc?.();
}}
/>
);
@ -75,7 +75,7 @@ export default function useModal(): [Omit<ModalStaticFunctions, 'warn'>, React.R
if (modalRef.current) {
destroyAction();
} else {
setActionQueue(prev => [...prev, destroyAction]);
setActionQueue((prev) => [...prev, destroyAction]);
}
},
update: (newConfig: ModalFuncProps) => {
@ -86,7 +86,7 @@ export default function useModal(): [Omit<ModalStaticFunctions, 'warn'>, React.R
if (modalRef.current) {
updateAction();
} else {
setActionQueue(prev => [...prev, updateAction]);
setActionQueue((prev) => [...prev, updateAction]);
}
},
};

View File

@ -4,6 +4,7 @@ exports[`renders ./components/progress/demo/circle.tsx extend context correctly
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-right:8px"
>
<div
@ -55,6 +56,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-exception ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -122,6 +124,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -195,6 +198,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.tsx extend context co
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-right:8px"
>
<div
@ -309,6 +313,7 @@ exports[`renders ./components/progress/demo/circle-micro.tsx extend context corr
Array [
<div
class="ant-progress ant-progress-inline-circle ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -393,6 +398,7 @@ exports[`renders ./components/progress/demo/circle-mini.tsx extend context corre
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-right:8px"
>
<div
@ -444,6 +450,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-exception ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -511,6 +518,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -584,6 +592,7 @@ exports[`renders ./components/progress/demo/dashboard.tsx extend context correct
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-right:8px"
>
<div
@ -635,6 +644,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -690,6 +700,7 @@ exports[`renders ./components/progress/demo/dynamic.tsx extend context correctly
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -775,6 +786,7 @@ exports[`renders ./components/progress/demo/format.tsx extend context correctly
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -825,6 +837,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -881,6 +894,7 @@ exports[`renders ./components/progress/demo/gradient-line.tsx extend context cor
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -903,6 +917,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-active ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -925,6 +940,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner ant-progress-circle-gradient"
@ -994,6 +1010,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -1086,6 +1103,7 @@ exports[`renders ./components/progress/demo/line.tsx extend context correctly 1`
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1108,6 +1126,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-active ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1130,6 +1149,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-exception ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1169,6 +1189,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1208,6 +1229,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1231,6 +1253,7 @@ exports[`renders ./components/progress/demo/line-mini.tsx extend context correct
>
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1253,6 +1276,7 @@ exports[`renders ./components/progress/demo/line-mini.tsx extend context correct
</div>
<div
class="ant-progress ant-progress-line ant-progress-status-active ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1275,6 +1299,7 @@ exports[`renders ./components/progress/demo/line-mini.tsx extend context correct
</div>
<div
class="ant-progress ant-progress-line ant-progress-status-exception ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1314,6 +1339,7 @@ exports[`renders ./components/progress/demo/line-mini.tsx extend context correct
</div>
<div
class="ant-progress ant-progress-line ant-progress-status-success ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1358,6 +1384,7 @@ exports[`renders ./components/progress/demo/linecap.tsx extend context correctly
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1381,6 +1408,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -1431,6 +1459,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -1487,6 +1516,7 @@ exports[`renders ./components/progress/demo/segment.tsx extend context correctly
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1537,6 +1567,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -1611,6 +1642,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -1691,6 +1723,7 @@ exports[`renders ./components/progress/demo/steps.tsx extend context correctly 1
Array [
<div
class="ant-progress ant-progress-steps ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-steps-outer"
@ -1718,6 +1751,7 @@ Array [
<br />,
<div
class="ant-progress ant-progress-steps ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-steps-outer"
@ -1753,6 +1787,7 @@ Array [
<br />,
<div
class="ant-progress ant-progress-steps ant-progress-status-success ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-steps-outer"
@ -1805,6 +1840,7 @@ Array [
<br />,
<div
class="ant-progress ant-progress-steps ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-steps-outer"

View File

@ -4,6 +4,7 @@ exports[`renders ./components/progress/demo/circle.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-right:8px"
>
<div
@ -55,6 +56,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-exception ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -122,6 +124,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -195,6 +198,7 @@ exports[`renders ./components/progress/demo/circle-dynamic.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-right:8px"
>
<div
@ -309,6 +313,7 @@ exports[`renders ./components/progress/demo/circle-micro.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-inline-circle ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -364,6 +369,7 @@ exports[`renders ./components/progress/demo/circle-mini.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-right:8px"
>
<div
@ -415,6 +421,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-exception ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -482,6 +489,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -555,6 +563,7 @@ exports[`renders ./components/progress/demo/dashboard.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-right:8px"
>
<div
@ -606,6 +615,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -661,6 +671,7 @@ exports[`renders ./components/progress/demo/dynamic.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -746,6 +757,7 @@ exports[`renders ./components/progress/demo/format.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -796,6 +808,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -852,6 +865,7 @@ exports[`renders ./components/progress/demo/gradient-line.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -874,6 +888,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-active ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -896,6 +911,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner ant-progress-circle-gradient"
@ -965,6 +981,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -1057,6 +1074,7 @@ exports[`renders ./components/progress/demo/line.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1079,6 +1097,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-active ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1101,6 +1120,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-exception ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1140,6 +1160,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1179,6 +1200,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1202,6 +1224,7 @@ exports[`renders ./components/progress/demo/line-mini.tsx correctly 1`] = `
>
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1224,6 +1247,7 @@ exports[`renders ./components/progress/demo/line-mini.tsx correctly 1`] = `
</div>
<div
class="ant-progress ant-progress-line ant-progress-status-active ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1246,6 +1270,7 @@ exports[`renders ./components/progress/demo/line-mini.tsx correctly 1`] = `
</div>
<div
class="ant-progress ant-progress-line ant-progress-status-exception ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1285,6 +1310,7 @@ exports[`renders ./components/progress/demo/line-mini.tsx correctly 1`] = `
</div>
<div
class="ant-progress ant-progress-line ant-progress-status-success ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1329,6 +1355,7 @@ exports[`renders ./components/progress/demo/linecap.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1352,6 +1379,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -1402,6 +1430,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -1458,6 +1487,7 @@ exports[`renders ./components/progress/demo/segment.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -1484,6 +1514,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -1534,6 +1565,7 @@ Array [
</div>,
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
style="margin-left:8px"
>
<div
@ -1590,6 +1622,7 @@ exports[`renders ./components/progress/demo/steps.tsx correctly 1`] = `
Array [
<div
class="ant-progress ant-progress-steps ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-steps-outer"
@ -1617,6 +1650,7 @@ Array [
<br />,
<div
class="ant-progress ant-progress-steps ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-steps-outer"
@ -1652,6 +1686,7 @@ Array [
<br />,
<div
class="ant-progress ant-progress-steps ant-progress-status-success ant-progress-show-info ant-progress-small"
role="progressbar"
>
<div
class="ant-progress-steps-outer"
@ -1704,6 +1739,7 @@ Array [
<br />,
<div
class="ant-progress ant-progress-steps ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-steps-outer"

View File

@ -3,6 +3,7 @@
exports[`Progress render dashboard 295 gapDegree 1`] = `
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -56,6 +57,7 @@ exports[`Progress render dashboard 295 gapDegree 1`] = `
exports[`Progress render dashboard 296 gapDegree 1`] = `
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -109,6 +111,7 @@ exports[`Progress render dashboard 296 gapDegree 1`] = `
exports[`Progress render dashboard zero gapDegree 1`] = `
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -162,6 +165,7 @@ exports[`Progress render dashboard zero gapDegree 1`] = `
exports[`Progress render format 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -191,6 +195,7 @@ exports[`Progress render format 1`] = `
exports[`Progress render negative progress 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -216,6 +221,7 @@ exports[`Progress render negative progress 1`] = `
exports[`Progress render negative successPercent 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -245,6 +251,7 @@ exports[`Progress render negative successPercent 1`] = `
exports[`Progress render normal progress 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -270,6 +277,7 @@ exports[`Progress render normal progress 1`] = `
exports[`Progress render out-of-range progress 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -312,6 +320,7 @@ exports[`Progress render out-of-range progress 1`] = `
exports[`Progress render out-of-range progress with info 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-success ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -354,6 +363,7 @@ exports[`Progress render out-of-range progress with info 1`] = `
exports[`Progress render strokeColor 1`] = `
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -407,6 +417,7 @@ exports[`Progress render strokeColor 1`] = `
exports[`Progress render strokeColor 2`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -432,6 +443,7 @@ exports[`Progress render strokeColor 2`] = `
exports[`Progress render strokeColor 3`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -458,6 +470,7 @@ exports[`Progress render strokeWidth of progress 1`] = `
<div>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -512,6 +525,7 @@ exports[`Progress render strokeWidth of progress 1`] = `
exports[`Progress render successColor progress 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -541,6 +555,7 @@ exports[`Progress render successColor progress 1`] = `
exports[`Progress render successColor progress type="circle" 1`] = `
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -594,6 +609,7 @@ exports[`Progress render successColor progress type="circle" 1`] = `
exports[`Progress render successColor progress type="dashboard" 1`] = `
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -647,6 +663,7 @@ exports[`Progress render successColor progress type="dashboard" 1`] = `
exports[`Progress render trailColor progress 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -673,6 +690,7 @@ exports[`Progress render trailColor progress 1`] = `
exports[`Progress rtl render component should be rendered correctly in RTL direction 1`] = `
<div
class="ant-progress ant-progress-line ant-progress-status-normal ant-progress-show-info ant-progress-default ant-progress-rtl"
role="progressbar"
>
<div
class="ant-progress-outer"
@ -698,6 +716,7 @@ exports[`Progress rtl render component should be rendered correctly in RTL direc
exports[`Progress should support steps 1`] = `
<div
class="ant-progress ant-progress-steps ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-steps-outer"

View File

@ -54,7 +54,7 @@ export interface ProgressProps {
children?: React.ReactNode;
}
const Progress: React.FC<ProgressProps> = props => {
const Progress: React.FC<ProgressProps> = (props) => {
const {
prefixCls: customizePrefixCls,
className,
@ -94,7 +94,7 @@ const Progress: React.FC<ProgressProps> = props => {
}
const successPercent = getSuccessPercent(props);
let text: React.ReactNode;
const textFormatter = format || (number => `${number}%`);
const textFormatter = format || ((number) => `${number}%`);
const isLineType = type === 'line';
if (format || (progressStatus !== 'exception' && progressStatus !== 'success')) {
text = textFormatter(validProgress(percent), validProgress(successPercent));
@ -167,6 +167,7 @@ const Progress: React.FC<ProgressProps> = props => {
return wrapSSR(
<div
className={classString}
role="progressbar"
{...omit(restProps, [
'trailColor',
'strokeWidth',

View File

@ -67,4 +67,11 @@ describe('Result', () => {
warnSpy.mockRestore();
});
it('should hide icon by setting icon to false or null', () => {
const { container } = render(<Result title="404" icon={null} />);
expect(container.querySelectorAll('.ant-result-icon')).toHaveLength(0);
const { container: container2 } = render(<Result title="404" icon={false} />);
expect(container2.querySelectorAll('.ant-result-icon')).toHaveLength(0);
});
});

View File

@ -75,10 +75,15 @@ const Icon: React.FC<IconProps> = ({ prefixCls, icon, status }) => {
</div>
);
}
const iconNode = React.createElement(
IconMap[status as Exclude<ResultStatusType, ExceptionStatusType>],
);
if (icon === null || icon === false) {
return null;
}
return <div className={className}>{icon || iconNode}</div>;
};

View File

@ -2109,6 +2109,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -2874,6 +2875,7 @@ exports[`renders ./components/steps/demo/progress.tsx extend context correctly 1
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -3115,6 +3117,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -3296,6 +3299,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -3477,6 +3481,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -3658,6 +3663,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"

View File

@ -1677,6 +1677,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -2442,6 +2443,7 @@ exports[`renders ./components/steps/demo/progress.tsx correctly 1`] = `
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -2683,6 +2685,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -2864,6 +2867,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -3045,6 +3049,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"
@ -3226,6 +3231,7 @@ Array [
>
<div
class="ant-progress ant-progress-circle ant-progress-status-normal ant-progress-show-info ant-progress-default"
role="progressbar"
>
<div
class="ant-progress-inner"

View File

@ -46,7 +46,7 @@ ReactDOM.render(<Alert message="After version 4.24.0, we provide a simpler usage
```jsx
// works when >=4.24.0, recommended ✅
const items = [{ title: 'first step' }, { title: 'second step' }, { title: 'third step' }];
return <Tabs items={items} />;
return <Steps items={items} />;
// works when <4.24.0, deprecated when >=4.24.0 🙅🏻‍♀️
<Steps>

View File

@ -25,23 +25,23 @@ demo:
## API
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| autoFocus | 组件自动获取焦点 | boolean | false |
| checked | 指定当前是否选中 | boolean | false |
| checkedChildren | 选中时的内容 | ReactNode | - |
| className | Switch 器类名 | string | - |
| defaultChecked | 初始是否选中 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| loading | 加载中的开关 | boolean | false |
| size | 开关大小,可选值:`default` `small` | string | `default` |
| unCheckedChildren | 非选中时的内容 | ReactNode | - |
| onChange | 变化时回调函数 | function(checked: boolean, event: Event) | - |
| onClick | 点击时回调函数 | function(checked: boolean, event: Event) | - |
| 参数 | 说明 | 类型 | 默认值 |
| ----------------- | ----------------------------------- | ---------------------------------------- | --------- |
| autoFocus | 组件自动获取焦点 | boolean | false |
| checked | 指定当前是否选中 | boolean | false |
| checkedChildren | 选中时的内容 | ReactNode | - |
| className | Switch 器类名 | string | - |
| defaultChecked | 初始是否选中 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| loading | 加载中的开关 | boolean | false |
| size | 开关大小,可选值:`default` `small` | string | `default` |
| unCheckedChildren | 非选中时的内容 | ReactNode | - |
| onChange | 变化时回调函数 | function(checked: boolean, event: Event) | - |
| onClick | 点击时回调函数 | function(checked: boolean, event: Event) | - |
## 方法
| 名称 | 描述 |
| --- | --- |
| blur() | 移除焦点 |
| 名称 | 描述 |
| ------- | -------- |
| blur() | 移除焦点 |
| focus() | 获取焦点 |

View File

@ -26,7 +26,7 @@ interface TimelineType extends React.FC<TimelineProps> {
Item: React.FC<TimelineItemProps>;
}
const Timeline: TimelineType = props => {
const Timeline: TimelineType = (props) => {
const { getPrefixCls, direction } = React.useContext(ConfigContext);
const {
prefixCls: customizePrefixCls,
@ -51,7 +51,7 @@ const Timeline: TimelineType = props => {
) : null;
const timeLineItems = React.Children.toArray(children);
timeLineItems.push(pendingItem as any);
timeLineItems.push(pendingItem!);
if (reverse) {
timeLineItems.reverse();
}
@ -69,7 +69,7 @@ const Timeline: TimelineType = props => {
};
// Remove falsy items
const truthyItems = timeLineItems.filter(item => !!item);
const truthyItems = timeLineItems.filter((item) => !!item);
const itemsCount = React.Children.count(truthyItems);
const lastCls = `${prefixCls}-item-last`;
const items = React.Children.map(truthyItems, (ele: React.ReactElement<any>, idx) => {

View File

@ -1,6 +1,8 @@
import React from 'react';
import type { KeyWiseTransferItem } from '..';
import { render } from '../../../tests/utils';
import type { TransferListProps } from '../list';
import type TransferList from '../list';
import List from '../list';
const listCommonProps: TransferListProps<any> = {
@ -34,18 +36,22 @@ describe('Transfer.List', () => {
});
it('when component has been unmounted, componentWillUnmount should be called', () => {
const instance = React.createRef<any>();
const instance = React.createRef<TransferList<KeyWiseTransferItem>>();
const { unmount } = render(<List ref={instance} {...listCommonProps} />);
const willUnmount = jest.spyOn(instance.current, 'componentWillUnmount');
const willUnmount = jest.spyOn(instance.current!, 'componentWillUnmount');
unmount();
expect(willUnmount).toHaveBeenCalled();
});
it('when value is not exists, handleFilter should return', () => {
const handleFilter = jest.fn();
const instance = React.createRef<any>();
const instance = React.createRef<TransferList<KeyWiseTransferItem>>();
render(<List ref={instance} {...listCommonProps} handleFilter={handleFilter} />);
expect(instance.current?.handleFilter({ target: 'test' })).toBe(undefined);
expect(
instance.current?.handleFilter({
target: 'test',
} as unknown as React.ChangeEvent<HTMLInputElement>),
).toBe(undefined);
expect(handleFilter).toHaveBeenCalled();
});
it('should render correctly when dataSource is not exists', () => {

View File

@ -25,64 +25,64 @@ demo:
<code src="./demo/placement.tsx">弹出位置</code>
<code src="./demo/status.tsx">自定义状态</code>
<code src="./demo/suffix.tsx" debug>后缀图标</code>
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
<code src="./demo/render-panel.tsx" debug>\_InternalPanelDoNotUseOrYouWillBeFired</code>
## API
### Tree props
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| allowClear | 显示清除按钮 | boolean | false | |
| autoClearSearchValue | 当多选模式下值被选择,自动清空搜索框 | boolean | true | |
| bordered | 是否显示边框 | boolean | true | |
| defaultValue | 指定默认选中的条目 | string \| string\[] | - | |
| disabled | 是否禁用 | boolean | false | |
| popupClassName | 下拉菜单的 className 属性 | string | - | 4.23.0 |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | |
| dropdownRender | 自定义下拉框内容 | (originNode: ReactNode, props) => ReactNode | - | |
| dropdownStyle | 下拉菜单的样式 | object | - | |
| fieldNames | 自定义节点 label、value、children 的字段 | object | { label: `label`, value: `value`, children: `children` } | 4.17.0 |
| filterTreeNode | 是否根据输入项进行筛选,默认用 treeNodeFilterProp 的值作为要筛选的 TreeNode 的属性值 | boolean \| function(inputValue: string, treeNode: TreeNode) (函数需要返回 bool 值) | function | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
| labelInValue | 是否把每个选项的 label 包装到 value 中,会把 value 类型从 `string` 变为 {value: string, label: ReactNode, halfChecked(treeCheckStrictly 时有效): string\[] } 的格式 | boolean | false | |
| listHeight | 设置弹窗滚动高度 | number | 256 | |
| loadData | 异步加载数据 | function(node) | - | |
| maxTagCount | 最多显示多少个 tag响应式模式会对性能产生损耗 | number \| `responsive` | - | responsive: 4.10 |
| maxTagPlaceholder | 隐藏 tag 时显示的内容 | ReactNode \| function(omittedValues) | - | |
| multiple | 支持多选(当设置 treeCheckable 时自动变为 true | boolean | false | |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | `Not Found` | |
| placeholder | 选择框默认文字 | string | - | |
| placement | 选择框弹出的位置 | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | |
| searchValue | 搜索框的值,可以通过 `onSearch` 获取用户输入 | string | - | |
| showArrow | 是否显示 `suffixIcon`,单选模式下默认 `true` | boolean | - | |
| showCheckedStrategy | 配置 `treeCheckable` 时,定义选中项回填的方式。`TreeSelect.SHOW_ALL`: 显示所有选中节点(包括父节点)。`TreeSelect.SHOW_PARENT`: 只显示父节点(当父节点下所有子节点都选中时)。 默认只显示子节点 | `TreeSelect.SHOW_ALL` \| `TreeSelect.SHOW_PARENT` \| `TreeSelect.SHOW_CHILD` | `TreeSelect.SHOW_CHILD` | |
| showSearch | 是否支持搜索框 | boolean | 单选false \| 多选true | |
| size | 选择框大小 | `large` \| `middle` \| `small` | - | |
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
| suffixIcon | 自定义的选择框后缀图标, 多选模式下必须同时设置 `showArrow` 为 true | ReactNode | - | |
| switcherIcon | 自定义树节点的展开/折叠图标 | ReactNode \| ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.20.0 |
| tagRender | 自定义 tag 内容,多选时生效 | (props) => ReactNode | - | |
| treeCheckable | 显示 Checkbox | boolean | false | |
| treeCheckStrictly | `checkable` 状态下节点选择完全受控(父子节点选中状态不再关联),会使得 `labelInValue` 强制为 true | boolean | false | |
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点value 在整个树范围内唯一) | array&lt;{value, title, children, \[disabled, disableCheckbox, selectable, checkable]}> | \[] | |
| treeDataSimpleMode | 使用简单格式的 treeData具体设置参考可设置的类型 (此时 treeData 应变为这样的数据结构: \[{id:1, pId:0, value:'1', title:"test1",...},...] `pId` 是父节点的 id) | boolean \| object&lt;{ id: string, pId: string, rootPId: string }> | false | |
| treeDefaultExpandAll | 默认展开所有树节点 | boolean | false | |
| treeDefaultExpandedKeys | 默认展开的树节点 | string\[] | - | |
| treeExpandAction | 点击节点 title 时的展开逻辑可选false \| `click` \| `doubleClick` | string \| boolean | false | 4.21.0 |
| treeExpandedKeys | 设置展开的树节点 | string\[] | - | |
| treeIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true需要自行定义图标相关样式 | boolean | false | |
| treeLine | 是否展示线条样式,请参考 [Tree - showLine](/components/tree/#components-tree-demo-line) | boolean \| object | false | 4.17.0 |
| treeLoadedKeys | (受控)已经加载的节点,需要配合 `loadData` 使用 | string[] | [] | |
| treeNodeFilterProp | 输入项过滤对应的 treeNode 属性 | string | `value` | |
| treeNodeLabelProp | 作为显示的 prop 设置 | string | `title` | |
| value | 指定当前选中的条目 | string \| string\[] | - | |
| virtual | 设置 false 时关闭虚拟滚动 | boolean | true | 4.1.0 |
| onChange | 选中树节点时调用此函数 | function(value, label, extra) | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
| onSearch | 文本框值变化时回调 | function(value: string) | - | |
| onSelect | 被选中时调用 | function(value, node, extra) | - | |
| onTreeExpand | 展示节点时调用 | function(expandedKeys) | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------------- | ------------------- |
| allowClear | 显示清除按钮 | boolean | false | |
| autoClearSearchValue | 当多选模式下值被选择,自动清空搜索框 | boolean | true | |
| bordered | 是否显示边框 | boolean | true | |
| defaultValue | 指定默认选中的条目 | string \| string\[] | - | |
| disabled | 是否禁用 | boolean | false | |
| popupClassName | 下拉菜单的 className 属性 | string | - | 4.23.0 |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean \| number | true | |
| dropdownRender | 自定义下拉框内容 | (originNode: ReactNode, props) => ReactNode | - | |
| dropdownStyle | 下拉菜单的样式 | object | - | |
| fieldNames | 自定义节点 label、value、children 的字段 | object | { label: `label`, value: `value`, children: `children` } | 4.17.0 |
| filterTreeNode | 是否根据输入项进行筛选,默认用 treeNodeFilterProp 的值作为要筛选的 TreeNode 的属性值 | boolean \| function(inputValue: string, treeNode: TreeNode) (函数需要返回 bool 值) | function | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
| labelInValue | 是否把每个选项的 label 包装到 value 中,会把 value 类型从 `string` 变为 {value: string, label: ReactNode, halfChecked(treeCheckStrictly 时有效): string\[] } 的格式 | boolean | false | |
| listHeight | 设置弹窗滚动高度 | number | 256 | |
| loadData | 异步加载数据 | function(node) | - | |
| maxTagCount | 最多显示多少个 tag响应式模式会对性能产生损耗 | number \| `responsive` | - | responsive: 4.10 |
| maxTagPlaceholder | 隐藏 tag 时显示的内容 | ReactNode \| function(omittedValues) | - | |
| multiple | 支持多选(当设置 treeCheckable 时自动变为 true | boolean | false | |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | `Not Found` | |
| placeholder | 选择框默认文字 | string | - | |
| placement | 选择框弹出的位置 | `bottomLeft` `bottomRight` `topLeft` `topRight` | bottomLeft | |
| searchValue | 搜索框的值,可以通过 `onSearch` 获取用户输入 | string | - | |
| showArrow | 是否显示 `suffixIcon`,单选模式下默认 `true` | boolean | - | |
| showCheckedStrategy | 配置 `treeCheckable` 时,定义选中项回填的方式。`TreeSelect.SHOW_ALL`: 显示所有选中节点(包括父节点)。`TreeSelect.SHOW_PARENT`: 只显示父节点(当父节点下所有子节点都选中时)。 默认只显示子节点 | `TreeSelect.SHOW_ALL` \| `TreeSelect.SHOW_PARENT` \| `TreeSelect.SHOW_CHILD` | `TreeSelect.SHOW_CHILD` | |
| showSearch | 是否支持搜索框 | boolean | 单选false \| 多选true | |
| size | 选择框大小 | `large` \| `middle` \| `small` | - | |
| status | 设置校验状态 | 'error' \| 'warning' | - | 4.19.0 |
| suffixIcon | 自定义的选择框后缀图标, 多选模式下必须同时设置 `showArrow` 为 true | ReactNode | - | |
| switcherIcon | 自定义树节点的展开/折叠图标 | ReactNode \| ((props: AntTreeNodeProps) => ReactNode) | - | renderProps: 4.20.0 |
| tagRender | 自定义 tag 内容,多选时生效 | (props) => ReactNode | - | |
| treeCheckable | 显示 Checkbox | boolean | false | |
| treeCheckStrictly | `checkable` 状态下节点选择完全受控(父子节点选中状态不再关联),会使得 `labelInValue` 强制为 true | boolean | false | |
| treeData | treeNodes 数据,如果设置则不需要手动构造 TreeNode 节点value 在整个树范围内唯一) | array&lt;{value, title, children, \[disabled, disableCheckbox, selectable, checkable]}> | \[] | |
| treeDataSimpleMode | 使用简单格式的 treeData具体设置参考可设置的类型 (此时 treeData 应变为这样的数据结构: \[{id:1, pId:0, value:'1', title:"test1",...},...] `pId` 是父节点的 id) | boolean \| object&lt;{ id: string, pId: string, rootPId: string }> | false | |
| treeDefaultExpandAll | 默认展开所有树节点 | boolean | false | |
| treeDefaultExpandedKeys | 默认展开的树节点 | string\[] | - | |
| treeExpandAction | 点击节点 title 时的展开逻辑可选false \| `click` \| `doubleClick` | string \| boolean | false | 4.21.0 |
| treeExpandedKeys | 设置展开的树节点 | string\[] | - | |
| treeIcon | 是否展示 TreeNode title 前的图标,没有默认样式,如设置为 true需要自行定义图标相关样式 | boolean | false | |
| treeLine | 是否展示线条样式,请参考 [Tree - showLine](/components/tree/#components-tree-demo-line) | boolean \| object | false | 4.17.0 |
| treeLoadedKeys | (受控)已经加载的节点,需要配合 `loadData` 使用 | string[] | [] | |
| treeNodeFilterProp | 输入项过滤对应的 treeNode 属性 | string | `value` | |
| treeNodeLabelProp | 作为显示的 prop 设置 | string | `title` | |
| value | 指定当前选中的条目 | string \| string\[] | - | |
| virtual | 设置 false 时关闭虚拟滚动 | boolean | true | 4.1.0 |
| onChange | 选中树节点时调用此函数 | function(value, label, extra) | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
| onSearch | 文本框值变化时回调 | function(value: string) | - | |
| onSelect | 被选中时调用 | function(value, node, extra) | - | |
| onTreeExpand | 展示节点时调用 | function(expandedKeys) | - | |
### Tree 方法

View File

@ -44,7 +44,7 @@ describe('Typography.Editable', () => {
it('should use editConfig.text over children in editing mode ', async () => {
const suffix = '--The information is very important';
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const { container: wrapper, unmount } = render(
<Base
ellipsis={{ rows: 1, suffix }}
@ -65,7 +65,7 @@ describe('Typography.Editable', () => {
it('should use children as the fallback of editConfig.text in editing mode', async () => {
const suffix = '--The information is very important';
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const { container: wrapper, unmount } = render(
<Base ellipsis={{ rows: 1, suffix }} component="p" ref={ref} editable>
{fullStr}

View File

@ -46,7 +46,7 @@ describe('Typography.Ellipsis', () => {
computeSpy = jest
.spyOn(window, 'getComputedStyle')
.mockImplementation(() => ({ fontSize: 12 } as unknown as CSSStyleDeclaration));
.mockImplementation(() => ({ fontSize: 12 }) as unknown as CSSStyleDeclaration);
});
afterEach(() => {
@ -65,7 +65,7 @@ describe('Typography.Ellipsis', () => {
'Bamboo is Little Light Bamboo is Little Light Bamboo is Little Light Bamboo is Little Light Bamboo is Little Light';
it('should trigger update', async () => {
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const onEllipsis = jest.fn();
const { container, rerender, unmount } = render(
<Base ellipsis={{ onEllipsis }} component="p" editable ref={ref}>
@ -73,7 +73,7 @@ describe('Typography.Ellipsis', () => {
</Base>,
);
triggerResize(ref.current);
triggerResize(ref.current!);
await waitFakeTimer();
expect(container.firstChild?.textContent).toEqual('Bamboo is Little ...');
@ -128,7 +128,7 @@ describe('Typography.Ellipsis', () => {
design language for background applications, is refined by Ant UED Team.
Ant Design, a design language for background applications, is refined by
Ant UED Team.`;
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const onEllipsis = jest.fn();
const { container: wrapper, unmount } = render(
<Base ellipsis={{ onEllipsis }} component="p" editable ref={ref}>
@ -136,7 +136,7 @@ describe('Typography.Ellipsis', () => {
</Base>,
);
triggerResize(ref.current);
triggerResize(ref.current!);
await waitFakeTimer();
expect(wrapper.firstChild?.textContent).toEqual('Ant Design, a des...');
@ -149,14 +149,14 @@ describe('Typography.Ellipsis', () => {
it('should middle ellipsis', async () => {
const suffix = '--suffix';
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const { container: wrapper, unmount } = render(
<Base ellipsis={{ rows: 1, suffix }} component="p" ref={ref}>
{fullStr}
</Base>,
);
triggerResize(ref.current);
triggerResize(ref.current!);
await waitFakeTimer();
expect(wrapper.querySelector('p')?.textContent).toEqual('Bamboo is...--suffix');
@ -165,7 +165,7 @@ describe('Typography.Ellipsis', () => {
it('should front or middle ellipsis', async () => {
const suffix = '--The information is very important';
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const {
container: wrapper,
rerender,
@ -176,7 +176,7 @@ describe('Typography.Ellipsis', () => {
</Base>,
);
triggerResize(ref.current);
triggerResize(ref.current!);
await waitFakeTimer();
expect(wrapper.querySelector('p')?.textContent).toEqual(
@ -206,7 +206,7 @@ describe('Typography.Ellipsis', () => {
const bamboo = 'Bamboo';
const is = ' is ';
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const { container: wrapper } = render(
<Base ellipsis component="p" editable ref={ref}>
{bamboo}
@ -216,7 +216,7 @@ describe('Typography.Ellipsis', () => {
</Base>,
);
triggerResize(ref.current);
triggerResize(ref.current!);
await waitFakeTimer();
expect(wrapper.textContent).toEqual('Bamboo is Little...');
@ -322,13 +322,13 @@ describe('Typography.Ellipsis', () => {
});
async function getWrapper(tooltip?: EllipsisConfig['tooltip']) {
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const wrapper = render(
<Base ellipsis={{ tooltip }} component="p" ref={ref}>
{fullStr}
</Base>,
);
triggerResize(ref.current);
triggerResize(ref.current!);
await waitFakeTimer();
return wrapper;
}
@ -419,13 +419,13 @@ describe('Typography.Ellipsis', () => {
},
});
const ref = React.createRef<any>();
const ref = React.createRef<HTMLElement>();
const { container, baseElement } = render(
<Base component={undefined} ellipsis={{ tooltip: 'This is tooltip', rows: 2 }} ref={ref}>
Ant Design, a design language for background applications, is refined by Ant UED Team.
</Base>,
);
triggerResize(ref.current);
triggerResize(ref.current!);
await waitFakeTimer();
fireEvent.mouseEnter(container.firstChild!);

View File

@ -3,8 +3,8 @@ import * as React from 'react';
export default function useMergedConfig<Target>(
propConfig: any,
templateConfig?: Target,
): [boolean, Target] {
return React.useMemo(() => {
): readonly [boolean, Target] {
return React.useMemo<readonly [boolean, Target]>(() => {
const support = !!propConfig;
return [
@ -13,6 +13,6 @@ export default function useMergedConfig<Target>(
...templateConfig,
...(support && typeof propConfig === 'object' ? propConfig : null),
},
];
] as const;
}, [propConfig]);
}

View File

@ -1,7 +1,7 @@
import * as React from 'react';
/** Similar with `useEffect` but only trigger after mounted */
export default (callback: () => void, conditions: any[]) => {
const useUpdatedEffect = (callback: () => void, conditions?: React.DependencyList) => {
const mountRef = React.useRef(false);
React.useEffect(() => {
@ -12,3 +12,5 @@ export default (callback: () => void, conditions: any[]) => {
}
}, conditions);
};
export default useUpdatedEffect;

View File

@ -18,13 +18,13 @@ export interface ComponentToken {
export type TypographyToken = FullToken<'Typography'>;
const genTypographyStyle: GenerateStyle<TypographyToken> = token => {
const genTypographyStyle: GenerateStyle<TypographyToken> = (token) => {
const { componentCls, sizeMarginHeadingVerticalStart } = token;
return {
[componentCls]: {
color: token.colorText,
overflowWrap: 'break-word',
wordBreak: 'break-word',
lineHeight: token.lineHeight,
'&&-secondary': {
color: token.colorTextDescription,
@ -122,7 +122,7 @@ const genTypographyStyle: GenerateStyle<TypographyToken> = token => {
};
// ============================== Export ==============================
export default genComponentStyleHook('Typography', token => [genTypographyStyle(token)], {
export default genComponentStyleHook('Typography', (token) => [genTypographyStyle(token)], {
sizeMarginHeadingVerticalStart: '1.2em',
sizeMarginHeadingVerticalEnd: '0.5em',
});

View File

@ -1,3 +1,3 @@
import { extendTest } from '../../../tests/shared/demoTest';
extendTest('upload');
extendTest('upload', { skip: ['crop-image.tsx'] });

View File

@ -1,3 +1,3 @@
import demoTest from '../../../tests/shared/demoTest';
demoTest('upload');
demoTest('upload', { skip: ['crop-image.tsx'] });

View File

@ -29,8 +29,8 @@ const fileList: UploadProps['fileList'] = [
describe('Upload List', () => {
// Mock for rc-util raf
window.requestAnimationFrame = callback => window.setTimeout(callback, 16);
window.cancelAnimationFrame = id => window.clearTimeout(id);
window.requestAnimationFrame = (callback) => window.setTimeout(callback, 16);
window.cancelAnimationFrame = (id) => window.clearTimeout(id);
// jsdom not support `createObjectURL` yet. Let's handle this.
const originCreateObjectURL = window.URL.createObjectURL;
@ -678,7 +678,7 @@ describe('Upload List', () => {
<Form.Item
name="file"
valuePropName="fileList"
getValueFromEvent={e => e.fileList}
getValueFromEvent={(e) => e.fileList}
rules={[
{
required: true,
@ -801,12 +801,12 @@ describe('Upload List', () => {
unmount();
});
it('extname should work correctly when url exists', done => {
it('extname should work correctly when url exists', (done) => {
const items = [{ status: 'done', uid: 'upload-list-item', url: '/example' }];
const { container: wrapper, unmount } = render(
<UploadList
listType="picture"
onDownload={file => {
onDownload={(file) => {
expect(file.url).toBe('/example');
unmount();
done();
@ -886,7 +886,7 @@ describe('Upload List', () => {
await waitFor(() => {
expect(previewFunc).toHaveBeenCalled();
});
await previewFunc(mockFile).then(dataUrl => {
await previewFunc(mockFile).then((dataUrl) => {
expect(dataUrl).toEqual('data:image/png;base64,');
});
unmount();
@ -915,7 +915,7 @@ describe('Upload List', () => {
await waitFor(() => {
expect(previewFunc).toHaveBeenCalled();
});
await previewFunc(mockFile).then(dataUrl => {
await previewFunc(mockFile).then((dataUrl) => {
expect(dataUrl).toEqual('data:image/png;base64,');
});
unmount();
@ -939,7 +939,7 @@ describe('Upload List', () => {
await waitFor(() => {
expect(previewFunc).toHaveBeenCalled();
});
await previewFunc(mockFile).then(dataUrl => {
await previewFunc(mockFile).then((dataUrl) => {
expect(dataUrl).toBe('');
});
@ -956,7 +956,7 @@ describe('Upload List', () => {
originFileObj: renderInstance(),
};
delete file.thumbUrl;
const ref = React.createRef();
const ref = React.createRef<any>();
const { container: wrapper, unmount } = render(
<Upload
ref={ref}
@ -1045,7 +1045,7 @@ describe('Upload List', () => {
let wrapper: ReturnType<typeof render>;
const onChange = jest.fn<void, Record<'fileList', UploadProps['fileList']>[]>(
({ fileList: files }) => {
const newFileList = files?.map<UploadFile<any>>(item => ({ ...item, thumbUrl }));
const newFileList = files?.map<UploadFile<any>>((item) => ({ ...item, thumbUrl }));
wrapper.rerender(
<Upload
@ -1139,7 +1139,7 @@ describe('Upload List', () => {
});
});
it('[deprecated] should support transformFile', done => {
it('[deprecated] should support transformFile', (done) => {
jest.useRealTimers();
let wrapper: ReturnType<typeof render>;
let lastFile: UploadFile;
@ -1228,7 +1228,7 @@ describe('Upload List', () => {
fileList={testFileList}
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
multiple
onChange={info => {
onChange={(info) => {
setTestFileList([...info.fileList]);
}}
>
@ -1244,7 +1244,7 @@ describe('Upload List', () => {
await act(() => {
uploadRef.current.onBatchStart(
fileNames.map(fileName => {
fileNames.map((fileName) => {
const file = new File([], fileName);
(file as any).uid = fileName;
return { file, parsedFile: file };

View File

@ -77,8 +77,8 @@
"lint:script": "eslint . --ext .js,.jsx,.ts,.tsx",
"pre-publish": "npm run test-all -- --skip-build",
"prettier": "prettier -c --write **/*",
"pretty-quick": "pretty-quick",
"pub": "npm run version && npm run collect-token-statistic && antd-tools run pub-experimental",
"rome:format": "rome format --write .",
"prepublishOnly": "antd-tools run guard",
"postpublish": "node ./scripts/post-script.js",
"site": "dumi build && cp .surgeignore _site",
@ -126,11 +126,11 @@
"rc-drawer": "~6.0.0",
"rc-dropdown": "~4.0.0",
"rc-field-form": "~1.27.0",
"rc-image": "~5.11.0",
"rc-image": "~5.12.0",
"rc-input": "~0.1.4",
"rc-input-number": "~7.3.9",
"rc-mentions": "~1.10.0",
"rc-menu": "~9.6.3",
"rc-mentions": "~1.11.0",
"rc-menu": "~9.7.2",
"rc-motion": "^2.6.1",
"rc-notification": "~5.0.0-alpha.9",
"rc-pagination": "~3.2.0",
@ -144,7 +144,7 @@
"rc-steps": "~6.0.0-alpha.2",
"rc-switch": "~4.0.0",
"rc-table": "~7.26.0",
"rc-tabs": "~12.2.0",
"rc-tabs": "~12.3.0",
"rc-textarea": "~0.4.5",
"rc-tooltip": "~5.2.0",
"rc-tree": "~5.7.0",
@ -248,6 +248,7 @@
"jsonml-to-react-element": "^1.1.11",
"jsonml.js": "^0.1.0",
"less-vars-to-js": "^1.3.0",
"lint-staged": "^13.0.3",
"lz-string": "^1.4.4",
"mini-css-extract-plugin": "^1.6.2",
"mockdate": "^3.0.0",
@ -255,7 +256,6 @@
"prettier": "^2.3.2",
"prettier-plugin-jsdoc": "^0.4.2",
"pretty-format": "^29.0.0",
"pretty-quick": "^3.0.0",
"prismjs": "^1.29.0",
"progress": "^2.0.3",
"qs": "^6.10.1",
@ -284,6 +284,7 @@
"remark-preset-lint-recommended": "^6.0.0",
"remove-files-webpack-plugin": "1.5.0",
"rimraf": "^3.0.0",
"rome": "^10.0.1",
"scrollama": "^3.0.0",
"semver": "^7.3.5",
"simple-git": "^3.0.0",
@ -320,5 +321,9 @@
"path": "./dist/antd.min.js",
"maxSize": "377.5 kB"
}
]
],
"lint-staged": {
"*.{ts,tsx,js,json,less}": "rome format --write",
"*.{md}": "prettier --ignore-unknown --write"
}
}

14
rome.json Normal file
View File

@ -0,0 +1,14 @@
{
"formatter": {
"enabled": true,
"ignore": ["./dist/*", "./es/**/*", "./lib/**/*", "_site/**/*"],
"indentStyle": "space",
"lineWidth": 100,
"indentSize": 2
},
"javascript": {
"formatter": {
"quoteStyle": "single"
}
}
}

View File

@ -57,7 +57,6 @@ if (changeLog) {
console.log(chalk.blue('[check-version-md]: Check Passed'));
console.log('\n');
process.exit(0);
return;
}
}
console.log('\n');

View File

@ -37,7 +37,7 @@ const MAINTAINERS = [
'madccc',
'MadCcc',
'li-jia-nan',
].map(author => author.toLowerCase());
].map((author) => author.toLowerCase());
const cwd = process.cwd();
const git = simpleGit(cwd);
@ -61,9 +61,11 @@ async function printLog() {
name: 'fromVersion',
message: '🏷 Please choose tag to compare with current branch:',
choices: tags.all
.filter(item => !item.includes('experimental'))
.filter((item) => !item.includes('experimental'))
.filter((item) => !item.includes('alpha'))
.filter((item) => !item.includes('resource'))
.reverse()
.slice(0, 10),
.slice(0, 50),
},
]);
let { toVersion } = await inquirer.prompt([
@ -103,14 +105,14 @@ async function printLog() {
const text = `${message} ${body}`;
const match = text.match(/#\d+/g);
const prs = (match || []).map(pr => pr.slice(1));
const prs = (match || []).map((pr) => pr.slice(1));
const validatePRs = [];
console.log(
`[${i + 1}/${logs.all.length}]`,
hash.slice(0, 6),
'-',
prs.length ? prs.map(pr => `#${pr}`).join(',') : '?',
prs.length ? prs.map((pr) => `#${pr}`).join(',') : '?',
);
for (let j = 0; j < prs.length; j += 1) {
const pr = prs[j];
@ -127,13 +129,13 @@ async function printLog() {
reject(new Error(`Fetch timeout of ${timeout}ms exceeded`));
}, timeout);
fetch(`https://github.com/ant-design/ant-design/pull/${pr}`)
.then(response => {
response.text().then(htmlRes => {
.then((response) => {
response.text().then((htmlRes) => {
html = htmlRes;
resolve(response);
});
})
.catch(error => {
.catch((error) => {
reject(error);
});
});
@ -165,8 +167,8 @@ async function printLog() {
});
});
const english = getDescription(lines.find(line => line.text.includes('🇺🇸 English')));
const chinese = getDescription(lines.find(line => line.text.includes('🇨🇳 Chinese')));
const english = getDescription(lines.find((line) => line.text.includes('🇺🇸 English')));
const chinese = getDescription(lines.find((line) => line.text.includes('🇨🇳 Chinese')));
if (english) {
console.log(` 🇨🇳 ${english}`);
}
@ -204,7 +206,7 @@ async function printLog() {
console.log('\n', chalk.green('Done. Here is the log:'));
function printPR(lang, postLang) {
prList.forEach(entity => {
prList.forEach((entity) => {
const { pr, author, hash, title } = entity;
if (pr) {
const str = postLang(entity[lang]);
@ -236,7 +238,7 @@ async function printLog() {
console.log('\n');
console.log(chalk.yellow('🇨🇳 Chinese changelog:'));
console.log('\n');
printPR('chinese', chinese =>
printPR('chinese', (chinese) =>
chinese[chinese.length - 1] === '。' || !chinese ? chinese : `${chinese}`,
);
@ -245,7 +247,7 @@ async function printLog() {
// English
console.log(chalk.yellow('🇺🇸 English changelog:'));
console.log('\n');
printPR('english', english => {
printPR('english', (english) => {
english = english.trim();
if (english[english.length - 1] !== '.' || !english) {
english = `${english}.`;
@ -270,7 +272,7 @@ async function printLog() {
shell: true,
},
);
ls.stdout.on('data', data => {
ls.stdout.on('data', (data) => {
console.log(data.toString());
});

View File

@ -4,7 +4,7 @@ import { sleep, render, fireEvent } from '../utils';
// eslint-disable-next-line jest/no-export
export default function focusTest(
Component: React.ComponentType<any>,
{ refFocus = false, testLib = false } = {},
{ refFocus = false, testLib = false, blurDelay = 0 } = {},
) {
describe('focus and blur', () => {
let focused = false;
@ -110,7 +110,7 @@ export default function focusTest(
expect(blurred).toBeTruthy();
fireEvent.blur(getElement(container));
await sleep(0);
await sleep(blurDelay);
expect(onBlur).toHaveBeenCalled();
});