@snack-uikit/stepper
Advanced tools
Comparing version
@@ -16,3 +16,3 @@ import { ReactElement } from 'react'; | ||
* Render function. Принимает аргументы: `stepper` - JSX-элемент степпера, | ||
* `goNext` - перейти на след. шаг, `goPrev` - перейти на пред. шаг, `setValidation` - установить состояние валидации для текущего шага, `isCompleted` - окончен ли процесс, `currentStepIndex` - индекс текущего шага, `stepCount` - кол-во шагов. | ||
* `goNext` - перейти на след. шаг, `goPrev` - перейти на пред. шаг, `resetValidation` - сбросить состояние валидации для текущего шага, `setValidator` добавляет функцию-валидатор, которая принимает в параметры индекс текущего шага, `isCompleted` - окончен ли процесс, `currentStepIndex` - индекс текущего шага, `stepCount` - кол-во шагов. | ||
* @type ({stepper, ...api}) => ReactElement | ||
@@ -19,0 +19,0 @@ */ |
@@ -16,3 +16,3 @@ var __rest = (this && this.__rest) || function (s, e) { | ||
import { extractSupportProps } from '@snack-uikit/utils'; | ||
import { STEP_STATE, STEP_VALIDATION_RESULT } from '../../constants'; | ||
import { STEP_STATE } from '../../constants'; | ||
import { Step } from '../../helperComponents'; | ||
@@ -27,2 +27,3 @@ import { StepperContext } from '../../StepperContext'; | ||
const [isCompleted, setIsCompleted] = useState(isCompletedByDefault); | ||
const [stepsValidator, setStepsValidator] = useState(); | ||
useEffect(() => { | ||
@@ -40,3 +41,3 @@ onCompleteChange === null || onCompleteChange === void 0 ? void 0 : onCompleteChange(isCompleted); | ||
const goNext = useCallback(() => { | ||
var _a, _b; | ||
var _a, _b, _c; | ||
if (currentStepIndex >= steps.length || isCompleted) { | ||
@@ -46,27 +47,25 @@ return; | ||
const currentStep = steps[currentStepIndex]; | ||
const stepperValidPromise = (_b = (_a = currentStep.validation) === null || _a === void 0 ? void 0 : _a.call(currentStep)) !== null && _b !== void 0 ? _b : Promise.resolve(STEP_STATE.Completed); | ||
setCurrentStepState(STEP_STATE.Loading); | ||
stepperValidPromise | ||
.then(validationResult => { | ||
switch (validationResult) { | ||
case STEP_VALIDATION_RESULT.Completed: | ||
if (currentStepIndex === steps.length - 1) { | ||
// завершился последний шаг | ||
setCurrentStepState(STEP_STATE.Completed); | ||
setIsCompleted(true); | ||
} | ||
else { | ||
setCurrentStepIndex(currentStepIndex + 1); | ||
setCurrentStepState(STEP_STATE.Current); | ||
} | ||
return; | ||
case STEP_VALIDATION_RESULT.Rejected: | ||
setCurrentStepState(STEP_STATE.Rejected); | ||
return; | ||
default: | ||
setCurrentStepState(STEP_STATE.Current); | ||
Promise.all([ | ||
(_b = (_a = currentStep.validation) === null || _a === void 0 ? void 0 : _a.call(currentStep)) !== null && _b !== void 0 ? _b : Promise.resolve(true), | ||
(_c = stepsValidator === null || stepsValidator === void 0 ? void 0 : stepsValidator.value(currentStepIndex)) !== null && _c !== void 0 ? _c : Promise.resolve(true), | ||
]) | ||
.then(results => results.every(isValid => isValid)) | ||
.catch(() => false) | ||
.then(isValid => { | ||
if (!isValid) { | ||
setCurrentStepState(STEP_STATE.Rejected); | ||
return; | ||
} | ||
}) | ||
.catch(() => setCurrentStepState(STEP_STATE.Rejected)); | ||
}, [currentStepIndex, isCompleted, setCurrentStepIndex, steps]); | ||
if (currentStepIndex === steps.length - 1) { | ||
// завершился последний шаг | ||
setCurrentStepState(STEP_STATE.Completed); | ||
setIsCompleted(true); | ||
} | ||
else { | ||
setCurrentStepIndex(currentStepIndex + 1); | ||
setCurrentStepState(STEP_STATE.Current); | ||
} | ||
}); | ||
}, [currentStepIndex, isCompleted, setCurrentStepIndex, steps, stepsValidator]); | ||
const goPrev = useCallback((index = currentStepIndex - 1) => { | ||
@@ -98,14 +97,22 @@ if (currentStepIndex === 0 || index < 0 || index > currentStepIndex) { | ||
}), [steps, currentStepIndex, goPrev, currentStepState, isCompleted, goNext]); | ||
const setValidation = useCallback((isValid) => { | ||
const setValidationValue = (isValid) => setCurrentStepState(isValid ? STEP_STATE.Current : STEP_STATE.Rejected); | ||
if (isValid instanceof Promise) { | ||
setCurrentStepState(STEP_STATE.Loading); | ||
isValid.then(setValidationValue).catch(() => setValidationValue(false)); | ||
return; | ||
const resetValidation = useCallback(() => { | ||
if (currentStepState === STEP_STATE.Rejected) { | ||
setCurrentStepState(STEP_STATE.Current); | ||
} | ||
setValidationValue(isValid); | ||
}, [currentStepState]); | ||
const setValidator = useCallback((validator) => { | ||
setStepsValidator({ value: validator }); | ||
}, []); | ||
const stepper = (_jsx("div", Object.assign({ className: cn(styles.stepper, className) }, extractSupportProps(props), { children: stepsView.map((step, index) => (_jsx(Step, { step: step, "data-test-id": props['data-test-id'], hideTailLine: index === steps.length - 1 }, step.title + index))) }))); | ||
const stepperApi = { goNext, goPrev, currentStepIndex, isCompleted, setValidation, stepCount: steps.length }; | ||
return _jsx(StepperContext.Provider, { value: stepperApi, children: children(Object.assign({ stepper }, stepperApi)) }); | ||
const stepperApi = { | ||
goNext, | ||
goPrev, | ||
currentStepIndex, | ||
isCompleted, | ||
resetValidation, | ||
stepCount: steps.length, | ||
stepper, | ||
setValidator, | ||
}; | ||
return _jsx(StepperContext.Provider, { value: stepperApi, children: children(stepperApi) }); | ||
} |
@@ -8,5 +8,1 @@ export declare const STEP_STATE: { | ||
}; | ||
export declare const STEP_VALIDATION_RESULT: { | ||
readonly Completed: "completed"; | ||
readonly Rejected: "rejected"; | ||
}; |
@@ -8,5 +8,1 @@ export const STEP_STATE = { | ||
}; | ||
export const STEP_VALIDATION_RESULT = { | ||
Completed: 'completed', | ||
Rejected: 'rejected', | ||
}; |
@@ -0,3 +1,5 @@ | ||
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime"; | ||
import { createContext, useContext } from 'react'; | ||
export const StepperContext = createContext({ | ||
stepper: _jsx(_Fragment, {}), | ||
stepCount: 0, | ||
@@ -12,6 +14,9 @@ isCompleted: false, | ||
}, | ||
setValidation() { | ||
resetValidation() { | ||
/* stub */ | ||
}, | ||
setValidator() { | ||
/* stub */ | ||
}, | ||
}); | ||
export const useStepperApi = () => useContext(StepperContext); |
@@ -0,9 +1,10 @@ | ||
import { JSX } from 'react'; | ||
import { ValueOf } from '@snack-uikit/utils'; | ||
import { STEP_STATE, STEP_VALIDATION_RESULT } from './constants'; | ||
import { STEP_STATE } from './constants'; | ||
export type StepState = ValueOf<typeof STEP_STATE>; | ||
export type StepValidationResult = ValueOf<typeof STEP_VALIDATION_RESULT>; | ||
export type StepsValidator = (stepIndex: number) => Promise<boolean>; | ||
export type StepData = { | ||
title: string; | ||
description?: string; | ||
validation?(): Promise<StepValidationResult>; | ||
validation?(): Promise<boolean>; | ||
}; | ||
@@ -16,5 +17,7 @@ export type StepViewData = StepData & { | ||
export type StepperApi = { | ||
stepper: JSX.Element; | ||
goNext(): void; | ||
goPrev(): void; | ||
setValidation(isValid: boolean | Promise<boolean>): void; | ||
resetValidation(): void; | ||
setValidator(validator: StepsValidator): void; | ||
isCompleted: boolean; | ||
@@ -21,0 +24,0 @@ currentStepIndex: number; |
@@ -7,3 +7,3 @@ { | ||
"title": "Stepper", | ||
"version": "0.5.10-preview-8e2ed733.0", | ||
"version": "0.5.10-preview-96ca8003.0", | ||
"sideEffects": [ | ||
@@ -43,3 +43,3 @@ "*.css", | ||
}, | ||
"gitHead": "98c8bfc998da448c39972953e87601d5174e1e23" | ||
"gitHead": "f34f4124d15e2215a4eca379bb530b21cf63b87b" | ||
} |
@@ -51,3 +51,3 @@ # Stepper | ||
|------|------|---------------|-------------| | ||
| children* | `({stepper, ...api}) => ReactElement` | - | Render function. Принимает аргументы: `stepper` - JSX-элемент степпера, `goNext` - перейти на след. шаг, `goPrev` - перейти на пред. шаг, `setValidation` - установить состояние валидации для текущего шага, `isCompleted` - окончен ли процесс, `currentStepIndex` - индекс текущего шага, `stepCount` - кол-во шагов. | | ||
| children* | `({stepper, ...api}) => ReactElement` | - | Render function. Принимает аргументы: `stepper` - JSX-элемент степпера, `goNext` - перейти на след. шаг, `goPrev` - перейти на пред. шаг, `resetValidation` - сбросить состояние валидации для текущего шага, `setValidator` добавляет функцию-валидатор, которая принимает в параметры индекс текущего шага, `isCompleted` - окончен ли процесс, `currentStepIndex` - индекс текущего шага, `stepCount` - кол-во шагов. | | ||
| steps* | `StepData[]` | - | Массив шагов | | ||
@@ -54,0 +54,0 @@ | defaultCurrentStepIndex | `number` | - | Индекс текущего шага по-дефолту | |
@@ -8,6 +8,1 @@ export const STEP_STATE = { | ||
} as const; | ||
export const STEP_VALIDATION_RESULT = { | ||
Completed: 'completed', | ||
Rejected: 'rejected', | ||
} as const; |
@@ -0,8 +1,10 @@ | ||
import { JSX } from 'react'; | ||
import { ValueOf } from '@snack-uikit/utils'; | ||
import { STEP_STATE, STEP_VALIDATION_RESULT } from './constants'; | ||
import { STEP_STATE } from './constants'; | ||
export type StepState = ValueOf<typeof STEP_STATE>; | ||
export type StepValidationResult = ValueOf<typeof STEP_VALIDATION_RESULT>; | ||
export type StepsValidator = (stepIndex: number) => Promise<boolean>; | ||
@@ -12,3 +14,3 @@ export type StepData = { | ||
description?: string; | ||
validation?(): Promise<StepValidationResult>; | ||
validation?(): Promise<boolean>; | ||
}; | ||
@@ -23,5 +25,7 @@ | ||
export type StepperApi = { | ||
stepper: JSX.Element; | ||
goNext(): void; | ||
goPrev(): void; | ||
setValidation(isValid: boolean | Promise<boolean>): void; | ||
resetValidation(): void; | ||
setValidator(validator: StepsValidator): void; | ||
isCompleted: boolean; | ||
@@ -28,0 +32,0 @@ currentStepIndex: number; |
Sorry, the diff of this file is not supported yet
60161
0.15%713
2.3%