-
Notifications
You must be signed in to change notification settings - Fork 468
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A new CardStepper component which controls the steps for new safe creation which can - go back and forth - jump to a specific step - set an initial step - set initial values - renders a progress bar - step data is stored in an object with a generic type - the update functions (onBack, onSubmit) use Partials of that type such that each step does not need to submit the full data change /demo route to /create-safe Co-authored-by: Usame Algan <[email protected]>
- Loading branch information
1 parent
614ee1b
commit 0b379c7
Showing
10 changed files
with
397 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import css from './styles.module.css' | ||
import { Card, LinearProgress, CardHeader, Avatar, Typography, CardContent } from '@mui/material' | ||
import type { TxStepperProps } from './useCardStepper' | ||
import { useCardStepper } from './useCardStepper' | ||
|
||
export function CardStepper<StepperData>(props: TxStepperProps<StepperData>) { | ||
const { activeStep, onSubmit, onBack, stepData, setStep } = useCardStepper<StepperData>(props) | ||
const { steps } = props | ||
const currentStep = steps[activeStep] | ||
const progress = (activeStep + 1 / steps.length) * 100 | ||
|
||
return ( | ||
<Card className={css.card}> | ||
<LinearProgress color="secondary" variant="determinate" value={Math.min(progress, 100)} /> | ||
<CardHeader | ||
title={currentStep.title} | ||
subheader={currentStep.subtitle} | ||
titleTypographyProps={{ variant: 'h4' }} | ||
subheaderTypographyProps={{ variant: 'body2' }} | ||
avatar={ | ||
<Avatar className={css.step}> | ||
<Typography variant="body2">{activeStep + 1}</Typography> | ||
</Avatar> | ||
} | ||
className={css.header} | ||
/> | ||
<CardContent className={css.content}>{currentStep.render(stepData, onSubmit, onBack, setStep)}</CardContent> | ||
</Card> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
.card { | ||
border: none; | ||
} | ||
|
||
.header { | ||
padding: var(--space-3) var(--space-2); | ||
} | ||
|
||
.header :global .MuiCardHeader-title { | ||
font-weight: 700; | ||
} | ||
|
||
.header :global .MuiCardHeader-subheader { | ||
color: var(--color-text-primary); | ||
} | ||
|
||
.step { | ||
background-color: var(--color-primary-main); | ||
height: 20px; | ||
width: 20px; | ||
} | ||
|
||
.content { | ||
padding: var(--space-3) 52px; | ||
border-top: 1px solid var(--color-border-light); | ||
border-bottom: 1px solid var(--color-border-light); | ||
} | ||
|
||
.actions { | ||
padding: var(--space-3) 52px; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import type { ReactElement } from 'react' | ||
import { useState } from 'react' | ||
import { trackEvent, MODALS_CATEGORY } from '@/services/analytics' | ||
|
||
export type StepRenderProps<TData> = { | ||
data: TData | ||
onSubmit: (data: Partial<TData>) => void | ||
onBack: (data?: Partial<TData>) => void | ||
setStep: (step: number) => void | ||
} | ||
|
||
export type Step<TData> = { | ||
title: string | ||
subtitle: string | ||
render: ( | ||
data: StepRenderProps<TData>['data'], | ||
onSubmit: StepRenderProps<TData>['onSubmit'], | ||
onBack: StepRenderProps<TData>['onBack'], | ||
setStep: StepRenderProps<TData>['setStep'], | ||
) => ReactElement | ||
} | ||
|
||
export type TxStepperProps<TData> = { | ||
steps: Array<Step<TData>> | ||
initialData: TData | ||
initialStep?: number | ||
eventCategory?: string | ||
onClose: () => void | ||
} | ||
|
||
export const useCardStepper = <TData>({ | ||
steps, | ||
initialData, | ||
initialStep, | ||
eventCategory = MODALS_CATEGORY, | ||
onClose, | ||
}: TxStepperProps<TData>) => { | ||
const [activeStep, setActiveStep] = useState<number>(initialStep || 0) | ||
const [stepData, setStepData] = useState(initialData) | ||
|
||
const handleNext = () => { | ||
setActiveStep((prevActiveStep) => prevActiveStep + 1) | ||
trackEvent({ category: eventCategory, action: lastStep ? 'Submit' : 'Next' }) | ||
} | ||
|
||
const handleBack = (data?: Partial<TData>) => { | ||
setActiveStep((prevActiveStep) => prevActiveStep - 1) | ||
trackEvent({ category: eventCategory, action: firstStep ? 'Cancel' : 'Back' }) | ||
|
||
if (data) { | ||
setStepData((previous) => ({ ...previous, ...data })) | ||
} | ||
} | ||
|
||
const setStep = (step: number) => { | ||
setActiveStep(step) | ||
} | ||
|
||
const firstStep = activeStep === 0 | ||
const lastStep = activeStep === steps.length - 1 | ||
|
||
const onBack = firstStep ? onClose : handleBack | ||
|
||
const onSubmit = (data: Partial<TData>) => { | ||
if (lastStep) { | ||
onClose() | ||
return | ||
} | ||
setStepData((previous) => ({ ...previous, ...data })) | ||
handleNext() | ||
} | ||
|
||
return { | ||
onBack, | ||
onSubmit, | ||
setStep, | ||
activeStep, | ||
stepData, | ||
firstStep, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.