@canvas-components/react-list-table 0.3.25 → 0.3.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -5,6 +5,7 @@ var reactDom = require('react-dom');
5
5
  var reactComponents = require('@canvas-components/react-components');
6
6
  var listTable = require('@canvas-components/list-table');
7
7
  var jsxRuntime = require('react/jsx-runtime');
8
+ var chart = require('@canvas-components/chart');
8
9
  var date = require('@canvas-components/utils/date');
9
10
  var number = require('@canvas-components/utils/number');
10
11
 
@@ -31,7 +32,7 @@ function styleInject(css, { insertAt } = {}) {
31
32
  }
32
33
 
33
34
  // src/styles/table-overrides.css
34
- 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");
35
+ 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 font-size: 14px;\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");
35
36
  var conditionalOperators = {
36
37
  eq: "\u7B49\u4E8E",
37
38
  neq: "\u4E0D\u7B49\u4E8E",
@@ -354,10 +355,325 @@ function buildCacheMenuItems(request) {
354
355
  });
355
356
  return items;
356
357
  }
358
+
359
+ // src/features/context-menu/chart-options.ts
360
+ var SELECTION_CHART_TYPES = [
361
+ { value: "line", label: "\u6298\u7EBF\u56FE" },
362
+ { value: "step-line", label: "\u9636\u68AF\u6298\u7EBF\u56FE" },
363
+ { value: "bump", label: "\u51F9\u51F8\u56FE\uFF08\u6392\u540D\uFF09" },
364
+ { value: "area", label: "\u9762\u79EF\u56FE" },
365
+ { value: "stacked-area", label: "\u5806\u79EF\u9762\u79EF\u56FE" },
366
+ { value: "bar", label: "\u67F1\u72B6\u56FE" },
367
+ { value: "stacked-bar", label: "\u5806\u79EF\u67F1\u72B6\u56FE" },
368
+ { value: "horizontal-bar", label: "\u6761\u5F62\u56FE" },
369
+ { value: "stacked-horizontal-bar", label: "\u5806\u79EF\u6761\u5F62\u56FE" },
370
+ { value: "mixed", label: "\u67F1\u7EBF\u6DF7\u5408\u56FE" },
371
+ { value: "pie", label: "\u997C\u56FE" },
372
+ { value: "donut", label: "\u73AF\u5F62\u56FE" },
373
+ { value: "rose", label: "\u73AB\u7470\u56FE" },
374
+ { value: "half-donut", label: "\u534A\u73AF\u5F62\u56FE" },
375
+ { value: "radar", label: "\u96F7\u8FBE\u56FE" },
376
+ { value: "gauge", label: "\u4EEA\u8868\u76D8" }
377
+ ];
378
+ var COLORS = ["#1677ff", "#13c2c2", "#fa8c16", "#722ed1", "#eb2f96"];
379
+ function createSelectionChartOption(data, chartType, seriesIndex = 0) {
380
+ const activeSeries = data.series[Math.min(seriesIndex, data.series.length - 1)];
381
+ if (["pie", "donut", "rose", "half-donut"].includes(chartType)) {
382
+ const option2 = {
383
+ color: COLORS,
384
+ legend: { show: true, orient: "vertical", left: "right", top: "middle" },
385
+ tooltip: { show: true },
386
+ series: {
387
+ type: "pie",
388
+ name: activeSeries.name,
389
+ data: data.labels.map((name, index) => ({
390
+ name,
391
+ value: Math.max(activeSeries.data[index] ?? 0, 0)
392
+ })),
393
+ radius: chartType === "pie" || chartType === "rose" ? "62%" : ["28%", "62%"],
394
+ center: ["39%", "50%"],
395
+ roseType: chartType === "rose" ? "radius" : void 0,
396
+ startAngle: chartType === "half-donut" ? 180 : void 0,
397
+ endAngle: chartType === "half-donut" ? 360 : void 0,
398
+ label: { show: true, position: "outside" },
399
+ labelLine: { show: true }
400
+ }
401
+ };
402
+ return { type: "pie", option: option2 };
403
+ }
404
+ if (chartType === "radar") {
405
+ const labels = data.labels.slice(0, 12);
406
+ const series = data.series.slice(0, 5);
407
+ const maximum = Math.max(
408
+ 1,
409
+ ...series.flatMap((item) => item.data.slice(0, labels.length))
410
+ );
411
+ const option2 = {
412
+ color: COLORS,
413
+ radar: {
414
+ indicator: labels.map((name) => ({
415
+ name,
416
+ max: Math.ceil(maximum * 1.1)
417
+ })),
418
+ radius: "58%",
419
+ center: ["50%", "55%"],
420
+ splitNumber: 4
421
+ },
422
+ legend: { show: series.length > 1 },
423
+ tooltip: { show: true },
424
+ series: {
425
+ type: "radar",
426
+ data: series.map((item) => ({
427
+ name: item.name,
428
+ value: item.data.slice(0, labels.length),
429
+ areaStyle: { opacity: 0.12 }
430
+ }))
431
+ }
432
+ };
433
+ return { type: "radar", option: option2 };
434
+ }
435
+ if (chartType === "gauge") {
436
+ const value = activeSeries.data[0] ?? 0;
437
+ const option2 = {
438
+ color: COLORS,
439
+ tooltip: { show: true },
440
+ series: {
441
+ type: "gauge",
442
+ name: activeSeries.name,
443
+ data: [{ name: data.labels[0] ?? activeSeries.name, value }],
444
+ min: Math.min(0, value),
445
+ max: Math.max(100, Math.ceil(value * 1.2)),
446
+ radius: "68%",
447
+ progress: { show: true },
448
+ pointer: { show: true },
449
+ detail: { show: true }
450
+ }
451
+ };
452
+ return { type: "gauge", option: option2 };
453
+ }
454
+ const horizontal = chartType.includes("horizontal");
455
+ const stacked = chartType.startsWith("stacked");
456
+ const area = chartType.includes("area");
457
+ const bumpData = chartType === "bump" ? resolveBumpRanks(data) : null;
458
+ const option = {
459
+ grid: {
460
+ show: true,
461
+ left: 20,
462
+ right: 20,
463
+ top: 36,
464
+ bottom: 28,
465
+ containLabel: true
466
+ },
467
+ legend: { show: data.series.length > 1 },
468
+ xAxis: horizontal ? { show: true, type: "value" } : { show: true, type: "category", data: data.labels },
469
+ yAxis: horizontal ? { show: true, type: "category", data: data.labels } : {
470
+ show: true,
471
+ type: "value",
472
+ min: bumpData ? 1 : void 0,
473
+ max: bumpData ? data.series.length : void 0,
474
+ inverse: Boolean(bumpData),
475
+ splitNumber: bumpData ? Math.max(data.series.length - 1, 1) : void 0,
476
+ axisLabel: bumpData ? { formatter: (value) => `\u7B2C${value}\u540D` } : void 0,
477
+ splitLine: { show: true }
478
+ },
479
+ tooltip: { show: true, trigger: "axis" },
480
+ series: data.series.map((series, index) => {
481
+ const color = COLORS[index % COLORS.length];
482
+ const isBar = chartType === "mixed" ? index % 2 === 0 : chartType.includes("bar");
483
+ return isBar ? {
484
+ type: "bar",
485
+ name: series.name,
486
+ data: series.data,
487
+ stack: stacked ? "total" : void 0,
488
+ itemStyle: { color }
489
+ } : {
490
+ type: "line",
491
+ name: series.name,
492
+ data: bumpData?.[index] ?? series.data,
493
+ stack: stacked ? "total" : void 0,
494
+ lineStyle: { color, width: 2 },
495
+ step: chartType === "step-line" ? "end" : void 0,
496
+ showSymbol: chartType === "bump",
497
+ symbolSize: chartType === "bump" ? 7 : void 0,
498
+ areaStyle: area ? { color, opacity: stacked ? 0.35 : 0.16 } : void 0
499
+ };
500
+ })
501
+ };
502
+ return { type: "sparkline", option };
503
+ }
504
+ function resolveBumpRanks(data) {
505
+ const ranks = data.series.map(() => []);
506
+ data.labels.forEach((_, dataIndex) => {
507
+ const order = data.series.map((series, seriesIndex) => ({
508
+ seriesIndex,
509
+ value: series.data[dataIndex] ?? Number.NEGATIVE_INFINITY
510
+ })).sort(
511
+ (left, right) => right.value - left.value || left.seriesIndex - right.seriesIndex
512
+ );
513
+ order.forEach(({ seriesIndex }, rankIndex) => {
514
+ ranks[seriesIndex][dataIndex] = rankIndex + 1;
515
+ });
516
+ });
517
+ return ranks;
518
+ }
519
+ function ChartDialog(props) {
520
+ const [chartType, setChartType] = react.useState("line");
521
+ const [seriesIndex, setSeriesIndex] = react.useState(0);
522
+ const [ready, setReady] = react.useState(false);
523
+ const chartHostRef = react.useRef(null);
524
+ const chartRef = react.useRef(null);
525
+ const chartConfig = react.useMemo(() => {
526
+ if (!props.data) return null;
527
+ return createSelectionChartOption(props.data, chartType, seriesIndex);
528
+ }, [chartType, props.data, seriesIndex]);
529
+ react.useEffect(() => {
530
+ if (!ready || !chartConfig || !chartHostRef.current) return;
531
+ let chart$1 = chartRef.current;
532
+ if (!chart$1) {
533
+ chart$1 = new chart.CanvasChart(chartHostRef.current, {
534
+ type: chartConfig.type,
535
+ option: chartConfig.option
536
+ });
537
+ chart$1.mount();
538
+ chartRef.current = chart$1;
539
+ } else {
540
+ chart$1.updateOptions({
541
+ type: chartConfig.type,
542
+ option: chartConfig.option
543
+ });
544
+ }
545
+ }, [chartConfig, ready]);
546
+ react.useEffect(
547
+ () => () => {
548
+ chartRef.current?.destroy();
549
+ chartRef.current = null;
550
+ },
551
+ []
552
+ );
553
+ return /* @__PURE__ */ jsxRuntime.jsx(
554
+ reactComponents.ReactModal,
555
+ {
556
+ open: true,
557
+ title: "\u521B\u5EFA\u56FE\u8868",
558
+ width: 760,
559
+ centered: true,
560
+ draggable: true,
561
+ resizable: true,
562
+ mask: false,
563
+ footer: false,
564
+ onCancel: props.onClose,
565
+ afterOpenChange: setReady,
566
+ bodyStyle: { padding: "12px 20px 20px", display: "flex" },
567
+ children: props.data ? /* @__PURE__ */ jsxRuntime.jsxs(
568
+ "div",
569
+ {
570
+ style: {
571
+ display: "flex",
572
+ flexDirection: "column",
573
+ flex: 1,
574
+ minHeight: 0,
575
+ gap: 12
576
+ },
577
+ children: [
578
+ /* @__PURE__ */ jsxRuntime.jsxs(
579
+ "label",
580
+ {
581
+ style: {
582
+ display: "flex",
583
+ alignItems: "center",
584
+ gap: 12,
585
+ whiteSpace: "nowrap"
586
+ },
587
+ children: [
588
+ "\u56FE\u8868\u7C7B\u578B",
589
+ /* @__PURE__ */ jsxRuntime.jsx(
590
+ reactComponents.ReactSelect,
591
+ {
592
+ value: chartType,
593
+ allowClear: false,
594
+ options: SELECTION_CHART_TYPES,
595
+ onChange: (value) => setChartType(value),
596
+ style: { width: 180 }
597
+ }
598
+ )
599
+ ]
600
+ }
601
+ ),
602
+ props.data.series.length > 1 && [
603
+ "pie",
604
+ "donut",
605
+ "rose",
606
+ "half-donut",
607
+ "gauge"
608
+ ].includes(chartType) ? /* @__PURE__ */ jsxRuntime.jsxs(
609
+ "label",
610
+ {
611
+ style: {
612
+ display: "flex",
613
+ alignItems: "center",
614
+ gap: 12,
615
+ whiteSpace: "nowrap"
616
+ },
617
+ children: [
618
+ "\u6570\u636E\u7CFB\u5217",
619
+ /* @__PURE__ */ jsxRuntime.jsx(
620
+ reactComponents.ReactSelect,
621
+ {
622
+ value: seriesIndex,
623
+ allowClear: false,
624
+ options: props.data.series.map((series, index) => ({
625
+ value: index,
626
+ label: series.name
627
+ })),
628
+ onChange: (value) => setSeriesIndex(Number(value)),
629
+ style: { width: 180 }
630
+ }
631
+ )
632
+ ]
633
+ }
634
+ ) : null,
635
+ /* @__PURE__ */ jsxRuntime.jsx(
636
+ "div",
637
+ {
638
+ ref: chartHostRef,
639
+ style: {
640
+ width: "100%",
641
+ height: 400,
642
+ flex: "1 1 200px",
643
+ minHeight: 160
644
+ }
645
+ }
646
+ )
647
+ ]
648
+ }
649
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "24px 0" }, children: "\u5F53\u524D\u9009\u533A\u6CA1\u6709\u53EF\u7ED8\u5236\u7684\u6570\u503C\u6570\u636E\u3002" })
650
+ }
651
+ );
652
+ }
653
+
654
+ // src/features/density/density-options.ts
655
+ var TABLE_DENSITY_OPTIONS = [
656
+ {
657
+ key: "density-comfortable",
658
+ label: "\u5BBD\u677E",
659
+ mode: "comfortable",
660
+ rowHeight: 56
661
+ },
662
+ { key: "density-middle", label: "\u4E2D\u7B49", mode: "middle", rowHeight: 48 },
663
+ { key: "density-compact", label: "\u7D27\u51D1", mode: "compact", rowHeight: 32 },
664
+ {
665
+ key: "density-ultra-compact",
666
+ label: "\u8D85\u7D27\u51D1",
667
+ mode: "ultra-compact",
668
+ rowHeight: 26
669
+ },
670
+ { key: "density-auto", label: "\u81EA\u9002\u5E94", mode: "auto", rowHeight: "auto" }
671
+ ];
357
672
  var CONTEXT_MENU_SURFACE_STYLE = {
358
673
  padding: 8,
359
674
  background: "#ffffff",
360
- boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)"
675
+ boxShadow: "0 8px 24px rgba(15, 23, 42, 0.16)",
676
+ fontSize: 14
361
677
  };
362
678
  function ReactTableContextMenuView(props) {
363
679
  const { request } = props;
@@ -375,9 +691,25 @@ function ReactTableContextMenuView(props) {
375
691
  ) : null;
376
692
  const [moreFormatRequest, setMoreFormatRequest] = react.useState(null);
377
693
  const [customSelectionRequest, setCustomSelectionRequest] = react.useState(null);
694
+ const [chartRequest, setChartRequest] = react.useState(null);
695
+ const [columnEditor, setColumnEditor] = react.useState(null);
696
+ const columnDialogs = /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: columnEditor ? /* @__PURE__ */ jsxRuntime.jsx(
697
+ ColumnEditorDialog,
698
+ {
699
+ request: columnEditor.request,
700
+ item: columnEditor.item,
701
+ parentItem: columnEditor.parentItem,
702
+ onClose: () => {
703
+ setColumnEditor(null);
704
+ columnEditor.request.onClose();
705
+ }
706
+ },
707
+ columnEditor.item?.key ?? "new"
708
+ ) : null });
378
709
  if (!request) {
379
710
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
380
711
  conditionalDialog,
712
+ columnDialogs,
381
713
  moreFormatRequest ? /* @__PURE__ */ jsxRuntime.jsx(
382
714
  MoreFormatDialog,
383
715
  {
@@ -394,6 +726,16 @@ function ReactTableContextMenuView(props) {
394
726
  customSelectionRequest.onClose();
395
727
  }
396
728
  }
729
+ ) : null,
730
+ chartRequest ? /* @__PURE__ */ jsxRuntime.jsx(
731
+ ChartDialog,
732
+ {
733
+ data: chartRequest.data,
734
+ onClose: () => {
735
+ chartRequest.request.onClose();
736
+ setChartRequest(null);
737
+ }
738
+ }
397
739
  ) : null
398
740
  ] });
399
741
  }
@@ -403,6 +745,7 @@ function ReactTableContextMenuView(props) {
403
745
  };
404
746
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
405
747
  conditionalDialog,
748
+ columnDialogs,
406
749
  /* @__PURE__ */ jsxRuntime.jsx(
407
750
  reactComponents.ReactPopup,
408
751
  {
@@ -412,7 +755,7 @@ function ReactTableContextMenuView(props) {
412
755
  minWidth: 260,
413
756
  onOpenChange: (open) => {
414
757
  setMenuOpen(open);
415
- if (!open && !moreFormatRequest && !customSelectionRequest && !conditionalEditor) {
758
+ if (!open && !moreFormatRequest && !customSelectionRequest && !chartRequest && !conditionalEditor && !columnEditor) {
416
759
  request.onClose();
417
760
  }
418
761
  },
@@ -483,6 +826,16 @@ function ReactTableContextMenuView(props) {
483
826
  }
484
827
  ),
485
828
  /* @__PURE__ */ jsxRuntime.jsx(MenuAction, { label: "\u67E5\u627E", onClick: request.onOpenSearch }),
829
+ /* @__PURE__ */ jsxRuntime.jsx(
830
+ MenuAction,
831
+ {
832
+ label: "\u521B\u5EFA\u56FE\u8868",
833
+ onClick: request.onCreateChart ? () => {
834
+ setChartRequest({ request, data: request.onCreateChart?.() ?? null });
835
+ setMenuOpen(false);
836
+ } : void 0
837
+ }
838
+ ),
486
839
  /* @__PURE__ */ jsxRuntime.jsx(
487
840
  MenuSubmenu,
488
841
  {
@@ -776,13 +1129,29 @@ function ReactTableContextMenuView(props) {
776
1129
  items: buildCacheMenuItems(request)
777
1130
  }
778
1131
  ),
779
- request.columns?.length && request.onToggleColumn ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1132
+ request.columns && request.onToggleColumn ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
780
1133
  /* @__PURE__ */ jsxRuntime.jsx(MenuDivider, {}),
781
1134
  /* @__PURE__ */ jsxRuntime.jsx(
782
1135
  ColumnVisibilityMenu,
783
1136
  {
784
1137
  columns: request.columns,
785
- onToggle: request.onToggleColumn
1138
+ onToggle: request.onToggleColumn,
1139
+ onAdd: () => {
1140
+ setColumnEditor({ request, item: null, parentItem: null });
1141
+ setMenuOpen(false);
1142
+ },
1143
+ onAddChild: (parentItem) => {
1144
+ setColumnEditor({ request, item: null, parentItem });
1145
+ setMenuOpen(false);
1146
+ },
1147
+ onEdit: (item) => {
1148
+ setColumnEditor({ request, item, parentItem: null });
1149
+ setMenuOpen(false);
1150
+ },
1151
+ onDelete: (item) => {
1152
+ request.onDeleteColumn?.(item.key);
1153
+ request.onClose();
1154
+ }
786
1155
  }
787
1156
  )
788
1157
  ] }) : null
@@ -808,6 +1177,16 @@ function ReactTableContextMenuView(props) {
808
1177
  customSelectionRequest.onClose();
809
1178
  }
810
1179
  }
1180
+ ) : null,
1181
+ chartRequest ? /* @__PURE__ */ jsxRuntime.jsx(
1182
+ ChartDialog,
1183
+ {
1184
+ data: chartRequest.data,
1185
+ onClose: () => {
1186
+ chartRequest.request.onClose();
1187
+ setChartRequest(null);
1188
+ }
1189
+ }
811
1190
  ) : null
812
1191
  ] });
813
1192
  }
@@ -1020,48 +1399,12 @@ function DensityMenu(props) {
1020
1399
  MenuSubmenu,
1021
1400
  {
1022
1401
  label: "\u8868\u683C\u5BC6\u5EA6",
1023
- items: [
1024
- {
1025
- key: "density-comfortable",
1026
- label: "\u5BBD\u677E",
1027
- selected: value === "comfortable",
1028
- onClick: () => {
1029
- onChange("comfortable");
1030
- }
1031
- },
1032
- {
1033
- key: "density-middle",
1034
- label: "\u4E2D\u7B49",
1035
- selected: value === "middle",
1036
- onClick: () => {
1037
- onChange("middle");
1038
- }
1039
- },
1040
- {
1041
- key: "density-compact",
1042
- label: "\u7D27\u51D1",
1043
- selected: value === "compact",
1044
- onClick: () => {
1045
- onChange("compact");
1046
- }
1047
- },
1048
- {
1049
- key: "density-ultra-compact",
1050
- label: "\u8D85\u7D27\u51D1",
1051
- selected: value === "ultra-compact",
1052
- onClick: () => {
1053
- onChange("ultra-compact");
1054
- }
1055
- },
1056
- {
1057
- key: "density-auto",
1058
- label: "\u81EA\u9002\u5E94",
1059
- selected: value === "auto",
1060
- onClick: () => {
1061
- onChange("auto");
1062
- }
1063
- }
1064
- ]
1402
+ items: TABLE_DENSITY_OPTIONS.map((option) => ({
1403
+ key: option.key,
1404
+ label: option.label,
1405
+ selected: value === option.mode,
1406
+ onClick: () => onChange(option.mode)
1407
+ }))
1065
1408
  }
1066
1409
  );
1067
1410
  }
@@ -1255,10 +1598,152 @@ function ZoomMenu(props) {
1255
1598
  }
1256
1599
  );
1257
1600
  }
1601
+ function ColumnEditorDialog(props) {
1602
+ const { item, parentItem, request } = props;
1603
+ const isUserColumn = item == null || item.userDefined === true;
1604
+ const [draft, setDraft] = react.useState(() => ({
1605
+ key: item?.key,
1606
+ parentKey: parentItem?.key,
1607
+ title: item?.title ?? "",
1608
+ dataIndex: item?.dataIndex ?? "",
1609
+ width: item?.width ?? 160,
1610
+ minWidth: item?.minWidth ?? Math.min(40, item?.width ?? 160),
1611
+ maxWidth: item?.maxWidth ?? Math.max(2e3, item?.width ?? 160),
1612
+ fixed: item?.fixed,
1613
+ order: item?.order ?? (parentItem?.children?.length ?? request.columns?.length ?? 0) + 1
1614
+ }));
1615
+ const [error, setError] = react.useState(null);
1616
+ const update = (patch) => {
1617
+ setDraft((current) => ({ ...current, ...patch }));
1618
+ setError(null);
1619
+ };
1620
+ const fieldStyle = {
1621
+ display: "grid",
1622
+ gap: 6,
1623
+ color: "#475569",
1624
+ fontSize: 13
1625
+ };
1626
+ return /* @__PURE__ */ jsxRuntime.jsx(
1627
+ reactComponents.ReactModal,
1628
+ {
1629
+ open: true,
1630
+ title: item ? "\u7F16\u8F91\u5217" : parentItem ? "\u65B0\u589E\u5B50\u5217" : "\u65B0\u589E\u5217",
1631
+ width: 440,
1632
+ centered: true,
1633
+ fullscreenable: false,
1634
+ onCancel: props.onClose,
1635
+ onOk: () => {
1636
+ const nextError = request.onSaveColumn ? request.onSaveColumn(draft) : "\u65E0\u6CD5\u4FDD\u5B58\u5217\u914D\u7F6E";
1637
+ if (nextError) {
1638
+ setError(nextError);
1639
+ } else {
1640
+ props.onClose();
1641
+ }
1642
+ },
1643
+ bodyStyle: { padding: "4px 20px 20px" },
1644
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 14 }, children: [
1645
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { style: fieldStyle, children: [
1646
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u5217\u540D\u79F0" }),
1647
+ /* @__PURE__ */ jsxRuntime.jsx(
1648
+ reactComponents.ReactInput,
1649
+ {
1650
+ autoFocus: true,
1651
+ value: draft.title,
1652
+ placeholder: "\u8BF7\u8F93\u5165\u5217\u540D\u79F0",
1653
+ onChange: (event) => update({ title: event.target.value })
1654
+ }
1655
+ )
1656
+ ] }),
1657
+ isUserColumn ? /* @__PURE__ */ jsxRuntime.jsxs("label", { style: fieldStyle, children: [
1658
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "dataIndex\uFF08\u5FC5\u586B\uFF09" }),
1659
+ /* @__PURE__ */ jsxRuntime.jsx(
1660
+ reactComponents.ReactSelect,
1661
+ {
1662
+ value: draft.dataIndex ?? "",
1663
+ placeholder: "\u8BF7\u9009\u62E9\u6570\u636E\u5B57\u6BB5",
1664
+ showSearch: true,
1665
+ allowClear: false,
1666
+ options: (request.dataIndexOptions ?? []).map((option) => ({
1667
+ label: option.disabled && option.label ? `${option.value}\uFF08${option.label}\uFF09` : option.value,
1668
+ value: option.value,
1669
+ disabled: option.disabled && option.value !== item?.dataIndex
1670
+ })),
1671
+ onChange: (value) => update({ dataIndex: value })
1672
+ }
1673
+ )
1674
+ ] }) : null,
1675
+ /* @__PURE__ */ jsxRuntime.jsx(
1676
+ "div",
1677
+ {
1678
+ style: {
1679
+ display: "grid",
1680
+ gridTemplateColumns: "repeat(3, minmax(0, 1fr))",
1681
+ gap: 10
1682
+ },
1683
+ children: [
1684
+ ["\u9ED8\u8BA4\u5BBD\u5EA6", "width"],
1685
+ ["\u6700\u5C0F\u5BBD\u5EA6", "minWidth"],
1686
+ ["\u6700\u5927\u5BBD\u5EA6", "maxWidth"]
1687
+ ].map(([label, key]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
1688
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
1689
+ label,
1690
+ "\uFF08px\uFF09"
1691
+ ] }),
1692
+ /* @__PURE__ */ jsxRuntime.jsx(
1693
+ reactComponents.ReactInputNumber,
1694
+ {
1695
+ value: draft[key],
1696
+ min: 1,
1697
+ precision: 0,
1698
+ onChange: (value) => update({ [key]: value ?? void 0 }),
1699
+ style: { width: "100%" }
1700
+ }
1701
+ )
1702
+ ] }, key))
1703
+ }
1704
+ ),
1705
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: fieldStyle, children: [
1706
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u5217\u987A\u5E8F\uFF08\u540C\u7EA7\uFF0C\u4ECE 1 \u5F00\u59CB\uFF09" }),
1707
+ /* @__PURE__ */ jsxRuntime.jsx(
1708
+ reactComponents.ReactInputNumber,
1709
+ {
1710
+ value: draft.order,
1711
+ min: 1,
1712
+ max: item?.siblingCount ?? (parentItem?.children?.length ?? request.columns?.length ?? 0) + 1,
1713
+ precision: 0,
1714
+ onChange: (value) => update({ order: value ?? void 0 }),
1715
+ style: { width: "100%" }
1716
+ }
1717
+ )
1718
+ ] }),
1719
+ isUserColumn ? /* @__PURE__ */ jsxRuntime.jsxs("label", { style: fieldStyle, children: [
1720
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "\u56FA\u5B9A\u4F4D\u7F6E" }),
1721
+ /* @__PURE__ */ jsxRuntime.jsx(
1722
+ reactComponents.ReactSelect,
1723
+ {
1724
+ value: draft.fixed ?? "none",
1725
+ allowClear: false,
1726
+ options: [
1727
+ { label: "\u4E0D\u56FA\u5B9A", value: "none" },
1728
+ { label: "\u56FA\u5B9A\u5DE6\u4FA7", value: "left" },
1729
+ { label: "\u56FA\u5B9A\u53F3\u4FA7", value: "right" }
1730
+ ],
1731
+ onChange: (value) => update({
1732
+ fixed: value === "none" ? void 0 : value
1733
+ })
1734
+ }
1735
+ )
1736
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { style: { color: "#64748b", fontSize: 12 }, children: "\u4EE3\u7801\u4F20\u5165\u7684\u5217\u4E0D\u53EF\u4FEE\u6539 dataIndex\u3001\u56FA\u5B9A\u4F4D\u7F6E\u6216\u5220\u9664\u3002" }),
1737
+ error ? /* @__PURE__ */ jsxRuntime.jsx("div", { role: "alert", style: { color: "#dc2626", fontSize: 12 }, children: error }) : null
1738
+ ] })
1739
+ }
1740
+ );
1741
+ }
1258
1742
  function ColumnVisibilityMenu(props) {
1259
- const { columns, onToggle } = props;
1743
+ const { columns, onToggle, onAdd, onAddChild, onEdit, onDelete } = props;
1260
1744
  const triggerRef = react.useRef(null);
1261
1745
  const [open, setOpen] = react.useState(false);
1746
+ const [deleteConfirmKey, setDeleteConfirmKey] = react.useState(null);
1262
1747
  const closeTimerRef = react.useRef(null);
1263
1748
  const clearCloseTimer = () => {
1264
1749
  if (closeTimerRef.current != null) {
@@ -1267,6 +1752,7 @@ function ColumnVisibilityMenu(props) {
1267
1752
  }
1268
1753
  };
1269
1754
  const scheduleClose = () => {
1755
+ if (deleteConfirmKey) return;
1270
1756
  clearCloseTimer();
1271
1757
  closeTimerRef.current = window.setTimeout(() => {
1272
1758
  setOpen(false);
@@ -1324,7 +1810,7 @@ function ColumnVisibilityMenu(props) {
1324
1810
  anchorRef: triggerRef,
1325
1811
  placement: "rightTop",
1326
1812
  offset: 2,
1327
- minWidth: 220,
1813
+ minWidth: 300,
1328
1814
  onOpenChange: setOpen,
1329
1815
  surfaceClassName: "canvas-react-scrollbar",
1330
1816
  surfaceStyle: {
@@ -1332,7 +1818,7 @@ function ColumnVisibilityMenu(props) {
1332
1818
  maxHeight: 360,
1333
1819
  overflow: "auto"
1334
1820
  },
1335
- children: /* @__PURE__ */ jsxRuntime.jsx(
1821
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1336
1822
  "div",
1337
1823
  {
1338
1824
  onMouseEnter: () => {
@@ -1341,14 +1827,35 @@ function ColumnVisibilityMenu(props) {
1341
1827
  onMouseLeave: () => {
1342
1828
  scheduleClose();
1343
1829
  },
1344
- children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
1345
- ColumnVisibilityItem,
1346
- {
1347
- item: column,
1348
- onToggle
1349
- },
1350
- column.key
1351
- ))
1830
+ children: [
1831
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "4px 10px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
1832
+ reactComponents.ReactButton,
1833
+ {
1834
+ type: "default",
1835
+ size: "small",
1836
+ onClick: onAdd,
1837
+ style: { height: 32, width: "100%", padding: "0 8px" },
1838
+ children: "\u65B0\u589E\u5217"
1839
+ }
1840
+ ) }),
1841
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { borderTop: "1px solid #e5e7eb", margin: "4px 0" } }),
1842
+ columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
1843
+ ColumnVisibilityItem,
1844
+ {
1845
+ item: column,
1846
+ onToggle,
1847
+ onAddChild,
1848
+ onEdit,
1849
+ onDelete,
1850
+ deleteConfirmKey,
1851
+ onDeleteConfirmOpenChange: (key) => {
1852
+ setDeleteConfirmKey(key);
1853
+ if (!key) setOpen(false);
1854
+ }
1855
+ },
1856
+ column.key
1857
+ ))
1858
+ ]
1352
1859
  }
1353
1860
  )
1354
1861
  }
@@ -1358,7 +1865,15 @@ function ColumnVisibilityMenu(props) {
1358
1865
  );
1359
1866
  }
1360
1867
  function ColumnVisibilityItem(props) {
1361
- const { item, onToggle } = props;
1868
+ const {
1869
+ item,
1870
+ onToggle,
1871
+ onAddChild,
1872
+ onEdit,
1873
+ onDelete,
1874
+ deleteConfirmKey,
1875
+ onDeleteConfirmOpenChange
1876
+ } = props;
1362
1877
  const triggerRef = react.useRef(null);
1363
1878
  const [open, setOpen] = react.useState(false);
1364
1879
  const closeTimerRef = react.useRef(null);
@@ -1370,6 +1885,7 @@ function ColumnVisibilityItem(props) {
1370
1885
  }
1371
1886
  };
1372
1887
  const scheduleClose = () => {
1888
+ if (deleteConfirmKey) return;
1373
1889
  clearCloseTimer();
1374
1890
  closeTimerRef.current = window.setTimeout(() => {
1375
1891
  setOpen(false);
@@ -1404,7 +1920,7 @@ function ColumnVisibilityItem(props) {
1404
1920
  fontSize: 14
1405
1921
  },
1406
1922
  children: [
1407
- /* @__PURE__ */ jsxRuntime.jsx(
1923
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: "1 1 auto", minWidth: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
1408
1924
  reactComponents.ReactCheckbox,
1409
1925
  {
1410
1926
  checked: item.checked,
@@ -1413,16 +1929,67 @@ function ColumnVisibilityItem(props) {
1413
1929
  onChange: (event) => {
1414
1930
  onToggle(item.key, !!event.target.checked);
1415
1931
  },
1416
- children: item.title
1932
+ children: [
1933
+ item.title,
1934
+ item.dataIndex ? `\uFF08${item.dataIndex}\uFF09` : ""
1935
+ ]
1417
1936
  }
1418
- ),
1419
- hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
1420
- "span",
1937
+ ) }),
1938
+ /* @__PURE__ */ jsxRuntime.jsxs(
1939
+ "div",
1421
1940
  {
1422
- className: `react-list-table-menu-chevron${open ? " react-list-table-menu-chevron-active" : ""}`,
1423
- "aria-hidden": "true"
1941
+ style: {
1942
+ display: "flex",
1943
+ alignItems: "center",
1944
+ gap: 6,
1945
+ flex: "none",
1946
+ marginLeft: "auto"
1947
+ },
1948
+ children: [
1949
+ item.userDefined ? /* @__PURE__ */ jsxRuntime.jsx(
1950
+ reactComponents.ReactPopconfirm,
1951
+ {
1952
+ title: `\u786E\u5B9A\u5220\u9664\u5217\u201C${item.title}\u201D\u5417\uFF1F`,
1953
+ placement: "rightTop",
1954
+ okText: "\u5220\u9664",
1955
+ open: deleteConfirmKey === item.key,
1956
+ onOpenChange: (nextOpen) => onDeleteConfirmOpenChange(nextOpen ? item.key : null),
1957
+ onConfirm: () => onDelete(item),
1958
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1959
+ "a",
1960
+ {
1961
+ href: "#",
1962
+ title: "\u5220\u9664\u5217",
1963
+ onClick: (event) => event.preventDefault(),
1964
+ style: { color: "#ff4d4f", fontSize: 12, textDecoration: "none" },
1965
+ children: "\u5220\u9664"
1966
+ }
1967
+ )
1968
+ }
1969
+ ) : null,
1970
+ /* @__PURE__ */ jsxRuntime.jsx(
1971
+ "a",
1972
+ {
1973
+ href: "#",
1974
+ title: "\u7F16\u8F91\u5217",
1975
+ onClick: (event) => {
1976
+ event.preventDefault();
1977
+ onEdit(item);
1978
+ },
1979
+ style: { color: "#1677ff", fontSize: 12, textDecoration: "none" },
1980
+ children: "\u7F16\u8F91"
1981
+ }
1982
+ ),
1983
+ hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
1984
+ "span",
1985
+ {
1986
+ className: `react-list-table-menu-chevron${open ? " react-list-table-menu-chevron-active" : ""}`,
1987
+ "aria-hidden": "true"
1988
+ }
1989
+ ) : null
1990
+ ]
1424
1991
  }
1425
- ) : null,
1992
+ ),
1426
1993
  hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
1427
1994
  reactComponents.ReactPopup,
1428
1995
  {
@@ -1431,7 +1998,7 @@ function ColumnVisibilityItem(props) {
1431
1998
  anchorRef: triggerRef,
1432
1999
  placement: "rightTop",
1433
2000
  offset: 2,
1434
- minWidth: 220,
2001
+ minWidth: 300,
1435
2002
  onOpenChange: setOpen,
1436
2003
  surfaceClassName: "canvas-react-scrollbar",
1437
2004
  surfaceStyle: {
@@ -1439,7 +2006,7 @@ function ColumnVisibilityItem(props) {
1439
2006
  maxHeight: 320,
1440
2007
  overflow: "auto"
1441
2008
  },
1442
- children: /* @__PURE__ */ jsxRuntime.jsx(
2009
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1443
2010
  "div",
1444
2011
  {
1445
2012
  onMouseEnter: () => {
@@ -1448,14 +2015,32 @@ function ColumnVisibilityItem(props) {
1448
2015
  onMouseLeave: () => {
1449
2016
  scheduleClose();
1450
2017
  },
1451
- children: item.children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
1452
- ColumnVisibilityItem,
1453
- {
1454
- item: child,
1455
- onToggle
1456
- },
1457
- child.key
1458
- ))
2018
+ children: [
2019
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "4px 10px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
2020
+ reactComponents.ReactButton,
2021
+ {
2022
+ type: "default",
2023
+ size: "small",
2024
+ onClick: () => onAddChild(item),
2025
+ style: { height: 32, width: "100%", padding: "0 8px" },
2026
+ children: "\u65B0\u589E\u5B50\u5217"
2027
+ }
2028
+ ) }),
2029
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { borderTop: "1px solid #e5e7eb", margin: "4px 0" } }),
2030
+ item.children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
2031
+ ColumnVisibilityItem,
2032
+ {
2033
+ item: child,
2034
+ onToggle,
2035
+ onAddChild,
2036
+ onEdit,
2037
+ onDelete,
2038
+ deleteConfirmKey,
2039
+ onDeleteConfirmOpenChange
2040
+ },
2041
+ child.key
2042
+ ))
2043
+ ]
1459
2044
  }
1460
2045
  )
1461
2046
  }
@@ -2589,16 +3174,22 @@ var SEARCH_MODAL_BODY_STYLE = {
2589
3174
  function ReactListTableSearchDialog(props) {
2590
3175
  const { request } = props;
2591
3176
  const [keyword, setKeyword] = react.useState(request.keyword);
3177
+ const [mode, setMode] = react.useState(request.mode);
3178
+ const [caseSensitive, setCaseSensitive] = react.useState(request.caseSensitive);
2592
3179
  react.useEffect(() => {
2593
3180
  setKeyword(request.keyword);
2594
- }, [request.keyword]);
2595
- const matchText = request.matchCount > 0 ? `${request.currentIndex + 1} / ${request.matchCount}` : "\u672A\u627E\u5230";
2596
- return /* @__PURE__ */ jsxRuntime.jsx(
3181
+ setMode(request.mode);
3182
+ setCaseSensitive(request.caseSensitive);
3183
+ }, [request.keyword, request.mode, request.caseSensitive]);
3184
+ const isDirty = keyword !== request.keyword || mode !== request.mode || caseSensitive !== request.caseSensitive;
3185
+ const submit = () => request.onSubmit(keyword, { mode, caseSensitive });
3186
+ const matchText = request.error ? "\u8868\u8FBE\u5F0F\u65E0\u6548" : request.matchCount > 0 ? `${request.currentIndex + 1} / ${request.matchCount}` : "\u672A\u627E\u5230";
3187
+ return /* @__PURE__ */ jsxRuntime.jsxs(
2597
3188
  reactComponents.ReactModal,
2598
3189
  {
2599
3190
  open: true,
2600
3191
  title: "\u67E5\u627E",
2601
- width: 360,
3192
+ width: 420,
2602
3193
  mask: false,
2603
3194
  centered: false,
2604
3195
  draggable: true,
@@ -2607,58 +3198,97 @@ function ReactListTableSearchDialog(props) {
2607
3198
  onCancel: request.onClose,
2608
3199
  bodyStyle: SEARCH_MODAL_BODY_STYLE,
2609
3200
  style: { marginTop: 96 },
2610
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: searchContentStyle, children: [
2611
- /* @__PURE__ */ jsxRuntime.jsx(
2612
- reactComponents.ReactInput,
2613
- {
2614
- autoFocus: true,
2615
- value: keyword,
2616
- placeholder: "\u67E5\u627E\u5185\u5BB9",
2617
- onChange: (event) => {
2618
- const value = event.target.value;
2619
- setKeyword(value);
2620
- },
2621
- onPressEnter: () => {
2622
- request.onSubmit(keyword);
3201
+ children: [
3202
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: searchContentStyle, children: [
3203
+ /* @__PURE__ */ jsxRuntime.jsx(
3204
+ reactComponents.ReactInput,
3205
+ {
3206
+ autoFocus: true,
3207
+ value: keyword,
3208
+ placeholder: "\u67E5\u627E\u5185\u5BB9",
3209
+ style: { flex: "1 1 0", minWidth: 0 },
3210
+ onChange: (event) => {
3211
+ const value = event.target.value;
3212
+ setKeyword(value);
3213
+ },
3214
+ onPressEnter: submit
2623
3215
  }
2624
- }
2625
- ),
2626
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: matchTextStyle, children: matchText }),
2627
- /* @__PURE__ */ jsxRuntime.jsx(
2628
- "button",
2629
- {
2630
- type: "button",
2631
- title: "\u4E0A\u4E00\u4E2A",
2632
- onClick: () => {
2633
- if (keyword !== request.keyword) {
2634
- request.onSubmit(keyword);
2635
- } else {
2636
- request.onNavigate("previous");
2637
- }
2638
- },
2639
- disabled: request.matchCount === 0 && keyword === request.keyword,
2640
- style: toolButtonStyle,
2641
- children: "\u2039"
2642
- }
2643
- ),
2644
- /* @__PURE__ */ jsxRuntime.jsx(
2645
- "button",
2646
- {
2647
- type: "button",
2648
- title: "\u4E0B\u4E00\u4E2A",
2649
- onClick: () => {
2650
- if (keyword !== request.keyword) {
2651
- request.onSubmit(keyword);
2652
- } else {
2653
- request.onNavigate("next");
3216
+ ),
3217
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: matchTextStyle, children: matchText }),
3218
+ /* @__PURE__ */ jsxRuntime.jsx(
3219
+ "button",
3220
+ {
3221
+ type: "button",
3222
+ title: "\u4E0A\u4E00\u4E2A",
3223
+ onClick: () => {
3224
+ if (isDirty) {
3225
+ submit();
3226
+ } else {
3227
+ request.onNavigate("previous");
3228
+ }
3229
+ },
3230
+ disabled: request.matchCount === 0 && !isDirty,
3231
+ style: toolButtonStyle,
3232
+ children: "\u2039"
3233
+ }
3234
+ ),
3235
+ /* @__PURE__ */ jsxRuntime.jsx(
3236
+ "button",
3237
+ {
3238
+ type: "button",
3239
+ title: "\u4E0B\u4E00\u4E2A",
3240
+ onClick: () => {
3241
+ if (isDirty) {
3242
+ submit();
3243
+ } else {
3244
+ request.onNavigate("next");
3245
+ }
3246
+ },
3247
+ disabled: request.matchCount === 0 && !isDirty,
3248
+ style: toolButtonStyle,
3249
+ children: "\u203A"
3250
+ }
3251
+ )
3252
+ ] }),
3253
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: searchOptionsStyle, children: [
3254
+ /* @__PURE__ */ jsxRuntime.jsx(
3255
+ reactComponents.ReactSelect,
3256
+ {
3257
+ value: mode,
3258
+ allowClear: false,
3259
+ options: [
3260
+ { label: "\u6A21\u7CCA\u5339\u914D", value: "fuzzy" },
3261
+ { label: "\u7CBE\u786E\u5339\u914D", value: "exact" },
3262
+ { label: "\u901A\u914D\u7B26 (* ?)", value: "wildcard" },
3263
+ { label: "\u6B63\u5219\u5339\u914D", value: "regex" }
3264
+ ],
3265
+ style: { width: 150 },
3266
+ onChange: (value) => {
3267
+ const nextMode = value;
3268
+ setMode(nextMode);
3269
+ request.onSubmit(keyword, { mode: nextMode, caseSensitive });
2654
3270
  }
2655
- },
2656
- disabled: request.matchCount === 0 && keyword === request.keyword,
2657
- style: toolButtonStyle,
2658
- children: "\u203A"
2659
- }
2660
- )
2661
- ] })
3271
+ }
3272
+ ),
3273
+ /* @__PURE__ */ jsxRuntime.jsx(
3274
+ reactComponents.ReactCheckbox,
3275
+ {
3276
+ checked: caseSensitive,
3277
+ style: { whiteSpace: "nowrap", flex: "none" },
3278
+ onChange: (event) => {
3279
+ const nextCaseSensitive = event.target.checked;
3280
+ setCaseSensitive(nextCaseSensitive);
3281
+ request.onSubmit(keyword, {
3282
+ mode,
3283
+ caseSensitive: nextCaseSensitive
3284
+ });
3285
+ },
3286
+ children: "\u533A\u5206\u5927\u5C0F\u5199"
3287
+ }
3288
+ )
3289
+ ] }),
3290
+ request.error ? /* @__PURE__ */ jsxRuntime.jsx("div", { style: searchErrorStyle, children: request.error }) : null
3291
+ ]
2662
3292
  }
2663
3293
  );
2664
3294
  }
@@ -2667,6 +3297,18 @@ var searchContentStyle = {
2667
3297
  alignItems: "center",
2668
3298
  gap: 8
2669
3299
  };
3300
+ var searchOptionsStyle = {
3301
+ display: "flex",
3302
+ alignItems: "center",
3303
+ flexWrap: "nowrap",
3304
+ gap: 12,
3305
+ marginTop: 10
3306
+ };
3307
+ var searchErrorStyle = {
3308
+ color: "#dc2626",
3309
+ fontSize: 12,
3310
+ marginTop: 6
3311
+ };
2670
3312
  var matchTextStyle = {
2671
3313
  minWidth: 58,
2672
3314
  color: "#64748b",
@@ -2674,8 +3316,10 @@ var matchTextStyle = {
2674
3316
  whiteSpace: "nowrap"
2675
3317
  };
2676
3318
  var toolButtonStyle = {
2677
- width: 28,
2678
- height: 28,
3319
+ width: 32,
3320
+ minWidth: 32,
3321
+ flex: "0 0 32px",
3322
+ height: 32,
2679
3323
  padding: 0,
2680
3324
  border: "1px solid #d1d5db",
2681
3325
  borderRadius: 4,
@@ -4066,7 +4710,7 @@ function resolveSortableTransform(index, sourceIndex, targetIndex, height) {
4066
4710
  }
4067
4711
 
4068
4712
  // src/features/toolbar/style.css
4069
- styleInject('.react-list-table-shell {\n background: #fff;\n font-size: 14px;\n}\n.react-list-table-titlebar {\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n box-sizing: border-box;\n background: #fff;\n}\n.react-list-table-shell-fullscreen {\n width: 100% !important;\n height: 100% !important;\n}\n.react-list-table-shell-fullscreen .canvas-list-table-root {\n height: 100% !important;\n}\n.react-list-table-title {\n min-width: 0;\n color: #1f2937;\n font-size: 14px;\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-tools {\n display: flex;\n align-items: center;\n gap: 14px;\n color: #475569;\n}\n.react-list-table-tool-wrap {\n position: relative;\n display: inline-flex;\n}\n.react-list-table-tool {\n width: 20px;\n height: 24px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n font: 16px/24px sans-serif;\n cursor: pointer;\n}\n.react-list-table-tool:hover {\n color: #1677ff;\n}\n.react-list-table-tool-menu,\n.react-list-table-column-setting {\n position: absolute;\n z-index: 120;\n top: 28px;\n right: 0;\n min-width: 112px;\n padding: 6px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, .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: 14px;\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 gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 4px 6px 8px;\n border-bottom: 1px solid #f0f0f0;\n flex: 0 0 auto;\n}\n.react-list-table-column-setting-head button {\n border: 0;\n color: #1677ff;\n background: transparent;\n cursor: pointer;\n}\n.react-list-table-column-setting-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.react-list-table-column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n padding: 7px 6px;\n box-sizing: border-box;\n cursor: pointer;\n}\n.react-list-table-column-main,\n.react-list-table-column-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.react-list-table-column-main {\n min-width: 0;\n}\n.react-list-table-column-actions {\n flex: 0 0 auto;\n}\n.react-list-table-column-actions > .canvas-react-select-wrap {\n flex: 0 0 96px;\n width: 96px;\n height: 24px;\n}\n.react-list-table-column-label {\n min-width: 64px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-column-width-input {\n height: 22px;\n padding-inline: 5px;\n}\n.react-list-table-column-fixed-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-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');
4713
+ styleInject(".react-list-table-shell {\n background: #fff;\n font-size: 14px;\n}\n.react-list-table-titlebar {\n height: 44px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 0;\n box-sizing: border-box;\n background: #fff;\n}\n.react-list-table-shell-fullscreen {\n width: 100% !important;\n height: 100% !important;\n}\n.react-list-table-shell-fullscreen .canvas-list-table-root {\n height: 100% !important;\n}\n.react-list-table-title {\n min-width: 0;\n color: #1f2937;\n font-size: 14px;\n font-weight: 600;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-tools {\n display: flex;\n align-items: center;\n gap: 14px;\n color: #475569;\n}\n.react-list-table-tool-wrap {\n position: relative;\n display: inline-flex;\n}\n.react-list-table-tool {\n width: 20px;\n height: 24px;\n padding: 0;\n border: 0;\n color: inherit;\n background: transparent;\n font: 16px/24px sans-serif;\n cursor: pointer;\n}\n.react-list-table-tool:hover {\n color: #1677ff;\n}\n.react-list-table-tool-menu,\n.react-list-table-column-setting {\n position: absolute;\n z-index: 120;\n top: 28px;\n right: 0;\n min-width: 112px;\n padding: 6px;\n border: 1px solid #e5e7eb;\n border-radius: 6px;\n background: #fff;\n box-shadow: 0 8px 24px rgba(15, 23, 42, 0.14);\n}\n.react-list-table-tool-menu button {\n display: flex;\n align-items: center;\n justify-content: flex-start;\n width: 100%;\n height: 32px;\n padding: 0 10px;\n border: 0;\n border-radius: 8px;\n background: transparent;\n color: #374151;\n font-size: 14px;\n text-align: left;\n cursor: pointer;\n}\n.react-list-table-tool-menu {\n width: max-content;\n min-width: 0;\n padding: 8px;\n border-radius: 8px;\n}\n.react-list-table-tool-menu-check {\n width: 16px;\n flex: 0 0 16px;\n margin-right: 6px;\n text-align: center;\n}\n.react-list-table-tool-menu button:hover {\n background: #f3f4f6;\n}\n.react-list-table-column-setting {\n width: 328px;\n max-height: 360px;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n}\n.react-list-table-column-setting-head {\n display: flex;\n gap: 12px;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n padding: 4px 6px 8px;\n border-bottom: 1px solid #f0f0f0;\n flex: 0 0 auto;\n}\n.react-list-table-column-setting-head button {\n border: 0;\n color: #1677ff;\n background: transparent;\n cursor: pointer;\n}\n.react-list-table-column-setting-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow: auto;\n}\n.react-list-table-column-item {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n padding: 7px 6px;\n box-sizing: border-box;\n cursor: pointer;\n}\n.react-list-table-column-main,\n.react-list-table-column-actions {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n.react-list-table-column-main {\n min-width: 0;\n}\n.react-list-table-column-actions {\n flex: 0 0 auto;\n}\n.react-list-table-column-actions > .canvas-react-select-wrap {\n flex: 0 0 96px;\n width: 96px;\n height: 24px;\n}\n.react-list-table-column-label {\n min-width: 64px;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n.react-list-table-column-width-input {\n height: 22px;\n padding-inline: 5px;\n}\n.react-list-table-column-fixed-input {\n height: 22px;\n padding-inline: 6px;\n font-size: 14px;\n}\n.react-list-table-column-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");
4070
4714
  function ReactTableToolbar(props) {
4071
4715
  const { toolbar, title } = props;
4072
4716
  const [densityOpen, setDensityOpen] = react.useState(false);
@@ -4152,18 +4796,28 @@ function ReactTableToolbar(props) {
4152
4796
  children: /* @__PURE__ */ jsxRuntime.jsx(ColumnHeightOutlined, {})
4153
4797
  }
4154
4798
  ),
4155
- densityOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "react-list-table-tool-menu", children: [56, 48, 32, 26].map((height) => /* @__PURE__ */ jsxRuntime.jsx(
4799
+ densityOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "react-list-table-tool-menu", children: TABLE_DENSITY_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsxs(
4156
4800
  "button",
4157
4801
  {
4158
4802
  type: "button",
4159
- className: props.density === height ? "active" : "",
4803
+ className: props.density === option.rowHeight ? "active" : "",
4160
4804
  onClick: () => {
4161
- props.onDensityChange(height);
4805
+ props.onDensityChange(option.rowHeight);
4162
4806
  setDensityOpen(false);
4163
4807
  },
4164
- children: height === 56 ? "\u5BBD\u677E" : height === 48 ? "\u4E2D\u7B49" : height === 32 ? "\u7D27\u51D1" : "\u8D85\u7D27\u51D1"
4808
+ children: [
4809
+ /* @__PURE__ */ jsxRuntime.jsx(
4810
+ "span",
4811
+ {
4812
+ className: "react-list-table-tool-menu-check",
4813
+ "aria-hidden": "true",
4814
+ children: props.density === option.rowHeight ? "\u2713" : ""
4815
+ }
4816
+ ),
4817
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: option.label })
4818
+ ]
4165
4819
  },
4166
- height
4820
+ option.key
4167
4821
  )) }) : null
4168
4822
  ] }) : null,
4169
4823
  config.showColumnSetting !== false ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-tool-wrap", children: [