@m4l/components 9.4.27 → 9.4.28-BE20260210-1
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/components/DynamicForm/DynamicForm.d.ts +28 -0
- package/components/DynamicForm/DynamicForm.js +126 -0
- package/components/DynamicForm/DynamicForm.styles.d.ts +2 -0
- package/components/DynamicForm/DynamicForm.styles.js +93 -0
- package/components/DynamicForm/constants.d.ts +14 -0
- package/components/DynamicForm/constants.js +18 -0
- package/components/DynamicForm/helpers/normalizeValidations.d.ts +15 -0
- package/components/DynamicForm/helpers/normalizeValidations.js +192 -0
- package/components/DynamicForm/helpers/resolveFieldComponent.d.ts +16 -0
- package/components/DynamicForm/helpers/resolveFieldComponent.js +118 -0
- package/components/DynamicForm/helpers/resolveInitialValue.d.ts +14 -0
- package/components/DynamicForm/helpers/resolveInitialValue.js +99 -0
- package/components/DynamicForm/hooks/useDynamicForm/useDynamicForm.d.ts +14 -0
- package/components/DynamicForm/hooks/useDynamicForm/useDynamicForm.js +38 -0
- package/components/DynamicForm/hooks/useDynamicFormConditionals/useDynamicFormConditionals.d.ts +12 -0
- package/components/DynamicForm/hooks/useDynamicFormConditionals/useDynamicFormConditionals.js +69 -0
- package/components/DynamicForm/hooks/useDynamicFormData/types.d.ts +18 -0
- package/components/DynamicForm/hooks/useDynamicFormData/useDynamicFormData.d.ts +12 -0
- package/components/DynamicForm/hooks/useDynamicFormData/useDynamicFormData.js +128 -0
- package/components/DynamicForm/index.d.ts +4 -0
- package/components/DynamicForm/index.js +1 -0
- package/components/DynamicForm/slots/DynamicFormEnum.d.ts +14 -0
- package/components/DynamicForm/slots/DynamicFormEnum.js +15 -0
- package/components/DynamicForm/slots/DynamicFormSlots.d.ts +14 -0
- package/components/DynamicForm/slots/DynamicFormSlots.js +51 -0
- package/components/DynamicForm/slots/index.d.ts +3 -0
- package/components/DynamicForm/slots/index.js +1 -0
- package/components/DynamicForm/subcomponents/DynamicFormContent/DynamicFormContent.d.ts +2 -0
- package/components/DynamicForm/subcomponents/DynamicFormContent/DynamicFormContent.js +71 -0
- package/components/DynamicForm/subcomponents/DynamicFormCoupled/DynamicFormCoupled.d.ts +32 -0
- package/components/DynamicForm/subcomponents/DynamicFormCoupled/DynamicFormCoupled.js +45 -0
- package/components/DynamicForm/subcomponents/DynamicFormCoupledInternal/DynamicFormCoupledInternal.d.ts +7 -0
- package/components/DynamicForm/subcomponents/DynamicFormCoupledInternal/DynamicFormCoupledInternal.js +86 -0
- package/components/DynamicForm/subcomponents/DynamicFormCoupledInternalContent/DynamicFormCoupledInternalContent.d.ts +9 -0
- package/components/DynamicForm/subcomponents/DynamicFormCoupledInternalContent/DynamicFormCoupledInternalContent.js +62 -0
- package/components/DynamicForm/subcomponents/index.d.ts +4 -0
- package/components/DynamicForm/subcomponents/index.js +1 -0
- package/components/DynamicForm/types.d.ts +313 -0
- package/components/extended/mui/Autocomplete/Autocomplete.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/constants.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/dictionary.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/hooks/useAutocomplete/useAutocomplete.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/hooks/useEndAdornments.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/hooks/useMultipleChips.js +13 -10
- package/components/extended/mui/Autocomplete/hooks/useMultipleChips.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/hooks/useValuesAndHandlers.js +0 -5
- package/components/extended/mui/Autocomplete/hooks/useValuesAndHandlers.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/icons.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/subcomponents/LoadingText/LoadingText.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/subcomponents/NoOptionsText/NoOptionsText.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/subcomponents/PopperComponent/PopperComponent.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/subcomponents/RenderAdornment/RenderAdornment.js +2 -1
- package/components/extended/mui/Autocomplete/subcomponents/RenderAdornment/RenderAdornment.test.d.ts +1 -0
- package/components/extended/mui/Autocomplete/subcomponents/renderOptions/renderOptions.test.d.ts +1 -0
- package/components/hook-form/RHFCheckbox/index.js +1 -0
- package/components/hook-form/RHFCheckbox/types.js +1 -0
- package/components/index.d.ts +1 -0
- package/index.js +66 -60
- package/package.json +1 -1
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
function resolveInitialValue(field) {
|
|
2
|
+
if (field.currentValue && field.currentValue.isVisible) {
|
|
3
|
+
const currentValue = field.currentValue;
|
|
4
|
+
const isCheckableList = field.fieldType.rhfComponent === "RHFCheckableList";
|
|
5
|
+
const isDaysOfWeekPicker = field.fieldType.rhfComponent === "RHFDaysOfWeekPicker";
|
|
6
|
+
if (isCheckableList || isDaysOfWeekPicker) {
|
|
7
|
+
if (currentValue.valueInteger !== null && currentValue.valueInteger !== void 0) {
|
|
8
|
+
return [currentValue.valueInteger];
|
|
9
|
+
}
|
|
10
|
+
if (currentValue.valueString !== null && currentValue.valueString !== void 0) {
|
|
11
|
+
try {
|
|
12
|
+
const parsed = JSON.parse(currentValue.valueString);
|
|
13
|
+
if (Array.isArray(parsed)) {
|
|
14
|
+
return parsed;
|
|
15
|
+
}
|
|
16
|
+
} catch {
|
|
17
|
+
const numValue = Number(currentValue.valueString);
|
|
18
|
+
if (!isNaN(numValue) && currentValue.valueString.trim() !== "") {
|
|
19
|
+
return [numValue];
|
|
20
|
+
}
|
|
21
|
+
return [currentValue.valueString];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (currentValue.value) {
|
|
25
|
+
try {
|
|
26
|
+
const parsed = JSON.parse(currentValue.value);
|
|
27
|
+
if (Array.isArray(parsed)) {
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
} catch {
|
|
31
|
+
const numValue = Number(currentValue.value);
|
|
32
|
+
if (!isNaN(numValue) && currentValue.value.trim() !== "") {
|
|
33
|
+
return [numValue];
|
|
34
|
+
}
|
|
35
|
+
return [currentValue.value];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
if (currentValue.valueString !== null && currentValue.valueString !== void 0) {
|
|
41
|
+
return currentValue.valueString;
|
|
42
|
+
}
|
|
43
|
+
if (currentValue.valueInteger !== null && currentValue.valueInteger !== void 0) {
|
|
44
|
+
return currentValue.valueInteger;
|
|
45
|
+
}
|
|
46
|
+
if (currentValue.valueDouble !== null && currentValue.valueDouble !== void 0) {
|
|
47
|
+
return currentValue.valueDouble;
|
|
48
|
+
}
|
|
49
|
+
if (currentValue.valueBoolean !== null && currentValue.valueBoolean !== void 0) {
|
|
50
|
+
return currentValue.valueBoolean;
|
|
51
|
+
}
|
|
52
|
+
if (currentValue.valueTimestamp !== null && currentValue.valueTimestamp !== void 0) {
|
|
53
|
+
return currentValue.valueTimestamp;
|
|
54
|
+
}
|
|
55
|
+
if (currentValue.value) {
|
|
56
|
+
const numValue = Number(currentValue.value);
|
|
57
|
+
if (!isNaN(numValue) && currentValue.value.trim() !== "") {
|
|
58
|
+
return numValue;
|
|
59
|
+
}
|
|
60
|
+
return currentValue.value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (field.defaultValue !== null && field.defaultValue !== void 0) {
|
|
64
|
+
if (field.fieldType.rhfComponent === "RHFCheckableList" || field.fieldType.rhfComponent === "RHFDaysOfWeekPicker") {
|
|
65
|
+
try {
|
|
66
|
+
const parsed = JSON.parse(field.defaultValue);
|
|
67
|
+
if (Array.isArray(parsed)) {
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
} catch {
|
|
71
|
+
const numValueArray = Number(field.defaultValue);
|
|
72
|
+
if (!isNaN(numValueArray) && field.defaultValue.trim() !== "") {
|
|
73
|
+
return [numValueArray];
|
|
74
|
+
}
|
|
75
|
+
return [field.defaultValue];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const numValue = Number(field.defaultValue);
|
|
79
|
+
if (!isNaN(numValue) && field.defaultValue.trim() !== "") {
|
|
80
|
+
return numValue;
|
|
81
|
+
}
|
|
82
|
+
return field.defaultValue;
|
|
83
|
+
}
|
|
84
|
+
const fieldType = field.fieldType.id;
|
|
85
|
+
const rhfComponent = field.fieldType.rhfComponent;
|
|
86
|
+
if (rhfComponent === "RHFCheckableList" || rhfComponent === "RHFDaysOfWeekPicker") {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
if (fieldType === "fft_boolean" || fieldType === "fft_checkbox") {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (fieldType === "fft_number" || fieldType === "fft_integer" || fieldType === "fft_double") {
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
resolveInitialValue as r
|
|
99
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { DynamicFormApiResponse } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook que gestiona la preparación de datos del formulario dinámico.
|
|
4
|
+
*
|
|
5
|
+
* Responsabilidades:
|
|
6
|
+
* - Resolver valores iniciales
|
|
7
|
+
* - Crear esquema de validación
|
|
8
|
+
*
|
|
9
|
+
* Nota: Este hook NO crea el formMethods, ya que eso lo hace RHFormProvider.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useDynamicForm(data: DynamicFormApiResponse): {
|
|
12
|
+
initialValues: Record<string, unknown>;
|
|
13
|
+
validationSchema: import('../../..').ValidationSchema<Record<string, unknown>>;
|
|
14
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { r as resolveInitialValue } from "../../helpers/resolveInitialValue.js";
|
|
3
|
+
import { c as createFieldValidationSchema } from "../../helpers/normalizeValidations.js";
|
|
4
|
+
import { b as createValidationPartialObject, c as createValidationSchema, a as createValidationFullObject } from "../../../hook-form/RHFormProvider/schema.js";
|
|
5
|
+
function useDynamicForm(data) {
|
|
6
|
+
const { fields } = data;
|
|
7
|
+
const initialValues = useMemo(() => {
|
|
8
|
+
const values = {};
|
|
9
|
+
fields.forEach((field) => {
|
|
10
|
+
if (field.currentValue?.isVisible !== false) {
|
|
11
|
+
values[field.name] = resolveInitialValue(field);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
return values;
|
|
15
|
+
}, [fields]);
|
|
16
|
+
const validationSchema = useMemo(() => {
|
|
17
|
+
const validationShape = createValidationPartialObject({});
|
|
18
|
+
fields.forEach((field) => {
|
|
19
|
+
const fieldSchema = createFieldValidationSchema(field);
|
|
20
|
+
if (fieldSchema) {
|
|
21
|
+
const isVisibleInitially = field.currentValue?.isVisible !== false;
|
|
22
|
+
if (field.isConditional && !isVisibleInitially) {
|
|
23
|
+
validationShape[field.name] = fieldSchema.optional();
|
|
24
|
+
} else {
|
|
25
|
+
validationShape[field.name] = fieldSchema;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return createValidationSchema(createValidationFullObject(validationShape));
|
|
30
|
+
}, [fields]);
|
|
31
|
+
return {
|
|
32
|
+
initialValues,
|
|
33
|
+
validationSchema
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export {
|
|
37
|
+
useDynamicForm as u
|
|
38
|
+
};
|
package/components/DynamicForm/hooks/useDynamicFormConditionals/useDynamicFormConditionals.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DynamicFormApiResponse } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook que gestiona las reglas condicionales del formulario dinámico.
|
|
4
|
+
* Debe usarse dentro del contexto de RHFormProvider.
|
|
5
|
+
*
|
|
6
|
+
* Responsabilidades:
|
|
7
|
+
* - Evaluar reglas condicionales
|
|
8
|
+
* - Gestionar visibilidad de campos
|
|
9
|
+
*/
|
|
10
|
+
export declare function useDynamicFormConditionals(data: DynamicFormApiResponse): {
|
|
11
|
+
visibleFields: import('../../types').Field[];
|
|
12
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useState, useCallback, useEffect, useMemo } from "react";
|
|
2
|
+
import { useFormContext, useWatch } from "react-hook-form";
|
|
3
|
+
function useDynamicFormConditionals(data) {
|
|
4
|
+
const { fields, conditionalRules } = data;
|
|
5
|
+
const { control } = useFormContext();
|
|
6
|
+
const [visibleFields, setVisibleFields] = useState(() => {
|
|
7
|
+
const visible = /* @__PURE__ */ new Set();
|
|
8
|
+
fields.forEach((field) => {
|
|
9
|
+
if (!field.isConditional && field.currentValue?.isVisible !== false) {
|
|
10
|
+
visible.add(field.name);
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
return visible;
|
|
14
|
+
});
|
|
15
|
+
const evaluateCondition = useCallback((rule, sourceValue) => {
|
|
16
|
+
const { operator, conditionValue } = rule;
|
|
17
|
+
switch (operator.name) {
|
|
18
|
+
case "equals":
|
|
19
|
+
return String(sourceValue) === String(conditionValue);
|
|
20
|
+
case "not_equals":
|
|
21
|
+
return String(sourceValue) !== String(conditionValue);
|
|
22
|
+
case "greater_than":
|
|
23
|
+
return Number(sourceValue) > Number(conditionValue);
|
|
24
|
+
case "less_than":
|
|
25
|
+
return Number(sourceValue) < Number(conditionValue);
|
|
26
|
+
case "greater_than_or_equal":
|
|
27
|
+
return Number(sourceValue) >= Number(conditionValue);
|
|
28
|
+
case "less_than_or_equal":
|
|
29
|
+
return Number(sourceValue) <= Number(conditionValue);
|
|
30
|
+
case "contains":
|
|
31
|
+
return String(sourceValue).includes(String(conditionValue));
|
|
32
|
+
case "not_contains":
|
|
33
|
+
return !String(sourceValue).includes(String(conditionValue));
|
|
34
|
+
default:
|
|
35
|
+
console.warn(`Operador no soportado: ${operator.name}`);
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}, []);
|
|
39
|
+
const watchValues = useWatch({ control });
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
const newVisibleFields = /* @__PURE__ */ new Set();
|
|
42
|
+
fields.forEach((field) => {
|
|
43
|
+
if (!field.isConditional && field.currentValue?.isVisible !== false) {
|
|
44
|
+
newVisibleFields.add(field.name);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
conditionalRules.filter((rule) => rule.isActive).forEach((rule) => {
|
|
48
|
+
const sourceValue = watchValues[rule.sourceFieldName];
|
|
49
|
+
const conditionMet = evaluateCondition(rule, sourceValue);
|
|
50
|
+
if (conditionMet && rule.actionType === "show") {
|
|
51
|
+
newVisibleFields.add(rule.targetFieldName);
|
|
52
|
+
} else if (!conditionMet && rule.actionType === "show") ;
|
|
53
|
+
else if (conditionMet && rule.actionType === "hide") ;
|
|
54
|
+
else if (!conditionMet && rule.actionType === "hide") {
|
|
55
|
+
newVisibleFields.add(rule.targetFieldName);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
setVisibleFields(newVisibleFields);
|
|
59
|
+
}, [watchValues, conditionalRules, fields, evaluateCondition]);
|
|
60
|
+
const sortedVisibleFields = useMemo(() => {
|
|
61
|
+
return fields.filter((field) => visibleFields.has(field.name)).sort((a, b) => a.displayOrder - b.displayOrder);
|
|
62
|
+
}, [fields, visibleFields]);
|
|
63
|
+
return {
|
|
64
|
+
visibleFields: sortedVisibleFields
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
useDynamicFormConditionals as u
|
|
69
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { FormStatusLoad } from '../../../hook-form/RHFormProvider/types';
|
|
2
|
+
import { DynamicFormApiResponse } from '../../types';
|
|
3
|
+
export interface UseDynamicFormDataProps {
|
|
4
|
+
idForm?: number;
|
|
5
|
+
idFormInstance?: number;
|
|
6
|
+
inputEndpoint?: string;
|
|
7
|
+
outputEndpoint?: string;
|
|
8
|
+
formatInputData?: (data: Record<string, unknown>) => Record<string, unknown>;
|
|
9
|
+
formatOutputData?: (data: Record<string, unknown>) => Record<string, unknown>;
|
|
10
|
+
onSubmit?: (data: Record<string, unknown>) => void | Promise<void>;
|
|
11
|
+
initialData?: DynamicFormApiResponse | null;
|
|
12
|
+
}
|
|
13
|
+
export interface UseDynamicFormDataReturn {
|
|
14
|
+
formData: DynamicFormApiResponse | null;
|
|
15
|
+
statusLoad: FormStatusLoad;
|
|
16
|
+
handleSubmit: (data: Record<string, unknown>) => Promise<void>;
|
|
17
|
+
isLoading: boolean;
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { UseDynamicFormDataProps, UseDynamicFormDataReturn } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Hook que gestiona la obtención y envío de datos del formulario dinámico.
|
|
4
|
+
*
|
|
5
|
+
* Responsabilidades:
|
|
6
|
+
* - Obtener datos del inputEndpoint mediante networkOperation
|
|
7
|
+
* - Aplicar formatInputData si existe
|
|
8
|
+
* - Manejar el estado de carga
|
|
9
|
+
* - Enviar datos al outputEndpoint cuando se hace submit
|
|
10
|
+
* - Aplicar formatOutputData antes de enviar
|
|
11
|
+
*/
|
|
12
|
+
export declare function useDynamicFormData(props: UseDynamicFormDataProps): UseDynamicFormDataReturn;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { useState, useRef, useEffect } from "react";
|
|
2
|
+
import { useNetwork } from "@m4l/core";
|
|
3
|
+
function useDynamicFormData(props) {
|
|
4
|
+
const {
|
|
5
|
+
idForm,
|
|
6
|
+
idFormInstance,
|
|
7
|
+
inputEndpoint: InputEndpoint,
|
|
8
|
+
outputEndpoint: OutputEndpoint,
|
|
9
|
+
formatInputData,
|
|
10
|
+
formatOutputData,
|
|
11
|
+
onSubmit: onSubmitCallback,
|
|
12
|
+
initialData
|
|
13
|
+
} = props;
|
|
14
|
+
const { networkOperation } = useNetwork();
|
|
15
|
+
const [formData, setFormData] = useState(initialData || null);
|
|
16
|
+
const [statusLoad, setStatusLoad] = useState(
|
|
17
|
+
InputEndpoint ? "edit" : initialData ? "ready" : "new"
|
|
18
|
+
);
|
|
19
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
20
|
+
const abortControllerRef = useRef(null);
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
let mounted = true;
|
|
23
|
+
if (statusLoad === "edit" && InputEndpoint) {
|
|
24
|
+
if (abortControllerRef.current) {
|
|
25
|
+
abortControllerRef.current.abort();
|
|
26
|
+
}
|
|
27
|
+
abortControllerRef.current = new AbortController();
|
|
28
|
+
setIsLoading(true);
|
|
29
|
+
const parms = {};
|
|
30
|
+
if (idFormInstance !== void 0) {
|
|
31
|
+
parms.form_instance_id = idFormInstance;
|
|
32
|
+
}
|
|
33
|
+
networkOperation({
|
|
34
|
+
method: "GET",
|
|
35
|
+
endPoint: InputEndpoint,
|
|
36
|
+
parms,
|
|
37
|
+
timeout: 6e4,
|
|
38
|
+
isRemote: true,
|
|
39
|
+
responseToCamelCase: true,
|
|
40
|
+
signal: abortControllerRef.current.signal
|
|
41
|
+
}).then((response) => {
|
|
42
|
+
if (!mounted) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
let processedData = response;
|
|
46
|
+
if (formatInputData) {
|
|
47
|
+
processedData = formatInputData(processedData);
|
|
48
|
+
}
|
|
49
|
+
setFormData(processedData);
|
|
50
|
+
setStatusLoad("reload_values_provider");
|
|
51
|
+
setIsLoading(false);
|
|
52
|
+
}).catch(() => {
|
|
53
|
+
if (!mounted) {
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
setStatusLoad("error");
|
|
57
|
+
setIsLoading(false);
|
|
58
|
+
});
|
|
59
|
+
} else if (statusLoad === "reload_values_provider") {
|
|
60
|
+
setStatusLoad("ready");
|
|
61
|
+
setIsLoading(false);
|
|
62
|
+
} else if (statusLoad === "new" || statusLoad === "ready" && formData) {
|
|
63
|
+
setIsLoading(false);
|
|
64
|
+
}
|
|
65
|
+
return () => {
|
|
66
|
+
mounted = false;
|
|
67
|
+
if (abortControllerRef.current) {
|
|
68
|
+
abortControllerRef.current.abort();
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}, [statusLoad, InputEndpoint, idForm, idFormInstance, formatInputData, networkOperation, formData]);
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (!InputEndpoint) {
|
|
74
|
+
if (initialData) {
|
|
75
|
+
setFormData(initialData);
|
|
76
|
+
setStatusLoad("ready");
|
|
77
|
+
} else {
|
|
78
|
+
setFormData(null);
|
|
79
|
+
setStatusLoad("new");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}, [initialData, InputEndpoint]);
|
|
83
|
+
const handleSubmit = async (data) => {
|
|
84
|
+
if (!OutputEndpoint) {
|
|
85
|
+
if (onSubmitCallback) {
|
|
86
|
+
await onSubmitCallback(data);
|
|
87
|
+
}
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
setIsLoading(true);
|
|
91
|
+
try {
|
|
92
|
+
let dataToSend = data;
|
|
93
|
+
if (formatOutputData) {
|
|
94
|
+
dataToSend = formatOutputData(data);
|
|
95
|
+
}
|
|
96
|
+
let endPoint = OutputEndpoint;
|
|
97
|
+
if (idFormInstance !== void 0) {
|
|
98
|
+
endPoint = `${OutputEndpoint}/${idFormInstance}`;
|
|
99
|
+
}
|
|
100
|
+
const method = idFormInstance !== void 0 ? "PUT" : "POST";
|
|
101
|
+
await networkOperation({
|
|
102
|
+
method,
|
|
103
|
+
endPoint,
|
|
104
|
+
data: dataToSend,
|
|
105
|
+
timeout: 6e4,
|
|
106
|
+
isRemote: true,
|
|
107
|
+
bodyToSnakeCase: true,
|
|
108
|
+
responseToCamelCase: true
|
|
109
|
+
});
|
|
110
|
+
if (onSubmitCallback) {
|
|
111
|
+
await onSubmitCallback(data);
|
|
112
|
+
}
|
|
113
|
+
} catch (error) {
|
|
114
|
+
throw error;
|
|
115
|
+
} finally {
|
|
116
|
+
setIsLoading(false);
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
formData,
|
|
121
|
+
statusLoad,
|
|
122
|
+
handleSubmit,
|
|
123
|
+
isLoading
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
export {
|
|
127
|
+
useDynamicFormData as u
|
|
128
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enum que define todos los slots disponibles para el componente DynamicForm.
|
|
3
|
+
*/
|
|
4
|
+
export declare enum DynamicFormSlots {
|
|
5
|
+
root = "root",
|
|
6
|
+
formProvider = "formProvider",
|
|
7
|
+
contentRoot = "contentRoot",
|
|
8
|
+
fieldWrapper = "fieldWrapper",
|
|
9
|
+
label = "label",
|
|
10
|
+
control = "control",
|
|
11
|
+
helperText = "helperText",
|
|
12
|
+
sectionDivider = "sectionDivider",
|
|
13
|
+
checkableListWrapper = "checkableListWrapper"
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
var DynamicFormSlots = /* @__PURE__ */ ((DynamicFormSlots2) => {
|
|
2
|
+
DynamicFormSlots2["root"] = "root";
|
|
3
|
+
DynamicFormSlots2["formProvider"] = "formProvider";
|
|
4
|
+
DynamicFormSlots2["contentRoot"] = "contentRoot";
|
|
5
|
+
DynamicFormSlots2["fieldWrapper"] = "fieldWrapper";
|
|
6
|
+
DynamicFormSlots2["label"] = "label";
|
|
7
|
+
DynamicFormSlots2["control"] = "control";
|
|
8
|
+
DynamicFormSlots2["helperText"] = "helperText";
|
|
9
|
+
DynamicFormSlots2["sectionDivider"] = "sectionDivider";
|
|
10
|
+
DynamicFormSlots2["checkableListWrapper"] = "checkableListWrapper";
|
|
11
|
+
return DynamicFormSlots2;
|
|
12
|
+
})(DynamicFormSlots || {});
|
|
13
|
+
export {
|
|
14
|
+
DynamicFormSlots as D
|
|
15
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { RHFormValues, RHFormProviderRef, RHFormProviderProps } from '../../hook-form/RHFormProvider/types';
|
|
2
|
+
import { RefAttributes, ReactElement } from 'react';
|
|
3
|
+
export declare const DynamicFormRootStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, Pick<import('react').DetailedHTMLProps<import('react').FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, keyof import('react').ClassAttributes<HTMLFormElement> | keyof import('react').FormHTMLAttributes<HTMLFormElement>>, {}>;
|
|
4
|
+
export declare const DynamicFormFormProviderStyledBase: import('@emotion/styled').StyledComponent<Pick<RHFormProviderProps<RHFormValues> & RefAttributes<RHFormProviderRef<RHFormValues>>, keyof RHFormProviderProps<RHFormValues> | keyof RefAttributes<RHFormProviderRef<RHFormValues>>> & import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, {}, {}>;
|
|
5
|
+
export declare const DynamicFormFormProviderStyled: <T extends RHFormValues>(props: RHFormProviderProps<T> & RefAttributes<RHFormProviderRef<T>>) => ReactElement;
|
|
6
|
+
export declare const DynamicFormContentRootStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
|
|
7
|
+
export declare const DynamicFormFieldWrapperStyled: import('@emotion/styled').StyledComponent<Pick<import('@mui/system').BoxOwnProps<import('@mui/material').Theme> & Omit<Omit<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & {
|
|
8
|
+
ref?: ((instance: HTMLDivElement | null) => void | import('react').DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES[keyof import('react').DO_NOT_USE_OR_YOU_WILL_BE_FIRED_CALLBACK_REF_RETURN_VALUES]) | import('react').RefObject<HTMLDivElement> | null | undefined;
|
|
9
|
+
}, keyof import('@mui/system').BoxOwnProps<import('@mui/material').Theme>>, "title" | "id" | "content" | "translate" | "className" | "style" | "slot" | "key" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | keyof import('@mui/system').BoxOwnProps<import('@mui/material').Theme>> & import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, {}, {}>;
|
|
10
|
+
export declare const DynamicFormLabelStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
|
|
11
|
+
export declare const DynamicFormControlStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
|
|
12
|
+
export declare const DynamicFormHelperTextStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
|
|
13
|
+
export declare const DynamicFormSectionDividerStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
|
|
14
|
+
export declare const DynamicFormCheckableListWrapperStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material').Theme> & Record<string, unknown>, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { styled } from "@mui/material/styles";
|
|
2
|
+
import { Box } from "@mui/material";
|
|
3
|
+
import { D as DynamicFormSlots } from "./DynamicFormEnum.js";
|
|
4
|
+
import { c as componentStyles } from "../DynamicForm.styles.js";
|
|
5
|
+
import { a as DYNAMIC_FORM_KEY_COMPONENT } from "../constants.js";
|
|
6
|
+
import { R as RHFormProvider } from "../../hook-form/RHFormProvider/RHFormProvider.js";
|
|
7
|
+
const DynamicFormRootStyled = styled("form", {
|
|
8
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
9
|
+
slot: DynamicFormSlots.root
|
|
10
|
+
})(componentStyles?.root);
|
|
11
|
+
const DynamicFormFormProviderStyledBase = styled(RHFormProvider, {
|
|
12
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
13
|
+
slot: DynamicFormSlots.formProvider
|
|
14
|
+
})(componentStyles?.formProvider);
|
|
15
|
+
const DynamicFormFormProviderStyled = DynamicFormFormProviderStyledBase;
|
|
16
|
+
const DynamicFormContentRootStyled = styled("div", {
|
|
17
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
18
|
+
slot: DynamicFormSlots.contentRoot
|
|
19
|
+
})(componentStyles?.contentRoot);
|
|
20
|
+
const DynamicFormFieldWrapperStyled = styled(Box, {
|
|
21
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
22
|
+
slot: DynamicFormSlots.fieldWrapper
|
|
23
|
+
})(componentStyles?.fieldWrapper);
|
|
24
|
+
styled("div", {
|
|
25
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
26
|
+
slot: DynamicFormSlots.label
|
|
27
|
+
})(componentStyles?.label);
|
|
28
|
+
const DynamicFormControlStyled = styled("div", {
|
|
29
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
30
|
+
slot: DynamicFormSlots.control
|
|
31
|
+
})(componentStyles?.control);
|
|
32
|
+
styled("div", {
|
|
33
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
34
|
+
slot: DynamicFormSlots.helperText
|
|
35
|
+
})(componentStyles?.helperText);
|
|
36
|
+
styled("div", {
|
|
37
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
38
|
+
slot: DynamicFormSlots.sectionDivider
|
|
39
|
+
})(componentStyles?.sectionDivider);
|
|
40
|
+
const DynamicFormCheckableListWrapperStyled = styled("div", {
|
|
41
|
+
name: DYNAMIC_FORM_KEY_COMPONENT,
|
|
42
|
+
slot: DynamicFormSlots.checkableListWrapper
|
|
43
|
+
})(componentStyles?.checkableListWrapper);
|
|
44
|
+
export {
|
|
45
|
+
DynamicFormRootStyled as D,
|
|
46
|
+
DynamicFormFormProviderStyled as a,
|
|
47
|
+
DynamicFormCheckableListWrapperStyled as b,
|
|
48
|
+
DynamicFormContentRootStyled as c,
|
|
49
|
+
DynamicFormFieldWrapperStyled as d,
|
|
50
|
+
DynamicFormControlStyled as e
|
|
51
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import { forwardRef } from "react";
|
|
3
|
+
import clsx from "clsx";
|
|
4
|
+
import { T as TEST_PROP_ID } from "../../../../test/constants_no_mock.js";
|
|
5
|
+
import { A as ActionsContainer } from "../../../CommonActions/components/ActionsContainer/ActionsContainer.js";
|
|
6
|
+
import { A as ActionFormIntro } from "../../../CommonActions/components/ActionFormIntro/ActionFormIntro.js";
|
|
7
|
+
import { u as useDynamicFormConditionals } from "../../hooks/useDynamicFormConditionals/useDynamicFormConditionals.js";
|
|
8
|
+
import { r as resolveFieldComponent } from "../../helpers/resolveFieldComponent.js";
|
|
9
|
+
import { D as DYNAMIC_FORM_CLASSES } from "../../constants.js";
|
|
10
|
+
import { c as DynamicFormContentRootStyled, d as DynamicFormFieldWrapperStyled, e as DynamicFormControlStyled } from "../../slots/DynamicFormSlots.js";
|
|
11
|
+
const DynamicFormContent = forwardRef((props, ref) => {
|
|
12
|
+
const {
|
|
13
|
+
data,
|
|
14
|
+
ownerState,
|
|
15
|
+
currentSize,
|
|
16
|
+
fieldWrapperClassName,
|
|
17
|
+
dataTestId,
|
|
18
|
+
coupled = false,
|
|
19
|
+
actionFormIntroProps,
|
|
20
|
+
renderActions
|
|
21
|
+
} = props;
|
|
22
|
+
const { visibleFields } = useDynamicFormConditionals(data);
|
|
23
|
+
return /* @__PURE__ */ jsxs(
|
|
24
|
+
DynamicFormContentRootStyled,
|
|
25
|
+
{
|
|
26
|
+
ref,
|
|
27
|
+
className: clsx(DYNAMIC_FORM_CLASSES.contentRoot),
|
|
28
|
+
...process.env.NODE_ENV !== "production" ? { [TEST_PROP_ID]: dataTestId } : {},
|
|
29
|
+
children: [
|
|
30
|
+
visibleFields.map((field) => {
|
|
31
|
+
const fieldComponent = resolveFieldComponent(field, {
|
|
32
|
+
name: field.name,
|
|
33
|
+
size: currentSize,
|
|
34
|
+
placeholder: field.placeholder,
|
|
35
|
+
rhfComponentProps: field.fieldType.rhfComponentProps || {}
|
|
36
|
+
});
|
|
37
|
+
if (!fieldComponent) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
return /* @__PURE__ */ jsx(
|
|
41
|
+
DynamicFormFieldWrapperStyled,
|
|
42
|
+
{
|
|
43
|
+
ownerState,
|
|
44
|
+
className: clsx(fieldWrapperClassName, DYNAMIC_FORM_CLASSES.fieldWrapper),
|
|
45
|
+
children: /* @__PURE__ */ jsx(
|
|
46
|
+
DynamicFormControlStyled,
|
|
47
|
+
{
|
|
48
|
+
ownerState,
|
|
49
|
+
className: DYNAMIC_FORM_CLASSES.control,
|
|
50
|
+
children: fieldComponent
|
|
51
|
+
}
|
|
52
|
+
)
|
|
53
|
+
},
|
|
54
|
+
field.id
|
|
55
|
+
);
|
|
56
|
+
}),
|
|
57
|
+
!coupled && /* @__PURE__ */ jsx(ActionsContainer, { children: renderActions ? renderActions() : /* @__PURE__ */ jsx(
|
|
58
|
+
ActionFormIntro,
|
|
59
|
+
{
|
|
60
|
+
size: currentSize,
|
|
61
|
+
...actionFormIntroProps
|
|
62
|
+
}
|
|
63
|
+
) })
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
DynamicFormContent.displayName = "DynamicFormContent";
|
|
69
|
+
export {
|
|
70
|
+
DynamicFormContent as D
|
|
71
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { DynamicFormCoupledProps } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Componente que expone el DynamicForm como un campo de React Hook Form mediante Controller.
|
|
4
|
+
* Se usa cuando coupled=true para integrar el formulario dentro de un formulario padre.
|
|
5
|
+
*
|
|
6
|
+
* **Propósito principal:**
|
|
7
|
+
* Este componente permite delegar el proceso de submit a un formulario superior (padre),
|
|
8
|
+
* lo que habilita escenarios donde se pueden ejecutar múltiples DynamicForms acoplados
|
|
9
|
+
* dentro de un único formulario padre y realizar un submit conjunto de todos ellos.
|
|
10
|
+
*
|
|
11
|
+
* **Casos de uso:**
|
|
12
|
+
* - Combinar varios DynamicForms en un solo formulario padre
|
|
13
|
+
* - Validar y enviar múltiples formularios dinámicos en una única operación
|
|
14
|
+
* - Centralizar la lógica de submit y manejo de errores en el formulario padre
|
|
15
|
+
* - Coordinar el envío de datos de múltiples formularios relacionados
|
|
16
|
+
*
|
|
17
|
+
* **Funcionamiento:**
|
|
18
|
+
* El componente usa `Controller` de React Hook Form para exponer el DynamicForm como
|
|
19
|
+
* un campo del formulario padre. Los valores y el estado de validación del DynamicForm
|
|
20
|
+
* se exponen al formulario padre a través del callback `onChange`, permitiendo que el
|
|
21
|
+
* formulario padre tenga control total sobre cuándo y cómo se realiza el submit.
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <RHFormProvider onSubmit={handleSubmitAllForms}>
|
|
25
|
+
* <DynamicForm coupled={true} name="form1" {...props} />
|
|
26
|
+
* <DynamicForm coupled={true} name="form2" {...props} />
|
|
27
|
+
* <DynamicForm coupled={true} name="form3" {...props} />
|
|
28
|
+
* <Button type="submit">Enviar todos los formularios</Button>
|
|
29
|
+
* </RHFormProvider>
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare const DynamicFormCoupled: import('react').ForwardRefExoticComponent<DynamicFormCoupledProps & import('react').RefAttributes<HTMLDivElement>>;
|