Form stepper with controlled navigation
const [step, setStep] = useState(1);
function setPage(page: number) {
if (page < 1 || page > 4) return;
setStep(page);
}<GoabFormStepper step={step} onChange={(event: GoabFormStepperOnChangeDetail) => setStep(event.step)}>
<GoabFormStep text="Personal details" />
<GoabFormStep text="Employment history" />
<GoabFormStep text="References" />
<GoabFormStep text="Review" />
</GoabFormStepper>
<GoabPages current={step} mb="3xl" mt="xl" mr="xl" ml="xl">
<div>
<GoabSkeleton type="article" />
</div>
<div>
<GoabSkeleton type="header" size="2" />
<GoabSkeleton type="text" />
<GoabSkeleton type="header" size="2" />
<GoabSkeleton type="text" />
</div>
<div>
<GoabSkeleton type="text" />
<GoabSpacer vSpacing="m" />
<GoabSkeleton type="text" />
</div>
<div>
<GoabSkeleton type="header" size="2" />
<GoabSkeleton type="text" />
<GoabSpacer vSpacing="m" />
<GoabSkeleton type="text" />
</div>
</GoabPages>
<div style={{ display: "flex", justifyContent: "space-between" }}>
<GoabxButton type="secondary" onClick={() => setPage(step - 1)}>
Previous
</GoabxButton>
<GoabxButton type="primary" onClick={() => setPage(step + 1)}>
Next
</GoabxButton>
</div>step = 1;
updateStep(event: GoabFormStepperOnChangeDetail): void {
this.step = event.step;
}
setPage(page: number): void {
if (page < 1 || page > 4) return;
this.step = page;
}<goab-form-stepper ml="s" mr="s" [step]="step" (onChange)="updateStep($event)">
<goab-form-step text="Personal details"></goab-form-step>
<goab-form-step text="Employment history"></goab-form-step>
<goab-form-step text="References"></goab-form-step>
<goab-form-step text="Review"></goab-form-step>
</goab-form-stepper>
<goab-pages [current]="step" mb="3xl" mt="xl" mr="xl" ml="xl">
<div>
<goab-skeleton type="article"></goab-skeleton>
</div>
<div>
<goab-skeleton type="header" size="2"></goab-skeleton>
<goab-skeleton type="text"></goab-skeleton>
<goab-skeleton type="header" size="2"></goab-skeleton>
<goab-skeleton type="text"></goab-skeleton>
</div>
<div>
<goab-skeleton type="text"></goab-skeleton>
<goab-spacer vSpacing="m"></goab-spacer>
<goab-skeleton type="text"></goab-skeleton>
</div>
<div>
<goab-skeleton type="header" size="2"></goab-skeleton>
<goab-skeleton type="text"></goab-skeleton>
<goab-spacer vSpacing="m"></goab-spacer>
<goab-skeleton type="text"></goab-skeleton>
</div>
</goab-pages>
<div style="display: flex; justify-content: space-between">
<goabx-button (onClick)="setPage(step - 1)" type="secondary">Previous</goabx-button>
<goabx-button (onClick)="setPage(step + 1)" type="primary">Next</goabx-button>
</div>const formStepper = document.getElementById('form-stepper');
const formPages = document.getElementById('form-pages');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
let currentStep = 1;
function updateStep(step) {
if (step < 1 || step > 4) return;
currentStep = step;
formStepper.setAttribute('step', currentStep);
formPages.setAttribute('current', currentStep);
}
formStepper.addEventListener('_change', (e) => {
updateStep(e.detail.step);
});
prevBtn.addEventListener('_click', () => {
updateStep(currentStep - 1);
});
nextBtn.addEventListener('_click', () => {
updateStep(currentStep + 1);
});<goa-form-stepper id="form-stepper" ml="s" mr="s" step="1">
<goa-form-step text="Personal details"></goa-form-step>
<goa-form-step text="Employment history"></goa-form-step>
<goa-form-step text="References"></goa-form-step>
<goa-form-step text="Review"></goa-form-step>
</goa-form-stepper>
<goa-pages id="form-pages" current="1" mb="3xl" mt="xl" mr="xl" ml="xl">
<div>
<goa-skeleton type="article"></goa-skeleton>
</div>
<div>
<goa-skeleton type="header" size="2"></goa-skeleton>
<goa-skeleton type="text"></goa-skeleton>
<goa-skeleton type="header" size="2"></goa-skeleton>
<goa-skeleton type="text"></goa-skeleton>
</div>
<div>
<goa-skeleton type="text"></goa-skeleton>
<goa-spacer vspacing="m"></goa-spacer>
<goa-skeleton type="text"></goa-skeleton>
</div>
<div>
<goa-skeleton type="header" size="2"></goa-skeleton>
<goa-skeleton type="text"></goa-skeleton>
<goa-spacer vspacing="m"></goa-spacer>
<goa-skeleton type="text"></goa-skeleton>
</div>
</goa-pages>
<div style="display: flex; justify-content: space-between">
<goa-button version="2" id="prev-btn" type="secondary">Previous</goa-button>
<goa-button version="2" id="next-btn" type="primary">Next</goa-button>
</div>Create a multi-step form with controlled navigation using Previous/Next buttons.
When to use
Use this pattern when:
- A form is too long to display on a single page
- You want to guide users through a sequential process
- Steps must be completed in order before proceeding
- Users should not be able to skip ahead to incomplete steps
Considerations
- Set an initial
stepvalue >= 1 to enable controlled mode - Steps that are “Not started” will not be clickable
- Use Previous/Next buttons to control navigation programmatically
- Validate step completion before allowing navigation forward
- Consider showing skeleton content while loading step data