@saas-ui/forms 3.0.0-alpha.0 → 3.0.0-alpha.10
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +92 -0
- package/dist/index.d.mts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/zod/index.d.mts +5 -3
- package/dist/zod/index.d.ts +5 -3
- package/dist/zod/index.js +1 -1
- package/dist/zod/index.js.map +1 -1
- package/dist/zod/index.mjs +1 -1
- package/dist/zod/index.mjs.map +1 -1
- package/package.json +9 -29
- package/dist/ajv/index.d.mts +0 -35
- package/dist/ajv/index.d.ts +0 -35
- package/dist/ajv/index.js +0 -57
- package/dist/ajv/index.js.map +0 -1
- package/dist/ajv/index.mjs +0 -30
- package/dist/ajv/index.mjs.map +0 -1
- package/src/array-field.tsx +0 -266
- package/src/auto-form.tsx +0 -71
- package/src/base-field.tsx +0 -69
- package/src/create-field.tsx +0 -171
- package/src/create-form.tsx +0 -100
- package/src/create-step-form.tsx +0 -118
- package/src/default-fields.tsx +0 -233
- package/src/display-field.tsx +0 -46
- package/src/display-if.tsx +0 -69
- package/src/field-resolver.ts +0 -66
- package/src/field.tsx +0 -44
- package/src/fields-context.tsx +0 -33
- package/src/fields.tsx +0 -93
- package/src/form-context.tsx +0 -80
- package/src/form-layout.tsx +0 -59
- package/src/form.tsx +0 -252
- package/src/index.ts +0 -310
- package/src/object-field.tsx +0 -58
- package/src/step-form.tsx +0 -191
- package/src/submit-button.tsx +0 -71
- package/src/types.ts +0 -242
- package/src/use-array-field.tsx +0 -158
- package/src/use-form.tsx +0 -24
- package/src/use-step-form.tsx +0 -202
- package/src/utils.ts +0 -35
- package/src/watch-field.tsx +0 -37
package/package.json
CHANGED
@@ -1,47 +1,29 @@
|
|
1
1
|
{
|
2
2
|
"name": "@saas-ui/forms",
|
3
|
-
"version": "3.0.0-alpha.
|
3
|
+
"version": "3.0.0-alpha.10",
|
4
4
|
"description": "Fully functional forms for Chakra UI.",
|
5
|
-
"source": "src/index.ts",
|
6
5
|
"exports": {
|
7
6
|
".": {
|
7
|
+
"sui": "./src/index.ts",
|
8
8
|
"require": "./dist/index.js",
|
9
9
|
"types": "./dist/index.d.ts",
|
10
10
|
"import": "./dist/index.mjs"
|
11
11
|
},
|
12
|
-
"./src": {
|
13
|
-
"default": "./src/index.ts"
|
14
|
-
},
|
15
12
|
"./yup": {
|
13
|
+
"sui": "./dist/yup/index.ts",
|
16
14
|
"require": "./dist/yup/index.js",
|
17
15
|
"types": "./dist/yup/index.d.ts",
|
18
16
|
"import": "./dist/yup/index.mjs"
|
19
17
|
},
|
20
|
-
"./yup/src": {
|
21
|
-
"default": "./yup/src/index.ts"
|
22
|
-
},
|
23
18
|
"./zod": {
|
19
|
+
"sui": "./dist/zod/index.ts",
|
24
20
|
"require": "./dist/zod/index.js",
|
25
21
|
"types": "./dist/zod/index.d.ts",
|
26
22
|
"import": "./dist/zod/index.mjs"
|
27
|
-
},
|
28
|
-
"./zod/src": {
|
29
|
-
"default": "./zod/src/index.ts"
|
30
|
-
},
|
31
|
-
"./ajv": {
|
32
|
-
"require": "./dist/ajv/index.js",
|
33
|
-
"types": "./dist/ajv/index.d.ts",
|
34
|
-
"import": "./dist/ajv/index.mjs"
|
35
|
-
},
|
36
|
-
"./ajv/src": {
|
37
|
-
"default": "./ajv/src/index.ts"
|
38
23
|
}
|
39
24
|
},
|
40
25
|
"typesVersions": {
|
41
26
|
"*": {
|
42
|
-
"ajv": [
|
43
|
-
"./dist/ajv/index.d.ts"
|
44
|
-
],
|
45
27
|
"yup": [
|
46
28
|
"./dist/yup/index.d.ts"
|
47
29
|
],
|
@@ -55,19 +37,17 @@
|
|
55
37
|
"types": "./dist/index.d.ts",
|
56
38
|
"scripts": {
|
57
39
|
"clean": "rimraf --no-glob ./dist",
|
58
|
-
"build": "yarn build:package && yarn build:yup && yarn build:zod
|
40
|
+
"build": "yarn build:package && yarn build:yup && yarn build:zod",
|
59
41
|
"build:package": "tsup src/index.ts --config tsup.config.ts",
|
60
42
|
"build:yup": "tsup yup/src/index.ts --config yup/tsup.config.ts",
|
61
43
|
"build:zod": "tsup zod/src/index.ts --config zod/tsup.config.ts",
|
62
|
-
"build:ajv": "tsup ajv/src/index.ts --config ajv/tsup.config.ts",
|
63
44
|
"lint": "eslint src --ext .ts,.tsx,.js,.jsx --config ../../.eslintrc.js",
|
64
45
|
"lint:staged": "lint-staged --allow-empty --config ../../lint-staged.config.js",
|
65
46
|
"typecheck": "tsc --noEmit",
|
66
47
|
"tsd": "tsd"
|
67
48
|
},
|
68
49
|
"files": [
|
69
|
-
"dist"
|
70
|
-
"src"
|
50
|
+
"dist"
|
71
51
|
],
|
72
52
|
"sideEffects": false,
|
73
53
|
"publishConfig": {
|
@@ -102,12 +82,12 @@
|
|
102
82
|
},
|
103
83
|
"dependencies": {
|
104
84
|
"@hookform/resolvers": "^3.9.1",
|
105
|
-
"@saas-ui/core": "3.0.0-alpha.
|
106
|
-
"@saas-ui/react": "3.0.0-alpha.
|
85
|
+
"@saas-ui/core": "3.0.0-alpha.4",
|
86
|
+
"@saas-ui/react": "3.0.0-alpha.10",
|
107
87
|
"react-hook-form": "^7.53.2"
|
108
88
|
},
|
109
89
|
"peerDependencies": {
|
110
|
-
"@chakra-ui/react": "^3.
|
90
|
+
"@chakra-ui/react": "^3.2.3",
|
111
91
|
"@emotion/react": ">=11.0.0",
|
112
92
|
"react": ">=18.0.0",
|
113
93
|
"react-dom": ">=18.0.0"
|
package/dist/ajv/index.d.mts
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
import * as _saas_ui_forms from '@saas-ui/forms';
|
2
|
-
import { CreateFormProps, WithFields, FormProps } from '@saas-ui/forms';
|
3
|
-
import { JTDDataType } from 'ajv/dist/jtd';
|
4
|
-
export { JTDDataType, JTDSchemaType } from 'ajv/dist/jtd';
|
5
|
-
import { ajvResolver } from '@hookform/resolvers/ajv';
|
6
|
-
export { ajvResolver } from '@hookform/resolvers/ajv';
|
7
|
-
import { JSONSchemaType } from 'ajv';
|
8
|
-
|
9
|
-
declare const ajvFieldResolver: (schema: JSONSchemaType<unknown>) => _saas_ui_forms.FieldResolver;
|
10
|
-
|
11
|
-
type ResolverArgs = Parameters<typeof ajvResolver>;
|
12
|
-
interface CreateAjvFormProps<FieldDefs> extends CreateFormProps<FieldDefs> {
|
13
|
-
schemaOptions?: ResolverArgs[1];
|
14
|
-
resolverOptions?: ResolverArgs[2];
|
15
|
-
}
|
16
|
-
type ParseJsonSchema<T> = T extends {
|
17
|
-
type: 'object';
|
18
|
-
} ? JTDDataType<T> extends infer R ? R extends object ? R : never : never : never;
|
19
|
-
type AjvFormType<FieldDefs, ExtraProps = object, JsonSchema extends Record<string, any> = Record<string, any>> = (<TSchema extends JsonSchema = JsonSchema, TFieldValues extends ParseJsonSchema<TSchema> = ParseJsonSchema<TSchema>, TContext extends object = object>(props: WithFields<FormProps<TSchema, TFieldValues, TContext>, FieldDefs> & {
|
20
|
-
ref?: React.ForwardedRef<HTMLFormElement>;
|
21
|
-
} & ExtraProps) => React.ReactElement) & {
|
22
|
-
displayName?: string;
|
23
|
-
id?: string;
|
24
|
-
};
|
25
|
-
/**
|
26
|
-
* Create a Form component with AJV validation that accepts JSON Type Definition schema
|
27
|
-
*
|
28
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/form
|
29
|
-
* @see https://ajv.js.org/json-type-definition.html
|
30
|
-
*/
|
31
|
-
declare function createAjvForm<FieldDefs>(options?: CreateAjvFormProps<FieldDefs>): AjvFormType<FieldDefs>;
|
32
|
-
|
33
|
-
declare const Form: AjvFormType<unknown, object, Record<string, any>>;
|
34
|
-
|
35
|
-
export { type CreateAjvFormProps, Form, ajvFieldResolver, createAjvForm };
|
package/dist/ajv/index.d.ts
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
import * as _saas_ui_forms from '@saas-ui/forms';
|
2
|
-
import { CreateFormProps, WithFields, FormProps } from '@saas-ui/forms';
|
3
|
-
import { JTDDataType } from 'ajv/dist/jtd';
|
4
|
-
export { JTDDataType, JTDSchemaType } from 'ajv/dist/jtd';
|
5
|
-
import { ajvResolver } from '@hookform/resolvers/ajv';
|
6
|
-
export { ajvResolver } from '@hookform/resolvers/ajv';
|
7
|
-
import { JSONSchemaType } from 'ajv';
|
8
|
-
|
9
|
-
declare const ajvFieldResolver: (schema: JSONSchemaType<unknown>) => _saas_ui_forms.FieldResolver;
|
10
|
-
|
11
|
-
type ResolverArgs = Parameters<typeof ajvResolver>;
|
12
|
-
interface CreateAjvFormProps<FieldDefs> extends CreateFormProps<FieldDefs> {
|
13
|
-
schemaOptions?: ResolverArgs[1];
|
14
|
-
resolverOptions?: ResolverArgs[2];
|
15
|
-
}
|
16
|
-
type ParseJsonSchema<T> = T extends {
|
17
|
-
type: 'object';
|
18
|
-
} ? JTDDataType<T> extends infer R ? R extends object ? R : never : never : never;
|
19
|
-
type AjvFormType<FieldDefs, ExtraProps = object, JsonSchema extends Record<string, any> = Record<string, any>> = (<TSchema extends JsonSchema = JsonSchema, TFieldValues extends ParseJsonSchema<TSchema> = ParseJsonSchema<TSchema>, TContext extends object = object>(props: WithFields<FormProps<TSchema, TFieldValues, TContext>, FieldDefs> & {
|
20
|
-
ref?: React.ForwardedRef<HTMLFormElement>;
|
21
|
-
} & ExtraProps) => React.ReactElement) & {
|
22
|
-
displayName?: string;
|
23
|
-
id?: string;
|
24
|
-
};
|
25
|
-
/**
|
26
|
-
* Create a Form component with AJV validation that accepts JSON Type Definition schema
|
27
|
-
*
|
28
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/form
|
29
|
-
* @see https://ajv.js.org/json-type-definition.html
|
30
|
-
*/
|
31
|
-
declare function createAjvForm<FieldDefs>(options?: CreateAjvFormProps<FieldDefs>): AjvFormType<FieldDefs>;
|
32
|
-
|
33
|
-
declare const Form: AjvFormType<unknown, object, Record<string, any>>;
|
34
|
-
|
35
|
-
export { type CreateAjvFormProps, Form, ajvFieldResolver, createAjvForm };
|
package/dist/ajv/index.js
DELETED
@@ -1,57 +0,0 @@
|
|
1
|
-
'use client'
|
2
|
-
"use strict";
|
3
|
-
var __defProp = Object.defineProperty;
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
7
|
-
var __export = (target, all) => {
|
8
|
-
for (var name in all)
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
10
|
-
};
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
13
|
-
for (let key of __getOwnPropNames(from))
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
16
|
-
}
|
17
|
-
return to;
|
18
|
-
};
|
19
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
20
|
-
|
21
|
-
// ajv/src/index.ts
|
22
|
-
var src_exports = {};
|
23
|
-
__export(src_exports, {
|
24
|
-
Form: () => Form,
|
25
|
-
ajvFieldResolver: () => ajvFieldResolver,
|
26
|
-
ajvResolver: () => import_ajv.ajvResolver,
|
27
|
-
createAjvForm: () => createAjvForm
|
28
|
-
});
|
29
|
-
module.exports = __toCommonJS(src_exports);
|
30
|
-
|
31
|
-
// ajv/src/ajv-resolver.ts
|
32
|
-
var import_ajv = require("@hookform/resolvers/ajv");
|
33
|
-
var import_forms = require("@saas-ui/forms");
|
34
|
-
var ajvFieldResolver = (schema) => {
|
35
|
-
return (0, import_forms.objectFieldResolver)(schema.properties);
|
36
|
-
};
|
37
|
-
|
38
|
-
// ajv/src/create-ajv-form.ts
|
39
|
-
var import_forms2 = require("@saas-ui/forms");
|
40
|
-
function createAjvForm(options) {
|
41
|
-
return (0, import_forms2.createForm)({
|
42
|
-
resolver: (schema) => (0, import_ajv.ajvResolver)(schema, options == null ? void 0 : options.schemaOptions, options == null ? void 0 : options.resolverOptions),
|
43
|
-
fieldResolver: ajvFieldResolver,
|
44
|
-
...options
|
45
|
-
});
|
46
|
-
}
|
47
|
-
|
48
|
-
// ajv/src/index.ts
|
49
|
-
var Form = createAjvForm();
|
50
|
-
// Annotate the CommonJS export names for ESM import in node:
|
51
|
-
0 && (module.exports = {
|
52
|
-
Form,
|
53
|
-
ajvFieldResolver,
|
54
|
-
ajvResolver,
|
55
|
-
createAjvForm
|
56
|
-
});
|
57
|
-
//# sourceMappingURL=index.js.map
|
package/dist/ajv/index.js.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../ajv/src/index.ts","../../ajv/src/ajv-resolver.ts","../../ajv/src/create-ajv-form.ts"],"sourcesContent":["export { ajvFieldResolver, ajvResolver } from './ajv-resolver'\nexport { createAjvForm } from './create-ajv-form'\nexport type { CreateAjvFormProps } from './create-ajv-form'\nexport type { JTDDataType, JTDSchemaType } from 'ajv/dist/jtd'\n\nimport { createAjvForm } from './create-ajv-form'\n\nexport const Form = createAjvForm()\n","import { ajvResolver } from '@hookform/resolvers/ajv'\nimport { objectFieldResolver } from '@saas-ui/forms'\nimport { JSONSchemaType } from 'ajv'\n\nexport { ajvResolver }\n\nexport const ajvFieldResolver = (schema: JSONSchemaType<unknown>) => {\n return objectFieldResolver(schema.properties)\n}\n","import {\n CreateFormProps,\n FormProps,\n WithFields,\n createForm,\n} from '@saas-ui/forms'\nimport { JTDDataType } from 'ajv/dist/jtd'\n\nimport { ajvFieldResolver, ajvResolver } from './ajv-resolver'\n\ntype ResolverArgs = Parameters<typeof ajvResolver>\n\nexport interface CreateAjvFormProps<FieldDefs>\n extends CreateFormProps<FieldDefs> {\n schemaOptions?: ResolverArgs[1]\n resolverOptions?: ResolverArgs[2]\n}\n\ntype ParseJsonSchema<T> = T extends { type: 'object' }\n ? JTDDataType<T> extends infer R\n ? R extends object\n ? R\n : never\n : never\n : never\n\nexport type AjvFormType<\n FieldDefs,\n ExtraProps = object,\n JsonSchema extends Record<string, any> = Record<string, any>,\n> = (<\n TSchema extends JsonSchema = JsonSchema,\n TFieldValues extends ParseJsonSchema<TSchema> = ParseJsonSchema<TSchema>,\n TContext extends object = object,\n>(\n props: WithFields<FormProps<TSchema, TFieldValues, TContext>, FieldDefs> & {\n ref?: React.ForwardedRef<HTMLFormElement>\n } & ExtraProps,\n) => React.ReactElement) & {\n displayName?: string\n id?: string\n}\n\n/**\n * Create a Form component with AJV validation that accepts JSON Type Definition schema\n *\n * @see Docs https://saas-ui.dev/docs/components/forms/form\n * @see https://ajv.js.org/json-type-definition.html\n */\nexport function createAjvForm<FieldDefs>(\n options?: CreateAjvFormProps<FieldDefs>,\n) {\n return createForm({\n resolver: (schema: any) =>\n ajvResolver(schema, options?.schemaOptions, options?.resolverOptions),\n fieldResolver: ajvFieldResolver,\n ...options,\n }) as AjvFormType<FieldDefs>\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,iBAA4B;AAC5B,mBAAoC;AAK7B,IAAM,mBAAmB,CAAC,WAAoC;AACnE,aAAO,kCAAoB,OAAO,UAAU;AAC9C;;;ACRA,IAAAA,gBAKO;AA4CA,SAAS,cACd,SACA;AACA,aAAO,0BAAW;AAAA,IAChB,UAAU,CAAC,eACT,wBAAY,QAAQ,mCAAS,eAAe,mCAAS,eAAe;AAAA,IACtE,eAAe;AAAA,IACf,GAAG;AAAA,EACL,CAAC;AACH;;;AFnDO,IAAM,OAAO,cAAc;","names":["import_forms"]}
|
package/dist/ajv/index.mjs
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
'use client'
|
2
|
-
|
3
|
-
// ajv/src/ajv-resolver.ts
|
4
|
-
import { ajvResolver } from "@hookform/resolvers/ajv";
|
5
|
-
import { objectFieldResolver } from "@saas-ui/forms";
|
6
|
-
var ajvFieldResolver = (schema) => {
|
7
|
-
return objectFieldResolver(schema.properties);
|
8
|
-
};
|
9
|
-
|
10
|
-
// ajv/src/create-ajv-form.ts
|
11
|
-
import {
|
12
|
-
createForm
|
13
|
-
} from "@saas-ui/forms";
|
14
|
-
function createAjvForm(options) {
|
15
|
-
return createForm({
|
16
|
-
resolver: (schema) => ajvResolver(schema, options == null ? void 0 : options.schemaOptions, options == null ? void 0 : options.resolverOptions),
|
17
|
-
fieldResolver: ajvFieldResolver,
|
18
|
-
...options
|
19
|
-
});
|
20
|
-
}
|
21
|
-
|
22
|
-
// ajv/src/index.ts
|
23
|
-
var Form = createAjvForm();
|
24
|
-
export {
|
25
|
-
Form,
|
26
|
-
ajvFieldResolver,
|
27
|
-
ajvResolver,
|
28
|
-
createAjvForm
|
29
|
-
};
|
30
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/ajv/index.mjs.map
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
{"version":3,"sources":["../../ajv/src/ajv-resolver.ts","../../ajv/src/create-ajv-form.ts","../../ajv/src/index.ts"],"sourcesContent":["import { ajvResolver } from '@hookform/resolvers/ajv'\nimport { objectFieldResolver } from '@saas-ui/forms'\nimport { JSONSchemaType } from 'ajv'\n\nexport { ajvResolver }\n\nexport const ajvFieldResolver = (schema: JSONSchemaType<unknown>) => {\n return objectFieldResolver(schema.properties)\n}\n","import {\n CreateFormProps,\n FormProps,\n WithFields,\n createForm,\n} from '@saas-ui/forms'\nimport { JTDDataType } from 'ajv/dist/jtd'\n\nimport { ajvFieldResolver, ajvResolver } from './ajv-resolver'\n\ntype ResolverArgs = Parameters<typeof ajvResolver>\n\nexport interface CreateAjvFormProps<FieldDefs>\n extends CreateFormProps<FieldDefs> {\n schemaOptions?: ResolverArgs[1]\n resolverOptions?: ResolverArgs[2]\n}\n\ntype ParseJsonSchema<T> = T extends { type: 'object' }\n ? JTDDataType<T> extends infer R\n ? R extends object\n ? R\n : never\n : never\n : never\n\nexport type AjvFormType<\n FieldDefs,\n ExtraProps = object,\n JsonSchema extends Record<string, any> = Record<string, any>,\n> = (<\n TSchema extends JsonSchema = JsonSchema,\n TFieldValues extends ParseJsonSchema<TSchema> = ParseJsonSchema<TSchema>,\n TContext extends object = object,\n>(\n props: WithFields<FormProps<TSchema, TFieldValues, TContext>, FieldDefs> & {\n ref?: React.ForwardedRef<HTMLFormElement>\n } & ExtraProps,\n) => React.ReactElement) & {\n displayName?: string\n id?: string\n}\n\n/**\n * Create a Form component with AJV validation that accepts JSON Type Definition schema\n *\n * @see Docs https://saas-ui.dev/docs/components/forms/form\n * @see https://ajv.js.org/json-type-definition.html\n */\nexport function createAjvForm<FieldDefs>(\n options?: CreateAjvFormProps<FieldDefs>,\n) {\n return createForm({\n resolver: (schema: any) =>\n ajvResolver(schema, options?.schemaOptions, options?.resolverOptions),\n fieldResolver: ajvFieldResolver,\n ...options,\n }) as AjvFormType<FieldDefs>\n}\n","export { ajvFieldResolver, ajvResolver } from './ajv-resolver'\nexport { createAjvForm } from './create-ajv-form'\nexport type { CreateAjvFormProps } from './create-ajv-form'\nexport type { JTDDataType, JTDSchemaType } from 'ajv/dist/jtd'\n\nimport { createAjvForm } from './create-ajv-form'\n\nexport const Form = createAjvForm()\n"],"mappings":";;;AAAA,SAAS,mBAAmB;AAC5B,SAAS,2BAA2B;AAK7B,IAAM,mBAAmB,CAAC,WAAoC;AACnE,SAAO,oBAAoB,OAAO,UAAU;AAC9C;;;ACRA;AAAA,EAIE;AAAA,OACK;AA4CA,SAAS,cACd,SACA;AACA,SAAO,WAAW;AAAA,IAChB,UAAU,CAAC,WACT,YAAY,QAAQ,mCAAS,eAAe,mCAAS,eAAe;AAAA,IACtE,eAAe;AAAA,IACf,GAAG;AAAA,EACL,CAAC;AACH;;;ACnDO,IAAM,OAAO,cAAc;","names":[]}
|
package/src/array-field.tsx
DELETED
@@ -1,266 +0,0 @@
|
|
1
|
-
import React, { forwardRef } from 'react'
|
2
|
-
|
3
|
-
import { Button, ButtonProps, chakra } from '@chakra-ui/react'
|
4
|
-
import type { MaybeRenderProp } from '@saas-ui/core/utils'
|
5
|
-
import { MinusIcon, PlusIcon } from '@saas-ui/react/icons'
|
6
|
-
import { FieldPath, FieldValues } from 'react-hook-form'
|
7
|
-
|
8
|
-
import { BaseField } from './base-field'
|
9
|
-
import { useFieldProps } from './form-context'
|
10
|
-
import { FormLayout, FormLayoutProps } from './form-layout'
|
11
|
-
import { BaseFieldProps } from './types'
|
12
|
-
import {
|
13
|
-
ArrayFieldOptions,
|
14
|
-
ArrayFieldProvider,
|
15
|
-
ArrayFieldRowProvider,
|
16
|
-
UseArrayFieldReturn,
|
17
|
-
useArrayField,
|
18
|
-
useArrayFieldAddButton,
|
19
|
-
useArrayFieldContext,
|
20
|
-
useArrayFieldRemoveButton,
|
21
|
-
useArrayFieldRow,
|
22
|
-
useArrayFieldRowContext,
|
23
|
-
} from './use-array-field'
|
24
|
-
import { mapNestedFields } from './utils'
|
25
|
-
|
26
|
-
export interface ArrayFieldButtonProps extends ButtonProps {}
|
27
|
-
|
28
|
-
interface ArrayField {
|
29
|
-
id: string
|
30
|
-
[key: string]: unknown
|
31
|
-
}
|
32
|
-
|
33
|
-
interface ArrayFieldRowProps extends FormLayoutProps {
|
34
|
-
/**
|
35
|
-
* The array index
|
36
|
-
*/
|
37
|
-
index: number
|
38
|
-
/**
|
39
|
-
* The fields
|
40
|
-
*/
|
41
|
-
children: React.ReactNode
|
42
|
-
}
|
43
|
-
|
44
|
-
/**
|
45
|
-
* Render prop component, to get access to the internal fields state. Must be a child of ArrayFieldContainer.
|
46
|
-
*
|
47
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/array-field
|
48
|
-
*/
|
49
|
-
export const ArrayFieldRow: React.FC<ArrayFieldRowProps> = ({
|
50
|
-
children,
|
51
|
-
index,
|
52
|
-
...rowFieldsProps
|
53
|
-
}) => {
|
54
|
-
return (
|
55
|
-
<ArrayFieldRowContainer index={index}>
|
56
|
-
<ArrayFieldRowFields {...rowFieldsProps}>{children}</ArrayFieldRowFields>
|
57
|
-
<ArrayFieldRemoveButton />
|
58
|
-
</ArrayFieldRowContainer>
|
59
|
-
)
|
60
|
-
}
|
61
|
-
|
62
|
-
ArrayFieldRow.displayName = 'ArrayFieldRow'
|
63
|
-
|
64
|
-
export interface ArrayFieldRowFieldsProps extends FormLayoutProps {
|
65
|
-
/**
|
66
|
-
* The fields
|
67
|
-
*/
|
68
|
-
children: React.ReactNode
|
69
|
-
}
|
70
|
-
/**
|
71
|
-
* Add the name prefix to the fields and acts as a horizontal form layout by default.
|
72
|
-
*
|
73
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/array-field
|
74
|
-
*/
|
75
|
-
export const ArrayFieldRowFields: React.FC<ArrayFieldRowFieldsProps> = ({
|
76
|
-
children,
|
77
|
-
...layoutProps
|
78
|
-
}) => {
|
79
|
-
const { name } = useArrayFieldRowContext()
|
80
|
-
return (
|
81
|
-
<FormLayout flex="1" mr="2" {...layoutProps}>
|
82
|
-
{mapNestedFields(name, children)}
|
83
|
-
</FormLayout>
|
84
|
-
)
|
85
|
-
}
|
86
|
-
|
87
|
-
ArrayFieldRowFields.displayName = 'ArrayFieldRowFields'
|
88
|
-
|
89
|
-
/**
|
90
|
-
* The row container component providers row context.
|
91
|
-
*
|
92
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/array-field
|
93
|
-
*/
|
94
|
-
export const ArrayFieldRowContainer: React.FC<ArrayFieldRowProps> = ({
|
95
|
-
children,
|
96
|
-
index,
|
97
|
-
...rest
|
98
|
-
}) => {
|
99
|
-
const context = useArrayFieldRow({ index })
|
100
|
-
|
101
|
-
const styles = {
|
102
|
-
display: 'flex',
|
103
|
-
flexDirection: 'row',
|
104
|
-
alignItems: 'flex-end',
|
105
|
-
width: '100%',
|
106
|
-
mb: 4,
|
107
|
-
}
|
108
|
-
|
109
|
-
return (
|
110
|
-
<ArrayFieldRowProvider value={context}>
|
111
|
-
<chakra.div {...rest} css={styles}>
|
112
|
-
{children}
|
113
|
-
</chakra.div>
|
114
|
-
</ArrayFieldRowProvider>
|
115
|
-
)
|
116
|
-
}
|
117
|
-
|
118
|
-
ArrayFieldRowContainer.displayName = 'ArrayFieldRowContainer'
|
119
|
-
|
120
|
-
/**
|
121
|
-
* The default remove button.
|
122
|
-
*
|
123
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/array-field
|
124
|
-
*/
|
125
|
-
export const ArrayFieldRemoveButton: React.FC<ArrayFieldButtonProps> = (
|
126
|
-
props,
|
127
|
-
) => {
|
128
|
-
return (
|
129
|
-
<Button aria-label="Remove row" {...useArrayFieldRemoveButton()} {...props}>
|
130
|
-
{props.children || <MinusIcon />}
|
131
|
-
</Button>
|
132
|
-
)
|
133
|
-
}
|
134
|
-
|
135
|
-
ArrayFieldRemoveButton.displayName = 'ArrayFieldRemoveButton'
|
136
|
-
|
137
|
-
/**
|
138
|
-
* The default add button.
|
139
|
-
*
|
140
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/array-field
|
141
|
-
*/
|
142
|
-
export const ArrayFieldAddButton: React.FC<ArrayFieldButtonProps> = (props) => {
|
143
|
-
return (
|
144
|
-
<Button
|
145
|
-
aria-label="Add row"
|
146
|
-
float="right"
|
147
|
-
{...useArrayFieldAddButton()}
|
148
|
-
{...props}
|
149
|
-
>
|
150
|
-
{props.children || <PlusIcon />}
|
151
|
-
</Button>
|
152
|
-
)
|
153
|
-
}
|
154
|
-
|
155
|
-
ArrayFieldAddButton.displayName = 'ArrayFieldAddButton'
|
156
|
-
|
157
|
-
export interface ArrayFieldProps<
|
158
|
-
TFieldValues extends FieldValues = FieldValues,
|
159
|
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
160
|
-
> extends ArrayFieldOptions<TFieldValues, TName>,
|
161
|
-
Omit<
|
162
|
-
BaseFieldProps<TFieldValues, TName>,
|
163
|
-
'name' | 'defaultValue' | 'children'
|
164
|
-
> {
|
165
|
-
children: MaybeRenderProp<ArrayField[]>
|
166
|
-
}
|
167
|
-
|
168
|
-
/**
|
169
|
-
* The wrapper component that composes the default ArrayField functionality.
|
170
|
-
*
|
171
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/array-field
|
172
|
-
*/
|
173
|
-
export const ArrayField = forwardRef(
|
174
|
-
(props: ArrayFieldProps, ref: React.ForwardedRef<UseArrayFieldReturn>) => {
|
175
|
-
const { children, ...containerProps } = props
|
176
|
-
|
177
|
-
const rowFn =
|
178
|
-
typeof children === 'function'
|
179
|
-
? children
|
180
|
-
: (fields: ArrayField[]) => (
|
181
|
-
<>
|
182
|
-
{fields.map(({ id }, index: number) => (
|
183
|
-
<ArrayFieldRow key={id} index={index}>
|
184
|
-
{children}
|
185
|
-
</ArrayFieldRow>
|
186
|
-
)) || null}
|
187
|
-
</>
|
188
|
-
)
|
189
|
-
|
190
|
-
return (
|
191
|
-
<ArrayFieldContainer ref={ref} {...containerProps}>
|
192
|
-
<ArrayFieldRows>{rowFn as any}</ArrayFieldRows>
|
193
|
-
<ArrayFieldAddButton />
|
194
|
-
</ArrayFieldContainer>
|
195
|
-
)
|
196
|
-
},
|
197
|
-
) as ((
|
198
|
-
props: ArrayFieldProps & {
|
199
|
-
ref?: React.ForwardedRef<UseArrayFieldReturn>
|
200
|
-
},
|
201
|
-
) => React.ReactElement) & {
|
202
|
-
displayName: string
|
203
|
-
}
|
204
|
-
|
205
|
-
ArrayField.displayName = 'ArrayField'
|
206
|
-
|
207
|
-
export interface ArrayFieldRowsProps {
|
208
|
-
children: (fields: ArrayField[]) => React.ReactElement | null
|
209
|
-
}
|
210
|
-
|
211
|
-
export const ArrayFieldRows = ({
|
212
|
-
children,
|
213
|
-
}: ArrayFieldRowsProps): React.ReactElement | null => {
|
214
|
-
const { fields } = useArrayFieldContext()
|
215
|
-
return children(fields)
|
216
|
-
}
|
217
|
-
|
218
|
-
ArrayFieldRows.displayName = 'ArrayFieldRows'
|
219
|
-
|
220
|
-
export interface ArrayFieldContainerProps
|
221
|
-
extends Omit<ArrayFieldProps, 'children'> {
|
222
|
-
children: React.ReactNode
|
223
|
-
}
|
224
|
-
|
225
|
-
/**
|
226
|
-
* The container component provides context and state management.
|
227
|
-
*
|
228
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/array-field
|
229
|
-
*/
|
230
|
-
export const ArrayFieldContainer = React.forwardRef(
|
231
|
-
(
|
232
|
-
{
|
233
|
-
name,
|
234
|
-
defaultValue,
|
235
|
-
keyName,
|
236
|
-
min,
|
237
|
-
max,
|
238
|
-
children,
|
239
|
-
...fieldProps
|
240
|
-
}: ArrayFieldContainerProps,
|
241
|
-
ref: React.ForwardedRef<UseArrayFieldReturn>,
|
242
|
-
) => {
|
243
|
-
const overrides = useFieldProps(name)
|
244
|
-
|
245
|
-
const context = useArrayField({
|
246
|
-
name,
|
247
|
-
defaultValue,
|
248
|
-
keyName,
|
249
|
-
min: min || (overrides as any)?.min,
|
250
|
-
max: max || (overrides as any)?.max,
|
251
|
-
})
|
252
|
-
|
253
|
-
// This exposes the useArrayField api through the forwarded ref
|
254
|
-
React.useImperativeHandle(ref, () => context, [ref, context])
|
255
|
-
|
256
|
-
return (
|
257
|
-
<ArrayFieldProvider value={context}>
|
258
|
-
<BaseField name={name} {...fieldProps} {...overrides}>
|
259
|
-
{children}
|
260
|
-
</BaseField>
|
261
|
-
</ArrayFieldProvider>
|
262
|
-
)
|
263
|
-
},
|
264
|
-
)
|
265
|
-
|
266
|
-
ArrayFieldContainer.displayName = 'ArrayFieldContainer'
|
package/src/auto-form.tsx
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
import React, { forwardRef } from 'react'
|
2
|
-
|
3
|
-
import { FieldValues } from 'react-hook-form'
|
4
|
-
|
5
|
-
import { AutoFields } from './fields'
|
6
|
-
import { Form, FormProps } from './form'
|
7
|
-
import { FormLayout } from './form-layout'
|
8
|
-
import { SubmitButton } from './submit-button'
|
9
|
-
|
10
|
-
interface AutoFormOptions {
|
11
|
-
/**
|
12
|
-
* The submit button label.
|
13
|
-
* Pass `null` to render no submit button.
|
14
|
-
*/
|
15
|
-
submitLabel?: React.ReactNode
|
16
|
-
/**
|
17
|
-
* The schema.
|
18
|
-
* Supports object schema, Zod, Yup or Ajv (JSON Schema).
|
19
|
-
* @see https://www.saas-ui.dev/docs/forms/auto-form
|
20
|
-
*/
|
21
|
-
schema: any
|
22
|
-
/**
|
23
|
-
* The field resolver.
|
24
|
-
*/
|
25
|
-
fieldResolver?: any
|
26
|
-
}
|
27
|
-
|
28
|
-
export interface AutoFormProps<
|
29
|
-
TFieldValues extends FieldValues,
|
30
|
-
TContext extends object = object,
|
31
|
-
> extends Omit<
|
32
|
-
FormProps<TFieldValues, TContext>,
|
33
|
-
'schema' | 'children' | 'fieldResolver'
|
34
|
-
>,
|
35
|
-
AutoFormOptions {
|
36
|
-
children?: React.ReactNode
|
37
|
-
}
|
38
|
-
/**
|
39
|
-
* The wrapper component that manages context and state.
|
40
|
-
*
|
41
|
-
* @see Docs https://saas-ui.dev/docs/components/forms/auto-form
|
42
|
-
*/
|
43
|
-
export const AutoForm = forwardRef(
|
44
|
-
<
|
45
|
-
TFieldValues extends FieldValues = FieldValues,
|
46
|
-
TContext extends object = object,
|
47
|
-
>(
|
48
|
-
props: AutoFormProps<TFieldValues, TContext>,
|
49
|
-
ref: React.ForwardedRef<HTMLFormElement>,
|
50
|
-
) => {
|
51
|
-
const {
|
52
|
-
schema,
|
53
|
-
submitLabel = 'Submit',
|
54
|
-
fieldResolver,
|
55
|
-
children,
|
56
|
-
...rest
|
57
|
-
} = props
|
58
|
-
|
59
|
-
return (
|
60
|
-
<Form {...rest} schema={schema} ref={ref}>
|
61
|
-
<FormLayout>
|
62
|
-
{<AutoFields schema={schema} fieldResolver={fieldResolver} />}
|
63
|
-
{submitLabel && <SubmitButton>{submitLabel}</SubmitButton>}
|
64
|
-
{children}
|
65
|
-
</FormLayout>
|
66
|
-
</Form>
|
67
|
-
)
|
68
|
-
},
|
69
|
-
)
|
70
|
-
|
71
|
-
AutoForm.displayName = 'AutoForm'
|
package/src/base-field.tsx
DELETED
@@ -1,69 +0,0 @@
|
|
1
|
-
import * as React from 'react'
|
2
|
-
|
3
|
-
import { Box, Field } from '@chakra-ui/react'
|
4
|
-
import { splitProps } from '@saas-ui/core/utils'
|
5
|
-
import { FormState, get } from 'react-hook-form'
|
6
|
-
|
7
|
-
import { useFormContext } from './form-context'
|
8
|
-
import type { BaseFieldProps } from './types'
|
9
|
-
|
10
|
-
const getError = (name: string, formState: FormState<{ [x: string]: any }>) => {
|
11
|
-
return get(formState.errors, name)
|
12
|
-
}
|
13
|
-
|
14
|
-
const isTouched = (
|
15
|
-
name: string,
|
16
|
-
formState: FormState<{ [x: string]: any }>,
|
17
|
-
) => {
|
18
|
-
return get(formState.touchedFields, name)
|
19
|
-
}
|
20
|
-
|
21
|
-
export const useBaseField = (props: BaseFieldProps) => {
|
22
|
-
const [fieldProps] = splitProps(props, ['name', 'label', 'help', 'hideLabel'])
|
23
|
-
|
24
|
-
const [controlProps] = splitProps(props, [
|
25
|
-
// 'id',
|
26
|
-
// 'orientation',
|
27
|
-
// 'disabled',
|
28
|
-
// 'invalid',
|
29
|
-
// 'readOnly',
|
30
|
-
// 'required',
|
31
|
-
])
|
32
|
-
|
33
|
-
const { formState } = useFormContext()
|
34
|
-
|
35
|
-
const error = getError(fieldProps.name, formState)
|
36
|
-
const touched = isTouched(fieldProps.name, formState)
|
37
|
-
|
38
|
-
return {
|
39
|
-
...fieldProps,
|
40
|
-
controlProps,
|
41
|
-
error,
|
42
|
-
touched,
|
43
|
-
}
|
44
|
-
}
|
45
|
-
|
46
|
-
/**
|
47
|
-
* The default BaseField component
|
48
|
-
* Composes the Chakra UI FormControl component, with FormLabel, FormHelperText and FormErrorMessage.
|
49
|
-
*/
|
50
|
-
export const BaseField: React.FC<BaseFieldProps> = (props) => {
|
51
|
-
const { label, help, hideLabel, error } = useBaseField(props)
|
52
|
-
|
53
|
-
const isInvalid = !!error //|| controlProps.
|
54
|
-
|
55
|
-
return (
|
56
|
-
<Field.Root invalid={isInvalid} {...props}>
|
57
|
-
{label && !hideLabel ? <Field.Label>{label}</Field.Label> : null}
|
58
|
-
<Box width="full">
|
59
|
-
{props.children}
|
60
|
-
{help && !error?.message ? (
|
61
|
-
<Field.HelperText>{help}</Field.HelperText>
|
62
|
-
) : null}
|
63
|
-
{error?.message && <Field.ErrorText>{error?.message}</Field.ErrorText>}
|
64
|
-
</Box>
|
65
|
-
</Field.Root>
|
66
|
-
)
|
67
|
-
}
|
68
|
-
|
69
|
-
BaseField.displayName = 'BaseField'
|