@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.
Files changed (59) hide show
  1. package/components/DynamicForm/DynamicForm.d.ts +28 -0
  2. package/components/DynamicForm/DynamicForm.js +126 -0
  3. package/components/DynamicForm/DynamicForm.styles.d.ts +2 -0
  4. package/components/DynamicForm/DynamicForm.styles.js +93 -0
  5. package/components/DynamicForm/constants.d.ts +14 -0
  6. package/components/DynamicForm/constants.js +18 -0
  7. package/components/DynamicForm/helpers/normalizeValidations.d.ts +15 -0
  8. package/components/DynamicForm/helpers/normalizeValidations.js +192 -0
  9. package/components/DynamicForm/helpers/resolveFieldComponent.d.ts +16 -0
  10. package/components/DynamicForm/helpers/resolveFieldComponent.js +118 -0
  11. package/components/DynamicForm/helpers/resolveInitialValue.d.ts +14 -0
  12. package/components/DynamicForm/helpers/resolveInitialValue.js +99 -0
  13. package/components/DynamicForm/hooks/useDynamicForm/useDynamicForm.d.ts +14 -0
  14. package/components/DynamicForm/hooks/useDynamicForm/useDynamicForm.js +38 -0
  15. package/components/DynamicForm/hooks/useDynamicFormConditionals/useDynamicFormConditionals.d.ts +12 -0
  16. package/components/DynamicForm/hooks/useDynamicFormConditionals/useDynamicFormConditionals.js +69 -0
  17. package/components/DynamicForm/hooks/useDynamicFormData/types.d.ts +18 -0
  18. package/components/DynamicForm/hooks/useDynamicFormData/useDynamicFormData.d.ts +12 -0
  19. package/components/DynamicForm/hooks/useDynamicFormData/useDynamicFormData.js +128 -0
  20. package/components/DynamicForm/index.d.ts +4 -0
  21. package/components/DynamicForm/index.js +1 -0
  22. package/components/DynamicForm/slots/DynamicFormEnum.d.ts +14 -0
  23. package/components/DynamicForm/slots/DynamicFormEnum.js +15 -0
  24. package/components/DynamicForm/slots/DynamicFormSlots.d.ts +14 -0
  25. package/components/DynamicForm/slots/DynamicFormSlots.js +51 -0
  26. package/components/DynamicForm/slots/index.d.ts +3 -0
  27. package/components/DynamicForm/slots/index.js +1 -0
  28. package/components/DynamicForm/subcomponents/DynamicFormContent/DynamicFormContent.d.ts +2 -0
  29. package/components/DynamicForm/subcomponents/DynamicFormContent/DynamicFormContent.js +71 -0
  30. package/components/DynamicForm/subcomponents/DynamicFormCoupled/DynamicFormCoupled.d.ts +32 -0
  31. package/components/DynamicForm/subcomponents/DynamicFormCoupled/DynamicFormCoupled.js +45 -0
  32. package/components/DynamicForm/subcomponents/DynamicFormCoupledInternal/DynamicFormCoupledInternal.d.ts +7 -0
  33. package/components/DynamicForm/subcomponents/DynamicFormCoupledInternal/DynamicFormCoupledInternal.js +86 -0
  34. package/components/DynamicForm/subcomponents/DynamicFormCoupledInternalContent/DynamicFormCoupledInternalContent.d.ts +9 -0
  35. package/components/DynamicForm/subcomponents/DynamicFormCoupledInternalContent/DynamicFormCoupledInternalContent.js +62 -0
  36. package/components/DynamicForm/subcomponents/index.d.ts +4 -0
  37. package/components/DynamicForm/subcomponents/index.js +1 -0
  38. package/components/DynamicForm/types.d.ts +313 -0
  39. package/components/extended/mui/Autocomplete/Autocomplete.test.d.ts +1 -0
  40. package/components/extended/mui/Autocomplete/constants.test.d.ts +1 -0
  41. package/components/extended/mui/Autocomplete/dictionary.test.d.ts +1 -0
  42. package/components/extended/mui/Autocomplete/hooks/useAutocomplete/useAutocomplete.test.d.ts +1 -0
  43. package/components/extended/mui/Autocomplete/hooks/useEndAdornments.test.d.ts +1 -0
  44. package/components/extended/mui/Autocomplete/hooks/useMultipleChips.js +13 -10
  45. package/components/extended/mui/Autocomplete/hooks/useMultipleChips.test.d.ts +1 -0
  46. package/components/extended/mui/Autocomplete/hooks/useValuesAndHandlers.js +0 -5
  47. package/components/extended/mui/Autocomplete/hooks/useValuesAndHandlers.test.d.ts +1 -0
  48. package/components/extended/mui/Autocomplete/icons.test.d.ts +1 -0
  49. package/components/extended/mui/Autocomplete/subcomponents/LoadingText/LoadingText.test.d.ts +1 -0
  50. package/components/extended/mui/Autocomplete/subcomponents/NoOptionsText/NoOptionsText.test.d.ts +1 -0
  51. package/components/extended/mui/Autocomplete/subcomponents/PopperComponent/PopperComponent.test.d.ts +1 -0
  52. package/components/extended/mui/Autocomplete/subcomponents/RenderAdornment/RenderAdornment.js +2 -1
  53. package/components/extended/mui/Autocomplete/subcomponents/RenderAdornment/RenderAdornment.test.d.ts +1 -0
  54. package/components/extended/mui/Autocomplete/subcomponents/renderOptions/renderOptions.test.d.ts +1 -0
  55. package/components/hook-form/RHFCheckbox/index.js +1 -0
  56. package/components/hook-form/RHFCheckbox/types.js +1 -0
  57. package/components/index.d.ts +1 -0
  58. package/index.js +66 -60
  59. package/package.json +1 -1
@@ -0,0 +1,28 @@
1
+ import { default as React } from 'react';
2
+ import { DynamicFormProps, DynamicFormRef } from './types';
3
+ /**
4
+ * Componente DynamicForm que renderiza y edita formularios dinámicos
5
+ * a partir del JSON real enviado por la API, usando React Hook Form.
6
+ *
7
+ * Este componente interpreta el contrato API y renderiza los campos
8
+ * según las especificaciones del backend, incluyendo:
9
+ * - Validaciones dinámicas
10
+ * - Reglas condicionales
11
+ * - Valores iniciales
12
+ * - Tipos de campos diversos
13
+ *
14
+ * ### Dependencias:
15
+ * - **`useDynamicForm:`** Hook que gestiona la lógica del formulario dinámico.
16
+ * - **`resolveFieldComponent:`** Helper que resuelve el componente RHF correspondiente.
17
+ * @param {DynamicFormProps} props - Propiedades del componente.
18
+ * @returns {JSX.Element} Elemento renderizado.
19
+ * @example
20
+ * ```tsx
21
+ * <DynamicForm
22
+ * data={formData}
23
+ * onSubmit={(data) => console.log(data)}
24
+ * size="medium"
25
+ * />
26
+ * ```
27
+ */
28
+ export declare const DynamicForm: React.ForwardRefExoticComponent<DynamicFormProps & React.RefAttributes<DynamicFormRef>>;
@@ -0,0 +1,126 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import React, { forwardRef, useMemo, useImperativeHandle } from "react";
3
+ import clsx from "clsx";
4
+ import { useModuleSkeleton } from "@m4l/core";
5
+ import { T as TEST_PROP_ID } from "../../test/constants_no_mock.js";
6
+ import { L as LinearProgress } from "../extended/mui/LinearProgress/index.js";
7
+ import { D as DynamicFormRootStyled, a as DynamicFormFormProviderStyled } from "./slots/DynamicFormSlots.js";
8
+ import { D as DYNAMIC_FORM_CLASSES, E as EMPTY_DATA } from "./constants.js";
9
+ import { u as useDynamicForm } from "./hooks/useDynamicForm/useDynamicForm.js";
10
+ import { u as useDynamicFormData } from "./hooks/useDynamicFormData/useDynamicFormData.js";
11
+ import { u as useComponentSize } from "../../hooks/useComponentSize/useComponentSize.js";
12
+ import { D as DynamicFormCoupled } from "./subcomponents/DynamicFormCoupled/DynamicFormCoupled.js";
13
+ import { D as DynamicFormContent } from "./subcomponents/DynamicFormContent/DynamicFormContent.js";
14
+ const DynamicForm = forwardRef((props, ref) => {
15
+ const {
16
+ idForm,
17
+ idFormInstance,
18
+ inputEndpoint,
19
+ outputEndpoint,
20
+ data,
21
+ formatInputData,
22
+ formatOutputData,
23
+ onSubmit,
24
+ onSubmitError,
25
+ size,
26
+ className,
27
+ dataTestId,
28
+ fieldWrapperClassName,
29
+ coupled = false,
30
+ name,
31
+ actionFormIntroProps,
32
+ renderActions,
33
+ ...others
34
+ } = props;
35
+ const { currentSize } = useComponentSize(size);
36
+ const isSkeleton = useModuleSkeleton();
37
+ const {
38
+ formData,
39
+ statusLoad,
40
+ handleSubmit
41
+ } = useDynamicFormData({
42
+ idForm,
43
+ idFormInstance,
44
+ inputEndpoint,
45
+ outputEndpoint,
46
+ initialData: data,
47
+ formatInputData,
48
+ formatOutputData,
49
+ onSubmit
50
+ });
51
+ const formDataToUse = formData || data;
52
+ const { initialValues, validationSchema } = useDynamicForm(formDataToUse || EMPTY_DATA);
53
+ const ownerState = useMemo(() => ({
54
+ size: currentSize
55
+ }), [currentSize]);
56
+ const formRef = React.useRef(null);
57
+ useImperativeHandle(ref, () => {
58
+ return formRef.current;
59
+ }, []);
60
+ if (!formDataToUse) {
61
+ return null;
62
+ }
63
+ if (isSkeleton) {
64
+ return /* @__PURE__ */ jsx(
65
+ DynamicFormRootStyled,
66
+ {
67
+ ownerState,
68
+ className: clsx(className, DYNAMIC_FORM_CLASSES.root),
69
+ ...process.env.NODE_ENV !== "production" ? { [TEST_PROP_ID]: dataTestId } : {},
70
+ ...others,
71
+ children: /* @__PURE__ */ jsx(LinearProgress, {})
72
+ }
73
+ );
74
+ }
75
+ if (coupled) {
76
+ if (!name) {
77
+ console.warn('DynamicForm: La prop "name" es requerida cuando el formulario está acoplado (coupled=true)');
78
+ return null;
79
+ }
80
+ return /* @__PURE__ */ jsx(
81
+ DynamicFormCoupled,
82
+ {
83
+ name,
84
+ value: formDataToUse,
85
+ initialValues,
86
+ validationSchema,
87
+ ownerState,
88
+ currentSize,
89
+ fieldWrapperClassName,
90
+ dataTestId,
91
+ className,
92
+ ...others
93
+ }
94
+ );
95
+ }
96
+ return /* @__PURE__ */ jsx(
97
+ DynamicFormFormProviderStyled,
98
+ {
99
+ ref: formRef,
100
+ values: initialValues,
101
+ validationSchema,
102
+ onSubmit: outputEndpoint ? handleSubmit : onSubmit,
103
+ onSubmitError,
104
+ statusLoad,
105
+ mode: "onChange",
106
+ className: clsx(className, DYNAMIC_FORM_CLASSES.root, DYNAMIC_FORM_CLASSES.formProvider),
107
+ children: formDataToUse && /* @__PURE__ */ jsx(
108
+ DynamicFormContent,
109
+ {
110
+ data: formDataToUse,
111
+ ownerState,
112
+ currentSize,
113
+ fieldWrapperClassName,
114
+ dataTestId,
115
+ coupled,
116
+ actionFormIntroProps,
117
+ renderActions
118
+ }
119
+ )
120
+ }
121
+ );
122
+ });
123
+ DynamicForm.displayName = "DynamicForm";
124
+ export {
125
+ DynamicForm as D
126
+ };
@@ -0,0 +1,2 @@
1
+ import { DynamicFormStyles } from './types';
2
+ export declare const componentStyles: DynamicFormStyles;
@@ -0,0 +1,93 @@
1
+ const componentStyles = {
2
+ /**
3
+ * Estilos para el elemento raíz del formulario dinámico.
4
+ */
5
+ root: ({ theme }) => ({
6
+ display: "flex",
7
+ flexDirection: "column",
8
+ gap: theme.vars.size.baseSpacings.sp2,
9
+ width: "100%",
10
+ "& .MuiLinearProgress-root": {
11
+ backgroundColor: theme.vars.palette.primary.opacity
12
+ }
13
+ }),
14
+ /**
15
+ * Estilos para el wrapper del RHFormProvider.
16
+ */
17
+ formProvider: () => ({
18
+ width: "100%"
19
+ }),
20
+ /**
21
+ * Estilos para el contenedor del contenido del formulario (div interno).
22
+ */
23
+ contentRoot: ({ theme }) => ({
24
+ display: "flex",
25
+ flexDirection: "column",
26
+ gap: theme.vars.size.baseSpacings.sp2,
27
+ width: "100%",
28
+ padding: theme.vars.size.baseSpacings.sp2,
29
+ border: `1px solid ${theme.vars.palette.border.default}`,
30
+ borderRadius: theme.vars.size.borderRadius.r1
31
+ }),
32
+ /**
33
+ * Estilos para el wrapper de cada campo del formulario.
34
+ */
35
+ fieldWrapper: ({ theme, ownerState }) => {
36
+ const ownerStateTyped = ownerState;
37
+ return {
38
+ display: "flex",
39
+ flexDirection: "column",
40
+ gap: theme.vars.size.baseSpacings.sp1,
41
+ width: "100%",
42
+ ...ownerStateTyped?.readOnly && {
43
+ opacity: 0.7
44
+ },
45
+ ...ownerStateTyped?.disabled && {
46
+ pointerEvents: "none",
47
+ opacity: 0.5
48
+ }
49
+ };
50
+ },
51
+ /**
52
+ * Estilos para el label de cada campo.
53
+ */
54
+ label: () => ({
55
+ width: "100%"
56
+ }),
57
+ /**
58
+ * Estilos para el control (input) de cada campo.
59
+ */
60
+ control: () => ({
61
+ width: "100%"
62
+ }),
63
+ /**
64
+ * Estilos para el helper text de cada campo.
65
+ */
66
+ helperText: () => ({
67
+ width: "100%"
68
+ }),
69
+ /**
70
+ * Estilos para el divisor de sección (si se necesita en el futuro).
71
+ */
72
+ sectionDivider: ({ theme }) => ({
73
+ width: "100%",
74
+ height: theme.vars.size.borderStroke.container,
75
+ backgroundColor: theme.vars.palette.border.main,
76
+ marginTop: theme.vars.size.baseSpacings.sp2,
77
+ marginBottom: theme.vars.size.baseSpacings.sp2
78
+ }),
79
+ /**
80
+ * Estilos para el wrapper del CheckableList que proporciona altura definida.
81
+ */
82
+ checkableListWrapper: () => ({
83
+ width: "100%",
84
+ height: "400px",
85
+ // Altura fija para que el CheckableList pueda calcular su contenedor
86
+ minHeight: "400px",
87
+ display: "flex",
88
+ flexDirection: "column"
89
+ })
90
+ };
91
+ export {
92
+ componentStyles as c
93
+ };
@@ -0,0 +1,14 @@
1
+ import { DynamicFormApiResponse } from './types';
2
+ /**
3
+ * Clave de identificación del componente dentro del sistema.
4
+ *
5
+ * Esta constante se utiliza como identificador único para asociar y personalizar estilos
6
+ * y configuraciones relacionadas con el componente dentro del sistema de temas y estilos.
7
+ * @default 'M4LDynamicForm'
8
+ */
9
+ export declare const DYNAMIC_FORM_KEY_COMPONENT = "M4LDynamicForm";
10
+ /**
11
+ * Inventario de clases CSS para el componente
12
+ */
13
+ export declare const DYNAMIC_FORM_CLASSES: Record<"label" | "root" | "control" | "helperText" | "formProvider" | "contentRoot" | "fieldWrapper" | "sectionDivider" | "checkableListWrapper", string>;
14
+ export declare const EMPTY_DATA: DynamicFormApiResponse;
@@ -0,0 +1,18 @@
1
+ import { g as getComponentClasses } from "../../utils/getComponentSlotRoot.js";
2
+ import { D as DynamicFormSlots } from "./slots/DynamicFormEnum.js";
3
+ const DYNAMIC_FORM_KEY_COMPONENT = "M4LDynamicForm";
4
+ const DYNAMIC_FORM_CLASSES = getComponentClasses(
5
+ DYNAMIC_FORM_KEY_COMPONENT,
6
+ DynamicFormSlots
7
+ );
8
+ const EMPTY_DATA = {
9
+ form: { id: 0, name: "", version: 0, nameDictionaryId: 0, descriptionDictionaryId: 0 },
10
+ fields: [],
11
+ instance: { id: 0, name: null, createdAt: "", updatedAt: "", resourceTypeId: "", resourceSerialId: "" },
12
+ conditionalRules: []
13
+ };
14
+ export {
15
+ DYNAMIC_FORM_CLASSES as D,
16
+ EMPTY_DATA as E,
17
+ DYNAMIC_FORM_KEY_COMPONENT as a
18
+ };
@@ -0,0 +1,15 @@
1
+ import { Field, FieldValidation } from '../types';
2
+ import * as Yup from 'yup';
3
+ /**
4
+ * Normaliza una validación para soportar tanto `validationType` como `type`.
5
+ * El JSON puede venir inconsistente, por lo que este helper unifica el formato.
6
+ * @param validation - Validación del campo
7
+ * @returns Validación normalizada con `validationType` siempre presente
8
+ */
9
+ export declare function normalizeValidation(validation: FieldValidation): FieldValidation;
10
+ /**
11
+ * Crea las reglas de validación de Yup para un campo específico.
12
+ * @param field - Campo del formulario
13
+ * @returns Schema de Yup para el campo o undefined si no hay validaciones ni es requerido
14
+ */
15
+ export declare function createFieldValidationSchema(field: Field): Yup.StringSchema | Yup.NumberSchema | Yup.BooleanSchema | Yup.ArraySchema<any, any, any, any> | undefined;
@@ -0,0 +1,192 @@
1
+ import * as Yup from "yup";
2
+ function normalizeValidation(validation) {
3
+ if (validation.validationType) {
4
+ return validation;
5
+ }
6
+ if (validation.type) {
7
+ return {
8
+ ...validation,
9
+ validationType: validation.type
10
+ };
11
+ }
12
+ return validation;
13
+ }
14
+ function createFieldValidationSchema(field) {
15
+ if ((!field.validations || field.validations.length === 0) && !field.isRequired) {
16
+ return void 0;
17
+ }
18
+ let baseSchema;
19
+ const fieldType = field.fieldType.id;
20
+ const rhfComponent = field.fieldType.rhfComponent;
21
+ if (rhfComponent === "RHFCheckableList" || rhfComponent === "RHFDaysOfWeekPicker") {
22
+ baseSchema = Yup.array().of(Yup.mixed());
23
+ } else if (fieldType === "fft_number" || fieldType === "fft_integer" || fieldType === "fft_double") {
24
+ baseSchema = Yup.number();
25
+ } else if (fieldType === "fft_boolean" || fieldType === "fft_checkbox") {
26
+ baseSchema = Yup.boolean();
27
+ } else {
28
+ baseSchema = Yup.string();
29
+ }
30
+ const activeValidations = field.validations ? field.validations.filter((v) => v.isActive).map(normalizeValidation).sort((a, b) => a.displayOrder - b.displayOrder) : [];
31
+ let schema = baseSchema;
32
+ activeValidations.forEach((validation) => {
33
+ const validationType = validation.validationType || validation.type;
34
+ if (!validationType) {
35
+ return;
36
+ }
37
+ switch (validationType.id) {
38
+ case "fvl_required":
39
+ if (field.isRequired) {
40
+ if (baseSchema instanceof Yup.StringSchema) {
41
+ schema = schema.nullable().required(validation.errorMessage || "Este campo es requerido");
42
+ } else if (baseSchema instanceof Yup.NumberSchema) {
43
+ schema = schema.required(validation.errorMessage || "Este campo es requerido");
44
+ } else if (baseSchema instanceof Yup.ArraySchema) {
45
+ schema = schema.min(1, validation.errorMessage || "Este campo es requerido");
46
+ } else {
47
+ schema = schema.required(validation.errorMessage || "Este campo es requerido");
48
+ }
49
+ }
50
+ break;
51
+ /**
52
+ * Validación de longitud máxima.
53
+ */
54
+ case "fvl_max_length":
55
+ if (validationType.requiresValue && validation.value && baseSchema instanceof Yup.StringSchema) {
56
+ const maxLength = parseInt(validation.value, 10);
57
+ if (!isNaN(maxLength)) {
58
+ schema = schema.max(maxLength, validation.errorMessage || `Máximo ${maxLength} caracteres`);
59
+ }
60
+ }
61
+ break;
62
+ case "fvl_min_length":
63
+ if (validationType.requiresValue && validation.value && baseSchema instanceof Yup.StringSchema) {
64
+ const minLength = parseInt(validation.value, 10);
65
+ if (!isNaN(minLength)) {
66
+ schema = schema.min(minLength, validation.errorMessage || `Mínimo ${minLength} caracteres`);
67
+ }
68
+ }
69
+ break;
70
+ case "fvl_max":
71
+ if (validationType.requiresValue && validation.value && baseSchema instanceof Yup.NumberSchema) {
72
+ const maxValue = parseFloat(validation.value);
73
+ if (!isNaN(maxValue)) {
74
+ schema = schema.max(maxValue, validation.errorMessage || `El valor máximo es ${maxValue}`);
75
+ }
76
+ }
77
+ break;
78
+ case "fvl_min":
79
+ if (validationType.requiresValue && validation.value && baseSchema instanceof Yup.NumberSchema) {
80
+ const minValue = parseFloat(validation.value);
81
+ if (!isNaN(minValue)) {
82
+ schema = schema.min(minValue, validation.errorMessage || `El valor mínimo es ${minValue}`);
83
+ }
84
+ }
85
+ break;
86
+ case "fvl_email":
87
+ if (baseSchema instanceof Yup.StringSchema) {
88
+ schema = schema.email(validation.errorMessage || "Debe ser un email válido");
89
+ }
90
+ break;
91
+ case "fvl_url":
92
+ if (baseSchema instanceof Yup.StringSchema) {
93
+ schema = schema.url(validation.errorMessage || "Debe ser una URL válida");
94
+ }
95
+ break;
96
+ case "fvl_pattern":
97
+ if (validationType.requiresValue && validation.value && baseSchema instanceof Yup.StringSchema) {
98
+ try {
99
+ const regex = new RegExp(validation.value);
100
+ schema = schema.matches(regex, validation.errorMessage || "El formato no es válido");
101
+ } catch (e) {
102
+ console.warn(`Patrón regex inválido: ${validation.value}`, e);
103
+ }
104
+ }
105
+ break;
106
+ /**
107
+ * Validación personalizada (custom).
108
+ * Permite implementar validaciones específicas usando una función de test.
109
+ * El valor de la validación puede contener:
110
+ * - Una expresión regular para validar strings
111
+ * - Un valor de comparación para números
112
+ * - Una función de validación personalizada (si se extiende el sistema)
113
+ */
114
+ case "fvl_custom":
115
+ if (validationType.requiresValue && validation.value) {
116
+ if (baseSchema instanceof Yup.StringSchema) {
117
+ schema = schema.test(
118
+ "custom",
119
+ validation.errorMessage || "El valor no cumple con la validación personalizada",
120
+ (value) => {
121
+ if (!value) {
122
+ return true;
123
+ }
124
+ try {
125
+ const regex = new RegExp(validation.value);
126
+ return regex.test(value);
127
+ } catch {
128
+ return value === validation.value;
129
+ }
130
+ }
131
+ );
132
+ } else if (baseSchema instanceof Yup.NumberSchema) {
133
+ schema = schema.test(
134
+ "custom",
135
+ validation.errorMessage || "El valor no cumple con la validación personalizada",
136
+ (value) => {
137
+ if (value === void 0 || value === null) {
138
+ return true;
139
+ }
140
+ const customValue = parseFloat(validation.value);
141
+ if (!isNaN(customValue)) {
142
+ return value === customValue;
143
+ }
144
+ return true;
145
+ }
146
+ );
147
+ }
148
+ } else {
149
+ if (baseSchema instanceof Yup.StringSchema) {
150
+ schema = schema.test(
151
+ "custom",
152
+ validation.errorMessage || "El valor no cumple con la validación personalizada",
153
+ (value) => {
154
+ if (!value) {
155
+ return true;
156
+ }
157
+ return true;
158
+ }
159
+ );
160
+ }
161
+ }
162
+ break;
163
+ default:
164
+ console.warn(`Tipo de validación no soportado: ${validationType.id}`);
165
+ }
166
+ });
167
+ if (field.isRequired && !activeValidations.some((v) => {
168
+ const vt = v.validationType || v.type;
169
+ return vt?.id === "fvl_required";
170
+ })) {
171
+ if (baseSchema instanceof Yup.StringSchema) {
172
+ schema = schema.nullable().required("Este campo es requerido");
173
+ } else if (baseSchema instanceof Yup.NumberSchema) {
174
+ schema = schema.required("Este campo es requerido");
175
+ } else if (baseSchema instanceof Yup.ArraySchema) {
176
+ schema = schema.min(1, "Este campo es requerido");
177
+ } else {
178
+ schema = schema.required("Este campo es requerido");
179
+ }
180
+ }
181
+ if (!field.isRequired) {
182
+ if (baseSchema instanceof Yup.ArraySchema) {
183
+ schema = schema.default([]);
184
+ } else {
185
+ schema = schema.nullable();
186
+ }
187
+ }
188
+ return schema;
189
+ }
190
+ export {
191
+ createFieldValidationSchema as c
192
+ };
@@ -0,0 +1,16 @@
1
+ import { ReactElement } from 'react';
2
+ import { Field } from '../types';
3
+ /**
4
+ * Resuelve el componente RHF correspondiente según el tipo de campo.
5
+ * @param field - Campo del formulario dinámico
6
+ * @param props - Props adicionales para el componente (size, disabled, etc.)
7
+ * @returns Componente RHF renderizado o null si no se encuentra el componente
8
+ */
9
+ export declare function resolveFieldComponent(field: Field, props: {
10
+ name: string;
11
+ size?: 'small' | 'medium';
12
+ disabled?: boolean;
13
+ readOnly?: boolean;
14
+ placeholder?: string | null;
15
+ rhfComponentProps?: Record<string, unknown>;
16
+ }): ReactElement | null;
@@ -0,0 +1,118 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { R as RHFDaysOfWeekPicker } from "../../hook-form/RHFDaysOfWeekPicker/RHFDaysOfWeekPicker.js";
3
+ import { b as DynamicFormCheckableListWrapperStyled } from "../slots/DynamicFormSlots.js";
4
+ import { R as RHFCheckableList } from "../../hook-form/RHFCheckableList/RHFCheckableList.js";
5
+ import { R as RHFCheckbox } from "../../hook-form/RHFCheckbox/RHFCheckbox.js";
6
+ import { R as RHFSelect } from "../../hook-form/RHFSelect/RHFSelect.js";
7
+ import { R as RHFNumberInput } from "../../hook-form/RHFNumberInput/RHFNumberInput.js";
8
+ import { R as RHFTextField } from "../../hook-form/RHFTextField/RHFTextField.js";
9
+ function resolveFieldComponent(field, props) {
10
+ const { name, size = "medium", disabled, readOnly, placeholder, rhfComponentProps = {} } = props;
11
+ const componentName = field.fieldType.rhfComponent;
12
+ const selectOptions = field.options.map((option) => ({
13
+ id: option.value,
14
+ label: option.name || option.value
15
+ }));
16
+ const checkableListItems = field.options.map((option) => ({
17
+ id: option.id,
18
+ label: option.name || option.value,
19
+ value: option.value
20
+ }));
21
+ switch (componentName) {
22
+ case "RHFTextField":
23
+ return /* @__PURE__ */ jsx(
24
+ RHFTextField,
25
+ {
26
+ name,
27
+ size,
28
+ label: field.name,
29
+ mandatory: field.isRequired,
30
+ helperMessage: field.helperText || "",
31
+ disabled: disabled || readOnly,
32
+ placeholder: placeholder || void 0,
33
+ ...rhfComponentProps
34
+ }
35
+ );
36
+ case "RHFSelect":
37
+ return /* @__PURE__ */ jsx(
38
+ RHFSelect,
39
+ {
40
+ name,
41
+ size,
42
+ label: field.name,
43
+ mandatory: field.isRequired,
44
+ options: selectOptions,
45
+ helperMessage: field.helperText || "",
46
+ disabled: disabled || readOnly,
47
+ placeholder: placeholder || void 0,
48
+ ...rhfComponentProps
49
+ }
50
+ );
51
+ case "RHFNumberInput":
52
+ return /* @__PURE__ */ jsx(
53
+ RHFNumberInput,
54
+ {
55
+ name,
56
+ size,
57
+ label: field.name,
58
+ mandatory: field.isRequired,
59
+ helperMessage: field.helperText || "",
60
+ disabled: disabled || readOnly,
61
+ ...rhfComponentProps
62
+ }
63
+ );
64
+ case "RHFCheckbox":
65
+ return /* @__PURE__ */ jsx(
66
+ RHFCheckbox,
67
+ {
68
+ name,
69
+ size,
70
+ label: field.name,
71
+ mandatory: field.isRequired,
72
+ helperMessage: field.helperText || "",
73
+ disabled: disabled || readOnly,
74
+ ...rhfComponentProps
75
+ }
76
+ );
77
+ case "RHFCheckableList":
78
+ const hasGroups = rhfComponentProps?.groups !== void 0 && Array.isArray(rhfComponentProps.groups) && rhfComponentProps.groups.length > 0;
79
+ const { groups: groupsFromProps, searchable: searchableFromProps, ...otherRHFProps } = rhfComponentProps || {};
80
+ const searchable = searchableFromProps !== void 0 && searchableFromProps !== null ? Boolean(searchableFromProps) : hasGroups;
81
+ return /* @__PURE__ */ jsx(DynamicFormCheckableListWrapperStyled, { children: /* @__PURE__ */ jsx(
82
+ RHFCheckableList,
83
+ {
84
+ name,
85
+ size,
86
+ label: field.name,
87
+ mandatory: field.isRequired,
88
+ items: hasGroups ? void 0 : checkableListItems,
89
+ groups: hasGroups ? groupsFromProps : void 0,
90
+ helperMessage: field.helperText || "",
91
+ disabled: disabled || readOnly,
92
+ searchable,
93
+ ...otherRHFProps
94
+ }
95
+ ) });
96
+ case "RHFDaysOfWeekPicker":
97
+ return (
98
+ // @ts-expect-error - value es proporcionado automáticamente por withRHFController
99
+ /* @__PURE__ */ jsx(
100
+ RHFDaysOfWeekPicker,
101
+ {
102
+ name,
103
+ size,
104
+ label: field.name,
105
+ mandatory: field.isRequired,
106
+ helperMessage: field.helperText || "",
107
+ disabled: disabled || readOnly,
108
+ ...rhfComponentProps
109
+ }
110
+ )
111
+ );
112
+ default:
113
+ return null;
114
+ }
115
+ }
116
+ export {
117
+ resolveFieldComponent as r
118
+ };
@@ -0,0 +1,14 @@
1
+ import { Field } from '../types';
2
+ /**
3
+ * Resuelve el valor inicial de un campo a partir de current_value o default_value.
4
+ *
5
+ * El componente debe resolver dinámicamente el valor según:
6
+ * - value_string
7
+ * - value_integer
8
+ * - value_double
9
+ * - value_boolean
10
+ * - value_timestamp
11
+ * @param field - Campo del formulario
12
+ * @returns Valor inicial resuelto o undefined (puede ser array para RHFCheckableList)
13
+ */
14
+ export declare function resolveInitialValue(field: Field): string | number | boolean | (string | number)[] | null | undefined;