zmdms-webui 2.2.9 → 2.3.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 (73) hide show
  1. package/dist/es/canvastable/canvasTable.js +367 -0
  2. package/dist/es/canvastable/components/BadgePopover.js +27 -0
  3. package/dist/es/canvastable/components/CanvasTableMenu.js +74 -0
  4. package/dist/es/canvastable/components/CellOverlay.js +49 -0
  5. package/dist/es/canvastable/components/ColumnDynamic.js +12 -0
  6. package/dist/es/canvastable/components/EmptyPlaceholder.js +20 -0
  7. package/dist/es/canvastable/components/FilterPopover.js +274 -0
  8. package/dist/es/canvastable/components/HeaderOverlay.js +22 -0
  9. package/dist/es/canvastable/components/Tooltip.js +27 -0
  10. package/dist/es/canvastable/hooks/useClickOutside.js +30 -0
  11. package/dist/es/canvastable/hooks/useColumnResize.js +130 -0
  12. package/dist/es/canvastable/hooks/useContainerSize.js +40 -0
  13. package/dist/es/canvastable/hooks/useCopyToClipboard.js +150 -0
  14. package/dist/es/canvastable/hooks/useHeaderHeight.js +103 -0
  15. package/dist/es/canvastable/hooks/useMergeCells.js +111 -0
  16. package/dist/es/canvastable/hooks/useOverlays.js +364 -0
  17. package/dist/es/canvastable/hooks/usePopovers.js +93 -0
  18. package/dist/es/canvastable/hooks/useProcessedColumns.js +94 -0
  19. package/dist/es/canvastable/hooks/useScroll.js +251 -0
  20. package/dist/es/canvastable/hooks/useSummaryRow.js +81 -0
  21. package/dist/es/canvastable/hooks/useTableInteraction.js +804 -0
  22. package/dist/es/canvastable/hooks/useTableRender.js +1289 -0
  23. package/dist/es/canvastable/hooks/useTableSelection.js +57 -0
  24. package/dist/es/canvastable/hooks/useTableState.js +218 -0
  25. package/dist/es/canvastable/index.js +5 -0
  26. package/dist/es/canvastable/utils/canvasDrawHelpers.js +156 -0
  27. package/dist/es/canvastable/utils/cellHelpers.js +121 -0
  28. package/dist/es/canvastable/utils/columnHelpers.js +67 -0
  29. package/dist/es/canvastable/utils/constants.js +42 -0
  30. package/dist/es/canvastable/utils/formatHelpers.js +60 -0
  31. package/dist/es/canvastable/utils/interactionHelpers.js +176 -0
  32. package/dist/es/canvastable/utils/multiHeaderHelpers.js +82 -0
  33. package/dist/es/canvastable/utils/tableCalculations.js +100 -0
  34. package/dist/es/form/form.js +1 -0
  35. package/dist/index.dark.css +1 -1
  36. package/dist/index.default.css +1 -1
  37. package/dist/index.es.css +1 -1
  38. package/dist/less/components/CanvasTable/style/index.less +106 -0
  39. package/dist/less/components/Form/style/index.less +6 -1
  40. package/package.json +1 -1
  41. package/dist/es/cascader/index.css +0 -1
  42. package/dist/es/collapse/index.css +0 -1
  43. package/dist/es/container/index.css +0 -1
  44. package/dist/es/datepicker/index.css +0 -1
  45. package/dist/es/descriptions/index.css +0 -1
  46. package/dist/es/detaillist/index.css +0 -1
  47. package/dist/es/differences/index.css +0 -1
  48. package/dist/es/dynamicsetting/index.css +0 -1
  49. package/dist/es/electronsignatures/index.css +0 -1
  50. package/dist/es/footer/index.css +0 -1
  51. package/dist/es/form/index.css +0 -1
  52. package/dist/es/formitem/index.css +0 -1
  53. package/dist/es/input/index.css +0 -1
  54. package/dist/es/inputnumber/index.css +0 -1
  55. package/dist/es/leftcontent/index.css +0 -1
  56. package/dist/es/message/index.css +0 -1
  57. package/dist/es/microloading/index.css +0 -1
  58. package/dist/es/modal/index.css +0 -1
  59. package/dist/es/notauthpage/index.css +0 -0
  60. package/dist/es/notroutepage/index.css +0 -0
  61. package/dist/es/pagination/index.css +0 -1
  62. package/dist/es/placeholder/index.css +0 -1
  63. package/dist/es/print/index.css +0 -1
  64. package/dist/es/select/index.css +0 -1
  65. package/dist/es/table/index.css +0 -1
  66. package/dist/es/tabs/index.css +0 -1
  67. package/dist/es/tag/index.css +0 -1
  68. package/dist/es/title/index.css +0 -1
  69. package/dist/es/tree/index.css +0 -1
  70. package/dist/es/treeselect/index.css +0 -1
  71. package/dist/es/uploadlist/index.css +0 -1
  72. package/dist/es/watermark/index.css +0 -1
  73. package/dist/es/zttransfer/index.css +0 -1
@@ -0,0 +1,274 @@
1
+ import { __assign, __spreadArray } from '../../_virtual/_tslib.js';
2
+ import { jsxs, jsx } from 'react/jsx-runtime';
3
+ import { useState, useEffect, useMemo } from 'react';
4
+ import { Select, Tabs, Space, Input, Button, Checkbox } from 'antd';
5
+
6
+ var Option = Select.Option;
7
+ var FilterPopover = function (_a) {
8
+ var visible = _a.visible; _a.columnKey; _a.columnTitle; var _b = _a.dataType, dataType = _b === void 0 ? "text" : _b, precision = _a.precision, thousand = _a.thousand, position = _a.position, filterOptions = _a.filterOptions, selectedValues = _a.selectedValues, onConfirm = _a.onConfirm, onReset = _a.onReset, onClose = _a.onClose, popoverRef = _a.popoverRef;
9
+ // 临时选中值(点击确认才生效)
10
+ var _c = useState([]), tempSelectedValues = _c[0], setTempSelectedValues = _c[1];
11
+ // 搜索关键词
12
+ var _d = useState(""), searchText = _d[0], setSearchText = _d[1];
13
+ // 数值筛选状态
14
+ var _e = useState("="), numberOperator = _e[0], setNumberOperator = _e[1];
15
+ var _f = useState(""), numberValue = _f[0], setNumberValue = _f[1];
16
+ // 区间筛选状态
17
+ var _g = useState(""), minValue = _g[0], setMinValue = _g[1];
18
+ var _h = useState(""), maxValue = _h[0], setMaxValue = _h[1];
19
+ var _j = useState(">="), minOperator = _j[0], setMinOperator = _j[1];
20
+ var _k = useState("<="), maxOperator = _k[0], setMaxOperator = _k[1];
21
+ // Tabs 激活的标签
22
+ var _l = useState("single"), activeTab = _l[0], setActiveTab = _l[1];
23
+ // 判断是否为数值筛选
24
+ var isNumberFilterValue = function (value) {
25
+ return (value &&
26
+ typeof value === "object" &&
27
+ "operator" in value &&
28
+ "value" in value);
29
+ };
30
+ // 当弹窗打开时,同步外部选中值到临时状态
31
+ useEffect(function () {
32
+ var _a;
33
+ if (visible) {
34
+ // 检查是否为模糊查询
35
+ if (selectedValues.length > 0 && ((_a = selectedValues[0]) === null || _a === void 0 ? void 0 : _a.__fuzzy__) === true) {
36
+ // 恢复之前的搜索文本
37
+ setSearchText(selectedValues[0].text || "");
38
+ setTempSelectedValues([]);
39
+ // 清空数值筛选状态
40
+ setNumberValue("");
41
+ setNumberOperator("=");
42
+ setMinValue("");
43
+ setMaxValue("");
44
+ setMinOperator(">=");
45
+ setMaxOperator("<=");
46
+ setActiveTab("single");
47
+ }
48
+ else if (selectedValues.length > 0 &&
49
+ isNumberFilterValue(selectedValues[0])) {
50
+ // 恢复数值筛选条件
51
+ if (selectedValues.length === 1) {
52
+ // 单值筛选
53
+ var filter = selectedValues[0];
54
+ setNumberValue(String(filter.value));
55
+ setNumberOperator(filter.operator);
56
+ setMinValue("");
57
+ setMaxValue("");
58
+ setActiveTab("single");
59
+ }
60
+ else if (selectedValues.length === 2) {
61
+ // 区间筛选
62
+ var filter1 = selectedValues[0];
63
+ var filter2 = selectedValues[1];
64
+ // 判断哪个是最小值,哪个是最大值
65
+ if (filter1.operator === ">=" || filter1.operator === ">") {
66
+ setMinValue(String(filter1.value));
67
+ setMinOperator(filter1.operator);
68
+ }
69
+ else {
70
+ setMaxValue(String(filter1.value));
71
+ setMaxOperator(filter1.operator);
72
+ }
73
+ if (filter2.operator === ">=" || filter2.operator === ">") {
74
+ setMinValue(String(filter2.value));
75
+ setMinOperator(filter2.operator);
76
+ }
77
+ else {
78
+ setMaxValue(String(filter2.value));
79
+ setMaxOperator(filter2.operator);
80
+ }
81
+ setNumberValue("");
82
+ setNumberOperator("=");
83
+ setActiveTab("range");
84
+ }
85
+ setTempSelectedValues([]);
86
+ setSearchText("");
87
+ }
88
+ else {
89
+ // 精确匹配的筛选
90
+ setTempSelectedValues(selectedValues);
91
+ setSearchText("");
92
+ setNumberValue("");
93
+ setNumberOperator("=");
94
+ setMinValue("");
95
+ setMaxValue("");
96
+ setMinOperator(">=");
97
+ setMaxOperator("<=");
98
+ setActiveTab("single");
99
+ }
100
+ }
101
+ }, [visible, selectedValues]);
102
+ // 根据搜索关键词过滤选项
103
+ var filteredOptions = useMemo(function () {
104
+ if (!searchText)
105
+ return filterOptions;
106
+ var lowerSearchText = searchText.toLowerCase();
107
+ return filterOptions.filter(function (option) {
108
+ return String(option.text).toLowerCase().includes(lowerSearchText);
109
+ });
110
+ }, [filterOptions, searchText]);
111
+ // 全选/取消全选
112
+ var isAllSelected = filteredOptions.length > 0 &&
113
+ filteredOptions.every(function (option) {
114
+ return tempSelectedValues.includes(option.value);
115
+ });
116
+ var isIndeterminate = tempSelectedValues.length > 0 &&
117
+ filteredOptions.some(function (option) {
118
+ return tempSelectedValues.includes(option.value);
119
+ }) &&
120
+ !isAllSelected;
121
+ var handleSelectAll = function () {
122
+ if (isAllSelected) {
123
+ // 取消全选:移除当前筛选结果中的所有值
124
+ var filteredValues_1 = filteredOptions.map(function (o) { return o.value; });
125
+ setTempSelectedValues(tempSelectedValues.filter(function (v) { return !filteredValues_1.includes(v); }));
126
+ }
127
+ else {
128
+ // 全选:添加当前筛选结果中的所有值
129
+ var newValues_1 = __spreadArray([], tempSelectedValues, true);
130
+ filteredOptions.forEach(function (option) {
131
+ if (!newValues_1.includes(option.value)) {
132
+ newValues_1.push(option.value);
133
+ }
134
+ });
135
+ setTempSelectedValues(newValues_1);
136
+ }
137
+ };
138
+ var handleCheckboxChange = function (value) {
139
+ var isSelected = tempSelectedValues.includes(value);
140
+ if (isSelected) {
141
+ setTempSelectedValues(tempSelectedValues.filter(function (v) { return v !== value; }));
142
+ }
143
+ else {
144
+ setTempSelectedValues(__spreadArray(__spreadArray([], tempSelectedValues, true), [value], false));
145
+ }
146
+ };
147
+ // 处理数值筛选
148
+ var handleNumberFilter = function () {
149
+ var filters = [];
150
+ // 区间筛选:如果有最小值或最大值
151
+ if (minValue || maxValue) {
152
+ if (minValue) {
153
+ var min = parseFloat(minValue);
154
+ if (!isNaN(min)) {
155
+ filters.push({
156
+ operator: minOperator,
157
+ value: min,
158
+ });
159
+ }
160
+ }
161
+ if (maxValue) {
162
+ var max = parseFloat(maxValue);
163
+ if (!isNaN(max)) {
164
+ filters.push({
165
+ operator: maxOperator,
166
+ value: max,
167
+ });
168
+ }
169
+ }
170
+ }
171
+ else if (numberValue) {
172
+ // 单值筛选
173
+ var num = parseFloat(numberValue);
174
+ if (!isNaN(num)) {
175
+ filters.push({
176
+ operator: numberOperator,
177
+ value: num,
178
+ });
179
+ }
180
+ }
181
+ if (filters.length === 0)
182
+ return;
183
+ onConfirm(filters);
184
+ onClose();
185
+ };
186
+ var handleConfirm = function () {
187
+ // 如果有搜索文本,使用搜索文本进行模糊查询
188
+ if (searchText.trim()) {
189
+ // 使用特殊标记来表示这是模糊查询
190
+ onConfirm([{ __fuzzy__: true, text: searchText.trim() }]);
191
+ }
192
+ else {
193
+ // 否则使用选中的值
194
+ onConfirm(tempSelectedValues);
195
+ }
196
+ onClose();
197
+ };
198
+ var handleResetAndClose = function () {
199
+ onReset();
200
+ onClose();
201
+ };
202
+ if (!visible)
203
+ return null;
204
+ // 数值类型的筛选界面(根据 precision 或 thousand 判断)
205
+ var isNumberType = precision !== undefined || thousand === true || dataType === "number";
206
+ if (isNumberType) {
207
+ return (jsxs("div", __assign({ ref: popoverRef, className: "canvas-table-filter-popover", style: {
208
+ position: "absolute",
209
+ left: position.x,
210
+ top: position.y,
211
+ zIndex: 1000,
212
+ background: "#fff",
213
+ boxShadow: "0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08)",
214
+ borderRadius: "2px",
215
+ padding: "12px",
216
+ minWidth: "240px",
217
+ } }, { children: [jsx(Tabs, { activeKey: activeTab, onChange: setActiveTab, size: "small", items: [
218
+ {
219
+ key: "single",
220
+ label: "单值",
221
+ children: (jsx("div", { children: jsxs(Space.Compact, __assign({ style: { width: "100%", marginBottom: "12px" } }, { children: [jsxs(Select, __assign({ value: numberOperator, onChange: setNumberOperator, style: { width: "80px" } }, { children: [jsx(Option, __assign({ value: "=" }, { children: "=" })), jsx(Option, __assign({ value: "!=" }, { children: "!=" })), jsx(Option, __assign({ value: ">" }, { children: ">" })), jsx(Option, __assign({ value: "<" }, { children: "<" })), jsx(Option, __assign({ value: ">=" }, { children: ">=" })), jsx(Option, __assign({ value: "<=" }, { children: "<=" }))] })), jsx(Input, { type: "number", placeholder: "\u8F93\u5165\u6570\u503C", value: numberValue, onChange: function (e) { return setNumberValue(e.target.value); }, onPressEnter: handleNumberFilter, style: { flex: 1 } })] })) })),
222
+ },
223
+ {
224
+ key: "range",
225
+ label: "区间",
226
+ children: (jsxs("div", { children: [jsxs("div", __assign({ style: { marginBottom: "8px" } }, { children: [jsx("div", __assign({ style: {
227
+ fontSize: "12px",
228
+ color: "#666",
229
+ marginBottom: "4px",
230
+ } }, { children: "\u6700\u5C0F\u503C\uFF1A" })), jsxs(Space.Compact, __assign({ style: { width: "100%" } }, { children: [jsxs(Select, __assign({ value: minOperator, onChange: setMinOperator, style: { width: "70px" } }, { children: [jsx(Option, __assign({ value: ">=" }, { children: ">=" })), jsx(Option, __assign({ value: ">" }, { children: ">" }))] })), jsx(Input, { type: "number", placeholder: "\u6700\u5C0F\u503C", value: minValue, onChange: function (e) { return setMinValue(e.target.value); }, onPressEnter: handleNumberFilter, style: { flex: 1 } })] }))] })), jsxs("div", __assign({ style: { marginBottom: "12px" } }, { children: [jsx("div", __assign({ style: {
231
+ fontSize: "12px",
232
+ color: "#666",
233
+ marginBottom: "4px",
234
+ } }, { children: "\u6700\u5927\u503C\uFF1A" })), jsxs(Space.Compact, __assign({ style: { width: "100%" } }, { children: [jsxs(Select, __assign({ value: maxOperator, onChange: setMaxOperator, style: { width: "70px" } }, { children: [jsx(Option, __assign({ value: "<=" }, { children: "<=" })), jsx(Option, __assign({ value: "<" }, { children: "<" }))] })), jsx(Input, { type: "number", placeholder: "\u6700\u5927\u503C", value: maxValue, onChange: function (e) { return setMaxValue(e.target.value); }, onPressEnter: handleNumberFilter, style: { flex: 1 } })] }))] })), jsx("div", __assign({ style: { fontSize: "12px", color: "#1890ff" } }, { children: "\u793A\u4F8B\uFF1A\u8BBE\u7F6E >=10 \u548C <=20 \u8868\u793A 10-20 \u4E4B\u95F4" }))] })),
235
+ },
236
+ ] }), jsx("div", __assign({ style: {
237
+ borderTop: "1px solid #f0f0f0",
238
+ paddingTop: "12px",
239
+ marginTop: "12px",
240
+ } }, { children: jsxs(Space, { children: [jsx(Button, __assign({ size: "small", type: "primary", onClick: handleNumberFilter, disabled: !numberValue && !minValue && !maxValue }, { children: "\u786E\u5B9A" })), jsx(Button, __assign({ size: "small", onClick: handleResetAndClose }, { children: "\u91CD\u7F6E" }))] }) }))] })));
241
+ }
242
+ // 文本类型的筛选界面
243
+ return (jsxs("div", __assign({ ref: popoverRef, className: "canvas-table-filter-popover", style: {
244
+ position: "absolute",
245
+ left: position.x,
246
+ top: position.y,
247
+ zIndex: 1000,
248
+ background: "#fff",
249
+ boxShadow: "0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08)",
250
+ borderRadius: "2px",
251
+ padding: "8px",
252
+ minWidth: "200px",
253
+ maxWidth: "300px",
254
+ } }, { children: [jsxs("div", __assign({ style: { padding: "4px 8px", marginBottom: "8px" } }, { children: [jsx(Input, { placeholder: "\u8F93\u5165\u5173\u952E\u8BCD\u6A21\u7CCA\u67E5\u8BE2", value: searchText, onChange: function (e) { return setSearchText(e.target.value); }, allowClear: true, size: "small", onPressEnter: handleConfirm }), searchText && (jsxs("div", __assign({ style: {
255
+ fontSize: "12px",
256
+ color: "#1890ff",
257
+ marginTop: "4px",
258
+ padding: "0 4px",
259
+ } }, { children: ["\u6309\u56DE\u8F66\u6216\u70B9\u51FB\u786E\u5B9A\u4EE5\u6A21\u7CCA\u67E5\u8BE2\"", searchText, "\""] })))] })), jsx("div", __assign({ style: {
260
+ padding: "5px 12px",
261
+ borderBottom: "1px solid #f0f0f0",
262
+ marginBottom: "4px",
263
+ } }, { children: jsx(Checkbox, __assign({ indeterminate: isIndeterminate, checked: isAllSelected, onChange: handleSelectAll }, { children: "\u5168\u9009" })) })), jsx("div", __assign({ style: { maxHeight: "300px", overflowY: "auto" } }, { children: filteredOptions.length > 0 ? (filteredOptions.map(function (filter) { return (jsx("div", __assign({ style: { padding: "5px 12px", cursor: "pointer" }, onClick: function () { return handleCheckboxChange(filter.value); } }, { children: jsx(Checkbox, __assign({ checked: tempSelectedValues.includes(filter.value) }, { children: filter.text })) }), filter.value)); })) : (jsx("div", __assign({ style: {
264
+ padding: "20px",
265
+ textAlign: "center",
266
+ color: "#999",
267
+ } }, { children: "\u6682\u65E0\u5339\u914D\u9879" }))) })), jsx("div", __assign({ style: {
268
+ borderTop: "1px solid #f0f0f0",
269
+ marginTop: "8px",
270
+ paddingTop: "8px",
271
+ } }, { children: jsxs(Space, { children: [jsx(Button, __assign({ size: "small", type: "primary", onClick: handleConfirm }, { children: "\u786E\u5B9A" })), jsx(Button, __assign({ size: "small", onClick: handleResetAndClose }, { children: "\u91CD\u7F6E" }))] }) }))] })));
272
+ };
273
+
274
+ export { FilterPopover as default };
@@ -0,0 +1,22 @@
1
+ import { __assign } from '../../_virtual/_tslib.js';
2
+ import { jsx, Fragment } from 'react/jsx-runtime';
3
+
4
+ var HeaderOverlay = function (_a) {
5
+ var overlays = _a.overlays;
6
+ return (jsx(Fragment, { children: overlays.map(function (overlay) { return (jsx("div", __assign({ className: "canvas-table-header-overlay", style: {
7
+ position: "absolute",
8
+ left: overlay.x,
9
+ top: overlay.y,
10
+ width: overlay.width,
11
+ height: overlay.height,
12
+ pointerEvents: "none",
13
+ display: "flex",
14
+ alignItems: "center",
15
+ paddingLeft: "16px",
16
+ paddingRight: "16px",
17
+ boxSizing: "border-box",
18
+ overflow: "hidden",
19
+ } }, { children: jsx("div", __assign({ style: { pointerEvents: "auto" } }, { children: overlay.content })) }), overlay.columnKey)); }) }));
20
+ };
21
+
22
+ export { HeaderOverlay as default };
@@ -0,0 +1,27 @@
1
+ import { __assign } from '../../_virtual/_tslib.js';
2
+ import { jsx } from 'react/jsx-runtime';
3
+
4
+ var Tooltip = function (_a) {
5
+ var visible = _a.visible, content = _a.content, position = _a.position;
6
+ if (!visible) {
7
+ return null;
8
+ }
9
+ return (jsx("div", __assign({ className: "canvas-table-tooltip", style: {
10
+ position: "fixed",
11
+ left: position.x,
12
+ top: position.y,
13
+ zIndex: 1001,
14
+ background: "rgba(0, 0, 0, 0.85)",
15
+ color: "#fff",
16
+ padding: "8px 12px",
17
+ borderRadius: "4px",
18
+ fontSize: "12px",
19
+ maxWidth: "300px",
20
+ wordBreak: "break-all",
21
+ whiteSpace: "pre-wrap",
22
+ boxShadow: "0 2px 8px rgba(0, 0, 0, 0.15)",
23
+ pointerEvents: "none",
24
+ } }, { children: content })));
25
+ };
26
+
27
+ export { Tooltip as default };
@@ -0,0 +1,30 @@
1
+ import { useEffect } from 'react';
2
+
3
+ /**
4
+ * 点击外部关闭弹窗 Hook
5
+ */
6
+ /**
7
+ * Hook: 点击外部区域时关闭弹窗
8
+ */
9
+ var useClickOutside = function (params) {
10
+ var ref = params.ref, isVisible = params.isVisible, onClose = params.onClose, _a = params.delay, delay = _a === void 0 ? 0 : _a;
11
+ useEffect(function () {
12
+ if (!isVisible)
13
+ return;
14
+ var handleClickOutside = function (e) {
15
+ if (ref.current && !ref.current.contains(e.target)) {
16
+ onClose();
17
+ }
18
+ };
19
+ // 延迟注册监听器,避免捕获到打开弹窗的点击事件
20
+ var timer = setTimeout(function () {
21
+ document.addEventListener("mousedown", handleClickOutside);
22
+ }, delay);
23
+ return function () {
24
+ clearTimeout(timer);
25
+ document.removeEventListener("mousedown", handleClickOutside);
26
+ };
27
+ }, [isVisible, onClose, ref, delay]);
28
+ };
29
+
30
+ export { useClickOutside };
@@ -0,0 +1,130 @@
1
+ import { __assign } from '../../_virtual/_tslib.js';
2
+ import { useState, useRef, useCallback } from 'react';
3
+ import { useMemoizedFn } from 'ahooks';
4
+
5
+ /**
6
+ * 列宽调整 Hook
7
+ * 支持拖拽调整列宽
8
+ */
9
+ var RESIZE_HANDLE_WIDTH = 8; // 调整手柄的宽度
10
+ var useColumnResize = function (params) {
11
+ var columnRenderInfos = params.columnRenderInfos, headerHeight = params.headerHeight, scrollLeft = params.scrollLeft, onColumnResize = params.onColumnResize;
12
+ var _a = useState({
13
+ isResizing: false,
14
+ resizingColumnIndex: null,
15
+ startX: 0,
16
+ startWidth: 0,
17
+ hoverResizeColumnIndex: null,
18
+ }), resizeState = _a[0], setResizeState = _a[1];
19
+ // 临时列宽(拖拽过程中)
20
+ var tempColumnWidthRef = useRef(new Map());
21
+ /**
22
+ * 检测鼠标是否在列调整手柄上
23
+ */
24
+ var checkResizeHandle = useMemoizedFn(function (x, y) {
25
+ // 只在表头区域检测
26
+ if (y >= headerHeight)
27
+ return null;
28
+ for (var i = 0; i < columnRenderInfos.length; i++) {
29
+ var info = columnRenderInfos[i];
30
+ var column = info.column, fixed = info.fixed, fixedLeft = info.fixedLeft, width = info.width;
31
+ // 跳过选择框列
32
+ if (column.key === "__selection__")
33
+ continue;
34
+ var drawX = fixed ? fixedLeft : info.x - scrollLeft;
35
+ var rightEdge = drawX + width;
36
+ // 检测是否在列的右边缘附近
37
+ if (x >= rightEdge - RESIZE_HANDLE_WIDTH / 2 &&
38
+ x <= rightEdge + RESIZE_HANDLE_WIDTH / 2) {
39
+ return i;
40
+ }
41
+ }
42
+ return null;
43
+ });
44
+ /**
45
+ * 开始调整列宽
46
+ */
47
+ var startResize = useMemoizedFn(function (columnIndex, x) {
48
+ var info = columnRenderInfos[columnIndex];
49
+ if (!info)
50
+ return;
51
+ setResizeState({
52
+ isResizing: true,
53
+ resizingColumnIndex: columnIndex,
54
+ startX: x,
55
+ startWidth: info.width,
56
+ hoverResizeColumnIndex: null,
57
+ });
58
+ });
59
+ /**
60
+ * 更新列宽(拖拽中)
61
+ */
62
+ var updateResize = useMemoizedFn(function (x) {
63
+ if (!resizeState.isResizing || resizeState.resizingColumnIndex === null) {
64
+ return;
65
+ }
66
+ var deltaX = x - resizeState.startX;
67
+ var newWidth = Math.max(50, resizeState.startWidth + deltaX); // 最小宽度50
68
+ tempColumnWidthRef.current.set(resizeState.resizingColumnIndex, newWidth);
69
+ // 触发重新渲染
70
+ setResizeState(function (prev) { return (__assign({}, prev)); });
71
+ });
72
+ /**
73
+ * 结束调整列宽
74
+ */
75
+ var endResize = useMemoizedFn(function () {
76
+ if (!resizeState.isResizing || resizeState.resizingColumnIndex === null) {
77
+ return;
78
+ }
79
+ var columnIndex = resizeState.resizingColumnIndex;
80
+ var newWidth = tempColumnWidthRef.current.get(columnIndex);
81
+ if (newWidth && onColumnResize) {
82
+ var info = columnRenderInfos[columnIndex];
83
+ onColumnResize(info.column.key, newWidth);
84
+ }
85
+ tempColumnWidthRef.current.clear();
86
+ setResizeState({
87
+ isResizing: false,
88
+ resizingColumnIndex: null,
89
+ startX: 0,
90
+ startWidth: 0,
91
+ hoverResizeColumnIndex: null,
92
+ });
93
+ });
94
+ /**
95
+ * 设置 hover 状态
96
+ */
97
+ var setHoverResizeColumn = useMemoizedFn(function (columnIndex) {
98
+ if (resizeState.isResizing)
99
+ return; // 拖拽时不更新 hover 状态
100
+ setResizeState(function (prev) {
101
+ if (prev.hoverResizeColumnIndex !== columnIndex) {
102
+ return __assign(__assign({}, prev), { hoverResizeColumnIndex: columnIndex });
103
+ }
104
+ return prev;
105
+ });
106
+ });
107
+ /**
108
+ * 获取列的实际宽度(考虑拖拽中的临时宽度)
109
+ */
110
+ var getColumnWidth = useCallback(function (columnIndex) {
111
+ var _a;
112
+ var tempWidth = tempColumnWidthRef.current.get(columnIndex);
113
+ if (tempWidth !== undefined) {
114
+ return tempWidth;
115
+ }
116
+ return ((_a = columnRenderInfos[columnIndex]) === null || _a === void 0 ? void 0 : _a.width) || 0;
117
+ }, [columnRenderInfos]);
118
+ return {
119
+ resizeState: resizeState,
120
+ checkResizeHandle: checkResizeHandle,
121
+ startResize: startResize,
122
+ updateResize: updateResize,
123
+ endResize: endResize,
124
+ setHoverResizeColumn: setHoverResizeColumn,
125
+ getColumnWidth: getColumnWidth,
126
+ RESIZE_HANDLE_WIDTH: RESIZE_HANDLE_WIDTH,
127
+ };
128
+ };
129
+
130
+ export { useColumnResize };
@@ -0,0 +1,40 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ /**
4
+ * 容器尺寸监听 Hook
5
+ */
6
+ var useContainerSize = function (params) {
7
+ var containerRef = params.containerRef, width = params.width, height = params.height;
8
+ var _a = useState({
9
+ width: width || 800,
10
+ height: height,
11
+ }), containerSize = _a[0], setContainerSize = _a[1];
12
+ useEffect(function () {
13
+ var container = containerRef.current;
14
+ if (!container)
15
+ return;
16
+ var updateSize = function () {
17
+ var newWidth = width || container.clientWidth || 800;
18
+ setContainerSize({
19
+ width: newWidth,
20
+ height: height,
21
+ });
22
+ };
23
+ // 初始化尺寸
24
+ updateSize();
25
+ // 使用 ResizeObserver 监听容器尺寸变化
26
+ var resizeObserver = new ResizeObserver(function () {
27
+ updateSize();
28
+ });
29
+ resizeObserver.observe(container);
30
+ // 监听窗口大小变化(兜底)
31
+ window.addEventListener("resize", updateSize);
32
+ return function () {
33
+ resizeObserver.disconnect();
34
+ window.removeEventListener("resize", updateSize);
35
+ };
36
+ }, [width, height, containerRef]);
37
+ return containerSize;
38
+ };
39
+
40
+ export { useContainerSize };