refactor: close: #3490

This commit is contained in:
Benjy Cui 2016-10-24 16:30:38 +08:00
parent 4878258f6c
commit 08e21e0a2f
19 changed files with 163 additions and 127 deletions

View File

@ -33,10 +33,7 @@ export interface RadioGroupProps {
export default class RadioGroup extends React.Component<RadioGroupProps, any> {
static defaultProps = {
prefixCls: 'ant-radio-group',
disabled: false,
onChange() {
},
};
constructor(props) {
super(props);
@ -76,11 +73,15 @@ export default class RadioGroup extends React.Component<RadioGroupProps, any> {
value: ev.target.value,
});
}
this.props.onChange(ev);
const onChange = this.props.onChange;
if (onChange) {
onChange(ev);
}
}
render() {
const props = this.props;
const children = React.Children.map(props.children, (radio: any) => {
const children = React.Children.map((props.children || {}), (radio: any) => {
if (radio && (radio.type === Radio || radio.type === RadioButton) && radio.props) {
const keyProps = {};
if (!('key' in radio) && typeof radio.props.value === 'string') {
@ -94,9 +95,10 @@ export default class RadioGroup extends React.Component<RadioGroupProps, any> {
}
return radio;
});
const prefixCls = props.prefixCls || 'ant-radio-group';
const classString = classNames({
[props.prefixCls]: true,
[`${props.prefixCls}-${props.size}`]: props.size,
[prefixCls]: true,
[`${prefixCls}-${props.size}`]: props.size,
});
return <div className={classString} style={props.style}>{children}</div>;
}

View File

@ -28,7 +28,7 @@ export default class Radio extends React.Component<RadioProps, any> {
return PureRenderMixin.shouldComponentUpdate.apply(this, args);
}
render() {
const { prefixCls, children, checked, disabled, className, style } = this.props;
const { prefixCls, children, checked, disabled, className = '', style } = this.props;
const wrapperClassString = classNames({
[`${prefixCls}-wrapper`]: true,
[`${prefixCls}-wrapper-checked`]: checked,

View File

@ -13,7 +13,7 @@ export interface SelectProps {
defaultValue?: SelectValue;
size?: 'default' | 'large' | 'small';
combobox?: boolean;
notFoundContent?: React.ReactNode | string;
notFoundContent?: React.ReactNode | null;
showSearch?: boolean;
transitionName?: string;
choiceTransitionName?: string;
@ -84,7 +84,7 @@ export default class Select extends React.Component<SelectProps, any> {
render() {
const {
prefixCls,
className,
className = '',
size,
combobox,
showSearch,

View File

@ -28,7 +28,7 @@ export default class Switch extends React.Component<SwitchProps, any> {
};
render() {
const { prefixCls, size, className } = this.props;
const { prefixCls, size, className = '' } = this.props;
const classes = classNames({
[className]: !!className,
[`${prefixCls}-small`]: size === 'small',

View File

@ -0,0 +1,13 @@
import React from 'react';
export interface FilterDropdownMenuWrapperProps {
onClick?: React.MouseEventHandler<any>;
children?: any;
className?: string;
}
export default class FilterDropdownMenuWrapper extends React.Component<FilterDropdownMenuWrapperProps, any> {
render() {
const { onClick, children, className } = this.props;
return <div className={className} onClick={onClick}>{children}</div>;
}
}

View File

@ -68,7 +68,7 @@ export interface TableProps {
pagination?: PaginationProps | boolean;
size?: 'default' | 'small';
dataSource?: Object[];
columns?: TableColumnConfig[];
columns: TableColumnConfig[];
rowKey?: string | ((record: Object, index: number) => string);
rowClassName?: (record: Object, index: number) => string;
expandedRowRender?: any;
@ -87,7 +87,7 @@ export interface TableProps {
footer?: (currentPageData: Object[]) => React.ReactNode;
title?: (currentPageData: Object[]) => React.ReactNode;
scroll?: { x?: boolean | number, y?: boolean | number};
childrenColumnName?: 'string';
childrenColumnName?: string;
bodyStyle?: React.CSSProperties;
className?: string;
}
@ -117,7 +117,6 @@ export default class Table extends React.Component<TableProps, any> {
static defaultProps = {
dataSource: [],
prefixCls: 'ant-table',
dropdownPrefixCls: 'ant-dropdown',
useFixedHeader: false,
rowSelection: null,
className: '',
@ -125,10 +124,8 @@ export default class Table extends React.Component<TableProps, any> {
loading: false,
bordered: false,
indentSize: 20,
onChange: noop,
locale: {},
rowKey: 'key',
childrenColumnName: 'children',
};
static contextTypes = {
@ -361,7 +358,10 @@ export default class Table extends React.Component<TableProps, any> {
this.setState(newState);
}
this.props.onChange.apply(null, this.prepareParamsArguments(assign({}, this.state, newState)));
const onChange = this.props.onChange;
if (onChange) {
onChange.apply(null, this.prepareParamsArguments(assign({}, this.state, newState)));
}
}
handleFilter = (column, nextFilters) => {
@ -409,11 +409,14 @@ export default class Table extends React.Component<TableProps, any> {
}
this.setState(newState, () => {
props.onChange.apply(null, this.prepareParamsArguments(assign({}, this.state, {
selectionDirty: false,
filters,
pagination,
})));
const onChange = this.props.onChange;
if (onChange) {
onChange.apply(null, this.prepareParamsArguments(assign({}, this.state, {
selectionDirty: false,
filters,
pagination,
})));
}
});
}
@ -463,7 +466,7 @@ export default class Table extends React.Component<TableProps, any> {
.map((item, i) => this.getRecordKey(item, i));
// 记录变化的列
const changeRowKeys = [];
const changeRowKeys: string[] = [];
if (checked) {
changableRowKeys.forEach(key => {
if (selectedRowKeys.indexOf(key) < 0) {
@ -511,10 +514,13 @@ export default class Table extends React.Component<TableProps, any> {
}
this.setState(newState);
this.props.onChange.apply(null, this.prepareParamsArguments(assign({}, this.state, {
selectionDirty: false,
pagination,
})));
const onChange = this.props.onChange;
if (onChange) {
onChange.apply(null, this.prepareParamsArguments(assign({}, this.state, {
selectionDirty: false,
pagination,
})));
}
}
renderSelectionRadio = (_, record, index) => {
@ -558,7 +564,7 @@ export default class Table extends React.Component<TableProps, any> {
);
}
getRecordKey(record, index?) {
getRecordKey(record, index?): string {
const rowKey = this.props.rowKey;
if (typeof rowKey === 'function') {
return rowKey(record, index);
@ -584,11 +590,11 @@ export default class Table extends React.Component<TableProps, any> {
}
renderRowSelection() {
const prefixCls = this.props.prefixCls;
const { prefixCls, rowSelection } = this.props;
const columns = this.props.columns.concat();
if (this.props.rowSelection) {
if (rowSelection) {
const data = this.getFlatCurrentPageData().filter((item) => {
if (this.props.rowSelection.getCheckboxProps) {
if (rowSelection.getCheckboxProps) {
return !this.getCheckboxPropsByItem(item).disabled;
}
return true;
@ -617,7 +623,7 @@ export default class Table extends React.Component<TableProps, any> {
);
}
let selectionColumn;
if (this.props.rowSelection.type === 'radio') {
if (rowSelection.type === 'radio') {
selectionColumn = {
key: 'selection-column',
render: this.renderSelectionRadio,
@ -689,7 +695,7 @@ export default class Table extends React.Component<TableProps, any> {
selectedKeys={colFilters}
confirmFilter={this.handleFilter}
prefixCls={`${prefixCls}-filter`}
dropdownPrefixCls={dropdownPrefixCls}
dropdownPrefixCls={dropdownPrefixCls || 'ant-dropdown'}
/>
);
}
@ -736,9 +742,13 @@ export default class Table extends React.Component<TableProps, any> {
pagination.onShowSizeChange(current, pageSize);
const nextPagination = assign({}, pagination, { pageSize, current });
this.setState({ pagination: nextPagination });
this.props.onChange.apply(null, this.prepareParamsArguments(assign({}, this.state, {
pagination: nextPagination,
})));
const onChange = this.props.onChange;
if (onChange) {
onChange.apply(null, this.prepareParamsArguments(assign({}, this.state, {
pagination: nextPagination,
})));
}
}
renderPagination() {
@ -819,7 +829,7 @@ export default class Table extends React.Component<TableProps, any> {
}
recursiveSort(data, sorterFn) {
const { childrenColumnName } = this.props;
const { childrenColumnName = 'children' } = this.props;
return data.sort(sorterFn).map(item => (item[childrenColumnName] ? assign(
{},
item, {
@ -849,8 +859,9 @@ export default class Table extends React.Component<TableProps, any> {
if (values.length === 0) {
return;
}
data = col.onFilter ? data.filter(record => {
return values.some(v => col.onFilter(v, record));
const onFilter = col.onFilter;
data = onFilter ? data.filter(record => {
return values.some(v => onFilter(v, record));
}) : data;
});
}

View File

@ -4,15 +4,7 @@ import Dropdown from '../dropdown';
import Icon from '../icon';
import Checkbox from '../checkbox';
import Radio from '../radio';
export interface FilterDropdownMenuWrapperProps {
onClick?: React.MouseEventHandler<any>;
children?: any;
className?: string;
}
const FilterDropdownMenuWrapper: React.StatelessComponent<FilterDropdownMenuWrapperProps> =
({ onClick, children, className }) =>
<div className={className} onClick={onClick}>{children}</div>;
import FilterDropdownMenuWrapper from './FilterDropdownMenuWrapper';
export interface FilterMenuProps {
locale: any;

View File

@ -1,6 +1,6 @@
import assign from 'object-assign';
export function flatArray(data = [], childrenName = 'children') {
const result = [];
export function flatArray(data: Object[] = [], childrenName = 'children') {
const result: Object[] = [];
const loop = (array) => {
array.forEach(item => {
const newItem = assign({}, item);

View File

@ -15,7 +15,7 @@ export interface TabsProps {
hideAdd?: boolean;
onChange?: (activeKey: string) => void;
onTabClick?: Function;
tabBarExtraContent?: React.ReactNode;
tabBarExtraContent?: React.ReactNode | null;
type?: TabsType;
tabPosition?: TabsPosition;
onEdit?: (targetKey: string, action: any) => void;
@ -24,6 +24,7 @@ export interface TabsProps {
prefixCls?: string;
className?: string;
animated?: boolean;
children: any;
}
// Tabs
@ -38,15 +39,15 @@ export default class Tabs extends React.Component<TabsProps, any> {
static defaultProps = {
prefixCls: 'ant-tabs',
type: 'line', // or 'card' 'editable-card'
onChange() { },
onEdit() { },
hideAdd: false,
animated: true,
};
createNewTab = (targetKey) => {
this.props.onEdit(targetKey, 'add');
const onEdit = this.props.onEdit;
if (onEdit) {
onEdit(targetKey, 'add');
}
}
removeTab = (targetKey, e) => {
@ -54,18 +55,26 @@ export default class Tabs extends React.Component<TabsProps, any> {
if (!targetKey) {
return;
}
this.props.onEdit(targetKey, 'remove');
const onEdit = this.props.onEdit;
if (onEdit) {
onEdit(targetKey, 'remove');
}
}
handleChange = (activeKey) => {
this.props.onChange(activeKey);
const onChange = this.props.onChange;
if (onChange) {
onChange(activeKey);
}
}
render() {
let {
prefixCls,
className = '',
size,
type,
type = 'line',
tabPosition,
children,
tabBarExtraContent,
@ -73,8 +82,8 @@ export default class Tabs extends React.Component<TabsProps, any> {
onTabClick,
animated,
} = this.props;
let className = classNames({
[this.props.className]: !!this.props.className,
let cls = classNames({
[className]: !!className,
[`${prefixCls}-mini`]: size === 'small' || size as string === 'mini',
[`${prefixCls}-vertical`]: tabPosition === 'left' || tabPosition === 'right',
[`${prefixCls}-card`]: type.indexOf('card') >= 0,
@ -115,7 +124,7 @@ export default class Tabs extends React.Component<TabsProps, any> {
return (
<RcTabs {...this.props}
className={className}
className={cls}
tabBarPosition={tabPosition}
renderTabBar={() => (
<ScrollableInkTabBar

View File

@ -22,8 +22,6 @@ export default class Tag extends React.Component<TagProps, any> {
static defaultProps = {
prefixCls: 'ant-tag',
closable: false,
onClose() { },
afterClose() { },
};
constructor(props) {
@ -36,7 +34,10 @@ export default class Tag extends React.Component<TagProps, any> {
}
close = (e) => {
this.props.onClose(e);
const onClose = this.props.onClose;
if (onClose) {
onClose(e);
}
if (e.defaultPrevented) {
return;
}
@ -55,7 +56,11 @@ export default class Tag extends React.Component<TagProps, any> {
closed: true,
closing: false,
});
this.props.afterClose();
const afterClose = this.props.afterClose;
if (afterClose) {
afterClose();
}
}
}

View File

@ -42,10 +42,7 @@ export interface TimePickerContext {
export default class TimePicker extends React.Component<TimePickerProps, any> {
static defaultProps = {
format: 'HH:mm:ss',
prefixCls: 'ant-time-picker',
onChange() {
},
align: {
offset: [0, -2],
},
@ -82,7 +79,10 @@ export default class TimePicker extends React.Component<TimePickerProps, any> {
if (!('value' in this.props)) {
this.setState({ value });
}
this.props.onChange(value, (value && value.format(this.props.format)) || '');
const { onChange, format = 'HH:mm:ss' } = this.props;
if (onChange) {
onChange(value, (value && value.format(format)) || '');
}
}
getLocale() {

View File

@ -41,7 +41,6 @@ export default class Tooltip extends React.Component<TooltipProps, any> {
transitionName: 'zoom-big-fast',
mouseEnterDelay: 0.1,
mouseLeaveDelay: 0.1,
onVisibleChange() {},
arrowPointAtCenter: false,
};
@ -59,7 +58,10 @@ export default class Tooltip extends React.Component<TooltipProps, any> {
onVisibleChange = (visible) => {
this.setState({ visible });
this.props.onVisibleChange(visible);
const onVisibleChange = this.props.onVisibleChange;
if (onVisibleChange) {
onVisibleChange(visible);
}
}
getPopupDomNode() {

View File

@ -9,7 +9,7 @@ function noop() {
}
export interface TransferItem {
key: number | string;
key: string;
title: string;
description?: string;
disabled?: boolean;
@ -50,15 +50,9 @@ export default class Transfer extends React.Component<TransferProps, any> {
static Search = Search;
static defaultProps = {
prefixCls: 'ant-transfer',
dataSource: [],
render: noop,
onChange: noop,
onSelectChange: noop,
operations: [],
showSearch: false,
body: noop,
footer: noop,
};
static propTypes = {
@ -119,20 +113,20 @@ export default class Transfer extends React.Component<TransferProps, any> {
});
}
}
splitDataSource(props) {
splitDataSource(props: TransferProps) {
if (this.splitedDataSource) {
return this.splitedDataSource;
}
const { dataSource, targetKeys = [] } = props;
if (props.rowKey) {
const { rowKey, dataSource, targetKeys = [] } = props;
if (rowKey) {
dataSource.forEach(record => {
record.key = props.rowKey(record);
record.key = rowKey(record);
});
}
const leftDataSource = dataSource.filter(({ key }) => targetKeys.indexOf(key) === -1);
const rightDataSource = [];
const rightDataSource: TransferItem[] = [];
targetKeys.forEach((targetKey) => {
const targetItem = dataSource.filter(record => record.key === targetKey)[0];
if (targetItem) {
@ -164,7 +158,9 @@ export default class Transfer extends React.Component<TransferProps, any> {
});
this.handleSelectChange(oppositeDirection, []);
onChange(newTargetKeys, direction, moveKeys);
if (onChange) {
onChange(newTargetKeys, direction, moveKeys);
}
}
moveToLeft = () => this.moveTo('left')
@ -173,6 +169,10 @@ export default class Transfer extends React.Component<TransferProps, any> {
handleSelectChange(direction: string, holder: string[]) {
const { leftCheckedKeys, rightCheckedKeys } = this.state;
const onSelectChange = this.props.onSelectChange;
if (!onSelectChange) {
return;
}
if (direction === 'left') {
onSelectChange(holder, rightCheckedKeys);
} else {
@ -253,8 +253,8 @@ export default class Transfer extends React.Component<TransferProps, any> {
render() {
const {
prefixCls, operations, showSearch, notFoundContent,
searchPlaceholder, body, footer, listStyle, className,
prefixCls = 'ant-transfer', operations = [], showSearch, notFoundContent,
searchPlaceholder, body, footer, listStyle, className = '',
filterOption, render,
} = this.props;
const { leftFilter, rightFilter, leftCheckedKeys, rightCheckedKeys } = this.state;

View File

@ -17,21 +17,21 @@ export function isRenderResultPlainObject(result) {
}
export interface TransferListProps {
prefixCls?: string;
prefixCls: string;
dataSource: TransferItem[];
filter?: string;
showSearch?: boolean;
searchPlaceholder?: string;
titleText?: string;
style?: React.CSSProperties;
handleFilter?: (e: any) => void;
handleSelect?: (selectedItem: any, checked: boolean) => void;
handleSelectAll?: (dataSource: any[], checkAll: boolean) => void;
handleClear?: () => void;
handleFilter: (e: any) => void;
handleSelect: (selectedItem: any, checked: boolean) => void;
handleSelectAll: (dataSource: any[], checkAll: boolean) => void;
handleClear: () => void;
render?: (item: any) => any;
body?: (props: any) => any;
footer?: (props: any) => void;
checkedKeys?: any[];
checkedKeys: string[];
checkStatus?: boolean;
position?: string;
notFoundContent?: React.ReactNode | string;
@ -49,14 +49,7 @@ export default class TransferList extends React.Component<TransferListProps, any
dataSource: [],
titleText: '',
showSearch: false,
handleClear: noop,
handleFilter: noop,
handleSelect: noop,
handleSelectAll: noop,
render: noop,
// advanced
body: noop,
footer: noop,
};
static propTypes = {
@ -161,7 +154,7 @@ export default class TransferList extends React.Component<TransferListProps, any
render() {
const { prefixCls, dataSource, titleText, filter, checkedKeys,
body, footer, showSearch, render, style } = this.props;
body = noop, footer = noop, showSearch, render = noop, style } = this.props;
let { searchPlaceholder, notFoundContent } = this.props;
@ -174,7 +167,7 @@ export default class TransferList extends React.Component<TransferListProps, any
[`${prefixCls}-with-footer`]: !!footerDom,
});
const filteredDataSource = [];
const filteredDataSource: TransferItem[] = [];
const showItems = dataSource.map((item) => {
const renderResult = render(item);
@ -207,7 +200,7 @@ export default class TransferList extends React.Component<TransferListProps, any
key={item.key}
className={className}
title={renderedText}
onClick={item.disabled ? null : () => this.handleSelect(item)}
onClick={item.disabled ? undefined : () => this.handleSelect(item)}
>
<Checkbox checked={checkedKeys.some(key => key === item.key)} disabled={item.disabled} />
<span>{renderedEl}</span>

View File

@ -2,9 +2,6 @@ import React from 'react';
import Icon from '../icon';
import Input from '../input';
function noop() {
}
export interface SearchProps {
prefixCls?: string;
placeholder?: string;
@ -16,17 +13,22 @@ export interface SearchProps {
export default class Search extends React.Component<SearchProps, any> {
static defaultProps = {
placeholder: '',
onChange: noop,
handleClear: noop,
};
handleChange = (e) => {
this.props.onChange(e);
const onChange = this.props.onChange;
if (onChange) {
onChange(e);
}
}
handleClear = (e) => {
e.preventDefault();
this.props.handleClear(e);
const handleClear = this.props.handleClear;
if (handleClear) {
handleClear(e);
}
}
render() {

View File

@ -28,7 +28,7 @@ export default class TreeSelect extends React.Component<TreeSelectProps, any> {
render() {
const props = this.props;
let {
size, className, notFoundContent, prefixCls,
size, className = '', notFoundContent, prefixCls,
} = this.props;
const cls = classNames({

View File

@ -6,16 +6,13 @@ import classNames from 'classnames';
import assign from 'object-assign';
import { UploadProps } from './interface';
function noop() {
}
function T() {
return true;
}
// Fix IE file.status problem
// via coping a new Object
function fileToObject(file) {
function fileToObject(file): any {
return {
lastModified: file.lastModified,
lastModifiedDate: file.lastModifiedDate,
@ -64,20 +61,16 @@ export default class Upload extends React.Component<UploadProps, any> {
static Dragger = Dragger;
static defaultProps = {
prefixCls: 'ant-upload',
type: 'select',
multiple: false,
action: '',
data: {},
accept: '',
onChange: noop,
beforeUpload: T,
showUploadList: true,
listType: 'text', // or pictrue
className: '',
disabled: false,
onRemove() {},
onPreview() {},
};
recentUploadStatus: boolean | PromiseLike<any>;
@ -194,7 +187,10 @@ export default class Upload extends React.Component<UploadProps, any> {
}
handleRemove(file) {
this.props.onRemove(file);
const onRemove = this.props.onRemove;
if (onRemove) {
onRemove(file);
}
let fileList = this.removeFile(file);
if (fileList) {
this.onChange({
@ -214,7 +210,11 @@ export default class Upload extends React.Component<UploadProps, any> {
if (!('fileList' in this.props)) {
this.setState({ fileList: info.fileList });
}
this.props.onChange(info);
const onChange = this.props.onChange;
if (onChange) {
onChange(info);
}
}
componentWillReceiveProps(nextProps) {
@ -237,7 +237,7 @@ export default class Upload extends React.Component<UploadProps, any> {
render() {
const {
prefixCls, showUploadList, listType, onPreview,
prefixCls = 'ant-upload', showUploadList, listType, onPreview,
type, disabled, children, className,
} = this.props;

View File

@ -15,7 +15,6 @@ const previewFile = (file, callback) => {
export default class UploadList extends React.Component<UploadListProps, any> {
static defaultProps = {
listType: 'text', // or picture
items: [],
progressAttr: {
strokeWidth: 3,
showInfo: false,
@ -24,19 +23,27 @@ export default class UploadList extends React.Component<UploadListProps, any> {
};
handleClose = (file) => {
this.props.onRemove(file);
const onRemove = this.props.onRemove;
if (onRemove) {
onRemove(file);
}
}
handlePreview = (file, e) => {
e.preventDefault();
return this.props.onPreview(file);
const onPreview = this.props.onPreview;
if (!onPreview) {
return;
}
return onPreview(file);
}
componentDidUpdate() {
if (this.props.listType !== 'picture' && this.props.listType !== 'picture-card') {
return;
}
this.props.items.forEach(file => {
(this.props.items || []).forEach(file => {
if (typeof document === 'undefined' ||
typeof window === 'undefined' ||
!(window as any).FileReader || !(window as any).File ||
@ -57,7 +64,7 @@ export default class UploadList extends React.Component<UploadListProps, any> {
}
render() {
const { prefixCls, items, listType } = this.props;
const { prefixCls, items = [], listType } = this.props;
const list = items.map(file => {
let progress;
let icon = <Icon type="paper-clip" />;

View File

@ -1,6 +1,6 @@
{
"compilerOptions": {
"strictNullChecks": false,
"strictNullChecks": true,
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"jsx": "preserve",