import * as React from 'react'; import * as _ from 'lodash'; import {CSSProperties} from 'react'; import {BasicConfig, BasicContainer, BasicContainerPropsInterface} from '../../render/core/Container/types'; import {IsBoolean, IsDefined, IsString} from 'class-validator'; import componentLoader from '../../render/util/componentLoader'; import {Checkbox, Tooltip} from '@native-ads/antd'; import {CheckboxProps} from '@native-ads/antd/lib/checkbox/Checkbox'; import {isExpression} from '../../render/util/vm'; export class CheckboxConfig extends BasicConfig { /** * Checkbox的数据模型Key */ @IsDefined() name: string; /** * 是否禁用 * @public * @default false */ @IsBoolean() disabled?: boolean; /** * 文字 * @public * @default '' */ @IsString() text?: string; /** * 多组多选框 */ groups?: CheckBoxGroupItem[]; /** * 添加全选框 */ groupSelectAll?: boolean; /** * 添加反选框 */ groupUnSelectAll?: boolean; /** * 初始是否选中 */ defaultValue?: boolean | string[]; /** * unknown */ @IsString() prefixCls?: string; /** * CSS class */ @IsString() className?: string; /** * 内联CSS属性 */ style?: CSSProperties; } export class CheckBoxGroupItem { /** * 多选的Key */ key: string; /** * 多选框文字 */ text: string; /** * 提示文字 */ tip?: string; } export class CheckboxPropsInterface extends BasicContainerPropsInterface { info: CheckboxConfig; /** * 当鼠标移入的回调 */ onMouseEnter?: (event: React.MouseEvent) => Object; /** * 当鼠标移开的回调 */ onMouseLeave?: (event: React.MouseEvent) => Object; /** * 当数据更新的回调 */ onChange?: (event: React.MouseEvent) => Object; } export default class AbstractCheckbox extends BasicContainer { private SELECT_ALL: string; constructor(props: CheckboxPropsInterface) { super(props); this.handleChange = this.handleChange.bind(this); this.handleGroupChange = this.handleGroupChange.bind(this); this.selectAll = this.selectAll.bind(this); this.SELECT_ALL = '_RCRE_SELECT_ALL_'; } private initCheckbox(info: CheckboxConfig) { if (this.props.$setData && !_.isNil(info.defaultValue)) { const defaultValue = info.defaultValue; const $setData = this.props.$setData; if (_.isArray(defaultValue)) { let data = {}; defaultValue.forEach(key => data[key] = true); $setData(info.name, data); } else if (typeof defaultValue === 'boolean') { $setData(info.name, defaultValue); } } } // 如果name是动态计算的,那么name属性在didMount是有可能不存在的 componentWillMount() { let info = this.getPropsInfo(this.props.info); if (!info.name) { return; } this.initCheckbox(info); } // 当上一次的name为空,下一次的name有值,就说明这个是刚刚动态计算出来的值 componentWillReceiveProps(nextProps: CheckboxPropsInterface) { let prevInfo = this.getPropsInfo(this.props.info, this.props); let nextInfo = this.getPropsInfo(nextProps.info, nextProps); if (!prevInfo.name && nextInfo.name) { this.initCheckbox(nextInfo); } } private handleChange(event: React.ChangeEvent) { let checked = event.target.checked; let info = this.getPropsInfo(this.props.info); if (this.props.$setData) { this.props.$setData(info.name, checked); } this.commonEventHandler('onChange', this.getExternalCallbackArgs([event], this.props.onChange)); } private handleGroupChange(key: string) { return () => { if (!this.isUnderContainerEnv()) { console.error('checkbox group should be under container component control'); return; } let info = this.getPropsInfo(this.props.info); let data = this.getValueFromDataStore(info.name) || {}; data[key] = !data[key]; if (_.every(info.groups, group => data[group.key])) { data[this.SELECT_ALL] = true; } else if (info.groupSelectAll) { data[this.SELECT_ALL] = false; } if (this.props.$setData) { this.props.$setData(info.name, data); } }; } private selectAll(event: React.ChangeEvent) { if (!this.isUnderContainerEnv()) { return; } let info = this.getPropsInfo(this.props.info); let data = this.getValueFromDataStore(info.name) || {}; let flag = !data[this.SELECT_ALL]; data[this.SELECT_ALL] = flag; _.each(info.groups, (item) => { let key = item.key; data[key] = flag; }); if (this.props.$setData) { this.props.$setData(info.name, data); } this.commonEventHandler('onSelectAll', { selected: flag }); } private mapOptions(info: CheckboxConfig): CheckboxProps { return { prefixCls: info.prefixCls, className: info.className, defaultChecked: info.defaultChecked, style: info.style, disabled: info.disabled }; } render() { let infoCopy = _.clone(this.props.info); let info = this.getPropsInfo(this.props.info, this.props); if (!info.name && !isExpression(infoCopy.name)) { return this.errorReport('name property is required for Checkbox Element', 'div'); } if (!this.isUnderContainerEnv()) { return
Checkbox Element is out of RCRE control, please put it inside container component
; } let value = this.getValueFromDataStore(info.name); let commonProps = { onMouseEnter: (event: React.MouseEvent) => { this.commonEventHandler('onMouseEnter', this.getExternalCallbackArgs([event], this.props.onMouseEnter)); }, onMouseLeave: (event: React.MouseEvent) => { this.commonEventHandler('onMouseLeave', this.getExternalCallbackArgs([event], this.props.onMouseLeave)); } }; let checkboxProps = this.mapOptions(info); if (!_.isArray(info.groups)) { return React.createElement(Checkbox, { checked: value, onChange: this.handleChange, ...checkboxProps, ...commonProps }, info.text); } let groupCheckbox = info.groups.map(group => { let text = group.text; let key = group.key; let isChecked = !!value ? !!value[key] : false; let checkboxElement = React.createElement(Checkbox, { checked: isChecked, onChange: this.handleGroupChange(group.key), key: group.key, ...checkboxProps, ...commonProps }, text); if (group.tip) { return ( {checkboxElement} ); } return checkboxElement; }); let selectAll; if (info.groupSelectAll) { let isChecked = false; if (!_.isNil(value) && value[this.SELECT_ALL]) { isChecked = true; } selectAll = React.createElement(Checkbox, { checked: isChecked, onChange: this.selectAll, ...checkboxProps, ...commonProps }, '全选'); } return (
{selectAll} {groupCheckbox}
); } } componentLoader.addComponent('checkbox', AbstractCheckbox, CheckboxPropsInterface);