import { type ReactNode } from 'react'
import { Button, Card, CardFooter, CardHeader, cn } from 'ui'
export type SteppedFlowStep = {
id: string
label: string
}
export type SteppedFlowFinalAction = {
label: string
onClick?: () => void
loading?: boolean
disabled?: boolean
form?: string
type?: 'button' | 'submit'
}
export const SteppedFlowHeader = ({
title,
description,
actions,
children,
}: {
title: string
description?: ReactNode
actions?: ReactNode
children?: ReactNode
}) => {
return (
{title}
{description ?
{description}
: null}
{actions ?
{actions}
: null}
{children}
)
}
export interface SteppedFlowProps {
steps: SteppedFlowStep[]
currentStep: string
onStepChange: (stepId: string) => void
nextDisabled?: boolean
nextLabel?: string
onNext?: () => void
nextLoading?: boolean
navigationDisabled?: boolean
onCancel?: () => void
cancelLabel?: string
finalAction?: SteppedFlowFinalAction
children: ReactNode
}
export const SteppedFlow = ({
steps,
currentStep,
onStepChange,
nextDisabled = false,
nextLabel = 'Next',
onNext,
nextLoading = false,
navigationDisabled = false,
onCancel,
cancelLabel = 'Cancel',
finalAction,
children,
}: SteppedFlowProps) => {
const currentIndex = Math.max(
0,
steps.findIndex((step) => step.id === currentStep)
)
const stepCount = steps.length
const isLastStep = stepCount > 0 && currentIndex === stepCount - 1
const isFirstStep = currentIndex === 0
const currentStepLabel = steps[currentIndex]?.label
const showCancel = isFirstStep && !!onCancel
const nextStepId = steps[currentIndex + 1]?.id
const handleNext = () => {
if (onNext) {
onNext()
return
}
if (nextStepId) {
onStepChange(nextStepId)
}
}
if (stepCount === 0) {
return null
}
return (
Step {currentIndex + 1} of {stepCount}
{currentStepLabel ? ` ยท ${currentStepLabel}` : ''}
{children}
0 || showCancel ? 'justify-between' : 'justify-end')}
>
{currentIndex > 0 ? (
) : null}
{currentIndex === 0 && showCancel ? (
) : null}
{isLastStep && finalAction ? (
) : (
)}
)
}