@form-engine-ts/react 1.0.0 → 2.0.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/README.md +42 -0
- package/dist/index.cjs +1262 -110
- package/dist/index.d.cts +114 -6
- package/dist/index.d.ts +114 -6
- package/dist/index.js +1270 -104
- package/dist/styles.css +77 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -1,14 +1,106 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, ComponentType } from 'react';
|
|
3
|
-
import { FormSchema, TranslationAdapter,
|
|
3
|
+
import { FieldType, FormSchema, FormField, SchemaIssue, TranslationAdapter, AsyncTranslationAdapter, ValidationError, FormValue, ValidationIssue, FormValues, AnswerValidationResult } from '@form-engine-ts/core';
|
|
4
|
+
|
|
5
|
+
interface BuilderPolicy {
|
|
6
|
+
readonly allowedFieldTypes?: readonly FieldType[];
|
|
7
|
+
readonly maxFields?: number;
|
|
8
|
+
readonly maxOptionsPerField?: number;
|
|
9
|
+
readonly maxTextLength?: number;
|
|
10
|
+
readonly requiredLocales?: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
interface FormBuilderOptions {
|
|
13
|
+
readonly schema: FormSchema;
|
|
14
|
+
readonly onChange: (schema: FormSchema) => void;
|
|
15
|
+
readonly policy?: BuilderPolicy;
|
|
16
|
+
readonly idFactory?: (kind: "field" | "option" | "page", existingIds: ReadonlySet<string>) => string;
|
|
17
|
+
}
|
|
18
|
+
type BuilderActionError = {
|
|
19
|
+
readonly type: "max_fields_exceeded";
|
|
20
|
+
readonly max: number;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: "max_options_exceeded";
|
|
23
|
+
readonly max: number;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: "disallowed_field_type";
|
|
26
|
+
readonly fieldType: FieldType;
|
|
27
|
+
} | {
|
|
28
|
+
readonly type: "invalid_operation";
|
|
29
|
+
readonly message: string;
|
|
30
|
+
};
|
|
31
|
+
interface BuilderActionResult {
|
|
32
|
+
readonly success: boolean;
|
|
33
|
+
readonly error?: BuilderActionError;
|
|
34
|
+
}
|
|
35
|
+
interface FormBuilderResult {
|
|
36
|
+
readonly schema: FormSchema;
|
|
37
|
+
readonly addField: (type: FieldType, pageId?: string) => BuilderActionResult;
|
|
38
|
+
readonly removeField: (fieldId: string) => void;
|
|
39
|
+
readonly moveField: (fieldId: string, targetIndex: number) => void;
|
|
40
|
+
readonly updateField: (fieldId: string, updater: (field: FormField) => FormField) => void;
|
|
41
|
+
readonly addOption: (fieldId: string) => BuilderActionResult;
|
|
42
|
+
readonly removeOption: (fieldId: string, optionId: string) => void;
|
|
43
|
+
readonly moveOption: (fieldId: string, optionId: string, targetIndex: number) => void;
|
|
44
|
+
readonly addPage: (questionId?: string) => void;
|
|
45
|
+
readonly removePage: (pageId: string) => void;
|
|
46
|
+
readonly setLocaleTranslation: (locale: string, target: "form" | string, property: string, text: string) => void;
|
|
47
|
+
readonly validationIssues: readonly SchemaIssue[];
|
|
48
|
+
}
|
|
49
|
+
declare function useFormBuilder({ schema, onChange, policy, idFactory }: FormBuilderOptions): FormBuilderResult;
|
|
4
50
|
|
|
5
51
|
interface FormBuilderProps {
|
|
6
52
|
readonly schema: FormSchema;
|
|
7
53
|
readonly onChange: (newSchema: FormSchema) => void;
|
|
8
54
|
readonly locale?: string;
|
|
9
55
|
readonly translator?: TranslationAdapter;
|
|
56
|
+
readonly translationAdapter?: AsyncTranslationAdapter;
|
|
57
|
+
readonly policy?: BuilderPolicy;
|
|
58
|
+
readonly idFactory?: (kind: "field" | "option" | "page", existingIds: ReadonlySet<string>) => string;
|
|
10
59
|
}
|
|
11
|
-
declare function FormBuilder({ schema, onChange, locale, translator }: FormBuilderProps): react.JSX.Element;
|
|
60
|
+
declare function FormBuilder({ schema, onChange, locale, translator, translationAdapter, policy, idFactory }: FormBuilderProps): react.JSX.Element;
|
|
61
|
+
|
|
62
|
+
type SubmitResult = {
|
|
63
|
+
readonly status: "invalid";
|
|
64
|
+
readonly issues: readonly ValidationError[];
|
|
65
|
+
} | {
|
|
66
|
+
readonly status: "cancelled";
|
|
67
|
+
} | {
|
|
68
|
+
readonly status: "success";
|
|
69
|
+
} | {
|
|
70
|
+
readonly status: "error";
|
|
71
|
+
readonly error: Error;
|
|
72
|
+
};
|
|
73
|
+
interface FormRendererSlots {
|
|
74
|
+
readonly renderHeader?: (props: {
|
|
75
|
+
readonly title: string;
|
|
76
|
+
readonly description?: string;
|
|
77
|
+
}) => ReactNode;
|
|
78
|
+
readonly renderField?: (props: {
|
|
79
|
+
readonly question: FormField;
|
|
80
|
+
readonly value: unknown;
|
|
81
|
+
readonly onChange: (value: unknown) => void;
|
|
82
|
+
readonly error?: ValidationError;
|
|
83
|
+
}) => ReactNode;
|
|
84
|
+
readonly renderNavigation?: (props: {
|
|
85
|
+
readonly currentPage: number;
|
|
86
|
+
readonly totalPages: number;
|
|
87
|
+
readonly canPrev: boolean;
|
|
88
|
+
readonly canNext: boolean;
|
|
89
|
+
readonly onPrev: () => void;
|
|
90
|
+
readonly onNext: () => void;
|
|
91
|
+
}) => ReactNode;
|
|
92
|
+
readonly renderSubmitButton?: (props: {
|
|
93
|
+
readonly isSubmitting: boolean;
|
|
94
|
+
readonly onSubmit: () => void;
|
|
95
|
+
}) => ReactNode;
|
|
96
|
+
readonly renderValidationSummary?: (props: {
|
|
97
|
+
readonly issues: readonly ValidationError[];
|
|
98
|
+
}) => ReactNode;
|
|
99
|
+
readonly renderCompletion?: (props: {
|
|
100
|
+
readonly message: string;
|
|
101
|
+
}) => ReactNode;
|
|
102
|
+
}
|
|
103
|
+
type BeforeSubmit = (values: Readonly<Record<string, unknown>>) => "continue" | "cancel" | Promise<"continue" | "cancel">;
|
|
12
104
|
|
|
13
105
|
type SubmitStatus = "idle" | "submitting" | "success" | "error";
|
|
14
106
|
interface FormContextValue {
|
|
@@ -17,13 +109,16 @@ interface FormContextValue {
|
|
|
17
109
|
readonly translator: TranslationAdapter;
|
|
18
110
|
readonly values: FormValues;
|
|
19
111
|
readonly visibility: Readonly<Record<string, boolean>>;
|
|
112
|
+
readonly pageVisibility: Readonly<Record<string, boolean>>;
|
|
20
113
|
readonly errors: Readonly<Record<string, ValidationIssue | undefined>>;
|
|
21
114
|
readonly submitStatus: SubmitStatus;
|
|
22
115
|
readonly submitError: Error | null;
|
|
23
116
|
readonly isSubmitting: boolean;
|
|
24
117
|
readonly setValue: (fieldId: string, value: FormValue) => void;
|
|
118
|
+
readonly restoreValues: (values: FormValues) => void;
|
|
119
|
+
readonly validatePage: (pageIndex: number) => AnswerValidationResult;
|
|
25
120
|
readonly reset: () => void;
|
|
26
|
-
readonly submit: () => Promise<
|
|
121
|
+
readonly submit: (beforeSubmit?: BeforeSubmit) => Promise<SubmitResult>;
|
|
27
122
|
readonly translate: (key: string, params?: Readonly<Record<string, string | number>>) => string;
|
|
28
123
|
}
|
|
29
124
|
interface FormProviderProps {
|
|
@@ -56,12 +151,25 @@ interface FieldComponentProps {
|
|
|
56
151
|
readonly helpId: string;
|
|
57
152
|
}
|
|
58
153
|
type FieldComponents = Partial<Record<FieldType, ComponentType<FieldComponentProps>>>;
|
|
59
|
-
interface
|
|
154
|
+
interface FormRendererPresentationProps {
|
|
60
155
|
readonly components?: FieldComponents;
|
|
61
156
|
readonly className?: string;
|
|
62
157
|
readonly successMessageKey?: string;
|
|
63
158
|
readonly errorMessageKey?: string;
|
|
159
|
+
readonly autoSaveKey?: string;
|
|
160
|
+
readonly beforeSubmit?: BeforeSubmit;
|
|
161
|
+
readonly onDraftSave?: (draft: FormValues) => void;
|
|
162
|
+
readonly slots?: FormRendererSlots;
|
|
163
|
+
}
|
|
164
|
+
interface StandaloneFormRendererProps extends FormRendererPresentationProps {
|
|
165
|
+
readonly schema: FormSchema;
|
|
166
|
+
readonly locale?: string;
|
|
167
|
+
readonly translator?: TranslationAdapter;
|
|
168
|
+
readonly initialValues?: FormValues;
|
|
169
|
+
readonly resetOnSuccess?: boolean;
|
|
170
|
+
readonly onSubmit: (answers: FormValues) => Promise<void> | void;
|
|
64
171
|
}
|
|
65
|
-
|
|
172
|
+
type FormRendererProps = FormRendererPresentationProps | StandaloneFormRendererProps;
|
|
173
|
+
declare function FormRenderer(props: FormRendererProps): react.JSX.Element;
|
|
66
174
|
|
|
67
|
-
export { type FieldComponentProps, type FieldComponents, type FieldState, FormBuilder, type FormBuilderProps, type FormContextValue, FormProvider, type FormProviderProps, FormRenderer, type FormRendererProps, type SubmitStatus, useField, useForm };
|
|
175
|
+
export { type BeforeSubmit, type BuilderActionError, type BuilderActionResult, type BuilderPolicy, type FieldComponentProps, type FieldComponents, type FieldState, FormBuilder, type FormBuilderOptions, type FormBuilderProps, type FormBuilderResult, type FormContextValue, FormProvider, type FormProviderProps, FormRenderer, type FormRendererPresentationProps, type FormRendererProps, type FormRendererSlots, type StandaloneFormRendererProps, type SubmitResult, type SubmitStatus, useField, useForm, useFormBuilder };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,106 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { ReactNode, ComponentType } from 'react';
|
|
3
|
-
import { FormSchema, TranslationAdapter,
|
|
3
|
+
import { FieldType, FormSchema, FormField, SchemaIssue, TranslationAdapter, AsyncTranslationAdapter, ValidationError, FormValue, ValidationIssue, FormValues, AnswerValidationResult } from '@form-engine-ts/core';
|
|
4
|
+
|
|
5
|
+
interface BuilderPolicy {
|
|
6
|
+
readonly allowedFieldTypes?: readonly FieldType[];
|
|
7
|
+
readonly maxFields?: number;
|
|
8
|
+
readonly maxOptionsPerField?: number;
|
|
9
|
+
readonly maxTextLength?: number;
|
|
10
|
+
readonly requiredLocales?: readonly string[];
|
|
11
|
+
}
|
|
12
|
+
interface FormBuilderOptions {
|
|
13
|
+
readonly schema: FormSchema;
|
|
14
|
+
readonly onChange: (schema: FormSchema) => void;
|
|
15
|
+
readonly policy?: BuilderPolicy;
|
|
16
|
+
readonly idFactory?: (kind: "field" | "option" | "page", existingIds: ReadonlySet<string>) => string;
|
|
17
|
+
}
|
|
18
|
+
type BuilderActionError = {
|
|
19
|
+
readonly type: "max_fields_exceeded";
|
|
20
|
+
readonly max: number;
|
|
21
|
+
} | {
|
|
22
|
+
readonly type: "max_options_exceeded";
|
|
23
|
+
readonly max: number;
|
|
24
|
+
} | {
|
|
25
|
+
readonly type: "disallowed_field_type";
|
|
26
|
+
readonly fieldType: FieldType;
|
|
27
|
+
} | {
|
|
28
|
+
readonly type: "invalid_operation";
|
|
29
|
+
readonly message: string;
|
|
30
|
+
};
|
|
31
|
+
interface BuilderActionResult {
|
|
32
|
+
readonly success: boolean;
|
|
33
|
+
readonly error?: BuilderActionError;
|
|
34
|
+
}
|
|
35
|
+
interface FormBuilderResult {
|
|
36
|
+
readonly schema: FormSchema;
|
|
37
|
+
readonly addField: (type: FieldType, pageId?: string) => BuilderActionResult;
|
|
38
|
+
readonly removeField: (fieldId: string) => void;
|
|
39
|
+
readonly moveField: (fieldId: string, targetIndex: number) => void;
|
|
40
|
+
readonly updateField: (fieldId: string, updater: (field: FormField) => FormField) => void;
|
|
41
|
+
readonly addOption: (fieldId: string) => BuilderActionResult;
|
|
42
|
+
readonly removeOption: (fieldId: string, optionId: string) => void;
|
|
43
|
+
readonly moveOption: (fieldId: string, optionId: string, targetIndex: number) => void;
|
|
44
|
+
readonly addPage: (questionId?: string) => void;
|
|
45
|
+
readonly removePage: (pageId: string) => void;
|
|
46
|
+
readonly setLocaleTranslation: (locale: string, target: "form" | string, property: string, text: string) => void;
|
|
47
|
+
readonly validationIssues: readonly SchemaIssue[];
|
|
48
|
+
}
|
|
49
|
+
declare function useFormBuilder({ schema, onChange, policy, idFactory }: FormBuilderOptions): FormBuilderResult;
|
|
4
50
|
|
|
5
51
|
interface FormBuilderProps {
|
|
6
52
|
readonly schema: FormSchema;
|
|
7
53
|
readonly onChange: (newSchema: FormSchema) => void;
|
|
8
54
|
readonly locale?: string;
|
|
9
55
|
readonly translator?: TranslationAdapter;
|
|
56
|
+
readonly translationAdapter?: AsyncTranslationAdapter;
|
|
57
|
+
readonly policy?: BuilderPolicy;
|
|
58
|
+
readonly idFactory?: (kind: "field" | "option" | "page", existingIds: ReadonlySet<string>) => string;
|
|
10
59
|
}
|
|
11
|
-
declare function FormBuilder({ schema, onChange, locale, translator }: FormBuilderProps): react.JSX.Element;
|
|
60
|
+
declare function FormBuilder({ schema, onChange, locale, translator, translationAdapter, policy, idFactory }: FormBuilderProps): react.JSX.Element;
|
|
61
|
+
|
|
62
|
+
type SubmitResult = {
|
|
63
|
+
readonly status: "invalid";
|
|
64
|
+
readonly issues: readonly ValidationError[];
|
|
65
|
+
} | {
|
|
66
|
+
readonly status: "cancelled";
|
|
67
|
+
} | {
|
|
68
|
+
readonly status: "success";
|
|
69
|
+
} | {
|
|
70
|
+
readonly status: "error";
|
|
71
|
+
readonly error: Error;
|
|
72
|
+
};
|
|
73
|
+
interface FormRendererSlots {
|
|
74
|
+
readonly renderHeader?: (props: {
|
|
75
|
+
readonly title: string;
|
|
76
|
+
readonly description?: string;
|
|
77
|
+
}) => ReactNode;
|
|
78
|
+
readonly renderField?: (props: {
|
|
79
|
+
readonly question: FormField;
|
|
80
|
+
readonly value: unknown;
|
|
81
|
+
readonly onChange: (value: unknown) => void;
|
|
82
|
+
readonly error?: ValidationError;
|
|
83
|
+
}) => ReactNode;
|
|
84
|
+
readonly renderNavigation?: (props: {
|
|
85
|
+
readonly currentPage: number;
|
|
86
|
+
readonly totalPages: number;
|
|
87
|
+
readonly canPrev: boolean;
|
|
88
|
+
readonly canNext: boolean;
|
|
89
|
+
readonly onPrev: () => void;
|
|
90
|
+
readonly onNext: () => void;
|
|
91
|
+
}) => ReactNode;
|
|
92
|
+
readonly renderSubmitButton?: (props: {
|
|
93
|
+
readonly isSubmitting: boolean;
|
|
94
|
+
readonly onSubmit: () => void;
|
|
95
|
+
}) => ReactNode;
|
|
96
|
+
readonly renderValidationSummary?: (props: {
|
|
97
|
+
readonly issues: readonly ValidationError[];
|
|
98
|
+
}) => ReactNode;
|
|
99
|
+
readonly renderCompletion?: (props: {
|
|
100
|
+
readonly message: string;
|
|
101
|
+
}) => ReactNode;
|
|
102
|
+
}
|
|
103
|
+
type BeforeSubmit = (values: Readonly<Record<string, unknown>>) => "continue" | "cancel" | Promise<"continue" | "cancel">;
|
|
12
104
|
|
|
13
105
|
type SubmitStatus = "idle" | "submitting" | "success" | "error";
|
|
14
106
|
interface FormContextValue {
|
|
@@ -17,13 +109,16 @@ interface FormContextValue {
|
|
|
17
109
|
readonly translator: TranslationAdapter;
|
|
18
110
|
readonly values: FormValues;
|
|
19
111
|
readonly visibility: Readonly<Record<string, boolean>>;
|
|
112
|
+
readonly pageVisibility: Readonly<Record<string, boolean>>;
|
|
20
113
|
readonly errors: Readonly<Record<string, ValidationIssue | undefined>>;
|
|
21
114
|
readonly submitStatus: SubmitStatus;
|
|
22
115
|
readonly submitError: Error | null;
|
|
23
116
|
readonly isSubmitting: boolean;
|
|
24
117
|
readonly setValue: (fieldId: string, value: FormValue) => void;
|
|
118
|
+
readonly restoreValues: (values: FormValues) => void;
|
|
119
|
+
readonly validatePage: (pageIndex: number) => AnswerValidationResult;
|
|
25
120
|
readonly reset: () => void;
|
|
26
|
-
readonly submit: () => Promise<
|
|
121
|
+
readonly submit: (beforeSubmit?: BeforeSubmit) => Promise<SubmitResult>;
|
|
27
122
|
readonly translate: (key: string, params?: Readonly<Record<string, string | number>>) => string;
|
|
28
123
|
}
|
|
29
124
|
interface FormProviderProps {
|
|
@@ -56,12 +151,25 @@ interface FieldComponentProps {
|
|
|
56
151
|
readonly helpId: string;
|
|
57
152
|
}
|
|
58
153
|
type FieldComponents = Partial<Record<FieldType, ComponentType<FieldComponentProps>>>;
|
|
59
|
-
interface
|
|
154
|
+
interface FormRendererPresentationProps {
|
|
60
155
|
readonly components?: FieldComponents;
|
|
61
156
|
readonly className?: string;
|
|
62
157
|
readonly successMessageKey?: string;
|
|
63
158
|
readonly errorMessageKey?: string;
|
|
159
|
+
readonly autoSaveKey?: string;
|
|
160
|
+
readonly beforeSubmit?: BeforeSubmit;
|
|
161
|
+
readonly onDraftSave?: (draft: FormValues) => void;
|
|
162
|
+
readonly slots?: FormRendererSlots;
|
|
163
|
+
}
|
|
164
|
+
interface StandaloneFormRendererProps extends FormRendererPresentationProps {
|
|
165
|
+
readonly schema: FormSchema;
|
|
166
|
+
readonly locale?: string;
|
|
167
|
+
readonly translator?: TranslationAdapter;
|
|
168
|
+
readonly initialValues?: FormValues;
|
|
169
|
+
readonly resetOnSuccess?: boolean;
|
|
170
|
+
readonly onSubmit: (answers: FormValues) => Promise<void> | void;
|
|
64
171
|
}
|
|
65
|
-
|
|
172
|
+
type FormRendererProps = FormRendererPresentationProps | StandaloneFormRendererProps;
|
|
173
|
+
declare function FormRenderer(props: FormRendererProps): react.JSX.Element;
|
|
66
174
|
|
|
67
|
-
export { type FieldComponentProps, type FieldComponents, type FieldState, FormBuilder, type FormBuilderProps, type FormContextValue, FormProvider, type FormProviderProps, FormRenderer, type FormRendererProps, type SubmitStatus, useField, useForm };
|
|
175
|
+
export { type BeforeSubmit, type BuilderActionError, type BuilderActionResult, type BuilderPolicy, type FieldComponentProps, type FieldComponents, type FieldState, FormBuilder, type FormBuilderOptions, type FormBuilderProps, type FormBuilderResult, type FormContextValue, FormProvider, type FormProviderProps, FormRenderer, type FormRendererPresentationProps, type FormRendererProps, type FormRendererSlots, type StandaloneFormRendererProps, type SubmitResult, type SubmitStatus, useField, useForm, useFormBuilder };
|