10 — Interaction Specification (Library Module)
- 1. Global interaction rules
- 2. Screen-level interactions
- 3. Motion summary
- 4. Keyboard & adaptive
- 5. a11y (module)
- 6. Analytics (proposed)
Micro-interactions, motion, feedback and platform behavior per screen/component. Timing tokens (
m-fast/m-base/m-slow), a11y and adaptive rules come from 00-shared/08 and 00-shared/09; this file lists module specifics only.
1. Global interaction rules
| Rule | Detail |
|---|---|
| Write feedback | every write (create/update/issue/return/pay) ends in a snackbar with the server's message; failures show the error code + requestId |
| No optimistic writes | all mutations await server; no rollback UI (nothing to roll back) |
| Double-tap guard | every submit button shows a spinner and is disabled while in flight; sheets not dismissible during submit |
| 409 handling | never auto-retry; always refresh the affected entity and re-render |
| Pull-to-refresh | catalog + borrows screens; bypasses cache TTL |
| Focus refresh | returning to any screen re-fetches (availability changes elsewhere) |
| 429 | countdown banner; no silent retry |
| Offline | reads from cache (TTL below); writes blocked with offline banner — no offline queue for library |
2. Screen-level interactions
S1 Catalog List
- Search debounce 300 ms; typing triggers shimmer under the search bar; results swap
in with
m-fastfade; clearing the query re-fetches page 1. - Infinite scroll: loader row appears when
meta.hasNext(buildPaginationMeta,library.service.ts:75); failure at page N → inline "Retry" chip. - Chip filter changes re-filter the current list in memory (no server call — OQ-5); chips show active state.
- Row tap → hero transition to S2 (
m-base).
S2 Book Detail
- Menu: Edit / Delete. Delete →
AppDialog(destructive tone, "Delete book?") →DELETE /books/:id(library.controller.ts:55-59); 409 → dialog swaps copy to "This book still has N active loans" (count unavailable client-side — generic server message shown verbatim). - Issue CTA enabled iff
availableCopies >= 1; disabled state explains why ("All copies on loan" / "Book marked damaged"). - After issue/return elsewhere: focus refresh.
S3 Book Form
- Live
CopyStepperprojection (create:available = total; edit:available + Δ, floor 0 —library.service.ts:41-46,87-90). - Back with dirty form → unsaved-changes dialog.
- 409 duplicate ISBN → inline error + (if cached) link to existing book.
S4 Issue Sheet
StudentPickersearch-as-you-type; selection locks the row; due dateAppDateFielddefaults +14 d, min = tomorrow (client rule).- Submit → spinner on Confirm; success → sheet closes with check animation; the detail behind it refreshes to the new availability.
- 409 no-copies → banner + detail re-fetches; 409 cap → banner shows the student's current active count.
S5 Borrowed-by-Me
- Tabs (Active/History) keep separate scroll positions; badge counts on tabs.
OverdueTaganimates in (m-fastpop) when a card crossesnow > dueDate— computed on ticker, refreshed on any re-fetch (derived; OQ-2).- Row → optional detail sheet (record fields verbatim: borrowedAt, dueDate, returnedAt?, fineAmount, fineStatus?, notes?).
- Staff rows:
[Return]button → S6 sheet;[Pay]on pending fines → confirm dialog.
S6 Return Sheet
- Opens prefilled from the record; fine panel computes
days = ceil((now − dueDate)/day)anddays × 5live (mirrorslibrary.service.ts:211-217); staff may editfineAmount(@Min(0),return-book.dto.ts:9-13). - Submit → spinner → success snackbar "Returned · fine 20 pending" → chips update in the list behind.
- If fine > 0 → inline secondary "Pay fine" → confirm dialog → pay endpoint
(
library.controller.ts:85-89) → chip flips to paid. - 409 "Book was not actively borrowed." → banner + record refresh.
S7 Overdue View
- Persistent info banner (server scan planned — IMPLEMENTATION_PLAN.md:228);
list derived from active borrows;
[Return]reuses S6; empty state "Nothing overdue".
3. Motion summary
| Transition | Token | Trigger |
|---|---|---|
| List → detail | m-base hero | row tap |
| Sheet present (issue/return) | m-base slide-up | CTA tap |
| Availability badge change | m-fast fade | after issue/return refresh |
| Overdue tag appear | m-fast pop | ticker crosses due date |
| Snackbar | m-fast | all writes |
| Dialog | m-base | delete / pay confirm |
4. Keyboard & adaptive
- Forms: keyboard avoidance +
resizeToAvoidBottomInset; fields advance viaonSubmit(title → author → isbn → …). - Date fields: native pickers, no manual typing.
- Phone: sheets for issue/return; tablet/desktop: centered dialogs ≤ 480 dp and master-detail for catalog (list left, detail right).
5. a11y (module)
AvailabilityBadge/OverdueTag/FineChipexpose full-sentence semantics.- Server 409/404 messages announced via live region (never just color).
- All interactive rows are buttons with visible focus.
- Spinner states announced ("Submitting issue…").
6. Analytics (proposed)
library.catalog.search, library.book.open, library.issue.submit|conflict,
library.return.submit|conflict, library.fine.pay, library.overdue.open —
naming per 00-shared/10 §8 (SDK open).