@snack-uikit/stepper 0.5.10-preview-96ca8003.0 → 0.5.10-preview-fa22a93d.0
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/README.md +9 -7
- package/dist/components/Stepper/Stepper.d.ts +5 -3
- package/dist/components/Stepper/Stepper.js +18 -12
- package/dist/types.d.ts +3 -4
- package/package.json +2 -2
- package/src/components/Stepper/Stepper.tsx +37 -31
- package/src/types.ts +3 -4
package/README.md
CHANGED
|
@@ -10,27 +10,28 @@
|
|
|
10
10
|
#### Использование
|
|
11
11
|
|
|
12
12
|
Компонент принимает массив шагов. В проп children принимает render-колбек, в который отдает сам компонент, методы управления и поля состояния.
|
|
13
|
-
При вызове метода `goNext` вызывается валидация текущего шага. Функция валидации должна вернуть результат валидации в Promise
|
|
13
|
+
При вызове метода `goNext` вызывается валидация текущего шага. Функция валидации принимает индекс текущего шага и должна вернуть результат валидации в Promise<boolean>. При успешной валдиции компонент переходит на следующий шаг, а при ошибке остается на текущем.
|
|
14
14
|
При вызове метода `goPrev` компонент переходит на предыдущий шаг.
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
```tsx
|
|
18
18
|
const steps = [
|
|
19
|
-
{ title: 'Step #1'
|
|
20
|
-
{ title: 'Step #2'
|
|
21
|
-
{ title: 'Step #3'
|
|
22
|
-
{ title: 'Step #4'
|
|
19
|
+
{ title: 'Step #1' },
|
|
20
|
+
{ title: 'Step #2' },
|
|
21
|
+
{ title: 'Step #3' },
|
|
22
|
+
{ title: 'Step #4' },
|
|
23
23
|
];
|
|
24
24
|
|
|
25
25
|
// ...
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
|
-
<Stepper steps={steps}>
|
|
28
|
+
<Stepper steps={steps} validator={validatorFunction}>
|
|
29
29
|
{({
|
|
30
30
|
stepper, // JSX элемент компонента
|
|
31
31
|
isCompleted, // состояние завершенности всей цепочки
|
|
32
32
|
goNext, // функция перехода к след. шагу
|
|
33
33
|
goPrev, // функция перехода к предыдущему шагу
|
|
34
|
+
setValidator, // функция установки валидатора
|
|
34
35
|
}) => (
|
|
35
36
|
<>
|
|
36
37
|
{stepper}
|
|
@@ -48,9 +49,10 @@ return (
|
|
|
48
49
|
### Props
|
|
49
50
|
| name | type | default value | description |
|
|
50
51
|
|------|------|---------------|-------------|
|
|
51
|
-
| children* | `({stepper, ...api}) => ReactElement` | - | Render function. Принимает аргументы: `stepper` - JSX-элемент степпера, `goNext` - перейти на след. шаг, `goPrev` - перейти на пред. шаг, `resetValidation` - сбросить состояние валидации для текущего шага, `setValidator`
|
|
52
|
+
| children* | `({stepper, ...api}) => ReactElement` | - | Render function. Принимает аргументы: `stepper` - JSX-элемент степпера, `goNext(stepIndex?: number)` - перейти на след. шаг, `goPrev(stepIndex?: number)` - перейти на пред. шаг, `resetValidation` - сбросить состояние валидации для текущего шага, `setValidator` переопределяет функцию-валидатор, которая принимает в параметры индекс текущего шага и индекс нового, `isCompleted` - окончен ли процесс, `currentStepIndex` - индекс текущего шага, `stepCount` - кол-во шагов. |
|
|
52
53
|
| steps* | `StepData[]` | - | Массив шагов |
|
|
53
54
|
| defaultCurrentStepIndex | `number` | - | Индекс текущего шага по-дефолту |
|
|
55
|
+
| validator | `StepsValidator` | - | Валидатор шагов. Выполняется при смене шага. Принимает первым аргументом индекс текущего, вторым - индекс нового шага. |
|
|
54
56
|
| className | `string` | - | CSS-класс |
|
|
55
57
|
| onChangeCurrentStep | `(newValue: number, prevValue: number) => void` | - | Колбек смены текущего степа |
|
|
56
58
|
| onCompleteChange | `(isCompleted: boolean) => void` | - | Колбек изменения завершенности |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { WithSupportProps } from '@snack-uikit/utils';
|
|
3
|
-
import { StepData, StepperApi } from '../../types';
|
|
3
|
+
import { StepData, StepperApi, StepsValidator } from '../../types';
|
|
4
4
|
export type StepperState = StepperApi & {
|
|
5
5
|
stepper: ReactElement;
|
|
6
6
|
};
|
|
@@ -9,11 +9,13 @@ export type StepperProps = WithSupportProps<{
|
|
|
9
9
|
steps: StepData[];
|
|
10
10
|
/** Индекс текущего шага по-дефолту */
|
|
11
11
|
defaultCurrentStepIndex: number;
|
|
12
|
+
/** Валидатор шагов. Выполняется при смене шага. Принимает первым аргументом индекс текущего, вторым - индекс нового шага. */
|
|
13
|
+
validator?: StepsValidator;
|
|
12
14
|
/** CSS-класс */
|
|
13
15
|
className?: string;
|
|
14
16
|
/**
|
|
15
17
|
* Render function. Принимает аргументы: `stepper` - JSX-элемент степпера,
|
|
16
|
-
* `goNext` - перейти на след. шаг, `goPrev` - перейти на пред. шаг, `resetValidation` - сбросить состояние валидации для текущего шага, `setValidator`
|
|
18
|
+
* `goNext(stepIndex?: number)` - перейти на след. шаг, `goPrev(stepIndex?: number)` - перейти на пред. шаг, `resetValidation` - сбросить состояние валидации для текущего шага, `setValidator` переопределяет функцию-валидатор, которая принимает в параметры индекс текущего шага и индекс нового, `isCompleted` - окончен ли процесс, `currentStepIndex` - индекс текущего шага, `stepCount` - кол-во шагов.
|
|
17
19
|
* @type ({stepper, ...api}) => ReactElement
|
|
18
20
|
*/
|
|
19
21
|
children: (params: StepperState) => ReactElement;
|
|
@@ -22,4 +24,4 @@ export type StepperProps = WithSupportProps<{
|
|
|
22
24
|
/** Колбек изменения завершенности */
|
|
23
25
|
onCompleteChange?: (isCompleted: boolean) => void;
|
|
24
26
|
}>;
|
|
25
|
-
export declare function Stepper({ children, steps, className, onChangeCurrentStep, onCompleteChange, defaultCurrentStepIndex, ...props }: StepperProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export declare function Stepper({ children, steps, className, onChangeCurrentStep, onCompleteChange, defaultCurrentStepIndex, validator: validatorProp, ...props }: StepperProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
11
|
var t = {};
|
|
3
12
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -17,8 +26,9 @@ import { STEP_STATE } from '../../constants';
|
|
|
17
26
|
import { Step } from '../../helperComponents';
|
|
18
27
|
import { StepperContext } from '../../StepperContext';
|
|
19
28
|
import styles from './styles.module.css';
|
|
29
|
+
const DEFAULT_VALIDATOR = () => __awaiter(void 0, void 0, void 0, function* () { return true; });
|
|
20
30
|
export function Stepper(_a) {
|
|
21
|
-
var { children, steps, className, onChangeCurrentStep, onCompleteChange, defaultCurrentStepIndex = 0 } = _a, props = __rest(_a, ["children", "steps", "className", "onChangeCurrentStep", "onCompleteChange", "defaultCurrentStepIndex"]);
|
|
31
|
+
var { children, steps, className, onChangeCurrentStep, onCompleteChange, defaultCurrentStepIndex = 0, validator: validatorProp = DEFAULT_VALIDATOR } = _a, props = __rest(_a, ["children", "steps", "className", "onChangeCurrentStep", "onCompleteChange", "defaultCurrentStepIndex", "validator"]);
|
|
22
32
|
const isCompletedByDefault = defaultCurrentStepIndex === steps.length - 1;
|
|
23
33
|
const [currentStepState, setCurrentStepState] = useState(isCompletedByDefault ? STEP_STATE.Completed : STEP_STATE.Current);
|
|
24
34
|
const [currentStepIndex, setCurrentStepIndexValue] = useState(defaultCurrentStepIndex);
|
|
@@ -35,18 +45,14 @@ export function Stepper(_a) {
|
|
|
35
45
|
return newValue;
|
|
36
46
|
});
|
|
37
47
|
}, [onChangeCurrentStep]);
|
|
38
|
-
const goNext = useCallback(() => {
|
|
39
|
-
|
|
40
|
-
if (currentStepIndex >= steps.length || isCompleted) {
|
|
48
|
+
const goNext = useCallback((newStepIndexUnsafety = currentStepIndex + 1) => {
|
|
49
|
+
if (currentStepIndex >= steps.length || isCompleted || newStepIndexUnsafety <= currentStepIndex) {
|
|
41
50
|
return;
|
|
42
51
|
}
|
|
43
|
-
const
|
|
52
|
+
const newStepIndex = Math.min(steps.length - 1, newStepIndexUnsafety);
|
|
44
53
|
setCurrentStepState(STEP_STATE.Loading);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
(_c = stepsValidator === null || stepsValidator === void 0 ? void 0 : stepsValidator.value(currentStepIndex)) !== null && _c !== void 0 ? _c : Promise.resolve(true),
|
|
48
|
-
])
|
|
49
|
-
.then(results => results.every(isValid => isValid))
|
|
54
|
+
const validator = (stepsValidator === null || stepsValidator === void 0 ? void 0 : stepsValidator.value) || validatorProp;
|
|
55
|
+
validator(currentStepIndex, newStepIndex)
|
|
50
56
|
.catch(() => false)
|
|
51
57
|
.then(isValid => {
|
|
52
58
|
if (!isValid) {
|
|
@@ -59,11 +65,11 @@ export function Stepper(_a) {
|
|
|
59
65
|
setIsCompleted(true);
|
|
60
66
|
}
|
|
61
67
|
else {
|
|
62
|
-
setCurrentStepIndex(
|
|
68
|
+
setCurrentStepIndex(newStepIndex);
|
|
63
69
|
setCurrentStepState(STEP_STATE.Current);
|
|
64
70
|
}
|
|
65
71
|
});
|
|
66
|
-
}, [currentStepIndex, isCompleted, setCurrentStepIndex, steps, stepsValidator]);
|
|
72
|
+
}, [currentStepIndex, isCompleted, setCurrentStepIndex, steps.length, stepsValidator === null || stepsValidator === void 0 ? void 0 : stepsValidator.value, validatorProp]);
|
|
67
73
|
const goPrev = useCallback((index = currentStepIndex - 1) => {
|
|
68
74
|
if (currentStepIndex === 0 || index < 0 || index > currentStepIndex) {
|
|
69
75
|
return;
|
package/dist/types.d.ts
CHANGED
|
@@ -2,11 +2,10 @@ import { JSX } from 'react';
|
|
|
2
2
|
import { ValueOf } from '@snack-uikit/utils';
|
|
3
3
|
import { STEP_STATE } from './constants';
|
|
4
4
|
export type StepState = ValueOf<typeof STEP_STATE>;
|
|
5
|
-
export type StepsValidator = (
|
|
5
|
+
export type StepsValidator = (prevStepIndex: number, newStepIndex: number) => Promise<boolean>;
|
|
6
6
|
export type StepData = {
|
|
7
7
|
title: string;
|
|
8
8
|
description?: string;
|
|
9
|
-
validation?(): Promise<boolean>;
|
|
10
9
|
};
|
|
11
10
|
export type StepViewData = StepData & {
|
|
12
11
|
onClick?(): void;
|
|
@@ -15,8 +14,8 @@ export type StepViewData = StepData & {
|
|
|
15
14
|
};
|
|
16
15
|
export type StepperApi = {
|
|
17
16
|
stepper: JSX.Element;
|
|
18
|
-
goNext(): void;
|
|
19
|
-
goPrev(): void;
|
|
17
|
+
goNext(stepIndex?: number): void;
|
|
18
|
+
goPrev(stepIndex?: number): void;
|
|
20
19
|
resetValidation(): void;
|
|
21
20
|
setValidator(validator: StepsValidator): void;
|
|
22
21
|
isCompleted: boolean;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
6
|
"title": "Stepper",
|
|
7
|
-
"version": "0.5.10-preview-
|
|
7
|
+
"version": "0.5.10-preview-fa22a93d.0",
|
|
8
8
|
"sideEffects": [
|
|
9
9
|
"*.css",
|
|
10
10
|
"*.woff",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"@snack-uikit/utils": "3.2.0",
|
|
40
40
|
"classnames": "2.3.2"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "8bc73eadbb15f1db5f9778820a423c54170732f9"
|
|
43
43
|
}
|
|
@@ -18,11 +18,13 @@ export type StepperProps = WithSupportProps<{
|
|
|
18
18
|
steps: StepData[];
|
|
19
19
|
/** Индекс текущего шага по-дефолту */
|
|
20
20
|
defaultCurrentStepIndex: number;
|
|
21
|
+
/** Валидатор шагов. Выполняется при смене шага. Принимает первым аргументом индекс текущего, вторым - индекс нового шага. */
|
|
22
|
+
validator?: StepsValidator;
|
|
21
23
|
/** CSS-класс */
|
|
22
24
|
className?: string;
|
|
23
25
|
/**
|
|
24
26
|
* Render function. Принимает аргументы: `stepper` - JSX-элемент степпера,
|
|
25
|
-
* `goNext` - перейти на след. шаг, `goPrev` - перейти на пред. шаг, `resetValidation` - сбросить состояние валидации для текущего шага, `setValidator`
|
|
27
|
+
* `goNext(stepIndex?: number)` - перейти на след. шаг, `goPrev(stepIndex?: number)` - перейти на пред. шаг, `resetValidation` - сбросить состояние валидации для текущего шага, `setValidator` переопределяет функцию-валидатор, которая принимает в параметры индекс текущего шага и индекс нового, `isCompleted` - окончен ли процесс, `currentStepIndex` - индекс текущего шага, `stepCount` - кол-во шагов.
|
|
26
28
|
* @type ({stepper, ...api}) => ReactElement
|
|
27
29
|
*/
|
|
28
30
|
children: (params: StepperState) => ReactElement;
|
|
@@ -32,6 +34,8 @@ export type StepperProps = WithSupportProps<{
|
|
|
32
34
|
onCompleteChange?: (isCompleted: boolean) => void;
|
|
33
35
|
}>;
|
|
34
36
|
|
|
37
|
+
const DEFAULT_VALIDATOR = async () => true;
|
|
38
|
+
|
|
35
39
|
export function Stepper({
|
|
36
40
|
children,
|
|
37
41
|
steps,
|
|
@@ -39,6 +43,7 @@ export function Stepper({
|
|
|
39
43
|
onChangeCurrentStep,
|
|
40
44
|
onCompleteChange,
|
|
41
45
|
defaultCurrentStepIndex = 0,
|
|
46
|
+
validator: validatorProp = DEFAULT_VALIDATOR,
|
|
42
47
|
...props
|
|
43
48
|
}: StepperProps) {
|
|
44
49
|
const isCompletedByDefault = defaultCurrentStepIndex === steps.length - 1;
|
|
@@ -65,37 +70,38 @@ export function Stepper({
|
|
|
65
70
|
[onChangeCurrentStep],
|
|
66
71
|
);
|
|
67
72
|
|
|
68
|
-
const goNext = useCallback(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const currentStep = steps[currentStepIndex];
|
|
74
|
-
|
|
75
|
-
setCurrentStepState(STEP_STATE.Loading);
|
|
76
|
-
|
|
77
|
-
Promise.all([
|
|
78
|
-
currentStep.validation?.() ?? Promise.resolve(true),
|
|
79
|
-
stepsValidator?.value(currentStepIndex) ?? Promise.resolve(true),
|
|
80
|
-
])
|
|
81
|
-
.then(results => results.every(isValid => isValid))
|
|
82
|
-
.catch(() => false)
|
|
83
|
-
.then(isValid => {
|
|
84
|
-
if (!isValid) {
|
|
85
|
-
setCurrentStepState(STEP_STATE.Rejected);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
73
|
+
const goNext = useCallback(
|
|
74
|
+
(newStepIndexUnsafety: number = currentStepIndex + 1) => {
|
|
75
|
+
if (currentStepIndex >= steps.length || isCompleted || newStepIndexUnsafety <= currentStepIndex) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
88
78
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
79
|
+
const newStepIndex = Math.min(steps.length - 1, newStepIndexUnsafety);
|
|
80
|
+
|
|
81
|
+
setCurrentStepState(STEP_STATE.Loading);
|
|
82
|
+
|
|
83
|
+
const validator = stepsValidator?.value || validatorProp;
|
|
84
|
+
|
|
85
|
+
validator(currentStepIndex, newStepIndex)
|
|
86
|
+
.catch(() => false)
|
|
87
|
+
.then(isValid => {
|
|
88
|
+
if (!isValid) {
|
|
89
|
+
setCurrentStepState(STEP_STATE.Rejected);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (currentStepIndex === steps.length - 1) {
|
|
94
|
+
// завершился последний шаг
|
|
95
|
+
setCurrentStepState(STEP_STATE.Completed);
|
|
96
|
+
setIsCompleted(true);
|
|
97
|
+
} else {
|
|
98
|
+
setCurrentStepIndex(newStepIndex);
|
|
99
|
+
setCurrentStepState(STEP_STATE.Current);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
[currentStepIndex, isCompleted, setCurrentStepIndex, steps.length, stepsValidator?.value, validatorProp],
|
|
104
|
+
);
|
|
99
105
|
|
|
100
106
|
const goPrev = useCallback(
|
|
101
107
|
(index: number = currentStepIndex - 1) => {
|
package/src/types.ts
CHANGED
|
@@ -6,12 +6,11 @@ import { STEP_STATE } from './constants';
|
|
|
6
6
|
|
|
7
7
|
export type StepState = ValueOf<typeof STEP_STATE>;
|
|
8
8
|
|
|
9
|
-
export type StepsValidator = (
|
|
9
|
+
export type StepsValidator = (prevStepIndex: number, newStepIndex: number) => Promise<boolean>;
|
|
10
10
|
|
|
11
11
|
export type StepData = {
|
|
12
12
|
title: string;
|
|
13
13
|
description?: string;
|
|
14
|
-
validation?(): Promise<boolean>;
|
|
15
14
|
};
|
|
16
15
|
|
|
17
16
|
export type StepViewData = StepData & {
|
|
@@ -22,8 +21,8 @@ export type StepViewData = StepData & {
|
|
|
22
21
|
|
|
23
22
|
export type StepperApi = {
|
|
24
23
|
stepper: JSX.Element;
|
|
25
|
-
goNext(): void;
|
|
26
|
-
goPrev(): void;
|
|
24
|
+
goNext(stepIndex?: number): void;
|
|
25
|
+
goPrev(stepIndex?: number): void;
|
|
27
26
|
resetValidation(): void;
|
|
28
27
|
setValidator(validator: StepsValidator): void;
|
|
29
28
|
isCompleted: boolean;
|