Skip to content
Permalink
Browse files

fix missing logic (#277)

  • Loading branch information
zombieJ committed Sep 20, 2019
1 parent 1b43b99 commit 2ffa933527c17b28ba7c6711ccb1f7af023f3fc2
Showing with 286 additions and 168 deletions.
  1. +15 −7 examples/funtionTitle.jsx
  2. +18 −5 src/Tree.tsx
  3. +0 −147 src/util.tsx
  4. +235 −0 src/utils/conductUtil.ts
  5. +18 −9 tests/util.spec.js
@@ -25,11 +25,9 @@ const motion = {
onLeaveActive: () => ({ height: 0 }),
};

const renderTitle = title => {
console.log('run');
return title;
};

const renderTitle = title =>
// console.log('run');
title;
const groupList = (list, targetVar) => {
const obj = {};
list.forEach(item => {
@@ -43,7 +41,7 @@ const groupList = (list, targetVar) => {
disabled,
});
});
console.log(obj);
// console.log(obj);
return (
Object.keys(obj)
.map(key => ({
@@ -56,6 +54,11 @@ const groupList = (list, targetVar) => {
};

function getTreeData() {
// return [
// { key: '00', children: [{ key: '000' }, { key: '001' }] },
// { key: '01', children: [{ key: '010' }, { key: '011' }] },
// ];

return groupList(
data.map(item => ({
title: () => renderTitle(item.fieldName),
@@ -70,6 +73,8 @@ function getTreeData() {

const Demo = () => {
const [keys, setKeys] = useState(data.map(item => item.fieldName));
// const [keys, setKeys] = useState(['00', '01']);

return (
<div className="animation">
<h2>expanded</h2>
@@ -85,7 +90,10 @@ const Demo = () => {
height={200}
checkedKeys={keys}
itemHeight={20}
onCheck={checkedKeys => setKeys(checkedKeys)}
onCheck={checkedKeys => {
console.log('onCheck:', checkedKeys);
setKeys(checkedKeys);
}}
style={{ border: '1px solid #000' }}
treeData={getTreeData()}
/>
@@ -19,7 +19,6 @@ import {
arrAdd,
arrDel,
posToArr,
conductCheck,
} from './util';
import {
DataNode,
@@ -41,6 +40,7 @@ import {
} from './utils/treeUtil';
import NodeList, { MOTION_KEY, MotionEntity, NodeListRef } from './NodeList';
import TreeNode from './TreeNode';
import { conductCheck } from './utils/conductUtil';

interface CheckInfo {
event: 'check';
@@ -647,10 +647,23 @@ class Tree extends React.Component<TreeProps, TreeState> {

this.setUncontrolledState({ checkedKeys });
} else {
const { checkedKeys, halfCheckedKeys } = conductCheck([key], checked, keyEntities, {
checkedKeys: oriCheckedKeys,
halfCheckedKeys: oriHalfCheckedKeys,
});
// Always fill first
let { checkedKeys, halfCheckedKeys } = conductCheck(
[...oriCheckedKeys, key],
true,
keyEntities,
);

// If remove, we do it again to correction
if (!checked) {
const keySet = new Set(checkedKeys);
keySet.delete(key);
({ checkedKeys, halfCheckedKeys } = conductCheck(
Array.from(keySet),
{ checked: false, halfCheckedKeys },
keyEntities,
));
}

checkedObj = checkedKeys;

@@ -150,153 +150,6 @@ export function parseCheckedKeys(keys: Key[] | { checked: Key[]; halfChecked: Ke
return keyProps;
}

/**
* Conduct check state by the keyList. It will conduct up & from the provided key.
* If the conduct path reach the disabled or already checked / unchecked node will stop conduct.
*/
export function conductCheck(
/** list of keys */
keyList: Key[],
/** is check the node or not */
isCheck: boolean,
/** parsed by `convertTreeToEntities` function in Tree */
keyEntities: Record<Key, DataEntity>,
/** Can pass current checked status for process (usually for uncheck operation) */
checkStatus: { checkedKeys?: Key[]; halfCheckedKeys?: Key[] } = {},
) {
const warningMissKeys: Key[] = [];

const checkedKeyMap: Map<Key, boolean> = new Map();
// Record the key has some child checked (include child half checked)
const halfCheckedKeyMap: Map<Key, boolean> = new Map();

(checkStatus.checkedKeys || []).forEach(key => {
checkedKeyMap.set(key, true);
});

(checkStatus.halfCheckedKeys || []).forEach(key => {
halfCheckedKeyMap.set(key, true);
});

// Conduct up
function conductUp(key: Key) {
if (checkedKeyMap.get(key) === isCheck) return;

const entity = keyEntities[key];
if (!entity) return;

const { children, parent, node } = entity;

if (isCheckDisabled(node)) return;

// Check child node checked status
let everyChildChecked = true;
let someChildChecked = false; // Child checked or half checked

if (children && children.length) {
children.forEach(({ key: childKey, node: childNode }) => {
if (isCheckDisabled(childNode)) return;

const childChecked = checkedKeyMap.get(childKey);
const childHalfChecked = halfCheckedKeyMap.get(childKey);

if (childChecked || childHalfChecked) someChildChecked = true;
if (!childChecked) everyChildChecked = false;
});
}

// Update checked status
if (isCheck) {
checkedKeyMap.set(key, everyChildChecked);
} else {
checkedKeyMap.set(key, false);
}
halfCheckedKeyMap.set(key, someChildChecked);

if (parent) {
conductUp(parent.key);
}
}

// Conduct down
function conductDown(key: Key) {
if (checkedKeyMap.get(key) === isCheck) return;

const entity = keyEntities[key];
if (!entity) return;

const { children, node } = entity;

if (isCheckDisabled(node)) return;

checkedKeyMap.set(key, isCheck);

(children || []).forEach(child => {
conductDown(child.key);
});
}

function conduct(key: Key) {
const entity = keyEntities[key];

if (!entity) {
warningMissKeys.push(key);
return;
}

const { children, parent, node } = entity;
checkedKeyMap.set(key, isCheck);

if (isCheckDisabled(node)) return;

// Conduct down
(children || [])
.filter(child => !isCheckDisabled(child.node))
.forEach(child => {
conductDown(child.key);
});

// Conduct up
if (parent) {
conductUp(parent.key);
}
}

(keyList || []).forEach(key => {
conduct(key);
});

const checkedKeyList = [];
const halfCheckedKeyList = [];

// Fill checked list
checkedKeyMap.forEach((checked, key) => {
if (checked) {
checkedKeyList.push(key);
}
});

// Fill half checked list
halfCheckedKeyMap.forEach((halfChecked, key) => {
if (!checkedKeyMap.get(key) && halfChecked) {
halfCheckedKeyList.push(key);
}
});

warning(
!warningMissKeys.length,
`Tree missing follow keys: ${warningMissKeys
.slice(0, 100)
.map(key => `'${key}'`)
.join(', ')}`,
);

return {
checkedKeys: checkedKeyList,
halfCheckedKeys: halfCheckedKeyList,
};
}

/**
* If user use `autoExpandParent` we should get the list of parent node
* @param keyList

1 comment on commit 2ffa933

@now

This comment has been minimized.

Please sign in to comment.
You can’t perform that action at this time.