@saas-ui/forms 1.5.3 → 2.0.0-next.1
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +19 -2
- package/dist/ajv/index.d.ts +21 -2
- package/dist/ajv/index.js +31 -2
- package/dist/ajv/index.js.map +1 -1
- package/dist/ajv/index.mjs +25 -0
- package/dist/ajv/index.mjs.map +1 -0
- package/dist/index.d.ts +606 -18
- package/dist/index.js +1251 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1140 -0
- package/dist/index.mjs.map +1 -0
- package/dist/yup/index.d.ts +41 -2
- package/dist/yup/index.js +95 -2
- package/dist/yup/index.js.map +1 -1
- package/dist/yup/index.mjs +86 -0
- package/dist/yup/index.mjs.map +1 -0
- package/dist/zod/index.d.ts +38 -2
- package/dist/zod/index.js +95 -2
- package/dist/zod/index.js.map +1 -1
- package/dist/zod/index.mjs +85 -0
- package/dist/zod/index.mjs.map +1 -0
- package/package.json +23 -33
- package/src/array-field.tsx +20 -13
- package/src/auto-form.tsx +13 -19
- package/src/field-resolver.ts +1 -1
- package/src/field.tsx +4 -9
- package/src/fields.tsx +1 -3
- package/src/form.tsx +69 -25
- package/src/index.ts +3 -0
- package/src/input-right-button/index.ts +1 -0
- package/src/input-right-button/input-right-button.stories.tsx +47 -0
- package/src/input-right-button/input-right-button.test.tsx +12 -0
- package/src/input-right-button/input-right-button.tsx +26 -0
- package/src/layout.tsx +1 -1
- package/src/number-input/index.ts +1 -0
- package/src/number-input/number-input.stories.tsx +39 -0
- package/src/number-input/number-input.test.tsx +6 -0
- package/src/number-input/number-input.tsx +56 -0
- package/src/object-field.tsx +1 -1
- package/src/password-input/index.ts +1 -0
- package/src/password-input/password-input.stories.tsx +50 -0
- package/src/password-input/password-input.test.tsx +20 -0
- package/src/password-input/password-input.tsx +69 -0
- package/src/pin-input/index.ts +1 -0
- package/src/pin-input/pin-input.stories.tsx +38 -0
- package/src/pin-input/pin-input.test.tsx +6 -0
- package/src/pin-input/pin-input.tsx +50 -0
- package/src/radio/index.ts +1 -0
- package/src/radio/radio-input.stories.tsx +45 -0
- package/src/radio/radio-input.tsx +58 -0
- package/src/radio/radio.test.tsx +6 -0
- package/src/select/index.ts +2 -0
- package/src/select/native-select.tsx +42 -0
- package/src/select/select.stories.tsx +144 -0
- package/src/select/select.test.tsx +8 -0
- package/src/select/select.tsx +185 -0
- package/src/step-form.tsx +24 -13
- package/src/submit-button.tsx +32 -38
- package/src/use-step-form.tsx +1 -1
- package/ajv/package.json +0 -28
- package/dist/ajv/ajv-resolver.d.ts +0 -11
- package/dist/ajv/ajv-resolver.d.ts.map +0 -1
- package/dist/ajv/index.d.ts.map +0 -1
- package/dist/ajv/index.modern.mjs +0 -2
- package/dist/ajv/index.modern.mjs.map +0 -1
- package/dist/array-field.d.ts +0 -64
- package/dist/array-field.d.ts.map +0 -1
- package/dist/auto-form.d.ts +0 -32
- package/dist/auto-form.d.ts.map +0 -1
- package/dist/display-field.d.ts +0 -10
- package/dist/display-field.d.ts.map +0 -1
- package/dist/display-if.d.ts +0 -15
- package/dist/display-if.d.ts.map +0 -1
- package/dist/field-resolver.d.ts +0 -13
- package/dist/field-resolver.d.ts.map +0 -1
- package/dist/field.d.ts +0 -147
- package/dist/field.d.ts.map +0 -1
- package/dist/fields.d.ts +0 -9
- package/dist/fields.d.ts.map +0 -1
- package/dist/form.d.ts +0 -44
- package/dist/form.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.modern.mjs +0 -2
- package/dist/index.modern.mjs.map +0 -1
- package/dist/layout.d.ts +0 -14
- package/dist/layout.d.ts.map +0 -1
- package/dist/object-field.d.ts +0 -12
- package/dist/object-field.d.ts.map +0 -1
- package/dist/step-form.d.ts +0 -38
- package/dist/step-form.d.ts.map +0 -1
- package/dist/submit-button.d.ts +0 -20
- package/dist/submit-button.d.ts.map +0 -1
- package/dist/use-array-field.d.ts +0 -95
- package/dist/use-array-field.d.ts.map +0 -1
- package/dist/use-step-form.d.ts +0 -40
- package/dist/use-step-form.d.ts.map +0 -1
- package/dist/utils.d.ts +0 -3
- package/dist/utils.d.ts.map +0 -1
- package/dist/watch-field.d.ts +0 -11
- package/dist/watch-field.d.ts.map +0 -1
- package/dist/yup/index.d.ts.map +0 -1
- package/dist/yup/index.modern.mjs +0 -2
- package/dist/yup/index.modern.mjs.map +0 -1
- package/dist/yup/yup-resolver.d.ts +0 -29
- package/dist/yup/yup-resolver.d.ts.map +0 -1
- package/dist/zod/index.d.ts.map +0 -1
- package/dist/zod/index.modern.mjs +0 -2
- package/dist/zod/index.modern.mjs.map +0 -1
- package/dist/zod/zod-resolver.d.ts +0 -35
- package/dist/zod/zod-resolver.d.ts.map +0 -1
- package/yup/package.json +0 -26
- package/zod/package.json +0 -27
package/dist/zod/index.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"
|
1
|
+
{"version":3,"sources":["../../zod/src/zod-resolver.ts","../../zod/src/create-zod-form.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,UAAX,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;AAE3B,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,SAAS,kBAA8C;AAWhD,IAAM,gBAAgB,CAAC,YAAiC;AAC7D,SAAO,WAA2B;AAAA,IAChC,UAAU,CAAC,WACT,YAAY,QAAQ,mCAAS,eAAe,mCAAS,eAAe;AAAA,IACtE,GAAG;AAAA,EACL,CAAC;AAMH","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 { createForm, CreateFormProps, FormProps } from '@saas-ui/forms'\nimport { zodResolver } from './zod-resolver'\nimport { z } from 'zod'\n\ntype ResolverArgs = Parameters<typeof zodResolver>\n\nexport interface CreateZodFormProps extends CreateFormProps {\n schemaOptions?: ResolverArgs[1]\n resolverOptions?: ResolverArgs[2]\n}\n\nexport const createZodForm = (options?: CreateZodFormProps) => {\n return createForm<z.AnyZodObject>({\n resolver: (schema) =>\n zodResolver(schema, options?.schemaOptions, options?.resolverOptions),\n ...options,\n }) as <\n TSchema extends z.AnyZodObject = z.AnyZodObject,\n TContext extends object = object\n >(\n props: FormProps<z.infer<TSchema>, TContext, TSchema>\n ) => React.ReactElement\n}\n"]}
|
@@ -0,0 +1,85 @@
|
|
1
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
2
|
+
export { zodResolver } from '@hookform/resolvers/zod';
|
3
|
+
import { get } from '@chakra-ui/utils';
|
4
|
+
import { createForm } from '@saas-ui/forms';
|
5
|
+
|
6
|
+
// zod/src/zod-resolver.ts
|
7
|
+
var getType = (field) => {
|
8
|
+
switch (field._def.typeName) {
|
9
|
+
case "ZodArray":
|
10
|
+
return "array";
|
11
|
+
case "ZodObject":
|
12
|
+
return "object";
|
13
|
+
case "ZodNumber":
|
14
|
+
return "number";
|
15
|
+
case "ZodDate":
|
16
|
+
return "date";
|
17
|
+
case "ZodString":
|
18
|
+
default:
|
19
|
+
return "text";
|
20
|
+
}
|
21
|
+
};
|
22
|
+
var getArrayOption = (field, name) => {
|
23
|
+
var _a;
|
24
|
+
return (_a = field._def[name]) == null ? void 0 : _a.value;
|
25
|
+
};
|
26
|
+
var getFieldsFromSchema = (schema) => {
|
27
|
+
const fields = [];
|
28
|
+
let schemaFields = {};
|
29
|
+
if (schema._def.typeName === "ZodArray") {
|
30
|
+
schemaFields = schema._def.type.shape;
|
31
|
+
} else if (schema._def.typeName === "ZodObject") {
|
32
|
+
schemaFields = schema._def.shape();
|
33
|
+
} else {
|
34
|
+
return fields;
|
35
|
+
}
|
36
|
+
for (const name in schemaFields) {
|
37
|
+
const field = schemaFields[name];
|
38
|
+
const options = {};
|
39
|
+
if (field._def.typeName === "ZodArray") {
|
40
|
+
options.min = getArrayOption(field, "minLength");
|
41
|
+
options.max = getArrayOption(field, "maxLength");
|
42
|
+
}
|
43
|
+
const meta = field.description && zodParseMeta(field.description);
|
44
|
+
fields.push({
|
45
|
+
name,
|
46
|
+
label: (meta == null ? void 0 : meta.label) || field.description || name,
|
47
|
+
type: (meta == null ? void 0 : meta.type) || getType(field),
|
48
|
+
...options
|
49
|
+
});
|
50
|
+
}
|
51
|
+
return fields;
|
52
|
+
};
|
53
|
+
var getNestedSchema = (schema, path) => {
|
54
|
+
return get(schema._def.shape(), path);
|
55
|
+
};
|
56
|
+
var zodFieldResolver = (schema) => {
|
57
|
+
return {
|
58
|
+
getFields() {
|
59
|
+
return getFieldsFromSchema(schema);
|
60
|
+
},
|
61
|
+
getNestedFields(name) {
|
62
|
+
return getFieldsFromSchema(getNestedSchema(schema, name));
|
63
|
+
}
|
64
|
+
};
|
65
|
+
};
|
66
|
+
var zodMeta = (meta) => {
|
67
|
+
return JSON.stringify(meta);
|
68
|
+
};
|
69
|
+
var zodParseMeta = (meta) => {
|
70
|
+
try {
|
71
|
+
return JSON.parse(meta);
|
72
|
+
} catch (e) {
|
73
|
+
return meta;
|
74
|
+
}
|
75
|
+
};
|
76
|
+
var createZodForm = (options) => {
|
77
|
+
return createForm({
|
78
|
+
resolver: (schema) => zodResolver(schema, options == null ? void 0 : options.schemaOptions, options == null ? void 0 : options.resolverOptions),
|
79
|
+
...options
|
80
|
+
});
|
81
|
+
};
|
82
|
+
|
83
|
+
export { createZodForm, getFieldsFromSchema, getNestedSchema, zodFieldResolver, zodMeta, zodParseMeta };
|
84
|
+
//# sourceMappingURL=out.js.map
|
85
|
+
//# sourceMappingURL=index.mjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["../../zod/src/zod-resolver.ts","../../zod/src/create-zod-form.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,UAAX,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;AAE3B,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,SAAS,kBAA8C;AAWhD,IAAM,gBAAgB,CAAC,YAAiC;AAC7D,SAAO,WAA2B;AAAA,IAChC,UAAU,CAAC,WACT,YAAY,QAAQ,mCAAS,eAAe,mCAAS,eAAe;AAAA,IACtE,GAAG;AAAA,EACL,CAAC;AAMH","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 { createForm, CreateFormProps, FormProps } from '@saas-ui/forms'\nimport { zodResolver } from './zod-resolver'\nimport { z } from 'zod'\n\ntype ResolverArgs = Parameters<typeof zodResolver>\n\nexport interface CreateZodFormProps extends CreateFormProps {\n schemaOptions?: ResolverArgs[1]\n resolverOptions?: ResolverArgs[2]\n}\n\nexport const createZodForm = (options?: CreateZodFormProps) => {\n return createForm<z.AnyZodObject>({\n resolver: (schema) =>\n zodResolver(schema, options?.schemaOptions, options?.resolverOptions),\n ...options,\n }) as <\n TSchema extends z.AnyZodObject = z.AnyZodObject,\n TContext extends object = object\n >(\n props: FormProps<z.infer<TSchema>, TContext, TSchema>\n ) => React.ReactElement\n}\n"]}
|
package/package.json
CHANGED
@@ -1,61 +1,55 @@
|
|
1
1
|
{
|
2
2
|
"name": "@saas-ui/forms",
|
3
|
-
"version": "
|
3
|
+
"version": "2.0.0-next.1",
|
4
4
|
"description": "Fully functional forms for Chakra UI.",
|
5
5
|
"source": "src/index.ts",
|
6
6
|
"exports": {
|
7
7
|
".": {
|
8
8
|
"require": "./dist/index.js",
|
9
|
-
"import": "./dist/index.
|
9
|
+
"import": "./dist/index.mjs"
|
10
10
|
},
|
11
11
|
"./src": {
|
12
12
|
"default": "./src/index.ts"
|
13
13
|
},
|
14
14
|
"./yup": {
|
15
15
|
"require": "./dist/yup/index.js",
|
16
|
-
"import": "./dist/yup/index.
|
16
|
+
"import": "./dist/yup/index.mjs"
|
17
17
|
},
|
18
18
|
"./yup/src": {
|
19
19
|
"default": "./yup/src/index.ts"
|
20
20
|
},
|
21
21
|
"./zod": {
|
22
22
|
"require": "./dist/zod/index.js",
|
23
|
-
"import": "./dist/zod/index.
|
23
|
+
"import": "./dist/zod/index.mjs"
|
24
24
|
},
|
25
25
|
"./zod/src": {
|
26
26
|
"default": "./zod/src/index.ts"
|
27
27
|
},
|
28
28
|
"./ajv": {
|
29
29
|
"require": "./dist/ajv/index.js",
|
30
|
-
"import": "./dist/ajv/index.
|
30
|
+
"import": "./dist/ajv/index.mjs"
|
31
31
|
},
|
32
32
|
"./ajv/src": {
|
33
33
|
"default": "./ajv/src/index.ts"
|
34
34
|
}
|
35
35
|
},
|
36
36
|
"main": "./dist/index.js",
|
37
|
-
"module": "./dist/index.
|
37
|
+
"module": "./dist/index.mjs",
|
38
38
|
"types": "./dist/index.d.ts",
|
39
39
|
"scripts": {
|
40
40
|
"clean": "rimraf --no-glob ./dist",
|
41
41
|
"build": "yarn build:package && yarn build:yup && yarn build:zod && yarn build:ajv",
|
42
|
-
"build:package": "
|
43
|
-
"build:yup": "
|
44
|
-
"build:zod": "
|
45
|
-
"build:ajv": "
|
42
|
+
"build:package": "tsup src/index.ts --config tsup.config.ts",
|
43
|
+
"build:yup": "tsup yup/src/index.ts --config yup/tsup.config.ts",
|
44
|
+
"build:zod": "tsup zod/src/index.ts --config zod/tsup.config.ts",
|
45
|
+
"build:ajv": "tsup ajv/src/index.ts --config ajv/tsup.config.ts",
|
46
46
|
"lint": "eslint src --ext .ts,.tsx,.js,.jsx --config ../../.eslintrc.js",
|
47
47
|
"lint:staged": "lint-staged --allow-empty --config ../../lint-staged.config.js",
|
48
48
|
"typecheck": "tsc --noEmit"
|
49
49
|
},
|
50
50
|
"files": [
|
51
51
|
"dist",
|
52
|
-
"src"
|
53
|
-
"yup/package.json",
|
54
|
-
"yup/src",
|
55
|
-
"zod/package.json",
|
56
|
-
"zod/src",
|
57
|
-
"ajv/package.json",
|
58
|
-
"ajv/src"
|
52
|
+
"src"
|
59
53
|
],
|
60
54
|
"sideEffects": false,
|
61
55
|
"publishConfig": {
|
@@ -92,26 +86,22 @@
|
|
92
86
|
"@chakra-ui/icons": "^2.0.16",
|
93
87
|
"@chakra-ui/react-utils": "^2.0.11",
|
94
88
|
"@chakra-ui/utils": "^2.0.14",
|
95
|
-
"@
|
96
|
-
"
|
97
|
-
"@saas-ui/input-right-button": "1.4.0",
|
98
|
-
"@saas-ui/number-input": "1.4.0",
|
99
|
-
"@saas-ui/password-input": "1.4.0",
|
100
|
-
"@saas-ui/pin-input": "1.4.0",
|
101
|
-
"@saas-ui/radio": "1.4.1",
|
102
|
-
"@saas-ui/react-utils": "1.2.0",
|
103
|
-
"@saas-ui/select": "1.4.0",
|
104
|
-
"@saas-ui/stepper": "1.4.0",
|
105
|
-
"react-hook-form": "^7.42.1"
|
89
|
+
"@saas-ui/core": "2.0.0-next.1",
|
90
|
+
"react-hook-form": "^7.43.0"
|
106
91
|
},
|
107
92
|
"peerDependencies": {
|
108
|
-
"@chakra-ui/react": ">=2.4.
|
109
|
-
"@
|
110
|
-
"
|
93
|
+
"@chakra-ui/react": ">=2.4.9",
|
94
|
+
"@emotion/react": ">=11.0.0",
|
95
|
+
"@emotion/styled": ">=11.0.0",
|
96
|
+
"framer-motion": ">=6.0.0",
|
97
|
+
"react": ">=18.0.0",
|
98
|
+
"react-dom": ">=18.0.0"
|
111
99
|
},
|
112
100
|
"devDependencies": {
|
113
|
-
"
|
101
|
+
"@hookform/resolvers": "^2.9.3",
|
102
|
+
"@types/json-schema": "^7.0.11",
|
103
|
+
"ajv": "^8.12.0",
|
114
104
|
"yup": "^0.32.11",
|
115
|
-
"zod": "^3.
|
105
|
+
"zod": "^3.20.2"
|
116
106
|
}
|
117
107
|
}
|
package/src/array-field.tsx
CHANGED
@@ -1,9 +1,14 @@
|
|
1
1
|
import * as React from 'react'
|
2
2
|
|
3
|
-
import {
|
3
|
+
import {
|
4
|
+
chakra,
|
5
|
+
ResponsiveValue,
|
6
|
+
forwardRef,
|
7
|
+
Button,
|
8
|
+
ButtonProps,
|
9
|
+
} from '@chakra-ui/react'
|
4
10
|
import { __DEV__ } from '@chakra-ui/utils'
|
5
11
|
import { AddIcon, MinusIcon } from '@chakra-ui/icons'
|
6
|
-
import { IconButton, ButtonProps } from '@saas-ui/button'
|
7
12
|
|
8
13
|
import { FormLayout, FormLayoutProps } from './layout'
|
9
14
|
import { BaseField, FieldProps } from './field'
|
@@ -23,6 +28,8 @@ import {
|
|
23
28
|
UseArrayFieldReturn,
|
24
29
|
} from './use-array-field'
|
25
30
|
|
31
|
+
export interface ArrayFieldButtonProps extends ButtonProps {}
|
32
|
+
|
26
33
|
interface ArrayField {
|
27
34
|
id: string
|
28
35
|
[key: string]: unknown
|
@@ -120,14 +127,13 @@ if (__DEV__) {
|
|
120
127
|
ArrayFieldRowContainer.displayName = 'ArrayFieldRowContainer'
|
121
128
|
}
|
122
129
|
|
123
|
-
export const ArrayFieldRemoveButton: React.FC<
|
130
|
+
export const ArrayFieldRemoveButton: React.FC<ArrayFieldButtonProps> = (
|
131
|
+
props
|
132
|
+
) => {
|
124
133
|
return (
|
125
|
-
<
|
126
|
-
|
127
|
-
|
128
|
-
{...useArrayFieldRemoveButton()}
|
129
|
-
{...props}
|
130
|
-
/>
|
134
|
+
<Button aria-label="Remove row" {...useArrayFieldRemoveButton()} {...props}>
|
135
|
+
{props.children || <MinusIcon />}
|
136
|
+
</Button>
|
131
137
|
)
|
132
138
|
}
|
133
139
|
|
@@ -135,15 +141,16 @@ if (__DEV__) {
|
|
135
141
|
ArrayFieldRemoveButton.displayName = 'ArrayFieldRemoveButton'
|
136
142
|
}
|
137
143
|
|
138
|
-
export const ArrayFieldAddButton: React.FC<
|
144
|
+
export const ArrayFieldAddButton: React.FC<ArrayFieldButtonProps> = (props) => {
|
139
145
|
return (
|
140
|
-
<
|
141
|
-
icon={<AddIcon />}
|
146
|
+
<Button
|
142
147
|
aria-label="Add row"
|
143
148
|
float="right"
|
144
149
|
{...useArrayFieldAddButton()}
|
145
150
|
{...props}
|
146
|
-
|
151
|
+
>
|
152
|
+
{props.children || <AddIcon />}
|
153
|
+
</Button>
|
147
154
|
)
|
148
155
|
}
|
149
156
|
|
package/src/auto-form.tsx
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
import * as React from 'react'
|
2
|
-
import { FieldValues
|
2
|
+
import { FieldValues } from 'react-hook-form'
|
3
3
|
import { forwardRef } from '@chakra-ui/react'
|
4
|
-
import { __DEV__ } from '@chakra-ui/utils'
|
5
4
|
|
6
5
|
import { Form, FormProps } from './form'
|
7
6
|
import { FormLayout } from './layout'
|
8
7
|
import { Fields } from './fields'
|
9
8
|
import { SubmitButton } from './submit-button'
|
10
|
-
import { FieldResolver } from '.'
|
11
9
|
|
12
10
|
interface AutoFormOptions {
|
13
11
|
/**
|
@@ -27,16 +25,21 @@ interface AutoFormOptions {
|
|
27
25
|
fieldResolver?: any
|
28
26
|
}
|
29
27
|
|
30
|
-
export interface AutoFormProps<
|
31
|
-
|
28
|
+
export interface AutoFormProps<
|
29
|
+
TFieldValues extends FieldValues,
|
30
|
+
TContext extends object = object
|
31
|
+
> extends Omit<FormProps<TFieldValues, TContext>, 'schema' | 'children'>,
|
32
32
|
AutoFormOptions {
|
33
33
|
children?: React.ReactNode
|
34
34
|
}
|
35
35
|
|
36
36
|
export const AutoForm = forwardRef(
|
37
|
-
<
|
38
|
-
|
39
|
-
|
37
|
+
<
|
38
|
+
TFieldValues extends FieldValues = FieldValues,
|
39
|
+
TContext extends object = object
|
40
|
+
>(
|
41
|
+
props: AutoFormProps<TFieldValues, TContext>,
|
42
|
+
ref: React.ForwardedRef<HTMLFormElement>
|
40
43
|
) => {
|
41
44
|
const {
|
42
45
|
schema,
|
@@ -56,15 +59,6 @@ export const AutoForm = forwardRef(
|
|
56
59
|
</Form>
|
57
60
|
)
|
58
61
|
}
|
59
|
-
)
|
60
|
-
props: AutoFormProps<TFieldValues> & {
|
61
|
-
ref?: React.ForwardedRef<UseFormReturn<TFieldValues>>
|
62
|
-
}
|
63
|
-
) => React.ReactElement) & {
|
64
|
-
displayName?: string
|
65
|
-
getFieldResolver?: (schema: any) => FieldResolver
|
66
|
-
}
|
62
|
+
)
|
67
63
|
|
68
|
-
|
69
|
-
AutoForm.displayName = 'AutoForm'
|
70
|
-
}
|
64
|
+
AutoForm.displayName = 'AutoForm'
|
package/src/field-resolver.ts
CHANGED
package/src/field.tsx
CHANGED
@@ -35,16 +35,11 @@ import {
|
|
35
35
|
} from '@chakra-ui/react'
|
36
36
|
import { __DEV__, FocusableElement, callAllHandlers } from '@chakra-ui/utils'
|
37
37
|
|
38
|
-
import { NumberInput, NumberInputProps } from '
|
39
|
-
import { PasswordInput, PasswordInputProps } from '
|
40
|
-
import { RadioInput, RadioInputProps } from '
|
38
|
+
import { NumberInput, NumberInputProps } from './number-input'
|
39
|
+
import { PasswordInput, PasswordInputProps } from './password-input'
|
40
|
+
import { RadioInput, RadioInputProps } from './radio'
|
41
41
|
|
42
|
-
import {
|
43
|
-
Select,
|
44
|
-
SelectProps,
|
45
|
-
NativeSelect,
|
46
|
-
NativeSelectProps,
|
47
|
-
} from '@saas-ui/select'
|
42
|
+
import { Select, SelectProps, NativeSelect, NativeSelectProps } from './select'
|
48
43
|
|
49
44
|
export interface Option {
|
50
45
|
value: string
|
package/src/fields.tsx
CHANGED
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,
|
4
|
+
import { cx, runIfFn, __DEV__ } from '@chakra-ui/utils'
|
5
5
|
|
6
6
|
import {
|
7
7
|
useForm,
|
@@ -13,7 +13,6 @@ import {
|
|
13
13
|
SubmitErrorHandler,
|
14
14
|
ResolverOptions,
|
15
15
|
ResolverResult,
|
16
|
-
ChangeHandler,
|
17
16
|
WatchObserver,
|
18
17
|
} from 'react-hook-form'
|
19
18
|
import { objectFieldResolver, FieldResolver } from './field-resolver'
|
@@ -21,14 +20,24 @@ import { MaybeRenderProp } from '@chakra-ui/react-utils'
|
|
21
20
|
|
22
21
|
export type { UseFormReturn, FieldValues, SubmitHandler }
|
23
22
|
|
24
|
-
|
23
|
+
import { Field as DefaultField, FieldProps } from './field'
|
24
|
+
|
25
|
+
interface FormRenderContext<
|
25
26
|
TFieldValues extends FieldValues = FieldValues,
|
26
27
|
TContext extends object = object
|
28
|
+
> extends UseFormReturn<TFieldValues, TContext> {
|
29
|
+
Field: React.FC<FieldProps<TFieldValues>>
|
30
|
+
}
|
31
|
+
|
32
|
+
interface FormOptions<
|
33
|
+
TFieldValues extends FieldValues = FieldValues,
|
34
|
+
TContext extends object = object,
|
35
|
+
TSchema = any
|
27
36
|
> {
|
28
37
|
/**
|
29
|
-
* The form schema,
|
38
|
+
* The form schema, supports Yup, Zod, and AJV.
|
30
39
|
*/
|
31
|
-
schema?:
|
40
|
+
schema?: TSchema
|
32
41
|
/**
|
33
42
|
* Triggers when any of the field change.
|
34
43
|
*/
|
@@ -42,34 +51,34 @@ interface FormOptions<
|
|
42
51
|
*/
|
43
52
|
onError?: SubmitErrorHandler<TFieldValues>
|
44
53
|
/**
|
45
|
-
*
|
54
|
+
* The Hook Form state ref.
|
46
55
|
*/
|
47
|
-
formRef?: React.RefObject<
|
56
|
+
formRef?: React.RefObject<UseFormReturn<TFieldValues, TContext>>
|
48
57
|
/**
|
49
58
|
* The form children, can be a render prop or a ReactNode.
|
50
59
|
*/
|
51
|
-
children?: MaybeRenderProp<
|
60
|
+
children?: MaybeRenderProp<FormRenderContext<TFieldValues, TContext>>
|
52
61
|
}
|
53
62
|
|
54
|
-
// @todo Figure out how to pass down FieldValues to all Field components, if at all possible.
|
55
|
-
|
56
63
|
export interface FormProps<
|
57
64
|
TFieldValues extends FieldValues = FieldValues,
|
58
|
-
TContext extends object = object
|
65
|
+
TContext extends object = object,
|
66
|
+
TSchema = any
|
59
67
|
> extends UseFormProps<TFieldValues, TContext>,
|
60
68
|
Omit<
|
61
69
|
HTMLChakraProps<'form'>,
|
62
70
|
'children' | 'onChange' | 'onSubmit' | 'onError'
|
63
71
|
>,
|
64
|
-
FormOptions<TFieldValues, TContext> {}
|
72
|
+
FormOptions<TFieldValues, TContext, TSchema> {}
|
65
73
|
|
66
74
|
export const Form = forwardRef(
|
67
75
|
<
|
68
76
|
TFieldValues extends FieldValues = FieldValues,
|
69
|
-
TContext extends object = object
|
77
|
+
TContext extends object = object,
|
78
|
+
TSchema = any
|
70
79
|
>(
|
71
|
-
props: FormProps<TFieldValues, TContext>,
|
72
|
-
ref: React.ForwardedRef<
|
80
|
+
props: FormProps<TFieldValues, TContext, TSchema>,
|
81
|
+
ref: React.ForwardedRef<HTMLFormElement>
|
73
82
|
) => {
|
74
83
|
const {
|
75
84
|
mode = 'all',
|
@@ -82,6 +91,9 @@ export const Form = forwardRef(
|
|
82
91
|
delayError,
|
83
92
|
schema,
|
84
93
|
defaultValues,
|
94
|
+
values,
|
95
|
+
context,
|
96
|
+
resetOptions,
|
85
97
|
onChange,
|
86
98
|
onSubmit,
|
87
99
|
onError,
|
@@ -94,12 +106,15 @@ export const Form = forwardRef(
|
|
94
106
|
mode,
|
95
107
|
resolver,
|
96
108
|
defaultValues,
|
109
|
+
values,
|
97
110
|
reValidateMode,
|
98
111
|
shouldFocusError,
|
99
112
|
shouldUnregister,
|
100
113
|
shouldUseNativeValidation,
|
101
114
|
criteriaMode,
|
102
115
|
delayError,
|
116
|
+
context,
|
117
|
+
resetOptions,
|
103
118
|
}
|
104
119
|
|
105
120
|
if (schema && !resolver) {
|
@@ -110,7 +125,7 @@ export const Form = forwardRef(
|
|
110
125
|
const { handleSubmit } = methods
|
111
126
|
|
112
127
|
// This exposes the useForm api through the forwarded ref
|
113
|
-
React.useImperativeHandle(
|
128
|
+
React.useImperativeHandle(formRef, () => methods, [formRef, methods])
|
114
129
|
|
115
130
|
React.useEffect(() => {
|
116
131
|
let subscription: any
|
@@ -120,22 +135,34 @@ export const Form = forwardRef(
|
|
120
135
|
return () => subscription?.unsubscribe()
|
121
136
|
}, [methods, onChange])
|
122
137
|
|
138
|
+
const Field: React.FC<FieldProps<TFieldValues>> = React.useMemo(
|
139
|
+
() => (props) => <DefaultField<TFieldValues> {...props} />,
|
140
|
+
[]
|
141
|
+
)
|
142
|
+
|
123
143
|
return (
|
124
144
|
<FormProvider {...methods}>
|
125
145
|
<chakra.form
|
126
|
-
ref={
|
146
|
+
ref={ref}
|
127
147
|
onSubmit={handleSubmit(onSubmit, onError)}
|
128
148
|
{...rest}
|
129
|
-
className={cx('
|
149
|
+
className={cx('sui-form', props.className)}
|
130
150
|
>
|
131
|
-
{runIfFn(children,
|
151
|
+
{runIfFn(children, {
|
152
|
+
Field,
|
153
|
+
...methods,
|
154
|
+
})}
|
132
155
|
</chakra.form>
|
133
156
|
</FormProvider>
|
134
157
|
)
|
135
158
|
}
|
136
|
-
) as (<
|
137
|
-
|
138
|
-
|
159
|
+
) as (<
|
160
|
+
TFieldValues extends FieldValues,
|
161
|
+
TContext extends object = object,
|
162
|
+
TSchema = any
|
163
|
+
>(
|
164
|
+
props: FormProps<TFieldValues, TContext, TSchema> & {
|
165
|
+
ref?: React.ForwardedRef<HTMLFormElement>
|
139
166
|
}
|
140
167
|
) => React.ReactElement) & {
|
141
168
|
displayName?: string
|
@@ -145,9 +172,7 @@ export const Form = forwardRef(
|
|
145
172
|
|
146
173
|
Form.getFieldResolver = objectFieldResolver
|
147
174
|
|
148
|
-
|
149
|
-
Form.displayName = 'Form'
|
150
|
-
}
|
175
|
+
Form.displayName = 'Form'
|
151
176
|
|
152
177
|
export type GetResolver = <
|
153
178
|
TFieldValues extends FieldValues,
|
@@ -161,3 +186,22 @@ export type GetResolver = <
|
|
161
186
|
) => Promise<ResolverResult<TFieldValues>>
|
162
187
|
|
163
188
|
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
|
+
}
|
package/src/index.ts
CHANGED
@@ -13,6 +13,9 @@ export * from './step-form'
|
|
13
13
|
export * from './use-step-form'
|
14
14
|
export * from './field-resolver'
|
15
15
|
export * from './watch-field'
|
16
|
+
export * from './input-right-button'
|
17
|
+
export * from './select'
|
18
|
+
export * from './password-input'
|
16
19
|
|
17
20
|
export type {
|
18
21
|
BatchFieldArrayUpdate,
|
@@ -0,0 +1 @@
|
|
1
|
+
export * from './input-right-button'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import {
|
2
|
+
Container,
|
3
|
+
Input,
|
4
|
+
InputGroup,
|
5
|
+
Icon,
|
6
|
+
FormControl,
|
7
|
+
FormLabel,
|
8
|
+
} from '@chakra-ui/react'
|
9
|
+
import * as React from 'react'
|
10
|
+
|
11
|
+
import { ComponentStory } from '@storybook/react'
|
12
|
+
|
13
|
+
import { InputRightButton } from '../src'
|
14
|
+
|
15
|
+
import { FiEye } from 'react-icons/fi'
|
16
|
+
|
17
|
+
export default {
|
18
|
+
title: 'Components/Forms/InputRightButton',
|
19
|
+
decorators: [
|
20
|
+
(Story: any) => (
|
21
|
+
<Container mt="40px">
|
22
|
+
<Story />
|
23
|
+
</Container>
|
24
|
+
),
|
25
|
+
],
|
26
|
+
}
|
27
|
+
|
28
|
+
const Template: ComponentStory<typeof InputRightButton> = (args) => (
|
29
|
+
<FormControl>
|
30
|
+
<FormLabel>Input Right Button</FormLabel>
|
31
|
+
<InputGroup>
|
32
|
+
<Input />
|
33
|
+
<InputRightButton {...args} />
|
34
|
+
</InputGroup>
|
35
|
+
</FormControl>
|
36
|
+
)
|
37
|
+
|
38
|
+
export const Basic = Template.bind({})
|
39
|
+
Basic.args = {
|
40
|
+
label: 'Save',
|
41
|
+
}
|
42
|
+
|
43
|
+
export const WithIcon = Template.bind({})
|
44
|
+
WithIcon.args = {
|
45
|
+
children: <Icon as={FiEye} />,
|
46
|
+
'aria-label': 'Show password',
|
47
|
+
}
|