diff --git a/components/_util/splitObject.tsx b/components/_util/splitObject.tsx deleted file mode 100644 index 03b908936f..0000000000 --- a/components/_util/splitObject.tsx +++ /dev/null @@ -1,12 +0,0 @@ -export default function splitObject(obj, parts): Array { - const left = {}; - const right = {}; - Object.keys(obj).forEach((k) => { - if (parts.indexOf(k) !== -1) { - left[k] = obj[k]; - } else { - right[k] = obj[k]; - } - }); - return [left, right]; -} diff --git a/components/badge/ScrollNumber.tsx b/components/badge/ScrollNumber.tsx index 768dc27a48..df1485bf96 100644 --- a/components/badge/ScrollNumber.tsx +++ b/components/badge/ScrollNumber.tsx @@ -20,7 +20,7 @@ export interface ScrollNumberProps { component?: string; onAnimated?: Function; height?: number; - style: React.CSSProperties; + style?: React.CSSProperties; } export default class ScrollNumber extends Component { diff --git a/components/badge/index.tsx b/components/badge/index.tsx index 57ef4f5f2f..1e25182eb3 100644 --- a/components/badge/index.tsx +++ b/components/badge/index.tsx @@ -3,7 +3,6 @@ import Animate from 'rc-animate'; import ScrollNumber from './ScrollNumber'; import classNames from 'classnames'; import warning from '../_util/warning'; -import splitObject from '../_util/splitObject'; export interface BadgeProps { /** Number to show in badge */ @@ -37,23 +36,16 @@ export default class Badge extends React.Component { }; render() { - let [{ - count, prefixCls, overflowCount, className, style, children, dot, status, text, - }, restProps] = splitObject( - this.props, - ['count', 'prefixCls', 'overflowCount', 'className', 'style', 'children', 'dot', 'status', 'text'] - ); + const { count, prefixCls, overflowCount, className, style, children, dot, status, text, ...restProps } = this.props; const isDot = dot || status; - const realCount = count; - count = count > overflowCount ? `${overflowCount}+` : count; - + let displayCount = count > overflowCount ? `${overflowCount}+` : count; // dot mode don't need count if (isDot) { - count = ''; + displayCount = ''; } // null undefined "" "0" 0 - const hidden = (!count || count === '0') && !isDot; + const hidden = (!displayCount || displayCount === '0') && !isDot; const scrollNumberCls = classNames({ [`${prefixCls}-dot`]: isDot, [`${prefixCls}-count`]: !isDot, @@ -85,7 +77,7 @@ export default class Badge extends React.Component { ); @@ -95,7 +87,7 @@ export default class Badge extends React.Component { ); return ( - + {children} {children}; diff --git a/components/button/button-group.tsx b/components/button/button-group.tsx index a5d873c8bc..2340562d55 100644 --- a/components/button/button-group.tsx +++ b/components/button/button-group.tsx @@ -1,6 +1,5 @@ import React from 'react'; import classNames from 'classnames'; -import splitObject from '../_util/splitObject'; export type ButtonSize = 'small' | 'large' @@ -12,8 +11,7 @@ export interface ButtonGroupProps { } export default function ButtonGroup(props: ButtonGroupProps) { - const [{ prefixCls = 'ant-btn-group', size, className }, others] = - splitObject(props, ['prefixCls', 'size', 'className']); + const { prefixCls = 'ant-btn-group', size = '', className, ...others } = props; // large => lg // small => sm diff --git a/components/button/button.tsx b/components/button/button.tsx index 27a39e8e8e..4fee0ca22d 100644 --- a/components/button/button.tsx +++ b/components/button/button.tsx @@ -2,7 +2,7 @@ import React from 'react'; import classNames from 'classnames'; import { findDOMNode } from 'react-dom'; import Icon from '../icon'; -import splitObject from '../_util/splitObject'; + const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/; const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); function isString(str) { @@ -102,8 +102,7 @@ export default class Button extends React.Component { render() { const props = this.props; - const [{ type, shape, size, className, htmlType, children, icon, loading, prefixCls }, others] = splitObject(props, - ['type', 'shape', 'size', 'className', 'htmlType', 'children', 'icon', 'loading', 'prefixCls']); + const { type, shape, size = '', className, htmlType, children, icon, loading, prefixCls, ...others } = props; // large => lg // small => sm diff --git a/components/card/index.tsx b/components/card/index.tsx index be438a980c..a8b3a187cb 100644 --- a/components/card/index.tsx +++ b/components/card/index.tsx @@ -1,8 +1,8 @@ import React from 'react'; import classNames from 'classnames'; -import splitObject from '../_util/splitObject'; export interface CardProps { + prefixCls?: string; title?: React.ReactNode; extra?: React.ReactNode; bordered?: boolean; @@ -15,11 +15,10 @@ export interface CardProps { } export default (props: CardProps) => { - const [{ + const { prefixCls = 'ant-card', className, extra, bodyStyle, - title, loading, bordered = true, - }, others] = splitObject(props, - ['prefixCls', 'className', 'children', 'extra', 'bodyStyle', 'title', 'loading', 'bordered']); + title, loading, bordered = true, ...others, + } = props; let children = props.children; const classString = classNames(prefixCls, className, { [`${prefixCls}-loading`]: loading, diff --git a/components/cascader/index.tsx b/components/cascader/index.tsx index 120afb6fff..fcc0a83205 100644 --- a/components/cascader/index.tsx +++ b/components/cascader/index.tsx @@ -5,7 +5,6 @@ import classNames from 'classnames'; import omit from 'omit.js'; import Input from '../input'; import Icon from '../icon'; -import splitObject from '../_util/splitObject'; export interface CascaderOptionType { value: string; @@ -101,7 +100,6 @@ export default class Cascader extends React.Component { options: [], disabled: false, allowClear: true, - showSearch: false, notFoundContent: 'Not Found', }; @@ -247,10 +245,10 @@ export default class Cascader extends React.Component { render() { const { props, state } = this; - const [{ prefixCls, inputPrefixCls, children, placeholder, size, disabled, - className, style, allowClear, showSearch }, otherProps] = splitObject(props, - ['prefixCls', 'inputPrefixCls', 'children', 'placeholder', 'size', 'disabled', - 'className', 'style', 'allowClear', 'showSearch']); + const { + prefixCls, inputPrefixCls, children, placeholder, size, disabled, + className, style, allowClear, showSearch = false, ...otherProps, + } = props; const value = state.value; const sizeCls = classNames({ @@ -311,7 +309,7 @@ export default class Cascader extends React.Component { dropdownMenuColumnStyle.height = 'auto'; // Height of one row. } // The default value of `matchInputWidth` is `true` - const resultListMatchInputWidth = showSearch.matchInputWidth === false ? false : true; + const resultListMatchInputWidth = (showSearch as ShowSearchType).matchInputWidth === false ? false : true; if (resultListMatchInputWidth && state.inputValue && this.refs.input) { dropdownMenuColumnStyle.width = this.refs.input.refs.input.offsetWidth; } @@ -324,7 +322,7 @@ export default class Cascader extends React.Component { 0 ? null : placeholder} + placeholder={value && value.length > 0 ? undefined : placeholder} className={`${prefixCls}-input ${sizeCls}`} value={state.inputValue} disabled={disabled} diff --git a/components/checkbox/index.tsx b/components/checkbox/index.tsx index 69703a694e..4e70217544 100644 --- a/components/checkbox/index.tsx +++ b/components/checkbox/index.tsx @@ -3,9 +3,9 @@ import React from 'react'; import CheckboxGroup from './Group'; import classNames from 'classnames'; import PureRenderMixin from 'rc-util/lib/PureRenderMixin'; -import splitObject from '../_util/splitObject'; export interface CheckboxProps { + prefixCls?: string; /** 指定当前是否选中 */ checked?: boolean; /** 初始是否选中 */ @@ -14,6 +14,8 @@ export interface CheckboxProps { indeterminate?: boolean; /** 变化时回调函数 */ onChange?: React.FormEventHandler; + onMouseEnter?: React.MouseEventHandler; + onMouseLeave?: React.MouseEventHandler; style?: React.CSSProperties; disabled?: boolean; className?: string; @@ -29,11 +31,10 @@ export default class Checkbox extends React.Component { return PureRenderMixin.shouldComponentUpdate.apply(this, args); } render() { - const [{ prefixCls, style, children, className, indeterminate, onMouseEnter, - onMouseLeave }, restProps] = splitObject( - this.props, ['prefixCls', 'style', 'children', 'className', 'indeterminate', - 'onMouseEnter', 'onMouseLeave'] - ); + const { + prefixCls, style, children, className, indeterminate, + onMouseEnter, onMouseLeave, ...restProps, + } = this.props; const classString = classNames(className, { [`${prefixCls}-wrapper`]: true, }); diff --git a/components/dropdown/dropdown-button.tsx b/components/dropdown/dropdown-button.tsx index 896ee2b540..669d0255c6 100644 --- a/components/dropdown/dropdown-button.tsx +++ b/components/dropdown/dropdown-button.tsx @@ -4,19 +4,20 @@ import Icon from '../icon'; import Dropdown from './dropdown'; const ButtonGroup = Button.Group; import classNames from 'classnames'; -import splitObject from '../_util/splitObject'; export interface DropdownButtonProps { - type?: 'primary' | 'ghost' | 'dash'; - onClick?: React.FormEventHandler; - trigger?: 'click' | 'hover'; + prefixCls?: string; + className?: string; + type?: 'primary' | 'ghost' | 'dashed'; + onClick?: React.MouseEventHandler; + trigger?: ('click' | 'hover')[]; + align?: any; overlay: React.ReactNode; visible?: boolean; disabled?: boolean; onVisibleChange?: (visible: boolean) => void; style?: React.CSSProperties; - prefixCls?: string; - children: any; + children?: any; } export default class DropdownButton extends React.Component { @@ -35,10 +36,10 @@ export default class DropdownButton extends React.Component; + trigger?: ('click' | 'hover')[]; overlay: React.ReactNode; style?: React.CSSProperties; onVisibleChange?: (visible?: boolean) => void; diff --git a/components/grid/col.tsx b/components/grid/col.tsx index 9581609c35..c5585b45fb 100644 --- a/components/grid/col.tsx +++ b/components/grid/col.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { PropTypes } from 'react'; import classNames from 'classnames'; import assign from 'object-assign'; -import splitObject from '../_util/splitObject'; const stringOrNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]); const objectOrNumber = PropTypes.oneOfType([PropTypes.object, PropTypes.number]); @@ -47,8 +46,7 @@ export default class Col extends React.Component { render() { const props = this.props; - const [{ span, order, offset, push, pull, className, children, prefixCls = 'ant-col' }, others] = splitObject(props, - ['span', 'order', 'offset', 'push', 'pull', 'className', 'children', 'prefixCls']); + const { span, order, offset, push, pull, className, children, prefixCls = 'ant-col', ...others } = props; let sizeClassObj = {}; ['xs', 'sm', 'md', 'lg'].forEach(size => { let sizeProps: ColSize = {}; diff --git a/components/grid/row.tsx b/components/grid/row.tsx index 3991f6c83f..dbf5cdaced 100644 --- a/components/grid/row.tsx +++ b/components/grid/row.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { Children, cloneElement } from 'react'; import classNames from 'classnames'; import assign from 'object-assign'; -import splitObject from '../_util/splitObject'; export interface RowProps { className?: string; @@ -17,7 +16,6 @@ export interface RowProps { export default class Row extends React.Component { static defaultProps = { gutter: 0, - prefixCls: 'ant-row', }; static propTypes = { type: React.PropTypes.string, @@ -29,8 +27,7 @@ export default class Row extends React.Component { prefixCls: React.PropTypes.string, }; render() { - const [{ type, justify, align, className, gutter, style, children, prefixCls }, others] = splitObject(this.props, - ['type', 'justify', 'align', 'className', 'gutter', 'style', 'children', 'prefixCls']); + const { type, justify, align, className, gutter, style, children, prefixCls = 'ant-row', ...others } = this.props; const classes = classNames({ [prefixCls]: !type, [`${prefixCls}-${type}`]: type, diff --git a/components/input-number/index.tsx b/components/input-number/index.tsx index 1cdac4cccd..72adeeb57d 100644 --- a/components/input-number/index.tsx +++ b/components/input-number/index.tsx @@ -1,7 +1,6 @@ import React from 'react'; import classNames from 'classnames'; import RcInputNumber from 'rc-input-number'; -import splitObject from '../_util/splitObject'; export interface InputNumberProps { prefixCls?: string; @@ -25,8 +24,7 @@ export default class InputNumber extends React.Component }; render() { - const [{ className, size }, others] = splitObject(this.props, - ['size', 'className']); + const { className, size, ...others } = this.props; const inputNumberClass = classNames({ [`${this.props.prefixCls}-lg`]: size === 'large', [`${this.props.prefixCls}-sm`]: size === 'small', diff --git a/components/input/Search.tsx b/components/input/Search.tsx index f6a787e3ef..a716c6e995 100644 --- a/components/input/Search.tsx +++ b/components/input/Search.tsx @@ -2,7 +2,6 @@ import React from 'react'; import classNames from 'classnames'; import Input from './Input'; import Icon from '../icon'; -import splitObject from '../_util/splitObject'; export interface SearchProps { className?: string; @@ -32,9 +31,7 @@ export default class Search extends React.Component { this.input.refs.input.focus(); } render() { - const [{ className, prefixCls, style }, others] = splitObject( - this.props, ['className', 'prefixCls', 'style'] - ); + const { className, prefixCls, style, ...others } = this.props; delete others.onSearch; const wrapperCls = classNames({ [`${prefixCls}-wrapper`]: true, diff --git a/components/popconfirm/index.tsx b/components/popconfirm/index.tsx index 2fa6d1501f..70abd60311 100644 --- a/components/popconfirm/index.tsx +++ b/components/popconfirm/index.tsx @@ -3,7 +3,6 @@ import Tooltip from '../tooltip'; import { AbstractTooltipProps } from '../tooltip'; import Icon from '../icon'; import Button from '../button'; -import splitObject from '../_util/splitObject'; export interface PopconfirmProps extends AbstractTooltipProps { title: React.ReactNode; @@ -83,8 +82,7 @@ export default class Popconfirm extends React.Component { render() { const { props, context } = this; - const [{ prefixCls, title, placement }, restProps] = - splitObject(props, ['prefixCls', 'title', 'placement']); + const { prefixCls, title, placement, ...restProps } = props; let { okText, cancelText } = props; const popconfirmLocale = context.antLocale && context.antLocale.Popconfirm; diff --git a/components/progress/progress.tsx b/components/progress/progress.tsx index 72664fddd2..fd68dadcf0 100644 --- a/components/progress/progress.tsx +++ b/components/progress/progress.tsx @@ -3,7 +3,6 @@ import React from 'react'; import Icon from '../icon'; import { Circle } from 'rc-progress'; import classNames from 'classnames'; -import splitObject from '../_util/splitObject'; const statusColorMap = { normal: '#108ee9', exception: '#ff5500', @@ -11,12 +10,15 @@ const statusColorMap = { }; export interface ProgressProps { + prefixCls?: string; + className?: string; type?: 'line' | 'circle'; percent?: number; format?: (percent: number) => string; status?: 'success' | 'active' | 'exception'; showInfo?: boolean; strokeWidth?: number; + trailColor?: string; width?: number; style?: React.CSSProperties; } @@ -45,14 +47,13 @@ export default class Progress extends React.Component { }; render() { - const [{ - prefixCls, status, format, percent, trailColor, - type, strokeWidth, width, className, showInfo, - }, restProps] = splitObject(this.props, - ['prefixCls', 'status', 'format', 'percent', 'trailColor', 'type', 'strokeWidth', 'width', - 'className', 'showInfo']); - const progressStatus = (parseInt(percent, 10) >= 100 && !('status' in this.props)) - ? 'success' : (status || 'normal'); + const props = this.props; + const { + prefixCls, className, percent = 0, status, format, trailColor, + type, strokeWidth, width, showInfo, ...restProps, + } = props; + const progressStatus = parseInt(percent.toString(), 10) >= 100 && !('status' in props) ? + 'success' : (status || 'normal'); let progressInfo; let progress; const textFormatter = format || (percentNumber => `${percentNumber}%`); diff --git a/components/spin/index.tsx b/components/spin/index.tsx index 35d5cec908..4343f1170f 100644 --- a/components/spin/index.tsx +++ b/components/spin/index.tsx @@ -4,7 +4,6 @@ import { findDOMNode } from 'react-dom'; import classNames from 'classnames'; import Animate from 'rc-animate'; import isCssAnimationSupported from '../_util/isCssAnimationSupported'; -import splitObject from '../_util/splitObject'; import omit from 'omit.js'; export interface SpinProps { @@ -69,17 +68,14 @@ export default class Spin extends React.Component { } } render() { - const [{ - className, size, prefixCls, tip, - }, restProps] = splitObject(this.props, - ['className', 'size', 'prefixCls', 'tip']); + const { className, size, prefixCls, tip, ...restProps } = this.props; const { spinning } = this.state; const spinClassName = classNames(prefixCls, { [`${prefixCls}-sm`]: size === 'small', [`${prefixCls}-lg`]: size === 'large', [`${prefixCls}-spinning`]: spinning, - [`${prefixCls}-show-text`]: !!this.props.tip, + [`${prefixCls}-show-text`]: !!tip, }, className); // fix https://fb.me/react-unknown-prop diff --git a/components/table/Table.tsx b/components/table/Table.tsx index d9285a3760..c055724b3f 100755 --- a/components/table/Table.tsx +++ b/components/table/Table.tsx @@ -7,7 +7,6 @@ import Spin from '../spin'; import classNames from 'classnames'; import { flatArray, treeMap, normalizeColumns } from './util'; import assign from 'object-assign'; -import splitObject from '../_util/splitObject'; import warning from '../_util/warning'; import createStore, { Store } from './createStore'; import SelectionBox from './SelectionBox'; @@ -75,6 +74,7 @@ export interface TableProps { childrenColumnName?: string; bodyStyle?: React.CSSProperties; className?: string; + style?: React.CSSProperties; } export interface TableContext { @@ -823,9 +823,7 @@ export default class Table extends React.Component, any> { } render() { - const [{ - style, className, prefixCls, - }, restProps] = splitObject(this.props, ['style', 'className', 'prefixCls']); + const { style, className, prefixCls, ...restProps } = this.props; const data = this.getCurrentPageData(); let columns = this.renderRowSelection(); const expandIconAsCell = this.props.expandedRowRender && this.props.expandIconAsCell !== false; @@ -846,7 +844,7 @@ export default class Table extends React.Component, any> { let expandIconColumnIndex = (columns[0] && columns[0].key === 'selection-column') ? 1 : 0; if ('expandIconColumnIndex' in restProps) { - expandIconColumnIndex = restProps.expandIconColumnIndex; + expandIconColumnIndex = restProps.expandIconColumnIndex as number; } let table = ( diff --git a/components/tag/CheckableTag.tsx b/components/tag/CheckableTag.tsx index 55ed63b1d4..edd8a35060 100644 --- a/components/tag/CheckableTag.tsx +++ b/components/tag/CheckableTag.tsx @@ -1,6 +1,5 @@ import React from 'react'; import classNames from 'classnames'; -import splitObject from '../_util/splitObject'; export interface CheckableTagProps { prefixCls?: string; @@ -17,15 +16,13 @@ export default class CheckableTag extends React.Component; + delete restProps.onChange; // TypeScript cannot check delete now. + return
; } } diff --git a/components/tag/index.tsx b/components/tag/index.tsx index 31e24cb725..00026221e4 100644 --- a/components/tag/index.tsx +++ b/components/tag/index.tsx @@ -6,10 +6,11 @@ import omit from 'omit.js'; import assign from 'object-assign'; import Icon from '../icon'; import warning from '../_util/warning'; -import splitObject from '../_util/splitObject'; import CheckableTag from './CheckableTag'; export interface TagProps { + prefixCls?: string; + className?: string; color?: string; /** 标签是否可以关闭 */ closable?: boolean; @@ -73,12 +74,7 @@ export default class Tag extends React.Component { } render() { - const [{ - prefixCls, closable, color, className, children, style, - }, otherProps] = splitObject( - this.props, - ['prefixCls', 'closable', 'color', 'className', 'children', 'style'] - ); + const { prefixCls, closable, color = '', className, children, style, ...otherProps } = this.props; const closeIcon = closable ? : ''; const classString = classNames(prefixCls, { [`${prefixCls}-${color}`]: !!color, diff --git a/components/timeline/Timeline.tsx b/components/timeline/Timeline.tsx index a4c7208125..a1ecb52396 100644 --- a/components/timeline/Timeline.tsx +++ b/components/timeline/Timeline.tsx @@ -1,9 +1,10 @@ import React from 'react'; import classNames from 'classnames'; import TimelineItem from './TimelineItem'; -import splitObject from '../_util/splitObject'; export interface TimelineProps { + prefixCls?: string; + className?: string; /** 指定最后一个幽灵节点是否存在或内容 */ pending?: boolean | React.ReactNode; style?: React.CSSProperties; @@ -16,17 +17,14 @@ export default class Timeline extends React.Component { }; render() { - const [{ - prefixCls, children, pending, className, - }, restProps] = splitObject(this.props, - ['prefixCls', 'children', 'pending', 'className']); + const { prefixCls, children, pending, className, ...restProps } = this.props; const pendingNode = typeof pending === 'boolean' ? null : pending; const classString = classNames(prefixCls, { [`${prefixCls}-pending`]: !!pending, }, className); const items = React.Children.map(children, (ele: React.ReactElement, idx) => React.cloneElement(ele, { - last: idx === children.length - 1, + last: idx === (children as { length: number }).length - 1, }) ); const pendingItem = (!!pending) ? ( diff --git a/components/timeline/TimelineItem.tsx b/components/timeline/TimelineItem.tsx index 64ad8c3146..6853eafcc2 100644 --- a/components/timeline/TimelineItem.tsx +++ b/components/timeline/TimelineItem.tsx @@ -1,13 +1,13 @@ import React from 'react'; import classNames from 'classnames'; -import splitObject from '../_util/splitObject'; -// Timeline export interface TimeLineItemProps { - /** 指定圆圈颜色 */ + prefixCls?: string; + className?: string; color?: string; dot?: React.ReactNode; pending?: boolean; + last?: boolean; style?: React.CSSProperties; } @@ -20,10 +20,7 @@ export default class TimelineItem extends React.Component