反应树列表
一个灵活且能表演的React组件库,用于构建树,列表,以及多选取支持的虚拟可滚动视图.
安装
npm install @dazl/tree-list
# or
yarn add @dazl/tree-list
# or
pnpm add @dazl/tree-list
特征
- 🌲 树形视图: 有相撞节点的分级树构件
- 📋 列表: 带有键盘导航和选择的简单列表组件
- 🔄 滚动列表: 高效渲染大数据集的虚拟列表
- ⌨️ 键盘导航: 全键盘导航支持
- ✅ 多选: 支持使用修改键选择和多选择区域
- 🔍 虚拟化: 只渲染可见的性能项目
- 📱 响应: 具有横向和纵向布局的工作
构成部分
列表
一个带有选择和键盘导航的基本列表组件.
import { List } from '@dazl/tree-list';
import type { ListItem } from '@dazl/tree-list';
interface ItemData {
id: string;
title: string;
}
const items = [
{ id: '1', title: 'Item 1' },
{ id: '2', title: 'Item 2' },
{ id: '3', title: 'Item 3' },
];
const ItemRenderer = ({ id, data, isFocused, isSelected }: ListItem<ItemData>) => (
<div
data-id={id}
style={{
background: isSelected ? 'lightblue' : 'white',
border: isFocused ? '1px solid blue' : '1px solid transparent',
padding: '8px',
}}
>
{data.title}
</div>
);
function MyList() {
const [selectedIds, setSelectedIds] = useState({ ids: [] });
const [focusedId, setFocusedId] = useState();
return (
<List
items={items}
getId={(item) => item.id}
ItemRenderer={ItemRenderer}
selectedIds={selectedIds}
setSelectedIds={setSelectedIds}
focusedId={focusedId}
setFocusedId={setFocusedId}
/>
);
}
滚动列表
用于高效渲染大数据集的虚拟列表.
import { ScrollList } from '@dazl/tree-list/scroll-list';
function MyScrollList() {
const [selectedIds, setSelectedIds] = useState({ ids: [] });
const [focusedId, setFocusedId] = useState();
return (
<ScrollList
items={manyItems}
getId={(item) => item.id}
ItemRenderer={ItemRenderer}
selectedIds={selectedIds}
setSelectedIds={setSelectedIds}
focusedId={focusedId}
setFocusedId={setFocusedId}
scrollListContainerProps={{
style: {
height: '500px',
overflow: 'auto'
}
}}
extraRenderSize={1}
scrollToFocused
/>
);
}
树
带有可折叠节点的分级树构件 .
import { Tree } from '@dazl/tree-list/tree';
import type { TreeItemProps } from '@dazl/tree-list';
interface TreeItemData {
id: string;
name: string;
children: TreeItemData[];
}
const TreeItemRenderer = ({
id,
data,
isSelected,
isFocused,
isOpen,
hasChildren,
indent,
open,
close
}: TreeItemProps<TreeItemData>) => (
<div
data-id={id}
style={{
paddingLeft: `${indent * 20}px`,
background: isSelected ? 'lightblue' : 'white',
border: isFocused ? '1px solid blue' : '1px solid transparent',
}}
>
{hasChildren && (
<button onClick={isOpen ? close : open}>
{isOpen ? '▼' : '►'}
</button>
)}
{data.name}
</div>
);
function MyTree() {
const [selectedIds, setSelectedIds] = useState({ ids: [] });
const [focusedId, setFocusedId] = useState();
const [openItemIds, setOpenItemIds] = useState(['root']);
return (
<Tree
data={treeData}
getChildren={(item) => item.children}
getId={(item) => item.id}
ItemRenderer={TreeItemRenderer}
selectedIds={selectedIds}
setSelectedIds={setSelectedIds}
focusedId={focusedId}
setFocusedId={setFocusedId}
openItemIds={openItemIds}
setOpenItemIds={setOpenItemIds}
/>
);
}
API 文档
列表选项
| Prop | 类型 | 说明 |
|---|---|---|
items | T[] | 拟制作的项目组 |
getId | (item: T) => string | 从项目中提取唯一 ID 的函数 |
ItemRenderer | React.FC<ListItem<T>> | 构成每个项目的构成部分 |
selectedIds | { ids: string[], lastSelectedId?: string } | 当前选中的项目 IDs |
setSelectedIds | (selection: ListSelection) => void | 回调以更新选择 |
focusedId | string | undefined | 目前重点讨论的项目d |
setFocusedId | (id?: string) => void | 回调以更新焦点 |
enableKeyboard | boolean | 启用键盘导航( 默认: 真) |
enableMultiselect | boolean | 启用多个选择( 默认: 真) |
style | React.CSSProperties | 列表容器的自定义样式 |
listRef | React.RefObject<HTMLDivElement> | 列表容器的参考文献 |
listContainerProps | React.HTMLAttributes<HTMLDivElement> | 列表容器的额外道具 |
更详细的类型定义和附加组件参见源代码.
许可证
麻省理工学院