|
| 1 | + |
| 2 | +# OmiTreeReact 组件(中英双语文档) |
| 3 | + |
| 4 | +## 简介 Introduction |
| 5 | + |
| 6 | +`OmiTreeReact` 是一个高质量、类型安全、支持大厂级业务场景的 React 树组件,基于 Omi Web Components 封装,支持属性编辑、嵌套/批量拖拽、分组、Undo/Redo、批量操作、分组节点联动、受控/非受控模式等能力,适用于低代码平台、表单引擎、可视化编辑器等复杂场景。 |
| 7 | + |
| 8 | +OmiTreeReact is a high-quality, type-safe React tree component based on Omi Web Components, supporting advanced business scenarios such as property editing, nested/batch drag-and-drop, grouping, Undo/Redo, batch operations, group node linkage, controlled/uncontrolled modes, etc. Suitable for low-code platforms, form engines, visual editors, and other complex scenarios. |
| 9 | + |
| 10 | +--- |
| 11 | + |
| 12 | +## 主要特性 Key Features |
| 13 | + |
| 14 | +- 属性编辑、批量属性编辑(支持分组节点联动) |
| 15 | +- 嵌套拖拽、批量拖拽、分组节点拖拽 |
| 16 | +- 拖拽到空白区自动新建分组 |
| 17 | +- 批量删除、Undo/Redo 全面支持 |
| 18 | +- 受控/非受控模式切换 |
| 19 | +- 类型安全、事件回调丰富、易于扩展 |
| 20 | +- 代码风格统一,工程化规范 |
| 21 | + |
| 22 | +--- |
| 23 | + |
| 24 | +## API 设计 |
| 25 | + |
| 26 | +### Props |
| 27 | + |
| 28 | +| 属性/Prop | 类型/Type | 说明/Description | |
| 29 | +| --------- | ---------------------------- | --------------------------------------- | |
| 30 | +| data | `TreeNode[]` | 树结构数据,受控模式下由外部管理 | |
| 31 | +| onChange | `(data: TreeNode[]) => void` | 数据变更回调,受控模式下必填 | |
| 32 | +| ... | ... | 其它扩展 props(如 render props、事件) | |
| 33 | + |
| 34 | +### TreeNode 结构 |
| 35 | + |
| 36 | +```ts |
| 37 | +export type TreeNode = { |
| 38 | + key: string |
| 39 | + label: string |
| 40 | + desc?: string |
| 41 | + group?: boolean // 是否为分组节点 |
| 42 | + children: TreeNode[] |
| 43 | +} |
| 44 | +``` |
| 45 | +
|
| 46 | +--- |
| 47 | +
|
| 48 | +## 典型用例 Usage Examples |
| 49 | +
|
| 50 | +### 1. 受控模式 Controlled Mode |
| 51 | +
|
| 52 | +```tsx |
| 53 | +import React, { useState } from 'react' |
| 54 | +import OmiTreeReact, { TreeNode } from 'omi-reactify' |
| 55 | + |
| 56 | +const initialData: TreeNode[] = [ |
| 57 | + { key: '1', label: '节点1', children: [] }, |
| 58 | + { key: '2', label: '节点2', children: [] }, |
| 59 | +] |
| 60 | + |
| 61 | +export default function Demo() { |
| 62 | + const [treeData, setTreeData] = useState<TreeNode[]>(initialData) |
| 63 | + return <OmiTreeReact data={treeData} onChange={setTreeData} /> |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +### 2. 非受控模式 Uncontrolled Mode |
| 68 | + |
| 69 | +```tsx |
| 70 | +<OmiTreeReact data={initialData} /> |
| 71 | +``` |
| 72 | + |
| 73 | +### 3. 批量拖拽、分组、批量属性编辑 |
| 74 | + |
| 75 | +- 按住 Ctrl/Shift 多选节点,拖拽可批量移动,拖拽到空白区自动新建分组。 |
| 76 | +- 多选分组节点时,属性面板支持批量编辑。 |
| 77 | + |
| 78 | +--- |
| 79 | + |
| 80 | +## 事件回调 Event Callbacks |
| 81 | + |
| 82 | +- `onChange(data: TreeNode[])`:数据变更时触发(受控模式下必填) |
| 83 | +- 未来可扩展:`onNodeAdd`、`onNodeDelete`、`onNodeMove`、`onNodeChange` 等 |
| 84 | +
|
| 85 | +--- |
| 86 | +
|
| 87 | +## 扩展点与最佳实践 |
| 88 | +
|
| 89 | +- 支持 render props,自定义节点渲染、属性面板、拖拽手柄等 |
| 90 | +- 支持事件回调扩展,便于业务集成 |
| 91 | +- 代码风格统一,支持 Prettier、ESLint、CI 检查 |
| 92 | +- Undo/Redo、批量操作、分组联动等能力可按需扩展 |
| 93 | +
|
| 94 | +--- |
| 95 | +
|
| 96 | +## 受控/非受控模式说明 |
| 97 | +
|
| 98 | +- 受控模式:由外部传入 `data` 和 `onChange`,所有数据变更由外部管理,适合与全局状态管理集成。 |
| 99 | +- 非受控模式:仅传入 `data`,组件内部自动管理数据和历史栈,适合简单场景。 |
| 100 | +
|
| 101 | +--- |
| 102 | +
|
| 103 | +## 常见问题 FAQ |
| 104 | +
|
| 105 | +- 如何实现批量拖拽/批量删除? |
| 106 | + > 按住 Ctrl/Shift 多选节点后,拖拽或点击“批量删除”按钮即可。 |
| 107 | +- 如何扩展分组节点属性? |
| 108 | + > TreeNode 支持自定义字段,可在属性面板中扩展更多属性。 |
| 109 | +- 如何接入 Undo/Redo? |
| 110 | + > 组件内置历史栈,所有操作都支持撤销/重做。 |
| 111 | +
|
| 112 | +--- |
| 113 | +
|
| 114 | +# OmiTreeReact Component (English) |
| 115 | +
|
| 116 | +## Introduction |
| 117 | +
|
| 118 | +OmiTreeReact is a high-quality, type-safe React tree component based on Omi Web Components, supporting advanced business scenarios such as property editing, nested/batch drag-and-drop, grouping, Undo/Redo, batch operations, group node linkage, controlled/uncontrolled modes, etc. Suitable for low-code platforms, form engines, visual editors, and other complex scenarios. |
| 119 | +
|
| 120 | +## Key Features |
| 121 | +
|
| 122 | +- Property editing, batch property editing (group node linkage) |
| 123 | +- Nested drag-and-drop, batch drag-and-drop, group node drag-and-drop |
| 124 | +- Drag to blank area to create group automatically |
| 125 | +- Batch delete, full Undo/Redo support |
| 126 | +- Controlled/uncontrolled mode switch |
| 127 | +- Type-safe, rich event callbacks, easy to extend |
| 128 | +- Unified code style, engineering specification |
| 129 | +
|
| 130 | +## API Design |
| 131 | +
|
| 132 | +### Props |
| 133 | +
|
| 134 | +| Prop | Type | Description | |
| 135 | +| -------- | ---------------------------- | -------------------------------------------------- | |
| 136 | +| data | `TreeNode[]` | Tree data, managed externally in controlled mode | |
| 137 | +| onChange | `(data: TreeNode[]) => void` | Data change callback, required in controlled mode | |
| 138 | +| ... | ... | Other extension props (render props, events, etc.) | |
| 139 | +
|
| 140 | +### TreeNode Structure |
| 141 | +
|
| 142 | +```ts |
| 143 | +export type TreeNode = { |
| 144 | + key: string |
| 145 | + label: string |
| 146 | + desc?: string |
| 147 | + group?: boolean // Is group node |
| 148 | + children: TreeNode[] |
| 149 | +} |
| 150 | +``` |
| 151 | +
|
| 152 | +## Usage Examples |
| 153 | +
|
| 154 | +### 1. Controlled Mode |
| 155 | +
|
| 156 | +```tsx |
| 157 | +import React, { useState } from 'react' |
| 158 | +import OmiTreeReact, { TreeNode } from 'omi-reactify' |
| 159 | + |
| 160 | +const initialData: TreeNode[] = [ |
| 161 | + { key: '1', label: 'Node 1', children: [] }, |
| 162 | + { key: '2', label: 'Node 2', children: [] }, |
| 163 | +] |
| 164 | + |
| 165 | +export default function Demo() { |
| 166 | + const [treeData, setTreeData] = useState<TreeNode[]>(initialData) |
| 167 | + return <OmiTreeReact data={treeData} onChange={setTreeData} /> |
| 168 | +} |
| 169 | +``` |
| 170 | + |
| 171 | +### 2. Uncontrolled Mode |
| 172 | + |
| 173 | +```tsx |
| 174 | +<OmiTreeReact data={initialData} /> |
| 175 | +``` |
| 176 | + |
| 177 | +### 3. Batch Drag, Group, Batch Property Edit |
| 178 | + |
| 179 | +- Hold Ctrl/Shift to multi-select nodes, drag to batch move, drag to blank area to create group automatically. |
| 180 | +- When multi-selecting group nodes, the property panel supports batch editing. |
| 181 | + |
| 182 | +## Event Callbacks |
| 183 | + |
| 184 | +- `onChange(data: TreeNode[])`: Triggered when data changes (required in controlled mode) |
| 185 | +- Future extensible: `onNodeAdd`, `onNodeDelete`, `onNodeMove`, `onNodeChange`, etc. |
| 186 | +
|
| 187 | +## Extension Points & Best Practices |
| 188 | +
|
| 189 | +- Support render props for custom node rendering, property panel, drag handle, etc. |
| 190 | +- Support event callback extension for business integration |
| 191 | +- Unified code style, Prettier, ESLint, CI support |
| 192 | +- Undo/Redo, batch operation, group linkage can be extended as needed |
| 193 | +
|
| 194 | +## Controlled/Uncontrolled Mode |
| 195 | +
|
| 196 | +- Controlled: Pass in `data` and `onChange`, all data changes managed externally, suitable for integration with global state management. |
| 197 | +- Uncontrolled: Only pass in `data`, component manages data and history stack internally, suitable for simple scenarios. |
| 198 | +
|
| 199 | +## FAQ |
| 200 | +
|
| 201 | +- How to batch drag/delete? |
| 202 | + > Hold Ctrl/Shift to multi-select nodes, then drag or click the "Batch Delete" button. |
| 203 | +- How to extend group node properties? |
| 204 | + > TreeNode supports custom fields, you can extend more properties in the property panel. |
| 205 | +- How to use Undo/Redo? |
| 206 | + > The component has a built-in history stack, all operations support undo/redo. |
| 207 | +
|
| 208 | + |
| 209 | +
|
0 commit comments