weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
120 lines (109 loc) • 3.43 kB
JSX
/** @jsx createElement */
;
import { createElement, Component, PropTypes } from 'rax';
import Text from 'nuke-text';
import { isWeb } from 'nuke-env';
import { connectStyle } from 'nuke-theme-provider';
import Icon from 'nuke-icon';
import Touchable from 'nuke-touchable';
import stylesProvider from '../styles';
// 下面的属性需要在Text上手工继承
const TextAttrArr = ['color', 'fontSize', 'fontStyle', 'fontWeight', 'lineHeight'];
const ActiveAttr = ['color', 'backgroundColor', 'borderColor'];
const LoadingPic = 'https://img.alicdn.com/tfs/TB179d4LpXXXXaUXVXXXXXXXXXX-32-32.gif?getAvatar=avatar';
class Button extends Component {
constructor(props) {
super(props);
this.onPress = this.onPress.bind(this);
this.onTextPress = this.onTextPress.bind(this);
}
onPress(e) {
if (this.props.disabled) return;
this.props.onPress(e);
}
onTextPress(e) {
if (this.props.disabled) return;
if (isWeb) {
e.stopPropagation();
}
this.props.onPress(e);
}
render() {
const { size, shape, type, style, disabled, block, loading, icon, text, warning, children, ...others } = this.props;
const s = this.props.themeStyle;
let btnStyle = {};
const textStyle = {};
const iconSrc = loading ? LoadingPic : icon || null;
const isWarning = shape === 'warning' || warning;
// 伪类有默认样式了,如果伪类的样式没传,需要和原来的一样
ActiveAttr.forEach((item) => {
if (style && style[item] && !style[`${item}:active`]) {
style[`${item}:active`] = style[item];
}
});
btnStyle = Object.assign(
{},
s.base,
type ? s[`${type}`] : {},
isWarning ? s[`warning-${type}`] : {},
disabled && type ? s[`${type}-disabled`] : {},
isWarning && disabled ? s['warning-disabled'] : {},
loading ? s['loading '] : {},
size ? s[`${size}`] : {},
block ? s.block : {},
style
);
TextAttrArr.forEach((item) => {
if (btnStyle[item]) {
textStyle[item] = btnStyle[item];
}
if (btnStyle[`${item}:active`]) {
textStyle[`${item}:active`] = btnStyle[`${item}:active`];
}
});
return (
<Touchable onPress={this.onPress} style={btnStyle} {...others}>
{iconSrc ? <Icon size="xs" src={iconSrc} style={{ marginRight: 10 }} /> : null}
{typeof children === 'string' ? (
<Text style={textStyle} onClick={this.onTextPress}>
{children}
</Text>
) : (
children
)}
</Touchable>
);
}
}
Button.displayName = 'Button';
Button.propTypes = {
...Touchable.propTypes,
type: PropTypes.oneOf(['normal', 'primary', 'secondary', 'third']),
size: PropTypes.oneOf(['small', 'medium', 'large']),
shape: PropTypes.oneOf(['warning']),
onPress: PropTypes.func,
block: PropTypes.boolean,
loading: PropTypes.boolean,
warning: PropTypes.boolean,
style: PropTypes.any,
disabled: PropTypes.boolean,
};
Button.defaultProps = {
shape: null,
type: 'normal',
size: 'medium',
onPress: () => {},
block: false,
warning: false,
loading: false,
style: {},
disabled: false,
};
Button.contextTypes = {
parentPath: PropTypes.any,
parentStyle: PropTypes.any,
androidConfigs: PropTypes.any,
getConfig: PropTypes.func,
};
const StyledButton = connectStyle(stylesProvider)(Button);
export default StyledButton;