@ticatec/uniface-element 0.3.18 → 0.3.19
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 +49 -98
- package/dist/lib/TreeNodes.js +97 -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,33 @@ 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
|
+
set children(value) {
|
|
135
|
+
this._children = value;
|
|
136
|
+
}
|
|
147
137
|
/**
|
|
148
138
|
* 添加子节点
|
|
149
139
|
* @param childItem 子节点数据
|
|
150
140
|
* @returns 新创建的子节点
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* const childNode = parentNode.append({ id: 1, name: "子节点" });
|
|
154
141
|
*/
|
|
155
142
|
append(childItem) {
|
|
156
|
-
|
|
143
|
+
if (Array.isArray(childItem)) {
|
|
144
|
+
let list = [];
|
|
145
|
+
this._children = [];
|
|
146
|
+
childItem.forEach(item => {
|
|
147
|
+
list.push(new TreeNode(item, this.nodes, this));
|
|
148
|
+
});
|
|
149
|
+
return list;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
return new TreeNode(childItem, this.nodes, this);
|
|
153
|
+
}
|
|
157
154
|
}
|
|
158
155
|
/**
|
|
159
156
|
* 从父节点中分离(删除当前节点)
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* node.detach();
|
|
163
157
|
*/
|
|
164
158
|
detach() {
|
|
165
159
|
if (!this.parent) {
|
|
@@ -191,19 +185,13 @@ export class TreeNode {
|
|
|
191
185
|
* 移动到另一个父节点下
|
|
192
186
|
* @param newParent 新的父节点
|
|
193
187
|
* @returns 新创建的节点(注意:返回的是新节点,不是原节点)
|
|
194
|
-
*
|
|
195
|
-
* @example
|
|
196
|
-
* node.moveTo(newParentNode);
|
|
197
188
|
*/
|
|
198
189
|
moveTo(newParent) {
|
|
199
|
-
return new TreeNode(this._item, newParent, this._children);
|
|
190
|
+
return new TreeNode(this._item, this.nodes, newParent, this._children);
|
|
200
191
|
}
|
|
201
192
|
/**
|
|
202
193
|
* 替换当前节点的数据
|
|
203
194
|
* @param newItem 新的数据对象
|
|
204
|
-
*
|
|
205
|
-
* @example
|
|
206
|
-
* node.replace({ id: 1, name: "新名称", ...otherFields });
|
|
207
195
|
*/
|
|
208
196
|
replace(newItem) {
|
|
209
197
|
this._item = newItem;
|
|
@@ -217,9 +205,6 @@ export class TreeNode {
|
|
|
217
205
|
}
|
|
218
206
|
/**
|
|
219
207
|
* 删除所有子节点
|
|
220
|
-
*
|
|
221
|
-
* @example
|
|
222
|
-
* node.removeChildren();
|
|
223
208
|
*/
|
|
224
209
|
removeChildren() {
|
|
225
210
|
this._children = [];
|
|
@@ -267,28 +252,6 @@ export class TreeNode {
|
|
|
267
252
|
* - 节点的映射和查找
|
|
268
253
|
* - 版本管理(用于响应式更新)
|
|
269
254
|
* - 层级展开控制
|
|
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
255
|
*/
|
|
293
256
|
export default class TreeNodes {
|
|
294
257
|
checkIsRoot;
|
|
@@ -326,13 +289,6 @@ export default class TreeNodes {
|
|
|
326
289
|
* 3. 根据 parentKeyField 建立父子关系
|
|
327
290
|
* 4. 应用展开深度设置
|
|
328
291
|
* 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
292
|
*/
|
|
337
293
|
setData(list) {
|
|
338
294
|
this.nodeMap = new Map();
|
|
@@ -340,7 +296,7 @@ export default class TreeNodes {
|
|
|
340
296
|
// 第一遍:创建所有节点(不设置父子关系)
|
|
341
297
|
for (const item of list) {
|
|
342
298
|
const key = item[this.keyField];
|
|
343
|
-
const node = new TreeNode(item); // 创建节点时不设置 parent
|
|
299
|
+
const node = new TreeNode(item, this); // 创建节点时不设置 parent
|
|
344
300
|
this.nodeMap.set(key, node);
|
|
345
301
|
}
|
|
346
302
|
// 第二遍:建立父子关系
|
|
@@ -402,12 +358,19 @@ export default class TreeNodes {
|
|
|
402
358
|
}
|
|
403
359
|
/**
|
|
404
360
|
* 获取展开的展示列表
|
|
361
|
+
* @returns 展开的所有节点(按层级顺序)
|
|
405
362
|
*/
|
|
406
363
|
getHierarchyList() {
|
|
407
364
|
let arr = [];
|
|
408
|
-
this.addExpandNodesToList(this.
|
|
365
|
+
this.addExpandNodesToList(this._nodes, arr);
|
|
409
366
|
return arr;
|
|
410
367
|
}
|
|
368
|
+
/**
|
|
369
|
+
* 将展开的节点添加到列表
|
|
370
|
+
* @param nodes 节点数组
|
|
371
|
+
* @param list 结果列表
|
|
372
|
+
* @private
|
|
373
|
+
*/
|
|
411
374
|
addExpandNodesToList(nodes, list) {
|
|
412
375
|
for (let node of nodes) {
|
|
413
376
|
list.push(node);
|
|
@@ -416,16 +379,6 @@ export default class TreeNodes {
|
|
|
416
379
|
}
|
|
417
380
|
}
|
|
418
381
|
}
|
|
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
382
|
/**
|
|
430
383
|
* 增加一个新节点(便捷方法,会自动根据 parentKeyField 找到父节点)
|
|
431
384
|
* @param item 要添加的节点数据
|
|
@@ -433,7 +386,7 @@ export default class TreeNodes {
|
|
|
433
386
|
append(item) {
|
|
434
387
|
if (parent) {
|
|
435
388
|
if (this.checkIsRoot(item)) {
|
|
436
|
-
let node = new TreeNode(item);
|
|
389
|
+
let node = new TreeNode(item, this);
|
|
437
390
|
this._nodes.push(node);
|
|
438
391
|
this._version++;
|
|
439
392
|
return node;
|
|
@@ -443,9 +396,9 @@ export default class TreeNodes {
|
|
|
443
396
|
}
|
|
444
397
|
}
|
|
445
398
|
else {
|
|
446
|
-
let parent = this.
|
|
399
|
+
let parent = this._findNodeFromList(this.nodes, item, this.parentKeyField);
|
|
447
400
|
if (!parent) {
|
|
448
|
-
let node = new TreeNode(item, parent);
|
|
401
|
+
let node = new TreeNode(item, this, parent);
|
|
449
402
|
this._version++;
|
|
450
403
|
return node;
|
|
451
404
|
}
|
|
@@ -454,18 +407,76 @@ export default class TreeNodes {
|
|
|
454
407
|
}
|
|
455
408
|
}
|
|
456
409
|
}
|
|
457
|
-
|
|
410
|
+
replace(item) {
|
|
411
|
+
let node = this._findNodeFromList(this.nodes, item, this.keyField);
|
|
412
|
+
if (node) {
|
|
413
|
+
node.replace(item);
|
|
414
|
+
this._version++;
|
|
415
|
+
}
|
|
416
|
+
return node;
|
|
417
|
+
}
|
|
418
|
+
remove(item) {
|
|
419
|
+
let node = this._findNodeFromList(this.nodes, item, this.keyField);
|
|
420
|
+
if (node) {
|
|
421
|
+
if (node.parent) {
|
|
422
|
+
node.detach();
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
let pos = this.nodes.indexOf(node);
|
|
426
|
+
if (pos > -1) {
|
|
427
|
+
this.nodes.splice(pos, 1);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
this._version++;
|
|
431
|
+
}
|
|
432
|
+
return node;
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* 从节点列表中查找节点
|
|
436
|
+
* @param nodes 节点数组
|
|
437
|
+
* @param item 要查找的数据项
|
|
438
|
+
* @param matchedKey 匹配的字段名
|
|
439
|
+
* @returns 找到的节点或 null
|
|
440
|
+
* @private
|
|
441
|
+
*/
|
|
442
|
+
_findNodeFromList(nodes, item, matchedKey) {
|
|
458
443
|
let found = null;
|
|
459
444
|
for (const node of nodes) {
|
|
460
445
|
if (!found) {
|
|
461
|
-
if (node.item[this.keyField] == item[
|
|
446
|
+
if (node.item[this.keyField] == item[matchedKey]) {
|
|
462
447
|
found = node;
|
|
463
448
|
}
|
|
464
449
|
else {
|
|
465
|
-
found = node.children && node.children.length > 0 ? this.
|
|
450
|
+
found = node.children && node.children.length > 0 ? this._findNodeFromList(node.children, item, matchedKey) : null;
|
|
466
451
|
}
|
|
467
452
|
}
|
|
468
453
|
}
|
|
469
454
|
return found;
|
|
470
455
|
}
|
|
471
456
|
}
|
|
457
|
+
export class MenuNodes extends TreeNodes {
|
|
458
|
+
/**
|
|
459
|
+
* 删除所有属于分支但没有子节点的节点
|
|
460
|
+
*/
|
|
461
|
+
cleanEmptyDirectories() {
|
|
462
|
+
console.log("原始菜单", this._nodes);
|
|
463
|
+
this._nodes = this._nodes.filter(n => this.pruneEmptyDirs(n) !== null);
|
|
464
|
+
}
|
|
465
|
+
pruneEmptyDirs(node) {
|
|
466
|
+
if (!node)
|
|
467
|
+
return null;
|
|
468
|
+
// 先递归处理子节点
|
|
469
|
+
if (node.children) {
|
|
470
|
+
node.children = node.children
|
|
471
|
+
.map((sn) => this.pruneEmptyDirs(sn))
|
|
472
|
+
.filter((child) => child !== null);
|
|
473
|
+
}
|
|
474
|
+
const isDir = this.checkIsDirectory?.(node);
|
|
475
|
+
const hasNoChildren = !node.children || node.children.length === 0;
|
|
476
|
+
// 如果是目录且没有子节点,则删除该节点
|
|
477
|
+
if (isDir && hasNoChildren) {
|
|
478
|
+
return null;
|
|
479
|
+
}
|
|
480
|
+
return node;
|
|
481
|
+
}
|
|
482
|
+
}
|
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;
|