mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-25 03:29:59 +08:00
Merge pull request #19202 from ant-design/master
chore: master merge feature
This commit is contained in:
commit
8bb4613bff
@ -45,14 +45,15 @@ export default class Collapse extends React.Component<CollapseProps, any> {
|
||||
|
||||
renderExpandIcon = (panelProps: PanelProps = {}, prefixCls: string) => {
|
||||
const { expandIcon } = this.props;
|
||||
const icon = expandIcon ? (
|
||||
const icon = (expandIcon ? (
|
||||
expandIcon(panelProps)
|
||||
) : (
|
||||
<Icon type="right" rotate={panelProps.isActive ? 90 : undefined} />
|
||||
);
|
||||
)) as React.ReactNode;
|
||||
|
||||
return React.isValidElement(icon)
|
||||
? React.cloneElement(icon as any, {
|
||||
className: `${prefixCls}-arrow`,
|
||||
className: classNames(icon.props.className, `${prefixCls}-arrow`),
|
||||
})
|
||||
: icon;
|
||||
};
|
||||
|
@ -27,6 +27,22 @@ describe('Collapse', () => {
|
||||
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', () => {
|
||||
const wrapper = mount(
|
||||
<Collapse>
|
||||
|
@ -70,7 +70,7 @@
|
||||
|
||||
.@{collapse-prefix-cls}-arrow {
|
||||
right: @padding-md;
|
||||
left: initial;
|
||||
left: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
30
components/config-provider/context.ts
Normal file
30
components/config-provider/context.ts
Normal 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;
|
@ -2,27 +2,13 @@
|
||||
// SFC has specified a displayName, but not worked.
|
||||
/* eslint-disable react/display-name */
|
||||
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 LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||
import { ConfigConsumer, ConfigContext, CSPConfig, ConfigConsumerProps } from './context';
|
||||
|
||||
export { RenderEmptyHandler };
|
||||
|
||||
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 { RenderEmptyHandler, ConfigConsumer, CSPConfig, ConfigConsumerProps };
|
||||
|
||||
export const configConsumerProps = [
|
||||
'getPopupContainer',
|
||||
@ -44,19 +30,6 @@ export interface ConfigProviderProps {
|
||||
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> {
|
||||
getPrefixCls = (suffixCls: string, customizePrefixCls?: string) => {
|
||||
const { prefixCls = 'ant' } = this.props;
|
||||
|
@ -904,7 +904,7 @@ exports[`renders ./components/descriptions/demo/vertical-border.md correctly 1`]
|
||||
</th>
|
||||
<th
|
||||
class="ant-descriptions-item-label ant-descriptions-item-colon"
|
||||
colspan="5"
|
||||
colspan="3"
|
||||
>
|
||||
Usage Time
|
||||
</th>
|
||||
@ -920,7 +920,7 @@ exports[`renders ./components/descriptions/demo/vertical-border.md correctly 1`]
|
||||
</td>
|
||||
<td
|
||||
class="ant-descriptions-item-content"
|
||||
colspan="5"
|
||||
colspan="3"
|
||||
>
|
||||
2019-04-24 18:00:00
|
||||
</td>
|
||||
|
@ -22,7 +22,7 @@ ReactDOM.render(
|
||||
<Descriptions.Item label="Billing Mode">Prepaid</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="Usage Time" span={3}>
|
||||
<Descriptions.Item label="Usage Time" span={2}>
|
||||
2019-04-24 18:00:00
|
||||
</Descriptions.Item>
|
||||
<Descriptions.Item label="Status" span={3}>
|
||||
|
@ -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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
@ -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 | | |
|
||||
| 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.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.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 | |
|
||||
|
@ -179,7 +179,7 @@ validateFields(['field1', 'field2'], options, (errors, values) => {
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 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.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.preserve | 即便字段不再使用,也保留该字段的值 | boolean | - | 3.12.0 |
|
||||
| options.rules | 校验规则,参考下方文档 | object\[] | | |
|
||||
|
@ -6,6 +6,7 @@ import ResizeObserver from 'rc-resize-observer';
|
||||
import calculateNodeHeight from './calculateNodeHeight';
|
||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||
import raf from '../_util/raf';
|
||||
import warning from '../_util/warning';
|
||||
|
||||
export interface AutoSizeType {
|
||||
minRows?: number;
|
||||
@ -16,7 +17,9 @@ export type HTMLTextareaProps = React.TextareaHTMLAttributes<HTMLTextAreaElement
|
||||
|
||||
export interface TextAreaProps extends HTMLTextareaProps {
|
||||
prefixCls?: string;
|
||||
/* deprecated, use autoSize instead */
|
||||
autosize?: boolean | AutoSizeType;
|
||||
autoSize?: boolean | AutoSizeType;
|
||||
onPressEnter?: React.KeyboardEventHandler<HTMLTextAreaElement>;
|
||||
}
|
||||
|
||||
@ -84,11 +87,11 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
|
||||
};
|
||||
|
||||
resizeTextarea = () => {
|
||||
const { autosize } = this.props;
|
||||
if (!autosize || !this.textAreaRef) {
|
||||
const autoSize = this.props.autoSize || this.props.autosize;
|
||||
if (!autoSize || !this.textAreaRef) {
|
||||
return;
|
||||
}
|
||||
const { minRows, maxRows } = autosize as AutoSizeType;
|
||||
const { minRows, maxRows } = autoSize as AutoSizeType;
|
||||
const textareaStyles = calculateNodeHeight(this.textAreaRef, false, minRows, maxRows);
|
||||
this.setState({ textareaStyles, resizing: true }, () => {
|
||||
raf.cancel(this.resizeFrameId);
|
||||
@ -108,14 +111,20 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
|
||||
|
||||
renderTextArea = ({ getPrefixCls }: ConfigConsumerProps) => {
|
||||
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 otherProps = omit(props, ['prefixCls', 'onPressEnter', 'autosize']);
|
||||
const otherProps = omit(props, ['prefixCls', 'onPressEnter', 'autoSize', 'autosize']);
|
||||
const prefixCls = getPrefixCls('input', customizePrefixCls);
|
||||
const cls = classNames(prefixCls, className, {
|
||||
[`${prefixCls}-disabled`]: disabled,
|
||||
});
|
||||
|
||||
warning(
|
||||
autosize === undefined,
|
||||
'Input.TextArea',
|
||||
'autosize is deprecated, please use autoSize instead.',
|
||||
);
|
||||
|
||||
const style = {
|
||||
...props.style,
|
||||
...textareaStyles,
|
||||
@ -127,7 +136,7 @@ class TextArea extends React.Component<TextAreaProps, TextAreaState> {
|
||||
otherProps.value = otherProps.value || '';
|
||||
}
|
||||
return (
|
||||
<ResizeObserver onResize={this.resizeOnNextFrame} disabled={!autosize}>
|
||||
<ResizeObserver onResize={this.resizeOnNextFrame} disabled={!(autoSize || autosize)}>
|
||||
<textarea
|
||||
{...otherProps}
|
||||
className={cls}
|
||||
|
@ -2021,7 +2021,7 @@ exports[`renders ./components/input/demo/textarea-resize.md correctly 1`] = `
|
||||
class="ant-input"
|
||||
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>
|
||||
</div>
|
||||
`;
|
||||
|
@ -74,7 +74,7 @@ describe('TextArea', () => {
|
||||
});
|
||||
|
||||
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');
|
||||
wrapper.setProps({ value: '1111\n2222\n3333' });
|
||||
jest.runAllTimers();
|
||||
|
@ -7,11 +7,11 @@ title:
|
||||
|
||||
## zh-CN
|
||||
|
||||
`autosize` 属性适用于 `textarea` 节点,并且只有高度会自动变化。另外 `autosize` 可以设定为一个对象,指定最小行数和最大行数。
|
||||
`autoSize` 属性适用于 `textarea` 节点,并且只有高度会自动变化。另外 `autoSize` 可以设定为一个对象,指定最小行数和最大行数。
|
||||
|
||||
## 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
|
||||
import { Input } from 'antd';
|
||||
@ -32,18 +32,18 @@ class Demo extends React.Component {
|
||||
|
||||
return (
|
||||
<div>
|
||||
<TextArea placeholder="Autosize height based on content lines" autosize />
|
||||
<TextArea placeholder="Autosize height based on content lines" autoSize />
|
||||
<div style={{ margin: '24px 0' }} />
|
||||
<TextArea
|
||||
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' }} />
|
||||
<TextArea
|
||||
value={value}
|
||||
onChange={this.onChange}
|
||||
placeholder="Controlled autosize"
|
||||
autosize={{ minRows: 3, maxRows: 5 }}
|
||||
autoSize={{ minRows: 3, maxRows: 5 }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
@ -20,7 +20,7 @@ import { Input, Button } from 'antd';
|
||||
const { TextArea } = Input;
|
||||
|
||||
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 {
|
||||
state = {
|
||||
@ -38,7 +38,7 @@ class Demo extends React.Component {
|
||||
>
|
||||
Auto Resize: {String(autoResize)}
|
||||
</Button>
|
||||
<TextArea rows={4} autosize={autoResize} defaultValue={defaultValue} />
|
||||
<TextArea rows={4} autoSize={autoResize} defaultValue={defaultValue} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -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 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 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 | | |
|
||||
| value | The input content value | string | | |
|
||||
| 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 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 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 | | |
|
||||
|
||||
Supports all props of `Input`.
|
||||
|
@ -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 | | |
|
||||
| value | 输入框内容 | string | | |
|
||||
| onPressEnter | 按下回车的回调 | function(e) | | |
|
||||
|
@ -1124,7 +1124,7 @@ exports[`renders ./components/menu/demo/theme.md correctly 1`] = `
|
||||
</svg>
|
||||
</i>
|
||||
<span>
|
||||
Navigtion Two
|
||||
Navigation Two
|
||||
</span>
|
||||
</span>
|
||||
<i
|
||||
|
@ -75,7 +75,7 @@ class Sider extends React.Component {
|
||||
title={
|
||||
<span>
|
||||
<Icon type="appstore" />
|
||||
<span>Navigtion Two</span>
|
||||
<span>Navigation Two</span>
|
||||
</span>
|
||||
}
|
||||
>
|
||||
|
@ -239,12 +239,12 @@ class NameColumn extends Table.Column<User> {}
|
||||
|
||||
## 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`.
|
||||
|
||||
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.
|
||||
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`.
|
||||
|
||||
![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
|
||||
// primary key is uid
|
||||
return <Table rowKey="uid" />;
|
||||
|
@ -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` 属性作为唯一的标识。
|
||||
|
||||
如果你的数据没有这个属性,务必使用 `rowKey` 来指定数据列的主键。若没有指定,控制台会出现以下的提示,表格组件也会出现各类奇怪的错误。
|
||||
按照 [React 的规范](https://zh-hans.reactjs.org/docs/lists-and-keys.html#keys),所有的数组组件必须绑定 `key`。在 Table 中,`dataSource` 和 `columns` 里的数据值都需要指定 `key` 值。对于 `dataSource` 默认将每列数据的 `key` 属性作为唯一的标识。
|
||||
|
||||
![控制台警告](https://os.alipayobjects.com/rmsportal/luLdLvhPOiRpyss.png)
|
||||
|
||||
如果 `dataSource[i].key` 没有提供,你应该使用 `rowKey` 来指定 `dataSource` 的主键,如下所示。若没有指定,控制台会出现以上的提示,表格组件也会出现各类奇怪的错误。
|
||||
|
||||
```jsx
|
||||
// 比如你的数据主键是 uid
|
||||
return <Table rowKey="uid" />;
|
||||
|
@ -13,7 +13,12 @@ import Tree, {
|
||||
AntTreeNodeSelectedEvent,
|
||||
AntTreeNode,
|
||||
} from './Tree';
|
||||
import { calcRangeKeys, getFullKeyList, convertDirectoryKeysToNodes } from './util';
|
||||
import {
|
||||
calcRangeKeys,
|
||||
getFullKeyList,
|
||||
convertDirectoryKeysToNodes,
|
||||
getFullKeyListByTreeData,
|
||||
} from './util';
|
||||
import Icon from '../icon';
|
||||
|
||||
export type ExpandAction = false | 'click' | 'doubleClick';
|
||||
@ -82,7 +87,11 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
|
||||
|
||||
// Expanded keys
|
||||
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) {
|
||||
this.state.expandedKeys = conductExpandParent(
|
||||
expandedKeys || defaultExpandedKeys,
|
||||
|
@ -1,5 +1,189 @@
|
||||
// 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`] = `
|
||||
<ul
|
||||
class="ant-tree ant-tree-directory"
|
||||
|
@ -119,6 +119,30 @@ describe('Directory Tree', () => {
|
||||
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', () => {
|
||||
const wrapper = render(createTree({ defaultExpandParent: true }));
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
|
@ -101,3 +101,15 @@ export function convertDirectoryKeysToNodes(
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ class Editable extends React.Component<EditableProps, EditableState> {
|
||||
onCompositionEnd={this.onCompositionEnd}
|
||||
onBlur={this.onBlur}
|
||||
aria-label={ariaLabel}
|
||||
autosize
|
||||
autoSize
|
||||
/>
|
||||
<Icon type="enter" className={`${prefixCls}-edit-content-confirm`} />
|
||||
</div>
|
||||
|
@ -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
|
||||
|
||||
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.
|
||||
|
@ -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)
|
||||
|
||||
### 蚂蚁金融科技
|
||||
|
||||
金融云是面向金融机构深度定制的行业云计算服务;助力金融机构向新金融转型升级,推动平台、数据和技术方面的能力全面对外开放。
|
||||
|
@ -162,7 +162,7 @@
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-plugin-add-react-displayname": "^0.0.5",
|
||||
"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-react": "^1.0.0",
|
||||
"bisheng-plugin-toc": "^0.4.4",
|
||||
|
@ -93,7 +93,7 @@ module.exports = {
|
||||
'app.footer.fengdie.slogan': 'Mobile web app builder',
|
||||
'app.footer.zhihu': 'Ant Design 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.slogan': 'Experience The Beauty',
|
||||
'app.publish.title': 'antd@3.0.0 has been released! 🎉 🎉 🎉',
|
||||
|
@ -207,7 +207,7 @@
|
||||
.text-wrapper {
|
||||
min-height: 200px;
|
||||
margin-top: 48px;
|
||||
padding: 0 16px;
|
||||
padding: 0;
|
||||
h1 {
|
||||
display: none;
|
||||
}
|
||||
@ -221,6 +221,11 @@
|
||||
min-width: 100%;
|
||||
white-space: nowrap;
|
||||
text-align: center;
|
||||
|
||||
.banner-btn {
|
||||
padding: 0 20px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -114,7 +114,10 @@ class MainContent extends Component {
|
||||
}
|
||||
|
||||
getMenuItems(footerNavIcons = {}) {
|
||||
const { themeConfig, intl: { locale } } = this.props;
|
||||
const {
|
||||
themeConfig,
|
||||
intl: { locale },
|
||||
} = this.props;
|
||||
const moduleData = getModuleData(this.props);
|
||||
const menuItems = utils.getMenuItems(
|
||||
moduleData,
|
||||
@ -159,7 +162,10 @@ class MainContent extends Component {
|
||||
}
|
||||
|
||||
getActiveMenuItem() {
|
||||
const { params: { children }, location } = this.props;
|
||||
const {
|
||||
params: { children },
|
||||
location,
|
||||
} = this.props;
|
||||
return (
|
||||
(children && children.replace('-cn', '')) || location.pathname.replace(/(^\/|-cn$)/g, '')
|
||||
);
|
||||
@ -290,7 +296,7 @@ class MainContent extends Component {
|
||||
});
|
||||
const menuChild = (
|
||||
<Menu
|
||||
inlineIndent="40"
|
||||
inlineIndent={40}
|
||||
className="aside-container menu-site"
|
||||
mode="inline"
|
||||
openKeys={openKeys}
|
||||
|
@ -73,7 +73,7 @@ class Footer extends React.Component {
|
||||
{
|
||||
title: 'Scaffolds',
|
||||
description: <FormattedMessage id="app.footer.scaffolds" />,
|
||||
url: 'https://scaffolds.ant.design',
|
||||
url: 'https://scaffold.ant.design',
|
||||
openExternal: true,
|
||||
},
|
||||
{
|
||||
@ -142,7 +142,7 @@ class Footer extends React.Component {
|
||||
icon: <Icon type="zhihu" style={{ color: '#0084ff' }} />,
|
||||
title: 'SEE Conf',
|
||||
description: <FormattedMessage id="app.footer.seeconf" />,
|
||||
url: 'http://zhuanlan.zhihu.com/xtech',
|
||||
url: 'https://seeconf.antfin.com/',
|
||||
openExternal: true,
|
||||
},
|
||||
{
|
||||
@ -402,8 +402,7 @@ class Footer extends React.Component {
|
||||
bottom={
|
||||
<>
|
||||
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">
|
||||
<FormattedMessage id="app.footer.company" />
|
||||
</a>
|
||||
|
@ -123,6 +123,11 @@ export default class Layout extends React.Component {
|
||||
<Helmet encodeSpecialCharacters={false}>
|
||||
<html lang={appLocale.locale === 'zh-CN' ? 'zh' : 'en'} />
|
||||
<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 property="og:title" content={title} />
|
||||
<meta property="og:type" content="website" />
|
||||
|
Loading…
Reference in New Issue
Block a user