@ticatec/uniface-element 0.3.18 → 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/COMPONENT_GUIDE.md +441 -0
- package/COMPONENT_GUIDE_CN.md +465 -0
- package/COMPONENT_SELECTION_PROMPTS.md +568 -0
- package/CONTRIBUTING.md +217 -0
- package/README.md +19 -9
- package/dist/attachment-files/README.md +169 -0
- package/dist/attachment-files/README_CN.md +169 -0
- package/dist/color-picker/README.md +184 -0
- package/dist/color-picker/README_CN.md +185 -0
- package/dist/form-field/README.md +193 -0
- package/dist/form-field/README_CN.md +193 -0
- package/dist/form-panel/flex-form/FlexForm.svelte +1 -1
- package/dist/inline-cell-editor/README.md +116 -0
- package/dist/inline-cell-editor/README_CN.md +116 -0
- package/dist/lib/TreeNode_README.md +32 -57
- package/dist/lib/TreeNode_README_CN.md +25 -43
- package/dist/lib/TreeNodes.d.ts +51 -98
- package/dist/lib/TreeNodes.js +100 -86
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.js +2 -0
- package/dist/nav-menu/MenuItem.d.ts +2 -2
- package/dist/navigator/README.md +377 -0
- package/dist/navigator/README_CN.md +377 -0
- package/dist/separator/README.md +105 -0
- package/dist/separator/README_CN.md +105 -0
- package/dist/split/README.md +240 -0
- package/dist/split/README_CN.md +240 -0
- package/dist/tree-view/README.md +48 -36
- package/dist/tree-view/README_CN.md +45 -9
- package/dist/tree-view/TreeNodeView.svelte +2 -5
- package/package.json +16 -9
package/dist/lib/TreeNodes.js
CHANGED
|
@@ -10,12 +10,6 @@ export function compareNumber(a, b) {
|
|
|
10
10
|
/**
|
|
11
11
|
* 节点视图配置类 - 定义节点的显示方式
|
|
12
12
|
* @template T 节点数据的类型
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* const options = new NodeViewOptions<MyData>({
|
|
16
|
-
* keyField: 'id',
|
|
17
|
-
* textField: 'name'
|
|
18
|
-
* });
|
|
19
13
|
*/
|
|
20
14
|
export class NodeViewOptions {
|
|
21
15
|
/**
|
|
@@ -56,8 +50,9 @@ export class NodeViewOptions {
|
|
|
56
50
|
}
|
|
57
51
|
}
|
|
58
52
|
/**
|
|
59
|
-
* TreeNode 类 -
|
|
53
|
+
* TreeNode 类 - 树节点,包含数据和方法(内部类)
|
|
60
54
|
* @template T 节点数据的类型
|
|
55
|
+
* @internal
|
|
61
56
|
*
|
|
62
57
|
* @description
|
|
63
58
|
* TreeNode 是树结构的基本单元,每个节点包含:
|
|
@@ -68,8 +63,10 @@ export class NodeViewOptions {
|
|
|
68
63
|
* - 加载状态(loading)
|
|
69
64
|
*
|
|
70
65
|
* 节点提供了丰富的操作方法,可以直接在节点上进行增删改查操作。
|
|
66
|
+
*
|
|
67
|
+
* 注意:此类为内部实现,外部应使用 ITreeNode 接口
|
|
71
68
|
*/
|
|
72
|
-
|
|
69
|
+
class TreeNode {
|
|
73
70
|
/**
|
|
74
71
|
* 节点数据(私有,只读)
|
|
75
72
|
* @private
|
|
@@ -97,21 +94,17 @@ export class TreeNode {
|
|
|
97
94
|
* @private
|
|
98
95
|
*/
|
|
99
96
|
_children = null;
|
|
97
|
+
nodes;
|
|
100
98
|
/**
|
|
101
99
|
* 创建树节点
|
|
102
100
|
* @param item 节点数据
|
|
101
|
+
* @param nodes
|
|
103
102
|
* @param parent 父节点(可选)
|
|
104
103
|
* @param children 子节点列表(可选)
|
|
105
|
-
*
|
|
106
|
-
* @example
|
|
107
|
-
* // 创建根节点
|
|
108
|
-
* const rootNode = new TreeNode({ id: 1, name: "根节点" });
|
|
109
|
-
*
|
|
110
|
-
* // 创建子节点
|
|
111
|
-
* const childNode = new TreeNode({ id: 2, name: "子节点" }, rootNode);
|
|
112
104
|
*/
|
|
113
|
-
constructor(item, parent = null, children = null) {
|
|
105
|
+
constructor(item, nodes, parent = null, children = null) {
|
|
114
106
|
this._item = item;
|
|
107
|
+
this.nodes = nodes;
|
|
115
108
|
this._level = parent ? parent._level + 1 : 0;
|
|
116
109
|
this.parent = parent;
|
|
117
110
|
this._children = children;
|
|
@@ -134,32 +127,36 @@ export class TreeNode {
|
|
|
134
127
|
/**
|
|
135
128
|
* 获取子节点列表(只读)
|
|
136
129
|
* @returns 子节点数组的浅拷贝,如果没有子节点返回 null
|
|
137
|
-
*
|
|
138
|
-
* @example
|
|
139
|
-
* const children = node.children;
|
|
140
|
-
* if (children) {
|
|
141
|
-
* children.forEach(child => console.log(child.item));
|
|
142
|
-
* }
|
|
143
130
|
*/
|
|
144
131
|
get children() {
|
|
145
132
|
return this._children ? [...this._children] : null;
|
|
146
133
|
}
|
|
134
|
+
sort(compareFn) {
|
|
135
|
+
this._children?.sort((c1, c2) => compareFn(c1.item, c2.item));
|
|
136
|
+
}
|
|
137
|
+
set children(value) {
|
|
138
|
+
this._children = value;
|
|
139
|
+
}
|
|
147
140
|
/**
|
|
148
141
|
* 添加子节点
|
|
149
142
|
* @param childItem 子节点数据
|
|
150
143
|
* @returns 新创建的子节点
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* const childNode = parentNode.append({ id: 1, name: "子节点" });
|
|
154
144
|
*/
|
|
155
145
|
append(childItem) {
|
|
156
|
-
|
|
146
|
+
if (Array.isArray(childItem)) {
|
|
147
|
+
let list = [];
|
|
148
|
+
this._children = [];
|
|
149
|
+
childItem.forEach(item => {
|
|
150
|
+
list.push(new TreeNode(item, this.nodes, this));
|
|
151
|
+
});
|
|
152
|
+
return list;
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
return new TreeNode(childItem, this.nodes, this);
|
|
156
|
+
}
|
|
157
157
|
}
|
|
158
158
|
/**
|
|
159
159
|
* 从父节点中分离(删除当前节点)
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* node.detach();
|
|
163
160
|
*/
|
|
164
161
|
detach() {
|
|
165
162
|
if (!this.parent) {
|
|
@@ -191,19 +188,13 @@ export class TreeNode {
|
|
|
191
188
|
* 移动到另一个父节点下
|
|
192
189
|
* @param newParent 新的父节点
|
|
193
190
|
* @returns 新创建的节点(注意:返回的是新节点,不是原节点)
|
|
194
|
-
*
|
|
195
|
-
* @example
|
|
196
|
-
* node.moveTo(newParentNode);
|
|
197
191
|
*/
|
|
198
192
|
moveTo(newParent) {
|
|
199
|
-
return new TreeNode(this._item, newParent, this._children);
|
|
193
|
+
return new TreeNode(this._item, this.nodes, newParent, this._children);
|
|
200
194
|
}
|
|
201
195
|
/**
|
|
202
196
|
* 替换当前节点的数据
|
|
203
197
|
* @param newItem 新的数据对象
|
|
204
|
-
*
|
|
205
|
-
* @example
|
|
206
|
-
* node.replace({ id: 1, name: "新名称", ...otherFields });
|
|
207
198
|
*/
|
|
208
199
|
replace(newItem) {
|
|
209
200
|
this._item = newItem;
|
|
@@ -217,9 +208,6 @@ export class TreeNode {
|
|
|
217
208
|
}
|
|
218
209
|
/**
|
|
219
210
|
* 删除所有子节点
|
|
220
|
-
*
|
|
221
|
-
* @example
|
|
222
|
-
* node.removeChildren();
|
|
223
211
|
*/
|
|
224
212
|
removeChildren() {
|
|
225
213
|
this._children = [];
|
|
@@ -267,28 +255,6 @@ export class TreeNode {
|
|
|
267
255
|
* - 节点的映射和查找
|
|
268
256
|
* - 版本管理(用于响应式更新)
|
|
269
257
|
* - 层级展开控制
|
|
270
|
-
*
|
|
271
|
-
* @example
|
|
272
|
-
* interface MyData {
|
|
273
|
-
* id: number;
|
|
274
|
-
* name: string;
|
|
275
|
-
* parentId: number | null;
|
|
276
|
-
* }
|
|
277
|
-
*
|
|
278
|
-
* const treeNodes = new TreeNodes<MyData>({
|
|
279
|
-
* keyField: 'id',
|
|
280
|
-
* textField: 'name',
|
|
281
|
-
* parentKeyField: 'parentId',
|
|
282
|
-
* checkIsRoot: (item) => item.parentId === null,
|
|
283
|
-
* checkIsDirectory: (node) => node.children !== null,
|
|
284
|
-
* expendDepth: 2
|
|
285
|
-
* });
|
|
286
|
-
*
|
|
287
|
-
* treeNodes.setData([
|
|
288
|
-
* { id: 1, name: "根节点", parentId: null },
|
|
289
|
-
* { id: 2, name: "子节点1", parentId: 1 },
|
|
290
|
-
* { id: 3, name: "子节点2", parentId: 1 }
|
|
291
|
-
* ]);
|
|
292
258
|
*/
|
|
293
259
|
export default class TreeNodes {
|
|
294
260
|
checkIsRoot;
|
|
@@ -326,13 +292,6 @@ export default class TreeNodes {
|
|
|
326
292
|
* 3. 根据 parentKeyField 建立父子关系
|
|
327
293
|
* 4. 应用展开深度设置
|
|
328
294
|
* 5. 触发版本更新
|
|
329
|
-
*
|
|
330
|
-
* @example
|
|
331
|
-
* treeNodes.setData([
|
|
332
|
-
* { id: 1, name: "根节点", parentId: null },
|
|
333
|
-
* { id: 2, name: "子节点1", parentId: 1 },
|
|
334
|
-
* { id: 3, name: "子节点2", parentId: 1 }
|
|
335
|
-
* ]);
|
|
336
295
|
*/
|
|
337
296
|
setData(list) {
|
|
338
297
|
this.nodeMap = new Map();
|
|
@@ -340,7 +299,7 @@ export default class TreeNodes {
|
|
|
340
299
|
// 第一遍:创建所有节点(不设置父子关系)
|
|
341
300
|
for (const item of list) {
|
|
342
301
|
const key = item[this.keyField];
|
|
343
|
-
const node = new TreeNode(item); // 创建节点时不设置 parent
|
|
302
|
+
const node = new TreeNode(item, this); // 创建节点时不设置 parent
|
|
344
303
|
this.nodeMap.set(key, node);
|
|
345
304
|
}
|
|
346
305
|
// 第二遍:建立父子关系
|
|
@@ -402,12 +361,19 @@ export default class TreeNodes {
|
|
|
402
361
|
}
|
|
403
362
|
/**
|
|
404
363
|
* 获取展开的展示列表
|
|
364
|
+
* @returns 展开的所有节点(按层级顺序)
|
|
405
365
|
*/
|
|
406
366
|
getHierarchyList() {
|
|
407
367
|
let arr = [];
|
|
408
|
-
this.addExpandNodesToList(this.
|
|
368
|
+
this.addExpandNodesToList(this._nodes, arr);
|
|
409
369
|
return arr;
|
|
410
370
|
}
|
|
371
|
+
/**
|
|
372
|
+
* 将展开的节点添加到列表
|
|
373
|
+
* @param nodes 节点数组
|
|
374
|
+
* @param list 结果列表
|
|
375
|
+
* @private
|
|
376
|
+
*/
|
|
411
377
|
addExpandNodesToList(nodes, list) {
|
|
412
378
|
for (let node of nodes) {
|
|
413
379
|
list.push(node);
|
|
@@ -416,16 +382,6 @@ export default class TreeNodes {
|
|
|
416
382
|
}
|
|
417
383
|
}
|
|
418
384
|
}
|
|
419
|
-
/**
|
|
420
|
-
* 不检测匹配情况,在指定的父节点下添加子节点
|
|
421
|
-
*/
|
|
422
|
-
batchAttachToParent(parent, list) {
|
|
423
|
-
let nodes = [];
|
|
424
|
-
for (let item of list) {
|
|
425
|
-
nodes.push(new TreeNode(item, parent));
|
|
426
|
-
}
|
|
427
|
-
return nodes;
|
|
428
|
-
}
|
|
429
385
|
/**
|
|
430
386
|
* 增加一个新节点(便捷方法,会自动根据 parentKeyField 找到父节点)
|
|
431
387
|
* @param item 要添加的节点数据
|
|
@@ -433,7 +389,7 @@ export default class TreeNodes {
|
|
|
433
389
|
append(item) {
|
|
434
390
|
if (parent) {
|
|
435
391
|
if (this.checkIsRoot(item)) {
|
|
436
|
-
let node = new TreeNode(item);
|
|
392
|
+
let node = new TreeNode(item, this);
|
|
437
393
|
this._nodes.push(node);
|
|
438
394
|
this._version++;
|
|
439
395
|
return node;
|
|
@@ -443,9 +399,9 @@ export default class TreeNodes {
|
|
|
443
399
|
}
|
|
444
400
|
}
|
|
445
401
|
else {
|
|
446
|
-
let parent = this.
|
|
402
|
+
let parent = this._findNodeFromList(this.nodes, item, this.parentKeyField);
|
|
447
403
|
if (!parent) {
|
|
448
|
-
let node = new TreeNode(item, parent);
|
|
404
|
+
let node = new TreeNode(item, this, parent);
|
|
449
405
|
this._version++;
|
|
450
406
|
return node;
|
|
451
407
|
}
|
|
@@ -454,18 +410,76 @@ export default class TreeNodes {
|
|
|
454
410
|
}
|
|
455
411
|
}
|
|
456
412
|
}
|
|
457
|
-
|
|
413
|
+
replace(item) {
|
|
414
|
+
let node = this._findNodeFromList(this.nodes, item, this.keyField);
|
|
415
|
+
if (node) {
|
|
416
|
+
node.replace(item);
|
|
417
|
+
this._version++;
|
|
418
|
+
}
|
|
419
|
+
return node;
|
|
420
|
+
}
|
|
421
|
+
remove(item) {
|
|
422
|
+
let node = this._findNodeFromList(this.nodes, item, this.keyField);
|
|
423
|
+
if (node) {
|
|
424
|
+
if (node.parent) {
|
|
425
|
+
node.detach();
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
let pos = this.nodes.indexOf(node);
|
|
429
|
+
if (pos > -1) {
|
|
430
|
+
this.nodes.splice(pos, 1);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
this._version++;
|
|
434
|
+
}
|
|
435
|
+
return node;
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* 从节点列表中查找节点
|
|
439
|
+
* @param nodes 节点数组
|
|
440
|
+
* @param item 要查找的数据项
|
|
441
|
+
* @param matchedKey 匹配的字段名
|
|
442
|
+
* @returns 找到的节点或 null
|
|
443
|
+
* @private
|
|
444
|
+
*/
|
|
445
|
+
_findNodeFromList(nodes, item, matchedKey) {
|
|
458
446
|
let found = null;
|
|
459
447
|
for (const node of nodes) {
|
|
460
448
|
if (!found) {
|
|
461
|
-
if (node.item[this.keyField] == item[
|
|
449
|
+
if (node.item[this.keyField] == item[matchedKey]) {
|
|
462
450
|
found = node;
|
|
463
451
|
}
|
|
464
452
|
else {
|
|
465
|
-
found = node.children && node.children.length > 0 ? this.
|
|
453
|
+
found = node.children && node.children.length > 0 ? this._findNodeFromList(node.children, item, matchedKey) : null;
|
|
466
454
|
}
|
|
467
455
|
}
|
|
468
456
|
}
|
|
469
457
|
return found;
|
|
470
458
|
}
|
|
471
459
|
}
|
|
460
|
+
export class MenuNodes extends TreeNodes {
|
|
461
|
+
/**
|
|
462
|
+
* 删除所有属于分支但没有子节点的节点
|
|
463
|
+
*/
|
|
464
|
+
cleanEmptyDirectories() {
|
|
465
|
+
console.log("原始菜单", this._nodes);
|
|
466
|
+
this._nodes = this._nodes.filter(n => this.pruneEmptyDirs(n) !== null);
|
|
467
|
+
}
|
|
468
|
+
pruneEmptyDirs(node) {
|
|
469
|
+
if (!node)
|
|
470
|
+
return null;
|
|
471
|
+
// 先递归处理子节点
|
|
472
|
+
if (node.children) {
|
|
473
|
+
node.children = node.children
|
|
474
|
+
.map((sn) => this.pruneEmptyDirs(sn))
|
|
475
|
+
.filter((child) => child !== null);
|
|
476
|
+
}
|
|
477
|
+
const isDir = this.checkIsDirectory?.(node);
|
|
478
|
+
const hasNoChildren = !node.children || node.children.length === 0;
|
|
479
|
+
// 如果是目录且没有子节点,则删除该节点
|
|
480
|
+
if (isDir && hasNoChildren) {
|
|
481
|
+
return null;
|
|
482
|
+
}
|
|
483
|
+
return node;
|
|
484
|
+
}
|
|
485
|
+
}
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import TreeNodes from "./TreeNodes";
|
|
2
2
|
import type { ITreeNode } from "./TreeNodes";
|
|
3
3
|
import type { CheckIsRoot, CompareFun, GetText, CheckIsDirectory, TreeNodeOptions } from "./TreeNodes";
|
|
4
|
+
import { MenuNodes } from "./TreeNodes";
|
|
4
5
|
import { compareNumber } from "./TreeNodes";
|
|
5
6
|
export default TreeNodes;
|
|
6
7
|
export { compareNumber };
|
|
8
|
+
export { MenuNodes };
|
|
7
9
|
export type { ITreeNode };
|
|
8
10
|
export type { CheckIsRoot, CompareFun, GetText, CheckIsDirectory, TreeNodeOptions };
|
package/dist/lib/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ITreeNode } from "../lib";
|
|
2
2
|
export default interface MenuItem {
|
|
3
3
|
[key: string]: any;
|
|
4
4
|
}
|
|
5
|
-
export interface MenuNode extends
|
|
5
|
+
export interface MenuNode extends ITreeNode<MenuItem> {
|
|
6
6
|
}
|
|
7
7
|
export type OnMenuClick = (item: MenuItem) => void;
|