@canvas-components/react-pivot-table 0.2.17 → 0.2.18
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 +188 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +188 -22
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -32,11 +32,12 @@ function styleInject(css, { insertAt } = {}) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// src/features/context-menu/pivot-context-menu.css
|
|
35
|
-
styleInject(".react-pivot-table-menu-action {\n transition: background-color 0.2s ease, color 0.2s ease;\n}\n.react-pivot-table-menu-action:hover {\n background: #f3f4f6 !important;\n}\n.react-pivot-table-menu-chevron {\n width: 7px;\n height: 7px;\n flex: 0 0 auto;\n margin-left: 8px;\n border-top: 1.5px solid #9ca3af;\n border-right: 1.5px solid #9ca3af;\n transform: rotate(45deg);\n transform-origin: center;\n transition: transform 0.18s ease, border-color 0.18s ease;\n}\n.react-pivot-table-menu-action:hover .react-pivot-table-menu-chevron,\n.react-pivot-table-menu-chevron-active {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n");
|
|
35
|
+
styleInject(".react-pivot-table-menu-action {\n font-size: inherit;\n transition: background-color 0.2s ease, color 0.2s ease;\n}\n.react-pivot-table-menu-action:hover {\n background: #f3f4f6 !important;\n}\n.react-pivot-table-menu-chevron {\n width: 7px;\n height: 7px;\n flex: 0 0 auto;\n margin-left: 8px;\n border-top: 1.5px solid #9ca3af;\n border-right: 1.5px solid #9ca3af;\n transform: rotate(45deg);\n transform-origin: center;\n transition: transform 0.18s ease, border-color 0.18s ease;\n}\n.react-pivot-table-menu-action:hover .react-pivot-table-menu-chevron,\n.react-pivot-table-menu-chevron-active {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n");
|
|
36
36
|
var CONTEXT_MENU_SURFACE_STYLE = {
|
|
37
37
|
padding: 8,
|
|
38
38
|
background: "#ffffff",
|
|
39
|
-
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)"
|
|
39
|
+
boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)",
|
|
40
|
+
fontSize: 14
|
|
40
41
|
};
|
|
41
42
|
function PivotContextMenu(props) {
|
|
42
43
|
const { request } = props;
|
|
@@ -146,7 +147,29 @@ function HeaderMenu(props) {
|
|
|
146
147
|
]
|
|
147
148
|
}
|
|
148
149
|
) : null,
|
|
149
|
-
request.
|
|
150
|
+
request.onAutoFitCurrentColumn || request.onAutoFitAllColumns ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
151
|
+
MenuSubmenu,
|
|
152
|
+
{
|
|
153
|
+
label: "\u81EA\u52A8\u8C03\u6574\u5217\u5BBD",
|
|
154
|
+
items: [
|
|
155
|
+
{
|
|
156
|
+
key: "auto-fit-current",
|
|
157
|
+
label: "\u5F53\u524D\u5217",
|
|
158
|
+
onClick: request.onAutoFitCurrentColumn
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
key: "auto-fit-all",
|
|
162
|
+
label: "\u5168\u90E8\u5217",
|
|
163
|
+
onClick: request.onAutoFitAllColumns
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
key: "auto-fit-fill-container",
|
|
167
|
+
label: "\u81EA\u52A8\u94FA\u6EE1\u5BB9\u5668",
|
|
168
|
+
onClick: request.onAutoFitFillContainer
|
|
169
|
+
}
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
) : null,
|
|
150
173
|
hasExpand ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
151
174
|
MenuSubmenu,
|
|
152
175
|
{
|
|
@@ -174,14 +197,35 @@ function HeaderMenu(props) {
|
|
|
174
197
|
}
|
|
175
198
|
function SummaryMenu(props) {
|
|
176
199
|
const { request } = props;
|
|
200
|
+
const [title, setTitle] = react.useState(request.summaryTitle ?? "");
|
|
177
201
|
const [precision, setPrecision] = react.useState(
|
|
178
202
|
request.summaryPrecision ?? null
|
|
179
203
|
);
|
|
204
|
+
const [roundingMode, setRoundingMode] = react.useState(
|
|
205
|
+
request.summaryRoundingMode ?? "round"
|
|
206
|
+
);
|
|
207
|
+
const [preserveTrailingZeros, setPreserveTrailingZeros] = react.useState(
|
|
208
|
+
request.summaryPreserveTrailingZeros ?? false
|
|
209
|
+
);
|
|
210
|
+
react.useEffect(() => {
|
|
211
|
+
setTitle(request.summaryTitle ?? "");
|
|
212
|
+
setPrecision(request.summaryPrecision ?? null);
|
|
213
|
+
setRoundingMode(request.summaryRoundingMode ?? "round");
|
|
214
|
+
setPreserveTrailingZeros(request.summaryPreserveTrailingZeros ?? false);
|
|
215
|
+
}, [
|
|
216
|
+
request.indicatorKey,
|
|
217
|
+
request.summaryTitle,
|
|
218
|
+
request.summaryPrecision,
|
|
219
|
+
request.summaryRoundingMode,
|
|
220
|
+
request.summaryPreserveTrailingZeros
|
|
221
|
+
]);
|
|
180
222
|
const aggregators = [
|
|
181
223
|
["sum", "\u6C42\u548C"],
|
|
182
224
|
["avg", "\u5E73\u5747\u503C"],
|
|
183
225
|
["count", "\u8BA1\u6570"],
|
|
184
226
|
["distinctCount", "\u53BB\u91CD\u8BA1\u6570"],
|
|
227
|
+
["rowCount", "\u884C\u6570"],
|
|
228
|
+
["mergedRowCount", "\u5408\u5E76\u884C\u6570"],
|
|
185
229
|
["min", "\u6700\u5C0F\u503C"],
|
|
186
230
|
["max", "\u6700\u5927\u503C"]
|
|
187
231
|
];
|
|
@@ -190,15 +234,62 @@ function SummaryMenu(props) {
|
|
|
190
234
|
MenuSubmenu,
|
|
191
235
|
{
|
|
192
236
|
label: "\u6C47\u603B\u65B9\u5F0F",
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
237
|
+
minWidth: 268,
|
|
238
|
+
header: request.onChangeSummaryTitle ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
239
|
+
"div",
|
|
240
|
+
{
|
|
241
|
+
style: {
|
|
242
|
+
display: "grid",
|
|
243
|
+
gridTemplateColumns: "56px 1fr",
|
|
244
|
+
gap: 8,
|
|
245
|
+
alignItems: "center",
|
|
246
|
+
padding: "2px 10px 10px",
|
|
247
|
+
marginBottom: 4,
|
|
248
|
+
borderBottom: "1px solid #e5e7eb"
|
|
249
|
+
},
|
|
250
|
+
children: [
|
|
251
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontSize: 14 }, children: "\u6807\u9898\uFF1A" }),
|
|
252
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
253
|
+
reactComponents.ReactInput,
|
|
254
|
+
{
|
|
255
|
+
value: title,
|
|
256
|
+
placeholder: "\u8BF7\u8F93\u5165\u6807\u9898",
|
|
257
|
+
onChange: (event) => {
|
|
258
|
+
setTitle(event.target.value);
|
|
259
|
+
request.onChangeSummaryTitle?.(event.target.value);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
]
|
|
200
264
|
}
|
|
201
|
-
|
|
265
|
+
) : void 0,
|
|
266
|
+
items: [
|
|
267
|
+
...aggregators.map(([value, label]) => ({
|
|
268
|
+
key: `summary-${value}`,
|
|
269
|
+
label,
|
|
270
|
+
selected: !request.summaryDisabled && request.summaryAggregator === value,
|
|
271
|
+
onClick: () => {
|
|
272
|
+
request.onChangeSummaryAggregator?.(value);
|
|
273
|
+
request.onClose();
|
|
274
|
+
}
|
|
275
|
+
})),
|
|
276
|
+
{
|
|
277
|
+
key: "summary-prefix",
|
|
278
|
+
label: "\u5C55\u793A\u6C47\u603B\u65B9\u5F0F\u524D\u7F00",
|
|
279
|
+
separatorBefore: true,
|
|
280
|
+
selected: request.summaryShowTypePrefix !== false,
|
|
281
|
+
disabled: request.summaryDisabled,
|
|
282
|
+
onClick: () => request.onChangeSummaryShowTypePrefix?.(
|
|
283
|
+
request.summaryShowTypePrefix === false
|
|
284
|
+
)
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
key: "summary-clear",
|
|
288
|
+
label: "\u53D6\u6D88\u6C47\u603B",
|
|
289
|
+
separatorBefore: true,
|
|
290
|
+
onClick: request.onClearSummary
|
|
291
|
+
}
|
|
292
|
+
],
|
|
202
293
|
footer: request.onChangeSummaryPrecision ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
203
294
|
"div",
|
|
204
295
|
{
|
|
@@ -212,7 +303,7 @@ function SummaryMenu(props) {
|
|
|
212
303
|
borderTop: "1px solid #e5e7eb"
|
|
213
304
|
},
|
|
214
305
|
children: [
|
|
215
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontSize:
|
|
306
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontSize: 14 }, children: "\u5C0F\u6570\u4F4D\u6570" }),
|
|
216
307
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
217
308
|
reactComponents.ReactInputNumber,
|
|
218
309
|
{
|
|
@@ -221,10 +312,42 @@ function SummaryMenu(props) {
|
|
|
221
312
|
max: 20,
|
|
222
313
|
step: 1,
|
|
223
314
|
precision: 0,
|
|
224
|
-
placeholder: "\
|
|
315
|
+
placeholder: "\u9ED8\u8BA4",
|
|
316
|
+
onChange: setPrecision,
|
|
317
|
+
onCommit: (value) => request.onChangeSummaryPrecision?.(value ?? void 0)
|
|
318
|
+
}
|
|
319
|
+
),
|
|
320
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontSize: 14 }, children: "\u53D6\u6574\u65B9\u5F0F" }),
|
|
321
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
322
|
+
reactComponents.ReactSelect,
|
|
323
|
+
{
|
|
324
|
+
value: roundingMode,
|
|
325
|
+
options: [
|
|
326
|
+
{ label: "\u56DB\u820D\u4E94\u5165", value: "round" },
|
|
327
|
+
{ label: "\u5411\u4E0B\u53D6\u6574", value: "floor" },
|
|
328
|
+
{ label: "\u5411\u4E0A\u53D6\u6574", value: "ceil" },
|
|
329
|
+
{ label: "\u820D\u53BB\u4E0D\u5904\u7406", value: "truncate" }
|
|
330
|
+
],
|
|
331
|
+
onChange: (value) => {
|
|
332
|
+
const mode = value;
|
|
333
|
+
setRoundingMode(mode);
|
|
334
|
+
request.onChangeSummaryRoundingMode?.(mode);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
),
|
|
338
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontSize: 14 }, children: "\u4FDD\u7559\u65E0\u6548\u96F6" }),
|
|
339
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
340
|
+
reactComponents.ReactSelect,
|
|
341
|
+
{
|
|
342
|
+
value: preserveTrailingZeros ? "true" : "false",
|
|
343
|
+
options: [
|
|
344
|
+
{ label: "\u4E0D\u4FDD\u7559", value: "false" },
|
|
345
|
+
{ label: "\u4FDD\u7559", value: "true" }
|
|
346
|
+
],
|
|
225
347
|
onChange: (value) => {
|
|
226
|
-
|
|
227
|
-
|
|
348
|
+
const enabled = value === "true";
|
|
349
|
+
setPreserveTrailingZeros(enabled);
|
|
350
|
+
request.onChangeSummaryPreserveTrailingZeros?.(enabled);
|
|
228
351
|
}
|
|
229
352
|
}
|
|
230
353
|
)
|
|
@@ -421,7 +544,7 @@ function MenuAction(props) {
|
|
|
421
544
|
);
|
|
422
545
|
}
|
|
423
546
|
function MenuSubmenu(props) {
|
|
424
|
-
const { label, items, footer, children, minWidth = 220 } = props;
|
|
547
|
+
const { label, items, footer, header, children, minWidth = 220 } = props;
|
|
425
548
|
const menuItems = items.filter((item) => item.onClick || item.disabled);
|
|
426
549
|
const reserveSelectionIcon = menuItems.some(
|
|
427
550
|
(item) => typeof item.selected === "boolean"
|
|
@@ -429,7 +552,7 @@ function MenuSubmenu(props) {
|
|
|
429
552
|
const triggerRef = react.useRef(null);
|
|
430
553
|
const [open, setOpen] = react.useState(false);
|
|
431
554
|
const closeTimerRef = react.useRef(null);
|
|
432
|
-
if (!menuItems.length && !footer && !children) return null;
|
|
555
|
+
if (!menuItems.length && !footer && !header && !children) return null;
|
|
433
556
|
const clearCloseTimer = () => {
|
|
434
557
|
if (closeTimerRef.current != null) {
|
|
435
558
|
window.clearTimeout(closeTimerRef.current);
|
|
@@ -496,6 +619,7 @@ function MenuSubmenu(props) {
|
|
|
496
619
|
onOpenChange: setOpen,
|
|
497
620
|
surfaceStyle: { ...CONTEXT_MENU_SURFACE_STYLE, width: minWidth },
|
|
498
621
|
children: /* @__PURE__ */ jsxRuntime.jsxs("div", { onMouseEnter: clearCloseTimer, onMouseLeave: scheduleClose, children: [
|
|
622
|
+
header,
|
|
499
623
|
menuItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
|
|
500
624
|
item.separatorBefore ? /* @__PURE__ */ jsxRuntime.jsx(MenuDivider, {}) : null,
|
|
501
625
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -1276,7 +1400,9 @@ var aggregatorOptions = [
|
|
|
1276
1400
|
{ label: "\u5E73\u5747\u503C", value: "avg" },
|
|
1277
1401
|
{ label: "\u6700\u5927\u503C", value: "max" },
|
|
1278
1402
|
{ label: "\u6700\u5C0F\u503C", value: "min" },
|
|
1279
|
-
{ label: "\u53BB\u91CD\u8BA1\u6570", value: "distinctCount" }
|
|
1403
|
+
{ label: "\u53BB\u91CD\u8BA1\u6570", value: "distinctCount" },
|
|
1404
|
+
{ label: "\u884C\u6570", value: "rowCount" },
|
|
1405
|
+
{ label: "\u5408\u5E76\u884C\u6570", value: "mergedRowCount" }
|
|
1280
1406
|
];
|
|
1281
1407
|
var popupStyle = {
|
|
1282
1408
|
padding: 0,
|
|
@@ -1805,6 +1931,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1805
1931
|
title: override.title ?? field.title,
|
|
1806
1932
|
indicator: {
|
|
1807
1933
|
...field.indicator,
|
|
1934
|
+
...override,
|
|
1808
1935
|
title: override.title ?? field.indicator?.title,
|
|
1809
1936
|
aggregator: override.aggregator ?? field.indicator?.aggregator,
|
|
1810
1937
|
precision: "precision" in override ? override.precision : field.indicator?.precision,
|
|
@@ -1824,6 +1951,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1824
1951
|
if (!override) return indicator;
|
|
1825
1952
|
return {
|
|
1826
1953
|
...indicator,
|
|
1954
|
+
...override,
|
|
1827
1955
|
title: override.title ?? indicator.title,
|
|
1828
1956
|
aggregator: override.aggregator ?? indicator.aggregator,
|
|
1829
1957
|
precision: "precision" in override ? override.precision : indicator.precision,
|
|
@@ -1860,8 +1988,35 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1860
1988
|
onChangeDataFormat: fieldKey == null ? void 0 : (dataFormat) => updateField(fieldKey, { dataFormat })
|
|
1861
1989
|
};
|
|
1862
1990
|
if (request.target === "summary" && fieldKey != null) {
|
|
1863
|
-
|
|
1864
|
-
|
|
1991
|
+
const changeSummary = (patch, menuPatch) => {
|
|
1992
|
+
updateField(fieldKey, patch);
|
|
1993
|
+
setContextMenuRequest(
|
|
1994
|
+
(current) => current?.target === "summary" && current.indicatorKey === fieldKey ? { ...current, ...menuPatch } : current
|
|
1995
|
+
);
|
|
1996
|
+
};
|
|
1997
|
+
enhancedRequest.onChangeSummaryAggregator = (aggregator) => changeSummary(
|
|
1998
|
+
{
|
|
1999
|
+
aggregator,
|
|
2000
|
+
summaryAggregator: aggregator,
|
|
2001
|
+
summaryDisabled: false
|
|
2002
|
+
},
|
|
2003
|
+
{ summaryAggregator: aggregator, summaryDisabled: false }
|
|
2004
|
+
);
|
|
2005
|
+
enhancedRequest.onChangeSummaryPrecision = (precision) => changeSummary({ precision }, { summaryPrecision: precision });
|
|
2006
|
+
enhancedRequest.onChangeSummaryTitle = (summaryTitle) => changeSummary({ summaryTitle }, { summaryTitle });
|
|
2007
|
+
enhancedRequest.onChangeSummaryShowTypePrefix = (summaryShowTypePrefix) => changeSummary(
|
|
2008
|
+
{ summaryShowTypePrefix },
|
|
2009
|
+
{ summaryShowTypePrefix }
|
|
2010
|
+
);
|
|
2011
|
+
enhancedRequest.onChangeSummaryRoundingMode = (summaryRoundingMode) => changeSummary({ summaryRoundingMode }, { summaryRoundingMode });
|
|
2012
|
+
enhancedRequest.onChangeSummaryPreserveTrailingZeros = (summaryPreserveTrailingZeros) => changeSummary(
|
|
2013
|
+
{ summaryPreserveTrailingZeros },
|
|
2014
|
+
{ summaryPreserveTrailingZeros }
|
|
2015
|
+
);
|
|
2016
|
+
enhancedRequest.onClearSummary = () => changeSummary(
|
|
2017
|
+
{ summaryDisabled: true },
|
|
2018
|
+
{ summaryDisabled: true }
|
|
2019
|
+
);
|
|
1865
2020
|
}
|
|
1866
2021
|
setContextMenuRequest(enhancedRequest);
|
|
1867
2022
|
return;
|
|
@@ -1881,10 +2036,10 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1881
2036
|
};
|
|
1882
2037
|
const sharedFilterRequest = react.useMemo(() => {
|
|
1883
2038
|
if (!filterRequest) return null;
|
|
1884
|
-
const { axis, dimensionKey } = filterRequest;
|
|
2039
|
+
const { axis, dimensionKey, columnPathKey } = filterRequest;
|
|
1885
2040
|
return toSharedFilterRequest(filterRequest, (value) => {
|
|
1886
2041
|
setFilterRequest(
|
|
1887
|
-
(current) => current?.axis === axis && current.dimensionKey === dimensionKey ? { ...current, value } : current
|
|
2042
|
+
(current) => current?.axis === axis && current.dimensionKey === dimensionKey && current.columnPathKey === columnPathKey ? { ...current, value } : current
|
|
1888
2043
|
);
|
|
1889
2044
|
});
|
|
1890
2045
|
}, [filterRequest]);
|
|
@@ -1935,6 +2090,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1935
2090
|
title: patch.title ?? field.title,
|
|
1936
2091
|
indicator: {
|
|
1937
2092
|
...field.indicator,
|
|
2093
|
+
...patch,
|
|
1938
2094
|
title: patch.title ?? field.indicator?.title,
|
|
1939
2095
|
aggregator: patch.aggregator ?? field.indicator?.aggregator,
|
|
1940
2096
|
precision: "precision" in patch ? patch.precision : field.indicator?.precision,
|
|
@@ -1986,6 +2142,7 @@ function ReactPivotTableInner(props, ref) {
|
|
|
1986
2142
|
react.useImperativeHandle(
|
|
1987
2143
|
ref,
|
|
1988
2144
|
() => ({
|
|
2145
|
+
autoFitColumnWidths: (target, fillContainer) => tableRef.current?.autoFitColumnWidths(target, fillContainer) ?? false,
|
|
1989
2146
|
getPivotModel: () => tableRef.current?.getPivotModel() ?? null,
|
|
1990
2147
|
getVisibleRowNodes: () => tableRef.current?.getVisibleRowNodes() ?? [],
|
|
1991
2148
|
getVisibleColumnNodes: () => tableRef.current?.getVisibleColumnNodes() ?? [],
|
|
@@ -2007,6 +2164,15 @@ function ReactPivotTableInner(props, ref) {
|
|
|
2007
2164
|
expandAll: (axis) => tableRef.current?.expandAll(axis) ?? 0,
|
|
2008
2165
|
collapseAll: (axis) => tableRef.current?.collapseAll(axis) ?? 0,
|
|
2009
2166
|
setDimensionFilter: (axis, dimensionKey, filter) => tableRef.current?.setDimensionFilter(axis, dimensionKey, filter) ?? null,
|
|
2167
|
+
setIndicatorFilter: (indicatorKey, columnPathKey, filter) => tableRef.current?.setIndicatorFilter(
|
|
2168
|
+
indicatorKey,
|
|
2169
|
+
columnPathKey,
|
|
2170
|
+
filter
|
|
2171
|
+
) ?? null,
|
|
2172
|
+
getIndicatorFilterOptions: (indicatorKey, columnPathKey) => tableRef.current?.getIndicatorFilterOptions(
|
|
2173
|
+
indicatorKey,
|
|
2174
|
+
columnPathKey
|
|
2175
|
+
) ?? [],
|
|
2010
2176
|
getDimensionFilterOptions: (axis, dimensionKey) => tableRef.current?.getDimensionFilterOptions(axis, dimensionKey) ?? [],
|
|
2011
2177
|
resetFilters: () => tableRef.current?.resetFilters() ?? null,
|
|
2012
2178
|
setDimensionSort: (axis, dimensionKey, direction) => tableRef.current?.setDimensionSort(axis, dimensionKey, direction) ?? [],
|