-
-
Notifications
You must be signed in to change notification settings - Fork 495
Expand file tree
/
Copy pathField.tsx
More file actions
110 lines (100 loc) · 2.32 KB
/
Field.tsx
File metadata and controls
110 lines (100 loc) · 2.32 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import * as React from "react";
import type { FieldProps, FieldRenderProps } from "./types";
import renderComponent from "./renderComponent";
import useField from "./useField";
function FieldComponent<
FieldValue = any,
T extends HTMLElement = HTMLElement,
FormValues = Record<string, any>,
>(
{
afterSubmit,
allowNull,
beforeSubmit,
children,
component,
data,
defaultValue,
format,
formatOnBlur,
initialValue,
input,
isEqual,
multiple,
name,
parse,
subscription,
type,
validate,
validateFields,
value,
...rest
}: FieldProps<FieldValue, T, FormValues>,
ref: React.Ref<T>,
) {
const field: FieldRenderProps<FieldValue, T> = useField(name, {
afterSubmit,
allowNull,
beforeSubmit,
component,
data,
defaultValue,
format,
formatOnBlur,
initialValue,
isEqual,
multiple,
parse,
subscription,
type,
validate,
validateFields,
value,
});
// Merge provided input prop with field.input
const mergedField = input
? { ...field, input: { ...field.input, ...input } }
: field;
if (typeof children === "function") {
return (
children as (
props: FieldRenderProps<FieldValue, T> & typeof rest,
) => React.ReactNode
)({ ...mergedField, ...rest });
}
if (typeof component === "string") {
// ignore meta, combine input with any other props
const inputProps = { ...mergedField.input };
// Ensure multiple select has array value
if (
component === "select" &&
multiple &&
!Array.isArray(inputProps.value)
) {
inputProps.value = [] as any;
}
return React.createElement(component, {
...inputProps,
children,
ref,
...rest,
});
}
if (!name) {
throw new Error("prop name cannot be undefined in <Field> component");
}
return renderComponent(
{ children, component, ...rest, ...mergedField },
{},
`Field(${name})`,
);
}
// Create a properly typed forwardRef component that preserves generics
const Field = React.forwardRef(FieldComponent as any) as <
FieldValue = any,
T extends HTMLElement = HTMLElement,
FormValues = Record<string, any>,
>(
props: FieldProps<FieldValue, T, FormValues> & { ref?: React.Ref<T> },
) => React.ReactElement | null;
export default Field;