@jetlinks-web/components 3.1.15 → 3.2.1

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.
Files changed (57) hide show
  1. package/es/EditTable/CellRender.js +69 -3
  2. package/es/EditTable/EditTable.js +108 -165
  3. package/es/EditTable/FormItem.js +234 -95
  4. package/es/EditTable/consts.js +13 -13
  5. package/es/EditTable/context.js +3 -2
  6. package/es/EditTable/fieldPool.js +166 -0
  7. package/es/EditTable/hooks/index.js +4 -2
  8. package/es/EditTable/hooks/useValidate.js +121 -51
  9. package/es/EditTable/hooks/useVirtualTreeTable.js +111 -0
  10. package/es/EditTable/index.js +0 -4
  11. package/es/EditTable/style/body.js +15 -2
  12. package/es/EditTable/style/form.js +2 -2
  13. package/es/EditTable/style/header.js +2 -2
  14. package/es/EditTable/style/table.js +2 -1
  15. package/es/Icon/icon.js +3 -3
  16. package/es/ProTable/ProTable.js +5 -0
  17. package/es/Search/Advanced/index.js +1 -1
  18. package/es/Search/Item.js +13 -1
  19. package/es/Search/util.js +1 -1
  20. package/es/VirtualTable/Table.js +367 -0
  21. package/es/VirtualTable/VirtualBody.js +94 -0
  22. package/es/VirtualTable/index.js +1 -1
  23. package/es/VirtualTable/useTreeData.js +243 -0
  24. package/es/VirtualTable/useVirtualScroll.js +159 -0
  25. package/lib/EditTable/CellRender.js +69 -3
  26. package/lib/EditTable/EditTable.js +108 -165
  27. package/lib/EditTable/FormItem.js +234 -95
  28. package/lib/EditTable/consts.js +13 -13
  29. package/lib/EditTable/context.js +3 -2
  30. package/lib/EditTable/fieldPool.js +173 -0
  31. package/lib/EditTable/hooks/index.js +15 -2
  32. package/lib/EditTable/hooks/useValidate.js +120 -50
  33. package/lib/EditTable/hooks/useVirtualTreeTable.js +117 -0
  34. package/lib/EditTable/index.js +0 -4
  35. package/lib/EditTable/style/body.js +15 -2
  36. package/lib/EditTable/style/form.js +2 -2
  37. package/lib/EditTable/style/header.js +2 -2
  38. package/lib/EditTable/style/table.js +2 -1
  39. package/lib/Icon/icon.js +3 -3
  40. package/lib/ProTable/ProTable.js +5 -0
  41. package/lib/Search/Advanced/index.js +1 -1
  42. package/lib/Search/Item.js +13 -1
  43. package/lib/Search/util.js +1 -1
  44. package/lib/VirtualTable/Table.js +374 -0
  45. package/lib/VirtualTable/VirtualBody.js +100 -0
  46. package/lib/VirtualTable/index.js +4 -4
  47. package/lib/VirtualTable/useTreeData.js +250 -0
  48. package/lib/VirtualTable/useVirtualScroll.js +165 -0
  49. package/package.json +3 -3
  50. package/es/EditTable/Body.js +0 -312
  51. package/es/EditTable/Header.js +0 -164
  52. package/es/EditTable/HeaderRender.js +0 -12
  53. package/es/VirtualTable/VirtualTable.js +0 -482
  54. package/lib/EditTable/Body.js +0 -312
  55. package/lib/EditTable/Header.js +0 -164
  56. package/lib/EditTable/HeaderRender.js +0 -12
  57. package/lib/VirtualTable/VirtualTable.js +0 -482
@@ -0,0 +1,243 @@
1
+ import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper";
2
+ import { computed, ref, watch, shallowRef } from 'vue';
3
+ /**
4
+ * 树形数据处理 Hook
5
+ * 用于将树形数据扁平化为虚拟滚动可用的列表
6
+ */
7
+ export function useTreeData(options) {
8
+ var data = options.data,
9
+ _options$childrenColu = options.childrenColumnName,
10
+ childrenColumnName = _options$childrenColu === void 0 ? 'children' : _options$childrenColu,
11
+ _options$rowKey = options.rowKey,
12
+ rowKey = _options$rowKey === void 0 ? 'key' : _options$rowKey,
13
+ _options$defaultExpan = options.defaultExpandedRowKeys,
14
+ defaultExpandedRowKeys = _options$defaultExpan === void 0 ? [] : _options$defaultExpan,
15
+ expandedRowKeys = options.expandedRowKeys,
16
+ _options$defaultExpan2 = options.defaultExpandAllRows,
17
+ defaultExpandAllRows = _options$defaultExpan2 === void 0 ? false : _options$defaultExpan2,
18
+ onExpandedRowsChange = options.onExpandedRowsChange;
19
+ // 内部展开状态
20
+ var internalExpandedKeys = ref(new Set(defaultExpandedRowKeys));
21
+ // 实际使用的展开状态 (支持受控和非受控模式)
22
+ var expandedKeys = computed({
23
+ get: function get() {
24
+ if (expandedRowKeys !== null && expandedRowKeys !== void 0 && expandedRowKeys.value) {
25
+ return new Set(expandedRowKeys.value);
26
+ }
27
+ return internalExpandedKeys.value;
28
+ },
29
+ set: function set(val) {
30
+ internalExpandedKeys.value = val;
31
+ onExpandedRowsChange === null || onExpandedRowsChange === void 0 ? void 0 : onExpandedRowsChange(Array.from(val));
32
+ }
33
+ });
34
+ /**
35
+ * 获取行的 key
36
+ */
37
+ var getRowKey = function getRowKey(record, index) {
38
+ if (typeof rowKey === 'function') {
39
+ return rowKey(record);
40
+ }
41
+ var key = record[rowKey];
42
+ if (key !== undefined && key !== null) {
43
+ return key;
44
+ }
45
+ // 如果没有 key,使用索引作为后备
46
+ return index !== undefined ? index : String(record);
47
+ };
48
+ /**
49
+ * 收集所有节点的 key (用于展开全部)
50
+ */
51
+ var collectAllKeys = function collectAllKeys(items) {
52
+ var keys = [];
53
+ var _traverse = function traverse(list) {
54
+ var _iterator = _createForOfIteratorHelper(list),
55
+ _step;
56
+ try {
57
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
58
+ var item = _step.value;
59
+ var key = getRowKey(item);
60
+ var children = item[childrenColumnName];
61
+ if (children && children.length > 0) {
62
+ keys.push(key);
63
+ _traverse(children);
64
+ }
65
+ }
66
+ } catch (err) {
67
+ _iterator.e(err);
68
+ } finally {
69
+ _iterator.f();
70
+ }
71
+ };
72
+ _traverse(items);
73
+ return keys;
74
+ };
75
+ // 初始化:如果设置了 defaultExpandAllRows,则展开所有
76
+ if (defaultExpandAllRows && data.value.length > 0) {
77
+ var allKeys = collectAllKeys(data.value);
78
+ internalExpandedKeys.value = new Set(allKeys);
79
+ }
80
+ /**
81
+ * 构建父子关系映射 (用于 getAncestorKeys)
82
+ */
83
+ var parentMap = shallowRef(new Map());
84
+ /**
85
+ * 扁平化树形数据
86
+ * 只包含当前可见的节点(已展开的节点的子节点)
87
+ */
88
+ var flattenedData = computed(function () {
89
+ var result = [];
90
+ var newParentMap = new Map();
91
+ var flatIndex = 0;
92
+ var _traverse2 = function traverse(items, level, parentKey) {
93
+ for (var i = 0; i < items.length; i++) {
94
+ var item = items[i];
95
+ var key = getRowKey(item, flatIndex);
96
+ var children = item[childrenColumnName];
97
+ var hasChildren = !!(children && children.length > 0);
98
+ var expanded = hasChildren && expandedKeys.value.has(key);
99
+ // 记录父子关系
100
+ newParentMap.set(key, parentKey);
101
+ result.push({
102
+ record: item,
103
+ key: key,
104
+ level: level,
105
+ hasChildren: hasChildren,
106
+ expanded: expanded,
107
+ childrenCount: (children === null || children === void 0 ? void 0 : children.length) || 0,
108
+ parentKey: parentKey,
109
+ flatIndex: flatIndex
110
+ });
111
+ flatIndex++;
112
+ // 如果展开了,递归处理子节点
113
+ if (expanded && children) {
114
+ _traverse2(children, level + 1, key);
115
+ }
116
+ }
117
+ };
118
+ _traverse2(data.value, 0);
119
+ parentMap.value = newParentMap;
120
+ return result;
121
+ });
122
+ /**
123
+ * 所有节点的 Map
124
+ */
125
+ var nodeMap = computed(function () {
126
+ var map = new Map();
127
+ var _iterator2 = _createForOfIteratorHelper(flattenedData.value),
128
+ _step2;
129
+ try {
130
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
131
+ var node = _step2.value;
132
+ map.set(node.key, node);
133
+ }
134
+ } catch (err) {
135
+ _iterator2.e(err);
136
+ } finally {
137
+ _iterator2.f();
138
+ }
139
+ return map;
140
+ });
141
+ /**
142
+ * 展开节点
143
+ */
144
+ var expand = function expand(key) {
145
+ var newSet = new Set(expandedKeys.value);
146
+ newSet.add(key);
147
+ expandedKeys.value = newSet;
148
+ };
149
+ /**
150
+ * 折叠节点
151
+ */
152
+ var collapse = function collapse(key) {
153
+ var newSet = new Set(expandedKeys.value);
154
+ newSet.delete(key);
155
+ expandedKeys.value = newSet;
156
+ };
157
+ /**
158
+ * 切换展开状态
159
+ */
160
+ var toggle = function toggle(key) {
161
+ if (expandedKeys.value.has(key)) {
162
+ collapse(key);
163
+ } else {
164
+ expand(key);
165
+ }
166
+ };
167
+ /**
168
+ * 展开所有
169
+ */
170
+ var expandAll = function expandAll() {
171
+ var allKeys = collectAllKeys(data.value);
172
+ expandedKeys.value = new Set(allKeys);
173
+ };
174
+ /**
175
+ * 折叠所有
176
+ */
177
+ var collapseAll = function collapseAll() {
178
+ expandedKeys.value = new Set();
179
+ };
180
+ /**
181
+ * 判断是否展开
182
+ */
183
+ var isExpanded = function isExpanded(key) {
184
+ return expandedKeys.value.has(key);
185
+ };
186
+ /**
187
+ * 获取节点的所有祖先 keys
188
+ */
189
+ var getAncestorKeys = function getAncestorKeys(key) {
190
+ var ancestors = [];
191
+ var currentKey = key;
192
+ while (currentKey !== undefined) {
193
+ var parentKey = parentMap.value.get(currentKey);
194
+ if (parentKey !== undefined) {
195
+ ancestors.unshift(parentKey);
196
+ }
197
+ currentKey = parentKey;
198
+ }
199
+ return ancestors;
200
+ };
201
+ /**
202
+ * 展开到指定节点 (展开其所有祖先)
203
+ */
204
+ var expandTo = function expandTo(key) {
205
+ var ancestors = getAncestorKeys(key);
206
+ if (ancestors.length > 0) {
207
+ var newSet = new Set(expandedKeys.value);
208
+ var _iterator3 = _createForOfIteratorHelper(ancestors),
209
+ _step3;
210
+ try {
211
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
212
+ var ancestorKey = _step3.value;
213
+ newSet.add(ancestorKey);
214
+ }
215
+ } catch (err) {
216
+ _iterator3.e(err);
217
+ } finally {
218
+ _iterator3.f();
219
+ }
220
+ expandedKeys.value = newSet;
221
+ }
222
+ };
223
+ // 监听外部传入的 expandedRowKeys 变化
224
+ if (expandedRowKeys) {
225
+ watch(expandedRowKeys, function (newKeys) {
226
+ internalExpandedKeys.value = new Set(newKeys);
227
+ });
228
+ }
229
+ return {
230
+ flattenedData: flattenedData,
231
+ nodeMap: nodeMap,
232
+ expandedKeys: internalExpandedKeys,
233
+ expand: expand,
234
+ collapse: collapse,
235
+ toggle: toggle,
236
+ expandAll: expandAll,
237
+ collapseAll: collapseAll,
238
+ getRowKey: getRowKey,
239
+ isExpanded: isExpanded,
240
+ getAncestorKeys: getAncestorKeys,
241
+ expandTo: expandTo
242
+ };
243
+ }
@@ -0,0 +1,159 @@
1
+ import { computed, ref, watch, isRef } from 'vue';
2
+ /**
3
+ * 虚拟滚动 Hook
4
+ */
5
+ export function useVirtualScroll(options) {
6
+ var itemCount = options.itemCount,
7
+ containerHeightOption = options.containerHeight,
8
+ _options$itemHeight = options.itemHeight,
9
+ itemHeight = _options$itemHeight === void 0 ? 54 : _options$itemHeight,
10
+ _options$overscan = options.overscan,
11
+ overscan = _options$overscan === void 0 ? 5 : _options$overscan,
12
+ _options$threshold = options.threshold,
13
+ threshold = _options$threshold === void 0 ? 100 : _options$threshold;
14
+ // 容器高度(支持响应式)
15
+ var containerHeight = computed(function () {
16
+ if (isRef(containerHeightOption)) {
17
+ return containerHeightOption.value;
18
+ }
19
+ return containerHeightOption;
20
+ });
21
+ // 滚动位置
22
+ var scrollTop = ref(0);
23
+ // 动态行高缓存
24
+ var itemHeights = ref(new Map());
25
+ /**
26
+ * 获取指定索引的行高
27
+ */
28
+ var getItemHeight = function getItemHeight(index) {
29
+ // 优先使用缓存的高度
30
+ if (itemHeights.value.has(index)) {
31
+ return itemHeights.value.get(index);
32
+ }
33
+ // 使用配置的高度
34
+ if (typeof itemHeight === 'function') {
35
+ return itemHeight(index);
36
+ }
37
+ return itemHeight;
38
+ };
39
+ /**
40
+ * 设置行高(用于动态测量)
41
+ */
42
+ var setItemHeight = function setItemHeight(index, height) {
43
+ if (height > 0 && itemHeights.value.get(index) !== height) {
44
+ itemHeights.value.set(index, height);
45
+ }
46
+ };
47
+ /**
48
+ * 计算总高度
49
+ */
50
+ var totalHeight = computed(function () {
51
+ var total = 0;
52
+ for (var i = 0; i < itemCount.value; i++) {
53
+ total += getItemHeight(i);
54
+ }
55
+ return total;
56
+ });
57
+ /**
58
+ * 计算可视范围的起始索引
59
+ */
60
+ var startIndex = computed(function () {
61
+ if (itemCount.value < threshold) {
62
+ return 0;
63
+ }
64
+ var accumulated = 0;
65
+ for (var i = 0; i < itemCount.value; i++) {
66
+ var height = getItemHeight(i);
67
+ if (accumulated + height > scrollTop.value) {
68
+ return Math.max(0, i - overscan);
69
+ }
70
+ accumulated += height;
71
+ }
72
+ return 0;
73
+ });
74
+ /**
75
+ * 计算可视范围的结束索引
76
+ */
77
+ var endIndex = computed(function () {
78
+ if (itemCount.value < threshold) {
79
+ return itemCount.value;
80
+ }
81
+ var start = startIndex.value;
82
+ var accumulated = 0;
83
+ // 从起始索引开始累加
84
+ for (var i = 0; i < start; i++) {
85
+ accumulated += getItemHeight(i);
86
+ }
87
+ for (var _i = start; _i < itemCount.value; _i++) {
88
+ accumulated += getItemHeight(_i);
89
+ if (accumulated > scrollTop.value + containerHeight.value) {
90
+ return Math.min(itemCount.value, _i + 1 + overscan);
91
+ }
92
+ }
93
+ return itemCount.value;
94
+ });
95
+ /**
96
+ * 顶部偏移量
97
+ */
98
+ var offsetY = computed(function () {
99
+ var offset = 0;
100
+ for (var i = 0; i < startIndex.value; i++) {
101
+ offset += getItemHeight(i);
102
+ }
103
+ return offset;
104
+ });
105
+ /**
106
+ * 可见行数
107
+ */
108
+ var visibleCount = computed(function () {
109
+ return endIndex.value - startIndex.value;
110
+ });
111
+ /**
112
+ * 处理滚动事件
113
+ */
114
+ var handleScroll = function handleScroll(e) {
115
+ var target = e.target;
116
+ if (target) {
117
+ scrollTop.value = target.scrollTop;
118
+ }
119
+ };
120
+ /**
121
+ * 滚动到指定位置
122
+ */
123
+ var scrollTo = function scrollTo(offset) {
124
+ scrollTop.value = Math.max(0, Math.min(offset, totalHeight.value - containerHeight.value));
125
+ };
126
+ /**
127
+ * 滚动到指定索引
128
+ */
129
+ var scrollToIndex = function scrollToIndex(index) {
130
+ if (index < 0 || index >= itemCount.value) {
131
+ return;
132
+ }
133
+ var offset = 0;
134
+ for (var i = 0; i < index; i++) {
135
+ offset += getItemHeight(i);
136
+ }
137
+ scrollTo(offset);
138
+ };
139
+ // 数据变化时重置滚动位置
140
+ watch(itemCount, function () {
141
+ var maxScroll = Math.max(0, totalHeight.value - containerHeight.value);
142
+ if (scrollTop.value > maxScroll) {
143
+ scrollTop.value = maxScroll;
144
+ }
145
+ });
146
+ return {
147
+ startIndex: startIndex,
148
+ endIndex: endIndex,
149
+ offsetY: offsetY,
150
+ totalHeight: totalHeight,
151
+ visibleCount: visibleCount,
152
+ scrollTop: scrollTop,
153
+ scrollTo: scrollTo,
154
+ scrollToIndex: scrollToIndex,
155
+ handleScroll: handleScroll,
156
+ getItemHeight: getItemHeight,
157
+ setItemHeight: setItemHeight
158
+ };
159
+ }
@@ -1,11 +1,77 @@
1
+ function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) {
2
+ const op = ops[i];
3
+ const fn = ops[i + 1];
4
+ i += 2;
5
+ if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) {
6
+ return undefined;
7
+ }
8
+ if (op === 'access' || op === 'optionalAccess') {
9
+ lastAccessLHS = value;
10
+ value = fn(value);
11
+ }
12
+ else if (op === 'call' || op === 'optionalCall') {
13
+ value = fn((...args) => value.call(lastAccessLHS, ...args));
14
+ lastAccessLHS = undefined;
15
+ }
16
+ } return value; }
1
17
  /* Analyzed bindings: {} */
2
- import { defineComponent } from 'vue';
18
+ import { defineComponent, h, shallowRef, } from 'vue';
19
+ /**
20
+ * CellRender - 优化的单元格渲染组件
21
+ * 使用 shallowRef 和手动更新检查来避免不必要的重渲染
22
+ */
3
23
  const __sfc_main__ = defineComponent({
4
24
  name: "CellRender",
5
- props: ['renderFn', 'value', 'record', 'index'],
25
+ props: {
26
+ renderFn: {
27
+ type: Function,
28
+ required: true
29
+ },
30
+ value: null,
31
+ record: {
32
+ type: Object,
33
+ required: true
34
+ },
35
+ index: {
36
+ type: Number,
37
+ required: true
38
+ }
39
+ },
6
40
  setup(props) {
41
+ // 使用 shallowRef 避免深度响应式
42
+ const cachedResult = shallowRef(null);
43
+ const lastValue = shallowRef(undefined);
44
+ const lastRecordId = shallowRef(undefined);
45
+ // 手动检查是否需要重新渲染
46
+ const shouldUpdate = () => {
47
+ // 检查 value 是否变化
48
+ if (props.value !== lastValue.value) {
49
+ return true;
50
+ }
51
+ // 检查 record 的关键属性是否变化(假设有 id 或 key)
52
+ const currentRecordId = _optionalChain([(props.record), 'optionalAccess', _ => _.id]) || _optionalChain([(props.record), 'optionalAccess', _2 => _2.key]);
53
+ if (currentRecordId !== lastRecordId.value) {
54
+ return true;
55
+ }
56
+ return false;
57
+ };
58
+ // 执行渲染函数
59
+ const render = () => {
60
+ if (shouldUpdate() || cachedResult.value === null) {
61
+ lastValue.value = props.value;
62
+ lastRecordId.value = _optionalChain([(props.record), 'optionalAccess', _3 => _3.id]) || _optionalChain([(props.record), 'optionalAccess', _4 => _4.key]);
63
+ try {
64
+ cachedResult.value = props.renderFn(props.value, props.record, props.index);
65
+ }
66
+ catch (error) {
67
+ console.error('[CellRender] Render error:', error);
68
+ cachedResult.value = null;
69
+ }
70
+ }
71
+ return cachedResult.value;
72
+ };
7
73
  return () => {
8
- return props.renderFn(props.value, props.record, props.index);
74
+ return h('div', { class: 'cell-render-wrapper' }, [render()]);
9
75
  };
10
76
  }
11
77
  });