resizable-pro-table 1.0.0 → 1.1.0
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/README.md +46 -17
- package/dist/index.d.mts +44 -8
- package/dist/index.d.ts +44 -8
- package/dist/index.js +79 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +73 -16
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# resizable-pro-table
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
为 Ant Design [ProTable](https://procomponents.ant.design/components/table) 和原生 [Table](https://ant.design/components/table) 提供可拖拽调整列宽能力的组件库。
|
|
4
4
|
|
|
5
5
|
## 依赖
|
|
6
6
|
|
|
7
7
|
- React 17+
|
|
8
|
-
- antd
|
|
8
|
+
- antd 4+
|
|
9
9
|
- @ant-design/pro-components 2+
|
|
10
10
|
|
|
11
11
|
## 安装
|
|
@@ -20,35 +20,64 @@ pnpm add resizable-pro-table
|
|
|
20
20
|
|
|
21
21
|
## 使用
|
|
22
22
|
|
|
23
|
+
### ResizableProTable(ProTable 版)
|
|
24
|
+
|
|
23
25
|
```tsx
|
|
24
26
|
import ResizableProTable from 'resizable-pro-table';
|
|
25
|
-
import 'resizable-pro-table/dist/style.css';
|
|
26
27
|
|
|
27
28
|
<ResizableProTable<YourDataType>
|
|
28
29
|
columns={columns}
|
|
29
30
|
request={async () => ({ data: [], success: true })}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
resizableConfig={{
|
|
32
|
+
persistenceKey: 'my-table-columns',
|
|
33
|
+
minWidth: 60,
|
|
34
|
+
maxWidth: 400,
|
|
35
|
+
defaultWidth: 120,
|
|
36
|
+
}}
|
|
33
37
|
/>
|
|
34
38
|
```
|
|
35
39
|
|
|
36
|
-
###
|
|
40
|
+
### ResizableTable(antd 原生 Table 版)
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
```tsx
|
|
43
|
+
import { ResizableTable } from 'resizable-pro-table';
|
|
44
|
+
|
|
45
|
+
<ResizableTable<YourDataType>
|
|
46
|
+
columns={columns}
|
|
47
|
+
dataSource={data}
|
|
48
|
+
resizableConfig={{
|
|
49
|
+
minWidth: 60,
|
|
50
|
+
maxWidth: 400,
|
|
51
|
+
}}
|
|
52
|
+
/>
|
|
53
|
+
```
|
|
43
54
|
|
|
44
|
-
|
|
55
|
+
### useResizableColumns(自定义集成)
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
57
|
+
如需集成到自己的表格组件,可直接使用底层 Hook:
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import { useResizableColumns } from 'resizable-pro-table';
|
|
61
|
+
|
|
62
|
+
const { mergedColumns, components } = useResizableColumns(columns, {
|
|
63
|
+
minWidth: 80,
|
|
64
|
+
maxWidth: 300,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
<Table columns={mergedColumns} components={components} dataSource={data} />
|
|
50
68
|
```
|
|
51
69
|
|
|
70
|
+
## resizableConfig
|
|
71
|
+
|
|
72
|
+
所有组件均通过 `resizableConfig` 属性统一配置拖拽行为:
|
|
73
|
+
|
|
74
|
+
| 字段 | 说明 | 类型 | 默认值 |
|
|
75
|
+
|------|------|------|--------|
|
|
76
|
+
| `persistenceKey` | 用于在 localStorage 持久化列宽的 key,不传则不持久化 | `string` | - |
|
|
77
|
+
| `minWidth` | 列最小宽度(px) | `number` | `60` |
|
|
78
|
+
| `maxWidth` | 列最大宽度(px),不传则不限制 | `number` | - |
|
|
79
|
+
| `defaultWidth` | 未设置 `width` 的列的默认初始宽度(px) | `number` | `120` |
|
|
80
|
+
|
|
52
81
|
## License
|
|
53
82
|
|
|
54
83
|
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -1,14 +1,50 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ProTableProps } from '@ant-design/pro-components';
|
|
2
|
+
import { ProTableProps, ProColumns } from '@ant-design/pro-components';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { TableProps, ColumnType } from 'antd/es/table';
|
|
5
|
+
|
|
6
|
+
type ColumnWidthMap = Record<string, number>;
|
|
7
|
+
interface ResizableConfig {
|
|
8
|
+
/** localStorage key,用于跨刷新持久化列宽 */
|
|
9
|
+
persistenceKey?: string;
|
|
10
|
+
/** 拖拽最小列宽(px),默认 60 */
|
|
11
|
+
minWidth?: number;
|
|
12
|
+
/** 拖拽最大列宽(px),无默认值表示不限制 */
|
|
13
|
+
maxWidth?: number;
|
|
14
|
+
/** 无 width 列的默认初始宽度(px),默认 120 */
|
|
15
|
+
defaultWidth?: number;
|
|
16
|
+
}
|
|
17
|
+
interface ResizableTitleProps extends React.ThHTMLAttributes<HTMLTableCellElement> {
|
|
18
|
+
onResizeEnd?: (width: number) => void;
|
|
19
|
+
width?: number;
|
|
20
|
+
minWidth?: number;
|
|
21
|
+
maxWidth?: number;
|
|
22
|
+
}
|
|
3
23
|
|
|
4
24
|
interface ResizableProTableProps<T extends Record<string, any>> extends Omit<ProTableProps<T, any>, 'components'> {
|
|
5
|
-
|
|
6
|
-
columnWidthPersistenceKey?: string;
|
|
7
|
-
/** Minimum column width in pixels (default: 60) */
|
|
8
|
-
minColumnWidth?: number;
|
|
9
|
-
/** Default width for columns without width (default: 120), used for drag handle */
|
|
10
|
-
defaultColumnWidth?: number;
|
|
25
|
+
resizableConfig?: ResizableConfig;
|
|
11
26
|
}
|
|
12
27
|
declare function ResizableProTable<T extends Record<string, any>>(props: ResizableProTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
13
28
|
|
|
14
|
-
|
|
29
|
+
interface ResizableTableProps<T extends object> extends Omit<TableProps<T>, 'components'> {
|
|
30
|
+
resizableConfig?: ResizableConfig;
|
|
31
|
+
}
|
|
32
|
+
declare function ResizableTable<T extends object>(props: ResizableTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
33
|
+
|
|
34
|
+
declare const ResizableTitle: React.FC<ResizableTitleProps>;
|
|
35
|
+
|
|
36
|
+
type Components = {
|
|
37
|
+
header: {
|
|
38
|
+
cell: typeof ResizableTitle;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
declare function useResizableColumns<T>(columns: ProColumns<T>[], resizableConfig?: ResizableConfig): {
|
|
42
|
+
mergedColumns: ProColumns<T>[];
|
|
43
|
+
components: Components;
|
|
44
|
+
};
|
|
45
|
+
declare function useResizableColumns<T>(columns: ColumnType<T>[], resizableConfig?: ResizableConfig): {
|
|
46
|
+
mergedColumns: ColumnType<T>[];
|
|
47
|
+
components: Components;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { type ColumnWidthMap, type ResizableConfig, ResizableProTable, type ResizableProTableProps, ResizableTable, type ResizableTableProps, type ResizableTitleProps, ResizableProTable as default, useResizableColumns };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,50 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ProTableProps } from '@ant-design/pro-components';
|
|
2
|
+
import { ProTableProps, ProColumns } from '@ant-design/pro-components';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { TableProps, ColumnType } from 'antd/es/table';
|
|
5
|
+
|
|
6
|
+
type ColumnWidthMap = Record<string, number>;
|
|
7
|
+
interface ResizableConfig {
|
|
8
|
+
/** localStorage key,用于跨刷新持久化列宽 */
|
|
9
|
+
persistenceKey?: string;
|
|
10
|
+
/** 拖拽最小列宽(px),默认 60 */
|
|
11
|
+
minWidth?: number;
|
|
12
|
+
/** 拖拽最大列宽(px),无默认值表示不限制 */
|
|
13
|
+
maxWidth?: number;
|
|
14
|
+
/** 无 width 列的默认初始宽度(px),默认 120 */
|
|
15
|
+
defaultWidth?: number;
|
|
16
|
+
}
|
|
17
|
+
interface ResizableTitleProps extends React.ThHTMLAttributes<HTMLTableCellElement> {
|
|
18
|
+
onResizeEnd?: (width: number) => void;
|
|
19
|
+
width?: number;
|
|
20
|
+
minWidth?: number;
|
|
21
|
+
maxWidth?: number;
|
|
22
|
+
}
|
|
3
23
|
|
|
4
24
|
interface ResizableProTableProps<T extends Record<string, any>> extends Omit<ProTableProps<T, any>, 'components'> {
|
|
5
|
-
|
|
6
|
-
columnWidthPersistenceKey?: string;
|
|
7
|
-
/** Minimum column width in pixels (default: 60) */
|
|
8
|
-
minColumnWidth?: number;
|
|
9
|
-
/** Default width for columns without width (default: 120), used for drag handle */
|
|
10
|
-
defaultColumnWidth?: number;
|
|
25
|
+
resizableConfig?: ResizableConfig;
|
|
11
26
|
}
|
|
12
27
|
declare function ResizableProTable<T extends Record<string, any>>(props: ResizableProTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
13
28
|
|
|
14
|
-
|
|
29
|
+
interface ResizableTableProps<T extends object> extends Omit<TableProps<T>, 'components'> {
|
|
30
|
+
resizableConfig?: ResizableConfig;
|
|
31
|
+
}
|
|
32
|
+
declare function ResizableTable<T extends object>(props: ResizableTableProps<T>): react_jsx_runtime.JSX.Element;
|
|
33
|
+
|
|
34
|
+
declare const ResizableTitle: React.FC<ResizableTitleProps>;
|
|
35
|
+
|
|
36
|
+
type Components = {
|
|
37
|
+
header: {
|
|
38
|
+
cell: typeof ResizableTitle;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
declare function useResizableColumns<T>(columns: ProColumns<T>[], resizableConfig?: ResizableConfig): {
|
|
42
|
+
mergedColumns: ProColumns<T>[];
|
|
43
|
+
components: Components;
|
|
44
|
+
};
|
|
45
|
+
declare function useResizableColumns<T>(columns: ColumnType<T>[], resizableConfig?: ResizableConfig): {
|
|
46
|
+
mergedColumns: ColumnType<T>[];
|
|
47
|
+
components: Components;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { type ColumnWidthMap, type ResizableConfig, ResizableProTable, type ResizableProTableProps, ResizableTable, type ResizableTableProps, type ResizableTitleProps, ResizableProTable as default, useResizableColumns };
|
package/dist/index.js
CHANGED
|
@@ -20,10 +20,38 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
-
|
|
23
|
+
ResizableProTable: () => ResizableProTable_default,
|
|
24
|
+
ResizableTable: () => ResizableTable_default,
|
|
25
|
+
default: () => ResizableProTable_default,
|
|
26
|
+
useResizableColumns: () => useResizableColumns_default
|
|
24
27
|
});
|
|
25
28
|
module.exports = __toCommonJS(index_exports);
|
|
26
29
|
|
|
30
|
+
// #style-inject:#style-inject
|
|
31
|
+
function styleInject(css, { insertAt } = {}) {
|
|
32
|
+
if (!css || typeof document === "undefined") return;
|
|
33
|
+
const head = document.head || document.getElementsByTagName("head")[0];
|
|
34
|
+
const style = document.createElement("style");
|
|
35
|
+
style.type = "text/css";
|
|
36
|
+
if (insertAt === "top") {
|
|
37
|
+
if (head.firstChild) {
|
|
38
|
+
head.insertBefore(style, head.firstChild);
|
|
39
|
+
} else {
|
|
40
|
+
head.appendChild(style);
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
head.appendChild(style);
|
|
44
|
+
}
|
|
45
|
+
if (style.styleSheet) {
|
|
46
|
+
style.styleSheet.cssText = css;
|
|
47
|
+
} else {
|
|
48
|
+
style.appendChild(document.createTextNode(css));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// src/style.css
|
|
53
|
+
styleInject('.ant-table-thead > tr > th {\n position: relative;\n overflow: visible !important;\n}\n.ant-table-wrapper .ant-table-thead,\n.ant-table .ant-table-thead {\n overflow: visible !important;\n}\n.resizable-handle {\n position: absolute;\n right: -6px;\n top: 0;\n bottom: 0;\n width: 12px;\n cursor: col-resize;\n z-index: 10;\n pointer-events: auto;\n}\n.resizable-handle::after {\n content: "";\n position: absolute;\n left: 5px;\n top: 15%;\n height: 70%;\n width: 2px;\n background: rgba(0, 0, 0, 0.08);\n transition: background 0.2s;\n}\n.resizable-handle:hover::after {\n background: #1677ff;\n}\n.resizable-handle--active::after {\n background: #1677ff;\n}\n');
|
|
54
|
+
|
|
27
55
|
// src/ResizableProTable.tsx
|
|
28
56
|
var import_pro_components = require("@ant-design/pro-components");
|
|
29
57
|
|
|
@@ -53,10 +81,12 @@ var ResizableTitle = ({
|
|
|
53
81
|
onResizeEnd,
|
|
54
82
|
width,
|
|
55
83
|
minWidth = 60,
|
|
84
|
+
maxWidth,
|
|
56
85
|
children,
|
|
57
86
|
...restProps
|
|
58
87
|
}) => {
|
|
59
88
|
const thRef = (0, import_react.useRef)(null);
|
|
89
|
+
const handleRef = (0, import_react.useRef)(null);
|
|
60
90
|
const widthRef = (0, import_react.useRef)(0);
|
|
61
91
|
const handleMouseDown = (0, import_react.useCallback)(
|
|
62
92
|
(e) => {
|
|
@@ -64,12 +94,17 @@ var ResizableTitle = ({
|
|
|
64
94
|
e.stopPropagation();
|
|
65
95
|
const th = thRef.current;
|
|
66
96
|
if (!th) return;
|
|
97
|
+
const handle = handleRef.current;
|
|
67
98
|
const startX = e.clientX;
|
|
68
99
|
const startWidth = th.getBoundingClientRect().width;
|
|
69
100
|
const cols = findCorrespondingCols(th);
|
|
70
101
|
widthRef.current = startWidth;
|
|
71
102
|
const onMouseMove = (ev) => {
|
|
72
|
-
const
|
|
103
|
+
const rawWidth = startWidth + (ev.clientX - startX);
|
|
104
|
+
const newWidth = Math.max(
|
|
105
|
+
minWidth,
|
|
106
|
+
maxWidth !== void 0 ? Math.min(maxWidth, rawWidth) : rawWidth
|
|
107
|
+
);
|
|
73
108
|
th.style.width = `${newWidth}px`;
|
|
74
109
|
cols.forEach((col) => {
|
|
75
110
|
col.style.width = `${newWidth}px`;
|
|
@@ -82,7 +117,7 @@ var ResizableTitle = ({
|
|
|
82
117
|
document.removeEventListener("mouseup", onMouseUp);
|
|
83
118
|
document.body.style.userSelect = "";
|
|
84
119
|
document.body.style.cursor = "";
|
|
85
|
-
|
|
120
|
+
handle?.classList.remove("resizable-handle--active");
|
|
86
121
|
onResizeEnd?.(widthRef.current);
|
|
87
122
|
const suppressClick = (ev) => {
|
|
88
123
|
ev.stopPropagation();
|
|
@@ -95,11 +130,11 @@ var ResizableTitle = ({
|
|
|
95
130
|
};
|
|
96
131
|
document.body.style.userSelect = "none";
|
|
97
132
|
document.body.style.cursor = "col-resize";
|
|
98
|
-
|
|
133
|
+
handle?.classList.add("resizable-handle--active");
|
|
99
134
|
document.addEventListener("mousemove", onMouseMove);
|
|
100
135
|
document.addEventListener("mouseup", onMouseUp);
|
|
101
136
|
},
|
|
102
|
-
[minWidth, onResizeEnd]
|
|
137
|
+
[minWidth, maxWidth, onResizeEnd]
|
|
103
138
|
);
|
|
104
139
|
if (!width || !onResizeEnd) {
|
|
105
140
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { ...restProps, children });
|
|
@@ -115,6 +150,7 @@ var ResizableTitle = ({
|
|
|
115
150
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
116
151
|
"span",
|
|
117
152
|
{
|
|
153
|
+
ref: handleRef,
|
|
118
154
|
className: "resizable-handle",
|
|
119
155
|
style: {
|
|
120
156
|
position: "absolute",
|
|
@@ -162,15 +198,15 @@ function safeWriteStorage(key, value) {
|
|
|
162
198
|
} catch {
|
|
163
199
|
}
|
|
164
200
|
}
|
|
165
|
-
function useResizableColumns(columns,
|
|
166
|
-
const {
|
|
201
|
+
function useResizableColumns(columns, resizableConfig) {
|
|
202
|
+
const { persistenceKey, minWidth, maxWidth, defaultWidth = 120 } = resizableConfig ?? {};
|
|
167
203
|
const [columnWidths, setColumnWidths] = (0, import_react2.useState)(
|
|
168
|
-
() =>
|
|
204
|
+
() => persistenceKey ? safeReadStorage(persistenceKey) : {}
|
|
169
205
|
);
|
|
170
206
|
const mergedColumns = (0, import_react2.useMemo)(
|
|
171
207
|
() => columns.map((col) => {
|
|
172
208
|
const colKey = getColumnKey(col);
|
|
173
|
-
const effectiveWidth = colKey !== void 0 ? columnWidths[colKey] ?? col.width ??
|
|
209
|
+
const effectiveWidth = colKey !== void 0 ? columnWidths[colKey] ?? col.width ?? defaultWidth : col.width;
|
|
174
210
|
if (colKey === void 0) {
|
|
175
211
|
return col;
|
|
176
212
|
}
|
|
@@ -179,13 +215,14 @@ function useResizableColumns(columns, options) {
|
|
|
179
215
|
width: effectiveWidth,
|
|
180
216
|
onHeaderCell: () => ({
|
|
181
217
|
width: effectiveWidth,
|
|
182
|
-
minWidth
|
|
183
|
-
|
|
218
|
+
minWidth,
|
|
219
|
+
maxWidth,
|
|
220
|
+
style: { width: effectiveWidth, minWidth: minWidth ?? 60 },
|
|
184
221
|
onResizeEnd: (finalWidth) => {
|
|
185
222
|
setColumnWidths((prev) => {
|
|
186
223
|
const next = { ...prev, [colKey]: finalWidth };
|
|
187
|
-
if (
|
|
188
|
-
safeWriteStorage(
|
|
224
|
+
if (persistenceKey) {
|
|
225
|
+
safeWriteStorage(persistenceKey, next);
|
|
189
226
|
}
|
|
190
227
|
return next;
|
|
191
228
|
});
|
|
@@ -193,7 +230,7 @@ function useResizableColumns(columns, options) {
|
|
|
193
230
|
})
|
|
194
231
|
};
|
|
195
232
|
}),
|
|
196
|
-
[columns, columnWidths,
|
|
233
|
+
[columns, columnWidths, minWidth, maxWidth, persistenceKey, defaultWidth]
|
|
197
234
|
);
|
|
198
235
|
const components = (0, import_react2.useMemo)(
|
|
199
236
|
() => ({
|
|
@@ -210,10 +247,10 @@ var useResizableColumns_default = useResizableColumns;
|
|
|
210
247
|
// src/ResizableProTable.tsx
|
|
211
248
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
212
249
|
function ResizableProTable(props) {
|
|
213
|
-
const { columns = [],
|
|
250
|
+
const { columns = [], resizableConfig, ...rest } = props;
|
|
214
251
|
const { mergedColumns, components } = useResizableColumns_default(
|
|
215
252
|
columns,
|
|
216
|
-
|
|
253
|
+
resizableConfig
|
|
217
254
|
);
|
|
218
255
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
219
256
|
import_pro_components.ProTable,
|
|
@@ -225,4 +262,30 @@ function ResizableProTable(props) {
|
|
|
225
262
|
);
|
|
226
263
|
}
|
|
227
264
|
var ResizableProTable_default = ResizableProTable;
|
|
265
|
+
|
|
266
|
+
// src/ResizableTable.tsx
|
|
267
|
+
var import_antd = require("antd");
|
|
268
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
269
|
+
function ResizableTable(props) {
|
|
270
|
+
const { columns = [], resizableConfig, ...rest } = props;
|
|
271
|
+
const { mergedColumns, components } = useResizableColumns_default(
|
|
272
|
+
columns,
|
|
273
|
+
resizableConfig
|
|
274
|
+
);
|
|
275
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
276
|
+
import_antd.Table,
|
|
277
|
+
{
|
|
278
|
+
...rest,
|
|
279
|
+
columns: mergedColumns,
|
|
280
|
+
components
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
var ResizableTable_default = ResizableTable;
|
|
285
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
286
|
+
0 && (module.exports = {
|
|
287
|
+
ResizableProTable,
|
|
288
|
+
ResizableTable,
|
|
289
|
+
useResizableColumns
|
|
290
|
+
});
|
|
228
291
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/ResizableProTable.tsx","../src/useResizableColumns.ts","../src/ResizableTitle.tsx"],"sourcesContent":["export { default } from './ResizableProTable';\nexport type { ResizableProTableProps } from './ResizableProTable';\n","import React from 'react';\nimport { ProTable } from '@ant-design/pro-components';\nimport type { ProTableProps, ProColumns } from '@ant-design/pro-components';\nimport useResizableColumns from './useResizableColumns';\n\nexport interface ResizableProTableProps<T extends Record<string, any>>\n extends Omit<ProTableProps<T, any>, 'components'> {\n /** localStorage key for persisting column widths across page refreshes */\n columnWidthPersistenceKey?: string;\n /** Minimum column width in pixels (default: 60) */\n minColumnWidth?: number;\n /** Default width for columns without width (default: 120), used for drag handle */\n defaultColumnWidth?: number;\n}\n\nfunction ResizableProTable<T extends Record<string, any>>(\n props: ResizableProTableProps<T>,\n) {\n const { columns = [], columnWidthPersistenceKey, minColumnWidth, defaultColumnWidth, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ProColumns<T>[],\n { columnWidthPersistenceKey, minColumnWidth, defaultColumnWidth },\n );\n\n return (\n <ProTable<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n />\n );\n}\n\nexport default ResizableProTable;\n","import { useMemo, useState } from 'react';\nimport type { ProColumns } from '@ant-design/pro-components';\nimport ResizableTitle from './ResizableTitle';\nimport type { ColumnWidthMap } from './types';\n\ninterface UseResizableColumnsOptions {\n columnWidthPersistenceKey?: string;\n minColumnWidth?: number;\n defaultColumnWidth?: number;\n}\n\nfunction getColumnKey<T>(col: ProColumns<T>): string | undefined {\n if (col.dataIndex !== undefined) {\n return ([] as string[]).concat(col.dataIndex as string | string[]).join('.');\n }\n if (col.key !== undefined) {\n return String(col.key);\n }\n if (typeof col.title === 'string') {\n return col.title;\n }\n return undefined;\n}\n\nfunction safeReadStorage(key: string): ColumnWidthMap {\n try {\n const raw = localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as ColumnWidthMap) : {};\n } catch {\n return {};\n }\n}\n\nfunction safeWriteStorage(key: string, value: ColumnWidthMap): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota exceeded or private mode\n }\n}\n\nfunction useResizableColumns<T>(\n columns: ProColumns<T>[],\n options?: UseResizableColumnsOptions,\n) {\n const { columnWidthPersistenceKey, minColumnWidth, defaultColumnWidth = 120 } = options ?? {};\n\n const [columnWidths, setColumnWidths] = useState<ColumnWidthMap>(() =>\n columnWidthPersistenceKey ? safeReadStorage(columnWidthPersistenceKey) : {},\n );\n\n const mergedColumns = useMemo<ProColumns<T>[]>(\n () =>\n columns.map((col) => {\n const colKey = getColumnKey(col);\n const effectiveWidth =\n colKey !== undefined\n ? (columnWidths[colKey] ?? (col.width as number | undefined) ?? defaultColumnWidth)\n : (col.width as number | undefined);\n\n if (colKey === undefined) {\n return col;\n }\n\n return {\n ...col,\n width: effectiveWidth,\n onHeaderCell: () => ({\n width: effectiveWidth,\n minWidth: minColumnWidth,\n style: { width: effectiveWidth, minWidth: minColumnWidth ?? 60 },\n onResizeEnd: (finalWidth: number) => {\n setColumnWidths((prev) => {\n const next = { ...prev, [colKey]: finalWidth };\n if (columnWidthPersistenceKey) {\n safeWriteStorage(columnWidthPersistenceKey, next);\n }\n return next;\n });\n },\n }),\n };\n }),\n [columns, columnWidths, minColumnWidth, columnWidthPersistenceKey, defaultColumnWidth],\n );\n\n const components = useMemo(\n () => ({\n header: {\n cell: ResizableTitle,\n },\n }),\n [],\n );\n\n return { mergedColumns, components };\n}\n\nexport default useResizableColumns;\n","import React, { useCallback, useRef } from 'react';\nimport type { ResizableTitleProps } from './types';\n\n/**\n * Find all <col> elements corresponding to the given <th> by matching cellIndex\n * across all <colgroup>s within the same .ant-table-wrapper.\n * Ant Design may split header and body into separate <table> elements when\n * scroll is enabled, each with its own <colgroup>.\n */\nfunction findCorrespondingCols(th: HTMLTableCellElement): HTMLElement[] {\n const cellIndex = th.cellIndex;\n const wrapper = th.closest('.ant-table-wrapper');\n if (!wrapper) {\n const table = th.closest('table');\n if (!table) return [];\n const col = table.querySelectorAll('colgroup > col')[cellIndex];\n return col ? [col as HTMLElement] : [];\n }\n const cols: HTMLElement[] = [];\n wrapper.querySelectorAll('colgroup').forEach((cg) => {\n const col = cg.children[cellIndex] as HTMLElement | undefined;\n if (col) cols.push(col);\n });\n return cols;\n}\n\nconst ResizableTitle: React.FC<ResizableTitleProps> = ({\n onResizeEnd,\n width,\n minWidth = 60,\n children,\n ...restProps\n}) => {\n const thRef = useRef<HTMLTableCellElement>(null);\n const widthRef = useRef<number>(0);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const th = thRef.current;\n if (!th) return;\n\n const startX = e.clientX;\n const startWidth = th.getBoundingClientRect().width;\n const cols = findCorrespondingCols(th);\n\n widthRef.current = startWidth;\n\n const onMouseMove = (ev: MouseEvent) => {\n const newWidth = Math.max(minWidth, startWidth + (ev.clientX - startX));\n th.style.width = `${newWidth}px`;\n cols.forEach((col) => {\n col.style.width = `${newWidth}px`;\n col.style.minWidth = `${newWidth}px`;\n });\n widthRef.current = newWidth;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n document.body.classList.remove('resizing-active');\n onResizeEnd?.(widthRef.current);\n\n const suppressClick = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n document.addEventListener('click', suppressClick, true);\n requestAnimationFrame(() => {\n document.removeEventListener('click', suppressClick, true);\n });\n };\n\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'col-resize';\n document.body.classList.add('resizing-active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n },\n [minWidth, onResizeEnd],\n );\n\n if (!width || !onResizeEnd) {\n return <th {...restProps}>{children}</th>;\n }\n\n return (\n <th\n ref={thRef}\n {...restProps}\n style={{ position: 'relative', ...restProps.style }}\n >\n {children}\n <span\n className=\"resizable-handle\"\n style={{\n position: 'absolute',\n right: -6,\n top: 0,\n bottom: 0,\n width: 12,\n cursor: 'col-resize',\n zIndex: 10,\n }}\n onMouseDown={handleMouseDown}\n onClick={(e) => e.stopPropagation()}\n />\n </th>\n );\n};\n\nexport default ResizableTitle;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,4BAAyB;;;ACDzB,IAAAA,gBAAkC;;;ACAlC,mBAA2C;AAwFhC;AA/EX,SAAS,sBAAsB,IAAyC;AACtE,QAAM,YAAY,GAAG;AACrB,QAAM,UAAU,GAAG,QAAQ,oBAAoB;AAC/C,MAAI,CAAC,SAAS;AACZ,UAAM,QAAQ,GAAG,QAAQ,OAAO;AAChC,QAAI,CAAC,MAAO,QAAO,CAAC;AACpB,UAAM,MAAM,MAAM,iBAAiB,gBAAgB,EAAE,SAAS;AAC9D,WAAO,MAAM,CAAC,GAAkB,IAAI,CAAC;AAAA,EACvC;AACA,QAAM,OAAsB,CAAC;AAC7B,UAAQ,iBAAiB,UAAU,EAAE,QAAQ,CAAC,OAAO;AACnD,UAAM,MAAM,GAAG,SAAS,SAAS;AACjC,QAAI,IAAK,MAAK,KAAK,GAAG;AAAA,EACxB,CAAC;AACD,SAAO;AACT;AAEA,IAAM,iBAAgD,CAAC;AAAA,EACrD;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,YAAQ,qBAA6B,IAAI;AAC/C,QAAM,eAAW,qBAAe,CAAC;AAEjC,QAAM,sBAAkB;AAAA,IACtB,CAAC,MAAwB;AACvB,QAAE,eAAe;AACjB,QAAE,gBAAgB;AAElB,YAAM,KAAK,MAAM;AACjB,UAAI,CAAC,GAAI;AAET,YAAM,SAAS,EAAE;AACjB,YAAM,aAAa,GAAG,sBAAsB,EAAE;AAC9C,YAAM,OAAO,sBAAsB,EAAE;AAErC,eAAS,UAAU;AAEnB,YAAM,cAAc,CAAC,OAAmB;AACtC,cAAM,WAAW,KAAK,IAAI,UAAU,cAAc,GAAG,UAAU,OAAO;AACtE,WAAG,MAAM,QAAQ,GAAG,QAAQ;AAC5B,aAAK,QAAQ,CAAC,QAAQ;AACpB,cAAI,MAAM,QAAQ,GAAG,QAAQ;AAC7B,cAAI,MAAM,WAAW,GAAG,QAAQ;AAAA,QAClC,CAAC;AACD,iBAAS,UAAU;AAAA,MACrB;AAEA,YAAM,YAAY,MAAM;AACtB,iBAAS,oBAAoB,aAAa,WAAW;AACrD,iBAAS,oBAAoB,WAAW,SAAS;AACjD,iBAAS,KAAK,MAAM,aAAa;AACjC,iBAAS,KAAK,MAAM,SAAS;AAC7B,iBAAS,KAAK,UAAU,OAAO,iBAAiB;AAChD,sBAAc,SAAS,OAAO;AAE9B,cAAM,gBAAgB,CAAC,OAAmB;AACxC,aAAG,gBAAgB;AACnB,aAAG,eAAe;AAAA,QACpB;AACA,iBAAS,iBAAiB,SAAS,eAAe,IAAI;AACtD,8BAAsB,MAAM;AAC1B,mBAAS,oBAAoB,SAAS,eAAe,IAAI;AAAA,QAC3D,CAAC;AAAA,MACH;AAEA,eAAS,KAAK,MAAM,aAAa;AACjC,eAAS,KAAK,MAAM,SAAS;AAC7B,eAAS,KAAK,UAAU,IAAI,iBAAiB;AAC7C,eAAS,iBAAiB,aAAa,WAAW;AAClD,eAAS,iBAAiB,WAAW,SAAS;AAAA,IAChD;AAAA,IACA,CAAC,UAAU,WAAW;AAAA,EACxB;AAEA,MAAI,CAAC,SAAS,CAAC,aAAa;AAC1B,WAAO,4CAAC,QAAI,GAAG,WAAY,UAAS;AAAA,EACtC;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACJ,GAAG;AAAA,MACJ,OAAO,EAAE,UAAU,YAAY,GAAG,UAAU,MAAM;AAAA,MAEjD;AAAA;AAAA,QACD;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,OAAO;AAAA,cACL,UAAU;AAAA,cACV,OAAO;AAAA,cACP,KAAK;AAAA,cACL,QAAQ;AAAA,cACR,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AAAA,YACA,aAAa;AAAA,YACb,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA;AAAA,QACpC;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,yBAAQ;;;ADzGf,SAAS,aAAgB,KAAwC;AAC/D,MAAI,IAAI,cAAc,QAAW;AAC/B,WAAQ,CAAC,EAAe,OAAO,IAAI,SAA8B,EAAE,KAAK,GAAG;AAAA,EAC7E;AACA,MAAI,IAAI,QAAQ,QAAW;AACzB,WAAO,OAAO,IAAI,GAAG;AAAA,EACvB;AACA,MAAI,OAAO,IAAI,UAAU,UAAU;AACjC,WAAO,IAAI;AAAA,EACb;AACA,SAAO;AACT;AAEA,SAAS,gBAAgB,KAA6B;AACpD,MAAI;AACF,UAAM,MAAM,aAAa,QAAQ,GAAG;AACpC,WAAO,MAAO,KAAK,MAAM,GAAG,IAAuB,CAAC;AAAA,EACtD,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,iBAAiB,KAAa,OAA6B;AAClE,MAAI;AACF,iBAAa,QAAQ,KAAK,KAAK,UAAU,KAAK,CAAC;AAAA,EACjD,QAAQ;AAAA,EAER;AACF;AAEA,SAAS,oBACP,SACA,SACA;AACA,QAAM,EAAE,2BAA2B,gBAAgB,qBAAqB,IAAI,IAAI,WAAW,CAAC;AAE5F,QAAM,CAAC,cAAc,eAAe,QAAI;AAAA,IAAyB,MAC/D,4BAA4B,gBAAgB,yBAAyB,IAAI,CAAC;AAAA,EAC5E;AAEA,QAAM,oBAAgB;AAAA,IACpB,MACE,QAAQ,IAAI,CAAC,QAAQ;AACnB,YAAM,SAAS,aAAa,GAAG;AAC/B,YAAM,iBACJ,WAAW,SACN,aAAa,MAAM,KAAM,IAAI,SAAgC,qBAC7D,IAAI;AAEX,UAAI,WAAW,QAAW;AACxB,eAAO;AAAA,MACT;AAEA,aAAO;AAAA,QACL,GAAG;AAAA,QACH,OAAO;AAAA,QACP,cAAc,OAAO;AAAA,UACnB,OAAO;AAAA,UACP,UAAU;AAAA,UACV,OAAO,EAAE,OAAO,gBAAgB,UAAU,kBAAkB,GAAG;AAAA,UAC/D,aAAa,CAAC,eAAuB;AACnC,4BAAgB,CAAC,SAAS;AACxB,oBAAM,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,GAAG,WAAW;AAC7C,kBAAI,2BAA2B;AAC7B,iCAAiB,2BAA2B,IAAI;AAAA,cAClD;AACA,qBAAO;AAAA,YACT,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,IACH,CAAC,SAAS,cAAc,gBAAgB,2BAA2B,kBAAkB;AAAA,EACvF;AAEA,QAAM,iBAAa;AAAA,IACjB,OAAO;AAAA,MACL,QAAQ;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,eAAe,WAAW;AACrC;AAEA,IAAO,8BAAQ;;;ADxEX,IAAAC,sBAAA;AAXJ,SAAS,kBACP,OACA;AACA,QAAM,EAAE,UAAU,CAAC,GAAG,2BAA2B,gBAAgB,oBAAoB,GAAG,KAAK,IAAI;AAEjG,QAAM,EAAE,eAAe,WAAW,IAAI;AAAA,IACpC;AAAA,IACA,EAAE,2BAA2B,gBAAgB,mBAAmB;AAAA,EAClE;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ,SAAS;AAAA,MACT;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,4BAAQ;","names":["import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","#style-inject:#style-inject","../src/style.css","../src/ResizableProTable.tsx","../src/useResizableColumns.ts","../src/ResizableTitle.tsx","../src/ResizableTable.tsx"],"sourcesContent":["import './style.css';\n\nexport { default } from './ResizableProTable';\nexport { default as ResizableProTable } from './ResizableProTable';\nexport type { ResizableProTableProps } from './ResizableProTable';\n\nexport { default as ResizableTable } from './ResizableTable';\nexport type { ResizableTableProps } from './ResizableTable';\n\nexport { default as useResizableColumns } from './useResizableColumns';\nexport type { ResizableConfig, ColumnWidthMap, ResizableTitleProps } from './types';\n","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".ant-table-thead > tr > th {\\n position: relative;\\n overflow: visible !important;\\n}\\n.ant-table-wrapper .ant-table-thead,\\n.ant-table .ant-table-thead {\\n overflow: visible !important;\\n}\\n.resizable-handle {\\n position: absolute;\\n right: -6px;\\n top: 0;\\n bottom: 0;\\n width: 12px;\\n cursor: col-resize;\\n z-index: 10;\\n pointer-events: auto;\\n}\\n.resizable-handle::after {\\n content: \\\"\\\";\\n position: absolute;\\n left: 5px;\\n top: 15%;\\n height: 70%;\\n width: 2px;\\n background: rgba(0, 0, 0, 0.08);\\n transition: background 0.2s;\\n}\\n.resizable-handle:hover::after {\\n background: #1677ff;\\n}\\n.resizable-handle--active::after {\\n background: #1677ff;\\n}\\n\")","import { ProTable } from '@ant-design/pro-components';\nimport type { ProTableProps, ProColumns } from '@ant-design/pro-components';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableProTableProps<T extends Record<string, any>>\n extends Omit<ProTableProps<T, any>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableProTable<T extends Record<string, any>>(\n props: ResizableProTableProps<T>,\n) {\n const { columns = [], resizableConfig, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ProColumns<T>[],\n resizableConfig,\n );\n\n return (\n <ProTable<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n />\n );\n}\n\nexport default ResizableProTable;\n","import { useMemo, useState } from 'react';\nimport type { ColumnType } from 'antd/es/table';\nimport type { ProColumns } from '@ant-design/pro-components';\nimport ResizableTitle from './ResizableTitle';\nimport type { ColumnWidthMap, ResizableConfig } from './types';\n\ntype Components = { header: { cell: typeof ResizableTitle } };\n\nfunction getColumnKey<T>(col: ColumnType<T>): string | undefined {\n if (col.dataIndex !== undefined) {\n return ([] as string[]).concat(col.dataIndex as string | string[]).join('.');\n }\n if (col.key !== undefined) {\n return String(col.key);\n }\n if (typeof col.title === 'string') {\n return col.title;\n }\n return undefined;\n}\n\nfunction safeReadStorage(key: string): ColumnWidthMap {\n try {\n const raw = localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as ColumnWidthMap) : {};\n } catch {\n return {};\n }\n}\n\nfunction safeWriteStorage(key: string, value: ColumnWidthMap): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota exceeded or private mode\n }\n}\n\nfunction useResizableColumns<T>(\n columns: ProColumns<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ProColumns<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: ColumnType<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ColumnType<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: any[],\n resizableConfig?: ResizableConfig,\n) {\n const { persistenceKey, minWidth, maxWidth, defaultWidth = 120 } = resizableConfig ?? {};\n\n const [columnWidths, setColumnWidths] = useState<ColumnWidthMap>(() =>\n persistenceKey ? safeReadStorage(persistenceKey) : {},\n );\n\n const mergedColumns = useMemo(\n () =>\n columns.map((col) => {\n const colKey = getColumnKey(col);\n const effectiveWidth =\n colKey !== undefined\n ? (columnWidths[colKey] ?? (col.width as number | undefined) ?? defaultWidth)\n : (col.width as number | undefined);\n\n if (colKey === undefined) {\n return col;\n }\n\n return {\n ...col,\n width: effectiveWidth,\n onHeaderCell: () => ({\n width: effectiveWidth,\n minWidth,\n maxWidth,\n style: { width: effectiveWidth, minWidth: minWidth ?? 60 },\n onResizeEnd: (finalWidth: number) => {\n setColumnWidths((prev) => {\n const next = { ...prev, [colKey]: finalWidth };\n if (persistenceKey) {\n safeWriteStorage(persistenceKey, next);\n }\n return next;\n });\n },\n }),\n };\n }),\n [columns, columnWidths, minWidth, maxWidth, persistenceKey, defaultWidth],\n );\n\n const components = useMemo(\n () => ({\n header: {\n cell: ResizableTitle,\n },\n }),\n [],\n );\n\n return { mergedColumns, components };\n}\n\nexport default useResizableColumns;\n","import React, { useCallback, useRef } from 'react';\nimport type { ResizableTitleProps } from './types';\n\n/**\n * Find all <col> elements corresponding to the given <th> by matching cellIndex\n * across all <colgroup>s within the same .ant-table-wrapper.\n * Ant Design may split header and body into separate <table> elements when\n * scroll is enabled, each with its own <colgroup>.\n */\nfunction findCorrespondingCols(th: HTMLTableCellElement): HTMLElement[] {\n const cellIndex = th.cellIndex;\n const wrapper = th.closest('.ant-table-wrapper');\n if (!wrapper) {\n const table = th.closest('table');\n if (!table) return [];\n const col = table.querySelectorAll('colgroup > col')[cellIndex];\n return col ? [col as HTMLElement] : [];\n }\n const cols: HTMLElement[] = [];\n wrapper.querySelectorAll('colgroup').forEach((cg) => {\n const col = cg.children[cellIndex] as HTMLElement | undefined;\n if (col) cols.push(col);\n });\n return cols;\n}\n\nconst ResizableTitle: React.FC<ResizableTitleProps> = ({\n onResizeEnd,\n width,\n minWidth = 60,\n maxWidth,\n children,\n ...restProps\n}) => {\n const thRef = useRef<HTMLTableCellElement>(null);\n const handleRef = useRef<HTMLSpanElement>(null);\n const widthRef = useRef<number>(0);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const th = thRef.current;\n if (!th) return;\n\n const handle = handleRef.current;\n const startX = e.clientX;\n const startWidth = th.getBoundingClientRect().width;\n const cols = findCorrespondingCols(th);\n\n widthRef.current = startWidth;\n\n const onMouseMove = (ev: MouseEvent) => {\n const rawWidth = startWidth + (ev.clientX - startX);\n const newWidth = Math.max(\n minWidth,\n maxWidth !== undefined ? Math.min(maxWidth, rawWidth) : rawWidth,\n );\n th.style.width = `${newWidth}px`;\n cols.forEach((col) => {\n col.style.width = `${newWidth}px`;\n col.style.minWidth = `${newWidth}px`;\n });\n widthRef.current = newWidth;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n handle?.classList.remove('resizable-handle--active');\n onResizeEnd?.(widthRef.current);\n\n const suppressClick = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n document.addEventListener('click', suppressClick, true);\n requestAnimationFrame(() => {\n document.removeEventListener('click', suppressClick, true);\n });\n };\n\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'col-resize';\n handle?.classList.add('resizable-handle--active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n },\n [minWidth, maxWidth, onResizeEnd],\n );\n\n if (!width || !onResizeEnd) {\n return <th {...restProps}>{children}</th>;\n }\n\n return (\n <th\n ref={thRef}\n {...restProps}\n style={{ position: 'relative', ...restProps.style }}\n >\n {children}\n <span\n ref={handleRef}\n className=\"resizable-handle\"\n style={{\n position: 'absolute',\n right: -6,\n top: 0,\n bottom: 0,\n width: 12,\n cursor: 'col-resize',\n zIndex: 10,\n }}\n onMouseDown={handleMouseDown}\n onClick={(e) => e.stopPropagation()}\n />\n </th>\n );\n};\n\nexport default ResizableTitle;\n","import { Table } from 'antd';\nimport type { TableProps, ColumnType } from 'antd/es/table';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableTableProps<T extends object>\n extends Omit<TableProps<T>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableTable<T extends object>(props: ResizableTableProps<T>) {\n const { columns = [], resizableConfig, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ColumnType<T>[],\n resizableConfig,\n );\n\n return (\n <Table<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n />\n );\n}\n\nexport default ResizableTable;\n"],"mappings":"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","names":["import_react","import_jsx_runtime","import_jsx_runtime"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
// #style-inject:#style-inject
|
|
2
|
+
function styleInject(css, { insertAt } = {}) {
|
|
3
|
+
if (!css || typeof document === "undefined") return;
|
|
4
|
+
const head = document.head || document.getElementsByTagName("head")[0];
|
|
5
|
+
const style = document.createElement("style");
|
|
6
|
+
style.type = "text/css";
|
|
7
|
+
if (insertAt === "top") {
|
|
8
|
+
if (head.firstChild) {
|
|
9
|
+
head.insertBefore(style, head.firstChild);
|
|
10
|
+
} else {
|
|
11
|
+
head.appendChild(style);
|
|
12
|
+
}
|
|
13
|
+
} else {
|
|
14
|
+
head.appendChild(style);
|
|
15
|
+
}
|
|
16
|
+
if (style.styleSheet) {
|
|
17
|
+
style.styleSheet.cssText = css;
|
|
18
|
+
} else {
|
|
19
|
+
style.appendChild(document.createTextNode(css));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/style.css
|
|
24
|
+
styleInject('.ant-table-thead > tr > th {\n position: relative;\n overflow: visible !important;\n}\n.ant-table-wrapper .ant-table-thead,\n.ant-table .ant-table-thead {\n overflow: visible !important;\n}\n.resizable-handle {\n position: absolute;\n right: -6px;\n top: 0;\n bottom: 0;\n width: 12px;\n cursor: col-resize;\n z-index: 10;\n pointer-events: auto;\n}\n.resizable-handle::after {\n content: "";\n position: absolute;\n left: 5px;\n top: 15%;\n height: 70%;\n width: 2px;\n background: rgba(0, 0, 0, 0.08);\n transition: background 0.2s;\n}\n.resizable-handle:hover::after {\n background: #1677ff;\n}\n.resizable-handle--active::after {\n background: #1677ff;\n}\n');
|
|
25
|
+
|
|
1
26
|
// src/ResizableProTable.tsx
|
|
2
27
|
import { ProTable } from "@ant-design/pro-components";
|
|
3
28
|
|
|
@@ -27,10 +52,12 @@ var ResizableTitle = ({
|
|
|
27
52
|
onResizeEnd,
|
|
28
53
|
width,
|
|
29
54
|
minWidth = 60,
|
|
55
|
+
maxWidth,
|
|
30
56
|
children,
|
|
31
57
|
...restProps
|
|
32
58
|
}) => {
|
|
33
59
|
const thRef = useRef(null);
|
|
60
|
+
const handleRef = useRef(null);
|
|
34
61
|
const widthRef = useRef(0);
|
|
35
62
|
const handleMouseDown = useCallback(
|
|
36
63
|
(e) => {
|
|
@@ -38,12 +65,17 @@ var ResizableTitle = ({
|
|
|
38
65
|
e.stopPropagation();
|
|
39
66
|
const th = thRef.current;
|
|
40
67
|
if (!th) return;
|
|
68
|
+
const handle = handleRef.current;
|
|
41
69
|
const startX = e.clientX;
|
|
42
70
|
const startWidth = th.getBoundingClientRect().width;
|
|
43
71
|
const cols = findCorrespondingCols(th);
|
|
44
72
|
widthRef.current = startWidth;
|
|
45
73
|
const onMouseMove = (ev) => {
|
|
46
|
-
const
|
|
74
|
+
const rawWidth = startWidth + (ev.clientX - startX);
|
|
75
|
+
const newWidth = Math.max(
|
|
76
|
+
minWidth,
|
|
77
|
+
maxWidth !== void 0 ? Math.min(maxWidth, rawWidth) : rawWidth
|
|
78
|
+
);
|
|
47
79
|
th.style.width = `${newWidth}px`;
|
|
48
80
|
cols.forEach((col) => {
|
|
49
81
|
col.style.width = `${newWidth}px`;
|
|
@@ -56,7 +88,7 @@ var ResizableTitle = ({
|
|
|
56
88
|
document.removeEventListener("mouseup", onMouseUp);
|
|
57
89
|
document.body.style.userSelect = "";
|
|
58
90
|
document.body.style.cursor = "";
|
|
59
|
-
|
|
91
|
+
handle?.classList.remove("resizable-handle--active");
|
|
60
92
|
onResizeEnd?.(widthRef.current);
|
|
61
93
|
const suppressClick = (ev) => {
|
|
62
94
|
ev.stopPropagation();
|
|
@@ -69,11 +101,11 @@ var ResizableTitle = ({
|
|
|
69
101
|
};
|
|
70
102
|
document.body.style.userSelect = "none";
|
|
71
103
|
document.body.style.cursor = "col-resize";
|
|
72
|
-
|
|
104
|
+
handle?.classList.add("resizable-handle--active");
|
|
73
105
|
document.addEventListener("mousemove", onMouseMove);
|
|
74
106
|
document.addEventListener("mouseup", onMouseUp);
|
|
75
107
|
},
|
|
76
|
-
[minWidth, onResizeEnd]
|
|
108
|
+
[minWidth, maxWidth, onResizeEnd]
|
|
77
109
|
);
|
|
78
110
|
if (!width || !onResizeEnd) {
|
|
79
111
|
return /* @__PURE__ */ jsx("th", { ...restProps, children });
|
|
@@ -89,6 +121,7 @@ var ResizableTitle = ({
|
|
|
89
121
|
/* @__PURE__ */ jsx(
|
|
90
122
|
"span",
|
|
91
123
|
{
|
|
124
|
+
ref: handleRef,
|
|
92
125
|
className: "resizable-handle",
|
|
93
126
|
style: {
|
|
94
127
|
position: "absolute",
|
|
@@ -136,15 +169,15 @@ function safeWriteStorage(key, value) {
|
|
|
136
169
|
} catch {
|
|
137
170
|
}
|
|
138
171
|
}
|
|
139
|
-
function useResizableColumns(columns,
|
|
140
|
-
const {
|
|
172
|
+
function useResizableColumns(columns, resizableConfig) {
|
|
173
|
+
const { persistenceKey, minWidth, maxWidth, defaultWidth = 120 } = resizableConfig ?? {};
|
|
141
174
|
const [columnWidths, setColumnWidths] = useState(
|
|
142
|
-
() =>
|
|
175
|
+
() => persistenceKey ? safeReadStorage(persistenceKey) : {}
|
|
143
176
|
);
|
|
144
177
|
const mergedColumns = useMemo(
|
|
145
178
|
() => columns.map((col) => {
|
|
146
179
|
const colKey = getColumnKey(col);
|
|
147
|
-
const effectiveWidth = colKey !== void 0 ? columnWidths[colKey] ?? col.width ??
|
|
180
|
+
const effectiveWidth = colKey !== void 0 ? columnWidths[colKey] ?? col.width ?? defaultWidth : col.width;
|
|
148
181
|
if (colKey === void 0) {
|
|
149
182
|
return col;
|
|
150
183
|
}
|
|
@@ -153,13 +186,14 @@ function useResizableColumns(columns, options) {
|
|
|
153
186
|
width: effectiveWidth,
|
|
154
187
|
onHeaderCell: () => ({
|
|
155
188
|
width: effectiveWidth,
|
|
156
|
-
minWidth
|
|
157
|
-
|
|
189
|
+
minWidth,
|
|
190
|
+
maxWidth,
|
|
191
|
+
style: { width: effectiveWidth, minWidth: minWidth ?? 60 },
|
|
158
192
|
onResizeEnd: (finalWidth) => {
|
|
159
193
|
setColumnWidths((prev) => {
|
|
160
194
|
const next = { ...prev, [colKey]: finalWidth };
|
|
161
|
-
if (
|
|
162
|
-
safeWriteStorage(
|
|
195
|
+
if (persistenceKey) {
|
|
196
|
+
safeWriteStorage(persistenceKey, next);
|
|
163
197
|
}
|
|
164
198
|
return next;
|
|
165
199
|
});
|
|
@@ -167,7 +201,7 @@ function useResizableColumns(columns, options) {
|
|
|
167
201
|
})
|
|
168
202
|
};
|
|
169
203
|
}),
|
|
170
|
-
[columns, columnWidths,
|
|
204
|
+
[columns, columnWidths, minWidth, maxWidth, persistenceKey, defaultWidth]
|
|
171
205
|
);
|
|
172
206
|
const components = useMemo(
|
|
173
207
|
() => ({
|
|
@@ -184,10 +218,10 @@ var useResizableColumns_default = useResizableColumns;
|
|
|
184
218
|
// src/ResizableProTable.tsx
|
|
185
219
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
186
220
|
function ResizableProTable(props) {
|
|
187
|
-
const { columns = [],
|
|
221
|
+
const { columns = [], resizableConfig, ...rest } = props;
|
|
188
222
|
const { mergedColumns, components } = useResizableColumns_default(
|
|
189
223
|
columns,
|
|
190
|
-
|
|
224
|
+
resizableConfig
|
|
191
225
|
);
|
|
192
226
|
return /* @__PURE__ */ jsx2(
|
|
193
227
|
ProTable,
|
|
@@ -199,7 +233,30 @@ function ResizableProTable(props) {
|
|
|
199
233
|
);
|
|
200
234
|
}
|
|
201
235
|
var ResizableProTable_default = ResizableProTable;
|
|
236
|
+
|
|
237
|
+
// src/ResizableTable.tsx
|
|
238
|
+
import { Table } from "antd";
|
|
239
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
240
|
+
function ResizableTable(props) {
|
|
241
|
+
const { columns = [], resizableConfig, ...rest } = props;
|
|
242
|
+
const { mergedColumns, components } = useResizableColumns_default(
|
|
243
|
+
columns,
|
|
244
|
+
resizableConfig
|
|
245
|
+
);
|
|
246
|
+
return /* @__PURE__ */ jsx3(
|
|
247
|
+
Table,
|
|
248
|
+
{
|
|
249
|
+
...rest,
|
|
250
|
+
columns: mergedColumns,
|
|
251
|
+
components
|
|
252
|
+
}
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
var ResizableTable_default = ResizableTable;
|
|
202
256
|
export {
|
|
203
|
-
ResizableProTable_default as
|
|
257
|
+
ResizableProTable_default as ResizableProTable,
|
|
258
|
+
ResizableTable_default as ResizableTable,
|
|
259
|
+
ResizableProTable_default as default,
|
|
260
|
+
useResizableColumns_default as useResizableColumns
|
|
204
261
|
};
|
|
205
262
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/ResizableProTable.tsx","../src/useResizableColumns.ts","../src/ResizableTitle.tsx"],"sourcesContent":["import React from 'react';\nimport { ProTable } from '@ant-design/pro-components';\nimport type { ProTableProps, ProColumns } from '@ant-design/pro-components';\nimport useResizableColumns from './useResizableColumns';\n\nexport interface ResizableProTableProps<T extends Record<string, any>>\n extends Omit<ProTableProps<T, any>, 'components'> {\n /** localStorage key for persisting column widths across page refreshes */\n columnWidthPersistenceKey?: string;\n /** Minimum column width in pixels (default: 60) */\n minColumnWidth?: number;\n /** Default width for columns without width (default: 120), used for drag handle */\n defaultColumnWidth?: number;\n}\n\nfunction ResizableProTable<T extends Record<string, any>>(\n props: ResizableProTableProps<T>,\n) {\n const { columns = [], columnWidthPersistenceKey, minColumnWidth, defaultColumnWidth, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ProColumns<T>[],\n { columnWidthPersistenceKey, minColumnWidth, defaultColumnWidth },\n );\n\n return (\n <ProTable<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n />\n );\n}\n\nexport default ResizableProTable;\n","import { useMemo, useState } from 'react';\nimport type { ProColumns } from '@ant-design/pro-components';\nimport ResizableTitle from './ResizableTitle';\nimport type { ColumnWidthMap } from './types';\n\ninterface UseResizableColumnsOptions {\n columnWidthPersistenceKey?: string;\n minColumnWidth?: number;\n defaultColumnWidth?: number;\n}\n\nfunction getColumnKey<T>(col: ProColumns<T>): string | undefined {\n if (col.dataIndex !== undefined) {\n return ([] as string[]).concat(col.dataIndex as string | string[]).join('.');\n }\n if (col.key !== undefined) {\n return String(col.key);\n }\n if (typeof col.title === 'string') {\n return col.title;\n }\n return undefined;\n}\n\nfunction safeReadStorage(key: string): ColumnWidthMap {\n try {\n const raw = localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as ColumnWidthMap) : {};\n } catch {\n return {};\n }\n}\n\nfunction safeWriteStorage(key: string, value: ColumnWidthMap): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota exceeded or private mode\n }\n}\n\nfunction useResizableColumns<T>(\n columns: ProColumns<T>[],\n options?: UseResizableColumnsOptions,\n) {\n const { columnWidthPersistenceKey, minColumnWidth, defaultColumnWidth = 120 } = options ?? {};\n\n const [columnWidths, setColumnWidths] = useState<ColumnWidthMap>(() =>\n columnWidthPersistenceKey ? safeReadStorage(columnWidthPersistenceKey) : {},\n );\n\n const mergedColumns = useMemo<ProColumns<T>[]>(\n () =>\n columns.map((col) => {\n const colKey = getColumnKey(col);\n const effectiveWidth =\n colKey !== undefined\n ? (columnWidths[colKey] ?? (col.width as number | undefined) ?? defaultColumnWidth)\n : (col.width as number | undefined);\n\n if (colKey === undefined) {\n return col;\n }\n\n return {\n ...col,\n width: effectiveWidth,\n onHeaderCell: () => ({\n width: effectiveWidth,\n minWidth: minColumnWidth,\n style: { width: effectiveWidth, minWidth: minColumnWidth ?? 60 },\n onResizeEnd: (finalWidth: number) => {\n setColumnWidths((prev) => {\n const next = { ...prev, [colKey]: finalWidth };\n if (columnWidthPersistenceKey) {\n safeWriteStorage(columnWidthPersistenceKey, next);\n }\n return next;\n });\n },\n }),\n };\n }),\n [columns, columnWidths, minColumnWidth, columnWidthPersistenceKey, defaultColumnWidth],\n );\n\n const components = useMemo(\n () => ({\n header: {\n cell: ResizableTitle,\n },\n }),\n [],\n );\n\n return { mergedColumns, components };\n}\n\nexport default useResizableColumns;\n","import React, { useCallback, useRef } from 'react';\nimport type { ResizableTitleProps } from './types';\n\n/**\n * Find all <col> elements corresponding to the given <th> by matching cellIndex\n * across all <colgroup>s within the same .ant-table-wrapper.\n * Ant Design may split header and body into separate <table> elements when\n * scroll is enabled, each with its own <colgroup>.\n */\nfunction findCorrespondingCols(th: HTMLTableCellElement): HTMLElement[] {\n const cellIndex = th.cellIndex;\n const wrapper = th.closest('.ant-table-wrapper');\n if (!wrapper) {\n const table = th.closest('table');\n if (!table) return [];\n const col = table.querySelectorAll('colgroup > col')[cellIndex];\n return col ? [col as HTMLElement] : [];\n }\n const cols: HTMLElement[] = [];\n wrapper.querySelectorAll('colgroup').forEach((cg) => {\n const col = cg.children[cellIndex] as HTMLElement | undefined;\n if (col) cols.push(col);\n });\n return cols;\n}\n\nconst ResizableTitle: React.FC<ResizableTitleProps> = ({\n onResizeEnd,\n width,\n minWidth = 60,\n children,\n ...restProps\n}) => {\n const thRef = useRef<HTMLTableCellElement>(null);\n const widthRef = useRef<number>(0);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const th = thRef.current;\n if (!th) return;\n\n const startX = e.clientX;\n const startWidth = th.getBoundingClientRect().width;\n const cols = findCorrespondingCols(th);\n\n widthRef.current = startWidth;\n\n const onMouseMove = (ev: MouseEvent) => {\n const newWidth = Math.max(minWidth, startWidth + (ev.clientX - startX));\n th.style.width = `${newWidth}px`;\n cols.forEach((col) => {\n col.style.width = `${newWidth}px`;\n col.style.minWidth = `${newWidth}px`;\n });\n widthRef.current = newWidth;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n document.body.classList.remove('resizing-active');\n onResizeEnd?.(widthRef.current);\n\n const suppressClick = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n document.addEventListener('click', suppressClick, true);\n requestAnimationFrame(() => {\n document.removeEventListener('click', suppressClick, true);\n });\n };\n\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'col-resize';\n document.body.classList.add('resizing-active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n },\n [minWidth, onResizeEnd],\n );\n\n if (!width || !onResizeEnd) {\n return <th {...restProps}>{children}</th>;\n }\n\n return (\n <th\n ref={thRef}\n {...restProps}\n style={{ position: 'relative', ...restProps.style }}\n >\n {children}\n <span\n className=\"resizable-handle\"\n style={{\n position: 'absolute',\n right: -6,\n top: 0,\n bottom: 0,\n width: 12,\n cursor: 'col-resize',\n zIndex: 10,\n }}\n onMouseDown={handleMouseDown}\n onClick={(e) => e.stopPropagation()}\n />\n </th>\n );\n};\n\nexport default ResizableTitle;\n"],"mappings":"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","names":["jsx"]}
|
|
1
|
+
{"version":3,"sources":["#style-inject:#style-inject","../src/style.css","../src/ResizableProTable.tsx","../src/useResizableColumns.ts","../src/ResizableTitle.tsx","../src/ResizableTable.tsx"],"sourcesContent":["\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".ant-table-thead > tr > th {\\n position: relative;\\n overflow: visible !important;\\n}\\n.ant-table-wrapper .ant-table-thead,\\n.ant-table .ant-table-thead {\\n overflow: visible !important;\\n}\\n.resizable-handle {\\n position: absolute;\\n right: -6px;\\n top: 0;\\n bottom: 0;\\n width: 12px;\\n cursor: col-resize;\\n z-index: 10;\\n pointer-events: auto;\\n}\\n.resizable-handle::after {\\n content: \\\"\\\";\\n position: absolute;\\n left: 5px;\\n top: 15%;\\n height: 70%;\\n width: 2px;\\n background: rgba(0, 0, 0, 0.08);\\n transition: background 0.2s;\\n}\\n.resizable-handle:hover::after {\\n background: #1677ff;\\n}\\n.resizable-handle--active::after {\\n background: #1677ff;\\n}\\n\")","import { ProTable } from '@ant-design/pro-components';\nimport type { ProTableProps, ProColumns } from '@ant-design/pro-components';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableProTableProps<T extends Record<string, any>>\n extends Omit<ProTableProps<T, any>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableProTable<T extends Record<string, any>>(\n props: ResizableProTableProps<T>,\n) {\n const { columns = [], resizableConfig, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ProColumns<T>[],\n resizableConfig,\n );\n\n return (\n <ProTable<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n />\n );\n}\n\nexport default ResizableProTable;\n","import { useMemo, useState } from 'react';\nimport type { ColumnType } from 'antd/es/table';\nimport type { ProColumns } from '@ant-design/pro-components';\nimport ResizableTitle from './ResizableTitle';\nimport type { ColumnWidthMap, ResizableConfig } from './types';\n\ntype Components = { header: { cell: typeof ResizableTitle } };\n\nfunction getColumnKey<T>(col: ColumnType<T>): string | undefined {\n if (col.dataIndex !== undefined) {\n return ([] as string[]).concat(col.dataIndex as string | string[]).join('.');\n }\n if (col.key !== undefined) {\n return String(col.key);\n }\n if (typeof col.title === 'string') {\n return col.title;\n }\n return undefined;\n}\n\nfunction safeReadStorage(key: string): ColumnWidthMap {\n try {\n const raw = localStorage.getItem(key);\n return raw ? (JSON.parse(raw) as ColumnWidthMap) : {};\n } catch {\n return {};\n }\n}\n\nfunction safeWriteStorage(key: string, value: ColumnWidthMap): void {\n try {\n localStorage.setItem(key, JSON.stringify(value));\n } catch {\n // quota exceeded or private mode\n }\n}\n\nfunction useResizableColumns<T>(\n columns: ProColumns<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ProColumns<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: ColumnType<T>[],\n resizableConfig?: ResizableConfig,\n): { mergedColumns: ColumnType<T>[]; components: Components };\nfunction useResizableColumns<T>(\n columns: any[],\n resizableConfig?: ResizableConfig,\n) {\n const { persistenceKey, minWidth, maxWidth, defaultWidth = 120 } = resizableConfig ?? {};\n\n const [columnWidths, setColumnWidths] = useState<ColumnWidthMap>(() =>\n persistenceKey ? safeReadStorage(persistenceKey) : {},\n );\n\n const mergedColumns = useMemo(\n () =>\n columns.map((col) => {\n const colKey = getColumnKey(col);\n const effectiveWidth =\n colKey !== undefined\n ? (columnWidths[colKey] ?? (col.width as number | undefined) ?? defaultWidth)\n : (col.width as number | undefined);\n\n if (colKey === undefined) {\n return col;\n }\n\n return {\n ...col,\n width: effectiveWidth,\n onHeaderCell: () => ({\n width: effectiveWidth,\n minWidth,\n maxWidth,\n style: { width: effectiveWidth, minWidth: minWidth ?? 60 },\n onResizeEnd: (finalWidth: number) => {\n setColumnWidths((prev) => {\n const next = { ...prev, [colKey]: finalWidth };\n if (persistenceKey) {\n safeWriteStorage(persistenceKey, next);\n }\n return next;\n });\n },\n }),\n };\n }),\n [columns, columnWidths, minWidth, maxWidth, persistenceKey, defaultWidth],\n );\n\n const components = useMemo(\n () => ({\n header: {\n cell: ResizableTitle,\n },\n }),\n [],\n );\n\n return { mergedColumns, components };\n}\n\nexport default useResizableColumns;\n","import React, { useCallback, useRef } from 'react';\nimport type { ResizableTitleProps } from './types';\n\n/**\n * Find all <col> elements corresponding to the given <th> by matching cellIndex\n * across all <colgroup>s within the same .ant-table-wrapper.\n * Ant Design may split header and body into separate <table> elements when\n * scroll is enabled, each with its own <colgroup>.\n */\nfunction findCorrespondingCols(th: HTMLTableCellElement): HTMLElement[] {\n const cellIndex = th.cellIndex;\n const wrapper = th.closest('.ant-table-wrapper');\n if (!wrapper) {\n const table = th.closest('table');\n if (!table) return [];\n const col = table.querySelectorAll('colgroup > col')[cellIndex];\n return col ? [col as HTMLElement] : [];\n }\n const cols: HTMLElement[] = [];\n wrapper.querySelectorAll('colgroup').forEach((cg) => {\n const col = cg.children[cellIndex] as HTMLElement | undefined;\n if (col) cols.push(col);\n });\n return cols;\n}\n\nconst ResizableTitle: React.FC<ResizableTitleProps> = ({\n onResizeEnd,\n width,\n minWidth = 60,\n maxWidth,\n children,\n ...restProps\n}) => {\n const thRef = useRef<HTMLTableCellElement>(null);\n const handleRef = useRef<HTMLSpanElement>(null);\n const widthRef = useRef<number>(0);\n\n const handleMouseDown = useCallback(\n (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n\n const th = thRef.current;\n if (!th) return;\n\n const handle = handleRef.current;\n const startX = e.clientX;\n const startWidth = th.getBoundingClientRect().width;\n const cols = findCorrespondingCols(th);\n\n widthRef.current = startWidth;\n\n const onMouseMove = (ev: MouseEvent) => {\n const rawWidth = startWidth + (ev.clientX - startX);\n const newWidth = Math.max(\n minWidth,\n maxWidth !== undefined ? Math.min(maxWidth, rawWidth) : rawWidth,\n );\n th.style.width = `${newWidth}px`;\n cols.forEach((col) => {\n col.style.width = `${newWidth}px`;\n col.style.minWidth = `${newWidth}px`;\n });\n widthRef.current = newWidth;\n };\n\n const onMouseUp = () => {\n document.removeEventListener('mousemove', onMouseMove);\n document.removeEventListener('mouseup', onMouseUp);\n document.body.style.userSelect = '';\n document.body.style.cursor = '';\n handle?.classList.remove('resizable-handle--active');\n onResizeEnd?.(widthRef.current);\n\n const suppressClick = (ev: MouseEvent) => {\n ev.stopPropagation();\n ev.preventDefault();\n };\n document.addEventListener('click', suppressClick, true);\n requestAnimationFrame(() => {\n document.removeEventListener('click', suppressClick, true);\n });\n };\n\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'col-resize';\n handle?.classList.add('resizable-handle--active');\n document.addEventListener('mousemove', onMouseMove);\n document.addEventListener('mouseup', onMouseUp);\n },\n [minWidth, maxWidth, onResizeEnd],\n );\n\n if (!width || !onResizeEnd) {\n return <th {...restProps}>{children}</th>;\n }\n\n return (\n <th\n ref={thRef}\n {...restProps}\n style={{ position: 'relative', ...restProps.style }}\n >\n {children}\n <span\n ref={handleRef}\n className=\"resizable-handle\"\n style={{\n position: 'absolute',\n right: -6,\n top: 0,\n bottom: 0,\n width: 12,\n cursor: 'col-resize',\n zIndex: 10,\n }}\n onMouseDown={handleMouseDown}\n onClick={(e) => e.stopPropagation()}\n />\n </th>\n );\n};\n\nexport default ResizableTitle;\n","import { Table } from 'antd';\nimport type { TableProps, ColumnType } from 'antd/es/table';\nimport useResizableColumns from './useResizableColumns';\nimport type { ResizableConfig } from './types';\n\nexport interface ResizableTableProps<T extends object>\n extends Omit<TableProps<T>, 'components'> {\n resizableConfig?: ResizableConfig;\n}\n\nfunction ResizableTable<T extends object>(props: ResizableTableProps<T>) {\n const { columns = [], resizableConfig, ...rest } = props;\n\n const { mergedColumns, components } = useResizableColumns<T>(\n columns as ColumnType<T>[],\n resizableConfig,\n );\n\n return (\n <Table<T>\n {...rest}\n columns={mergedColumns}\n components={components}\n />\n );\n}\n\nexport default ResizableTable;\n"],"mappings":"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","names":["jsx","jsx"]}
|
package/dist/style.css
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "resizable-pro-table",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "ProTable with resizable columns for Ant Design",
|
|
5
5
|
"author": "yinzhimin",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"peerDependencies": {
|
|
27
27
|
"react": ">=17.0.0",
|
|
28
28
|
"react-dom": ">=17.0.0",
|
|
29
|
-
"antd": ">=
|
|
29
|
+
"antd": ">=4.0.0",
|
|
30
30
|
"@ant-design/pro-components": ">=2.0.0"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|