@canvas-components/react-pivot-table 0.2.4 → 0.2.6

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 CHANGED
@@ -8,74 +8,237 @@ var reactDom = require('react-dom');
8
8
  var chart = require('@canvas-components/chart');
9
9
 
10
10
  // src/components/react-pivot-table.tsx
11
+
12
+ // #style-inject:#style-inject
13
+ function styleInject(css, { insertAt } = {}) {
14
+ if (!css || typeof document === "undefined") return;
15
+ const head = document.head || document.getElementsByTagName("head")[0];
16
+ const style = document.createElement("style");
17
+ style.type = "text/css";
18
+ if (insertAt === "top") {
19
+ if (head.firstChild) {
20
+ head.insertBefore(style, head.firstChild);
21
+ } else {
22
+ head.appendChild(style);
23
+ }
24
+ } else {
25
+ head.appendChild(style);
26
+ }
27
+ if (style.styleSheet) {
28
+ style.styleSheet.cssText = css;
29
+ } else {
30
+ style.appendChild(document.createTextNode(css));
31
+ }
32
+ }
33
+
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");
36
+ var CONTEXT_MENU_SURFACE_STYLE = {
37
+ padding: 8,
38
+ background: "#ffffff",
39
+ boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)"
40
+ };
11
41
  function PivotContextMenu(props) {
12
42
  const { request } = props;
43
+ const [menuOpen, setMenuOpen] = react.useState(true);
44
+ react.useEffect(() => {
45
+ if (request) setMenuOpen(true);
46
+ }, [request]);
13
47
  if (!request) return null;
14
48
  return /* @__PURE__ */ jsxRuntime.jsx(
15
49
  reactComponents.ReactPopup,
16
50
  {
17
- open: true,
51
+ open: menuOpen,
18
52
  anchorRect: { x: request.x, y: request.y, width: 0, height: 0 },
19
53
  offset: 4,
20
54
  matchAnchorWidth: false,
21
- minWidth: 180,
55
+ minWidth: 260,
22
56
  onOpenChange: (open) => {
57
+ setMenuOpen(open);
23
58
  if (!open) request.onClose();
24
59
  },
25
- surfaceStyle: { padding: 6 },
26
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", minWidth: 180 }, children: [
60
+ surfaceStyle: { ...CONTEXT_MENU_SURFACE_STYLE, width: 260 },
61
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
62
+ request.title ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "6px 10px", color: "#8f959e", fontSize: 12 }, children: request.title }) : null,
27
63
  /* @__PURE__ */ jsxRuntime.jsx(
28
- MenuButton,
64
+ MenuSubmenu,
29
65
  {
30
- label: "\u590D\u5236\u5355\u5143\u683C",
31
- onClick: request.onCopy,
32
- close: request.onClose
66
+ label: "\u590D\u5236",
67
+ items: [
68
+ {
69
+ key: "copy-cell",
70
+ label: request.target === "header" ? "\u590D\u5236\u8868\u5934" : "\u590D\u5236\u5355\u5143\u683C",
71
+ onClick: request.onCopy
72
+ },
73
+ {
74
+ key: "copy-selection",
75
+ label: "\u590D\u5236\u9009\u533A",
76
+ onClick: request.target === "header" ? void 0 : request.onCopySelection
77
+ }
78
+ ],
79
+ children: request.target !== "header" ? /* @__PURE__ */ jsxRuntime.jsx(CustomSelectionMenu, { request }) : null
33
80
  }
34
81
  ),
35
- request.onCopySelection ? /* @__PURE__ */ jsxRuntime.jsx(
36
- MenuButton,
37
- {
38
- label: "\u590D\u5236\u9009\u533A",
39
- onClick: request.onCopySelection,
40
- close: request.onClose
41
- }
42
- ) : null,
43
- /* @__PURE__ */ jsxRuntime.jsx(
44
- CustomSelectionMenu,
82
+ request.target === "header" ? /* @__PURE__ */ jsxRuntime.jsx(HeaderMenu, { request }) : null,
83
+ request.target === "summary" ? /* @__PURE__ */ jsxRuntime.jsx(
84
+ SummaryMenu,
45
85
  {
46
86
  request
47
87
  },
48
- `${request.x}-${request.y}`
49
- ),
50
- /* @__PURE__ */ jsxRuntime.jsx(
51
- MenuButton,
52
- {
53
- label: "\u5BFC\u51FA CSV",
54
- onClick: request.onExportCsv,
55
- close: request.onClose
56
- }
57
- ),
88
+ `${request.indicatorKey}-${request.x}-${request.y}`
89
+ ) : null,
90
+ /* @__PURE__ */ jsxRuntime.jsx(DataFormatMenu, { request }),
91
+ /* @__PURE__ */ jsxRuntime.jsx(DensityMenu, { request }),
58
92
  /* @__PURE__ */ jsxRuntime.jsx(
59
- MenuButton,
93
+ MenuSubmenu,
60
94
  {
61
- label: "\u5BFC\u51FA XLSX",
62
- onClick: request.onExportXlsx,
63
- close: request.onClose
95
+ label: "\u5BFC\u51FA",
96
+ items: [
97
+ {
98
+ key: "export-csv",
99
+ label: "\u5BFC\u51FA CSV",
100
+ onClick: request.onExportCsv
101
+ },
102
+ {
103
+ key: "export-xlsx",
104
+ label: "\u5BFC\u51FA XLSX",
105
+ onClick: request.onExportXlsx
106
+ }
107
+ ]
64
108
  }
65
109
  ),
66
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "8px 10px", color: "#8f959e", fontSize: 12 }, children: [
110
+ request.recordCount != null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: "8px 10px", color: "#8f959e", fontSize: 12 }, children: [
67
111
  "\u4E0B\u94BB\u8BB0\u5F55 ",
68
112
  request.recordCount,
69
113
  " \u6761"
70
- ] })
114
+ ] }) : null
71
115
  ] })
72
116
  }
73
117
  );
74
118
  }
119
+ function HeaderMenu(props) {
120
+ const { request } = props;
121
+ const hasSort = request.onSortAsc || request.onSortDesc || request.onClearSort;
122
+ const hasExpand = request.onExpand || request.onCollapse || request.onExpandAll || request.onCollapseAll;
123
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
124
+ hasSort ? /* @__PURE__ */ jsxRuntime.jsx(
125
+ MenuSubmenu,
126
+ {
127
+ label: "\u6392\u5E8F",
128
+ items: [
129
+ {
130
+ key: "sort-asc",
131
+ label: "\u5347\u5E8F",
132
+ selected: request.sortDirection === "asc",
133
+ onClick: request.onSortAsc
134
+ },
135
+ {
136
+ key: "sort-desc",
137
+ label: "\u964D\u5E8F",
138
+ selected: request.sortDirection === "desc",
139
+ onClick: request.onSortDesc
140
+ },
141
+ {
142
+ key: "sort-clear",
143
+ label: "\u53D6\u6D88\u6392\u5E8F",
144
+ onClick: request.onClearSort
145
+ }
146
+ ]
147
+ }
148
+ ) : null,
149
+ request.onOpenFilter ? /* @__PURE__ */ jsxRuntime.jsx(MenuAction, { label: "\u6253\u5F00\u7B5B\u9009\u9762\u677F", onClick: request.onOpenFilter }) : null,
150
+ hasExpand ? /* @__PURE__ */ jsxRuntime.jsx(
151
+ MenuSubmenu,
152
+ {
153
+ label: "\u5C55\u5F00/\u6298\u53E0",
154
+ items: [
155
+ {
156
+ key: "toggle-current",
157
+ label: request.expanded ? "\u6298\u53E0\u5F53\u524D\u9879" : "\u5C55\u5F00\u5F53\u524D\u9879",
158
+ onClick: request.expanded ? request.onCollapse : request.onExpand
159
+ },
160
+ {
161
+ key: "expand-all",
162
+ label: "\u5168\u90E8\u5C55\u5F00",
163
+ onClick: request.onExpandAll
164
+ },
165
+ {
166
+ key: "collapse-all",
167
+ label: "\u5168\u90E8\u6298\u53E0",
168
+ onClick: request.onCollapseAll
169
+ }
170
+ ]
171
+ }
172
+ ) : null
173
+ ] });
174
+ }
175
+ function SummaryMenu(props) {
176
+ const { request } = props;
177
+ const [precision, setPrecision] = react.useState(
178
+ request.summaryPrecision ?? null
179
+ );
180
+ const aggregators = [
181
+ ["sum", "\u6C42\u548C"],
182
+ ["avg", "\u5E73\u5747\u503C"],
183
+ ["count", "\u8BA1\u6570"],
184
+ ["distinctCount", "\u53BB\u91CD\u8BA1\u6570"],
185
+ ["min", "\u6700\u5C0F\u503C"],
186
+ ["max", "\u6700\u5927\u503C"]
187
+ ];
188
+ if (!request.onChangeSummaryAggregator) return null;
189
+ return /* @__PURE__ */ jsxRuntime.jsx(
190
+ MenuSubmenu,
191
+ {
192
+ label: "\u6C47\u603B\u65B9\u5F0F",
193
+ items: aggregators.map(([value, label]) => ({
194
+ key: `summary-${value}`,
195
+ label,
196
+ selected: request.summaryAggregator === value,
197
+ onClick: () => {
198
+ request.onChangeSummaryAggregator?.(value);
199
+ request.onClose();
200
+ }
201
+ })),
202
+ footer: request.onChangeSummaryPrecision ? /* @__PURE__ */ jsxRuntime.jsxs(
203
+ "div",
204
+ {
205
+ style: {
206
+ display: "grid",
207
+ gridTemplateColumns: "72px 1fr",
208
+ gap: 8,
209
+ alignItems: "center",
210
+ marginTop: 4,
211
+ padding: "10px 10px 4px",
212
+ borderTop: "1px solid #e5e7eb"
213
+ },
214
+ children: [
215
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontSize: 13 }, children: "\u5C0F\u6570\u4F4D\u6570" }),
216
+ /* @__PURE__ */ jsxRuntime.jsx(
217
+ reactComponents.ReactInputNumber,
218
+ {
219
+ value: precision,
220
+ min: 0,
221
+ max: 20,
222
+ step: 1,
223
+ precision: 0,
224
+ placeholder: "\u81EA\u52A8",
225
+ onChange: (value) => {
226
+ setPrecision(value);
227
+ request.onChangeSummaryPrecision?.(value ?? void 0);
228
+ }
229
+ }
230
+ )
231
+ ]
232
+ }
233
+ ) : null
234
+ }
235
+ );
236
+ }
237
+ function MenuDivider() {
238
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: 1, margin: "6px 0", background: "#f0f0f0" } });
239
+ }
75
240
  function CustomSelectionMenu(props) {
76
241
  const { request } = props;
77
- const triggerRef = react.useRef(null);
78
- const [open, setOpen] = react.useState(false);
79
242
  const [range, setRange] = react.useState(
80
243
  request.customSelection ?? {
81
244
  startRow: 1,
@@ -93,104 +256,79 @@ function CustomSelectionMenu(props) {
93
256
  [key]: value == null ? 1 : Math.floor(value)
94
257
  }));
95
258
  };
96
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
259
+ return /* @__PURE__ */ jsxRuntime.jsx(MenuSubmenu, { label: "\u590D\u5236\u81EA\u5B9A\u4E49\u9009\u533A", items: [], minWidth: 250, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: 6 }, children: [
260
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#6b7280", fontSize: 12, marginBottom: 6 }, children: "\u8F93\u5165\u8D77\u59CB\u4F4D\u7F6E\u548C\u7ED3\u675F\u4F4D\u7F6E" }),
261
+ /* @__PURE__ */ jsxRuntime.jsxs(
262
+ "div",
263
+ {
264
+ style: {
265
+ display: "grid",
266
+ gridTemplateColumns: "38px 1fr 1fr",
267
+ gap: 6,
268
+ marginBottom: 4,
269
+ color: "#6b7280",
270
+ fontSize: 12,
271
+ textAlign: "center"
272
+ },
273
+ children: [
274
+ /* @__PURE__ */ jsxRuntime.jsx("span", {}),
275
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u884C" }),
276
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u5217" })
277
+ ]
278
+ }
279
+ ),
97
280
  /* @__PURE__ */ jsxRuntime.jsx(
98
- "button",
281
+ CustomSelectionRow,
99
282
  {
100
- ref: triggerRef,
101
- type: "button",
102
- onClick: () => setOpen((value) => !value),
103
- style: menuButtonStyle,
104
- children: "\u590D\u5236\u81EA\u5B9A\u4E49\u9009\u533A"
283
+ label: "\u8D77\u59CB",
284
+ row: range.startRow,
285
+ column: range.startColumn,
286
+ maxRow: range.rowCount,
287
+ maxColumn: range.columnCount,
288
+ onRowChange: (value) => update("startRow", value),
289
+ onColumnChange: (value) => update("startColumn", value)
105
290
  }
106
291
  ),
107
292
  /* @__PURE__ */ jsxRuntime.jsx(
108
- reactComponents.ReactPopup,
293
+ CustomSelectionRow,
109
294
  {
110
- open,
111
- anchorRef: triggerRef,
112
- placement: "rightTop",
113
- offset: 2,
114
- minWidth: 250,
115
- onOpenChange: setOpen,
116
- surfaceStyle: { padding: 6, width: 250 },
117
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: 6 }, children: [
118
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#6b7280", fontSize: 12, marginBottom: 6 }, children: "\u8F93\u5165\u8D77\u59CB\u4F4D\u7F6E\u548C\u7ED3\u675F\u4F4D\u7F6E" }),
119
- /* @__PURE__ */ jsxRuntime.jsxs(
120
- "div",
121
- {
122
- style: {
123
- display: "grid",
124
- gridTemplateColumns: "38px 1fr 1fr",
125
- gap: 6,
126
- marginBottom: 4,
127
- color: "#6b7280",
128
- fontSize: 12,
129
- textAlign: "center"
130
- },
131
- children: [
132
- /* @__PURE__ */ jsxRuntime.jsx("span", {}),
133
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u884C" }),
134
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u5217" })
135
- ]
136
- }
137
- ),
138
- /* @__PURE__ */ jsxRuntime.jsx(
139
- CustomSelectionRow,
140
- {
141
- label: "\u8D77\u59CB",
142
- row: range.startRow,
143
- column: range.startColumn,
144
- maxRow: range.rowCount,
145
- maxColumn: range.columnCount,
146
- onRowChange: (value) => update("startRow", value),
147
- onColumnChange: (value) => update("startColumn", value)
148
- }
149
- ),
150
- /* @__PURE__ */ jsxRuntime.jsx(
151
- CustomSelectionRow,
152
- {
153
- label: "\u7ED3\u675F",
154
- row: range.endRow,
155
- column: range.endColumn,
156
- maxRow: range.rowCount,
157
- maxColumn: range.columnCount,
158
- onRowChange: (value) => update("endRow", value),
159
- onColumnChange: (value) => update("endColumn", value)
160
- }
161
- ),
162
- /* @__PURE__ */ jsxRuntime.jsx(
163
- "button",
164
- {
165
- type: "button",
166
- style: {
167
- display: "block",
168
- width: "100%",
169
- height: 32,
170
- marginTop: 6,
171
- border: "none",
172
- borderRadius: 4,
173
- background: "#1677ff",
174
- color: "#fff",
175
- cursor: "pointer"
176
- },
177
- onClick: () => {
178
- request.onCopyCustomSelection?.({
179
- startRow: range.startRow,
180
- startColumn: range.startColumn,
181
- endRow: range.endRow,
182
- endColumn: range.endColumn
183
- });
184
- setOpen(false);
185
- request.onClose();
186
- },
187
- children: "\u590D\u5236"
188
- }
189
- )
190
- ] })
295
+ label: "\u7ED3\u675F",
296
+ row: range.endRow,
297
+ column: range.endColumn,
298
+ maxRow: range.rowCount,
299
+ maxColumn: range.columnCount,
300
+ onRowChange: (value) => update("endRow", value),
301
+ onColumnChange: (value) => update("endColumn", value)
302
+ }
303
+ ),
304
+ /* @__PURE__ */ jsxRuntime.jsx(
305
+ "button",
306
+ {
307
+ type: "button",
308
+ style: {
309
+ display: "block",
310
+ width: "100%",
311
+ height: 32,
312
+ marginTop: 6,
313
+ border: "none",
314
+ borderRadius: 4,
315
+ background: "#1677ff",
316
+ color: "#fff",
317
+ cursor: "pointer"
318
+ },
319
+ onClick: () => {
320
+ request.onCopyCustomSelection?.({
321
+ startRow: range.startRow,
322
+ startColumn: range.startColumn,
323
+ endRow: range.endRow,
324
+ endColumn: range.endColumn
325
+ });
326
+ request.onClose();
327
+ },
328
+ children: "\u590D\u5236"
191
329
  }
192
330
  )
193
- ] });
331
+ ] }) });
194
332
  }
195
333
  function CustomSelectionRow(props) {
196
334
  return /* @__PURE__ */ jsxRuntime.jsxs(
@@ -233,27 +371,324 @@ function CustomSelectionRow(props) {
233
371
  }
234
372
  );
235
373
  }
236
- var menuButtonStyle = {
237
- height: 34,
238
- padding: "0 10px",
239
- border: 0,
240
- borderRadius: 4,
241
- background: "transparent",
242
- color: "#1f2329",
243
- textAlign: "left",
244
- cursor: "pointer"
245
- };
246
- function MenuButton(props) {
247
- return /* @__PURE__ */ jsxRuntime.jsx(
374
+ function MenuAction(props) {
375
+ const { label, preview, onClick, selected, disabled, reserveSelectionIcon } = props;
376
+ if (!onClick && !disabled) return null;
377
+ return /* @__PURE__ */ jsxRuntime.jsxs(
248
378
  "button",
249
379
  {
250
380
  type: "button",
251
- onClick: () => {
252
- props.onClick();
253
- props.close();
381
+ onClick: disabled ? void 0 : onClick,
382
+ disabled,
383
+ className: "react-pivot-table-menu-action",
384
+ style: {
385
+ display: "flex",
386
+ alignItems: "center",
387
+ width: "100%",
388
+ height: 32,
389
+ padding: "0 10px",
390
+ border: "none",
391
+ borderRadius: 8,
392
+ background: "transparent",
393
+ color: disabled ? "#9ca3af" : "#374151",
394
+ textAlign: "left",
395
+ cursor: disabled ? "default" : "pointer"
254
396
  },
255
- style: menuButtonStyle,
256
- children: props.label
397
+ children: [
398
+ reserveSelectionIcon ? /* @__PURE__ */ jsxRuntime.jsx(
399
+ "span",
400
+ {
401
+ "aria-hidden": "true",
402
+ style: {
403
+ width: 16,
404
+ flex: "0 0 16px",
405
+ marginRight: 6,
406
+ textAlign: "center"
407
+ },
408
+ children: selected ? "\u2713" : ""
409
+ }
410
+ ) : null,
411
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { flex: 1, whiteSpace: "nowrap" }, children: label }),
412
+ preview ? /* @__PURE__ */ jsxRuntime.jsx(
413
+ "span",
414
+ {
415
+ style: { marginLeft: 16, color: "#9ca3af", whiteSpace: "nowrap" },
416
+ children: preview
417
+ }
418
+ ) : null
419
+ ]
420
+ }
421
+ );
422
+ }
423
+ function MenuSubmenu(props) {
424
+ const { label, items, footer, children, minWidth = 220 } = props;
425
+ const menuItems = items.filter((item) => item.onClick || item.disabled);
426
+ const reserveSelectionIcon = menuItems.some(
427
+ (item) => typeof item.selected === "boolean"
428
+ );
429
+ const triggerRef = react.useRef(null);
430
+ const [open, setOpen] = react.useState(false);
431
+ const closeTimerRef = react.useRef(null);
432
+ if (!menuItems.length && !footer && !children) return null;
433
+ const clearCloseTimer = () => {
434
+ if (closeTimerRef.current != null) {
435
+ window.clearTimeout(closeTimerRef.current);
436
+ closeTimerRef.current = null;
437
+ }
438
+ };
439
+ const scheduleClose = () => {
440
+ clearCloseTimer();
441
+ closeTimerRef.current = window.setTimeout(() => {
442
+ setOpen(false);
443
+ closeTimerRef.current = null;
444
+ }, 120);
445
+ };
446
+ return /* @__PURE__ */ jsxRuntime.jsxs(
447
+ "div",
448
+ {
449
+ onMouseEnter: () => {
450
+ clearCloseTimer();
451
+ setOpen(true);
452
+ },
453
+ onMouseLeave: scheduleClose,
454
+ children: [
455
+ /* @__PURE__ */ jsxRuntime.jsxs(
456
+ "button",
457
+ {
458
+ ref: triggerRef,
459
+ type: "button",
460
+ onClick: () => setOpen((value) => !value),
461
+ className: "react-pivot-table-menu-action react-pivot-table-menu-action-submenu",
462
+ style: {
463
+ display: "flex",
464
+ alignItems: "center",
465
+ justifyContent: "space-between",
466
+ width: "100%",
467
+ height: 32,
468
+ padding: "0 10px",
469
+ border: "none",
470
+ borderRadius: 8,
471
+ background: "transparent",
472
+ color: "#374151",
473
+ textAlign: "left",
474
+ cursor: "pointer"
475
+ },
476
+ children: [
477
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
478
+ /* @__PURE__ */ jsxRuntime.jsx(
479
+ "span",
480
+ {
481
+ className: `react-pivot-table-menu-chevron${open ? " react-pivot-table-menu-chevron-active" : ""}`,
482
+ "aria-hidden": "true"
483
+ }
484
+ )
485
+ ]
486
+ }
487
+ ),
488
+ /* @__PURE__ */ jsxRuntime.jsx(
489
+ reactComponents.ReactPopup,
490
+ {
491
+ open,
492
+ anchorRef: triggerRef,
493
+ placement: "rightTop",
494
+ offset: 2,
495
+ minWidth,
496
+ onOpenChange: setOpen,
497
+ surfaceStyle: { ...CONTEXT_MENU_SURFACE_STYLE, width: minWidth },
498
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { onMouseEnter: clearCloseTimer, onMouseLeave: scheduleClose, children: [
499
+ menuItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(react.Fragment, { children: [
500
+ item.separatorBefore ? /* @__PURE__ */ jsxRuntime.jsx(MenuDivider, {}) : null,
501
+ /* @__PURE__ */ jsxRuntime.jsx(
502
+ MenuAction,
503
+ {
504
+ label: item.label,
505
+ preview: item.preview,
506
+ selected: item.selected,
507
+ disabled: item.disabled,
508
+ onClick: item.onClick,
509
+ reserveSelectionIcon
510
+ }
511
+ )
512
+ ] }, item.key)),
513
+ children,
514
+ footer
515
+ ] })
516
+ }
517
+ )
518
+ ]
519
+ }
520
+ );
521
+ }
522
+ function DensityMenu(props) {
523
+ const { request } = props;
524
+ if (!request.onChangeDensity) return null;
525
+ return /* @__PURE__ */ jsxRuntime.jsx(
526
+ MenuSubmenu,
527
+ {
528
+ label: "\u8868\u683C\u5BC6\u5EA6",
529
+ items: [
530
+ {
531
+ key: "density-comfortable",
532
+ label: "\u5BBD\u677E",
533
+ selected: request.density === "comfortable",
534
+ onClick: () => request.onChangeDensity?.("comfortable")
535
+ },
536
+ {
537
+ key: "density-middle",
538
+ label: "\u4E2D\u7B49",
539
+ selected: request.density === "middle",
540
+ onClick: () => request.onChangeDensity?.("middle")
541
+ },
542
+ {
543
+ key: "density-compact",
544
+ label: "\u7D27\u51D1",
545
+ selected: request.density === "compact",
546
+ onClick: () => request.onChangeDensity?.("compact")
547
+ },
548
+ {
549
+ key: "density-ultra-compact",
550
+ label: "\u8D85\u7D27\u51D1",
551
+ selected: request.density === "ultra-compact",
552
+ onClick: () => request.onChangeDensity?.("ultra-compact")
553
+ },
554
+ {
555
+ key: "density-auto",
556
+ label: "\u81EA\u9002\u5E94",
557
+ selected: request.density === "auto",
558
+ onClick: () => request.onChangeDensity?.("auto")
559
+ }
560
+ ]
561
+ }
562
+ );
563
+ }
564
+ function DataFormatMenu(props) {
565
+ const { request } = props;
566
+ if (!request.onChangeDataFormat) return null;
567
+ const formats = [
568
+ { key: "default", label: "\u5E38\u89C4", value: "default" },
569
+ { key: "text", label: "\u7EAF\u6587\u672C", value: "text" },
570
+ {
571
+ key: "number",
572
+ label: "\u6570\u5B57",
573
+ preview: "1024",
574
+ value: "number",
575
+ separatorBefore: true
576
+ },
577
+ {
578
+ key: "thousands",
579
+ label: "\u6570\u5B57\uFF08\u5343\u5206\u4F4D\uFF09",
580
+ preview: "1,024",
581
+ value: "thousands"
582
+ },
583
+ {
584
+ key: "decimal",
585
+ label: "\u6570\u5B57\uFF08\u5343\u5206\u4F4D\uFF0C\u5C0F\u6570\u70B9\uFF09",
586
+ preview: "1,024.56",
587
+ value: "decimal"
588
+ },
589
+ {
590
+ key: "percent",
591
+ label: "\u767E\u5206\u6BD4",
592
+ preview: "10%",
593
+ value: "percent",
594
+ separatorBefore: true
595
+ },
596
+ {
597
+ key: "percentDecimal",
598
+ label: "\u767E\u5206\u6BD4\uFF08\u5C0F\u6570\u70B9\uFF09",
599
+ preview: "10.24%",
600
+ value: "percentDecimal"
601
+ },
602
+ {
603
+ key: "scientific",
604
+ label: "\u79D1\u5B66\u8BB0\u6570",
605
+ preview: "1.02E+003",
606
+ value: "scientific"
607
+ },
608
+ {
609
+ key: "numberToChineseUpper",
610
+ label: "\u6570\u5B57\u8F6C\u5927\u5199",
611
+ preview: "\u7396\u62FE\u58F9\u4E07\u634C\u4EDF",
612
+ value: "numberToChineseUpper"
613
+ },
614
+ {
615
+ key: "chineseUpperToNumber",
616
+ label: "\u5927\u5199\u8F6C\u6570\u5B57",
617
+ preview: "918000",
618
+ value: "chineseUpperToNumber"
619
+ },
620
+ {
621
+ key: "cny",
622
+ label: "\u4EBA\u6C11\u5E01",
623
+ preview: "\xA51,024",
624
+ value: "cny",
625
+ separatorBefore: true
626
+ },
627
+ {
628
+ key: "cnyDecimal",
629
+ label: "\u4EBA\u6C11\u5E01\uFF08\u5C0F\u6570\u70B9\uFF09",
630
+ preview: "\xA51,024.56",
631
+ value: "cnyDecimal"
632
+ },
633
+ { key: "usd", label: "\u7F8E\u5143", preview: "$1,024", value: "usd" },
634
+ {
635
+ key: "usdDecimal",
636
+ label: "\u7F8E\u5143\uFF08\u5C0F\u6570\u70B9\uFF09",
637
+ preview: "$1,024.56",
638
+ value: "usdDecimal"
639
+ },
640
+ {
641
+ key: "dateSlash",
642
+ label: "\u65E5\u671F\uFF08\u659C\u6760\uFF09",
643
+ preview: "2017/08/01",
644
+ value: "dateSlash",
645
+ separatorBefore: true
646
+ },
647
+ {
648
+ key: "dateDash",
649
+ label: "\u65E5\u671F\uFF08\u77ED\u6A2A\u7EBF\uFF09",
650
+ preview: "2017-08-01",
651
+ value: "dateDash"
652
+ },
653
+ {
654
+ key: "dateFullCN",
655
+ label: "\u65E5\u671F\uFF08\u4E2D\u6587\uFF09",
656
+ preview: "2017\u5E748\u67081\u65E5",
657
+ value: "dateFullCN"
658
+ },
659
+ { key: "time", label: "\u65F6\u95F4", preview: "23:24:25", value: "time" },
660
+ {
661
+ key: "timeShort",
662
+ label: "\u65F6\u95F4\uFF08\u5206\uFF09",
663
+ preview: "23:24",
664
+ value: "timeShort"
665
+ },
666
+ {
667
+ key: "datetime",
668
+ label: "\u65E5\u671F\u65F6\u95F4",
669
+ preview: "2017/08/01 23:24:25",
670
+ value: "datetime"
671
+ },
672
+ {
673
+ key: "datetime12",
674
+ label: "\u65E5\u671F\u65F6\u95F4\uFF08\u4E0A\u4E0B\uFF09",
675
+ preview: "2017/08/01 \u4E0B\u534811:24",
676
+ value: "datetime12"
677
+ }
678
+ ];
679
+ return /* @__PURE__ */ jsxRuntime.jsx(
680
+ MenuSubmenu,
681
+ {
682
+ label: "\u683C\u5F0F",
683
+ minWidth: 340,
684
+ items: formats.map((item) => ({
685
+ key: `data-format-${item.key}`,
686
+ label: item.label,
687
+ preview: "preview" in item ? item.preview : void 0,
688
+ separatorBefore: "separatorBefore" in item ? item.separatorBefore : void 0,
689
+ selected: request.dataFormat === item.value,
690
+ onClick: () => request.onChangeDataFormat?.(item.value)
691
+ }))
257
692
  }
258
693
  );
259
694
  }
@@ -288,28 +723,6 @@ function PivotTooltip(props) {
288
723
  );
289
724
  }
290
725
 
291
- // #style-inject:#style-inject
292
- function styleInject(css, { insertAt } = {}) {
293
- if (!css || typeof document === "undefined") return;
294
- const head = document.head || document.getElementsByTagName("head")[0];
295
- const style = document.createElement("style");
296
- style.type = "text/css";
297
- if (insertAt === "top") {
298
- if (head.firstChild) {
299
- head.insertBefore(style, head.firstChild);
300
- } else {
301
- head.appendChild(style);
302
- }
303
- } else {
304
- head.appendChild(style);
305
- }
306
- if (style.styleSheet) {
307
- style.styleSheet.cssText = css;
308
- } else {
309
- style.appendChild(document.createTextNode(css));
310
- }
311
- }
312
-
313
726
  // src/features/field-panel/pivot-field-panel.css
314
727
  styleInject('.react-pivot-table-customization {\n position: relative;\n overflow: hidden;\n}\n.react-pivot-table-customization__table {\n position: relative;\n min-width: 0;\n min-height: 0;\n width: 100%;\n height: 100%;\n overflow: hidden;\n}\n.react-pivot-table-customization__panel-column {\n flex-grow: 0 !important;\n overflow: hidden;\n}\n.react-pivot-table-customization__chart-column {\n flex-grow: 0 !important;\n overflow: hidden;\n}\n.react-pivot-field-panel {\n display: flex;\n width: 100%;\n min-width: 280px;\n height: 100%;\n flex-direction: column;\n overflow: hidden;\n background: #fff;\n color: #1f2329;\n font-family:\n "Segoe UI",\n "Microsoft YaHei",\n sans-serif;\n font-size: 13px;\n box-sizing: border-box;\n}\n.react-pivot-field-panel button,\n.react-pivot-field-panel input,\n.react-pivot-field-panel select {\n font: inherit;\n}\n.react-pivot-field-panel__header {\n display: flex;\n height: 42px;\n flex: 0 0 42px;\n align-items: center;\n justify-content: space-between;\n padding: 0 10px 0 14px;\n border-bottom: 1px solid #edf0f2;\n background: #fff;\n}\n.react-pivot-field-panel__icon-button {\n display: inline-flex;\n width: 24px;\n height: 24px;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: 0;\n background: transparent;\n color: #646a73;\n cursor: pointer;\n font: 18px/24px "Segoe UI", sans-serif;\n}\n.react-pivot-field-panel__icon-button:hover {\n background: #f2f3f5;\n color: #d14343;\n}\n.react-pivot-field-panel__layout {\n width: 100%;\n height: auto;\n min-height: 0;\n flex: 1 1 0;\n overflow: hidden;\n}\n.react-pivot-field-panel__layout > .canvas-react-resizable-panels-item > .canvas-react-resizable-panel {\n overflow: hidden;\n}\n.react-pivot-field-panel__section {\n height: 100%;\n padding: 10px 12px 0;\n box-sizing: border-box;\n}\n.react-pivot-field-panel__section--fields,\n.react-pivot-field-panel__section--areas {\n display: flex;\n min-height: 0;\n flex-direction: column;\n}\n.react-pivot-field-panel__section--fields {\n padding-bottom: 6px;\n}\n.react-pivot-field-panel__section--areas {\n padding-bottom: 12px;\n}\n.react-pivot-field-panel__section-title {\n margin-bottom: 5px;\n font-weight: 600;\n}\n.react-pivot-field-panel__hint {\n margin-bottom: 8px;\n color: #646a73;\n font-size: 12px;\n}\n.react-pivot-field-panel__search {\n display: flex;\n height: 32px;\n align-items: center;\n gap: 8px;\n padding: 0 9px;\n border: 1px solid #d5d9de;\n border-radius: 3px;\n background: #fff;\n box-sizing: border-box;\n}\n.react-pivot-field-panel__search > span {\n width: 12px;\n height: 12px;\n border: 1.5px solid #4f5660;\n border-radius: 50%;\n position: relative;\n}\n.react-pivot-field-panel__search > span::after {\n position: absolute;\n right: -4px;\n bottom: -3px;\n width: 5px;\n height: 1.5px;\n background: #4f5660;\n content: "";\n transform: rotate(45deg);\n}\n.react-pivot-field-panel__search input {\n min-width: 0;\n flex: 1;\n border: 0;\n outline: 0;\n color: #1f2329;\n}\n.react-pivot-field-panel__field-list {\n min-height: 0;\n flex: 1;\n margin-top: 6px;\n overflow: auto;\n border: 1px solid #dfe3e7;\n border-radius: 3px;\n background: #fff;\n}\n.react-pivot-field-panel__field,\n.react-pivot-field-panel__area-field {\n display: grid;\n height: 28px;\n align-items: center;\n column-gap: 6px;\n box-sizing: border-box;\n}\n.react-pivot-field-panel__field {\n grid-template-columns: 10px 16px minmax(0, 1fr);\n padding: 0 8px 0 6px;\n}\n.react-pivot-field-panel__field:hover {\n background: #f5f8fb;\n}\n.react-pivot-field-panel__field[data-dragging] {\n opacity: 0.45;\n}\n.react-pivot-field-panel__field > span:nth-of-type(2),\n.react-pivot-field-panel__area-field > span:nth-of-type(2) {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.react-pivot-field-panel__drag {\n width: 8px;\n height: 12px;\n cursor: grab;\n background-image:\n radial-gradient(\n circle at 2px 2px,\n #8f959e 1px,\n transparent 1.2px);\n background-position: 0 0;\n background-size: 4px 4px;\n background-repeat: repeat;\n}\n.react-pivot-field-panel__empty,\n.react-pivot-field-panel__area-empty {\n display: grid;\n height: 100%;\n place-items: center;\n color: #8f959e;\n font-size: 12px;\n}\n.react-pivot-field-panel__areas {\n display: grid;\n min-height: 0;\n flex: 1;\n grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);\n grid-template-rows: minmax(0, 1fr) minmax(0, 1fr);\n gap: 8px;\n}\n.react-pivot-field-panel__area-wrap {\n display: flex;\n min-width: 0;\n min-height: 0;\n flex-direction: column;\n}\n.react-pivot-field-panel__area-title {\n display: grid;\n height: 25px;\n grid-template-columns: minmax(0, 1fr);\n align-items: center;\n gap: 5px;\n color: #3f454d;\n}\n.react-pivot-field-panel__area {\n min-height: 0;\n flex: 1;\n overflow: auto;\n border: 1px solid #dfe3e7;\n border-radius: 3px;\n background: #fff;\n}\n.react-pivot-field-panel__area[data-dragging] {\n border-color: #2f78d0;\n background: #f7faff;\n}\n.react-pivot-field-panel__area-field {\n grid-template-columns: 9px minmax(0, 1fr) 18px;\n padding: 0 7px 0 5px;\n}\n.react-pivot-field-panel__area-field:hover {\n background: #f5f8fb;\n}\n.react-pivot-field-panel__area-field-menu {\n display: grid;\n width: 18px;\n height: 22px;\n padding: 0;\n place-items: center;\n border: 0;\n background: transparent;\n color: #646a73;\n cursor: pointer;\n}\n.react-pivot-field-panel__area-field-menu:hover {\n color: #1f2329;\n background: #e9edf2;\n}\n.react-pivot-field-panel__area-field-menu > span {\n width: 0;\n height: 0;\n border-top: 5px solid currentColor;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n}\n.react-pivot-field-menu {\n min-width: 176px;\n padding: 5px 0;\n color: #1f2329;\n font:\n 13px "Segoe UI",\n "Microsoft YaHei",\n sans-serif;\n}\n.react-pivot-field-menu__item {\n display: block;\n width: 100%;\n height: 30px;\n padding: 0 12px;\n border: 0;\n background: transparent;\n color: inherit;\n text-align: left;\n cursor: pointer;\n}\n.react-pivot-field-menu__item:hover:not(:disabled) {\n background: #e9f2fc;\n}\n.react-pivot-field-menu__item:disabled {\n color: #a7abb2;\n cursor: default;\n}\n.react-pivot-field-menu__item[data-danger] {\n color: #c9372c;\n}\n.react-pivot-field-menu__separator {\n height: 1px;\n margin: 4px 0;\n background: #e1e4e8;\n}\n.react-pivot-field-settings {\n display: grid;\n min-width: 260px;\n gap: 12px;\n padding: 14px;\n color: #1f2329;\n font:\n 13px "Segoe UI",\n "Microsoft YaHei",\n sans-serif;\n}\n.react-pivot-field-settings label {\n display: grid;\n gap: 5px;\n color: #515761;\n}\n.react-pivot-field-settings__name-input,\n.react-pivot-field-settings__aggregator {\n height: 30px;\n font: inherit;\n}\n.react-pivot-field-settings__actions {\n display: flex;\n justify-content: flex-end;\n gap: 8px;\n}\n.react-pivot-field-settings__actions button {\n height: 30px;\n padding: 0 14px;\n border: 1px solid #bfc4cb;\n border-radius: 3px;\n background: #fff;\n cursor: pointer;\n}\n.react-pivot-field-settings__actions button.is-primary {\n border-color: #2f78d0;\n background: #2f78d0;\n color: #fff;\n}\n');
315
728
  function PivotFieldPanel(props) {
@@ -575,7 +988,7 @@ function FieldContextMenu(props) {
575
988
  },
576
989
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-pivot-field-menu", role: "menu", children: [
577
990
  /* @__PURE__ */ jsxRuntime.jsx(
578
- MenuAction,
991
+ MenuAction2,
579
992
  {
580
993
  label: "\u4E0A\u79FB",
581
994
  disabled: index <= 0,
@@ -584,7 +997,7 @@ function FieldContextMenu(props) {
584
997
  }
585
998
  ),
586
999
  /* @__PURE__ */ jsxRuntime.jsx(
587
- MenuAction,
1000
+ MenuAction2,
588
1001
  {
589
1002
  label: "\u4E0B\u79FB",
590
1003
  disabled: index < 0 || index >= keys.length - 1,
@@ -593,7 +1006,7 @@ function FieldContextMenu(props) {
593
1006
  }
594
1007
  ),
595
1008
  /* @__PURE__ */ jsxRuntime.jsx(
596
- MenuAction,
1009
+ MenuAction2,
597
1010
  {
598
1011
  label: "\u79FB\u81F3\u5F00\u5934",
599
1012
  disabled: index <= 0,
@@ -602,7 +1015,7 @@ function FieldContextMenu(props) {
602
1015
  }
603
1016
  ),
604
1017
  /* @__PURE__ */ jsxRuntime.jsx(
605
- MenuAction,
1018
+ MenuAction2,
606
1019
  {
607
1020
  label: "\u79FB\u81F3\u672B\u5C3E",
608
1021
  disabled: index === keys.length - 1,
@@ -612,7 +1025,7 @@ function FieldContextMenu(props) {
612
1025
  ),
613
1026
  /* @__PURE__ */ jsxRuntime.jsx(MenuSeparator, {}),
614
1027
  /* @__PURE__ */ jsxRuntime.jsx(
615
- MenuAction,
1028
+ MenuAction2,
616
1029
  {
617
1030
  label: "\u6DFB\u52A0\u5230\u62A5\u8868\u7B5B\u9009",
618
1031
  disabled: state.area === "filter",
@@ -621,7 +1034,7 @@ function FieldContextMenu(props) {
621
1034
  }
622
1035
  ),
623
1036
  /* @__PURE__ */ jsxRuntime.jsx(
624
- MenuAction,
1037
+ MenuAction2,
625
1038
  {
626
1039
  label: "\u6DFB\u52A0\u5230\u884C\u6807\u7B7E",
627
1040
  disabled: state.area === "row",
@@ -630,7 +1043,7 @@ function FieldContextMenu(props) {
630
1043
  }
631
1044
  ),
632
1045
  /* @__PURE__ */ jsxRuntime.jsx(
633
- MenuAction,
1046
+ MenuAction2,
634
1047
  {
635
1048
  label: "\u6DFB\u52A0\u5230\u5217\u6807\u7B7E",
636
1049
  disabled: state.area === "column",
@@ -639,7 +1052,7 @@ function FieldContextMenu(props) {
639
1052
  }
640
1053
  ),
641
1054
  /* @__PURE__ */ jsxRuntime.jsx(
642
- MenuAction,
1055
+ MenuAction2,
643
1056
  {
644
1057
  label: "\u79FB\u52A8\u5230\u503C",
645
1058
  disabled: state.area === "value",
@@ -649,7 +1062,7 @@ function FieldContextMenu(props) {
649
1062
  ),
650
1063
  /* @__PURE__ */ jsxRuntime.jsx(MenuSeparator, {}),
651
1064
  /* @__PURE__ */ jsxRuntime.jsx(
652
- MenuAction,
1065
+ MenuAction2,
653
1066
  {
654
1067
  label: "\u5220\u9664\u5B57\u6BB5",
655
1068
  danger: true,
@@ -658,7 +1071,7 @@ function FieldContextMenu(props) {
658
1071
  }
659
1072
  ),
660
1073
  /* @__PURE__ */ jsxRuntime.jsx(
661
- MenuAction,
1074
+ MenuAction2,
662
1075
  {
663
1076
  label: "\u5B57\u6BB5\u8BBE\u7F6E...",
664
1077
  onClick: () => props.onSettings(state)
@@ -741,7 +1154,7 @@ function FieldSettingsPopup(props) {
741
1154
  }
742
1155
  );
743
1156
  }
744
- function MenuAction(props) {
1157
+ function MenuAction2(props) {
745
1158
  return /* @__PURE__ */ jsxRuntime.jsx(
746
1159
  "button",
747
1160
  {
@@ -1250,8 +1663,31 @@ function PivotChartCanvas(props) {
1250
1663
  }, [props.chartOption]);
1251
1664
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className: "react-pivot-chart-card__canvas" });
1252
1665
  }
1666
+ var ReactPivotTableDebugContext = react.createContext(false);
1667
+ function ReactPivotTableDebugProvider(props) {
1668
+ return /* @__PURE__ */ jsxRuntime.jsx(ReactPivotTableDebugContext.Provider, { value: props.enabled, children: props.children });
1669
+ }
1670
+ function useReactPivotTableDebugEnabled() {
1671
+ return react.useContext(ReactPivotTableDebugContext);
1672
+ }
1673
+ function resolveReactPivotTableDebugOptions(debug, inheritedEnabled) {
1674
+ if (!inheritedEnabled) return debug;
1675
+ return {
1676
+ ...pivotTable.DEFAULT_PIVOT_TABLE_DEBUG_OPTIONS,
1677
+ ...typeof debug === "object" ? debug : null,
1678
+ enabled: true
1679
+ };
1680
+ }
1253
1681
  function ReactPivotTableInner(props, ref) {
1254
1682
  const { className, style, customization, title, ...tableOptions } = props;
1683
+ const inheritedDebugEnabled = useReactPivotTableDebugEnabled();
1684
+ const resolvedDebug = react.useMemo(
1685
+ () => resolveReactPivotTableDebugOptions(
1686
+ tableOptions.debug,
1687
+ inheritedDebugEnabled
1688
+ ),
1689
+ [inheritedDebugEnabled, tableOptions.debug]
1690
+ );
1255
1691
  const containerRef = react.useRef(null);
1256
1692
  const tableRef = react.useRef(null);
1257
1693
  const customizationOptions = customization && typeof customization === "object" ? customization : void 0;
@@ -1273,6 +1709,7 @@ function ReactPivotTableInner(props, ref) {
1273
1709
  () => customizationOptions?.defaultLayout ?? pivotTable.createEmptyPivotFieldLayout()
1274
1710
  );
1275
1711
  const [fieldOverrides, setFieldOverrides] = react.useState({});
1712
+ const [densityOverride, setDensityOverride] = react.useState(null);
1276
1713
  const [filterRequest, setFilterRequest] = react.useState(null);
1277
1714
  const [contextMenuRequest, setContextMenuRequest] = react.useState(null);
1278
1715
  const [tooltipRequest, setTooltipRequest] = react.useState(null);
@@ -1316,7 +1753,9 @@ function ReactPivotTableInner(props, ref) {
1316
1753
  indicator: {
1317
1754
  ...field.indicator,
1318
1755
  title: override.title ?? field.indicator?.title,
1319
- aggregator: override.aggregator ?? field.indicator?.aggregator
1756
+ aggregator: override.aggregator ?? field.indicator?.aggregator,
1757
+ precision: "precision" in override ? override.precision : field.indicator?.precision,
1758
+ dataFormat: "dataFormat" in override ? override.dataFormat : field.indicator?.dataFormat
1320
1759
  }
1321
1760
  };
1322
1761
  }),
@@ -1326,6 +1765,20 @@ function ReactPivotTableInner(props, ref) {
1326
1765
  () => customizationEnabled ? pivotTable.resolvePivotFieldLayoutOptions(fields, fieldLayout) : null,
1327
1766
  [customizationEnabled, fieldLayout, fields]
1328
1767
  );
1768
+ const overriddenIndicators = react.useMemo(
1769
+ () => tableOptions.indicators.map((indicator) => {
1770
+ const override = fieldOverrides[indicator.key];
1771
+ if (!override) return indicator;
1772
+ return {
1773
+ ...indicator,
1774
+ title: override.title ?? indicator.title,
1775
+ aggregator: override.aggregator ?? indicator.aggregator,
1776
+ precision: "precision" in override ? override.precision : indicator.precision,
1777
+ dataFormat: "dataFormat" in override ? override.dataFormat : indicator.dataFormat
1778
+ };
1779
+ }),
1780
+ [fieldOverrides, tableOptions.indicators]
1781
+ );
1329
1782
  const refreshChartModel = () => {
1330
1783
  const nextModel = tableRef.current?.getPivotModel() ?? null;
1331
1784
  setChartModel((current) => current === nextModel ? current : nextModel);
@@ -1333,9 +1786,32 @@ function ReactPivotTableInner(props, ref) {
1333
1786
  const options = {
1334
1787
  ...tableOptions,
1335
1788
  ...customizedOptions,
1789
+ debug: resolvedDebug,
1790
+ rowHeight: densityOverride == null ? tableOptions.rowHeight : resolveDensityRowHeight(densityOverride),
1791
+ indicators: customizedOptions?.indicators ?? overriddenIndicators,
1336
1792
  ui: {
1337
1793
  onFilterPanelRequest: setFilterRequest,
1338
- onContextMenuRequest: setContextMenuRequest,
1794
+ onContextMenuRequest: (request) => {
1795
+ if (request) {
1796
+ const nativeChangeDensity = request.onChangeDensity;
1797
+ const fieldKey = request.indicatorKey;
1798
+ const enhancedRequest = {
1799
+ ...request,
1800
+ onChangeDensity: (density) => {
1801
+ nativeChangeDensity?.(density);
1802
+ setDensityOverride(density);
1803
+ },
1804
+ onChangeDataFormat: fieldKey == null ? void 0 : (dataFormat) => updateField(fieldKey, { dataFormat })
1805
+ };
1806
+ if (request.target === "summary" && fieldKey != null) {
1807
+ enhancedRequest.onChangeSummaryAggregator = (aggregator) => updateField(fieldKey, { aggregator });
1808
+ enhancedRequest.onChangeSummaryPrecision = (precision) => updateField(fieldKey, { precision });
1809
+ }
1810
+ setContextMenuRequest(enhancedRequest);
1811
+ return;
1812
+ }
1813
+ setContextMenuRequest(null);
1814
+ },
1339
1815
  onTooltipRequest: setTooltipRequest
1340
1816
  },
1341
1817
  onFilterChange: (event) => {
@@ -1389,7 +1865,7 @@ function ReactPivotTableInner(props, ref) {
1389
1865
  const removeField = (fieldKey) => {
1390
1866
  applyLayout(pivotTable.removePivotField(fieldLayout, fieldKey));
1391
1867
  };
1392
- const updateField = (fieldKey, patch) => {
1868
+ function updateField(fieldKey, patch) {
1393
1869
  setFieldOverrides((current) => ({
1394
1870
  ...current,
1395
1871
  [fieldKey]: { ...current[fieldKey], ...patch }
@@ -1404,11 +1880,13 @@ function ReactPivotTableInner(props, ref) {
1404
1880
  indicator: {
1405
1881
  ...field.indicator,
1406
1882
  title: patch.title ?? field.indicator?.title,
1407
- aggregator: patch.aggregator ?? field.indicator?.aggregator
1883
+ aggregator: patch.aggregator ?? field.indicator?.aggregator,
1884
+ precision: "precision" in patch ? patch.precision : field.indicator?.precision,
1885
+ dataFormat: "dataFormat" in patch ? patch.dataFormat : field.indicator?.dataFormat
1408
1886
  }
1409
1887
  });
1410
1888
  }
1411
- };
1889
+ }
1412
1890
  react.useEffect(() => {
1413
1891
  const container = containerRef.current;
1414
1892
  if (!container) return;
@@ -1590,6 +2068,13 @@ function ReactPivotTableInner(props, ref) {
1590
2068
  /* @__PURE__ */ jsxRuntime.jsx(PivotTooltip, { request: tooltipRequest })
1591
2069
  ] });
1592
2070
  }
2071
+ function resolveDensityRowHeight(density) {
2072
+ if (density === "comfortable") return 56;
2073
+ if (density === "middle") return 48;
2074
+ if (density === "compact") return 32;
2075
+ if (density === "ultra-compact") return 26;
2076
+ return void 0;
2077
+ }
1593
2078
  var ReactPivotTable = react.forwardRef(ReactPivotTableInner);
1594
2079
  function toSharedFilterRequest(request, onValueChange) {
1595
2080
  if (!request) return null;
@@ -1754,5 +2239,6 @@ function inferFieldAggregator(records, dataIndex) {
1754
2239
  }
1755
2240
 
1756
2241
  exports.ReactPivotTable = ReactPivotTable;
2242
+ exports.ReactPivotTableDebugProvider = ReactPivotTableDebugProvider;
1757
2243
  //# sourceMappingURL=index.cjs.map
1758
2244
  //# sourceMappingURL=index.cjs.map