2.6 KB101 lines
Blame
1/**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8import type {MultiStepperContext} from 'isl-components/multi_stepper/MultiStepperContext';
9
10import * as stylex from '@stylexjs/stylex';
11import {Icon} from 'isl-components/Icon';
12
13const styles = stylex.create({
14 stepItem: {
15 display: 'flex',
16 alignItems: 'center',
17 gap: '12px',
18 padding: '12px',
19 borderRadius: '4px',
20 marginBottom: '8px',
21 },
22 stepItemActive: {
23 backgroundColor: 'var(--highlight-background)',
24 },
25 stepItemCompleted: {
26 cursor: 'pointer',
27 },
28 stepNumber: {
29 display: 'flex',
30 alignItems: 'center',
31 justifyContent: 'center',
32 width: '20px',
33 height: '20px',
34 borderRadius: '50%',
35 border: '2px solid var(--foreground)',
36 fontSize: '12px',
37 fontWeight: 'bold',
38 },
39 stepNumberActive: {
40 backgroundColor: 'var(--button-primary-background)',
41 borderColor: 'var(--button-primary-background)',
42 color: 'var(--button-primary-foreground)',
43 },
44 stepNumberCompleted: {
45 backgroundColor: 'var(--success-background)',
46 borderColor: 'var(--success-background)',
47 },
48 stepLabel: {
49 fontSize: '14px',
50 },
51 stepLabelActive: {
52 fontWeight: 'bold',
53 },
54});
55
56type Props<TKey> = {
57 stepper: MultiStepperContext<TKey>;
58};
59
60/**
61 * A vertical progress bar for a multi-step stepper.
62 */
63export function VerticalStepperProgress<TKey>({stepper}: Props<TKey>) {
64 const icon = <Icon icon="check" />;
65
66 const steps = stepper.getAllSteps();
67 const currentIndex = stepper.getStepIndex();
68
69 return (
70 <div>
71 {steps.map((step, index) => {
72 const isActive = index === currentIndex;
73 const isCompleted = index < currentIndex;
74
75 return (
76 <div
77 key={String(step.key)}
78 onClick={() => (isCompleted ? stepper.goToStepByKey(step.key) : undefined)}
79 {...stylex.props(
80 styles.stepItem,
81 isActive && styles.stepItemActive,
82 isCompleted && styles.stepItemCompleted,
83 )}>
84 <div
85 {...stylex.props(
86 styles.stepNumber,
87 isActive && styles.stepNumberActive,
88 isCompleted && styles.stepNumberCompleted,
89 )}>
90 {isCompleted ? icon : index + 1}
91 </div>
92 <div {...stylex.props(styles.stepLabel, isActive && styles.stepLabelActive)}>
93 {step.label}
94 </div>
95 </div>
96 );
97 })}
98 </div>
99 );
100}
101