-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
/
HorizontalNonLinearStepper.js
144 lines (130 loc) · 3.93 KB
/
HorizontalNonLinearStepper.js
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Stepper from '@material-ui/core/Stepper';
import Step from '@material-ui/core/Step';
import StepButton from '@material-ui/core/StepButton';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
const useStyles = makeStyles(theme => ({
root: {
width: '100%',
},
button: {
marginRight: theme.spacing(1),
},
completed: {
display: 'inline-block',
},
instructions: {
marginTop: theme.spacing(1),
marginBottom: theme.spacing(1),
},
}));
function getSteps() {
return ['Select campaign settings', 'Create an ad group', 'Create an ad'];
}
function getStepContent(step) {
switch (step) {
case 0:
return 'Step 1: Select campaign settings...';
case 1:
return 'Step 2: What is an ad group anyways?';
case 2:
return 'Step 3: This is the bit I really care about!';
default:
return 'Unknown step';
}
}
export default function HorizontalNonLinearStepper() {
const classes = useStyles();
const [activeStep, setActiveStep] = React.useState(0);
const [completed, setCompleted] = React.useState({});
const steps = getSteps();
const totalSteps = () => {
return steps.length;
};
const completedSteps = () => {
return Object.keys(completed).length;
};
const isLastStep = () => {
return activeStep === totalSteps() - 1;
};
const allStepsCompleted = () => {
return completedSteps() === totalSteps();
};
const handleNext = () => {
const newActiveStep =
isLastStep() && !allStepsCompleted()
? // It's the last step, but not all steps have been completed,
// find the first step that has been completed
steps.findIndex((step, i) => !(i in completed))
: activeStep + 1;
setActiveStep(newActiveStep);
};
const handleBack = () => {
setActiveStep(prevActiveStep => prevActiveStep - 1);
};
const handleStep = step => () => {
setActiveStep(step);
};
const handleComplete = () => {
const newCompleted = completed;
newCompleted[activeStep] = true;
setCompleted(newCompleted);
handleNext();
};
const handleReset = () => {
setActiveStep(0);
setCompleted({});
};
return (
<div className={classes.root}>
<Stepper nonLinear activeStep={activeStep}>
{steps.map((label, index) => (
<Step key={label}>
<StepButton onClick={handleStep(index)} completed={completed[index]}>
{label}
</StepButton>
</Step>
))}
</Stepper>
<div>
{allStepsCompleted() ? (
<div>
<Typography className={classes.instructions}>
All steps completed - you're finished
</Typography>
<Button onClick={handleReset}>Reset</Button>
</div>
) : (
<div>
<Typography className={classes.instructions}>{getStepContent(activeStep)}</Typography>
<div>
<Button disabled={activeStep === 0} onClick={handleBack} className={classes.button}>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={handleNext}
className={classes.button}
>
Next
</Button>
{activeStep !== steps.length &&
(completed[activeStep] ? (
<Typography variant="caption" className={classes.completed}>
Step {activeStep + 1} already completed
</Typography>
) : (
<Button variant="contained" color="primary" onClick={handleComplete}>
{completedSteps() === totalSteps() - 1 ? 'Finish' : 'Complete Step'}
</Button>
))}
</div>
</div>
)}
</div>
</div>
);
}