@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.
- package/components/Stepper/Stepper.js +77 -0
- package/components/Stepper/Stepper.styles.js +289 -0
- package/components/Stepper/constants.js +6 -0
- package/components/Stepper/dictionary.js +14 -0
- package/components/Stepper/helpers/evaluateVisibilityStepCondition/index.js +17 -0
- package/components/Stepper/helpers/findNextVisibleValidStep/index.js +13 -0
- package/components/Stepper/helpers/findPrevVisibleValidStep/index.js +13 -0
- package/components/Stepper/helpers/index.js +1 -0
- package/components/Stepper/helpers/isLastVisibleValidStep/index.js +16 -0
- package/components/Stepper/hooks/useIsLastVisibleValidStep/index.js +16 -0
- package/components/Stepper/hooks/useStepper/index.js +20 -0
- package/components/Stepper/hooks/useStepperActions/index.js +1 -0
- package/components/Stepper/hooks/useStepperActions/useStepperActions.js +63 -0
- package/components/Stepper/hooks/useStickyStepperFooter/index.d.ts +7 -0
- package/components/Stepper/hooks/useStickyStepperFooter/index.js +20 -0
- package/components/Stepper/icons.js +12 -0
- package/components/Stepper/index.d.ts +9 -4
- package/components/Stepper/index.js +1 -0
- package/components/Stepper/slots/StepperEnum.js +36 -0
- package/components/Stepper/slots/StepperSlot.js +97 -0
- package/components/Stepper/store/StepperContext/index.js +103 -0
- package/components/Stepper/store/StepperStore/index.js +152 -0
- package/components/Stepper/subcomponents/ContentArea/index.js +24 -0
- package/components/Stepper/subcomponents/ContentArea/subcomponents/WrapperIcon/index.js +26 -0
- package/components/Stepper/subcomponents/ContentArea/subcomponents/WrapperTitle/index.js +23 -0
- package/components/Stepper/subcomponents/StepArea/index.js +135 -0
- package/components/Stepper/subcomponents/StepArea/subcomponents/Inidicator/index.js +85 -0
- package/components/Stepper/subcomponents/StepperButtons/StepperCancelButton/index.js +25 -0
- package/components/Stepper/subcomponents/StepperButtons/StepperNextButton/index.js +46 -0
- package/components/Stepper/subcomponents/StepperButtons/StepperPrevButton/index.js +52 -0
- package/components/Stepper/subcomponents/StepperButtons/StepperSubmitButton/index.js +20 -0
- package/components/Stepper/subcomponents/StepperButtons/index.js +1 -0
- package/components/Stepper/subcomponents/StepperContent/index.js +23 -0
- package/components/Stepper/subcomponents/StepperContent/subcomponents/Step/index.js +42 -0
- package/components/Stepper/subcomponents/StepperFooter/index.js +48 -0
- package/components/Stepper/subcomponents/StepperFooter/subcomponents/StepperFooterLeftActions/index.js +9 -0
- package/components/Stepper/subcomponents/StepperFooter/subcomponents/StepperFooterRightActions/index.js +33 -0
- package/components/Stepper/types.d.ts +7 -1
- package/components/index.d.ts +1 -0
- package/helpers/getStepsAndValidationSchema/getStepsAndValidationSchema.js +44 -0
- package/helpers/getStepsAndValidationSchema/index.d.ts +1 -0
- package/helpers/getStepsAndValidationSchema/index.js +1 -0
- package/helpers/getStepsAndValidationSchema/types.js +1 -0
- package/helpers/index.d.ts +1 -0
- package/helpers/index.js +1 -0
- package/index.d.ts +1 -0
- package/index.js +80 -52
- package/package.json +1 -1
- package/storybook/components/Stepper/helpers/useSteps.d.ts +1 -1
- 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
|
+
};
|