refactor: ref: #3490

This commit is contained in:
Benjy Cui 2016-10-24 12:04:26 +08:00
parent 1da5490ab8
commit 4878258f6c
23 changed files with 189 additions and 154 deletions

View File

@ -93,9 +93,9 @@ export default class ScrollNumber extends Component<any, any> {
}
renderNumberList(position) {
const childrenToReturn = [];
const childrenToReturn: React.ReactElement<any>[] = [];
for (let i = 0; i < 30; i++) {
const currentClassName = (position === i) ? 'current' : null;
const currentClassName = (position === i) ? 'current' : '';
childrenToReturn.push(<p key={i.toString()} className={currentClassName}>{i % 10}</p>);
}
return childrenToReturn;

View File

@ -24,19 +24,20 @@ function getBreadcrumbName(route, params) {
return name;
}
function defaultItemRender(route, params, routes, paths) {
const isLastItem = routes.indexOf(route) === routes.length - 1;
const name = getBreadcrumbName(route, params);
return isLastItem
? <span>{name}</span>
: <a href={`#/${paths.join('/')}`}>{name}</a>;
}
export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
static Item: any;
static defaultProps = {
prefixCls: 'ant-breadcrumb',
separator: '/',
itemRender: (route, params, routes, paths) => {
const isLastItem = routes.indexOf(route) === routes.length - 1;
const name = getBreadcrumbName(route, params);
return isLastItem
? <span>{name}</span>
: <a href={`#/${paths.join('/')}`}>{name}</a>;
},
};
static propTypes = {
@ -62,12 +63,12 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
render() {
let crumbs;
const { separator, prefixCls, routes, params, children, itemRender } = this.props;
const { separator, prefixCls, routes, params = {}, children, itemRender = defaultItemRender } = this.props;
if (routes && routes.length > 0) {
const paths = [];
const paths: string[] = [];
crumbs = routes.map((route) => {
route.path = route.path || '';
let path = route.path.replace(/^\//, '');
let path: string = route.path.replace(/^\//, '');
Object.keys(params).forEach(key => {
path = path.replace(`:${key}`, params[key]);
});
@ -83,7 +84,7 @@ export default class Breadcrumb extends React.Component<BreadcrumbProps, any> {
}
return null;
});
} else {
} else if (children) {
crumbs = React.Children.map(children, (element: any, index) => {
return cloneElement(element, {
separator,

View File

@ -48,7 +48,6 @@ export default class Button extends React.Component<ButtonProps, any> {
static defaultProps = {
prefixCls: 'ant-btn',
onClick() {},
loading: false,
};
@ -87,7 +86,10 @@ export default class Button extends React.Component<ButtonProps, any> {
clearTimeout(this.timeout);
this.timeout = setTimeout(() => this.clearButton(buttonNode), 500);
this.props.onClick(e);
const onClick = this.props.onClick;
if (onClick) {
onClick(e);
}
}
// Handle auto focus when click button in Chrome

View File

@ -1,12 +1,11 @@
import React from 'react';
import { PropTypes } from 'react';
import moment from 'moment';
import { PREFIX_CLS } from './Constants';
import Select from '../select';
import { Group, Button } from '../radio';
const Option = Select.Option;
function noop() {}
export interface HeaderProps {
prefixCls?: string;
locale?: any;
@ -24,8 +23,6 @@ export default class Header extends React.Component<HeaderProps, any> {
prefixCls: `${PREFIX_CLS}-header`,
yearSelectOffset: 10,
yearSelectTotal: 20,
onValueChange: noop,
onTypeChange: noop,
};
static propTypes = {
@ -47,13 +44,13 @@ export default class Header extends React.Component<HeaderProps, any> {
const end = start + yearSelectTotal;
const suffix = locale.year === '年' ? '年' : '';
const options = [];
const options: React.ReactElement<any>[] = [];
for (let index = start; index < end; index++) {
options.push(<Option key={`${index}`}>{index + suffix}</Option>);
}
return (
<Select
size={fullscreen ? null : 'small'}
size={fullscreen ? 'default' : 'small'}
dropdownMatchSelectWidth={false}
className={`${prefixCls}-year-select`}
onChange={this.onYearChange}
@ -64,10 +61,10 @@ export default class Header extends React.Component<HeaderProps, any> {
);
}
getMonthsLocale(value) {
getMonthsLocale(value: moment.Moment) {
const current = value.clone();
const localeData = value.localeData();
const months = [];
const months: any[] = [];
for (let i = 0; i < 12; i++) {
current.month(i);
months.push(localeData.monthsShort(current));
@ -78,7 +75,7 @@ export default class Header extends React.Component<HeaderProps, any> {
getMonthSelectElement(month, months) {
const props = this.props;
const { prefixCls, fullscreen } = props;
const options = [];
const options: React.ReactElement<any>[] = [];
for (let index = 0; index < 12; index++) {
options.push(<Option key={`${index}`}>{months[index]}</Option>);
@ -86,7 +83,7 @@ export default class Header extends React.Component<HeaderProps, any> {
return (
<Select
size={fullscreen ? null : 'small'}
size={fullscreen ? 'default' : 'small'}
dropdownMatchSelectWidth={false}
className={`${prefixCls}-month-select`}
value={String(month)}
@ -100,17 +97,27 @@ export default class Header extends React.Component<HeaderProps, any> {
onYearChange = (year) => {
const newValue = this.props.value.clone();
newValue.year(parseInt(year, 10));
this.props.onValueChange(newValue);
const onValueChange = this.props.onValueChange;
if (onValueChange) {
onValueChange(newValue);
}
}
onMonthChange = (month) => {
const newValue = this.props.value.clone();
newValue.month(parseInt(month, 10));
this.props.onValueChange(newValue);
const onValueChange = this.props.onValueChange;
if (onValueChange) {
onValueChange(newValue);
}
}
onTypeChange = (e) => {
this.props.onTypeChange(e.target.value);
const onTypeChange = this.props.onTypeChange;
if (onTypeChange) {
onTypeChange(e.target.value);
}
}
render() {

View File

@ -38,12 +38,9 @@ export interface CalendarProps {
export default class Calendar extends React.Component<CalendarProps, any> {
static defaultProps = {
monthCellRender: noop,
dateCellRender: noop,
locale: {},
fullscreen: true,
prefixCls: PREFIX_CLS,
onPanelChange: noop,
mode: 'month',
};
@ -82,28 +79,28 @@ export default class Calendar extends React.Component<CalendarProps, any> {
}
monthCellRender = (value) => {
const prefixCls = this.props.prefixCls;
const { prefixCls, monthCellRender = noop as Function } = this.props;
return (
<div className={`${prefixCls}-month`}>
<div className={`${prefixCls}-value`}>
{value.localeData().monthsShort(value)}
</div>
<div className={`${prefixCls}-content`}>
{this.props.monthCellRender(value)}
{monthCellRender(value)}
</div>
</div>
);
}
dateCellRender = (value) => {
const prefixCls = this.props.prefixCls;
const { prefixCls, dateCellRender = noop as Function } = this.props;
return (
<div className={`${prefixCls}-date`}>
<div className={`${prefixCls}-value`}>
{zerofixed(value.date())}
</div>
<div className={`${prefixCls}-content`}>
{this.props.dateCellRender(value)}
{dateCellRender(value)}
</div>
</div>
);
@ -113,14 +110,20 @@ export default class Calendar extends React.Component<CalendarProps, any> {
if (!('value' in this.props) && this.state.value !== value) {
this.setState({ value });
}
this.props.onPanelChange(value, this.state.mode);
const onPanelChange = this.props.onPanelChange;
if (onPanelChange) {
onPanelChange(value, this.state.mode);
}
}
setType = (type) => {
const mode = (type === 'date') ? 'month' : 'year';
if (this.state.mode !== mode) {
this.setState({ mode });
this.props.onPanelChange(this.state.value, mode);
const onPanelChange = this.props.onPanelChange;
if (onPanelChange) {
onPanelChange(this.state.value, mode);
}
}
}

View File

@ -89,6 +89,8 @@ function defaultSortFilteredOption(a, b, inputValue) {
return a.findIndex(callback) - b.findIndex(callback);
}
const defaultDisplayRender = label => label.join(' / ');
export default class Cascader extends React.Component<CascaderProps, any> {
static defaultProps = {
prefixCls: 'ant-cascader',
@ -96,14 +98,11 @@ export default class Cascader extends React.Component<CascaderProps, any> {
placeholder: 'Please select',
transitionName: 'slide-up',
popupPlacement: 'bottomLeft',
onChange() {},
options: [],
displayRender: label => label.join(' / '),
disabled: false,
allowClear: true,
showSearch: false,
notFoundContent: 'Not Found',
onPopupVisibleChange() {},
};
cachedOptions: CascaderOptionType[];
@ -146,7 +145,11 @@ export default class Cascader extends React.Component<CascaderProps, any> {
inputFocused: popupVisible,
inputValue: popupVisible ? this.state.inputValue : '',
});
this.props.onPopupVisibleChange(popupVisible);
const onPopupVisibleChange = this.props.onPopupVisibleChange;
if (onPopupVisibleChange) {
onPopupVisibleChange(popupVisible);
}
}
handleInputBlur = () => {
@ -173,11 +176,14 @@ export default class Cascader extends React.Component<CascaderProps, any> {
if (!('value' in this.props)) {
this.setState({ value });
}
this.props.onChange(value, selectedOptions);
const onChange = this.props.onChange;
if (onChange) {
onChange(value, selectedOptions);
}
}
getLabel() {
const { options, displayRender } = this.props;
const { options, displayRender = defaultDisplayRender as Function } = this.props;
const value = this.state.value;
const unwrappedValue = Array.isArray(value[0]) ? value[0] : value;
const selectedOptions = arrayTreeFilter(options, (o, level) => o.value === unwrappedValue[level]);
@ -197,7 +203,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
}
flattenTree(options, changeOnSelect, ancestor = []) {
let flattenOptions = [];
let flattenOptions: any = [];
options.forEach((option) => {
const path = ancestor.concat(option);
if (changeOnSelect || !option.children) {
@ -293,10 +299,7 @@ export default class Cascader extends React.Component<CascaderProps, any> {
this.cachedOptions = options;
}
const dropdownMenuColumnStyle = {
width: undefined,
height: undefined,
};
const dropdownMenuColumnStyle: { width?: number, height?: string } = {};
const isNotFound = (options || []).length === 1 && options[0].value === 'ANT_CASCADER_NOT_FOUND';
if (isNotFound) {
dropdownMenuColumnStyle.height = 'auto'; // Height of one row.
@ -330,9 +333,9 @@ export default class Cascader extends React.Component<CascaderProps, any> {
disabled={disabled}
readOnly={!showSearch}
autoComplete="off"
onClick={showSearch ? this.handleInputClick : null}
onBlur={showSearch ? this.handleInputBlur : null}
onChange={showSearch ? this.handleInputChange : null}
onClick={showSearch ? this.handleInputClick : undefined}
onBlur={showSearch ? this.handleInputBlur : undefined}
onChange={showSearch ? this.handleInputChange : undefined}
/>
<span className={`${prefixCls}-picker-label`}>
{this.getLabel()}

View File

@ -29,7 +29,6 @@ export interface CheckboxGroupState {
export default class CheckboxGroup extends React.Component<CheckboxGroupProps, CheckboxGroupState> {
static defaultProps = {
options: [],
onChange() {},
prefixCls: 'ant-checkbox-group',
};
static propTypes = {
@ -78,7 +77,10 @@ export default class CheckboxGroup extends React.Component<CheckboxGroupProps, C
if (!('value' in this.props)) {
this.setState({ value });
}
this.props.onChange(value);
const onChange = this.props.onChange;
if (onChange) {
onChange(value);
}
}
render() {
const { prefixCls } = this.props;

View File

@ -123,7 +123,7 @@ export default function createPicker(TheCalendar) {
);
// default width for showTime
const pickerStyle = { width: undefined };
const pickerStyle: { width?: number } = {};
if (props.showTime) {
pickerStyle.width = 180;
}

View File

@ -162,7 +162,7 @@ export default class Form extends React.Component<FormProps, any> {
}
render() {
const { prefixCls, className, inline, horizontal, vertical } = this.props;
const { prefixCls, className = '', inline, horizontal, vertical } = this.props;
const formClassName = classNames({
[`${prefixCls}`]: true,
[`${prefixCls}-horizontal`]: horizontal,

View File

@ -15,7 +15,7 @@ export interface FormItemLabelColOption {
export interface FormItemProps {
prefixCls?: string;
id?: string;
label?: string | React.ReactNode;
label?: React.ReactNode;
labelCol?: FormItemLabelColOption;
wrapperCol?: FormItemLabelColOption;
help?: React.ReactNode;
@ -26,6 +26,7 @@ export interface FormItemProps {
required?: boolean;
style?: React.CSSProperties;
colon?: boolean;
children: any;
}
export interface FormItemContext {
@ -86,7 +87,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
}
getControls(children, recursively) {
let controls = [];
let controls: React.ReactElement<any>[] = [];
const childrenArray = React.Children.toArray(children);
for (let i = 0; i < childrenArray.length; i++) {
if (!recursively && controls.length > 0) {
@ -220,7 +221,7 @@ export default class FormItem extends React.Component<FormItemProps, any> {
// remove user input colon
let label = props.label;
if (typeof label === 'string' && label.trim() !== '') {
if (typeof label === 'string' && (label as string).trim() !== '') {
label = (props.label as string).replace(/[|:]\s*$/, '');
}

View File

@ -10,14 +10,15 @@ export interface GroupProps {
}
const Group: React.StatelessComponent<GroupProps> = (props) => {
const className = classNames({
[props.prefixCls]: true,
const { prefixCls = 'ant-input-group', className = '' } = props;
const cls = classNames({
[prefixCls]: true,
[`${props.prefixCls}-lg`]: props.size === 'large',
[`${props.prefixCls}-sm`]: props.size === 'small',
[props.className]: !!props.className,
[className]: !!className,
});
return (
<span className={className} style={props.style}>
<span className={cls} style={props.style}>
{props.children}
</span>
);
@ -27,8 +28,4 @@ Group.propTypes = {
children: React.PropTypes.any,
};
Group.defaultProps = {
prefixCls: 'ant-input-group',
};
export default Group;

View File

@ -61,9 +61,6 @@ export default class Input extends Component<InputProps, any> {
disabled: false,
prefixCls: 'ant-input',
type: 'text',
onPressEnter() {},
onKeyDown() {},
onChange() {},
autosize: false,
};
@ -114,17 +111,23 @@ export default class Input extends Component<InputProps, any> {
}
handleKeyDown = (e) => {
if (e.keyCode === 13) {
this.props.onPressEnter(e);
const { onPressEnter, onKeyDown } = this.props;
if (e.keyCode === 13 && onPressEnter) {
onPressEnter(e);
}
if (onKeyDown) {
onKeyDown(e);
}
this.props.onKeyDown(e);
}
handleTextareaChange = (e) => {
if (!('value' in this.props)) {
this.resizeTextarea();
}
this.props.onChange(e);
const onChange = this.props.onChange;
if (onChange) {
onChange(e);
}
}
resizeTextarea = () => {

View File

@ -87,8 +87,8 @@ function calculateNodeStyling(node, useCache = false) {
export default function calculateNodeHeight(
uiTextNode,
useCache = false,
minRows = null,
maxRows = null
minRows: number | null = null,
maxRows: number | null = null
) {
if (!hiddenTextarea) {
hiddenTextarea = document.createElement('textarea');

View File

@ -30,52 +30,53 @@ export interface ColProps {
style?: React.CSSProperties;
}
const Col: React.StatelessComponent<ColProps> = (props) => {
const [{ span, order, offset, push, pull, className, children, prefixCls = 'ant-col' }, others] = splitObject(props,
['span', 'order', 'offset', 'push', 'pull', 'className', 'children', 'prefixCls']);
let sizeClassObj = {};
['xs', 'sm', 'md', 'lg'].forEach(size => {
let sizeProps: ColSize = {};
if (typeof props[size] === 'number') {
sizeProps.span = props[size];
} else if (typeof props[size] === 'object') {
sizeProps = props[size] || {};
}
export default class Col extends React.Component<ColProps, any> {
static propTypes = {
span: stringOrNumber,
order: stringOrNumber,
offset: stringOrNumber,
push: stringOrNumber,
pull: stringOrNumber,
className: PropTypes.string,
children: PropTypes.node,
xs: objectOrNumber,
sm: objectOrNumber,
md: objectOrNumber,
lg: objectOrNumber,
};
delete others[size];
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']);
let sizeClassObj = {};
['xs', 'sm', 'md', 'lg'].forEach(size => {
let sizeProps: ColSize = {};
if (typeof props[size] === 'number') {
sizeProps.span = props[size];
} else if (typeof props[size] === 'object') {
sizeProps = props[size] || {};
}
sizeClassObj = assign({}, sizeClassObj, {
[`${prefixCls}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
[`${prefixCls}-${size}-order-${sizeProps.order}`]: sizeProps.order,
[`${prefixCls}-${size}-offset-${sizeProps.offset}`]: sizeProps.offset,
[`${prefixCls}-${size}-push-${sizeProps.push}`]: sizeProps.push,
[`${prefixCls}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull,
delete others[size];
sizeClassObj = assign({}, sizeClassObj, {
[`${prefixCls}-${size}-${sizeProps.span}`]: sizeProps.span !== undefined,
[`${prefixCls}-${size}-order-${sizeProps.order}`]: sizeProps.order,
[`${prefixCls}-${size}-offset-${sizeProps.offset}`]: sizeProps.offset,
[`${prefixCls}-${size}-push-${sizeProps.push}`]: sizeProps.push,
[`${prefixCls}-${size}-pull-${sizeProps.pull}`]: sizeProps.pull,
});
});
});
const classes = classNames(assign({}, {
[`${prefixCls}-${span}`]: span !== undefined,
[`${prefixCls}-order-${order}`]: order,
[`${prefixCls}-offset-${offset}`]: offset,
[`${prefixCls}-push-${push}`]: push,
[`${prefixCls}-pull-${pull}`]: pull,
[className]: !!className,
}, sizeClassObj));
const classes = classNames(assign({}, {
[`${prefixCls}-${span}`]: span !== undefined,
[`${prefixCls}-order-${order}`]: order,
[`${prefixCls}-offset-${offset}`]: offset,
[`${prefixCls}-push-${push}`]: push,
[`${prefixCls}-pull-${pull}`]: pull,
[className]: !!className,
}, sizeClassObj));
return <div {...others} className={classes}>{children}</div>;
};
Col.propTypes = {
span: stringOrNumber,
order: stringOrNumber,
offset: stringOrNumber,
push: stringOrNumber,
pull: stringOrNumber,
className: PropTypes.string,
children: PropTypes.node,
xs: objectOrNumber,
sm: objectOrNumber,
md: objectOrNumber,
lg: objectOrNumber,
};
export default Col;
return <div {...others} className={classes}>{children}</div>;
}
}

View File

@ -13,6 +13,7 @@ export interface LocaleProviderProps {
Transfer?: Object,
Select?: Object,
};
children: any;
}
export default class LocaleProvider extends React.Component<LocaleProviderProps, any> {

View File

@ -31,7 +31,6 @@ export default class Mention extends React.Component<MentionProps, MentionState>
static getMentions = getMentions;
static defaultProps = {
prefixCls: 'ant-mention',
suggestions: [],
notFoundContent: '无匹配结果,轻敲空格完成输入',
loading: false,
multiLines: false,
@ -65,7 +64,7 @@ export default class Mention extends React.Component<MentionProps, MentionState>
defaultSearchChange(value: String): void {
const searchValue = value.toLowerCase();
const filteredSuggestions = this.props.suggestions.filter(
const filteredSuggestions = (this.props.suggestions || []).filter(
suggestion => suggestion.toLowerCase().indexOf(searchValue) !== -1
);
this.setState({
@ -74,7 +73,7 @@ export default class Mention extends React.Component<MentionProps, MentionState>
}
render() {
const { className, prefixCls, style, multiLines, defaultValue } = this.props;
const { className = '', prefixCls, style, multiLines, defaultValue } = this.props;
let { notFoundContent } = this.props;
const { suggestions, focus } = this.state;

View File

@ -3,9 +3,6 @@ import RcMenu, { Item, Divider, SubMenu, ItemGroup } from 'rc-menu';
import animation from '../_util/openAnimation';
import warning from 'warning';
function noop() {
}
export interface SelectParam {
key: string;
keyPath: Array<string>;
@ -61,8 +58,6 @@ export default class Menu extends React.Component<MenuProps, any> {
static ItemGroup = ItemGroup;
static defaultProps = {
prefixCls: 'ant-menu',
onClick: noop,
onOpenChange: noop,
className: '',
theme: 'light', // or dark
};
@ -90,11 +85,19 @@ export default class Menu extends React.Component<MenuProps, any> {
}
handleClick = (e) => {
this.setOpenKeys([]);
this.props.onClick(e);
const onClick = this.props.onClick;
if (onClick) {
onClick(e);
}
}
handleOpenChange = (openKeys: string[]) => {
this.setOpenKeys(openKeys);
this.props.onOpenChange(openKeys);
const onOpenChange = this.props.onOpenChange;
if (onOpenChange) {
onOpenChange(openKeys);
}
}
setOpenKeys(openKeys) {
if (!('openKeys' in this.props)) {

View File

@ -23,7 +23,7 @@ function notice(
content: React.ReactNode,
duration: number = defaultDuration,
type: NoticeType,
onClose: () => void) {
onClose?: () => void) {
let iconType = ({
info: 'info-circle',
success: 'check-circle',
@ -64,7 +64,7 @@ export interface ConfigOptions {
}
export default {
info(content: ConfigContent, duration?: ConfigDuration, onClose?: () => ConfigOnClose) {
info(content: ConfigContent, duration?: ConfigDuration, onClose?: ConfigOnClose) {
return notice(content, duration, 'info', onClose);
},
success(content: ConfigContent, duration?: ConfigDuration, onClose?: ConfigOnClose) {
@ -85,13 +85,13 @@ export default {
},
config(options: ConfigOptions) {
if ('top' in options) {
if (options.top !== undefined) {
defaultTop = options.top;
}
if ('duration' in options) {
if (options.duration !== undefined) {
defaultDuration = options.duration;
}
if ('prefixCls' in options) {
if (options.prefixCls !== undefined) {
prefixCls = options.prefixCls;
}
},

View File

@ -4,8 +4,6 @@ import Dialog from 'rc-dialog';
import addEventListener from 'rc-util/lib/Dom/addEventListener';
import Button from '../button';
function noop() {}
let mousePosition;
let mousePositionEventBinded;
@ -55,8 +53,6 @@ export default class Modal extends React.Component<ModalProps, any> {
static defaultProps = {
prefixCls: 'ant-modal',
onOk: noop,
onCancel: noop,
width: 520,
transitionName: 'zoom',
maskTransitionName: 'fade',
@ -86,11 +82,17 @@ export default class Modal extends React.Component<ModalProps, any> {
context: ModalContext;
handleCancel = (e) => {
this.props.onCancel(e);
const onCancel = this.props.onCancel;
if (onCancel) {
onCancel(e);
}
}
handleOk = () => {
this.props.onOk();
const onOk = this.props.onOk;
if (onOk) {
onOk();
}
}
componentDidMount() {

View File

@ -101,7 +101,7 @@ export default function confirm(config) {
</div>
);
let footer = null;
let footer: React.ReactElement<any> | null = null;
if (props.okCancel) {
footer = (
<div className={`${prefixCls}-btns`}>

View File

@ -113,10 +113,10 @@ const api: {
}
},
config(options: ConfigProps) {
if ('top' in options) {
if (options.top !== undefined) {
defaultTop = options.top;
}
if ('duration' in options) {
if (options.duration !== undefined) {
defaultDuration = options.duration;
}
},

View File

@ -4,8 +4,6 @@ import Icon from '../icon';
import Button from '../button';
import splitObject from '../_util/splitObject';
const noop = () => {};
export interface PopconfirmProps {
/**
* Position of popup-container, options:`top`, `left`, `right`, `bottom`
@ -46,9 +44,6 @@ export default class Popconfirm extends React.Component<PopconfirmProps, any> {
transitionName: 'zoom-big',
placement: 'top',
trigger: 'click',
onConfirm: noop,
onCancel: noop,
onVisibleChange: noop,
};
static contextTypes = {
@ -72,12 +67,20 @@ export default class Popconfirm extends React.Component<PopconfirmProps, any> {
confirm = () => {
this.setVisible(false);
this.props.onConfirm.call(this);
const onConfirm = this.props.onConfirm;
if (onConfirm) {
onConfirm.call(this);
}
}
cancel = () => {
this.setVisible(false);
this.props.onCancel.call(this);
const onCancel = this.props.onCancel;
if (onCancel) {
onCancel.call(this);
}
}
onVisibleChange = (visible) => {
@ -88,7 +91,11 @@ export default class Popconfirm extends React.Component<PopconfirmProps, any> {
if (!('visible' in this.props)) {
this.setState({ visible });
}
this.props.onVisibleChange(visible);
const onVisibleChange = this.props.onVisibleChange;
if (onVisibleChange) {
onVisibleChange(visible);
}
}
render() {

View File

@ -1,4 +1,5 @@
import React from 'react';
import assign from 'object-assign';
import Tooltip from '../tooltip';
export interface PopoverProps {
@ -11,7 +12,7 @@ export interface PopoverProps {
placement?: 'top' | 'left' | 'right' | 'bottom' | 'topLeft' | 'topRight' |
'bottomLeft' | 'bottomRight' | 'leftTop' | 'leftBottom' | 'rightTop' | 'rightBottom';
/** title of popup-container */
title?: React.ReactNode | string;
title?: React.ReactNode;
/** classname of popup-container */
overlayClassName?: string;
/** Style of overlay */
@ -43,10 +44,12 @@ export default class Popover extends React.Component<PopoverProps, any> {
};
render() {
const props = assign({}, this.props);
delete props.title;
return (
<Tooltip
ref="tooltip"
{...this.props}
{...props}
overlay={this.getOverlay()}
/>
);