@canvas-components/react-list-table 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,2915 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var reactDom = require('react-dom');
5
+ var reactComponents = require('@canvas-components/react-components');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var listTable = require('@canvas-components/list-table');
8
+
9
+ // #style-inject:#style-inject
10
+ function styleInject(css, { insertAt } = {}) {
11
+ if (!css || typeof document === "undefined") return;
12
+ const head = document.head || document.getElementsByTagName("head")[0];
13
+ const style = document.createElement("style");
14
+ style.type = "text/css";
15
+ if (insertAt === "top") {
16
+ if (head.firstChild) {
17
+ head.insertBefore(style, head.firstChild);
18
+ } else {
19
+ head.appendChild(style);
20
+ }
21
+ } else {
22
+ head.appendChild(style);
23
+ }
24
+ if (style.styleSheet) {
25
+ style.styleSheet.cssText = css;
26
+ } else {
27
+ style.appendChild(document.createTextNode(css));
28
+ }
29
+ }
30
+
31
+ // src/styles/table-overrides.css
32
+ styleInject(".react-list-table-filter-option {\n transition: background-color 0.2s ease;\n}\n.react-list-table-filter-option:hover {\n background: #f3f4f6;\n}\n.react-list-table-menu-action,\n.react-list-table-menu-row {\n transition: background-color 0.2s ease, color 0.2s ease;\n}\n.react-list-table-menu-action:hover,\n.react-list-table-menu-row:hover {\n background: #f3f4f6 !important;\n}\n.react-list-table-custom-selection-copy {\n transition: background-color 0.2s ease;\n}\n.react-list-table-custom-selection-copy:hover {\n background: #4096ff !important;\n}\n.react-list-table-custom-selection-input > .canvas-react-input-number-handler-down {\n display: none;\n}\n.react-list-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-list-table-menu-action:hover .react-list-table-menu-chevron,\n.react-list-table-menu-row:hover .react-list-table-menu-chevron {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n.react-list-table-menu-chevron-active {\n border-color: #6b7280;\n transform: rotate(135deg);\n}\n");
33
+ var CONTEXT_MENU_SURFACE_STYLE = {
34
+ padding: 8,
35
+ background: "#ffffff",
36
+ boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)"
37
+ };
38
+ function ReactTableContextMenuView(props) {
39
+ const { request } = props;
40
+ if (!request) {
41
+ return null;
42
+ }
43
+ const surfaceStyle = {
44
+ ...CONTEXT_MENU_SURFACE_STYLE,
45
+ width: 260,
46
+ maxHeight: 420,
47
+ overflow: "auto"
48
+ };
49
+ return /* @__PURE__ */ jsxRuntime.jsx(
50
+ reactComponents.ReactPopup,
51
+ {
52
+ open: true,
53
+ anchorRect: { x: request.x, y: request.y, width: 0, height: 0 },
54
+ minWidth: 260,
55
+ onOpenChange: (open) => {
56
+ if (!open) {
57
+ request.onClose();
58
+ }
59
+ },
60
+ surfaceStyle,
61
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
62
+ /* @__PURE__ */ jsxRuntime.jsx(
63
+ MenuSubmenu,
64
+ {
65
+ label: "\u590D\u5236",
66
+ items: [
67
+ {
68
+ key: "copy-cell",
69
+ label: "\u590D\u5236\u5355\u5143\u683C",
70
+ onClick: request.onCopyCell
71
+ },
72
+ {
73
+ key: "copy-column",
74
+ label: "\u590D\u5236\u6574\u5217",
75
+ onClick: request.onCopyColumn
76
+ },
77
+ {
78
+ key: "copy-row-text",
79
+ label: "\u590D\u5236\u5F53\u524D\u884C\u6587\u672C",
80
+ onClick: request.onCopyRowText
81
+ },
82
+ {
83
+ key: "copy-row-json",
84
+ label: "\u590D\u5236\u5F53\u524D\u884C JSON",
85
+ onClick: request.onCopyRowJson
86
+ },
87
+ {
88
+ key: "copy-selection",
89
+ label: "\u590D\u5236\u9009\u533A",
90
+ onClick: request.onCopySelection
91
+ }
92
+ ]
93
+ }
94
+ ),
95
+ /* @__PURE__ */ jsxRuntime.jsx(CustomSelectionMenu, { request }),
96
+ /* @__PURE__ */ jsxRuntime.jsx(
97
+ MenuSubmenu,
98
+ {
99
+ label: "\u5BFC\u51FA",
100
+ items: [
101
+ {
102
+ key: "export-txt",
103
+ label: "\u5BFC\u51FA TXT",
104
+ onClick: request.onExportTxt
105
+ },
106
+ {
107
+ key: "export-csv",
108
+ label: "\u5BFC\u51FA CSV",
109
+ onClick: request.onExportCsv
110
+ },
111
+ {
112
+ key: "export-xlsx",
113
+ label: "\u5BFC\u51FA XLSX",
114
+ onClick: request.onExportXlsx
115
+ },
116
+ {
117
+ key: "export-json",
118
+ label: "\u5BFC\u51FA JSON",
119
+ onClick: request.onExportJson
120
+ }
121
+ ]
122
+ }
123
+ ),
124
+ /* @__PURE__ */ jsxRuntime.jsx(
125
+ MenuAction,
126
+ {
127
+ label: request.downloadContentLabel ?? "",
128
+ onClick: request.onDownloadContent
129
+ }
130
+ ),
131
+ /* @__PURE__ */ jsxRuntime.jsx(
132
+ MenuAction,
133
+ {
134
+ label: request.toggleExpandRowLabel ?? "",
135
+ onClick: request.onToggleExpandRow
136
+ }
137
+ ),
138
+ /* @__PURE__ */ jsxRuntime.jsx(
139
+ MenuAction,
140
+ {
141
+ label: "\u53D6\u6D88\u5168\u90E8\u6298\u53E0\u884C",
142
+ onClick: request.onExpandAllCollapsedRows
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsxRuntime.jsx(
146
+ MenuAction,
147
+ {
148
+ label: request.toggleColumnLabel ?? "",
149
+ onClick: request.onToggleCurrentColumn
150
+ }
151
+ ),
152
+ /* @__PURE__ */ jsxRuntime.jsx(
153
+ MenuAction,
154
+ {
155
+ label: "\u53D6\u6D88\u5168\u90E8\u6298\u53E0\u5217",
156
+ onClick: request.onExpandAllCollapsedColumns
157
+ }
158
+ ),
159
+ /* @__PURE__ */ jsxRuntime.jsx(
160
+ MenuAction,
161
+ {
162
+ label: request.summaryVisible ? "\u9690\u85CF\u6C47\u603B\u680F" : "\u663E\u793A\u6C47\u603B\u680F",
163
+ onClick: request.onToggleSummary
164
+ }
165
+ ),
166
+ /* @__PURE__ */ jsxRuntime.jsx(SummaryMenu, { request }),
167
+ /* @__PURE__ */ jsxRuntime.jsx(
168
+ MenuSubmenu,
169
+ {
170
+ label: "\u51BB\u7ED3",
171
+ items: [
172
+ {
173
+ key: "freeze-top",
174
+ label: "\u51BB\u7ED3\u5230\u9876\u90E8",
175
+ onClick: request.onFreezeRowTop
176
+ },
177
+ {
178
+ key: "freeze-bottom",
179
+ label: "\u51BB\u7ED3\u5230\u5E95\u90E8",
180
+ onClick: request.onFreezeRowBottom
181
+ },
182
+ {
183
+ key: "unfreeze",
184
+ label: "\u53D6\u6D88\u51BB\u7ED3",
185
+ onClick: request.onUnfreezeRow
186
+ }
187
+ ]
188
+ }
189
+ ),
190
+ /* @__PURE__ */ jsxRuntime.jsx(
191
+ MenuSubmenu,
192
+ {
193
+ label: "\u91CD\u7F6E",
194
+ items: [
195
+ {
196
+ key: "reset-filter",
197
+ label: "\u91CD\u7F6E\u7B5B\u9009",
198
+ onClick: request.onResetFilter
199
+ },
200
+ {
201
+ key: "reset-sort",
202
+ label: "\u91CD\u7F6E\u6392\u5E8F",
203
+ onClick: request.onResetSort
204
+ },
205
+ {
206
+ key: "reset-header",
207
+ label: "\u91CD\u7F6E\u8868\u5934\u914D\u7F6E",
208
+ onClick: request.onResetHeader
209
+ }
210
+ ]
211
+ }
212
+ ),
213
+ /* @__PURE__ */ jsxRuntime.jsx(
214
+ DensityMenu,
215
+ {
216
+ value: request.density ?? "middle",
217
+ onChange: request.onChangeDensity
218
+ }
219
+ ),
220
+ /* @__PURE__ */ jsxRuntime.jsx(
221
+ ZoomMenu,
222
+ {
223
+ value: request.zoom ?? 1,
224
+ onChange: request.onChangeZoom
225
+ }
226
+ ),
227
+ request.columns?.length && request.onToggleColumn ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
228
+ /* @__PURE__ */ jsxRuntime.jsx(MenuDivider, {}),
229
+ /* @__PURE__ */ jsxRuntime.jsx(
230
+ ColumnVisibilityMenu,
231
+ {
232
+ columns: request.columns,
233
+ onToggle: request.onToggleColumn
234
+ }
235
+ )
236
+ ] }) : null
237
+ ] })
238
+ }
239
+ );
240
+ }
241
+ function MenuAction(props) {
242
+ const { label, onClick, selected, reserveSelectionIcon } = props;
243
+ if (!onClick) {
244
+ return null;
245
+ }
246
+ return /* @__PURE__ */ jsxRuntime.jsxs(
247
+ "button",
248
+ {
249
+ type: "button",
250
+ onClick,
251
+ className: "react-list-table-menu-action",
252
+ style: {
253
+ display: "flex",
254
+ alignItems: "center",
255
+ width: "100%",
256
+ height: 32,
257
+ padding: "0 10px",
258
+ border: "none",
259
+ borderRadius: 8,
260
+ background: "transparent",
261
+ color: "#374151",
262
+ textAlign: "left",
263
+ cursor: "pointer"
264
+ },
265
+ children: [
266
+ reserveSelectionIcon ? /* @__PURE__ */ jsxRuntime.jsx(
267
+ "span",
268
+ {
269
+ "aria-hidden": "true",
270
+ style: {
271
+ width: 16,
272
+ flex: "0 0 16px",
273
+ marginRight: 6,
274
+ textAlign: "center"
275
+ },
276
+ children: selected ? "\u2713" : ""
277
+ }
278
+ ) : null,
279
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label })
280
+ ]
281
+ }
282
+ );
283
+ }
284
+ function MenuSubmenu(props) {
285
+ const { label, items, footer } = props;
286
+ const menuItems = items.filter((item) => item.onClick);
287
+ const reserveSelectionIcon = menuItems.some(
288
+ (item) => typeof item.selected === "boolean"
289
+ );
290
+ const triggerRef = react.useRef(null);
291
+ const [open, setOpen] = react.useState(false);
292
+ const closeTimerRef = react.useRef(null);
293
+ if (!menuItems.length && !footer) {
294
+ return null;
295
+ }
296
+ const clearCloseTimer = () => {
297
+ if (closeTimerRef.current != null) {
298
+ window.clearTimeout(closeTimerRef.current);
299
+ closeTimerRef.current = null;
300
+ }
301
+ };
302
+ const scheduleClose = () => {
303
+ clearCloseTimer();
304
+ closeTimerRef.current = window.setTimeout(() => {
305
+ setOpen(false);
306
+ closeTimerRef.current = null;
307
+ }, 120);
308
+ };
309
+ return /* @__PURE__ */ jsxRuntime.jsxs(
310
+ "div",
311
+ {
312
+ onMouseEnter: () => {
313
+ clearCloseTimer();
314
+ setOpen(true);
315
+ },
316
+ onMouseLeave: () => {
317
+ scheduleClose();
318
+ },
319
+ children: [
320
+ /* @__PURE__ */ jsxRuntime.jsxs(
321
+ "button",
322
+ {
323
+ ref: triggerRef,
324
+ type: "button",
325
+ className: "react-list-table-menu-action react-list-table-menu-action-submenu",
326
+ style: {
327
+ display: "flex",
328
+ alignItems: "center",
329
+ justifyContent: "space-between",
330
+ width: "100%",
331
+ height: 32,
332
+ padding: "0 10px",
333
+ border: "none",
334
+ borderRadius: 8,
335
+ background: "transparent",
336
+ color: "#374151",
337
+ textAlign: "left",
338
+ cursor: "pointer"
339
+ },
340
+ children: [
341
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: label }),
342
+ /* @__PURE__ */ jsxRuntime.jsx(
343
+ "span",
344
+ {
345
+ className: `react-list-table-menu-chevron${open ? " react-list-table-menu-chevron-active" : ""}`,
346
+ "aria-hidden": "true"
347
+ }
348
+ )
349
+ ]
350
+ }
351
+ ),
352
+ /* @__PURE__ */ jsxRuntime.jsx(
353
+ reactComponents.ReactPopup,
354
+ {
355
+ open,
356
+ anchorRef: triggerRef,
357
+ placement: "rightTop",
358
+ offset: 2,
359
+ minWidth: 220,
360
+ onOpenChange: setOpen,
361
+ surfaceStyle: {
362
+ ...CONTEXT_MENU_SURFACE_STYLE,
363
+ maxHeight: 360,
364
+ overflow: "auto"
365
+ },
366
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
367
+ "div",
368
+ {
369
+ onMouseEnter: () => {
370
+ clearCloseTimer();
371
+ },
372
+ onMouseLeave: () => {
373
+ scheduleClose();
374
+ },
375
+ children: [
376
+ menuItems.map((item) => /* @__PURE__ */ jsxRuntime.jsx(
377
+ MenuAction,
378
+ {
379
+ label: item.label,
380
+ onClick: item.onClick,
381
+ selected: item.selected,
382
+ reserveSelectionIcon
383
+ },
384
+ item.key
385
+ )),
386
+ footer
387
+ ]
388
+ }
389
+ )
390
+ }
391
+ )
392
+ ]
393
+ }
394
+ );
395
+ }
396
+ function DensityMenu(props) {
397
+ const { value, onChange } = props;
398
+ if (!onChange) {
399
+ return null;
400
+ }
401
+ return /* @__PURE__ */ jsxRuntime.jsx(
402
+ MenuSubmenu,
403
+ {
404
+ label: "\u8868\u683C\u5BC6\u5EA6",
405
+ items: [
406
+ {
407
+ key: "density-comfortable",
408
+ label: "\u5BBD\u677E",
409
+ selected: value === "comfortable",
410
+ onClick: () => {
411
+ onChange("comfortable");
412
+ }
413
+ },
414
+ {
415
+ key: "density-middle",
416
+ label: "\u4E2D\u7B49",
417
+ selected: value === "middle",
418
+ onClick: () => {
419
+ onChange("middle");
420
+ }
421
+ },
422
+ {
423
+ key: "density-compact",
424
+ label: "\u7D27\u51D1",
425
+ selected: value === "compact",
426
+ onClick: () => {
427
+ onChange("compact");
428
+ }
429
+ }
430
+ ]
431
+ }
432
+ );
433
+ }
434
+ var CONTEXT_MENU_ZOOM_MIN = 50;
435
+ var CONTEXT_MENU_ZOOM_MAX = 200;
436
+ var CONTEXT_MENU_ZOOM_STEP = 10;
437
+ function ZoomMenu(props) {
438
+ const { value, onChange } = props;
439
+ const triggerRef = react.useRef(null);
440
+ const [open, setOpen] = react.useState(false);
441
+ const closeTimerRef = react.useRef(null);
442
+ if (!onChange) {
443
+ return null;
444
+ }
445
+ const percent = Math.round(value * 100);
446
+ const clearCloseTimer = () => {
447
+ if (closeTimerRef.current != null) {
448
+ window.clearTimeout(closeTimerRef.current);
449
+ closeTimerRef.current = null;
450
+ }
451
+ };
452
+ const scheduleClose = () => {
453
+ clearCloseTimer();
454
+ closeTimerRef.current = window.setTimeout(() => {
455
+ setOpen(false);
456
+ closeTimerRef.current = null;
457
+ }, 120);
458
+ };
459
+ return /* @__PURE__ */ jsxRuntime.jsxs(
460
+ "div",
461
+ {
462
+ onMouseEnter: () => {
463
+ clearCloseTimer();
464
+ setOpen(true);
465
+ },
466
+ onMouseLeave: () => {
467
+ scheduleClose();
468
+ },
469
+ children: [
470
+ /* @__PURE__ */ jsxRuntime.jsxs(
471
+ "button",
472
+ {
473
+ ref: triggerRef,
474
+ type: "button",
475
+ className: "react-list-table-menu-action react-list-table-menu-action-submenu",
476
+ style: {
477
+ display: "flex",
478
+ alignItems: "center",
479
+ justifyContent: "space-between",
480
+ width: "100%",
481
+ height: 32,
482
+ padding: "0 10px",
483
+ border: "none",
484
+ borderRadius: 8,
485
+ background: "transparent",
486
+ color: "#374151",
487
+ textAlign: "left",
488
+ cursor: "pointer"
489
+ },
490
+ children: [
491
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u7F29\u653E" }),
492
+ /* @__PURE__ */ jsxRuntime.jsxs(
493
+ "span",
494
+ {
495
+ style: {
496
+ display: "inline-flex",
497
+ alignItems: "center",
498
+ gap: 8,
499
+ color: "#6b7280",
500
+ fontSize: 12
501
+ },
502
+ children: [
503
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
504
+ percent,
505
+ "%"
506
+ ] }),
507
+ /* @__PURE__ */ jsxRuntime.jsx(
508
+ "span",
509
+ {
510
+ className: `react-list-table-menu-chevron${open ? " react-list-table-menu-chevron-active" : ""}`,
511
+ "aria-hidden": "true"
512
+ }
513
+ )
514
+ ]
515
+ }
516
+ )
517
+ ]
518
+ }
519
+ ),
520
+ /* @__PURE__ */ jsxRuntime.jsx(
521
+ reactComponents.ReactPopup,
522
+ {
523
+ open,
524
+ anchorRef: triggerRef,
525
+ placement: "rightTop",
526
+ offset: 2,
527
+ minWidth: 220,
528
+ onOpenChange: setOpen,
529
+ surfaceStyle: {
530
+ ...CONTEXT_MENU_SURFACE_STYLE,
531
+ width: 220
532
+ },
533
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
534
+ "div",
535
+ {
536
+ onMouseEnter: () => {
537
+ clearCloseTimer();
538
+ },
539
+ onMouseLeave: () => {
540
+ scheduleClose();
541
+ },
542
+ style: {
543
+ display: "flex",
544
+ flexDirection: "column",
545
+ gap: 8,
546
+ padding: "4px 2px"
547
+ },
548
+ children: [
549
+ /* @__PURE__ */ jsxRuntime.jsx(
550
+ "div",
551
+ {
552
+ style: {
553
+ color: "#6b7280",
554
+ fontSize: 12,
555
+ padding: "0 8px"
556
+ },
557
+ children: "\u8868\u683C\u7F29\u653E\uFF0850% - 200%\uFF09"
558
+ }
559
+ ),
560
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0 8px 4px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
561
+ reactComponents.ReactInputNumber,
562
+ {
563
+ value: percent,
564
+ min: CONTEXT_MENU_ZOOM_MIN,
565
+ max: CONTEXT_MENU_ZOOM_MAX,
566
+ step: CONTEXT_MENU_ZOOM_STEP,
567
+ precision: 0,
568
+ addonAfter: "%",
569
+ onChange: (next) => {
570
+ if (next == null || !Number.isFinite(next)) {
571
+ return;
572
+ }
573
+ onChange(Math.round(next) / 100);
574
+ }
575
+ }
576
+ ) }),
577
+ /* @__PURE__ */ jsxRuntime.jsx(
578
+ "button",
579
+ {
580
+ type: "button",
581
+ disabled: percent === 100,
582
+ onClick: () => {
583
+ onChange(1);
584
+ },
585
+ className: "react-list-table-menu-action",
586
+ style: {
587
+ display: "block",
588
+ width: "100%",
589
+ height: 32,
590
+ padding: "0 8px",
591
+ border: "none",
592
+ borderRadius: 8,
593
+ background: "transparent",
594
+ color: percent === 100 ? "#9ca3af" : "#374151",
595
+ textAlign: "left",
596
+ cursor: percent === 100 ? "not-allowed" : "pointer"
597
+ },
598
+ children: "\u91CD\u7F6E\u7F29\u653E"
599
+ }
600
+ )
601
+ ]
602
+ }
603
+ )
604
+ }
605
+ )
606
+ ]
607
+ }
608
+ );
609
+ }
610
+ function ColumnVisibilityMenu(props) {
611
+ const { columns, onToggle } = props;
612
+ const triggerRef = react.useRef(null);
613
+ const [open, setOpen] = react.useState(false);
614
+ const closeTimerRef = react.useRef(null);
615
+ const clearCloseTimer = () => {
616
+ if (closeTimerRef.current != null) {
617
+ window.clearTimeout(closeTimerRef.current);
618
+ closeTimerRef.current = null;
619
+ }
620
+ };
621
+ const scheduleClose = () => {
622
+ clearCloseTimer();
623
+ closeTimerRef.current = window.setTimeout(() => {
624
+ setOpen(false);
625
+ closeTimerRef.current = null;
626
+ }, 120);
627
+ };
628
+ return /* @__PURE__ */ jsxRuntime.jsxs(
629
+ "div",
630
+ {
631
+ onMouseEnter: () => {
632
+ clearCloseTimer();
633
+ setOpen(true);
634
+ },
635
+ onMouseLeave: () => {
636
+ scheduleClose();
637
+ },
638
+ children: [
639
+ /* @__PURE__ */ jsxRuntime.jsxs(
640
+ "button",
641
+ {
642
+ ref: triggerRef,
643
+ type: "button",
644
+ className: "react-list-table-menu-action react-list-table-menu-action-submenu",
645
+ style: {
646
+ display: "flex",
647
+ alignItems: "center",
648
+ justifyContent: "space-between",
649
+ width: "100%",
650
+ height: 32,
651
+ padding: "0 10px",
652
+ border: "none",
653
+ borderRadius: 8,
654
+ background: "transparent",
655
+ color: "#374151",
656
+ textAlign: "left",
657
+ cursor: "pointer"
658
+ },
659
+ children: [
660
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u5217\u663E\u793A" }),
661
+ /* @__PURE__ */ jsxRuntime.jsx(
662
+ "span",
663
+ {
664
+ className: `react-list-table-menu-chevron${open ? " react-list-table-menu-chevron-active" : ""}`,
665
+ "aria-hidden": "true"
666
+ }
667
+ )
668
+ ]
669
+ }
670
+ ),
671
+ /* @__PURE__ */ jsxRuntime.jsx(
672
+ reactComponents.ReactPopup,
673
+ {
674
+ open,
675
+ anchorRef: triggerRef,
676
+ placement: "rightTop",
677
+ offset: 2,
678
+ minWidth: 220,
679
+ onOpenChange: setOpen,
680
+ surfaceStyle: {
681
+ ...CONTEXT_MENU_SURFACE_STYLE,
682
+ maxHeight: 360,
683
+ overflow: "auto"
684
+ },
685
+ children: /* @__PURE__ */ jsxRuntime.jsx(
686
+ "div",
687
+ {
688
+ onMouseEnter: () => {
689
+ clearCloseTimer();
690
+ },
691
+ onMouseLeave: () => {
692
+ scheduleClose();
693
+ },
694
+ children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
695
+ ColumnVisibilityItem,
696
+ {
697
+ item: column,
698
+ onToggle
699
+ },
700
+ column.key
701
+ ))
702
+ }
703
+ )
704
+ }
705
+ )
706
+ ]
707
+ }
708
+ );
709
+ }
710
+ function ColumnVisibilityItem(props) {
711
+ const { item, onToggle } = props;
712
+ const triggerRef = react.useRef(null);
713
+ const [open, setOpen] = react.useState(false);
714
+ const closeTimerRef = react.useRef(null);
715
+ const hasChildren = !!item.children?.length;
716
+ const clearCloseTimer = () => {
717
+ if (closeTimerRef.current != null) {
718
+ window.clearTimeout(closeTimerRef.current);
719
+ closeTimerRef.current = null;
720
+ }
721
+ };
722
+ const scheduleClose = () => {
723
+ clearCloseTimer();
724
+ closeTimerRef.current = window.setTimeout(() => {
725
+ setOpen(false);
726
+ closeTimerRef.current = null;
727
+ }, 120);
728
+ };
729
+ return /* @__PURE__ */ jsxRuntime.jsxs(
730
+ "div",
731
+ {
732
+ ref: triggerRef,
733
+ className: "react-list-table-menu-row",
734
+ onMouseEnter: () => {
735
+ if (hasChildren) {
736
+ clearCloseTimer();
737
+ setOpen(true);
738
+ }
739
+ },
740
+ onMouseLeave: () => {
741
+ if (hasChildren) {
742
+ scheduleClose();
743
+ }
744
+ },
745
+ style: {
746
+ display: "flex",
747
+ alignItems: "center",
748
+ justifyContent: "space-between",
749
+ gap: 8,
750
+ minHeight: 32,
751
+ padding: "0 10px",
752
+ borderRadius: 8,
753
+ color: item.disabled ? "#9ca3af" : "#374151",
754
+ fontSize: 14
755
+ },
756
+ children: [
757
+ /* @__PURE__ */ jsxRuntime.jsx(
758
+ reactComponents.ReactCheckbox,
759
+ {
760
+ checked: item.checked,
761
+ disabled: item.disabled,
762
+ indeterminate: !!item.indeterminate,
763
+ onChange: (event) => {
764
+ onToggle(item.key, !!event.target.checked);
765
+ },
766
+ children: item.title
767
+ }
768
+ ),
769
+ hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
770
+ "span",
771
+ {
772
+ className: `react-list-table-menu-chevron${open ? " react-list-table-menu-chevron-active" : ""}`,
773
+ "aria-hidden": "true"
774
+ }
775
+ ) : null,
776
+ hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
777
+ reactComponents.ReactPopup,
778
+ {
779
+ open,
780
+ anchorRef: triggerRef,
781
+ placement: "rightTop",
782
+ offset: 2,
783
+ minWidth: 220,
784
+ onOpenChange: setOpen,
785
+ surfaceStyle: {
786
+ ...CONTEXT_MENU_SURFACE_STYLE,
787
+ maxHeight: 320,
788
+ overflow: "auto"
789
+ },
790
+ children: /* @__PURE__ */ jsxRuntime.jsx(
791
+ "div",
792
+ {
793
+ onMouseEnter: () => {
794
+ clearCloseTimer();
795
+ },
796
+ onMouseLeave: () => {
797
+ scheduleClose();
798
+ },
799
+ children: item.children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
800
+ ColumnVisibilityItem,
801
+ {
802
+ item: child,
803
+ onToggle
804
+ },
805
+ child.key
806
+ ))
807
+ }
808
+ )
809
+ }
810
+ ) : null
811
+ ]
812
+ }
813
+ );
814
+ }
815
+ function MenuDivider() {
816
+ return /* @__PURE__ */ jsxRuntime.jsx(
817
+ "div",
818
+ {
819
+ style: {
820
+ height: 1,
821
+ margin: "6px 0",
822
+ background: "#f0f0f0"
823
+ }
824
+ }
825
+ );
826
+ }
827
+ function CustomSelectionMenu(props) {
828
+ const { request } = props;
829
+ const triggerRef = react.useRef(null);
830
+ const [open, setOpen] = react.useState(false);
831
+ const initial = request.customSelection ?? {
832
+ startRow: 1,
833
+ startColumn: 1,
834
+ endRow: 1,
835
+ endColumn: 1,
836
+ rowCount: 0,
837
+ columnCount: 0
838
+ };
839
+ const [range, setRange] = react.useState(initial);
840
+ if (!request.onCopyCustomSelection || !request.customSelection) {
841
+ return null;
842
+ }
843
+ const update = (key, value) => {
844
+ setRange((current) => ({
845
+ ...current,
846
+ [key]: value == null ? 1 : Math.floor(value)
847
+ }));
848
+ };
849
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
850
+ /* @__PURE__ */ jsxRuntime.jsx(
851
+ "button",
852
+ {
853
+ ref: triggerRef,
854
+ type: "button",
855
+ className: "react-list-table-menu-action",
856
+ style: {
857
+ display: "flex",
858
+ alignItems: "center",
859
+ width: "100%",
860
+ height: 32,
861
+ padding: "0 10px",
862
+ border: "none",
863
+ borderRadius: 8,
864
+ background: "transparent",
865
+ color: "#374151",
866
+ textAlign: "left",
867
+ cursor: "pointer"
868
+ },
869
+ onClick: () => setOpen((value) => !value),
870
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u590D\u5236\u81EA\u5B9A\u4E49\u9009\u533A" })
871
+ }
872
+ ),
873
+ /* @__PURE__ */ jsxRuntime.jsx(
874
+ reactComponents.ReactPopup,
875
+ {
876
+ open,
877
+ anchorRef: triggerRef,
878
+ placement: "rightTop",
879
+ offset: 2,
880
+ minWidth: 250,
881
+ onOpenChange: setOpen,
882
+ surfaceStyle: { ...CONTEXT_MENU_SURFACE_STYLE, width: 250 },
883
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { padding: 6 }, children: [
884
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#6b7280", fontSize: 12, marginBottom: 6 }, children: "\u8F93\u5165\u8D77\u59CB\u4F4D\u7F6E\u548C\u7ED3\u675F\u4F4D\u7F6E" }),
885
+ /* @__PURE__ */ jsxRuntime.jsxs(
886
+ "div",
887
+ {
888
+ style: {
889
+ display: "grid",
890
+ gridTemplateColumns: "38px 1fr 1fr",
891
+ gap: 6,
892
+ marginBottom: 4,
893
+ color: "#6b7280",
894
+ fontSize: 12,
895
+ textAlign: "center"
896
+ },
897
+ children: [
898
+ /* @__PURE__ */ jsxRuntime.jsx("span", {}),
899
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u884C" }),
900
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u5217" })
901
+ ]
902
+ }
903
+ ),
904
+ /* @__PURE__ */ jsxRuntime.jsx(
905
+ CustomSelectionRow,
906
+ {
907
+ label: "\u8D77\u59CB",
908
+ row: range.startRow,
909
+ column: range.startColumn,
910
+ onRowChange: (value) => update("startRow", value),
911
+ onColumnChange: (value) => update("startColumn", value)
912
+ }
913
+ ),
914
+ /* @__PURE__ */ jsxRuntime.jsx(
915
+ CustomSelectionRow,
916
+ {
917
+ label: "\u7ED3\u675F",
918
+ row: range.endRow,
919
+ column: range.endColumn,
920
+ onRowChange: (value) => update("endRow", value),
921
+ onColumnChange: (value) => update("endColumn", value)
922
+ }
923
+ ),
924
+ /* @__PURE__ */ jsxRuntime.jsx(
925
+ "button",
926
+ {
927
+ type: "button",
928
+ className: "react-list-table-custom-selection-copy",
929
+ style: {
930
+ display: "block",
931
+ width: "100%",
932
+ height: 32,
933
+ marginTop: 6,
934
+ border: "none",
935
+ borderRadius: 8,
936
+ background: "#1677ff",
937
+ color: "#fff",
938
+ cursor: "pointer"
939
+ },
940
+ onClick: () => {
941
+ request.onCopyCustomSelection?.({
942
+ startRow: Math.max(range.startRow, 1),
943
+ startColumn: Math.max(range.startColumn, 1),
944
+ endRow: Math.max(range.endRow, 1),
945
+ endColumn: Math.max(range.endColumn, 1)
946
+ });
947
+ setOpen(false);
948
+ },
949
+ children: "\u590D\u5236"
950
+ }
951
+ )
952
+ ] })
953
+ }
954
+ )
955
+ ] });
956
+ }
957
+ function CustomSelectionRow(props) {
958
+ return /* @__PURE__ */ jsxRuntime.jsxs(
959
+ "div",
960
+ {
961
+ style: {
962
+ display: "grid",
963
+ gridTemplateColumns: "38px 1fr 1fr",
964
+ gap: 6,
965
+ alignItems: "center",
966
+ marginBottom: 6
967
+ },
968
+ children: [
969
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontSize: 12 }, children: props.label }),
970
+ /* @__PURE__ */ jsxRuntime.jsx(
971
+ reactComponents.ReactInputNumber,
972
+ {
973
+ className: "react-list-table-custom-selection-input",
974
+ value: props.row,
975
+ min: 1,
976
+ step: 1,
977
+ precision: 0,
978
+ placeholder: "\u884C",
979
+ onChange: props.onRowChange
980
+ }
981
+ ),
982
+ /* @__PURE__ */ jsxRuntime.jsx(
983
+ reactComponents.ReactInputNumber,
984
+ {
985
+ className: "react-list-table-custom-selection-input",
986
+ value: props.column,
987
+ min: 1,
988
+ step: 1,
989
+ precision: 0,
990
+ placeholder: "\u5217",
991
+ onChange: props.onColumnChange
992
+ }
993
+ )
994
+ ]
995
+ }
996
+ );
997
+ }
998
+ function SummaryMenu(props) {
999
+ const { request } = props;
1000
+ const [precision, setPrecision] = react.useState(
1001
+ request.summaryPrecision ?? null
1002
+ );
1003
+ react.useEffect(() => {
1004
+ setPrecision(request.summaryPrecision ?? null);
1005
+ }, [request.summaryColumnKey, request.summaryPrecision]);
1006
+ if (!request.summaryColumnKey) {
1007
+ return null;
1008
+ }
1009
+ const summaryTypes = [
1010
+ { key: "sum", label: "\u6C42\u548C", value: "sum" },
1011
+ { key: "avg", label: "\u5E73\u5747\u503C", value: "avg" },
1012
+ { key: "count", label: "\u8BA1\u6570", value: "count" },
1013
+ { key: "unionCount", label: "\u53BB\u91CD\u8BA1\u6570", value: "unionCount" },
1014
+ { key: "rowCount", label: "\u884C\u6570", value: "rowCount" },
1015
+ { key: "mergedRowCount", label: "\u5408\u5E76\u884C\u6570", value: "mergedRowCount" },
1016
+ { key: "min", label: "\u6700\u5C0F\u503C", value: "min" },
1017
+ { key: "max", label: "\u6700\u5927\u503C", value: "max" }
1018
+ ];
1019
+ return /* @__PURE__ */ jsxRuntime.jsx(
1020
+ MenuSubmenu,
1021
+ {
1022
+ label: "\u6C47\u603B\u65B9\u5F0F",
1023
+ items: summaryTypes.map((item) => ({
1024
+ key: item.key,
1025
+ label: item.label,
1026
+ selected: request.summaryType === item.value,
1027
+ onClick: () => request.onChangeSummaryType?.(item.value)
1028
+ })),
1029
+ footer: request.onChangeSummaryPrecision ? /* @__PURE__ */ jsxRuntime.jsxs(
1030
+ "div",
1031
+ {
1032
+ style: {
1033
+ display: "grid",
1034
+ gridTemplateColumns: "72px 1fr",
1035
+ gap: 8,
1036
+ alignItems: "center",
1037
+ marginTop: 4,
1038
+ padding: "10px 10px 2px",
1039
+ borderTop: "1px solid #e5e7eb"
1040
+ },
1041
+ children: [
1042
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#374151", fontSize: 13 }, children: "\u5C0F\u6570\u4F4D\u6570" }),
1043
+ /* @__PURE__ */ jsxRuntime.jsx(
1044
+ reactComponents.ReactInputNumber,
1045
+ {
1046
+ value: precision,
1047
+ min: 0,
1048
+ max: 20,
1049
+ step: 1,
1050
+ precision: 0,
1051
+ placeholder: "\u9ED8\u8BA4",
1052
+ onChange: setPrecision,
1053
+ onCommit: (value) => {
1054
+ request.onChangeSummaryPrecision?.(value ?? void 0);
1055
+ }
1056
+ }
1057
+ )
1058
+ ]
1059
+ }
1060
+ ) : void 0
1061
+ }
1062
+ );
1063
+ }
1064
+
1065
+ // src/features/editor/utils.ts
1066
+ function toNumberValue(value) {
1067
+ if (typeof value === "number" && Number.isFinite(value)) {
1068
+ return value;
1069
+ }
1070
+ if (typeof value === "string" && value.trim().length > 0) {
1071
+ const nextValue = Number(value);
1072
+ return Number.isFinite(nextValue) ? nextValue : null;
1073
+ }
1074
+ return null;
1075
+ }
1076
+ function toNumericProp(value) {
1077
+ if (typeof value === "number") {
1078
+ return value;
1079
+ }
1080
+ if (typeof value === "string" && value.trim().length > 0) {
1081
+ const nextValue = Number(value);
1082
+ return Number.isFinite(nextValue) ? nextValue : void 0;
1083
+ }
1084
+ return void 0;
1085
+ }
1086
+ function resolvePadding(value, fallback = 0) {
1087
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : fallback;
1088
+ }
1089
+ function resolveEditorControlSize(request) {
1090
+ const targetRect = request.hostRect ?? request.rect;
1091
+ const height = Math.max(targetRect.height - 2, 1);
1092
+ const fontSize = typeof request.theme.fontSize === "number" && Number.isFinite(request.theme.fontSize) && request.theme.fontSize > 0 ? request.theme.fontSize : void 0;
1093
+ const paddingInline = resolvePadding(request.theme.paddingInline);
1094
+ const paddingBlock = resolvePadding(request.theme.paddingBlock);
1095
+ const contentZoom = typeof request.theme.contentZoom === "number" && Number.isFinite(request.theme.contentZoom) && request.theme.contentZoom > 0 ? request.theme.contentZoom : 1;
1096
+ return { height, fontSize, paddingInline, paddingBlock, contentZoom };
1097
+ }
1098
+ function getEditorInputStyle(request) {
1099
+ const { height, fontSize, paddingInline, paddingBlock, contentZoom } = resolveEditorControlSize(request);
1100
+ return {
1101
+ width: "100%",
1102
+ height,
1103
+ minHeight: height,
1104
+ color: request.theme.cellColor ?? request.theme.textColor,
1105
+ fontFamily: request.theme.fontFamily,
1106
+ fontSize,
1107
+ // 用像素 token,确保 select/time/color 触发器与内部 Input 同步缩放。
1108
+ ["--canvas-react-control-height"]: `${height}px`,
1109
+ ["--canvas-react-font-size"]: fontSize != null ? `${fontSize}px` : void 0,
1110
+ ["--canvas-react-control-padding-inline"]: `${paddingInline}px`,
1111
+ ["--canvas-react-control-padding-block"]: `${paddingBlock}px`,
1112
+ ["--canvas-react-content-zoom"]: String(contentZoom),
1113
+ boxSizing: "border-box"
1114
+ };
1115
+ }
1116
+ function resolveEditorOverlayStyle(params) {
1117
+ const { rect, hostRect, fontSize, paddingInline, paddingBlock, contentZoom } = params;
1118
+ const targetRect = hostRect ?? rect;
1119
+ const height = Math.max(targetRect.height - 2, 1);
1120
+ const resolvedFontSize = typeof fontSize === "number" && Number.isFinite(fontSize) && fontSize > 0 ? fontSize : void 0;
1121
+ const resolvedPaddingInline = resolvePadding(paddingInline);
1122
+ const resolvedPaddingBlock = resolvePadding(paddingBlock);
1123
+ const resolvedContentZoom = typeof contentZoom === "number" && Number.isFinite(contentZoom) && contentZoom > 0 ? contentZoom : 1;
1124
+ return {
1125
+ position: hostRect ? "absolute" : "fixed",
1126
+ left: targetRect.x,
1127
+ top: targetRect.y + 1,
1128
+ width: Math.max(targetRect.width, 1),
1129
+ height,
1130
+ minHeight: height,
1131
+ zIndex: 1200,
1132
+ boxSizing: "border-box",
1133
+ // 覆盖表单组件 token,使输入框高度/字号/内边距跟随表格缩放。
1134
+ ["--canvas-react-control-height"]: `${height}px`,
1135
+ ["--canvas-react-control-padding-inline"]: `${resolvedPaddingInline}px`,
1136
+ ["--canvas-react-control-padding-block"]: `${resolvedPaddingBlock}px`,
1137
+ ["--canvas-react-content-zoom"]: String(resolvedContentZoom),
1138
+ ...resolvedFontSize != null ? {
1139
+ ["--canvas-react-font-size"]: `${resolvedFontSize}px`,
1140
+ fontSize: resolvedFontSize
1141
+ } : null
1142
+ };
1143
+ }
1144
+ function ReactTableEditorOverlay(props) {
1145
+ const { request } = props;
1146
+ const editorHostRef = react.useRef(null);
1147
+ const style = resolveEditorOverlayStyle({
1148
+ rect: request.rect,
1149
+ hostRect: request.hostRect,
1150
+ fontSize: request.theme.fontSize,
1151
+ paddingInline: request.theme.paddingInline,
1152
+ paddingBlock: request.theme.paddingBlock,
1153
+ contentZoom: request.theme.contentZoom
1154
+ });
1155
+ const contentZoom = typeof request.theme.contentZoom === "number" && Number.isFinite(request.theme.contentZoom) && request.theme.contentZoom > 0 ? request.theme.contentZoom : 1;
1156
+ react.useLayoutEffect(() => {
1157
+ const input = editorHostRef.current?.querySelector("input");
1158
+ if (!input) {
1159
+ return;
1160
+ }
1161
+ focusAndSelectEditorInput(input);
1162
+ }, [request]);
1163
+ return /* @__PURE__ */ jsxRuntime.jsx(reactComponents.ReactContentScaleProvider, { scale: contentZoom, children: /* @__PURE__ */ jsxRuntime.jsx("div", { ref: editorHostRef, children: renderEditorByType(request, style) }, request.editorKey) });
1164
+ }
1165
+ function renderEditorByType(request, style) {
1166
+ switch (request.config.valueType ?? "text") {
1167
+ case "number":
1168
+ return /* @__PURE__ */ jsxRuntime.jsx(NumberEditor, { request, style });
1169
+ case "input-range":
1170
+ return /* @__PURE__ */ jsxRuntime.jsx(InputRangeEditor, { request, style });
1171
+ case "year":
1172
+ return /* @__PURE__ */ jsxRuntime.jsx(YearEditor, { request, style });
1173
+ case "quarter":
1174
+ return /* @__PURE__ */ jsxRuntime.jsx(QuarterEditor, { request, style });
1175
+ case "month":
1176
+ return /* @__PURE__ */ jsxRuntime.jsx(MonthEditor, { request, style });
1177
+ case "date":
1178
+ return /* @__PURE__ */ jsxRuntime.jsx(DateEditor, { request, style });
1179
+ case "date-range":
1180
+ return /* @__PURE__ */ jsxRuntime.jsx(DateRangeEditor, { request, style });
1181
+ case "time":
1182
+ return /* @__PURE__ */ jsxRuntime.jsx(TimeEditor, { request, style });
1183
+ case "datetime":
1184
+ return /* @__PURE__ */ jsxRuntime.jsx(DateTimeEditor, { request, style });
1185
+ case "datetime-range":
1186
+ return /* @__PURE__ */ jsxRuntime.jsx(DateTimeRangeEditor, { request, style });
1187
+ case "timerange":
1188
+ return /* @__PURE__ */ jsxRuntime.jsx(TimeRangeEditor, { request, style });
1189
+ case "color":
1190
+ return /* @__PURE__ */ jsxRuntime.jsx(ColorEditor, { request, style });
1191
+ case "select":
1192
+ return /* @__PURE__ */ jsxRuntime.jsx(SelectEditor, { request, style });
1193
+ case "auto-complete":
1194
+ return /* @__PURE__ */ jsxRuntime.jsx(AutoCompleteEditor, { request, style });
1195
+ default:
1196
+ return /* @__PURE__ */ jsxRuntime.jsx(TextEditor, { request, style });
1197
+ }
1198
+ }
1199
+ function TextEditor(props) {
1200
+ const { request, style } = props;
1201
+ const [value, setValue] = react.useState(String(request.value ?? ""));
1202
+ const hostRef = react.useRef(null);
1203
+ const skipBlurCommitRef = react.useRef(false);
1204
+ react.useLayoutEffect(() => {
1205
+ const input = hostRef.current?.querySelector("input");
1206
+ focusAndSelectEditorInput(input);
1207
+ }, [request]);
1208
+ react.useEffect(() => {
1209
+ setValue(String(request.value ?? ""));
1210
+ }, [request.value]);
1211
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: hostRef, style, children: /* @__PURE__ */ jsxRuntime.jsx(
1212
+ reactComponents.ReactInput,
1213
+ {
1214
+ value,
1215
+ placeholder: request.config.placeholder ?? "",
1216
+ onChange: (event) => {
1217
+ const nextValue = event.target.value;
1218
+ setValue(nextValue);
1219
+ request.onChange(nextValue);
1220
+ },
1221
+ onPressEnter: () => {
1222
+ request.onCommit({ restoreTableFocus: true });
1223
+ },
1224
+ onBlur: (event) => {
1225
+ handleEditorBlur(event, skipBlurCommitRef, request);
1226
+ },
1227
+ onKeyDown: (event) => {
1228
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1229
+ return;
1230
+ }
1231
+ handleEditorEscapeKey(event, request);
1232
+ },
1233
+ style: getEditorInputStyle(request)
1234
+ }
1235
+ ) });
1236
+ }
1237
+ function NumberEditor(props) {
1238
+ const { request, style } = props;
1239
+ const [value, setValue] = react.useState(
1240
+ toNumberValue(request.value)
1241
+ );
1242
+ const hostRef = react.useRef(null);
1243
+ const skipBlurCommitRef = react.useRef(false);
1244
+ react.useLayoutEffect(() => {
1245
+ const input = hostRef.current?.querySelector("input");
1246
+ focusAndSelectEditorInput(input);
1247
+ }, [request]);
1248
+ react.useEffect(() => {
1249
+ setValue(toNumberValue(request.value));
1250
+ }, [request.value]);
1251
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: hostRef, style, children: /* @__PURE__ */ jsxRuntime.jsx(
1252
+ reactComponents.ReactNumberInput,
1253
+ {
1254
+ value,
1255
+ min: toNumericProp(request.config.min),
1256
+ max: toNumericProp(request.config.max),
1257
+ step: toNumericProp(request.config.step),
1258
+ onChange: (nextValue) => {
1259
+ setValue(nextValue);
1260
+ request.onChange(nextValue);
1261
+ },
1262
+ onPressEnter: () => {
1263
+ request.onCommit({ restoreTableFocus: true });
1264
+ },
1265
+ onBlur: (event) => {
1266
+ handleEditorBlur(event, skipBlurCommitRef, request);
1267
+ },
1268
+ onKeyDown: (event) => {
1269
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1270
+ return;
1271
+ }
1272
+ handleEditorEscapeKey(event, request);
1273
+ },
1274
+ style: getEditorInputStyle(request)
1275
+ }
1276
+ ) });
1277
+ }
1278
+ function InputRangeEditor(props) {
1279
+ const { request, style } = props;
1280
+ const [value, setValue] = react.useState(
1281
+ toNumberRangeTuple(request.value)
1282
+ );
1283
+ const skipBlurCommitRef = react.useRef(false);
1284
+ react.useEffect(() => {
1285
+ setValue(toNumberRangeTuple(request.value));
1286
+ }, [request.value]);
1287
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-list-table-range-editor": true, style, children: /* @__PURE__ */ jsxRuntime.jsx(
1288
+ reactComponents.ReactInputRange,
1289
+ {
1290
+ value,
1291
+ autoFocus: true,
1292
+ min: toNumericProp(request.config.min),
1293
+ max: toNumericProp(request.config.max),
1294
+ step: toNumericProp(request.config.step),
1295
+ rangeSeparator: request.config.rangeSeparator,
1296
+ onChange: (nextValue) => {
1297
+ setValue(nextValue);
1298
+ request.onChange(nextValue);
1299
+ },
1300
+ onPressEnter: () => {
1301
+ request.onCommit({ restoreTableFocus: true });
1302
+ },
1303
+ onBlur: (event) => {
1304
+ handleEditorBlur(event, skipBlurCommitRef, request);
1305
+ },
1306
+ onKeyDown: (event) => {
1307
+ if (handleRangeInputTab(event)) {
1308
+ return;
1309
+ }
1310
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1311
+ return;
1312
+ }
1313
+ handleEditorEscapeKey(event, request);
1314
+ },
1315
+ style: getEditorInputStyle(request)
1316
+ }
1317
+ ) });
1318
+ }
1319
+ function YearEditor(props) {
1320
+ const { request, style } = props;
1321
+ const [value, setValue] = react.useState(
1322
+ request.value == null ? "" : String(request.value)
1323
+ );
1324
+ const skipBlurCommitRef = react.useRef(false);
1325
+ react.useEffect(() => {
1326
+ setValue(request.value == null ? "" : String(request.value));
1327
+ }, [request.value]);
1328
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1329
+ reactComponents.ReactYearPicker,
1330
+ {
1331
+ value,
1332
+ autoFocus: true,
1333
+ allowClear: false,
1334
+ showArrow: false,
1335
+ onChange: (nextValue) => {
1336
+ setValue(nextValue);
1337
+ request.onChange(nextValue);
1338
+ request.onCommit();
1339
+ },
1340
+ onBlur: (event) => {
1341
+ handleEditorBlur(event, skipBlurCommitRef, request);
1342
+ },
1343
+ onKeyDown: (event) => {
1344
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1345
+ return;
1346
+ }
1347
+ handleEditorEscapeKey(event, request);
1348
+ },
1349
+ style: getEditorInputStyle(request)
1350
+ }
1351
+ ) });
1352
+ }
1353
+ function QuarterEditor(props) {
1354
+ const { request, style } = props;
1355
+ const [value, setValue] = react.useState(
1356
+ request.value == null ? "" : String(request.value)
1357
+ );
1358
+ const skipBlurCommitRef = react.useRef(false);
1359
+ react.useEffect(() => {
1360
+ setValue(request.value == null ? "" : String(request.value));
1361
+ }, [request.value]);
1362
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1363
+ reactComponents.ReactQuarterPicker,
1364
+ {
1365
+ value,
1366
+ autoFocus: true,
1367
+ allowClear: false,
1368
+ showArrow: false,
1369
+ onChange: (nextValue) => {
1370
+ setValue(nextValue);
1371
+ request.onChange(nextValue);
1372
+ request.onCommit();
1373
+ },
1374
+ onBlur: (event) => {
1375
+ handleEditorBlur(event, skipBlurCommitRef, request);
1376
+ },
1377
+ onKeyDown: (event) => {
1378
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1379
+ return;
1380
+ }
1381
+ handleEditorEscapeKey(event, request);
1382
+ },
1383
+ style: getEditorInputStyle(request)
1384
+ }
1385
+ ) });
1386
+ }
1387
+ function MonthEditor(props) {
1388
+ const { request, style } = props;
1389
+ const [value, setValue] = react.useState(
1390
+ request.value == null ? "" : String(request.value)
1391
+ );
1392
+ const skipBlurCommitRef = react.useRef(false);
1393
+ react.useEffect(() => {
1394
+ setValue(request.value == null ? "" : String(request.value));
1395
+ }, [request.value]);
1396
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1397
+ reactComponents.ReactMonthPicker,
1398
+ {
1399
+ value,
1400
+ autoFocus: true,
1401
+ allowClear: false,
1402
+ showArrow: false,
1403
+ onChange: (nextValue) => {
1404
+ setValue(nextValue);
1405
+ request.onChange(nextValue);
1406
+ request.onCommit();
1407
+ },
1408
+ onBlur: (event) => {
1409
+ handleEditorBlur(event, skipBlurCommitRef, request);
1410
+ },
1411
+ onKeyDown: (event) => {
1412
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1413
+ return;
1414
+ }
1415
+ handleEditorEscapeKey(event, request);
1416
+ },
1417
+ style: getEditorInputStyle(request)
1418
+ }
1419
+ ) });
1420
+ }
1421
+ function DateEditor(props) {
1422
+ const { request, style } = props;
1423
+ const [value, setValue] = react.useState(
1424
+ request.value == null ? "" : String(request.value)
1425
+ );
1426
+ const skipBlurCommitRef = react.useRef(false);
1427
+ react.useEffect(() => {
1428
+ setValue(request.value == null ? "" : String(request.value));
1429
+ }, [request.value]);
1430
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1431
+ reactComponents.ReactDatePicker,
1432
+ {
1433
+ value,
1434
+ autoFocus: true,
1435
+ allowClear: false,
1436
+ showArrow: false,
1437
+ onChange: (nextValue) => {
1438
+ setValue(nextValue);
1439
+ request.onChange(nextValue);
1440
+ request.onCommit();
1441
+ },
1442
+ onBlur: (event) => {
1443
+ handleEditorBlur(event, skipBlurCommitRef, request);
1444
+ },
1445
+ onKeyDown: (event) => {
1446
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1447
+ return;
1448
+ }
1449
+ handleEditorEscapeKey(event, request);
1450
+ },
1451
+ style: getEditorInputStyle(request)
1452
+ }
1453
+ ) });
1454
+ }
1455
+ function SelectEditor(props) {
1456
+ const { request, style } = props;
1457
+ const options = request.config.options ?? [];
1458
+ const [value, setValue] = react.useState(
1459
+ request.value == null ? void 0 : String(request.value)
1460
+ );
1461
+ const skipBlurCommitRef = react.useRef(false);
1462
+ react.useEffect(() => {
1463
+ setValue(request.value == null ? void 0 : String(request.value));
1464
+ }, [request.value]);
1465
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1466
+ reactComponents.ReactSelect,
1467
+ {
1468
+ value,
1469
+ autoFocus: true,
1470
+ showArrow: false,
1471
+ showSearch: request.config.showSearch,
1472
+ filterOption: request.config.filterOption,
1473
+ options,
1474
+ onChange: (nextValue, info) => {
1475
+ const resolvedValue = String(nextValue);
1476
+ setValue(resolvedValue);
1477
+ request.onChange(
1478
+ options.find((option) => String(option.value) === resolvedValue)?.value ?? resolvedValue
1479
+ );
1480
+ if (info.trigger === "mouse") {
1481
+ request.onCommit();
1482
+ }
1483
+ },
1484
+ onBlur: (event) => {
1485
+ handleEditorBlur(event, skipBlurCommitRef, request);
1486
+ },
1487
+ onKeyDown: (event) => {
1488
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1489
+ return;
1490
+ }
1491
+ handleEditorEscapeKey(event, request);
1492
+ },
1493
+ style: getEditorInputStyle(request)
1494
+ }
1495
+ ) });
1496
+ }
1497
+ function AutoCompleteEditor(props) {
1498
+ const { request, style } = props;
1499
+ const [value, setValue] = react.useState(
1500
+ request.value == null ? "" : String(request.value)
1501
+ );
1502
+ const [options, setOptions] = react.useState(request.config.options ?? []);
1503
+ const skipBlurCommitRef = react.useRef(false);
1504
+ react.useEffect(() => {
1505
+ setValue(request.value == null ? "" : String(request.value));
1506
+ }, [request.value]);
1507
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1508
+ reactComponents.ReactAutoComplete,
1509
+ {
1510
+ value,
1511
+ autoFocus: true,
1512
+ showArrow: false,
1513
+ options,
1514
+ placeholder: request.config.placeholder ?? "",
1515
+ onChange: (nextValue, info) => {
1516
+ setValue(nextValue);
1517
+ request.onChange(nextValue);
1518
+ if (info.trigger === "mouse") {
1519
+ request.onCommit();
1520
+ }
1521
+ },
1522
+ onPressEnter: async (input) => {
1523
+ const nextOptions = await request.config.onPressEnter?.(input);
1524
+ if (nextOptions) {
1525
+ setOptions(nextOptions);
1526
+ }
1527
+ return nextOptions;
1528
+ },
1529
+ onBlur: () => {
1530
+ if (!skipBlurCommitRef.current) request.onCommit();
1531
+ skipBlurCommitRef.current = false;
1532
+ },
1533
+ onKeyDown: (event) => {
1534
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1535
+ return;
1536
+ }
1537
+ handleEditorEscapeKey(event, request);
1538
+ },
1539
+ style: getEditorInputStyle(request)
1540
+ }
1541
+ ) });
1542
+ }
1543
+ function ColorEditor(props) {
1544
+ const { request, style } = props;
1545
+ const [value, setValue] = react.useState(
1546
+ request.value == null ? "" : String(request.value)
1547
+ );
1548
+ const skipBlurCommitRef = react.useRef(false);
1549
+ react.useEffect(() => {
1550
+ setValue(request.value == null ? "" : String(request.value));
1551
+ }, [request.value]);
1552
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1553
+ reactComponents.ReactColorPicker,
1554
+ {
1555
+ value,
1556
+ autoFocus: true,
1557
+ showArrow: false,
1558
+ onChange: (nextValue) => {
1559
+ setValue(nextValue);
1560
+ request.onChange(nextValue);
1561
+ },
1562
+ onBlur: (event) => {
1563
+ handleEditorBlur(event, skipBlurCommitRef, request);
1564
+ },
1565
+ onKeyDown: (event) => {
1566
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1567
+ return;
1568
+ }
1569
+ handleEditorEscapeKey(event, request);
1570
+ },
1571
+ style: getEditorInputStyle(request)
1572
+ }
1573
+ ) });
1574
+ }
1575
+ function DateRangeEditor(props) {
1576
+ const { request, style } = props;
1577
+ const separator = request.config.rangeSeparator ?? " ~ ";
1578
+ const [value, setValue] = react.useState(
1579
+ toRangeTuple(request.value)
1580
+ );
1581
+ const skipBlurCommitRef = react.useRef(false);
1582
+ react.useEffect(() => {
1583
+ setValue(toRangeTuple(request.value));
1584
+ }, [request.value]);
1585
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-list-table-range-editor": true, style, children: /* @__PURE__ */ jsxRuntime.jsx(
1586
+ reactComponents.ReactDateRangePicker,
1587
+ {
1588
+ value,
1589
+ autoFocus: true,
1590
+ allowClear: false,
1591
+ showArrow: false,
1592
+ rangeSeparator: separator,
1593
+ onChange: (nextValue) => {
1594
+ setValue(nextValue);
1595
+ request.onChange(nextValue);
1596
+ },
1597
+ onBlur: (event) => {
1598
+ handleEditorBlur(event, skipBlurCommitRef, request);
1599
+ },
1600
+ onKeyDown: (event) => {
1601
+ if (handleRangeInputTab(event)) {
1602
+ return;
1603
+ }
1604
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1605
+ return;
1606
+ }
1607
+ handleEditorEscapeKey(event, request);
1608
+ },
1609
+ style: getEditorInputStyle(request)
1610
+ }
1611
+ ) });
1612
+ }
1613
+ function TimeEditor(props) {
1614
+ const { request, style } = props;
1615
+ const [value, setValue] = react.useState(
1616
+ request.value == null ? "" : String(request.value)
1617
+ );
1618
+ const skipBlurCommitRef = react.useRef(false);
1619
+ react.useEffect(() => {
1620
+ setValue(request.value == null ? "" : String(request.value));
1621
+ }, [request.value]);
1622
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1623
+ reactComponents.ReactTimePicker,
1624
+ {
1625
+ value,
1626
+ autoFocus: true,
1627
+ allowClear: false,
1628
+ showArrow: false,
1629
+ onChange: (nextValue) => {
1630
+ setValue(nextValue);
1631
+ request.onChange(nextValue);
1632
+ },
1633
+ onBlur: (event) => {
1634
+ handleEditorBlur(event, skipBlurCommitRef, request);
1635
+ },
1636
+ onKeyDown: (event) => {
1637
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1638
+ return;
1639
+ }
1640
+ handleEditorEscapeKey(event, request);
1641
+ },
1642
+ style: getEditorInputStyle(request)
1643
+ }
1644
+ ) });
1645
+ }
1646
+ function DateTimeEditor(props) {
1647
+ const { request, style } = props;
1648
+ const [value, setValue] = react.useState(
1649
+ request.value == null ? "" : String(request.value)
1650
+ );
1651
+ const skipBlurCommitRef = react.useRef(false);
1652
+ react.useEffect(() => {
1653
+ setValue(request.value == null ? "" : String(request.value));
1654
+ }, [request.value]);
1655
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: /* @__PURE__ */ jsxRuntime.jsx(
1656
+ reactComponents.ReactDateTimePicker,
1657
+ {
1658
+ value,
1659
+ autoFocus: true,
1660
+ allowClear: false,
1661
+ showArrow: false,
1662
+ onChange: (nextValue) => {
1663
+ setValue(nextValue);
1664
+ request.onChange(nextValue);
1665
+ request.onCommit();
1666
+ },
1667
+ onBlur: (event) => {
1668
+ handleEditorBlur(event, skipBlurCommitRef, request);
1669
+ },
1670
+ onKeyDown: (event) => {
1671
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1672
+ return;
1673
+ }
1674
+ handleEditorEscapeKey(event, request);
1675
+ },
1676
+ style: getEditorInputStyle(request)
1677
+ }
1678
+ ) });
1679
+ }
1680
+ function DateTimeRangeEditor(props) {
1681
+ const { request, style } = props;
1682
+ const separator = request.config.rangeSeparator ?? " ~ ";
1683
+ const [value, setValue] = react.useState(
1684
+ toRangeTuple(request.value)
1685
+ );
1686
+ const skipBlurCommitRef = react.useRef(false);
1687
+ react.useEffect(() => {
1688
+ setValue(toRangeTuple(request.value));
1689
+ }, [request.value]);
1690
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-list-table-range-editor": true, style, children: /* @__PURE__ */ jsxRuntime.jsx(
1691
+ reactComponents.ReactDateTimeRangePicker,
1692
+ {
1693
+ value,
1694
+ autoFocus: true,
1695
+ allowClear: false,
1696
+ showArrow: false,
1697
+ rangeSeparator: separator,
1698
+ onChange: (nextValue) => {
1699
+ setValue(nextValue);
1700
+ request.onChange(nextValue);
1701
+ },
1702
+ onBlur: (event) => {
1703
+ handleEditorBlur(event, skipBlurCommitRef, request);
1704
+ },
1705
+ onKeyDown: (event) => {
1706
+ if (handleRangeInputTab(event)) {
1707
+ return;
1708
+ }
1709
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1710
+ return;
1711
+ }
1712
+ handleEditorEscapeKey(event, request);
1713
+ },
1714
+ style: getEditorInputStyle(request)
1715
+ }
1716
+ ) });
1717
+ }
1718
+ function TimeRangeEditor(props) {
1719
+ const { request, style } = props;
1720
+ const separator = request.config.rangeSeparator ?? " ~ ";
1721
+ const [value, setValue] = react.useState(
1722
+ toRangeTuple(request.value)
1723
+ );
1724
+ const skipBlurCommitRef = react.useRef(false);
1725
+ react.useEffect(() => {
1726
+ setValue(toRangeTuple(request.value));
1727
+ }, [request.value]);
1728
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-list-table-range-editor": true, style, children: /* @__PURE__ */ jsxRuntime.jsx(
1729
+ reactComponents.ReactTimeRangePicker,
1730
+ {
1731
+ value,
1732
+ autoFocus: true,
1733
+ showArrow: false,
1734
+ rangeSeparator: separator,
1735
+ onChange: (nextValue) => {
1736
+ setValue(nextValue);
1737
+ request.onChange(nextValue);
1738
+ },
1739
+ onBlur: (event) => {
1740
+ handleEditorBlur(event, skipBlurCommitRef, request);
1741
+ },
1742
+ onKeyDown: (event) => {
1743
+ if (handleRangeInputTab(event)) {
1744
+ return;
1745
+ }
1746
+ if (handleEditorNavigationKey(event, request, skipBlurCommitRef)) {
1747
+ return;
1748
+ }
1749
+ handleEditorEscapeKey(event, request);
1750
+ },
1751
+ style: getEditorInputStyle(request)
1752
+ }
1753
+ ) });
1754
+ }
1755
+ function handleEditorNavigationKey(event, request, skipBlurCommitRef) {
1756
+ const direction = resolveNavigationDirection(event);
1757
+ if (!direction || !request.onNavigate) {
1758
+ return false;
1759
+ }
1760
+ event.preventDefault();
1761
+ skipBlurCommitRef.current = true;
1762
+ request.onNavigate(direction);
1763
+ return true;
1764
+ }
1765
+ function handleRangeInputTab(event) {
1766
+ if (event.key !== "Tab") {
1767
+ return false;
1768
+ }
1769
+ const host = event.currentTarget.closest(
1770
+ "[data-list-table-range-editor]"
1771
+ );
1772
+ const inputs = Array.from(
1773
+ host?.querySelectorAll("input") ?? []
1774
+ );
1775
+ const currentIndex = inputs.indexOf(event.currentTarget);
1776
+ const nextIndex = event.shiftKey ? currentIndex - 1 : currentIndex + 1;
1777
+ const nextInput = inputs[nextIndex];
1778
+ if (!nextInput) {
1779
+ return false;
1780
+ }
1781
+ event.preventDefault();
1782
+ focusAndSelectEditorInput(nextInput);
1783
+ return true;
1784
+ }
1785
+ function focusAndSelectEditorInput(input) {
1786
+ if (!input) {
1787
+ return;
1788
+ }
1789
+ input.focus();
1790
+ try {
1791
+ input.select();
1792
+ } catch {
1793
+ }
1794
+ }
1795
+ function handleEditorEscapeKey(event, request) {
1796
+ if (event.key !== "Escape") {
1797
+ return;
1798
+ }
1799
+ event.preventDefault();
1800
+ request.onCancel();
1801
+ }
1802
+ function toRangeTuple(value) {
1803
+ if (!Array.isArray(value)) {
1804
+ return ["", ""];
1805
+ }
1806
+ return [String(value[0] ?? ""), String(value[1] ?? "")];
1807
+ }
1808
+ function toNumberRangeTuple(value) {
1809
+ if (!Array.isArray(value)) {
1810
+ return [null, null];
1811
+ }
1812
+ return [toNumberValue(value[0]), toNumberValue(value[1])];
1813
+ }
1814
+ function handleEditorBlur(_event, skipBlurCommitRef, request) {
1815
+ if (skipBlurCommitRef.current) {
1816
+ skipBlurCommitRef.current = false;
1817
+ return;
1818
+ }
1819
+ request.onCommit();
1820
+ }
1821
+ function resolveNavigationDirection(event) {
1822
+ if (event.key === "ArrowUp") {
1823
+ return "up";
1824
+ }
1825
+ if (event.key === "ArrowDown") {
1826
+ return "down";
1827
+ }
1828
+ if (event.key === "Tab") {
1829
+ return event.shiftKey ? "prev" : "next";
1830
+ }
1831
+ return null;
1832
+ }
1833
+ function ReactTableFixedPopupView(props) {
1834
+ const { request } = props;
1835
+ if (!request) {
1836
+ return null;
1837
+ }
1838
+ const surfaceStyle = {
1839
+ minWidth: 160,
1840
+ padding: 8
1841
+ };
1842
+ return /* @__PURE__ */ jsxRuntime.jsx(
1843
+ reactComponents.ReactPopup,
1844
+ {
1845
+ open: true,
1846
+ anchorRect: request.anchorRect,
1847
+ offset: 8,
1848
+ minWidth: 160,
1849
+ onOpenChange: (open) => {
1850
+ if (!open) {
1851
+ request.onClose();
1852
+ }
1853
+ },
1854
+ surfaceStyle,
1855
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1856
+ /* @__PURE__ */ jsxRuntime.jsx(
1857
+ PopupAction,
1858
+ {
1859
+ active: request.currentFixed === "left",
1860
+ onClick: () => request.onSelect("left"),
1861
+ children: "\u56FA\u5B9A\u5230\u5DE6\u4FA7"
1862
+ }
1863
+ ),
1864
+ /* @__PURE__ */ jsxRuntime.jsx(
1865
+ PopupAction,
1866
+ {
1867
+ active: request.currentFixed === "right",
1868
+ onClick: () => request.onSelect("right"),
1869
+ children: "\u56FA\u5B9A\u5230\u53F3\u4FA7"
1870
+ }
1871
+ ),
1872
+ /* @__PURE__ */ jsxRuntime.jsx(PopupAction, { onClick: () => request.onSelect("none"), children: "\u53D6\u6D88\u56FA\u5B9A" })
1873
+ ] })
1874
+ }
1875
+ );
1876
+ }
1877
+ function PopupAction(props) {
1878
+ const { active = false, onClick, children } = props;
1879
+ const [hovered, setHovered] = react.useState(false);
1880
+ const backgroundColor = active ? hovered ? "#bae0ff" : "#e6f4ff" : hovered ? "#f5faff" : "transparent";
1881
+ return /* @__PURE__ */ jsxRuntime.jsx(
1882
+ "button",
1883
+ {
1884
+ type: "button",
1885
+ onClick,
1886
+ onMouseEnter: () => {
1887
+ setHovered(true);
1888
+ },
1889
+ onMouseLeave: () => {
1890
+ setHovered(false);
1891
+ },
1892
+ style: {
1893
+ display: "block",
1894
+ width: "100%",
1895
+ height: 32,
1896
+ marginBottom: 4,
1897
+ border: "none",
1898
+ borderRadius: 8,
1899
+ background: backgroundColor,
1900
+ color: active ? "#1677ff" : "#374151",
1901
+ textAlign: "left",
1902
+ padding: "0 10px",
1903
+ cursor: "pointer"
1904
+ },
1905
+ children
1906
+ }
1907
+ );
1908
+ }
1909
+ function ReactTableFilterPanelView(props) {
1910
+ return /* @__PURE__ */ jsxRuntime.jsx(
1911
+ reactComponents.ReactFilterPanel,
1912
+ {
1913
+ request: props.request
1914
+ }
1915
+ );
1916
+ }
1917
+ function ReactTablePaginationView(props) {
1918
+ const { config } = props;
1919
+ if (!config) {
1920
+ return null;
1921
+ }
1922
+ return /* @__PURE__ */ jsxRuntime.jsx(
1923
+ "div",
1924
+ {
1925
+ style: {
1926
+ position: "absolute",
1927
+ right: 0,
1928
+ bottom: 0,
1929
+ display: "flex",
1930
+ justifyContent: "flex-end",
1931
+ paddingTop: 12
1932
+ },
1933
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1934
+ reactComponents.ReactPagination,
1935
+ {
1936
+ current: config.current,
1937
+ total: config.total,
1938
+ pageSize: config.pageSize,
1939
+ pageSizeOptions: config.pageSizeOptions,
1940
+ disabled: config.disabled,
1941
+ showSizeChanger: config.showSizeChanger,
1942
+ showQuickJumper: config.showQuickJumper,
1943
+ showLessItems: config.showLessItems,
1944
+ simple: config.simple,
1945
+ showTotal: config.showTotal,
1946
+ onChange: (page, pageSize) => {
1947
+ config.onChange?.(page, pageSize);
1948
+ },
1949
+ onPageSizeChange: (page, pageSize) => {
1950
+ config.onPageSizeChange?.(page, pageSize);
1951
+ }
1952
+ }
1953
+ )
1954
+ }
1955
+ );
1956
+ }
1957
+ function ReactTableDangerConfirmView(props) {
1958
+ const { request, onClose } = props;
1959
+ const confirmingRef = react.useRef(false);
1960
+ react.useEffect(() => {
1961
+ confirmingRef.current = false;
1962
+ }, [request]);
1963
+ if (!request) {
1964
+ return null;
1965
+ }
1966
+ return /* @__PURE__ */ jsxRuntime.jsx(
1967
+ reactComponents.ReactPopconfirm,
1968
+ {
1969
+ open: true,
1970
+ title: request.title,
1971
+ description: request.description,
1972
+ okText: request.okText,
1973
+ cancelText: request.cancelText,
1974
+ placement: "topLeft",
1975
+ onConfirm: () => {
1976
+ confirmingRef.current = true;
1977
+ try {
1978
+ request.onConfirm();
1979
+ } finally {
1980
+ onClose();
1981
+ }
1982
+ },
1983
+ onOpenChange: (open) => {
1984
+ if (open) {
1985
+ return;
1986
+ }
1987
+ if (confirmingRef.current) {
1988
+ confirmingRef.current = false;
1989
+ return;
1990
+ }
1991
+ request.onCancel();
1992
+ onClose();
1993
+ },
1994
+ style: {
1995
+ position: "fixed",
1996
+ left: request.anchorRect.x,
1997
+ top: request.anchorRect.y,
1998
+ width: Math.max(request.anchorRect.width, 1),
1999
+ height: Math.max(request.anchorRect.height, 1),
2000
+ pointerEvents: "none"
2001
+ },
2002
+ children: /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true" })
2003
+ }
2004
+ );
2005
+ }
2006
+ function ReactTableTooltipView(props) {
2007
+ const { request } = props;
2008
+ if (!request) {
2009
+ return null;
2010
+ }
2011
+ const zoom = typeof request.contentZoom === "number" && Number.isFinite(request.contentZoom) && request.contentZoom > 0 ? request.contentZoom : 1;
2012
+ const fontSize = 12 * zoom;
2013
+ const paddingBlock = 6 * zoom;
2014
+ const paddingInline = 10 * zoom;
2015
+ const borderRadius = 6 * zoom;
2016
+ const maxWidth = 320 * zoom;
2017
+ const style = {
2018
+ position: "fixed",
2019
+ left: request.x,
2020
+ top: request.y,
2021
+ transform: "translate(-50%, 0)",
2022
+ maxWidth,
2023
+ padding: `${paddingBlock}px ${paddingInline}px`,
2024
+ borderRadius,
2025
+ background: request.variant === "error" ? "#ffffff" : "rgba(17, 24, 39, 0.92)",
2026
+ color: request.variant === "error" ? "#ff4d4f" : "#fff",
2027
+ fontSize,
2028
+ lineHeight: 1.5,
2029
+ boxShadow: request.variant === "error" ? "0 10px 30px rgba(255, 77, 79, 0.16)" : "0 10px 30px rgba(15, 23, 42, 0.18)",
2030
+ border: request.variant === "error" ? "1px solid rgba(255, 77, 79, 0.2)" : "none",
2031
+ pointerEvents: "none",
2032
+ zIndex: 1200,
2033
+ whiteSpace: "pre-wrap",
2034
+ wordBreak: "break-word"
2035
+ };
2036
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { style, children: request.content });
2037
+ }
2038
+ function ToolbarIcon(props) {
2039
+ const { path, ...svgProps } = props;
2040
+ return /* @__PURE__ */ jsxRuntime.jsx(
2041
+ "svg",
2042
+ {
2043
+ viewBox: "64 64 896 896",
2044
+ width: "1em",
2045
+ height: "1em",
2046
+ fill: "currentColor",
2047
+ "aria-hidden": "true",
2048
+ focusable: "false",
2049
+ ...svgProps,
2050
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: path })
2051
+ }
2052
+ );
2053
+ }
2054
+ function FullscreenOutlined() {
2055
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolbarIcon, { path: "M290 236.4l43.9-43.9a8.01 8.01 0 00-4.7-13.6L169 160c-5.1-.6-9.5 3.7-8.9 8.9L179 329.1c.8 6.6 8.9 9.4 13.6 4.7l43.7-43.7L370 423.7c3.1 3.1 8.2 3.1 11.3 0l42.4-42.3c3.1-3.1 3.1-8.2 0-11.3L290 236.4zm352.7 187.3c3.1 3.1 8.2 3.1 11.3 0l133.7-133.6 43.7 43.7a8.01 8.01 0 0013.6-4.7L863.9 169c.6-5.1-3.7-9.5-8.9-8.9L694.8 179c-6.6.8-9.4 8.9-4.7 13.6l43.9 43.9L600.3 370a8.03 8.03 0 000 11.3l42.4 42.4zM845 694.9c-.8-6.6-8.9-9.4-13.6-4.7l-43.7 43.7L654 600.3a8.03 8.03 0 00-11.3 0l-42.4 42.3a8.03 8.03 0 000 11.3L734 787.6l-43.9 43.9a8.01 8.01 0 004.7 13.6L855 864c5.1.6 9.5-3.7 8.9-8.9L845 694.9zm-463.7-94.6a8.03 8.03 0 00-11.3 0L236.3 733.9l-43.7-43.7a8.01 8.01 0 00-13.6 4.7L160.1 855c-.6 5.1 3.7 9.5 8.9 8.9L329.2 845c6.6-.8 9.4-8.9 4.7-13.6L290 787.6 423.7 654c3.1-3.1 3.1-8.2 0-11.3l-42.4-42.4z" });
2056
+ }
2057
+ function FullscreenExitOutlined() {
2058
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolbarIcon, { path: "M391 240.9c-.8-6.6-8.9-9.4-13.6-4.7l-43.7 43.7L200 146.3a8.03 8.03 0 00-11.3 0l-42.4 42.3a8.03 8.03 0 000 11.3L280 333.6l-43.9 43.9a8.01 8.01 0 004.7 13.6L401 410c5.1.6 9.5-3.7 8.9-8.9L391 240.9zm10.1 373.2L240.8 633c-6.6.8-9.4 8.9-4.7 13.6l43.9 43.9L146.3 824a8.03 8.03 0 000 11.3l42.4 42.3c3.1 3.1 8.2 3.1 11.3 0L333.7 744l43.7 43.7A8.01 8.01 0 00391 783l18.9-160.1c.6-5.1-3.7-9.4-8.8-8.8zm221.8-204.2L783.2 391c6.6-.8 9.4-8.9 4.7-13.6L744 333.6 877.7 200c3.1-3.1 3.1-8.2 0-11.3l-42.4-42.3a8.03 8.03 0 00-11.3 0L690.3 279.9l-43.7-43.7a8.01 8.01 0 00-13.6 4.7L614.1 401c-.6 5.2 3.7 9.5 8.8 8.9zM744 690.4l43.9-43.9a8.01 8.01 0 00-4.7-13.6L623 614c-5.1-.6-9.5 3.7-8.9 8.9L633 783.1c.8 6.6 8.9 9.4 13.6 4.7l43.7-43.7L824 877.7c3.1 3.1 8.2 3.1 11.3 0l42.4-42.3c3.1-3.1 3.1-8.2 0-11.3L744 690.4z" });
2059
+ }
2060
+ function ReloadOutlined() {
2061
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolbarIcon, { path: "M909.1 209.3l-56.4 44.1C775.8 155.1 656.2 92 521.9 92 290 92 102.3 279.5 102 511.5 101.7 743.7 289.8 932 521.9 932c181.3 0 335.8-115 394.6-276.1 1.5-4.2-.7-8.9-4.9-10.3l-56.7-19.5a8 8 0 00-10.1 4.8c-1.8 5-3.8 10-5.9 14.9-17.3 41-42.1 77.8-73.7 109.4A344.77 344.77 0 01655.9 829c-42.3 17.9-87.4 27-133.8 27-46.5 0-91.5-9.1-133.8-27A341.5 341.5 0 01279 755.2a342.16 342.16 0 01-73.7-109.4c-17.9-42.4-27-87.4-27-133.9s9.1-91.5 27-133.9c17.3-41 42.1-77.8 73.7-109.4 31.6-31.6 68.4-56.4 109.3-73.8 42.3-17.9 87.4-27 133.8-27 46.5 0 91.5 9.1 133.8 27a341.5 341.5 0 01109.3 73.8c9.9 9.9 19.2 20.4 27.8 31.4l-60.2 47a8 8 0 003 14.1l175.6 43c5 1.2 9.9-2.6 9.9-7.7l.8-180.9c-.1-6.6-7.8-10.3-13-6.2z" });
2062
+ }
2063
+ function ExportOutlined() {
2064
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolbarIcon, { path: "M880 912H144c-17.7 0-32-14.3-32-32V144c0-17.7 14.3-32 32-32h360c4.4 0 8 3.6 8 8v56c0 4.4-3.6 8-8 8H184v656h656V520c0-4.4 3.6-8 8-8h56c4.4 0 8 3.6 8 8v360c0 17.7-14.3 32-32 32zM770.87 199.13l-52.2-52.2a8.01 8.01 0 014.7-13.6l179.4-21c5.1-.6 9.5 3.7 8.9 8.9l-21 179.4c-.8 6.6-8.9 9.4-13.6 4.7l-52.4-52.4-256.2 256.2a8.03 8.03 0 01-11.3 0l-42.4-42.4a8.03 8.03 0 010-11.3l256.1-256.3z" });
2065
+ }
2066
+ function ColumnHeightOutlined() {
2067
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolbarIcon, { path: "M840 836H184c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h656c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8zm0-724H184c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h656c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8zM610.8 378c6 0 9.4-7 5.7-11.7L515.7 238.7a7.14 7.14 0 00-11.3 0L403.6 366.3a7.23 7.23 0 005.7 11.7H476v268h-62.8c-6 0-9.4 7-5.7 11.7l100.8 127.5c2.9 3.7 8.5 3.7 11.3 0l100.8-127.5c3.7-4.7.4-11.7-5.7-11.7H548V378h62.8z" });
2068
+ }
2069
+ function SettingOutlined() {
2070
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolbarIcon, { path: "M924.8 625.7l-65.5-56c3.1-19 4.7-38.4 4.7-57.8s-1.6-38.8-4.7-57.8l65.5-56a32.03 32.03 0 009.3-35.2l-.9-2.6a443.74 443.74 0 00-79.7-137.9l-1.8-2.1a32.12 32.12 0 00-35.1-9.5l-81.3 28.9c-30-24.6-63.5-44-99.7-57.6l-15.7-85a32.05 32.05 0 00-25.8-25.7l-2.7-.5c-52.1-9.4-106.9-9.4-159 0l-2.7.5a32.05 32.05 0 00-25.8 25.7l-15.8 85.4a351.86 351.86 0 00-99 57.4l-81.9-29.1a32 32 0 00-35.1 9.5l-1.8 2.1a446.02 446.02 0 00-79.7 137.9l-.9 2.6c-4.5 12.5-.8 26.5 9.3 35.2l66.3 56.6c-3.1 18.8-4.6 38-4.6 57.1 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 00-9.3 35.2l.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1a32.12 32.12 0 0035.1 9.5l81.9-29.1c29.8 24.5 63.1 43.9 99 57.4l15.8 85.4a32.05 32.05 0 0025.8 25.7l2.7.5a449.4 449.4 0 00159 0l2.7-.5a32.05 32.05 0 0025.8-25.7l15.7-85a350 350 0 0099.7-57.6l81.3 28.9a32 32 0 0035.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l.9-2.6c4.5-12.3.8-26.3-9.3-35zM788.3 465.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 01-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97a377.5 377.5 0 01-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9zM512 326c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176zm79.2 255.2A111.6 111.6 0 01512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 01400 502c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 01624 502c0 29.9-11.7 58-32.8 79.2z" });
2071
+ }
2072
+ function HolderOutlined() {
2073
+ return /* @__PURE__ */ jsxRuntime.jsx(ToolbarIcon, { path: "M300 276.5a56 56 0 1056-97 56 56 0 00-56 97zm0 284a56 56 0 1056-97 56 56 0 00-56 97zM640 228a56 56 0 10112 0 56 56 0 00-112 0zm0 284a56 56 0 10112 0 56 56 0 00-112 0zM300 844.5a56 56 0 1056-97 56 56 0 00-56 97zM640 796a56 56 0 10112 0 56 56 0 00-112 0z" });
2074
+ }
2075
+ function SortableList(props) {
2076
+ const { items, onOrderChange } = props;
2077
+ const rootRef = react.useRef(null);
2078
+ const dragRef = react.useRef(null);
2079
+ const [dragState, setDragState] = react.useState(null);
2080
+ react.useEffect(
2081
+ () => () => {
2082
+ document.body.classList.remove("react-list-table-sorting");
2083
+ document.body.style.removeProperty("user-select");
2084
+ },
2085
+ []
2086
+ );
2087
+ react.useEffect(() => {
2088
+ if (!dragState) return;
2089
+ const handleMove = (event) => {
2090
+ const current = dragRef.current;
2091
+ if (!current) return;
2092
+ const target = resolveClosestSortableItem({
2093
+ items,
2094
+ parentKey: current.source.parentKey,
2095
+ layouts: current.layouts,
2096
+ overlayCenterY: event.clientY - current.offsetY + current.height / 2
2097
+ });
2098
+ if (target) {
2099
+ current.target = target;
2100
+ }
2101
+ setDragState({
2102
+ sourceKey: current.source.key,
2103
+ targetKey: current.target.key,
2104
+ pointerY: event.clientY
2105
+ });
2106
+ };
2107
+ const handleEnd = () => {
2108
+ const current = dragRef.current;
2109
+ if (current && current.source.key !== current.target.key) {
2110
+ const siblings = items.filter(
2111
+ (item) => item.parentKey === current.source.parentKey
2112
+ );
2113
+ const orderedKeys = resolveNextSortableOrder(
2114
+ siblings.map((item) => item.key),
2115
+ current.source.key,
2116
+ current.target.key
2117
+ );
2118
+ if (orderedKeys) {
2119
+ onOrderChange(current.source.parentKey, orderedKeys);
2120
+ }
2121
+ }
2122
+ dragRef.current = null;
2123
+ setDragState(null);
2124
+ document.body.classList.remove("react-list-table-sorting");
2125
+ document.body.style.removeProperty("user-select");
2126
+ };
2127
+ window.addEventListener("pointermove", handleMove);
2128
+ window.addEventListener("pointerup", handleEnd, { once: true });
2129
+ window.addEventListener("pointercancel", handleEnd, { once: true });
2130
+ return () => {
2131
+ window.removeEventListener("pointermove", handleMove);
2132
+ window.removeEventListener("pointerup", handleEnd);
2133
+ window.removeEventListener("pointercancel", handleEnd);
2134
+ };
2135
+ }, [dragState != null, items, onOrderChange]);
2136
+ const sourceIndex = dragState ? items.findIndex((item) => item.key === dragState.sourceKey) : -1;
2137
+ const targetIndex = dragState ? items.findIndex((item) => item.key === dragState.targetKey) : -1;
2138
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, children: [
2139
+ items.map((item, index) => {
2140
+ const style = resolveSortableTransform(
2141
+ index,
2142
+ sourceIndex,
2143
+ targetIndex,
2144
+ dragRef.current?.height ?? 0
2145
+ );
2146
+ return /* @__PURE__ */ jsxRuntime.jsx(
2147
+ "div",
2148
+ {
2149
+ "data-sortable-key": item.key,
2150
+ className: dragState?.sourceKey === item.key ? "dragging" : "",
2151
+ style,
2152
+ children: props.renderItem(item, {
2153
+ onPointerDown: (event) => {
2154
+ if (event.button !== 0) return;
2155
+ const row = event.currentTarget.closest(
2156
+ "[data-sortable-key]"
2157
+ );
2158
+ if (!row) return;
2159
+ const rect = row.getBoundingClientRect();
2160
+ dragRef.current = {
2161
+ source: item,
2162
+ target: item,
2163
+ layouts: collectSortableItemLayouts(rootRef.current),
2164
+ offsetY: event.clientY - rect.top,
2165
+ width: rect.width,
2166
+ left: rect.left,
2167
+ height: rect.height
2168
+ };
2169
+ setDragState({
2170
+ sourceKey: item.key,
2171
+ targetKey: item.key,
2172
+ pointerY: event.clientY
2173
+ });
2174
+ document.body.classList.add("react-list-table-sorting");
2175
+ document.body.style.userSelect = "none";
2176
+ event.preventDefault();
2177
+ }
2178
+ })
2179
+ },
2180
+ item.key
2181
+ );
2182
+ }),
2183
+ dragState && dragRef.current ? reactDom.createPortal(
2184
+ /* @__PURE__ */ jsxRuntime.jsx(
2185
+ "div",
2186
+ {
2187
+ className: "react-list-table-sort-overlay",
2188
+ style: {
2189
+ left: dragRef.current.left,
2190
+ top: dragState.pointerY - dragRef.current.offsetY,
2191
+ width: dragRef.current.width,
2192
+ height: dragRef.current.height
2193
+ },
2194
+ children: props.renderItem(dragRef.current.source, {
2195
+ onPointerDown: (event) => event.preventDefault()
2196
+ })
2197
+ }
2198
+ ),
2199
+ document.body
2200
+ ) : null
2201
+ ] });
2202
+ }
2203
+ function resolveNextSortableOrder(currentKeys, sourceKey, targetKey) {
2204
+ const sourceIndex = currentKeys.indexOf(sourceKey);
2205
+ const targetIndex = currentKeys.indexOf(targetKey);
2206
+ if (sourceIndex < 0 || targetIndex < 0 || sourceIndex === targetIndex) {
2207
+ return null;
2208
+ }
2209
+ const nextKeys = [...currentKeys];
2210
+ const [source] = nextKeys.splice(sourceIndex, 1);
2211
+ nextKeys.splice(targetIndex, 0, source);
2212
+ return nextKeys;
2213
+ }
2214
+ function collectSortableItemLayouts(root) {
2215
+ if (!root) return [];
2216
+ return Array.from(
2217
+ root.querySelectorAll("[data-sortable-key]")
2218
+ ).map((element) => {
2219
+ const rect = element.getBoundingClientRect();
2220
+ return {
2221
+ key: element.dataset.sortableKey ?? "",
2222
+ centerY: rect.top + rect.height / 2
2223
+ };
2224
+ });
2225
+ }
2226
+ function resolveClosestSortableItem(params) {
2227
+ let closestItem = null;
2228
+ let closestDistance = Number.POSITIVE_INFINITY;
2229
+ params.layouts.forEach((layout) => {
2230
+ const item = params.items.find((candidate) => candidate.key === layout.key);
2231
+ if (!item || item.parentKey !== params.parentKey) return;
2232
+ const distance = Math.abs(params.overlayCenterY - layout.centerY);
2233
+ if (distance < closestDistance) {
2234
+ closestDistance = distance;
2235
+ closestItem = item;
2236
+ }
2237
+ });
2238
+ return closestItem;
2239
+ }
2240
+ function resolveSortableTransform(index, sourceIndex, targetIndex, height) {
2241
+ let translateY = 0;
2242
+ if (sourceIndex < targetIndex && index > sourceIndex && index <= targetIndex) {
2243
+ translateY = -height;
2244
+ } else if (sourceIndex > targetIndex && index >= targetIndex && index < sourceIndex) {
2245
+ translateY = height;
2246
+ }
2247
+ return {
2248
+ transform: translateY ? `translate3d(0, ${translateY}px, 0)` : void 0,
2249
+ transition: sourceIndex >= 0 ? "transform 180ms ease" : void 0
2250
+ };
2251
+ }
2252
+
2253
+ // src/features/toolbar/style.css
2254
+ styleInject('.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-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, .14);\n}\n.react-list-table-tool-menu button {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n padding: 6px 10px;\n border: 0;\n border-radius: 4px;\n background: transparent;\n text-align: left;\n cursor: pointer;\n}\n.react-list-table-tool-menu button.active::after {\n content: "\\2713";\n margin-left: 12px;\n font-size: 12px;\n}\n.react-list-table-tool-menu button:hover,\n.react-list-table-tool-menu button.active {\n color: #1677ff;\n background: #e6f4ff;\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 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: 12px;\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');
2255
+ function ReactTableToolbar(props) {
2256
+ const { toolbar, title } = props;
2257
+ const [densityOpen, setDensityOpen] = react.useState(false);
2258
+ const [settingOpen, setSettingOpen] = react.useState(false);
2259
+ const [isFullscreen, setIsFullscreen] = react.useState(false);
2260
+ const rootRef = react.useRef(null);
2261
+ const hasToolbar = toolbar !== void 0 && toolbar !== false;
2262
+ react.useEffect(() => {
2263
+ const close = (event) => {
2264
+ if (event.target?.closest(".canvas-react-popup")) {
2265
+ return;
2266
+ }
2267
+ if (!rootRef.current?.contains(event.target)) {
2268
+ setDensityOpen(false);
2269
+ setSettingOpen(false);
2270
+ }
2271
+ };
2272
+ document.addEventListener("mousedown", close);
2273
+ return () => document.removeEventListener("mousedown", close);
2274
+ }, []);
2275
+ react.useEffect(() => {
2276
+ const handleFullscreenChange = () => {
2277
+ const fullscreenNode = (typeof toolbar === "object" ? toolbar.getFullscreenNode?.() : null) ?? props.hostRef.current;
2278
+ setIsFullscreen(document.fullscreenElement === fullscreenNode);
2279
+ };
2280
+ document.addEventListener("fullscreenchange", handleFullscreenChange);
2281
+ return () => document.removeEventListener("fullscreenchange", handleFullscreenChange);
2282
+ }, [props.hostRef, toolbar]);
2283
+ if (!title && !hasToolbar) return null;
2284
+ const config = typeof toolbar === "object" ? toolbar : {};
2285
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-titlebar", ref: rootRef, children: [
2286
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "react-list-table-title", children: title }),
2287
+ hasToolbar ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-tools", children: [
2288
+ config.extra,
2289
+ config.showFullscreen !== false ? /* @__PURE__ */ jsxRuntime.jsx(
2290
+ ToolButton,
2291
+ {
2292
+ label: isFullscreen ? "\u9000\u51FA\u5168\u5C4F" : "\u5168\u5C4F",
2293
+ onClick: () => {
2294
+ if (isFullscreen) {
2295
+ void document.exitFullscreen?.();
2296
+ } else {
2297
+ const fullscreenNode = config.getFullscreenNode?.() ?? props.hostRef.current;
2298
+ void fullscreenNode?.requestFullscreen?.();
2299
+ }
2300
+ },
2301
+ children: isFullscreen ? /* @__PURE__ */ jsxRuntime.jsx(FullscreenExitOutlined, {}) : /* @__PURE__ */ jsxRuntime.jsx(FullscreenOutlined, {})
2302
+ }
2303
+ ) : null,
2304
+ config.showRefresh !== false ? /* @__PURE__ */ jsxRuntime.jsx(ToolButton, { label: "\u5237\u65B0", iconSize: 14, onClick: () => config.onRefresh?.(), children: /* @__PURE__ */ jsxRuntime.jsx(ReloadOutlined, {}) }) : null,
2305
+ config.showExport ? /* @__PURE__ */ jsxRuntime.jsx(
2306
+ ToolButton,
2307
+ {
2308
+ label: "\u5BFC\u51FA",
2309
+ iconSize: 14,
2310
+ onClick: () => {
2311
+ if (config.onExport) {
2312
+ config.onExport();
2313
+ } else {
2314
+ props.onExport();
2315
+ }
2316
+ },
2317
+ children: /* @__PURE__ */ jsxRuntime.jsx(ExportOutlined, {})
2318
+ }
2319
+ ) : null,
2320
+ config.showDensity !== false ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-tool-wrap", children: [
2321
+ /* @__PURE__ */ jsxRuntime.jsx(ToolButton, { label: "\u8868\u683C\u5BC6\u5EA6", onClick: () => setDensityOpen((v) => !v), children: /* @__PURE__ */ jsxRuntime.jsx(ColumnHeightOutlined, {}) }),
2322
+ densityOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "react-list-table-tool-menu", children: [48, 40, 32].map((height) => /* @__PURE__ */ jsxRuntime.jsx(
2323
+ "button",
2324
+ {
2325
+ type: "button",
2326
+ className: props.density === height ? "active" : "",
2327
+ onClick: () => {
2328
+ props.onDensityChange(height);
2329
+ setDensityOpen(false);
2330
+ },
2331
+ children: height === 48 ? "\u5BBD\u677E" : height === 40 ? "\u4E2D\u7B49" : "\u7D27\u51D1"
2332
+ },
2333
+ height
2334
+ )) }) : null
2335
+ ] }) : null,
2336
+ config.showColumnSetting !== false ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-tool-wrap", children: [
2337
+ /* @__PURE__ */ jsxRuntime.jsx(ToolButton, { label: "\u5217\u8BBE\u7F6E", onClick: () => setSettingOpen((v) => !v), children: /* @__PURE__ */ jsxRuntime.jsx(SettingOutlined, {}) }),
2338
+ settingOpen ? /* @__PURE__ */ jsxRuntime.jsxs(
2339
+ "div",
2340
+ {
2341
+ className: "react-list-table-column-setting",
2342
+ style: { width: config.columnSettingWidth },
2343
+ children: [
2344
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-column-setting-head", children: [
2345
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "\u5217\u8BBE\u7F6E" }),
2346
+ /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: props.onResetColumns, children: "\u91CD\u7F6E" })
2347
+ ] }),
2348
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "react-list-table-column-setting-body", children: /* @__PURE__ */ jsxRuntime.jsx(
2349
+ SortableList,
2350
+ {
2351
+ items: flattenColumns(props.columns),
2352
+ onOrderChange: props.onColumnOrderChange,
2353
+ renderItem: (column, handleProps) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-column-item", children: [
2354
+ /* @__PURE__ */ jsxRuntime.jsxs(
2355
+ "span",
2356
+ {
2357
+ className: "react-list-table-column-main",
2358
+ style: { paddingLeft: column.level * 16 },
2359
+ children: [
2360
+ /* @__PURE__ */ jsxRuntime.jsx(
2361
+ "span",
2362
+ {
2363
+ className: "react-list-table-column-drag",
2364
+ ...handleProps,
2365
+ onClick: (event) => {
2366
+ event.preventDefault();
2367
+ event.stopPropagation();
2368
+ },
2369
+ children: /* @__PURE__ */ jsxRuntime.jsx(HolderOutlined, {})
2370
+ }
2371
+ ),
2372
+ /* @__PURE__ */ jsxRuntime.jsx(
2373
+ "input",
2374
+ {
2375
+ type: "checkbox",
2376
+ checked: !column.hidden,
2377
+ onChange: (event) => props.onColumnVisibilityChange(
2378
+ column.key,
2379
+ event.target.checked
2380
+ )
2381
+ }
2382
+ ),
2383
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "react-list-table-column-label", children: column.label })
2384
+ ]
2385
+ }
2386
+ ),
2387
+ !column.isGroup ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "react-list-table-column-actions", children: [
2388
+ /* @__PURE__ */ jsxRuntime.jsx(
2389
+ reactComponents.ReactNumberInput,
2390
+ {
2391
+ className: "react-list-table-column-width-input",
2392
+ min: column.minWidth,
2393
+ max: column.maxWidth,
2394
+ value: column.width,
2395
+ allowClear: false,
2396
+ "aria-label": `${column.label}\u5217\u5BBD`,
2397
+ style: { width: 80, height: 24 },
2398
+ onChange: (width) => {
2399
+ if (width != null && Number.isFinite(width) && width > 0 && (column.minWidth == null || width >= column.minWidth) && (column.maxWidth == null || width <= column.maxWidth)) {
2400
+ props.onColumnWidthChange(column.key, width);
2401
+ }
2402
+ }
2403
+ }
2404
+ ),
2405
+ /* @__PURE__ */ jsxRuntime.jsx(
2406
+ reactComponents.ReactSelect,
2407
+ {
2408
+ className: "react-list-table-column-fixed-input",
2409
+ value: column.fixed ?? "none",
2410
+ options: [
2411
+ { label: "\u4E0D\u56FA\u5B9A", value: "none" },
2412
+ { label: "\u56FA\u5B9A\u5DE6\u4FA7", value: "left" },
2413
+ { label: "\u56FA\u5B9A\u53F3\u4FA7", value: "right" }
2414
+ ],
2415
+ allowClear: false,
2416
+ showSearch: false,
2417
+ style: { width: "100%", height: 24 },
2418
+ "aria-label": `${column.label}\u56FA\u5B9A\u65B9\u5411`,
2419
+ onChange: (value) => {
2420
+ props.onColumnFixedChange(
2421
+ column.key,
2422
+ value === "left" || value === "right" ? value : void 0
2423
+ );
2424
+ }
2425
+ }
2426
+ )
2427
+ ] }) : null
2428
+ ] })
2429
+ }
2430
+ ) })
2431
+ ]
2432
+ }
2433
+ ) : null
2434
+ ] }) : null
2435
+ ] }) : null
2436
+ ] });
2437
+ }
2438
+ function ToolButton(props) {
2439
+ return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "react-list-table-tool", style: { fontSize: props.iconSize ?? 16 }, title: props.label, "aria-label": props.label, onClick: props.onClick, children: props.children });
2440
+ }
2441
+ function flattenColumns(columns, parentKey = "root", level = 0) {
2442
+ return columns.flatMap((column) => {
2443
+ const key = String(column.key ?? column.dataIndex);
2444
+ const label = typeof column.title === "string" ? column.title : key;
2445
+ const current = {
2446
+ key,
2447
+ label,
2448
+ hidden: column.hidden === true,
2449
+ parentKey,
2450
+ width: Number(column.width) || 160,
2451
+ minWidth: typeof column.minWidth === "number" ? column.minWidth : void 0,
2452
+ maxWidth: typeof column.maxWidth === "number" ? column.maxWidth : void 0,
2453
+ fixed: column.fixed,
2454
+ level,
2455
+ isGroup: Boolean(column.children?.length)
2456
+ };
2457
+ return column.children?.length ? [current, ...flattenColumns(column.children, key, level + 1)] : [current];
2458
+ });
2459
+ }
2460
+ function useReactListTableState(options) {
2461
+ const containerRef = react.useRef(null);
2462
+ const tableRef = react.useRef(null);
2463
+ const [editorRequest, setEditorRequest] = react.useState(null);
2464
+ const [paginationConfig, setPaginationConfig] = react.useState(null);
2465
+ const [tooltipRequest, setTooltipRequest] = react.useState(null);
2466
+ const [loadingRequest, setLoadingRequest] = react.useState(null);
2467
+ const [filterPanelRequest, setFilterPanelRequest] = react.useState(null);
2468
+ const [fixedPopupRequest, setFixedPopupRequest] = react.useState(null);
2469
+ const [headerContextMenuRequest, setHeaderContextMenuRequest] = react.useState(null);
2470
+ const [imagePreviewRequest, setImagePreviewRequest] = react.useState(null);
2471
+ const [dangerConfirmRequest, setDangerConfirmRequest] = react.useState(null);
2472
+ const uiOptions = react.useMemo(
2473
+ () => ({
2474
+ ...options.ui,
2475
+ onEditorRequest: (request) => {
2476
+ setEditorRequest(request);
2477
+ options.ui?.onEditorRequest?.(request);
2478
+ },
2479
+ onPaginationRender: (config) => {
2480
+ setPaginationConfig(config);
2481
+ options.ui?.onPaginationRender?.(config);
2482
+ },
2483
+ onTooltipRequest: (request) => {
2484
+ setTooltipRequest(request);
2485
+ options.ui?.onTooltipRequest?.(request);
2486
+ },
2487
+ onLoadingRequest: (request) => {
2488
+ setLoadingRequest(request);
2489
+ options.ui?.onLoadingRequest?.(request);
2490
+ },
2491
+ onFilterPanelRequest: (request) => {
2492
+ setFilterPanelRequest(request);
2493
+ options.ui?.onFilterPanelRequest?.(request);
2494
+ },
2495
+ onFixedPopupRequest: (request) => {
2496
+ setFixedPopupRequest(request);
2497
+ options.ui?.onFixedPopupRequest?.(request);
2498
+ },
2499
+ onHeaderContextMenuRequest: (request) => {
2500
+ setHeaderContextMenuRequest(request);
2501
+ options.ui?.onHeaderContextMenuRequest?.(request);
2502
+ },
2503
+ onImagePreviewRequest: (request) => {
2504
+ setImagePreviewRequest(request);
2505
+ options.ui?.onImagePreviewRequest?.(request);
2506
+ },
2507
+ onDangerConfirmRequest: (request) => {
2508
+ setDangerConfirmRequest(request);
2509
+ options.ui?.onDangerConfirmRequest?.(request);
2510
+ }
2511
+ }),
2512
+ [options.ui]
2513
+ );
2514
+ react.useEffect(() => {
2515
+ const container = containerRef.current;
2516
+ if (!container) {
2517
+ return;
2518
+ }
2519
+ const table = new listTable.ListTable(container, {
2520
+ ...options,
2521
+ ui: uiOptions
2522
+ });
2523
+ table.mount();
2524
+ tableRef.current = table;
2525
+ return () => {
2526
+ table.destroy();
2527
+ tableRef.current = null;
2528
+ setEditorRequest(null);
2529
+ setPaginationConfig(null);
2530
+ setTooltipRequest(null);
2531
+ setLoadingRequest(null);
2532
+ setFilterPanelRequest(null);
2533
+ setFixedPopupRequest(null);
2534
+ setHeaderContextMenuRequest(null);
2535
+ setImagePreviewRequest(null);
2536
+ setDangerConfirmRequest(null);
2537
+ };
2538
+ }, []);
2539
+ react.useEffect(() => {
2540
+ tableRef.current?.updateOptions({
2541
+ ...options,
2542
+ ui: uiOptions
2543
+ });
2544
+ }, [options, uiOptions]);
2545
+ return {
2546
+ containerRef,
2547
+ tableRef,
2548
+ editorRequest,
2549
+ paginationConfig,
2550
+ tooltipRequest,
2551
+ loadingRequest,
2552
+ filterPanelRequest,
2553
+ fixedPopupRequest,
2554
+ headerContextMenuRequest,
2555
+ imagePreviewRequest,
2556
+ dangerConfirmRequest,
2557
+ closeDangerConfirmRequest: () => {
2558
+ setDangerConfirmRequest(null);
2559
+ options.ui?.onDangerConfirmRequest?.(null);
2560
+ }
2561
+ };
2562
+ }
2563
+
2564
+ // src/components/build-list-table-options.ts
2565
+ function buildListTableOptions(props) {
2566
+ const {
2567
+ width,
2568
+ height,
2569
+ emptyText,
2570
+ scroll,
2571
+ locale,
2572
+ onChange,
2573
+ query,
2574
+ ...restProps
2575
+ } = props;
2576
+ return {
2577
+ type: "list",
2578
+ ...restProps,
2579
+ width: scroll?.x === true ? "100%" : scroll?.x ?? width,
2580
+ height: scroll?.y ?? height,
2581
+ emptyText: locale?.emptyText ?? emptyText,
2582
+ query: onChange ? {
2583
+ ...query,
2584
+ onChange
2585
+ } : query
2586
+ };
2587
+ }
2588
+ function ReactListTableInner(props, ref) {
2589
+ const {
2590
+ className,
2591
+ style,
2592
+ width,
2593
+ height,
2594
+ emptyText,
2595
+ scroll,
2596
+ locale,
2597
+ onChange,
2598
+ rowKey,
2599
+ columns,
2600
+ dataSource,
2601
+ theme,
2602
+ striped,
2603
+ highlightMode,
2604
+ contextMenu,
2605
+ rowHeight,
2606
+ headerRowHeight,
2607
+ summaryRowHeight,
2608
+ overscanRowCount,
2609
+ query,
2610
+ rowSelection,
2611
+ expandable,
2612
+ pagination,
2613
+ scrollbar,
2614
+ carouselScroll,
2615
+ stretchColumns,
2616
+ resizable,
2617
+ storageKey,
2618
+ draggable,
2619
+ tableId,
2620
+ rowDrag,
2621
+ debug,
2622
+ title,
2623
+ toolbar
2624
+ } = props;
2625
+ const shellRef = react.useRef(null);
2626
+ const [densityOverride, setDensityOverride] = react.useState(
2627
+ null
2628
+ );
2629
+ const [columnVisibility, setColumnVisibility] = react.useState(() => /* @__PURE__ */ new Map());
2630
+ const [columnOrders, setColumnOrders] = react.useState(
2631
+ () => /* @__PURE__ */ new Map()
2632
+ );
2633
+ const [columnConfig, setColumnConfig] = react.useState(() => /* @__PURE__ */ new Map());
2634
+ const resolvedColumns = react.useMemo(
2635
+ () => applyColumnManagerState(
2636
+ columns,
2637
+ columnVisibility,
2638
+ columnOrders,
2639
+ columnConfig
2640
+ ),
2641
+ [columns, columnVisibility, columnOrders, columnConfig]
2642
+ );
2643
+ const resolvedRowHeight = densityOverride ?? rowHeight;
2644
+ const options = react.useMemo(
2645
+ () => buildListTableOptions({
2646
+ width,
2647
+ height,
2648
+ emptyText,
2649
+ scroll,
2650
+ locale,
2651
+ onChange,
2652
+ rowKey,
2653
+ columns: resolvedColumns,
2654
+ dataSource,
2655
+ theme,
2656
+ striped,
2657
+ highlightMode,
2658
+ contextMenu,
2659
+ rowHeight: resolvedRowHeight,
2660
+ headerRowHeight,
2661
+ summaryRowHeight,
2662
+ overscanRowCount,
2663
+ query,
2664
+ rowSelection,
2665
+ expandable,
2666
+ pagination,
2667
+ scrollbar,
2668
+ carouselScroll,
2669
+ stretchColumns,
2670
+ resizable,
2671
+ storageKey,
2672
+ draggable,
2673
+ tableId,
2674
+ rowDrag,
2675
+ debug
2676
+ }),
2677
+ [
2678
+ width,
2679
+ height,
2680
+ emptyText,
2681
+ scroll,
2682
+ locale,
2683
+ onChange,
2684
+ rowKey,
2685
+ resolvedColumns,
2686
+ dataSource,
2687
+ theme,
2688
+ striped,
2689
+ highlightMode,
2690
+ contextMenu,
2691
+ resolvedRowHeight,
2692
+ headerRowHeight,
2693
+ summaryRowHeight,
2694
+ overscanRowCount,
2695
+ query,
2696
+ rowSelection,
2697
+ expandable,
2698
+ pagination,
2699
+ scrollbar,
2700
+ carouselScroll,
2701
+ stretchColumns,
2702
+ resizable,
2703
+ storageKey,
2704
+ draggable,
2705
+ tableId,
2706
+ rowDrag,
2707
+ debug
2708
+ ]
2709
+ );
2710
+ const {
2711
+ containerRef,
2712
+ tableRef,
2713
+ editorRequest,
2714
+ paginationConfig,
2715
+ tooltipRequest,
2716
+ loadingRequest,
2717
+ filterPanelRequest,
2718
+ fixedPopupRequest,
2719
+ headerContextMenuRequest,
2720
+ imagePreviewRequest,
2721
+ dangerConfirmRequest,
2722
+ closeDangerConfirmRequest
2723
+ } = useReactListTableState(options);
2724
+ const hasPagination = paginationConfig != null;
2725
+ react.useImperativeHandle(
2726
+ ref,
2727
+ () => ({
2728
+ validate: () => tableRef.current?.validate() ?? Promise.resolve([]),
2729
+ exportXlsx: () => {
2730
+ tableRef.current?.exportXlsx();
2731
+ },
2732
+ scrollTo: (options2) => {
2733
+ tableRef.current?.scrollTo(options2);
2734
+ },
2735
+ getDebugSnapshot: () => tableRef.current?.getDebugSnapshot() ?? null,
2736
+ resetSorter: () => {
2737
+ tableRef.current?.resetSorter();
2738
+ },
2739
+ resetFilter: () => {
2740
+ tableRef.current?.resetFilter();
2741
+ }
2742
+ }),
2743
+ []
2744
+ );
2745
+ return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2746
+ /* @__PURE__ */ jsxRuntime.jsxs(
2747
+ "div",
2748
+ {
2749
+ ref: shellRef,
2750
+ className,
2751
+ style: {
2752
+ position: "relative",
2753
+ display: "flex",
2754
+ flexDirection: "column",
2755
+ paddingBottom: hasPagination ? 44 : void 0,
2756
+ ...style
2757
+ },
2758
+ children: [
2759
+ /* @__PURE__ */ jsxRuntime.jsx(
2760
+ ReactTableToolbar,
2761
+ {
2762
+ title,
2763
+ toolbar,
2764
+ columns: resolvedColumns,
2765
+ density: resolvedRowHeight === "auto" ? 40 : resolvedRowHeight ?? 40,
2766
+ hostRef: shellRef,
2767
+ onExport: () => tableRef.current?.exportXlsx(),
2768
+ onDensityChange: setDensityOverride,
2769
+ onColumnVisibilityChange: (columnKey, visible) => {
2770
+ setColumnVisibility((current) => {
2771
+ const next = new Map(current);
2772
+ next.set(columnKey, visible);
2773
+ return next;
2774
+ });
2775
+ },
2776
+ onColumnOrderChange: (parentKey, orderedKeys) => {
2777
+ setColumnOrders((current) => {
2778
+ const next = new Map(current);
2779
+ next.set(parentKey, orderedKeys);
2780
+ return next;
2781
+ });
2782
+ },
2783
+ onColumnWidthChange: (columnKey, width2) => {
2784
+ setColumnConfig((current) => {
2785
+ const next = new Map(current);
2786
+ next.set(columnKey, {
2787
+ ...next.get(columnKey),
2788
+ width: width2
2789
+ });
2790
+ return next;
2791
+ });
2792
+ },
2793
+ onColumnFixedChange: (columnKey, fixed) => {
2794
+ setColumnConfig((current) => {
2795
+ const next = new Map(current);
2796
+ next.set(columnKey, {
2797
+ ...next.get(columnKey),
2798
+ fixed: fixed ?? null
2799
+ });
2800
+ return next;
2801
+ });
2802
+ },
2803
+ onResetColumns: () => {
2804
+ setColumnVisibility(/* @__PURE__ */ new Map());
2805
+ setColumnOrders(/* @__PURE__ */ new Map());
2806
+ setColumnConfig(/* @__PURE__ */ new Map());
2807
+ }
2808
+ }
2809
+ ),
2810
+ /* @__PURE__ */ jsxRuntime.jsx(
2811
+ "div",
2812
+ {
2813
+ ref: containerRef,
2814
+ style: { flex: 1, minWidth: 0, width: "100%", minHeight: 0 },
2815
+ children: /* @__PURE__ */ jsxRuntime.jsx(ReactTablePaginationView, { config: paginationConfig })
2816
+ }
2817
+ ),
2818
+ loadingRequest ? /* @__PURE__ */ jsxRuntime.jsx(
2819
+ "div",
2820
+ {
2821
+ style: {
2822
+ position: "absolute",
2823
+ inset: 0,
2824
+ display: "flex",
2825
+ alignItems: "center",
2826
+ justifyContent: "center",
2827
+ background: "rgba(255, 255, 255, 0.68)",
2828
+ color: "#475569",
2829
+ fontSize: 14,
2830
+ pointerEvents: "auto",
2831
+ cursor: "progress"
2832
+ },
2833
+ children: loadingRequest.text ?? "\u5904\u7406\u4E2D\u2026"
2834
+ }
2835
+ ) : null
2836
+ ]
2837
+ }
2838
+ ),
2839
+ tooltipRequest ? reactDom.createPortal(
2840
+ /* @__PURE__ */ jsxRuntime.jsx(ReactTableTooltipView, { request: tooltipRequest }),
2841
+ document.body
2842
+ ) : null,
2843
+ filterPanelRequest ? reactDom.createPortal(
2844
+ /* @__PURE__ */ jsxRuntime.jsx(ReactTableFilterPanelView, { request: filterPanelRequest }),
2845
+ document.body
2846
+ ) : null,
2847
+ fixedPopupRequest ? reactDom.createPortal(
2848
+ /* @__PURE__ */ jsxRuntime.jsx(ReactTableFixedPopupView, { request: fixedPopupRequest }),
2849
+ document.body
2850
+ ) : null,
2851
+ headerContextMenuRequest ? reactDom.createPortal(
2852
+ /* @__PURE__ */ jsxRuntime.jsx(ReactTableContextMenuView, { request: headerContextMenuRequest }),
2853
+ document.body
2854
+ ) : null,
2855
+ dangerConfirmRequest ? reactDom.createPortal(
2856
+ /* @__PURE__ */ jsxRuntime.jsx(
2857
+ ReactTableDangerConfirmView,
2858
+ {
2859
+ request: dangerConfirmRequest,
2860
+ onClose: closeDangerConfirmRequest
2861
+ }
2862
+ ),
2863
+ document.body
2864
+ ) : null,
2865
+ editorRequest ? reactDom.createPortal(
2866
+ /* @__PURE__ */ jsxRuntime.jsx(ReactTableEditorOverlay, { request: editorRequest }),
2867
+ editorRequest.hostElement ?? document.body
2868
+ ) : null,
2869
+ imagePreviewRequest ? reactDom.createPortal(
2870
+ /* @__PURE__ */ jsxRuntime.jsx(
2871
+ reactComponents.ReactImagePreview,
2872
+ {
2873
+ open: true,
2874
+ src: imagePreviewRequest.src,
2875
+ alt: imagePreviewRequest.alt,
2876
+ onClose: imagePreviewRequest.onClose
2877
+ }
2878
+ ),
2879
+ document.body
2880
+ ) : null
2881
+ ] });
2882
+ }
2883
+ function applyColumnManagerState(columns, visibility, orders, config, parentKey = "root") {
2884
+ const order = orders.get(parentKey);
2885
+ const sortedColumns = order ? [...columns].sort(
2886
+ (left, right) => order.indexOf(resolveColumnKey(left)) - order.indexOf(resolveColumnKey(right))
2887
+ ) : columns;
2888
+ return sortedColumns.map((column) => {
2889
+ const key = resolveColumnKey(column);
2890
+ const managedConfig = config.get(key);
2891
+ return {
2892
+ ...column,
2893
+ hidden: visibility.has(key) ? visibility.get(key) === false : column.hidden,
2894
+ width: managedConfig?.width ?? column.width,
2895
+ minWidth: column.minWidth,
2896
+ maxWidth: column.maxWidth,
2897
+ fixed: managedConfig?.fixed === null ? void 0 : managedConfig?.fixed ?? column.fixed,
2898
+ children: column.children ? applyColumnManagerState(
2899
+ column.children,
2900
+ visibility,
2901
+ orders,
2902
+ config,
2903
+ key
2904
+ ) : void 0
2905
+ };
2906
+ });
2907
+ }
2908
+ function resolveColumnKey(column) {
2909
+ return String(column.key ?? column.dataIndex);
2910
+ }
2911
+ var ReactListTable = react.forwardRef(ReactListTableInner);
2912
+
2913
+ exports.ReactListTable = ReactListTable;
2914
+ //# sourceMappingURL=index.cjs.map
2915
+ //# sourceMappingURL=index.cjs.map