@m4l/components 9.3.39 → 9.3.41-JT04122025.beta.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 (39) hide show
  1. package/{helpers → components/Stepper/helpers}/getStepsAndValidationSchema/getStepsAndValidationSchema.d.ts +4 -4
  2. package/{helpers → components/Stepper/helpers}/getStepsAndValidationSchema/getStepsAndValidationSchema.js +6 -12
  3. package/{helpers → components/Stepper/helpers}/getStepsAndValidationSchema/types.d.ts +6 -3
  4. package/components/Stepper/hooks/useDynamicValidation/index.d.ts +2 -1
  5. package/components/Stepper/hooks/useDynamicValidation/index.js +31 -6
  6. package/components/Stepper/index.d.ts +1 -0
  7. package/components/hook-form/RHFActionsGroup/RHFActionsGroup.js +2 -2
  8. package/components/hook-form/RHFAutocomplete/RHFAutocomplete.js +2 -2
  9. package/components/hook-form/RHFCheckbox/RHFCheckbox.js +2 -2
  10. package/components/hook-form/RHFColorPicker/RFHColorPicker.js +2 -2
  11. package/components/hook-form/RHFDatePicker/RHFDatePicker.js +2 -2
  12. package/components/hook-form/RHFDateTime/RHFDateTime.js +2 -2
  13. package/components/hook-form/RHFNumberInput/RHFNumberInput.js +2 -2
  14. package/components/hook-form/RHFPeriod/RHFPeriod.js +2 -2
  15. package/components/hook-form/RHFPeriod/subcomponents/Period/Period.js +1 -0
  16. package/components/hook-form/RHFSelect/RHFSelect.js +2 -2
  17. package/components/hook-form/RHFTextField/RHFTextField.js +2 -2
  18. package/components/hook-form/RHFTextFieldPassword/RHFTextFieldPassword.js +2 -2
  19. package/components/hook-form/RHFUpload/RHFUploadImage/RHFUploadImage.js +3 -1
  20. package/components/hook-form/RHFUpload/RHFUploadImage/subcomponents/UploadImage/UploadImage.js +4 -3
  21. package/components/hook-form/RHFUpload/RHFUploadImage/types.d.ts +4 -0
  22. package/components/hook-form/RHFUpload/RHFUploadSingleFile/RHFUploadSingleFile.js +6 -4
  23. package/components/hook-form/RHFUpload/RHFUploadSingleFile/subcomponents/Preview/Preview.js +3 -2
  24. package/components/hook-form/RHFUpload/RHFUploadSingleFile/subcomponents/Preview/types.d.ts +1 -1
  25. package/components/hook-form/RHFUpload/RHFUploadSingleFile/subcomponents/UploadSingleFile/index.js +13 -4
  26. package/components/hook-form/RHFUpload/RHFUploadSingleFile/types.d.ts +4 -0
  27. package/components/mui_extended/Tabs/Tabs.js +48 -2
  28. package/components/mui_extended/Tabs/Tabs.styles.js +52 -26
  29. package/components/mui_extended/Tabs/icons.d.ts +4 -0
  30. package/components/mui_extended/Tabs/icons.js +7 -0
  31. package/components/mui_extended/Tabs/types.d.ts +4 -1
  32. package/index.d.ts +0 -1
  33. package/index.js +24 -24
  34. package/package.json +1 -1
  35. package/helpers/index.d.ts +0 -1
  36. package/helpers/index.js +0 -1
  37. /package/{helpers → components/Stepper/helpers}/getStepsAndValidationSchema/index.d.ts +0 -0
  38. /package/{helpers → components/Stepper/helpers}/getStepsAndValidationSchema/index.js +0 -0
  39. /package/{helpers → components/Stepper/helpers}/getStepsAndValidationSchema/types.js +0 -0
@@ -1,11 +1,11 @@
1
- import { Step } from '../../components/Stepper/types';
1
+ import { Step } from '../../types';
2
2
  import { GetStepsAndValidationSchemaProps } from './types';
3
- import { RHFormValues } from '../../components/hook-form/RHFormProvider/types';
3
+ import { RHFormValues } from '../../../hook-form/RHFormProvider/types';
4
4
  /**
5
5
  * Hook personalizado que recibe un array de steps con validaciones y regresa todo listo para el Stepper
6
6
  * Una sola configuración genera: validationSchema + steps + validationFields automáticamente
7
7
  */
8
- export declare function getStepsAndValidationSchema<T extends RHFormValues>({ steps, visibilityData, }: GetStepsAndValidationSchemaProps<T>): {
9
- validationSchema: import('../../components/hook-form/RHFormProvider/types').ValidationSchema<T>;
8
+ export declare function getStepsAndValidationSchema<T extends RHFormValues>({ steps, }: GetStepsAndValidationSchemaProps<T>): {
9
+ validationSchema: import('../../../hook-form/RHFormProvider/types').ValidationSchema<T>;
10
10
  steps: Step[];
11
11
  };
@@ -1,24 +1,18 @@
1
- import { b as createValidationPartialObject, c as createValidationSchema, a as createValidationFullObject } from "../../components/hook-form/RHFormProvider/schema.js";
2
- import { e as evaluateVisibilityStepCondition } from "../../components/Stepper/helpers/evaluateVisibilityStepCondition/index.js";
1
+ import { b as createValidationPartialObject, c as createValidationSchema, a as createValidationFullObject } from "../../../hook-form/RHFormProvider/schema.js";
3
2
  function getStepsAndValidationSchema({
4
- steps,
5
- visibilityData
3
+ steps
6
4
  }) {
7
5
  const validationSchema = (() => {
8
6
  const combinedValidations = createValidationPartialObject({});
9
- const visibleSteps = steps.filter((step) => {
10
- if (!step.visibilityCondition) {
11
- return true;
12
- }
13
- return evaluateVisibilityStepCondition(step, void 0, visibilityData);
14
- });
15
- visibleSteps.forEach((step) => {
7
+ steps.forEach((step) => {
16
8
  if (step.validationFunction) {
17
9
  const validationResult = step.validationFunction();
18
10
  Object.assign(combinedValidations, validationResult);
19
11
  }
20
12
  });
21
- return createValidationSchema(createValidationFullObject(combinedValidations));
13
+ return createValidationSchema(
14
+ createValidationFullObject(combinedValidations)
15
+ );
22
16
  })();
23
17
  const processedSteps = steps.map((step) => {
24
18
  let validationFields = [];
@@ -1,5 +1,5 @@
1
- import { RHFormValues, ValidationPartialObject } from '../../components/hook-form/RHFormProvider/types';
2
- import { Step } from '../../components/Stepper/types';
1
+ import { RHFormValues, ValidationPartialObject } from '../../../hook-form/RHFormProvider/types';
2
+ import { Step } from '../../types';
3
3
  /**
4
4
  * Configuración completa de un step con validaciones incluidas
5
5
  */
@@ -16,7 +16,10 @@ export interface GetStepsAndValidationSchemaProps<T extends RHFormValues> {
16
16
  */
17
17
  steps: StepWithValidation<T>[];
18
18
  /**
19
- * Datos adicionales para visibilityCondition (ej: objectId)
19
+ * @deprecated Esta propiedad ya no se utiliza en el helper.
20
+ * El schema ahora incluye validaciones de TODOS los steps, no solo los visibles.
21
+ * visibilityData se debe pasar directamente al componente Stepper para evaluar
22
+ * visibilityCondition en tiempo real. Se eliminará en futuras versiones.
20
23
  */
21
24
  visibilityData?: any;
22
25
  }
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Hook que simula validación onChange de campos específicos del Stepper, manteniendo el formulario en modo onSubmit para preservar el rendimiento.
2
+ * Hook que simula validación onChange de campos específicos del Stepper,
3
+ * manteniendo el formulario en modo onSubmit para preservar el rendimiento.
3
4
  * @returns Objeto con funciones para manejar la validación dinámica
4
5
  */
5
6
  export declare function useDynamicValidation(): {
@@ -3,7 +3,7 @@ import { useFormContext, useWatch } from "react-hook-form";
3
3
  import { p as parseWatchedValues } from "../../helpers/parseWatchedValues/index.js";
4
4
  import { g as getInitialFieldValues } from "../../helpers/getInitialFieldValues/index.js";
5
5
  function useDynamicValidation() {
6
- const { trigger, getValues } = useFormContext();
6
+ const { trigger, getValues, clearErrors } = useFormContext();
7
7
  const [activeFields, setActiveFields] = useState([]);
8
8
  const [isValidating, setIsValidating] = useState(false);
9
9
  const statusLoad = useWatch({
@@ -13,6 +13,8 @@ function useDynamicValidation() {
13
13
  name: activeFields.length > 0 ? activeFields : ["__dummy__"]
14
14
  });
15
15
  const lastValuesRef = useRef({});
16
+ const pendingFieldsRef = useRef(/* @__PURE__ */ new Set());
17
+ const validationTimeoutRef = useRef(null);
16
18
  useEffect(() => {
17
19
  if (activeFields.length === 0 || statusLoad !== "ready" || isValidating) {
18
20
  return;
@@ -28,12 +30,30 @@ function useDynamicValidation() {
28
30
  return hasChanged;
29
31
  });
30
32
  if (changedFields.length > 0) {
31
- const timeoutId = setTimeout(() => {
32
- trigger(changedFields);
33
- }, 100);
34
- return () => clearTimeout(timeoutId);
33
+ changedFields.forEach((field) => pendingFieldsRef.current.add(field));
34
+ if (validationTimeoutRef.current) {
35
+ clearTimeout(validationTimeoutRef.current);
36
+ }
37
+ validationTimeoutRef.current = setTimeout(async () => {
38
+ const fieldsToValidate = Array.from(pendingFieldsRef.current);
39
+ pendingFieldsRef.current.clear();
40
+ validationTimeoutRef.current = null;
41
+ for (const field of fieldsToValidate) {
42
+ const isValid = await trigger(field);
43
+ if (isValid) {
44
+ clearErrors(field);
45
+ }
46
+ }
47
+ }, 150);
35
48
  }
36
- }, [activeFields, trigger, watchValues, statusLoad, isValidating]);
49
+ }, [
50
+ activeFields,
51
+ trigger,
52
+ clearErrors,
53
+ watchValues,
54
+ statusLoad,
55
+ isValidating
56
+ ]);
37
57
  const startExternalValidation = useCallback(() => {
38
58
  setIsValidating(true);
39
59
  }, []);
@@ -55,6 +75,11 @@ function useDynamicValidation() {
55
75
  const clearAllValidation = useCallback(() => {
56
76
  setActiveFields([]);
57
77
  lastValuesRef.current = {};
78
+ pendingFieldsRef.current.clear();
79
+ if (validationTimeoutRef.current) {
80
+ clearTimeout(validationTimeoutRef.current);
81
+ validationTimeoutRef.current = null;
82
+ }
58
83
  }, []);
59
84
  return {
60
85
  activateFieldsValidation,
@@ -10,5 +10,6 @@ export { StepperPrevButton } from './subcomponents/StepperButtons/StepperPrevBut
10
10
  export { StepperCancelButton } from './subcomponents/StepperButtons/StepperCancelButton';
11
11
  export { StepperSubmitButton } from './subcomponents/StepperButtons/StepperSubmitButton';
12
12
  export { evaluateVisibilityStepCondition } from './helpers/evaluateVisibilityStepCondition';
13
+ export { getStepsAndValidationSchema } from './helpers/getStepsAndValidationSchema';
13
14
  export { type Step as TypeStep } from './types';
14
15
  export { getStepperComponentsDictionary } from './dictionary';
@@ -38,7 +38,7 @@ const RHFActionsGroup = (props) => {
38
38
  {
39
39
  name,
40
40
  control,
41
- render: ({ field: { value, onChange }, fieldState: { error } }) => {
41
+ render: ({ field: { value, onChange }, fieldState: { error }, formState: { isSubmitting } }) => {
42
42
  const currentValue = value ?? null;
43
43
  return /* @__PURE__ */ jsxs(Fragment, { children: [
44
44
  label && /* @__PURE__ */ jsx(
@@ -60,7 +60,7 @@ const RHFActionsGroup = (props) => {
60
60
  actions,
61
61
  value: currentValue,
62
62
  onChange,
63
- disabled,
63
+ disabled: disabled || isSubmitting,
64
64
  ariaLabel,
65
65
  ariaLabelledBy,
66
66
  size,
@@ -73,7 +73,7 @@ function RHFAutocomplete(props) {
73
73
  {
74
74
  name: nameRHF,
75
75
  control,
76
- render: ({ field: { onChange, value }, fieldState: { error } }) => {
76
+ render: ({ field: { onChange, value }, fieldState: { error }, formState: { isSubmitting } }) => {
77
77
  const [inputValue, setInputValue] = useState(
78
78
  getOptionLabelLocal(value)
79
79
  );
@@ -113,7 +113,7 @@ function RHFAutocomplete(props) {
113
113
  },
114
114
  onChangeFilterParmsLocal,
115
115
  refresh,
116
- disabled,
116
+ disabled: disabled || isSubmitting,
117
117
  loading,
118
118
  onOpen: onOpenLocal,
119
119
  onClose: onCloseLocal,
@@ -38,7 +38,7 @@ const RHFCheckbox = forwardRef(function RHFCheckbox2(props, ref) {
38
38
  {
39
39
  name,
40
40
  control,
41
- render: ({ field: { onChange, value }, fieldState: { error } }) => {
41
+ render: ({ field: { onChange, value }, fieldState: { error }, formState: { isSubmitting } }) => {
42
42
  return /* @__PURE__ */ jsxs(Fragment, { children: [
43
43
  label && /* @__PURE__ */ jsx(
44
44
  LabelComponent,
@@ -59,7 +59,7 @@ const RHFCheckbox = forwardRef(function RHFCheckbox2(props, ref) {
59
59
  size: adjustedSize,
60
60
  onChange,
61
61
  checked: value,
62
- disabled: disabled ? true : false,
62
+ disabled: disabled || isSubmitting,
63
63
  disableRipple: true,
64
64
  inlineText,
65
65
  htmlFor: finalId,
@@ -45,7 +45,7 @@ const RHFColorPicker = (props) => {
45
45
  name,
46
46
  control,
47
47
  defaultValue: "",
48
- render: ({ field: { value, onChange }, fieldState: { error } }) => /* @__PURE__ */ jsx(
48
+ render: ({ field: { value, onChange }, fieldState: { error }, formState: { isSubmitting } }) => /* @__PURE__ */ jsx(
49
49
  ColorPickerField,
50
50
  {
51
51
  value,
@@ -56,7 +56,7 @@ const RHFColorPicker = (props) => {
56
56
  mandatory,
57
57
  mandatoryMessage,
58
58
  helperMessage,
59
- disabled,
59
+ disabled: disabled || isSubmitting,
60
60
  isSkeleton,
61
61
  className,
62
62
  instaceDataTestId,
@@ -40,7 +40,7 @@ const RHFDatePicker = (props) => {
40
40
  name,
41
41
  control,
42
42
  defaultValue: null,
43
- render: ({ field: { value, onChange }, fieldState: { error } }) => /* @__PURE__ */ jsxs(Fragment, { children: [
43
+ render: ({ field: { value, onChange }, fieldState: { error }, formState: { isSubmitting } }) => /* @__PURE__ */ jsxs(Fragment, { children: [
44
44
  label && /* @__PURE__ */ jsx(
45
45
  Label,
46
46
  {
@@ -62,7 +62,7 @@ const RHFDatePicker = (props) => {
62
62
  readOnly,
63
63
  error,
64
64
  size: currentSize,
65
- disabled,
65
+ disabled: disabled || isSubmitting,
66
66
  className
67
67
  }
68
68
  ),
@@ -43,7 +43,7 @@ function RHFDateTime(props) {
43
43
  {
44
44
  name: nameRHF,
45
45
  control,
46
- render: ({ field: { value, onChange, ref }, fieldState: { error } }) => {
46
+ render: ({ field: { value, onChange, ref }, fieldState: { error }, formState: { isSubmitting } }) => {
47
47
  return /* @__PURE__ */ jsxs(Fragment, { children: [
48
48
  label && /* @__PURE__ */ jsx(
49
49
  Label,
@@ -62,7 +62,7 @@ function RHFDateTime(props) {
62
62
  {
63
63
  variant,
64
64
  size: adjustedSize,
65
- disabled,
65
+ disabled: disabled || isSubmitting,
66
66
  inputRef: ref,
67
67
  slotProps: {
68
68
  field: {
@@ -42,7 +42,7 @@ const RHFNumberInput = (props) => {
42
42
  {
43
43
  name,
44
44
  control,
45
- render: ({ field: { value, onChange }, fieldState: { error } }) => {
45
+ render: ({ field: { value, onChange }, fieldState: { error }, formState: { isSubmitting } }) => {
46
46
  const onChangeLocal = (_event, newValue) => {
47
47
  onChange(newValue);
48
48
  };
@@ -69,7 +69,7 @@ const RHFNumberInput = (props) => {
69
69
  value,
70
70
  onChange: onChangeLocal,
71
71
  variant,
72
- disabled,
72
+ disabled: disabled || isSubmitting,
73
73
  startAdornment,
74
74
  endAdornment,
75
75
  error: !!error,
@@ -47,7 +47,7 @@ const RHFPeriod = (props) => {
47
47
  name: name || "",
48
48
  control,
49
49
  defaultValue: { selPeriodTime: "", singleValue: "" },
50
- render: ({ field: { onChange, value }, fieldState: { error } }) => {
50
+ render: ({ field: { onChange, value }, fieldState: { error }, formState: { isSubmitting } }) => {
51
51
  return /* @__PURE__ */ jsxs(Fragment, { children: [
52
52
  label && /* @__PURE__ */ jsx(
53
53
  Label,
@@ -64,7 +64,7 @@ const RHFPeriod = (props) => {
64
64
  {
65
65
  name,
66
66
  control,
67
- disabled,
67
+ disabled: disabled || isSubmitting,
68
68
  value,
69
69
  onChange,
70
70
  size
@@ -124,6 +124,7 @@ const Period = (props) => {
124
124
  variant: "outlined",
125
125
  value: singleValue,
126
126
  withDecimal: true,
127
+ disabled,
127
128
  onChange: (_event, newValue) => {
128
129
  onTotalChange(selPeriodTime, newValue);
129
130
  }
@@ -36,7 +36,7 @@ const RHFSelect = (props) => {
36
36
  {
37
37
  name,
38
38
  control,
39
- render: ({ field: { value, onChange, ref }, fieldState: { error } }) => {
39
+ render: ({ field: { value, onChange, ref }, fieldState: { error }, formState: { isSubmitting } }) => {
40
40
  const onChangeLocal = (opt) => {
41
41
  if (!opt) {
42
42
  onChange(null);
@@ -75,7 +75,7 @@ const RHFSelect = (props) => {
75
75
  variant,
76
76
  value,
77
77
  onChange: onChangeLocal,
78
- disabled,
78
+ disabled: disabled || isSubmitting,
79
79
  className: RHFSELECT_CLASSES.select,
80
80
  error: Boolean(error),
81
81
  placeholder,
@@ -60,7 +60,7 @@ const RHFTextField = forwardRef((props, ref) => {
60
60
  {
61
61
  name,
62
62
  control,
63
- render: ({ field: { onChange, value, ref: inputRef }, fieldState: { error } }) => {
63
+ render: ({ field: { onChange, value, ref: inputRef }, fieldState: { error }, formState: { isSubmitting } }) => {
64
64
  const onInternalChange = (event) => {
65
65
  const finalValue = other.maxLength ? getLimitCharacters({ limitCharacters: other.maxLength, value: event.target.value }) : event.target.value;
66
66
  const stringValue = String(finalValue || "");
@@ -83,7 +83,7 @@ const RHFTextField = forwardRef((props, ref) => {
83
83
  TextFieldStyled,
84
84
  {
85
85
  ownerState: { ...ownerState, error: !!error },
86
- disabled,
86
+ disabled: disabled || isSubmitting,
87
87
  inputRef,
88
88
  ref,
89
89
  InputLabelProps: { shrink: true },
@@ -28,7 +28,7 @@ const RHFTextFieldPassword = (props) => {
28
28
  {
29
29
  name,
30
30
  control,
31
- render: ({ field: { onChange, value, ref }, fieldState: { error } }) => {
31
+ render: ({ field: { onChange, value, ref }, fieldState: { error }, formState: { isSubmitting } }) => {
32
32
  const onInternalChange = (event) => {
33
33
  const finalValue = other.maxLength ? getLimitCharacters({ limitCharacters: other.maxLength, value: event.target.value }) : event.target.value;
34
34
  const stringValue = String(finalValue || "");
@@ -56,7 +56,7 @@ const RHFTextFieldPassword = (props) => {
56
56
  type: showPassword ? "text" : "password",
57
57
  size,
58
58
  error: !!error,
59
- disabled,
59
+ disabled: disabled || isSubmitting,
60
60
  inputProps: {
61
61
  role: "textbox",
62
62
  "aria-label": name,
@@ -15,6 +15,7 @@ function RHFUploadImage(props) {
15
15
  mandatoryMessage,
16
16
  maxSize,
17
17
  helperMessage,
18
+ disabled,
18
19
  ...other
19
20
  } = props;
20
21
  const { currentSize } = useComponentSize(size);
@@ -25,7 +26,7 @@ function RHFUploadImage(props) {
25
26
  {
26
27
  name,
27
28
  control,
28
- render: ({ field: { value, onChange }, fieldState: { error } }) => {
29
+ render: ({ field: { value, onChange }, fieldState: { error }, formState: { isSubmitting } }) => {
29
30
  const checkError = !!error && !value;
30
31
  return /* @__PURE__ */ jsxs(Fragment, { children: [
31
32
  label && /* @__PURE__ */ jsx(
@@ -56,6 +57,7 @@ function RHFUploadImage(props) {
56
57
  onChange(null);
57
58
  },
58
59
  error: checkError,
60
+ disabled: disabled || isSubmitting,
59
61
  ...other,
60
62
  file: value,
61
63
  size: adjustedSize,
@@ -12,7 +12,7 @@ import { u as useComponentSize } from "../../../../../../hooks/useComponentSize/
12
12
  import { g as getComponentClasses } from "../../../../../../utils/getComponentSlotRoot.js";
13
13
  import { T as Typography } from "../../../../../mui_extended/Typography/Typography.js";
14
14
  const UploadImage = (props) => {
15
- const { file, size, onDrop, onRemove, maxSize, dataTestId, error = false, multiple, ...other } = props;
15
+ const { file, size, onDrop, onRemove, maxSize, dataTestId, error = false, multiple, disabled, ...other } = props;
16
16
  const { currentSize } = useComponentSize(size);
17
17
  const { toast } = useHostTools();
18
18
  const adjustedSize = currentSize === "small" || currentSize === "medium" ? currentSize : "medium";
@@ -62,7 +62,8 @@ const UploadImage = (props) => {
62
62
  variant: "contained",
63
63
  icon: `${host_static_assets}/${environment_assets}/frontend/components/chip/assets/icons/closeSmall.svg`,
64
64
  onClick: onRemove,
65
- size: adjustedSize
65
+ size: adjustedSize,
66
+ disabled
66
67
  }
67
68
  ),
68
69
  /* @__PURE__ */ jsx(
@@ -100,7 +101,7 @@ const UploadImage = (props) => {
100
101
  ] })
101
102
  ] })
102
103
  ] }),
103
- !file ? /* @__PURE__ */ jsx(ButtonStyled, { variant: "contained", color: "primary", onClick: open, label: getLabel(getUploadImageDictionary(COMPONENTS_DICTIONARY_KEYS.click_button)), size: adjustedSize }) : null
104
+ !file ? /* @__PURE__ */ jsx(ButtonStyled, { variant: "contained", color: "primary", onClick: open, label: getLabel(getUploadImageDictionary(COMPONENTS_DICTIONARY_KEYS.click_button)), size: adjustedSize, disabled }) : null
104
105
  ]
105
106
  }
106
107
  )
@@ -6,6 +6,10 @@ import { UploadImageProps } from './subcomponents/UploadImage/types';
6
6
  import { M4LOverridesStyleRules } from '../../../../@types/augmentations';
7
7
  export interface RHFUploadImageProps extends Omit<UploadImageProps, 'file' | 'onDrop' | 'onRemove'>, Omit<LabelProps, 'size' | 'error' | 'disabled' | 'children'> {
8
8
  name: string;
9
+ /**
10
+ * Si es true, el componente estará deshabilitado.
11
+ */
12
+ disabled?: boolean;
9
13
  }
10
14
  export type RHFUploadImageSlotsType = keyof typeof Slots;
11
15
  export type RHFUploadImageOwnerState = {
@@ -9,7 +9,7 @@ import { R as RHFUploadSingleFileSlots } from "./slots/RHFUploadSingleFileEnum.j
9
9
  import { u as useComponentSize } from "../../../../hooks/useComponentSize/useComponentSize.js";
10
10
  function RHFUploadSingleFile(props) {
11
11
  const { control } = useFormContext();
12
- const { name, label, skeletonWidth, size, className, helperMessage, mandatory, mandatoryMessage, maxFileSize = DEFAULT_MAX_FILE_SIZE, dataTestId, accept = "*/*" } = props;
12
+ const { name, label, skeletonWidth, size, className, helperMessage, mandatory, mandatoryMessage, maxFileSize = DEFAULT_MAX_FILE_SIZE, dataTestId, accept = "*/*", disabled } = props;
13
13
  const { currentSize } = useComponentSize(size);
14
14
  const adjustedSize = currentSize === "small" || currentSize === "medium" ? currentSize : "medium";
15
15
  const acceptObj = {
@@ -28,7 +28,7 @@ function RHFUploadSingleFile(props) {
28
28
  {
29
29
  name,
30
30
  control,
31
- render: ({ field: { value, onChange }, fieldState: { error } }) => {
31
+ render: ({ field: { value, onChange }, fieldState: { error }, formState: { isSubmitting } }) => {
32
32
  const errorUpload = !!error;
33
33
  return /* @__PURE__ */ jsxs(Fragment, { children: [
34
34
  label && /* @__PURE__ */ jsx(
@@ -41,7 +41,8 @@ function RHFUploadSingleFile(props) {
41
41
  mandatoryMessage,
42
42
  helperMessage,
43
43
  size: adjustedSize,
44
- skeletonWidth
44
+ skeletonWidth,
45
+ disabled
45
46
  }
46
47
  ),
47
48
  /* @__PURE__ */ jsx(
@@ -51,7 +52,8 @@ function RHFUploadSingleFile(props) {
51
52
  accept: acceptObj,
52
53
  file: value,
53
54
  onChange,
54
- size: adjustedSize
55
+ size: adjustedSize,
56
+ disabled: disabled || isSubmitting
55
57
  }
56
58
  ),
57
59
  errorUpload && /* @__PURE__ */ jsx(
@@ -4,7 +4,7 @@ import { d as ContainerPreviewStyled, e as ImagePreviewStyled, f as ContainerNam
4
4
  import { useEnvironment } from "@m4l/core";
5
5
  import { f as formatFileSize } from "../../helpers/formatFileSize.js";
6
6
  const Preview = (props) => {
7
- const { file, onChange, onClose } = props;
7
+ const { file, onChange, onClose, disabled } = props;
8
8
  const { host_static_assets, environment_assets } = useEnvironment();
9
9
  const icon = `${host_static_assets}/${environment_assets}/${FILES_ICONS[file.type] || FILES_ICONS["application/octet-stream"]}`;
10
10
  const closePreviewIcon = `${host_static_assets}/${environment_assets}/${CLOSE_PREVIEW_ICON}`;
@@ -25,7 +25,8 @@ const Preview = (props) => {
25
25
  e.stopPropagation();
26
26
  onChange && onChange(null);
27
27
  onClose();
28
- }
28
+ },
29
+ disabled
29
30
  }
30
31
  )
31
32
  ] });
@@ -1,5 +1,5 @@
1
1
  import { UploadSingleFileProps } from '../UploadSingleFile/types';
2
- export interface PreviewProps extends Pick<UploadSingleFileProps, 'onChange' | 'size'> {
2
+ export interface PreviewProps extends Pick<UploadSingleFileProps, 'onChange' | 'size' | 'disabled'> {
3
3
  uploadProgress: number | null;
4
4
  file: File;
5
5
  onClose: () => void;
@@ -11,7 +11,7 @@ import { u as uploadReducer } from "../../helpers/uploadReducer.js";
11
11
  import { f as formatFileSize } from "../../helpers/formatFileSize.js";
12
12
  import { g as getReadableFileType } from "../../helpers/getReadableFileType.js";
13
13
  function UploadSingleFile(props) {
14
- const { file, accept, onChange, maxFileSize, size } = props;
14
+ const { file, accept, onChange, maxFileSize, size, disabled } = props;
15
15
  const { toast } = useHostTools();
16
16
  const { getLabel } = useModuleDictionary();
17
17
  const isSkeleton = useModuleSkeleton();
@@ -22,6 +22,7 @@ function UploadSingleFile(props) {
22
22
  });
23
23
  const { getRootProps, getInputProps } = useDropzone({
24
24
  multiple: false,
25
+ disabled,
25
26
  /**
26
27
  * Maneja el evento de drop del archivo
27
28
  */
@@ -60,9 +61,17 @@ function UploadSingleFile(props) {
60
61
  }
61
62
  }
62
63
  });
64
+ useEffect(() => {
65
+ if (!!file && !uploadState.validFile) {
66
+ dispatch({ type: "SET_VALID_FILE", payload: true });
67
+ dispatch({ type: "SET_PREVIEW", payload: true });
68
+ } else if (!file && uploadState.validFile) {
69
+ dispatch({ type: "RESET" });
70
+ }
71
+ }, [file, uploadState.validFile]);
63
72
  useEffect(() => {
64
73
  let interval;
65
- if (uploadState.validFile && !!file) {
74
+ if (!!file && uploadState.validFile && !uploadState.preview) {
66
75
  interval = setInterval(() => {
67
76
  dispatch({ type: "SET_PROGRESS", payload: (uploadState.progress ?? 0) + 10 });
68
77
  if (uploadState.progress !== null && uploadState.progress >= 100) {
@@ -77,10 +86,10 @@ function UploadSingleFile(props) {
77
86
  clearInterval(interval);
78
87
  }
79
88
  };
80
- }, [file, uploadState.progress, uploadState.validFile]);
89
+ }, [file, uploadState.progress, uploadState.validFile, uploadState.preview]);
81
90
  return /* @__PURE__ */ jsx(ContainerDropZoneStyled, { ownerState: {}, className: RHF_UPLOAD_SINGLE_FILE_CLASSES.containerDropZone, children: /* @__PURE__ */ jsxs(DropZoneStyled, { ...getRootProps(), ownerState: { isSkeleton }, className: RHF_UPLOAD_SINGLE_FILE_CLASSES.dropZone, children: [
82
91
  /* @__PURE__ */ jsx(BlockContent, { value: uploadState.progress, hidden: uploadState.preview, size }),
83
- uploadState.preview && !!file && /* @__PURE__ */ jsx(Preview, { uploadProgress: uploadState.progress, file, onChange, onClose: () => dispatch({ type: "RESET" }), size }),
92
+ uploadState.preview && !!file && /* @__PURE__ */ jsx(Preview, { uploadProgress: uploadState.progress, file, onChange, onClose: () => dispatch({ type: "RESET" }), size, disabled }),
84
93
  !isSkeleton && /* @__PURE__ */ jsx("input", { role: "button", "aria-label": "button-upload-single-file", ...getInputProps() })
85
94
  ] }) });
86
95
  }
@@ -33,6 +33,10 @@ export interface RHFUploadSingleFileProps extends Omit<LabelProps, 'size' | 'err
33
33
  * Tipos de archivos aceptados.
34
34
  */
35
35
  accept?: string;
36
+ /**
37
+ * Si es true, el componente estará deshabilitado.
38
+ */
39
+ disabled?: boolean;
36
40
  }
37
41
  export type RHFUploadSingleFileSlotsType = keyof typeof RHFUploadSingleFileSlots;
38
42
  export type RHFUploadSingleFileOwnerState = Pick<RHFUploadSingleFileProps, 'size' | 'variant'> & {
@@ -1,9 +1,55 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
2
  import { R as RootStyled } from "./slots/TabsSlots.js";
3
+ import { useEnvironment } from "@m4l/core";
4
+ import { T as TABS_ICONS } from "./icons.js";
5
+ import React, { useMemo } from "react";
6
+ import { u as useComponentSize } from "../../../hooks/useComponentSize/useComponentSize.js";
7
+ import { I as IconButton } from "../IconButton/IconButton.js";
8
+ const createScrollButtonIcon = (src, size) => {
9
+ const ScrollButtonIconComponent = React.forwardRef(
10
+ (props, _ref) => {
11
+ const { fontSize, ownerState, ...otherProps } = props;
12
+ const finalProps = {
13
+ src,
14
+ size,
15
+ ...otherProps
16
+ };
17
+ return /* @__PURE__ */ jsx(IconButton, { ...finalProps });
18
+ }
19
+ );
20
+ ScrollButtonIconComponent.displayName = "ScrollButtonIcon";
21
+ return ScrollButtonIconComponent;
22
+ };
3
23
  const Tabs = (props) => {
4
- const { children, className, ...others } = props;
24
+ const { children, className, size, ...others } = props;
5
25
  const ownerState = {};
6
- return /* @__PURE__ */ jsx(RootStyled, { ownerState: { ownerState }, ...others, children });
26
+ const { currentSize } = useComponentSize(size);
27
+ const { host_static_assets, environment_assets } = useEnvironment();
28
+ const leftIconSrc = `${host_static_assets}/${environment_assets}/${TABS_ICONS.ARROW_LEFT}`;
29
+ const rightIconSrc = `${host_static_assets}/${environment_assets}/${TABS_ICONS.ARROW_RIGHT}`;
30
+ const StartScrollButtonIcon = useMemo(
31
+ () => createScrollButtonIcon(leftIconSrc, currentSize),
32
+ [leftIconSrc, currentSize]
33
+ );
34
+ const EndScrollButtonIcon = useMemo(
35
+ () => createScrollButtonIcon(rightIconSrc, currentSize),
36
+ [rightIconSrc, currentSize]
37
+ );
38
+ return /* @__PURE__ */ jsx(
39
+ RootStyled,
40
+ {
41
+ ...others,
42
+ scrollButtons: "auto",
43
+ ownerState: { ownerState },
44
+ variant: "scrollable",
45
+ className,
46
+ slots: {
47
+ StartScrollButtonIcon,
48
+ EndScrollButtonIcon
49
+ },
50
+ children
51
+ }
52
+ );
7
53
  };
8
54
  export {
9
55
  Tabs as T
@@ -3,33 +3,59 @@ const tabsStyles = {
3
3
  * Elemento root referencia a `MuiTabs` de MUI
4
4
  */
5
5
  root: ({ theme }) => ({
6
- position: "relative",
7
- zIndex: 1,
8
- display: "flex",
9
- overflow: "auto",
10
- width: "100%",
11
- height: "fit-content",
12
- maxWidth: "fit-content",
13
- minHeight: "fit-content",
14
- background: theme.vars.palette.background.default,
15
- paddingBottom: theme.vars.size.baseSpacings.sp0,
16
- gap: theme.vars.size.baseSpacings.sp0,
17
- borderRadius: theme.vars.size.borderRadius.r1,
18
- borderBottomLeftRadius: theme.vars.size.borderRadius.r0,
19
- borderBottomRightRadius: theme.vars.size.borderRadius.r0,
20
- marginBottom: "1px",
21
- "& .MuiTabs-flexContainer": {
22
- background: "transparent"
23
- },
24
- "& .MuiTabs-scroller": {
25
- overflow: "visible !important"
26
- },
27
- "& .MuiTabs-indicator": {
28
- display: "none"
29
- },
30
- "& .simplebar-content": {
6
+ "&&&": {
7
+ position: "relative",
8
+ zIndex: 1,
31
9
  display: "flex",
32
- gap: theme.vars.size.baseSpacings.sp0
10
+ overflow: "auto",
11
+ alignItems: "center",
12
+ width: "100%",
13
+ height: "fit-content",
14
+ maxWidth: "fit-content",
15
+ minHeight: "fit-content",
16
+ gap: theme.vars.size.baseSpacings.sp4,
17
+ background: theme.vars.palette.background.default,
18
+ paddingBottom: theme.vars.size.baseSpacings.sp0,
19
+ borderRadius: theme.vars.size.borderRadius.r1,
20
+ borderBottomLeftRadius: theme.vars.size.borderRadius.r0,
21
+ borderBottomRightRadius: theme.vars.size.borderRadius.r0,
22
+ marginBottom: "1px",
23
+ "& .MuiTabs-flexContainer": {
24
+ background: "transparent"
25
+ },
26
+ "& .MuiTabs-indicator": {
27
+ display: "none"
28
+ },
29
+ "& .simplebar-content": {
30
+ display: "flex",
31
+ gap: theme.vars.size.baseSpacings.sp0
32
+ },
33
+ "& .MuiTabScrollButton-root": {
34
+ width: "fit-content",
35
+ height: "fit-content",
36
+ padding: "0",
37
+ margin: "0",
38
+ border: "none",
39
+ borderRadius: "0",
40
+ "& .MuiTouchRipple-root": {
41
+ display: "none !important"
42
+ },
43
+ "& .MuiButtonBase-ripple": {
44
+ display: "none !important"
45
+ },
46
+ "& .MuiTouchRipple-ripple": {
47
+ display: "none !important"
48
+ },
49
+ "& .MuiTouchRipple-rippleVisible": {
50
+ display: "none !important"
51
+ },
52
+ "& .M4LIconButton-styledMUIIconButton, & .MuiSkeleton-root": {
53
+ width: theme.vars.size.baseSpacings.sp4,
54
+ "& .M4LIcon-icon": {
55
+ backgroundColor: theme.vars.palette.text.primary
56
+ }
57
+ }
58
+ }
33
59
  }
34
60
  })
35
61
  };
@@ -0,0 +1,4 @@
1
+ export declare const TABS_ICONS: {
2
+ ARROW_LEFT: string;
3
+ ARROW_RIGHT: string;
4
+ };
@@ -0,0 +1,7 @@
1
+ const TABS_ICONS = {
2
+ ARROW_LEFT: "frontend/components/tabs/assets/icons/chevron_left.svg",
3
+ ARROW_RIGHT: "frontend/components/tabs/assets/icons/chevron_right.svg"
4
+ };
5
+ export {
6
+ TABS_ICONS as T
7
+ };
@@ -3,10 +3,13 @@ import { TabsProps as MuiTabProps } from '@mui/material/Tabs';
3
3
  import { TabsSlots } from './slots/TabsEnum';
4
4
  import { TABS_KEY_COMPONENT } from './constants';
5
5
  import { Theme } from '@mui/material';
6
+ import { Sizes } from '@m4l/styles';
6
7
  /**
7
8
  * Props for the tabs component.
8
9
  */
9
- export type TabsProps = MuiTabProps;
10
+ export type TabsProps = MuiTabProps & {
11
+ size?: Extract<Sizes, 'small' | 'medium'>;
12
+ };
10
13
  /**
11
14
  * State for the tabs component.
12
15
  */
package/index.d.ts CHANGED
@@ -8,5 +8,4 @@ export * from './hooks';
8
8
  export * from './@types/export.d';
9
9
  export * from './@types/types.d';
10
10
  export * from './utils';
11
- export * from './helpers';
12
11
  export type { M4LOverridesStyleRules } from './@types/augmentations';
package/index.js CHANGED
@@ -230,15 +230,16 @@ import { S as S18 } from "./components/Stepper/subcomponents/StepperButtons/Step
230
230
  import { S as S19 } from "./components/Stepper/subcomponents/StepperButtons/StepperCancelButton/index.js";
231
231
  import { S as S20 } from "./components/Stepper/subcomponents/StepperButtons/StepperSubmitButton/index.js";
232
232
  import { e as e2 } from "./components/Stepper/helpers/evaluateVisibilityStepCondition/index.js";
233
- import { g as g30 } from "./components/Stepper/dictionary.js";
234
- import { g as g31 } from "./components/hook-form/RHFormProvider/dictionary.js";
233
+ import { g as g30 } from "./components/Stepper/helpers/getStepsAndValidationSchema/getStepsAndValidationSchema.js";
234
+ import { g as g31 } from "./components/Stepper/dictionary.js";
235
+ import { g as g32 } from "./components/hook-form/RHFormProvider/dictionary.js";
235
236
  import { u as u23 } from "./contexts/AppearanceComponentContext/useAppearanceComponentStore.js";
236
237
  import { A as A17 } from "./contexts/AppearanceComponentContext/AppearanceComponentContext.js";
237
238
  import { a as a17, M as M10 } from "./contexts/ModalContext/index.js";
238
239
  import { u as u24 } from "./hooks/useFormAddEdit/useFormAddEdit.js";
239
240
  import { u as u25 } from "./hooks/useModal/index.js";
240
241
  import { u as u26 } from "./hooks/useTab/index.js";
241
- import { g as g32 } from "./hooks/useFormAddEdit/dictionary.js";
242
+ import { g as g33 } from "./hooks/useFormAddEdit/dictionary.js";
242
243
  import { u as u27 } from "./hooks/useFormFocus/index.js";
243
244
  import { u as u28 } from "./hooks/useInterval/index.js";
244
245
  import { u as u29 } from "./hooks/useComponentSize/useComponentSize.js";
@@ -254,18 +255,17 @@ import { u as u37 } from "./hooks/useSizeContainer/index.js";
254
255
  import { u as u38 } from "./hooks/useWatchTyped/useTypedWatch.js";
255
256
  import { c as c5 } from "./utils/capitalizeFirstLetter.js";
256
257
  import { i as i2 } from "./utils/isValidDate.js";
257
- import { g as g33 } from "./utils/getComponentUtilityClass.js";
258
- import { g as g34 } from "./utils/getPaletteColor.js";
259
- import { g as g35 } from "./utils/getTypographyStyles.js";
260
- import { g as g36 } from "./utils/getIconColor.js";
261
- import { a as a18, g as g37 } from "./utils/getSizeStyles/getSizeStyles.js";
258
+ import { g as g34 } from "./utils/getComponentUtilityClass.js";
259
+ import { g as g35 } from "./utils/getPaletteColor.js";
260
+ import { g as g36 } from "./utils/getTypographyStyles.js";
261
+ import { g as g37 } from "./utils/getIconColor.js";
262
+ import { a as a18, g as g38 } from "./utils/getSizeStyles/getSizeStyles.js";
262
263
  import { O as O2 } from "./utils/ObjectQueue.js";
263
- import { g as g38, a as a19 } from "./utils/getComponentSlotRoot.js";
264
+ import { g as g39, a as a19 } from "./utils/getComponentSlotRoot.js";
264
265
  import { f as f2 } from "./utils/formatDistanceToNow/formatDistanteToNow.js";
265
- import { g as g39 } from "./utils/getValidDate.js";
266
- import { g as g40 } from "./utils/getNullGuard.js";
266
+ import { g as g40 } from "./utils/getValidDate.js";
267
+ import { g as g41 } from "./utils/getNullGuard.js";
267
268
  import { c as c6, d as d5 } from "./utils/deepShallow.js";
268
- import { g as g41 } from "./helpers/getStepsAndValidationSchema/getStepsAndValidationSchema.js";
269
269
  export {
270
270
  A8 as AREAS_DICCTIONARY,
271
271
  a3 as AREAS_DICTIONARY_ID,
@@ -487,23 +487,23 @@ export {
487
487
  b2 as getAreasComponentsDictionary,
488
488
  g3 as getAreasDictionary,
489
489
  g4 as getCommonActionsDictionary,
490
- g38 as getComponentClasses,
490
+ g39 as getComponentClasses,
491
491
  a19 as getComponentSlotRoot,
492
- g33 as getComponentUtilityClass,
492
+ g34 as getComponentUtilityClass,
493
493
  g5 as getDataGridComponentsDictionary,
494
494
  g6 as getDataGridRowsFromSet,
495
495
  g17 as getDistanceToNowFormatterComponentsDictionary,
496
496
  g7 as getDynamicFilterComponentsDictionary,
497
497
  a6 as getDynamicSortComponentsDictionary,
498
498
  a5 as getFilterGroupFieldsByName,
499
- g31 as getFormComponentsDictionary,
499
+ g32 as getFormComponentsDictionary,
500
500
  g15 as getFormatConcatenated,
501
501
  g12 as getFormatDate,
502
502
  g14 as getFormatPoints,
503
503
  g16 as getFormatPrice,
504
504
  g18 as getFormattersComponentsDictionary,
505
505
  a18 as getHeightSizeStyles,
506
- g36 as getIconColor,
506
+ g37 as getIconColor,
507
507
  g8 as getIsIfInDynamicFilter,
508
508
  g22 as getLoadingErrorComponentsDictionary,
509
509
  g24 as getMFLoaderComponentsDictionary,
@@ -512,23 +512,23 @@ export {
512
512
  g29 as getModalDictionary,
513
513
  g26 as getNoItemPrivilegesComponentsDictionary,
514
514
  g25 as getNoItemSelectedComponentsDictionary,
515
- g40 as getNullGuard,
515
+ g41 as getNullGuard,
516
516
  g27 as getObjectLogsComponentsDictionary,
517
517
  g11 as getPagerComponentsDictionary,
518
- g34 as getPaletteColor,
518
+ g35 as getPaletteColor,
519
519
  g21 as getPeriodComponetsDictionary,
520
520
  g20 as getRHFAutocompleteAsyncComponentsDictionary,
521
521
  g19 as getRHFAutocompleteComponentsDictionary,
522
522
  g9 as getRawFiltersForNetwork,
523
523
  g10 as getRawSortsForNetwork,
524
- g37 as getSizeStyles,
525
- g30 as getStepperComponentsDictionary,
526
- g41 as getStepsAndValidationSchema,
524
+ g38 as getSizeStyles,
525
+ g31 as getStepperComponentsDictionary,
526
+ g30 as getStepsAndValidationSchema,
527
527
  g28 as getTabsNavigatorComponentsDictionary,
528
- g35 as getTypographyStyles,
528
+ g36 as getTypographyStyles,
529
529
  g13 as getUncertaintyFormat,
530
- g39 as getValidDate,
531
- g32 as getformAddEditDictionary,
530
+ g40 as getValidDate,
531
+ g33 as getformAddEditDictionary,
532
532
  i as isEqualLayout,
533
533
  k as isEqualLayouts,
534
534
  i2 as isValidDate,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@m4l/components",
3
- "version": "9.3.39",
3
+ "version": "9.3.41-JT04122025.beta.1",
4
4
  "license": "UNLICENSED",
5
5
  "description": "M4L Components",
6
6
  "lint-staged": {
@@ -1 +0,0 @@
1
- export * from './getStepsAndValidationSchema';
package/helpers/index.js DELETED
@@ -1 +0,0 @@
1
-