T5.1 - A4/S9: a vertical stepper, ten real buttons, states in words
The step rail was ten div elements carrying onclick inside a horizontal
scroller. Not in the tab order, not operable by keyboard, and silent about
progress - the only thing on the page that said where you were was a "1 / 10"
pill in the app bar, detached from the control it described.
The rail is now a vertical column beside the form: ten <button> elements in an
<ol> inside a named <nav>, with arrow keys, Home and End on top of the Enter and
Space a button gives for free. All ten stay in the tab order; a roving tabindex
would have satisfied "arrow keys" by breaking "tab", which the done-when asks
for both of.
Four states, each carrying a word and a marker shape as well as a colour (C1):
Complete (green disc, tick), Current step (blue disc, aria-current="step"),
Locked (dashed outline) and a plain default. Locked steps keep aria-disabled
rather than disabled, so a keyboard user can reach one and be told what is in
the way instead of finding a control that has vanished from the tab order.
Reachability is the guard's own rule, deliberately not a stricter one: you may
leave the step you are on once its required fields are filled. The tempting rule
- lock everything after the first unmet gate anywhere - is not what
validateStep() enforces, and a padlock the Next button walks straight past is
the drift this change exists to remove. validateStep() and the rail now read one
STEP_GATES table, so they cannot disagree; T5.8 widens that table rather than
editing four functions.
Clicking a step you cannot reach announces why through a role="alert" region and
puts the cursor in the field that is missing. Saying "no" and leaving you where
you were, with no idea which of five inputs was empty, is what the dialog did.
Below 900px the rail collapses to a disclosure naming the step you are on -
ten vertical rows above the fields is most of a 390px screen before you reach an
input. 44px tap targets, since Field View is the gloved-hands surface.
Also: going backwards is no longer gated. previousStep() never validated, so a
rail that did would have trapped you on an incomplete step.
html/work-package-suite.html rail markup, counter removed
html/work-package-suite-styles.css #tool-sop grid, .step-rail*, 899px collapse
html/work-package-suite-app.js STEP_GATES, renderStepRail, keyboard, watcher
tests/stepper_check.py new - 70 checks
Done when
[x] all 10 steps are <button> elements
[x] keyboard: tab, arrow keys, Home/End, Enter and Space
[x] aria-current on the current step, exactly one
[x] complete / current / unavailable told apart without colour
[x] the "1 / 10" counter is gone - no .step-counter, no N/10 in the app bar
[x] app-wide <div onclick> 12 -> 2, down exactly 10
Verified one at a time
stepper_check 70/70 new
browser_check 71/71
url_state 23/23
a11y 22/22 sop now rings 37 focusable elements, all >= 3:1
autosave 34/34
aggregates 16/16
f_items F1-F5 FIXED, F6 REPRODUCES (T7.2)
baseline_shots 14 shots; only the sop pair changed. The beforeunload log on
sop@1440 and creator@1440 is present at HEAD too - captured
both sides to check rather than assume.
No colour literal was added: all five page sheets and all seven inline <style>
blocks still hold zero. New spacing consumes --wp-s*; three raw font sizes were
added and three removed, so BL-010 is unchanged in kind.
Raised, not fixed
BL-016 Back to a URL with no `step` leaves the wizard where it was. T4.2's
popstate handler parses NaN and ignores it; its own probe never took
that branch. stepper_check pins the current behaviour by name so the
fix has a test waiting.
BL-017 The native-dialog baseline counts the word `alert(` in comments. Four
comments written here - all of them about removing a dialog - moved
the number from 80 to 82 while two real calls were being deleted. They
were reworded; the metric still needs a comment-stripped variant, which
T5.8 owns.
Question for the PR, per CLAUDE.md: BL-015 leaves the creator's .step-tab
uppercase as the last forced-uppercase interactive text in the suite, on the
grounds that A5 scopes sentence case to buttons and field labels. The wizard's
rail is now buttons, so its labels are sentence case ("Sign-offs", "WP types").
The two are consistent by rule and inconsistent on screen until T7.x.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -264,6 +264,40 @@ deliberately deferred.
|
||||
- **Why not now:** out of `A5`'s stated scope, and `A4`/`S9` rebuild the stepper.
|
||||
- **Suggested wave or follow-up:** `T7.x`, with the stepper rebuild.
|
||||
|
||||
### BL-016 — Back to a URL with no `step` leaves the wizard on the step it was on
|
||||
|
||||
- **Found during:** T5.1
|
||||
- **Where:** `html/work-package-suite-app.js`, the `WPUrl.onChange` handler
|
||||
- **What:** the popstate handler reads `parseInt(state.step, 10)` and acts only when
|
||||
the result is `>= 1`. Going from `?project=X&step=6` back to `?project=X` yields
|
||||
`NaN`, so nothing happens and the wizard stays on step 6 while the address bar says
|
||||
step 1. `T4.2`'s own probe never caught it because it moves between two URLs that
|
||||
both carry a `step`, so the NaN branch was never taken. The fix is one expression —
|
||||
treat a missing `step` as 1 — but it is `S3`'s code and `T4.2`'s done-whens, not
|
||||
`A4`'s.
|
||||
- **Why not now:** `CLAUDE.md` — do not fix what you notice in passing. `T5.1`'s rail
|
||||
makes it easier to reach (ten keyboard-reachable buttons instead of ten chips) but
|
||||
does not cause it, and folding an `S3` correction into an `A4` diff makes both
|
||||
unreviewable.
|
||||
- **Suggested wave or follow-up:** wave 9, with `C2`. `tests/stepper_check.py` pins the
|
||||
current behaviour with a named check so the fix has a test waiting for it.
|
||||
|
||||
### BL-017 — The native-dialog baseline metric counts prose
|
||||
|
||||
- **Found during:** T5.1
|
||||
- **Where:** `docs/reference/file-map.md` §4, metric 1
|
||||
- **What:** the metric is `grep -ohE '\b(alert|confirm|prompt)\(' *.js *.html`, which
|
||||
matches those words inside comments as readily as inside code. Four comments written
|
||||
during `T5.1` — every one of them *about* removing a dialog — pushed the count from
|
||||
80 to 82 while the task was deleting two real calls. They were reworded, but the next
|
||||
person to explain a dialog in a comment will move the number again, and `T5.8` and
|
||||
wave 9 both have to drive it to a target.
|
||||
- **Why not now:** redefining a wave 0 baseline mid-plan is worse than the noise; the
|
||||
count is comparable to itself as long as everyone measures it the same way.
|
||||
- **Suggested wave or follow-up:** `T5.8`, which owns the wizard's count, should record
|
||||
a comment-stripped figure alongside the raw one and state both. Wave 9 sets the
|
||||
target against the stripped figure.
|
||||
|
||||
### BL-014 — Four controls fall back to the browser's default focus ring
|
||||
|
||||
- **Found during:** T3.4
|
||||
|
||||
Reference in New Issue
Block a user