Browse Source

docs: Add Tree virtual scroll demo (#20911)

* docs: Add Tree virtual scroll demo

* update snapshot

* show debug demo

* rename

* fix lint

* skip virtual list demo snapshot since conflict in node test
pull/20913/merge
二货机器人 5 years ago
committed by GitHub
parent
commit
246adcd5dd
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 39
      components/tree/DirectoryTree.tsx
  2. 33
      components/tree/Tree.tsx
  3. 2
      components/tree/__tests__/demo.test.js
  4. 40
      components/tree/demo/virtual-scroll.md
  5. 2
      package.json
  6. 2
      site/theme/template/Content/ComponentDoc.jsx
  7. 1
      typings/custom-typings.d.ts

39
components/tree/DirectoryTree.tsx

@ -3,17 +3,12 @@ import classNames from 'classnames';
import omit from 'omit.js'; import omit from 'omit.js';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import { conductExpandParent } from 'rc-tree/lib/util'; import { conductExpandParent } from 'rc-tree/lib/util';
import { EventDataNode, DataNode } from 'rc-tree/lib/interface';
import { convertDataToEntities, convertTreeToData } from 'rc-tree/lib/utils/treeUtil'; import { convertDataToEntities, convertTreeToData } from 'rc-tree/lib/utils/treeUtil';
import { FileOutlined, FolderOpenOutlined, FolderOutlined } from '@ant-design/icons'; import { FileOutlined, FolderOpenOutlined, FolderOutlined } from '@ant-design/icons';
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
import Tree, { import Tree, { TreeProps, AntdTreeNodeAttribute } from './Tree';
TreeProps,
AntdTreeNodeAttribute,
AntTreeNodeExpandedEvent,
AntTreeNodeSelectedEvent,
AntTreeNode,
} from './Tree';
import { calcRangeKeys, convertDirectoryKeysToNodes } from './utils/dictUtil'; import { calcRangeKeys, convertDirectoryKeysToNodes } from './utils/dictUtil';
export type ExpandAction = false | 'click' | 'doubleClick'; export type ExpandAction = false | 'click' | 'doubleClick';
@ -60,7 +55,7 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
tree: Tree; tree: Tree;
onDebounceExpand: (event: React.MouseEvent<HTMLElement>, node: AntTreeNode) => void; onDebounceExpand: (event: React.MouseEvent<HTMLElement>, node: EventDataNode) => void;
// Shift click usage // Shift click usage
lastSelectedKey?: string; lastSelectedKey?: string;
@ -95,7 +90,14 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
}); });
} }
onExpand = (expandedKeys: string[], info: AntTreeNodeExpandedEvent) => { onExpand = (
expandedKeys: string[],
info: {
node: EventDataNode;
expanded: boolean;
nativeEvent: MouseEvent;
},
) => {
const { onExpand } = this.props; const { onExpand } = this.props;
this.setUncontrolledState({ expandedKeys }); this.setUncontrolledState({ expandedKeys });
@ -108,7 +110,7 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
return undefined; return undefined;
}; };
onClick = (event: React.MouseEvent<HTMLElement>, node: AntTreeNode) => { onClick = (event: React.MouseEvent<HTMLElement>, node: EventDataNode) => {
const { onClick, expandAction } = this.props; const { onClick, expandAction } = this.props;
// Expand the tree // Expand the tree
@ -121,7 +123,7 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
} }
}; };
onDoubleClick = (event: React.MouseEvent<HTMLElement>, node: AntTreeNode) => { onDoubleClick = (event: React.MouseEvent<HTMLElement>, node: EventDataNode) => {
const { onDoubleClick, expandAction } = this.props; const { onDoubleClick, expandAction } = this.props;
// Expand the tree // Expand the tree
@ -134,7 +136,16 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
} }
}; };
onSelect = (keys: string[], event: AntTreeNodeSelectedEvent) => { onSelect = (
keys: string[],
event: {
event: 'select';
selected: boolean;
node: any;
selectedNodes: DataNode[];
nativeEvent: MouseEvent;
},
) => {
const { onSelect, multiple } = this.props; const { onSelect, multiple } = this.props;
const { expandedKeys = [] } = this.state; const { expandedKeys = [] } = this.state;
const { node, nativeEvent } = event; const { node, nativeEvent } = event;
@ -144,7 +155,7 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
const newState: DirectoryTreeState = {}; const newState: DirectoryTreeState = {};
// We need wrap this event since some value is not same // We need wrap this event since some value is not same
const newEvent: AntTreeNodeSelectedEvent = { const newEvent: any = {
...event, ...event,
selected: true, // Directory selected always true selected: true, // Directory selected always true
}; };
@ -190,7 +201,7 @@ class DirectoryTree extends React.Component<DirectoryTreeProps, DirectoryTreeSta
this.tree = node; this.tree = node;
}; };
expandFolderNode = (event: React.MouseEvent<HTMLElement>, node: AntTreeNode) => { expandFolderNode = (event: React.MouseEvent<HTMLElement>, node: any) => {
const { isLeaf } = node.props; const { isLeaf } = node.props;
if (isLeaf || event.shiftKey || event.metaKey || event.ctrlKey) { if (isLeaf || event.shiftKey || event.metaKey || event.ctrlKey) {

33
components/tree/Tree.tsx

@ -1,5 +1,5 @@
import * as React from 'react'; import * as React from 'react';
import RcTree, { TreeNode } from 'rc-tree'; import RcTree, { TreeNode, TreeProps as RcTreeProps } from 'rc-tree';
import classNames from 'classnames'; import classNames from 'classnames';
import { DataNode } from 'rc-tree/lib/interface'; import { DataNode } from 'rc-tree/lib/interface';
@ -98,7 +98,7 @@ export interface TreeNodeNormal {
children?: TreeNodeNormal[]; children?: TreeNodeNormal[];
} }
export interface TreeProps { export interface TreeProps extends Omit<RcTreeProps, 'prefixCls'> {
showLine?: boolean; showLine?: boolean;
className?: string; className?: string;
/** 是否支持多选 */ /** 是否支持多选 */
@ -128,50 +128,23 @@ export interface TreeProps {
/** 默认选中的树节点 */ /** 默认选中的树节点 */
defaultSelectedKeys?: string[]; defaultSelectedKeys?: string[];
selectable?: boolean; selectable?: boolean;
/** 展开/收起节点时触发 */
onExpand?: (expandedKeys: string[], info: AntTreeNodeExpandedEvent) => void | PromiseLike<void>;
/** 点击复选框触发 */
onCheck?: (
checkedKeys: string[] | { checked: string[]; halfChecked: string[] },
e: AntTreeNodeCheckedEvent,
) => void;
/** 点击树节点触发 */ /** 点击树节点触发 */
onSelect?: (selectedKeys: string[], e: AntTreeNodeSelectedEvent) => void;
/** 单击树节点触发 */
onClick?: (e: React.MouseEvent<HTMLElement>, node: AntTreeNode) => void;
/** 双击树节点触发 */
onDoubleClick?: (e: React.MouseEvent<HTMLElement>, node: AntTreeNode) => void;
/** filter some AntTreeNodes as you need. it should return true */
filterAntTreeNode?: (node: AntTreeNode) => boolean; filterAntTreeNode?: (node: AntTreeNode) => boolean;
/** 异步加载数据 */
loadData?: (node: AntTreeNode) => PromiseLike<void>;
loadedKeys?: string[]; loadedKeys?: string[];
onLoad?: (loadedKeys: string[], info: { event: 'load'; node: AntTreeNode }) => void;
/** 响应右键点击 */
onRightClick?: (options: AntTreeNodeMouseEvent) => void;
/** 设置节点可拖拽(IE>8) */ /** 设置节点可拖拽(IE>8) */
draggable?: boolean; draggable?: boolean;
onDragStart?: (options: AntTreeNodeMouseEvent) => void;
onDragEnter?: (options: AntTreeNodeDragEnterEvent) => void;
onDragOver?: (options: AntTreeNodeMouseEvent) => void;
onDragLeave?: (options: AntTreeNodeMouseEvent) => void;
onDragEnd?: (options: AntTreeNodeMouseEvent) => void;
onMouseEnter?: (options: AntTreeNodeMouseEvent) => void;
onMouseLeave?: (options: AntTreeNodeMouseEvent) => void;
onDrop?: (options: AntTreeNodeDropEvent) => void;
style?: React.CSSProperties; style?: React.CSSProperties;
showIcon?: boolean; showIcon?: boolean;
icon?: ((nodeProps: AntdTreeNodeAttribute) => React.ReactNode) | React.ReactNode; icon?: ((nodeProps: AntdTreeNodeAttribute) => React.ReactNode) | React.ReactNode;
switcherIcon?: React.ReactElement<any>; switcherIcon?: React.ReactElement<any>;
prefixCls?: string; prefixCls?: string;
filterTreeNode?: (node: AntTreeNode) => boolean;
children?: React.ReactNode; children?: React.ReactNode;
blockNode?: boolean; blockNode?: boolean;
treeData?: Array<TreeNodeNormal>; treeData?: Array<TreeNodeNormal>;
} }
export default class Tree extends React.Component<TreeProps, any> { export default class Tree extends React.Component<TreeProps, any> {
static TreeNode: React.ComponentClass<AntTreeNodeProps> = TreeNode; static TreeNode = TreeNode;
static DirectoryTree = DirectoryTree; static DirectoryTree = DirectoryTree;

2
components/tree/__tests__/demo.test.js

@ -1,3 +1,3 @@
import demoTest from '../../../tests/shared/demoTest'; import demoTest from '../../../tests/shared/demoTest';
demoTest('tree', { skip: ['big-data.md'] }); demoTest('tree', { skip: ['big-data.md', 'virtual-scroll.md'] });

40
components/tree/demo/virtual-scroll.md

@ -0,0 +1,40 @@
---
order: 9
title:
zh-CN: 虚拟滚动
en-US: Virtual scroll
---
## zh-CN
使用 `height` 属性则切换为虚拟滚动。
## en-US
Use virtual list through `height` prop.
```jsx
import { Tree } from 'antd';
function dig(path = '0', level = 3) {
const list = [];
for (let i = 0; i < 10; i += 1) {
const key = `${path}-${i}`;
const treeNode = {
title: key,
key,
};
if (level > 0) {
treeNode.children = dig(key, level - 1);
}
list.push(treeNode);
}
return list;
}
const treeData = dig();
ReactDOM.render(<Tree treeData={treeData} height={233} defaultExpandAll />, mountNode);
```

2
package.json

@ -137,7 +137,7 @@
"warning": "~4.0.3" "warning": "~4.0.3"
}, },
"devDependencies": { "devDependencies": {
"@ant-design/bisheng-plugin": "^2.1.0", "@ant-design/bisheng-plugin": "^2.3.0",
"@ant-design/colors": "^4.0.0-alpha.0", "@ant-design/colors": "^4.0.0-alpha.0",
"@ant-design/hitu": "^0.0.0-alpha.13", "@ant-design/hitu": "^0.0.0-alpha.13",
"@ant-design/tools": "^8.0.4", "@ant-design/tools": "^8.0.4",

2
site/theme/template/Content/ComponentDoc.jsx

@ -187,7 +187,7 @@ class ComponentDoc extends React.Component {
} }
> >
{visibleAll ? ( {visibleAll ? (
<BugFilled style={{ display: 'none' }} className={expandTriggerClass} onClick={this.handleVisibleToggle} /> <BugFilled className={expandTriggerClass} onClick={this.handleVisibleToggle} />
) : ( ) : (
<BugOutlined className={expandTriggerClass} onClick={this.handleVisibleToggle} /> <BugOutlined className={expandTriggerClass} onClick={this.handleVisibleToggle} />
)} )}

1
typings/custom-typings.d.ts

@ -28,7 +28,6 @@ declare module 'rc-editor-mention';
declare module 'rc-tabs*'; declare module 'rc-tabs*';
declare module 'rc-tree';
declare module 'rc-tree/lib/util'; declare module 'rc-tree/lib/util';
declare module 'rc-input-number'; declare module 'rc-input-number';

Loading…
Cancel
Save