Merge pull request #27275 from ant-design/merge-into-feature

chore: merge master into feature
This commit is contained in:
偏右 2020-10-21 21:04:42 +08:00 committed by GitHub
commit bcc05fcc18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
224 changed files with 2511 additions and 2663 deletions

View File

@ -1,4 +1,8 @@
**/*.png
**/*.svg
CODEOWNERS
.dockerignore
Dockerfile.ui-test
package.json
.umi
.umi-production
@ -17,6 +21,8 @@ yarn-error.log
*.snap
components/*/*.js
components/*/*.jsx
components/*/*.md
docs/**/*.md
.gitignore
.npmignore
.prettierignore

View File

@ -15,6 +15,42 @@ timeline: true
---
## 4.7.2
`2020-10-19`
- 💄 Fix Layout.Sider `light` theme lost styles. [#27227](https://github.com/ant-design/ant-design/pull/27227) [@lingjieee](https://github.com/lingjieee)
- 💄 Fix TextArea wrapped with additional div when `showCount` is `false`, and pass `className` and `style` to outer wrapper when `showCount` is `true`. [#27216](https://github.com/ant-design/ant-design/pull/27216)
- 🐞 Fix Checkbox.Group TS2559 error. [#27231](https://github.com/ant-design/ant-design/pull/27231)
## 4.7.1
`2020-10-18`
- DatePicker
- 🐞 Fix DatePicker don't work correctly when `showTime` is `true` and `format` is function. [#27156](https://github.com/ant-design/ant-design/pull/27156)
- 💄 Fix DatePicker wrong animation direction when auto overflow. [#27101](https://github.com/ant-design/ant-design/pull/27101)
- Typography
- 💄 Fix Typography miss `pre` and `blockquote` style. [#27150](https://github.com/ant-design/ant-design/pull/27150)
- 🐞 Fix Typography.Link hover color. [#27119](https://github.com/ant-design/ant-design/pull/27119)
- 🐞 Fix Typography.Link hover color when type is danger. [#27104](https://github.com/ant-design/ant-design/pull/27104)
- 💄 Fix Descriptions `ant-descriptions-item-content` and add style `word-break:break-word;`. [#27195](https://github.com/ant-design/ant-design/pull/27195) [@WLyKan](https://github.com/WLyKan)
- 🐞 Fix clear Password value attribute in controlled mode. [#27191](https://github.com/ant-design/ant-design/pull/27191)
- 🐞 Optimize Notification width in small screen. [#27189](https://github.com/ant-design/ant-design/pull/27189)
- 🐞 Fix Cascader className duplicate. [#27187](https://github.com/ant-design/ant-design/pull/27187) [@huntdream](https://github.com/huntdream)
- 🐞 Fix the issue that the Drawer will trigger form submit. [#27175](https://github.com/ant-design/ant-design/pull/27175)
- 🐞 Fix Dropdown icon missing margin. [#27165](https://github.com/ant-design/ant-design/pull/27165)
- 💄 Fix Layout.Sider `collapsedWidth` cannot work without modifying `@menu-collapsed-width`. [#27154](https://github.com/ant-design/ant-design/pull/27154)
- 🐞 Fix Tabs `animated={true}` not working for panels. [#27145](https://github.com/ant-design/ant-design/pull/27145)
- 🐞 Fix Divider color when contains text. [#27134](https://github.com/ant-design/ant-design/pull/27134)
- 💄 Fix the cursor style when the Radio option is selected and disabled. [#27125](https://github.com/ant-design/ant-design/pull/27125)
- 🇪🇸 Add missing translations in es_ES. [#27079](https://github.com/ant-design/ant-design/pull/27079) [@gersongams](https://github.com/gersongams)
- RTL
- 💄 Optimize the style of Input.TextArea character count in RTL mode. [#27098](https://github.com/ant-design/ant-design/pull/27098)
- TypeScript
- 🤖 Button shape remove undeclared doc type. [#27159](https://github.com/ant-design/ant-design/pull/27159)
- 🤖 Add optional `rules` property into `FormListProps`. [#27164](https://github.com/ant-design/ant-design/pull/27164) [@huntdream](https://github.com/huntdream)
## 4.7.0
`2020-10-10`
@ -35,7 +71,7 @@ timeline: true
- 🆕 Table `sticky` now support `getContainer`. [#26973](https://github.com/ant-design/ant-design/pull/26973)
- 🐞 Fix Table should not render dropdown filter icon when filterDropdown is `undefined`. [#27002](https://github.com/ant-design/ant-design/pull/27002) [@shangyilim](https://github.com/shangyilim)
- Modal
- 🛠 Refactor Modal animation code so that it will remove all dom element when closed. [#26940](https://github.com/ant-design/ant-design/pull/26940)
- 🛠 Refactor Modal animation code so that it will remove all dom element by `destroyOnClose` when closed. [#26940](https://github.com/ant-design/ant-design/pull/26940)
- 🆕 Modal add `modalRender` prop which can be used for draggable dialog. [#26507](https://github.com/ant-design/ant-design/pull/26507) [@jhoneybee](https://github.com/jhoneybee)
- 🆕 Space add `split` prop. [#26948](https://github.com/ant-design/ant-design/pull/26948)
- 🆕 Image `preview` prop now support `visible` and `onVisibleChange`. [#26915](https://github.com/ant-design/ant-design/pull/26915)

View File

@ -15,6 +15,42 @@ timeline: true
---
## 4.7.2
`2020-10-19`
- 💄 修复 Layout.Sider `light` 主题失效问题。[#27227](https://github.com/ant-design/ant-design/pull/27227) [@lingjieee](https://github.com/lingjieee)
- 💄 修复 TextArea 没有设置 `showCount` 时仍然会包裹 div 的问题,同时解决 `showCount``className``style` 没有传递给最外层节点的问题。[#27216](https://github.com/ant-design/ant-design/pull/27216)
- 🐞 修复 Checkbox.Group TS2559 错误。[#27231](https://github.com/ant-design/ant-design/pull/27231)
## 4.7.1
`2020-10-18`
- DatePicker
- 🐞 修复 DatePicker `showTime``true` 并且 `format` 为一个函数时报错的问题。[#27156](https://github.com/ant-design/ant-design/pull/27156)
- 💄 修复 DatePicker 在下拉空间不足时的动画方向问题。[#27101](https://github.com/ant-design/ant-design/pull/27101)
- Typography
- 💄 修复 Typography 没有 `pre``blockquote` 样式的问题。[#27150](https://github.com/ant-design/ant-design/pull/27150)
- 🐞 修复 Typography.Link 悬浮颜色错误的问题。[#27119](https://github.com/ant-design/ant-design/pull/27119)
- 🐞 修复 Typography.Link 危险类型的悬浮颜色问题。[#27104](https://github.com/ant-design/ant-design/pull/27104)
- 💄 修复 Descriptions 组件的内容含有超长数字时无法换行的问题。[#27195](https://github.com/ant-design/ant-design/pull/27195) [@WLyKan](https://github.com/WLyKan)
- 🐞 修复 Password 在受控模式下未清除 `value` 属性的问题。[#27191](https://github.com/ant-design/ant-design/pull/27191)
- 🐞 修复 Notification 在小尺寸屏幕下的宽度问题。[#27189](https://github.com/ant-design/ant-design/pull/27189)
- 🐞 修复 Cascader 类名重复的问题。[#27187](https://github.com/ant-design/ant-design/pull/27187) [@huntdream](https://github.com/huntdream)
- 🐞 修复 Drawer 会触发 Form 提交事件的问题。[#27175](https://github.com/ant-design/ant-design/pull/27175)
- 🐞 修复 Dropdown 下拉菜单图标间距丢失的问题。[#27165](https://github.com/ant-design/ant-design/pull/27165)
- 💄 修复 Layout.Sider 指定 `collapsedWidth` 后侧边菜单部分宽度不对的问题。[#27154](https://github.com/ant-design/ant-design/pull/27154)
- 🐞 修复 Tabs `animated` 属性为 `true` 时未开启内容切换动画的问题。[#27145](https://github.com/ant-design/ant-design/pull/27145)
- 🐞 修复 Divider 带标题时的分割线颜色。[#27134](https://github.com/ant-design/ant-design/pull/27134)
- 💄 修复 Radio 选项选中并禁用时的鼠标样式。[#27125](https://github.com/ant-design/ant-design/pull/27125)
- 🇪🇸 为西班牙语 es_ES 中添加缺少的翻译。[#27079](https://github.com/ant-design/ant-design/pull/27079) [@gerongams](https://github.com/gersongams)
- RTL
- 💄 优化 Input.TextArea 字数提示在 RTL 模式下的样式。[#27098](https://github.com/ant-design/ant-design/pull/27098)
- TypeScript
- 🤖 Button `shape` 移除文档中未声明的类型。[#27159](https://github.com/ant-design/ant-design/pull/27159)
- 🤖 修复 Form.List `rules` 属性缺失的问题。[#27164](https://github.com/ant-design/ant-design/pull/27164) [@huntdream](https://github.com/huntdream)
## 4.7.0
`2020-10-10`
@ -35,7 +71,7 @@ timeline: true
- 🆕 Table `sticky` 支持 `getContainer` 以指定滚动容器。[#26973](https://github.com/ant-design/ant-design/pull/26973)
- 🐞 修复 Table `column.filterDropdown``undefined` 时依旧会展示筛选菜单的问题。[#27002](https://github.com/ant-design/ant-design/pull/27002) [@shangyilim](https://github.com/shangyilim)
- Modal
- 🛠 重构 Modal 组件动画,现在关闭时将完全清理相关 Dom 节点。[#26940](https://github.com/ant-design/ant-design/pull/26940)
- 🛠 重构 Modal 组件动画,现在 `destroyOnClose` 关闭时将完全清理相关 Dom 节点。[#26940](https://github.com/ant-design/ant-design/pull/26940)
- 🆕 Modal 新增 `modalRender` 属性,支持可拖拽的对话框。[#26507](https://github.com/ant-design/ant-design/pull/26507) [@jhoneybee](https://github.com/jhoneybee)
- 🆕 Space 增加 `split` 属性以支持分隔符间隔。[#26948](https://github.com/ant-design/ant-design/pull/26948)
- 🆕 Image `preview` 属性扩展支持 `visible``onVisibleChange`。[#26915](https://github.com/ant-design/ant-design/pull/26915)
@ -326,7 +362,7 @@ timeline: true
- 🐞 修复 Form 垂直布局时 Form.Item 设置 `labelCol={{ offset: number }}` 不生效的问题。[#25713](https://github.com/ant-design/ant-design/pull/25713) [@zhangchen915](https://github.com/zhangchen915)
- ⌨️ Form 错误信息节点增加属性 `role="alert"` 以增强可访问性。[#25735](https://github.com/ant-design/ant-design/pull/25735) [@AlbertAZ1992](https://github.com/AlbertAZ1992)
- Calendar
- 🐞 修复 Calendar 组件的 `validRange` 导致 `disabledDate` 不生效 。[#25626](https://github.com/ant-design/ant-design/pull/25626) [@zhangchen915](https://github.com/zhangchen915)
- 🐞 修复 Calendar 组件的 `validRange` 导致 `disabledDate` 不生效。[#25626](https://github.com/ant-design/ant-design/pull/25626) [@zhangchen915](https://github.com/zhangchen915)
- 🐞 修复 Calendar `validRange` 对月份下拉菜单不生效的问题。[#25626](https://github.com/ant-design/ant-design/pull/25626) [@zhangchen915](https://github.com/zhangchen915)
- 🐞 修复 Table `getCheckboxProps` 返回的 `indeterminate` 不生效。[#25649](https://github.com/ant-design/ant-design/pull/25649)
- 🐞 修复 Select 清除按钮在 Form.Item 下位置不对的问题。[#25728](https://github.com/ant-design/ant-design/pull/25728)

View File

@ -10,7 +10,6 @@
一套企业级 UI 设计语言和 React 组件库。
[![CircleCI status][circleci-image]][circleci-url] [![CI status][github-action-image]][github-action-url] [![codecov][codecov-image]][codecov-url] [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url]
[![david deps][david-image]][david-url] [![david devDeps][david-dev-image]][david-dev-url] [![Total alerts][lgtm-image]][lgtm-url] [![FOSSA Status][fossa-image]][fossa-url] [![Issues need help][help-wanted-image]][help-wanted-url]

View File

@ -2,8 +2,7 @@
## Supported Versions
Use this section to tell people about which versions of your project are
currently being supported with security updates.
Use this section to tell people about which versions of your project are currently being supported with security updates.
| Version | Supported |
| ------- | ------------------ |
@ -14,6 +13,4 @@ currently being supported with security updates.
Use this section to tell people how to report a vulnerability.
Tell them where to go, how often they can expect to get an update on a
reported vulnerability, what to expect if the vulnerability is accepted or
declined, etc.
Tell them where to go, how often they can expect to get an update on a reported vulnerability, what to expect if the vulnerability is accepted or declined, etc.

View File

@ -0,0 +1,19 @@
import * as React from 'react';
import { fillRef } from '../ref';
function useCombinedRefs<T>(
...refs: Array<React.MutableRefObject<T> | ((instance: T) => void) | null>
) {
const targetRef = React.useRef();
React.useEffect(() => {
refs.forEach(ref => {
if (!ref) return;
fillRef(ref, targetRef.current);
});
}, [refs]);
return targetRef;
}
export default useCombinedRefs;

View File

@ -19,8 +19,8 @@ Please note that Affix should not cover other content on the page, especially wh
| --- | --- | --- | --- |
| offsetBottom | Offset from the bottom of the viewport (in pixels) | number | - |
| offsetTop | Offset from the top of the viewport (in pixels) | number | 0 |
| onChange | Callback for when Affix state is changed | function(affixed) | - |
| target | Specifies the scrollable area DOM node | () => HTMLElement | () => window |
| onChange | Callback for when Affix state is changed | function(affixed) | - |
**Note:** Children of `Affix` must not have the property `position: absolute`, but you can set `position: absolute` on `Affix` itself:

View File

@ -20,8 +20,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/tX6-md4H6/Affix.svg
| --- | --- | --- | --- |
| offsetBottom | 距离窗口底部达到指定偏移量后触发 | number | - |
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | - |
| onChange | 固定状态改变时触发的回调函数 | function(affixed) | - |
| target | 设置 `Affix` 需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window |
| onChange | 固定状态改变时触发的回调函数 | function(affixed) | - |
**注意:**`Affix` 内的元素不要使用绝对定位,如需要绝对定位的效果,可以直接设置 `Affix` 为绝对定位:

View File

@ -29,7 +29,7 @@ Alert component for feedback.
### Alert.ErrorBoundary
| Property | Description | Type | Default | Version |
| ----------- | -------------------------------- | --------- | ----------------- | ------- |
| message | Custom error message to show | ReactNode | {{ error }} | |
| description | Custom error description to show | ReactNode | {{ error stack }} | |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| description | Custom error description to show | ReactNode | {{ error stack }} | |
| message | Custom error message to show | ReactNode | {{ error }} | |

View File

@ -32,5 +32,5 @@ cover: https://gw.alipayobjects.com/zos/alicdn/8emPa3fjl/Alert.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| message | 自定义错误标题,如果未指定会展示原生报错信息 | ReactNode | {{ error }} | |
| description | 自定义错误内容,如果未指定会展示报错堆栈 | ReactNode | {{ error stack }} | |
| message | 自定义错误标题,如果未指定会展示原生报错信息 | ReactNode | {{ error }} | |

View File

@ -21,17 +21,17 @@ For displaying anchor hyperlinks on page and jumping between them.
| affix | Fixed mode of Anchor | boolean | true | |
| bounds | Bounding distance of anchor area | number | 5 | |
| getContainer | Scrolling container | () => HTMLElement | () => window | |
| getCurrentAnchor | Customize the anchor highlight | () => string | - | |
| offsetTop | Pixels to offset from top when calculating position of scroll | number | 0 | |
| showInkInFixed | Whether show ink-balls when `affix={false}` | boolean | false | |
| onClick | Set the handler to handle `click` event | function(e: Event, link: Object) | - | |
| getCurrentAnchor | Customize the anchor highlight | () => string | - | |
| targetOffset | Anchor scroll offset, default as `offsetTop`, [example](#components-anchor-demo-targetOffset) | number | - | |
| onChange | Listening for anchor link change | (currentActiveLink: string) => void | | |
| onClick | Set the handler to handle `click` event | function(e: Event, link: Object) | - | |
### Link Props
| Property | Description | Type | Default | Version |
| -------- | ----------------------------------------- | --------- | ------- | ------- |
| href | The target of hyperlink | string | | |
| title | The content of hyperlink | ReactNode | | |
| target | Specifies where to display the linked URL | string | | |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| href | The target of hyperlink | string | | |
| target | Specifies where to display the linked URL | string | | |
| title | The content of hyperlink | ReactNode | | |

View File

@ -22,17 +22,17 @@ cover: https://gw.alipayobjects.com/zos/alicdn/_1-C1JwsC/Anchor.svg
| affix | 固定模式 | boolean | true | |
| bounds | 锚点区域边界 | number | 5 | |
| getContainer | 指定滚动的容器 | () => HTMLElement | () => window | |
| getCurrentAnchor | 自定义高亮的锚点 | () => string | - | |
| offsetTop | 距离窗口顶部达到指定偏移量后触发 | number | | |
| showInkInFixed | `affix={false}` 时是否显示小圆点 | boolean | false | |
| onClick | `click` 事件的 handler | function(e: Event, link: Object) | - | |
| getCurrentAnchor | 自定义高亮的锚点 | () => string | - | |
| targetOffset | 锚点滚动偏移量,默认与 offsetTop 相同,[例子](#components-anchor-demo-targetOffset) | number | - | |
| onChange | 监听锚点链接改变 | (currentActiveLink: string) => void | - | |
| onClick | `click` 事件的 handler | function(e: Event, link: Object) | - | |
### Link Props
| 成员 | 说明 | 类型 | 默认值 | 版本 |
| ------ | -------------------------------- | --------- | ------ | ---- |
| href | 锚点链接 | string | - | |
| title | 文字内容 | ReactNode | - | |
| target | 该属性指定在何处显示链接的资源。 | string | - | |
| 成员 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| href | 锚点链接 | string | - | |
| target | 该属性指定在何处显示链接的资源。 | string | - | |
| title | 文字内容 | ReactNode | - | |

View File

@ -147,23 +147,19 @@ exports[`renders ./components/auto-complete/demo/custom.md correctly 1`] = `
<span
class="ant-select-selection-search"
>
<div
class="ant-input-textarea"
>
<textarea
aria-activedescendant="undefined_list_0"
aria-autocomplete="list"
aria-controls="undefined_list"
aria-haspopup="listbox"
aria-owns="undefined_list"
autocomplete="off"
class="ant-input ant-select-selection-search-input"
placeholder="input here"
role="combobox"
style="height:50px"
type="search"
/>
</div>
<textarea
aria-activedescendant="undefined_list_0"
aria-autocomplete="list"
aria-controls="undefined_list"
aria-haspopup="listbox"
aria-owns="undefined_list"
autocomplete="off"
class="ant-input ant-select-selection-search-input"
placeholder="input here"
role="combobox"
style="height:50px"
type="search"
/>
</span>
<span
class="ant-select-selection-placeholder"

View File

@ -24,10 +24,7 @@ describe('AutoComplete children could be focus', () => {
it('focus() and onFocus', () => {
const handleFocus = jest.fn();
const wrapper = mount(<AutoComplete onFocus={handleFocus} />, { attachTo: container });
wrapper
.find('input')
.instance()
.focus();
wrapper.find('input').instance().focus();
jest.runAllTimers();
expect(handleFocus).toHaveBeenCalled();
});
@ -35,15 +32,9 @@ describe('AutoComplete children could be focus', () => {
it('blur() and onBlur', () => {
const handleBlur = jest.fn();
const wrapper = mount(<AutoComplete onBlur={handleBlur} />, { attachTo: container });
wrapper
.find('input')
.instance()
.focus();
wrapper.find('input').instance().focus();
jest.runAllTimers();
wrapper
.find('input')
.instance()
.blur();
wrapper.find('input').instance().blur();
jest.runAllTimers();
expect(handleBlur).toHaveBeenCalled();
});

View File

@ -22,30 +22,30 @@ When there is a need for autocomplete functionality.
| children (for customize input element) | Customize input element | HTMLInputElement \| HTMLTextAreaElement \| React.ReactElement&lt;InputProps> | &lt;Input /> | |
| children (for dataSource) | Data source to auto complete | React.ReactElement&lt;OptionProps> \| Array&lt;React.ReactElement&lt;OptionProps>> | - | |
| defaultActiveFirstOption | Whether active first option by default | boolean | true | |
| defaultOpen | Initial open state of dropdown | boolean | - | |
| defaultValue | Initial selected option | string | - | |
| disabled | Whether disabled select | boolean | false | |
| dropdownClassName | The className of dropdown menu | string | - | |
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | true | |
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns true, the option will be included in the filtered set; Otherwise, it will be excluded | boolean \| function(inputValue, option) | true | |
| notFoundContent | Specify content to show when no result matches | string | `Not Found` | |
| open | Controlled open state of dropdown | boolean | - | |
| options | Select options. Will get better perf than jsx definition | { label, value }\[] | - | |
| placeholder | The placeholder of input | string | - | |
| value | Selected option | string | - | |
| onBlur | Called when leaving the component | function() | - | |
| onChange | Called when select an option or input value change, or value of input is changed | function(value) | - | |
| onDropdownVisibleChange | Call when dropdown open | function(open) | - | |
| onFocus | Called when entering the component | function() | - | |
| onSearch | Called when searching items | function(value) | - | |
| onSelect | Called when a option is selected. param is option's value and option instance | function(value, option) | - | |
| defaultOpen | Initial open state of dropdown | boolean | - | |
| open | Controlled open state of dropdown | boolean | - | |
| options | Select options. Will get better perf than jsx definition | { label, value }[] | - | |
| onDropdownVisibleChange | Call when dropdown open | function(open) | - | |
| notFoundContent | Specify content to show when no result matches | string | `Not Found` | |
## Methods
| Name | Description | Version |
| ------- | ------------ | ------- |
| blur() | Remove focus | |
| focus() | Get focus | |
| Name | Description | Version |
| --- | --- | --- |
| blur() | Remove focus | |
| focus() | Get focus | |
## FAQ

View File

@ -20,34 +20,34 @@ cover: https://gw.alipayobjects.com/zos/alicdn/qtJm4yt45/AutoComplete.svg
| allowClear | 支持清除, 单选模式有效 | boolean | false | |
| autoFocus | 自动获取焦点 | boolean | false | |
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
| children (自定义输入框) | 自定义输入框 | HTMLInputElement \| HTMLTextAreaElement \| React.ReactElement&lt;InputProps> | &lt;Input /> | |
| 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 | |
| dropdownClassName | 下拉菜单的 className 属性 | string | - | |
| 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 | - | |
| value | 指定当前选中的条目 | string | - | |
| onBlur | 失去焦点时的回调 | function() | - | |
| onChange | 选中 option或 input 的 value 变化时,调用此函数 | function(value) | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
| onFocus | 获得焦点时的回调 | function() | - | |
| onSearch | 搜索补全项的时候调用 | function(value) | - | |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | - | |
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
| open | 是否展开下拉菜单 | boolean | - | |
| options | 数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能 | { label, value }[] | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | - | |
## 方法
| 名称 | 描述 | 版本 |
| ------- | -------- | ---- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |
| 名称 | 描述 | 版本 |
| --- | --- | --- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |
## FAQ

View File

@ -13,21 +13,21 @@ Avatars can be used to represent people or objects. It supports images, `Icon`s,
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| alt | This attribute defines the alternative text describing the image | string | - | |
| gap | Letter type unit distance between left and right sides | number | 4 | 4.3.0 |
| icon | Custom icon type for an icon avatar | ReactNode | - | |
| shape | The shape of avatar | `circle` \| `square` | `circle` | |
| size | The size of the avatar | number \| `large` \| `small` \| `default` \| `{ xs: number, sm: number, ...}` | `default` | 4.7.0 |
| src | The address of the image for an image avatar | string | - | |
| srcSet | A list of sources to use for different screen resolutions | string | - | |
| alt | This attribute defines the alternative text describing the image | string | - | |
| onError | Handler when img load error, return false to prevent default fallback behavior | () => boolean | - | |
| gap | Letter type unit distance between left and right sides | number | 4 | 4.3.0 |
> Tip: You can set `icon` or `children` as the fallback for image load error, with the priority of `icon` > `children`
### Avatar.Group (4.5.0+)
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------------------- | -------------------------------------- | ----------------- | ------ | ---- |
| maxCount | Max avatars to show | number | - | |
| maxStyle | The style of excess avatar style | CSSProperties | - | |
| maxPopoverPlacement | The placement of excess avatar Popover | `top` \| `bottom` | `top` | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| maxCount | Max avatars to show | number | - | |
| maxPopoverPlacement | The placement of excess avatar Popover | `top` \| `bottom` | `top` | |
| maxStyle | The style of excess avatar style | CSSProperties | - | |

View File

@ -10,7 +10,7 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/aBcnbw68hP/Avatar.svg
## 设计师专属
安装 [Kitchen Sketch 插件 💎](https://kitchen.alipay.com),一键填充高逼格头像和文本.
安装 [Kitchen Sketch 插件 💎](https://kitchen.alipay.com),一键填充高逼格头像和文本
## API
@ -18,21 +18,21 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/aBcnbw68hP/Avatar.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| alt | 图像无法显示时的替代文本 | string | - | |
| gap | 字符类型距离左右两侧边界单位像素 | number | 4 | 4.3.0 |
| icon | 设置头像的自定义图标 | ReactNode | - | |
| shape | 指定头像的形状 | `circle` \| `square` | `circle` | |
| size | 设置头像的大小 | number \| `large` \| `small` \| `default` \| `{ xs: number, sm: number, ...}` | `default` | 4.7.0 |
| src | 图片类头像的资源地址 | string | - | |
| srcSet | 设置图片类头像响应式资源地址 | string | - | |
| alt | 图像无法显示时的替代文本 | string | - | |
| onError | 图片加载失败的事件,返回 false 会关闭组件默认的 fallback 行为 | () => boolean | - | |
| gap | 字符类型距离左右两侧边界单位像素 | number | 4 | 4.3.0 |
> Tip你可以设置 `icon``children` 作为图片加载失败的默认 fallback 行为,优先级为 `icon` > `children`
### Avatar.Group (4.5.0+)
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ------------------- | -------------------- | ----------------- | ------ | ---- |
| maxCount | 显示的最大头像个数 | number | - | |
| maxStyle | 多余头像样式 | CSSProperties | - | |
| maxPopoverPlacement | 多余头像气泡弹出位置 | `top` \| `bottom` | `top` | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| maxCount | 显示的最大头像个数 | number | - | |
| maxPopoverPlacement | 多余头像气泡弹出位置 | `top` \| `bottom` | `top` | |
| maxStyle | 多余头像样式 | CSSProperties | - | |

View File

@ -20,7 +20,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/tJZ5jbTwX/BackTop.svg
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| duration | Time to return to topms | number | 450 | 4.4.0 |
| target | Specifies the scrollable area dom node | () => HTMLElement | () => window | |
| visibilityHeight | The BackTop button will not show until the scroll height reaches this value | number | 400 | |
| onClick | A callback function, which can be executed when you click the button | function | - | |
| duration | Time to return to topms | number | 450 | 4.4.0 |

View File

@ -21,7 +21,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/tJZ5jbTwX/BackTop.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| duration | 回到顶部所需时间ms | number | 450 | 4.4.0 |
| target | 设置需要监听其滚动事件的元素,值为一个返回对应 DOM 元素的函数 | () => HTMLElement | () => window | |
| visibilityHeight | 滚动高度达到此参数值才出现 BackTop | number | 400 | |
| onClick | 点击按钮的回调函数 | function | - | |
| duration | 回到顶部所需时间ms | number | 450 | 4.4.0 |

View File

@ -23,8 +23,8 @@ Badge normally appears in proximity to notifications or user avatars with eye-ca
| offset | Set offset of the badge dot | \[number, number] | - | |
| overflowCount | Max count to show | number | 99 | |
| showZero | Whether to show badge when `count` is zero | boolean | false | |
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | - | |
| size | If `count` is set, `size` sets the size of badge | `default` \| `small` | - | 4.6.0 |
| status | Set Badge as a status dot | `success` \| `processing` \| `default` \| `error` \| `warning` | - | |
| text | If `status` is set, `text` sets the display text of the status `dot` | ReactNode | - | |
| title | Text to show when hovering over the badge | string | - | |

View File

@ -24,8 +24,8 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/6%26GF9WHwvY/Badge.svg
| offset | 设置状态点的位置偏移 | \[number, number] | - | |
| overflowCount | 展示封顶的数字值 | number | 99 | |
| showZero | 当数值为 0 时,是否展示 Badge | boolean | false | |
| status | 设置 Badge 为状态点 | `success` \| `processing` \| `default` \| `error` \| `warning` | - | |
| size | 在设置了 `count` 的前提下有效,设置小圆点的大小 | `default` \| `small` | - | 4.6.0 |
| status | 设置 Badge 为状态点 | `success` \| `processing` \| `default` \| `error` \| `warning` | - | |
| text | 在设置了 `status` 的前提下有效,设置状态点的文本 | ReactNode | - | |
| title | 设置鼠标放在状态点上时显示的文字 | string | - | |

View File

@ -72,23 +72,12 @@ describe('react router', () => {
</MemoryRouter>,
);
expect(wrapper.find('BreadcrumbItem').length).toBe(1);
expect(
wrapper
.find('BreadcrumbItem .ant-breadcrumb-link')
.at(0)
.text(),
).toBe('Home');
wrapper
.find('.demo-nav a')
.at(1)
.simulate('click');
expect(wrapper.find('BreadcrumbItem .ant-breadcrumb-link').at(0).text()).toBe('Home');
wrapper.find('.demo-nav a').at(1).simulate('click');
expect(wrapper.find('BreadcrumbItem').length).toBe(2);
expect(
wrapper
.find('BreadcrumbItem .ant-breadcrumb-link')
.at(1)
.text(),
).toBe('Application List');
expect(wrapper.find('BreadcrumbItem .ant-breadcrumb-link').at(1).text()).toBe(
'Application List',
);
});
it('react router 3', () => {

View File

@ -30,14 +30,14 @@ A breadcrumb displays the current location within a hierarchy. It allows going b
| --- | --- | --- | --- | --- |
| dropdownProps | The dropdown props | [Dropdown](/components/dropdown) | - | |
| href | Target of hyperlink | string | - | |
| onClick | Set the handler to handle click event | (e:MouseEvent) => void | - | |
| overlay | The dropdown menu | [Menu](/components/menu) \| () => Menu | - | |
| onClick | Set the handler to handle click event | (e:MouseEvent) => void | - | |
### Breadcrumb.Separator
| Property | Description | Type | Default | Version |
| -------- | ---------------- | --------- | ------- | ------- |
| children | Custom separator | ReactNode | `/` | |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| children | Custom separator | ReactNode | `/` | |
> When using `Breadcrumb.Separator`,its parent component must be set to `separator=""`, otherwise the default separator of the parent component will appear.

View File

@ -31,14 +31,14 @@ cover: https://gw.alipayobjects.com/zos/alicdn/9Ltop8JwH/Breadcrumb.svg
| --- | --- | --- | --- | --- |
| dropdownProps | 弹出下拉菜单的自定义配置 | [Dropdown](/components/dropdown) | - | |
| href | 链接的目的地 | string | - | |
| onClick | 单击事件 | (e:MouseEvent) => void | - | |
| overlay | 下拉菜单的内容 | [Menu](/components/menu) \| () => Menu | - | |
| onClick | 单击事件 | (e:MouseEvent) => void | - | |
### Breadcrumb.Separator
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| -------- | -------------- | --------- | ------ | ---- |
| children | 要显示的分隔符 | ReactNode | `/` | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| children | 要显示的分隔符 | ReactNode | `/` | |
> 注意:在使用 `Breadcrumb.Separator` 时,其父组件的分隔符必须设置为 `separator=""`,否则会出现父组件默认的分隔符。

View File

@ -976,34 +976,43 @@ Array [
secondary
</span>
</button>,
<button
class="ant-btn ant-dropdown-trigger"
type="button"
<div
class="ant-btn-group ant-dropdown-button"
>
<span>
Actions
</span>
<span
aria-label="down"
class="anticon anticon-down"
role="img"
<button
class="ant-btn ant-btn-default"
type="button"
>
<svg
aria-hidden="true"
class=""
data-icon="down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
<span>
Actions
</span>
</button>
<button
class="ant-btn ant-btn-default ant-btn-icon-only ant-dropdown-trigger"
type="button"
>
<span
aria-label="ellipsis"
class="anticon anticon-ellipsis"
role="img"
>
<path
d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"
/>
</svg>
</span>
</button>,
<svg
aria-hidden="true"
class=""
data-icon="ellipsis"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M176 511a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0zm280 0a56 56 0 10112 0 56 56 0 10-112 0z"
/>
</svg>
</span>
</button>
</div>,
]
`;

View File

@ -74,7 +74,7 @@ function spaceChildren(children: React.ReactNode, needInserted: boolean) {
const ButtonTypes = tuple('default', 'primary', 'ghost', 'dashed', 'link', 'text');
export type ButtonType = typeof ButtonTypes[number];
const ButtonShapes = tuple('circle', 'circle-outline', 'round');
const ButtonShapes = tuple('circle', 'round');
export type ButtonShape = typeof ButtonShapes[number];
const ButtonHTMLTypes = tuple('submit', 'button', 'reset');
export type ButtonHTMLType = typeof ButtonHTMLTypes[number];

View File

@ -7,15 +7,14 @@ title:
## zh-CN
按钮组合使用时,推荐使用 1 个主操作 + n 个次操作3 个以上操作时把更多操作放到 `Dropdown.Button` 中组合使用。
按钮组合使用时,推荐使用 1 个主操作 + n 个次操作3 个以上操作时把更多操作放到 [Dropdown.Button](/components/dropdown/#components-dropdown-demo-dropdown-button) 中组合使用。
## en-US
If you need several buttons, we recommend that you use 1 primary button + n secondary buttons, and if there are more than three operations, you can group some of them into `Dropdown.Button`.
If you need several buttons, we recommend that you use 1 primary button + n secondary buttons, and if there are more than three operations, you can group some of them into [Dropdown.Button](/components/dropdown/#components-dropdown-demo-dropdown-button).
```jsx
import { Button, Menu, Dropdown } from 'antd';
import { DownOutlined } from '@ant-design/icons';
function handleMenuClick(e) {
console.log('click', e);
@ -33,11 +32,7 @@ ReactDOM.render(
<>
<Button type="primary">primary</Button>
<Button>secondary</Button>
<Dropdown overlay={menu}>
<Button>
Actions <DownOutlined />
</Button>
</Dropdown>
<Dropdown.Button overlay={menu}>Actions</Dropdown.Button>
</>,
mountNode,
);

View File

@ -40,11 +40,11 @@ Different button styles can be generated by setting Button properties. The recom
| htmlType | Set the original html `type` of `button`, see: [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | |
| icon | Set the icon component of button | ReactNode | - | |
| loading | Set the loading status of button | boolean \| { delay: number } | false | |
| onClick | Set the handler to handle `click` event | (event) => void | - | |
| shape | Can be set to `circle`, `round` or omitted | string | - | |
| shape | Can be set button shape | `circle` \| `round` | - | |
| size | Set the size of button | `large` \| `middle` \| `small` | - | |
| target | Same as target attribute of a, works when href is specified | string | - | |
| type | Can be set to `primary` `ghost` `dashed` `link` `text` `default` | string | `default` | |
| onClick | Set the handler to handle `click` event | (event) => void | - | |
It accepts all props which native buttons support.

View File

@ -43,11 +43,11 @@ cover: https://gw.alipayobjects.com/zos/alicdn/fNUKzY1sk/Button.svg
| htmlType | 设置 `button` 原生的 `type` 值,可选值请参考 [HTML 标准](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-type) | string | `button` | |
| icon | 设置按钮的图标组件 | ReactNode | - | |
| loading | 设置按钮载入状态 | boolean \| { delay: number } | false | |
| onClick | 点击按钮时的回调 | (event) => void | - | |
| shape | 设置按钮形状,可选值为 `circle``round` 或者不设 | string | - | |
| shape | 设置按钮形状 | `circle` \| `round` | - | |
| size | 设置按钮大小 | `large` \| `middle` \| `small` | - | |
| target | 相当于 a 链接的 target 属性href 存在时生效 | string | - | |
| type | 设置按钮类型 | `primary` \| `ghost` \| `dashed` \| `link` \| `text` \| `default` | `default` | |
| onClick | 点击按钮时的回调 | (event) => void | - | |
支持原生 button 的其他所有属性。

View File

@ -111,8 +111,7 @@
}
}
&-circle,
&-circle-outline {
&-circle {
.btn-circle(@btn-prefix-cls);
}

View File

@ -57,9 +57,7 @@ ReactDOM.render(
}
return (
<div style={{ padding: 8 }}>
<Typography.Title level={4}>
Custom header
</Typography.Title>
<Typography.Title level={4}>Custom header</Typography.Title>
<Row gutter={8}>
<Col>
<Radio.Group size="small" onChange={e => onTypeChange(e.target.value)} value={type}>

View File

@ -37,16 +37,16 @@ When data is in the form of dates, such as schedules, timetables, prices calenda
| defaultValue | The date selected by default | [moment](http://momentjs.com/) | - | |
| disabledDate | Function that specifies the dates that cannot be selected | (currentDate: moment) => boolean | - | |
| fullscreen | Whether to display in full-screen | boolean | true | |
| headerRender | Render custom header in panel | function(object:{value: moment, type: string, onChange: f(), onTypeChange: f()}) | - | |
| locale | The calendar's locale | object | [(default)](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | |
| mode | The display mode of the calendar | `month` \| `year` | `month` | |
| monthCellRender | Customize the display of the month cell, the returned content will be appended to the cell | function(date: moment): ReactNode | - | |
| monthFullCellRender | Customize the display of the month cell, the returned content will override the cell | function(date: moment): ReactNode | - | |
| validRange | To set valid range | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - | |
| value | The current selected date | [moment](http://momentjs.com/) | - | |
| onChange | Callback for when date changes | function(date: moment | - | |
| onPanelChange | Callback for when panel changes | function(date: moment, mode: string) | - | |
| onSelect | Callback for when a date is selected | function(date: moment | - | |
| onChange | Callback for when date changes | function(date: moment | - | |
| headerRender | Render custom header in panel | function(object:{value: moment, type: string, onChange: f(), onTypeChange: f()}) | - | |
## FAQ

View File

@ -38,16 +38,16 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/dPQmLq08DI/Calendar.svg
| defaultValue | 默认展示的日期 | [moment](http://momentjs.com/) | - | |
| disabledDate | 不可选择的日期 | (currentDate: moment) => boolean | - | |
| fullscreen | 是否全屏显示 | boolean | true | |
| headerRender | 自定义头部内容 | function(object:{value: moment, type: string, onChange: f(), onTypeChange: f()}) | - | |
| locale | 国际化配置 | object | [(默认配置)](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | |
| mode | 初始模式 | `month` \| `year` | `month` | |
| monthCellRender | 自定义渲染月单元格,返回内容会被追加到单元格 | function(date: moment): ReactNode | - | |
| monthFullCellRender | 自定义渲染月单元格,返回内容覆盖单元格 | function(date: moment): ReactNode | - | |
| validRange | 设置可以显示的日期 | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - | |
| value | 展示日期 | [moment](http://momentjs.com/) | - | |
| onChange | 日期变化回调 | function(date: moment | - | |
| onPanelChange | 日期面板变化回调 | function(date: moment, mode: string) | - | |
| onSelect | 点击选择日期回调 | function(date: moment | - | |
| onChange | 日期变化回调 | function(date: moment | - | |
| headerRender | 自定义头部内容 | function(object:{value: moment, type: string, onChange: f(), onTypeChange: f()}) | - | |
## FAQ

View File

@ -52,10 +52,7 @@ describe('Card', () => {
xxx
</Card>,
);
wrapper
.find('.ant-tabs-tab')
.at(1)
.simulate('click');
wrapper.find('.ant-tabs-tab').at(1).simulate('click');
expect(onTabChange).toHaveBeenCalledWith('tab2');
});

View File

@ -24,36 +24,36 @@ A card can be used to display content related to a single subject. The content c
| --- | --- | --- | --- | --- |
| actions | The action list, shows at the bottom of the Card | Array&lt;ReactNode> | - | |
| activeTabKey | Current TabPane's key | string | - | |
| headStyle | Inline style to apply to the card head | CSSProperties | - | |
| bodyStyle | Inline style to apply to the card content | CSSProperties | - | |
| bordered | Toggles rendering of the border around the card | boolean | true | |
| cover | Card cover | ReactNode | - | |
| defaultActiveTabKey | Initial active TabPane's key, if `activeTabKey` is not set | string | - | |
| extra | Content to render in the top-right corner of the card | ReactNode | - | |
| headStyle | Inline style to apply to the card head | CSSProperties | - | |
| hoverable | Lift up when hovering card | boolean | false | |
| loading | Shows a loading indicator while the contents of the card are being fetched | boolean | false | |
| tabList | List of TabPane's head | Array&lt;{key: string, tab: ReactNode}> | - | |
| tabBarExtraContent | Extra content in tab bar | ReactNode | - | |
| size | Size of card | `default` \| `small` | `default` | |
| tabBarExtraContent | Extra content in tab bar | ReactNode | - | |
| tabList | List of TabPane's head | Array&lt;{key: string, tab: ReactNode}> | - | |
| tabProps | [Tabs](/components/tabs/#Tabs) | - | - | |
| title | Card title | ReactNode | - | |
| type | Card style type, can be set to `inner` or not set | string | - | |
| onTabChange | Callback when tab is switched | (key) => void | - | |
| tabProps | [Tabs](/components/tabs/#Tabs) | - | - | |
### Card.Grid
| Property | Description | Type | Default | Version |
| --------- | ------------------------------- | ------------- | ------- | ------- |
| className | The className of container | string | - | |
| hoverable | Lift up when hovering card grid | boolean | true | |
| style | The style object of container | CSSProperties | - | |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| className | The className of container | string | - | |
| hoverable | Lift up when hovering card grid | boolean | true | |
| style | The style object of container | CSSProperties | - | |
### Card.Meta
| Property | Description | Type | Default | Version |
| ----------- | ----------------------------- | ------------- | ------- | ------- |
| avatar | Avatar or icon | ReactNode | - | |
| className | The className of container | string | - | |
| description | Description content | ReactNode | - | |
| style | The style object of container | CSSProperties | - | |
| title | Title content | ReactNode | - | |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| avatar | Avatar or icon | ReactNode | - | |
| className | The className of container | string | - | |
| description | Description content | ReactNode | - | |
| style | The style object of container | CSSProperties | - | |
| title | Title content | ReactNode | - | |

View File

@ -25,36 +25,36 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/NqXt8DJhky/Card.svg
| --- | --- | --- | --- | --- |
| actions | 卡片操作组,位置在卡片底部 | Array&lt;ReactNode> | - | |
| activeTabKey | 当前激活页签的 key | string | - | |
| headStyle | 自定义标题区域样式 | CSSProperties | - | |
| bodyStyle | 内容区域自定义样式 | CSSProperties | - | |
| bordered | 是否有边框 | boolean | true | |
| cover | 卡片封面 | ReactNode | - | |
| defaultActiveTabKey | 初始化选中页签的 key如果没有设置 activeTabKey | string | `第一个页签` | |
| extra | 卡片右上角的操作区域 | ReactNode | - | |
| headStyle | 自定义标题区域样式 | CSSProperties | - | |
| hoverable | 鼠标移过时可浮起 | boolean | false | |
| loading | 当卡片内容还在加载中时,可以用 loading 展示一个占位 | boolean | false | |
| tabList | 页签标题列表 | Array&lt;{key: string, tab: ReactNode}> | - | |
| tabBarExtraContent | tab bar 上额外的元素 | ReactNode | - | |
| size | card 的尺寸 | `default` \| `small` | `default` | |
| tabBarExtraContent | tab bar 上额外的元素 | ReactNode | - | |
| tabList | 页签标题列表 | Array&lt;{key: string, tab: ReactNode}> | - | |
| tabProps | [Tabs](/components/tabs/#Tabs) | - | - | |
| title | 卡片标题 | ReactNode | - | |
| type | 卡片类型,可设置为 `inner` 或 不设置 | string | - | |
| onTabChange | 页签切换的回调 | (key) => void | - | |
| tabProps | [Tabs](/components/tabs/#Tabs) | - | - | |
### Card.Grid
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --------- | ---------------------- | ------------- | ------ | ---- |
| className | 网格容器类名 | string | - | |
| hoverable | 鼠标移过时可浮起 | boolean | true | |
| style | 定义网格容器类名的样式 | CSSProperties | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| className | 网格容器类名 | string | - | |
| hoverable | 鼠标移过时可浮起 | boolean | true | |
| style | 定义网格容器类名的样式 | CSSProperties | - | |
### Card.Meta
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ----------- | ------------------ | ------------- | ------ | ---- |
| avatar | 头像/图标 | ReactNode | - | |
| className | 容器类名 | string | - | |
| description | 描述内容 | ReactNode | - | |
| style | 定义容器类名的样式 | CSSProperties | - | |
| title | 标题内容 | ReactNode | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| avatar | 头像/图标 | ReactNode | - | |
| className | 容器类名 | string | - | |
| description | 描述内容 | ReactNode | - | |
| style | 定义容器类名的样式 | CSSProperties | - | |
| title | 标题内容 | ReactNode | - | |

View File

@ -57,6 +57,13 @@
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
> .@{ant-prefix}-typography,
> .@{ant-prefix}-typography-edit-content {
left: 0;
margin-top: 0;
margin-bottom: 0;
}
}
.@{ant-prefix}-tabs {

View File

@ -17,13 +17,13 @@ A carousel component. Scales with its container.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| afterChange | Callback function called after the current index changes | function(current) | - | |
| autoplay | Whether to scroll automatically | boolean | false | |
| beforeChange | Callback function called before the current index changes | function(from, to) | - | |
| dotPosition | The position of the dots, which can be one of `top` `bottom` `left` `right` | string | `bottom` | |
| dots | Whether to show the dots at the bottom of the gallery, `object` for `dotsClass` and any others | boolean \| { className?: string } | true | |
| easing | Transition interpolation function name | string | `linear` | |
| effect | Transition effect | `scrollx` \| `fade` | `scrollx` | |
| afterChange | Callback function called after the current index changes | function(current) | - | |
| beforeChange | Callback function called before the current index changes | function(from, to) | - | |
## Methods

View File

@ -18,20 +18,20 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/%24C9tmj978R/Carousel.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| afterChange | 切换面板的回调 | function(current) | - | | |
| autoplay | 是否自动切换 | boolean | false | | |
| beforeChange | 切换面板的回调 | function(from, to) | - | | |
| autoplay | 是否自动切换 | boolean | false | |
| dotPosition | 面板指示点位置,可选 `top` `bottom` `left` `right` | string | `bottom` | |
| dots | 是否显示面板指示点,如果为 `object` 则同时可以指定 `dotsClass` 或者 | boolean \| { className?: string } | true | | |
| easing | 动画效果 | string | `linear` | | |
| effect | 动画效果函数 | `scrollx` \| `fade` | `scrollx` | | |
| dots | 是否显示面板指示点,如果为 `object` 则同时可以指定 `dotsClass` 或者 | boolean \| { className?: string } | true | |
| easing | 动画效果 | string | `linear` | |
| effect | 动画效果函数 | `scrollx` \| `fade` | `scrollx` | |
| afterChange | 切换面板的回调 | function(current) | - | |
| beforeChange | 切换面板的回调 | function(from, to) | - | |
## 方法
| 名称 | 描述 |
| ------------------------------ | ------------------------------------------------- |
| 名称 | 描述 |
| --- | --- |
| goTo(slideNumber, dontAnimate) | 切换到指定面板, dontAnimate = true 时,不使用动画 |
| next() | 切换到下一面板 |
| prev() | 切换到上一面板 |
| next() | 切换到下一面板 |
| prev() | 切换到上一面板 |
更多 API 可参考:<https://react-slick.neostack.com/docs/api>

View File

@ -38,7 +38,6 @@ describe('Cascader.typescript', () => {
},
];
const result = <Cascader options={options} defaultValue={[1, 'hangzhou']} />;
expect(result).toBeTruthy();

View File

@ -62,11 +62,7 @@ function dropdownRender(menus) {
}
ReactDOM.render(
<Cascader
options={options}
dropdownRender={dropdownRender}
placeholder="Please select"
/>,
<Cascader options={options} dropdownRender={dropdownRender} placeholder="Please select" />,
mountNode,
);
```

View File

@ -29,13 +29,14 @@ Cascade selection box.
| defaultValue | Initial selected value | string\[] \| number\[] | \[] | |
| disabled | Whether disabled select | boolean | false | |
| displayRender | The render function of displaying selected options | (label, selectedOptions) => ReactNode | label => label.join(`/`) | |
| expandTrigger | expand current item when click or hover, one of `click` `hover` | string | `click` | |
| dropdownRender | Customize dropdown content | (menus: ReactNode) => ReactNode | - | 4.4.0 |
| expandIcon | Customize the current item expand icon | ReactNode | - | 4.4.0 |
| expandTrigger | expand current item when click or hover, one of `click` `hover` | string | `click` | |
| fieldNames | Custom field name for label and value and children | object | { label: `label`, value: `value`, children: `children` } | |
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. [example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
| loadData | To load option lazily, and it cannot work with `showSearch` | (selectedOptions) => void | - | |
| notFoundContent | Specify content to show when no result matches | string | `Not Found` | |
| options | The data options of cascade | [Option](#Option)[] | - | |
| options | The data options of cascade | [Option](#Option)\[] | - | |
| placeholder | The input placeholder | string | `Please select` | |
| popupClassName | The additional className of popup overlay | string | - | |
| popupPlacement | Use preset popup align config from builtinPlacements`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | |
@ -45,7 +46,6 @@ Cascade selection box.
| style | The additional style | CSSProperties | - | |
| suffixIcon | The custom suffix icon | ReactNode | - | |
| value | The selected value | string\[] \| number\[] | - | |
| dropdownRender | Customize dropdown content | (menus: ReactNode) => ReactNode | - | 4.4.0 |
| onChange | Callback when finishing cascader select | (value, selectedOptions) => void | - | |
| onPopupVisibleChange | Callback when popup shown or hidden | (value) => void | - | |
@ -72,7 +72,7 @@ interface Option {
## Methods
| Name | Description | Version |
| ------- | ------------ | ------- |
| blur() | Remove focus | |
| focus() | Get focus | |
| Name | Description | Version |
| --- | --- | --- |
| blur() | Remove focus | |
| focus() | Get focus | |

View File

@ -642,12 +642,19 @@ class Cascader extends React.Component<CascaderProps, CascaderState> {
);
const getPopupContainer = props.getPopupContainer || getContextPopupContainer;
const rest = omit(props, ['inputIcon', 'expandIcon', 'loadingIcon', 'bordered']);
const rest = omit(props, [
'inputIcon',
'expandIcon',
'loadingIcon',
'bordered',
'className',
]);
const rcCascaderPopupClassName = classNames(popupClassName, {
[`${prefixCls}-menu-${direction}`]: direction === 'rtl',
[`${prefixCls}-menu-empty`]:
options.length === 1 && options[0].value === 'ANT_CASCADER_NOT_FOUND',
});
return (
<RcCascader
{...rest}

View File

@ -30,13 +30,14 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
| defaultValue | 默认的选中项 | string\[] \| number\[] | \[] | |
| disabled | 禁用 | boolean | false | |
| displayRender | 选择后展示的渲染函数 | (label, selectedOptions) => ReactNode | label => label.join(`/`) | |
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | `click` | |
| dropdownRender | 自定义下拉框内容 | (menus: ReactNode) => ReactNode | - | 4.4.0 |
| expandIcon | 自定义次级菜单展开图标 | ReactNode | - | 4.4.0 |
| expandTrigger | 次级菜单的展开方式,可选 'click' 和 'hover' | string | `click` | |
| fieldNames | 自定义 options 中 label name children 的字段 | object | { label: `label`, value: `value`, children: `children` } | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
| loadData | 用于动态加载选项,无法与 `showSearch` 一起使用 | (selectedOptions) => void | - | |
| notFoundContent | 当下拉列表为空时显示的内容 | string | `Not Found` | |
| options | 可选项数据源 | [Option](#Option)[] | - | |
| options | 可选项数据源 | [Option](#Option)\[] | - | |
| placeholder | 输入框占位文本 | string | `请选择` | |
| popupClassName | 自定义浮层类名 | string | - | |
| popupPlacement | 浮层预设位置:`bottomLeft` `bottomRight` `topLeft` `topRight` | string | `bottomLeft` | |
@ -46,7 +47,6 @@ cover: https://gw.alipayobjects.com/zos/alicdn/UdS8y8xyZ/Cascader.svg
| style | 自定义样式 | CSSProperties | - | |
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| value | 指定选中项 | string\[] \| number\[] | - | |
| dropdownRender | 自定义下拉框内容 | (menus: ReactNode) => ReactNode | - | 4.4.0 |
| onChange | 选择完成后的回调 | (value, selectedOptions) => void | - | |
| onPopupVisibleChange | 显示/隐藏浮层的回调 | (value) => void | - | |
@ -73,9 +73,9 @@ interface Option {
## 方法
| 名称 | 描述 | 版本 |
| ------- | -------- | ---- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |
| 名称 | 描述 | 版本 |
| --- | --- | --- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |
> 注意,如果需要获得中国省市区数据,可以参考 [china-division](https://gist.github.com/afc163/7582f35654fd03d5be7009444345ea17)。

View File

@ -2,7 +2,7 @@ import * as React from 'react';
import classNames from 'classnames';
import omit from 'omit.js';
import Checkbox, { CheckboxChangeEvent } from './Checkbox';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
export type CheckboxValueType = string | number | boolean;
@ -27,11 +27,7 @@ export interface CheckboxGroupProps extends AbstractCheckboxGroupProps {
defaultValue?: Array<CheckboxValueType>;
value?: Array<CheckboxValueType>;
onChange?: (checkedValue: Array<CheckboxValueType>) => void;
}
export interface CheckboxGroupState {
value: CheckboxValueType[];
registeredValues: CheckboxValueType[];
children?: React.ReactNode;
}
export interface CheckboxGroupContext {
@ -42,135 +38,119 @@ export interface CheckboxGroupContext {
export const GroupContext = React.createContext<CheckboxGroupContext | null>(null);
class CheckboxGroup extends React.PureComponent<CheckboxGroupProps, CheckboxGroupState> {
static defaultProps = {
options: [],
};
const CheckboxGroup: React.FC<CheckboxGroupProps> = ({
defaultValue,
children,
options = [],
prefixCls: customizePrefixCls,
className,
style,
onChange,
...restProps
}) => {
const { getPrefixCls, direction } = React.useContext(ConfigContext);
static getDerivedStateFromProps(nextProps: CheckboxGroupProps) {
if ('value' in nextProps) {
return {
value: nextProps.value || [],
};
const [value, setValue] = React.useState<CheckboxValueType[]>(
restProps.value || defaultValue || [],
);
const [registeredValues, setRegisteredValues] = React.useState<CheckboxValueType[]>([]);
React.useEffect(() => {
if ('value' in restProps) {
setValue(restProps.value || []);
}
return null;
}
}, [restProps.value]);
constructor(props: CheckboxGroupProps) {
super(props);
this.state = {
value: props.value || props.defaultValue || [],
registeredValues: [],
};
}
getOptions() {
const { options } = this.props;
// https://github.com/Microsoft/TypeScript/issues/7960
return (options as Array<CheckboxOptionType>).map(option => {
const getOptions = () => {
return options.map(option => {
if (typeof option === 'string') {
return {
label: option,
value: option,
} as CheckboxOptionType;
};
}
return option;
});
}
cancelValue = (value: string) => {
this.setState(({ registeredValues }) => ({
registeredValues: registeredValues.filter(val => val !== value),
}));
};
registerValue = (value: string) => {
this.setState(({ registeredValues }) => ({
registeredValues: [...registeredValues, value],
}));
const cancelValue = (val: string) => {
setRegisteredValues(prevValues => prevValues.filter(v => v !== val));
};
toggleOption = (option: CheckboxOptionType) => {
const { registeredValues } = this.state;
const optionIndex = this.state.value.indexOf(option.value);
const value = [...this.state.value];
const registerValue = (val: string) => {
setRegisteredValues(prevValues => [...prevValues, val]);
};
const toggleOption = (option: CheckboxOptionType) => {
const optionIndex = value.indexOf(option.value);
const newValue = [...value];
if (optionIndex === -1) {
value.push(option.value);
newValue.push(option.value);
} else {
value.splice(optionIndex, 1);
newValue.splice(optionIndex, 1);
}
if (!('value' in this.props)) {
this.setState({ value });
if (!('value' in restProps)) {
setValue(newValue);
}
const { onChange } = this.props;
if (onChange) {
const options = this.getOptions();
const opts = getOptions();
onChange(
value
newValue
.filter(val => registeredValues.indexOf(val) !== -1)
.sort((a, b) => {
const indexA = options.findIndex(opt => opt.value === a);
const indexB = options.findIndex(opt => opt.value === b);
const indexA = opts.findIndex(opt => opt.value === a);
const indexB = opts.findIndex(opt => opt.value === b);
return indexA - indexB;
}),
);
}
};
renderGroup = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const { props, state } = this;
const { prefixCls: customizePrefixCls, className, style, options, ...restProps } = props;
const prefixCls = getPrefixCls('checkbox', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`;
const prefixCls = getPrefixCls('checkbox', customizePrefixCls);
const groupPrefixCls = `${prefixCls}-group`;
const domProps = omit(restProps, ['children', 'defaultValue', 'value', 'onChange', 'disabled']);
const domProps = omit(restProps, ['value', 'disabled']);
let { children } = props;
if (options && options.length > 0) {
children = this.getOptions().map(option => (
<Checkbox
prefixCls={prefixCls}
key={option.value.toString()}
disabled={'disabled' in option ? option.disabled : props.disabled}
value={option.value}
checked={state.value.indexOf(option.value) !== -1}
onChange={option.onChange}
className={`${groupPrefixCls}-item`}
style={option.style}
>
{option.label}
</Checkbox>
));
}
if (options && options.length > 0) {
children = getOptions().map(option => (
<Checkbox
prefixCls={prefixCls}
key={option.value.toString()}
disabled={'disabled' in option ? option.disabled : restProps.disabled}
value={option.value}
checked={value.indexOf(option.value) !== -1}
onChange={option.onChange}
className={`${groupPrefixCls}-item`}
style={option.style}
>
{option.label}
</Checkbox>
));
}
const context = {
toggleOption: this.toggleOption,
value: this.state.value,
disabled: this.props.disabled,
name: this.props.name,
const context = {
toggleOption,
value,
disabled: restProps.disabled,
name: restProps.name,
// https://github.com/ant-design/ant-design/issues/16376
registerValue: this.registerValue,
cancelValue: this.cancelValue,
};
const classString = classNames(
groupPrefixCls,
{
[`${groupPrefixCls}-rtl`]: direction === 'rtl',
},
className,
);
return (
<div className={classString} style={style} {...domProps}>
<GroupContext.Provider value={context}>{children}</GroupContext.Provider>
</div>
);
// https://github.com/ant-design/ant-design/issues/16376
registerValue,
cancelValue,
};
render() {
return <ConfigConsumer>{this.renderGroup}</ConfigConsumer>;
}
}
const classString = classNames(
groupPrefixCls,
{
[`${groupPrefixCls}-rtl`]: direction === 'rtl',
},
className,
);
return (
<div className={classString} style={style} {...domProps}>
<GroupContext.Provider value={context}>{children}</GroupContext.Provider>
</div>
);
};
export default CheckboxGroup;
export default React.memo(CheckboxGroup);

View File

@ -14,25 +14,13 @@ describe('CheckboxGroup', () => {
const wrapper = mount(
<Checkbox.Group options={['Apple', 'Pear', 'Orange']} onChange={onChange} />,
);
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(onChange).toHaveBeenCalledWith(['Apple']);
wrapper
.find('.ant-checkbox-input')
.at(1)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(1).simulate('change');
expect(onChange).toHaveBeenCalledWith(['Apple', 'Pear']);
wrapper
.find('.ant-checkbox-input')
.at(2)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(2).simulate('change');
expect(onChange).toHaveBeenCalledWith(['Apple', 'Pear', 'Orange']);
wrapper
.find('.ant-checkbox-input')
.at(1)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(1).simulate('change');
expect(onChange).toHaveBeenCalledWith(['Apple', 'Orange']);
});
@ -47,15 +35,9 @@ describe('CheckboxGroup', () => {
const groupWrapper = mount(
<Checkbox.Group options={options} onChange={onChangeGroup} disabled />,
);
groupWrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
groupWrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(onChangeGroup).not.toHaveBeenCalled();
groupWrapper
.find('.ant-checkbox-input')
.at(1)
.simulate('change');
groupWrapper.find('.ant-checkbox-input').at(1).simulate('change');
expect(onChangeGroup).not.toHaveBeenCalled();
});
@ -68,15 +50,9 @@ describe('CheckboxGroup', () => {
];
const groupWrapper = mount(<Checkbox.Group options={options} onChange={onChangeGroup} />);
groupWrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
groupWrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(onChangeGroup).toHaveBeenCalledWith(['Apple']);
groupWrapper
.find('.ant-checkbox-input')
.at(1)
.simulate('change');
groupWrapper.find('.ant-checkbox-input').at(1).simulate('change');
expect(onChangeGroup).toHaveBeenCalledWith(['Apple']);
});
@ -105,10 +81,10 @@ describe('CheckboxGroup', () => {
];
const wrapper = mount(<Checkbox.Group options={options} />);
expect(wrapper.instance().state.value).toEqual([]);
expect(wrapper.find('.ant-checkbox-checked').length).toBe(0);
wrapper.setProps({ value: ['Apple'] });
expect(wrapper.instance().state.value).toEqual(['Apple']);
wrapper.update();
expect(wrapper.find('.ant-checkbox-checked').length).toBe(1);
});
// https://github.com/ant-design/ant-design/issues/12642
@ -119,10 +95,7 @@ describe('CheckboxGroup', () => {
<Checkbox value="my" onChange={onChange} />
</Checkbox.Group>,
);
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(onChange).toHaveBeenCalled();
expect(onChange.mock.calls[0][0].target.value).toEqual('my');
});
@ -141,10 +114,7 @@ describe('CheckboxGroup', () => {
children: [<Checkbox key={2} value={2} />],
});
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(onChange).toHaveBeenCalledWith([2]);
});
@ -160,12 +130,7 @@ describe('CheckboxGroup', () => {
wrapper.setProps({
children: [<Checkbox key={1} value={2} />],
});
expect(
wrapper
.find('.ant-checkbox-input')
.at(0)
.prop('checked'),
).toBe(false);
expect(wrapper.find('.ant-checkbox-input').at(0).prop('checked')).toBe(false);
});
// https://github.com/ant-design/ant-design/issues/17297
@ -180,25 +145,13 @@ describe('CheckboxGroup', () => {
</Checkbox.Group>,
);
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(onChange).toHaveBeenCalledWith([1]);
wrapper
.find('.ant-checkbox-input')
.at(1)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(1).simulate('change');
expect(onChange).toHaveBeenCalledWith([1, 2]);
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(onChange).toHaveBeenCalledWith([2]);
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(onChange).toHaveBeenCalledWith([1, 2]);
});
@ -215,30 +168,10 @@ describe('CheckboxGroup', () => {
</Collapse>
</Checkbox.Group>,
);
wrapper
.find('.ant-collapse-item')
.at(0)
.find('.ant-collapse-header')
.simulate('click');
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
expect(
wrapper
.find(Checkbox.Group)
.at(0)
.state('value'),
).toEqual(['1']);
wrapper
.find('.ant-checkbox-input')
.at(0)
.simulate('change');
expect(
wrapper
.find(Checkbox.Group)
.at(0)
.state('value'),
).toEqual([]);
wrapper.find('.ant-collapse-item').at(0).find('.ant-collapse-header').simulate('click');
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(wrapper.find('.ant-checkbox-checked').length).toBe(1);
wrapper.find('.ant-checkbox-input').at(0).simulate('change');
expect(wrapper.find('.ant-checkbox-checked').length).toBe(0);
});
});

View File

@ -0,0 +1,15 @@
import * as React from 'react';
import Checkbox from '..';
import Input from '../../input';
describe('Checkbox.typescript', () => {
it('Checkbox.Group', () => {
const group = (
<Checkbox.Group>
<Input />
</Checkbox.Group>
);
expect(group).toBeTruthy();
});
});

View File

@ -42,7 +42,7 @@ Checkbox component.
#### Checkbox
| Name | Description | Version |
| ------- | ------------ | ------- |
| blur() | Remove focus | |
| focus() | Get focus | |
| Name | Description | Version |
| --- | --- | --- |
| blur() | Remove focus | |
| focus() | Get focus | |

View File

@ -19,14 +19,14 @@ cover: https://gw.alipayobjects.com/zos/alicdn/8nbVbHEm_/CheckBox.svg
#### Checkbox
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| -------------- | --------------------------------------- | ----------------- | ------ | ---- |
| autoFocus | 自动获取焦点 | boolean | false | |
| checked | 指定当前是否选中 | boolean | false | |
| defaultChecked | 初始是否选中 | boolean | false | |
| disabled | 失效状态 | boolean | false | |
| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false | |
| onChange | 变化时回调函数 | function(e:Event) | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| autoFocus | 自动获取焦点 | boolean | false | |
| checked | 指定当前是否选中 | boolean | false | |
| defaultChecked | 初始是否选中 | boolean | false | |
| disabled | 失效状态 | boolean | false | |
| indeterminate | 设置 indeterminate 状态,只负责样式控制 | boolean | false | |
| onChange | 变化时回调函数 | function(e:Event) | - | |
#### Checkbox Group
@ -53,7 +53,7 @@ interface Option {
#### Checkbox
| 名称 | 描述 | 版本 |
| ------- | -------- | ---- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |
| 名称 | 描述 | 版本 |
| --- | --- | --- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |

View File

@ -19,23 +19,23 @@ A content area which can be collapsed and expanded.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| activeKey | Key of the active panel | string\[] \| string <br/> number\[] \| number | No default value. In `accordion` mode, it's the key of the first panel | |
| defaultActiveKey | Key of the initial active panel | string\[] \| string <br/> number\[] \| number | - | |
| bordered | Toggles rendering of the border around the collapse block | boolean | true | |
| accordion | If true, Collapse renders as Accordion | boolean | false | |
| onChange | Callback function executed when active panel is changed | function | - | |
| activeKey | Key of the active panel | string\[] \| string <br/> number\[] \| number | No default value. In `accordion` mode, it's the key of the first panel | |
| bordered | Toggles rendering of the border around the collapse block | boolean | true | |
| defaultActiveKey | Key of the initial active panel | string\[] \| string <br/> number\[] \| number | - | |
| destroyInactivePanel | Destroy Inactive Panel | boolean | false | |
| expandIcon | Allow to customize collapse icon | (panelProps) => ReactNode | - | |
| expandIconPosition | Set expand icon position | `left` \| `right` | - | |
| destroyInactivePanel | Destroy Inactive Panel | boolean | false | |
| ghost | Make the collapse borderless and its background transparent | boolean | false | 4.4.0 |
| onChange | Callback function executed when active panel is changed | function | - | |
### Collapse.Panel
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| disabled | If true, panel cannot be opened or closed | boolean | false | |
| extra | The extra element in the corner | ReactNode | - | |
| forceRender | Forced render of content on panel, instead of lazy rending after clicking on header | boolean | false | |
| header | Title of the panel | ReactNode | - | |
| key | Unique key identifying the panel from among its siblings | string \| number | - | |
| showArrow | If false, panel will not show arrow icon | boolean | true | |
| extra | The extra element in the corner | ReactNode | - | |

View File

@ -20,23 +20,23 @@ cover: https://gw.alipayobjects.com/zos/alicdn/IxH16B9RD/Collapse.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| activeKey | 当前激活 tab 面板的 key | string\[] \| string <br/> number\[] \| number | 默认无accordion 模式下默认第一个元素 | |
| defaultActiveKey | 初始化选中面板的 key | string\[] \| string<br/> number\[] \| number | - | |
| bordered | 带边框风格的折叠面板 | boolean | true | |
| accordion | 手风琴模式 | boolean | false | |
| onChange | 切换面板的回调 | function | - | |
| activeKey | 当前激活 tab 面板的 key | string\[] \| string <br/> number\[] \| number | 默认无accordion 模式下默认第一个元素 | |
| bordered | 带边框风格的折叠面板 | boolean | true | |
| defaultActiveKey | 初始化选中面板的 key | string\[] \| string<br/> number\[] \| number | - | |
| destroyInactivePanel | 销毁折叠隐藏的面板 | boolean | false | |
| expandIcon | 自定义切换图标 | (panelProps) => ReactNode | - | |
| expandIconPosition | 设置图标位置 | `left` \| `right` | - | |
| destroyInactivePanel | 销毁折叠隐藏的面板 | boolean | false | |
| ghost | 使折叠面板透明且无边框 | boolean | false | 4.4.0 |
| onChange | 切换面板的回调 | function | - | |
### Collapse.Panel
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ----------- | ------------------------------------------ | ---------------- | ------ | ---- |
| disabled | 禁用后的面板展开与否将无法通过用户交互改变 | boolean | false | |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false | |
| header | 面板头内容 | ReactNode | - | |
| key | 对应 activeKey | string \| number | - | |
| showArrow | 是否展示当前面板上的箭头 | boolean | true | |
| extra | 自定义渲染每个面板右上角的内容 | ReactNode | - | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| disabled | 禁用后的面板展开与否将无法通过用户交互改变 | boolean | false | |
| extra | 自定义渲染每个面板右上角的内容 | ReactNode | - | |
| forceRender | 被隐藏时是否渲染 DOM 结构 | boolean | false | |
| header | 面板头内容 | ReactNode | - | |
| key | 对应 activeKey | string \| number | - | |
| showArrow | 是否展示当前面板上的箭头 | boolean | true | |

View File

@ -156,14 +156,10 @@ exports[`renders ./components/comment/demo/editor.md correctly 1`] = `
<div
class="ant-form-item-control-input-content"
>
<div
class="ant-input-textarea"
>
<textarea
class="ant-input"
rows="4"
/>
</div>
<textarea
class="ant-input"
rows="4"
/>
</div>
</div>
</div>

View File

@ -30,16 +30,8 @@ const data = [
</p>
),
datetime: (
<Tooltip
title={moment()
.subtract(1, 'days')
.format('YYYY-MM-DD HH:mm:ss')}
>
<span>
{moment()
.subtract(1, 'days')
.fromNow()}
</span>
<Tooltip title={moment().subtract(1, 'days').format('YYYY-MM-DD HH:mm:ss')}>
<span>{moment().subtract(1, 'days').fromNow()}</span>
</Tooltip>
),
},
@ -55,16 +47,8 @@ const data = [
</p>
),
datetime: (
<Tooltip
title={moment()
.subtract(2, 'days')
.format('YYYY-MM-DD HH:mm:ss')}
>
<span>
{moment()
.subtract(2, 'days')
.fromNow()}
</span>
<Tooltip title={moment().subtract(2, 'days').format('YYYY-MM-DD HH:mm:ss')}>
<span>{moment().subtract(2, 'days').fromNow()}</span>
</Tooltip>
),
},

View File

@ -13138,6 +13138,7 @@ exports[`ConfigProvider components Drawer configProvider 1`] = `
aria-label="Close"
class="config-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -13199,6 +13200,7 @@ exports[`ConfigProvider components Drawer configProvider componentSize large 1`]
aria-label="Close"
class="config-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -13260,6 +13262,7 @@ exports[`ConfigProvider components Drawer configProvider componentSize middle 1`
aria-label="Close"
class="config-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -13321,6 +13324,7 @@ exports[`ConfigProvider components Drawer configProvider virtual and dropdownMat
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -13382,6 +13386,7 @@ exports[`ConfigProvider components Drawer normal 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -13443,6 +13448,7 @@ exports[`ConfigProvider components Drawer prefixCls 1`] = `
aria-label="Close"
class="prefix-Drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -14539,13 +14545,9 @@ exports[`ConfigProvider components Input configProvider 1`] = `
</span>
</span>
</span>
<div
class="config-input-textarea"
>
<textarea
class="config-input"
/>
</div>
<textarea
class="config-input"
/>
</div>
`;
@ -14640,13 +14642,9 @@ exports[`ConfigProvider components Input configProvider componentSize large 1`]
</span>
</span>
</span>
<div
class="config-input-textarea"
>
<textarea
class="config-input config-input-lg"
/>
</div>
<textarea
class="config-input config-input-lg"
/>
</div>
`;
@ -14741,13 +14739,9 @@ exports[`ConfigProvider components Input configProvider componentSize middle 1`]
</span>
</span>
</span>
<div
class="config-input-textarea"
>
<textarea
class="config-input"
/>
</div>
<textarea
class="config-input"
/>
</div>
`;
@ -14842,13 +14836,9 @@ exports[`ConfigProvider components Input configProvider virtual and dropdownMatc
</span>
</span>
</span>
<div
class="ant-input-textarea"
>
<textarea
class="ant-input"
/>
</div>
<textarea
class="ant-input"
/>
</div>
`;
@ -14943,13 +14933,9 @@ exports[`ConfigProvider components Input normal 1`] = `
</span>
</span>
</span>
<div
class="ant-input-textarea"
>
<textarea
class="ant-input"
/>
</div>
<textarea
class="ant-input"
/>
</div>
`;
@ -15044,13 +15030,9 @@ exports[`ConfigProvider components Input prefixCls 1`] = `
</span>
</span>
</span>
<div
class="prefix-Input-textarea"
>
<textarea
class="prefix-Input"
/>
</div>
<textarea
class="prefix-Input"
/>
</div>
`;

View File

@ -41,18 +41,18 @@ Some components use dynamic style to support wave effect. You can config `csp` p
| autoInsertSpaceInButton | Set false to remove space between 2 chinese characters on Button | boolean | true | |
| componentSize | Config antd component size | `small` \| `middle` \| `large` | - | |
| csp | Set [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) config | { nonce: string } | - | |
| direction | Set direction of layout. See [demo](#components-config-provider-demo-direction) | `ltr` \| `rtl` | `ltr` | |
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | - | 4.3.0 |
| form | Set Form common props | { validateMessages?: [ValidateMessages](/components/form/#validateMessages) } | - | |
| input | Set Input common props | { autoComplete?: string } | - | 4.2.0 |
| renderEmpty | Set empty content of components. Ref [Empty](/components/empty/) | function(componentName: string): ReactNode | - | |
| getPopupContainer | To set the container of the popup element. The default is to create a `div` element in `body` | function(triggerNode) | () => document.body | |
| getTargetContainer | Config Affix, Anchor scroll target container | () => HTMLElement | () => window | 4.2.0 |
| locale | Language package setting, you can find the packages in [antd/es/locale](http://unpkg.com/antd/es/locale/) | object | - |
| prefixCls | Set prefix className (cooperated with [@ant-prefix](https://github.com/ant-design/ant-design/blob/2c6c789e3a9356f96c47aea0083f5a15538315cf/components/style/themes/default.less#L7)) | string | `ant` | |
| input | Set Input common props | { autoComplete?: string } | - | 4.2.0 |
| locale | Language package setting, you can find the packages in [antd/es/locale](http://unpkg.com/antd/es/locale/) | object | - | |
| pageHeader | Unify the ghost of PageHeader, ref [PageHeader](/components/page-header) | { ghost: boolean } | true | |
| direction | Set direction of layout. See [demo](#components-config-provider-demo-direction) | `ltr` \| `rtl` | `ltr` | |
| prefixCls | Set prefix className (cooperated with [@ant-prefix](https://github.com/ant-design/ant-design/blob/2c6c789e3a9356f96c47aea0083f5a15538315cf/components/style/themes/default.less#L7)) | string | `ant` | |
| renderEmpty | Set empty content of components. Ref [Empty](/components/empty/) | function(componentName: string): ReactNode | - | |
| space | Set Space `size`, ref [Space](/components/space) | { size: `small` \| `middle` \| `large` \| `number` } | - | 4.1.0 |
| virtual | Disable virtual scroll when set to `false` | boolean | - | 4.3.0 |
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. Will ignore when value less than select width. `false` will disable virtual scroll | boolean \| number | - | 4.3.0 |
## FAQ
@ -71,7 +71,7 @@ moment.locale('zh-cn');
#### Modal throw error when setting `getPopupContainer`?
Related issue: https://github.com/ant-design/ant-design/issues/19974
Related issue: <https://github.com/ant-design/ant-design/issues/19974>
When you config `getPopupContainer` to parentNode globally, Modal will throw error of `triggerNode is undefined` because it did not have a triggerNode. You can try the [fix](https://github.com/afc163/feedback-antd/commit/3e4d1ad1bc1a38460dc3bf3c56517f737fe7d44a) below.

View File

@ -42,18 +42,18 @@ export default () => (
| autoInsertSpaceInButton | 设置为 `false` 时,移除按钮中 2 个汉字之间的空格 | boolean | true | |
| componentSize | 设置 antd 组件大小 | `small` \| `middle` \| `large` | - | |
| csp | 设置 [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP) 配置 | { nonce: string } | - | |
| direction | 设置文本展示方向。 [示例](#components-config-provider-demo-direction) | `ltr` \| `rtl` | `ltr` | |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`,当值小于选择框宽度时会被忽略。`false` 时会关闭虚拟滚动 | boolean \| number | - | 4.3.0 |
| form | 设置 Form 组件的通用属性 | { validateMessages?: [ValidateMessages](/components/form/#validateMessages) } | - | |
| input | 设置 Input 组件的通用属性 | { autoComplete?: string } | - | 4.2.0 |
| renderEmpty | 自定义组件空状态。参考 [空状态](/components/empty/) | function(componentName: string): ReactNode | - | |
| getPopupContainer | 弹出框Select, Tooltip, Menu 等等)渲染父节点,默认渲染到 body 上。 | function(triggerNode) | () => document.body | |
| getTargetContainer | 配置 Affix、Anchor 滚动监听容器。 | () => HTMLElement | () => window | 4.2.0 |
| input | 设置 Input 组件的通用属性 | { autoComplete?: string } | - | 4.2.0 |
| locale | 语言包配置,语言包可到 [antd/es/locale](http://unpkg.com/antd/es/locale/) 目录下寻找 | object | - | |
| prefixCls | 设置统一样式前缀。注意:需要配合 `less` 变量 [@ant-prefix](https://github.com/ant-design/ant-design/blob/2c6c789e3a9356f96c47aea0083f5a15538315cf/components/style/themes/default.less#L7) 使用 | string | `ant` | |
| pageHeader | 统一设置 PageHeader 的 ghost参考 [PageHeader](/components/page-header) | { ghost: boolean } | true | |
| direction | 设置文本展示方向。 [示例](#components-config-provider-demo-direction) | `ltr` \| `rtl` | `ltr` | |
| prefixCls | 设置统一样式前缀。注意:需要配合 `less` 变量 [@ant-prefix](https://github.com/ant-design/ant-design/blob/2c6c789e3a9356f96c47aea0083f5a15538315cf/components/style/themes/default.less#L7) 使用 | string | `ant` | |
| renderEmpty | 自定义组件空状态。参考 [空状态](/components/empty/) | function(componentName: string): ReactNode | - | |
| space | 设置 Space 的 `size`,参考 [Space](/components/space) | { size: `small` \| `middle` \| `large` \| `number` } | - | 4.1.0 |
| virtual | 设置 `false` 时关闭虚拟滚动 | boolean | - | 4.3.0 |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`,当值小于选择框宽度时会被忽略。`false` 时会关闭虚拟滚动 | boolean \| number | - | 4.3.0 |
## FAQ
@ -72,7 +72,7 @@ moment.locale('zh-cn');
#### 配置 `getPopupContainer` 导致 Modal 报错?
相关 issuehttps://github.com/ant-design/ant-design/issues/19974
相关 issue<https://github.com/ant-design/ant-design/issues/19974>
当如下全局设置 `getPopupContainer` 为触发节点的 parentNode 时,由于 Modal 的用法不存在 `triggerNode`,这样会导致 `triggerNode is undefined` 的报错,需要增加一个[判断条件](https://github.com/afc163/feedback-antd/commit/3e4d1ad1bc1a38460dc3bf3c56517f737fe7d44a)。

View File

@ -138,6 +138,13 @@ describe('DatePicker', () => {
.length,
).toBe(60);
});
it('showTime should work correctly when format is custom function', () => {
const wrapper = mount(
<DatePicker defaultValue={moment()} showTime format={val => val.format('YYYY-MM-DD')} open />,
);
const input = wrapper.find('input').simulate('mousedown');
expect(input.simulate.bind(input, 'focus')).not.toThrowError();
});
it('12 hours', () => {
const wrapper = mount(

View File

@ -43,27 +43,13 @@ describe('MonthPicker and WeekPicker', () => {
const birthday = moment('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');
const wrapper = mount(<MonthPicker open />);
wrapper.setProps({ value: birthday });
expect(
render(
wrapper
.find('Trigger')
.instance()
.getComponent(),
),
).toMatchSnapshot();
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
});
it('render WeekPicker', () => {
const birthday = moment('2000-01-01', 'YYYY-MM-DD').locale('zh-cn');
const wrapper = mount(<WeekPicker open />);
wrapper.setProps({ value: birthday });
expect(
render(
wrapper
.find('Trigger')
.instance()
.getComponent(),
),
).toMatchSnapshot();
expect(render(wrapper.find('Trigger').instance().getComponent())).toMatchSnapshot();
});
});

View File

@ -18,10 +18,7 @@ export function openPanel(wrapper) {
}
export function clearInput(wrapper) {
wrapper
.find('.ant-calendar-picker-clear')
.hostNodes()
.simulate('click');
wrapper.find('.ant-calendar-picker-clear').hostNodes().simulate('click');
}
export function nextYear(wrapper) {
@ -33,17 +30,10 @@ export function nextMonth(wrapper) {
}
export function openPicker(wrapper, index = 0) {
wrapper
.find('input')
.at(index)
.simulate('mousedown')
.simulate('focus');
wrapper.find('input').at(index).simulate('mousedown').simulate('focus');
}
export function closePicker(wrapper, index = 0) {
wrapper
.find('input')
.at(index)
.simulate('blur');
wrapper.find('input').at(index).simulate('blur');
}
export function selectCell(wrapper, text, index = 0) {

View File

@ -34,7 +34,9 @@ const App = () => {
<RangePicker
disabledDate={disabledDate}
onCalendarChange={value => {
setDates(value);
const [start, end] = value;
const [oldStart, oldEnd] = dates;
setDates([start || oldStart, end || oldEnd]);
}}
/>
);

View File

@ -56,6 +56,11 @@ export function getTimeProps<DateType>(
return showTimeObj;
}
if (typeof firstFormat === 'function') {
// format of showTime should use default when format is custom format function
delete showTimeObj.format;
}
return {
showTime: showTimeObj,
};

View File

@ -54,12 +54,14 @@ The following APIs are shared by DatePicker, RangePicker.
| --- | --- | --- | --- | --- |
| allowClear | Whether to show clear button | boolean | true | |
| autoFocus | If get focus when component mounted | boolean | false | |
| bordered | Whether has border style | boolean | true | |
| className | The picker className | string | - | |
| dateRender | Custom rendering function for date cells | function(currentDate: moment, today: moment) => React.ReactNode | - | |
| disabled | Determine whether the DatePicker is disabled | boolean | false | |
| disabledDate | Specify the date that cannot be selected | (currentDate: moment) => boolean | - | |
| dropdownClassName | To customize the className of the popup calendar | string | - | |
| getPopupContainer | To set the container of the floating layer, while the default is to create a `div` element in `body` | function(trigger) | - | |
| inputReadOnly | Set the `readonly` attribute of the input tag (avoids virtual keyboard on touch devices) | boolean | false | |
| locale | Localization configuration | object | [default](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | |
| mode | The picker panel mode [Cannot select year or month anymore?](/docs/react/faq#When-set-mode-to-DatePicker/RangePicker,-cannot-select-year-or-month-anymore?) ) | `time` \| `date` \| `month` \| `year` \| `decade` | - | |
| open | The open state of picker | boolean | - | |
@ -68,29 +70,28 @@ The following APIs are shared by DatePicker, RangePicker.
| placeholder | The placeholder of date input | string \| \[string,string] | - | |
| popupStyle | To customize the style of the popup calendar | CSSProperties | {} | |
| size | The determine the size of the input box, the height of `large` and `small`, are 40px and 24px respectively, while default size is 32px | `large` \| `middle` \| `small` | - | |
| bordered | Whether has border style | boolean | true | |
| suffixIcon | The custom suffix icon | ReactNode | - | |
| style | To customize the style of the input box | CSSProperties | {} | |
| suffixIcon | The custom suffix icon | ReactNode | - | |
| onOpenChange | Callback function, can be executed whether the popup calendar is popped up or closed | function(open) | - | |
| onPanelChange | Callback when picker panel mode is changed | function(value, mode) | - | |
| inputReadOnly | Set the `readonly` attribute of the input tag (avoids virtual keyboard on touch devices) | boolean | false | |
### Common Methods
| Name | Description | Version |
| ------- | ------------ | ------- |
| blur() | Remove focus | |
| focus() | Get focus | |
| Name | Description | Version |
| --- | --- | --- |
| blur() | Remove focus | |
| focus() | Get focus | |
### DatePicker
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| defaultValue | To set default date, if start time or end time is null or undefined, the date range will be an open interval | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | To set default picker date | [moment](http://momentjs.com/) | - | |
| defaultValue | To set default date, if start time or end time is null or undefined, the date range will be an open interval | [moment](http://momentjs.com/) | - | |
| disabledTime | To specify the time that cannot be selected | function(date) | - | |
| format | To set the date format, refer to [moment.js](http://momentjs.com/). When an array is provided, all values are used for parsing and first value is used for formatting, support [Custom Format](#components-date-picker-demo-format) | string \| (value: moment) => string \| (string \| (value: moment) => string)[] | `YYYY-MM-DD` | |
| format | To set the date format, refer to [moment.js](http://momentjs.com/). When an array is provided, all values are used for parsing and first value is used for formatting, support [Custom Format](#components-date-picker-demo-format) | string \| (value: moment) => string \| (string \| (value: moment) => string)\[] | `YYYY-MM-DD` | |
| renderExtraFooter | Render extra footer in panel | (mode) => React.ReactNode | - | |
| showNow | Whether to show 'Now' button on panel when `showTime` is set | boolean | - | 4.4.0 |
| showTime | To provide an additional time selection | object \| boolean | [TimePicker Options](/components/time-picker/#API) | |
| showTime.defaultValue | To set default time of selected date, [demo](#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/) | moment() | |
| showToday | Whether to show `Today` button | boolean | true | |
@ -98,14 +99,13 @@ The following APIs are shared by DatePicker, RangePicker.
| onChange | Callback function, can be executed when the selected time is changing | function(date: moment, dateString: string) | - | |
| onOk | Callback when click ok button | function() | - | |
| onPanelChange | Callback function for panel changing | function(value, mode) | - | |
| showNow | Whether to show 'Now' button on panel when `showTime` is set | boolean | - | 4.4.0 |
### DatePicker\[picker=year]
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| defaultValue | To set default date | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | To set default picker date | [moment](http://momentjs.com/) | - | |
| defaultValue | To set default date | [moment](http://momentjs.com/) | - | |
| format | To set the date format, refer to [moment.js](http://momentjs.com/) | string | `YYYY` | |
| renderExtraFooter | Render extra footer in panel | () => React.ReactNode | - | |
| value | To set date | [moment](http://momentjs.com/) | - | |
@ -117,8 +117,8 @@ Added in `4.1.0`.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| defaultValue | To set default date | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | To set default picker date | [moment](http://momentjs.com/) | - | |
| defaultValue | To set default date | [moment](http://momentjs.com/) | - | |
| format | To set the date format, refer to [moment.js](http://momentjs.com/) | string | `YYYY-\QQ` | |
| renderExtraFooter | Render extra footer in panel | () => React.ReactNode | - | |
| value | To set date | [moment](http://momentjs.com/) | - | |
@ -128,8 +128,8 @@ Added in `4.1.0`.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| defaultValue | To set default date | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | To set default picker date | [moment](http://momentjs.com/) | - | |
| defaultValue | To set default date | [moment](http://momentjs.com/) | - | |
| format | To set the date format, refer to [moment.js](http://momentjs.com/) | string | `YYYY-MM` | |
| monthCellRender | Custom month cell content render method | function(date, locale): ReactNode | - | |
| renderExtraFooter | Render extra footer in panel | () => React.ReactNode | - | |
@ -140,12 +140,12 @@ Added in `4.1.0`.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| defaultValue | To set default date | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | To set default picker date | [moment](http://momentjs.com/) | - | |
| defaultValue | To set default date | [moment](http://momentjs.com/) | - | |
| format | To set the date format, refer to [moment.js](http://momentjs.com/) | string | `YYYY-wo` | |
| renderExtraFooter | Render extra footer in panel | (mode) => React.ReactNode | - | |
| value | To set date | [moment](http://momentjs.com/) | - | |
| onChange | Callback function, can be executed when the selected time is changing | function(date: moment, dateString: string) | - | |
| renderExtraFooter | Render extra footer in panel | (mode) => React.ReactNode | - | |
### RangePicker
@ -153,11 +153,11 @@ Added in `4.1.0`.
| --- | --- | --- | --- | --- |
| allowEmpty | Allow start or end input leave empty | \[boolean, boolean] | \[false, false] | |
| dateRender | Customize date cell. `info` argument is added in 4.3.0 | function(currentDate: moment, today: moment, info: { range: `start` \| `end` }) => React.ReactNode | - | |
| defaultPickerValue | To set default picker date | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - | |
| defaultValue | To set default date | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)] | - | |
| defaultPickerValue | To set default picker date | \[[moment](http://momentjs.com/), [moment](http://momentjs.com/)\] | - | |
| disabled | If disable start or end | \[boolean, boolean] | - | |
| disabledTime | To specify the time that cannot be selected | function(date: moment, partial: `start` \| `end`) | - | |
| format | To set the date format, refer to [moment.js](http://momentjs.com/). When an array is provided, all values are used for parsing and first value is used for formatting | string \| string[] | `YYYY-MM-DD HH:mm:ss` | |
| format | To set the date format, refer to [moment.js](http://momentjs.com/). When an array is provided, all values are used for parsing and first value is used for formatting | string \| string\[] | `YYYY-MM-DD HH:mm:ss` | |
| ranges | The preseted ranges for quick selection | { \[range: string]: [moment](http://momentjs.com/)\[] } \| { \[range: string]: () => [moment](http://momentjs.com/)\[] } | - | |
| renderExtraFooter | Render extra footer in panel | () => React.ReactNode | - | |
| separator | Set separator between inputs | string | `~` | |
@ -183,7 +183,11 @@ DatePicker default set `locale` as `en` in v4. You can config DatePicker `locale
### How to modify start day of week?
Please use correct [language](/docs/react/i18n) ([#5605](https://github.com/ant-design/ant-design/issues/5605)), or update moment `locale` config: https://codesandbox.io/s/moment-day-of-week-6dby5
Please use correct [language](/docs/react/i18n) ([#5605](https://github.com/ant-design/ant-design/issues/5605)), or update moment `locale` config: <https://codesandbox.io/s/moment-day-of-week-6dby5>
### Why origin panel don't switch when using `panelRender`?
When you change the layout of nodes by `panelRender`, React will unmount and re-mount it which reset the component state. You should keep the layout stable. Please ref [#27263](https://github.com/ant-design/ant-design/issues/27263) for more info.
```js
moment.locale('en', {

View File

@ -55,12 +55,14 @@ import locale from 'antd/es/locale/zh_CN';
| --- | --- | --- | --- | --- |
| allowClear | 是否显示清除按钮 | boolean | true | |
| autoFocus | 自动获取焦点 | boolean | false | |
| bordered | 是否有边框 | boolean | true | |
| className | 选择器 className | string | - | |
| dateRender | 自定义日期单元格的内容 | function(currentDate: moment, today: moment) => React.ReactNode | - | |
| disabled | 禁用 | boolean | false | |
| disabledDate | 不可选择的日期 | (currentDate: moment) => boolean | - | |
| dropdownClassName | 额外的弹出日历 className | string | - | |
| getPopupContainer | 定义浮层的容器,默认为 body 上新建 div | function(trigger) | - | |
| inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false | |
| locale | 国际化配置 | object | [默认配置](https://github.com/ant-design/ant-design/blob/master/components/date-picker/locale/example.json) | |
| mode | 日期面板的状态([设置后无法选择年份/月份?](/docs/react/faq#当我指定了-DatePicker/RangePicker-的-mode-属性后,点击后无法选择年份/月份?) | `time` \| `date` \| `month` \| `year` \| `decade` | - | |
| open | 控制弹层是否展开 | boolean | - | |
@ -69,29 +71,28 @@ import locale from 'antd/es/locale/zh_CN';
| placeholder | 输入框提示文字 | string \| \[string, string] | - | |
| popupStyle | 额外的弹出日历样式 | CSSProperties | {} | |
| size | 输入框大小,`large` 高度为 40px`small` 为 24px默认是 32px | `large` \| `middle` \| `small` | - | |
| bordered | 是否有边框 | boolean | true | |
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| style | 自定义输入框样式 | CSSProperties | {} | |
| suffixIcon | 自定义的选择框后缀图标 | ReactNode | - | |
| onOpenChange | 弹出日历和关闭日历的回调 | function(open) | - | |
| onPanelChange | 日历面板切换的回调 | function(value, mode) | - | |
| inputReadOnly | 设置输入框为只读(避免在移动设备上打开虚拟键盘) | boolean | false | |
### 共同的方法
| 名称 | 描述 | 版本 |
| ------- | -------- | ---- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |
| 名称 | 描述 | 版本 |
| --- | --- | --- |
| blur() | 移除焦点 | |
| focus() | 获取焦点 | |
### DatePicker
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| defaultValue | 默认日期,如果开始时间或结束时间为 `null` 或者 `undefined`,日期范围将是一个开区间 | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | - | |
| defaultValue | 默认日期,如果开始时间或结束时间为 `null` 或者 `undefined`,日期范围将是一个开区间 | [moment](http://momentjs.com/) | - | |
| disabledTime | 不可选择的时间 | function(date) | - | |
| format | 设置日期格式,为数组时支持多格式匹配,展示以第一个为准。配置参考 [moment.js](http://momentjs.com/),支持[自定义格式](#components-date-picker-demo-format) | string \| (value: moment) => string \| (string \| (value: moment) => string)[] | `YYYY-MM-DD` | |
| format | 设置日期格式,为数组时支持多格式匹配,展示以第一个为准。配置参考 [moment.js](http://momentjs.com/),支持[自定义格式](#components-date-picker-demo-format) | string \| (value: moment) => string \| (string \| (value: moment) => string)\[] | `YYYY-MM-DD` | |
| renderExtraFooter | 在面板中添加额外的页脚 | (mode) => React.ReactNode | - | |
| showNow | 当设定了 `showTime` 的时候,面板是否显示“此刻”按钮 | boolean | - | 4.4.0 |
| showTime | 增加时间选择功能 | Object \| boolean | [TimePicker Options](/components/time-picker/#API) | |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/) | moment() | |
| showToday | 是否展示“今天”按钮 | boolean | true | |
@ -99,14 +100,13 @@ import locale from 'antd/es/locale/zh_CN';
| onChange | 时间发生变化的回调 | function(date: moment, dateString: string) | - | |
| onOk | 点击确定按钮的回调 | function() | - | |
| onPanelChange | 日期面板变化时的回调 | function(value, mode) | - | |
| showNow | 当设定了 `showTime` 的时候,面板是否显示“此刻”按钮 | boolean | - | 4.4.0 |
### DatePicker\[picker=year]
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | - | |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | |
| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | `YYYY` | |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | |
| value | 日期 | [moment](http://momentjs.com/) | - | |
@ -118,8 +118,8 @@ import locale from 'antd/es/locale/zh_CN';
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | - | |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | |
| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | `YYYY-\QQ` | |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | |
| value | 日期 | [moment](http://momentjs.com/) | - | |
@ -129,8 +129,8 @@ import locale from 'antd/es/locale/zh_CN';
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | - | |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | |
| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | `YYYY-MM` | |
| monthCellRender | 自定义的月份内容渲染方法 | function(date, locale): ReactNode | - | |
| renderExtraFooter | 在面板中添加额外的页脚 | () => React.ReactNode | - | |
@ -141,12 +141,12 @@ import locale from 'antd/es/locale/zh_CN';
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | |
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/) | - | |
| defaultValue | 默认日期 | [moment](http://momentjs.com/) | - | |
| format | 展示的日期格式,配置参考 [moment.js](http://momentjs.com/) | string | `YYYY-wo` | |
| renderExtraFooter | 在面板中添加额外的页脚 | (mode) => React.ReactNode | - | |
| value | 日期 | [moment](http://momentjs.com/) | - | |
| onChange | 时间发生变化的回调,发生在用户选择时间时 | function(date: moment, dateString: string) | - | |
| renderExtraFooter | 在面板中添加额外的页脚 | (mode) => React.ReactNode | - | |
### RangePicker
@ -154,8 +154,8 @@ import locale from 'antd/es/locale/zh_CN';
| --- | --- | --- | --- | --- |
| allowEmpty | 允许起始项部分为空 | \[boolean, boolean] | \[false, false] | |
| dateRender | 自定义日期单元格的内容。`info` 参数自 4.3.0 添加 | function(currentDate: moment, today: moment, info: { range: `start` \| `end` }) => React.ReactNode | - | |
| defaultValue | 默认日期 | [moment](http://momentjs.com/)\[] | - | |
| defaultPickerValue | 默认面板日期 | [moment](http://momentjs.com/)\[] | - | |
| defaultValue | 默认日期 | [moment](http://momentjs.com/)\[] | - | |
| disabled | 禁用起始项 | \[boolean, boolean] | - | |
| disabledTime | 不可选择的时间 | function(date: moment, partial: `start` \| `end`) | - | |
| format | 展示的日期格式 | string | `YYYY-MM-DD HH:mm:ss` | |
@ -165,8 +165,8 @@ import locale from 'antd/es/locale/zh_CN';
| showTime | 增加时间选择功能 | Object\|boolean | [TimePicker Options](/components/time-picker/#API) | |
| showTime.defaultValue | 设置用户选择日期时默认的时分秒,[例子](#components-date-picker-demo-disabled-date) | [moment](http://momentjs.com/)\[] | \[moment(), moment()] | |
| value | 日期 | [moment](http://momentjs.com/)\[] | - | |
| onCalendarChange | 待选日期发生变化的回调。`info` 参数自 4.4.0 添加 | function(dates: \[moment, moment\], dateStrings: \[string, string\], info: { range:`start`\|`end` }) | - | |
| onChange | 日期范围发生变化的回调 | function(dates: \[moment, moment\], dateStrings: \[string, string\]) | - | |
| onCalendarChange | 待选日期发生变化的回调。`info` 参数自 4.4.0 添加 | function(dates: \[moment, moment], dateStrings: \[string, string], info: { range:`start`\|`end` }) | - | |
| onChange | 日期范围发生变化的回调 | function(dates: \[moment, moment], dateStrings: \[string, string]) | - | |
## FAQ
@ -184,7 +184,11 @@ v4 中DatePicker 默认 `locale` 为 `en`。你可以通过 DatePicker 的 `l
### 如何修改周的起始日?
请使用正确的[语言包](/docs/react/i18n)[#5605](https://github.com/ant-design/ant-design/issues/5605)),或者修改 moment 的 `locale` 配置https://codesandbox.io/s/moment-day-of-week-6dby5
请使用正确的[语言包](/docs/react/i18n)[#5605](https://github.com/ant-design/ant-design/issues/5605)),或者修改 moment 的 `locale` 配置:<https://codesandbox.io/s/moment-day-of-week-6dby5>
### 为何使用 `panelRender` 时,原来面板无法切换?
当你通过 `panelRender` 动态改变层级结构时,会使得原本的 Panel 被当做新的节点删除并创建。这使得其原本的状态会被重置,保持结构稳定即可。详情请参考 [#27263](https://github.com/ant-design/ant-design/issues/27263)。
```js
moment.locale('en', {

View File

@ -18,19 +18,19 @@ Commonly displayed on the details page.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| title | The title of the description list, placed at the top | ReactNode | - | |
| extra | The action area of the description list, placed at the top-right | ReactNode | - | 4.5.0 |
| bordered | Whether to display the border | boolean | false | |
| column | The number of `DescriptionItems` in a row,could be a number or a object like `{ xs: 8, sm: 16, md: 24}`,(Only set `bordered={true}` to take effect) | number | 3 | |
| size | Set the size of the list. Can be set to `middle`,`small`, or not filled | `default` \| `middle` \| `small` | - | |
| layout | Define description layout | `horizontal` \| `vertical` | `horizontal` | |
| colon | Change default props `colon` value of Descriptions.Item | boolean | true | |
| column | The number of `DescriptionItems` in a row,could be a number or a object like `{ xs: 8, sm: 16, md: 24}`,(Only set `bordered={true}` to take effect) | number | 3 | |
| extra | The action area of the description list, placed at the top-right | ReactNode | - | 4.5.0 |
| layout | Define description layout | `horizontal` \| `vertical` | `horizontal` | |
| size | Set the size of the list. Can be set to `middle`,`small`, or not filled | `default` \| `middle` \| `small` | - | |
| title | The title of the description list, placed at the top | ReactNode | - | |
### DescriptionItem
| Property | Description | Type | Default | Version |
| -------- | ------------------------------ | --------- | ------- | ------- |
| label | The description of the content | ReactNode | - | |
| span | The number of columns included | number | 1 | |
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| label | The description of the content | ReactNode | - | |
| span | The number of columns included | number | 1 | |
> The number of span Description.Item. Span={2} takes up the width of two DescriptionItems.

View File

@ -19,19 +19,19 @@ cover: https://gw.alipayobjects.com/zos/alicdn/MjtG9_FOI/Descriptions.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| title | 描述列表的标题,显示在最顶部 | ReactNode | - | |
| extra | 描述列表的操作区域,显示在右上方 | ReactNode | - | 4.5.0 |
| bordered | 是否展示边框 | boolean | false | |
| column | 一行的 `DescriptionItems` 数量,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number | 3 | |
| size | 设置列表的大小。可以设置为 `middle` 、`small`, 或不填(只有设置 `bordered={true}` 生效) | `default` \| `middle` \| `small` | - | |
| layout | 描述布局 | `horizontal` \| `vertical` | `horizontal` | |
| colon | 配置 `Descriptions.Item``colon` 的默认值 | boolean | true | |
| column | 一行的 `DescriptionItems` 数量,可以写成像素值或支持响应式的对象写法 `{ xs: 8, sm: 16, md: 24}` | number | 3 | |
| extra | 描述列表的操作区域,显示在右上方 | ReactNode | - | 4.5.0 |
| layout | 描述布局 | `horizontal` \| `vertical` | `horizontal` | |
| size | 设置列表的大小。可以设置为 `middle` 、`small`, 或不填(只有设置 `bordered={true}` 生效) | `default` \| `middle` \| `small` | - | |
| title | 描述列表的标题,显示在最顶部 | ReactNode | - | |
### DescriptionItem
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ----- | ------------ | --------- | ------ | ---- |
| label | 内容的描述 | ReactNode | - | |
| span | 包含列的数量 | number | 1 | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| label | 内容的描述 | ReactNode | - | |
| span | 包含列的数量 | number | 1 | |
> span 是 Description.Item 的数量。 span={2} 会占用两个 DescriptionItem 的宽度。

View File

@ -86,6 +86,7 @@
color: @text-color;
font-size: @font-size-base;
line-height: @line-height-base;
word-break: break-word;
overflow-wrap: break-word;
}

View File

@ -15,11 +15,11 @@ cover: https://gw.alipayobjects.com/zos/alicdn/5swjECahe/Divider.svg
## API
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| ----------- | -------------------------- | ----------------------------- | ------------ | ----- |
| className | 分割线样式类 | string | - | |
| dashed | 是否虚线 | boolean | false | |
| orientation | 分割线标题的位置 | `left` \| `right` \| `center` | `center` | |
| plain | 文字是否显示为普通正文样式 | boolean | false | 4.2.0 |
| style | 分割线样式对象 | CSSProperties | - | |
| type | 水平还是垂直类型 | `horizontal` \| `vertical` | `horizontal` | |
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| className | 分割线样式类 | string | - | |
| dashed | 是否虚线 | boolean | false | |
| orientation | 分割线标题的位置 | `left` \| `right` \| `center` | `center` | |
| plain | 文字是否显示为普通正文样式 | boolean | false | 4.2.0 |
| style | 分割线样式对象 | CSSProperties | - | |
| type | 水平还是垂直类型 | `horizontal` \| `vertical` | `horizontal` | |

View File

@ -29,6 +29,7 @@ exports[`Drawer className is test_drawer 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -126,6 +127,7 @@ exports[`Drawer destroyOnClose is true 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -192,6 +194,7 @@ exports[`Drawer getContainer return undefined 2`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar: 0px;"
type="button"
>
<span
aria-label="close"
@ -256,6 +259,7 @@ exports[`Drawer have a footer 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -329,6 +333,7 @@ exports[`Drawer have a title 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -392,6 +397,7 @@ exports[`Drawer render correctly 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -455,6 +461,7 @@ exports[`Drawer render top drawer 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -523,6 +530,7 @@ exports[`Drawer style/drawerStyle/headerStyle/bodyStyle should work 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span
aria-label="close"
@ -587,6 +595,7 @@ exports[`Drawer support closeIcon 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar:0px"
type="button"
>
<span>
close

View File

@ -37,6 +37,7 @@ exports[`Drawer render correctly 1`] = `
aria-label="Close"
class="ant-drawer-close"
style="--scroll-bar: 0px;"
type="button"
>
<span
aria-label="close"

View File

@ -20,28 +20,28 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
| Props | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| closable | Whether a close (x) button is visible on top right of the Drawer dialog or not | boolean | true |
| closeIcon | Custom close icon | ReactNode | &lt;CloseOutlined /> |
| destroyOnClose | Whether to unmount child components on closing drawer or not | boolean | false |
| forceRender | Prerender Drawer component forcely | boolean | false |
| getContainer | Return the mounted node for Drawer | HTMLElement \| () => HTMLElement \| Selectors \| false | body |
| mask | Whether to show mask or not | boolean | true |
| maskClosable | Clicking on the mask (area outside the Drawer) to close the Drawer or not | boolean | true |
| maskStyle | Style for Drawer's mask element | CSSProperties | {} |
| style | Style of wrapper element which **contains mask** compare to `drawerStyle` | CSSProperties | - |
| drawerStyle | Style of the popup layer element | object | - |
| headerStyle | Style of the drawer header part | object | - |
| bodyStyle | Style of the drawer content part | object | - |
| title | The title for Drawer | ReactNode | - |
| visible | Whether the Drawer dialog is visible or not | boolean | false |
| width | Width of the Drawer dialog | string \| number | 256 |
| height | Placement is `top` or `bottom`, height of the Drawer dialog | string \| number | 256 |
| className | The class name of the container of the Drawer dialog | string | - |
| zIndex | The `z-index` of the Drawer | number | 1000 |
| placement | The placement of the Drawer | `top` \| `right` \| `bottom` \| `left` | `right` |
| onClose | Specify a callback that will be called when a user clicks mask, close button or Cancel button | function(e) | - |
| afterVisibleChange | Callback after the animation ends when switching drawers | function(visible) | - |
| keyboard | Whether support press esc to close | boolean | true |
| footer | The footer for Drawer | ReactNode | - |
| footerStyle | Style of the drawer footer part | CSSProperties | - |
| afterVisibleChange | Callback after the animation ends when switching drawers | function(visible) | - | |
| bodyStyle | Style of the drawer content part | object | - | |
| className | The class name of the container of the Drawer dialog | string | - | |
| closable | Whether a close (x) button is visible on top right of the Drawer dialog or not | boolean | true | |
| closeIcon | Custom close icon | ReactNode | &lt;CloseOutlined /> | |
| destroyOnClose | Whether to unmount child components on closing drawer or not | boolean | false | |
| drawerStyle | Style of the popup layer element | object | - | |
| footer | The footer for Drawer | ReactNode | - | |
| footerStyle | Style of the drawer footer part | CSSProperties | - | |
| forceRender | Prerender Drawer component forcely | boolean | false | |
| getContainer | Return the mounted node for Drawer | HTMLElement \| () => HTMLElement \| Selectors \| false | body | |
| headerStyle | Style of the drawer header part | object | - | |
| height | Placement is `top` or `bottom`, height of the Drawer dialog | string \| number | 256 | |
| keyboard | Whether support press esc to close | boolean | true | |
| mask | Whether to show mask or not | boolean | true | |
| maskClosable | Clicking on the mask (area outside the Drawer) to close the Drawer or not | boolean | true | |
| maskStyle | Style for Drawer's mask element | CSSProperties | {} | |
| placement | The placement of the Drawer | `top` \| `right` \| `bottom` \| `left` | `right` | |
| push | Nested drawers push behavior | boolean \| { distance: string \| number } | { distance: 180 } | 4.5.0+ |
| style | Style of wrapper element which **contains mask** compare to `drawerStyle` | CSSProperties | - | |
| title | The title for Drawer | ReactNode | - | |
| visible | Whether the Drawer dialog is visible or not | boolean | false | |
| width | Width of the Drawer dialog | string \| number | 256 | |
| zIndex | The `z-index` of the Drawer | number | 1000 | |
| onClose | Specify a callback that will be called when a user clicks mask, close button or Cancel button | function(e) | - | |

View File

@ -218,8 +218,8 @@ class Drawer extends React.Component<DrawerProps & ConfigConsumerProps, IDrawerS
const { closable, closeIcon = <CloseOutlined />, prefixCls, onClose } = this.props;
return (
closable && (
// eslint-disable-next-line react/button-has-type
<button
type="button"
onClick={onClose}
aria-label="Close"
className={`${prefixCls}-close`}

View File

@ -19,28 +19,28 @@ cover: https://gw.alipayobjects.com/zos/alicdn/7z8NJQhFb/Drawer.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| closable | 是否显示右上角的关闭按钮 | boolean | true |
| closeIcon | 自定义关闭图标 | ReactNode | &lt;CloseOutlined /> |
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false |
| forceRender | 预渲染 Drawer 内元素 | boolean | false |
| getContainer | 指定 Drawer 挂载的 HTML 节点, false 为挂载在当前 dom | HTMLElement \| () => HTMLElement \| Selectors \| false | body |
| maskClosable | 点击蒙层是否允许关闭 | boolean | true |
| mask | 是否展示遮罩 | boolean | true |
| maskStyle | 遮罩样式 | CSSProperties | {} |
| style | 可用于设置 Drawer 最外层容器的样式,和 `drawerStyle` 的区别是作用节点包括 `mask` | CSSProperties | - |
| drawerStyle | 用于设置 Drawer 弹出层的样式 | CSSProperties | - |
| headerStyle | 用于设置 Drawer 头部的样式 | CSSProperties | - |
| bodyStyle | 可用于设置 Drawer 内容部分的样式 | CSSProperties | - |
| title | 标题 | ReactNode | - |
| visible | Drawer 是否可见 | boolean | - |
| width | 宽度 | string \| number | 256 |
| height | 高度, 在 `placement``top``bottom` 时使用 | string \| number | 256 |
| className | 对话框外层容器的类名 | string | - |
| zIndex | 设置 Drawer 的 `z-index` | number | 1000 |
| placement | 抽屉的方向 | `top` \| `right` \| `bottom` \| `left` | `right` |
| onClose | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | - |
| afterVisibleChange | 切换抽屉时动画结束后的回调 | function(visible) | - |
| keyboard | 是否支持键盘 esc 关闭 | boolean | true |
| footer | 抽屉的页脚 | ReactNode | - |
| footerStyle | 抽屉页脚部件的样式 | CSSProperties | - |
| afterVisibleChange | 切换抽屉时动画结束后的回调 | function(visible) | - | |
| bodyStyle | 可用于设置 Drawer 内容部分的样式 | CSSProperties | - | |
| className | 对话框外层容器的类名 | string | - | |
| closable | 是否显示右上角的关闭按钮 | boolean | true | |
| closeIcon | 自定义关闭图标 | ReactNode | &lt;CloseOutlined /> | |
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | false | |
| drawerStyle | 用于设置 Drawer 弹出层的样式 | CSSProperties | - | |
| footer | 抽屉的页脚 | ReactNode | - | |
| footerStyle | 抽屉页脚部件的样式 | CSSProperties | - | |
| forceRender | 预渲染 Drawer 内元素 | boolean | false | |
| getContainer | 指定 Drawer 挂载的 HTML 节点, false 为挂载在当前 dom | HTMLElement \| () => HTMLElement \| Selectors \| false | body | |
| headerStyle | 用于设置 Drawer 头部的样式 | CSSProperties | - | |
| height | 高度, 在 `placement``top``bottom` 时使用 | string \| number | 256 | |
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
| mask | 是否展示遮罩 | boolean | true | |
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | |
| maskStyle | 遮罩样式 | CSSProperties | {} | |
| placement | 抽屉的方向 | `top` \| `right` \| `bottom` \| `left` | `right` | |
| push | 用于设置多层 Drawer 的推动行为 | boolean \| { distance: string \| number } | { distance: 180 } | 4.5.0+ |
| style | 可用于设置 Drawer 最外层容器的样式,和 `drawerStyle` 的区别是作用节点包括 `mask` | CSSProperties | - | |
| title | 标题 | ReactNode | - | |
| visible | Drawer 是否可见 | boolean | - | |
| width | 宽度 | string \| number | 256 | |
| zIndex | 设置 Drawer 的 `z-index` | number | 1000 | |
| onClose | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | - | |

View File

@ -19,14 +19,14 @@ When there are more than a few options to choose from, you can wrap them in a `D
| --- | --- | --- | --- | --- |
| arrow | Whether the dropdown arrow should be visible | boolean | false | |
| disabled | Whether the dropdown menu is disabled | boolean | - | |
| getPopupContainer | To set the container of the dropdown menu. The default is to create a div element in body, but you can reset it to the scrolling area and make a relative reposition. [Example on CodePen](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
| getPopupContainer | To set the container of the dropdown menu. The default is to create a div element in body, but you can reset it to the scrolling area and make a relative reposition. [Example on CodePen](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) => HTMLElement | () => document.body | |
| overlay | The dropdown menu | [Menu](/components/menu) \| () => Menu | - | |
| overlayClassName | The class name of the dropdown root element | string | - | |
| overlayStyle | The style of the dropdown root element | object | - | |
| onVisibleChange | Called when the visible state is changed | function(visible) | - | |
| overlayStyle | The style of the dropdown root element | CSSProperties | - | |
| placement | Placement of popup menu: `bottomLeft`, `bottomCenter`, `bottomRight`, `topLeft`, `topCenter` or `topRight` | string | `bottomLeft` | |
| trigger | The trigger mode which executes the dropdown action. Note that hover can't be used on touchscreens | Array&lt;`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
| visible | Whether the dropdown menu is currently visible | boolean | - | |
| onVisibleChange | Called when the visible state is changed | (visible: boolean) => void | - | |
You should use [Menu](/components/menu/) as `overlay`. The menu items and dividers are also available by using `Menu.Item` and `Menu.Divider`.
@ -38,14 +38,14 @@ You should use [Menu](/components/menu/) as `overlay`. The menu items and divide
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| buttonsRender | Custom buttons inside Dropdown.Button | ([buttons: ReactNode[]]) => ReactNode | - | |
| buttonsRender | Custom buttons inside Dropdown.Button | (buttons: ReactNode\[]) => ReactNode\[] | - | |
| disabled | Whether the dropdown menu is disabled | boolean | - | |
| icon | Icon (appears on the right) | ReactNode | - | |
| onClick | The same as [Button](/components/button): called when you click the button on the left | function | - | |
| onVisibleChange | Called when the visible state is changed | function | - | |
| overlay | The dropdown menu | [Menu](/components/menu) | - | |
| placement | Placement of popup menu: `bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | string | `bottomLeft` | |
| size | Size of the button, the same as [Button](/components/button) | string | `default` | |
| size | Size of the button, the same as [Button](/components/button/#API) | string | `default` | |
| trigger | The trigger mode which executes the dropdown action | Array&lt;`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
| type | Type of the button, the same as [Button](/components/button) | string | `default` | |
| type | Type of the button, the same as [Button](/components/button/#API) | string | `default` | |
| visible | Whether the dropdown menu is currently visible | boolean | - | |
| onClick | The same as [Button](/components/button/#API): called when you click the button on the left | (event) => void | - | |
| onVisibleChange | Called when the visible state is changed | (visible: boolean) => void | - | |

View File

@ -23,14 +23,14 @@ cover: https://gw.alipayobjects.com/zos/alicdn/eedWN59yJ/Dropdown.svg
| --- | --- | --- | --- | --- |
| arrow | 下拉框箭头是否显示 | boolean | false | |
| disabled | 菜单是否禁用 | boolean | - | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | function(triggerNode) | () => document.body | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | (triggerNode: HTMLElement) => HTMLElement | () => document.body | |
| overlay | 菜单 | [Menu](/components/menu) \| () => Menu | - | |
| overlayClassName | 下拉根元素的类名称 | string | - | |
| overlayStyle | 下拉根元素的样式 | object | - | |
| onVisibleChange | 菜单显示状态改变时调用,参数为 `visible` | function(visible) | - | |
| overlayStyle | 下拉根元素的样式 | CSSProperties | - | |
| placement | 菜单弹出位置:`bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | string | `bottomLeft` | |
| trigger | 触发下拉的行为, 移动端不支持 hover | Array&lt;`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
| visible | 菜单是否显示 | boolean | - | |
| onVisibleChange | 菜单显示状态改变时调用,参数为 `visible` | (visible: boolean) => void | - | |
`overlay` 菜单使用 [Menu](/components/menu/),还包括菜单项 `Menu.Item`,分割线 `Menu.Divider`
@ -42,14 +42,14 @@ cover: https://gw.alipayobjects.com/zos/alicdn/eedWN59yJ/Dropdown.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| buttonsRender | 自定义左右两个按钮 | ([buttons: ReactNode[]]) => ReactNode | - | |
| buttonsRender | 自定义左右两个按钮 | (buttons: ReactNode\[]) => ReactNode\[] | - | |
| disabled | 菜单是否禁用 | boolean | - | |
| icon | 右侧的 icon | ReactNode | - | |
| onClick | 点击左侧按钮的回调,和 [Button](/components/button/) 一致 | function | - | |
| onVisibleChange | 菜单显示状态改变时调用,参数为 `visible` | function | - | |
| overlay | 菜单 | [Menu](/components/menu/) | - | |
| placement | 菜单弹出位置:`bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | string | `bottomLeft` | |
| size | 按钮大小,和 [Button](/components/button/) 一致 | string | `default` | |
| size | 按钮大小,和 [Button](/components/button/#API) 一致 | string | `default` | |
| trigger | 触发下拉的行为 | Array&lt;`click`\|`hover`\|`contextMenu`> | \[`hover`] | |
| type | 按钮类型,和 [Button](/components/button/) 一致 | string | `default` | |
| type | 按钮类型,和 [Button](/components/button/#API) 一致 | string | `default` | |
| visible | 菜单是否显示 | boolean | - | |
| onClick | 点击左侧按钮的回调,和 [Button](/components/button/#API) 一致 | (event) => void | - | |
| onVisibleChange | 菜单显示状态改变时调用,参数为 `visible` | (visible: boolean) => void | - | |

View File

@ -170,10 +170,12 @@
transition: all 0.3s;
> .@{iconfont-css-prefix}:first-child,
> a > .@{iconfont-css-prefix}:first-child,
> span > .@{iconfont-css-prefix}:first-child {
min-width: 12px;
margin-right: 8px;
font-size: @font-size-sm;
vertical-align: -0.1em;
}
> a {

View File

@ -24,8 +24,8 @@ Empty state placeholder.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| description | Customize description | ReactNode | - | |
| imageStyle | The style of image | CSSProperties | - | |
| image | Customize image. Will treat as image url when string provided | ReactNode | `Empty.PRESENTED_IMAGE_DEFAULT` | |
| imageStyle | The style of image | CSSProperties | - | |
## Built-in images

View File

@ -25,8 +25,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/MNbKfLBVb/Empty.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| description | 自定义描述内容 | ReactNode | - | |
| imageStyle | 图片样式 | CSSProperties | - | |
| image | 设置显示图片,为 string 时表示自定义图片地址。 | ReactNode | `Empty.PRESENTED_IMAGE_DEFAULT` | |
| imageStyle | 图片样式 | CSSProperties | - | |
## 内置图片

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { List } from 'rc-field-form';
import { StoreValue } from 'rc-field-form/lib/interface';
import { ValidatorRule, StoreValue } from 'rc-field-form/lib/interface';
import devWarning from '../_util/devWarning';
import { ConfigContext } from '../config-provider';
import { FormItemPrefixContext } from './context';
@ -20,6 +20,7 @@ export interface FormListOperation {
export interface FormListProps {
prefixCls?: string;
name: string | number | (string | number)[];
rules?: ValidatorRule[];
children: (
fields: FormListFieldData[],
operation: FormListOperation,

View File

@ -1549,86 +1549,84 @@ exports[`renders ./components/form/demo/dynamic-form-item.md correctly 1`] = `
class="ant-form ant-form-horizontal"
id="dynamic_form_item"
>
<div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-row ant-form-item"
class="ant-col ant-form-item-control ant-col-xs-24 ant-col-xs-offset-0 ant-col-sm-20 ant-col-sm-offset-4"
>
<div
class="ant-col ant-form-item-control ant-col-xs-24 ant-col-xs-offset-0 ant-col-sm-20 ant-col-sm-offset-4"
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input"
class="ant-form-item-control-input-content"
>
<div
class="ant-form-item-control-input-content"
<button
class="ant-btn ant-btn-dashed"
style="width:60%"
type="button"
>
<button
class="ant-btn ant-btn-dashed"
style="width:60%"
type="button"
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
>
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
<svg
aria-hidden="true"
class=""
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
class=""
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs />
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
<span>
Add field
</span>
</button>
<button
class="ant-btn ant-btn-dashed"
style="width:60%;margin-top:20px"
type="button"
<defs />
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
<span>
Add field
</span>
</button>
<button
class="ant-btn ant-btn-dashed"
style="width:60%;margin-top:20px"
type="button"
>
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
>
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
<svg
aria-hidden="true"
class=""
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
class=""
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs />
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
<span>
Add field at head
</span>
</button>
</div>
<defs />
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
<span>
Add field at head
</span>
</button>
</div>
</div>
</div>
@ -1666,52 +1664,50 @@ exports[`renders ./components/form/demo/dynamic-form-items.md correctly 1`] = `
class="ant-form ant-form-horizontal"
id="dynamic_form_nest_item"
>
<div>
<div
class="ant-row ant-form-item"
>
<div
class="ant-row ant-form-item"
class="ant-col ant-form-item-control"
>
<div
class="ant-col ant-form-item-control"
class="ant-form-item-control-input"
>
<div
class="ant-form-item-control-input"
class="ant-form-item-control-input-content"
>
<div
class="ant-form-item-control-input-content"
<button
class="ant-btn ant-btn-dashed ant-btn-block"
type="button"
>
<button
class="ant-btn ant-btn-dashed ant-btn-block"
type="button"
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
>
<span
aria-label="plus"
class="anticon anticon-plus"
role="img"
<svg
aria-hidden="true"
class=""
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<svg
aria-hidden="true"
class=""
data-icon="plus"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<defs />
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
<span>
Add field
</span>
</button>
</div>
<defs />
<path
d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"
/>
<path
d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"
/>
</svg>
</span>
<span>
Add field
</span>
</button>
</div>
</div>
</div>
@ -1875,7 +1871,7 @@ exports[`renders ./components/form/demo/dynamic-form-items-complex.md correctly
</svg>
</span>
<span>
Add sights
Add sights
</span>
</button>
</div>
@ -2788,14 +2784,10 @@ exports[`renders ./components/form/demo/nest-messages.md correctly 1`] = `
<div
class="ant-form-item-control-input-content"
>
<div
class="ant-input-textarea"
>
<textarea
class="ant-input"
id="nest-messages_user_introduction"
/>
</div>
<textarea
class="ant-input"
id="nest-messages_user_introduction"
/>
</div>
</div>
</div>
@ -7630,7 +7622,7 @@ exports[`renders ./components/form/demo/validate-static.md correctly 1`] = `
class="ant-form-item-control-input-content"
>
<span
class="ant-input-affix-wrapper ant-input-password"
class="ant-input-affix-wrapper"
>
<input
action="click"

View File

@ -35,14 +35,14 @@ const Demo = () => {
const onGenderChange = value => {
switch (value) {
case "male":
form.setFieldsValue({ note: "Hi, man!" });
case 'male':
form.setFieldsValue({ note: 'Hi, man!' });
return;
case "female":
form.setFieldsValue({ note: "Hi, lady!" });
case 'female':
form.setFieldsValue({ note: 'Hi, lady!' });
return;
case "other":
form.setFieldsValue({ note: "Hi there!" });
case 'other':
form.setFieldsValue({ note: 'Hi there!' });
return;
}
};

View File

@ -53,68 +53,61 @@ const DynamicFieldSet = () => {
},
]}
>
{(fields, { add, remove }, { errors }) => {
return (
<div>
{fields.map((field, index) => (
{(fields, { add, remove }, { errors }) => (
<>
{fields.map((field, index) => (
<Form.Item
{...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
label={index === 0 ? 'Passengers' : ''}
required={false}
key={field.key}
>
<Form.Item
{...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
label={index === 0 ? 'Passengers' : ''}
required={false}
key={field.key}
{...field}
validateTrigger={['onChange', 'onBlur']}
rules={[
{
required: true,
whitespace: true,
message: "Please input passenger's name or delete this field.",
},
]}
noStyle
>
<Form.Item
{...field}
validateTrigger={['onChange', 'onBlur']}
rules={[
{
required: true,
whitespace: true,
message: "Please input passenger's name or delete this field.",
},
]}
noStyle
>
<Input placeholder="passenger name" style={{ width: '60%' }} />
</Form.Item>
{fields.length > 1 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px' }}
onClick={() => {
remove(field.name);
}}
/>
) : null}
<Input placeholder="passenger name" style={{ width: '60%' }} />
</Form.Item>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
style={{ width: '60%' }}
>
<PlusOutlined /> Add field
</Button>
<Button
type="dashed"
onClick={() => {
add('The head item', 0);
}}
style={{ width: '60%', marginTop: '20px' }}
>
<PlusOutlined /> Add field at head
</Button>
<Form.ErrorList errors={errors} />
{fields.length > 1 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
onClick={() => remove(field.name)}
/>
) : null}
</Form.Item>
</div>
);
}}
))}
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
style={{ width: '60%' }}
icon={<PlusOutlined />}
>
Add field
</Button>
<Button
type="dashed"
onClick={() => {
add('The head item', 0);
}}
style={{ width: '60%', marginTop: '20px' }}
icon={<PlusOutlined />}
>
Add field at head
</Button>
<Form.ErrorList errors={errors} />
</Form.Item>
</>
)}
</Form.List>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit
@ -129,6 +122,7 @@ ReactDOM.render(<DynamicFieldSet />, mountNode);
```css
.dynamic-delete-button {
margin: 0 8px;
cursor: pointer;
position: relative;
top: 4px;

View File

@ -17,6 +17,8 @@ This example demonstrates the case that a form contains multiple form controls.
import { Form, Input, Button, Space, Select } from 'antd';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
const { Option } = Select;
const areas = [
{ label: 'Beijing', value: 'Beijing' },
{ label: 'Shanghai', value: 'Shanghai' },
@ -44,65 +46,56 @@ const Demo = () => {
<Select options={areas} onChange={handleChange} />
</Form.Item>
<Form.List name="sights">
{(fields, { add, remove }) => {
return (
<>
{fields.map(field => (
<Space key={field.key} align="start">
<Form.Item
noStyle
shouldUpdate={(prevValues, curValues) =>
prevValues.area !== curValues.area || prevValues.sights !== curValues.sights
}
>
{() => (
<Form.Item
{...field}
label="Sight"
name={[field.name, 'sight']}
fieldKey={[field.fieldKey, 'sight']}
rules={[{ required: true, message: 'Missing sight' }]}
>
<Select disabled={!form.getFieldValue('area')} style={{ width: 130 }}>
{(sights[form.getFieldValue('area')] || []).map(item => (
<Select.Option key={item} value={item}>
{item}
</Select.Option>
))}
</Select>
</Form.Item>
)}
</Form.Item>
<Form.Item
{...field}
label="Price"
name={[field.name, 'price']}
fieldKey={[field.fieldKey, 'price']}
rules={[{ required: true, message: 'Missing price' }]}
>
<Input />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
{(fields, { add, remove }) => (
<>
{fields.map(field => (
<Space key={field.key} align="baseline">
<Form.Item
noStyle
shouldUpdate={(prevValues, curValues) =>
prevValues.area !== curValues.area || prevValues.sights !== curValues.sights
}
>
<PlusOutlined /> Add sights
</Button>
</Form.Item>
</>
);
}}
</Form.List>
{() => (
<Form.Item
{...field}
label="Sight"
name={[field.name, 'sight']}
fieldKey={[field.fieldKey, 'sight']}
rules={[{ required: true, message: 'Missing sight' }]}
>
<Select disabled={!form.getFieldValue('area')} style={{ width: 130 }}>
{(sights[form.getFieldValue('area')] || []).map(item => (
<Option key={item} value={item}>
{item}
</Option>
))}
</Select>
</Form.Item>
)}
</Form.Item>
<Form.Item
{...field}
label="Price"
name={[field.name, 'price']}
fieldKey={[field.fieldKey, 'price']}
rules={[{ required: true, message: 'Missing price' }]}
>
<Input />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Add sights
</Button>
</Form.Item>
</>
)}
</Form.List>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit

View File

@ -25,52 +25,37 @@ const Demo = () => {
return (
<Form name="dynamic_form_nest_item" onFinish={onFinish} autoComplete="off">
<Form.List name="users">
{(fields, { add, remove }) => {
return (
<div>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name, 'first']}
fieldKey={[field.fieldKey, 'first']}
rules={[{ required: true, message: 'Missing first name' }]}
>
<Input placeholder="First Name" />
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'last']}
fieldKey={[field.fieldKey, 'last']}
rules={[{ required: true, message: 'Missing last name' }]}
>
<Input placeholder="Last Name" />
</Form.Item>
<MinusCircleOutlined
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
{(fields, { add, remove }) => (
<>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="baseline">
<Form.Item
{...field}
name={[field.name, 'first']}
fieldKey={[field.fieldKey, 'first']}
rules={[{ required: true, message: 'Missing first name' }]}
>
<PlusOutlined /> Add field
</Button>
</Form.Item>
</div>
);
}}
<Input placeholder="First Name" />
</Form.Item>
<Form.Item
{...field}
name={[field.name, 'last']}
fieldKey={[field.fieldKey, 'last']}
rules={[{ required: true, message: 'Missing last name' }]}
>
<Input placeholder="Last Name" />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button type="dashed" onClick={() => add()} block icon={<PlusOutlined />}>
Add field
</Button>
</Form.Item>
</>
)}
</Form.List>
<Form.Item>
<Button type="primary" htmlType="submit">
Submit

View File

@ -251,7 +251,10 @@ const RegistrationForm = () => {
name="agreement"
valuePropName="checked"
rules={[
{ validator:(_, value) => value ? Promise.resolve() : Promise.reject('Should accept agreement') },
{
validator: (_, value) =>
value ? Promise.resolve() : Promise.reject('Should accept agreement'),
},
]}
{...tailFormItemLayout}
>

View File

@ -19,8 +19,8 @@ High performance Form component with data scope management. Including data colle
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| component | Set the Form rendering element. Do not create a DOM node for `false` | ComponentType \| false | form | |
| colon | Configure the default value of `colon` for Form.Item. Indicates whether the colon after the label is displayed (only effective when prop layout is horizontal) | boolean | true | |
| component | Set the Form rendering element. Do not create a DOM node for `false` | ComponentType \| false | form | |
| fields | Control of form fields through state management (such as redux). Not recommended for non-strong demand. View [example](#components-form-demo-global-state) | [FieldData](#FieldData)\[] | - | |
| form | Form control instance created by `Form.useForm()`. Automatically created when not provided | [FormInstance](#FormInstance) | - | |
| initialValues | Set value by Form initialization or reset | object | - | |
@ -33,11 +33,11 @@ High performance Form component with data scope management. Including data colle
| scrollToFirstError | Auto scroll to first failed field when submit | boolean | false | |
| size | Set field component size (antd components only) | `small` \| `middle` \| `large` | - | |
| validateMessages | Validation prompt template, description [see below](#validateMessages) | [ValidateMessages](https://github.com/react-component/field-form/blob/master/src/utils/messages.ts) | - | |
| validateTrigger | Config field validate trigger | string \| string[] | `onChange` | 4.3.0 |
| validateTrigger | Config field validate trigger | string \| string\[] | `onChange` | 4.3.0 |
| wrapperCol | The layout for input controls, same as `labelCol` | [object](/components/grid/#Col) | - | |
| onFieldsChange | Trigger when field updated | function(changedFields, allFields) | - | |
| onFinish | Trigger after submitting the form and verifying data successfully | function(values) | - | |
| onFinishFailed | Trigger after submitting the form and verifying data failed | function({ values, errorFields, outOfDate }) | - | |
| onFieldsChange | Trigger when field updated | function(changedFields, allFields) | - | |
| onValuesChange | Trigger when value updated | function(changedValues, allValues) | - | |
### validateMessages
@ -73,33 +73,33 @@ Form field component for data bidirectional binding, validation, layout, and so
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| colon | Used with `label`, whether to display `:` after label text. | boolean | true | |
| dependencies | Set the dependency field. See [below](#dependencies) | [NamePath](#NamePath)[] | - | |
| dependencies | Set the dependency field. See [below](#dependencies) | [NamePath](#NamePath)\[] | - | |
| extra | The extra prompt message. It is similar to help. Usage example: to display error message and prompt message at the same time | ReactNode | - | |
| getValueFromEvent | Specify how to get value from event or other onChange arguments | (..args: any[]) => any | - | |
| getValueFromEvent | Specify how to get value from event or other onChange arguments | (..args: any\[]) => any | - | |
| getValueProps | Additional props with sub component | (value: any) => any | - | 4.2.0 |
| hasFeedback | Used with `validateStatus`, this option specifies the validation status icon. Recommended to be used only with `Input` | boolean | false | |
| help | The prompt message. If not provided, the prompt message will be generated by the validation rule. | ReactNode | - | |
| hidden | Whether to hide Form.Item (still collect and validate value) | boolean | false | |
| htmlFor | Set sub label `htmlFor` | string | - | |
| initialValue | Config sub default value. Form `initialValues` get higher priority when conflict | string | - | 4.2.0 |
| noStyle | No style for `true`, used as a pure field control | boolean | false | |
| label | Label text | ReactNode | - | |
| labelAlign | The text align of label | `left` \| `right` | `right` | |
| labelCol | The layout of label. You can set `span` `offset` to something like `{span: 3, offset: 12}` or `sm: {span: 3, offset: 12}` same as with `<Col>`. You can set `labelCol` on Form which will not affect nest Item. If both exists, use Item first | [object](/components/grid/#Col) | - | |
| messageVariables | default validate filed info | Record<string, string> | - | 4.7.0 |
| messageVariables | default validate filed info | Record&lt;string, string> | - | 4.7.0 |
| name | Field name, support array | [NamePath](#NamePath) | - | |
| normalize | Normalize value from component value before passing to Form instance | (value, prevValue, prevValues) => any | - | |
| noStyle | No style for `true`, used as a pure field control | boolean | false | |
| preserve | Keep field value even when field removed | boolean | true | 4.4.0 |
| required | Display required style. It will be generated by the validation rule | boolean | false | |
| rules | Rules for field validation. Click [here](#components-form-demo-basic) to see an example | [Rule](#Rule)[] | - | |
| rules | Rules for field validation. Click [here](#components-form-demo-basic) to see an example | [Rule](#Rule)\[] | - | |
| shouldUpdate | Custom field update logic. See [below](#shouldUpdate) | boolean \| (prevValue, curValue) => boolean | false | |
| tooltip | Config tooltip info | ReactNode \| [TooltipProps & { icon: ReactNode }](/components/tooltip#API) | - | 4.7.0 |
| trigger | When to collect the value of children node | string | `onChange` | |
| validateFirst | Whether stop validate on first rule of error for this field. Will parallel validate when `parallel` cofigured | boolean \| `parallel` | false | `parallel`: 4.5.0 |
| validateStatus | The validation status. If not provided, it will be generated by validation rule. options: `success` `warning` `error` `validating` | string | - | |
| validateTrigger | When to validate the value of children node | string \| string[] | `onChange` | |
| validateTrigger | When to validate the value of children node | string \| string\[] | `onChange` | |
| valuePropName | Props of children node, for example, the prop of Switch is 'checked'. This prop is an encapsulation of `getValueProps`, which will be invalid after customizing `getValueProps` | string | `value` | |
| wrapperCol | The layout for input controls, same as `labelCol`. You can set `wrapperCol` on Form which will not affect nest Item. If both exists, use Item first | [object](/components/grid/#Col) | - | |
| hidden | Whether to hide Form.Item (still collect and validate value) | boolean | false | |
After wrapped by `Form.Item` with `name` property, `value`(or other property defined by `valuePropName`) `onChange`(or other property defined by `trigger`) props will be added to form controls, the flow of form data will be handled by Form which will cause:
@ -168,9 +168,9 @@ Provides array management for fields.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| children | Render function | (fields: Field\[], operation: { add, remove, move }) => React.ReactNode | - | |
| name | Field name, support array | [NamePath](#NamePath) | - | |
| children | Render function | (fields: Field[], operation: { add, remove, move }) => React.ReactNode | - | |
| rules | Validate rules, only support customize validator. Should work with [ErrorList](#Form.ErrorList) | { validator, message }[] | - | 4.7.0 |
| rules | Validate rules, only support customize validator. Should work with [ErrorList](#Form.ErrorList) | { validator, message }\[] | - | 4.7.0 |
```tsx
<Form.List>
@ -193,16 +193,16 @@ Some operator functions in render form of Form.List.
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| add | add form item | (defaultValue?: any, insertIndex?: number) => void | insertIndex: 4.6.0 |
| remove | remove form item | (index: number \| number[]) => void | number[]: 4.5.0 |
| move | move form item | (from: number, to: number) => void | - |
| remove | remove form item | (index: number \| number\[]) => void | number\[]: 4.5.0 |
## Form.ErrorList
New in 4.7.0. Show error messages, should only work with `rules` of Form.List.
| Property | Description | Type | Default |
| -------- | ----------- | ----------- | ------- |
| errors | Error list | ReactNode[] | - |
| Property | Description | Type | Default |
| --- | --- | --- | --- |
| errors | Error list | ReactNode\[] | - |
## Form.Provider
@ -230,20 +230,20 @@ Provide linkage between forms. If a sub form with `name` prop update, it will au
| Name | Description | Type | Version |
| --- | --- | --- | --- |
| getFieldError | Get the error messages by the field name | (name: [NamePath](#NamePath)) => string\[] | |
| getFieldInstance | Get field instance | (name: [NamePath](#NamePath)) => any | 4.4.0 |
| getFieldsError | Get the error messages by the fields name. Return as an array | (nameList?: [NamePath](#NamePath)\[]) => FieldError\[] | |
| getFieldsValue | Get values by a set of field names. Return according to the corresponding structure | (nameList?: [NamePath](#NamePath)\[], filterFunc?: (meta: { touched: boolean, validating: boolean }) => boolean) => any | |
| getFieldValue | Get the value by the field name | (name: [NamePath](#NamePath)) => any | |
| getFieldsValue | Get values by a set of field names. Return according to the corresponding structure | (nameList?: [NamePath](#NamePath)[], filterFunc?: (meta: { touched: boolean, validating: boolean }) => boolean) => any | |
| getFieldError | Get the error messages by the field name | (name: [NamePath](#NamePath)) => string[] | |
| getFieldsError | Get the error messages by the fields name. Return as an array | (nameList?: [NamePath](#NamePath)[]) => FieldError[] | |
| isFieldsTouched | Check if fields have been operated. Check if all fields is touched when `allTouched` is `true` | (nameList?: [NamePath](#NamePath)\[], allTouched?: boolean) => boolean | |
| isFieldTouched | Check if a field has been operated | (name: [NamePath](#NamePath)) => boolean | |
| isFieldsTouched | Check if fields have been operated. Check if all fields is touched when `allTouched` is `true` | (nameList?: [NamePath](#NamePath)[], allTouched?: boolean) => boolean | |
| isFieldValidating | Check fields if is in validating | (name: [NamePath](#NamePath)) => boolean | |
| resetFields | Reset fields to `initialValues` | (fields?: [NamePath](#NamePath)[]) => void | |
| scrollToField | Scroll to field position | (name: [NamePath](#NamePath), options: [[ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)]) => void | |
| setFields | Set fields status | (fields: [FieldData](#FieldData)[]) => void | |
| resetFields | Reset fields to `initialValues` | (fields?: [NamePath](#NamePath)\[]) => void | |
| scrollToField | Scroll to field position | (name: [NamePath](#NamePath), options: \[[ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)]) => void | |
| setFields | Set fields status | (fields: [FieldData](#FieldData)\[]) => void | |
| setFieldsValue | Set fields value | (values) => void | |
| submit | Submit the form. It's same as click `submit` button | () => void | |
| validateFields | Validate fields | (nameList?: [NamePath](#NamePath)[]) => Promise | |
| validateFields | Validate fields | (nameList?: [NamePath](#NamePath)\[]) => Promise | |
#### validateFields return sample
@ -283,13 +283,13 @@ validateFields()
#### FieldData
| Name | Description | Type |
| ---------- | ------------------------ | ----------------------- |
| touched | Whether is operated | boolean |
| validating | Whether is in validating | boolean |
| errors | Error messages | string[] |
| name | Field name path | [NamePath](#NamePath)[] |
| value | Field value | any |
| Name | Description | Type |
| --- | --- | --- |
| errors | Error messages | string\[] |
| name | Field name path | [NamePath](#NamePath)\[] |
| touched | Whether is operated | boolean |
| validating | Whether is in validating | boolean |
| value | Field value | any |
#### Rule
@ -301,7 +301,7 @@ type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
| Name | Description | Type |
| --- | --- | --- |
| enum | Match enum value. You need to set `type` to `enum` to enable this | any[] |
| enum | Match enum value. You need to set `type` to `enum` to enable this | any\[] |
| len | Length of string, number, array | number |
| max | `type` required: max length of `string`, `number`, `array` | number |
| message | Error message. Will auto generate by [template](#validateMessages) if not provided | string |
@ -310,9 +310,9 @@ type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
| required | Required field | boolean |
| transform | Transform value to the rule before validation | (value) => any |
| type | Normally `string` \|`number` \|`boolean` \|`url` \| `email`. More type to ref [here](https://github.com/yiminghe/async-validator#type) | string |
| validateTrigger | Set validate trigger event. Must be the sub set of `validateTrigger` in Form.Item | string \| string\[] |
| validator | Customize validation rule. Accept Promise as return. See [example](#components-form-demo-register) | ([rule](#Rule), value) => Promise |
| whitespace | Failed if only has whitespace | boolean |
| validateTrigger | Set validate trigger event. Must be the sub set of `validateTrigger` in Form.Item | string \| string[] |
## Migrate to v4
@ -366,7 +366,7 @@ Components inside Form.Item with name property will turn into controlled mode, w
### Why can not call `ref` of Form at first time?
`ref` only receives the mounted instance. please ref React official doc: https://reactjs.org/docs/refs-and-the-dom.html#accessing-refs
`ref` only receives the mounted instance. please ref React official doc: <https://reactjs.org/docs/refs-and-the-dom.html#accessing-refs>
### Why `resetFields` will re-mount component?

View File

@ -20,8 +20,8 @@ cover: https://gw.alipayobjects.com/zos/alicdn/ORmcdeaoO/Form.svg
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| component | 设置 Form 渲染元素,为 `false` 则不创建 DOM 节点 | ComponentType \| false | form | |
| colon | 配置 Form.Item 的 `colon` 的默认值。表示是否显示 label 后面的冒号 (只有在属性 layout 为 horizontal 时有效) | boolean | true | |
| component | 设置 Form 渲染元素,为 `false` 则不创建 DOM 节点 | ComponentType \| false | form | |
| fields | 通过状态管理(如 redux控制表单字段如非强需求不推荐使用。查看[示例](#components-form-demo-global-state) | [FieldData](#FieldData)\[] | - | |
| form | 经 `Form.useForm()` 创建的 form 控制实例,不提供时会自动创建 | [FormInstance](#FormInstance) | - | |
| initialValues | 表单默认值,只有初始化以及重置时生效 | object | - | |
@ -34,11 +34,11 @@ cover: https://gw.alipayobjects.com/zos/alicdn/ORmcdeaoO/Form.svg
| scrollToFirstError | 提交失败自动滚动到第一个错误字段 | boolean | false | |
| size | 设置字段组件的尺寸(仅限 antd 组件) | `small` \| `middle` \| `large` | - | |
| validateMessages | 验证提示模板,说明[见下](#validateMessages) | [ValidateMessages](https://github.com/react-component/field-form/blob/master/src/utils/messages.ts) | - | |
| validateTrigger | 统一设置字段校验规则 | string \| string[] | `onChange` | 4.3.0 |
| validateTrigger | 统一设置字段校验规则 | string \| string\[] | `onChange` | 4.3.0 |
| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 labelCol | [object](/components/grid/#Col) | - | |
| onFieldsChange | 字段更新时触发回调事件 | function(changedFields, allFields) | - | |
| onFinish | 提交表单且数据验证成功后回调事件 | function(values) | - | |
| onFinishFailed | 提交表单且数据验证失败后回调事件 | function({ values, errorFields, outOfDate }) | - | |
| onFieldsChange | 字段更新时触发回调事件 | function(changedFields, allFields) | - | |
| onValuesChange | 字段值更新时触发回调事件 | function(changedValues, allValues) | - | |
### validateMessages
@ -74,33 +74,33 @@ const validateMessages = {
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| colon | 配合 `label` 属性使用,表示是否显示 `label` 后面的冒号 | boolean | true | |
| dependencies | 设置依赖字段,说明[见下](#dependencies) | [NamePath](#NamePath)[] | - | |
| dependencies | 设置依赖字段,说明[见下](#dependencies) | [NamePath](#NamePath)\[] | - | |
| extra | 额外的提示信息,和 `help` 类似,当需要错误信息和提示文案同时出现时,可以使用这个。 | ReactNode | - | |
| getValueFromEvent | 设置如何将 event 的值转换成字段值 | (..args: any[]) => any | - | |
| getValueFromEvent | 设置如何将 event 的值转换成字段值 | (..args: any\[]) => any | - | |
| getValueProps | 为子元素添加额外的属性 | (value: any) => any | - | 4.2.0 |
| hasFeedback | 配合 `validateStatus` 属性使用,展示校验状态图标,建议只配合 Input 组件使用 | boolean | false | |
| help | 提示信息,如不设置,则会根据校验规则自动生成 | ReactNode | - | |
| hidden | 是否隐藏字段(依然会收集和校验字段) | boolean | false | |
| htmlFor | 设置子元素 label `htmlFor` 属性 | string | - | |
| initialValue | 设置子元素默认值,如果与 Form 的 `initialValues` 冲突则以 Form 为准 | string | - | 4.2.0 |
| noStyle | 为 `true` 时不带样式,作为纯字段控件使用 | boolean | false | |
| label | `label` 标签的文本 | ReactNode | - | |
| labelAlign | 标签文本对齐方式 | `left` \| `right` | `right` | |
| labelCol | `label` 标签布局,同 `<Col>` 组件,设置 `span` `offset` 值,如 `{span: 3, offset: 12}``sm: {span: 3, offset: 12}`。你可以通过 Form 的 `labelCol` 进行统一设置,,不会作用于嵌套 Item。当和 Form 同时设置时,以 Item 为准 | [object](/components/grid/#Col) | - | |
| messageVariables | 默认验证字段的信息 | Record<string, string> | - | 4.7.0 |
| messageVariables | 默认验证字段的信息 | Record&lt;string, string> | - | 4.7.0 |
| name | 字段名,支持数组 | [NamePath](#NamePath) | - | |
| preserve | 当字段被删除时保留字段值 | boolean | true | 4.4.0 |
| normalize | 组件获取值后进行转换,再放入 Form 中 | (value, prevValue, prevValues) => any | - | |
| noStyle | 为 `true` 时不带样式,作为纯字段控件使用 | boolean | false | |
| preserve | 当字段被删除时保留字段值 | boolean | true | 4.4.0 |
| required | 必填样式设置。如不设置,则会根据校验规则自动生成 | boolean | false | |
| rules | 校验规则,设置字段的校验逻辑。点击[此处](#components-form-demo-basic)查看示例 | [Rule](#Rule)[] | - | |
| rules | 校验规则,设置字段的校验逻辑。点击[此处](#components-form-demo-basic)查看示例 | [Rule](#Rule)\[] | - | |
| shouldUpdate | 自定义字段更新逻辑,说明[见下](#shouldUpdate) | boolean \| (prevValue, curValue) => boolean | false | |
| tooltip | 配置提示信息 | ReactNode \| [TooltipProps & { icon: ReactNode }](/components/tooltip#API) | - | 4.7.0 |
| trigger | 设置收集字段值变更的时机 | string | `onChange` | |
| validateFirst | 当某一规则校验不通过时,是否停止剩下的规则的校验。设置 `parallel` 时会并行校验 | boolean \| `parallel` | false | `parallel`: 4.5.0 |
| validateStatus | 校验状态,如不设置,则会根据校验规则自动生成,可选:'success' 'warning' 'error' 'validating' | string | - | |
| validateTrigger | 设置字段校验的时机 | string \| string[] | `onChange` | |
| validateTrigger | 设置字段校验的时机 | string \| string\[] | `onChange` | |
| valuePropName | 子节点的值的属性,如 Switch 的是 'checked'。该属性为 `getValueProps` 的封装,自定义 `getValueProps` 后会失效 | string | `value` | |
| wrapperCol | 需要为输入控件设置布局样式时,使用该属性,用法同 `labelCol`。你可以通过 Form 的 `wrapperCol` 进行统一设置,不会作用于嵌套 Item。当和 Form 同时设置时,以 Item 为准 | [object](/components/grid/#Col) | - | |
| hidden | 是否隐藏字段(依然会收集和校验字段) | boolean | false | |
被设置了 `name` 属性的 `Form.Item` 包装的控件,表单控件会自动添加 `value`(或 `valuePropName` 指定的其他属性) `onChange`(或 `trigger` 指定的其他属性),数据同步将被 Form 接管,这会导致以下结果:
@ -169,9 +169,9 @@ Form 通过增量更新方式,只更新被修改的字段相关组件以达到
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| children | 渲染函数 | (fields: Field\[], operation: { add, remove, move }) => React.ReactNode | - | |
| name | 字段名,支持数组 | [NamePath](#NamePath) | - | |
| children | 渲染函数 | (fields: Field[], operation: { add, remove, move }) => React.ReactNode | - | |
| rules | 校验规则,仅支持自定义规则。需要配合 [ErrorList](#Form.ErrorList) 一同使用。 | { validator, message }[] | - | 4.7.0 |
| rules | 校验规则,仅支持自定义规则。需要配合 [ErrorList](#Form.ErrorList) 一同使用。 | { validator, message }\[] | - | 4.7.0 |
```tsx
<Form.List>
@ -192,19 +192,19 @@ Form 通过增量更新方式,只更新被修改的字段相关组件以达到
Form.List 渲染表单相关操作函数。
| 参数 | 说明 | 类型 | 默认值 |
| ------ | ---------- | -------------------------------------------------- | ------------------ |
| add | 新增表单项 | (defaultValue?: any, insertIndex?: number) => void | insertIndex: 4.6.0 |
| remove | 删除表单项 | (index: number \| number[]) => void | number[]: 4.5.0 |
| move | 移动表单项 | (from: number, to: number) => void | - |
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| add | 新增表单项 | (defaultValue?: any, insertIndex?: number) => void | insertIndex: 4.6.0 |
| move | 移动表单项 | (from: number, to: number) => void | - |
| remove | 删除表单项 | (index: number \| number\[]) => void | number\[]: 4.5.0 |
## Form.ErrorList
4.7.0 新增。错误展示组件,仅限配合 Form.List 的 rules 一同使用。
| 参数 | 说明 | 类型 | 默认值 |
| ------ | -------- | ----------- | ------ |
| errors | 错误列表 | ReactNode[] | - |
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| errors | 错误列表 | ReactNode\[] | - |
## Form.Provider
@ -232,20 +232,20 @@ Form.List 渲染表单相关操作函数。
| 名称 | 说明 | 类型 | 版本 |
| --- | --- | --- | --- |
| getFieldError | 获取对应字段名的错误信息 | (name: [NamePath](#NamePath)) => string\[] | |
| getFieldInstance | 获取对应字段实例 | (name: [NamePath](#NamePath)) => any | 4.4.0 |
| getFieldsError | 获取一组字段名对应的错误信息,返回为数组形式 | (nameList?: [NamePath](#NamePath)\[]) => FieldError\[] | |
| getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回 | (nameList?: [NamePath](#NamePath)\[], filterFunc?: (meta: { touched: boolean, validating: boolean }) => boolean) => any | |
| getFieldValue | 获取对应字段名的值 | (name: [NamePath](#NamePath)) => any | |
| getFieldsValue | 获取一组字段名对应的值,会按照对应结构返回 | (nameList?: [NamePath](#NamePath)[], filterFunc?: (meta: { touched: boolean, validating: boolean }) => boolean) => any | |
| getFieldError | 获取对应字段名的错误信息 | (name: [NamePath](#NamePath)) => string[] | |
| getFieldsError | 获取一组字段名对应的错误信息,返回为数组形式 | (nameList?: [NamePath](#NamePath)[]) => FieldError[] | |
| isFieldsTouched | 检查一组字段是否被用户操作过,`allTouched` 为 `true` 时检查是否所有字段都被操作过 | (nameList?: [NamePath](#NamePath)\[], allTouched?: boolean) => boolean | |
| isFieldTouched | 检查对应字段是否被用户操作过 | (name: [NamePath](#NamePath)) => boolean | |
| isFieldsTouched | 检查一组字段是否被用户操作过,`allTouched` 为 `true` 时检查是否所有字段都被操作过 | (nameList?: [NamePath](#NamePath)[], allTouched?: boolean) => boolean | |
| isFieldValidating | 检查一组字段是否正在校验 | (name: [NamePath](#NamePath)) => boolean | |
| resetFields | 重置一组字段到 `initialValues` | (fields?: [NamePath](#NamePath)[]) => void | |
| scrollToField | 滚动到对应字段位置 | (name: [NamePath](#NamePath), options: [[ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)]) => void | |
| setFields | 设置一组字段状态 | (fields: [FieldData](#FieldData)[]) => void | |
| resetFields | 重置一组字段到 `initialValues` | (fields?: [NamePath](#NamePath)\[]) => void | |
| scrollToField | 滚动到对应字段位置 | (name: [NamePath](#NamePath), options: \[[ScrollOptions](https://github.com/stipsan/scroll-into-view-if-needed/tree/ece40bd9143f48caf4b99503425ecb16b0ad8249#options)]) => void | |
| setFields | 设置一组字段状态 | (fields: [FieldData](#FieldData)\[]) => void | |
| setFieldsValue | 设置表单的值 | (values) => void | |
| submit | 提交表单,与点击 `submit` 按钮效果相同 | () => void | |
| validateFields | 触发表单验证 | (nameList?: [NamePath](#NamePath)[]) => Promise | |
| validateFields | 触发表单验证 | (nameList?: [NamePath](#NamePath)\[]) => Promise | |
#### validateFields 返回示例
@ -285,13 +285,13 @@ validateFields()
#### FieldData
| 名称 | 说明 | 类型 |
| ---------- | ---------------- | ----------------------- |
| touched | 是否被用户操作过 | boolean |
| validating | 是否正在校验 | boolean |
| errors | 错误信息 | string[] |
| name | 字段名称 | [NamePath](#NamePath)[] |
| value | 字段对应值 | any |
| 名称 | 说明 | 类型 |
| --- | --- | --- |
| errors | 错误信息 | string\[] |
| name | 字段名称 | [NamePath](#NamePath)\[] |
| touched | 是否被用户操作过 | boolean |
| validating | 是否正在校验 | boolean |
| value | 字段对应值 | any |
#### Rule
@ -303,7 +303,7 @@ type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
| 名称 | 说明 | 类型 |
| --- | --- | --- |
| enum | 是否匹配枚举中的值(需要将 `type` 设置为 `enum` | any[] |
| enum | 是否匹配枚举中的值(需要将 `type` 设置为 `enum` | any\[] |
| len | string 类型时为字符串长度number 类型时为确定数字; array 类型时为数组长度 | number |
| max | 必须设置 `type`string 类型为字符串最大长度number 类型时为最大值array 类型时为数组最大长度 | number |
| message | 错误信息,不设置时会通过[模板](#validateMessages)自动生成 | string |
@ -312,9 +312,9 @@ type Rule = RuleConfig | ((form: FormInstance) => RuleConfig);
| required | 是否为必选字段 | boolean |
| transform | 将字段值转换成目标值后进行校验 | (value) => any |
| type | 类型,常见有 `string` \|`number` \|`boolean` \|`url` \| `email`。更多请参考[此处](https://github.com/yiminghe/async-validator#type) | string |
| validateTrigger | 设置触发验证时机,必须是 Form.Item 的 `validateTrigger` 的子集 | string \| string\[] |
| validator | 自定义校验,接收 Promise 作为返回值。[示例](#components-form-demo-register)参考 | ([rule](#Rule), value) => Promise |
| whitespace | 如果字段仅包含空格则校验不通过 | boolean |
| validateTrigger | 设置触发验证时机,必须是 Form.Item 的 `validateTrigger` 的子集 | string \| string[] |
## 从 v3 升级到 v4
@ -368,7 +368,7 @@ validator(rule, value, callback) => {
### 为什么第一次调用 `ref` 的 From 为空?
`ref` 仅在节点被加载时才会被赋值,请参考 React 官方文档https://reactjs.org/docs/refs-and-the-dom.html#accessing-refs
`ref` 仅在节点被加载时才会被赋值,请参考 React 官方文档:<https://reactjs.org/docs/refs-and-the-dom.html#accessing-refs>
### 为什么 `resetFields` 会重新 mount 组件?

View File

@ -9,6 +9,7 @@
.@{ant-prefix}-input-affix-wrapper {
&,
&:hover {
background-color: @background-color;
border-color: @border-color;
}
@ -18,16 +19,15 @@
}
}
.@{ant-prefix}-input {
&:not(&-disabled) {
background-color: @background-color;
}
.@{ant-prefix}-input-disabled {
background-color: @input-disabled-bg;
border-color: @input-border-color;
}
.@{ant-prefix}-input-affix-wrapper {
&:not(&-disabled) {
background-color: @background-color;
}
.@{ant-prefix}-input-affix-wrapper-disabled {
background-color: @input-disabled-bg;
border-color: @input-border-color;
input:focus {
box-shadow: none !important;
}

View File

@ -137,6 +137,7 @@
//select
.@{ant-prefix}-select:not(.@{ant-prefix}-select-borderless) {
.@{ant-prefix}-select-selector {
background-color: @form-warning-input-bg;
border-color: @warning-color !important;
}
&.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,
@ -148,12 +149,14 @@
//input-number, timepicker
.@{ant-prefix}-input-number,
.@{ant-prefix}-picker {
background-color: @form-warning-input-bg;
border-color: @warning-color;
&-focused,
&:focus {
.active(@warning-color);
}
&:not([disabled]):hover {
background-color: @form-warning-input-bg;
border-color: @warning-color;
}
}
@ -175,6 +178,7 @@
//select
.@{ant-prefix}-select:not(.@{ant-prefix}-select-borderless) {
.@{ant-prefix}-select-selector {
background-color: @form-error-input-bg;
border-color: @error-color !important;
}
&.@{ant-prefix}-select-open .@{ant-prefix}-select-selector,
@ -200,17 +204,34 @@
//input-number, timepicker
.@{ant-prefix}-input-number,
.@{ant-prefix}-picker {
background-color: @form-error-input-bg;
border-color: @error-color;
&-focused,
&:focus {
.active(@error-color);
}
&:not([disabled]):hover {
background-color: @form-error-input-bg;
border-color: @error-color;
}
}
.@{ant-prefix}-mention-wrapper {
.@{ant-prefix}-mention-editor {
&,
&:not([disabled]):hover {
background-color: @form-error-input-bg;
border-color: @error-color;
}
}
&.@{ant-prefix}-mention-active:not([disabled]) .@{ant-prefix}-mention-editor,
.@{ant-prefix}-mention-editor:not([disabled]):focus {
.active(@error-color);
}
}
.@{ant-prefix}-cascader-picker:focus .@{ant-prefix}-cascader-input {
background-color: @form-error-input-bg;
.active(@error-color);
}

View File

@ -87,11 +87,11 @@ If the Ant Design grid layout component does not meet your needs, you can use th
### Row
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| align | Vertical alignment | `top` \| `middle` \| `bottom` | `top` | |
| Property | Description | Type | Default | Version | |
| --- | --- | --- | --- | --- | --- |
| align | Vertical alignment | `top` \| `middle` \| `bottom` | `top` | | |
| gutter | Spacing between grids, could be a number or a object like { xs: 8, sm: 16, md: 24}. Or you can use array to make horizontal and vertical spacing work at the same time `[horizontal, vertical]` | number \| object \| array | 0 | | |
| justify | Horizontal arrangement | `start` \| `end` \| `center` \| `space-around` \| `space-between` | `start` | |
| justify | Horizontal arrangement | `start` \| `end` \| `center` \| `space-around` \| `space-between` | `start` | | |
### Col

View File

@ -14,7 +14,7 @@ npm install --save @ant-design/icons
## List of icons
```__react
```_\_react
import IconDisplay from 'site/theme/template/IconDisplay';
ReactDOM.render(<IconDisplay />, mountNode);
```
@ -45,7 +45,7 @@ import { StarOutlined, StarFilled, StarTwoTone } from '@ant-design/icons';
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| component | The component used for the root node | ComponentType<CustomIconComponentProps\> | - | |
| component | The component used for the root node | ComponentType&lt;CustomIconComponentProps> | - | |
| rotate | Rotate degrees (not working in IE9) | number | - | |
| spin | Rotate icon with animation | boolean | false | |
| style | The style properties of icon, like `fontSize` and `color` | CSSProperties | - | |
@ -113,7 +113,7 @@ The following options are available:
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| extraCommonProps | Define extra properties to the component | { \[key: string]: any } | {} | |
| scriptUrl | The URL generated by [iconfont.cn](http://iconfont.cn/) project. Support `string[]` after `@ant-design/icons@4.1.0` | string \| string[] | - | |
| scriptUrl | The URL generated by [iconfont.cn](http://iconfont.cn/) project. Support `string[]` after `@ant-design/icons@4.1.0` | string \| string\[] | - | |
The property `scriptUrl` should be set to import the SVG sprite symbols.

View File

@ -19,7 +19,7 @@ npm install --save @ant-design/icons
## 图标列表
```__react
```_\_react
import IconDisplay from 'site/theme/template/IconDisplay';
ReactDOM.render(<IconDisplay />, mountNode);
```
@ -52,7 +52,7 @@ import { StarOutlined, StarFilled, StarTwoTone } from '@ant-design/icons';
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| component | 控制如何渲染图标,通常是一个渲染根标签为 `<svg>` 的 React 组件 | ComponentType<CustomIconComponentProps\> | - | |
| component | 控制如何渲染图标,通常是一个渲染根标签为 `<svg>` 的 React 组件 | ComponentType&lt;CustomIconComponentProps> | - | |
| rotate | 图标旋转角度IE9 无效) | number | - | |
| spin | 是否有旋转动画 | boolean | false | |
| style | 设置图标的样式,例如 `fontSize``color` | CSSProperties | - | |
@ -108,7 +108,7 @@ options 的配置项如下:
| 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| extraCommonProps | 给所有的 `svg` 图标 `<Icon />` 组件设置额外的属性 | { \[key: string]: any } | {} | |
| scriptUrl | [iconfont.cn](http://iconfont.cn/) 项目在线生成的 js 地址,`@ant-design/icons@4.1.0` 之后支持 `string[]` 类型 | string \| string[] | - | |
| scriptUrl | [iconfont.cn](http://iconfont.cn/) 项目在线生成的 js 地址,`@ant-design/icons@4.1.0` 之后支持 `string[]` 类型 | string \| string\[] | - | |
`scriptUrl` 都设置有效的情况下,组件在渲染前会自动引入 [iconfont.cn](http://iconfont.cn/) 项目中的图标符号集,无需手动引入。
@ -148,10 +148,10 @@ ReactDOM.render(<Icon component={MessageSvg} />, mountNode);
`Icon` 中的 `component` 组件的接受的属性如下:
| 字段 | 说明 | 类型 | 只读值 | 版本 |
| --------- | ----------------------- | ---------------- | -------------- | ---- |
| className | 计算后的 `svg` 类名 | string | - | |
| fill | `svg` 元素填充的颜色 | string | `currentColor` | |
| height | `svg` 元素高度 | string \| number | `1em` | |
| style | 计算后的 `svg` 元素样式 | CSSProperties | - | |
| width | `svg` 元素宽度 | string \| number | `1em` | |
| 字段 | 说明 | 类型 | 只读值 | 版本 |
| --- | --- | --- | --- | --- |
| className | 计算后的 `svg` 类名 | string | - | |
| fill | `svg` 元素填充的颜色 | string | `currentColor` | |
| height | `svg` 元素高度 | string \| number | `1em` | |
| style | 计算后的 `svg` 元素样式 | CSSProperties | - | |
| width | `svg` 元素宽度 | string \| number | `1em` | |

View File

@ -35,4 +35,4 @@ Previewable image.
}
```
Other attributes [<img\>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes)
Other attributes [&lt;img>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes)

View File

@ -36,4 +36,4 @@ cover: https://gw.alipayobjects.com/zos/antfincdn/D1dXz9PZqa/image.svg
}
```
其他属性见 [<img\>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes)
其他属性见 [&lt;img>](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#Attributes)

View File

@ -16,28 +16,28 @@ When a numeric value needs to be provided.
| Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- |
| autoFocus | If get focus when component mounted | boolean | false | - |
| decimalSeparator | Decimal separator | string | - | - |
| defaultValue | The initial value | number | - | - |
| disabled | If disable the input | boolean | false | - |
| readOnly | If readonly the input | boolean | false | - |
| formatter | Specifies the format of the value presented | function(value: number \| string): string | - | - |
| max | The max value | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) | - |
| min | The min value | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) | - |
| parser | Specifies the value extracted from formatter | function(string): number | - | - |
| precision | The precision of input value | number | - | - |
| decimalSeparator | Decimal separator | string | - | - |
| readOnly | If readonly the input | boolean | false | - |
| size | The height of input box | `large` \| `middle` \| `small` | - | - |
| step | The number to which the current value is increased or decreased. It can be an integer or decimal | number \| string | 1 | - |
| value | The current value | number | - | - |
| onChange | The callback triggered when the value is changed | function(value: number \| string) | - | - |
| onPressEnter | The callback function that is triggered when Enter key is pressed | function(e) | - | - |
| onStep | The callback function that is triggered when click up or down buttons | `(value: number, info: { offset: number, type: 'up' | 'down' }) => void` | - | 4.7.0 |
| onStep | The callback function that is triggered when click up or down buttons | (value: number, info: { offset: number, type: 'up' \| 'down' }) => void | - | 4.7.0 |
## Methods
| Name | Description |
| ------- | ------------ |
| blur() | Remove focus |
| focus() | Get focus |
| Name | Description |
| --- | --- |
| blur() | Remove focus |
| focus() | Get focus |
## Notes

View File

@ -19,25 +19,25 @@ cover: https://gw.alipayobjects.com/zos/alicdn/XOS8qZ0kU/InputNumber.svg
| 成员 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- |
| autoFocus | 自动获取焦点 | boolean | false | - |
| decimalSeparator | 小数点 | string | - | - |
| defaultValue | 初始值 | number | - | - |
| disabled | 禁用 | boolean | false | - |
| readOnly | 只读 | boolean | false | - |
| formatter | 指定输入框展示值的格式 | function(value: number \| string): string | - | - |
| max | 最大值 | number | [Number.MAX_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER) | - |
| min | 最小值 | number | [Number.MIN_SAFE_INTEGER](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER) | - |
| parser | 指定从 `formatter` 里转换回数字的方式,和 `formatter` 搭配使用 | function(string): number | - | - |
| precision | 数值精度 | number | - | - |
| decimalSeparator | 小数点 | string | - | - |
| readOnly | 只读 | boolean | false | - |
| size | 输入框大小 | `large` \| `middle` \| `small` | - | - |
| step | 每次改变步数,可以为小数 | number \| string | 1 | - |
| value | 当前值 | number | - | - |
| onChange | 变化回调 | function(value: number \| string) | - | - |
| onPressEnter | 按下回车的回调 | function(e) | - | - |
| onStep | 点击上下箭头的回调 | `(value: number, info: { offset: number, type: 'up' | 'down' }) => void` | - | 4.7.0 |
| onStep | 点击上下箭头的回调 | (value: number, info: { offset: number, type: 'up' \| 'down' }) => void | - | 4.7.0 |
## 方法
| 名称 | 描述 |
| ------- | -------- |
| blur() | 移除焦点 |
| 名称 | 描述 |
| --- | --- |
| blur() | 移除焦点 |
| focus() | 获取焦点 |

View File

@ -112,20 +112,18 @@ class ClearableLabeledInput extends React.Component<ClearableInputProps> {
const prefixNode = prefix ? <span className={`${prefixCls}-prefix`}>{prefix}</span> : null;
const affixWrapperCls = classNames(
`${prefixCls}-affix-wrapper`,
{
[`${prefixCls}-affix-wrapper-focused`]: focused,
[`${prefixCls}-affix-wrapper-disabled`]: disabled,
[`${prefixCls}-affix-wrapper-sm`]: size === 'small',
[`${prefixCls}-affix-wrapper-lg`]: size === 'large',
[`${prefixCls}-affix-wrapper-input-with-clear-btn`]: suffix && allowClear && value,
[`${prefixCls}-affix-wrapper-rtl`]: direction === 'rtl',
[`${prefixCls}-affix-wrapper-readonly`]: readOnly,
[`${prefixCls}-affix-wrapper-borderless`]: !bordered,
},
className,
);
const affixWrapperCls = classNames(`${prefixCls}-affix-wrapper`, {
[`${prefixCls}-affix-wrapper-focused`]: focused,
[`${prefixCls}-affix-wrapper-disabled`]: disabled,
[`${prefixCls}-affix-wrapper-sm`]: size === 'small',
[`${prefixCls}-affix-wrapper-lg`]: size === 'large',
[`${prefixCls}-affix-wrapper-input-with-clear-btn`]: suffix && allowClear && value,
[`${prefixCls}-affix-wrapper-rtl`]: direction === 'rtl',
[`${prefixCls}-affix-wrapper-readonly`]: readOnly,
[`${prefixCls}-affix-wrapper-borderless`]: !bordered,
// https://github.com/ant-design/ant-design/issues/27258
[`${className}`]: !allowClear && className,
});
return (
<span
ref={this.containerRef}

View File

@ -210,6 +210,8 @@ class Input extends React.Component<InputProps, InputState> {
setValue(value: string, callback?: () => void) {
if (this.props.value === undefined) {
this.setState({ value }, callback);
} else {
callback?.();
}
}

View File

@ -4,8 +4,8 @@ import omit from 'omit.js';
import classNames from 'classnames';
import ClearableLabeledInput from './ClearableLabeledInput';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import SizeContext, { SizeType } from '../config-provider/SizeContext';
import { fixControlledValue, resolveOnChange } from './Input';
import SizeContext, { SizeType } from '../config-provider/SizeContext';
export interface TextAreaProps extends RcTextAreaProps {
allowClear?: boolean;
@ -79,18 +79,18 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
};
renderTextArea = (prefixCls: string, bordered: boolean, size?: SizeType) => {
const { size: customizeSize } = this.props;
const { showCount, className, style, size: customizeSize } = this.props;
return (
<RcTextArea
{...omit(this.props, ['allowClear', 'bordered', 'showCount', 'size'])}
className={classNames(
{
[`${prefixCls}-borderless`]: !bordered,
[`${prefixCls}-sm`]: size === 'small' || customizeSize === 'small',
[`${prefixCls}-lg`]: size === 'large' || customizeSize === 'large',
},
this.props.className,
)}
className={classNames({
[`${prefixCls}-borderless`]: !bordered,
[className!]: className && !showCount,
[`${prefixCls}-sm`]: size === 'small' || customizeSize === 'small',
[`${prefixCls}-lg`]: size === 'large' || customizeSize === 'large',
})}
style={showCount ? null : style}
prefixCls={prefixCls}
onChange={this.handleChange}
ref={this.saveTextArea}
@ -105,40 +105,60 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
bordered = true,
showCount = false,
maxLength,
className,
style,
} = this.props;
const prefixCls = getPrefixCls('input', customizePrefixCls);
// Max length value
const hasMaxLength = Number(maxLength) > 0;
value = hasMaxLength ? value.slice(0, maxLength) : value;
const valueLength = [...value].length;
const dataCount = `${valueLength}${hasMaxLength ? ` / ${maxLength}` : ''}`;
return (
<SizeContext.Consumer>
{size => (
<div
className={classNames(`${prefixCls}-textarea`, {
[`${prefixCls}-textarea-show-count`]: showCount,
[`${prefixCls}-textarea-rtl`]: direction === 'rtl',
})}
{...(showCount ? { 'data-count': dataCount } : {})}
>
<ClearableLabeledInput
size={size}
{...this.props}
prefixCls={prefixCls}
direction={direction}
inputType="text"
value={value}
element={this.renderTextArea(prefixCls, bordered, size)}
handleReset={this.handleReset}
ref={this.saveClearableInput}
triggerFocus={this.focus}
bordered={bordered}
/>
</div>
)}
</SizeContext.Consumer>
// TextArea
const textareaNode = (size?: SizeType) => (
<ClearableLabeledInput
{...this.props}
prefixCls={prefixCls}
direction={direction}
inputType="text"
value={value}
element={this.renderTextArea(prefixCls, bordered, size)}
handleReset={this.handleReset}
ref={this.saveClearableInput}
triggerFocus={this.focus}
bordered={bordered}
/>
);
// Only show text area wrapper when needed
if (showCount) {
const valueLength = [...value].length;
const dataCount = `${valueLength}${hasMaxLength ? ` / ${maxLength}` : ''}`;
return (
<SizeContext.Consumer>
{(size?: SizeType) => (
<div
className={classNames(
`${prefixCls}-textarea`,
{
[`${prefixCls}-textarea-rtl`]: direction === 'rtl',
},
`${prefixCls}-textarea-show-count`,
className,
)}
style={style}
data-count={dataCount}
>
{textareaNode(size)}
</div>
)}
</SizeContext.Consumer>
);
}
return <SizeContext.Consumer>{textareaNode}</SizeContext.Consumer>;
};
render() {

View File

@ -209,4 +209,11 @@ describe('Input.Search', () => {
wrapper.find('button').simulate('mousedown');
}).not.toThrow();
});
// https://github.com/ant-design/ant-design/issues/27258
it('Search with allowClear should have one className only', () => {
const wrapper = mount(<Search allowClear className="className" />);
expect(wrapper.find('.ant-input-group-wrapper').hasClass('className')).toBe(true);
expect(wrapper.find('.ant-input-affix-wrapper').hasClass('className')).toBe(false);
});
});

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