Enhance WizardView component by adding support for controlled current step management and optional sub-step descriptions using Timeline. Introduce new props for sidebar width, button visibility, and step skipping functionality, improving user interaction and flexibility in the wizard flow.

This commit is contained in:
Tom Butcher 2026-07-20 02:05:58 +01:00
parent 0c6fe5cbac
commit 9442c9105b

View File

@ -9,13 +9,15 @@ import {
Divider,
Progress,
Button,
Dropdown
Dropdown,
Timeline
} from 'antd'
import NewObjectButtons from './NewObjectButtons'
const { Title } = Typography
const WizardView = ({
sizeBarWidth = '160px',
showSteps = true,
steps,
title = 'Wizard View',
@ -27,22 +29,76 @@ const WizardView = ({
progress = 0,
actions = [],
sideBarGrow = false,
disabled = false
disabled = false,
showButtons = true,
showTitle = true,
currentStep: controlledCurrentStep,
currentSubStep = 0,
onStepChange,
showSkipButton = false,
onSkip = () => {}
}) => {
const [currentStep, setCurrentStep] = useState(0)
const [internalCurrentStep, setInternalCurrentStep] = useState(0)
const currentStep = controlledCurrentStep ?? internalCurrentStep
const isMobile = useMediaQuery({ maxWidth: 768 })
const setCurrentStep = (step) => {
if (controlledCurrentStep === undefined) {
setInternalCurrentStep(step)
}
onStepChange?.(step)
}
return (
<Flex gap='middle' style={{ width: '100%' }}>
{!isMobile && showSteps == true ? (
sideBar != null ? (
sideBar
) : (
<div style={{ minWidth: sideBarGrow == true ? '100%' : '160px' }}>
<div
style={{ minWidth: sideBarGrow == true ? '100%' : sizeBarWidth }}
>
<Steps
current={currentStep}
items={steps.map((step, index) => ({
items={steps.map(({ subSteps, ...step }, index) => ({
...step,
description: subSteps ? (
<Timeline
className='subSteps'
items={subSteps.map((subStep, subStepIndex) => {
const complete =
index < currentStep ||
(index === currentStep && subStepIndex < currentSubStep)
const current =
index === currentStep && subStepIndex === currentSubStep
const disabled = index < currentStep
return {
...subStep,
children: subStep.title,
dot: complete ? (
<div
className={`subSteps-dot ${disabled ? 'subSteps-dot-disabled' : ''}`}
>
<CheckIcon
style={{
fontSize: '5px',
marginTop: '0px',
marginRight: '0px',
color: disabled
? 'var(--color-primary)'
: 'var(--layout-modal-bg)'
}}
/>
</div>
) : undefined,
color: complete ? 'blue' : current ? 'blue' : 'gray'
}
})}
/>
) : (
step.description
),
icon:
index < currentStep ? (
<div className='ant-steps-item-icon'>
@ -76,13 +132,27 @@ const WizardView = ({
}
>
<Flex vertical gap='middle' style={{ flexGrow: 1, width: '100%' }}>
{showTitle ? (
<Title level={2} style={{ margin: '0 0 8px 0', lineHeight: 0.7 }}>
{title}
</Title>
) : null}
<div style={{ minHeight: '260px', marginBottom: 4, width: '100%' }}>
{steps[currentStep].content}
</div>
</Flex>
{showButtons || progress > 0 || actions.length > 0 ? (
<Flex
gap={'middle'}
align='center'
justify={showSkipButton ? 'space-between' : 'end'}
>
{showSkipButton && showButtons && (
<Button onClick={onSkip} disabled={disabled}>
Skip
</Button>
)}
<Flex gap={'middle'} align='center' justify='end'>
{progress > 0 ? (
<Progress
@ -95,7 +165,10 @@ const WizardView = ({
if (action.steps.includes(steps[currentStep].key)) {
if (action.children) {
return (
<Dropdown menu={{ items: action.children }} key={action.key}>
<Dropdown
menu={{ items: action.children }}
key={action.key}
>
<Button
onClick={action?.onClick}
disabled={action?.disabled || disabled}
@ -120,19 +193,23 @@ const WizardView = ({
return null
})}
{showButtons && (
<NewObjectButtons
disabled={disabled}
currentStep={currentStep}
totalSteps={steps.length}
onPrevious={() => setCurrentStep((prev) => prev - 1)}
onNext={() => setCurrentStep((prev) => prev + 1)}
onPrevious={() => setCurrentStep(currentStep - 1)}
onNext={() => setCurrentStep(currentStep + 1)}
onSubmit={onSubmit}
formValid={formValid}
submitLoading={loading}
submitText={submitText}
/>
)}
</Flex>
</Flex>
) : null}
</Flex>
</Flex>
)
}
@ -149,7 +226,15 @@ WizardView.propTypes = {
submitText: PropTypes.string,
progress: PropTypes.number,
actions: PropTypes.array,
sideBarGrow: PropTypes.bool
sideBarGrow: PropTypes.bool,
showButtons: PropTypes.bool,
showTitle: PropTypes.bool,
currentStep: PropTypes.number,
currentSubStep: PropTypes.number,
onStepChange: PropTypes.func,
showSkipButton: PropTypes.bool,
onSkip: PropTypes.func,
sizeBarWidth: PropTypes.string
}
export default WizardView