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 (Settings Module)

Module-specific interactions precise for the settings list, typed editors and batch save, layered on shared 00-shared/08. Covers every input modality on phone/tablet/desktop.


1. Phone / touch

GestureBehaviourWhere
Tapopen row, open editor, toggle switch, chip filter, FAB newall
Tap row menuAppMenu (Edit value, Duplicate key, Delete)rows
Long-pressenter batch selection mode (multi-select)rows
Double-tapnone (no media)
Swipe leftnone — destructive swipe disabled (delete needs confirm)
Pull downRefreshIndicator → refetch current group (bypasses cache)list
Pinch/dragnone
Hardware backclose editor (discard prompt if dirty) → list; on root → exitall
Edge swipeshell drawer (authed)shell

2. Keyboard / desktop / mouse

InputBehaviour
Tabsearch → chips → rows → FAB (desktop pane: then detail fields key→group→value)
Entersave active editor (single-line); submit Create sheet
Escclose editor/sheet/dialog → focus returns to trigger; cancels selection mode
Ctrl/Cmd+Ffocus client search (00-shared/08 §2)
Ctrl/Cmd+Entersave JSON editor
+ / Nnew setting (list screen, desktop)
Arrowsnavigate group chips (focused chip), dropdown options
Right-clickcontext menu (same as long-press: row menu, multi-select toggle)
Hoverrow tint m-fast, tooltip after 500 ms (key copy button, type chip)
Focusvisible primary ring on all controls; logical order

3. Haptics (mobile)

EventHapticRef
Save successlightImpact
Save/batch failuremediumImpact
Boolean toggle appliedselectionClick
Delete confirmheavyImpact
Ruledisabled when system haptics off; none on desktop08 §3

4. Motion language (module extension of 00-shared/08 §4)

TransitionDuration/curveUsed by
Route push (list→detail)m-base slidephone
Detail pane swap (master-detail)m-base fadetablet/desktop
Row saved → dirty dot clearsm-fast fadelist
Row removed (delete)m-base fade-outlist
Batch bar appearsm-entrance (300 ms, easeOutBack)list
JSON editor errorm-fast outline color swap + AnimatedSwitcher message (no shake)editors
FAB hide/show on scrollm-entrance/fade, scroll-dir drivenlist

Reduced-motion: fades + instant only; no stagger, no entrance bounce (00-shared/08 §4).

5. Micro-interactions catalogue

InteractionDetail
Save pressedbutton loading spinner swap m-base; double-tap locked; on success check + snackbar
Boolean toggleswitch animates m-fast, optimistic; failure → rollback + error snackbar
Group chip tapchip indicator slide m-base; list refetches (server filter)
Dirty editrow dot primary pops in m-fast; Save bar count updates
Batch save completesper-row ✓/✗ (m-fast); snackbar "Saved N of M"
Type chip taptooltip "value type: number" (desktop) / no-op (phone)
Key copy (detail)Clipboard.setData + snackbar "Copied" + selectionClick

6. Frustration controls (shared 08 §6 + module)

  • All presses respond < 100 ms with m-fast ripple.
  • Every network action shows pending state (row spinner, button spinner).
  • Save buttons disabled while pending — no double-submit.
  • 429 → never auto-retry; countdown surfaced.
  • Errors persist until corrected/dismissed (banner or inline field error).

7. Special interactions

  • Batch retry: tap a failed row's ✓/✗ chip → re-sends the full dirty set for that key (idempotent upsert, 08 §4).
  • JSON paste: editor accepts multi-line paste; parse check runs debounced (300 ms); invalid → Save disabled until fixed.
  • Deep links (forward-looking): studylyon://settings/group/:group pre-selects chip; studylyon://settings/:key opens detail directly.

8. Validation of interaction to server semantics

  • "Save all" only ever sends dirty keys, each as full {key, value, group} — matches PUT /settings/bulk (settings.controller.ts:43-47).
  • No optimistic saves for explicit editors (server truth returned in data, setting.repository.ts:39).
  • Delete never offers undo (soft-delete is irreversible through the API — OQ-5).
  • Group chips always refetch server-side — never client-filter the full list, because the API contract filters on the server (settings.controller.ts:26-28).