-
Notifications
You must be signed in to change notification settings - Fork 95
/
Copy pathStepper.tsx
71 lines (64 loc) · 2.23 KB
/
Stepper.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
* Copyright Zendesk, Inc.
*
* Use of this source code is governed under the Apache License, Version 2.0
* found at http://www.apache.org/licenses/LICENSE-2.0.
*/
import React, { Children, forwardRef, isValidElement, useMemo } from 'react';
import { IStepperProps } from '../../types';
import { StyledStepper } from '../../styled';
import { StepContext, StepperContext } from '../../utils';
import { Step } from './components/Step';
import { Label } from './components/Label';
import { Content } from './components/Content';
const DEFAULT_ACTIVE_INDEX = 0;
const StepperComponent = forwardRef<HTMLOListElement, IStepperProps>(
({ activeIndex = DEFAULT_ACTIVE_INDEX, isHorizontal, children, ...props }, ref) => {
const stepperContext = useMemo(
() => ({
activeIndex,
isHorizontal: isHorizontal || false
}),
[activeIndex, isHorizontal]
);
return (
<StepperContext.Provider value={stepperContext}>
<StyledStepper ref={ref} $isHorizontal={isHorizontal} {...props}>
{useMemo(
() =>
Children.toArray(children)
.filter(isValidElement)
.map((child, index) => (
<StepContext.Provider
// eslint-disable-next-line react/no-array-index-key
key={index}
// eslint-disable-next-line react/jsx-no-constructed-context-values
value={{
currentStepIndex: index,
isActive: stepperContext.activeIndex === index,
isCompleted: stepperContext.activeIndex > index,
isHorizontal: stepperContext.isHorizontal
}}
>
{child}
</StepContext.Provider>
)),
[children, stepperContext]
)}
</StyledStepper>
</StepperContext.Provider>
);
}
);
StepperComponent.displayName = 'Stepper';
/**
* @extends OlHTMLAttributes<HTMLOListElement>
*/
export const Stepper = StepperComponent as typeof StepperComponent & {
Content: typeof Content;
Label: typeof Label;
Step: typeof Step;
};
Stepper.Content = Content;
Stepper.Label = Label;
Stepper.Step = Step;