10 — Interaction Specification (Exams Module)
- 1. List → Detail (S1 → S2)
- 2. Exam Detail (S2)
- 3. Marks Entry (S3) — the core cadence
- 4. Add Subject Slot (S4)
- 5. Report Card (S7)
- 6. Keyboard & focus
- 7. Haptics summary
- 8. Motion budget
Precise micro-interactions for the Exams screens. Motion tokens (
Mo.fast,Mo.base,Mo.shake) and haptics per 00-shared/08_Interaction_&_Motion.md; state management per 13_State_Management.md; components per 07.
1. List → Detail (S1 → S2)
- Tap card: 120 ms pressed
stateLayer; on release navigate; row-to-header shared-element transition (exam name)Mo.base(200 ms, easeOutCubic); list fades backMo.fast. - Pull-to-refresh: re-fetch
GET /examinations(bypass cache); on 304/no-change, no animation; new rows stagger-inMo.fast(30 ms). - Pagination: auto-load next page at 300 px from bottom when
hasNext(pagination-query.dto.ts:46-54); footer spinner; failure → inline "Load more failed — Retry".
2. Exam Detail (S2)
- Segmented control Schedule/Coverage:
Mo.fast(120 ms) indicator slide; content cross-fade, no rebuild of the other tab (lazy). - Slot tap: chevron rotates 90°, navigation to S3 with slot header shared
element (
Mo.base). - Menu (Edit/Delete): bottom sheet (phone) / menu (desktop). Delete →
AppDialog"Delete this exam? Subjects and marks stay on the server." — soft delete, no cascade (examination.service.ts:99-110,base.repository.ts:68-74); confirm → spinner on action → success pop + snackbar "Exam deleted". - Publish (S5 dialog): opens with coverage recap; confirm =
FilledButton(tertiary). While submitting: barrier lock, button spinner, hapticmediumImpacton success; badge flips topublishedwithMo.fastpop; hapticerroron failure + dialog reopens with error line.
3. Marks Entry (S3) — the core cadence
- Enter = save + advance: typing digits into
MarksTextField, pressing Enter (or Tab-out) saves that row (POST /results/exam-subject/:id/marks) and focuses the next row's field. Saves are optimistic with server-confirm rollback (row shows local value immediately; on error → rollback + shake). - Save-state per row: pending (field outline primary) → saving (spinner 120 ms
min display to avoid flicker) → saved (check
Mo.fast, hapticlightImpact) → failed (shakeMo.shake300 ms, error icon, "Retry"). - Max-marks clamp: typing past
maximumMarksdigits is blocked; paste over-clamped values → inline error, field select-all (pre-validates the 404 server path,examination.service.ts:145-146). - Grade sheet: tap
GradeChip→ bottom sheet with common grades (A+, A, B+, B, C, D, F — matching report-card bands,result.service.ts:130-138) + free text; select → chip fills, save on row save. - Remarks: inline expansion (chevron) → 2–3 line field; saved with row.
- Offline: row → dashed outline + cloud icon;
MarksSummaryBarshows "2 offline · 1 failed"; reconnect → auto-flush (order FIFO, 13_State_Management.md §4); conflict (409) → per-row conflict sheet: preview server vs local, choose overwrite/discard. - Back navigation with unsaved rows: save-confirm sheet "Save 3 unsaved
marks?" [Save & exit / Discard / Stay];
publishedexam → confirm sheet before any edit (immutability contract, OQ-5). - Coverage bar: width animates 200 ms ease; at 100% turns
tertiary+ hapticlightImpact(milestone).
4. Add Subject Slot (S4)
- Field order matters: subject → class → date → times → marks; date picker clamps to exam window (08_Form_Specifications.md §3).
- Overlap detection on submit: animate a highlight ring around the conflicting slot (in a mini-schedule strip) while the confirm dialog appears — "Overlaps with Math 09:00–12:00 — add anyway?"
- Submit: spinner on
Save; success → pop with slot card slide-in on S2 (Mo.fast).
5. Report Card (S7)
- Share: action → render card to image (RepaintBoundary) → share sheet
(proposed); hapticselectionon share. - Rows: fade
Mo.faststagger; unmarked rows muted with "not marked" hint (payload ambiguity,result.service.ts:70). - Grade badge: pop-in
Mo.baseon load; announcement via live region.
6. Keyboard & focus
| Screen | Behaviour |
|---|---|
| S1/S2 | scroll navigation; N = new exam (desktop); P = publish (detail, desktop) |
| S3 | Tab cycles fields; Enter saves+advances; Esc clears current input; hardware-keyboard users get the full row cadence (§3) |
| S4/S8 | autofocus first field (name/subject); Enter submits when on last field; submit on keyboard done |
7. Haptics summary
| Action | Haptic |
|---|---|
| Row saved | lightImpact |
| Publish success | mediumImpact |
| Save failure / max violation | error (heavy) |
| Coverage 100% | lightImpact |
| Overlap warning shown | selection |
8. Motion budget
Per screen, total transition budget < 400 ms (list) / < 300 ms (forms); reduced-motion doubles durations off (00-shared/08 §5); no screen has infinite/looping animations except the publish progress spinner.