@saas-ui/forms 2.0.0-next.19 → 2.0.0-next.20
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.
- package/CHANGELOG.md +11 -0
- package/dist/index.d.ts +100 -60
- package/dist/index.js +44 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +44 -20
- package/dist/index.mjs.map +1 -1
- package/dist/yup/index.d.ts +514 -9
- package/dist/yup/index.js +18 -5
- package/dist/yup/index.js.map +1 -1
- package/dist/yup/index.mjs +16 -4
- package/dist/yup/index.mjs.map +1 -1
- package/dist/zod/index.d.ts +516 -10
- package/dist/zod/index.js +12 -0
- package/dist/zod/index.js.map +1 -1
- package/dist/zod/index.mjs +13 -2
- package/dist/zod/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/create-step-form.tsx +44 -105
- package/src/index.ts +9 -2
- package/src/step-form.tsx +49 -81
- package/src/use-step-form.tsx +24 -7
package/dist/zod/index.mjs
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { zodResolver } from '@hookform/resolvers/zod';
|
2
2
|
export { zodResolver } from '@hookform/resolvers/zod';
|
3
3
|
import { get } from '@chakra-ui/utils';
|
4
|
-
import { createForm } from '@saas-ui/forms';
|
4
|
+
import { createForm, createStepForm } from '@saas-ui/forms';
|
5
5
|
|
6
6
|
// zod/src/zod-resolver.ts
|
7
7
|
var getType = (field) => {
|
@@ -83,10 +83,21 @@ var createZodForm = (options) => {
|
|
83
83
|
ZodForm.id = "ZodForm";
|
84
84
|
return ZodForm;
|
85
85
|
};
|
86
|
+
var createZodStepForm = (options) => {
|
87
|
+
const ZodStepForm = createStepForm({
|
88
|
+
resolver: (schema) => zodResolver(schema, options == null ? void 0 : options.schemaOptions, options == null ? void 0 : options.resolverOptions),
|
89
|
+
fieldResolver: zodFieldResolver,
|
90
|
+
...options
|
91
|
+
});
|
92
|
+
ZodStepForm.displayName = "ZodStepForm";
|
93
|
+
ZodStepForm.id = "ZodStepForm";
|
94
|
+
return ZodStepForm;
|
95
|
+
};
|
86
96
|
|
87
97
|
// zod/src/index.ts
|
88
98
|
var Form = createZodForm();
|
99
|
+
var StepForm = createZodStepForm();
|
89
100
|
|
90
|
-
export { Form, createZodForm, getFieldsFromSchema, getNestedSchema, zodFieldResolver, zodMeta, zodParseMeta };
|
101
|
+
export { Form, StepForm, createZodForm, getFieldsFromSchema, getNestedSchema, zodFieldResolver, zodMeta, zodParseMeta };
|
91
102
|
//# sourceMappingURL=out.js.map
|
92
103
|
//# sourceMappingURL=index.mjs.map
|
package/dist/zod/index.mjs.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["../../zod/src/zod-resolver.ts","../../zod/src/create-zod-form.ts","../../zod/src/index.ts"],"names":[],"mappings":";AACA,SAAS,mBAAmB;AAC5B,SAAS,WAAW;AAUpB,IAAM,UAAU,CAAC,UAAwB;AACvC,UAAQ,MAAM,KAAK,UAAU;AAAA,IAC3B,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAEA,IAAM,iBAAiB,CAAC,OAAY,SAAiB;AA5BrD;AA6BE,UAAO,WAAM,KAAK,IAAI,MAAf,mBAAkB;AAC3B;AAQO,IAAM,sBAAsB,CAAC,WAAuC;AACzE,QAAM,SAAuB,CAAC;AAE9B,MAAI,eAAoC,CAAC;AACzC,MAAI,OAAO,KAAK,aAAa,YAAY;AACvC,mBAAe,OAAO,KAAK,KAAK;AAAA,EAClC,WAAW,OAAO,KAAK,aAAa,aAAa;AAC/C,mBAAe,OAAO,KAAK,MAAM;AAAA,EACnC,OAAO;AACL,WAAO;AAAA,EACT;AAEA,aAAW,QAAQ,cAAc;AAC/B,UAAM,QAAQ,aAAa,IAAI;AAE/B,UAAM,UAAmB,CAAC;AAC1B,QAAI,MAAM,KAAK,aAAa,YAAY;AACtC,cAAQ,MAAM,eAAe,OAAO,WAAW;AAC/C,cAAQ,MAAM,eAAe,OAAO,WAAW;AAAA,IACjD;AAEA,UAAM,OAAO,MAAM,eAAe,aAAa,MAAM,WAAW;AAEhE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,QAAO,6BAAM,UAAS,MAAM,eAAe;AAAA,MAC3C,OAAM,6BAAM,SAAQ,QAAQ,KAAK;AAAA,MACjC,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEO,IAAM,kBAAkB,CAAC,QAAsB,SAAiB;AACrE,SAAO,IAAI,OAAO,KAAK,MAAM,GAAG,IAAI;AACtC;AAEO,IAAM,mBAAmB,CAAyB,WAAc;AACrE,SAAO;AAAA,IACL,YAAY;AACV,aAAO,oBAAoB,MAAM;AAAA,IACnC;AAAA,IACA,gBAAgB,MAAc;AAC5B,aAAO,oBAAoB,gBAAgB,QAAQ,IAAI,CAAC;AAAA,IAC1D;AAAA,EACF;AACF;AAOO,IAAM,UAAU,CAAC,SAAkB;AACxC,SAAO,KAAK,UAAU,IAAI;AAC5B;AAEO,IAAM,eAAe,CAAC,SAAiB;AAC5C,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,GAAP;AACA,WAAO;AAAA,EACT;AACF;;;ACrGA;AAAA,EACE;AAAA,OAKK;AAkCA,IAAM,gBAAgB,CAC3B,YACG;AACH,QAAM,UAAU,WAAW;AAAA,IACzB,UAAU,CAAC,WACT,YAAY,QAAQ,mCAAS,eAAe,mCAAS,eAAe;AAAA,IACtE,eAAe;AAAA,IACf,GAAG;AAAA,EACL,CAAC;AAED,UAAQ,cAAc;AACtB,UAAQ,KAAK;AAEb,SAAO;AACT;;;
|
1
|
+
{"version":3,"sources":["../../zod/src/zod-resolver.ts","../../zod/src/create-zod-form.ts","../../zod/src/create-zod-step-form.ts","../../zod/src/index.ts"],"names":[],"mappings":";AACA,SAAS,mBAAmB;AAC5B,SAAS,WAAW;AAUpB,IAAM,UAAU,CAAC,UAAwB;AACvC,UAAQ,MAAM,KAAK,UAAU;AAAA,IAC3B,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL;AACE,aAAO;AAAA,EACX;AACF;AAEA,IAAM,iBAAiB,CAAC,OAAY,SAAiB;AA5BrD;AA6BE,UAAO,WAAM,KAAK,IAAI,MAAf,mBAAkB;AAC3B;AAQO,IAAM,sBAAsB,CAAC,WAAuC;AACzE,QAAM,SAAuB,CAAC;AAE9B,MAAI,eAAoC,CAAC;AACzC,MAAI,OAAO,KAAK,aAAa,YAAY;AACvC,mBAAe,OAAO,KAAK,KAAK;AAAA,EAClC,WAAW,OAAO,KAAK,aAAa,aAAa;AAC/C,mBAAe,OAAO,KAAK,MAAM;AAAA,EACnC,OAAO;AACL,WAAO;AAAA,EACT;AAEA,aAAW,QAAQ,cAAc;AAC/B,UAAM,QAAQ,aAAa,IAAI;AAE/B,UAAM,UAAmB,CAAC;AAC1B,QAAI,MAAM,KAAK,aAAa,YAAY;AACtC,cAAQ,MAAM,eAAe,OAAO,WAAW;AAC/C,cAAQ,MAAM,eAAe,OAAO,WAAW;AAAA,IACjD;AAEA,UAAM,OAAO,MAAM,eAAe,aAAa,MAAM,WAAW;AAEhE,WAAO,KAAK;AAAA,MACV;AAAA,MACA,QAAO,6BAAM,UAAS,MAAM,eAAe;AAAA,MAC3C,OAAM,6BAAM,SAAQ,QAAQ,KAAK;AAAA,MACjC,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEO,IAAM,kBAAkB,CAAC,QAAsB,SAAiB;AACrE,SAAO,IAAI,OAAO,KAAK,MAAM,GAAG,IAAI;AACtC;AAEO,IAAM,mBAAmB,CAAyB,WAAc;AACrE,SAAO;AAAA,IACL,YAAY;AACV,aAAO,oBAAoB,MAAM;AAAA,IACnC;AAAA,IACA,gBAAgB,MAAc;AAC5B,aAAO,oBAAoB,gBAAgB,QAAQ,IAAI,CAAC;AAAA,IAC1D;AAAA,EACF;AACF;AAOO,IAAM,UAAU,CAAC,SAAkB;AACxC,SAAO,KAAK,UAAU,IAAI;AAC5B;AAEO,IAAM,eAAe,CAAC,SAAiB;AAC5C,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,SAAS,GAAP;AACA,WAAO;AAAA,EACT;AACF;;;ACrGA;AAAA,EACE;AAAA,OAKK;AAkCA,IAAM,gBAAgB,CAC3B,YACG;AACH,QAAM,UAAU,WAAW;AAAA,IACzB,UAAU,CAAC,WACT,YAAY,QAAQ,mCAAS,eAAe,mCAAS,eAAe;AAAA,IACtE,eAAe;AAAA,IACf,GAAG;AAAA,EACL,CAAC;AAED,UAAQ,cAAc;AACtB,UAAQ,KAAK;AAEb,SAAO;AACT;;;ACtDA;AAAA,EAEE;AAAA,OAGK;AA6CA,IAAM,oBAAoB,CAC/B,YACG;AACH,QAAM,cAAc,eAAmC;AAAA,IACrD,UAAU,CAAC,WACT,YAAY,QAAQ,mCAAS,eAAe,mCAAS,eAAe;AAAA,IACtE,eAAe;AAAA,IACf,GAAG;AAAA,EACL,CAAC;AAED,cAAY,cAAc;AAC1B,cAAY,KAAK;AAEjB,SAAO;AACT;;;AClDO,IAAM,OAAO,cAAc;AAE3B,IAAM,WAAW,kBAAkB","sourcesContent":["import * as z from 'zod'\nimport { zodResolver } from '@hookform/resolvers/zod'\nimport { get } from '@chakra-ui/utils'\nimport { FieldProps } from '@saas-ui/forms'\n\nexport { zodResolver }\n\nexport type Options = {\n min?: number\n max?: number\n}\n\nconst getType = (field: z.ZodTypeAny) => {\n switch (field._def.typeName) {\n case 'ZodArray':\n return 'array'\n case 'ZodObject':\n return 'object'\n case 'ZodNumber':\n return 'number'\n case 'ZodDate':\n return 'date'\n case 'ZodString':\n default:\n return 'text'\n }\n}\n\nconst getArrayOption = (field: any, name: string) => {\n return field._def[name]?.value\n}\n\n/**\n * A helper function to render forms automatically based on a Yup schema\n *\n * @param schema The Yup schema\n * @returns {FieldProps[]}\n */\nexport const getFieldsFromSchema = (schema: z.ZodTypeAny): FieldProps[] => {\n const fields: FieldProps[] = []\n\n let schemaFields: Record<string, any> = {}\n if (schema._def.typeName === 'ZodArray') {\n schemaFields = schema._def.type.shape\n } else if (schema._def.typeName === 'ZodObject') {\n schemaFields = schema._def.shape()\n } else {\n return fields\n }\n\n for (const name in schemaFields) {\n const field = schemaFields[name]\n\n const options: Options = {}\n if (field._def.typeName === 'ZodArray') {\n options.min = getArrayOption(field, 'minLength')\n options.max = getArrayOption(field, 'maxLength')\n }\n\n const meta = field.description && zodParseMeta(field.description)\n\n fields.push({\n name,\n label: meta?.label || field.description || name,\n type: meta?.type || getType(field),\n ...options,\n })\n }\n return fields\n}\n\nexport const getNestedSchema = (schema: z.ZodTypeAny, path: string) => {\n return get(schema._def.shape(), path)\n}\n\nexport const zodFieldResolver = <T extends z.ZodTypeAny>(schema: T) => {\n return {\n getFields() {\n return getFieldsFromSchema(schema)\n },\n getNestedFields(name: string) {\n return getFieldsFromSchema(getNestedSchema(schema, name))\n },\n }\n}\n\nexport interface ZodMeta {\n label: string\n type?: string\n}\n\nexport const zodMeta = (meta: ZodMeta) => {\n return JSON.stringify(meta)\n}\n\nexport const zodParseMeta = (meta: string) => {\n try {\n return JSON.parse(meta)\n } catch (e) {\n return meta\n }\n}\n","import {\n createForm,\n CreateFormProps,\n WithFields,\n FormProps,\n FieldValues,\n} from '@saas-ui/forms'\nimport { zodFieldResolver, zodResolver } from './zod-resolver'\nimport { z } from 'zod'\n\ntype ResolverArgs = Parameters<typeof zodResolver>\n\nexport interface CreateZodFormProps<FieldDefs>\n extends CreateFormProps<FieldDefs> {\n schemaOptions?: ResolverArgs[1]\n resolverOptions?: ResolverArgs[2]\n}\n\nexport type ZodFormType<\n FieldDefs,\n ExtraProps = object,\n ExtraOverrides = object,\n Type extends 'zod' = 'zod'\n> = (<\n TSchema extends z.AnyZodObject = z.AnyZodObject,\n TFieldValues extends z.infer<TSchema> = z.infer<TSchema>,\n TContext extends object = object\n>(\n props: WithFields<\n FormProps<TSchema, TFieldValues, TContext>,\n FieldDefs,\n ExtraOverrides\n > & {\n ref?: React.ForwardedRef<HTMLFormElement>\n } & ExtraProps\n) => React.ReactElement) & {\n displayName?: string\n id?: string\n}\n\nexport const createZodForm = <FieldDefs>(\n options?: CreateZodFormProps<FieldDefs>\n) => {\n const ZodForm = createForm({\n resolver: (schema: any) =>\n zodResolver(schema, options?.schemaOptions, options?.resolverOptions),\n fieldResolver: zodFieldResolver,\n ...options,\n })\n\n ZodForm.displayName = 'ZodForm'\n ZodForm.id = 'ZodForm'\n\n return ZodForm as ZodFormType<FieldDefs>\n}\n","import {\n CreateFormProps,\n createStepForm,\n StepsOptions,\n UseStepFormProps,\n} from '@saas-ui/forms'\nimport { zodFieldResolver, zodResolver } from './zod-resolver'\nimport { AnyZodObject, z } from 'zod'\nimport React from 'react'\n\ntype ResolverArgs = Parameters<typeof zodResolver>\n\nexport interface CreateZodFormProps<FieldDefs>\n extends CreateFormProps<FieldDefs> {\n schemaOptions?: ResolverArgs[1]\n resolverOptions?: ResolverArgs[2]\n}\n\ntype InferStepType<T extends Required<StepsOptions<AnyZodObject>>> = T extends [\n infer Step,\n ...infer Rest\n]\n ? Step extends { schema: AnyZodObject }\n ? z.infer<Step['schema']> &\n (Rest extends Required<StepsOptions<AnyZodObject>>\n ? InferStepType<Rest>\n : object)\n : object\n : object\n\ntype ZodStepFormType<\n FieldDefs,\n ExtraProps = object,\n ExtraOverrides = object\n> = (<\n TSteps extends Required<StepsOptions<AnyZodObject>> = Required<\n StepsOptions<AnyZodObject>\n >,\n TFieldValues extends InferStepType<TSteps> = InferStepType<TSteps>,\n TContext extends object = object\n>(\n props: UseStepFormProps<TSteps, TFieldValues, TContext> & {\n steps: TSteps\n ref?: React.ForwardedRef<HTMLFormElement>\n }\n) => React.ReactElement) & {\n displayName?: string\n id?: string\n}\n\nexport const createZodStepForm = <FieldDefs>(\n options?: CreateZodFormProps<FieldDefs>\n) => {\n const ZodStepForm = createStepForm<any, any, any, any>({\n resolver: (schema: any) =>\n zodResolver(schema, options?.schemaOptions, options?.resolverOptions),\n fieldResolver: zodFieldResolver,\n ...options,\n })\n\n ZodStepForm.displayName = 'ZodStepForm'\n ZodStepForm.id = 'ZodStepForm'\n\n return ZodStepForm as ZodStepFormType<FieldDefs>\n}\n","export {\n zodResolver,\n getFieldsFromSchema,\n getNestedSchema,\n zodFieldResolver,\n zodMeta,\n zodParseMeta,\n} from './zod-resolver'\nexport type { Options, ZodMeta } from './zod-resolver'\nexport { createZodForm, type ZodFormType } from './create-zod-form'\n\nimport { createZodForm } from './create-zod-form'\nimport { createZodStepForm } from './create-zod-step-form'\n\nexport const Form = createZodForm()\n\nexport const StepForm = createZodStepForm()\n"]}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@saas-ui/forms",
|
3
|
-
"version": "2.0.0-next.
|
3
|
+
"version": "2.0.0-next.20",
|
4
4
|
"description": "Fully functional forms for Chakra UI.",
|
5
5
|
"source": "src/index.ts",
|
6
6
|
"exports": {
|
@@ -103,8 +103,8 @@
|
|
103
103
|
"dependencies": {
|
104
104
|
"@chakra-ui/react-utils": "^2.0.12",
|
105
105
|
"@chakra-ui/utils": "^2.0.15",
|
106
|
-
"@hookform/resolvers": "^3.0
|
107
|
-
"@saas-ui/core": "2.0.0-next.
|
106
|
+
"@hookform/resolvers": "^3.1.0",
|
107
|
+
"@saas-ui/core": "2.0.0-next.17",
|
108
108
|
"react-hook-form": "^7.43.9"
|
109
109
|
},
|
110
110
|
"peerDependencies": {
|
@@ -119,9 +119,9 @@
|
|
119
119
|
"@types/json-schema": "^7.0.11",
|
120
120
|
"ajv": "^8.12.0",
|
121
121
|
"ajv-errors": "^3.0.0",
|
122
|
-
"json-schema-to-ts": "^2.
|
122
|
+
"json-schema-to-ts": "^2.8.2",
|
123
123
|
"tsd": "^0.28.1",
|
124
|
-
"yup": "^1.
|
124
|
+
"yup": "^1.1.1",
|
125
125
|
"zod": "^3.21.4"
|
126
126
|
},
|
127
127
|
"tsd": {
|
package/src/create-step-form.tsx
CHANGED
@@ -1,58 +1,39 @@
|
|
1
|
-
import { useMemo } from 'react'
|
1
|
+
import React, { useMemo } from 'react'
|
2
2
|
import { forwardRef } from '@chakra-ui/react'
|
3
|
-
import { FormType } from './create-form'
|
4
3
|
import {
|
5
4
|
ArrayField,
|
6
5
|
DisplayIf,
|
7
6
|
FieldProps,
|
8
7
|
FieldValues,
|
8
|
+
FieldsProvider,
|
9
9
|
Form,
|
10
|
+
GetFieldResolver,
|
10
11
|
ObjectField,
|
11
12
|
} from './'
|
12
13
|
import { Field } from './field'
|
13
|
-
import {
|
14
|
+
import { FormStep, StepsOptions } from './step-form'
|
14
15
|
import {
|
15
16
|
StepFormProvider,
|
16
17
|
UseStepFormProps,
|
17
18
|
useStepForm,
|
18
19
|
} from './use-step-form'
|
19
|
-
import { YupFormType } from '../yup/src/create-yup-form'
|
20
|
-
import { ZodFormType } from '../zod/src/create-zod-form'
|
21
20
|
import { StepperProvider } from '@saas-ui/core'
|
22
21
|
import { runIfFn } from '@chakra-ui/utils'
|
22
|
+
import { GetResolver } from './form'
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
>
|
38
|
-
: T extends ZodFormType<
|
39
|
-
infer FieldDefs,
|
40
|
-
infer ExtraProps,
|
41
|
-
infer ExtraOverrides,
|
42
|
-
'zod'
|
43
|
-
>
|
44
|
-
? ZodFormType<
|
45
|
-
FieldDefs,
|
46
|
-
ExtraProps & Omit<StepFormProps, 'children'>,
|
47
|
-
ExtraOverrides
|
48
|
-
>
|
49
|
-
: T extends FormType<infer FieldDefs, infer ExtraProps, infer ExtraOverrides>
|
50
|
-
? FormType<
|
51
|
-
FieldDefs,
|
52
|
-
ExtraProps & Omit<StepFormProps, 'children'>,
|
53
|
-
ExtraOverrides
|
54
|
-
>
|
55
|
-
: never
|
24
|
+
type StepFormType<FieldDefs, ExtraProps = object, ExtraOverrides = object> = (<
|
25
|
+
TSteps extends StepsOptions<any> = StepsOptions<any>,
|
26
|
+
TFieldValues extends FieldValues = FieldValues,
|
27
|
+
TContext extends object = object,
|
28
|
+
TFieldTypes = FieldProps<TFieldValues>
|
29
|
+
>(
|
30
|
+
props: UseStepFormProps<TSteps, TFieldValues, TContext, TFieldTypes> & {
|
31
|
+
ref?: React.ForwardedRef<HTMLFormElement>
|
32
|
+
}
|
33
|
+
) => React.ReactElement) & {
|
34
|
+
displayName?: string
|
35
|
+
id?: string
|
36
|
+
}
|
56
37
|
|
57
38
|
export type DefaultFormType<
|
58
39
|
FieldDefs = any,
|
@@ -69,59 +50,25 @@ export type DefaultFormType<
|
|
69
50
|
id?: string
|
70
51
|
}
|
71
52
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
// FieldDefs,
|
78
|
-
// ExtraProps,
|
79
|
-
// ExtraOverrides
|
80
|
-
// > = DefaultFormType<FieldDefs, ExtraProps, ExtraOverrides>
|
81
|
-
// >(Form: TFormType) {
|
82
|
-
// const StepForm = forwardRef<any, 'div'>((props, ref) => {
|
83
|
-
// const { children, ...rest } = props
|
84
|
-
|
85
|
-
// const stepper = useStepForm(props)
|
86
|
-
|
87
|
-
// const { getFormProps, ...ctx } = stepper
|
88
|
-
|
89
|
-
// const context = useMemo(() => ctx, [ctx])
|
90
|
-
|
91
|
-
// return (
|
92
|
-
// <StepperProvider value={context}>
|
93
|
-
// <StepFormProvider value={context}>
|
94
|
-
// <Form ref={ref} {...rest} {...getFormProps()}>
|
95
|
-
// {runIfFn(children, {
|
96
|
-
// ...stepper,
|
97
|
-
// FormStep,
|
98
|
-
// Field,
|
99
|
-
// })}
|
100
|
-
// </Form>
|
101
|
-
// </StepFormProvider>
|
102
|
-
// </StepperProvider>
|
103
|
-
// )
|
104
|
-
// }) as MergeStepFormProps<TFormType>
|
105
|
-
|
106
|
-
// StepForm.displayName = `Step${Form.displayName || Form.name}`
|
107
|
-
|
108
|
-
// return StepForm
|
109
|
-
// }
|
53
|
+
export interface CreateFormProps<FieldDefs> {
|
54
|
+
resolver?: GetResolver
|
55
|
+
fieldResolver?: GetFieldResolver
|
56
|
+
fields?: FieldDefs extends Record<string, React.FC<any>> ? FieldDefs : never
|
57
|
+
}
|
110
58
|
|
111
59
|
export function createStepForm<
|
112
60
|
FieldDefs = any,
|
113
61
|
ExtraProps = object,
|
114
|
-
ExtraOverrides = object
|
115
|
-
|
116
|
-
FieldDefs,
|
117
|
-
ExtraProps,
|
118
|
-
ExtraOverrides
|
119
|
-
> = DefaultFormType<FieldDefs, ExtraProps, ExtraOverrides>
|
120
|
-
>(Form: TFormType) {
|
62
|
+
ExtraOverrides = object
|
63
|
+
>({ fields, resolver, fieldResolver }: CreateFormProps<FieldDefs> = {}) {
|
121
64
|
const StepForm = forwardRef<any, 'div'>((props, ref) => {
|
122
|
-
const { children, ...rest } = props
|
65
|
+
const { children, steps, ...rest } = props
|
123
66
|
|
124
|
-
const stepper = useStepForm(
|
67
|
+
const stepper = useStepForm({
|
68
|
+
resolver,
|
69
|
+
fieldResolver,
|
70
|
+
...props,
|
71
|
+
})
|
125
72
|
|
126
73
|
const { getFormProps, ...ctx } = stepper
|
127
74
|
|
@@ -130,30 +77,22 @@ export function createStepForm<
|
|
130
77
|
return (
|
131
78
|
<StepperProvider value={context}>
|
132
79
|
<StepFormProvider value={context}>
|
133
|
-
<
|
134
|
-
{
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
80
|
+
<FieldsProvider value={fields || {}}>
|
81
|
+
<Form ref={ref} {...rest} {...getFormProps()}>
|
82
|
+
{runIfFn(children, {
|
83
|
+
...stepper,
|
84
|
+
Field: Field as any,
|
85
|
+
FormStep: FormStep as any,
|
86
|
+
DisplayIf: DisplayIf as any,
|
87
|
+
ArrayField: ArrayField as any,
|
88
|
+
ObjectField: ObjectField as any,
|
89
|
+
})}
|
90
|
+
</Form>
|
91
|
+
</FieldsProvider>
|
142
92
|
</StepFormProvider>
|
143
93
|
</StepperProvider>
|
144
94
|
)
|
145
|
-
}) as
|
146
|
-
TFieldValues extends FieldValues = FieldValues,
|
147
|
-
TContext extends object = object,
|
148
|
-
TFieldTypes = FieldProps<TFieldValues>
|
149
|
-
>(
|
150
|
-
props: UseStepFormProps<TFieldValues, TContext, TFieldTypes> & {
|
151
|
-
ref?: React.ForwardedRef<HTMLFormElement>
|
152
|
-
}
|
153
|
-
) => React.ReactElement) & {
|
154
|
-
displayName?: string
|
155
|
-
id?: string
|
156
|
-
}
|
95
|
+
}) as StepFormType<FieldDefs, ExtraProps, ExtraOverrides>
|
157
96
|
|
158
97
|
StepForm.displayName = `Step${Form.displayName || Form.name}`
|
159
98
|
|
package/src/index.ts
CHANGED
@@ -57,14 +57,21 @@ export { FormProvider, useFormContext } from './form-context'
|
|
57
57
|
import { createForm } from './create-form'
|
58
58
|
import { createStepForm } from './create-step-form'
|
59
59
|
|
60
|
+
/**
|
61
|
+
* Form component.
|
62
|
+
*
|
63
|
+
* @see Docs https://saas-ui.dev/docs/components/forms/form
|
64
|
+
*/
|
60
65
|
export const Form = createForm()
|
61
66
|
|
67
|
+
export { createStepForm } from './create-step-form'
|
68
|
+
|
62
69
|
/**
|
63
|
-
*
|
70
|
+
* Multi-step form component.
|
64
71
|
*
|
65
72
|
* @see Docs https://saas-ui.dev/docs/components/forms/step-form
|
66
73
|
*/
|
67
|
-
export const StepForm = createStepForm(
|
74
|
+
export const StepForm = createStepForm()
|
68
75
|
|
69
76
|
export type {
|
70
77
|
BatchFieldArrayUpdate,
|
package/src/step-form.tsx
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import * as React from 'react'
|
2
2
|
|
3
|
-
import { FieldValues
|
3
|
+
import { FieldValues } from 'react-hook-form'
|
4
4
|
|
5
5
|
import {
|
6
6
|
chakra,
|
@@ -10,90 +10,48 @@ import {
|
|
10
10
|
ThemingProps,
|
11
11
|
} from '@chakra-ui/react'
|
12
12
|
|
13
|
-
import { callAllHandlers,
|
13
|
+
import { callAllHandlers, cx } from '@chakra-ui/utils'
|
14
14
|
|
15
15
|
import {
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
Steps,
|
17
|
+
StepsItem,
|
18
|
+
StepsItemProps,
|
19
|
+
StepsProps,
|
20
20
|
useStepperContext,
|
21
|
-
StepperContainer,
|
22
|
-
StepperProps,
|
23
21
|
} from '@saas-ui/core'
|
24
22
|
|
25
|
-
import { Form } from './'
|
26
|
-
import { Field } from './field'
|
27
|
-
|
28
23
|
import { SubmitButton } from './submit-button'
|
29
24
|
|
30
25
|
import {
|
31
|
-
useStepForm,
|
32
26
|
useFormStep,
|
33
|
-
StepFormProvider,
|
34
27
|
UseStepFormProps,
|
35
28
|
FormStepSubmitHandler,
|
36
29
|
} from './use-step-form'
|
37
30
|
import { FieldProps } from './types'
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
31
|
+
|
32
|
+
export type StepsOptions<TSchema, TName extends string = string> = {
|
33
|
+
/**
|
34
|
+
* The step name
|
35
|
+
*/
|
36
|
+
name: TName
|
37
|
+
/**
|
38
|
+
* Schema
|
39
|
+
*/
|
40
|
+
schema?: TSchema
|
41
|
+
}[]
|
42
42
|
|
43
43
|
export interface StepFormProps<
|
44
|
+
TSteps extends StepsOptions<any> = StepsOptions<any>,
|
44
45
|
TFieldValues extends FieldValues = FieldValues,
|
45
46
|
TContext extends object = object,
|
46
47
|
TFieldTypes = FieldProps<TFieldValues>
|
47
|
-
> extends UseStepFormProps<TFieldValues, TContext, TFieldTypes> {}
|
48
|
-
|
49
|
-
|
50
|
-
// <
|
51
|
-
// TFieldValues extends FieldValues = FieldValues,
|
52
|
-
// TContext extends object = object,
|
53
|
-
// TFieldTypes = FieldProps<TFieldValues>
|
54
|
-
// >(
|
55
|
-
// props: StepFormProps<TFieldValues, TContext, TFieldTypes>,
|
56
|
-
// ref: React.ForwardedRef<HTMLFormElement>
|
57
|
-
// ) => {
|
58
|
-
// const { children, ...rest } = props
|
59
|
-
|
60
|
-
// const stepper = useStepForm(props)
|
61
|
-
|
62
|
-
// const { getFormProps, ...ctx } = stepper
|
63
|
-
|
64
|
-
// const context = React.useMemo(() => ctx, [ctx])
|
65
|
-
|
66
|
-
// return (
|
67
|
-
// <StepperProvider value={context}>
|
68
|
-
// <StepFormProvider value={context}>
|
69
|
-
// <Form ref={ref} {...rest} {...getFormProps()}>
|
70
|
-
// {runIfFn(children, {
|
71
|
-
// ...stepper,
|
72
|
-
// Field: Field as any,
|
73
|
-
// DisplayIf: DisplayIf as any,
|
74
|
-
// ArrayField: ArrayField as any,
|
75
|
-
// ObjectField: ObjectField as any,
|
76
|
-
// })}
|
77
|
-
// </Form>
|
78
|
-
// </StepFormProvider>
|
79
|
-
// </StepperProvider>
|
80
|
-
// )
|
81
|
-
// }
|
82
|
-
// ) as <
|
83
|
-
// TFieldValues extends FieldValues = FieldValues,
|
84
|
-
// TContext extends object = object,
|
85
|
-
// TFieldTypes = FieldProps<TFieldValues>
|
86
|
-
// >(
|
87
|
-
// props: UseStepFormProps<TFieldValues, TContext, TFieldTypes> & {
|
88
|
-
// ref?: React.ForwardedRef<HTMLFormElement>
|
89
|
-
// }
|
90
|
-
// ) => React.ReactElement
|
91
|
-
|
92
|
-
export interface FormStepOptions {
|
48
|
+
> extends UseStepFormProps<TSteps, TFieldValues, TContext, TFieldTypes> {}
|
49
|
+
|
50
|
+
export interface FormStepOptions<TName extends string = string> {
|
93
51
|
/**
|
94
52
|
* The step name
|
95
53
|
*/
|
96
|
-
name:
|
54
|
+
name: TName
|
97
55
|
/**
|
98
56
|
* Schema
|
99
57
|
*/
|
@@ -104,9 +62,9 @@ export interface FormStepOptions {
|
|
104
62
|
resolver?: any
|
105
63
|
}
|
106
64
|
|
107
|
-
export interface FormStepperProps
|
108
|
-
|
109
|
-
|
65
|
+
export interface FormStepperProps extends StepsProps, ThemingProps<'Stepper'> {
|
66
|
+
render?: StepsItemProps['render']
|
67
|
+
}
|
110
68
|
|
111
69
|
/**
|
112
70
|
* Renders a stepper that displays progress above the form.
|
@@ -116,7 +74,16 @@ export interface FormStepperProps
|
|
116
74
|
export const FormStepper: React.FC<FormStepperProps> = (props) => {
|
117
75
|
const { activeIndex, setIndex } = useStepperContext()
|
118
76
|
|
119
|
-
const {
|
77
|
+
const {
|
78
|
+
children,
|
79
|
+
orientation,
|
80
|
+
variant,
|
81
|
+
colorScheme,
|
82
|
+
size,
|
83
|
+
onChange: onChangeProp,
|
84
|
+
render,
|
85
|
+
...rest
|
86
|
+
} = props
|
120
87
|
|
121
88
|
const elements = React.Children.map(children, (child) => {
|
122
89
|
if (
|
@@ -125,14 +92,15 @@ export const FormStepper: React.FC<FormStepperProps> = (props) => {
|
|
125
92
|
) {
|
126
93
|
const { isCompleted } = useFormStep(child.props) // Register this step
|
127
94
|
return (
|
128
|
-
<
|
95
|
+
<StepsItem
|
96
|
+
render={render}
|
129
97
|
name={child.props.name}
|
130
98
|
title={child.props.title}
|
131
99
|
isCompleted={isCompleted}
|
132
100
|
{...rest}
|
133
101
|
>
|
134
102
|
{child.props.children}
|
135
|
-
</
|
103
|
+
</StepsItem>
|
136
104
|
)
|
137
105
|
}
|
138
106
|
return child
|
@@ -140,10 +108,11 @@ export const FormStepper: React.FC<FormStepperProps> = (props) => {
|
|
140
108
|
|
141
109
|
const onChange = React.useCallback((i: number) => {
|
142
110
|
setIndex(i)
|
111
|
+
onChangeProp?.(i)
|
143
112
|
}, [])
|
144
113
|
|
145
114
|
return (
|
146
|
-
<
|
115
|
+
<Steps
|
147
116
|
orientation={orientation}
|
148
117
|
step={activeIndex}
|
149
118
|
variant={variant}
|
@@ -151,15 +120,13 @@ export const FormStepper: React.FC<FormStepperProps> = (props) => {
|
|
151
120
|
size={size}
|
152
121
|
onChange={onChange}
|
153
122
|
>
|
154
|
-
|
155
|
-
|
156
|
-
</StepperSteps>
|
157
|
-
</StepperContainer>
|
123
|
+
{elements}
|
124
|
+
</Steps>
|
158
125
|
)
|
159
126
|
}
|
160
127
|
|
161
|
-
export interface FormStepProps
|
162
|
-
extends FormStepOptions
|
128
|
+
export interface FormStepProps<TName extends string = string>
|
129
|
+
extends FormStepOptions<TName>,
|
163
130
|
Omit<HTMLChakraProps<'div'>, 'onSubmit'> {
|
164
131
|
onSubmit?: FormStepSubmitHandler
|
165
132
|
}
|
@@ -168,10 +135,11 @@ export interface FormStepProps
|
|
168
135
|
*
|
169
136
|
* @see Docs https://saas-ui.dev/docs/components/forms/step-form
|
170
137
|
*/
|
171
|
-
export const FormStep
|
172
|
-
|
173
|
-
|
174
|
-
const
|
138
|
+
export const FormStep = <TName extends string = string>(
|
139
|
+
props: FormStepProps<TName>
|
140
|
+
) => {
|
141
|
+
const { name, children, className, onSubmit, ...rest } = props
|
142
|
+
const step = useFormStep({ name, onSubmit })
|
175
143
|
|
176
144
|
const { isActive } = step
|
177
145
|
|
package/src/use-step-form.tsx
CHANGED
@@ -34,7 +34,7 @@ export const [StepFormProvider, useStepFormContext] =
|
|
34
34
|
})
|
35
35
|
|
36
36
|
import { FormProps } from './form'
|
37
|
-
import { FormStepProps } from './step-form'
|
37
|
+
import { FormStepProps, StepsOptions } from './step-form'
|
38
38
|
import { FieldProps } from './types'
|
39
39
|
import { FocusableElement } from '@chakra-ui/utils'
|
40
40
|
import { DisplayIfProps } from './display-if'
|
@@ -42,12 +42,17 @@ import { ArrayFieldProps } from './array-field'
|
|
42
42
|
import { UseArrayFieldReturn } from './use-array-field'
|
43
43
|
import { ObjectFieldProps } from './object-field'
|
44
44
|
|
45
|
+
type StepName<T extends { [k: number]: { readonly name: string } }> =
|
46
|
+
T[number]['name']
|
47
|
+
|
45
48
|
interface StepFormRenderContext<
|
49
|
+
TSteps extends StepsOptions<any> = StepsOptions<any>,
|
46
50
|
TFieldValues extends FieldValues = FieldValues,
|
47
51
|
TContext extends object = object,
|
48
52
|
TFieldTypes = FieldProps<TFieldValues>
|
49
53
|
> extends UseStepFormReturn<TFieldValues> {
|
50
54
|
Field: React.FC<TFieldTypes & React.RefAttributes<FocusableElement>>
|
55
|
+
FormStep: React.FC<FormStepProps<StepName<TSteps>>>
|
51
56
|
DisplayIf: React.FC<DisplayIfProps<TFieldValues>>
|
52
57
|
ArrayField: React.FC<
|
53
58
|
ArrayFieldProps<TFieldValues> & React.RefAttributes<UseArrayFieldReturn>
|
@@ -56,13 +61,15 @@ interface StepFormRenderContext<
|
|
56
61
|
}
|
57
62
|
|
58
63
|
export interface UseStepFormProps<
|
64
|
+
TSteps extends StepsOptions<any> = StepsOptions<any>,
|
59
65
|
TFieldValues extends FieldValues = FieldValues,
|
60
66
|
TContext extends object = object,
|
61
67
|
TFieldTypes = FieldProps<TFieldValues>
|
62
68
|
> extends Omit<UseStepperProps, 'onChange'>,
|
63
69
|
Omit<FormProps<any, TFieldValues, TContext, TFieldTypes>, 'children'> {
|
70
|
+
steps?: TSteps
|
64
71
|
children: MaybeRenderProp<
|
65
|
-
StepFormRenderContext<TFieldValues, TContext, TFieldTypes>
|
72
|
+
StepFormRenderContext<TSteps, TFieldValues, TContext, TFieldTypes>
|
66
73
|
>
|
67
74
|
}
|
68
75
|
|
@@ -79,15 +86,18 @@ export interface UseStepFormReturn<
|
|
79
86
|
}
|
80
87
|
|
81
88
|
export function useStepForm<
|
89
|
+
TSteps extends StepsOptions<any> = StepsOptions<any>,
|
82
90
|
TFieldValues extends FieldValues = FieldValues,
|
83
91
|
TContext extends object = object,
|
84
92
|
TFieldTypes = FieldProps<TFieldValues>
|
85
93
|
>(
|
86
|
-
props: UseStepFormProps<TFieldValues, TContext, TFieldTypes>
|
94
|
+
props: UseStepFormProps<TSteps, TFieldValues, TContext, TFieldTypes>
|
87
95
|
): UseStepFormReturn<TFieldValues> {
|
88
|
-
const { onChange, ...rest } = props
|
96
|
+
const { onChange, steps: stepsOptions, resolver, ...rest } = props
|
89
97
|
const stepper = useStepper(rest)
|
90
98
|
|
99
|
+
const [options, setOptions] = React.useState<TSteps | undefined>(stepsOptions)
|
100
|
+
|
91
101
|
const { activeStep, isLastStep, nextStep } = stepper
|
92
102
|
|
93
103
|
const [steps, updateSteps] = React.useState<Record<string, StepState>>({})
|
@@ -121,23 +131,30 @@ export function useStepForm<
|
|
121
131
|
|
122
132
|
const getFormProps = React.useCallback(() => {
|
123
133
|
const step = steps[activeStep]
|
134
|
+
|
124
135
|
return {
|
125
136
|
onSubmit: onSubmitStep,
|
126
137
|
schema: step?.schema,
|
127
|
-
resolver: step?.
|
138
|
+
resolver: step?.schema
|
139
|
+
? /* @todo fix resolver type */ (resolver as any)?.(step.schema)
|
140
|
+
: undefined,
|
128
141
|
}
|
129
142
|
}, [steps, onSubmitStep, activeStep])
|
130
143
|
|
131
144
|
const updateStep = React.useCallback(
|
132
145
|
(step: StepState) => {
|
146
|
+
const stepOptions = options?.find((s) => s.name === step.name)
|
133
147
|
updateSteps((steps) => {
|
134
148
|
return {
|
135
149
|
...steps,
|
136
|
-
[step.name]:
|
150
|
+
[step.name]: {
|
151
|
+
...step,
|
152
|
+
schema: stepOptions?.schema,
|
153
|
+
},
|
137
154
|
}
|
138
155
|
})
|
139
156
|
},
|
140
|
-
[steps]
|
157
|
+
[steps, options]
|
141
158
|
)
|
142
159
|
|
143
160
|
return {
|