@canvas-components/react-list-table 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -164,6 +164,8 @@ function ReactTableContextMenuView(props) {
164
164
  }
165
165
  ),
166
166
  /* @__PURE__ */ jsxRuntime.jsx(SummaryMenu, { request }),
167
+ /* @__PURE__ */ jsxRuntime.jsx(AlignmentMenu, { request }),
168
+ /* @__PURE__ */ jsxRuntime.jsx(DataFormatMenu, { request }),
167
169
  /* @__PURE__ */ jsxRuntime.jsx(
168
170
  MenuSubmenu,
169
171
  {
@@ -217,13 +219,7 @@ function ReactTableContextMenuView(props) {
217
219
  onChange: request.onChangeDensity
218
220
  }
219
221
  ),
220
- /* @__PURE__ */ jsxRuntime.jsx(
221
- ZoomMenu,
222
- {
223
- value: request.zoom ?? 1,
224
- onChange: request.onChangeZoom
225
- }
226
- ),
222
+ /* @__PURE__ */ jsxRuntime.jsx(ZoomMenu, { value: request.zoom ?? 1, onChange: request.onChangeZoom }),
227
223
  request.columns?.length && request.onToggleColumn ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
228
224
  /* @__PURE__ */ jsxRuntime.jsx(MenuDivider, {}),
229
225
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -524,11 +520,11 @@ function ZoomMenu(props) {
524
520
  anchorRef: triggerRef,
525
521
  placement: "rightTop",
526
522
  offset: 2,
527
- minWidth: 220,
523
+ minWidth: 280,
528
524
  onOpenChange: setOpen,
529
525
  surfaceStyle: {
530
526
  ...CONTEXT_MENU_SURFACE_STYLE,
531
- width: 220
527
+ width: 280
532
528
  },
533
529
  children: /* @__PURE__ */ jsxRuntime.jsxs(
534
530
  "div",
@@ -557,45 +553,58 @@ function ZoomMenu(props) {
557
553
  children: "\u8868\u683C\u7F29\u653E\uFF0850% - 200%\uFF09"
558
554
  }
559
555
  ),
560
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { padding: "0 8px 4px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
561
- reactComponents.ReactInputNumber,
562
- {
563
- value: percent,
564
- min: CONTEXT_MENU_ZOOM_MIN,
565
- max: CONTEXT_MENU_ZOOM_MAX,
566
- step: CONTEXT_MENU_ZOOM_STEP,
567
- precision: 0,
568
- addonAfter: "%",
569
- onChange: (next) => {
570
- if (next == null || !Number.isFinite(next)) {
571
- return;
572
- }
573
- onChange(Math.round(next) / 100);
574
- }
575
- }
576
- ) }),
577
- /* @__PURE__ */ jsxRuntime.jsx(
578
- "button",
556
+ /* @__PURE__ */ jsxRuntime.jsxs(
557
+ "div",
579
558
  {
580
- type: "button",
581
- disabled: percent === 100,
582
- onClick: () => {
583
- onChange(1);
584
- },
585
- className: "react-list-table-menu-action",
586
559
  style: {
587
- display: "block",
588
- width: "100%",
589
- height: 32,
590
- padding: "0 8px",
591
- border: "none",
592
- borderRadius: 8,
593
- background: "transparent",
594
- color: percent === 100 ? "#9ca3af" : "#374151",
595
- textAlign: "left",
596
- cursor: percent === 100 ? "not-allowed" : "pointer"
560
+ display: "flex",
561
+ alignItems: "stretch",
562
+ gap: 6,
563
+ padding: "0 8px 4px"
597
564
  },
598
- children: "\u91CD\u7F6E\u7F29\u653E"
565
+ children: [
566
+ /* @__PURE__ */ jsxRuntime.jsx(
567
+ reactComponents.ReactInputNumber,
568
+ {
569
+ value: percent,
570
+ min: CONTEXT_MENU_ZOOM_MIN,
571
+ max: CONTEXT_MENU_ZOOM_MAX,
572
+ step: CONTEXT_MENU_ZOOM_STEP,
573
+ precision: 0,
574
+ addonAfter: "%",
575
+ style: { flex: "1 1 auto", minWidth: 0 },
576
+ onChange: (next) => {
577
+ if (next == null || !Number.isFinite(next)) {
578
+ return;
579
+ }
580
+ onChange(Math.round(next) / 100);
581
+ }
582
+ }
583
+ ),
584
+ /* @__PURE__ */ jsxRuntime.jsx(
585
+ "button",
586
+ {
587
+ type: "button",
588
+ disabled: percent === 100,
589
+ onClick: () => {
590
+ onChange(1);
591
+ },
592
+ className: "react-list-table-menu-action",
593
+ style: {
594
+ flex: "0 0 52px",
595
+ height: 32,
596
+ padding: 0,
597
+ border: "1px solid #d1d5db",
598
+ borderRadius: 6,
599
+ background: "#ffffff",
600
+ color: percent === 100 ? "#9ca3af" : "#374151",
601
+ textAlign: "center",
602
+ cursor: percent === 100 ? "not-allowed" : "pointer"
603
+ },
604
+ children: "\u91CD\u7F6E"
605
+ }
606
+ )
607
+ ]
599
608
  }
600
609
  )
601
610
  ]
@@ -1061,6 +1070,129 @@ function SummaryMenu(props) {
1061
1070
  }
1062
1071
  );
1063
1072
  }
1073
+ function AlignmentMenu(props) {
1074
+ const { request } = props;
1075
+ if (!request.alignment || !request.onChangeAlignment) {
1076
+ return null;
1077
+ }
1078
+ return /* @__PURE__ */ jsxRuntime.jsx(
1079
+ MenuSubmenu,
1080
+ {
1081
+ label: "\u5BF9\u9F50\u65B9\u5F0F",
1082
+ items: [],
1083
+ footer: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 10, padding: "4px 8px" }, children: [
1084
+ /* @__PURE__ */ jsxRuntime.jsx(
1085
+ AlignmentGroup,
1086
+ {
1087
+ label: "\u8868\u5934",
1088
+ horizontal: request.alignment.headerHorizontal,
1089
+ vertical: request.alignment.headerVertical,
1090
+ onHorizontalChange: (value) => request.onChangeAlignment?.("header", "horizontal", value),
1091
+ onVerticalChange: (value) => request.onChangeAlignment?.("header", "vertical", value)
1092
+ }
1093
+ ),
1094
+ /* @__PURE__ */ jsxRuntime.jsx(
1095
+ AlignmentGroup,
1096
+ {
1097
+ label: "\u8868\u4F53",
1098
+ horizontal: request.alignment.bodyHorizontal,
1099
+ vertical: request.alignment.bodyVertical,
1100
+ onHorizontalChange: (value) => request.onChangeAlignment?.("body", "horizontal", value),
1101
+ onVerticalChange: (value) => request.onChangeAlignment?.("body", "vertical", value)
1102
+ }
1103
+ )
1104
+ ] })
1105
+ }
1106
+ );
1107
+ }
1108
+ function AlignmentGroup(props) {
1109
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "grid", gap: 6 }, children: [
1110
+ /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: "#374151", fontSize: 13 }, children: props.label }),
1111
+ /* @__PURE__ */ jsxRuntime.jsx(
1112
+ AlignmentSegment,
1113
+ {
1114
+ label: "\u6C34\u5E73",
1115
+ value: props.horizontal,
1116
+ options: [
1117
+ { label: "\u5DE6", value: "left" },
1118
+ { label: "\u4E2D", value: "center" },
1119
+ { label: "\u53F3", value: "right" }
1120
+ ],
1121
+ onChange: props.onHorizontalChange
1122
+ }
1123
+ ),
1124
+ /* @__PURE__ */ jsxRuntime.jsx(
1125
+ AlignmentSegment,
1126
+ {
1127
+ label: "\u5782\u76F4",
1128
+ value: props.vertical,
1129
+ options: [
1130
+ { label: "\u4E0A", value: "top" },
1131
+ { label: "\u4E2D", value: "middle" },
1132
+ { label: "\u4E0B", value: "bottom" }
1133
+ ],
1134
+ onChange: props.onVerticalChange
1135
+ }
1136
+ )
1137
+ ] });
1138
+ }
1139
+ function AlignmentSegment(props) {
1140
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1141
+ "div",
1142
+ {
1143
+ style: {
1144
+ display: "grid",
1145
+ gridTemplateColumns: "40px repeat(3, 1fr)",
1146
+ gap: 4,
1147
+ alignItems: "center"
1148
+ },
1149
+ children: [
1150
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: "#6b7280", fontSize: 12 }, children: props.label }),
1151
+ props.options.map((option) => /* @__PURE__ */ jsxRuntime.jsx(
1152
+ "button",
1153
+ {
1154
+ type: "button",
1155
+ className: "react-list-table-menu-action",
1156
+ style: {
1157
+ height: 28,
1158
+ border: "1px solid #d1d5db",
1159
+ borderRadius: 4,
1160
+ background: props.value === option.value ? "#e8f3ff" : "#ffffff",
1161
+ color: props.value === option.value ? "#1677ff" : "#374151",
1162
+ cursor: "pointer"
1163
+ },
1164
+ onClick: () => props.onChange(option.value),
1165
+ children: option.label
1166
+ },
1167
+ option.value
1168
+ ))
1169
+ ]
1170
+ }
1171
+ );
1172
+ }
1173
+ function DataFormatMenu(props) {
1174
+ const { request } = props;
1175
+ if (!request.onChangeDataFormat) {
1176
+ return null;
1177
+ }
1178
+ return /* @__PURE__ */ jsxRuntime.jsx(
1179
+ MenuSubmenu,
1180
+ {
1181
+ label: "\u6570\u636E\u683C\u5F0F",
1182
+ items: [
1183
+ { key: "default", label: "\u9ED8\u8BA4", value: "default" },
1184
+ { key: "number", label: "\u666E\u901A\u6570\u5B57", value: "number" },
1185
+ { key: "thousands", label: "\u5343\u4F4D\u5206\u9694", value: "thousands" },
1186
+ { key: "money", label: "\u91D1\u989D\uFF08\u4E24\u4F4D\u5C0F\u6570\uFF09", value: "money" }
1187
+ ].map((item) => ({
1188
+ key: `data-format-${item.key}`,
1189
+ label: item.label,
1190
+ selected: request.dataFormat === item.value,
1191
+ onClick: () => request.onChangeDataFormat?.(item.value)
1192
+ }))
1193
+ }
1194
+ );
1195
+ }
1064
1196
 
1065
1197
  // src/features/editor/utils.ts
1066
1198
  function toNumberValue(value) {
@@ -2301,7 +2433,15 @@ function ReactTableToolbar(props) {
2301
2433
  children: isFullscreen ? /* @__PURE__ */ jsxRuntime.jsx(FullscreenExitOutlined, {}) : /* @__PURE__ */ jsxRuntime.jsx(FullscreenOutlined, {})
2302
2434
  }
2303
2435
  ) : null,
2304
- config.showRefresh !== false ? /* @__PURE__ */ jsxRuntime.jsx(ToolButton, { label: "\u5237\u65B0", iconSize: 14, onClick: () => config.onRefresh?.(), children: /* @__PURE__ */ jsxRuntime.jsx(ReloadOutlined, {}) }) : null,
2436
+ config.showRefresh !== false ? /* @__PURE__ */ jsxRuntime.jsx(
2437
+ ToolButton,
2438
+ {
2439
+ label: "\u5237\u65B0",
2440
+ iconSize: 14,
2441
+ onClick: () => config.onRefresh?.(),
2442
+ children: /* @__PURE__ */ jsxRuntime.jsx(ReloadOutlined, {})
2443
+ }
2444
+ ) : null,
2305
2445
  config.showExport ? /* @__PURE__ */ jsxRuntime.jsx(
2306
2446
  ToolButton,
2307
2447
  {
@@ -2311,14 +2451,21 @@ function ReactTableToolbar(props) {
2311
2451
  if (config.onExport) {
2312
2452
  config.onExport();
2313
2453
  } else {
2314
- props.onExport();
2454
+ props.onExport(config.exportOptions);
2315
2455
  }
2316
2456
  },
2317
2457
  children: /* @__PURE__ */ jsxRuntime.jsx(ExportOutlined, {})
2318
2458
  }
2319
2459
  ) : null,
2320
2460
  config.showDensity !== false ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-tool-wrap", children: [
2321
- /* @__PURE__ */ jsxRuntime.jsx(ToolButton, { label: "\u8868\u683C\u5BC6\u5EA6", onClick: () => setDensityOpen((v) => !v), children: /* @__PURE__ */ jsxRuntime.jsx(ColumnHeightOutlined, {}) }),
2461
+ /* @__PURE__ */ jsxRuntime.jsx(
2462
+ ToolButton,
2463
+ {
2464
+ label: "\u8868\u683C\u5BC6\u5EA6",
2465
+ onClick: () => setDensityOpen((v) => !v),
2466
+ children: /* @__PURE__ */ jsxRuntime.jsx(ColumnHeightOutlined, {})
2467
+ }
2468
+ ),
2322
2469
  densityOpen ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "react-list-table-tool-menu", children: [48, 40, 32].map((height) => /* @__PURE__ */ jsxRuntime.jsx(
2323
2470
  "button",
2324
2471
  {
@@ -2334,7 +2481,14 @@ function ReactTableToolbar(props) {
2334
2481
  )) }) : null
2335
2482
  ] }) : null,
2336
2483
  config.showColumnSetting !== false ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-tool-wrap", children: [
2337
- /* @__PURE__ */ jsxRuntime.jsx(ToolButton, { label: "\u5217\u8BBE\u7F6E", onClick: () => setSettingOpen((v) => !v), children: /* @__PURE__ */ jsxRuntime.jsx(SettingOutlined, {}) }),
2484
+ /* @__PURE__ */ jsxRuntime.jsx(
2485
+ ToolButton,
2486
+ {
2487
+ label: "\u5217\u8BBE\u7F6E",
2488
+ onClick: () => setSettingOpen((v) => !v),
2489
+ children: /* @__PURE__ */ jsxRuntime.jsx(SettingOutlined, {})
2490
+ }
2491
+ ),
2338
2492
  settingOpen ? /* @__PURE__ */ jsxRuntime.jsxs(
2339
2493
  "div",
2340
2494
  {
@@ -2343,6 +2497,7 @@ function ReactTableToolbar(props) {
2343
2497
  children: [
2344
2498
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "react-list-table-column-setting-head", children: [
2345
2499
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "\u5217\u8BBE\u7F6E" }),
2500
+ /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginLeft: "auto" }, children: config.columnSettingHeaderExtra }),
2346
2501
  /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: props.onResetColumns, children: "\u91CD\u7F6E" })
2347
2502
  ] }),
2348
2503
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "react-list-table-column-setting-body", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -2374,6 +2529,7 @@ function ReactTableToolbar(props) {
2374
2529
  {
2375
2530
  type: "checkbox",
2376
2531
  checked: !column.hidden,
2532
+ disabled: column.disableHide,
2377
2533
  onChange: (event) => props.onColumnVisibilityChange(
2378
2534
  column.key,
2379
2535
  event.target.checked
@@ -2397,7 +2553,10 @@ function ReactTableToolbar(props) {
2397
2553
  style: { width: 80, height: 24 },
2398
2554
  onChange: (width) => {
2399
2555
  if (width != null && Number.isFinite(width) && width > 0 && (column.minWidth == null || width >= column.minWidth) && (column.maxWidth == null || width <= column.maxWidth)) {
2400
- props.onColumnWidthChange(column.key, width);
2556
+ props.onColumnWidthChange(
2557
+ column.key,
2558
+ width
2559
+ );
2401
2560
  }
2402
2561
  }
2403
2562
  }
@@ -2436,12 +2595,26 @@ function ReactTableToolbar(props) {
2436
2595
  ] });
2437
2596
  }
2438
2597
  function ToolButton(props) {
2439
- return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "react-list-table-tool", style: { fontSize: props.iconSize ?? 16 }, title: props.label, "aria-label": props.label, onClick: props.onClick, children: props.children });
2598
+ return /* @__PURE__ */ jsxRuntime.jsx(
2599
+ "button",
2600
+ {
2601
+ type: "button",
2602
+ className: "react-list-table-tool",
2603
+ style: { fontSize: props.iconSize ?? 16 },
2604
+ title: props.label,
2605
+ "aria-label": props.label,
2606
+ onClick: props.onClick,
2607
+ children: props.children
2608
+ }
2609
+ );
2440
2610
  }
2441
2611
  function flattenColumns(columns, parentKey = "root", level = 0) {
2442
2612
  return columns.flatMap((column) => {
2613
+ if (column.hideInSetting) {
2614
+ return [];
2615
+ }
2443
2616
  const key = String(column.key ?? column.dataIndex);
2444
- const label = typeof column.title === "string" ? column.title : key;
2617
+ const label = column.settingTitle ?? (typeof column.title === "string" ? column.title : key);
2445
2618
  const current = {
2446
2619
  key,
2447
2620
  label,
@@ -2452,7 +2625,8 @@ function flattenColumns(columns, parentKey = "root", level = 0) {
2452
2625
  maxWidth: typeof column.maxWidth === "number" ? column.maxWidth : void 0,
2453
2626
  fixed: column.fixed,
2454
2627
  level,
2455
- isGroup: Boolean(column.children?.length)
2628
+ isGroup: Boolean(column.children?.length),
2629
+ disableHide: column.disableHide === true
2456
2630
  };
2457
2631
  return column.children?.length ? [current, ...flattenColumns(column.children, key, level + 1)] : [current];
2458
2632
  });
@@ -2726,8 +2900,8 @@ function ReactListTableInner(props, ref) {
2726
2900
  ref,
2727
2901
  () => ({
2728
2902
  validate: () => tableRef.current?.validate() ?? Promise.resolve([]),
2729
- exportXlsx: () => {
2730
- tableRef.current?.exportXlsx();
2903
+ exportXlsx: (options2) => {
2904
+ tableRef.current?.exportXlsx(options2);
2731
2905
  },
2732
2906
  scrollTo: (options2) => {
2733
2907
  tableRef.current?.scrollTo(options2);
@@ -2764,7 +2938,7 @@ function ReactListTableInner(props, ref) {
2764
2938
  columns: resolvedColumns,
2765
2939
  density: resolvedRowHeight === "auto" ? 40 : resolvedRowHeight ?? 40,
2766
2940
  hostRef: shellRef,
2767
- onExport: () => tableRef.current?.exportXlsx(),
2941
+ onExport: (options2) => tableRef.current?.exportXlsx(options2),
2768
2942
  onDensityChange: setDensityOverride,
2769
2943
  onColumnVisibilityChange: (columnKey, visible) => {
2770
2944
  setColumnVisibility((current) => {
@@ -2882,15 +3056,13 @@ function ReactListTableInner(props, ref) {
2882
3056
  }
2883
3057
  function applyColumnManagerState(columns, visibility, orders, config, parentKey = "root") {
2884
3058
  const order = orders.get(parentKey);
2885
- const sortedColumns = order ? [...columns].sort(
2886
- (left, right) => order.indexOf(resolveColumnKey(left)) - order.indexOf(resolveColumnKey(right))
2887
- ) : columns;
3059
+ const sortedColumns = order ? applyManagedColumnOrder(columns, order) : columns;
2888
3060
  return sortedColumns.map((column) => {
2889
3061
  const key = resolveColumnKey(column);
2890
3062
  const managedConfig = config.get(key);
2891
3063
  return {
2892
3064
  ...column,
2893
- hidden: visibility.has(key) ? visibility.get(key) === false : column.hidden,
3065
+ hidden: visibility.has(key) ? visibility.get(key) === false : column.hidden ?? column.initialHide,
2894
3066
  width: managedConfig?.width ?? column.width,
2895
3067
  minWidth: column.minWidth,
2896
3068
  maxWidth: column.maxWidth,
@@ -2905,6 +3077,24 @@ function applyColumnManagerState(columns, visibility, orders, config, parentKey
2905
3077
  };
2906
3078
  });
2907
3079
  }
3080
+ function applyManagedColumnOrder(columns, orderedKeys) {
3081
+ const managedKeySet = new Set(orderedKeys);
3082
+ const managedSlots = columns.map(
3083
+ (column, index) => managedKeySet.has(resolveColumnKey(column)) ? index : -1
3084
+ ).filter((index) => index >= 0);
3085
+ const columnByKey = new Map(
3086
+ columns.map((column) => [resolveColumnKey(column), column])
3087
+ );
3088
+ const next = [...columns];
3089
+ orderedKeys.forEach((key, index) => {
3090
+ const slot = managedSlots[index];
3091
+ const column = columnByKey.get(key);
3092
+ if (slot != null && column) {
3093
+ next[slot] = column;
3094
+ }
3095
+ });
3096
+ return next;
3097
+ }
2908
3098
  function resolveColumnKey(column) {
2909
3099
  return String(column.key ?? column.dataIndex);
2910
3100
  }