@m4l/components 9.3.12-JT270825.beta.1 → 9.3.12-JT290825.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 (50) hide show
  1. package/components/Stepper/Stepper.js +77 -0
  2. package/components/Stepper/Stepper.styles.js +289 -0
  3. package/components/Stepper/constants.js +6 -0
  4. package/components/Stepper/dictionary.js +14 -0
  5. package/components/Stepper/helpers/evaluateVisibilityStepCondition/index.js +17 -0
  6. package/components/Stepper/helpers/findNextVisibleValidStep/index.js +13 -0
  7. package/components/Stepper/helpers/findPrevVisibleValidStep/index.js +13 -0
  8. package/components/Stepper/helpers/index.js +1 -0
  9. package/components/Stepper/helpers/isLastVisibleValidStep/index.js +16 -0
  10. package/components/Stepper/hooks/useIsLastVisibleValidStep/index.js +16 -0
  11. package/components/Stepper/hooks/useStepper/index.js +20 -0
  12. package/components/Stepper/hooks/useStepperActions/index.js +1 -0
  13. package/components/Stepper/hooks/useStepperActions/useStepperActions.js +63 -0
  14. package/components/Stepper/hooks/useStickyStepperFooter/index.d.ts +7 -0
  15. package/components/Stepper/hooks/useStickyStepperFooter/index.js +20 -0
  16. package/components/Stepper/icons.js +12 -0
  17. package/components/Stepper/index.d.ts +9 -4
  18. package/components/Stepper/index.js +1 -0
  19. package/components/Stepper/slots/StepperEnum.js +36 -0
  20. package/components/Stepper/slots/StepperSlot.js +97 -0
  21. package/components/Stepper/store/StepperContext/index.js +103 -0
  22. package/components/Stepper/store/StepperStore/index.js +152 -0
  23. package/components/Stepper/subcomponents/ContentArea/index.js +24 -0
  24. package/components/Stepper/subcomponents/ContentArea/subcomponents/WrapperIcon/index.js +26 -0
  25. package/components/Stepper/subcomponents/ContentArea/subcomponents/WrapperTitle/index.js +23 -0
  26. package/components/Stepper/subcomponents/StepArea/index.js +135 -0
  27. package/components/Stepper/subcomponents/StepArea/subcomponents/Inidicator/index.js +85 -0
  28. package/components/Stepper/subcomponents/StepperButtons/StepperCancelButton/index.js +25 -0
  29. package/components/Stepper/subcomponents/StepperButtons/StepperNextButton/index.js +46 -0
  30. package/components/Stepper/subcomponents/StepperButtons/StepperPrevButton/index.js +52 -0
  31. package/components/Stepper/subcomponents/StepperButtons/StepperSubmitButton/index.js +20 -0
  32. package/components/Stepper/subcomponents/StepperButtons/index.js +1 -0
  33. package/components/Stepper/subcomponents/StepperContent/index.js +23 -0
  34. package/components/Stepper/subcomponents/StepperContent/subcomponents/Step/index.js +42 -0
  35. package/components/Stepper/subcomponents/StepperFooter/index.js +48 -0
  36. package/components/Stepper/subcomponents/StepperFooter/subcomponents/StepperFooterLeftActions/index.js +9 -0
  37. package/components/Stepper/subcomponents/StepperFooter/subcomponents/StepperFooterRightActions/index.js +33 -0
  38. package/components/Stepper/types.d.ts +7 -1
  39. package/components/index.d.ts +1 -0
  40. package/helpers/getStepsAndValidationSchema/getStepsAndValidationSchema.js +44 -0
  41. package/helpers/getStepsAndValidationSchema/index.d.ts +1 -0
  42. package/helpers/getStepsAndValidationSchema/index.js +1 -0
  43. package/helpers/getStepsAndValidationSchema/types.js +1 -0
  44. package/helpers/index.d.ts +1 -0
  45. package/helpers/index.js +1 -0
  46. package/index.d.ts +1 -0
  47. package/index.js +80 -52
  48. package/package.json +1 -1
  49. package/storybook/components/Stepper/helpers/useSteps.d.ts +1 -1
  50. package/storybook/components/Stepper/subcomponents/StepperDecorator.d.ts +1 -1
@@ -0,0 +1,97 @@
1
+ import { styled } from "@mui/material/styles";
2
+ import { S as STEPPER_PREFIX_NAME } from "../constants.js";
3
+ import { S as StepperSlots, C as ContentSlots, a as StepperFooterSlots, b as ContentAreaSlots } from "./StepperEnum.js";
4
+ import { s as stepperStyles } from "../Stepper.styles.js";
5
+ import { T as Typography } from "../../mui_extended/Typography/Typography.js";
6
+ import { I as Icon } from "../../Icon/Icon.js";
7
+ const StepperRootStyled = styled("div", {
8
+ name: STEPPER_PREFIX_NAME,
9
+ slot: StepperSlots.stepperRoot
10
+ })(stepperStyles.stepperRoot);
11
+ const ContentSectionStyled = styled("section", {
12
+ name: STEPPER_PREFIX_NAME,
13
+ slot: ContentSlots.contentSection
14
+ })(stepperStyles.contentSection);
15
+ const StepAreaStyled = styled("div", {
16
+ name: STEPPER_PREFIX_NAME,
17
+ slot: ContentSlots.stepArea
18
+ })(stepperStyles.stepArea);
19
+ const ContentAreaStyled = styled("div", {
20
+ name: STEPPER_PREFIX_NAME,
21
+ slot: ContentAreaSlots.contentArea
22
+ })(stepperStyles.contentArea);
23
+ const StepStyled = styled("div", {
24
+ name: STEPPER_PREFIX_NAME,
25
+ slot: ContentSlots.step
26
+ })(stepperStyles.step);
27
+ const StepNameStyled = styled(Typography, {
28
+ name: STEPPER_PREFIX_NAME,
29
+ slot: ContentSlots.stepName
30
+ })(stepperStyles.stepName);
31
+ const IndicatorStyled = styled("div", {
32
+ name: STEPPER_PREFIX_NAME,
33
+ slot: ContentSlots.indicator
34
+ })(stepperStyles.indicator);
35
+ const TextNumberStyled = styled(Typography, {
36
+ name: STEPPER_PREFIX_NAME,
37
+ slot: ContentSlots.textNumber
38
+ })(stepperStyles.textNumber);
39
+ const ContentAreaHeaderStyled = styled("div", {
40
+ name: STEPPER_PREFIX_NAME,
41
+ slot: ContentAreaSlots.contentAreaHeader
42
+ })(stepperStyles.contentAreaHeader);
43
+ const WrapperIconStyled = styled("div", {
44
+ name: STEPPER_PREFIX_NAME,
45
+ slot: ContentAreaSlots.wrapperIcon
46
+ })(stepperStyles.wrapperIcon);
47
+ const WrapperTitleStyled = styled("div", {
48
+ name: STEPPER_PREFIX_NAME,
49
+ slot: ContentAreaSlots.wrapperTitle
50
+ })(stepperStyles.wrapperTitle);
51
+ const IconStyled = styled(Icon, {
52
+ name: STEPPER_PREFIX_NAME,
53
+ slot: ContentAreaSlots.icon
54
+ })(stepperStyles.icon);
55
+ const TitleStyled = styled(Typography, {
56
+ name: STEPPER_PREFIX_NAME,
57
+ slot: ContentAreaSlots.title
58
+ })(stepperStyles.title);
59
+ const DescriptionStyled = styled(Typography, {
60
+ name: STEPPER_PREFIX_NAME,
61
+ slot: ContentAreaSlots.description
62
+ })(stepperStyles.description);
63
+ const StepperFooterSectionStyled = styled("section", {
64
+ name: STEPPER_PREFIX_NAME,
65
+ slot: StepperFooterSlots.stepperFooterSection
66
+ })(stepperStyles.stepperFooterSection);
67
+ const StepperFooterLeftActionsStyled = styled("div", {
68
+ name: STEPPER_PREFIX_NAME,
69
+ slot: StepperFooterSlots.stepperFooterLeftActions
70
+ })(stepperStyles.stepperFooterLeftActions);
71
+ const StepperFooterRightActionsStyled = styled("div", {
72
+ name: STEPPER_PREFIX_NAME,
73
+ slot: StepperFooterSlots.stepperFooterRightActions
74
+ })(stepperStyles.stepperFooterRightActions);
75
+ styled("div", {
76
+ name: STEPPER_PREFIX_NAME,
77
+ slot: StepperFooterSlots.wrapperButtons
78
+ })(stepperStyles.wrapperButtons);
79
+ export {
80
+ ContentSectionStyled as C,
81
+ DescriptionStyled as D,
82
+ IconStyled as I,
83
+ StepperRootStyled as S,
84
+ TitleStyled as T,
85
+ WrapperIconStyled as W,
86
+ ContentAreaStyled as a,
87
+ ContentAreaHeaderStyled as b,
88
+ WrapperTitleStyled as c,
89
+ StepAreaStyled as d,
90
+ StepStyled as e,
91
+ StepNameStyled as f,
92
+ IndicatorStyled as g,
93
+ TextNumberStyled as h,
94
+ StepperFooterSectionStyled as i,
95
+ StepperFooterLeftActionsStyled as j,
96
+ StepperFooterRightActionsStyled as k
97
+ };
@@ -0,0 +1,103 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { createContext, useRef, useEffect } from "react";
3
+ import { useEnvironment } from "@m4l/core";
4
+ import { c as createStepperStore } from "../StepperStore/index.js";
5
+ import { f as findNextVisibleValidStep } from "../../helpers/findNextVisibleValidStep/index.js";
6
+ const StepperContext = createContext(null);
7
+ const StepperProvider = (props) => {
8
+ const {
9
+ storeId,
10
+ storeDevtoolsEnabled,
11
+ steps,
12
+ visibleTitle = true,
13
+ indicatorType = "number",
14
+ orientation = "horizontal",
15
+ visibilityData,
16
+ children
17
+ } = props;
18
+ const { host_static_assets, environment_assets } = useEnvironment();
19
+ const stepperStoreRef = useRef();
20
+ const prevVisibilityDataRef = useRef(visibilityData);
21
+ if (!stepperStoreRef.current) {
22
+ stepperStoreRef.current = createStepperStore(
23
+ {
24
+ storeId,
25
+ steps,
26
+ visibleTitle,
27
+ ownerState: {},
28
+ host_static_assets,
29
+ environment_assets,
30
+ indicatorType,
31
+ orientation,
32
+ visibilityData
33
+ },
34
+ storeDevtoolsEnabled
35
+ );
36
+ stepperStoreRef.current.getState().actions.init(steps);
37
+ }
38
+ useEffect(() => {
39
+ if (stepperStoreRef.current) {
40
+ const currentState = stepperStoreRef.current.getState();
41
+ if (currentState.visibleTitle !== visibleTitle) {
42
+ stepperStoreRef.current.setState((state) => ({
43
+ ...state,
44
+ visibleTitle
45
+ }));
46
+ }
47
+ if (currentState.orientation !== orientation) {
48
+ stepperStoreRef.current.setState((state) => ({
49
+ ...state,
50
+ orientation
51
+ }));
52
+ }
53
+ if (currentState.indicatorType !== indicatorType) {
54
+ stepperStoreRef.current.setState((state) => ({
55
+ ...state,
56
+ indicatorType
57
+ }));
58
+ }
59
+ if (currentState.visibilityData !== visibilityData) {
60
+ stepperStoreRef.current.setState((state) => ({
61
+ ...state,
62
+ visibilityData
63
+ }));
64
+ }
65
+ }
66
+ }, [visibleTitle, orientation, indicatorType, visibilityData]);
67
+ useEffect(() => {
68
+ if (stepperStoreRef.current && steps) {
69
+ const store = stepperStoreRef.current;
70
+ const currentState = store.getState();
71
+ store.getState().actions.init(steps);
72
+ if (visibilityData) {
73
+ const hasVisibilityDataChanged = JSON.stringify(prevVisibilityDataRef.current) !== JSON.stringify(visibilityData);
74
+ if (hasVisibilityDataChanged) {
75
+ const nextStepIndex = findNextVisibleValidStep(
76
+ currentState.currentStep,
77
+ steps,
78
+ {},
79
+ visibilityData
80
+ );
81
+ if (nextStepIndex < steps.length && nextStepIndex !== currentState.currentStep) {
82
+ store.getState().actions.setCurrentStep(nextStepIndex);
83
+ store.getState().actions.setStepValidationStatus(currentState.currentStep, true);
84
+ }
85
+ }
86
+ }
87
+ }
88
+ prevVisibilityDataRef.current = visibilityData;
89
+ }, [steps, visibilityData]);
90
+ return /* @__PURE__ */ jsx(
91
+ StepperContext.Provider,
92
+ {
93
+ value: {
94
+ store: stepperStoreRef.current
95
+ },
96
+ children
97
+ }
98
+ );
99
+ };
100
+ export {
101
+ StepperProvider as S,
102
+ StepperContext as a
103
+ };
@@ -0,0 +1,152 @@
1
+ import { createStore } from "zustand";
2
+ import { devtools } from "zustand/middleware";
3
+ import { immer } from "zustand/middleware/immer";
4
+ import { a as STEPPER_STORE_ID } from "../../constants.js";
5
+ import { f as findNextVisibleValidStep } from "../../helpers/findNextVisibleValidStep/index.js";
6
+ import { f as findPrevVisibleValidStep } from "../../helpers/findPrevVisibleValidStep/index.js";
7
+ const createDevtools = (immerMiddlewere, config) => {
8
+ const { enabled = false } = config;
9
+ if (enabled && process.env.NODE_ENV === "development") {
10
+ return devtools(immerMiddlewere, config);
11
+ }
12
+ return immerMiddlewere;
13
+ };
14
+ const createStepperStore = (initProps, storeDevtoolsEnabled = false) => {
15
+ const startProps = {
16
+ currentStep: 0,
17
+ completedSteps: [],
18
+ stepValidationStatus: {},
19
+ isValidating: false,
20
+ ...initProps
21
+ };
22
+ return createStore(
23
+ createDevtools(
24
+ /**
25
+ * immer es un middleware de Zustand que permite trabajar con el estado de manera inmutable
26
+ */
27
+ immer((set, get) => ({
28
+ ...startProps,
29
+ actions: {
30
+ /**
31
+ * init es la acción que se ejecuta al inicializar el store
32
+ */
33
+ init: (steps) => {
34
+ set((state) => {
35
+ state.steps = steps;
36
+ state.completedSteps = [];
37
+ state.stepValidationStatus = {};
38
+ });
39
+ },
40
+ /**
41
+ * setCurrentStep es la acción que se ejecuta para cambiar el step actual
42
+ */
43
+ setCurrentStep: (currentStep) => {
44
+ set((state) => {
45
+ state.currentStep = currentStep;
46
+ });
47
+ },
48
+ /**
49
+ * setCompletedStep es la acción que se ejecuta para marcar un paso como completado
50
+ * @param stepIndex - Índice del paso a marcar como completado
51
+ */
52
+ setCompletedStep: (stepIndex) => {
53
+ set((state) => {
54
+ if (!state.completedSteps.includes(stepIndex)) {
55
+ state.completedSteps.push(stepIndex);
56
+ }
57
+ });
58
+ },
59
+ /**
60
+ * setStepValidationStatus es la acción que se ejecuta para establecer el estado de validación de un paso
61
+ * @param stepIndex
62
+ * @param isValid
63
+ */
64
+ setStepValidationStatus: (stepIndex, isValid) => {
65
+ set((state) => {
66
+ state.stepValidationStatus[stepIndex] = isValid;
67
+ });
68
+ },
69
+ /**
70
+ * prevStep - Función que retrocede al paso anterior válido del Stepper.
71
+ * @param formData Datos del formulario actual para evaluar las conditions de los pasos
72
+ * @param visibilityData Datos adicionales para evaluar las conditions (opcional, usa el del store si no se proporciona)
73
+ */
74
+ prevStep: (formData = {}, visibilityData) => {
75
+ const state = get();
76
+ const { currentStep, steps } = state;
77
+ const dataForVisibility = visibilityData ?? state.visibilityData;
78
+ const prevValidStepIndex = findPrevVisibleValidStep(
79
+ currentStep,
80
+ steps,
81
+ formData,
82
+ dataForVisibility
83
+ );
84
+ if (prevValidStepIndex < 0) {
85
+ return;
86
+ }
87
+ set((draft) => {
88
+ draft.currentStep = prevValidStepIndex;
89
+ });
90
+ },
91
+ /**
92
+ * nextStep - Función que valida el paso actual y avanza al siguiente paso del Stepper.
93
+ * @param validateFn Función de validación externa que debe retornar una promesa que resuelve a true o false
94
+ * @param formData Datos del formulario actual para evaluar las conditions de los pasos
95
+ * @param visibilityData Datos adicionales para evaluar las conditions (opcional, usa el del store si no se proporciona)
96
+ * @returns Promise<boolean> Retorna true si se avanzó al siguiente paso, false en caso contrario
97
+ */
98
+ nextStep: async (validateFn, formData = {}, visibilityData) => {
99
+ const state = get();
100
+ const { currentStep, steps } = state;
101
+ const dataForVisibility = visibilityData ?? state.visibilityData;
102
+ set((draft) => {
103
+ draft.isValidating = true;
104
+ });
105
+ const isValid = await validateFn();
106
+ if (!isValid) {
107
+ set((draft) => {
108
+ draft.isValidating = false;
109
+ });
110
+ state.actions.setStepValidationStatus(currentStep, false);
111
+ return false;
112
+ }
113
+ state.actions.setStepValidationStatus(currentStep, true);
114
+ const nextValidStepIndex = findNextVisibleValidStep(
115
+ currentStep,
116
+ steps,
117
+ formData,
118
+ dataForVisibility
119
+ );
120
+ state.actions.setCompletedStep(currentStep);
121
+ set((draft) => {
122
+ if (!draft.completedSteps.includes(currentStep)) {
123
+ draft.completedSteps.push(currentStep);
124
+ }
125
+ draft.currentStep = nextValidStepIndex;
126
+ draft.isValidating = false;
127
+ });
128
+ return true;
129
+ },
130
+ /**
131
+ * resetStepper - Resetea el Stepper a su estado inicial
132
+ */
133
+ resetStepper: () => {
134
+ set((state) => {
135
+ state.currentStep = 0;
136
+ state.completedSteps = [];
137
+ state.stepValidationStatus = {};
138
+ state.isValidating = false;
139
+ });
140
+ }
141
+ }
142
+ })),
143
+ {
144
+ name: `${STEPPER_STORE_ID}: ${initProps.storeId}`,
145
+ enabled: storeDevtoolsEnabled
146
+ }
147
+ )
148
+ );
149
+ };
150
+ export {
151
+ createStepperStore as c
152
+ };
@@ -0,0 +1,24 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { u as useStepper } from "../../hooks/useStepper/index.js";
3
+ import { a as ContentAreaStyled, b as ContentAreaHeaderStyled } from "../../slots/StepperSlot.js";
4
+ import { W as WrapperIcon } from "./subcomponents/WrapperIcon/index.js";
5
+ import { W as WrapperTitle } from "./subcomponents/WrapperTitle/index.js";
6
+ function ContentArea(props) {
7
+ const { children } = props;
8
+ const { orientation } = useStepper((state) => ({
9
+ orientation: state.orientation
10
+ }));
11
+ const ownerState = {
12
+ orientation
13
+ };
14
+ return /* @__PURE__ */ jsxs(ContentAreaStyled, { ownerState, children: [
15
+ /* @__PURE__ */ jsxs(ContentAreaHeaderStyled, { children: [
16
+ /* @__PURE__ */ jsx(WrapperIcon, {}),
17
+ /* @__PURE__ */ jsx(WrapperTitle, {})
18
+ ] }),
19
+ children
20
+ ] });
21
+ }
22
+ export {
23
+ ContentArea as C
24
+ };
@@ -0,0 +1,26 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { W as WrapperIconStyled, I as IconStyled } from "../../../../slots/StepperSlot.js";
4
+ import { p as pathIcons } from "../../../../icons.js";
5
+ import { u as useStepper } from "../../../../hooks/useStepper/index.js";
6
+ function WrapperIcon() {
7
+ const { steps, currentStep, host_static_assets, environment_assets } = useStepper((state) => ({
8
+ host_static_assets: state.host_static_assets,
9
+ environment_assets: state.environment_assets,
10
+ steps: state.steps,
11
+ currentStep: state.currentStep
12
+ }));
13
+ const currentStepConfig = useMemo(() => {
14
+ return steps[currentStep];
15
+ }, [steps, currentStep]);
16
+ return /* @__PURE__ */ jsx(WrapperIconStyled, { children: /* @__PURE__ */ jsx(
17
+ IconStyled,
18
+ {
19
+ color: "primary.enabled",
20
+ src: currentStepConfig.icon ? currentStepConfig.icon : `${host_static_assets}/${environment_assets}/${pathIcons.patronum}`
21
+ }
22
+ ) });
23
+ }
24
+ export {
25
+ WrapperIcon as W
26
+ };
@@ -0,0 +1,23 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { u as useStepper } from "../../../../hooks/useStepper/index.js";
4
+ import { c as WrapperTitleStyled, T as TitleStyled, D as DescriptionStyled } from "../../../../slots/StepperSlot.js";
5
+ function WrapperTitle() {
6
+ const { steps, currentStep } = useStepper((state) => ({
7
+ steps: state.steps,
8
+ currentStep: state.currentStep
9
+ }));
10
+ const currentStepConfig = useMemo(() => {
11
+ return steps[currentStep];
12
+ }, [steps, currentStep]);
13
+ if (!currentStepConfig) {
14
+ return null;
15
+ }
16
+ return /* @__PURE__ */ jsxs(WrapperTitleStyled, { children: [
17
+ /* @__PURE__ */ jsx(TitleStyled, { variant: "paragraphDens", children: currentStepConfig.title }),
18
+ currentStepConfig.description && /* @__PURE__ */ jsx(DescriptionStyled, { variant: "body", children: currentStepConfig.description })
19
+ ] });
20
+ }
21
+ export {
22
+ WrapperTitle as W
23
+ };
@@ -0,0 +1,135 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { useFormContext, useWatch } from "react-hook-form";
4
+ import { u as useStepper } from "../../hooks/useStepper/index.js";
5
+ import { d as StepAreaStyled, e as StepStyled, f as StepNameStyled } from "../../slots/StepperSlot.js";
6
+ import { I as Indicator } from "./subcomponents/Inidicator/index.js";
7
+ import { e as evaluateVisibilityStepCondition } from "../../helpers/evaluateVisibilityStepCondition/index.js";
8
+ function StepArea() {
9
+ const { trigger, clearErrors } = useFormContext();
10
+ const formValues = useWatch();
11
+ const {
12
+ currentStep,
13
+ steps,
14
+ visibleTitle,
15
+ setCurrentStep,
16
+ orientation,
17
+ setStepValidationStatus,
18
+ stepValidationStatus,
19
+ visibilityData
20
+ } = useStepper((state) => ({
21
+ currentStep: state.currentStep,
22
+ steps: state.steps,
23
+ visibleTitle: state.visibleTitle,
24
+ setCurrentStep: state.actions.setCurrentStep,
25
+ indicatorType: state.indicatorType,
26
+ orientation: state.orientation,
27
+ setStepValidationStatus: state.actions.setStepValidationStatus,
28
+ stepValidationStatus: state.stepValidationStatus,
29
+ visibilityData: state.visibilityData
30
+ }));
31
+ const validSteps = useMemo(() => {
32
+ return steps.filter(
33
+ (step) => evaluateVisibilityStepCondition(step, formValues || {}, visibilityData)
34
+ );
35
+ }, [steps, formValues, visibilityData]);
36
+ const ownerState = {
37
+ visibleTitle,
38
+ orientation,
39
+ totalSteps: validSteps.length
40
+ };
41
+ const handleStepClick = async (targetIndex) => {
42
+ const currentIndex = validSteps.findIndex(
43
+ (step) => step.key === steps[currentStep].key
44
+ );
45
+ if (targetIndex === currentIndex) {
46
+ return;
47
+ }
48
+ const isNavigatingForward = targetIndex > currentIndex;
49
+ const targetOriginalIndex = steps.findIndex(
50
+ (s) => s.key === validSteps[targetIndex].key
51
+ );
52
+ if (!isNavigatingForward) {
53
+ setCurrentStep(targetOriginalIndex);
54
+ return;
55
+ }
56
+ const isSkippingSteps = targetIndex > currentIndex + 1;
57
+ if (isSkippingSteps) {
58
+ for (let i = currentIndex; i < targetIndex; i++) {
59
+ const step = validSteps[i];
60
+ const stepOriginalIndex = steps.findIndex((s) => s.key === step.key);
61
+ const isValid = await trigger(step.validationFields);
62
+ if (!isValid) {
63
+ setCurrentStep(stepOriginalIndex);
64
+ setStepValidationStatus(stepOriginalIndex, false);
65
+ return;
66
+ }
67
+ setStepValidationStatus(stepOriginalIndex, true);
68
+ }
69
+ } else {
70
+ const currentStepData = validSteps[currentIndex];
71
+ const currentStepOriginalIndex = steps.findIndex(
72
+ (s) => s.key === currentStepData.key
73
+ );
74
+ const isCurrentValid = await trigger(currentStepData.validationFields);
75
+ if (!isCurrentValid) {
76
+ setStepValidationStatus(currentStepOriginalIndex, false);
77
+ return;
78
+ }
79
+ setStepValidationStatus(currentStepOriginalIndex, true);
80
+ }
81
+ setCurrentStep(targetOriginalIndex);
82
+ if (isNavigatingForward) {
83
+ const currentStepData = validSteps[currentIndex];
84
+ const currentStepOriginalIndex = steps.findIndex(
85
+ (s) => s.key === currentStepData.key
86
+ );
87
+ const isCurrentStepValid = stepValidationStatus[currentStepOriginalIndex] !== false;
88
+ if (isCurrentStepValid) {
89
+ const targetStep = validSteps[targetIndex];
90
+ const targetStepFields = targetStep.validationFields || [];
91
+ if (targetStepFields.length > 0) {
92
+ clearErrors(targetStepFields);
93
+ setTimeout(() => {
94
+ clearErrors(targetStepFields);
95
+ setStepValidationStatus(targetOriginalIndex, true);
96
+ }, 100);
97
+ }
98
+ }
99
+ }
100
+ };
101
+ return /* @__PURE__ */ jsx(StepAreaStyled, { ownerState, children: validSteps.map((step, validIndex) => {
102
+ const originalIndex = steps.findIndex((s) => s.key === step.key);
103
+ return /* @__PURE__ */ jsxs(
104
+ StepStyled,
105
+ {
106
+ role: "button",
107
+ onClick: () => handleStepClick(validIndex),
108
+ ownerState: { ...ownerState, currentStep, step: validIndex },
109
+ children: [
110
+ visibleTitle && /* @__PURE__ */ jsx(
111
+ StepNameStyled,
112
+ {
113
+ variant: "body",
114
+ ownerState: { ...ownerState, currentStep, step: validIndex },
115
+ children: step.title
116
+ }
117
+ ),
118
+ /* @__PURE__ */ jsx(
119
+ Indicator,
120
+ {
121
+ currentStep,
122
+ step: validIndex,
123
+ totalSteps: validSteps.length,
124
+ originalStepIndex: originalIndex
125
+ }
126
+ )
127
+ ]
128
+ },
129
+ step.key
130
+ );
131
+ }) });
132
+ }
133
+ export {
134
+ StepArea as S
135
+ };
@@ -0,0 +1,85 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { useMemo } from "react";
3
+ import { g as IndicatorStyled, h as TextNumberStyled } from "../../../../slots/StepperSlot.js";
4
+ import { u as useStepper } from "../../../../hooks/useStepper/index.js";
5
+ import { p as pathIcons } from "../../../../icons.js";
6
+ import { useIsMobile } from "@m4l/graphics";
7
+ import { u as useComponentSize } from "../../../../../../hooks/useComponentSize/useComponentSize.js";
8
+ import { I as Icon } from "../../../../../Icon/Icon.js";
9
+ function Indicator(props) {
10
+ const { step, currentStep, totalSteps, originalStepIndex } = props;
11
+ const {
12
+ host_static_assets,
13
+ environment_assets,
14
+ orientation,
15
+ size,
16
+ indicatorType,
17
+ stepValidationStatus
18
+ } = useStepper((state) => ({
19
+ host_static_assets: state.host_static_assets,
20
+ environment_assets: state.environment_assets,
21
+ orientation: state.orientation,
22
+ size: state.size,
23
+ indicatorType: state.indicatorType,
24
+ stepValidationStatus: state.stepValidationStatus
25
+ }));
26
+ const { currentSize } = useComponentSize(size);
27
+ const ownerState = {
28
+ size: currentSize,
29
+ currentStep,
30
+ step,
31
+ totalSteps,
32
+ orientation,
33
+ indicatorType,
34
+ stepValidationStatus
35
+ };
36
+ const isMobile = useIsMobile();
37
+ const effectiveIndicatorType = useMemo(() => {
38
+ return isMobile ? "dot" : indicatorType;
39
+ }, [isMobile, indicatorType]);
40
+ const { isCompleted, isValidStep, hasBeenValidated } = useMemo(() => {
41
+ const completed = currentStep > originalStepIndex;
42
+ const validationStatus = stepValidationStatus[originalStepIndex];
43
+ const validated = validationStatus !== void 0;
44
+ const valid = validationStatus === true;
45
+ return {
46
+ isCompleted: completed,
47
+ isValidStep: valid,
48
+ hasBeenValidated: validated
49
+ };
50
+ }, [currentStep, originalStepIndex, stepValidationStatus]);
51
+ return /* @__PURE__ */ jsx(IndicatorStyled, { ownerState, children: hasBeenValidated && !isValidStep ? (
52
+ // Mostrar error solo si ha sido validado y es inválido
53
+ /* @__PURE__ */ jsx(
54
+ Icon,
55
+ {
56
+ src: `${host_static_assets}/${environment_assets}/${pathIcons.circleError}`,
57
+ size: "small",
58
+ color: "error.contrastText"
59
+ }
60
+ )
61
+ ) : isCompleted && isValidStep ? (
62
+ // Mostrar completado solo si está completado Y es válido
63
+ /* @__PURE__ */ jsx(
64
+ Icon,
65
+ {
66
+ src: `${host_static_assets}/${environment_assets}/${effectiveIndicatorType === "number" ? pathIcons.circleCheck : pathIcons.dotOutline}`,
67
+ size: "small",
68
+ color: "primary.semanticText"
69
+ }
70
+ )
71
+ ) : (
72
+ // Mostrar estado normal (número o dot) para pasos no validados o actuales
73
+ /* @__PURE__ */ jsx(TextNumberStyled, { variant: "body", ownerState: { currentStep, step }, children: effectiveIndicatorType === "number" ? step + 1 : /* @__PURE__ */ jsx(
74
+ Icon,
75
+ {
76
+ src: `${host_static_assets}/${environment_assets}/${currentStep === originalStepIndex ? pathIcons.dotSelected : pathIcons.dotOutline}`,
77
+ size: "small",
78
+ color: currentStep === originalStepIndex ? "primary.semanticText" : "text.disabled"
79
+ }
80
+ ) })
81
+ ) });
82
+ }
83
+ export {
84
+ Indicator as I
85
+ };
@@ -0,0 +1,25 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { D as DICTIONARY } from "../../../dictionary.js";
3
+ import { useModuleDictionary } from "@m4l/core";
4
+ import { u as useStepperActions } from "../../../hooks/useStepperActions/useStepperActions.js";
5
+ import { B as Button } from "../../../../mui_extended/Button/Button.js";
6
+ function StepperCancelButton() {
7
+ const { getLabel } = useModuleDictionary();
8
+ const { cancelAction } = useStepperActions();
9
+ const handleCancel = () => {
10
+ cancelAction();
11
+ };
12
+ return /* @__PURE__ */ jsx(
13
+ Button,
14
+ {
15
+ type: "button",
16
+ label: getLabel(DICTIONARY.LABEL_CANCEL_BUTTON),
17
+ variant: "outlined",
18
+ color: "default",
19
+ onClick: handleCancel
20
+ }
21
+ );
22
+ }
23
+ export {
24
+ StepperCancelButton as S
25
+ };