diff --git a/project_docs/UI_KEYBOARD_V1_DESIGN.md b/project_docs/UI_KEYBOARD_V1_DESIGN.md new file mode 100644 index 0000000..85dd9ed --- /dev/null +++ b/project_docs/UI_KEYBOARD_V1_DESIGN.md @@ -0,0 +1,140 @@ +# UI_KEYBOARD_V1_DESIGN.md + +## 1) Doel + +Keyboard navigation v1 maakt de huidige dual-pane UI efficiƫnter voor snelle bestandsnavigatie en selectie, in lijn met een Midnight Commander-achtige workflow: minder muisgebruik, voorspelbare focus, snelle pane-switching. + +### In scope (v1) +- `Tab` wisselt actief paneel. +- `ArrowUp` / `ArrowDown` verplaatst `current row` in actief paneel. +- `Enter` opent de map van de `current row` als die row een directory is. +- `Space` togglet selectie van `current row`. +- `Escape` wist selectie in actief paneel. + +### Out of scope (v1) +- Geen `F3/F4` viewer/editor. +- Geen `F5/F6/F7/F8` keyboard-acties. +- Geen shift/ctrl/insert multi-selectgedrag. +- Geen globale override van onbetrouwbare browser-shortcuts. + +--- + +## 2) Scope Keyboard v1 (klein en veilig) + +### Shortcutset +- `Tab`: + - als focus niet in een input/control zit: wissel `activePane` (`left` <-> `right`). + - default browser tab-navigatie blokkeren in dit geval. +- `ArrowUp` / `ArrowDown`: + - beweeg `currentRowIndex` binnen zichtbare lijst van actief paneel. + - clamp tussen `0` en `items.length - 1`. + - geen wrap-around in v1. +- `Enter`: + - als `current row` directory is: navigeer naar die directory. + - als `current row` file is: geen open; behoud selectiegedrag (geen viewer). +- `Space`: + - toggle selectie op `current row` item. +- `Escape`: + - clear alle geselecteerde items in actief paneel. + +--- + +## 3) State model + +Per paneel (`left`/`right`) expliciet onderscheid: +- `currentPath`: huidige padcontext. +- `entries`: gecombineerde zichtbare lijst (dirs/files) in rendervolgorde. +- `currentRowIndex`: keyboard-cursorpositie binnen `entries`. +- `selectedItems`: geselecteerde items (set/list op pad). + +Globaal: +- `activePane`: `left` of `right`. + +### Semantiek +- `current row` is focus/cursor voor keyboardnavigatie. +- `selected items` is actiedoel (rename/delete/copy/move-regels blijven gelden). +- `active pane` bepaalt waar keyboardinput op werkt. + +### Bij navigatie +- `ArrowUp/Down` verandert alleen `currentRowIndex` in actief paneel. +- Geen wijziging in ander paneel. + +### Bij directory openen (`Enter` op directory) +- Navigeer in actief paneel naar directory. +- Wis selectie in actief paneel. +- Reset `currentRowIndex` naar eerste item (of `null` bij lege lijst). +- Inactief paneel blijft ongewijzigd. + +### Bij leeg paneel +- `currentRowIndex = null`. +- `ArrowUp/Down/Enter/Space` doen niets. +- `Escape` blijft selectie-clear uitvoeren (idempotent). + +--- + +## 4) UX-regels + +### Focusveiligheid +Shortcuts zijn alleen actief als event target **geen** interactieve invoercontrol is: +- `input`, `textarea`, `select`, `button`, checkbox, of `contenteditable`. + +### Wanneer shortcuts actief zijn +- Alleen op documentniveau handler als focus op lijst/paneelcontainer of body staat. +- Als gebruiker expliciet in form/control werkt, geen keyboard-capturing. + +### Visualisatie +- `current row` krijgt aparte, subtiele cursorstijl (`is-current-row`). +- `selected rows` behouden bestaande selectiehighlight (`is-selected`). +- Row kan beide states tegelijk hebben: current + selected. +- `activePane` blijft via border/focusrand zichtbaar; geen sterke achtergrondwissel. + +--- + +## 5) Impactanalyse + +Waarschijnlijk te wijzigen: +- `webui/html/app.js` + - keyboard event handling + - state uitbreiding met `currentRowIndex` + - paneelgerichte row-navigation helpers +- `webui/html/style.css` + - styling voor `is-current-row` + gecombineerde state met `is-selected` +- `webui/html/index.html` + - alleen kleine aanpassingen indien nodig (bv. paneelcontainer attributes) +- `webui/backend/tests/golden/test_ui_smoke_golden.py` + - alleen bij structurele id/class wijzigingen + +### Regressierisico +- Bestaande klik/selectieflow kan botsen met nieuwe current-row state. +- Event bubbling kan dubbele selectie-updates geven. +- Tab-handling kan browser-focusflow verstoren als te agressief. + +Mitigatie: +- Centrale `shouldHandleShortcut(event)` guard. +- Centrale helpers voor `setCurrentRow`, `toggleSelectionForCurrentRow`, `openCurrentRowDirectory`. +- Geen backendaanpassingen. + +--- + +## 6) Teststrategie + +### Geautomatiseerd (klein) +- Bestaande UI smoke tests behouden (`/ui`, panelen, assets). +- Optioneel kleine regressietest op aanwezigheid van paneelcontainers en lijststructuur; geen zware browser-E2E in v1. + +### Handmatige validatie (primair voor v1) +- `Tab` wisselt actief paneel betrouwbaar. +- `ArrowUp/Down` beweegt current row alleen in actief paneel. +- `Enter` opent alleen directory op current row. +- `Space` togglet selectie op current row. +- `Escape` wist selectie in actief paneel. +- Shortcuts doen niets tijdens focus in input/checkbox/button. +- Leeg paneel geeft geen errors bij keyboardinput. + +### Regressiechecks +- Bestaand klikgedrag blijft intact: + - checkbox toggle + - rij-click selectie + - directory-naam opent directory +- Onderbalkacties blijven werken op `selectedItems` van actief paneel. +