@saas-ui/forms 2.0.0-next.2 → 2.0.0-next.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/README.md +53 -6
  3. package/dist/ajv/index.d.ts +1 -1
  4. package/dist/ajv/index.js.map +1 -1
  5. package/dist/ajv/index.mjs.map +1 -1
  6. package/dist/index.d.ts +265 -166
  7. package/dist/index.js +2821 -556
  8. package/dist/index.js.map +1 -1
  9. package/dist/index.mjs +2814 -555
  10. package/dist/index.mjs.map +1 -1
  11. package/dist/yup/index.d.ts +98 -6
  12. package/dist/yup/index.js.map +1 -1
  13. package/dist/yup/index.mjs.map +1 -1
  14. package/dist/zod/index.d.ts +97 -4
  15. package/dist/zod/index.js.map +1 -1
  16. package/dist/zod/index.mjs.map +1 -1
  17. package/package.json +5 -3
  18. package/src/array-field.tsx +50 -30
  19. package/src/auto-form.tsx +7 -3
  20. package/src/base-field.tsx +59 -0
  21. package/src/create-field.tsx +143 -0
  22. package/src/create-form.tsx +31 -0
  23. package/src/default-fields.tsx +146 -0
  24. package/src/display-field.tsx +8 -9
  25. package/src/display-if.tsx +6 -5
  26. package/src/field-resolver.ts +1 -1
  27. package/src/field.tsx +14 -444
  28. package/src/fields-context.tsx +23 -0
  29. package/src/fields.tsx +18 -8
  30. package/src/form.tsx +27 -37
  31. package/src/index.ts +38 -0
  32. package/src/input-right-button/input-right-button.stories.tsx +1 -1
  33. package/src/input-right-button/input-right-button.tsx +0 -2
  34. package/src/layout.tsx +16 -11
  35. package/src/number-input/number-input.tsx +9 -5
  36. package/src/object-field.tsx +8 -7
  37. package/src/password-input/password-input.stories.tsx +23 -2
  38. package/src/password-input/password-input.tsx +5 -5
  39. package/src/pin-input/pin-input.tsx +1 -5
  40. package/src/radio/radio-input.stories.tsx +1 -1
  41. package/src/radio/radio-input.tsx +12 -10
  42. package/src/select/native-select.tsx +1 -4
  43. package/src/select/select.test.tsx +1 -1
  44. package/src/select/select.tsx +18 -14
  45. package/src/step-form.tsx +29 -11
  46. package/src/submit-button.tsx +5 -1
  47. package/src/types.ts +91 -0
  48. package/src/utils.ts +15 -0
  49. /package/src/radio/{radio.test.tsx → radio-input.test.tsx} +0 -0
package/src/field.tsx CHANGED
@@ -1,45 +1,9 @@
1
1
  import * as React from 'react'
2
- import {
3
- useFormContext,
4
- FormState,
5
- Controller,
6
- get,
7
- RegisterOptions,
8
- FieldValues,
9
- FieldPath,
10
- } from 'react-hook-form'
11
-
12
- import {
13
- forwardRef,
14
- Box,
15
- FormControl,
16
- FormControlProps,
17
- FormLabel,
18
- FormHelperText,
19
- FormErrorMessage,
20
- Input,
21
- Textarea,
22
- Checkbox,
23
- Switch,
24
- useMergeRefs,
25
- InputGroup,
26
- InputProps,
27
- TextareaProps,
28
- SwitchProps,
29
- CheckboxProps,
30
- PinInputField,
31
- HStack,
32
- PinInput,
33
- UsePinInputProps,
34
- SystemProps,
35
- } from '@chakra-ui/react'
36
- import { __DEV__, FocusableElement, callAllHandlers } from '@chakra-ui/utils'
37
-
38
- import { NumberInput, NumberInputProps } from './number-input'
39
- import { PasswordInput, PasswordInputProps } from './password-input'
40
- import { RadioInput, RadioInputProps } from './radio'
2
+ import { RegisterOptions, FieldValues } from 'react-hook-form'
41
3
 
42
- import { Select, SelectProps, NativeSelect, NativeSelectProps } from './select'
4
+ import { FocusableElement } from '@chakra-ui/utils'
5
+ import { useField } from './fields-context'
6
+ import { FieldProps } from './types'
43
7
 
44
8
  export interface Option {
45
9
  value: string
@@ -52,425 +16,31 @@ export type FieldRules = Pick<
52
16
  'required' | 'min' | 'max' | 'maxLength' | 'minLength' | 'pattern'
53
17
  >
54
18
 
55
- export interface FieldProps<
56
- TFieldValues extends FieldValues = FieldValues,
57
- TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
58
- > extends Omit<FormControlProps, 'label' | 'type'> {
59
- /**
60
- * The field name
61
- */
62
- name: TName
63
- /**
64
- * The field label
65
- */
66
- label?: string
67
- /**
68
- * Hide the field label
69
- */
70
- hideLabel?: boolean
71
- /**
72
- * Field help text
73
- */
74
- help?: string
75
- /**
76
- * React hook form rules
77
- */
78
- rules?: Omit<
79
- RegisterOptions<TFieldValues, TName>,
80
- 'valueAsNumber' | 'valueAsDate' | 'setValueAs' | 'disabled'
81
- >
82
- /**
83
- * Build-in types:
84
- * - text
85
- * - number
86
- * - password
87
- * - textarea
88
- * - select
89
- * - native-select
90
- * - checkbox
91
- * - radio
92
- * - switch
93
- * - pin
94
- *
95
- * Will default to a text field if there is no matching type.
96
- */
97
- type?: string
98
- /**
99
- * The input placeholder
100
- */
101
- placeholder?: string
102
- }
103
-
104
- const inputTypes: Record<string, React.FC<any>> = {}
105
-
106
19
  const defaultInputType = 'text'
107
20
 
108
- const getInput = (type: string) => {
109
- return inputTypes[type] || inputTypes[defaultInputType]
110
- }
111
-
112
- const getError = (name: string, formState: FormState<{ [x: string]: any }>) => {
113
- return get(formState.errors, name)
114
- }
115
-
116
- const isTouched = (
117
- name: string,
118
- formState: FormState<{ [x: string]: any }>
119
- ) => {
120
- return get(formState.touchedFields, name)
121
- }
122
-
123
- export const BaseField: React.FC<FieldProps> = (props) => {
124
- const { name, label, help, hideLabel, children, ...controlProps } = props
125
-
126
- const { formState } = useFormContext()
127
-
128
- const error = getError(name, formState)
129
-
130
- return (
131
- <FormControl {...controlProps} isInvalid={!!error}>
132
- {label && !hideLabel ? <FormLabel>{label}</FormLabel> : null}
133
- <Box>
134
- {children}
135
- {help && !error?.message ? (
136
- <FormHelperText>{help}</FormHelperText>
137
- ) : null}
138
- {error?.message && (
139
- <FormErrorMessage>{error?.message}</FormErrorMessage>
140
- )}
141
- </Box>
142
- </FormControl>
143
- )
144
- }
145
-
146
- if (__DEV__) {
147
- BaseField.displayName = 'BaseField'
148
- }
149
-
150
- export type As<Props = any> = React.ElementType<Props>
151
-
152
- export type PropsOf<T extends As> = React.ComponentPropsWithoutRef<T> & {
153
- type?: FieldTypes
154
- }
155
-
156
21
  /**
22
+ * Form field component.
23
+ *
157
24
  * Build-in types:
158
- * - text
159
- * - number
160
- * - password
161
- * - textarea
162
- * - select
163
- * - native-select
164
- * - checkbox
165
- * - radio
166
- * - switch
167
- * - pin
25
+ * text, number, password, textarea, select, native-select, checkbox, radio, switch, pin
168
26
  *
169
27
  * Will default to a text field if there is no matching type.
28
+
29
+ * @see Docs https://saas-ui.dev/docs/components/forms/field
170
30
  */
171
31
  export const Field = React.forwardRef(
172
32
  <TFieldValues extends FieldValues = FieldValues>(
173
- props: FieldProps<TFieldValues> | FieldTypeProps,
33
+ props: FieldProps<TFieldValues>,
174
34
  ref: React.ForwardedRef<FocusableElement>
175
35
  ) => {
176
36
  const { type = defaultInputType } = props
177
- const InputComponent = getInput(type)
178
-
37
+ const InputComponent = useField(type)
179
38
  return <InputComponent ref={ref} {...props} />
180
39
  }
181
40
  ) as (<TFieldValues extends FieldValues>(
182
- props: FieldProps<TFieldValues> &
183
- FieldTypeProps & {
184
- ref?: React.ForwardedRef<FocusableElement>
185
- }
41
+ props: FieldProps<TFieldValues> & {
42
+ ref?: React.ForwardedRef<FocusableElement>
43
+ }
186
44
  ) => React.ReactElement) & {
187
45
  displayName?: string
188
46
  }
189
-
190
- interface CreateFieldProps {
191
- displayName: string
192
- hideLabel?: boolean
193
- BaseField: React.FC<any>
194
- }
195
-
196
- const createField = (
197
- InputComponent: React.FC<any>,
198
- { displayName, hideLabel, BaseField }: CreateFieldProps
199
- ) => {
200
- const Field = forwardRef((props, ref) => {
201
- const {
202
- id,
203
- name,
204
- label,
205
- help,
206
- isDisabled,
207
- isInvalid,
208
- isReadOnly,
209
- isRequired,
210
- rules,
211
- ...inputProps
212
- } = props
213
-
214
- const inputRules = {
215
- required: isRequired,
216
- ...rules,
217
- }
218
-
219
- return (
220
- <BaseField
221
- id={id}
222
- name={name}
223
- label={label}
224
- help={help}
225
- hideLabel={hideLabel}
226
- isDisabled={isDisabled}
227
- isInvalid={isInvalid}
228
- isReadOnly={isReadOnly}
229
- isRequired={isRequired}
230
- >
231
- <InputComponent
232
- ref={ref}
233
- id={id}
234
- name={name}
235
- label={hideLabel ? label : undefined} // Only pass down the label when it should be inline.
236
- rules={inputRules}
237
- {...inputProps}
238
- />
239
- </BaseField>
240
- )
241
- })
242
- Field.displayName = displayName
243
-
244
- return Field
245
- }
246
-
247
- export const withControlledInput = (InputComponent: React.FC<any>) => {
248
- return forwardRef<FieldProps, typeof InputComponent>(
249
- ({ name, rules, ...inputProps }, ref) => {
250
- const { control } = useFormContext()
251
-
252
- return (
253
- <Controller
254
- name={name}
255
- control={control}
256
- rules={rules}
257
- render={({ field: { ref: _ref, ...field } }) => (
258
- <InputComponent
259
- {...field}
260
- {...inputProps}
261
- onChange={callAllHandlers(inputProps.onChange, field.onChange)}
262
- onBlur={callAllHandlers(inputProps.onBlur, field.onBlur)}
263
- ref={useMergeRefs(ref, _ref)}
264
- />
265
- )}
266
- />
267
- )
268
- }
269
- )
270
- }
271
-
272
- export const withUncontrolledInput = (InputComponent: React.FC<any>) => {
273
- return forwardRef<FieldProps, typeof InputComponent>(
274
- ({ name, rules, ...inputProps }, ref) => {
275
- const { register } = useFormContext()
276
-
277
- const { ref: _ref, ...field } = register(name, rules)
278
-
279
- return (
280
- <InputComponent
281
- {...field}
282
- {...inputProps}
283
- onChange={callAllHandlers(inputProps.onChange, field.onChange)}
284
- onBlur={callAllHandlers(inputProps.onBlur, field.onBlur)}
285
- ref={useMergeRefs(ref, _ref)}
286
- />
287
- )
288
- }
289
- )
290
- }
291
-
292
- export interface RegisterFieldTypeOptions {
293
- isControlled?: boolean
294
- hideLabel?: boolean
295
- BaseField?: React.FC<any>
296
- }
297
-
298
- /**
299
- * Register a new field type
300
- * @param type The name for this field in kebab-case, eg `email` or `array-field`
301
- * @param component The React component
302
- * @param options
303
- * @param options.isControlled Set this to true if this is a controlled field.
304
- * @param options.hideLabel Hide the field label, for example for the checkbox field.
305
- */
306
- export const registerFieldType = <T extends object>(
307
- type: string,
308
- component: React.FC<T>,
309
- options?: RegisterFieldTypeOptions
310
- ) => {
311
- let InputComponent
312
- if (options?.isControlled) {
313
- InputComponent = withControlledInput(component)
314
- } else {
315
- InputComponent = withUncontrolledInput(component)
316
- }
317
-
318
- const Field = createField(InputComponent, {
319
- displayName: `${type
320
- .split('-')
321
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
322
- .join('')}Field`,
323
- hideLabel: options?.hideLabel,
324
- BaseField: options?.BaseField || BaseField,
325
- }) as React.FC<T & FieldProps>
326
-
327
- inputTypes[type] = Field
328
-
329
- return Field
330
- }
331
-
332
- export interface InputFieldProps extends InputProps {
333
- type?: string
334
- leftAddon?: React.ReactNode
335
- rightAddon?: React.ReactNode
336
- }
337
-
338
- export const InputField = registerFieldType<InputFieldProps>(
339
- 'text',
340
- forwardRef(({ type = 'text', leftAddon, rightAddon, size, ...rest }, ref) => {
341
- const input = <Input type={type} size={size} {...rest} ref={ref} />
342
- if (leftAddon || rightAddon) {
343
- return (
344
- <InputGroup size={size}>
345
- {leftAddon}
346
- {input}
347
- {rightAddon}
348
- </InputGroup>
349
- )
350
- }
351
- return input
352
- })
353
- )
354
-
355
- export interface NumberInputFieldProps extends NumberInputProps {
356
- type: 'number'
357
- }
358
-
359
- export const NumberInputField = registerFieldType<NumberInputFieldProps>(
360
- 'number',
361
- NumberInput,
362
- {
363
- isControlled: true,
364
- }
365
- )
366
-
367
- export const PasswordInputField = registerFieldType<PasswordInputProps>(
368
- 'password',
369
- forwardRef((props, ref) => <PasswordInput ref={ref} {...props} />)
370
- )
371
-
372
- export const TextareaField = registerFieldType<TextareaProps>(
373
- 'textarea',
374
- Textarea
375
- )
376
-
377
- export const SwitchField = registerFieldType<SwitchProps>(
378
- 'switch',
379
- forwardRef(({ type, value, ...rest }, ref) => {
380
- return <Switch isChecked={!!value} {...rest} ref={ref} />
381
- }),
382
- {
383
- isControlled: true,
384
- }
385
- )
386
-
387
- export const SelectField = registerFieldType<SelectProps>('select', Select, {
388
- isControlled: true,
389
- })
390
-
391
- export const CheckboxField = registerFieldType<CheckboxProps>(
392
- 'checkbox',
393
- forwardRef(({ label, type, ...props }, ref) => {
394
- return (
395
- <Checkbox ref={ref} {...props}>
396
- {label}
397
- </Checkbox>
398
- )
399
- }),
400
- {
401
- hideLabel: true,
402
- }
403
- )
404
-
405
- export const RadioField = registerFieldType<RadioInputProps>(
406
- 'radio',
407
- RadioInput,
408
- {
409
- isControlled: true,
410
- }
411
- )
412
-
413
- export const NativeSelectField = registerFieldType<NativeSelectProps>(
414
- 'native-select',
415
- NativeSelect,
416
- { isControlled: true }
417
- )
418
-
419
- export interface PinFieldProps extends Omit<UsePinInputProps, 'type'> {
420
- pinLength?: number
421
- pinType?: 'alphanumeric' | 'number'
422
- spacing?: SystemProps['margin']
423
- }
424
-
425
- export const PinField = registerFieldType<PinFieldProps>(
426
- 'pin',
427
- forwardRef((props, ref) => {
428
- const { pinLength = 4, pinType, spacing, ...inputProps } = props
429
-
430
- const inputs: React.ReactNode[] = []
431
- for (let i = 0; i < pinLength; i++) {
432
- inputs.push(<PinInputField key={i} ref={ref} />)
433
- }
434
-
435
- return (
436
- <HStack spacing={spacing}>
437
- <PinInput {...inputProps} type={pinType}>
438
- {inputs}
439
- </PinInput>
440
- </HStack>
441
- )
442
- }),
443
- {
444
- isControlled: true,
445
- }
446
- )
447
-
448
- const fieldTypes = {
449
- text: InputField,
450
- email: InputField,
451
- url: InputField,
452
- phone: InputField,
453
- number: NumberInputField,
454
- password: PasswordInputField,
455
- textarea: TextareaField,
456
- switch: SwitchField,
457
- checkbox: CheckboxField,
458
- radio: RadioField,
459
- pin: PinField,
460
- select: SelectField,
461
- 'native-select': NativeSelectField,
462
- }
463
-
464
- type FieldTypes = typeof fieldTypes
465
-
466
- type FieldType<Props = any> = React.ElementType<Props>
467
-
468
- type TypeProps<P extends FieldType, T> = React.ComponentPropsWithoutRef<P> & {
469
- type: T
470
- }
471
-
472
- type FieldTypeProps =
473
- | {
474
- [Property in keyof FieldTypes]: TypeProps<FieldTypes[Property], Property>
475
- }[keyof FieldTypes]
476
- | { type?: string }
@@ -0,0 +1,23 @@
1
+ import React from 'react'
2
+ import { defaultFieldTypes, InputField } from './default-fields'
3
+
4
+ const FieldsContext = React.createContext<Record<string, React.FC<any>> | null>(
5
+ null
6
+ )
7
+
8
+ export const FieldsProvider: React.FC<{
9
+ value: Record<string, React.FC<any>>
10
+ children: React.ReactNode
11
+ }> = (props) => {
12
+ const fields = { ...defaultFieldTypes, ...props.value }
13
+ return (
14
+ <FieldsContext.Provider value={fields}>
15
+ {props.children}
16
+ </FieldsContext.Provider>
17
+ )
18
+ }
19
+
20
+ export const useField = (type: string): React.FC<any> => {
21
+ const context = React.useContext(FieldsContext)
22
+ return context?.[type] || InputField
23
+ }
package/src/fields.tsx CHANGED
@@ -1,9 +1,9 @@
1
1
  import * as React from 'react'
2
- import { __DEV__ } from '@chakra-ui/utils'
3
2
 
4
3
  import { Form } from './form'
5
4
  import { FormLayout } from './layout'
6
- import { Field, FieldProps } from './field'
5
+ import { BaseFieldProps } from './types'
6
+ import { Field } from './field'
7
7
 
8
8
  import { ArrayField } from './array-field'
9
9
  import { ObjectField } from './object-field'
@@ -20,13 +20,21 @@ const mapNestedFields = (resolver: FieldResolver, name: string) => {
20
20
  return resolver
21
21
  .getNestedFields(name)
22
22
  ?.map(
23
- ({ name, type, ...nestedFieldProps }: FieldProps, i): React.ReactNode => (
24
- <Field key={name || i} name={name} type={type} {...nestedFieldProps} />
23
+ (
24
+ { name, type, ...nestedFieldProps }: BaseFieldProps,
25
+ i
26
+ ): React.ReactNode => (
27
+ <Field
28
+ key={name || i}
29
+ name={name}
30
+ type={type as any}
31
+ {...nestedFieldProps}
32
+ />
25
33
  )
26
34
  )
27
35
  }
28
36
 
29
- export const Fields: React.FC<FieldsProps> = ({
37
+ export const AutoFields: React.FC<FieldsProps> = ({
30
38
  schema,
31
39
  fieldResolver,
32
40
  focusFirstField,
@@ -55,7 +63,7 @@ export const Fields: React.FC<FieldsProps> = ({
55
63
  type,
56
64
  defaultValue,
57
65
  ...fieldProps
58
- }: FieldProps): React.ReactNode => {
66
+ }: BaseFieldProps): React.ReactNode => {
59
67
  if (type === 'array') {
60
68
  return (
61
69
  <ArrayField key={name} name={name} {...fieldProps}>
@@ -70,11 +78,13 @@ export const Fields: React.FC<FieldsProps> = ({
70
78
  )
71
79
  }
72
80
 
73
- return <Field key={name} name={name} type={type} {...fieldProps} />
81
+ return (
82
+ <Field key={name} name={name} type={type as any} {...fieldProps} />
83
+ )
74
84
  }
75
85
  )}
76
86
  </FormLayout>
77
87
  )
78
88
  }
79
89
 
80
- Fields.displayName = 'Fields'
90
+ AutoFields.displayName = 'Fields'
package/src/form.tsx CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react'
2
2
 
3
3
  import { chakra, HTMLChakraProps, forwardRef } from '@chakra-ui/react'
4
- import { cx, runIfFn, __DEV__ } from '@chakra-ui/utils'
4
+ import { cx, runIfFn } from '@chakra-ui/utils'
5
5
 
6
6
  import {
7
7
  useForm,
@@ -20,19 +20,23 @@ import { MaybeRenderProp } from '@chakra-ui/react-utils'
20
20
 
21
21
  export type { UseFormReturn, FieldValues, SubmitHandler }
22
22
 
23
- import { Field as DefaultField, FieldProps } from './field'
23
+ import { FieldProps } from './types'
24
24
 
25
- interface FormRenderContext<
25
+ import { Field as DefaultField } from './field'
26
+
27
+ export interface FormRenderContext<
26
28
  TFieldValues extends FieldValues = FieldValues,
27
- TContext extends object = object
29
+ TContext extends object = object,
30
+ TFieldTypes = FieldProps<TFieldValues>
28
31
  > extends UseFormReturn<TFieldValues, TContext> {
29
- Field: React.FC<FieldProps<TFieldValues>>
32
+ Field: React.FC<TFieldTypes>
30
33
  }
31
34
 
32
35
  interface FormOptions<
33
36
  TFieldValues extends FieldValues = FieldValues,
34
37
  TContext extends object = object,
35
- TSchema = any
38
+ TSchema = any,
39
+ TFieldTypes = FieldProps<TFieldValues>
36
40
  > {
37
41
  /**
38
42
  * The form schema, supports Yup, Zod, and AJV.
@@ -57,25 +61,34 @@ interface FormOptions<
57
61
  /**
58
62
  * The form children, can be a render prop or a ReactNode.
59
63
  */
60
- children?: MaybeRenderProp<FormRenderContext<TFieldValues, TContext>>
64
+ children?: MaybeRenderProp<
65
+ FormRenderContext<TFieldValues, TContext, TFieldTypes>
66
+ >
61
67
  }
62
68
 
63
69
  export interface FormProps<
64
70
  TFieldValues extends FieldValues = FieldValues,
65
71
  TContext extends object = object,
66
- TSchema = any
72
+ TSchema = any,
73
+ TFieldTypes = FieldProps<TFieldValues>
67
74
  > extends UseFormProps<TFieldValues, TContext>,
68
75
  Omit<
69
76
  HTMLChakraProps<'form'>,
70
77
  'children' | 'onChange' | 'onSubmit' | 'onError'
71
78
  >,
72
- FormOptions<TFieldValues, TContext, TSchema> {}
79
+ FormOptions<TFieldValues, TContext, TSchema, TFieldTypes> {}
73
80
 
81
+ /**
82
+ * The wrapper component provides context, state, and focus management.
83
+ *
84
+ * @see Docs https://saas-ui.dev/docs/components/forms/form
85
+ */
74
86
  export const Form = forwardRef(
75
87
  <
76
88
  TFieldValues extends FieldValues = FieldValues,
77
89
  TContext extends object = object,
78
- TSchema = any
90
+ TSchema = any,
91
+ TFieldTypes = FieldProps<TFieldValues>
79
92
  >(
80
93
  props: FormProps<TFieldValues, TContext, TSchema>,
81
94
  ref: React.ForwardedRef<HTMLFormElement>
@@ -135,11 +148,6 @@ export const Form = forwardRef(
135
148
  return () => subscription?.unsubscribe()
136
149
  }, [methods, onChange])
137
150
 
138
- const Field: React.FC<FieldProps<TFieldValues>> = React.useMemo(
139
- () => (props) => <DefaultField<TFieldValues> {...props} />,
140
- []
141
- )
142
-
143
151
  return (
144
152
  <FormProvider {...methods}>
145
153
  <chakra.form
@@ -149,7 +157,7 @@ export const Form = forwardRef(
149
157
  className={cx('sui-form', props.className)}
150
158
  >
151
159
  {runIfFn(children, {
152
- Field,
160
+ Field: DefaultField as any,
153
161
  ...methods,
154
162
  })}
155
163
  </chakra.form>
@@ -159,9 +167,10 @@ export const Form = forwardRef(
159
167
  ) as (<
160
168
  TFieldValues extends FieldValues,
161
169
  TContext extends object = object,
162
- TSchema = any
170
+ TSchema = any,
171
+ TFieldTypes = FieldProps<TFieldValues>
163
172
  >(
164
- props: FormProps<TFieldValues, TContext, TSchema> & {
173
+ props: FormProps<TFieldValues, TContext, TSchema, TFieldTypes> & {
165
174
  ref?: React.ForwardedRef<HTMLFormElement>
166
175
  }
167
176
  ) => React.ReactElement) & {
@@ -186,22 +195,3 @@ export type GetResolver = <
186
195
  ) => Promise<ResolverResult<TFieldValues>>
187
196
 
188
197
  export type GetFieldResolver = (schema: any) => FieldResolver
189
-
190
- export interface CreateFormProps {
191
- resolver?: GetResolver
192
- }
193
-
194
- export function createForm<Schema = any>({ resolver }: CreateFormProps) {
195
- const CreateForm = <
196
- TFieldValues extends FieldValues,
197
- TContext extends object = object,
198
- TSchema extends Schema = Schema
199
- >(
200
- props: FormProps<TFieldValues, TContext, TSchema>
201
- ) => {
202
- const { schema, ...rest } = props
203
- return <Form resolver={resolver?.(props.schema)} {...rest} />
204
- }
205
-
206
- return CreateForm
207
- }