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

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.
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
- }