You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
4.6 KiB

import React from 'react';
import classNames from 'classnames';
import { findDOMNode } from 'react-dom';
import Icon from '../icon';
import omit from 'omit.js';
import getRequestAnimationFrame, { cancelRequestAnimationFrame } from '../_util/getRequestAnimationFrame';
const reqAnimFrame = getRequestAnimationFrame();
const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
function isString(str) {
return typeof str === 'string';
}
// Insert one space between two chinese characters automatically.
function insertSpace(child) {
if (isString(child.type) && isTwoCNChar(child.props.children)) {
return React.cloneElement(child, {},
child.props.children.split('').join(' '));
}
if (isString(child)) {
if (isTwoCNChar(child)) {
child = child.split('').join(' ');
}
return <span>{child}</span>;
}
return child;
}
export type ButtonType = 'primary' | 'ghost' | 'dashed' | 'danger'
export type ButtonShape = 'circle' | 'circle-outline'
export type ButtonSize = 'small' | 'large'
8 years ago
export interface ButtonProps {
8 years ago
type?: ButtonType;
htmlType?: string;
icon?: string;
shape?: ButtonShape;
size?: ButtonSize;
8 years ago
onClick?: React.FormEventHandler<any>;
onMouseUp?: React.FormEventHandler<any>;
8 years ago
loading?: boolean;
disabled?: boolean;
style?: React.CSSProperties;
prefixCls?: string;
className?: string;
ghost?: boolean;
8 years ago
}
export default class Button extends React.Component<ButtonProps, any> {
static Group: any;
static __ANT_BUTTON = true;
8 years ago
static defaultProps = {
9 years ago
prefixCls: 'ant-btn',
loading: false,
ghost: false,
};
static propTypes = {
type: React.PropTypes.string,
shape: React.PropTypes.oneOf(['circle', 'circle-outline']),
size: React.PropTypes.oneOf(['large', 'default', 'small']),
htmlType: React.PropTypes.oneOf(['submit', 'button', 'reset']),
onClick: React.PropTypes.func,
loading: React.PropTypes.bool,
className: React.PropTypes.string,
icon: React.PropTypes.string,
};
8 years ago
timeout: any;
clickedTimeout: any;
delayTimeout: number;
constructor(props) {
super(props);
this.state = {
loading: props.loading,
};
}
componentWillReceiveProps(nextProps) {
const currentLoading = this.props.loading;
const loading = nextProps.loading;
if (currentLoading) {
clearTimeout(this.delayTimeout);
}
if (loading) {
this.delayTimeout = setTimeout(() => this.setState({ loading }), 200);
} else {
this.setState({ loading });
}
}
8 years ago
componentWillUnmount() {
if (this.clickedTimeout) {
cancelRequestAnimationFrame(this.clickedTimeout);
}
if (this.timeout) {
clearTimeout(this.timeout);
}
if (this.delayTimeout) {
clearTimeout(this.delayTimeout);
}
}
9 years ago
clearButton = (button) => {
button.className = button.className.replace(` ${this.props.prefixCls}-clicked`, '');
9 years ago
}
8 years ago
handleClick = (e) => {
// Add click effect
const buttonNode = findDOMNode(this);
9 years ago
this.clearButton(buttonNode);
this.clickedTimeout = reqAnimFrame(() => buttonNode.className += ` ${this.props.prefixCls}-clicked`);
clearTimeout(this.timeout);
9 years ago
this.timeout = setTimeout(() => this.clearButton(buttonNode), 500);