feat(ui): keyboard navigation and focus restore in album grid

- Cursor separate from selection; arrow keys move it, Space/Shift+Arrow/Enter/Esc act
- Click on empty grid space clears selection back to album properties
- Focus returns to the last viewed photo after closing the viewer
This commit is contained in:
iu
2026-10-11 14:51:00 +03:00
parent d99ac77587
commit 7359495a73
9 changed files with 588 additions and 5 deletions
@@ -0,0 +1,47 @@
# Proposal
## Why
Сетку фото можно выбирать только мышью: клавиатура не даёт перемещаться между фото, а снять
выделение можно лишь выбрав другое фото. Пользователю в «lightroom»-режиме нужна навигация
стрелками и быстрый возврат к свойствам альбома кликом по пустому месту сетки.
## What Changes
- **Курсор сетки (новое состояние).** Сетка получает «курсор» — текущую ячейку, отдельную от
выделения. Стрелки двигают курсор; выделение при этом не меняется, поэтому правая панель
остаётся на прежнем фото или свойствах альбома.
- **Клавиши.** `←/→` — курсор по документу (с переносом на соседнюю строку), `↑/↓` — на строку
(`density.cols`), с упором в границы. `Space` — переключить выделение ячейки под курсором
(правая панель обновляется), `Shift+стрелки` — двигать курсор и расширять выделение от
якоря, `Enter` — открыть просмотр, `Esc` — снять выделение. Клавиши работают, только когда
фокус внутри сетки.
- **Снятие выделения кликом.** Клик по области сетки и её отступам (не по фото и не по
элементам тулбара/панелей) снимает выделение и возвращает в правой панели свойства
альбома; фокус остаётся в сетке, чтобы стрелки работали сразу.
- **Визуализация.** Курсор показывается отдельным контуром, отличимым от рамки выделения;
оба состояния могут отображаться на одной ячейке.
- **Возврат фокуса из просмотра.** При закрытии просмотра сетка выделяет последнее просмотренное
фото, ставит на него курсор, возвращает фокус и прокручивает к ячейке; фото догружается, если
его нет на загруженной странице.
## Capabilities
### New Capabilities
Нет.
### Modified Capabilities
- `ui-workspace`: добавляются требования «Курсор в сетке фото», «Клавиши сетки фото» и «Снятие
выделения кликом по пустому месту». Поведение выбора мышью не меняется.
## Impact
- **Frontend:** `lib/components/PhotoGrid.svelte` (состояние курсора, обработка клавиш, контур,
roving tabindex), `routes/(app)/albums/[id]/+page.svelte` (курсор/якорь/снятие выделения,
обработчик клика по пустому месту, `scrollIntoView`, догрузка при выходе за загруженные
фото). Стор выделения (`lib/stores/selection.svelte.ts`) не меняет контракт.
- **Спеки:** `ui-workspace` (дельта).
- **Совместимость:** API и данные не затрагиваются; поведение мыши (клик, ctrl/shift, двойной
клик, контекстное меню, drag) сохраняется.