Skip to content

Commit

Permalink
✨ feat: add virtual config"
Browse files Browse the repository at this point in the history
  • Loading branch information
rdmclin2 committed Dec 30, 2023
1 parent c8e7b76 commit b10760f
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 56 deletions.
9 changes: 8 additions & 1 deletion src/SortableTree/container/StoreUpdater.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { SortableTreeInstance, useSortableTree } from '../hooks/useSortableTree'
import type { ControlledState, OnTreeDataChange } from '../store';
import { useStoreApi } from '../store';

import type { FlattenNode, Projected, RenderNodeProps, TreeData } from '../types';
import type { FlattenNode, Projected, RenderNodeProps, TreeData, VirtualConfig } from '../types';

export interface StoreUpdaterProps<T = any> extends ControlledState {
/**
Expand Down Expand Up @@ -46,6 +46,11 @@ export interface StoreUpdaterProps<T = any> extends ControlledState {
targetNode: FlattenNode<T>;
projected: Projected;
}) => boolean;

/**
* 开启虚拟滚动
*/
virtual?: VirtualConfig;
}

const StoreUpdater = ({
Expand All @@ -61,6 +66,7 @@ const StoreUpdater = ({
indentationWidth,
disableDrag,
sortableRule,
virtual,
}: StoreUpdaterProps) => {
const storeApi = useStoreApi();

Expand All @@ -75,6 +81,7 @@ const StoreUpdater = ({
useStoreUpdater('indentationWidth', indentationWidth);
useStoreUpdater('hideAdd', hideAdd);
useStoreUpdater('hideRemove', hideRemove);
useStoreUpdater('virtual', virtual);
useStoreUpdater('disableDrag', disableDrag);
useStoreUpdater('sortableRule', sortableRule);

Expand Down
25 changes: 17 additions & 8 deletions src/SortableTree/demos/virtual.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
/**
* title: 虚拟滚动
* description: 数据量较大时,使用 virtual 配置虚拟滚动
*/
import { SortableTree } from '@ant-design/pro-editor';

interface DataContent {
Expand Down Expand Up @@ -3951,14 +3955,19 @@ const LayerManager = () => {
];

return (
<SortableTree<DataContent>
treeData={treeData as any}
renderContent={(item) => <div>{item.id}</div>}
SHOW_STORE_IN_DEVTOOLS
onTreeDataChange={(data) => {
console.log('变更:', data);
}}
/>
<div style={{ width: 340 }}>
<SortableTree<DataContent>
treeData={treeData as any}
renderContent={(item) => <div>{item.id}</div>}
SHOW_STORE_IN_DEVTOOLS
virtual={{
height: 480,
}}
onTreeDataChange={(data) => {
console.log('变更:', data);
}}
/>
</div>
);
};
export default LayerManager;
40 changes: 23 additions & 17 deletions src/SortableTree/features/TreeList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,30 +75,36 @@ interface TreeListProps {
}

const TreeList = memo<TreeListProps>(({ prefixCls }) => {
const [dispatchTreeData, hideAdd] = useStore(
(s) => [s.dispatchTreeData, s.hideAdd, s.hideRemove],
const [dispatchTreeData, hideAdd, virtual] = useStore(
(s) => [s.dispatchTreeData, s.hideAdd, s.virtual],
shallow,
);
const flattenData: FlattenNode[] = useStore(dataFlattenSelector, isEqual);
const { styles } = useStyle(prefixCls);

const { height = 800, itemHeight = () => 36, width = '100%' } = virtual || {};

return (
<>
<VariableSizeList
itemCount={flattenData!.length}
height={800}
itemSize={() => 36}
itemData={flattenData}
width={275}
>
{({ index, data, style }) => {
return <TreeNode prefixCls={prefixCls} node={data[index]} virtualStyle={style} />;
}}
</VariableSizeList>

{/* {flattenData.map((node) => (
<TreeNode key={node.id} node={node} prefixCls={prefixCls} />
))} */}
{virtual ? (
<VariableSizeList
itemCount={flattenData!.length}
height={height}
itemSize={itemHeight}
itemData={flattenData}
width={width}
>
{({ index, data, style }) => {
return <TreeNode prefixCls={prefixCls} node={data[index]} virtualStyle={style} />;
}}
</VariableSizeList>
) : (
<>
{flattenData.map((node) => (
<TreeNode key={node.id} node={node} prefixCls={prefixCls} />
))}
</>
)}
{hideAdd ? null : (
<Button
block
Expand Down
69 changes: 40 additions & 29 deletions src/SortableTree/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,52 +28,63 @@ demo:

### 属性

| 名称 | 类型 | 描述 |
| ------------------- | ----------------------------------------------------------------------------------------------------- | ----------- |
| hideAdd | `boolean` | 隐藏默认的添加按钮 |
| hideRemove | `boolean` | 隐藏默认的删除按钮 |
| disableDrag | `boolean` | 禁用拖拽 |
| indentationWidth | `number` | 缩进宽度 |
| onSelectedIdsChange | `(selectedIds: UniqueIdentifier[]) => void` | 选中 ID 变更回调 |
| treeData | `TreeData<T>` | 树的数据 |
| defaultTreeData | `TreeData<T>` | 默认数据 |
| onTreeDataChange | `(treeData: TreeData<T>,event: TreeDataDispatchPayload) => void` | 数据变更回调 |
| renderContent | `(node: FlattenNode<T>) => JSX.Element` | 渲染内容 |
| renderExtra | `(node: FlattenNode<T>) => JSX.Element` | 渲染额外项 |
| ref | `MutableRefObject<SortableTreeInstance<T>>` | 对外部暴露方法 |
| sortableRule | `data: { activeNode: FlattenNode<T>; targetNode: FlattenNode<T>; projected: Projected; }) => boolean` | 控制拖动排序的规则函数 |
| 名称 | 类型 | 描述 |
| ------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------- |
| hideAdd | `boolean` | 隐藏默认的添加按钮 |
| hideRemove | `boolean` | 隐藏默认的删除按钮 |
| disableDrag | `boolean` | 禁用拖拽 |
| indentationWidth | `number` | 缩进宽度 |
| onSelectedIdsChange | `(selectedIds: UniqueIdentifier[]) => void` | 选中 ID 变更回调 |
| treeData | `TreeData<T>` | 树的数据 |
| defaultTreeData | `TreeData<T>` | 默认数据 |
| onTreeDataChange | `(treeData: TreeData<T>,event: TreeDataDispatchPayload) => void` | 数据变更回调 |
| renderContent | `(node: FlattenNode<T>) => JSX.Element` | 渲染内容 |
| renderExtra | `(node: FlattenNode<T>) => JSX.Element` | 渲染额外项 |
| ref | `MutableRefObject<SortableTreeInstance<T>>` | 对外部暴露方法 |
| sortableRule | `data: { activeNode: FlattenNode<T>; targetNode: FlattenNode<T>; projected: Projected; }) => boolean` | 控制拖动排序的规则函数 |
| virtual | `VirtualConfig` \| `false` | 虚拟滚动配置,默认为 false |

## VirtualConfig

虚拟滚动配置

| 名称 | 类型 | 描述 |
| ---------- | --------------------------- | --------------------------- |
| height | `number` | 虚拟滚动容器高度,必填 |
| width | `number`\| `string` | 虚拟滚动容器宽度,默认 100% |
| itemHeight | `(index: number) => number` | 列表项高度,默认为 36 |

## TreeNode

树节点

| 名称 | 类型 | 描述 |
| --------- | ------------------ | -------- |
| id | `UniqueIdentifier` | 节点 ID |
| children | `TreeNode<T>[]` | 子节点列表 |
| collapsed | `boolean` | 组是否折叠 |
| 名称 | 类型 | 描述 |
| --------- | ------------------ | ---------------- |
| id | `UniqueIdentifier` | 节点 ID |
| children | `TreeNode<T>[]` | 子节点列表 |
| collapsed | `boolean` | 组是否折叠 |
| showExtra | `boolean` | 是否显示额外区域 |
| content | `T` | 节点数据 |
| content | `T` | 节点数据 |

## FlattenNode

展平的节点

| 名称 | 类型 | 描述 |
| -------- | ---------------------------- | -------------------- |
| 名称 | 类型 | 描述 |
| -------- | ---------------------------- | -------------------------------- |
| parentId | `UniqueIdentifier` \| `null` | 父节点 ID,如果是根节点则为 null |
| depth | `number` | 节点深度 |
| index | `number` | 节点在同级节点中的位置 |
| depth | `number` | 节点深度 |
| index | `number` | 节点在同级节点中的位置 |

## Projected

放置目标位置信息

| 名称 | 类型 | 描述 |
| -------- | ---------------------------- | -------------------- |
| depth | `number` | 放置目标位置深度 |
| maxDepth | `number` | 目标位置可放置最大深度 |
| minDepth | `number` | 目标位置可放置可放置最小深度 |
| 名称 | 类型 | 描述 |
| -------- | ---------------------------- | -------------------------------- |
| depth | `number` | 放置目标位置深度 |
| maxDepth | `number` | 目标位置可放置最大深度 |
| minDepth | `number` | 目标位置可放置可放置最小深度 |
| parentId | `UniqueIdentifier` \| `null` | 父节点 ID,如果是根节点则为 null |

## SortableTreeInstance
Expand Down
14 changes: 13 additions & 1 deletion src/SortableTree/store/initialState.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import type { FlattenNode, Projected, RenderNodeProps, TreeData, UniqueIdentifier } from '../types';
import type {
FlattenNode,
Projected,
RenderNodeProps,
TreeData,
UniqueIdentifier,
VirtualConfig,
} from '../types';
import { TreeDataDispatchPayload } from './treeDataReducer';

export type OnTreeDataChange<T = any> = (
Expand Down Expand Up @@ -89,6 +96,10 @@ export interface State<T = any> extends ControlledState {
targetNode: FlattenNode<T>;
projected: Projected;
}) => boolean;
/**
* 虚拟滚动配置
*/
virtual?: VirtualConfig;
}

export const initialDragState: Pick<
Expand All @@ -108,6 +119,7 @@ export const initialState: State = {
renderContent: undefined,
renderExtra: undefined,
hideAdd: false,
virtual: false,
disableDrag: false,
hideRemove: false,
...initialDragState,
Expand Down
17 changes: 17 additions & 0 deletions src/SortableTree/types/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,20 @@ import { FC } from 'react';
import type { FlattenNode } from './data';

export type RenderNodeProps<T = any> = (node: FlattenNode<T>) => ReturnType<FC>;

export type VirtualConfig =
| {
/**
* @title 虚拟滚动的高度
*/
height: number;
/**
* @title 虚拟滚动的宽度
*/
width?: number;
/**
* @title 虚拟滚动的行高
*/
itemHeight?: (index: number) => number;
}
| false;

0 comments on commit b10760f

Please sign in to comment.