Skip to content

Commit b692c01

Browse files
authored
Merge pull request #988 from Arreboi06/new1
feat:补充 omi-reactify 封装 omi tree组件实现 react 组件#964
2 parents e217825 + b853b05 commit b692c01

File tree

16 files changed

+2255
-287
lines changed

16 files changed

+2255
-287
lines changed

20250719-1628-44.2776850.mp4

7.96 MB
Binary file not shown.
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"extends": ["eslint:recommended", "plugin:react/recommended", "airbnb-base", "prettier"],
3+
"plugins": ["react"],
4+
"env": {
5+
"browser": true,
6+
"es2021": true
7+
},
8+
"parserOptions": {
9+
"ecmaFeatures": {
10+
"jsx": true
11+
},
12+
"ecmaVersion": 12,
13+
"sourceType": "module"
14+
},
15+
"rules": {
16+
"quotes": [2, "single"],
17+
"semi": [2, "never"],
18+
"comma-dangle": [2, "only-multiline"],
19+
"react/jsx-uses-react": "off",
20+
"react/react-in-jsx-scope": "off"
21+
}
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main, master]
6+
pull_request:
7+
branches: [main, master]
8+
9+
jobs:
10+
build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
- name: Use Node.js
15+
uses: actions/setup-node@v3
16+
with:
17+
node-version: 18
18+
- name: Install dependencies
19+
run: npm install
20+
- name: Lint
21+
run: npx eslint . --ext .ts,.tsx
22+
- name: Prettier
23+
run: npx prettier --check .
24+
- name: Type Check
25+
run: npx tsc --noEmit
26+
- name: Test
27+
run: npm test || true

packages/omi-reactify/.prettierrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"singleQuote": true,
3+
"semi": false,
4+
"trailingComma": "es5",
5+
"printWidth": 100,
6+
"tabWidth": 2
7+
}

packages/omi-reactify/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@ const App = () => {
3737
</OmiReactComponent>
3838
}
3939
```
40+
41+
更多 OmiTreeReact 组件文档请见 [OmiTreeReact.md](./OmiTreeReact.md)
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
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

Comments
 (0)