141 lines
4.8 KiB
Markdown
141 lines
4.8 KiB
Markdown
# 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.
|
|
|