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

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
  {
@@ -775,13 +1128,29 @@ function ReactTableContextMenuView(props) {
775
1128
  items: buildCacheMenuItems(request)
776
1129
  }
777
1130
  ),
778
- request.columns?.length && request.onToggleColumn ? /* @__PURE__ */ jsxs(Fragment, { children: [
1131
+ request.columns && request.onToggleColumn ? /* @__PURE__ */ jsxs(Fragment, { children: [
779
1132
  /* @__PURE__ */ jsx(MenuDivider, {}),
780
1133
  /* @__PURE__ */ jsx(
781
1134
  ColumnVisibilityMenu,
782
1135
  {
783
1136
  columns: request.columns,
784
- 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
+ }
785
1154
  }
786
1155
  )
787
1156
  ] }) : null
@@ -807,6 +1176,16 @@ function ReactTableContextMenuView(props) {
807
1176
  customSelectionRequest.onClose();
808
1177
  }
809
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
+ }
810
1189
  ) : null
811
1190
  ] });
812
1191
  }
@@ -1019,48 +1398,12 @@ function DensityMenu(props) {
1019
1398
  MenuSubmenu,
1020
1399
  {
1021
1400
  label: "\u8868\u683C\u5BC6\u5EA6",
1022
- items: [
1023
- {
1024
- key: "density-comfortable",
1025
- label: "\u5BBD\u677E",
1026
- selected: value === "comfortable",
1027
- onClick: () => {
1028
- onChange("comfortable");
1029
- }
1030
- },
1031
- {
1032
- key: "density-middle",
1033
- label: "\u4E2D\u7B49",
1034
- selected: value === "middle",
1035
- onClick: () => {
1036
- onChange("middle");
1037
- }
1038
- },
1039
- {
1040
- key: "density-compact",
1041
- label: "\u7D27\u51D1",
1042
- selected: value === "compact",
1043
- onClick: () => {
1044
- onChange("compact");
1045
- }
1046
- },
1047
- {
1048
- key: "density-ultra-compact",
1049
- label: "\u8D85\u7D27\u51D1",
1050
- selected: value === "ultra-compact",
1051
- onClick: () => {
1052
- onChange("ultra-compact");
1053
- }
1054
- },
1055
- {
1056
- key: "density-auto",
1057
- label: "\u81EA\u9002\u5E94",
1058
- selected: value === "auto",
1059
- onClick: () => {
1060
- onChange("auto");
1061
- }
1062
- }
1063
- ]
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
+ }))
1064
1407
  }
1065
1408
  );
1066
1409
  }
@@ -1254,10 +1597,152 @@ function ZoomMenu(props) {
1254
1597
  }
1255
1598
  );
1256
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
+ }
1257
1741
  function ColumnVisibilityMenu(props) {
1258
- const { columns, onToggle } = props;
1742
+ const { columns, onToggle, onAdd, onAddChild, onEdit, onDelete } = props;
1259
1743
  const triggerRef = useRef(null);
1260
1744
  const [open, setOpen] = useState(false);
1745
+ const [deleteConfirmKey, setDeleteConfirmKey] = useState(null);
1261
1746
  const closeTimerRef = useRef(null);
1262
1747
  const clearCloseTimer = () => {
1263
1748
  if (closeTimerRef.current != null) {
@@ -1266,6 +1751,7 @@ function ColumnVisibilityMenu(props) {
1266
1751
  }
1267
1752
  };
1268
1753
  const scheduleClose = () => {
1754
+ if (deleteConfirmKey) return;
1269
1755
  clearCloseTimer();
1270
1756
  closeTimerRef.current = window.setTimeout(() => {
1271
1757
  setOpen(false);
@@ -1323,7 +1809,7 @@ function ColumnVisibilityMenu(props) {
1323
1809
  anchorRef: triggerRef,
1324
1810
  placement: "rightTop",
1325
1811
  offset: 2,
1326
- minWidth: 220,
1812
+ minWidth: 300,
1327
1813
  onOpenChange: setOpen,
1328
1814
  surfaceClassName: "canvas-react-scrollbar",
1329
1815
  surfaceStyle: {
@@ -1331,7 +1817,7 @@ function ColumnVisibilityMenu(props) {
1331
1817
  maxHeight: 360,
1332
1818
  overflow: "auto"
1333
1819
  },
1334
- children: /* @__PURE__ */ jsx(
1820
+ children: /* @__PURE__ */ jsxs(
1335
1821
  "div",
1336
1822
  {
1337
1823
  onMouseEnter: () => {
@@ -1340,14 +1826,35 @@ function ColumnVisibilityMenu(props) {
1340
1826
  onMouseLeave: () => {
1341
1827
  scheduleClose();
1342
1828
  },
1343
- children: columns.map((column) => /* @__PURE__ */ jsx(
1344
- ColumnVisibilityItem,
1345
- {
1346
- item: column,
1347
- onToggle
1348
- },
1349
- column.key
1350
- ))
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
+ ]
1351
1858
  }
1352
1859
  )
1353
1860
  }
@@ -1357,7 +1864,15 @@ function ColumnVisibilityMenu(props) {
1357
1864
  );
1358
1865
  }
1359
1866
  function ColumnVisibilityItem(props) {
1360
- const { item, onToggle } = props;
1867
+ const {
1868
+ item,
1869
+ onToggle,
1870
+ onAddChild,
1871
+ onEdit,
1872
+ onDelete,
1873
+ deleteConfirmKey,
1874
+ onDeleteConfirmOpenChange
1875
+ } = props;
1361
1876
  const triggerRef = useRef(null);
1362
1877
  const [open, setOpen] = useState(false);
1363
1878
  const closeTimerRef = useRef(null);
@@ -1369,6 +1884,7 @@ function ColumnVisibilityItem(props) {
1369
1884
  }
1370
1885
  };
1371
1886
  const scheduleClose = () => {
1887
+ if (deleteConfirmKey) return;
1372
1888
  clearCloseTimer();
1373
1889
  closeTimerRef.current = window.setTimeout(() => {
1374
1890
  setOpen(false);
@@ -1403,7 +1919,7 @@ function ColumnVisibilityItem(props) {
1403
1919
  fontSize: 14
1404
1920
  },
1405
1921
  children: [
1406
- /* @__PURE__ */ jsx(
1922
+ /* @__PURE__ */ jsx("div", { style: { flex: "1 1 auto", minWidth: 0 }, children: /* @__PURE__ */ jsxs(
1407
1923
  ReactCheckbox,
1408
1924
  {
1409
1925
  checked: item.checked,
@@ -1412,16 +1928,67 @@ function ColumnVisibilityItem(props) {
1412
1928
  onChange: (event) => {
1413
1929
  onToggle(item.key, !!event.target.checked);
1414
1930
  },
1415
- children: item.title
1931
+ children: [
1932
+ item.title,
1933
+ item.dataIndex ? `\uFF08${item.dataIndex}\uFF09` : ""
1934
+ ]
1416
1935
  }
1417
- ),
1418
- hasChildren ? /* @__PURE__ */ jsx(
1419
- "span",
1936
+ ) }),
1937
+ /* @__PURE__ */ jsxs(
1938
+ "div",
1420
1939
  {
1421
- className: `react-list-table-menu-chevron${open ? " react-list-table-menu-chevron-active" : ""}`,
1422
- "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
+ ]
1423
1990
  }
1424
- ) : null,
1991
+ ),
1425
1992
  hasChildren ? /* @__PURE__ */ jsx(
1426
1993
  ReactPopup,
1427
1994
  {
@@ -1430,7 +1997,7 @@ function ColumnVisibilityItem(props) {
1430
1997
  anchorRef: triggerRef,
1431
1998
  placement: "rightTop",
1432
1999
  offset: 2,
1433
- minWidth: 220,
2000
+ minWidth: 300,
1434
2001
  onOpenChange: setOpen,
1435
2002
  surfaceClassName: "canvas-react-scrollbar",
1436
2003
  surfaceStyle: {
@@ -1438,7 +2005,7 @@ function ColumnVisibilityItem(props) {
1438
2005
  maxHeight: 320,
1439
2006
  overflow: "auto"
1440
2007
  },
1441
- children: /* @__PURE__ */ jsx(
2008
+ children: /* @__PURE__ */ jsxs(
1442
2009
  "div",
1443
2010
  {
1444
2011
  onMouseEnter: () => {
@@ -1447,14 +2014,32 @@ function ColumnVisibilityItem(props) {
1447
2014
  onMouseLeave: () => {
1448
2015
  scheduleClose();
1449
2016
  },
1450
- children: item.children.map((child) => /* @__PURE__ */ jsx(
1451
- ColumnVisibilityItem,
1452
- {
1453
- item: child,
1454
- onToggle
1455
- },
1456
- child.key
1457
- ))
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
+ ]
1458
2043
  }
1459
2044
  )
1460
2045
  }
@@ -2588,16 +3173,22 @@ var SEARCH_MODAL_BODY_STYLE = {
2588
3173
  function ReactListTableSearchDialog(props) {
2589
3174
  const { request } = props;
2590
3175
  const [keyword, setKeyword] = useState(request.keyword);
3176
+ const [mode, setMode] = useState(request.mode);
3177
+ const [caseSensitive, setCaseSensitive] = useState(request.caseSensitive);
2591
3178
  useEffect(() => {
2592
3179
  setKeyword(request.keyword);
2593
- }, [request.keyword]);
2594
- const matchText = request.matchCount > 0 ? `${request.currentIndex + 1} / ${request.matchCount}` : "\u672A\u627E\u5230";
2595
- 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(
2596
3187
  ReactModal,
2597
3188
  {
2598
3189
  open: true,
2599
3190
  title: "\u67E5\u627E",
2600
- width: 360,
3191
+ width: 420,
2601
3192
  mask: false,
2602
3193
  centered: false,
2603
3194
  draggable: true,
@@ -2606,58 +3197,97 @@ function ReactListTableSearchDialog(props) {
2606
3197
  onCancel: request.onClose,
2607
3198
  bodyStyle: SEARCH_MODAL_BODY_STYLE,
2608
3199
  style: { marginTop: 96 },
2609
- children: /* @__PURE__ */ jsxs("div", { style: searchContentStyle, children: [
2610
- /* @__PURE__ */ jsx(
2611
- ReactInput,
2612
- {
2613
- autoFocus: true,
2614
- value: keyword,
2615
- placeholder: "\u67E5\u627E\u5185\u5BB9",
2616
- onChange: (event) => {
2617
- const value = event.target.value;
2618
- setKeyword(value);
2619
- },
2620
- onPressEnter: () => {
2621
- 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
2622
3214
  }
2623
- }
2624
- ),
2625
- /* @__PURE__ */ jsx("span", { style: matchTextStyle, children: matchText }),
2626
- /* @__PURE__ */ jsx(
2627
- "button",
2628
- {
2629
- type: "button",
2630
- title: "\u4E0A\u4E00\u4E2A",
2631
- onClick: () => {
2632
- if (keyword !== request.keyword) {
2633
- request.onSubmit(keyword);
2634
- } else {
2635
- request.onNavigate("previous");
2636
- }
2637
- },
2638
- disabled: request.matchCount === 0 && keyword === request.keyword,
2639
- style: toolButtonStyle,
2640
- children: "\u2039"
2641
- }
2642
- ),
2643
- /* @__PURE__ */ jsx(
2644
- "button",
2645
- {
2646
- type: "button",
2647
- title: "\u4E0B\u4E00\u4E2A",
2648
- onClick: () => {
2649
- if (keyword !== request.keyword) {
2650
- request.onSubmit(keyword);
2651
- } else {
2652
- 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 });
2653
3269
  }
2654
- },
2655
- disabled: request.matchCount === 0 && keyword === request.keyword,
2656
- style: toolButtonStyle,
2657
- children: "\u203A"
2658
- }
2659
- )
2660
- ] })
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
+ ]
2661
3291
  }
2662
3292
  );
2663
3293
  }
@@ -2666,6 +3296,18 @@ var searchContentStyle = {
2666
3296
  alignItems: "center",
2667
3297
  gap: 8
2668
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
+ };
2669
3311
  var matchTextStyle = {
2670
3312
  minWidth: 58,
2671
3313
  color: "#64748b",
@@ -2673,8 +3315,10 @@ var matchTextStyle = {
2673
3315
  whiteSpace: "nowrap"
2674
3316
  };
2675
3317
  var toolButtonStyle = {
2676
- width: 28,
2677
- height: 28,
3318
+ width: 32,
3319
+ minWidth: 32,
3320
+ flex: "0 0 32px",
3321
+ height: 32,
2678
3322
  padding: 0,
2679
3323
  border: "1px solid #d1d5db",
2680
3324
  borderRadius: 4,
@@ -4065,7 +4709,7 @@ function resolveSortableTransform(index, sourceIndex, targetIndex, height) {
4065
4709
  }
4066
4710
 
4067
4711
  // src/features/toolbar/style.css
4068
- 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");
4069
4713
  function ReactTableToolbar(props) {
4070
4714
  const { toolbar, title } = props;
4071
4715
  const [densityOpen, setDensityOpen] = useState(false);
@@ -4151,18 +4795,28 @@ function ReactTableToolbar(props) {
4151
4795
  children: /* @__PURE__ */ jsx(ColumnHeightOutlined, {})
4152
4796
  }
4153
4797
  ),
4154
- 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(
4155
4799
  "button",
4156
4800
  {
4157
4801
  type: "button",
4158
- className: props.density === height ? "active" : "",
4802
+ className: props.density === option.rowHeight ? "active" : "",
4159
4803
  onClick: () => {
4160
- props.onDensityChange(height);
4804
+ props.onDensityChange(option.rowHeight);
4161
4805
  setDensityOpen(false);
4162
4806
  },
4163
- 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
+ ]
4164
4818
  },
4165
- height
4819
+ option.key
4166
4820
  )) }) : null
4167
4821
  ] }) : null,
4168
4822
  config.showColumnSetting !== false ? /* @__PURE__ */ jsxs("div", { className: "react-list-table-tool-wrap", children: [