@canvas-components/react-list-table 0.3.20 → 0.3.21

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
@@ -1,6 +1,6 @@
1
1
  import { createContext, forwardRef, useMemo, useRef, useState, useImperativeHandle, useContext, useEffect, useLayoutEffect, Fragment as Fragment$1 } from 'react';
2
2
  import { createPortal } from 'react-dom';
3
- import { ReactImagePreview, ReactCheckbox, ReactNumberInput, ReactSelect, ReactPagination, ReactFilterPanel, ReactPopup, ReactModal, ReactInput, ReactPopconfirm, ReactContentScaleProvider, ReactButton, ReactColorPicker, ReactInputNumber, ReactAutoComplete, ReactTimeRangePicker, ReactDateTimeRangePicker, ReactDateTimePicker, ReactTimePicker, ReactDateRangePicker, ReactDatePicker, ReactMonthPicker, ReactQuarterPicker, ReactYearPicker, ReactInputRange, ReactCascader } from '@canvas-components/react-components';
3
+ import { ReactImagePreview, ReactCheckbox, ReactNumberInput, ReactSelect, ReactPagination, ReactFilterPanel, ReactPopup, ReactModal, ReactInput, ReactPopconfirm, ReactContentScaleProvider, ReactButton, ReactColorPicker, ReactInputNumber, ReactAutoComplete, ReactTimeRangePicker, ReactDateTimeRangePicker, ReactDateTimePicker, ReactTimePicker, ReactDateRangePicker, ReactDatePicker, ReactMonthPicker, ReactQuarterPicker, ReactYearPicker, ReactInputRange, ReactCascader, ReactTreeSelect } from '@canvas-components/react-components';
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';
@@ -2679,6 +2679,58 @@ var toolButtonStyle = {
2679
2679
  lineHeight: 1,
2680
2680
  cursor: "pointer"
2681
2681
  };
2682
+ function ReactListTableExportNameDialog({
2683
+ request
2684
+ }) {
2685
+ const extension = request.fileName.match(/\.(xlsx|csv|txt|json)$/i)?.[0] ?? "";
2686
+ const [fileName, setFileName] = useState(
2687
+ extension ? request.fileName.slice(0, -extension.length) : request.fileName
2688
+ );
2689
+ const [invalid, setInvalid] = useState(false);
2690
+ const confirm = () => {
2691
+ if (!fileName.trim()) {
2692
+ setInvalid(true);
2693
+ return;
2694
+ }
2695
+ request.onConfirm(`${fileName.trim()}${extension}`);
2696
+ };
2697
+ return /* @__PURE__ */ jsxs(
2698
+ ReactModal,
2699
+ {
2700
+ open: true,
2701
+ title: "\u5BFC\u51FA\u6587\u4EF6",
2702
+ width: 420,
2703
+ fullscreenable: false,
2704
+ onCancel: request.onCancel,
2705
+ onOk: confirm,
2706
+ okText: "\u5BFC\u51FA",
2707
+ cancelText: "\u53D6\u6D88",
2708
+ children: [
2709
+ /* @__PURE__ */ jsxs("label", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [
2710
+ "\u6587\u4EF6\u540D\u79F0",
2711
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
2712
+ /* @__PURE__ */ jsx(
2713
+ ReactInput,
2714
+ {
2715
+ autoFocus: true,
2716
+ value: fileName,
2717
+ placeholder: "\u8BF7\u8F93\u5165\u6587\u4EF6\u540D\u79F0",
2718
+ onFocus: (event) => event.target.select(),
2719
+ onChange: (event) => {
2720
+ setFileName(event.target.value);
2721
+ setInvalid(false);
2722
+ },
2723
+ onPressEnter: confirm
2724
+ }
2725
+ ),
2726
+ /* @__PURE__ */ jsx("span", { "aria-label": "\u6587\u4EF6\u540E\u7F00", style: { flexShrink: 0 }, children: extension })
2727
+ ] })
2728
+ ] }),
2729
+ invalid ? /* @__PURE__ */ jsx("div", { role: "alert", style: { color: "#ff4d4f", marginTop: 8 }, children: "\u8BF7\u8F93\u5165\u6587\u4EF6\u540D\u79F0" }) : null
2730
+ ]
2731
+ }
2732
+ );
2733
+ }
2682
2734
 
2683
2735
  // src/features/editor/utils.ts
2684
2736
  function toNumberValue(value) {
@@ -2780,12 +2832,14 @@ function ReactTableEditorOverlay(props) {
2780
2832
  if (!input) {
2781
2833
  return;
2782
2834
  }
2783
- focusAndSelectEditorInput(input);
2835
+ focusAndSelectEditorInput(input, request.selectOnFocus);
2784
2836
  }, [request]);
2785
2837
  return /* @__PURE__ */ jsx(ReactContentScaleProvider, { scale: contentZoom, children: /* @__PURE__ */ jsx("div", { ref: editorHostRef, children: renderEditorByType(request, style) }, request.editorKey) });
2786
2838
  }
2787
2839
  function renderEditorByType(request, style) {
2788
2840
  switch (request.config.valueType ?? "text") {
2841
+ case "tree-select":
2842
+ return /* @__PURE__ */ jsx(TreeSelectEditor, { request, style });
2789
2843
  case "cascader":
2790
2844
  return /* @__PURE__ */ jsx(CascaderEditor, { request, style });
2791
2845
  case "number":
@@ -2827,7 +2881,7 @@ function TextEditor(props) {
2827
2881
  const skipBlurCommitRef = useRef(false);
2828
2882
  useLayoutEffect(() => {
2829
2883
  const input = hostRef.current?.querySelector("input");
2830
- focusAndSelectEditorInput(input);
2884
+ focusAndSelectEditorInput(input, request.selectOnFocus);
2831
2885
  }, [request]);
2832
2886
  useEffect(() => {
2833
2887
  setValue(String(request.value ?? ""));
@@ -2867,7 +2921,7 @@ function NumberEditor(props) {
2867
2921
  const skipBlurCommitRef = useRef(false);
2868
2922
  useLayoutEffect(() => {
2869
2923
  const input = hostRef.current?.querySelector("input");
2870
- focusAndSelectEditorInput(input);
2924
+ focusAndSelectEditorInput(input, request.selectOnFocus);
2871
2925
  }, [request]);
2872
2926
  useEffect(() => {
2873
2927
  setValue(toNumberValue(request.value));
@@ -3076,14 +3130,56 @@ function DateEditor(props) {
3076
3130
  }
3077
3131
  ) });
3078
3132
  }
3079
- function CascaderEditor({
3133
+ function TreeSelectEditor({
3080
3134
  request,
3081
3135
  style
3082
3136
  }) {
3083
3137
  const [value, setValue] = useState(
3084
- Array.isArray(request.value) ? request.value : []
3138
+ request.value ?? null
3085
3139
  );
3086
3140
  const skipBlurCommitRef = useRef(false);
3141
+ useEffect(() => {
3142
+ setValue(request.value ?? null);
3143
+ }, [request.value]);
3144
+ return /* @__PURE__ */ jsx("div", { style, children: /* @__PURE__ */ jsx(
3145
+ ReactTreeSelect,
3146
+ {
3147
+ autoFocus: true,
3148
+ value,
3149
+ treeData: request.config.treeData,
3150
+ multiple: request.config.multiple,
3151
+ showSearch: request.config.showSearch,
3152
+ treeDefaultExpandAll: request.config.treeDefaultExpandAll,
3153
+ treeDefaultExpandedKeys: request.config.treeDefaultExpandedKeys,
3154
+ allowClear: request.config.allowClear,
3155
+ placeholder: request.config.placeholder,
3156
+ style: getEditorInputStyle(request),
3157
+ onChange: (next, _nodes, info) => {
3158
+ setValue(next);
3159
+ request.onChange(next);
3160
+ if (info.complete && info.trigger !== "clear") {
3161
+ skipBlurCommitRef.current = true;
3162
+ request.onCommit();
3163
+ }
3164
+ },
3165
+ onBlur: (event) => handleEditorBlur(event, skipBlurCommitRef, request),
3166
+ onKeyDown: (event) => {
3167
+ if (event.key === "Tab")
3168
+ handleEditorNavigationKey(event, request, skipBlurCommitRef);
3169
+ if (event.key === "Escape") {
3170
+ skipBlurCommitRef.current = true;
3171
+ handleEditorEscapeKey(event, request);
3172
+ }
3173
+ }
3174
+ }
3175
+ ) });
3176
+ }
3177
+ function CascaderEditor({
3178
+ request,
3179
+ style
3180
+ }) {
3181
+ const [value, setValue] = useState(Array.isArray(request.value) ? request.value : []);
3182
+ const skipBlurCommitRef = useRef(false);
3087
3183
  useEffect(() => {
3088
3184
  setValue(Array.isArray(request.value) ? request.value : []);
3089
3185
  }, [request.value]);
@@ -3097,6 +3193,8 @@ function CascaderEditor({
3097
3193
  showSearch: request.config.showSearch,
3098
3194
  allowClear: request.config.allowClear,
3099
3195
  changeOnSelect: request.config.changeOnSelect,
3196
+ multiple: request.config.multiple,
3197
+ showCheckedStrategy: request.config.showCheckedStrategy,
3100
3198
  expandTrigger: request.config.expandTrigger,
3101
3199
  displayRender: request.config.displayRender,
3102
3200
  style: getEditorInputStyle(request),
@@ -3450,13 +3548,14 @@ function handleRangeInputTab(event) {
3450
3548
  focusAndSelectEditorInput(nextInput);
3451
3549
  return true;
3452
3550
  }
3453
- function focusAndSelectEditorInput(input) {
3551
+ function focusAndSelectEditorInput(input, selectOnFocus = true) {
3454
3552
  if (!input) {
3455
3553
  return;
3456
3554
  }
3457
3555
  input.focus();
3458
3556
  try {
3459
- input.select();
3557
+ if (selectOnFocus) input.select();
3558
+ else input.setSelectionRange(input.value.length, input.value.length);
3460
3559
  } catch {
3461
3560
  }
3462
3561
  }
@@ -4222,9 +4321,14 @@ function useReactListTableState(options) {
4222
4321
  const [searchRequest, setSearchRequest] = useState(null);
4223
4322
  const [imagePreviewRequest, setImagePreviewRequest] = useState(null);
4224
4323
  const [dangerConfirmRequest, setDangerConfirmRequest] = useState(null);
4324
+ const [exportNameRequest, setExportNameRequest] = useState(null);
4225
4325
  const uiOptions = useMemo(
4226
4326
  () => ({
4227
4327
  ...options.ui,
4328
+ onExportNameRequest: (request) => {
4329
+ setExportNameRequest(request);
4330
+ options.ui?.onExportNameRequest?.(request);
4331
+ },
4228
4332
  onEditorRequest: (request) => {
4229
4333
  setEditorRequest(request);
4230
4334
  options.ui?.onEditorRequest?.(request);
@@ -4292,6 +4396,7 @@ function useReactListTableState(options) {
4292
4396
  setSearchRequest(null);
4293
4397
  setImagePreviewRequest(null);
4294
4398
  setDangerConfirmRequest(null);
4399
+ setExportNameRequest(null);
4295
4400
  };
4296
4401
  }, []);
4297
4402
  useEffect(() => {
@@ -4313,6 +4418,7 @@ function useReactListTableState(options) {
4313
4418
  searchRequest,
4314
4419
  imagePreviewRequest,
4315
4420
  dangerConfirmRequest,
4421
+ exportNameRequest,
4316
4422
  closeDangerConfirmRequest: () => {
4317
4423
  setDangerConfirmRequest(null);
4318
4424
  options.ui?.onDangerConfirmRequest?.(null);
@@ -4417,7 +4523,8 @@ function ReactListTableInner(props, ref) {
4417
4523
  rowDrag,
4418
4524
  debug,
4419
4525
  title,
4420
- toolbar
4526
+ toolbar,
4527
+ exportOptions
4421
4528
  } = props;
4422
4529
  const inheritedDebugEnabled = useReactListTableDebugEnabled();
4423
4530
  const resolvedDebug = useMemo(
@@ -4458,6 +4565,7 @@ function ReactListTableInner(props, ref) {
4458
4565
  );
4459
4566
  const options = useMemo(() => {
4460
4567
  const nextOptions = buildListTableOptions({
4568
+ exportOptions,
4461
4569
  width,
4462
4570
  height,
4463
4571
  emptyText,
@@ -4519,6 +4627,7 @@ function ReactListTableInner(props, ref) {
4519
4627
  }
4520
4628
  };
4521
4629
  }, [
4630
+ exportOptions,
4522
4631
  width,
4523
4632
  height,
4524
4633
  emptyText,
@@ -4574,6 +4683,7 @@ function ReactListTableInner(props, ref) {
4574
4683
  searchRequest,
4575
4684
  imagePreviewRequest,
4576
4685
  dangerConfirmRequest,
4686
+ exportNameRequest,
4577
4687
  closeDangerConfirmRequest
4578
4688
  } = useReactListTableState(options);
4579
4689
  const hasPagination = paginationConfig != null;
@@ -4753,6 +4863,10 @@ function ReactListTableInner(props, ref) {
4753
4863
  /* @__PURE__ */ jsx(ReactListTableSearchDialog, { request: searchRequest }),
4754
4864
  document.body
4755
4865
  ) : null,
4866
+ exportNameRequest ? createPortal(
4867
+ /* @__PURE__ */ jsx(ReactListTableExportNameDialog, { request: exportNameRequest }),
4868
+ document.body
4869
+ ) : null,
4756
4870
  dangerConfirmRequest ? createPortal(
4757
4871
  /* @__PURE__ */ jsx(
4758
4872
  ReactTableDangerConfirmView,