Proxy of event info (#15967)

This commit is contained in:
zombieJ 2019-04-09 14:20:59 +08:00 committed by GitHub
parent 4c3a351bc7
commit 645557f3d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 7 deletions

View File

@ -13,7 +13,7 @@ import Tree, {
AntTreeNodeSelectedEvent,
AntTreeNode,
} from './Tree';
import { calcRangeKeys, getFullKeyList } from './util';
import { calcRangeKeys, getFullKeyList, convertDirectoryKeysToNodes } from './util';
import Icon from '../icon';
export type ExpandAction = false | 'click' | 'doubleClick';
@ -141,6 +141,12 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
const newState: DirectoryTreeState = {};
// We need wrap this event since some value is not same
const newEvent: AntTreeNodeSelectedEvent = {
...event,
selected: true, // Directory selected always true
};
// Windows / Mac single pick
const ctrlPick: boolean = nativeEvent.ctrlKey || nativeEvent.metaKey;
const shiftPick: boolean = nativeEvent.shiftKey;
@ -152,6 +158,7 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
newSelectedKeys = keys;
this.lastSelectedKey = eventKey;
this.cachedSelectedKeys = newSelectedKeys;
newEvent.selectedNodes = convertDirectoryKeysToNodes(children, newSelectedKeys);
} else if (multiple && shiftPick) {
// Shift click
newSelectedKeys = Array.from(
@ -160,16 +167,18 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
...calcRangeKeys(children, expandedKeys, eventKey, this.lastSelectedKey),
]),
);
newEvent.selectedNodes = convertDirectoryKeysToNodes(children, newSelectedKeys);
} else {
// Single click
newSelectedKeys = [eventKey];
this.lastSelectedKey = eventKey;
this.cachedSelectedKeys = newSelectedKeys;
newEvent.selectedNodes = [event.node];
}
newState.selectedKeys = newSelectedKeys;
if (onSelect) {
onSelect(newSelectedKeys, event);
onSelect(newSelectedKeys, newEvent);
}
this.setUncontrolledState(newState);

View File

@ -131,6 +131,7 @@ describe('Directory Tree', () => {
it('group select', () => {
let nativeEventProto = null;
const onSelect = jest.fn();
const wrapper = mount(
createTree({
defaultExpandAll: true,
@ -139,6 +140,7 @@ describe('Directory Tree', () => {
onClick: e => {
nativeEventProto = Object.getPrototypeOf(e.nativeEvent);
},
onSelect,
}),
);
@ -147,6 +149,18 @@ describe('Directory Tree', () => {
.find('.ant-tree-node-content-wrapper')
.at(0)
.simulate('click');
expect(onSelect.mock.calls[0][1].selected).toBeTruthy();
expect(onSelect.mock.calls[0][1].selectedNodes.length).toBe(1);
// Click twice should keep selected
wrapper
.find(TreeNode)
.find('.ant-tree-node-content-wrapper')
.at(0)
.simulate('click');
expect(onSelect.mock.calls[1][1].selected).toBeTruthy();
expect(onSelect.mock.calls[0][0]).toEqual(onSelect.mock.calls[1][0]);
expect(onSelect.mock.calls[1][1].selectedNodes.length).toBe(1);
// React not simulate full of NativeEvent. Hook it.
// Ref: https://github.com/facebook/react/blob/master/packages/react-dom/src/test-utils/ReactTestUtils.js#L360
@ -158,6 +172,9 @@ describe('Directory Tree', () => {
.at(1)
.simulate('click');
expect(wrapper.render()).toMatchSnapshot();
expect(onSelect.mock.calls[2][0].length).toBe(2);
expect(onSelect.mock.calls[2][1].selected).toBeTruthy();
expect(onSelect.mock.calls[2][1].selectedNodes.length).toBe(2);
delete nativeEventProto.ctrlKey;
nativeEventProto.shiftKey = true;
@ -168,6 +185,9 @@ describe('Directory Tree', () => {
.at(4)
.simulate('click');
expect(wrapper.render()).toMatchSnapshot();
expect(onSelect.mock.calls[3][0].length).toBe(5);
expect(onSelect.mock.calls[3][1].selected).toBeTruthy();
expect(onSelect.mock.calls[3][1].selectedNodes.length).toBe(5);
delete nativeEventProto.shiftKey;
});

View File

@ -20,8 +20,8 @@ const DirectoryTree = Tree.DirectoryTree;
const { TreeNode } = Tree;
class Demo extends React.Component {
onSelect = () => {
console.log('Trigger Select');
onSelect = (keys, event) => {
console.log('Trigger Select', keys, event);
};
onExpand = () => {

View File

@ -1,6 +1,6 @@
import * as React from 'react';
import { getNodeChildren, convertTreeToEntities } from 'rc-tree/lib/util';
import { AntTreeNodeProps } from './Tree';
import { AntTreeNodeProps, AntTreeNode } from './Tree';
enum Record {
None,
@ -11,7 +11,7 @@ enum Record {
// TODO: Move this logic into `rc-tree`
function traverseNodesKey(
rootChildren: React.ReactNode | React.ReactNode[],
callback: (key: string | number | null) => boolean,
callback: (key: string | number | null, node: AntTreeNode) => boolean,
) {
const nodeList: React.ReactNode[] = getNodeChildren(rootChildren) || [];
@ -20,7 +20,7 @@ function traverseNodesKey(
key,
props: { children },
} = node;
if (callback(key) !== false) {
if (callback(key, node as any) !== false) {
traverseNodesKey(children, callback);
}
}
@ -83,3 +83,18 @@ export function calcRangeKeys(
return keys;
}
export function convertDirectoryKeysToNodes(rootChildren: React.ReactNode | React.ReactNode[], keys: string[]) {
const restKeys: string[] = [...keys];
const nodes: AntTreeNode[] = [];
traverseNodesKey(rootChildren, (key: string, node: AntTreeNode) => {
const index = restKeys.indexOf(key);
if (index !== -1) {
nodes.push(node);
restKeys.splice(index, 1);
}
return !!restKeys.length;
});
return nodes;
}