@canvas-components/react-list-table 0.3.24 → 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
  {
@@ -572,6 +925,11 @@ function ReactTableContextMenuView(props) {
572
925
  key: "auto-fit-all",
573
926
  label: "\u5168\u90E8\u5217",
574
927
  onClick: request.onAutoFitAllColumns
928
+ },
929
+ {
930
+ key: "auto-fit-fill-container",
931
+ label: "\u81EA\u52A8\u94FA\u6EE1\u5BB9\u5668",
932
+ onClick: request.onAutoFitFillContainer
575
933
  }
576
934
  ]
577
935
  }
@@ -771,13 +1129,29 @@ function ReactTableContextMenuView(props) {
771
1129
  items: buildCacheMenuItems(request)
772
1130
  }
773
1131
  ),
774
- request.columns?.length && request.onToggleColumn ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1132
+ request.columns && request.onToggleColumn ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
775
1133
  /* @__PURE__ */ jsxRuntime.jsx(MenuDivider, {}),
776
1134
  /* @__PURE__ */ jsxRuntime.jsx(
777
1135
  ColumnVisibilityMenu,
778
1136
  {
779
1137
  columns: request.columns,
780
- 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
+ }
781
1155
  }
782
1156
  )
783
1157
  ] }) : null
@@ -803,6 +1177,16 @@ function ReactTableContextMenuView(props) {
803
1177
  customSelectionRequest.onClose();
804
1178
  }
805
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
+ }
806
1190
  ) : null
807
1191
  ] });
808
1192
  }
@@ -1015,48 +1399,12 @@ function DensityMenu(props) {
1015
1399
  MenuSubmenu,
1016
1400
  {
1017
1401
  label: "\u8868\u683C\u5BC6\u5EA6",
1018
- items: [
1019
- {
1020
- key: "density-comfortable",
1021
- label: "\u5BBD\u677E",
1022
- selected: value === "comfortable",
1023
- onClick: () => {
1024
- onChange("comfortable");
1025
- }
1026
- },
1027
- {
1028
- key: "density-middle",
1029
- label: "\u4E2D\u7B49",
1030
- selected: value === "middle",
1031
- onClick: () => {
1032
- onChange("middle");
1033
- }
1034
- },
1035
- {
1036
- key: "density-compact",
1037
- label: "\u7D27\u51D1",
1038
- selected: value === "compact",
1039
- onClick: () => {
1040
- onChange("compact");
1041
- }
1042
- },
1043
- {
1044
- key: "density-ultra-compact",
1045
- label: "\u8D85\u7D27\u51D1",
1046
- selected: value === "ultra-compact",
1047
- onClick: () => {
1048
- onChange("ultra-compact");
1049
- }
1050
- },
1051
- {
1052
- key: "density-auto",
1053
- label: "\u81EA\u9002\u5E94",
1054
- selected: value === "auto",
1055
- onClick: () => {
1056
- onChange("auto");
1057
- }
1058
- }
1059
- ]
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
+ }))
1060
1408
  }
1061
1409
  );
1062
1410
  }
@@ -1250,10 +1598,152 @@ function ZoomMenu(props) {
1250
1598
  }
1251
1599
  );
1252
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
+ }
1253
1742
  function ColumnVisibilityMenu(props) {
1254
- const { columns, onToggle } = props;
1743
+ const { columns, onToggle, onAdd, onAddChild, onEdit, onDelete } = props;
1255
1744
  const triggerRef = react.useRef(null);
1256
1745
  const [open, setOpen] = react.useState(false);
1746
+ const [deleteConfirmKey, setDeleteConfirmKey] = react.useState(null);
1257
1747
  const closeTimerRef = react.useRef(null);
1258
1748
  const clearCloseTimer = () => {
1259
1749
  if (closeTimerRef.current != null) {
@@ -1262,6 +1752,7 @@ function ColumnVisibilityMenu(props) {
1262
1752
  }
1263
1753
  };
1264
1754
  const scheduleClose = () => {
1755
+ if (deleteConfirmKey) return;
1265
1756
  clearCloseTimer();
1266
1757
  closeTimerRef.current = window.setTimeout(() => {
1267
1758
  setOpen(false);
@@ -1319,7 +1810,7 @@ function ColumnVisibilityMenu(props) {
1319
1810
  anchorRef: triggerRef,
1320
1811
  placement: "rightTop",
1321
1812
  offset: 2,
1322
- minWidth: 220,
1813
+ minWidth: 300,
1323
1814
  onOpenChange: setOpen,
1324
1815
  surfaceClassName: "canvas-react-scrollbar",
1325
1816
  surfaceStyle: {
@@ -1327,7 +1818,7 @@ function ColumnVisibilityMenu(props) {
1327
1818
  maxHeight: 360,
1328
1819
  overflow: "auto"
1329
1820
  },
1330
- children: /* @__PURE__ */ jsxRuntime.jsx(
1821
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1331
1822
  "div",
1332
1823
  {
1333
1824
  onMouseEnter: () => {
@@ -1336,14 +1827,35 @@ function ColumnVisibilityMenu(props) {
1336
1827
  onMouseLeave: () => {
1337
1828
  scheduleClose();
1338
1829
  },
1339
- children: columns.map((column) => /* @__PURE__ */ jsxRuntime.jsx(
1340
- ColumnVisibilityItem,
1341
- {
1342
- item: column,
1343
- onToggle
1344
- },
1345
- column.key
1346
- ))
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
+ ]
1347
1859
  }
1348
1860
  )
1349
1861
  }
@@ -1353,7 +1865,15 @@ function ColumnVisibilityMenu(props) {
1353
1865
  );
1354
1866
  }
1355
1867
  function ColumnVisibilityItem(props) {
1356
- const { item, onToggle } = props;
1868
+ const {
1869
+ item,
1870
+ onToggle,
1871
+ onAddChild,
1872
+ onEdit,
1873
+ onDelete,
1874
+ deleteConfirmKey,
1875
+ onDeleteConfirmOpenChange
1876
+ } = props;
1357
1877
  const triggerRef = react.useRef(null);
1358
1878
  const [open, setOpen] = react.useState(false);
1359
1879
  const closeTimerRef = react.useRef(null);
@@ -1365,6 +1885,7 @@ function ColumnVisibilityItem(props) {
1365
1885
  }
1366
1886
  };
1367
1887
  const scheduleClose = () => {
1888
+ if (deleteConfirmKey) return;
1368
1889
  clearCloseTimer();
1369
1890
  closeTimerRef.current = window.setTimeout(() => {
1370
1891
  setOpen(false);
@@ -1399,7 +1920,7 @@ function ColumnVisibilityItem(props) {
1399
1920
  fontSize: 14
1400
1921
  },
1401
1922
  children: [
1402
- /* @__PURE__ */ jsxRuntime.jsx(
1923
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: "1 1 auto", minWidth: 0 }, children: /* @__PURE__ */ jsxRuntime.jsxs(
1403
1924
  reactComponents.ReactCheckbox,
1404
1925
  {
1405
1926
  checked: item.checked,
@@ -1408,16 +1929,67 @@ function ColumnVisibilityItem(props) {
1408
1929
  onChange: (event) => {
1409
1930
  onToggle(item.key, !!event.target.checked);
1410
1931
  },
1411
- children: item.title
1932
+ children: [
1933
+ item.title,
1934
+ item.dataIndex ? `\uFF08${item.dataIndex}\uFF09` : ""
1935
+ ]
1412
1936
  }
1413
- ),
1414
- hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
1415
- "span",
1937
+ ) }),
1938
+ /* @__PURE__ */ jsxRuntime.jsxs(
1939
+ "div",
1416
1940
  {
1417
- className: `react-list-table-menu-chevron${open ? " react-list-table-menu-chevron-active" : ""}`,
1418
- "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
+ ]
1419
1991
  }
1420
- ) : null,
1992
+ ),
1421
1993
  hasChildren ? /* @__PURE__ */ jsxRuntime.jsx(
1422
1994
  reactComponents.ReactPopup,
1423
1995
  {
@@ -1426,7 +1998,7 @@ function ColumnVisibilityItem(props) {
1426
1998
  anchorRef: triggerRef,
1427
1999
  placement: "rightTop",
1428
2000
  offset: 2,
1429
- minWidth: 220,
2001
+ minWidth: 300,
1430
2002
  onOpenChange: setOpen,
1431
2003
  surfaceClassName: "canvas-react-scrollbar",
1432
2004
  surfaceStyle: {
@@ -1434,7 +2006,7 @@ function ColumnVisibilityItem(props) {
1434
2006
  maxHeight: 320,
1435
2007
  overflow: "auto"
1436
2008
  },
1437
- children: /* @__PURE__ */ jsxRuntime.jsx(
2009
+ children: /* @__PURE__ */ jsxRuntime.jsxs(
1438
2010
  "div",
1439
2011
  {
1440
2012
  onMouseEnter: () => {
@@ -1443,14 +2015,32 @@ function ColumnVisibilityItem(props) {
1443
2015
  onMouseLeave: () => {
1444
2016
  scheduleClose();
1445
2017
  },
1446
- children: item.children.map((child) => /* @__PURE__ */ jsxRuntime.jsx(
1447
- ColumnVisibilityItem,
1448
- {
1449
- item: child,
1450
- onToggle
1451
- },
1452
- child.key
1453
- ))
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
+ ]
1454
2044
  }
1455
2045
  )
1456
2046
  }
@@ -2584,16 +3174,22 @@ var SEARCH_MODAL_BODY_STYLE = {
2584
3174
  function ReactListTableSearchDialog(props) {
2585
3175
  const { request } = props;
2586
3176
  const [keyword, setKeyword] = react.useState(request.keyword);
3177
+ const [mode, setMode] = react.useState(request.mode);
3178
+ const [caseSensitive, setCaseSensitive] = react.useState(request.caseSensitive);
2587
3179
  react.useEffect(() => {
2588
3180
  setKeyword(request.keyword);
2589
- }, [request.keyword]);
2590
- const matchText = request.matchCount > 0 ? `${request.currentIndex + 1} / ${request.matchCount}` : "\u672A\u627E\u5230";
2591
- 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(
2592
3188
  reactComponents.ReactModal,
2593
3189
  {
2594
3190
  open: true,
2595
3191
  title: "\u67E5\u627E",
2596
- width: 360,
3192
+ width: 420,
2597
3193
  mask: false,
2598
3194
  centered: false,
2599
3195
  draggable: true,
@@ -2602,58 +3198,97 @@ function ReactListTableSearchDialog(props) {
2602
3198
  onCancel: request.onClose,
2603
3199
  bodyStyle: SEARCH_MODAL_BODY_STYLE,
2604
3200
  style: { marginTop: 96 },
2605
- children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: searchContentStyle, children: [
2606
- /* @__PURE__ */ jsxRuntime.jsx(
2607
- reactComponents.ReactInput,
2608
- {
2609
- autoFocus: true,
2610
- value: keyword,
2611
- placeholder: "\u67E5\u627E\u5185\u5BB9",
2612
- onChange: (event) => {
2613
- const value = event.target.value;
2614
- setKeyword(value);
2615
- },
2616
- onPressEnter: () => {
2617
- 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
2618
3215
  }
2619
- }
2620
- ),
2621
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: matchTextStyle, children: matchText }),
2622
- /* @__PURE__ */ jsxRuntime.jsx(
2623
- "button",
2624
- {
2625
- type: "button",
2626
- title: "\u4E0A\u4E00\u4E2A",
2627
- onClick: () => {
2628
- if (keyword !== request.keyword) {
2629
- request.onSubmit(keyword);
2630
- } else {
2631
- request.onNavigate("previous");
2632
- }
2633
- },
2634
- disabled: request.matchCount === 0 && keyword === request.keyword,
2635
- style: toolButtonStyle,
2636
- children: "\u2039"
2637
- }
2638
- ),
2639
- /* @__PURE__ */ jsxRuntime.jsx(
2640
- "button",
2641
- {
2642
- type: "button",
2643
- title: "\u4E0B\u4E00\u4E2A",
2644
- onClick: () => {
2645
- if (keyword !== request.keyword) {
2646
- request.onSubmit(keyword);
2647
- } else {
2648
- 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 });
2649
3270
  }
2650
- },
2651
- disabled: request.matchCount === 0 && keyword === request.keyword,
2652
- style: toolButtonStyle,
2653
- children: "\u203A"
2654
- }
2655
- )
2656
- ] })
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
+ ]
2657
3292
  }
2658
3293
  );
2659
3294
  }
@@ -2662,6 +3297,18 @@ var searchContentStyle = {
2662
3297
  alignItems: "center",
2663
3298
  gap: 8
2664
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
+ };
2665
3312
  var matchTextStyle = {
2666
3313
  minWidth: 58,
2667
3314
  color: "#64748b",
@@ -2669,8 +3316,10 @@ var matchTextStyle = {
2669
3316
  whiteSpace: "nowrap"
2670
3317
  };
2671
3318
  var toolButtonStyle = {
2672
- width: 28,
2673
- height: 28,
3319
+ width: 32,
3320
+ minWidth: 32,
3321
+ flex: "0 0 32px",
3322
+ height: 32,
2674
3323
  padding: 0,
2675
3324
  border: "1px solid #d1d5db",
2676
3325
  borderRadius: 4,
@@ -4061,7 +4710,7 @@ function resolveSortableTransform(index, sourceIndex, targetIndex, height) {
4061
4710
  }
4062
4711
 
4063
4712
  // src/features/toolbar/style.css
4064
- 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");
4065
4714
  function ReactTableToolbar(props) {
4066
4715
  const { toolbar, title } = props;
4067
4716
  const [densityOpen, setDensityOpen] = react.useState(false);
@@ -4147,18 +4796,28 @@ function ReactTableToolbar(props) {
4147
4796
  children: /* @__PURE__ */ jsxRuntime.jsx(ColumnHeightOutlined, {})
4148
4797
  }
4149
4798
  ),
4150
- 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(
4151
4800
  "button",
4152
4801
  {
4153
4802
  type: "button",
4154
- className: props.density === height ? "active" : "",
4803
+ className: props.density === option.rowHeight ? "active" : "",
4155
4804
  onClick: () => {
4156
- props.onDensityChange(height);
4805
+ props.onDensityChange(option.rowHeight);
4157
4806
  setDensityOpen(false);
4158
4807
  },
4159
- 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
+ ]
4160
4819
  },
4161
- height
4820
+ option.key
4162
4821
  )) }) : null
4163
4822
  ] }) : null,
4164
4823
  config.showColumnSetting !== false ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-tool-wrap", children: [