@saas-ui/forms 0.6.0-next.1 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,18 +7,23 @@ export type FieldResolver = {
7
7
  getNestedFields(name: string): FieldProps[]
8
8
  }
9
9
 
10
- // @todo finalize this
11
- export type FormSchema = Record<string, any>
10
+ interface SchemaField extends FieldProps {
11
+ items?: SchemaField[]
12
+ properties?: Record<string, SchemaField>
13
+ }
14
+
15
+ export type ObjectSchema = Record<string, SchemaField>
12
16
 
13
- const mapFields = (schema: FormSchema) =>
17
+ const mapFields = (schema: ObjectSchema) =>
18
+ schema &&
14
19
  Object.entries(schema).map(([name, field]) => {
15
20
  return {
16
- name,
17
21
  ...field,
22
+ name,
18
23
  }
19
24
  })
20
25
 
21
- export const defaultFieldResolver = (schema: FormSchema): FieldResolver => {
26
+ export const objectFieldResolver = (schema: ObjectSchema): FieldResolver => {
22
27
  const getFields = () => {
23
28
  return mapFields(schema)
24
29
  }
package/src/fields.tsx CHANGED
@@ -1,12 +1,12 @@
1
1
  import * as React from 'react'
2
2
 
3
+ import { Form } from './form'
3
4
  import { FormLayout } from './layout'
4
5
  import { Field, FieldProps } from './field'
5
6
 
6
7
  import { ArrayField } from './array-field'
7
8
  import { ObjectField } from './object-field'
8
9
  import { FieldResolver } from './field-resolver'
9
- import { defaultFieldResolver } from './field-resolver'
10
10
 
11
11
  export interface FieldsProps {
12
12
  schema: any
@@ -29,7 +29,7 @@ export const Fields: React.FC<FieldsProps> = ({
29
29
  ...props
30
30
  }) => {
31
31
  const resolver = React.useMemo(
32
- () => fieldResolver || defaultFieldResolver(schema),
32
+ () => fieldResolver || Form.getFieldResolver(schema),
33
33
  [schema, fieldResolver]
34
34
  )
35
35
 
package/src/form.tsx CHANGED
@@ -10,7 +10,11 @@ import {
10
10
  FieldValues,
11
11
  SubmitHandler,
12
12
  SubmitErrorHandler,
13
+ UnpackNestedValue,
14
+ ResolverOptions,
15
+ ResolverResult,
13
16
  } from 'react-hook-form'
17
+ import { objectFieldResolver, FieldResolver } from './field-resolver'
14
18
 
15
19
  export type { UseFormReturn, FieldValues, SubmitHandler }
16
20
 
@@ -77,6 +81,10 @@ export const Form = forwardRef(
77
81
  delayError,
78
82
  }
79
83
 
84
+ if (schema && !resolver) {
85
+ form.resolver = Form.getResolver?.(schema)
86
+ }
87
+
80
88
  const methods = useForm<TFieldValues>(form)
81
89
  const { handleSubmit } = methods
82
90
 
@@ -95,8 +103,23 @@ export const Form = forwardRef(
95
103
  </FormProvider>
96
104
  )
97
105
  }
98
- ) as <TFieldValues extends FieldValues>(
106
+ ) as (<TFieldValues extends FieldValues>(
99
107
  props: FormProps<TFieldValues> & {
100
108
  ref?: React.ForwardedRef<UseFormReturn<TFieldValues>>
101
109
  }
102
- ) => React.ReactElement
110
+ ) => React.ReactElement) & {
111
+ getResolver?: GetResolver
112
+ getFieldResolver: GetFieldResolver
113
+ }
114
+
115
+ Form.getFieldResolver = objectFieldResolver
116
+
117
+ export type GetResolver = (
118
+ schema: any
119
+ ) => <TFieldValues extends FieldValues, TContext>(
120
+ values: UnpackNestedValue<TFieldValues>,
121
+ context: TContext | undefined,
122
+ options: ResolverOptions<TFieldValues>
123
+ ) => Promise<ResolverResult<TFieldValues>>
124
+
125
+ export type GetFieldResolver = (schema: any) => FieldResolver
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../yup/src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"yup.d.ts","sourceRoot":"","sources":["../../../yup/src/yup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,eAAe,EAAE,MAAM,KAAK,CAAA;AAG5C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAmC5C;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,+BAA8B,UAAU,EA4BvE,CAAA;AAED,eAAO,MAAM,eAAe,kCAAmC,MAAM,QAEpE,CAAA;AAED,eAAO,MAAM,aAAa;;0BAKA,MAAM;CAI/B,CAAA;AAED,eAAO,MAAM,OAAO;;;;;8BANM,MAAM;;CAgB/B,CAAA"}
package/yup/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './src'
package/yup/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export * from './yup'
package/yup/src/yup.ts DELETED
@@ -1,100 +0,0 @@
1
- import { reach, AnyObjectSchema } from 'yup'
2
- import { yupResolver } from '@hookform/resolvers/yup'
3
-
4
- import { FieldProps } from '../../src/field'
5
-
6
- // @TODO get proper typings for the schema fields
7
-
8
- const getType = (field: any) => {
9
- if (field.spec.meta?.type) {
10
- return field.spec.meta.type
11
- }
12
-
13
- switch (field.type) {
14
- case 'array':
15
- return 'array'
16
- case 'object':
17
- return 'object'
18
- case 'number':
19
- return 'number'
20
- case 'date':
21
- return 'date'
22
- case 'string':
23
- default:
24
- return 'text'
25
- }
26
- }
27
-
28
- type Options = {
29
- min?: number
30
- max?: number
31
- }
32
-
33
- const getArrayOption = (field: any, name: string) => {
34
- for (const test of field.tests) {
35
- if (test.OPTIONS?.params[name]) return test.OPTIONS.params[name]
36
- }
37
- }
38
-
39
- /**
40
- * A helper function to render forms automatically based on a Yup schema
41
- *
42
- * @param schema The Yup schema
43
- * @returns {FieldProps[]}
44
- */
45
- export const getFieldsFromSchema = (schema: AnyObjectSchema): FieldProps[] => {
46
- const fields = []
47
-
48
- let schemaFields: Record<string, any> = {}
49
- if (schema.type === 'array') {
50
- /* @ts-ignore this is actually valid */
51
- schemaFields = schema.innerType.fields
52
- } else {
53
- schemaFields = schema.fields
54
- }
55
-
56
- for (const name in schemaFields) {
57
- const field = schemaFields[name]
58
-
59
- const options: Options = {}
60
- if (field.type === 'array') {
61
- options.min = getArrayOption(field, 'min')
62
- options.max = getArrayOption(field, 'max')
63
- }
64
-
65
- fields.push({
66
- name,
67
- label: field.spec.label || name,
68
- type: getType(field),
69
- ...options,
70
- })
71
- }
72
- return fields
73
- }
74
-
75
- export const getNestedSchema = (schema: AnyObjectSchema, path: string) => {
76
- return reach(schema, path)
77
- }
78
-
79
- export const fieldResolver = (schema: AnyObjectSchema) => {
80
- return {
81
- getFields() {
82
- return getFieldsFromSchema(schema)
83
- },
84
- getNestedFields(name: string) {
85
- return getFieldsFromSchema(getNestedSchema(schema, name))
86
- },
87
- }
88
- }
89
-
90
- export const yupForm = (
91
- schema: AnyObjectSchema,
92
- schemaOptions = {},
93
- resolverOptions = {}
94
- ) => {
95
- return {
96
- schema,
97
- resolver: yupResolver(schema, schemaOptions, resolverOptions),
98
- fieldResolver: fieldResolver(schema),
99
- }
100
- }
package/yup/tsconfig.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "include": ["src/*"],
4
- "compilerOptions": {
5
- "outDir": "../dist",
6
- "declarationDir": "../dist"
7
- }
8
- }