@hzab/edit-table 0.1.9 → 0.1.11

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.
@@ -1,242 +1,255 @@
1
- import { useEffect, useMemo, useRef, useState } from "react";
2
-
3
- import type {
4
- Cell,
5
- CellTemplate,
6
- Compatible,
7
- Uncertain,
8
- UncertainCompatible} from "@silevis/reactgrid";
9
- import {
10
- getCellProperty,
11
- getCharFromKey,
12
- isAlphaNumericKey,
13
- isNavigationKey,
14
- keyCodes
15
- } from "@silevis/reactgrid";
16
- import { InfoCircleOutlined } from "@ant-design/icons";
17
- import { Popover } from "antd";
18
- import { isTriggerBlur } from "./childAntdComponent";
19
- export type OptionType = {
20
- label: string;
21
- value: string | number;
22
- isDisabled?: boolean;
23
- };
24
-
25
- export interface BaseCell extends Cell {
26
- selectedValue?: string;
27
- value: string | number;
28
- values: OptionType[];
29
- isDisabled?: boolean;
30
- }
31
- interface DIProps {
32
- onCellChanged: (...args: any[]) => void;
33
- cell: Record<string, any>;
34
- isInEditMode?: boolean;
35
- }
36
-
37
- export const WidthWrapHoc = (WrapComponent: any, props = {}) => {
38
- class createBaseCellTemplate implements CellTemplate<BaseCell> {
39
- getCompatibleCell(uncertainCell: Uncertain<BaseCell>): Compatible<BaseCell> {
40
- let values: any;
41
- try {
42
- values = getCellProperty(uncertainCell, "values", "object");
43
- } catch {
44
- values = [];
45
- }
46
- const value = uncertainCell.selectedValue ? parseFloat(uncertainCell.selectedValue) : NaN;
47
- let isDisabled = true;
48
- try {
49
- isDisabled = getCellProperty(uncertainCell, "isDisabled", "boolean");
50
- } catch {
51
- isDisabled = false;
52
- }
53
- const selectedValue = uncertainCell.selectedValue;
54
- const text = selectedValue || "";
55
- return { ...uncertainCell, selectedValue, text, value, values, isDisabled };
56
- }
57
-
58
- update(cell: Compatible<BaseCell>, cellToMerge: UncertainCompatible<BaseCell>): Compatible<BaseCell> {
59
- const selectedValueFromText = cell.values.some((val: any) => val.value == cellToMerge.text)
60
- ? cellToMerge.text
61
- : cellToMerge?.text || undefined;
62
-
63
- return this.getCompatibleCell({
64
- ...cell,
65
- selectedValue: selectedValueFromText,
66
- });
67
- }
68
-
69
- getClassName(cell: Compatible<BaseCell>, isInEditMode: boolean): string {
70
- return "";
71
- }
72
- /** enableEditMode为true 时输入中文会报错 */
73
- handleCompositionEnd(
74
- cell: Compatible<BaseCell>,
75
- eventData: any,
76
- ): { cell: Compatible<BaseCell>; enableEditMode: boolean } {
77
- return {
78
- cell: {
79
- ...cell,
80
- },
81
- enableEditMode: false,
82
- };
83
- }
84
- /** render 不能抽出来组件,否则点击会失效 */
85
- render(cell: any, isInEditMode: boolean, onCellChanged: (cell: any, commit: boolean) => void): React.ReactNode {
86
- const [edit, setEdit] = useState<boolean>(false);
87
- const [open, setOpen] = useState<boolean>(false);
88
- const datatypeId = cell?.columnId + cell?.rowId;
89
- const [comValue, setComValue] = useState(cell?.text);
90
- const [isValidator, setIsValidator] = useState(false);
91
- const comValueInit = useRef<any>(cell?.text);
92
- const openTimerRef = useRef<any>();
93
- useEffect(() => {
94
- setComValue(cell?.text);
95
- comValueInit.current = cell?.text;
96
- }, [cell?.text]);
97
-
98
- useEffect(() => {
99
- // 处理下拉选项弹层失焦逻辑
100
- function onClick(e) {
101
- if ((window as any).gridEditId != datatypeId) {
102
- setEdit(false);
103
- }
104
- }
105
- document.addEventListener("click", onClick);
106
- return () => {
107
- document.removeEventListener("click", onClick);
108
- };
109
- }, []);
110
-
111
- /** 校验触发器 */
112
- const onValidator = (val) => {
113
- let flag = false;
114
- let isVerify = false;
115
- for (const it of cell?.validatorList || []) {
116
- if (it?.pattern?.test(val)) {
117
- flag = true;
118
- }
119
- break;
120
- }
121
- isVerify = !flag && Array.isArray(cell?.validatorList) && cell?.validatorList?.length > 0;
122
- setIsValidator(isVerify);
123
- };
124
-
125
- useEffect(() => {
126
- if (!open) return;
127
- // 等下一帧,弹窗DOM渲染完成
128
- const timer = setTimeout(() => {
129
- const popup: any = document.querySelector(".ant-picker-dropdown");
130
- if (!popup) return;
131
-
132
- const stopPointer = (e: PointerEvent) => {
133
- // 阻断事件往上冒泡到document
134
- e.stopPropagation();
135
- };
136
- // 捕获阶段监听 pointerdown!!必须是pointerdown不是mousedown
137
- popup.addEventListener("pointerdown", stopPointer, true);
138
-
139
- // 清理函数
140
- return () => {
141
- popup.removeEventListener("pointerdown", stopPointer, true);
142
- };
143
- }, 0);
144
-
145
- return () => clearTimeout(timer);
146
- }, [open]);
147
-
148
- /** 失焦提交 */
149
- const onBlurSubmit = () => {
150
- const targetValue = comValueInit.current;
151
- onCellChanged(
152
- this.getCompatibleCell({
153
- ...cell,
154
- text: targetValue,
155
- selectedValue: targetValue,
156
- }),
157
- true,
158
- );
159
- };
160
-
161
- const dataPickerProps = useMemo(() => {
162
- if (isTriggerBlur?.includes(cell?.type)) {
163
- return {
164
- open: open,
165
- /** 兼容datapicker 闪烁问题 */
166
- onOpenChange: (isOpen) => {
167
- if (openTimerRef.current) {
168
- clearTimeout(openTimerRef.current);
169
- }
170
- openTimerRef.current = setTimeout(() => {
171
- setOpen(isOpen);
172
- }, 80);
173
- },
174
- };
175
- }
176
- return {};
177
- }, [cell]);
178
- /** 监听上传组件失焦回调 */
179
- useEffect(() => {
180
- if (!edit && cell.type == "Upload" && (window as any).uploadEdit && (window as any).uploadEdit == datatypeId) {
181
- (window as any).uploadEdit = null;
182
- onBlurSubmit();
183
- }
184
- }, [edit, comValue]);
185
-
186
- return (
187
- <div
188
- className={`base-hoc ${edit ? "base-hoc-edit" : ""}`}
189
- onDoubleClick={(e) => {
190
- if (cell?.nonEditable) {
191
- return;
192
- }
193
- if (cell.type === "Upload") {
194
- (window as any).uploadEdit = datatypeId;
195
- }
196
- setEdit(true);
197
- }}
198
- >
199
- <WrapComponent
200
- {...props}
201
- onPointerDown={(e) => e.stopPropagation()}
202
- componentProps={{
203
- style: { width: "100%", display: "flex", alignItems: "center" },
204
- value: comValue,
205
- options: cell.values,
206
- onChange: (e) => {
207
- const targetValue = e?.target?.value ?? e;
208
- setComValue(targetValue);
209
- comValueInit.current = targetValue;
210
- onValidator(targetValue);
211
- },
212
- onBlur: (e) => {
213
- onBlurSubmit();
214
- if (!isTriggerBlur?.includes(cell?.type)) {
215
- setEdit(false);
216
- }
217
- },
218
-
219
- onPointerDown: (e) => {
220
- e.stopPropagation();
221
- },
222
- onKeyDown: (e) => {
223
- if (isAlphaNumericKey(e.keyCode) || isNavigationKey(e.keyCode)) e.stopPropagation();
224
- },
225
- ...dataPickerProps,
226
- ...((cell?.getField && cell?.getField()["x-component-props"]) || {}),
227
- }}
228
- pattern={edit ? "" : "readPretty"}
229
- cell={cell}
230
- ></WrapComponent>
231
- {isValidator && (
232
- <Popover content={cell?.validatorMessage ?? "该字段不合法"}>
233
- <InfoCircleOutlined className="validator-icon" />
234
- </Popover>
235
- )}
236
- </div>
237
- );
238
- }
239
- }
240
-
241
- return new createBaseCellTemplate();
242
- };
1
+ import { useEffect, useMemo, useRef, useState } from "react";
2
+
3
+ import type {
4
+ Cell,
5
+ CellTemplate,
6
+ Compatible,
7
+ Uncertain,
8
+ UncertainCompatible,
9
+ } from "@silevis/reactgrid";
10
+ import {
11
+ getCellProperty,
12
+ getCharFromKey,
13
+ isAlphaNumericKey,
14
+ isNavigationKey,
15
+ keyCodes,
16
+ } from "@silevis/reactgrid";
17
+ import { InfoCircleOutlined } from "@ant-design/icons";
18
+ import { Popover } from "antd";
19
+ import { isTriggerBlur } from "./childAntdComponent";
20
+ export type OptionType = {
21
+ label: string;
22
+ value: string | number;
23
+ isDisabled?: boolean;
24
+ };
25
+
26
+ export interface BaseCell extends Cell {
27
+ selectedValue?: string;
28
+ value: string | number;
29
+ values: OptionType[];
30
+ isDisabled?: boolean;
31
+ }
32
+ interface DIProps {
33
+ onCellChanged: (...args: any[]) => void;
34
+ cell: Record<string, any>;
35
+ isInEditMode?: boolean;
36
+ }
37
+
38
+ export const WidthWrapHoc = (WrapComponent: any, props = {}) => {
39
+ class createBaseCellTemplate implements CellTemplate<BaseCell> {
40
+ getCompatibleCell(uncertainCell: Uncertain<BaseCell>): Compatible<BaseCell> {
41
+ let values: any;
42
+ try {
43
+ values = getCellProperty(uncertainCell, "values", "object");
44
+ } catch {
45
+ values = [];
46
+ }
47
+ const value = uncertainCell.selectedValue ? parseFloat(uncertainCell.selectedValue) : NaN;
48
+ let isDisabled = true;
49
+ try {
50
+ isDisabled = getCellProperty(uncertainCell, "isDisabled", "boolean");
51
+ } catch {
52
+ isDisabled = false;
53
+ }
54
+ const selectedValue = uncertainCell.selectedValue;
55
+ const text = selectedValue || "";
56
+ return { ...uncertainCell, selectedValue, text, value, values, isDisabled };
57
+ }
58
+
59
+ update(
60
+ cell: Compatible<BaseCell>,
61
+ cellToMerge: UncertainCompatible<BaseCell>,
62
+ ): Compatible<BaseCell> {
63
+ const selectedValueFromText = cell.values.some((val: any) => val.value == cellToMerge.text)
64
+ ? cellToMerge.text
65
+ : cellToMerge?.text || undefined;
66
+
67
+ return this.getCompatibleCell({
68
+ ...cell,
69
+ selectedValue: selectedValueFromText,
70
+ });
71
+ }
72
+
73
+ getClassName(cell: Compatible<BaseCell>, isInEditMode: boolean): string {
74
+ return "";
75
+ }
76
+ /** enableEditMode为true 时输入中文会报错 */
77
+ handleCompositionEnd(
78
+ cell: Compatible<BaseCell>,
79
+ eventData: any,
80
+ ): { cell: Compatible<BaseCell>; enableEditMode: boolean } {
81
+ return {
82
+ cell: {
83
+ ...cell,
84
+ },
85
+ enableEditMode: false,
86
+ };
87
+ }
88
+ /** render 不能抽出来组件,否则点击会失效 */
89
+ render(
90
+ cell: any,
91
+ isInEditMode: boolean,
92
+ onCellChanged: (cell: any, commit: boolean) => void,
93
+ ): React.ReactNode {
94
+ const [edit, setEdit] = useState<boolean>(false);
95
+ const [open, setOpen] = useState<boolean>(false);
96
+ const datatypeId = cell?.columnId + cell?.rowId;
97
+ const [comValue, setComValue] = useState(cell?.text);
98
+ const [isValidator, setIsValidator] = useState(false);
99
+ const comValueInit = useRef<any>(cell?.text);
100
+ const openTimerRef = useRef<any>();
101
+ useEffect(() => {
102
+ setComValue(cell?.text);
103
+ comValueInit.current = cell?.text;
104
+ }, [cell?.text]);
105
+
106
+ useEffect(() => {
107
+ // 处理下拉选项弹层失焦逻辑
108
+ function onClick(e) {
109
+ if ((window as any).gridEditId != datatypeId) {
110
+ setEdit(false);
111
+ }
112
+ }
113
+ document.addEventListener("click", onClick);
114
+ return () => {
115
+ document.removeEventListener("click", onClick);
116
+ };
117
+ }, []);
118
+
119
+ /** 校验触发器 */
120
+ const onValidator = (val) => {
121
+ let flag = false;
122
+ let isVerify = false;
123
+ for (const it of cell?.validatorList || []) {
124
+ if (it?.pattern?.test(val)) {
125
+ flag = true;
126
+ }
127
+ break;
128
+ }
129
+ isVerify = !flag && Array.isArray(cell?.validatorList) && cell?.validatorList?.length > 0;
130
+ setIsValidator(isVerify);
131
+ };
132
+
133
+ useEffect(() => {
134
+ if (!open) return;
135
+ // 等下一帧,弹窗DOM渲染完成
136
+ const timer = setTimeout(() => {
137
+ const popup: any = document.querySelector(".ant-picker-dropdown");
138
+ if (!popup) return;
139
+
140
+ const stopPointer = (e: PointerEvent) => {
141
+ // 阻断事件往上冒泡到document
142
+ e.stopPropagation();
143
+ };
144
+ // 捕获阶段监听 pointerdown!!必须是pointerdown不是mousedown
145
+ popup.addEventListener("pointerdown", stopPointer, true);
146
+
147
+ // 清理函数
148
+ return () => {
149
+ popup.removeEventListener("pointerdown", stopPointer, true);
150
+ };
151
+ }, 0);
152
+
153
+ return () => clearTimeout(timer);
154
+ }, [open]);
155
+
156
+ /** 失焦提交 */
157
+ const onBlurSubmit = () => {
158
+ const targetValue = comValueInit.current;
159
+ onCellChanged(
160
+ this.getCompatibleCell({
161
+ ...cell,
162
+ text: targetValue,
163
+ selectedValue: targetValue,
164
+ }),
165
+ true,
166
+ );
167
+ };
168
+
169
+ const dataPickerProps = useMemo(() => {
170
+ if (isTriggerBlur?.includes(cell?.type)) {
171
+ return {
172
+ open: open,
173
+ /** 兼容datapicker 闪烁问题 */
174
+ onOpenChange: (isOpen) => {
175
+ if (openTimerRef.current) {
176
+ clearTimeout(openTimerRef.current);
177
+ }
178
+ openTimerRef.current = setTimeout(() => {
179
+ setOpen(isOpen);
180
+ }, 80);
181
+ },
182
+ };
183
+ }
184
+ return {};
185
+ }, [cell]);
186
+ /** 监听上传组件失焦回调 */
187
+ useEffect(() => {
188
+ if (
189
+ !edit &&
190
+ cell.type == "Upload" &&
191
+ (window as any).uploadEdit &&
192
+ (window as any).uploadEdit == datatypeId
193
+ ) {
194
+ (window as any).uploadEdit = null;
195
+ onBlurSubmit();
196
+ }
197
+ }, [edit, comValue]);
198
+
199
+ return (
200
+ <div
201
+ className={`base-hoc ${edit ? "base-hoc-edit" : ""}`}
202
+ onDoubleClick={(e) => {
203
+ if (cell?.nonEditable) {
204
+ return;
205
+ }
206
+ if (cell.type === "Upload") {
207
+ (window as any).uploadEdit = datatypeId;
208
+ }
209
+ setEdit(true);
210
+ }}
211
+ >
212
+ <WrapComponent
213
+ {...props}
214
+ onPointerDown={(e) => e.stopPropagation()}
215
+ componentProps={{
216
+ style: { width: "100%", display: "flex", alignItems: "center" },
217
+ value: comValue,
218
+ options: cell.values,
219
+ onChange: (e) => {
220
+ const targetValue = e?.target?.value ?? e;
221
+ setComValue(targetValue);
222
+ comValueInit.current = targetValue;
223
+ onValidator(targetValue);
224
+ },
225
+ onBlur: (e) => {
226
+ onBlurSubmit();
227
+ if (!isTriggerBlur?.includes(cell?.type)) {
228
+ setEdit(false);
229
+ }
230
+ },
231
+
232
+ onPointerDown: (e) => {
233
+ e.stopPropagation();
234
+ },
235
+ onKeyDown: (e) => {
236
+ if (isAlphaNumericKey(e.keyCode) || isNavigationKey(e.keyCode)) e.stopPropagation();
237
+ },
238
+ ...dataPickerProps,
239
+ ...((cell?.getField && cell?.getField()["x-component-props"]) || {}),
240
+ }}
241
+ pattern={edit ? "" : "readPretty"}
242
+ cell={cell}
243
+ ></WrapComponent>
244
+ {isValidator && (
245
+ <Popover content={cell?.validatorMessage ?? "该字段不合法"}>
246
+ <InfoCircleOutlined className="validator-icon" />
247
+ </Popover>
248
+ )}
249
+ </div>
250
+ );
251
+ }
252
+ }
253
+
254
+ return new createBaseCellTemplate();
255
+ };
@@ -1,16 +1,24 @@
1
- import { DatePicker, Input, TimePicker } from "antd";
2
-
3
- export const childAntdComponent: any = {
4
- "DatePicker.MonthPicker": DatePicker.MonthPicker,
5
- "DatePicker.QuarterPicker": DatePicker.QuarterPicker,
6
- "DatePicker.RangePicker": DatePicker.RangePicker,
7
- "DatePicker.TimePicker": DatePicker.TimePicker,
8
- "DatePicker.WeekPicker": DatePicker.WeekPicker,
9
- "DatePicker.YearPicker": DatePicker.YearPicker,
10
- "Input.Password": Input.Password,
11
- "Input.Search": Input.Search,
12
- "Input.TextArea": Input.TextArea,
13
- "TimePicker.RangePicker": TimePicker.RangePicker,
14
- }
15
- export const isTriggerBlur = ["DatePicker", "DatePicker.MonthPicker", "DatePicker.QuarterPicker", "DatePicker.RangePicker", "DatePicker.TimePicker", "DatePicker.WeekPicker", "DatePicker.YearPicker", "TimePicker.RangePicker"];
16
-
1
+ import { DatePicker, Input, TimePicker } from "antd";
2
+
3
+ export const childAntdComponent: any = {
4
+ "DatePicker.MonthPicker": DatePicker.MonthPicker,
5
+ "DatePicker.QuarterPicker": DatePicker.QuarterPicker,
6
+ "DatePicker.RangePicker": DatePicker.RangePicker,
7
+ "DatePicker.TimePicker": DatePicker.TimePicker,
8
+ "DatePicker.WeekPicker": DatePicker.WeekPicker,
9
+ "DatePicker.YearPicker": DatePicker.YearPicker,
10
+ "Input.Password": Input.Password,
11
+ "Input.Search": Input.Search,
12
+ "Input.TextArea": Input.TextArea,
13
+ "TimePicker.RangePicker": TimePicker.RangePicker,
14
+ };
15
+ export const isTriggerBlur = [
16
+ "DatePicker",
17
+ "DatePicker.MonthPicker",
18
+ "DatePicker.QuarterPicker",
19
+ "DatePicker.RangePicker",
20
+ "DatePicker.TimePicker",
21
+ "DatePicker.WeekPicker",
22
+ "DatePicker.YearPicker",
23
+ "TimePicker.RangePicker",
24
+ ];