@canvas-components/react-list-table 0.3.36 → 0.3.38
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/dist/index.cjs +265 -115
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +265 -115
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -3573,6 +3573,37 @@ var toolButtonStyle = {
|
|
|
3573
3573
|
lineHeight: 1,
|
|
3574
3574
|
cursor: "pointer"
|
|
3575
3575
|
};
|
|
3576
|
+
function readExportCache(storageKey) {
|
|
3577
|
+
if (!storageKey) return null;
|
|
3578
|
+
try {
|
|
3579
|
+
const value = JSON.parse(localStorage.getItem(`canvas-table-export:${storageKey}`) ?? "null");
|
|
3580
|
+
if (value?.version !== 1 || !Array.isArray(value.rows) || !Array.isArray(value.selectedKeys) || !value.selectedKeys.every((key) => typeof key === "string") || typeof value.includeSummary !== "boolean") return null;
|
|
3581
|
+
if (!value.rows.every((row) => row && typeof row.key === "string" && ["default", "ascend", "descend"].includes(row.sortOrder) && summaryOptions.some((option) => option.value === row.summaryType) && roundingOptions.some((option) => option.value === row.roundingMode) && ["yes", "no"].includes(row.showTypePrefix) && ["yes", "no"].includes(row.preserveTrailingZeros) && (row.precision == null || Number.isInteger(row.precision) && row.precision >= 0 && row.precision <= 20) && (row.sortIndex == null || Number.isFinite(row.sortIndex)) && (row.sortPriority == null || Number.isFinite(row.sortPriority)))) return null;
|
|
3582
|
+
return value;
|
|
3583
|
+
} catch {
|
|
3584
|
+
return null;
|
|
3585
|
+
}
|
|
3586
|
+
}
|
|
3587
|
+
function writeExportCache(storageKey, value) {
|
|
3588
|
+
if (!storageKey) return;
|
|
3589
|
+
try {
|
|
3590
|
+
const key = `canvas-table-export:${storageKey}`;
|
|
3591
|
+
if (value) localStorage.setItem(key, JSON.stringify(value));
|
|
3592
|
+
else localStorage.removeItem(key);
|
|
3593
|
+
} catch {
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
function restoreExportRows(columns, cache) {
|
|
3597
|
+
const current = new Map(createExportDialogRows(columns).map((row) => [row.key, row]));
|
|
3598
|
+
const rows = [];
|
|
3599
|
+
cache?.rows.forEach((saved) => {
|
|
3600
|
+
const row = current.get(saved.key);
|
|
3601
|
+
if (!row) return;
|
|
3602
|
+
rows.push({ ...saved, key: row.key, title: row.title });
|
|
3603
|
+
current.delete(saved.key);
|
|
3604
|
+
});
|
|
3605
|
+
return [...rows, ...current.values()];
|
|
3606
|
+
}
|
|
3576
3607
|
var sortOptions = [
|
|
3577
3608
|
{ value: "default", label: "\u9ED8\u8BA4" },
|
|
3578
3609
|
{ value: "ascend", label: "\u5347\u5E8F" },
|
|
@@ -3644,18 +3675,34 @@ function buildExportDialogSettings(rows, selectedKeys, includeSummary) {
|
|
|
3644
3675
|
function ReactListTableExportNameDialog({
|
|
3645
3676
|
request,
|
|
3646
3677
|
onClose,
|
|
3647
|
-
renderTable
|
|
3678
|
+
renderTable,
|
|
3679
|
+
storageKey
|
|
3648
3680
|
}) {
|
|
3649
3681
|
const tableId = react.useId();
|
|
3682
|
+
const tableHostRef = react.useRef(null);
|
|
3683
|
+
const [tableWidth, setTableWidth] = react.useState(0);
|
|
3684
|
+
react.useEffect(() => {
|
|
3685
|
+
const host = tableHostRef.current;
|
|
3686
|
+
if (!host || typeof ResizeObserver === "undefined") return;
|
|
3687
|
+
const update = () => setTableWidth(host.clientWidth);
|
|
3688
|
+
update();
|
|
3689
|
+
const observer = new ResizeObserver(update);
|
|
3690
|
+
observer.observe(host);
|
|
3691
|
+
return () => observer.disconnect();
|
|
3692
|
+
}, []);
|
|
3650
3693
|
const extension = request.fileName.match(/\.(xlsx|csv|txt|json)$/i)?.[0] ?? "";
|
|
3651
3694
|
const [fileName, setFileName] = react.useState(
|
|
3652
3695
|
extension ? request.fileName.slice(0, -extension.length) : request.fileName
|
|
3653
3696
|
);
|
|
3654
|
-
const [
|
|
3697
|
+
const [cached] = react.useState(() => readExportCache(storageKey));
|
|
3698
|
+
const [cacheEnabled, setCacheEnabled] = react.useState(Boolean(storageKey));
|
|
3699
|
+
const [rows, setRows] = react.useState(() => restoreExportRows(request.columns ?? [], cached));
|
|
3655
3700
|
const [selectedKeys, setSelectedKeys] = react.useState(
|
|
3656
|
-
() => (request.columns ?? []).filter((column) => column.selected !== false).map((column) => column.key)
|
|
3701
|
+
() => (request.columns ?? []).filter((column) => cached?.rows.some((row) => row.key === column.key) ? cached.selectedKeys.includes(column.key) : column.selected !== false).map((column) => column.key)
|
|
3702
|
+
);
|
|
3703
|
+
const [includeSummary, setIncludeSummary] = react.useState(
|
|
3704
|
+
() => cached?.includeSummary ?? (request.includeSummary === true || (request.columns?.some((column) => column.summary.type !== "none") ?? false))
|
|
3657
3705
|
);
|
|
3658
|
-
const [includeSummary, setIncludeSummary] = react.useState(request.includeSummary ?? false);
|
|
3659
3706
|
const [error, setError] = react.useState("");
|
|
3660
3707
|
const columns = react.useMemo(
|
|
3661
3708
|
() => [
|
|
@@ -3733,9 +3780,16 @@ function ReactListTableExportNameDialog({
|
|
|
3733
3780
|
],
|
|
3734
3781
|
[includeSummary, request.columns]
|
|
3735
3782
|
);
|
|
3783
|
+
const fittedColumns = react.useMemo(
|
|
3784
|
+
() => fitExportDialogColumns(columns, tableWidth),
|
|
3785
|
+
[columns, tableWidth]
|
|
3786
|
+
);
|
|
3736
3787
|
const confirm = () => {
|
|
3737
3788
|
if (!fileName.trim()) return setError("\u8BF7\u8F93\u5165\u6587\u4EF6\u540D\u79F0");
|
|
3738
3789
|
if (request.columns && !selectedKeys.length) return setError("\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u5217");
|
|
3790
|
+
if (request.columns && cacheEnabled) {
|
|
3791
|
+
writeExportCache(storageKey, { version: 1, rows, selectedKeys: selectedKeys.map(String), includeSummary });
|
|
3792
|
+
}
|
|
3739
3793
|
request.onConfirm(
|
|
3740
3794
|
`${fileName.trim()}${extension}`,
|
|
3741
3795
|
request.columns ? buildExportDialogSettings(rows, selectedKeys, includeSummary) : void 0
|
|
@@ -3747,7 +3801,7 @@ function ReactListTableExportNameDialog({
|
|
|
3747
3801
|
{
|
|
3748
3802
|
open: true,
|
|
3749
3803
|
title: "\u5BFC\u51FA\u6587\u4EF6",
|
|
3750
|
-
width: request.columns ? 1180 : 420,
|
|
3804
|
+
width: request.columns ? includeSummary ? 1320 : 1180 : 420,
|
|
3751
3805
|
fullscreenable: false,
|
|
3752
3806
|
onOk: confirm,
|
|
3753
3807
|
okText: "\u5BFC\u51FA",
|
|
@@ -3780,6 +3834,27 @@ function ReactListTableExportNameDialog({
|
|
|
3780
3834
|
request.columns ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginTop: 16 }, children: [
|
|
3781
3835
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 16, marginBottom: 8 }, children: [
|
|
3782
3836
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600 }, children: "\u5BFC\u51FA\u8868\u683C\u5217" }),
|
|
3837
|
+
storageKey ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3838
|
+
"label",
|
|
3839
|
+
{
|
|
3840
|
+
style: { display: "inline-flex", alignItems: "center", gap: 6 },
|
|
3841
|
+
title: "\u5BFC\u51FA\u65F6\u4FDD\u5B58\u914D\u7F6E\uFF0C\u4E0B\u6B21\u6253\u5F00\u81EA\u52A8\u6062\u590D\uFF1B\u53D6\u6D88\u52FE\u9009\u6E05\u9664\u7F13\u5B58",
|
|
3842
|
+
children: [
|
|
3843
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3844
|
+
reactComponents.ReactCheckbox,
|
|
3845
|
+
{
|
|
3846
|
+
checked: cacheEnabled,
|
|
3847
|
+
"aria-label": "\u7F13\u5B58\u5BFC\u51FA\u914D\u7F6E",
|
|
3848
|
+
onChange: (event) => {
|
|
3849
|
+
setCacheEnabled(event.target.checked);
|
|
3850
|
+
if (!event.target.checked) writeExportCache(storageKey, null);
|
|
3851
|
+
}
|
|
3852
|
+
}
|
|
3853
|
+
),
|
|
3854
|
+
"\u7F13\u5B58\u5BFC\u51FA\u914D\u7F6E"
|
|
3855
|
+
]
|
|
3856
|
+
}
|
|
3857
|
+
) : null,
|
|
3783
3858
|
/* @__PURE__ */ jsxRuntime.jsxs("label", { style: { display: "inline-flex", alignItems: "center", gap: 6 }, children: [
|
|
3784
3859
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3785
3860
|
reactComponents.ReactCheckbox,
|
|
@@ -3792,9 +3867,9 @@ function ReactListTableExportNameDialog({
|
|
|
3792
3867
|
"\u5BFC\u51FA\u6C47\u603B\u884C"
|
|
3793
3868
|
] })
|
|
3794
3869
|
] }),
|
|
3795
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: "min(45vh, 520px)", minHeight: 250, overflow: "hidden" }, children: renderTable({
|
|
3870
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: tableHostRef, style: { height: "min(45vh, 520px)", minHeight: 250, overflow: "hidden" }, children: renderTable({
|
|
3796
3871
|
tableId,
|
|
3797
|
-
columns,
|
|
3872
|
+
columns: fittedColumns,
|
|
3798
3873
|
dataSource: rows,
|
|
3799
3874
|
rowKey: "key",
|
|
3800
3875
|
rowHeight: 42,
|
|
@@ -3839,6 +3914,17 @@ function ReactListTableExportNameDialog({
|
|
|
3839
3914
|
}
|
|
3840
3915
|
);
|
|
3841
3916
|
}
|
|
3917
|
+
function fitExportDialogColumns(columns, availableWidth) {
|
|
3918
|
+
if (availableWidth <= 0) return columns;
|
|
3919
|
+
const totalWidth = (items) => items.reduce((sum, column) => sum + (column.key === listTable.ROW_SELECTION_COLUMN.key ? 0 : column.children?.length ? totalWidth(column.children) : Number(column.width) || 160), 0);
|
|
3920
|
+
const ratio = Math.min(1, Math.max(availableWidth - 54 - 32, 1) / totalWidth(columns));
|
|
3921
|
+
const fit = (items) => items.map((column) => {
|
|
3922
|
+
if (column.key === listTable.ROW_SELECTION_COLUMN.key) return column;
|
|
3923
|
+
if (column.children?.length) return { ...column, children: fit(column.children) };
|
|
3924
|
+
return { ...column, width: Math.max(1, Math.floor((Number(column.width) || 160) * ratio)), minWidth: 1 };
|
|
3925
|
+
});
|
|
3926
|
+
return fit(columns);
|
|
3927
|
+
}
|
|
3842
3928
|
|
|
3843
3929
|
// src/features/editor/utils.ts
|
|
3844
3930
|
function toNumberValue(value) {
|
|
@@ -5003,14 +5089,18 @@ function SortableList(props) {
|
|
|
5003
5089
|
);
|
|
5004
5090
|
react.useEffect(() => {
|
|
5005
5091
|
if (!dragState) return;
|
|
5006
|
-
const
|
|
5092
|
+
const scrollContainer = props.scrollContainerRef?.current;
|
|
5093
|
+
let frameId = 0;
|
|
5094
|
+
let lastTime = null;
|
|
5095
|
+
const updateTarget = () => {
|
|
5007
5096
|
const current = dragRef.current;
|
|
5008
5097
|
if (!current) return;
|
|
5009
5098
|
const target = resolveClosestSortableItem({
|
|
5010
5099
|
items,
|
|
5011
5100
|
parentKey: current.source.parentKey,
|
|
5012
5101
|
layouts: current.layouts,
|
|
5013
|
-
|
|
5102
|
+
// 保留拖拽开始时的布局,补偿滚动位移,避免受行交换动画影响。
|
|
5103
|
+
overlayCenterY: current.pointerY - current.offsetY + current.height / 2 + current.rootTop - (rootRef.current?.getBoundingClientRect().top ?? current.rootTop)
|
|
5014
5104
|
});
|
|
5015
5105
|
if (target) {
|
|
5016
5106
|
current.target = target;
|
|
@@ -5018,12 +5108,44 @@ function SortableList(props) {
|
|
|
5018
5108
|
setDragState({
|
|
5019
5109
|
sourceKey: current.source.key,
|
|
5020
5110
|
targetKey: current.target.key,
|
|
5021
|
-
pointerY:
|
|
5111
|
+
pointerY: current.pointerY
|
|
5022
5112
|
});
|
|
5023
5113
|
};
|
|
5024
|
-
const
|
|
5114
|
+
const handleMove = (event) => {
|
|
5115
|
+
const current = dragRef.current;
|
|
5116
|
+
if (!current || event.pointerId !== current.pointerId) return;
|
|
5117
|
+
current.pointerY = event.clientY;
|
|
5118
|
+
updateTarget();
|
|
5119
|
+
};
|
|
5120
|
+
const tick = (time) => {
|
|
5121
|
+
const current = dragRef.current;
|
|
5122
|
+
if (!current) return;
|
|
5123
|
+
const elapsed = lastTime == null ? 0 : Math.min(time - lastTime, 50);
|
|
5124
|
+
lastTime = time;
|
|
5125
|
+
if (scrollContainer) {
|
|
5126
|
+
const rect = scrollContainer.getBoundingClientRect();
|
|
5127
|
+
const top = rect.top + scrollContainer.clientTop;
|
|
5128
|
+
const height = scrollContainer.clientHeight;
|
|
5129
|
+
const edge = Math.min(40, height / 2);
|
|
5130
|
+
const bottom = top + height;
|
|
5131
|
+
const direction = edge <= 0 ? 0 : current.pointerY < top + edge ? -Math.min(1, (top + edge - current.pointerY) / edge) : current.pointerY > bottom - edge ? Math.min(1, (current.pointerY - bottom + edge) / edge) : 0;
|
|
5132
|
+
if (direction) {
|
|
5133
|
+
scrollContainer.scrollTop = Math.max(
|
|
5134
|
+
0,
|
|
5135
|
+
Math.min(
|
|
5136
|
+
scrollContainer.scrollHeight - height,
|
|
5137
|
+
scrollContainer.scrollTop + direction * elapsed * 0.5
|
|
5138
|
+
)
|
|
5139
|
+
);
|
|
5140
|
+
updateTarget();
|
|
5141
|
+
}
|
|
5142
|
+
}
|
|
5143
|
+
frameId = requestAnimationFrame(tick);
|
|
5144
|
+
};
|
|
5145
|
+
const finish = (commit) => {
|
|
5025
5146
|
const current = dragRef.current;
|
|
5026
|
-
|
|
5147
|
+
cancelAnimationFrame(frameId);
|
|
5148
|
+
if (commit && current && current.source.key !== current.target.key) {
|
|
5027
5149
|
const siblings = items.filter(
|
|
5028
5150
|
(item) => item.parentKey === current.source.parentKey
|
|
5029
5151
|
);
|
|
@@ -5041,15 +5163,30 @@ function SortableList(props) {
|
|
|
5041
5163
|
document.body.classList.remove("react-list-table-sorting");
|
|
5042
5164
|
document.body.style.removeProperty("user-select");
|
|
5043
5165
|
};
|
|
5166
|
+
const handleEnd = (event) => {
|
|
5167
|
+
if (event.pointerId !== dragRef.current?.pointerId) return;
|
|
5168
|
+
handleMove(event);
|
|
5169
|
+
finish(true);
|
|
5170
|
+
};
|
|
5171
|
+
const handleCancel = (event) => {
|
|
5172
|
+
if (event.pointerId === dragRef.current?.pointerId) finish(false);
|
|
5173
|
+
};
|
|
5174
|
+
const handleBlur = () => finish(false);
|
|
5175
|
+
frameId = requestAnimationFrame(tick);
|
|
5176
|
+
scrollContainer?.addEventListener("scroll", updateTarget);
|
|
5044
5177
|
window.addEventListener("pointermove", handleMove);
|
|
5045
|
-
window.addEventListener("pointerup", handleEnd
|
|
5046
|
-
window.addEventListener("pointercancel",
|
|
5178
|
+
window.addEventListener("pointerup", handleEnd);
|
|
5179
|
+
window.addEventListener("pointercancel", handleCancel);
|
|
5180
|
+
window.addEventListener("blur", handleBlur);
|
|
5047
5181
|
return () => {
|
|
5182
|
+
cancelAnimationFrame(frameId);
|
|
5183
|
+
scrollContainer?.removeEventListener("scroll", updateTarget);
|
|
5048
5184
|
window.removeEventListener("pointermove", handleMove);
|
|
5049
5185
|
window.removeEventListener("pointerup", handleEnd);
|
|
5050
|
-
window.removeEventListener("pointercancel",
|
|
5186
|
+
window.removeEventListener("pointercancel", handleCancel);
|
|
5187
|
+
window.removeEventListener("blur", handleBlur);
|
|
5051
5188
|
};
|
|
5052
|
-
}, [dragState != null, items, onOrderChange]);
|
|
5189
|
+
}, [dragState != null, items, onOrderChange, props.scrollContainerRef]);
|
|
5053
5190
|
const sourceIndex = dragState ? items.findIndex((item) => item.key === dragState.sourceKey) : -1;
|
|
5054
5191
|
const targetIndex = dragState ? items.findIndex((item) => item.key === dragState.targetKey) : -1;
|
|
5055
5192
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, children: [
|
|
@@ -5068,7 +5205,7 @@ function SortableList(props) {
|
|
|
5068
5205
|
style,
|
|
5069
5206
|
children: props.renderItem(item, {
|
|
5070
5207
|
onPointerDown: (event) => {
|
|
5071
|
-
if (event.button !== 0) return;
|
|
5208
|
+
if (event.button !== 0 || dragRef.current) return;
|
|
5072
5209
|
const row = event.currentTarget.closest(
|
|
5073
5210
|
"[data-sortable-key]"
|
|
5074
5211
|
);
|
|
@@ -5081,7 +5218,10 @@ function SortableList(props) {
|
|
|
5081
5218
|
offsetY: event.clientY - rect.top,
|
|
5082
5219
|
width: rect.width,
|
|
5083
5220
|
left: rect.left,
|
|
5084
|
-
height: rect.height
|
|
5221
|
+
height: rect.height,
|
|
5222
|
+
pointerId: event.pointerId,
|
|
5223
|
+
pointerY: event.clientY,
|
|
5224
|
+
rootTop: rootRef.current?.getBoundingClientRect().top ?? 0
|
|
5085
5225
|
};
|
|
5086
5226
|
setDragState({
|
|
5087
5227
|
sourceKey: item.key,
|
|
@@ -5168,13 +5308,14 @@ function resolveSortableTransform(index, sourceIndex, targetIndex, height) {
|
|
|
5168
5308
|
}
|
|
5169
5309
|
|
|
5170
5310
|
// src/features/toolbar/style.css
|
|
5171
|
-
styleInject(".react-list-table-shell {\n background: #fff;\n font-size: 14px;\n}\n.react-list-table-titlebar {\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n box-sizing: border-box;\n background: #fff;\n}\n.react-list-table-shell-fullscreen {\n width: 100% !important;\n height: 100% !important;\n}\n.react-list-table-shell-fullscreen .canvas-list-table-root {\n height: 100% !important;\n}\n.react-list-table-title {\n min-width: 0;\n color: #1f2937;\n font-size: 14px;\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-tools {\n display: flex;\n align-items: center;\n gap: 14px;\n color: #475569;\n}\n.react-list-table-tool-wrap {\n position: relative;\n display: inline-flex;\n}\n.react-list-table-tool {\n width: 20px;\n height: 24px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n font: 16px/24px sans-serif;\n cursor: pointer;\n}\n.react-list-table-tool:hover {\n color: #1677ff;\n}\n.react-list-table-tool-menu,\n.react-list-table-column-setting {\n position: absolute;\n z-index: 120;\n top: 28px;\n right: 0;\n min-width: 112px;\n padding: 6px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);\n}\n.react-list-table-tool-menu button {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #374151;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n}\n.react-list-table-tool-menu {\n width: max-content;\n min-width: 0;\n padding: 8px;\n border-radius: 8px;\n}\n.react-list-table-tool-menu-check {\n width: 16px;\n flex: 0 0 16px;\n margin-right: 6px;\n text-align: center;\n}\n.react-list-table-tool-menu button:hover {\n background: #f3f4f6;\n}\n.react-list-table-column-setting {\n width: 328px;\n max-height: 360px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.react-list-table-column-setting-head {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 4px 6px 8px;\n border-bottom: 1px solid #f0f0f0;\n flex: 0 0 auto;\n}\n.react-list-table-column-setting-head button {\n border: 0;\n color: #1677ff;\n background: transparent;\n cursor: pointer;\n}\n.react-list-table-column-setting-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.react-list-table-column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n padding: 7px 6px;\n box-sizing: border-box;\n cursor: pointer;\n}\n.react-list-table-column-main,\n.react-list-table-column-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.react-list-table-column-main {\n min-width: 0;\n}\n.react-list-table-column-actions {\n flex: 0 0 auto;\n}\n.react-list-table-column-actions > .canvas-react-select-wrap {\n flex: 0 0 96px;\n width: 96px;\n height: 24px;\n}\n.react-list-table-column-label {\n min-width: 64px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-column-width-input {\n height: 22px;\n padding-inline: 5px;\n}\n.react-list-table-column-fixed-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-sort-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-setting label.dragging {\n opacity: 0.45;\n background: #e6f4ff;\n}\n.react-list-table-column-setting [data-sortable-key].dragging {\n opacity: 0.28;\n}\n.react-list-table-column-drag {\n color: #94a3b8;\n display: inline-flex;\n font-size: 14px;\n cursor: grab;\n user-select: none;\n}\nbody.react-list-table-sorting,\nbody.react-list-table-sorting * {\n cursor: grabbing !important;\n}\n.react-list-table-sort-overlay {\n position: fixed;\n z-index: 1400;\n display: block;\n padding: 0;\n box-sizing: border-box;\n color: #334155;\n background: #fff;\n border: 1px solid #91caff;\n border-radius: 6px;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);\n pointer-events: none;\n}\n.react-list-table-sort-overlay .react-list-table-column-item {\n width: 100%;\n height: 100%;\n}\n");
|
|
5311
|
+
styleInject(".react-list-table-shell {\n background: #fff;\n font-size: 14px;\n}\n.react-list-table-titlebar {\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n box-sizing: border-box;\n background: #fff;\n}\n.react-list-table-shell-fullscreen {\n width: 100% !important;\n height: 100% !important;\n}\n.react-list-table-shell-fullscreen .canvas-list-table-root {\n height: 100% !important;\n}\n.react-list-table-title {\n min-width: 0;\n color: #1f2937;\n font-size: 14px;\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-tools {\n display: flex;\n align-items: center;\n gap: 14px;\n color: #475569;\n}\n.react-list-table-tool-wrap {\n position: relative;\n display: inline-flex;\n}\n.react-list-table-tool {\n width: 20px;\n height: 24px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n font: 16px/24px sans-serif;\n cursor: pointer;\n}\n.react-list-table-tool:hover {\n color: #1677ff;\n}\n.react-list-table-tool-menu,\n.react-list-table-column-setting {\n position: absolute;\n z-index: 120;\n top: 28px;\n right: 0;\n min-width: 112px;\n padding: 6px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);\n}\n.react-list-table-tool-menu button {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #374151;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n}\n.react-list-table-tool-menu {\n width: max-content;\n min-width: 0;\n padding: 8px;\n border-radius: 8px;\n}\n.react-list-table-tool-menu-check {\n width: 16px;\n flex: 0 0 16px;\n margin-right: 6px;\n text-align: center;\n}\n.react-list-table-tool-menu button:hover {\n background: #f3f4f6;\n}\n.react-list-table-column-setting {\n width: 328px;\n max-height: 360px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.react-list-table-column-setting-head {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 4px 6px 8px;\n border-bottom: 1px solid #f0f0f0;\n flex: 0 0 auto;\n}\n.react-list-table-column-setting-head button {\n border: 0;\n color: #1677ff;\n background: transparent;\n cursor: pointer;\n}\n.react-list-table-column-setting-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.react-list-table-column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n padding: 7px 6px;\n box-sizing: border-box;\n cursor: pointer;\n}\n.react-list-table-column-main,\n.react-list-table-column-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.react-list-table-column-main {\n min-width: 0;\n}\n.react-list-table-column-actions {\n flex: 0 0 auto;\n}\n.react-list-table-column-actions > .canvas-react-select-wrap {\n flex: 0 0 96px;\n width: 96px;\n height: 24px;\n}\n.react-list-table-column-label {\n min-width: 64px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-column-width-input {\n height: 22px;\n padding-inline: 5px;\n}\n.react-list-table-column-fixed-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-sort-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-setting label.dragging {\n opacity: 0.45;\n background: #e6f4ff;\n}\n.react-list-table-column-setting [data-sortable-key].dragging {\n opacity: 0.28;\n}\n.react-list-table-column-drag {\n touch-action: none;\n color: #94a3b8;\n display: inline-flex;\n font-size: 14px;\n cursor: grab;\n user-select: none;\n}\nbody.react-list-table-sorting,\nbody.react-list-table-sorting * {\n cursor: grabbing !important;\n}\n.react-list-table-sort-overlay {\n position: fixed;\n z-index: 1400;\n display: block;\n padding: 0;\n box-sizing: border-box;\n color: #334155;\n background: #fff;\n border: 1px solid #91caff;\n border-radius: 6px;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);\n pointer-events: none;\n}\n.react-list-table-sort-overlay .react-list-table-column-item {\n width: 100%;\n height: 100%;\n}\n");
|
|
5172
5312
|
function ReactTableToolbar(props) {
|
|
5173
5313
|
const { toolbar, title } = props;
|
|
5174
5314
|
const [densityOpen, setDensityOpen] = react.useState(false);
|
|
5175
5315
|
const [settingOpen, setSettingOpen] = react.useState(false);
|
|
5176
5316
|
const [isFullscreen, setIsFullscreen] = react.useState(false);
|
|
5177
5317
|
const rootRef = react.useRef(null);
|
|
5318
|
+
const columnSettingsBodyRef = react.useRef(null);
|
|
5178
5319
|
const hasToolbar = toolbar !== void 0 && toolbar !== false;
|
|
5179
5320
|
react.useEffect(() => {
|
|
5180
5321
|
const close = (event) => {
|
|
@@ -5313,116 +5454,124 @@ function ReactTableToolbar(props) {
|
|
|
5313
5454
|
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: "auto" }, children: config.columnSettingHeaderExtra }),
|
|
5314
5455
|
/* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: props.onResetColumns, children: "\u91CD\u7F6E" })
|
|
5315
5456
|
] }),
|
|
5316
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5317
|
-
|
|
5457
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5458
|
+
"div",
|
|
5318
5459
|
{
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5460
|
+
ref: columnSettingsBodyRef,
|
|
5461
|
+
className: "react-list-table-column-setting-body canvas-react-scrollbar",
|
|
5462
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
5463
|
+
SortableList,
|
|
5464
|
+
{
|
|
5465
|
+
scrollContainerRef: columnSettingsBodyRef,
|
|
5466
|
+
items: flattenColumns(props.columns),
|
|
5467
|
+
onOrderChange: props.onColumnOrderChange,
|
|
5468
|
+
renderItem: (column, handleProps) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-column-item", children: [
|
|
5469
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5470
|
+
"span",
|
|
5471
|
+
{
|
|
5472
|
+
className: "react-list-table-column-main",
|
|
5473
|
+
style: { paddingLeft: column.level * 16 },
|
|
5474
|
+
children: [
|
|
5475
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5476
|
+
"span",
|
|
5477
|
+
{
|
|
5478
|
+
className: "react-list-table-column-drag",
|
|
5479
|
+
...handleProps,
|
|
5480
|
+
onClick: (event) => {
|
|
5481
|
+
event.preventDefault();
|
|
5482
|
+
event.stopPropagation();
|
|
5483
|
+
},
|
|
5484
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(HolderOutlined, {})
|
|
5485
|
+
}
|
|
5486
|
+
),
|
|
5487
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5488
|
+
"input",
|
|
5489
|
+
{
|
|
5490
|
+
type: "checkbox",
|
|
5491
|
+
checked: !column.hidden,
|
|
5492
|
+
disabled: column.disableHide,
|
|
5493
|
+
onChange: (event) => props.onColumnVisibilityChange(
|
|
5494
|
+
column.key,
|
|
5495
|
+
event.target.checked
|
|
5496
|
+
)
|
|
5497
|
+
}
|
|
5498
|
+
),
|
|
5499
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "react-list-table-column-label", children: column.label })
|
|
5500
|
+
]
|
|
5501
|
+
}
|
|
5502
|
+
),
|
|
5503
|
+
!column.isGroup ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "react-list-table-column-actions", children: [
|
|
5328
5504
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5329
|
-
|
|
5505
|
+
reactComponents.ReactNumberInput,
|
|
5330
5506
|
{
|
|
5331
|
-
className: "react-list-table-column-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
|
|
5336
|
-
}
|
|
5337
|
-
|
|
5507
|
+
className: "react-list-table-column-width-input",
|
|
5508
|
+
min: column.minWidth,
|
|
5509
|
+
max: column.maxWidth,
|
|
5510
|
+
value: column.width,
|
|
5511
|
+
allowClear: false,
|
|
5512
|
+
"aria-label": `${column.label}\u5217\u5BBD`,
|
|
5513
|
+
style: { width: 80, height: 24 },
|
|
5514
|
+
onChange: (width) => {
|
|
5515
|
+
if (width != null && Number.isFinite(width) && width > 0 && (column.minWidth == null || width >= column.minWidth) && (column.maxWidth == null || width <= column.maxWidth)) {
|
|
5516
|
+
props.onColumnWidthChange(
|
|
5517
|
+
column.key,
|
|
5518
|
+
width
|
|
5519
|
+
);
|
|
5520
|
+
}
|
|
5521
|
+
}
|
|
5338
5522
|
}
|
|
5339
5523
|
),
|
|
5340
5524
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5341
|
-
|
|
5525
|
+
reactComponents.ReactSelect,
|
|
5342
5526
|
{
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5346
|
-
|
|
5527
|
+
className: "react-list-table-column-sort-input",
|
|
5528
|
+
value: props.sortState.find(
|
|
5529
|
+
(item) => item.key === column.key
|
|
5530
|
+
)?.order ?? "default",
|
|
5531
|
+
options: [
|
|
5532
|
+
{ label: "\u9ED8\u8BA4\u6392\u5E8F", value: "default" },
|
|
5533
|
+
{ label: "\u5347\u5E8F", value: "ascend" },
|
|
5534
|
+
{ label: "\u964D\u5E8F", value: "descend" }
|
|
5535
|
+
],
|
|
5536
|
+
disabled: !column.sortable,
|
|
5537
|
+
allowClear: false,
|
|
5538
|
+
showSearch: false,
|
|
5539
|
+
style: { width: "100%", height: 24 },
|
|
5540
|
+
"aria-label": `${column.label}\u6392\u5E8F\u65B9\u5F0F`,
|
|
5541
|
+
onChange: (value) => props.onColumnSortChange(
|
|
5347
5542
|
column.key,
|
|
5348
|
-
|
|
5543
|
+
value === "ascend" || value === "descend" ? value : null
|
|
5349
5544
|
)
|
|
5350
5545
|
}
|
|
5351
5546
|
),
|
|
5352
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
);
|
|
5547
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5548
|
+
reactComponents.ReactSelect,
|
|
5549
|
+
{
|
|
5550
|
+
className: "react-list-table-column-fixed-input",
|
|
5551
|
+
value: column.fixed ?? "none",
|
|
5552
|
+
options: [
|
|
5553
|
+
{ label: "\u4E0D\u56FA\u5B9A", value: "none" },
|
|
5554
|
+
{ label: "\u56FA\u5B9A\u5DE6\u4FA7", value: "left" },
|
|
5555
|
+
{ label: "\u56FA\u5B9A\u53F3\u4FA7", value: "right" }
|
|
5556
|
+
],
|
|
5557
|
+
allowClear: false,
|
|
5558
|
+
showSearch: false,
|
|
5559
|
+
style: { width: "100%", height: 24 },
|
|
5560
|
+
"aria-label": `${column.label}\u56FA\u5B9A\u65B9\u5411`,
|
|
5561
|
+
onChange: (value) => {
|
|
5562
|
+
props.onColumnFixedChange(
|
|
5563
|
+
column.key,
|
|
5564
|
+
value === "left" || value === "right" ? value : void 0
|
|
5565
|
+
);
|
|
5566
|
+
}
|
|
5373
5567
|
}
|
|
5374
|
-
}
|
|
5375
|
-
}
|
|
5376
|
-
),
|
|
5377
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5378
|
-
reactComponents.ReactSelect,
|
|
5379
|
-
{
|
|
5380
|
-
className: "react-list-table-column-sort-input",
|
|
5381
|
-
value: props.sortState.find(
|
|
5382
|
-
(item) => item.key === column.key
|
|
5383
|
-
)?.order ?? "default",
|
|
5384
|
-
options: [
|
|
5385
|
-
{ label: "\u9ED8\u8BA4\u6392\u5E8F", value: "default" },
|
|
5386
|
-
{ label: "\u5347\u5E8F", value: "ascend" },
|
|
5387
|
-
{ label: "\u964D\u5E8F", value: "descend" }
|
|
5388
|
-
],
|
|
5389
|
-
disabled: !column.sortable,
|
|
5390
|
-
allowClear: false,
|
|
5391
|
-
showSearch: false,
|
|
5392
|
-
style: { width: "100%", height: 24 },
|
|
5393
|
-
"aria-label": `${column.label}\u6392\u5E8F\u65B9\u5F0F`,
|
|
5394
|
-
onChange: (value) => props.onColumnSortChange(
|
|
5395
|
-
column.key,
|
|
5396
|
-
value === "ascend" || value === "descend" ? value : null
|
|
5397
5568
|
)
|
|
5398
|
-
}
|
|
5399
|
-
)
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
{
|
|
5403
|
-
className: "react-list-table-column-fixed-input",
|
|
5404
|
-
value: column.fixed ?? "none",
|
|
5405
|
-
options: [
|
|
5406
|
-
{ label: "\u4E0D\u56FA\u5B9A", value: "none" },
|
|
5407
|
-
{ label: "\u56FA\u5B9A\u5DE6\u4FA7", value: "left" },
|
|
5408
|
-
{ label: "\u56FA\u5B9A\u53F3\u4FA7", value: "right" }
|
|
5409
|
-
],
|
|
5410
|
-
allowClear: false,
|
|
5411
|
-
showSearch: false,
|
|
5412
|
-
style: { width: "100%", height: 24 },
|
|
5413
|
-
"aria-label": `${column.label}\u56FA\u5B9A\u65B9\u5411`,
|
|
5414
|
-
onChange: (value) => {
|
|
5415
|
-
props.onColumnFixedChange(
|
|
5416
|
-
column.key,
|
|
5417
|
-
value === "left" || value === "right" ? value : void 0
|
|
5418
|
-
);
|
|
5419
|
-
}
|
|
5420
|
-
}
|
|
5421
|
-
)
|
|
5422
|
-
] }) : null
|
|
5423
|
-
] })
|
|
5569
|
+
] }) : null
|
|
5570
|
+
] })
|
|
5571
|
+
}
|
|
5572
|
+
)
|
|
5424
5573
|
}
|
|
5425
|
-
)
|
|
5574
|
+
)
|
|
5426
5575
|
]
|
|
5427
5576
|
}
|
|
5428
5577
|
) : null
|
|
@@ -6203,6 +6352,7 @@ function ReactListTableInner(props, ref) {
|
|
|
6203
6352
|
ReactListTableExportNameDialog,
|
|
6204
6353
|
{
|
|
6205
6354
|
request: exportNameRequest,
|
|
6355
|
+
storageKey: storageKey ? `list:${storageKey}` : void 0,
|
|
6206
6356
|
onClose: closeExportNameRequest,
|
|
6207
6357
|
renderTable: (tableProps) => /* @__PURE__ */ jsxRuntime.jsx(ReactListTable, { ...tableProps })
|
|
6208
6358
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -111,9 +111,11 @@ interface ExportDialogRow {
|
|
|
111
111
|
preserveTrailingZeros: "yes" | "no";
|
|
112
112
|
}
|
|
113
113
|
/** 使用 ReactListTable 承载大量导出列的弹窗。 */
|
|
114
|
-
declare function ReactListTableExportNameDialog({ request, onClose, renderTable, }: {
|
|
114
|
+
declare function ReactListTableExportNameDialog({ request, onClose, renderTable, storageKey, }: {
|
|
115
115
|
request: ListTableExportNameRequest;
|
|
116
116
|
onClose?: () => void;
|
|
117
|
+
/** 用于隔离不同表格的导出配置缓存。 */
|
|
118
|
+
storageKey?: string;
|
|
117
119
|
renderTable: (props: ReactListTableProps<ExportDialogRow>) => ReactNode;
|
|
118
120
|
}): react.JSX.Element;
|
|
119
121
|
|
package/dist/index.d.ts
CHANGED
|
@@ -111,9 +111,11 @@ interface ExportDialogRow {
|
|
|
111
111
|
preserveTrailingZeros: "yes" | "no";
|
|
112
112
|
}
|
|
113
113
|
/** 使用 ReactListTable 承载大量导出列的弹窗。 */
|
|
114
|
-
declare function ReactListTableExportNameDialog({ request, onClose, renderTable, }: {
|
|
114
|
+
declare function ReactListTableExportNameDialog({ request, onClose, renderTable, storageKey, }: {
|
|
115
115
|
request: ListTableExportNameRequest;
|
|
116
116
|
onClose?: () => void;
|
|
117
|
+
/** 用于隔离不同表格的导出配置缓存。 */
|
|
118
|
+
storageKey?: string;
|
|
117
119
|
renderTable: (props: ReactListTableProps<ExportDialogRow>) => ReactNode;
|
|
118
120
|
}): react.JSX.Element;
|
|
119
121
|
|
package/dist/index.js
CHANGED
|
@@ -3572,6 +3572,37 @@ var toolButtonStyle = {
|
|
|
3572
3572
|
lineHeight: 1,
|
|
3573
3573
|
cursor: "pointer"
|
|
3574
3574
|
};
|
|
3575
|
+
function readExportCache(storageKey) {
|
|
3576
|
+
if (!storageKey) return null;
|
|
3577
|
+
try {
|
|
3578
|
+
const value = JSON.parse(localStorage.getItem(`canvas-table-export:${storageKey}`) ?? "null");
|
|
3579
|
+
if (value?.version !== 1 || !Array.isArray(value.rows) || !Array.isArray(value.selectedKeys) || !value.selectedKeys.every((key) => typeof key === "string") || typeof value.includeSummary !== "boolean") return null;
|
|
3580
|
+
if (!value.rows.every((row) => row && typeof row.key === "string" && ["default", "ascend", "descend"].includes(row.sortOrder) && summaryOptions.some((option) => option.value === row.summaryType) && roundingOptions.some((option) => option.value === row.roundingMode) && ["yes", "no"].includes(row.showTypePrefix) && ["yes", "no"].includes(row.preserveTrailingZeros) && (row.precision == null || Number.isInteger(row.precision) && row.precision >= 0 && row.precision <= 20) && (row.sortIndex == null || Number.isFinite(row.sortIndex)) && (row.sortPriority == null || Number.isFinite(row.sortPriority)))) return null;
|
|
3581
|
+
return value;
|
|
3582
|
+
} catch {
|
|
3583
|
+
return null;
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3586
|
+
function writeExportCache(storageKey, value) {
|
|
3587
|
+
if (!storageKey) return;
|
|
3588
|
+
try {
|
|
3589
|
+
const key = `canvas-table-export:${storageKey}`;
|
|
3590
|
+
if (value) localStorage.setItem(key, JSON.stringify(value));
|
|
3591
|
+
else localStorage.removeItem(key);
|
|
3592
|
+
} catch {
|
|
3593
|
+
}
|
|
3594
|
+
}
|
|
3595
|
+
function restoreExportRows(columns, cache) {
|
|
3596
|
+
const current = new Map(createExportDialogRows(columns).map((row) => [row.key, row]));
|
|
3597
|
+
const rows = [];
|
|
3598
|
+
cache?.rows.forEach((saved) => {
|
|
3599
|
+
const row = current.get(saved.key);
|
|
3600
|
+
if (!row) return;
|
|
3601
|
+
rows.push({ ...saved, key: row.key, title: row.title });
|
|
3602
|
+
current.delete(saved.key);
|
|
3603
|
+
});
|
|
3604
|
+
return [...rows, ...current.values()];
|
|
3605
|
+
}
|
|
3575
3606
|
var sortOptions = [
|
|
3576
3607
|
{ value: "default", label: "\u9ED8\u8BA4" },
|
|
3577
3608
|
{ value: "ascend", label: "\u5347\u5E8F" },
|
|
@@ -3643,18 +3674,34 @@ function buildExportDialogSettings(rows, selectedKeys, includeSummary) {
|
|
|
3643
3674
|
function ReactListTableExportNameDialog({
|
|
3644
3675
|
request,
|
|
3645
3676
|
onClose,
|
|
3646
|
-
renderTable
|
|
3677
|
+
renderTable,
|
|
3678
|
+
storageKey
|
|
3647
3679
|
}) {
|
|
3648
3680
|
const tableId = useId();
|
|
3681
|
+
const tableHostRef = useRef(null);
|
|
3682
|
+
const [tableWidth, setTableWidth] = useState(0);
|
|
3683
|
+
useEffect(() => {
|
|
3684
|
+
const host = tableHostRef.current;
|
|
3685
|
+
if (!host || typeof ResizeObserver === "undefined") return;
|
|
3686
|
+
const update = () => setTableWidth(host.clientWidth);
|
|
3687
|
+
update();
|
|
3688
|
+
const observer = new ResizeObserver(update);
|
|
3689
|
+
observer.observe(host);
|
|
3690
|
+
return () => observer.disconnect();
|
|
3691
|
+
}, []);
|
|
3649
3692
|
const extension = request.fileName.match(/\.(xlsx|csv|txt|json)$/i)?.[0] ?? "";
|
|
3650
3693
|
const [fileName, setFileName] = useState(
|
|
3651
3694
|
extension ? request.fileName.slice(0, -extension.length) : request.fileName
|
|
3652
3695
|
);
|
|
3653
|
-
const [
|
|
3696
|
+
const [cached] = useState(() => readExportCache(storageKey));
|
|
3697
|
+
const [cacheEnabled, setCacheEnabled] = useState(Boolean(storageKey));
|
|
3698
|
+
const [rows, setRows] = useState(() => restoreExportRows(request.columns ?? [], cached));
|
|
3654
3699
|
const [selectedKeys, setSelectedKeys] = useState(
|
|
3655
|
-
() => (request.columns ?? []).filter((column) => column.selected !== false).map((column) => column.key)
|
|
3700
|
+
() => (request.columns ?? []).filter((column) => cached?.rows.some((row) => row.key === column.key) ? cached.selectedKeys.includes(column.key) : column.selected !== false).map((column) => column.key)
|
|
3701
|
+
);
|
|
3702
|
+
const [includeSummary, setIncludeSummary] = useState(
|
|
3703
|
+
() => cached?.includeSummary ?? (request.includeSummary === true || (request.columns?.some((column) => column.summary.type !== "none") ?? false))
|
|
3656
3704
|
);
|
|
3657
|
-
const [includeSummary, setIncludeSummary] = useState(request.includeSummary ?? false);
|
|
3658
3705
|
const [error, setError] = useState("");
|
|
3659
3706
|
const columns = useMemo(
|
|
3660
3707
|
() => [
|
|
@@ -3732,9 +3779,16 @@ function ReactListTableExportNameDialog({
|
|
|
3732
3779
|
],
|
|
3733
3780
|
[includeSummary, request.columns]
|
|
3734
3781
|
);
|
|
3782
|
+
const fittedColumns = useMemo(
|
|
3783
|
+
() => fitExportDialogColumns(columns, tableWidth),
|
|
3784
|
+
[columns, tableWidth]
|
|
3785
|
+
);
|
|
3735
3786
|
const confirm = () => {
|
|
3736
3787
|
if (!fileName.trim()) return setError("\u8BF7\u8F93\u5165\u6587\u4EF6\u540D\u79F0");
|
|
3737
3788
|
if (request.columns && !selectedKeys.length) return setError("\u8BF7\u81F3\u5C11\u9009\u62E9\u4E00\u5217");
|
|
3789
|
+
if (request.columns && cacheEnabled) {
|
|
3790
|
+
writeExportCache(storageKey, { version: 1, rows, selectedKeys: selectedKeys.map(String), includeSummary });
|
|
3791
|
+
}
|
|
3738
3792
|
request.onConfirm(
|
|
3739
3793
|
`${fileName.trim()}${extension}`,
|
|
3740
3794
|
request.columns ? buildExportDialogSettings(rows, selectedKeys, includeSummary) : void 0
|
|
@@ -3746,7 +3800,7 @@ function ReactListTableExportNameDialog({
|
|
|
3746
3800
|
{
|
|
3747
3801
|
open: true,
|
|
3748
3802
|
title: "\u5BFC\u51FA\u6587\u4EF6",
|
|
3749
|
-
width: request.columns ? 1180 : 420,
|
|
3803
|
+
width: request.columns ? includeSummary ? 1320 : 1180 : 420,
|
|
3750
3804
|
fullscreenable: false,
|
|
3751
3805
|
onOk: confirm,
|
|
3752
3806
|
okText: "\u5BFC\u51FA",
|
|
@@ -3779,6 +3833,27 @@ function ReactListTableExportNameDialog({
|
|
|
3779
3833
|
request.columns ? /* @__PURE__ */ jsxs("div", { style: { marginTop: 16 }, children: [
|
|
3780
3834
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 16, marginBottom: 8 }, children: [
|
|
3781
3835
|
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600 }, children: "\u5BFC\u51FA\u8868\u683C\u5217" }),
|
|
3836
|
+
storageKey ? /* @__PURE__ */ jsxs(
|
|
3837
|
+
"label",
|
|
3838
|
+
{
|
|
3839
|
+
style: { display: "inline-flex", alignItems: "center", gap: 6 },
|
|
3840
|
+
title: "\u5BFC\u51FA\u65F6\u4FDD\u5B58\u914D\u7F6E\uFF0C\u4E0B\u6B21\u6253\u5F00\u81EA\u52A8\u6062\u590D\uFF1B\u53D6\u6D88\u52FE\u9009\u6E05\u9664\u7F13\u5B58",
|
|
3841
|
+
children: [
|
|
3842
|
+
/* @__PURE__ */ jsx(
|
|
3843
|
+
ReactCheckbox,
|
|
3844
|
+
{
|
|
3845
|
+
checked: cacheEnabled,
|
|
3846
|
+
"aria-label": "\u7F13\u5B58\u5BFC\u51FA\u914D\u7F6E",
|
|
3847
|
+
onChange: (event) => {
|
|
3848
|
+
setCacheEnabled(event.target.checked);
|
|
3849
|
+
if (!event.target.checked) writeExportCache(storageKey, null);
|
|
3850
|
+
}
|
|
3851
|
+
}
|
|
3852
|
+
),
|
|
3853
|
+
"\u7F13\u5B58\u5BFC\u51FA\u914D\u7F6E"
|
|
3854
|
+
]
|
|
3855
|
+
}
|
|
3856
|
+
) : null,
|
|
3782
3857
|
/* @__PURE__ */ jsxs("label", { style: { display: "inline-flex", alignItems: "center", gap: 6 }, children: [
|
|
3783
3858
|
/* @__PURE__ */ jsx(
|
|
3784
3859
|
ReactCheckbox,
|
|
@@ -3791,9 +3866,9 @@ function ReactListTableExportNameDialog({
|
|
|
3791
3866
|
"\u5BFC\u51FA\u6C47\u603B\u884C"
|
|
3792
3867
|
] })
|
|
3793
3868
|
] }),
|
|
3794
|
-
/* @__PURE__ */ jsx("div", { style: { height: "min(45vh, 520px)", minHeight: 250, overflow: "hidden" }, children: renderTable({
|
|
3869
|
+
/* @__PURE__ */ jsx("div", { ref: tableHostRef, style: { height: "min(45vh, 520px)", minHeight: 250, overflow: "hidden" }, children: renderTable({
|
|
3795
3870
|
tableId,
|
|
3796
|
-
columns,
|
|
3871
|
+
columns: fittedColumns,
|
|
3797
3872
|
dataSource: rows,
|
|
3798
3873
|
rowKey: "key",
|
|
3799
3874
|
rowHeight: 42,
|
|
@@ -3838,6 +3913,17 @@ function ReactListTableExportNameDialog({
|
|
|
3838
3913
|
}
|
|
3839
3914
|
);
|
|
3840
3915
|
}
|
|
3916
|
+
function fitExportDialogColumns(columns, availableWidth) {
|
|
3917
|
+
if (availableWidth <= 0) return columns;
|
|
3918
|
+
const totalWidth = (items) => items.reduce((sum, column) => sum + (column.key === ROW_SELECTION_COLUMN.key ? 0 : column.children?.length ? totalWidth(column.children) : Number(column.width) || 160), 0);
|
|
3919
|
+
const ratio = Math.min(1, Math.max(availableWidth - 54 - 32, 1) / totalWidth(columns));
|
|
3920
|
+
const fit = (items) => items.map((column) => {
|
|
3921
|
+
if (column.key === ROW_SELECTION_COLUMN.key) return column;
|
|
3922
|
+
if (column.children?.length) return { ...column, children: fit(column.children) };
|
|
3923
|
+
return { ...column, width: Math.max(1, Math.floor((Number(column.width) || 160) * ratio)), minWidth: 1 };
|
|
3924
|
+
});
|
|
3925
|
+
return fit(columns);
|
|
3926
|
+
}
|
|
3841
3927
|
|
|
3842
3928
|
// src/features/editor/utils.ts
|
|
3843
3929
|
function toNumberValue(value) {
|
|
@@ -5002,14 +5088,18 @@ function SortableList(props) {
|
|
|
5002
5088
|
);
|
|
5003
5089
|
useEffect(() => {
|
|
5004
5090
|
if (!dragState) return;
|
|
5005
|
-
const
|
|
5091
|
+
const scrollContainer = props.scrollContainerRef?.current;
|
|
5092
|
+
let frameId = 0;
|
|
5093
|
+
let lastTime = null;
|
|
5094
|
+
const updateTarget = () => {
|
|
5006
5095
|
const current = dragRef.current;
|
|
5007
5096
|
if (!current) return;
|
|
5008
5097
|
const target = resolveClosestSortableItem({
|
|
5009
5098
|
items,
|
|
5010
5099
|
parentKey: current.source.parentKey,
|
|
5011
5100
|
layouts: current.layouts,
|
|
5012
|
-
|
|
5101
|
+
// 保留拖拽开始时的布局,补偿滚动位移,避免受行交换动画影响。
|
|
5102
|
+
overlayCenterY: current.pointerY - current.offsetY + current.height / 2 + current.rootTop - (rootRef.current?.getBoundingClientRect().top ?? current.rootTop)
|
|
5013
5103
|
});
|
|
5014
5104
|
if (target) {
|
|
5015
5105
|
current.target = target;
|
|
@@ -5017,12 +5107,44 @@ function SortableList(props) {
|
|
|
5017
5107
|
setDragState({
|
|
5018
5108
|
sourceKey: current.source.key,
|
|
5019
5109
|
targetKey: current.target.key,
|
|
5020
|
-
pointerY:
|
|
5110
|
+
pointerY: current.pointerY
|
|
5021
5111
|
});
|
|
5022
5112
|
};
|
|
5023
|
-
const
|
|
5113
|
+
const handleMove = (event) => {
|
|
5114
|
+
const current = dragRef.current;
|
|
5115
|
+
if (!current || event.pointerId !== current.pointerId) return;
|
|
5116
|
+
current.pointerY = event.clientY;
|
|
5117
|
+
updateTarget();
|
|
5118
|
+
};
|
|
5119
|
+
const tick = (time) => {
|
|
5120
|
+
const current = dragRef.current;
|
|
5121
|
+
if (!current) return;
|
|
5122
|
+
const elapsed = lastTime == null ? 0 : Math.min(time - lastTime, 50);
|
|
5123
|
+
lastTime = time;
|
|
5124
|
+
if (scrollContainer) {
|
|
5125
|
+
const rect = scrollContainer.getBoundingClientRect();
|
|
5126
|
+
const top = rect.top + scrollContainer.clientTop;
|
|
5127
|
+
const height = scrollContainer.clientHeight;
|
|
5128
|
+
const edge = Math.min(40, height / 2);
|
|
5129
|
+
const bottom = top + height;
|
|
5130
|
+
const direction = edge <= 0 ? 0 : current.pointerY < top + edge ? -Math.min(1, (top + edge - current.pointerY) / edge) : current.pointerY > bottom - edge ? Math.min(1, (current.pointerY - bottom + edge) / edge) : 0;
|
|
5131
|
+
if (direction) {
|
|
5132
|
+
scrollContainer.scrollTop = Math.max(
|
|
5133
|
+
0,
|
|
5134
|
+
Math.min(
|
|
5135
|
+
scrollContainer.scrollHeight - height,
|
|
5136
|
+
scrollContainer.scrollTop + direction * elapsed * 0.5
|
|
5137
|
+
)
|
|
5138
|
+
);
|
|
5139
|
+
updateTarget();
|
|
5140
|
+
}
|
|
5141
|
+
}
|
|
5142
|
+
frameId = requestAnimationFrame(tick);
|
|
5143
|
+
};
|
|
5144
|
+
const finish = (commit) => {
|
|
5024
5145
|
const current = dragRef.current;
|
|
5025
|
-
|
|
5146
|
+
cancelAnimationFrame(frameId);
|
|
5147
|
+
if (commit && current && current.source.key !== current.target.key) {
|
|
5026
5148
|
const siblings = items.filter(
|
|
5027
5149
|
(item) => item.parentKey === current.source.parentKey
|
|
5028
5150
|
);
|
|
@@ -5040,15 +5162,30 @@ function SortableList(props) {
|
|
|
5040
5162
|
document.body.classList.remove("react-list-table-sorting");
|
|
5041
5163
|
document.body.style.removeProperty("user-select");
|
|
5042
5164
|
};
|
|
5165
|
+
const handleEnd = (event) => {
|
|
5166
|
+
if (event.pointerId !== dragRef.current?.pointerId) return;
|
|
5167
|
+
handleMove(event);
|
|
5168
|
+
finish(true);
|
|
5169
|
+
};
|
|
5170
|
+
const handleCancel = (event) => {
|
|
5171
|
+
if (event.pointerId === dragRef.current?.pointerId) finish(false);
|
|
5172
|
+
};
|
|
5173
|
+
const handleBlur = () => finish(false);
|
|
5174
|
+
frameId = requestAnimationFrame(tick);
|
|
5175
|
+
scrollContainer?.addEventListener("scroll", updateTarget);
|
|
5043
5176
|
window.addEventListener("pointermove", handleMove);
|
|
5044
|
-
window.addEventListener("pointerup", handleEnd
|
|
5045
|
-
window.addEventListener("pointercancel",
|
|
5177
|
+
window.addEventListener("pointerup", handleEnd);
|
|
5178
|
+
window.addEventListener("pointercancel", handleCancel);
|
|
5179
|
+
window.addEventListener("blur", handleBlur);
|
|
5046
5180
|
return () => {
|
|
5181
|
+
cancelAnimationFrame(frameId);
|
|
5182
|
+
scrollContainer?.removeEventListener("scroll", updateTarget);
|
|
5047
5183
|
window.removeEventListener("pointermove", handleMove);
|
|
5048
5184
|
window.removeEventListener("pointerup", handleEnd);
|
|
5049
|
-
window.removeEventListener("pointercancel",
|
|
5185
|
+
window.removeEventListener("pointercancel", handleCancel);
|
|
5186
|
+
window.removeEventListener("blur", handleBlur);
|
|
5050
5187
|
};
|
|
5051
|
-
}, [dragState != null, items, onOrderChange]);
|
|
5188
|
+
}, [dragState != null, items, onOrderChange, props.scrollContainerRef]);
|
|
5052
5189
|
const sourceIndex = dragState ? items.findIndex((item) => item.key === dragState.sourceKey) : -1;
|
|
5053
5190
|
const targetIndex = dragState ? items.findIndex((item) => item.key === dragState.targetKey) : -1;
|
|
5054
5191
|
return /* @__PURE__ */ jsxs("div", { ref: rootRef, children: [
|
|
@@ -5067,7 +5204,7 @@ function SortableList(props) {
|
|
|
5067
5204
|
style,
|
|
5068
5205
|
children: props.renderItem(item, {
|
|
5069
5206
|
onPointerDown: (event) => {
|
|
5070
|
-
if (event.button !== 0) return;
|
|
5207
|
+
if (event.button !== 0 || dragRef.current) return;
|
|
5071
5208
|
const row = event.currentTarget.closest(
|
|
5072
5209
|
"[data-sortable-key]"
|
|
5073
5210
|
);
|
|
@@ -5080,7 +5217,10 @@ function SortableList(props) {
|
|
|
5080
5217
|
offsetY: event.clientY - rect.top,
|
|
5081
5218
|
width: rect.width,
|
|
5082
5219
|
left: rect.left,
|
|
5083
|
-
height: rect.height
|
|
5220
|
+
height: rect.height,
|
|
5221
|
+
pointerId: event.pointerId,
|
|
5222
|
+
pointerY: event.clientY,
|
|
5223
|
+
rootTop: rootRef.current?.getBoundingClientRect().top ?? 0
|
|
5084
5224
|
};
|
|
5085
5225
|
setDragState({
|
|
5086
5226
|
sourceKey: item.key,
|
|
@@ -5167,13 +5307,14 @@ function resolveSortableTransform(index, sourceIndex, targetIndex, height) {
|
|
|
5167
5307
|
}
|
|
5168
5308
|
|
|
5169
5309
|
// src/features/toolbar/style.css
|
|
5170
|
-
styleInject(".react-list-table-shell {\n background: #fff;\n font-size: 14px;\n}\n.react-list-table-titlebar {\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n box-sizing: border-box;\n background: #fff;\n}\n.react-list-table-shell-fullscreen {\n width: 100% !important;\n height: 100% !important;\n}\n.react-list-table-shell-fullscreen .canvas-list-table-root {\n height: 100% !important;\n}\n.react-list-table-title {\n min-width: 0;\n color: #1f2937;\n font-size: 14px;\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-tools {\n display: flex;\n align-items: center;\n gap: 14px;\n color: #475569;\n}\n.react-list-table-tool-wrap {\n position: relative;\n display: inline-flex;\n}\n.react-list-table-tool {\n width: 20px;\n height: 24px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n font: 16px/24px sans-serif;\n cursor: pointer;\n}\n.react-list-table-tool:hover {\n color: #1677ff;\n}\n.react-list-table-tool-menu,\n.react-list-table-column-setting {\n position: absolute;\n z-index: 120;\n top: 28px;\n right: 0;\n min-width: 112px;\n padding: 6px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);\n}\n.react-list-table-tool-menu button {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #374151;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n}\n.react-list-table-tool-menu {\n width: max-content;\n min-width: 0;\n padding: 8px;\n border-radius: 8px;\n}\n.react-list-table-tool-menu-check {\n width: 16px;\n flex: 0 0 16px;\n margin-right: 6px;\n text-align: center;\n}\n.react-list-table-tool-menu button:hover {\n background: #f3f4f6;\n}\n.react-list-table-column-setting {\n width: 328px;\n max-height: 360px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.react-list-table-column-setting-head {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 4px 6px 8px;\n border-bottom: 1px solid #f0f0f0;\n flex: 0 0 auto;\n}\n.react-list-table-column-setting-head button {\n border: 0;\n color: #1677ff;\n background: transparent;\n cursor: pointer;\n}\n.react-list-table-column-setting-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.react-list-table-column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n padding: 7px 6px;\n box-sizing: border-box;\n cursor: pointer;\n}\n.react-list-table-column-main,\n.react-list-table-column-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.react-list-table-column-main {\n min-width: 0;\n}\n.react-list-table-column-actions {\n flex: 0 0 auto;\n}\n.react-list-table-column-actions > .canvas-react-select-wrap {\n flex: 0 0 96px;\n width: 96px;\n height: 24px;\n}\n.react-list-table-column-label {\n min-width: 64px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-column-width-input {\n height: 22px;\n padding-inline: 5px;\n}\n.react-list-table-column-fixed-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-sort-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-setting label.dragging {\n opacity: 0.45;\n background: #e6f4ff;\n}\n.react-list-table-column-setting [data-sortable-key].dragging {\n opacity: 0.28;\n}\n.react-list-table-column-drag {\n color: #94a3b8;\n display: inline-flex;\n font-size: 14px;\n cursor: grab;\n user-select: none;\n}\nbody.react-list-table-sorting,\nbody.react-list-table-sorting * {\n cursor: grabbing !important;\n}\n.react-list-table-sort-overlay {\n position: fixed;\n z-index: 1400;\n display: block;\n padding: 0;\n box-sizing: border-box;\n color: #334155;\n background: #fff;\n border: 1px solid #91caff;\n border-radius: 6px;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);\n pointer-events: none;\n}\n.react-list-table-sort-overlay .react-list-table-column-item {\n width: 100%;\n height: 100%;\n}\n");
|
|
5310
|
+
styleInject(".react-list-table-shell {\n background: #fff;\n font-size: 14px;\n}\n.react-list-table-titlebar {\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n box-sizing: border-box;\n background: #fff;\n}\n.react-list-table-shell-fullscreen {\n width: 100% !important;\n height: 100% !important;\n}\n.react-list-table-shell-fullscreen .canvas-list-table-root {\n height: 100% !important;\n}\n.react-list-table-title {\n min-width: 0;\n color: #1f2937;\n font-size: 14px;\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-tools {\n display: flex;\n align-items: center;\n gap: 14px;\n color: #475569;\n}\n.react-list-table-tool-wrap {\n position: relative;\n display: inline-flex;\n}\n.react-list-table-tool {\n width: 20px;\n height: 24px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n font: 16px/24px sans-serif;\n cursor: pointer;\n}\n.react-list-table-tool:hover {\n color: #1677ff;\n}\n.react-list-table-tool-menu,\n.react-list-table-column-setting {\n position: absolute;\n z-index: 120;\n top: 28px;\n right: 0;\n min-width: 112px;\n padding: 6px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);\n}\n.react-list-table-tool-menu button {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #374151;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n}\n.react-list-table-tool-menu {\n width: max-content;\n min-width: 0;\n padding: 8px;\n border-radius: 8px;\n}\n.react-list-table-tool-menu-check {\n width: 16px;\n flex: 0 0 16px;\n margin-right: 6px;\n text-align: center;\n}\n.react-list-table-tool-menu button:hover {\n background: #f3f4f6;\n}\n.react-list-table-column-setting {\n width: 328px;\n max-height: 360px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.react-list-table-column-setting-head {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 4px 6px 8px;\n border-bottom: 1px solid #f0f0f0;\n flex: 0 0 auto;\n}\n.react-list-table-column-setting-head button {\n border: 0;\n color: #1677ff;\n background: transparent;\n cursor: pointer;\n}\n.react-list-table-column-setting-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.react-list-table-column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n padding: 7px 6px;\n box-sizing: border-box;\n cursor: pointer;\n}\n.react-list-table-column-main,\n.react-list-table-column-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.react-list-table-column-main {\n min-width: 0;\n}\n.react-list-table-column-actions {\n flex: 0 0 auto;\n}\n.react-list-table-column-actions > .canvas-react-select-wrap {\n flex: 0 0 96px;\n width: 96px;\n height: 24px;\n}\n.react-list-table-column-label {\n min-width: 64px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-column-width-input {\n height: 22px;\n padding-inline: 5px;\n}\n.react-list-table-column-fixed-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-sort-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-setting label.dragging {\n opacity: 0.45;\n background: #e6f4ff;\n}\n.react-list-table-column-setting [data-sortable-key].dragging {\n opacity: 0.28;\n}\n.react-list-table-column-drag {\n touch-action: none;\n color: #94a3b8;\n display: inline-flex;\n font-size: 14px;\n cursor: grab;\n user-select: none;\n}\nbody.react-list-table-sorting,\nbody.react-list-table-sorting * {\n cursor: grabbing !important;\n}\n.react-list-table-sort-overlay {\n position: fixed;\n z-index: 1400;\n display: block;\n padding: 0;\n box-sizing: border-box;\n color: #334155;\n background: #fff;\n border: 1px solid #91caff;\n border-radius: 6px;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.18);\n pointer-events: none;\n}\n.react-list-table-sort-overlay .react-list-table-column-item {\n width: 100%;\n height: 100%;\n}\n");
|
|
5171
5311
|
function ReactTableToolbar(props) {
|
|
5172
5312
|
const { toolbar, title } = props;
|
|
5173
5313
|
const [densityOpen, setDensityOpen] = useState(false);
|
|
5174
5314
|
const [settingOpen, setSettingOpen] = useState(false);
|
|
5175
5315
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
5176
5316
|
const rootRef = useRef(null);
|
|
5317
|
+
const columnSettingsBodyRef = useRef(null);
|
|
5177
5318
|
const hasToolbar = toolbar !== void 0 && toolbar !== false;
|
|
5178
5319
|
useEffect(() => {
|
|
5179
5320
|
const close = (event) => {
|
|
@@ -5312,116 +5453,124 @@ function ReactTableToolbar(props) {
|
|
|
5312
5453
|
/* @__PURE__ */ jsx("span", { style: { marginLeft: "auto" }, children: config.columnSettingHeaderExtra }),
|
|
5313
5454
|
/* @__PURE__ */ jsx("button", { type: "button", onClick: props.onResetColumns, children: "\u91CD\u7F6E" })
|
|
5314
5455
|
] }),
|
|
5315
|
-
/* @__PURE__ */ jsx(
|
|
5316
|
-
|
|
5456
|
+
/* @__PURE__ */ jsx(
|
|
5457
|
+
"div",
|
|
5317
5458
|
{
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5325
|
-
|
|
5326
|
-
|
|
5459
|
+
ref: columnSettingsBodyRef,
|
|
5460
|
+
className: "react-list-table-column-setting-body canvas-react-scrollbar",
|
|
5461
|
+
children: /* @__PURE__ */ jsx(
|
|
5462
|
+
SortableList,
|
|
5463
|
+
{
|
|
5464
|
+
scrollContainerRef: columnSettingsBodyRef,
|
|
5465
|
+
items: flattenColumns(props.columns),
|
|
5466
|
+
onOrderChange: props.onColumnOrderChange,
|
|
5467
|
+
renderItem: (column, handleProps) => /* @__PURE__ */ jsxs("div", { className: "react-list-table-column-item", children: [
|
|
5468
|
+
/* @__PURE__ */ jsxs(
|
|
5469
|
+
"span",
|
|
5470
|
+
{
|
|
5471
|
+
className: "react-list-table-column-main",
|
|
5472
|
+
style: { paddingLeft: column.level * 16 },
|
|
5473
|
+
children: [
|
|
5474
|
+
/* @__PURE__ */ jsx(
|
|
5475
|
+
"span",
|
|
5476
|
+
{
|
|
5477
|
+
className: "react-list-table-column-drag",
|
|
5478
|
+
...handleProps,
|
|
5479
|
+
onClick: (event) => {
|
|
5480
|
+
event.preventDefault();
|
|
5481
|
+
event.stopPropagation();
|
|
5482
|
+
},
|
|
5483
|
+
children: /* @__PURE__ */ jsx(HolderOutlined, {})
|
|
5484
|
+
}
|
|
5485
|
+
),
|
|
5486
|
+
/* @__PURE__ */ jsx(
|
|
5487
|
+
"input",
|
|
5488
|
+
{
|
|
5489
|
+
type: "checkbox",
|
|
5490
|
+
checked: !column.hidden,
|
|
5491
|
+
disabled: column.disableHide,
|
|
5492
|
+
onChange: (event) => props.onColumnVisibilityChange(
|
|
5493
|
+
column.key,
|
|
5494
|
+
event.target.checked
|
|
5495
|
+
)
|
|
5496
|
+
}
|
|
5497
|
+
),
|
|
5498
|
+
/* @__PURE__ */ jsx("span", { className: "react-list-table-column-label", children: column.label })
|
|
5499
|
+
]
|
|
5500
|
+
}
|
|
5501
|
+
),
|
|
5502
|
+
!column.isGroup ? /* @__PURE__ */ jsxs("span", { className: "react-list-table-column-actions", children: [
|
|
5327
5503
|
/* @__PURE__ */ jsx(
|
|
5328
|
-
|
|
5504
|
+
ReactNumberInput,
|
|
5329
5505
|
{
|
|
5330
|
-
className: "react-list-table-column-
|
|
5331
|
-
|
|
5332
|
-
|
|
5333
|
-
|
|
5334
|
-
|
|
5335
|
-
}
|
|
5336
|
-
|
|
5506
|
+
className: "react-list-table-column-width-input",
|
|
5507
|
+
min: column.minWidth,
|
|
5508
|
+
max: column.maxWidth,
|
|
5509
|
+
value: column.width,
|
|
5510
|
+
allowClear: false,
|
|
5511
|
+
"aria-label": `${column.label}\u5217\u5BBD`,
|
|
5512
|
+
style: { width: 80, height: 24 },
|
|
5513
|
+
onChange: (width) => {
|
|
5514
|
+
if (width != null && Number.isFinite(width) && width > 0 && (column.minWidth == null || width >= column.minWidth) && (column.maxWidth == null || width <= column.maxWidth)) {
|
|
5515
|
+
props.onColumnWidthChange(
|
|
5516
|
+
column.key,
|
|
5517
|
+
width
|
|
5518
|
+
);
|
|
5519
|
+
}
|
|
5520
|
+
}
|
|
5337
5521
|
}
|
|
5338
5522
|
),
|
|
5339
5523
|
/* @__PURE__ */ jsx(
|
|
5340
|
-
|
|
5524
|
+
ReactSelect,
|
|
5341
5525
|
{
|
|
5342
|
-
|
|
5343
|
-
|
|
5344
|
-
|
|
5345
|
-
|
|
5526
|
+
className: "react-list-table-column-sort-input",
|
|
5527
|
+
value: props.sortState.find(
|
|
5528
|
+
(item) => item.key === column.key
|
|
5529
|
+
)?.order ?? "default",
|
|
5530
|
+
options: [
|
|
5531
|
+
{ label: "\u9ED8\u8BA4\u6392\u5E8F", value: "default" },
|
|
5532
|
+
{ label: "\u5347\u5E8F", value: "ascend" },
|
|
5533
|
+
{ label: "\u964D\u5E8F", value: "descend" }
|
|
5534
|
+
],
|
|
5535
|
+
disabled: !column.sortable,
|
|
5536
|
+
allowClear: false,
|
|
5537
|
+
showSearch: false,
|
|
5538
|
+
style: { width: "100%", height: 24 },
|
|
5539
|
+
"aria-label": `${column.label}\u6392\u5E8F\u65B9\u5F0F`,
|
|
5540
|
+
onChange: (value) => props.onColumnSortChange(
|
|
5346
5541
|
column.key,
|
|
5347
|
-
|
|
5542
|
+
value === "ascend" || value === "descend" ? value : null
|
|
5348
5543
|
)
|
|
5349
5544
|
}
|
|
5350
5545
|
),
|
|
5351
|
-
/* @__PURE__ */ jsx(
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
5371
|
-
);
|
|
5546
|
+
/* @__PURE__ */ jsx(
|
|
5547
|
+
ReactSelect,
|
|
5548
|
+
{
|
|
5549
|
+
className: "react-list-table-column-fixed-input",
|
|
5550
|
+
value: column.fixed ?? "none",
|
|
5551
|
+
options: [
|
|
5552
|
+
{ label: "\u4E0D\u56FA\u5B9A", value: "none" },
|
|
5553
|
+
{ label: "\u56FA\u5B9A\u5DE6\u4FA7", value: "left" },
|
|
5554
|
+
{ label: "\u56FA\u5B9A\u53F3\u4FA7", value: "right" }
|
|
5555
|
+
],
|
|
5556
|
+
allowClear: false,
|
|
5557
|
+
showSearch: false,
|
|
5558
|
+
style: { width: "100%", height: 24 },
|
|
5559
|
+
"aria-label": `${column.label}\u56FA\u5B9A\u65B9\u5411`,
|
|
5560
|
+
onChange: (value) => {
|
|
5561
|
+
props.onColumnFixedChange(
|
|
5562
|
+
column.key,
|
|
5563
|
+
value === "left" || value === "right" ? value : void 0
|
|
5564
|
+
);
|
|
5565
|
+
}
|
|
5372
5566
|
}
|
|
5373
|
-
}
|
|
5374
|
-
}
|
|
5375
|
-
),
|
|
5376
|
-
/* @__PURE__ */ jsx(
|
|
5377
|
-
ReactSelect,
|
|
5378
|
-
{
|
|
5379
|
-
className: "react-list-table-column-sort-input",
|
|
5380
|
-
value: props.sortState.find(
|
|
5381
|
-
(item) => item.key === column.key
|
|
5382
|
-
)?.order ?? "default",
|
|
5383
|
-
options: [
|
|
5384
|
-
{ label: "\u9ED8\u8BA4\u6392\u5E8F", value: "default" },
|
|
5385
|
-
{ label: "\u5347\u5E8F", value: "ascend" },
|
|
5386
|
-
{ label: "\u964D\u5E8F", value: "descend" }
|
|
5387
|
-
],
|
|
5388
|
-
disabled: !column.sortable,
|
|
5389
|
-
allowClear: false,
|
|
5390
|
-
showSearch: false,
|
|
5391
|
-
style: { width: "100%", height: 24 },
|
|
5392
|
-
"aria-label": `${column.label}\u6392\u5E8F\u65B9\u5F0F`,
|
|
5393
|
-
onChange: (value) => props.onColumnSortChange(
|
|
5394
|
-
column.key,
|
|
5395
|
-
value === "ascend" || value === "descend" ? value : null
|
|
5396
5567
|
)
|
|
5397
|
-
}
|
|
5398
|
-
)
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
{
|
|
5402
|
-
className: "react-list-table-column-fixed-input",
|
|
5403
|
-
value: column.fixed ?? "none",
|
|
5404
|
-
options: [
|
|
5405
|
-
{ label: "\u4E0D\u56FA\u5B9A", value: "none" },
|
|
5406
|
-
{ label: "\u56FA\u5B9A\u5DE6\u4FA7", value: "left" },
|
|
5407
|
-
{ label: "\u56FA\u5B9A\u53F3\u4FA7", value: "right" }
|
|
5408
|
-
],
|
|
5409
|
-
allowClear: false,
|
|
5410
|
-
showSearch: false,
|
|
5411
|
-
style: { width: "100%", height: 24 },
|
|
5412
|
-
"aria-label": `${column.label}\u56FA\u5B9A\u65B9\u5411`,
|
|
5413
|
-
onChange: (value) => {
|
|
5414
|
-
props.onColumnFixedChange(
|
|
5415
|
-
column.key,
|
|
5416
|
-
value === "left" || value === "right" ? value : void 0
|
|
5417
|
-
);
|
|
5418
|
-
}
|
|
5419
|
-
}
|
|
5420
|
-
)
|
|
5421
|
-
] }) : null
|
|
5422
|
-
] })
|
|
5568
|
+
] }) : null
|
|
5569
|
+
] })
|
|
5570
|
+
}
|
|
5571
|
+
)
|
|
5423
5572
|
}
|
|
5424
|
-
)
|
|
5573
|
+
)
|
|
5425
5574
|
]
|
|
5426
5575
|
}
|
|
5427
5576
|
) : null
|
|
@@ -6202,6 +6351,7 @@ function ReactListTableInner(props, ref) {
|
|
|
6202
6351
|
ReactListTableExportNameDialog,
|
|
6203
6352
|
{
|
|
6204
6353
|
request: exportNameRequest,
|
|
6354
|
+
storageKey: storageKey ? `list:${storageKey}` : void 0,
|
|
6205
6355
|
onClose: closeExportNameRequest,
|
|
6206
6356
|
renderTable: (tableProps) => /* @__PURE__ */ jsx(ReactListTable, { ...tableProps })
|
|
6207
6357
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@canvas-components/react-list-table",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.38",
|
|
4
4
|
"description": "React adapter for the list table core engine.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@canvas-components/chart": "0.3.7",
|
|
32
|
-
"@canvas-components/
|
|
33
|
-
"@canvas-components/
|
|
32
|
+
"@canvas-components/list-table": "0.3.32",
|
|
33
|
+
"@canvas-components/react-components": "0.3.16"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"react": ">=16.8.0",
|