6.9 KiB
created, status, requirements, system_design, legacy_specs
| created | status | requirements | system_design | legacy_specs | ||
|---|---|---|---|---|---|---|
| 2026-08-26 | complete |
|
|
Implementation Plan: Compact Workflow Step Navigation
Overview
Add an interactive disclosure to the compact task top-bar stepper. Reuse the existing movement policy and task-move callback.
Implement the component behavior and its browser proof in one vertical work order. This order keeps the responsive contract and movement result in one TDD cycle.
Scope
In scope
- Make the compact stepper a semantic and accessible trigger for active tasks.
- Show every workflow step in workflow order from the compact presentation.
- Permit moves only to targets that the full stepper already permits.
- Use an interactive Popover for fine pointers and an inset drawer for coarse pointers. The fine-pointer trigger and dialog expose matching ARIA semantics, and the move buttons remain keyboard tabbable.
- Give the coarse-pointer trigger a 44px hit area and visible disclosure cue.
- Preserve the existing phone movement path and full-stepper behavior.
- Cover the compact desktop and tablet paths with component and E2E tests.
Out of scope
- Backend task-move changes.
- Cross-workflow movement from the compact stepper.
- A new phone top-bar control.
- New move notifications or error copy.
- Public documentation changes.
Technical approach
Stepper model and disclosure
Update apps/web/components/task/workflow-stepper.tsx. Keep WorkflowStepper as the owner of sorted steps, the current index, and move state.
Replace the static active-task branch in MinimalWorkflowStepper with a disclosure trigger. Keep the archived branch static.
Extract one disclosure body that renders each step from a shared row model. The model uses canMoveToStep for every target.
Reuse StepCircleIndicator, task:currentStep, task:moveHere, task:moving, and task:stepOf. Do not add untranslated copy.
Use useTouchDrawer to select the surface. Fine pointers use a controlled Popover with hover and focus behavior, dialog semantics, keyboard focus handling, and compact desktop-sized movement buttons. Coarse pointers use Drawer with internal overflow, safe-area padding, a 44px trigger hit area, 44px action hit areas, and a visible disclosure cue. Apply touch sizing only through coarse-pointer styles.
Keep the move request in handleMove. Return its success result so the temporary surface closes only after a successful request.
Component tests
Extend apps/web/components/task/workflow-stepper.test.tsx. Mock width collapse and pointer mode independently.
Add tests for these results:
- fine-pointer hover or focus shows all ordered steps
- eligible targets show movement controls and the current step does not
- selection calls
moveTaskwith the existing payload - coarse-pointer activation opens the drawer with the same targets
- archived compact state stays static
- expanded mode does not mount the compact disclosure
Browser tests
Add apps/web/e2e/tests/layout/task-topbar-workflow-stepper.spec.ts. Use a long task title and a 900px viewport to force the measured compact state.
The desktop scenario hovers and focuses the compact trigger, verifies the Popover dialog semantics, tabs to a step-specific move button, activates it with Enter, and polls the task API for the new step.
The tablet scenario uses tabletTestPage. It verifies the trigger hit area, opens the touch drawer, checks viewport containment, selects a target, and polls the same API result.
Keep apps/web/e2e/tests/task/mobile-sidebar-task-actions.spec.ts unchanged. Its current Pixel 5 move scenario remains the phone parity proof.
Tests
| Acceptance criterion | Evidence |
|---|---|
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.1 |
Compact component test and desktop E2E trigger assertion |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.2 |
Fine-pointer component test and desktop Popover E2E |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.3 |
Touch-drawer component test and tablet trigger geometry E2E |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.4 |
Eligibility and current-step component tests |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.5 |
moveTask payload component test and API-poll E2E assertions |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.6 |
Keyboard desktop E2E with Tab and Enter, plus tablet geometry |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.7 |
Archived compact-state component test |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.8 |
Existing expanded-mode component test |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.9 |
Existing Pixel 5 mobile task-drawer E2E scenario |
AC-UI-COMPACT-WORKFLOW-STEP-NAVIGATION-001.10 |
Desktop compact button and coarse-pointer hit-area E2E |
E2E tests
apps/web/e2e/tests/layout/task-topbar-workflow-stepper.spec.ts, Chromium project: compact hover disclosure and task movement.apps/web/e2e/tests/layout/task-topbar-workflow-stepper.spec.ts, Chromium project withtabletTestPage: touch drawer, geometry, and task movement.apps/web/e2e/tests/task/mobile-sidebar-task-actions.spec.ts, mobile-chrome project: existing phone task movement through Move to.
Work orders
Verification results
Completed 2026-08-26.
- Component tests: 9 passed in
components/task/workflow-stepper.test.tsx. - Focused ESLint: passed with no warnings for the changed component, test, and E2E files.
- TypeScript typecheck: passed.
- i18n checks: passed with no new violations.
- Chromium E2E: compact Popover dialog semantics, keyboard Tab and Enter movement, Escape dismissal, focus return, and tablet touch-drawer scenarios passed.
- Mobile-chrome E2E: the existing phone Move to scenario passed.
- Desktop density: the fine-pointer move button measured below 40px, while the coarse-pointer move button and disclosure trigger remained at least 44px.
- Tablet geometry: the disclosure trigger and touch rows measured at least 44px, the touch drawer stayed inside the viewport, and the document did not gain horizontal overflow.
Risks
- A nested disclosure can close its parent before a movement button receives the pointer. The design uses one Popover surface and no nested hover roots.
- The compact state depends on rendered width. The E2E fixture must prove that
workflow-stepper-minimalis visible before it opens the disclosure. - Tablet pointer detection depends on browser media queries. The E2E uses the existing
tabletTestPagetouch context. - A failed move must not leave movement controls disabled or close the disclosure.