@canvas-components/react-pivot-table 0.2.18 → 0.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/index.cjs +367 -117
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +369 -119
- package/dist/index.js.map +1 -1
- package/package.json +10 -8
- package/LICENSE +0 -21
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { CSSProperties, ReactNode, ForwardedRef, PropsWithChildren } from 'react';
|
|
3
|
-
import { PivotTableOptions,
|
|
3
|
+
import { PivotTableOptions, PivotFieldLayout, PivotField, PivotTable, PivotModel, PivotSelectionState, PivotFilterState, PivotSortRule, PivotCellAddress, PivotAxis, PivotFilterAxis, PivotDimensionFilter, PivotFilterOptionItem, PivotExportOptions, PivotTableStateSnapshot } from '@canvas-components/pivot-table';
|
|
4
4
|
|
|
5
5
|
/** PivotTable 自定义字段面板配置。 */
|
|
6
6
|
interface ReactPivotTableCustomizationOptions<RecordType = Record<string, unknown>> {
|
|
@@ -28,6 +28,8 @@ interface ReactPivotTableProps<RecordType = Record<string, unknown>> extends Omi
|
|
|
28
28
|
style?: CSSProperties;
|
|
29
29
|
/** 标题栏左侧内容。 */
|
|
30
30
|
title?: ReactNode;
|
|
31
|
+
/** 初始透视字段区域;字段 key 从行、列、指标及 customization.fields 中查找,已缓存布局优先。 */
|
|
32
|
+
pivotAreas?: PivotFieldLayout;
|
|
31
33
|
/** 开启字段自定义模式及右侧字段面板。 */
|
|
32
34
|
customization?: boolean | ReactPivotTableCustomizationOptions<RecordType>;
|
|
33
35
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { CSSProperties, ReactNode, ForwardedRef, PropsWithChildren } from 'react';
|
|
3
|
-
import { PivotTableOptions,
|
|
3
|
+
import { PivotTableOptions, PivotFieldLayout, PivotField, PivotTable, PivotModel, PivotSelectionState, PivotFilterState, PivotSortRule, PivotCellAddress, PivotAxis, PivotFilterAxis, PivotDimensionFilter, PivotFilterOptionItem, PivotExportOptions, PivotTableStateSnapshot } from '@canvas-components/pivot-table';
|
|
4
4
|
|
|
5
5
|
/** PivotTable 自定义字段面板配置。 */
|
|
6
6
|
interface ReactPivotTableCustomizationOptions<RecordType = Record<string, unknown>> {
|
|
@@ -28,6 +28,8 @@ interface ReactPivotTableProps<RecordType = Record<string, unknown>> extends Omi
|
|
|
28
28
|
style?: CSSProperties;
|
|
29
29
|
/** 标题栏左侧内容。 */
|
|
30
30
|
title?: ReactNode;
|
|
31
|
+
/** 初始透视字段区域;字段 key 从行、列、指标及 customization.fields 中查找,已缓存布局优先。 */
|
|
32
|
+
pivotAreas?: PivotFieldLayout;
|
|
31
33
|
/** 开启字段自定义模式及右侧字段面板。 */
|
|
32
34
|
customization?: boolean | ReactPivotTableCustomizationOptions<RecordType>;
|
|
33
35
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createContext, forwardRef, useMemo, useRef, useState, useEffect, useImperativeHandle, useContext, Fragment as Fragment$1 } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { ReactResizablePanels, ReactFilterPanel, ReactPopup, ReactCheckbox,
|
|
2
|
+
import { createPivotFieldLayout, createPivotFieldCatalog, resolvePivotDimensionKey, resolvePivotFieldLayoutOptions, PivotTable, loadPivotScrollbarConfig, loadPivotFieldLayout, DEFAULT_PIVOT_TABLE_DEBUG_OPTIONS, getValueByDataIndex, resolvePivotDimensionTitle, findPivotFieldArea, removePivotField, movePivotField, savePivotScrollbarConfig, resolvePivotValueFieldTitle, savePivotFieldLayout, createPivotCellKey } from '@canvas-components/pivot-table';
|
|
3
|
+
import { getSharedScrollbarSettings, subscribeSharedScrollbarSettings, ReactResizablePanels, ReactFilterPanel, ReactPopup, ReactCheckbox, ReactScrollbarSettingsDialog, ReactScrollbarPositionDialog, setSharedScrollbarSettings, ReactInput, ReactSelect, ReactButton, ReactInputNumber } from '@canvas-components/react-components';
|
|
4
4
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
5
|
+
import { ReactListTableExportNameDialog, ReactListTable } from '@canvas-components/react-list-table';
|
|
5
6
|
import { createPortal } from 'react-dom';
|
|
6
7
|
import { CanvasChart } from '@canvas-components/chart';
|
|
7
8
|
|
|
@@ -37,83 +38,269 @@ var CONTEXT_MENU_SURFACE_STYLE = {
|
|
|
37
38
|
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)",
|
|
38
39
|
fontSize: 14
|
|
39
40
|
};
|
|
41
|
+
function ScrollbarModeMenu(props) {
|
|
42
|
+
const { request, onOpenSettings } = props;
|
|
43
|
+
return /* @__PURE__ */ jsx(
|
|
44
|
+
MenuSubmenu,
|
|
45
|
+
{
|
|
46
|
+
label: "\u6EDA\u52A8\u6761\u6A21\u5F0F",
|
|
47
|
+
items: [
|
|
48
|
+
["scrollbar", "\u6EDA\u52A8\u6761"],
|
|
49
|
+
["button", "\u6309\u94AE"]
|
|
50
|
+
].map(([mode, label]) => ({
|
|
51
|
+
key: `scrollbar-mode-${mode}`,
|
|
52
|
+
label,
|
|
53
|
+
selected: (request.scrollbar?.mode ?? "scrollbar") === mode,
|
|
54
|
+
onClick: () => {
|
|
55
|
+
request.onChangeScrollbar?.({
|
|
56
|
+
...request.scrollbar,
|
|
57
|
+
mode,
|
|
58
|
+
horizontal: request.scrollbar?.horizontal === false ? false : { ...request.scrollbar?.horizontal, mode },
|
|
59
|
+
vertical: request.scrollbar?.vertical === false ? false : { ...request.scrollbar?.vertical, mode }
|
|
60
|
+
});
|
|
61
|
+
request.onClose();
|
|
62
|
+
}
|
|
63
|
+
})),
|
|
64
|
+
footer: /* @__PURE__ */ jsx(ReactButton, { onClick: onOpenSettings, children: "\u914D\u7F6E\u6EDA\u52A8\u6761\u5C5E\u6027" })
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
function ScrollbarCacheMenu(props) {
|
|
69
|
+
const { request } = props;
|
|
70
|
+
return /* @__PURE__ */ jsx(
|
|
71
|
+
MenuSubmenu,
|
|
72
|
+
{
|
|
73
|
+
label: "\u7F13\u5B58\u5230\u672C\u5730",
|
|
74
|
+
items: [
|
|
75
|
+
{
|
|
76
|
+
key: "cache-scrollbar",
|
|
77
|
+
label: "\u6EDA\u52A8\u6761",
|
|
78
|
+
selected: request.scrollbarCacheAvailable === true && request.cacheScrollbar !== false,
|
|
79
|
+
disabled: request.scrollbarCacheAvailable !== true,
|
|
80
|
+
onClick: () => request.onChangeCacheScrollbar?.(request.cacheScrollbar === false)
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
40
86
|
function PivotContextMenu(props) {
|
|
41
87
|
const { request } = props;
|
|
42
88
|
const [menuOpen, setMenuOpen] = useState(true);
|
|
89
|
+
const [scrollbarSettingsRequest, setScrollbarSettingsRequest] = useState(null);
|
|
90
|
+
const [scrollbarPositionRequest, setScrollbarPositionRequest] = useState(null);
|
|
43
91
|
useEffect(() => {
|
|
44
92
|
if (request) setMenuOpen(true);
|
|
45
93
|
}, [request]);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
ReactPopup,
|
|
94
|
+
const scrollbarDialog = scrollbarSettingsRequest ? /* @__PURE__ */ jsx(
|
|
95
|
+
ReactScrollbarSettingsDialog,
|
|
49
96
|
{
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
if (!open) request.onClose();
|
|
97
|
+
value: scrollbarSettingsRequest.scrollbar,
|
|
98
|
+
onConfirm: (value) => {
|
|
99
|
+
scrollbarSettingsRequest.onChangeScrollbar?.({
|
|
100
|
+
...scrollbarSettingsRequest.scrollbar,
|
|
101
|
+
...value
|
|
102
|
+
});
|
|
103
|
+
setScrollbarSettingsRequest(null);
|
|
58
104
|
},
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
105
|
+
onClose: () => setScrollbarSettingsRequest(null)
|
|
106
|
+
}
|
|
107
|
+
) : null;
|
|
108
|
+
const scrollbarPositionDialog = scrollbarPositionRequest ? /* @__PURE__ */ jsx(
|
|
109
|
+
ReactScrollbarPositionDialog,
|
|
110
|
+
{
|
|
111
|
+
rowCount: scrollbarPositionRequest.scrollbarRowCount ?? 0,
|
|
112
|
+
columnCount: scrollbarPositionRequest.scrollbarColumnCount ?? 0,
|
|
113
|
+
onConfirm: (row, column) => scrollbarPositionRequest.onScrollToPosition?.(row, column),
|
|
114
|
+
onClose: () => setScrollbarPositionRequest(null)
|
|
115
|
+
}
|
|
116
|
+
) : null;
|
|
117
|
+
if (!request)
|
|
118
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
119
|
+
scrollbarDialog,
|
|
120
|
+
scrollbarPositionDialog
|
|
121
|
+
] });
|
|
122
|
+
const openScrollbarSettings = () => {
|
|
123
|
+
setScrollbarSettingsRequest(request);
|
|
124
|
+
request.onClose();
|
|
125
|
+
};
|
|
126
|
+
const exportAndClose = (action) => action ? () => {
|
|
127
|
+
setMenuOpen(false);
|
|
128
|
+
request.onClose();
|
|
129
|
+
action();
|
|
130
|
+
} : void 0;
|
|
131
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
132
|
+
scrollbarDialog,
|
|
133
|
+
scrollbarPositionDialog,
|
|
134
|
+
/* @__PURE__ */ jsx(
|
|
135
|
+
ReactPopup,
|
|
136
|
+
{
|
|
137
|
+
open: menuOpen,
|
|
138
|
+
anchorRect: { x: request.x, y: request.y, width: 0, height: 0 },
|
|
139
|
+
offset: 4,
|
|
140
|
+
matchAnchorWidth: false,
|
|
141
|
+
minWidth: 260,
|
|
142
|
+
onOpenChange: (open) => {
|
|
143
|
+
setMenuOpen(open);
|
|
144
|
+
if (!open) request.onClose();
|
|
145
|
+
},
|
|
146
|
+
surfaceStyle: { ...CONTEXT_MENU_SURFACE_STYLE, width: 260 },
|
|
147
|
+
children: /* @__PURE__ */ jsx("div", { children: request.target === "scrollbar" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
148
|
+
/* @__PURE__ */ jsx(
|
|
149
|
+
ScrollbarModeMenu,
|
|
150
|
+
{
|
|
151
|
+
request,
|
|
152
|
+
onOpenSettings: openScrollbarSettings
|
|
153
|
+
}
|
|
154
|
+
),
|
|
155
|
+
/* @__PURE__ */ jsx(
|
|
156
|
+
MenuAction,
|
|
157
|
+
{
|
|
158
|
+
label: "\u6EDA\u52A8\u5230\u6307\u5B9A\u884C / \u5217",
|
|
159
|
+
onClick: () => {
|
|
160
|
+
setScrollbarPositionRequest(request);
|
|
161
|
+
request.onClose();
|
|
76
162
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
label: "\u5BFC\u51FA CSV",
|
|
99
|
-
onClick: request.onExportCsv
|
|
163
|
+
}
|
|
164
|
+
),
|
|
165
|
+
/* @__PURE__ */ jsx(
|
|
166
|
+
MenuAction,
|
|
167
|
+
{
|
|
168
|
+
label: "\u91CD\u7F6E\u6EDA\u52A8\u6761",
|
|
169
|
+
onClick: () => {
|
|
170
|
+
request.onResetScrollbar?.();
|
|
171
|
+
request.onClose();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
/* @__PURE__ */ jsx(ScrollbarCacheMenu, { request })
|
|
176
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
177
|
+
request.title ? /* @__PURE__ */ jsx(
|
|
178
|
+
"div",
|
|
179
|
+
{
|
|
180
|
+
style: {
|
|
181
|
+
padding: "6px 10px",
|
|
182
|
+
color: "#8f959e",
|
|
183
|
+
fontSize: 12
|
|
100
184
|
},
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
185
|
+
children: request.title
|
|
186
|
+
}
|
|
187
|
+
) : null,
|
|
188
|
+
/* @__PURE__ */ jsx(
|
|
189
|
+
MenuSubmenu,
|
|
190
|
+
{
|
|
191
|
+
label: "\u590D\u5236",
|
|
192
|
+
items: [
|
|
193
|
+
{
|
|
194
|
+
key: "copy-cell",
|
|
195
|
+
label: request.target === "header" ? "\u590D\u5236\u8868\u5934" : "\u590D\u5236\u5355\u5143\u683C",
|
|
196
|
+
onClick: request.onCopy
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
key: "copy-selection",
|
|
200
|
+
label: "\u590D\u5236\u9009\u533A",
|
|
201
|
+
onClick: request.target === "header" ? void 0 : request.onCopySelection
|
|
202
|
+
},
|
|
203
|
+
...["all", "selection", "viewport"].map(
|
|
204
|
+
(scope) => ({
|
|
205
|
+
key: `copy-image-${scope}`,
|
|
206
|
+
label: `\u590D\u5236\u4E3A\u56FE\u7247 \xB7 ${{ all: "\u6240\u6709\u533A\u57DF", selection: "\u9009\u4E2D\u533A\u57DF", viewport: "\u89C6\u53E3\u533A\u57DF" }[scope]}`,
|
|
207
|
+
onClick: scope === "selection" && !request.hasImageSelection ? void 0 : request.onCopyImage ? () => request.onCopyImage?.(scope) : void 0
|
|
208
|
+
})
|
|
209
|
+
)
|
|
210
|
+
],
|
|
211
|
+
children: request.target !== "header" ? /* @__PURE__ */ jsx(CustomSelectionMenu, { request }) : null
|
|
212
|
+
}
|
|
213
|
+
),
|
|
214
|
+
request.target === "header" ? /* @__PURE__ */ jsx(HeaderMenu, { request }) : null,
|
|
215
|
+
request.target === "summary" ? /* @__PURE__ */ jsx(
|
|
216
|
+
SummaryMenu,
|
|
217
|
+
{
|
|
218
|
+
request
|
|
219
|
+
},
|
|
220
|
+
`${request.indicatorKey}-${request.x}-${request.y}`
|
|
221
|
+
) : null,
|
|
222
|
+
/* @__PURE__ */ jsx(DataFormatMenu, { request }),
|
|
223
|
+
/* @__PURE__ */ jsx(DensityMenu, { request }),
|
|
224
|
+
/* @__PURE__ */ jsx(
|
|
225
|
+
ScrollbarModeMenu,
|
|
226
|
+
{
|
|
227
|
+
request,
|
|
228
|
+
onOpenSettings: openScrollbarSettings
|
|
229
|
+
}
|
|
230
|
+
),
|
|
231
|
+
/* @__PURE__ */ jsx(
|
|
232
|
+
MenuAction,
|
|
233
|
+
{
|
|
234
|
+
label: "\u6EDA\u52A8\u5230\u6307\u5B9A\u884C / \u5217",
|
|
235
|
+
onClick: () => {
|
|
236
|
+
setScrollbarPositionRequest(request);
|
|
237
|
+
request.onClose();
|
|
105
238
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
239
|
+
}
|
|
240
|
+
),
|
|
241
|
+
/* @__PURE__ */ jsx(ScrollbarCacheMenu, { request }),
|
|
242
|
+
/* @__PURE__ */ jsx(
|
|
243
|
+
MenuSubmenu,
|
|
244
|
+
{
|
|
245
|
+
label: "\u91CD\u7F6E",
|
|
246
|
+
items: [
|
|
247
|
+
{
|
|
248
|
+
key: "reset-scrollbar",
|
|
249
|
+
label: "\u91CD\u7F6E\u6EDA\u52A8\u6761",
|
|
250
|
+
onClick: () => {
|
|
251
|
+
request.onResetScrollbar?.();
|
|
252
|
+
request.onClose();
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
),
|
|
258
|
+
/* @__PURE__ */ jsx(
|
|
259
|
+
MenuSubmenu,
|
|
260
|
+
{
|
|
261
|
+
label: "\u5BFC\u51FA",
|
|
262
|
+
items: [
|
|
263
|
+
{
|
|
264
|
+
key: "export-csv",
|
|
265
|
+
label: "\u5BFC\u51FA CSV",
|
|
266
|
+
onClick: exportAndClose(request.onExportCsv)
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
key: "export-xlsx",
|
|
270
|
+
label: "\u5BFC\u51FA XLSX",
|
|
271
|
+
onClick: exportAndClose(request.onExportXlsx)
|
|
272
|
+
},
|
|
273
|
+
...["all", "selection", "viewport"].map(
|
|
274
|
+
(scope) => ({
|
|
275
|
+
key: `export-image-${scope}`,
|
|
276
|
+
label: `\u5BFC\u51FA\u56FE\u7247 \xB7 ${{ all: "\u6240\u6709\u533A\u57DF", selection: "\u9009\u4E2D\u533A\u57DF", viewport: "\u89C6\u53E3\u533A\u57DF" }[scope]}`,
|
|
277
|
+
onClick: exportAndClose(
|
|
278
|
+
scope === "selection" && !request.hasImageSelection ? void 0 : request.onExportImage ? () => request.onExportImage?.(scope) : void 0
|
|
279
|
+
)
|
|
280
|
+
})
|
|
281
|
+
)
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
),
|
|
285
|
+
request.recordCount != null ? /* @__PURE__ */ jsxs(
|
|
286
|
+
"div",
|
|
287
|
+
{
|
|
288
|
+
style: {
|
|
289
|
+
padding: "8px 10px",
|
|
290
|
+
color: "#8f959e",
|
|
291
|
+
fontSize: 12
|
|
292
|
+
},
|
|
293
|
+
children: [
|
|
294
|
+
"\u4E0B\u94BB\u8BB0\u5F55 ",
|
|
295
|
+
request.recordCount,
|
|
296
|
+
" \u6761"
|
|
297
|
+
]
|
|
298
|
+
}
|
|
299
|
+
) : null
|
|
300
|
+
] }) })
|
|
301
|
+
}
|
|
302
|
+
)
|
|
303
|
+
] });
|
|
117
304
|
}
|
|
118
305
|
function HeaderMenu(props) {
|
|
119
306
|
const { request } = props;
|
|
@@ -815,54 +1002,15 @@ function DataFormatMenu(props) {
|
|
|
815
1002
|
);
|
|
816
1003
|
}
|
|
817
1004
|
function PivotExportNameDialog({
|
|
818
|
-
request
|
|
1005
|
+
request,
|
|
1006
|
+
onClose
|
|
819
1007
|
}) {
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
extension ? request.fileName.slice(0, -extension.length) : request.fileName
|
|
823
|
-
);
|
|
824
|
-
const [invalid, setInvalid] = useState(false);
|
|
825
|
-
const confirm = () => {
|
|
826
|
-
if (!fileName.trim()) {
|
|
827
|
-
setInvalid(true);
|
|
828
|
-
return;
|
|
829
|
-
}
|
|
830
|
-
request.onConfirm(`${fileName.trim()}${extension}`);
|
|
831
|
-
};
|
|
832
|
-
return /* @__PURE__ */ jsxs(
|
|
833
|
-
ReactModal,
|
|
1008
|
+
return /* @__PURE__ */ jsx(
|
|
1009
|
+
ReactListTableExportNameDialog,
|
|
834
1010
|
{
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
fullscreenable: false,
|
|
839
|
-
onCancel: request.onCancel,
|
|
840
|
-
onOk: confirm,
|
|
841
|
-
okText: "\u5BFC\u51FA",
|
|
842
|
-
cancelText: "\u53D6\u6D88",
|
|
843
|
-
children: [
|
|
844
|
-
/* @__PURE__ */ jsxs("label", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
|
|
845
|
-
"\u6587\u4EF6\u540D\u79F0",
|
|
846
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
|
|
847
|
-
/* @__PURE__ */ jsx(
|
|
848
|
-
ReactInput,
|
|
849
|
-
{
|
|
850
|
-
autoFocus: true,
|
|
851
|
-
value: fileName,
|
|
852
|
-
placeholder: "\u8BF7\u8F93\u5165\u6587\u4EF6\u540D\u79F0",
|
|
853
|
-
onFocus: (event) => event.target.select(),
|
|
854
|
-
onChange: (event) => {
|
|
855
|
-
setFileName(event.target.value);
|
|
856
|
-
setInvalid(false);
|
|
857
|
-
},
|
|
858
|
-
onPressEnter: confirm
|
|
859
|
-
}
|
|
860
|
-
),
|
|
861
|
-
/* @__PURE__ */ jsx("span", { "aria-label": "\u6587\u4EF6\u540E\u7F00", style: { flexShrink: 0 }, children: extension })
|
|
862
|
-
] })
|
|
863
|
-
] }),
|
|
864
|
-
invalid ? /* @__PURE__ */ jsx("div", { role: "alert", style: { color: "#ff4d4f", marginTop: 8 }, children: "\u8BF7\u8F93\u5165\u6587\u4EF6\u540D\u79F0" }) : null
|
|
865
|
-
]
|
|
1011
|
+
request,
|
|
1012
|
+
onClose,
|
|
1013
|
+
renderTable: (props) => /* @__PURE__ */ jsx(ReactListTable, { ...props })
|
|
866
1014
|
}
|
|
867
1015
|
);
|
|
868
1016
|
}
|
|
@@ -1855,7 +2003,14 @@ function resolveReactPivotTableDebugOptions(debug, inheritedEnabled) {
|
|
|
1855
2003
|
};
|
|
1856
2004
|
}
|
|
1857
2005
|
function ReactPivotTableInner(props, ref) {
|
|
1858
|
-
const {
|
|
2006
|
+
const {
|
|
2007
|
+
className,
|
|
2008
|
+
style,
|
|
2009
|
+
customization,
|
|
2010
|
+
pivotAreas,
|
|
2011
|
+
title,
|
|
2012
|
+
...tableOptions
|
|
2013
|
+
} = props;
|
|
1859
2014
|
const inheritedDebugEnabled = useReactPivotTableDebugEnabled();
|
|
1860
2015
|
const resolvedDebug = useMemo(
|
|
1861
2016
|
() => resolveReactPivotTableDebugOptions(
|
|
@@ -1868,6 +2023,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1868
2023
|
const tableRef = useRef(null);
|
|
1869
2024
|
const customizationOptions = customization && typeof customization === "object" ? customization : void 0;
|
|
1870
2025
|
const customizationEnabled = customization === true || customizationOptions != null;
|
|
2026
|
+
const pivotLayoutEnabled = customizationEnabled || pivotAreas != null;
|
|
1871
2027
|
const [internalPanelOpen, setInternalPanelOpen] = useState(
|
|
1872
2028
|
customizationOptions?.defaultOpen ?? false
|
|
1873
2029
|
);
|
|
@@ -1882,13 +2038,35 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1882
2038
|
const chartIdRef = useRef(0);
|
|
1883
2039
|
const layoutRevisionRef = useRef(0);
|
|
1884
2040
|
const [internalLayout, setInternalLayout] = useState(
|
|
1885
|
-
() => customizationOptions?.defaultLayout ??
|
|
2041
|
+
() => pivotAreas ?? customizationOptions?.defaultLayout ?? createPivotFieldLayout({
|
|
2042
|
+
filterDimensions: tableOptions.filterDimensions,
|
|
2043
|
+
columns: tableOptions.columns,
|
|
2044
|
+
rows: tableOptions.rows,
|
|
2045
|
+
indicators: tableOptions.indicators
|
|
2046
|
+
})
|
|
1886
2047
|
);
|
|
1887
2048
|
const [fieldOverrides, setFieldOverrides] = useState({});
|
|
1888
2049
|
const [densityOverride, setDensityOverride] = useState(null);
|
|
2050
|
+
const [scrollbarOverride, setScrollbarOverride] = useState(null);
|
|
2051
|
+
const [sharedScrollbar, setSharedScrollbar] = useState(
|
|
2052
|
+
getSharedScrollbarSettings
|
|
2053
|
+
);
|
|
2054
|
+
useEffect(
|
|
2055
|
+
() => subscribeSharedScrollbarSettings(
|
|
2056
|
+
() => setSharedScrollbar(getSharedScrollbarSettings())
|
|
2057
|
+
),
|
|
2058
|
+
[]
|
|
2059
|
+
);
|
|
2060
|
+
const [scrollbarCacheEnabled, setScrollbarCacheEnabled] = useState(true);
|
|
2061
|
+
const scrollbarRevisionRef = useRef(0);
|
|
2062
|
+
const scrollbarStorageKey = customizationOptions?.storageKey;
|
|
2063
|
+
const effectiveScrollbar = sharedScrollbar.shared ? sharedScrollbar.value : scrollbarOverride ?? tableOptions.scrollbar;
|
|
1889
2064
|
const [filterRequest, setFilterRequest] = useState(null);
|
|
1890
2065
|
const [contextMenuRequest, setContextMenuRequest] = useState(null);
|
|
1891
2066
|
const [exportNameRequest, setExportNameRequest] = useState(null);
|
|
2067
|
+
const [exportLoadingText, setExportLoadingText] = useState(
|
|
2068
|
+
null
|
|
2069
|
+
);
|
|
1892
2070
|
const [tooltipRequest, setTooltipRequest] = useState(null);
|
|
1893
2071
|
const panelOpen = customizationOptions?.open ?? internalPanelOpen;
|
|
1894
2072
|
const fieldLayout = customizationOptions?.layout ?? internalLayout;
|
|
@@ -1940,8 +2118,8 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1940
2118
|
[baseFields, fieldOverrides]
|
|
1941
2119
|
);
|
|
1942
2120
|
const customizedOptions = useMemo(
|
|
1943
|
-
() =>
|
|
1944
|
-
[
|
|
2121
|
+
() => pivotLayoutEnabled ? resolvePivotFieldLayoutOptions(fields, fieldLayout) : null,
|
|
2122
|
+
[pivotLayoutEnabled, fieldLayout, fields]
|
|
1945
2123
|
);
|
|
1946
2124
|
const overriddenIndicators = useMemo(
|
|
1947
2125
|
() => tableOptions.indicators.map((indicator) => {
|
|
@@ -1965,10 +2143,12 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1965
2143
|
const options = {
|
|
1966
2144
|
...tableOptions,
|
|
1967
2145
|
...customizedOptions,
|
|
2146
|
+
scrollbar: effectiveScrollbar,
|
|
1968
2147
|
debug: resolvedDebug,
|
|
1969
2148
|
rowHeight: densityOverride == null ? tableOptions.rowHeight : resolveDensityRowHeight(densityOverride),
|
|
1970
2149
|
indicators: customizedOptions?.indicators ?? overriddenIndicators,
|
|
1971
2150
|
ui: {
|
|
2151
|
+
onLoadingRequest: (request) => setExportLoadingText(request ? request.text ?? "\u6B63\u5728\u5BFC\u51FA\u2026" : null),
|
|
1972
2152
|
onExportNameRequest: (request) => {
|
|
1973
2153
|
setExportNameRequest(request);
|
|
1974
2154
|
},
|
|
@@ -1979,6 +2159,39 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1979
2159
|
const fieldKey = request.indicatorKey;
|
|
1980
2160
|
const enhancedRequest = {
|
|
1981
2161
|
...request,
|
|
2162
|
+
scrollbar: effectiveScrollbar,
|
|
2163
|
+
cacheScrollbar: scrollbarCacheEnabled,
|
|
2164
|
+
scrollbarCacheAvailable: Boolean(scrollbarStorageKey),
|
|
2165
|
+
onChangeCacheScrollbar: (enabled) => {
|
|
2166
|
+
setScrollbarCacheEnabled(enabled);
|
|
2167
|
+
scrollbarRevisionRef.current += 1;
|
|
2168
|
+
if (scrollbarStorageKey)
|
|
2169
|
+
void savePivotScrollbarConfig(scrollbarStorageKey, {
|
|
2170
|
+
enabled,
|
|
2171
|
+
scrollbar: enabled ? effectiveScrollbar : void 0
|
|
2172
|
+
});
|
|
2173
|
+
},
|
|
2174
|
+
onChangeScrollbar: (value) => {
|
|
2175
|
+
setScrollbarOverride(value);
|
|
2176
|
+
if (getSharedScrollbarSettings().shared)
|
|
2177
|
+
setSharedScrollbarSettings({ shared: true, value });
|
|
2178
|
+
scrollbarRevisionRef.current += 1;
|
|
2179
|
+
if (scrollbarStorageKey && scrollbarCacheEnabled)
|
|
2180
|
+
void savePivotScrollbarConfig(scrollbarStorageKey, {
|
|
2181
|
+
enabled: true,
|
|
2182
|
+
scrollbar: value
|
|
2183
|
+
});
|
|
2184
|
+
},
|
|
2185
|
+
onResetScrollbar: () => {
|
|
2186
|
+
setScrollbarOverride(null);
|
|
2187
|
+
if (getSharedScrollbarSettings().shared)
|
|
2188
|
+
setSharedScrollbarSettings({ shared: true, value: {} });
|
|
2189
|
+
scrollbarRevisionRef.current += 1;
|
|
2190
|
+
if (scrollbarStorageKey && scrollbarCacheEnabled)
|
|
2191
|
+
void savePivotScrollbarConfig(scrollbarStorageKey, {
|
|
2192
|
+
enabled: true
|
|
2193
|
+
});
|
|
2194
|
+
},
|
|
1982
2195
|
onChangeDensity: (density) => {
|
|
1983
2196
|
nativeChangeDensity?.(density);
|
|
1984
2197
|
setDensityOverride(density);
|
|
@@ -2116,6 +2329,21 @@ function ReactPivotTableInner(props, ref) {
|
|
|
2116
2329
|
table.updateOptions(options);
|
|
2117
2330
|
refreshChartModel();
|
|
2118
2331
|
}, [options]);
|
|
2332
|
+
useEffect(() => {
|
|
2333
|
+
if (!scrollbarStorageKey) return;
|
|
2334
|
+
let active = true;
|
|
2335
|
+
const revision = scrollbarRevisionRef.current;
|
|
2336
|
+
void loadPivotScrollbarConfig(scrollbarStorageKey).then((stored) => {
|
|
2337
|
+
if (!active || scrollbarRevisionRef.current !== revision || !stored)
|
|
2338
|
+
return;
|
|
2339
|
+
setScrollbarCacheEnabled(stored.enabled);
|
|
2340
|
+
if (stored.enabled && stored.scrollbar)
|
|
2341
|
+
setScrollbarOverride(stored.scrollbar);
|
|
2342
|
+
});
|
|
2343
|
+
return () => {
|
|
2344
|
+
active = false;
|
|
2345
|
+
};
|
|
2346
|
+
}, [scrollbarStorageKey]);
|
|
2119
2347
|
useEffect(() => {
|
|
2120
2348
|
const storageKey = customizationOptions?.storageKey;
|
|
2121
2349
|
if (!storageKey || customizationOptions?.layout !== void 0) return;
|
|
@@ -2188,11 +2416,27 @@ function ReactPivotTableInner(props, ref) {
|
|
|
2188
2416
|
{
|
|
2189
2417
|
className: `react-pivot-table${className ? ` ${className}` : ""}`,
|
|
2190
2418
|
style: {
|
|
2419
|
+
position: "relative",
|
|
2191
2420
|
width: props.width ?? "100%",
|
|
2192
2421
|
height: props.height ?? "100%",
|
|
2193
2422
|
...style
|
|
2194
2423
|
},
|
|
2195
2424
|
children: [
|
|
2425
|
+
exportLoadingText ? /* @__PURE__ */ jsx(
|
|
2426
|
+
"div",
|
|
2427
|
+
{
|
|
2428
|
+
role: "status",
|
|
2429
|
+
style: {
|
|
2430
|
+
position: "absolute",
|
|
2431
|
+
inset: 0,
|
|
2432
|
+
zIndex: 10,
|
|
2433
|
+
display: "grid",
|
|
2434
|
+
placeItems: "center",
|
|
2435
|
+
background: "rgba(255,255,255,0.75)"
|
|
2436
|
+
},
|
|
2437
|
+
children: exportLoadingText
|
|
2438
|
+
}
|
|
2439
|
+
) : null,
|
|
2196
2440
|
/* @__PURE__ */ jsx(
|
|
2197
2441
|
PivotTitlebar,
|
|
2198
2442
|
{
|
|
@@ -2285,7 +2529,13 @@ function ReactPivotTableInner(props, ref) {
|
|
|
2285
2529
|
),
|
|
2286
2530
|
/* @__PURE__ */ jsx(ReactFilterPanel, { request: sharedFilterRequest }),
|
|
2287
2531
|
/* @__PURE__ */ jsx(PivotContextMenu, { request: contextMenuRequest }),
|
|
2288
|
-
exportNameRequest ? /* @__PURE__ */ jsx(
|
|
2532
|
+
exportNameRequest ? /* @__PURE__ */ jsx(
|
|
2533
|
+
PivotExportNameDialog,
|
|
2534
|
+
{
|
|
2535
|
+
request: exportNameRequest,
|
|
2536
|
+
onClose: () => setExportNameRequest(null)
|
|
2537
|
+
}
|
|
2538
|
+
) : null,
|
|
2289
2539
|
/* @__PURE__ */ jsx(PivotTooltip, { request: tooltipRequest })
|
|
2290
2540
|
] });
|
|
2291
2541
|
}
|