StepSlider blocks all navigation when disableNextStep is true, not just forward navigation
- Dominant language
- JavaScript
- Stars
- 400
- Forks
- 89
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 149
Description
### Current Behavior
In StepSlider.vue:54, the select method bails out entirely when disableNextStep is true:
```js
select (key, disabled) {
if (this.disableNextStep) {
return
}
// ...
}
```
`disableNextStep` semantically means "the current step isn't complete, don't let the user advance." But the check blocks all step clicks, including going back to already completed steps. If you're on step 3 and the step isn't valid yet, you can't click step 1 or 2 either.
The guard should only block navigation when the target step is ahead of the current one (`key` > `currentEntry`).
Fixing that introduces a second problem. There's nothing preventing users from skipping intermediary steps entirely. `MultiStepForm.selectStep` just sets `currentStepKey` directly with no bounds checking:
```js
selectStep (key) {
this.currentStepKey = key
}
```
So clicking from step 1 straight to step 3 would work as long as `disableNextStep` is false on step 1, bypassing step 2's validation completely.
### Suggested approach
**Phase 1**: Track a "high water mark" of the furthest step the user has validly reached. Only allow navigation to steps up to that point. Any change on step N resets the high water mark back to N, forcing the user to re-walk through N+1, N+2, etc. This is intentionally blunt but safe.
Concretely this means:
- New state in `MultiStepForm` (something like `maxReachedStep`) that increments as the user progresses forward via the Next button
- Pass it down to `StepSlider` as a prop to gate which steps are clickable
- When a step emits an update (via step-updated), reset the high water mark to the current step
- Fix the `disableNextStep` guard to only block forward navigation, not backward
*Phase 2 (follow-up)**: The blunt reset is too aggressive for forms where steps aren't all interdependent. For example, changing something in step 1 shouldn't force re-walking step 2 if step 2 has no dependency on step 1. This would introduce per-step dependency declarations so concrete form implementations can define which steps depend on which. A change on step N would then only invalidate steps that declare a dependency on it. The step definition format already supports disabled and hidden, so something like a `dependsOn` array or a validation callback per step could slot in there.
### Expected Behavior
_No response_
### Steps To Reproduce
_No response_
### Environment
- FlowFuse version: 2.32.0
- Node.js version:
- npm version:
- Platform/OS:
- Browser:
### Have you provided an initial effort estimate for this issue?
I have provided an initial effort estimate
Contributor guide
Research direction
Start by reading StepSlider.vue:54 and MultiStepForm.selectStep, then trace the step-updated event and the Next-button progression. Implement the stated Phase 1 boundary so backward navigation remains available, forward navigation cannot skip intermediary steps, and edits reset the reachable boundary to the current step. Confirm the behavior against the issue's step 1-to-3 and step 3-to-1 scenarios.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100