@m4l/components 9.4.25 → 9.4.26
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 +1 -1
- package/components/Stepper/Stepper.styles.js +22 -9
- package/components/Stepper/helpers/findAllVisibleStepsBefore/index.d.ts +19 -0
- package/components/Stepper/helpers/findAllVisibleStepsBefore/index.js +22 -0
- package/components/Stepper/helpers/findStepIndexByKey/index.d.ts +8 -0
- package/components/Stepper/helpers/findStepIndexByKey/index.js +6 -0
- package/components/Stepper/helpers/index.d.ts +2 -0
- package/components/Stepper/hooks/useInitialStepKey/index.d.ts +5 -0
- package/components/Stepper/hooks/useInitialStepKey/index.js +44 -0
- package/components/Stepper/slots/StepperEnum.d.ts +1 -0
- package/components/Stepper/slots/StepperEnum.js +1 -0
- package/components/Stepper/slots/StepperSlot.d.ts +3 -0
- package/components/Stepper/slots/StepperSlot.js +16 -11
- package/components/Stepper/store/StepperContext/index.js +3 -1
- package/components/Stepper/store/StepperStore/index.js +70 -0
- package/components/Stepper/store/types.d.ts +12 -2
- package/components/Stepper/subcomponents/ContentArea/index.js +3 -1
- package/components/Stepper/subcomponents/ContentArea/subcomponents/WrapperIcon/index.js +1 -1
- package/components/Stepper/subcomponents/ContentArea/subcomponents/WrapperTitle/index.js +1 -1
- package/components/Stepper/subcomponents/StepArea/index.js +2 -2
- package/components/Stepper/subcomponents/StepperContent/subcomponents/Step/index.js +1 -1
- package/components/Stepper/subcomponents/StepperFooter/index.js +1 -1
- package/components/Stepper/subcomponents/StepperFooter/subcomponents/StepperFooterLeftActions/index.js +1 -1
- package/components/Stepper/subcomponents/StepperFooter/subcomponents/StepperFooterRightActions/index.js +1 -1
- package/components/Stepper/types.d.ts +22 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo, Children, isValidElement } from "react";
|
|
3
3
|
import clsx from "clsx";
|
|
4
4
|
import { useFlagsPresent, CommonFlags } from "@m4l/core";
|
|
5
|
-
import {
|
|
5
|
+
import { m as StepperRootStyled, n as ContentSectionStyled } from "./slots/StepperSlot.js";
|
|
6
6
|
import { g as getComponentSlotRoot } from "../../utils/getComponentSlotRoot.js";
|
|
7
7
|
import { a as STEPPER_PREFIX_NAME } from "./constants.js";
|
|
8
8
|
import { S as StepArea } from "./subcomponents/StepArea/index.js";
|
|
@@ -111,35 +111,47 @@ const stepperStyles = {
|
|
|
111
111
|
* Estilos para el nombre del paso dentro del Stepper.
|
|
112
112
|
*/
|
|
113
113
|
stepName: ({ theme, ownerState }) => ({
|
|
114
|
-
...ownerState?.orientation === "horizontal" && {
|
|
115
|
-
|
|
114
|
+
...ownerState?.orientation === "horizontal" && !theme.generalSettings.isMobile && {
|
|
115
|
+
minHeight: theme.vars.size.desktop.medium.action,
|
|
116
|
+
maxWidth: "120px",
|
|
117
|
+
width: "100%"
|
|
116
118
|
},
|
|
117
119
|
...(ownerState?.orientation === "vertical" || theme.generalSettings.isMobile) && {
|
|
118
120
|
maxWidth: "120px",
|
|
119
121
|
width: "100%",
|
|
120
|
-
lineHeight: "1.2",
|
|
121
122
|
marginTop: theme.vars.size.baseSpacings.sp1
|
|
122
123
|
},
|
|
123
124
|
alignContent: "center",
|
|
124
125
|
cursor: "pointer",
|
|
125
|
-
overflow: "hidden",
|
|
126
126
|
...theme.generalSettings.isMobile ? {
|
|
127
127
|
display: "none"
|
|
128
128
|
} : {
|
|
129
|
-
display: ownerState?.visibleTitle ? "
|
|
129
|
+
display: ownerState?.visibleTitle ? "block" : "none"
|
|
130
130
|
},
|
|
131
|
-
WebkitBoxOrient: "vertical",
|
|
132
|
-
WebkitLineClamp: 2,
|
|
133
|
-
textOverflow: "ellipsis",
|
|
134
131
|
flex: 1,
|
|
135
132
|
minWidth: 0,
|
|
136
|
-
whiteSpace: "normal",
|
|
137
133
|
order: ownerState?.orientation === "vertical" || theme.generalSettings.isMobile ? 1 : 0,
|
|
138
134
|
"&.M4LTypography-root": {
|
|
139
135
|
color: ownerState?.originalStepIndex !== void 0 && typeof ownerState.originalStepIndex === "number" ? (ownerState.currentStep ?? 0) > ownerState.originalStepIndex ? theme.vars.palette.primary.semanticText : (ownerState.currentStep ?? 0) === ownerState.originalStepIndex ? theme.vars.palette.text.primary : theme.vars.palette.text.secondary : theme.vars.palette.text.secondary,
|
|
140
136
|
textAlign: ownerState?.orientation === "vertical" || theme.generalSettings.isMobile ? "center" : "right"
|
|
141
137
|
}
|
|
142
138
|
}),
|
|
139
|
+
/**
|
|
140
|
+
* Estilos para el texto del nombre del paso con truncado (line-clamp).
|
|
141
|
+
*/
|
|
142
|
+
stepNameText: ({ theme, ownerState }) => ({
|
|
143
|
+
display: "-webkit-box",
|
|
144
|
+
"-webkit-box-orient": "vertical",
|
|
145
|
+
"-webkit-line-clamp": "2",
|
|
146
|
+
overflow: "hidden",
|
|
147
|
+
textOverflow: "ellipsis",
|
|
148
|
+
wordBreak: "break-word",
|
|
149
|
+
whiteSpace: "normal",
|
|
150
|
+
width: "100%",
|
|
151
|
+
direction: "ltr",
|
|
152
|
+
lineHeight: 1.2,
|
|
153
|
+
textAlign: ownerState?.orientation === "vertical" || theme.generalSettings.isMobile ? "center" : "left"
|
|
154
|
+
}),
|
|
143
155
|
/**
|
|
144
156
|
* Estilos para el indicador numérico de cada paso del Stepper.
|
|
145
157
|
*/
|
|
@@ -228,6 +240,7 @@ const stepperStyles = {
|
|
|
228
240
|
display: "flex",
|
|
229
241
|
alignItems: "center",
|
|
230
242
|
justifyContent: "center",
|
|
243
|
+
flexShrink: 0,
|
|
231
244
|
background: theme.vars.palette.primary.enabledOpacity,
|
|
232
245
|
borderRadius: theme.vars.size.borderRadius["r1-5"],
|
|
233
246
|
...getSizeStyles(theme, ownerState?.size || "medium", "box", (size) => ({
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { FormData, Step, StepWithIndex, VisibilityData } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* Obtiene todos los steps visibles que están antes de un step específico.
|
|
4
|
+
*
|
|
5
|
+
* Esta función es utilizada por la feature `initialStepKey` para determinar
|
|
6
|
+
* qué steps deben ser validados antes de poder navegar al step inicial deseado.
|
|
7
|
+
* @example
|
|
8
|
+
* // Si tenemos steps: [A, B (oculto), C, D] y queremos iniciar en D (índice 3)
|
|
9
|
+
* // Esta función retornará: [{ step: A, originalIndex: 0 }, { step: C, originalIndex: 2 }]
|
|
10
|
+
* // El step B se omite porque está oculto por su visibilityCondition
|
|
11
|
+
* @param initialStepIndex - El índice del step donde se desea iniciar.
|
|
12
|
+
* Los steps en este índice y posteriores NO se incluyen en el resultado.
|
|
13
|
+
* @param steps - Array completo de steps configurados en el Stepper.
|
|
14
|
+
* @param formData - Valores actuales del formulario para evaluar las condiciones de visibilidad.
|
|
15
|
+
* @param visibilityData - Datos adicionales para evaluar visibilidad (ej: objectId, accountId).
|
|
16
|
+
* @returns Array de steps visibles con su índice original, ordenados de menor a mayor índice.
|
|
17
|
+
* Retorna array vacío si initialStepIndex es 0 o no hay steps visibles antes.
|
|
18
|
+
*/
|
|
19
|
+
export declare const findAllVisibleStepsBefore: (initialStepIndex: number, steps: Step[], formData?: FormData, visibilityData?: VisibilityData) => StepWithIndex[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { e as evaluateVisibilityStepCondition } from "../evaluateVisibilityStepCondition/index.js";
|
|
2
|
+
const findAllVisibleStepsBefore = (initialStepIndex, steps, formData, visibilityData) => {
|
|
3
|
+
const visibleStepsBefore = [];
|
|
4
|
+
for (let currentIndex = 0; currentIndex < initialStepIndex && currentIndex < steps.length; currentIndex++) {
|
|
5
|
+
const currentStep = steps[currentIndex];
|
|
6
|
+
const isStepVisible = evaluateVisibilityStepCondition(
|
|
7
|
+
currentStep,
|
|
8
|
+
formData || {},
|
|
9
|
+
visibilityData
|
|
10
|
+
);
|
|
11
|
+
if (isStepVisible) {
|
|
12
|
+
visibleStepsBefore.push({
|
|
13
|
+
step: currentStep,
|
|
14
|
+
originalIndex: currentIndex
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return visibleStepsBefore;
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
findAllVisibleStepsBefore as f
|
|
22
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Step } from '../../types';
|
|
2
|
+
/**
|
|
3
|
+
* findStepIndexByKey - Encuentra el índice de un step por su key
|
|
4
|
+
* @param stepKey - La key del step a buscar
|
|
5
|
+
* @param steps - Array de steps
|
|
6
|
+
* @returns El índice del step, o -1 si no se encuentra
|
|
7
|
+
*/
|
|
8
|
+
export declare const findStepIndexByKey: (stepKey: string, steps: Step[]) => number;
|
|
@@ -6,3 +6,5 @@ export { isElementInViewport } from './isElementInViewport';
|
|
|
6
6
|
export { isLastVisibleValidStep } from './isLastVisibleValidStep';
|
|
7
7
|
export { parseWatchedValues } from './parseWatchedValues';
|
|
8
8
|
export { getInitialFieldValues } from './getInitialFieldValues';
|
|
9
|
+
export { findStepIndexByKey } from './findStepIndexByKey';
|
|
10
|
+
export { findAllVisibleStepsBefore } from './findAllVisibleStepsBefore';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
import { useFormContext, useWatch } from "react-hook-form";
|
|
3
|
+
import { shallow } from "zustand/shallow";
|
|
4
|
+
import { u as useStepper } from "../useStepper/index.js";
|
|
5
|
+
function useInitialStepKey() {
|
|
6
|
+
const { trigger, getValues } = useFormContext();
|
|
7
|
+
const hasAttemptedRef = useRef(false);
|
|
8
|
+
const statusLoad = useWatch({ name: "statusLoad" });
|
|
9
|
+
const { initialStepKey, initialStepKeyApplied, applyInitialStepKey } = useStepper(
|
|
10
|
+
(state) => ({
|
|
11
|
+
initialStepKey: state.initialStepKey,
|
|
12
|
+
initialStepKeyApplied: state.initialStepKeyApplied,
|
|
13
|
+
applyInitialStepKey: state.actions.applyInitialStepKey
|
|
14
|
+
}),
|
|
15
|
+
shallow
|
|
16
|
+
);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (statusLoad !== "ready" || !initialStepKey || initialStepKeyApplied || hasAttemptedRef.current) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
hasAttemptedRef.current = true;
|
|
22
|
+
const executeInitialStepKey = async () => {
|
|
23
|
+
const validateFieldsFn = async (fields) => {
|
|
24
|
+
if (fields.length === 0) {
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return trigger(fields);
|
|
28
|
+
};
|
|
29
|
+
const formData = getValues();
|
|
30
|
+
await applyInitialStepKey(validateFieldsFn, formData);
|
|
31
|
+
};
|
|
32
|
+
executeInitialStepKey();
|
|
33
|
+
}, [
|
|
34
|
+
statusLoad,
|
|
35
|
+
initialStepKey,
|
|
36
|
+
initialStepKeyApplied,
|
|
37
|
+
applyInitialStepKey,
|
|
38
|
+
trigger,
|
|
39
|
+
getValues
|
|
40
|
+
]);
|
|
41
|
+
}
|
|
42
|
+
export {
|
|
43
|
+
useInitialStepKey as u
|
|
44
|
+
};
|
|
@@ -7,6 +7,7 @@ var ContentSlots = /* @__PURE__ */ ((ContentSlots2) => {
|
|
|
7
7
|
ContentSlots2["stepArea"] = "stepArea";
|
|
8
8
|
ContentSlots2["step"] = "step";
|
|
9
9
|
ContentSlots2["stepName"] = "stepName";
|
|
10
|
+
ContentSlots2["stepNameText"] = "stepNameText";
|
|
10
11
|
ContentSlots2["indicator"] = "indicator";
|
|
11
12
|
ContentSlots2["textNumber"] = "textNumber";
|
|
12
13
|
return ContentSlots2;
|
|
@@ -22,6 +22,9 @@ export declare const StepStyled: import('@emotion/styled').StyledComponent<impor
|
|
|
22
22
|
export declare const StepNameStyled: import('@emotion/styled').StyledComponent<Pick<Omit<import('../../mui_extended/Typography/types').TypographyProps, "ref"> & import('react').RefAttributes<HTMLSpanElement>, "size" | "children" | "title" | "component" | "zIndex" | "id" | "disabled" | "paragraph" | "border" | "fontWeight" | "lineHeight" | "letterSpacing" | "fontSize" | "textTransform" | "fontFamily" | "typography" | "flex" | "variant" | "color" | "dataTestid" | "alignContent" | "alignItems" | "alignSelf" | "bottom" | "boxShadow" | "boxSizing" | "columnGap" | "content" | "display" | "flexBasis" | "flexDirection" | "flexGrow" | "flexShrink" | "flexWrap" | "fontStyle" | "gridAutoColumns" | "gridAutoFlow" | "gridAutoRows" | "gridTemplateAreas" | "gridTemplateColumns" | "gridTemplateRows" | "height" | "justifyContent" | "justifyItems" | "justifySelf" | "left" | "marginBlockEnd" | "marginBlockStart" | "marginBottom" | "marginInlineEnd" | "marginInlineStart" | "marginLeft" | "marginRight" | "marginTop" | "maxHeight" | "maxWidth" | "minHeight" | "minWidth" | "order" | "paddingBlockEnd" | "paddingBlockStart" | "paddingBottom" | "paddingInlineEnd" | "paddingInlineStart" | "paddingLeft" | "paddingRight" | "paddingTop" | "position" | "right" | "rowGap" | "textAlign" | "textOverflow" | "top" | "translate" | "visibility" | "whiteSpace" | "width" | "borderBottom" | "borderColor" | "borderLeft" | "borderRadius" | "borderRight" | "borderTop" | "gap" | "gridArea" | "gridColumn" | "gridRow" | "margin" | "marginBlock" | "marginInline" | "overflow" | "padding" | "paddingBlock" | "paddingInline" | "className" | "style" | "classes" | "sx" | "p" | "slot" | "defaultChecked" | "defaultValue" | "suppressContentEditableWarning" | "suppressHydrationWarning" | "accessKey" | "autoCapitalize" | "autoFocus" | "contentEditable" | "contextMenu" | "dir" | "draggable" | "enterKeyHint" | "hidden" | "lang" | "nonce" | "spellCheck" | "tabIndex" | "radioGroup" | "role" | "about" | "datatype" | "inlist" | "prefix" | "property" | "rel" | "resource" | "rev" | "typeof" | "vocab" | "autoCorrect" | "autoSave" | "itemProp" | "itemScope" | "itemType" | "itemID" | "itemRef" | "results" | "security" | "unselectable" | "inputMode" | "is" | "exportparts" | "part" | "aria-activedescendant" | "aria-atomic" | "aria-autocomplete" | "aria-braillelabel" | "aria-brailleroledescription" | "aria-busy" | "aria-checked" | "aria-colcount" | "aria-colindex" | "aria-colindextext" | "aria-colspan" | "aria-controls" | "aria-current" | "aria-describedby" | "aria-description" | "aria-details" | "aria-disabled" | "aria-dropeffect" | "aria-errormessage" | "aria-expanded" | "aria-flowto" | "aria-grabbed" | "aria-haspopup" | "aria-hidden" | "aria-invalid" | "aria-keyshortcuts" | "aria-label" | "aria-labelledby" | "aria-level" | "aria-live" | "aria-modal" | "aria-multiline" | "aria-multiselectable" | "aria-orientation" | "aria-owns" | "aria-placeholder" | "aria-posinset" | "aria-pressed" | "aria-readonly" | "aria-relevant" | "aria-required" | "aria-roledescription" | "aria-rowcount" | "aria-rowindex" | "aria-rowindextext" | "aria-rowspan" | "aria-selected" | "aria-setsize" | "aria-sort" | "aria-valuemax" | "aria-valuemin" | "aria-valuenow" | "aria-valuetext" | "dangerouslySetInnerHTML" | "onCopy" | "onCopyCapture" | "onCut" | "onCutCapture" | "onPaste" | "onPasteCapture" | "onCompositionEnd" | "onCompositionEndCapture" | "onCompositionStart" | "onCompositionStartCapture" | "onCompositionUpdate" | "onCompositionUpdateCapture" | "onFocus" | "onFocusCapture" | "onBlur" | "onBlurCapture" | "onChange" | "onChangeCapture" | "onBeforeInput" | "onBeforeInputCapture" | "onInput" | "onInputCapture" | "onReset" | "onResetCapture" | "onSubmit" | "onSubmitCapture" | "onInvalid" | "onInvalidCapture" | "onLoad" | "onLoadCapture" | "onError" | "onErrorCapture" | "onKeyDown" | "onKeyDownCapture" | "onKeyPress" | "onKeyPressCapture" | "onKeyUp" | "onKeyUpCapture" | "onAbort" | "onAbortCapture" | "onCanPlay" | "onCanPlayCapture" | "onCanPlayThrough" | "onCanPlayThroughCapture" | "onDurationChange" | "onDurationChangeCapture" | "onEmptied" | "onEmptiedCapture" | "onEncrypted" | "onEncryptedCapture" | "onEnded" | "onEndedCapture" | "onLoadedData" | "onLoadedDataCapture" | "onLoadedMetadata" | "onLoadedMetadataCapture" | "onLoadStart" | "onLoadStartCapture" | "onPause" | "onPauseCapture" | "onPlay" | "onPlayCapture" | "onPlaying" | "onPlayingCapture" | "onProgress" | "onProgressCapture" | "onRateChange" | "onRateChangeCapture" | "onSeeked" | "onSeekedCapture" | "onSeeking" | "onSeekingCapture" | "onStalled" | "onStalledCapture" | "onSuspend" | "onSuspendCapture" | "onTimeUpdate" | "onTimeUpdateCapture" | "onVolumeChange" | "onVolumeChangeCapture" | "onWaiting" | "onWaitingCapture" | "onAuxClick" | "onAuxClickCapture" | "onClick" | "onClickCapture" | "onContextMenu" | "onContextMenuCapture" | "onDoubleClick" | "onDoubleClickCapture" | "onDrag" | "onDragCapture" | "onDragEnd" | "onDragEndCapture" | "onDragEnter" | "onDragEnterCapture" | "onDragExit" | "onDragExitCapture" | "onDragLeave" | "onDragLeaveCapture" | "onDragOver" | "onDragOverCapture" | "onDragStart" | "onDragStartCapture" | "onDrop" | "onDropCapture" | "onMouseDown" | "onMouseDownCapture" | "onMouseEnter" | "onMouseLeave" | "onMouseMove" | "onMouseMoveCapture" | "onMouseOut" | "onMouseOutCapture" | "onMouseOver" | "onMouseOverCapture" | "onMouseUp" | "onMouseUpCapture" | "onSelect" | "onSelectCapture" | "onTouchCancel" | "onTouchCancelCapture" | "onTouchEnd" | "onTouchEndCapture" | "onTouchMove" | "onTouchMoveCapture" | "onTouchStart" | "onTouchStartCapture" | "onPointerDown" | "onPointerDownCapture" | "onPointerMove" | "onPointerMoveCapture" | "onPointerUp" | "onPointerUpCapture" | "onPointerCancel" | "onPointerCancelCapture" | "onPointerEnter" | "onPointerLeave" | "onPointerOver" | "onPointerOverCapture" | "onPointerOut" | "onPointerOutCapture" | "onGotPointerCapture" | "onGotPointerCaptureCapture" | "onLostPointerCapture" | "onLostPointerCaptureCapture" | "onScroll" | "onScrollCapture" | "onWheel" | "onWheelCapture" | "onAnimationStart" | "onAnimationStartCapture" | "onAnimationEnd" | "onAnimationEndCapture" | "onAnimationIteration" | "onAnimationIterationCapture" | "onTransitionEnd" | "onTransitionEndCapture" | "bgcolor" | "m" | "mt" | "mr" | "mb" | "ml" | "mx" | "marginX" | "my" | "marginY" | "pt" | "pr" | "pb" | "pl" | "px" | "paddingX" | "py" | "paddingY" | "displayPrint" | "align" | "htmlFor" | "gutterBottom" | "noWrap" | "variantMapping" | "skeletonWidth" | "skeletonRows" | "ellipsis" | keyof import('react').RefAttributes<HTMLSpanElement>> & import('@mui/system').MUIStyledCommonProps<import('@mui/material/styles').Theme> & Record<string, unknown> & {
|
|
23
23
|
ownerState?: (Partial<import('../types').StepperOwnerState> & Record<string, unknown>) | undefined;
|
|
24
24
|
}, {}, {}>;
|
|
25
|
+
export declare const StepNameTextStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material/styles').Theme> & Record<string, unknown> & {
|
|
26
|
+
ownerState?: (Partial<import('../types').StepperOwnerState> & Record<string, unknown>) | undefined;
|
|
27
|
+
}, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
|
|
25
28
|
export declare const IndicatorStyled: import('@emotion/styled').StyledComponent<import('@mui/system').MUIStyledCommonProps<import('@mui/material/styles').Theme> & Record<string, unknown> & {
|
|
26
29
|
ownerState?: (Partial<import('../types').StepperOwnerState> & Record<string, unknown>) | undefined;
|
|
27
30
|
}, Pick<import('react').DetailedHTMLProps<import('react').HTMLAttributes<HTMLDivElement>, HTMLDivElement>, keyof import('react').ClassAttributes<HTMLDivElement> | keyof import('react').HTMLAttributes<HTMLDivElement>>, {}>;
|
|
@@ -32,6 +32,10 @@ const StepNameStyled = styled(Typography, {
|
|
|
32
32
|
name: STEPPER_PREFIX_NAME,
|
|
33
33
|
slot: ContentSlots.stepName
|
|
34
34
|
})(stepperStyles.stepName);
|
|
35
|
+
const StepNameTextStyled = styled("div", {
|
|
36
|
+
name: STEPPER_PREFIX_NAME,
|
|
37
|
+
slot: ContentSlots.stepNameText
|
|
38
|
+
})(stepperStyles.stepNameText);
|
|
35
39
|
const IndicatorStyled = styled("div", {
|
|
36
40
|
name: STEPPER_PREFIX_NAME,
|
|
37
41
|
slot: ContentSlots.indicator
|
|
@@ -93,15 +97,16 @@ export {
|
|
|
93
97
|
WrapperIconStyled as W,
|
|
94
98
|
StepStyled as a,
|
|
95
99
|
StepNameStyled as b,
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
100
|
+
StepNameTextStyled as c,
|
|
101
|
+
IconStyled as d,
|
|
102
|
+
WrapperTitleStyled as e,
|
|
103
|
+
TitleStyled as f,
|
|
104
|
+
ContentAreaHeaderStyled as g,
|
|
105
|
+
ContentAreaBodyStyled as h,
|
|
106
|
+
StepperFooterLeftActionsStyled as i,
|
|
107
|
+
StepperFooterRightActionsStyled as j,
|
|
108
|
+
StepperFooterSectionStyled as k,
|
|
109
|
+
StepContentStyled as l,
|
|
110
|
+
StepperRootStyled as m,
|
|
111
|
+
ContentSectionStyled as n
|
|
107
112
|
};
|
|
@@ -12,6 +12,7 @@ const StepperProvider = (props) => {
|
|
|
12
12
|
indicatorType = "number",
|
|
13
13
|
orientation = "horizontal",
|
|
14
14
|
visibilityData,
|
|
15
|
+
initialStepKey,
|
|
15
16
|
children
|
|
16
17
|
} = props;
|
|
17
18
|
const stepperStoreRef = useRef();
|
|
@@ -25,7 +26,8 @@ const StepperProvider = (props) => {
|
|
|
25
26
|
ownerState: {},
|
|
26
27
|
indicatorType,
|
|
27
28
|
orientation,
|
|
28
|
-
visibilityData
|
|
29
|
+
visibilityData,
|
|
30
|
+
initialStepKey
|
|
29
31
|
},
|
|
30
32
|
storeDevtoolsEnabled
|
|
31
33
|
);
|
|
@@ -2,6 +2,9 @@ import { createStore } from "zustand";
|
|
|
2
2
|
import { devtools } from "zustand/middleware";
|
|
3
3
|
import { immer } from "zustand/middleware/immer";
|
|
4
4
|
import { S as STEPPER_STORE_ID } from "../../constants.js";
|
|
5
|
+
import { f as findStepIndexByKey } from "../../helpers/findStepIndexByKey/index.js";
|
|
6
|
+
import { e as evaluateVisibilityStepCondition } from "../../helpers/evaluateVisibilityStepCondition/index.js";
|
|
7
|
+
import { f as findAllVisibleStepsBefore } from "../../helpers/findAllVisibleStepsBefore/index.js";
|
|
5
8
|
import { f as findNextVisibleValidStep } from "../../helpers/findNextVisibleValidStep/index.js";
|
|
6
9
|
import { f as findPrevVisibleValidStep } from "../../helpers/findPrevVisibleValidStep/index.js";
|
|
7
10
|
const createDevtools = (immerMiddlewere, config) => {
|
|
@@ -16,6 +19,7 @@ const createStepperStore = (initProps, storeDevtoolsEnabled = false) => {
|
|
|
16
19
|
currentStep: 0,
|
|
17
20
|
stepValidationStatus: {},
|
|
18
21
|
isValidating: false,
|
|
22
|
+
initialStepKeyApplied: false,
|
|
19
23
|
...initProps
|
|
20
24
|
};
|
|
21
25
|
return createStore(
|
|
@@ -128,6 +132,7 @@ const createStepperStore = (initProps, storeDevtoolsEnabled = false) => {
|
|
|
128
132
|
set((state) => {
|
|
129
133
|
state.stepValidationStatus = {};
|
|
130
134
|
state.isValidating = false;
|
|
135
|
+
state.initialStepKeyApplied = false;
|
|
131
136
|
const firstVisibleStepIndex = findNextVisibleValidStep(
|
|
132
137
|
-1,
|
|
133
138
|
// Comenzar desde -1 para encontrar el primer step visible
|
|
@@ -137,6 +142,71 @@ const createStepperStore = (initProps, storeDevtoolsEnabled = false) => {
|
|
|
137
142
|
);
|
|
138
143
|
state.currentStep = firstVisibleStepIndex < state.steps.length ? firstVisibleStepIndex : 0;
|
|
139
144
|
});
|
|
145
|
+
},
|
|
146
|
+
/**
|
|
147
|
+
* applyInitialStepKey - Valida los steps anteriores y navega al step indicado por initialStepKey.
|
|
148
|
+
* Si algún step anterior tiene errores, navega al primer step con errores.
|
|
149
|
+
*/
|
|
150
|
+
applyInitialStepKey: async (validateFieldsFn, formData) => {
|
|
151
|
+
const state = get();
|
|
152
|
+
const { initialStepKey, steps, visibilityData, initialStepKeyApplied } = state;
|
|
153
|
+
if (!initialStepKey || initialStepKey.trim() === "" || initialStepKeyApplied) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const initialStepIndex = findStepIndexByKey(initialStepKey, steps);
|
|
157
|
+
if (initialStepIndex === -1) {
|
|
158
|
+
const availableKeys = steps.map((s) => s.key).join(", ");
|
|
159
|
+
throw new Error(
|
|
160
|
+
`Stepper: initialStepKey "${initialStepKey}" no corresponde a ningún step. Keys disponibles: [${availableKeys}]`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
const initialStep = steps[initialStepIndex];
|
|
164
|
+
if (!evaluateVisibilityStepCondition(initialStep, formData, visibilityData)) {
|
|
165
|
+
console.warn(
|
|
166
|
+
`Stepper: initialStepKey "${initialStepKey}" apunta a un step oculto. Iniciando en step 0.`
|
|
167
|
+
);
|
|
168
|
+
set((draft) => {
|
|
169
|
+
draft.initialStepKeyApplied = true;
|
|
170
|
+
});
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (initialStepIndex === 0) {
|
|
174
|
+
set((draft) => {
|
|
175
|
+
draft.initialStepKeyApplied = true;
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const previousVisibleSteps = findAllVisibleStepsBefore(
|
|
180
|
+
initialStepIndex,
|
|
181
|
+
steps,
|
|
182
|
+
formData,
|
|
183
|
+
visibilityData
|
|
184
|
+
);
|
|
185
|
+
for (const { step, originalIndex } of previousVisibleSteps) {
|
|
186
|
+
const fieldsToValidate = step.validationFields || [];
|
|
187
|
+
if (fieldsToValidate.length === 0) {
|
|
188
|
+
set((draft) => {
|
|
189
|
+
draft.stepValidationStatus[originalIndex] = true;
|
|
190
|
+
});
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const isValid = await validateFieldsFn(fieldsToValidate);
|
|
194
|
+
if (!isValid) {
|
|
195
|
+
set((draft) => {
|
|
196
|
+
draft.currentStep = originalIndex;
|
|
197
|
+
draft.stepValidationStatus[originalIndex] = false;
|
|
198
|
+
draft.initialStepKeyApplied = true;
|
|
199
|
+
});
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
set((draft) => {
|
|
203
|
+
draft.stepValidationStatus[originalIndex] = true;
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
set((draft) => {
|
|
207
|
+
draft.currentStep = initialStepIndex;
|
|
208
|
+
draft.initialStepKeyApplied = true;
|
|
209
|
+
});
|
|
140
210
|
}
|
|
141
211
|
}
|
|
142
212
|
})),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { Step, StepperOwnerState, StepperProps } from '../types';
|
|
3
|
-
export interface StepperState extends Pick<StepperProps, 'storeId' | 'visibleTitle' | 'steps' | 'indicatorType' | 'orientation' | 'size' | 'visibilityData'> {
|
|
3
|
+
export interface StepperState extends Pick<StepperProps, 'storeId' | 'visibleTitle' | 'steps' | 'indicatorType' | 'orientation' | 'size' | 'visibilityData' | 'initialStepKey'> {
|
|
4
4
|
/**
|
|
5
5
|
* "ownerState" estado a nivel de clases del componente
|
|
6
6
|
*/
|
|
@@ -18,6 +18,10 @@ export interface StepperState extends Pick<StepperProps, 'storeId' | 'visibleTit
|
|
|
18
18
|
* "isValidating" indica si el stepper está en proceso de validación
|
|
19
19
|
*/
|
|
20
20
|
isValidating: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Indica si initialStepKey ya fue aplicado. Previene re-aplicación después de navegación.
|
|
23
|
+
*/
|
|
24
|
+
initialStepKeyApplied: boolean;
|
|
21
25
|
}
|
|
22
26
|
export interface StepperStateWithActions extends StepperState {
|
|
23
27
|
actions: {
|
|
@@ -55,9 +59,15 @@ export interface StepperStateWithActions extends StepperState {
|
|
|
55
59
|
* resetStepper - Resetea el Stepper a su estado inicial
|
|
56
60
|
*/
|
|
57
61
|
resetStepper: () => void;
|
|
62
|
+
/**
|
|
63
|
+
* Aplica initialStepKey validando los steps anteriores.
|
|
64
|
+
* @param validateFieldsFn - Función que valida campos específicos usando RHF trigger()
|
|
65
|
+
* @param formData - Valores actuales del formulario
|
|
66
|
+
*/
|
|
67
|
+
applyInitialStepKey: (validateFieldsFn: (fields: string[]) => Promise<boolean>, formData: Record<string, any>) => Promise<void>;
|
|
58
68
|
};
|
|
59
69
|
}
|
|
60
70
|
export interface StepperContextProps extends StepperProps {
|
|
61
71
|
children: ReactNode;
|
|
62
72
|
}
|
|
63
|
-
export type InitialStoreProps = Pick<StepperState, 'ownerState' | 'storeId' | 'steps' | 'visibleTitle' | 'indicatorType' | 'orientation' | 'visibilityData'>;
|
|
73
|
+
export type InitialStoreProps = Pick<StepperState, 'ownerState' | 'storeId' | 'steps' | 'visibleTitle' | 'indicatorType' | 'orientation' | 'visibilityData' | 'initialStepKey'>;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { u as useStepper } from "../../hooks/useStepper/index.js";
|
|
3
|
-
import {
|
|
3
|
+
import { u as useInitialStepKey } from "../../hooks/useInitialStepKey/index.js";
|
|
4
|
+
import { C as ContentAreaStyled, g as ContentAreaHeaderStyled, h as ContentAreaBodyStyled } from "../../slots/StepperSlot.js";
|
|
4
5
|
import { W as WrapperIcon } from "./subcomponents/WrapperIcon/index.js";
|
|
5
6
|
import { W as WrapperTitle } from "./subcomponents/WrapperTitle/index.js";
|
|
6
7
|
function ContentArea(props) {
|
|
@@ -8,6 +9,7 @@ function ContentArea(props) {
|
|
|
8
9
|
const { orientation } = useStepper((state) => ({
|
|
9
10
|
orientation: state.orientation
|
|
10
11
|
}));
|
|
12
|
+
useInitialStepKey();
|
|
11
13
|
const ownerState = {
|
|
12
14
|
orientation
|
|
13
15
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
|
-
import { W as WrapperIconStyled,
|
|
3
|
+
import { W as WrapperIconStyled, d as IconStyled } from "../../../../slots/StepperSlot.js";
|
|
4
4
|
import { p as pathIcons } from "../../../../icons.js";
|
|
5
5
|
import { u as useStepper } from "../../../../hooks/useStepper/index.js";
|
|
6
6
|
import { useEnvironment } from "@m4l/core";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from "react";
|
|
3
3
|
import { u as useStepper } from "../../../../hooks/useStepper/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { e as WrapperTitleStyled, f as TitleStyled, D as DescriptionStyled } from "../../../../slots/StepperSlot.js";
|
|
5
5
|
function WrapperTitle() {
|
|
6
6
|
const { steps, currentStep } = useStepper((state) => ({
|
|
7
7
|
steps: state.steps,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { S as StepAreaStyled, a as StepStyled, b as StepNameStyled } from "../../slots/StepperSlot.js";
|
|
2
|
+
import { S as StepAreaStyled, a as StepStyled, b as StepNameStyled, c as StepNameTextStyled } from "../../slots/StepperSlot.js";
|
|
3
3
|
import { I as Indicator } from "./subcomponents/Inidicator/index.js";
|
|
4
4
|
import { u as useStepArea } from "./hooks/useStepArea.js";
|
|
5
5
|
import { u as useVisibileSteps } from "./hooks/useVisibileSteps.js";
|
|
@@ -39,7 +39,7 @@ function StepArea() {
|
|
|
39
39
|
originalStepIndex: originalIndex,
|
|
40
40
|
isStepVisible
|
|
41
41
|
},
|
|
42
|
-
children: step.title
|
|
42
|
+
children: /* @__PURE__ */ jsx(StepNameTextStyled, { ownerState: { orientation }, children: step.title })
|
|
43
43
|
}
|
|
44
44
|
),
|
|
45
45
|
/* @__PURE__ */ jsx(
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { l as StepContentStyled } from "../../../../slots/StepperSlot.js";
|
|
3
3
|
import { u as useIsStepVisible } from "./hooks/useIsStepVisible.js";
|
|
4
4
|
function Step(props) {
|
|
5
5
|
const { stepKey, children } = props;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo, Children, isValidElement } from "react";
|
|
3
|
-
import {
|
|
3
|
+
import { k as StepperFooterSectionStyled } from "../../slots/StepperSlot.js";
|
|
4
4
|
import { S as StepperFooterLeftActions } from "./subcomponents/StepperFooterLeftActions/index.js";
|
|
5
5
|
import { S as StepperFooterRightActions } from "./subcomponents/StepperFooterRightActions/index.js";
|
|
6
6
|
function StepperFooter(props) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { i as StepperFooterLeftActionsStyled } from "../../../../slots/StepperSlot.js";
|
|
3
3
|
function StepperFooterLeftActions(props) {
|
|
4
4
|
const { children } = props;
|
|
5
5
|
return /* @__PURE__ */ jsx(StepperFooterLeftActionsStyled, { children });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import React, { useState, useEffect, useMemo } from "react";
|
|
3
3
|
import { u as useIsLastVisibleValidStep } from "../../../../hooks/useIsLastVisibleValidStep/index.js";
|
|
4
|
-
import {
|
|
4
|
+
import { j as StepperFooterRightActionsStyled } from "../../../../slots/StepperSlot.js";
|
|
5
5
|
import { S as StepperSubmitButton } from "../../../StepperButtons/StepperSubmitButton/index.js";
|
|
6
6
|
import { S as StepperNextButton } from "../../../StepperButtons/StepperNextButton/index.js";
|
|
7
7
|
function StepperFooterRightActions(props) {
|
|
@@ -83,6 +83,13 @@ export interface StepperProps {
|
|
|
83
83
|
* Clase personalizada para el Stepper.
|
|
84
84
|
*/
|
|
85
85
|
className?: string;
|
|
86
|
+
/**
|
|
87
|
+
* Key del step en el que se desea iniciar el Stepper.
|
|
88
|
+
* Si se proporciona, valida los steps anteriores antes de navegar al step indicado.
|
|
89
|
+
* Si algún step anterior tiene errores, inicia en el primer step con errores.
|
|
90
|
+
* Lanza Error si la key no corresponde a ningún step.
|
|
91
|
+
*/
|
|
92
|
+
initialStepKey?: string;
|
|
86
93
|
}
|
|
87
94
|
/**
|
|
88
95
|
* Props del StepperContent
|
|
@@ -172,5 +179,20 @@ export interface StepperOwnerState extends Pick<StepperProps, 'visibleTitle'>, R
|
|
|
172
179
|
stepValidationStatus?: Record<number, boolean>;
|
|
173
180
|
isStepVisible?: boolean;
|
|
174
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Representa un step junto con su posición original en el array de steps.
|
|
184
|
+
* Se usa para mantener la referencia al índice original después de filtrar steps ocultos.
|
|
185
|
+
*/
|
|
186
|
+
export interface StepWithIndex {
|
|
187
|
+
/**
|
|
188
|
+
* El objeto Step con toda su configuración (key, title, validationFields, etc.)
|
|
189
|
+
*/
|
|
190
|
+
step: Step;
|
|
191
|
+
/**
|
|
192
|
+
* El índice del step en el array original de steps.
|
|
193
|
+
* Es necesario para actualizar correctamente el stepValidationStatus del store.
|
|
194
|
+
*/
|
|
195
|
+
originalIndex: number;
|
|
196
|
+
}
|
|
175
197
|
export type StepperSlotsType = StepperSlots | ContentSlots | ContentAreaSlots | StepperFooterSlots;
|
|
176
198
|
export type StepperStyles = M4LOverridesStyleRules<StepperSlotsType, typeof STEPPER_PREFIX_NAME, Theme>;
|