simpler api for Form.save
Massimo Melina committed
Mar 16, 2022 at 15:56 UTC
3547d3da893d46cf9854dcb64d479570ac5379ec
1 file changed
+26
-21
admin/src/Form.ts
+26
-21
@@ -33,7 +33,7 @@ interface FormProps {
33
defaults?: (f:FieldDescriptor) => Dict | any
34
values: Dict
35
set: (v: any, fieldK: string) => void
36
- save?: Partial<Parameters<typeof Button>[0]>
36
+ save: Partial<Parameters<typeof Button>[0]> | (()=>any)
37
stickyBar?: boolean
38
addToBar?: ReactNode[]
39
barSx?: Dict
@@ -43,28 +43,28 @@ interface FormProps {
43
export function Form({ fields, values, set, defaults, save, stickyBar, addToBar=[], barSx, formRef, onError, ...rest }: FormProps) {
44
const [loading, setLoading] = useStateMounted(false)
45
const [errors, setErrors] = useStateMounted<Dict>({})
46
- const onClick = save?.onClick
47
- if (onClick)
48
- save.onClick = async function (ev) {
49
- setLoading(true)
50
- try {
51
- for (const f of fields) {
52
- if (!f || isValidElement(f) || !f.k || !f.validate) continue
53
- const res = await f.validate(values?.[f.k], { values, fields })
54
- if (res !== true)
55
- return setErrors({ [f.k]: res || true })
56
- }
57
- setErrors({})
58
- return await onClick(ev)
46
+ const saveBtn = typeof save === 'function' ? { onClick: save } : save
47
+ const { onClick } = saveBtn
48
+ saveBtn.onClick = onClick && async function (ev) {
49
+ setLoading(true)
50
+ try {
51
+ for (const f of fields) {
52
+ if (!f || isValidElement(f) || !f.k || !f.validate) continue
53
+ const res = await f.validate(values?.[f.k], { values, fields })
54
+ if (res !== true)
55
+ return setErrors({ [f.k]: res || true })
56
}
60
- catch(e) { onError?.(e) }
61
- finally { setLoading(false) }
57
+ setErrors({})
58
+ return await onClick(ev)
59
}
60
+ catch(e) { onError?.(e) }
61
+ finally { setLoading(false) }
62
+ }
63
64
const [pendingSubmit, setPendingSubmit] = useStateMounted(false)
65
useEffect(() => {
66
if (!pendingSubmit) return
67
- setTimeout(save?.onClick!)
67
+ setTimeout(saveBtn.onClick!)
68
setPendingSubmit(false)
69
}, [pendingSubmit]) //eslint-disable-line
70
@@ -74,7 +74,7 @@ export function Form({ fields, values, set, defaults, save, stickyBar, addToBar=
74
ev.preventDefault()
75
},
76
onKeyDown(ev) {
77
- if (!save?.disabled && (ev.ctrlKey || ev.metaKey) && ev.key === 'Enter')
77
+ if (!saveBtn.disabled && (ev.ctrlKey || ev.metaKey) && ev.key === 'Enter')
78
setPendingSubmit(true) // we need to let outer component perform its state changes
79
}
80
},
@@ -169,14 +169,19 @@ export function StringField({ value, onChange, fromField=_.identity, toField=_.i
169
InputLabelProps: state || props.placeholder ? { shrink: true } : undefined,
170
...props,
171
value: state,
172
- onChange(event) {
173
- setState(event.target.value)
172
+ onChange(ev) {
173
+ props.onChange?.(ev)
174
+ setState(ev.target.value)
175
},
176
onKeyDown(ev) {
177
+ props.onKeyDown?.(ev)
178
if (ev.key === 'Enter')
179
go(ev)
180
},
179
- onBlur: go
181
+ onBlur(ev) {
182
+ props.onBlur?.(ev)
183
+ go(ev)
184
+ }
185
})
186
187
function go(event: any) {