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