182 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Vue
		
	
	
			
		
		
	
	
			182 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			Vue
		
	
	
| import { filterEmpty } from '../../_util/props-util';
 | |
| import type { VNodeChild } from 'vue';
 | |
| import { camelize } from 'vue';
 | |
| import { warning } from '../../vc-util/warning';
 | |
| import type {
 | |
|   DataNode,
 | |
|   LegacyDataNode,
 | |
|   ChangeEventExtra,
 | |
|   InternalDataEntity,
 | |
|   RawValueType,
 | |
|   LegacyCheckedNode,
 | |
| } from '../interface';
 | |
| import TreeNode from '../TreeNode';
 | |
| 
 | |
| function isTreeSelectNode(node: any) {
 | |
|   return node && node.type && (node.type as any).isTreeSelectNode;
 | |
| }
 | |
| export function convertChildrenToData(rootNodes: VNodeChild): DataNode[] {
 | |
|   function dig(treeNodes: any[] = []): DataNode[] {
 | |
|     return filterEmpty(treeNodes).map(treeNode => {
 | |
|       // Filter invalidate node
 | |
|       if (!isTreeSelectNode(treeNode)) {
 | |
|         warning(!treeNode, 'TreeSelect/TreeSelectNode can only accept TreeSelectNode as children.');
 | |
|         return null;
 | |
|       }
 | |
|       const slots = (treeNode.children as any) || {};
 | |
|       const key = treeNode.key as string | number;
 | |
|       const props: any = {};
 | |
|       for (const [k, v] of Object.entries(treeNode.props)) {
 | |
|         props[camelize(k)] = v;
 | |
|       }
 | |
|       const { isLeaf, checkable, selectable, disabled, disableCheckbox } = props;
 | |
|       // 默认值为 undefined
 | |
|       const newProps = {
 | |
|         isLeaf: isLeaf || isLeaf === '' || undefined,
 | |
|         checkable: checkable || checkable === '' || undefined,
 | |
|         selectable: selectable || selectable === '' || undefined,
 | |
|         disabled: disabled || disabled === '' || undefined,
 | |
|         disableCheckbox: disableCheckbox || disableCheckbox === '' || undefined,
 | |
|       };
 | |
|       const slotsProps = { ...props, ...newProps };
 | |
|       const {
 | |
|         title = slots.title?.(slotsProps),
 | |
|         switcherIcon = slots.switcherIcon?.(slotsProps),
 | |
|         ...rest
 | |
|       } = props;
 | |
|       const children = slots.default?.();
 | |
|       const dataNode: DataNode = {
 | |
|         ...rest,
 | |
|         title,
 | |
|         switcherIcon,
 | |
|         key,
 | |
|         isLeaf,
 | |
|         ...newProps,
 | |
|       };
 | |
| 
 | |
|       const parsedChildren = dig(children);
 | |
|       if (parsedChildren.length) {
 | |
|         dataNode.children = parsedChildren;
 | |
|       }
 | |
| 
 | |
|       return dataNode;
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   return dig(rootNodes as any[]);
 | |
| }
 | |
| 
 | |
| export function fillLegacyProps(dataNode: DataNode): LegacyDataNode {
 | |
|   // Skip if not dataNode exist
 | |
|   if (!dataNode) {
 | |
|     return dataNode as LegacyDataNode;
 | |
|   }
 | |
| 
 | |
|   const cloneNode = { ...dataNode };
 | |
| 
 | |
|   if (!('props' in cloneNode)) {
 | |
|     Object.defineProperty(cloneNode, 'props', {
 | |
|       get() {
 | |
|         warning(
 | |
|           false,
 | |
|           'New `rc-tree-select` not support return node instance as argument anymore. Please consider to remove `props` access.',
 | |
|         );
 | |
|         return cloneNode;
 | |
|       },
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   return cloneNode as LegacyDataNode;
 | |
| }
 | |
| 
 | |
| export function fillAdditionalInfo(
 | |
|   extra: ChangeEventExtra,
 | |
|   triggerValue: RawValueType,
 | |
|   checkedValues: RawValueType[],
 | |
|   treeData: InternalDataEntity[],
 | |
|   showPosition: boolean,
 | |
| ) {
 | |
|   let triggerNode = null;
 | |
|   let nodeList: LegacyCheckedNode[] = null;
 | |
| 
 | |
|   function generateMap() {
 | |
|     function dig(list: InternalDataEntity[], level = '0', parentIncluded = false) {
 | |
|       return list
 | |
|         .map((dataNode, index) => {
 | |
|           const pos = `${level}-${index}`;
 | |
|           const included = checkedValues.includes(dataNode.value);
 | |
|           const children = dig(dataNode.children || [], pos, included);
 | |
|           const node = <TreeNode {...dataNode}>{children.map(child => child.node)}</TreeNode>;
 | |
| 
 | |
|           // Link with trigger node
 | |
|           if (triggerValue === dataNode.value) {
 | |
|             triggerNode = node;
 | |
|           }
 | |
| 
 | |
|           if (included) {
 | |
|             const checkedNode: LegacyCheckedNode = {
 | |
|               pos,
 | |
|               node,
 | |
|               children,
 | |
|             };
 | |
| 
 | |
|             if (!parentIncluded) {
 | |
|               nodeList.push(checkedNode);
 | |
|             }
 | |
| 
 | |
|             return checkedNode;
 | |
|           }
 | |
|           return null;
 | |
|         })
 | |
|         .filter(node => node);
 | |
|     }
 | |
| 
 | |
|     if (!nodeList) {
 | |
|       nodeList = [];
 | |
| 
 | |
|       dig(treeData);
 | |
| 
 | |
|       // Sort to keep the checked node length
 | |
|       nodeList.sort(
 | |
|         (
 | |
|           {
 | |
|             node: {
 | |
|               props: { value: val1 },
 | |
|             },
 | |
|           },
 | |
|           {
 | |
|             node: {
 | |
|               props: { value: val2 },
 | |
|             },
 | |
|           },
 | |
|         ) => {
 | |
|           const index1 = checkedValues.indexOf(val1);
 | |
|           const index2 = checkedValues.indexOf(val2);
 | |
|           return index1 - index2;
 | |
|         },
 | |
|       );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   Object.defineProperty(extra, 'triggerNode', {
 | |
|     get() {
 | |
|       warning(false, '`triggerNode` is deprecated. Please consider decoupling data with node.');
 | |
|       generateMap();
 | |
| 
 | |
|       return triggerNode;
 | |
|     },
 | |
|   });
 | |
|   Object.defineProperty(extra, 'allCheckedNodes', {
 | |
|     get() {
 | |
|       warning(false, '`allCheckedNodes` is deprecated. Please consider decoupling data with node.');
 | |
|       generateMap();
 | |
| 
 | |
|       if (showPosition) {
 | |
|         return nodeList;
 | |
|       }
 | |
| 
 | |
|       return nodeList.map(({ node }) => node);
 | |
|     },
 | |
|   });
 | |
| }
 |