import React, {CSSProperties} from 'react'; import { BasicConfig, BasicContainer, BasicContainerPropsInterface } from '../../render/core/Container/types'; import {TreeSelect} from '@native-ads/antd'; import {isExpression, parseExpressionString} from '../../render/util/vm'; import componentLoader from '../../render/util/componentLoader'; import {TreeNodeConfig} from '../Tree/Tree'; import * as _ from 'lodash'; const TreeNode = TreeSelect.TreeNode; export class TreeSelectConfig extends BasicConfig { /** * 同步的数据模型Key */ name: string; /** * 子节点配置 */ options: TreeNodeConfig[]; /** * 显示清除按钮 */ allowClear?: boolean; /** * 默认值 */ defaultValue?: string | string[]; /** * 是否禁用 */ disabled?: boolean; /** * 下拉菜单和选择器同宽 */ dropdownMatchSelectWidth?: boolean; /** * 下拉菜单的样式 */ dropdownStyle?: CSSProperties; /** * 输入项过滤 */ filterTreeNode?: boolean | string; /** * 是否把每个选项的 label 包装到 value 中 */ labelInValue?: boolean; /** * checkable 状态下节点选择完全受控(父子节点选中状态不再关联),会使得 labelInValue 强制为 true */ treeCheckStrictly?: boolean; /** * 是否多选 */ multiple?: boolean; /** * 选择框默认文字 */ placeholder?: string; /** * 搜索框默认文字 */ searchPlaceholder?: string; /** * 定义选中项回填的方式 * * SHOW_ALL: 显示所有选中节点(包括父节点) * SHOW_PARENT: 只显示父节点(当父节点下所有子节点都选中时). * SHOW_CHILD: 只显示子节点. (默认) */ showCheckedStrategy?: 'SHOW_ALL' | 'SHOW_PARENT' | 'SHOW_CHILD'; /** * 是否显示搜索框 */ showSearch?: boolean; /** * 选择框大小 */ size?: 'default' | 'large' | 'small'; /** * checkbox多选 */ treeCheckable?: boolean; /** * 默认展开所有的节点 */ treeDefaultExpandAll?: boolean; /** * 默认展开的节点 */ treeDefaultExpandedKeys?: string[]; } export class TreeSelectPropsInterface extends BasicContainerPropsInterface { info: TreeSelectConfig; } export class AbstractTreeSelect extends BasicContainer { constructor(props: TreeSelectPropsInterface) { super(props); } componentDidMount() { let info = this.getPropsInfo(this.props.info); if (info.defaultValue && this.props.$setData && info.name) { this.props.$setData(info.name, info.defaultValue); } this.handleTreeChange = this.handleTreeChange.bind(this); this.parseFilterTreeNode = this.parseFilterTreeNode.bind(this); } private handleTreeChange(value: any) { let info = this.getPropsInfo(this.props.info); if (this.props.$setData) { this.props.$setData(info.name, value); } this.commonEventHandler('onChange', { value: value }); } private parseFilterTreeNode(inputValue: string, treeNode: any) { let info = this.props.info; let runTime = this.getRuntimeContext(); if (typeof info.filterTreeNode === 'boolean') { return info.filterTreeNode; } if (typeof info.filterTreeNode === 'string' && isExpression(info.filterTreeNode)) { return parseExpressionString(info.filterTreeNode, { ...runTime, $args: { inputValue, treeNode } }); } return true; } private renderTreeNode(options: TreeNodeConfig[]): React.ReactNode[] { return options.map((op, index) => { let title = op.title; let key = op.key || index; let isLeaf = op.isLeaf; let disabled = op.disabled; let disabledCheckbox = op.disableCheckbox; let selectable = typeof op.selectable === 'boolean' ? op.selectable : true; let children; if (_.isArray(op.children) && op.children.length > 0) { children = this.renderTreeNode(op.children); } return React.createElement(TreeNode, { title, key, value: key, isLeaf, disabled, selectable, disabledCheckbox }, children); }); } render() { let info = this.getPropsInfo(this.props.info, this.props, ['filterTreeNode']); if (!info.name) { return
name property is required for TreeSelect Component
; } if (!this.isUnderContainerEnv()) { console.error('TreeSelect is not under container control, please it inside of container component'); return ; } let value = this.getValueFromDataStore(info.name); let options = info.options; if (!options || !(options instanceof Array)) { options = []; } if ((info.treeCheckStrictly || info.labelInValue) && !value) { value = []; } return ( { let val = args[0]; let event = args[2]; this.commonEventHandler('onSelect', { value: val, checked: event.checked }); }} onSearch={(val: any) => { this.commonEventHandler('onSearch', { value: val }); }} value={value} disabled={info.disabled} dropdownMatchSelectWidth={info.dropdownMatchSelectWidth} dropdownStyle={info.dropdownStyle} labelInValue={info.labelInValue} multiple={info.multiple} placeholder={info.placeholder} searchPlaceholder={info.searchPlaceholder} showCheckedStrategy={info.showCheckedStrategy} size={info.size} showSearch={info.showSearch} style={{ width: 300 }} treeCheckable={info.treeCheckable} treeDefaultExpandAll={info.treeDefaultExpandAll} treeDefaultExpandedKeys={info.treeDefaultExpandedKeys} treeCheckStrictly={info.treeCheckStrictly} > {this.renderTreeNode(options)} ); } } componentLoader.addComponent('treeSelect', AbstractTreeSelect, TreeSelectPropsInterface);