Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

10 — Interaction Specification (Library Module)

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

RuleDetail
Write feedbackevery write (create/update/issue/return/pay) ends in a snackbar with the server's message; failures show the error code + requestId
No optimistic writesall mutations await server; no rollback UI (nothing to roll back)
Double-tap guardevery submit button shows a spinner and is disabled while in flight; sheets not dismissible during submit
409 handlingnever auto-retry; always refresh the affected entity and re-render
Pull-to-refreshcatalog + borrows screens; bypasses cache TTL
Focus refreshreturning to any screen re-fetches (availability changes elsewhere)
429countdown banner; no silent retry
Offlinereads 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-fast fade; 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 CopyStepper projection (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

  • StudentPicker search-as-you-type; selection locks the row; due date AppDateField defaults +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.
  • OverdueTag animates in (m-fast pop) when a card crosses now > 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) and days × 5 live (mirrors library.service.ts:211-217); staff may edit fineAmount (@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

TransitionTokenTrigger
List → detailm-base herorow tap
Sheet present (issue/return)m-base slide-upCTA tap
Availability badge changem-fast fadeafter issue/return refresh
Overdue tag appearm-fast popticker crosses due date
Snackbarm-fastall writes
Dialogm-basedelete / pay confirm

4. Keyboard & adaptive

  • Forms: keyboard avoidance + resizeToAvoidBottomInset; fields advance via onSubmit (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/FineChip expose 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).