Merge pull request #19202 from ant-design/master

chore: master merge feature
This commit is contained in:
二货机器人 2019-10-14 11:19:20 +08:00 committed by GitHub
commit 8bb4613bff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 368 additions and 79 deletions

View File

@ -45,14 +45,15 @@ export default class Collapse extends React.Component<CollapseProps, any> {
renderExpandIcon = (panelProps: PanelProps = {}, prefixCls: string) => { renderExpandIcon = (panelProps: PanelProps = {}, prefixCls: string) => {
const { expandIcon } = this.props; const { expandIcon } = this.props;
const icon = expandIcon ? ( const icon = (expandIcon ? (
expandIcon(panelProps) expandIcon(panelProps)
) : ( ) : (
<Icon type="right" rotate={panelProps.isActive ? 90 : undefined} /> <Icon type="right" rotate={panelProps.isActive ? 90 : undefined} />
); )) as React.ReactNode;
return React.isValidElement(icon) return React.isValidElement(icon)
? React.cloneElement(icon as any, { ? React.cloneElement(icon as any, {
className: `${prefixCls}-arrow`, className: classNames(icon.props.className, `${prefixCls}-arrow`),
}) })
: icon; : icon;
}; };

View File

@ -27,6 +27,22 @@ describe('Collapse', () => {
expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.render()).toMatchSnapshot();
}); });
it('should keep the className of the expandIcon', () => {
const wrapper = mount(
<Collapse
expandIcon={() => (
<button type="button" className="custom-expandicon-classname">
action
</button>
)}
>
<Collapse.Panel header="header" />
</Collapse>,
);
expect(wrapper.find('.custom-expandicon-classname').exists()).toBe(true);
});
it('should render extra node of panel', () => { it('should render extra node of panel', () => {
const wrapper = mount( const wrapper = mount(
<Collapse> <Collapse>

View File

@ -70,7 +70,7 @@
.@{collapse-prefix-cls}-arrow { .@{collapse-prefix-cls}-arrow {
right: @padding-md; right: @padding-md;
left: initial; left: auto;
} }
} }
} }

View File

@ -0,0 +1,30 @@
import createReactContext from '@ant-design/create-react-context';
import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty';
import { Locale } from '../locale-provider';
export interface CSPConfig {
nonce?: string;
}
export interface ConfigConsumerProps {
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
rootPrefixCls?: string;
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => string;
renderEmpty: RenderEmptyHandler;
csp?: CSPConfig;
autoInsertSpaceInButton?: boolean;
locale?: Locale;
}
export const ConfigContext = createReactContext<ConfigConsumerProps>({
// We provide a default function for Context without provider
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls;
return `ant-${suffixCls}`;
},
renderEmpty: defaultRenderEmpty,
});
export const ConfigConsumer = ConfigContext.Consumer;

View File

@ -2,27 +2,13 @@
// SFC has specified a displayName, but not worked. // SFC has specified a displayName, but not worked.
/* eslint-disable react/display-name */ /* eslint-disable react/display-name */
import * as React from 'react'; import * as React from 'react';
import createReactContext from '@ant-design/create-react-context';
import defaultRenderEmpty, { RenderEmptyHandler } from './renderEmpty'; import { RenderEmptyHandler } from './renderEmpty';
import LocaleProvider, { Locale, ANT_MARK } from '../locale-provider'; import LocaleProvider, { Locale, ANT_MARK } from '../locale-provider';
import LocaleReceiver from '../locale-provider/LocaleReceiver'; import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { ConfigConsumer, ConfigContext, CSPConfig, ConfigConsumerProps } from './context';
export { RenderEmptyHandler }; export { RenderEmptyHandler, ConfigConsumer, CSPConfig, ConfigConsumerProps };
export interface CSPConfig {
nonce?: string;
}
export interface ConfigConsumerProps {
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
rootPrefixCls?: string;
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => string;
renderEmpty: RenderEmptyHandler;
csp?: CSPConfig;
autoInsertSpaceInButton?: boolean;
locale?: Locale;
}
export const configConsumerProps = [ export const configConsumerProps = [
'getPopupContainer', 'getPopupContainer',
@ -44,19 +30,6 @@ export interface ConfigProviderProps {
locale?: Locale; locale?: Locale;
} }
const ConfigContext = createReactContext<ConfigConsumerProps>({
// We provide a default function for Context without provider
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls;
return `ant-${suffixCls}`;
},
renderEmpty: defaultRenderEmpty,
});
export const ConfigConsumer = ConfigContext.Consumer;
class ConfigProvider extends React.Component<ConfigProviderProps> { class ConfigProvider extends React.Component<ConfigProviderProps> {
getPrefixCls = (suffixCls: string, customizePrefixCls?: string) => { getPrefixCls = (suffixCls: string, customizePrefixCls?: string) => {
const { prefixCls = 'ant' } = this.props; const { prefixCls = 'ant' } = this.props;

View File

@ -904,7 +904,7 @@ exports[`renders ./components/descriptions/demo/vertical-border.md correctly 1`]
</th> </th>
<th <th
class="ant-descriptions-item-label ant-descriptions-item-colon" class="ant-descriptions-item-label ant-descriptions-item-colon"
colspan="5" colspan="3"
> >
Usage Time Usage Time
</th> </th>
@ -920,7 +920,7 @@ exports[`renders ./components/descriptions/demo/vertical-border.md correctly 1`]
</td> </td>
<td <td
class="ant-descriptions-item-content" class="ant-descriptions-item-content"
colspan="5" colspan="3"
> >
2019-04-24 18:00:00 2019-04-24 18:00:00
</td> </td>

View File

@ -22,7 +22,7 @@ ReactDOM.render(
<Descriptions.Item label="Billing Mode">Prepaid</Descriptions.Item> <Descriptions.Item label="Billing Mode">Prepaid</Descriptions.Item>
<Descriptions.Item label="Automatic Renewal">YES</Descriptions.Item> <Descriptions.Item label="Automatic Renewal">YES</Descriptions.Item>
<Descriptions.Item label="Order time">2018-04-24 18:00:00</Descriptions.Item> <Descriptions.Item label="Order time">2018-04-24 18:00:00</Descriptions.Item>
<Descriptions.Item label="Usage Time" span={3}> <Descriptions.Item label="Usage Time" span={2}>
2019-04-24 18:00:00 2019-04-24 18:00:00
</Descriptions.Item> </Descriptions.Item>
<Descriptions.Item label="Status" span={3}> <Descriptions.Item label="Status" span={3}>

View File

@ -32,7 +32,7 @@ A Drawer is a panel that is typically overlaid on top of a page and slides in fr
| title | The title for Drawer. | string\|ReactNode | - | 3.7.0 | | title | The title for Drawer. | string\|ReactNode | - | 3.7.0 |
| visible | Whether the Drawer dialog is visible or not. | boolean | false | 3.7.0 | | visible | Whether the Drawer dialog is visible or not. | boolean | false | 3.7.0 |
| width | Width of the Drawer dialog. | string\|number | 256 | 3.7.0 | | width | Width of the Drawer dialog. | string\|number | 256 | 3.7.0 |
| height | placement is `top` or `bottom`, height of the Drawer dialog. | string\|number | - | 3.9.0 | | height | placement is `top` or `bottom`, height of the Drawer dialog. | string\|number | 256 | 3.9.0 |
| className | The class name of the container of the Drawer dialog. | string | - | 3.8.0 | | className | The class name of the container of the Drawer dialog. | string | - | 3.8.0 |
| zIndex | The `z-index` of the Drawer. | Number | 1000 | 3.7.0 | | zIndex | The `z-index` of the Drawer. | Number | 1000 | 3.7.0 |
| placement | The placement of the Drawer. | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | 3.7.0 | | placement | The placement of the Drawer. | 'top' \| 'right' \| 'bottom' \| 'left' | 'right' | 3.7.0 |

View File

@ -177,7 +177,7 @@ If you use `react@<15.3.0`, then, you can't use `getFieldDecorator` in stateless
| id | The unique identifier is required. support [nested fields format](https://github.com/react-component/form/pull/48). | string | | | | id | The unique identifier is required. support [nested fields format](https://github.com/react-component/form/pull/48). | string | | |
| options.getValueFromEvent | Specify how to get value from event or other onChange arguments | function(..args) | [reference](https://github.com/react-component/form#option-object) | | | options.getValueFromEvent | Specify how to get value from event or other onChange arguments | function(..args) | [reference](https://github.com/react-component/form#option-object) | |
| options.getValueProps | Get the component props according to field value. | function(value): any | [reference](https://github.com/react-component/form#option-object) | 3.9.0 | | options.getValueProps | Get the component props according to field value. | function(value): any | [reference](https://github.com/react-component/form#option-object) | 3.9.0 |
| options.initialValue | You can specify initial value, type, optional value of children node. (Note: Because `Form` will test equality with `===` internally, we recommend to use variable as `initialValue`, instead of literal) | | n/a | | | options.initialValue | You can specify initial value, type, optional value of children node. ([Note: Because `Form` will test equality with `===` internally, we recommend to use variable as `initialValue`, instead of literal](https://github.com/ant-design/ant-design/issues/4093)) | | n/a | |
| options.normalize | Normalize value to form component, [a select-all example](https://codepen.io/afc163/pen/JJVXzG?editors=001) | function(value, prevValue, allValues): any | - | | | options.normalize | Normalize value to form component, [a select-all example](https://codepen.io/afc163/pen/JJVXzG?editors=001) | function(value, prevValue, allValues): any | - | |
| options.preserve | Keep the field even if field removed | boolean | - | 3.12.0 | | options.preserve | Keep the field even if field removed | boolean | - | 3.12.0 |
| options.rules | Includes validation rules. Please refer to "Validation Rules" part for details. | object\[] | n/a | | | options.rules | Includes validation rules. Please refer to "Validation Rules" part for details. | object\[] | n/a | |

View File

@ -179,7 +179,7 @@ validateFields(['field1', 'field2'], options, (errors, values) => {
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| id | 必填输入控件唯一标志。支持嵌套式的[写法](https://github.com/react-component/form/pull/48)。 | string | | | | id | 必填输入控件唯一标志。支持嵌套式的[写法](https://github.com/react-component/form/pull/48)。 | string | | |
| options.getValueFromEvent | 可以把 onChange 的参数(如 event转化为控件的值 | function(..args) | [reference](https://github.com/react-component/form#option-object) | | | options.getValueFromEvent | 可以把 onChange 的参数(如 event转化为控件的值 | function(..args) | [reference](https://github.com/react-component/form#option-object) | |
| options.initialValue | 子节点的初始值,类型、可选值均由子节点决定(注意:由于内部校验时使用 `===` 判断是否变化,建议使用变量缓存所需设置的值而非直接使用字面量)) | | | | | options.initialValue | 子节点的初始值,类型、可选值均由子节点决定([注意:由于内部校验时使用 `===` 判断是否变化,建议使用变量缓存所需设置的值而非直接使用字面量](https://github.com/ant-design/ant-design/issues/4093)) | | | |
| options.normalize | 转换默认的 value 给控件,[一个选择全部的例子](https://codepen.io/afc163/pen/JJVXzG?editors=001) | function(value, prevValue, allValues): any | - | | | options.normalize | 转换默认的 value 给控件,[一个选择全部的例子](https://codepen.io/afc163/pen/JJVXzG?editors=001) | function(value, prevValue, allValues): any | - | |
| options.preserve | 即便字段不再使用,也保留该字段的值 | boolean | - | 3.12.0 | | options.preserve | 即便字段不再使用,也保留该字段的值 | boolean | - | 3.12.0 |
| options.rules | 校验规则,参考下方文档 | object\[] | | | | options.rules | 校验规则,参考下方文档 | object\[] | | |

View File

@ -6,6 +6,7 @@ import ResizeObserver from 'rc-resize-observer';
import calculateNodeHeight from './calculateNodeHeight'; import calculateNodeHeight from './calculateNodeHeight';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import raf from '../_util/raf'; import raf from '../_util/raf';
import warning from '../_util/warning';
export interface AutoSizeType { export interface AutoSizeType {
minRows?: number; minRows?: number;
@ -16,7 +17,9 @@ export type HTMLTextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement
export interface TextAreaProps extends HTMLTextareaProps { export interface TextAreaProps extends HTMLTextareaProps {
prefixCls?: string; prefixCls?: string;
/* deprecated, use autoSize instead */
autosize?: boolean | AutoSizeType; autosize?: boolean | AutoSizeType;
autoSize?: boolean | AutoSizeType;
onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>; onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;
} }
@ -84,11 +87,11 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
}; };
resizeTextarea = () => { resizeTextarea = () => {
const { autosize } = this.props; const autoSize = this.props.autoSize || this.props.autosize;
if (!autosize || !this.textAreaRef) { if (!autoSize || !this.textAreaRef) {
return; return;
} }
const { minRows, maxRows } = autosize as AutoSizeType; const { minRows, maxRows } = autoSize as AutoSizeType;
const textareaStyles = calculateNodeHeight(this.textAreaRef, false, minRows, maxRows); const textareaStyles = calculateNodeHeight(this.textAreaRef, false, minRows, maxRows);
this.setState({ textareaStyles, resizing: true }, () => { this.setState({ textareaStyles, resizing: true }, () => {
raf.cancel(this.resizeFrameId); raf.cancel(this.resizeFrameId);
@ -108,14 +111,20 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
renderTextArea = ({ getPrefixCls }: ConfigConsumerProps) => { renderTextArea = ({ getPrefixCls }: ConfigConsumerProps) => {
const { textareaStyles, resizing } = this.state; const { textareaStyles, resizing } = this.state;
const { prefixCls: customizePrefixCls, className, disabled, autosize } = this.props; const { prefixCls: customizePrefixCls, className, disabled, autoSize, autosize } = this.props;
const { ...props } = this.props; const { ...props } = this.props;
const otherProps = omit(props, ['prefixCls', 'onPressEnter', 'autosize']); const otherProps = omit(props, ['prefixCls', 'onPressEnter', 'autoSize', 'autosize']);
const prefixCls = getPrefixCls('input', customizePrefixCls); const prefixCls = getPrefixCls('input', customizePrefixCls);
const cls = classNames(prefixCls, className, { const cls = classNames(prefixCls, className, {
[`${prefixCls}-disabled`]: disabled, [`${prefixCls}-disabled`]: disabled,
}); });
warning(
autosize === undefined,
'Input.TextArea',
'autosize is deprecated, please use autoSize instead.',
);
const style = { const style = {
...props.style, ...props.style,
...textareaStyles, ...textareaStyles,
@ -127,7 +136,7 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
otherProps.value = otherProps.value || ''; otherProps.value = otherProps.value || '';
} }
return ( return (
<ResizeObserver onResize={this.resizeOnNextFrame} disabled={!autosize}> <ResizeObserver onResize={this.resizeOnNextFrame} disabled={!(autoSize || autosize)}>
<textarea <textarea
{...otherProps} {...otherProps}
className={cls} className={cls}

View File

@ -2021,7 +2021,7 @@ exports[`renders ./components/input/demo/textarea-resize.md correctly 1`] = `
class="ant-input" class="ant-input"
rows="4" rows="4"
> >
autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。ending autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。ending
</textarea> </textarea>
</div> </div>
`; `;

View File

@ -74,7 +74,7 @@ describe('TextArea', () => {
}); });
it('should auto calculate height according to content length', () => { it('should auto calculate height according to content length', () => {
const wrapper = mount(<TextArea value="" readOnly autosize />); const wrapper = mount(<TextArea value="" readOnly autoSize />);
const mockFunc = jest.spyOn(wrapper.instance(), 'resizeTextarea'); const mockFunc = jest.spyOn(wrapper.instance(), 'resizeTextarea');
wrapper.setProps({ value: '1111\n2222\n3333' }); wrapper.setProps({ value: '1111\n2222\n3333' });
jest.runAllTimers(); jest.runAllTimers();

View File

@ -7,11 +7,11 @@ title:
## zh-CN ## zh-CN
`autosize` 属性适用于 `textarea` 节点,并且只有高度会自动变化。另外 `autosize` 可以设定为一个对象,指定最小行数和最大行数。 `autoSize` 属性适用于 `textarea` 节点,并且只有高度会自动变化。另外 `autoSize` 可以设定为一个对象,指定最小行数和最大行数。
## en-US ## en-US
`autosize` prop for a `textarea` type of `Input` makes the height to automatically adjust based on the content. An options object can be provided to `autosize` to specify the minimum and maximum number of lines the textarea will automatically adjust. `autoSize` prop for a `textarea` type of `Input` makes the height to automatically adjust based on the content. An options object can be provided to `autoSize` to specify the minimum and maximum number of lines the textarea will automatically adjust.
```jsx ```jsx
import { Input } from 'antd'; import { Input } from 'antd';
@ -32,18 +32,18 @@ class Demo extends React.Component {
return ( return (
<div> <div>
<TextArea placeholder="Autosize height based on content lines" autosize /> <TextArea placeholder="Autosize height based on content lines" autoSize />
<div style={{ margin: '24px 0' }} /> <div style={{ margin: '24px 0' }} />
<TextArea <TextArea
placeholder="Autosize height with minimum and maximum number of lines" placeholder="Autosize height with minimum and maximum number of lines"
autosize={{ minRows: 2, maxRows: 6 }} autoSize={{ minRows: 2, maxRows: 6 }}
/> />
<div style={{ margin: '24px 0' }} /> <div style={{ margin: '24px 0' }} />
<TextArea <TextArea
value={value} value={value}
onChange={this.onChange} onChange={this.onChange}
placeholder="Controlled autosize" placeholder="Controlled autosize"
autosize={{ minRows: 3, maxRows: 5 }} autoSize={{ minRows: 3, maxRows: 5 }}
/> />
</div> </div>
); );

View File

@ -20,7 +20,7 @@ import { Input, Button } from 'antd';
const { TextArea } = Input; const { TextArea } = Input;
const defaultValue = const defaultValue =
'autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。autosize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autosize 可以设定为一个对象指定最小行数和最大行数。ending'; 'autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。autoSize 属性适用于 textarea 节点,并且只有高度会自动变化。另外 autoSize 可以设定为一个对象指定最小行数和最大行数。ending';
class Demo extends React.Component { class Demo extends React.Component {
state = { state = {
@ -38,7 +38,7 @@ class Demo extends React.Component {
> >
Auto Resize: {String(autoResize)} Auto Resize: {String(autoResize)}
</Button> </Button>
<TextArea rows={4} autosize={autoResize} defaultValue={defaultValue} /> <TextArea rows={4} autoSize={autoResize} defaultValue={defaultValue} />
</div> </div>
); );
} }

View File

@ -41,7 +41,7 @@ The rest of the props of Input are exactly the same as the original [input](http
| Property | Description | Type | Default | Version | | Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| autosize | Height autosize feature, can be set to `true|false` or an object `{ minRows: 2, maxRows: 6 }` | boolean\|object | false | | | autoSize | Height autosize feature, can be set to `true|false` or an object `{ minRows: 2, maxRows: 6 }` | boolean\|object | false | |
| defaultValue | The initial input content | string | | | | defaultValue | The initial input content | string | | |
| value | The input content value | string | | | | value | The input content value | string | | |
| onPressEnter | The callback function that is triggered when Enter key is pressed. | function(e) | | | | onPressEnter | The callback function that is triggered when Enter key is pressed. | function(e) | | |
@ -55,7 +55,7 @@ The rest of the props of `Input.TextArea` are the same as the original [textarea
| Property | Description | Type | Default | Version | | Property | Description | Type | Default | Version |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| enterButton | to show an enter button after input. This prop is conflict with addon. | boolean\|ReactNode | false | | | enterButton | to show an enter button after input. This prop is conflict with addon. | boolean\|ReactNode | false | |
| onSearch | The callback function that is triggered when you click on the search-icon or press Enter key. | function(value, event) | | | | onSearch | The callback function triggered when you click on the search-icon, the clear-icon or press the Enter key. | function(value, event) | | |
| loading | Search box with loading. | boolean | | | | loading | Search box with loading. | boolean | | |
Supports all props of `Input`. Supports all props of `Input`.

View File

@ -42,7 +42,7 @@ Input 的其他属性和 React 自带的 [input](https://facebook.github.io/reac
| 参数 | 说明 | 类型 | 默认值 | 版本 | | 参数 | 说明 | 类型 | 默认值 | 版本 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- |
| autosize | 自适应内容高度,可设置为 `true|false` 或对象:`{ minRows: 2, maxRows: 6 }` | boolean\|object | false | | | autoSize | 自适应内容高度,可设置为 `true|false` 或对象:`{ minRows: 2, maxRows: 6 }` | boolean\|object | false | |
| defaultValue | 输入框默认内容 | string | | | | defaultValue | 输入框默认内容 | string | | |
| value | 输入框内容 | string | | | | value | 输入框内容 | string | | |
| onPressEnter | 按下回车的回调 | function(e) | | | | onPressEnter | 按下回车的回调 | function(e) | | |

View File

@ -1124,7 +1124,7 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
</svg> </svg>
</i> </i>
<span> <span>
Navigtion Two Navigation Two
</span> </span>
</span> </span>
<i <i

View File

@ -75,7 +75,7 @@ class Sider extends React.Component {
title={ title={
<span> <span>
<Icon type="appstore" /> <Icon type="appstore" />
<span>Navigtion Two</span> <span>Navigation Two</span>
</span> </span>
} }
> >

View File

@ -239,12 +239,12 @@ class NameColumn extends Table.Column<User> {}
## Note ## Note
According to [React documentation](https://facebook.github.io/react/docs/lists-and-keys.html#keys), every child in array should be assigned a unique key. The values inside `dataSource` and `columns` should follow this in Table, and `dataSource[i].key` would be treated as key value default for `dataSource`. According to the [React documentation](https://facebook.github.io/react/docs/lists-and-keys.html#keys), every child in an array should be assigned a unique key. The values inside the Table's `dataSource` and `columns` should follow this rule. By default, `dataSource[i].key` will be treated as the key value for `dataSource`.
If `dataSource[i].key` is not provided, then you should specify the primary key of dataSource value via `rowKey`. If not, warnings like above will show in browser console.
![console warning](https://os.alipayobjects.com/rmsportal/luLdLvhPOiRpyss.png) ![console warning](https://os.alipayobjects.com/rmsportal/luLdLvhPOiRpyss.png)
If `dataSource[i].key` is not provided, then you should specify the primary key of dataSource value via `rowKey`, as shown below. If not, warnings like the one above will show in browser console.
```jsx ```jsx
// primary key is uid // primary key is uid
return <Table rowKey="uid" />; return <Table rowKey="uid" />;

View File

@ -243,12 +243,12 @@ class NameColumn extends Table.Column<User> {}
## 注意 ## 注意
按照 [React 的规范](https://facebook.github.io/react/docs/lists-and-keys.html#keys),所有的组件数组必须绑定 key。在 Table 中,`dataSource` 和 `columns` 里的数据值都需要指定 `key` 值。对于 `dataSource` 默认将每列数据的 `key` 属性作为唯一的标识。 按照 [React 的规范](https://zh-hans.reactjs.org/docs/lists-and-keys.html#keys),所有的数组组件必须绑定 `key`。在 Table 中,`dataSource` 和 `columns` 里的数据值都需要指定 `key` 值。对于 `dataSource` 默认将每列数据的 `key` 属性作为唯一的标识。
如果你的数据没有这个属性,务必使用 `rowKey` 来指定数据列的主键。若没有指定,控制台会出现以下的提示,表格组件也会出现各类奇怪的错误。
![控制台警告](https://os.alipayobjects.com/rmsportal/luLdLvhPOiRpyss.png) ![控制台警告](https://os.alipayobjects.com/rmsportal/luLdLvhPOiRpyss.png)
如果 `dataSource[i].key` 没有提供,你应该使用 `rowKey` 来指定 `dataSource` 的主键,如下所示。若没有指定,控制台会出现以上的提示,表格组件也会出现各类奇怪的错误。
```jsx ```jsx
// 比如你的数据主键是 uid // 比如你的数据主键是 uid
return <Table rowKey="uid" />; return <Table rowKey="uid" />;

View File

@ -13,7 +13,12 @@ import Tree, {
AntTreeNodeSelectedEvent, AntTreeNodeSelectedEvent,
AntTreeNode, AntTreeNode,
} from './Tree'; } from './Tree';
import { calcRangeKeys, getFullKeyList, convertDirectoryKeysToNodes } from './util'; import {
calcRangeKeys,
getFullKeyList,
convertDirectoryKeysToNodes,
getFullKeyListByTreeData,
} from './util';
import Icon from '../icon'; import Icon from '../icon';
export type ExpandAction = false | 'click' | 'doubleClick'; export type ExpandAction = false | 'click' | 'doubleClick';
@ -82,7 +87,11 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
// Expanded keys // Expanded keys
if (defaultExpandAll) { if (defaultExpandAll) {
this.state.expandedKeys = getFullKeyList(props.children); if (props.treeData) {
this.state.expandedKeys = getFullKeyListByTreeData(props.treeData);
} else {
this.state.expandedKeys = getFullKeyList(props.children);
}
} else if (defaultExpandParent) { } else if (defaultExpandParent) {
this.state.expandedKeys = conductExpandParent( this.state.expandedKeys = conductExpandParent(
expandedKeys || defaultExpandedKeys, expandedKeys || defaultExpandedKeys,

View File

@ -1,5 +1,189 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Directory Tree DirectoryTree should expend all when use treeData and defaultExpandAll is true 1`] = `
<ul
class="ant-tree ant-tree-directory"
role="tree"
unselectable="on"
>
<li
class="ant-tree-treenode-switcher-open"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<i
aria-label="icon: caret-down"
class="anticon anticon-caret-down ant-tree-switcher-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="caret-down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="Folder"
>
<span
class="ant-tree-iconEle ant-tree-icon__customize"
>
<i
aria-label="icon: folder-open"
class="anticon anticon-folder-open"
>
<svg
aria-hidden="true"
class=""
data-icon="folder-open"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M928 444H820V330.4c0-17.7-14.3-32-32-32H473L355.7 186.2a8.15 8.15 0 0 0-5.5-2.2H96c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h698c13 0 24.8-7.9 29.7-20l134-332c1.5-3.8 2.3-7.9 2.3-12 0-17.7-14.3-32-32-32zM136 256h188.5l119.6 114.4H748V444H238c-13 0-24.8 7.9-29.7 20L136 643.2V256zm635.3 512H159l103.3-256h612.4L771.3 768z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-title"
>
Folder
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
role="group"
>
<li
class="ant-tree-treenode-switcher-open"
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher_open"
>
<i
aria-label="icon: caret-down"
class="anticon anticon-caret-down ant-tree-switcher-icon"
>
<svg
aria-hidden="true"
class=""
data-icon="caret-down"
fill="currentColor"
focusable="false"
height="1em"
viewBox="0 0 1024 1024"
width="1em"
>
<path
d="M840.4 300H183.6c-19.7 0-30.7 20.8-18.5 35l328.4 380.8c9.4 10.9 27.5 10.9 37 0L858.9 335c12.2-14.2 1.2-35-18.5-35z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-open"
title="Folder2"
>
<span
class="ant-tree-iconEle ant-tree-icon__customize"
>
<i
aria-label="icon: folder-open"
class="anticon anticon-folder-open"
>
<svg
aria-hidden="true"
class=""
data-icon="folder-open"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M928 444H820V330.4c0-17.7-14.3-32-32-32H473L355.7 186.2a8.15 8.15 0 0 0-5.5-2.2H96c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h698c13 0 24.8-7.9 29.7-20l134-332c1.5-3.8 2.3-7.9 2.3-12 0-17.7-14.3-32-32-32zM136 256h188.5l119.6 114.4H748V444H238c-13 0-24.8 7.9-29.7 20L136 643.2V256zm635.3 512H159l103.3-256h612.4L771.3 768z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-title"
>
Folder2
</span>
</span>
<ul
class="ant-tree-child-tree ant-tree-child-tree-open"
data-expanded="true"
role="group"
>
<li
class=""
role="treeitem"
>
<span
class="ant-tree-switcher ant-tree-switcher-noop"
/>
<span
class="ant-tree-node-content-wrapper ant-tree-node-content-wrapper-normal"
title="File"
>
<span
class="ant-tree-iconEle ant-tree-icon__customize"
>
<i
aria-label="icon: file"
class="anticon anticon-file"
>
<svg
aria-hidden="true"
class=""
data-icon="file"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M854.6 288.6L639.4 73.4c-6-6-14.1-9.4-22.6-9.4H192c-17.7 0-32 14.3-32 32v832c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V311.3c0-8.5-3.4-16.7-9.4-22.7zM790.2 326H602V137.8L790.2 326zm1.8 562H232V136h302v216a42 42 0 0 0 42 42h216v494z"
/>
</svg>
</i>
</span>
<span
class="ant-tree-title"
>
File
</span>
</span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
`;
exports[`Directory Tree defaultExpandAll 1`] = ` exports[`Directory Tree defaultExpandAll 1`] = `
<ul <ul
class="ant-tree ant-tree-directory" class="ant-tree ant-tree-directory"

View File

@ -119,6 +119,30 @@ describe('Directory Tree', () => {
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();
}); });
it('DirectoryTree should expend all when use treeData and defaultExpandAll is true', () => {
const treeData = [
{
key: '0-0-0',
title: 'Folder',
children: [
{
title: 'Folder2',
key: '0-0-1',
children: [
{
title: 'File',
key: '0-0-2',
isLeaf: true,
},
],
},
],
},
];
const wrapper = render(createTree({ defaultExpandAll: true, treeData }));
expect(wrapper).toMatchSnapshot();
});
it('defaultExpandParent', () => { it('defaultExpandParent', () => {
const wrapper = render(createTree({ defaultExpandParent: true })); const wrapper = render(createTree({ defaultExpandParent: true }));
expect(wrapper).toMatchSnapshot(); expect(wrapper).toMatchSnapshot();

View File

@ -101,3 +101,15 @@ export function convertDirectoryKeysToNodes(
}); });
return nodes; return nodes;
} }
export function getFullKeyListByTreeData(treeData: any[], keys: any = []): any[] {
(treeData || []).forEach(item => {
if (item.children) {
keys.push(item.key);
keys.concat(getFullKeyListByTreeData(item.children, keys));
} else {
keys.push(item.key);
}
});
return keys;
}

View File

@ -125,7 +125,7 @@ class Editable extends React.Component<EditableProps, EditableState> {
onCompositionEnd={this.onCompositionEnd} onCompositionEnd={this.onCompositionEnd}
onBlur={this.onBlur} onBlur={this.onBlur}
aria-label={ariaLabel} aria-label={ariaLabel}
autosize autoSize
/> />
<Icon type="enter" className={`${prefixCls}-edit-content-confirm`} /> <Icon type="enter" className={`${prefixCls}-edit-content-confirm`} />
</div> </div>

View File

@ -12,6 +12,14 @@ Currently, there are many products and sites using Ant Design. If your solutions
--- ---
### Umi UI
The local R&D workbench for Umi projects, code based, visualization function as an aid, further improve project development efficiency.
[More](https://umijs.org/guide/umi-ui.html#%E2%9C%A8-%E7%89%B9%E6%80%A7)
![Umi UI](https://gw.alipayobjects.com/zos/antfincdn/Xyns37N5nY/6591859e-7c16-48f5-852f-7817803425e9.png)
### Ant Financial Technology ### Ant Financial Technology
Cloud-oriented financial services, used by financial institutions that benefit from customized business cloud computing services. It assists financial institutions to upgrade to a new financial restructuring, promotion of capacity platforms, data and technology. Cloud-oriented financial services, used by financial institutions that benefit from customized business cloud computing services. It assists financial institutions to upgrade to a new financial restructuring, promotion of capacity platforms, data and technology.

View File

@ -10,6 +10,14 @@ Ant Design 目前在外部也有许多产品实践,如果你的公司和产品
## 最佳实践 ## 最佳实践
### Umi UI
umi 项目的本地研发工作台,本地研发工作台。以代码为基础、可视化功能作为辅助,进一步提升项目研发效率。
[了解更多](https://umijs.org/zh/guide/umi-ui.html#%E2%9C%A8-%E7%89%B9%E6%80%A7)
![Umi UI](https://gw.alipayobjects.com/zos/antfincdn/Xyns37N5nY/6591859e-7c16-48f5-852f-7817803425e9.png)
### 蚂蚁金融科技 ### 蚂蚁金融科技
金融云是面向金融机构深度定制的行业云计算服务;助力金融机构向新金融转型升级,推动平台、数据和技术方面的能力全面对外开放。 金融云是面向金融机构深度定制的行业云计算服务;助力金融机构向新金融转型升级,推动平台、数据和技术方面的能力全面对外开放。

View File

@ -162,7 +162,7 @@
"babel-eslint": "^10.0.1", "babel-eslint": "^10.0.1",
"babel-plugin-add-react-displayname": "^0.0.5", "babel-plugin-add-react-displayname": "^0.0.5",
"bisheng": "^1.3.1-alpha.0", "bisheng": "^1.3.1-alpha.0",
"bisheng-plugin-antd": "^1.0.2", "bisheng-plugin-antd": "^1.3.1",
"bisheng-plugin-description": "^0.1.4", "bisheng-plugin-description": "^0.1.4",
"bisheng-plugin-react": "^1.0.0", "bisheng-plugin-react": "^1.0.0",
"bisheng-plugin-toc": "^0.4.4", "bisheng-plugin-toc": "^0.4.4",

View File

@ -93,7 +93,7 @@ module.exports = {
'app.footer.fengdie.slogan': 'Mobile web app builder', 'app.footer.fengdie.slogan': 'Mobile web app builder',
'app.footer.zhihu': 'Ant Design Blog', 'app.footer.zhihu': 'Ant Design Blog',
'app.footer.zhihu.xtech': 'Experience Cloud Blog', 'app.footer.zhihu.xtech': 'Experience Cloud Blog',
'app.footer.seeconf': 'Seeking Experience & Engineering Conference', 'app.footer.seeconf': 'Experience Tech Conference',
'app.footer.xtech': 'Ant Financial Experience Tech', 'app.footer.xtech': 'Ant Financial Experience Tech',
'app.footer.xtech.slogan': 'Experience The Beauty', 'app.footer.xtech.slogan': 'Experience The Beauty',
'app.publish.title': 'antd@3.0.0 has been released! 🎉 🎉 🎉', 'app.publish.title': 'antd@3.0.0 has been released! 🎉 🎉 🎉',

View File

@ -207,7 +207,7 @@
.text-wrapper { .text-wrapper {
min-height: 200px; min-height: 200px;
margin-top: 48px; margin-top: 48px;
padding: 0 16px; padding: 0;
h1 { h1 {
display: none; display: none;
} }
@ -221,6 +221,11 @@
min-width: 100%; min-width: 100%;
white-space: nowrap; white-space: nowrap;
text-align: center; text-align: center;
.banner-btn {
padding: 0 20px;
font-size: 14px;
}
} }
} }
} }

View File

@ -114,7 +114,10 @@ class MainContent extends Component {
} }
getMenuItems(footerNavIcons = {}) { getMenuItems(footerNavIcons = {}) {
const { themeConfig, intl: { locale } } = this.props; const {
themeConfig,
intl: { locale },
} = this.props;
const moduleData = getModuleData(this.props); const moduleData = getModuleData(this.props);
const menuItems = utils.getMenuItems( const menuItems = utils.getMenuItems(
moduleData, moduleData,
@ -159,7 +162,10 @@ class MainContent extends Component {
} }
getActiveMenuItem() { getActiveMenuItem() {
const { params: { children }, location } = this.props; const {
params: { children },
location,
} = this.props;
return ( return (
(children && children.replace('-cn', '')) || location.pathname.replace(/(^\/|-cn$)/g, '') (children && children.replace('-cn', '')) || location.pathname.replace(/(^\/|-cn$)/g, '')
); );
@ -290,7 +296,7 @@ class MainContent extends Component {
}); });
const menuChild = ( const menuChild = (
<Menu <Menu
inlineIndent="40" inlineIndent={40}
className="aside-container menu-site" className="aside-container menu-site"
mode="inline" mode="inline"
openKeys={openKeys} openKeys={openKeys}

View File

@ -73,7 +73,7 @@ class Footer extends React.Component {
{ {
title: 'Scaffolds', title: 'Scaffolds',
description: <FormattedMessage id="app.footer.scaffolds" />, description: <FormattedMessage id="app.footer.scaffolds" />,
url: 'https://scaffolds.ant.design', url: 'https://scaffold.ant.design',
openExternal: true, openExternal: true,
}, },
{ {
@ -142,7 +142,7 @@ class Footer extends React.Component {
icon: <Icon type="zhihu" style={{ color: '#0084ff' }} />, icon: <Icon type="zhihu" style={{ color: '#0084ff' }} />,
title: 'SEE Conf', title: 'SEE Conf',
description: <FormattedMessage id="app.footer.seeconf" />, description: <FormattedMessage id="app.footer.seeconf" />,
url: 'http://zhuanlan.zhihu.com/xtech', url: 'https://seeconf.antfin.com/',
openExternal: true, openExternal: true,
}, },
{ {
@ -402,8 +402,7 @@ class Footer extends React.Component {
bottom={ bottom={
<> <>
Made with <span style={{ color: '#fff' }}></span> by Made with <span style={{ color: '#fff' }}></span> by
{/* eslint-disable-next-line react/jsx-curly-brace-presence */} {/* eslint-disable-next-line react/jsx-curly-brace-presence */}{' '}
{' '}
<a target="_blank" rel="noopener noreferrer" href="https://xtech.antfin.com"> <a target="_blank" rel="noopener noreferrer" href="https://xtech.antfin.com">
<FormattedMessage id="app.footer.company" /> <FormattedMessage id="app.footer.company" />
</a> </a>

View File

@ -123,6 +123,11 @@ export default class Layout extends React.Component {
<Helmet encodeSpecialCharacters={false}> <Helmet encodeSpecialCharacters={false}>
<html lang={appLocale.locale === 'zh-CN' ? 'zh' : 'en'} /> <html lang={appLocale.locale === 'zh-CN' ? 'zh' : 'en'} />
<title>{title}</title> <title>{title}</title>
<link
rel="apple-touch-icon-precomposed"
sizes="144x144"
href="https://gw.alipayobjects.com/zos/antfincdn/UmVnt3t4T0/antd.png"
/>
<meta name="description" content={description} /> <meta name="description" content={description} />
<meta property="og:title" content={title} /> <meta property="og:title" content={title} />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />