@canvas-components/react-list-table 0.3.20 → 0.3.22
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/README.md +2 -0
- package/dist/index.cjs +138 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +139 -18
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
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
|
|
3133
|
+
function TreeSelectEditor({
|
|
3080
3134
|
request,
|
|
3081
3135
|
style
|
|
3082
3136
|
}) {
|
|
3083
3137
|
const [value, setValue] = useState(
|
|
3084
|
-
|
|
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
|
}
|
|
@@ -3767,6 +3866,12 @@ function SettingOutlined() {
|
|
|
3767
3866
|
function HolderOutlined() {
|
|
3768
3867
|
return /* @__PURE__ */ jsx(ToolbarIcon, { path: "M300 276.5a56 56 0 1056-97 56 56 0 00-56 97zm0 284a56 56 0 1056-97 56 56 0 00-56 97zM640 228a56 56 0 10112 0 56 56 0 00-112 0zm0 284a56 56 0 10112 0 56 56 0 00-112 0zM300 844.5a56 56 0 1056-97 56 56 0 00-56 97zM640 796a56 56 0 10112 0 56 56 0 00-112 0z" });
|
|
3769
3868
|
}
|
|
3869
|
+
|
|
3870
|
+
// src/components/fullscreen-portal.ts
|
|
3871
|
+
function resolveFullscreenPortalContainer(host) {
|
|
3872
|
+
const fullscreenElement = document.fullscreenElement;
|
|
3873
|
+
return fullscreenElement instanceof HTMLElement && host && fullscreenElement.contains(host) ? fullscreenElement : document.body;
|
|
3874
|
+
}
|
|
3770
3875
|
function SortableList(props) {
|
|
3771
3876
|
const { items, onOrderChange } = props;
|
|
3772
3877
|
const rootRef = useRef(null);
|
|
@@ -3891,7 +3996,7 @@ function SortableList(props) {
|
|
|
3891
3996
|
})
|
|
3892
3997
|
}
|
|
3893
3998
|
),
|
|
3894
|
-
|
|
3999
|
+
resolveFullscreenPortalContainer(rootRef.current)
|
|
3895
4000
|
) : null
|
|
3896
4001
|
] });
|
|
3897
4002
|
}
|
|
@@ -4222,9 +4327,14 @@ function useReactListTableState(options) {
|
|
|
4222
4327
|
const [searchRequest, setSearchRequest] = useState(null);
|
|
4223
4328
|
const [imagePreviewRequest, setImagePreviewRequest] = useState(null);
|
|
4224
4329
|
const [dangerConfirmRequest, setDangerConfirmRequest] = useState(null);
|
|
4330
|
+
const [exportNameRequest, setExportNameRequest] = useState(null);
|
|
4225
4331
|
const uiOptions = useMemo(
|
|
4226
4332
|
() => ({
|
|
4227
4333
|
...options.ui,
|
|
4334
|
+
onExportNameRequest: (request) => {
|
|
4335
|
+
setExportNameRequest(request);
|
|
4336
|
+
options.ui?.onExportNameRequest?.(request);
|
|
4337
|
+
},
|
|
4228
4338
|
onEditorRequest: (request) => {
|
|
4229
4339
|
setEditorRequest(request);
|
|
4230
4340
|
options.ui?.onEditorRequest?.(request);
|
|
@@ -4292,6 +4402,7 @@ function useReactListTableState(options) {
|
|
|
4292
4402
|
setSearchRequest(null);
|
|
4293
4403
|
setImagePreviewRequest(null);
|
|
4294
4404
|
setDangerConfirmRequest(null);
|
|
4405
|
+
setExportNameRequest(null);
|
|
4295
4406
|
};
|
|
4296
4407
|
}, []);
|
|
4297
4408
|
useEffect(() => {
|
|
@@ -4313,6 +4424,7 @@ function useReactListTableState(options) {
|
|
|
4313
4424
|
searchRequest,
|
|
4314
4425
|
imagePreviewRequest,
|
|
4315
4426
|
dangerConfirmRequest,
|
|
4427
|
+
exportNameRequest,
|
|
4316
4428
|
closeDangerConfirmRequest: () => {
|
|
4317
4429
|
setDangerConfirmRequest(null);
|
|
4318
4430
|
options.ui?.onDangerConfirmRequest?.(null);
|
|
@@ -4417,7 +4529,8 @@ function ReactListTableInner(props, ref) {
|
|
|
4417
4529
|
rowDrag,
|
|
4418
4530
|
debug,
|
|
4419
4531
|
title,
|
|
4420
|
-
toolbar
|
|
4532
|
+
toolbar,
|
|
4533
|
+
exportOptions
|
|
4421
4534
|
} = props;
|
|
4422
4535
|
const inheritedDebugEnabled = useReactListTableDebugEnabled();
|
|
4423
4536
|
const resolvedDebug = useMemo(
|
|
@@ -4458,6 +4571,7 @@ function ReactListTableInner(props, ref) {
|
|
|
4458
4571
|
);
|
|
4459
4572
|
const options = useMemo(() => {
|
|
4460
4573
|
const nextOptions = buildListTableOptions({
|
|
4574
|
+
exportOptions,
|
|
4461
4575
|
width,
|
|
4462
4576
|
height,
|
|
4463
4577
|
emptyText,
|
|
@@ -4519,6 +4633,7 @@ function ReactListTableInner(props, ref) {
|
|
|
4519
4633
|
}
|
|
4520
4634
|
};
|
|
4521
4635
|
}, [
|
|
4636
|
+
exportOptions,
|
|
4522
4637
|
width,
|
|
4523
4638
|
height,
|
|
4524
4639
|
emptyText,
|
|
@@ -4574,10 +4689,12 @@ function ReactListTableInner(props, ref) {
|
|
|
4574
4689
|
searchRequest,
|
|
4575
4690
|
imagePreviewRequest,
|
|
4576
4691
|
dangerConfirmRequest,
|
|
4692
|
+
exportNameRequest,
|
|
4577
4693
|
closeDangerConfirmRequest
|
|
4578
4694
|
} = useReactListTableState(options);
|
|
4579
4695
|
const hasPagination = paginationConfig != null;
|
|
4580
4696
|
const paginationLayout = resolveReactListTablePaginationLayout(resolvedRowHeight);
|
|
4697
|
+
const portalContainer = resolveFullscreenPortalContainer(shellRef.current);
|
|
4581
4698
|
useImperativeHandle(
|
|
4582
4699
|
ref,
|
|
4583
4700
|
() => ({
|
|
@@ -4735,23 +4852,27 @@ function ReactListTableInner(props, ref) {
|
|
|
4735
4852
|
),
|
|
4736
4853
|
tooltipRequest ? createPortal(
|
|
4737
4854
|
/* @__PURE__ */ jsx(ReactTableTooltipView, { request: tooltipRequest }),
|
|
4738
|
-
|
|
4855
|
+
portalContainer
|
|
4739
4856
|
) : null,
|
|
4740
4857
|
filterPanelRequest ? createPortal(
|
|
4741
4858
|
/* @__PURE__ */ jsx(ReactTableFilterPanelView, { request: filterPanelRequest }),
|
|
4742
|
-
|
|
4859
|
+
portalContainer
|
|
4743
4860
|
) : null,
|
|
4744
4861
|
fixedPopupRequest ? createPortal(
|
|
4745
4862
|
/* @__PURE__ */ jsx(ReactTableFixedPopupView, { request: fixedPopupRequest }),
|
|
4746
|
-
|
|
4863
|
+
portalContainer
|
|
4747
4864
|
) : null,
|
|
4748
4865
|
headerContextMenuRequest ? createPortal(
|
|
4749
4866
|
/* @__PURE__ */ jsx(ReactTableContextMenuView, { request: headerContextMenuRequest }),
|
|
4750
|
-
|
|
4867
|
+
portalContainer
|
|
4751
4868
|
) : null,
|
|
4752
4869
|
searchRequest ? createPortal(
|
|
4753
4870
|
/* @__PURE__ */ jsx(ReactListTableSearchDialog, { request: searchRequest }),
|
|
4754
|
-
|
|
4871
|
+
portalContainer
|
|
4872
|
+
) : null,
|
|
4873
|
+
exportNameRequest ? createPortal(
|
|
4874
|
+
/* @__PURE__ */ jsx(ReactListTableExportNameDialog, { request: exportNameRequest }),
|
|
4875
|
+
portalContainer
|
|
4755
4876
|
) : null,
|
|
4756
4877
|
dangerConfirmRequest ? createPortal(
|
|
4757
4878
|
/* @__PURE__ */ jsx(
|
|
@@ -4761,11 +4882,11 @@ function ReactListTableInner(props, ref) {
|
|
|
4761
4882
|
onClose: closeDangerConfirmRequest
|
|
4762
4883
|
}
|
|
4763
4884
|
),
|
|
4764
|
-
|
|
4885
|
+
portalContainer
|
|
4765
4886
|
) : null,
|
|
4766
4887
|
editorRequest ? createPortal(
|
|
4767
4888
|
/* @__PURE__ */ jsx(ReactTableEditorOverlay, { request: editorRequest }),
|
|
4768
|
-
editorRequest.hostElement
|
|
4889
|
+
editorRequest.hostElement && portalContainer.contains(editorRequest.hostElement) ? editorRequest.hostElement : portalContainer
|
|
4769
4890
|
) : null,
|
|
4770
4891
|
imagePreviewRequest ? createPortal(
|
|
4771
4892
|
/* @__PURE__ */ jsx(
|
|
@@ -4777,7 +4898,7 @@ function ReactListTableInner(props, ref) {
|
|
|
4777
4898
|
onClose: imagePreviewRequest.onClose
|
|
4778
4899
|
}
|
|
4779
4900
|
),
|
|
4780
|
-
|
|
4901
|
+
portalContainer
|
|
4781
4902
|
) : null
|
|
4782
4903
|
] });
|
|
4783
4904
|
}
|