weex-nuke
Version:
基于 Rax 、Weex 的高性能组件体系 ~~
223 lines (210 loc) • 5.24 kB
JSX
/** @jsx createElement */
;
import { createElement, Component, PropTypes } from 'rax';
import View from 'nuke-view';
import Touchable from 'nuke-touchable';
import Icon from 'nuke-icon';
import { connectStyle } from 'nuke-theme-provider';
import stylesProvider from '../styles';
const TextAttrArr = [
'color',
'fontSize',
'fontStyle',
'fontWeight',
'lineHeight',
];
/**
* Checkbox
* @description 复选框处理
*/
class Checkbox extends Component {
constructor(props, context) {
super(props);
this.onChange = this.onChange.bind(this);
let checked;
if (
context.value &&
context.value.indexOf(props.value) > -1 &&
!this.props.ignoreContext
) {
checked = props.value;
} else if ('checked' in props) checked = props.checked;
else checked = props.defaultChecked;
this.state = {
checked,
};
}
componentWillReceiveProps(nextProps, nextContext) {
if (this.context.__group__ && !this.props.ignoreContext) {
if (
typeof nextContext.value === 'object' &&
nextContext.value.indexOf(nextProps.value) > -1
) {
this.setState({
checked: true,
});
} else {
this.setState({
checked: false,
});
}
} else if ('checked' in nextProps) {
if (nextProps.checked != this.props.checked) {
// if(this.props.disabled)
// return;
this.setState({
checked: nextProps.checked,
});
}
}
}
onChange(e) {
const { onChange, disabled, value } = this.props;
if (disabled) return;
const tmp = this.state.checked;
if (this.context && this.context.__group__ && !this.props.ignoreContext) {
this.context.onChange(value, !tmp, value);
} else if (!('checked' in this.props)) {
this.setState({
checked: !tmp,
});
}
onChange(!tmp);
e.stopPropagation && e.stopPropagation();
}
render() {
const {
size,
style,
disabled,
type,
checkedStyle,
unCheckedStyle,
touchStyle,
themeStyle,
} = this.props;
const checked = this.state.checked;
const elementTouchStyle = Object.assign(
{},
themeStyle[`touch-${size}`],
touchStyle
);
const checkedStyleAll = Object.assign(
{},
themeStyle[size],
themeStyle[`${type}-checked`],
checkedStyle
);
const unCheckedStyleAll = Object.assign(
{},
themeStyle[size],
themeStyle[`wrap-${type}-${size}`],
style,
unCheckedStyle
);
let disabledStyle = {};
if (type === 'list') {
// list的disable样式区别于其他两种
disabledStyle = themeStyle['list-disabled'];
} else if (checked) {
disabledStyle = themeStyle['checked-disabled'];
} else {
disabledStyle = themeStyle.disabled;
}
const iconWrapStyle = Object.assign(
{},
style,
unCheckedStyleAll,
checked ? checkedStyleAll : {},
disabled ? disabledStyle : {}
);
const iconStyle = Object.assign(
{},
checked ? { color: checkedStyleAll.color } : {},
themeStyle[size],
disabled ? disabledStyle : {}
);
TextAttrArr.forEach((item) => {
if (iconWrapStyle[item]) {
iconStyle[item] = iconWrapStyle[item];
}
});
return (
<Touchable x="checkbox" style={elementTouchStyle} onPress={this.onChange}>
<View style={iconWrapStyle}>
{checked ? <Icon style={iconStyle} name="right" /> : null}
</View>
</Touchable>
);
}
}
Checkbox.displayName = 'Checkbox';
Checkbox.propTypes = {
/**
* 受控下是否选中 controlled select or not
*/
checked: PropTypes.bool,
/**
* 非受控是否选中 uncontrolled select or not
*/
defaultChecked: PropTypes.bool,
/**
* 尺寸 size
* @enumdesc small,medium
*/
size: PropTypes.oneOf(['small', 'medium']),
/**
* 禁用 disable bool
*/
disabled: PropTypes.bool,
/**
* 点击checkbox的回调 click callback
*/
onChange: PropTypes.func,
/**
* 显示类型
* @enumdesc normal, list, empty
*/
type: PropTypes.oneOf(['normal', 'list', 'empty']),
/**
* group选择时的选中value
*/
value: PropTypes.any,
themeStyle: PropTypes.object,
/**
* 选中时的默认样式,会覆盖style
*/
checkedStyle: PropTypes.object,
/**
* 未选中时的默认样式,会覆盖style
*/
unCheckedStyle: PropTypes.object,
/**
* style样式
*/
style: PropTypes.object,
/**
* 忽略上层父级 context,当 check.group 的子级存在非 group 模式的 checkbox 时需设置为 false
* ignore context passing. usually use the nested with checkbox group
*/
ignoreContext: PropTypes.boolean,
};
Checkbox.defaultProps = {
size: 'medium',
disabled: false,
defaultChecked: false,
onChange: () => {},
type: 'normal',
value: '',
themeStyle: {},
checkedStyle: {},
unCheckedStyle: {},
style: {},
ignoreContext: false,
};
Checkbox.contextTypes = {
onChange: PropTypes.func,
__group__: PropTypes.bool,
value: PropTypes.any,
};
export default connectStyle(stylesProvider)(Checkbox);