@saas-ui/forms 1.5.2 → 2.0.0-next.0
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 +15 -0
- 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 -19
- 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 +18 -28
- 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 +70 -26
- package/src/index.ts +3 -1
- 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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@saas-ui/forms",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-next.0",
|
|
4
4
|
"description": "Fully functional forms for Chakra UI.",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"exports": {
|
|
@@ -39,23 +39,17 @@
|
|
|
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.0",
|
|
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,23 +106,26 @@ 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) {
|
|
106
|
-
form.resolver = Form.getResolver
|
|
121
|
+
form.resolver = Form.getResolver?.(schema)
|
|
107
122
|
}
|
|
108
123
|
|
|
109
124
|
const methods = useForm<TFieldValues, TContext>(form)
|
|
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,7 +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 '
|
|
16
|
+
export * from './input-right-button'
|
|
17
|
+
export * from './select'
|
|
18
|
+
export * from './password-input'
|
|
17
19
|
|
|
18
20
|
export type {
|
|
19
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
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import * as React from 'react'
|
|
2
|
+
|
|
3
|
+
import { render, testStories } from '@saas-ui/test-utils'
|
|
4
|
+
import * as stories from './input-right-button.stories'
|
|
5
|
+
|
|
6
|
+
const { Basic } = testStories<typeof stories>(stories)
|
|
7
|
+
|
|
8
|
+
test('should render a label', async () => {
|
|
9
|
+
const { getByText } = render(<Basic />)
|
|
10
|
+
|
|
11
|
+
expect(getByText('Save')).toBeVisible()
|
|
12
|
+
})
|