Merge pull request #17305 from ant-design/master-to-merge

Master master into feature
This commit is contained in:
zombieJ 2019-06-26 15:21:36 +08:00 committed by GitHub
commit fed8e85edb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
141 changed files with 602 additions and 345 deletions

2
.github/FUNDING.yml vendored
View File

@ -1,8 +1,8 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: ant-design
patreon: ant_design
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
custom: # Replace with a single custom sponsorship URL

View File

@ -15,6 +15,25 @@ timeline: true
---
## 3.19.8
`2019-06-24`
- 🐞 Revert `unknown` to `any` for now to avoid introducing tones of errors in one time. [#17249](https://github.com/ant-design/ant-design/issues/17249)
## 3.19.7
`2019-06-21`
- 🐞 Fix Descriptions throw error when contains falsy child. [#17207](https://github.com/ant-design/ant-design/pull/17207) [@superandrew213](http://github.com/superandrew213)
- 🐞 Fix a scrollbar style problem of empty Table in IE. [#17223](https://github.com/ant-design/ant-design/pull/17223)
- 🐞 Fix single Breadcrumb not showing on PageHeader. [#17209](https://github.com/ant-design/ant-design/pull/17209)
- 🐞 Fix Modal that 24px botton area cannot trigger mask click event. [#17229](https://github.com/ant-design/ant-design/pull/17229)
- 🐞 Fix Layout Siders zero-width trigger `z-index` bug. [#17228](https://github.com/ant-design/ant-design/pull/17228)
- TypeScript
- ⚡️ Use the `unknown` type in typescript 3.0 to improve defintions. [#14044](https://github.com/ant-design/ant-design/issues/14044) [@Zzzen](http://github.com/Zzzen)
- 🐞 Fix Calendar `headerRender` should be optional. [#17063](https://github.com/ant-design/ant-design/pull/17063) [@wonderjar](http://github.com/wonderjar)
## 3.19.6
`2019-06-19`

View File

@ -15,6 +15,25 @@ timeline: true
---
## 3.19.8
`2019-06-24`
- 🐞 回滚 `unknown``any` 避免一次性引入大量 TS 错误。[#17249](https://github.com/ant-design/ant-design/issues/17249)
## 3.19.7
`2019-06-21`
- 🐞 修复 Descriptions 内无法嵌套空值的问题。[#17207](https://github.com/ant-design/ant-design/pull/17207) [@superandrew213](http://github.com/superandrew213)
- 🐞 修复 Table 空数据表格在 IE 下的一个滚动条样式问题。[#17223](https://github.com/ant-design/ant-design/pull/17223)
- 🐞 修复单个 Breadcrumb 未在 PageHeader 上显示的问题。[#17209](https://github.com/ant-design/ant-design/pull/17209)
- 🐞 修复 Modal 底部 24px 像素遮罩区域无法触发关闭弹窗行为。[#17229](https://github.com/ant-design/ant-design/pull/17229)
- 🐞 修复 Layout Sider 的展开按钮 `z-index` 太低的问题。[#17228](https://github.com/ant-design/ant-design/pull/17228)
- TypeScript
- ⚡️ 使用 `unknown` 代替 `any` 优化 TypeScript 定义。[#14044](https://github.com/ant-design/ant-design/issues/14044) [@Zzzen](http://github.com/Zzzen)
- 🐞 修复 Calendar `headerRender` 属性为可选。[#17063](https://github.com/ant-design/ant-design/pull/17063) [@wonderjar](http://github.com/wonderjar)
## 3.19.6
`2019-06-19`

View File

@ -169,7 +169,11 @@ describe('Test utils function', () => {
it('should not throw when click it', () => {
expect(() => {
const wrapper = mount(<Wave><div /></Wave>);
const wrapper = mount(
<Wave>
<div />
</Wave>,
);
wrapper.simulate('click');
}).not.toThrow();
});
@ -184,9 +188,7 @@ describe('Test utils function', () => {
describe('TransButton', () => {
it('can be focus/blur', () => {
const wrapper = mount(
<TransButton>TransButton</TransButton>,
);
const wrapper = mount(<TransButton>TransButton</TransButton>);
expect(typeof wrapper.instance().focus).toBe('function');
expect(typeof wrapper.instance().blur).toBe('function');
});
@ -194,9 +196,7 @@ describe('Test utils function', () => {
it('should trigger onClick when press enter', () => {
const onClick = jest.fn();
const preventDefault = jest.fn();
const wrapper = mount(
<TransButton onClick={onClick}>TransButton</TransButton>,
);
const wrapper = mount(<TransButton onClick={onClick}>TransButton</TransButton>);
wrapper.simulate('keyUp', { keyCode: KeyCode.ENTER });
expect(onClick).toHaveBeenCalled();
wrapper.simulate('keyDown', { keyCode: KeyCode.ENTER, preventDefault });

View File

@ -1,4 +1,5 @@
// https://github.com/moment/moment/issues/3650
// since we are using ts 3.5.1, it should be safe to remove.
export default function interopDefault(m: any) {
return m.default || m;
}

View File

@ -9,7 +9,7 @@ export interface AnchorLinkProps {
prefixCls?: string;
href: string;
title: React.ReactNode;
children?: any;
children?: React.ReactNode;
className?: string;
}

View File

@ -20,7 +20,7 @@ export interface AvatarProps {
style?: React.CSSProperties;
prefixCls?: string;
className?: string;
children?: any;
children?: React.ReactNode;
alt?: string;
/* callback when img load error */
/* return false to prevent Avatar show default fallback behavior, then you can do fallback by your self*/

View File

@ -25,7 +25,7 @@ function getDefaultTarget() {
export interface BackTopProps {
visibilityHeight?: number;
onClick?: React.MouseEventHandler<any>;
onClick?: React.MouseEventHandler<HTMLElement>;
target?: () => HTMLElement | Window;
prefixCls?: string;
className?: string;

View File

@ -22,7 +22,7 @@ export interface ScrollNumberProps {
prefixCls?: string;
className?: string;
count?: string | number | null;
displayComponent?: React.ReactElement<any>;
displayComponent?: React.ReactElement<HTMLElement>;
component?: string;
onAnimated?: Function;
style?: React.CSSProperties;
@ -105,7 +105,7 @@ class ScrollNumber extends Component<ScrollNumberProps, ScrollNumberState> {
if (onAnimated) {
onAnimated();
}
}
};
renderNumberList(position: number) {
const childrenToReturn: React.ReactElement<any>[] = [];

View File

@ -20,9 +20,9 @@ export interface BreadcrumbProps {
params?: any;
separator?: React.ReactNode;
itemRender?: (
route: any,
route: Route,
params: any,
routes: Array<any>,
routes: Array<Route>,
paths: Array<string>,
) => React.ReactNode;
style?: React.CSSProperties;
@ -72,21 +72,21 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
}
getPath = (path: string, params: any) => {
path = (path || '').replace(/^\//, '');
Object.keys(params).forEach(key => {
path = path.replace(`:${key}`, params[key]);
});
return path;
}
path = (path || '').replace(/^\//, '');
Object.keys(params).forEach(key => {
path = path.replace(`:${key}`, params[key]);
});
return path;
};
addChildPath = (paths: string[], childPath: string = '', params: any) => {
const originalPaths = [...paths];
const path = this.getPath(childPath, params);
if (path) {
originalPaths.push(path);
originalPaths.push(path);
}
return originalPaths;
}
};
genForRoutes = ({
routes = [],
@ -107,12 +107,10 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
overlay = (
<Menu>
{route.children.map(child => (
<Menu.Item key={child.breadcrumbName || child.path}>
{
itemRender(child, params, routes, this.addChildPath(paths, child.path, params))
}
</Menu.Item>
))}
<Menu.Item key={child.breadcrumbName || child.path}>
{itemRender(child, params, routes, this.addChildPath(paths, child.path, params))}
</Menu.Item>
))}
</Menu>
);
}

View File

@ -91,15 +91,15 @@ export interface BaseButtonProps {
export type AnchorButtonProps = {
href: string;
target?: string;
onClick?: React.MouseEventHandler<any>;
onClick?: React.MouseEventHandler<HTMLElement>;
} & BaseButtonProps &
Omit<React.AnchorHTMLAttributes<any>, 'type'>;
Omit<React.AnchorHTMLAttributes<any>, 'type' | 'onClick'>;
export type NativeButtonProps = {
htmlType?: ButtonHTMLType;
onClick?: React.MouseEventHandler<any>;
onClick?: React.MouseEventHandler<HTMLElement>;
} & BaseButtonProps &
Omit<React.ButtonHTMLAttributes<any>, 'type'>;
Omit<React.ButtonHTMLAttributes<any>, 'type' | 'onClick'>;
export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>;
@ -289,7 +289,7 @@ class Button extends React.Component<ButtonProps, ButtonState> {
const buttonNode = (
<button
{...otherProps as NativeButtonProps}
{...(otherProps as NativeButtonProps)}
type={htmlType}
className={classes}
onClick={this.handleClick}

View File

@ -30,7 +30,7 @@ class ButtonSize extends React.Component {
};
render() {
const size = this.state.size;
const { size } = this.state;
return (
<div>
<Radio.Group value={size} onChange={this.handleSizeChange}>

View File

@ -31,15 +31,13 @@ To get a customized button, just set `type`/`shape`/`size`/`loading`/`disabled`.
It accepts all props which native button support.
`<Button>Hello world!</Button>` will be rendered into `<button><span>Hello world!</span></button>`, and all the properties which are not listed above will be transferred to the `<button>` tag.
`<Button href="http://example.com">Hello world!</Button>` will be rendered into `<a href="http://example.com"><span>Hello world!</span></a>`.
## FAQ
### How to remove space between 2 chinese characters
### How to remove space between 2 chinese characters?
Use [ConfigProvider](/components/config-provider/#API) to set `autoInsertSpaceInButton` as `false`.
Following Ant Design specification, we will add one space between if Button contains two chinese characters only. If you don't need that, you can use [ConfigProvider](/components/config-provider/#API) to set `autoInsertSpaceInButton` as `false`.
![](https://gw.alipayobjects.com/zos/antfincdn/Hz5HL9gsT4/f29f170d-b78d-4d2b-aa71-0da6a9ead4d9.png)
<style>
[id^=components-button-demo-] .ant-btn {

View File

@ -34,15 +34,13 @@ subtitle: 按钮
支持原生 button 的其他所有属性。
`<Button>Hello world!</Button>` 最终会被渲染为 `<button><span>Hello world!</span></button>`,并且除了上表中的属性,其它属性都会直接传到原生 button 上。
`<Button href="http://example.com">Hello world!</Button>` 则会渲染为 `<a href="http://example.com"><span>Hello world!</span></a>`
## FAQ
### 如何移除 2 个汉字之间的空格
### 如何移除两个汉字之间的空格?
设置 [ConfigProvider](/components/config-provider/#API) 的 `autoInsertSpaceInButton``false`
根据 Ant Design 设计规范要求,我们会在按钮内只有两个汉字时自动添加空格,如果你不需要这个特性,可以设置 [ConfigProvider](/components/config-provider/#API) 的 `autoInsertSpaceInButton``false`
![](https://gw.alipayobjects.com/zos/antfincdn/Hz5HL9gsT4/f29f170d-b78d-4d2b-aa71-0da6a9ead4d9.png)
<style>
[id^="components-button-demo-"] .ant-btn {

View File

@ -12,6 +12,8 @@ export interface RenderHeader {
onTypeChange: (type: string) => void;
}
export type HeaderRender = (headerRender: RenderHeader) => React.ReactNode;
export interface HeaderProps {
prefixCls?: string;
locale?: any;
@ -23,7 +25,7 @@ export interface HeaderProps {
onTypeChange?: (type: string) => void;
value: moment.Moment;
validRange?: [moment.Moment, moment.Moment];
headerRender: (header: RenderHeader) => React.ReactNode;
headerRender?: HeaderRender;
}
export default class Header extends React.Component<HeaderProps, any> {
@ -138,7 +140,7 @@ export default class Header extends React.Component<HeaderProps, any> {
};
onInternalTypeChange = (e: RadioChangeEvent) => {
this.onTypeChange(e.target.value);
this.onTypeChange(e.target.value as string);
};
onTypeChange = (type: string) => {
@ -178,8 +180,8 @@ export default class Header extends React.Component<HeaderProps, any> {
);
};
headerRenderCustom = (): React.ReactNode => {
const { headerRender, type, onValueChange, value } = this.props;
headerRenderCustom = (headerRender: HeaderRender): React.ReactNode => {
const { type, onValueChange, value } = this.props;
return headerRender({
value,
@ -194,7 +196,7 @@ export default class Header extends React.Component<HeaderProps, any> {
const typeSwitch = this.getTypeSwitch();
const { yearReactNode, monthReactNode } = this.getMonthYearSelections(getPrefixCls);
return headerRender ? (
this.headerRenderCustom()
this.headerRenderCustom(headerRender)
) : (
<div className={`${prefixCls}-header`} ref={this.getCalenderHeaderNode}>
{yearReactNode}

View File

@ -2,7 +2,7 @@ import * as React from 'react';
import * as PropTypes from 'prop-types';
import * as moment from 'moment';
import FullCalendar from 'rc-calendar/lib/FullCalendar';
import Header, { RenderHeader } from './Header';
import Header, { HeaderRender } from './Header';
import enUS from './locale/en_US';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
@ -41,7 +41,7 @@ export interface CalendarProps {
onChange?: (date?: moment.Moment) => void;
disabledDate?: (current: moment.Moment) => boolean;
validRange?: [moment.Moment, moment.Moment];
headerRender: (header: RenderHeader) => React.ReactNode;
headerRender?: HeaderRender;
}
export interface CalendarState {
@ -56,7 +56,6 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
onSelect: noop,
onPanelChange: noop,
onChange: noop,
headerRender: null,
};
static propTypes = {
@ -73,6 +72,7 @@ class Calendar extends React.Component<CalendarProps, CalendarState> {
value: PropTypes.object as PropTypes.Requireable<moment.Moment>,
onSelect: PropTypes.func,
onChange: PropTypes.func,
headerRender: PropTypes.func,
};
static getDerivedStateFromProps(nextProps: CalendarProps) {

View File

@ -3,11 +3,11 @@ import { mount } from 'enzyme';
import Carousel from '..';
describe('Carousel', () => {
beforeAll(() => {
beforeEach(() => {
jest.useFakeTimers();
});
afterAll(() => {
afterEach(() => {
jest.useRealTimers();
});

View File

@ -15,11 +15,11 @@ export interface AbstractCheckboxProps<T> {
style?: React.CSSProperties;
disabled?: boolean;
onChange?: (e: T) => void;
onClick?: React.MouseEventHandler<any>;
onMouseEnter?: React.MouseEventHandler<any>;
onMouseLeave?: React.MouseEventHandler<any>;
onKeyPress?: React.KeyboardEventHandler<any>;
onKeyDown?: React.KeyboardEventHandler<any>;
onClick?: React.MouseEventHandler<HTMLElement>;
onMouseEnter?: React.MouseEventHandler<HTMLElement>;
onMouseLeave?: React.MouseEventHandler<HTMLElement>;
onKeyPress?: React.KeyboardEventHandler<HTMLElement>;
onKeyDown?: React.KeyboardEventHandler<HTMLElement>;
value?: any;
tabIndex?: number;
name?: string;

View File

@ -19,7 +19,7 @@ export interface CollapseProps {
className?: string;
bordered?: boolean;
prefixCls?: string;
expandIcon?: (panelProps: any) => React.ReactNode;
expandIcon?: (panelProps: PanelProps) => React.ReactNode;
expandIconPosition?: ExpandIconPosition;
}

View File

@ -16,7 +16,7 @@ In accordion mode, only one panel can be expanded at a time.
```jsx
import { Collapse } from 'antd';
const Panel = Collapse.Panel;
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.

View File

@ -16,7 +16,7 @@ By default, any number of panels can be expanded at a time. The first panel is e
```jsx
import { Collapse } from 'antd';
const Panel = Collapse.Panel;
const { Panel } = Collapse;
function callback(key) {
console.log(key);

View File

@ -16,7 +16,7 @@ A borderless style of Collapse.
```jsx
import { Collapse } from 'antd';
const Panel = Collapse.Panel;
const { Panel } = Collapse;
const text = (
<p style={{ paddingLeft: 24 }}>

View File

@ -16,7 +16,7 @@ Customize the background, border, margin styles and icon for each panel.
```jsx
import { Collapse, Icon } from 'antd';
const Panel = Collapse.Panel;
const { Panel } = Collapse;
const text = `
A dog is a type of domesticated animal.

View File

@ -16,7 +16,7 @@ title:
```jsx
import { Collapse } from 'antd';
const Panel = Collapse.Panel;
const { Panel } = Collapse;
function callback(key) {
console.log(key);

View File

@ -16,7 +16,7 @@ You can hide the arrow icon by passing `showArrow={false}` to `CollapsePanel` co
```jsx
import { Collapse } from 'antd';
const Panel = Collapse.Panel;
const { Panel } = Collapse;
function callback(key) {
console.log(key);

View File

@ -14,7 +14,7 @@ export interface CommentProps {
/** The main content of the comment */
content: React.ReactNode;
/** Nested comments should be provided as children of the Comment */
children?: any;
children?: React.ReactNode;
/** Comment prefix defaults to '.ant-comment' */
prefixCls?: string;
/** Additional style for the comment */

View File

@ -2,7 +2,7 @@ import * as React from 'react';
import Icon from '../icon';
import classNames from 'classnames';
export default function InputIcon(props: { suffixIcon: any; prefixCls: string }) {
export default function InputIcon(props: { suffixIcon: React.ReactNode; prefixCls: string }) {
const { suffixIcon, prefixCls } = props;
return (
(suffixIcon &&

View File

@ -30,7 +30,7 @@ class DateRange extends React.Component {
};
disabledStartDate = startValue => {
const endValue = this.state.endValue;
const { endValue } = this.state;
if (!startValue || !endValue) {
return false;
}
@ -38,7 +38,7 @@ class DateRange extends React.Component {
};
disabledEndDate = endValue => {
const startValue = this.state.startValue;
const { startValue } = this.state;
if (!endValue || !startValue) {
return false;
}

View File

@ -99,3 +99,120 @@ exports[`Descriptions column is number 1`] = `
</div>
</Descriptions>
`;
exports[`Descriptions when item is rendered conditionally 1`] = `
<Descriptions
column={
Object {
"lg": 3,
"md": 3,
"sm": 2,
"xl": 3,
"xs": 1,
"xxl": 3,
}
}
size="default"
>
<div
className="ant-descriptions"
>
<div
className="ant-descriptions-view"
>
<table>
<tbody>
<tr
className="ant-descriptions-row"
key="0"
>
<td
className="ant-descriptions-item"
colSpan={1}
>
<span
className="ant-descriptions-item-label"
key="label"
>
Product
</span>
<span
className="ant-descriptions-item-content"
key="content"
>
Cloud Database
</span>
</td>
</tr>
<tr
className="ant-descriptions-row"
key="1"
>
<td
className="ant-descriptions-item"
colSpan={1}
>
<span
className="ant-descriptions-item-label"
key="label"
>
Billing
</span>
<span
className="ant-descriptions-item-content"
key="content"
>
Prepaid
</span>
</td>
</tr>
<tr
className="ant-descriptions-row"
key="2"
>
<td
className="ant-descriptions-item"
colSpan={1}
>
<span
className="ant-descriptions-item-label"
key="label"
>
time
</span>
<span
className="ant-descriptions-item-content"
key="content"
>
18:00:00
</span>
</td>
</tr>
<tr
className="ant-descriptions-row"
key="3"
>
<td
className="ant-descriptions-item"
colSpan={1}
>
<span
className="ant-descriptions-item-label"
key="label"
>
Amount
</span>
<span
className="ant-descriptions-item-content"
key="content"
>
$80.00
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</Descriptions>
`;

View File

@ -109,4 +109,19 @@ describe('Descriptions', () => {
'Warning: [antd: Descriptions] Sum of column `span` in a line exceeds `column` of Descriptions.',
);
});
it('when item is rendered conditionally', () => {
const hasDiscount = false;
const wrapper = mount(
<Descriptions>
<Descriptions.Item label="Product">Cloud Database</Descriptions.Item>
<Descriptions.Item label="Billing">Prepaid</Descriptions.Item>
<Descriptions.Item label="time">18:00:00</Descriptions.Item>
<Descriptions.Item label="Amount">$80.00</Descriptions.Item>
{hasDiscount && <Descriptions.Item label="Discount">$20.00</Descriptions.Item>}
</Descriptions>,
);
expect(wrapper).toMatchSnapshot();
wrapper.unmount();
});
});

View File

@ -209,9 +209,12 @@ class Descriptions extends React.Component<
const cloneChildren = React.Children.map(
children,
(child: React.ReactElement<DescriptionsItemProps>) => {
return React.cloneElement(child, {
prefixCls,
});
if (React.isValidElement(child)) {
return React.cloneElement(child, {
prefixCls,
});
}
return child;
},
);

View File

@ -21,7 +21,7 @@ export interface DropdownButtonProps extends ButtonGroupProps, DropDownProps {
*/
icon?: React.ReactNode;
href?: string;
children?: any;
children?: React.ReactNode;
}
export default class DropdownButton extends React.Component<DropdownButtonProps, any> {

View File

@ -34,7 +34,7 @@ export type FormLayout = (typeof FormLayouts)[number];
export interface FormProps extends React.FormHTMLAttributes<HTMLFormElement> {
layout?: FormLayout;
form?: WrappedFormUtils;
onSubmit?: React.FormEventHandler<any>;
onSubmit?: React.FormEventHandler<HTMLElement>;
style?: React.CSSProperties;
className?: string;
prefixCls?: string;

View File

@ -71,7 +71,7 @@ class PriceInput extends React.Component {
triggerChange = changedValue => {
// Should provide an event to pass value to Form.
const onChange = this.props.onChange;
const { onChange } = this.props;
if (onChange) {
onChange(Object.assign({}, this.state, changedValue));
}
@ -79,7 +79,7 @@ class PriceInput extends React.Component {
render() {
const { size } = this.props;
const state = this.state;
const { state } = this;
return (
<span>
<Input

View File

@ -70,7 +70,7 @@ class CollectionsPage extends React.Component {
};
handleCreate = () => {
const form = this.formRef.props.form;
const { form } = this.formRef.props;
form.validateFields((err, values) => {
if (err) {
return;

View File

@ -67,7 +67,7 @@ class Demo extends React.Component {
};
render() {
const fields = this.state.fields;
const { fields } = this.state;
return (
<div>
<CustomizedForm {...fields} onChange={this.handleFormChange} />

View File

@ -82,12 +82,12 @@ class RegistrationForm extends React.Component {
};
handleConfirmBlur = e => {
const value = e.target.value;
const { value } = e.target;
this.setState({ confirmDirty: this.state.confirmDirty || !!value });
};
compareToFirstPassword = (rule, value, callback) => {
const form = this.props.form;
const { form } = this.props;
if (value && value !== form.getFieldValue('password')) {
callback('Two passwords that you enter is inconsistent!');
} else {
@ -96,7 +96,7 @@ class RegistrationForm extends React.Component {
};
validateToNextPassword = (rule, value, callback) => {
const form = this.props.form;
const { form } = this.props;
if (value && this.state.confirmDirty) {
form.validateFields(['confirm'], { force: true });
}

View File

@ -50,7 +50,7 @@ class RawForm extends React.Component {
labelCol: { span: 7 },
wrapperCol: { span: 12 },
};
const number = this.state.number;
const { number } = this.state;
const tips =
'A prime is a natural number greater than 1 that has no positive divisors other than 1 and itself.';
return (

View File

@ -61,7 +61,7 @@ type NonReactStatics<
: S extends React.ForwardRefExoticComponent<any>
? keyof FORWARD_REF_STATICS | keyof C
: keyof REACT_STATICS | keyof KNOWN_STATICS | keyof C
>]: S[key]
>]: S[key];
};
// Copy from @types/react-redux https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-redux/index.d.ts
@ -70,7 +70,7 @@ export type Matching<InjectedProps, DecorationTargetProps> = {
? InjectedProps[P] extends DecorationTargetProps[P]
? DecorationTargetProps[P]
: InjectedProps[P]
: DecorationTargetProps[P]
: DecorationTargetProps[P];
};
export type GetProps<C> = C extends React.ComponentType<infer P> ? P : never;

View File

@ -1,7 +1,7 @@
import React from 'react';
import { render, mount } from 'enzyme';
import Icon from '..';
import ReactIcon from '@ant-design/icons-react';
import Icon from '..';
import Tooltip from '../../tooltip';
import { getThemeFromTypeName, withThemeSuffix } from '../utils';

View File

@ -5,7 +5,7 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
export interface GroupProps {
className?: string;
size?: 'large' | 'small' | 'default';
children?: any;
children?: React.ReactNode;
style?: React.CSSProperties;
onMouseEnter?: React.MouseEventHandler<HTMLSpanElement>;
onMouseLeave?: React.MouseEventHandler<HTMLSpanElement>;

View File

@ -10,7 +10,7 @@ export interface SearchProps extends InputProps {
onSearch?: (
value: string,
event?: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLInputElement>,
) => any;
) => void;
enterButton?: boolean | React.ReactNode;
}

View File

@ -16,7 +16,7 @@ Example of creating a search box by grouping a standard input with a search butt
```jsx
import { Input } from 'antd';
const Search = Input.Search;
const { Search } = Input;
ReactDOM.render(
<div>

View File

@ -80,9 +80,9 @@
max-width: 100%; // prevent textearea resize from coming out of its container
height: auto;
min-height: @input-height-base;
line-height: @line-height-base;
vertical-align: bottom;
transition: all 0.3s, height 0s;
line-height: @line-height-base;
}
// Size

View File

@ -96,6 +96,7 @@
position: absolute;
top: @layout-header-height;
right: -@layout-zero-trigger-width;
z-index: 1;
width: @layout-zero-trigger-width;
height: @layout-zero-trigger-height;
color: @layout-trigger-color;

View File

@ -116,7 +116,7 @@ export default class Item extends React.Component<ListItemProps, any> {
const Tag = grid ? 'div' : 'li';
const itemChildren = (
<Tag
{...others as any} // `li` element `onCopy` prop args is not same as `div`
{...(others as any)} // `li` element `onCopy` prop args is not same as `div`
className={classNames(`${prefixCls}-item`, className, {
[`${prefixCls}-item-no-flex`]: !this.isFlexMode(),
})}

View File

@ -49,7 +49,7 @@ class InfiniteListExample extends React.Component {
};
handleInfiniteOnLoad = () => {
let data = this.state.data;
let { data } = this.state;
this.setState({
loading: true,
});

View File

@ -58,7 +58,7 @@ class VirtualizedExample extends React.Component {
};
handleInfiniteOnLoad = ({ startIndex, stopIndex }) => {
let data = this.state.data;
let { data } = this.state;
this.setState({
loading: true,
});

View File

@ -45,7 +45,7 @@ export interface ListProps<T> {
loadMore?: React.ReactNode;
pagination?: PaginationConfig | false;
prefixCls?: string;
rowKey?: any;
rowKey?: ((item: T) => string) | string;
renderItem?: (item: T, index: number) => React.ReactNode;
size?: ListSize;
split?: boolean;

View File

@ -5,7 +5,7 @@ import defaultLocaleData from './default';
export interface LocaleReceiverProps {
componentName?: string;
defaultLocale?: object | Function;
children: (locale: object, localeCode?: string) => React.ReactElement<any>;
children: (locale: object, localeCode?: string) => React.ReactNode;
}
interface LocaleInterface {

View File

@ -18,7 +18,7 @@ Customize suggestions.
```jsx
import { Mention, Avatar } from 'antd';
const Nav = Mention.Nav;
const { Nav } = Mention;
const webFrameworks = [
{

View File

@ -18,7 +18,7 @@ Customize suggestions.
```jsx
import { Mention } from 'antd';
const Nav = Mention.Nav;
const { Nav } = Mention;
const webFrameworks = [
{ name: 'React', type: 'JavaScript' },

View File

@ -8,13 +8,15 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
export type MentionPlacement = 'top' | 'bottom';
type SuggestionItme = React.ReactElement<{ value?: string }> | string;
export interface MentionProps {
prefixCls?: string;
suggestionStyle?: React.CSSProperties;
defaultSuggestions?: Array<any>;
suggestions?: Array<any>;
defaultSuggestions?: Array<SuggestionItme>;
suggestions?: Array<React.ReactElement<any>>;
onSearchChange?: (value: string, trigger: string) => any;
onChange?: (contentState: any) => any;
onChange?: (contentState: any) => void;
notFoundContent?: any;
loading?: boolean;
style?: React.CSSProperties;
@ -27,7 +29,7 @@ export interface MentionProps {
getSuggestionContainer?: (triggerNode: Element) => HTMLElement;
onFocus?: React.FocusEventHandler<HTMLElement>;
onBlur?: React.FocusEventHandler<HTMLElement>;
onSelect?: (suggestion: string, data?: any) => any;
onSelect?: (suggestion: string, data?: any) => void;
readOnly?: boolean;
disabled?: boolean;
placement?: MentionPlacement;
@ -81,12 +83,13 @@ class Mention extends React.Component<MentionProps, MentionState> {
defaultSearchChange(value: string): void {
const searchValue = value.toLowerCase();
const filteredSuggestions = (this.props.defaultSuggestions || []).filter(suggestion => {
if (suggestion.type && suggestion.type === Nav) {
if (typeof suggestion === 'string') {
return suggestion.toLowerCase().indexOf(searchValue) !== -1;
} else if (suggestion.type && suggestion.type === Nav) {
return suggestion.props.value
? suggestion.props.value.toLowerCase().indexOf(searchValue) !== -1
: true;
}
return suggestion.toLowerCase().indexOf(searchValue) !== -1;
});
this.setState({
filteredSuggestions,

View File

@ -49,28 +49,26 @@ class Mentions extends React.Component<MentionProps, MentionState> {
return value
.split(split)
.map(
(str = ''): MentionsEntity | null => {
let hitPrefix: string | null = null;
.map((str = ''): MentionsEntity | null => {
let hitPrefix: string | null = null;
prefixList.some(prefixStr => {
const startStr = str.slice(0, prefixStr.length);
if (startStr === prefixStr) {
hitPrefix = prefixStr;
return true;
}
return false;
});
if (hitPrefix !== null) {
return {
prefix: hitPrefix,
value: str.slice(hitPrefix!.length),
};
prefixList.some(prefixStr => {
const startStr = str.slice(0, prefixStr.length);
if (startStr === prefixStr) {
hitPrefix = prefixStr;
return true;
}
return null;
},
)
return false;
});
if (hitPrefix !== null) {
return {
prefix: hitPrefix,
value: str.slice(hitPrefix!.length),
};
}
return null;
})
.filter((entity): entity is MentionsEntity => !!entity && !!entity.value);
};

View File

@ -19,6 +19,7 @@ export interface SubMenuProps {
onTitleClick?: (e: TitleEventEntity) => void;
onTitleMouseEnter?: (e: TitleEventEntity) => void;
onTitleMouseLeave?: (e: TitleEventEntity) => void;
popupOffset?: [number, number];
}
class SubMenu extends React.Component<SubMenuProps, any> {

View File

@ -16,7 +16,7 @@ Horizontal top navigation menu.
```jsx
import { Menu, Icon } from 'antd';
const { SubMenu } = Menu;
const { SubMenu } = Menu;
class App extends React.Component {
state = {

View File

@ -20,7 +20,7 @@ Here is [a complete demo](/components/layout/#components-layout-demo-side) with
```jsx
import { Menu, Icon, Button } from 'antd';
const { SubMenu } = Menu;
const { SubMenu } = Menu;
class App extends React.Component {
state = {

View File

@ -16,7 +16,7 @@ Vertical menu with inline submenus.
```jsx
import { Menu, Icon } from 'antd';
const { SubMenu } = Menu;
const { SubMenu } = Menu;
class Sider extends React.Component {
handleClick = e => {

View File

@ -16,7 +16,7 @@ Click the menu and you will see that all the other menus gets collapsed to keep
```jsx
import { Menu, Icon } from 'antd';
const { SubMenu } = Menu;
const { SubMenu } = Menu;
class Sider extends React.Component {
// submenu keys of first level

View File

@ -16,7 +16,7 @@ There are two built-in themes: 'light' and 'dark'. The default value is 'light'.
```jsx
import { Menu, Icon, Switch } from 'antd';
const { SubMenu } = Menu;
const { SubMenu } = Menu;
class Sider extends React.Component {
state = {

View File

@ -16,7 +16,7 @@ Submenus open as pop-ups.
```jsx
import { Menu, Icon } from 'antd';
const { SubMenu } = Menu;
const { SubMenu } = Menu;
function handleClick(e) {
console.log('click', e);

View File

@ -16,7 +16,7 @@ export interface SelectParam {
key: string;
keyPath: Array<string>;
item: any;
domEvent: any;
domEvent: Event;
selectedKeys: Array<string>;
}
@ -24,7 +24,7 @@ export interface ClickParam {
key: string;
keyPath: Array<string>;
item: any;
domEvent: any;
domEvent: Event;
}
export type MenuMode = 'vertical' | 'vertical-left' | 'vertical-right' | 'horizontal' | 'inline';

View File

@ -39,13 +39,13 @@ function getMessageInstance(callback: (i: any) => void) {
type NoticeType = 'info' | 'success' | 'error' | 'warning' | 'loading';
export interface ThenableArgument {
(_: any): any;
(val: any): void;
}
export interface MessageType {
(): void;
then: (fill: ThenableArgument, reject: ThenableArgument) => Promise<any>;
promise: Promise<any>;
then: (fill: ThenableArgument, reject: ThenableArgument) => Promise<void>;
promise: Promise<void>;
}
export interface ArgsProps {

View File

@ -40,9 +40,9 @@ export interface ModalProps {
/** 是否显示右上角的关闭按钮*/
closable?: boolean;
/** 点击确定回调*/
onOk?: (e: React.MouseEvent<any>) => void;
onOk?: (e: React.MouseEvent<HTMLElement>) => void;
/** 点击模态框右上角叉、取消按钮、Props.maskClosable 值为 true 时的遮罩层或键盘按下 Esc 时的回调*/
onCancel?: (e: React.MouseEvent<any>) => void;
onCancel?: (e: React.MouseEvent<HTMLElement>) => void;
afterClose?: () => void;
/** 垂直居中 */
centered?: boolean;
@ -84,8 +84,9 @@ export interface ModalFuncProps {
visible?: boolean;
title?: React.ReactNode;
content?: React.ReactNode;
onOk?: (...args: any[]) => any | PromiseLike<any>;
onCancel?: (...args: any[]) => any | PromiseLike<any>;
// TODO: find out exact types
onOk?: (...args: any[]) => any;
onCancel?: (...args: any[]) => any;
okButtonProps?: NativeButtonProps;
cancelButtonProps?: NativeButtonProps;
centered?: boolean;
@ -213,7 +214,7 @@ export default class Modal extends React.Component<ModalProps, {}> {
const closeIcon = (
<span className={`${prefixCls}-close-x`}>
<Icon className={`${prefixCls}-close-icon`} type={'close'} />
<Icon className={`${prefixCls}-close-icon`} type="close" />
</span>
);

View File

@ -16,7 +16,7 @@ Use `confirm()` to show a confirmation modal dialog. Let onCancel/onOk function
```jsx
import { Modal, Button } from 'antd';
const confirm = Modal.confirm;
const { confirm } = Modal;
function showConfirm() {
confirm({

View File

@ -20,7 +20,7 @@ function destroyAll() {
Modal.destroyAll();
}
const confirm = Modal.confirm;
const { confirm } = Modal;
function showConfirm() {
for (let i = 0; i < 3; i += 1) {

View File

@ -16,7 +16,7 @@ Use `confirm()` to show a confirmation modal dialog.
```jsx
import { Modal, Button } from 'antd';
const confirm = Modal.confirm;
const { confirm } = Modal;
function showConfirm() {
confirm({

View File

@ -11,6 +11,7 @@
width: auto;
margin: 0 auto;
padding-bottom: 24px;
pointer-events: none;
&-wrap {
position: fixed;
@ -40,6 +41,7 @@
border: 0;
border-radius: @border-radius-base;
box-shadow: @shadow-2;
pointer-events: auto;
}
&-close {

View File

@ -21,6 +21,19 @@ describe('PageHeader', () => {
const wrapper = mount(<PageHeader title="Page Title" breadcrumb={{ routes }} />);
expect(wrapper.find('.ant-page-header-back')).toHaveLength(0);
});
it('pageHeader should have breadcrumb', () => {
const routes = [
{
path: 'index',
breadcrumbName: 'First-level Menu',
},
];
const wrapper = mount(<PageHeader title="Page Title" breadcrumb={{ routes }} />);
expect(wrapper.find('.ant-breadcrumb')).toHaveLength(1);
expect(wrapper.find('.ant-page-header-back')).toHaveLength(0);
});
it('pageHeader should no contain back', () => {
const wrapper = mount(<PageHeader title="Page Title" backIcon={false} />);
expect(wrapper.find('.ant-page-header-back')).toHaveLength(0);

View File

@ -1,11 +1,11 @@
import * as React from 'react';
import classnames from 'classnames';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Icon from '../icon';
import classnames from 'classnames';
import { BreadcrumbProps } from '../breadcrumb';
import Divider from '../divider';
import Tag from '../tag';
import Breadcrumb from '../breadcrumb';
import Breadcrumb, { BreadcrumbProps } from '../breadcrumb';
import TransButton from '../_util/transButton';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
@ -59,7 +59,7 @@ const renderBreadcrumb = (breadcrumb: BreadcrumbProps) => {
const renderHeader = (prefixCls: string, props: PageHeaderProps) => {
const { breadcrumb, backIcon, onBack } = props;
if (breadcrumb && breadcrumb.routes && breadcrumb.routes.length >= 2) {
if (breadcrumb && breadcrumb.routes) {
return renderBreadcrumb(breadcrumb);
}
return renderBack(prefixCls, backIcon, onBack);

View File

@ -11,15 +11,15 @@ import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
export interface PopconfirmProps extends AbstractTooltipProps {
title: React.ReactNode;
disabled?: boolean;
onConfirm?: (e?: React.MouseEvent<any>) => void;
onCancel?: (e?: React.MouseEvent<any>) => void;
onConfirm?: (e?: React.MouseEvent<HTMLElement>) => void;
onCancel?: (e?: React.MouseEvent<HTMLElement>) => void;
okText?: React.ReactNode;
okType?: ButtonType;
cancelText?: React.ReactNode;
okButtonProps?: NativeButtonProps;
cancelButtonProps?: NativeButtonProps;
icon?: React.ReactNode;
onVisibleChange?: (visible: boolean, e?: React.MouseEvent<any>) => void;
onVisibleChange?: (visible: boolean, e?: React.MouseEvent<HTMLElement>) => void;
}
export interface PopconfirmState {

View File

@ -23,7 +23,7 @@ Properties that shared by all types.
| format | template function of the content | function(percent, successPercent) | `percent => percent + '%'` |
| percent | to set the completion percentage | number | 0 |
| showInfo | whether to display the progress value and the status icon | boolean | true |
| status | to set the status of the Progress, options: `success` `exception` `active` `normal` | string | - |
| status | to set the status of the Progress, options: `success` `exception` `normal` `active`(line only) | string | - |
| strokeLinecap | to set the style of the progress linecap | Enum{ 'round', 'square' } | `round` |
| strokeColor | color of progress bar | string | - |
| successPercent | segmented success percent | number | 0 |

View File

@ -24,7 +24,7 @@ title: Progress
| format | 内容的模板函数 | function(percent, successPercent) | `percent => percent + '%'` |
| percent | 百分比 | number | 0 |
| showInfo | 是否显示进度数值或状态图标 | boolean | true |
| status | 状态,可选:`success` `exception` `active` `normal` | string | - |
| status | 状态,可选:`success` `exception` `normal` `active`(仅限 line) | string | - |
| strokeLinecap | | Enum{ 'round', 'square' } | `round` |
| strokeColor | 进度条的色彩 | string | - |
| successPercent | 已完成的分段百分比 | number | 0 |

View File

@ -15,8 +15,8 @@ export interface RateProps {
allowClear?: boolean;
disabled?: boolean;
tooltips?: Array<string>;
onChange?: (value: number) => any;
onHoverChange?: (value: number) => any;
onChange?: (value: number) => void;
onHoverChange?: (value: number) => void;
character?: React.ReactNode;
className?: string;
style?: React.CSSProperties;

View File

@ -39,7 +39,7 @@ function fetch(value, callback) {
.then(response => response.json())
.then(d => {
if (currentValue === value) {
const result = d.result;
const { result } = d;
const data = [];
result.forEach(r => {
data.push({

View File

@ -14,9 +14,9 @@ Select component to select value from options.
## API
```html
<Select>
<Option value="lucy">lucy</Option>
</Select>
<select>
<option value="lucy">lucy</option>
</select>
```
### Select props

View File

@ -30,9 +30,11 @@ export interface AbstractSelectProps {
dropdownStyle?: React.CSSProperties;
dropdownMenuStyle?: React.CSSProperties;
dropdownMatchSelectWidth?: boolean;
onSearch?: (value: string) => any;
onSearch?: (value: string) => void;
getPopupContainer?: (triggerNode: HTMLElement) => HTMLElement;
filterOption?: boolean | ((inputValue: string, option: React.ReactElement<OptionProps>) => any);
filterOption?:
| boolean
| ((inputValue: string, option: React.ReactElement<OptionProps>) => boolean);
id?: string;
defaultOpen?: boolean;
open?: boolean;
@ -55,15 +57,18 @@ export interface SelectProps<T = SelectValue> extends AbstractSelectProps {
mode?: 'default' | 'multiple' | 'tags' | 'combobox' | string;
optionLabelProp?: string;
firstActiveValue?: string | string[];
onChange?: (value: T, option: React.ReactElement<any> | React.ReactElement<any>[]) => void;
onSelect?: (value: T extends (infer I)[] ? I : T, option: React.ReactElement<any>) => any;
onDeselect?: (value: T extends (infer I)[] ? I : T) => any;
onChange?: (
value: T,
option: React.ReactElement<any> | React.ReactElement<any>[],
) => void;
onSelect?: (value: T extends (infer I)[] ? I : T, option: React.ReactElement<any>) => void;
onDeselect?: (value: T extends (infer I)[] ? I : T) => void;
onBlur?: (value: T) => void;
onFocus?: () => void;
onPopupScroll?: React.UIEventHandler<HTMLDivElement>;
onInputKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
onMouseEnter?: (e: React.MouseEvent<HTMLInputElement>) => any;
onMouseLeave?: (e: React.MouseEvent<HTMLInputElement>) => any;
onMouseEnter?: (e: React.MouseEvent<HTMLInputElement>) => void;
onMouseLeave?: (e: React.MouseEvent<HTMLInputElement>) => void;
maxTagCount?: number;
maxTagTextLength?: number;
maxTagPlaceholder?: React.ReactNode | ((omittedValues: T[]) => React.ReactNode);

View File

@ -14,9 +14,9 @@ title: Select
## API
```html
```jsx
<Select>
<Option value="lucy">lucy</Option>
<Select.Option value="lucy">lucy</Select.Option>
</Select>
```

View File

@ -5,7 +5,7 @@ export interface SkeletonAvatarProps {
prefixCls?: string;
className?: string;
style?: object;
size?: 'large' | 'small' | 'default';
size?: 'large' | 'small' | 'default' | number;
shape?: 'circle' | 'square';
}

View File

@ -25,7 +25,7 @@ interface HandleGeneratorInfo {
export type HandleGeneratorFn = (
tooltipPrefixCls: string,
info: HandleGeneratorInfo,
) => React.ReactElement<any>;
) => React.ReactNode;
export interface SliderProps {
prefixCls?: string;

View File

@ -8,7 +8,7 @@ import { tuple } from '../_util/type';
const SpinSizes = tuple('small', 'default', 'large');
export type SpinSize = (typeof SpinSizes)[number];
export type SpinIndicator = React.ReactElement<any>;
export type SpinIndicator = React.ReactElement<HTMLElement>;
export interface SpinProps {
prefixCls?: string;
@ -34,8 +34,8 @@ function renderIndicator(prefixCls: string, props: SpinProps): React.ReactNode {
const { indicator } = props;
const dotClassName = `${prefixCls}-dot`;
if (React.isValidElement(indicator)) {
return React.cloneElement(indicator as SpinIndicator, {
className: classNames((indicator as SpinIndicator).props.className, dotClassName),
return React.cloneElement(indicator, {
className: classNames(indicator.props.className, dotClassName),
});
}

View File

@ -16,7 +16,7 @@ Countdown component.
```jsx
import { Statistic, Row, Col } from 'antd';
const Countdown = Statistic.Countdown;
const { Countdown } = Statistic;
const deadline = Date.now() + 1000 * 60 * 60 * 24 * 2 + 1000 * 30; // Moment is also OK
function onFinish() {

View File

@ -23,7 +23,7 @@ export interface StepProps {
className?: string;
description?: React.ReactNode;
icon?: React.ReactNode;
onClick?: React.MouseEventHandler<any>;
onClick?: React.MouseEventHandler<HTMLElement>;
status?: 'wait' | 'process' | 'finish' | 'error';
title?: React.ReactNode;
style?: React.CSSProperties;

View File

@ -1,6 +1,6 @@
import React from 'react';
import Switch from '..';
import { mount } from 'enzyme';
import Switch from '..';
import focusTest from '../../../tests/shared/focusTest';
describe('Switch', () => {

View File

@ -13,8 +13,8 @@ export interface SwitchProps {
className?: string;
checked?: boolean;
defaultChecked?: boolean;
onChange?: (checked: boolean, event: MouseEvent) => any;
onClick?: (checked: boolean, event: MouseEvent) => any;
onChange?: (checked: boolean, event: MouseEvent) => void;
onClick?: (checked: boolean, event: MouseEvent) => void;
checkedChildren?: React.ReactNode;
unCheckedChildren?: React.ReactNode;
disabled?: boolean;

View File

@ -1,7 +1,7 @@
import * as React from 'react';
export interface FilterDropdownMenuWrapperProps {
children?: any;
children?: React.ReactNode;
className?: string;
}

View File

@ -1,5 +1,5 @@
export interface Store {
setState: (partial: Object) => void;
setState: (partial: object) => void;
getState: () => any;
subscribe: (listener: () => void) => () => void;
}

View File

@ -15,7 +15,7 @@ By using custom components, we can integrate table with react-dnd to implement d
```jsx
import { Table } from 'antd';
import { DragDropContext, DragSource, DropTarget } from 'react-dnd';
import { DndProvider, DragSource, DropTarget } from 'react-dnd';
import HTML5Backend from 'react-dnd-html5-backend';
import update from 'immutability-helper';
@ -26,7 +26,7 @@ class BodyRow extends React.Component {
const { isOver, connectDragSource, connectDropTarget, moveRow, ...restProps } = this.props;
const style = { ...restProps.style, cursor: 'move' };
let className = restProps.className;
let { className } = restProps;
if (isOver) {
if (restProps.index > dragingIndex) {
className += ' drop-over-downward';
@ -144,22 +144,22 @@ class DragSortingTable extends React.Component {
render() {
return (
<Table
columns={columns}
dataSource={this.state.data}
components={this.components}
onRow={(record, index) => ({
index,
moveRow: this.moveRow,
})}
/>
<DndProvider backend={HTML5Backend}>
<Table
columns={columns}
dataSource={this.state.data}
components={this.components}
onRow={(record, index) => ({
index,
moveRow: this.moveRow,
})}
/>
</DndProvider>
);
}
}
const Demo = DragDropContext(HTML5Backend)(DragSortingTable);
ReactDOM.render(<Demo />, mountNode);
ReactDOM.render(<DragSortingTable />, mountNode);
```
```css

View File

@ -132,7 +132,7 @@ class Demo extends React.Component {
};
render() {
const state = this.state;
const { state } = this;
return (
<div>
<div className="components-table-demo-control-bar">

View File

@ -122,6 +122,7 @@ ReactDOM.render(<Demo />, mountNode);
```css
#components-table-demo-resizable-column .react-resizable {
position: relative;
background-clip: padding-box;
}
#components-table-demo-resizable-column .react-resizable-handle {
@ -131,5 +132,6 @@ ReactDOM.render(<Demo />, mountNode);
bottom: 0;
right: -5px;
cursor: col-resize;
z-index: 1;
}
```

View File

@ -96,7 +96,6 @@ class App extends React.Component {
},
},
],
onSelection: this.onSelection,
};
return <Table rowSelection={rowSelection} columns={columns} dataSource={data} />;
}

View File

@ -47,9 +47,9 @@ export interface ColumnProps<T> {
filteredValue?: any[];
sortOrder?: SortOrder | boolean;
children?: ColumnProps<T>[];
onCellClick?: (record: T, event: any) => void;
onCell?: (record: T, rowIndex: number) => any;
onHeaderCell?: (props: ColumnProps<T>) => any;
onCellClick?: (record: T, event: Event) => void;
onCell?: (record: T, rowIndex: number) => TableEventListeners;
onHeaderCell?: (props: ColumnProps<T>) => TableEventListeners;
sortDirections?: SortOrder[];
}
@ -88,7 +88,7 @@ export type SelectionSelectFn<T> = (
selected: boolean,
selectedRows: Object[],
nativeEvent: Event,
) => any;
) => void;
export type TableSelectWay = 'onSelect' | 'onSelectMultiple' | 'onSelectAll' | 'onSelectInvert';
@ -129,6 +129,15 @@ export interface TableCurrentDataSource<T> {
currentDataSource: T[];
}
export interface TableEventListeners {
onClick?: (arg: React.SyntheticEvent) => void;
onDoubleClick?: (arg: React.SyntheticEvent) => void;
onContextMenu?: (arg: React.SyntheticEvent) => void;
onMouseEnter?: (arg: React.SyntheticEvent) => void;
onMouseLeave?: (arg: React.SyntheticEvent) => void;
[name: string]: any; // https://github.com/ant-design/ant-design/issues/17245#issuecomment-504807714
}
export interface TableProps<T> {
prefixCls?: string;
dropdownPrefixCls?: string;
@ -165,8 +174,8 @@ export interface TableProps<T> {
locale?: TableLocale;
indentSize?: number;
onRowClick?: (record: T, index: number, event: Event) => void;
onRow?: (record: T, index: number) => any;
onHeaderRow?: (columns: ColumnProps<T>[], index: number) => any;
onRow?: (record: T, index: number) => TableEventListeners;
onHeaderRow?: (columns: ColumnProps<T>[]) => TableEventListeners;
useFixedHeader?: boolean;
bordered?: boolean;
showHeader?: boolean;
@ -193,7 +202,7 @@ export interface TableState<T> {
pivot?: number;
}
export type SelectionItemSelectFn = (key: string[]) => any;
export type SelectionItemSelectFn = (key: string[]) => void;
type GetPopupContainer = (triggerNode?: HTMLElement) => HTMLElement;
export interface SelectionItem {
@ -204,10 +213,10 @@ export interface SelectionItem {
export interface SelectionCheckboxAllProps<T> {
store: Store;
locale: any;
locale: TableLocale;
disabled: boolean;
getCheckboxPropsByItem: (item: any, index: number) => any;
getRecordKey: (record: any, index?: number) => string;
getCheckboxPropsByItem: (item: T, index: number) => { defaultChecked: boolean };
getRecordKey: (record: T, index?: number) => string;
data: T[];
prefixCls: string | undefined;
onSelect: (key: string, index: number, selectFunc: any) => void;
@ -255,7 +264,7 @@ export interface FilterMenuProps<T> {
export interface FilterMenuState<T> {
selectedKeys: string[];
valueKeys: { [name: string]: any };
valueKeys: { [name: string]: string };
keyPathOfSelectedItem: { [key: string]: string };
visible?: boolean;
prevProps: FilterMenuProps<T>;
@ -267,5 +276,5 @@ export type PrepareParamsArgumentsReturn<T> = [
Object,
{
currentDataSource: T[];
}
},
];

View File

@ -22,7 +22,10 @@
}
&-empty &-body {
overflow: auto !important;
// https://github.com/ant-design/ant-design/issues/11135
overflow-x: auto !important;
// https://github.com/ant-design/ant-design/issues/17175
overflow-y: hidden !important;
}
table {
@ -408,11 +411,13 @@
&-placeholder {
position: relative;
z-index: 1;
margin-top: -1px;
padding: @table-padding-vertical @table-padding-horizontal;
color: @disabled-color;
font-size: @font-size-base;
text-align: center;
background: @component-background;
border-top: @border-width-base @border-style-base @border-color-split;
border-bottom: @border-width-base @border-style-base @border-color-split;
border-radius: 0 0 @border-radius-base @border-radius-base;
.@{iconfont-css-prefix} {

View File

@ -41,14 +41,14 @@ class Demo extends React.Component {
};
add = () => {
const panes = this.state.panes;
const { panes } = this.state;
const activeKey = `newTab${this.newTabIndex++}`;
panes.push({ title: 'New Tab', content: 'New Tab Pane', key: activeKey });
this.setState({ panes, activeKey });
};
remove = targetKey => {
let activeKey = this.state.activeKey;
let { activeKey } = this.state;
let lastIndex;
this.state.panes.forEach((pane, i) => {
if (pane.key === targetKey) {

View File

@ -47,14 +47,14 @@ class Demo extends React.Component {
};
add = () => {
const panes = this.state.panes;
const { panes } = this.state;
const activeKey = `newTab${this.newTabIndex++}`;
panes.push({ title: 'New Tab', content: 'Content of new Tab', key: activeKey });
this.setState({ panes, activeKey });
};
remove = targetKey => {
let activeKey = this.state.activeKey;
let { activeKey } = this.state;
let lastIndex;
this.state.panes.forEach((pane, i) => {
if (pane.key === targetKey) {

View File

@ -40,7 +40,7 @@ class SlidingTabsDemo extends React.Component {
<Radio.Button value="left">Vertical</Radio.Button>
</Radio.Group>
<Tabs defaultActiveKey="1" tabPosition={mode} style={{ height: 220 }}>
{[...Array(30).keys()].map((i) => (
{[...Array(30).keys()].map(i => (
<TabPane tab={`Tab-${i}`} key={i}>
Content of tab {i}
</TabPane>

View File

@ -18,13 +18,13 @@ export interface TabsProps {
hideAdd?: boolean;
onChange?: (activeKey: string) => void;
onTabClick?: Function;
onPrevClick?: React.MouseEventHandler<any>;
onNextClick?: React.MouseEventHandler<any>;
onPrevClick?: React.MouseEventHandler<HTMLElement>;
onNextClick?: React.MouseEventHandler<HTMLElement>;
tabBarExtraContent?: React.ReactNode | null;
tabBarStyle?: React.CSSProperties;
type?: TabsType;
tabPosition?: TabsPosition;
onEdit?: (targetKey: string | React.MouseEvent<HTMLElement>, action: any) => void;
onEdit?: (targetKey: string | React.MouseEvent<HTMLElement>, action: 'add' | 'remove') => void;
size?: 'large' | 'default' | 'small';
style?: React.CSSProperties;
prefixCls?: string;
@ -32,6 +32,7 @@ export interface TabsProps {
animated?: boolean | { inkBar: boolean; tabPane: boolean };
tabBarGutter?: number;
renderTabBar?: (props: TabsProps, DefaultTabBar: React.ReactNode) => React.ReactElement<any>;
destroyInactiveTabPane?: boolean;
}
// Tabs

View File

@ -29,7 +29,7 @@ export default class CheckableTag extends React.Component<CheckableTagProps> {
);
delete (restProps as any).onChange; // TypeScript cannot check delete now.
return <div {...restProps as any} className={cls} onClick={this.handleClick} />;
return <div {...(restProps as any)} className={cls} onClick={this.handleClick} />;
};
render() {

View File

@ -16,7 +16,7 @@ Select your favourite topics.
```jsx
import { Tag } from 'antd';
const CheckableTag = Tag.CheckableTag;
const { CheckableTag } = Tag;
const tagsFromServer = ['Movies', 'Books', 'Music', 'Sports'];

View File

@ -22,10 +22,10 @@ export interface PlacementsConfig {
horizontalArrowShift?: number;
verticalArrowShift?: number;
arrowPointAtCenter?: boolean;
autoAdjustOverflow?: any;
autoAdjustOverflow?: boolean | AdjustOverflow;
}
export function getOverflowOptions(autoAdjustOverflow: any) {
export function getOverflowOptions(autoAdjustOverflow: boolean | AdjustOverflow) {
if (typeof autoAdjustOverflow === 'boolean') {
return autoAdjustOverflow ? autoAdjustOverflowEnabled : autoAdjustOverflowDisabled;
}

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