form.fields.validate as RegExp

Massimo Melina committed Mar 22, 2022 at 17:14 UTC f58e8553e5a7f59b22335b8842f34dbe7be41ddf
1 file changed +11 -6
admin/src/Form.ts
+11 -6
@@ -19,7 +19,7 @@ interface FieldDescriptor {
19 k:string
20 comp?: any
21 label?: ReactNode
22 - validate?: (v: any, extra:any) => string | boolean
22 + validate?: RegExp | ((v: any, extra:any) => string | boolean)
23 [extraProp:string]:any
24 }
25
@@ -28,10 +28,10 @@ export type Field<T> = FC<FieldProps<T>>
28
29 type Dict<T=any> = Record<string,T>
30
31 -export interface FormProps {
31 +export interface FormProps<Values> {
32 fields: (FieldDescriptor | ReactElement | null | undefined | false)[]
33 defaults?: (f:FieldDescriptor) => any
34 - values: Dict
34 + values: Values
35 set: (v: any, fieldK: string) => void
36 save: Partial<Parameters<typeof Button>[0]> | (()=>any)
37 stickyBar?: boolean
@@ -40,7 +40,7 @@ export interface FormProps {
40 onError?: (err: any) => void
41 formRef?: Ref<HTMLFormElement>
42 }
43 -export function Form({ fields, values, set, defaults, save, stickyBar, addToBar=[], barSx, formRef, onError, ...rest }: FormProps) {
43 +export function Form<Values extends Dict>({ fields, values, set, defaults, save, stickyBar, addToBar=[], barSx, formRef, onError, ...rest }: FormProps<Values>) {
44 const mounted = useRef(false)
45 useEffect(() => {
46 mounted.current = true
@@ -53,12 +53,17 @@ export function Form({ fields, values, set, defaults, save, stickyBar, addToBar=
53 const [errors, setErrors] = useState<Dict>({})
54 const saveBtn = typeof save === 'function' ? { onClick: save } : save
55 const { onClick } = saveBtn
56 - saveBtn.onClick = onClick && async function (ev) {
56 + saveBtn.onClick = onClick && async function (ev: Parameters<NonNullable<typeof saveBtn.onClick>>[0]) {
57 setLoading(true)
58 try {
59 for (const f of fields) {
60 if (!f || isValidElement(f) || !f.k || !f.validate) continue
61 - const res = await f.validate(values?.[f.k], { values, fields })
61 + let fv = f.validate
62 + if (fv instanceof RegExp) {
63 + const re = fv
64 + fv = x => re.test(x)
65 + }
66 + const res = await fv(values?.[f.k], { values, fields })
67 if (!mounted.current) return
68 if (res !== true)
69 return setErrors({ [f.k]: res || true })