diff --git a/docs/superpowers/specs/2026-06-18-pagination-loading-overlay-design.md b/docs/superpowers/specs/2026-06-18-pagination-loading-overlay-design.md new file mode 100644 index 0000000..86e5c79 --- /dev/null +++ b/docs/superpowers/specs/2026-06-18-pagination-loading-overlay-design.md @@ -0,0 +1,116 @@ +# Индикация загрузки при переключении страниц в таблицах брокера + +Дата: 2026-06-18 +Статус: черновик + +## Контекст + +Страница детального просмотра брокерского счёта (`BrokerAccountDetailPage.tsx`) содержит несколько таблиц с пагинацией: + +- **PositionGroupTable** — Акции, Облигации, ETF, Фонды (4 независимые таблицы с курсорной пагинацией) +- **BrokerOperationsTable** — Операции (курсорная пагинация, управляемая из родительского компонента) + +Текущее поведение при переключении страниц: `isLoading === true` → таблица скрывается, показывается `TableSkeleton` (shimmer-строки). Это создаёт визуальный flash: контент исчезает → скелетон → новые данные. При этом `placeholderData: keepPreviousData` уже настроен в хуках, но компоненты его не используют — они проверяют `isLoading`, а не `data`. + +## Цель + +Добавить плавную индикацию загрузки при переключении страниц, чтобы пользователь видел, что данные обновляются, но не терял визуальный контекст. + +## Дизайн (выбран C3) + +### Визуальное поведение + +1. При нажатии «→» (вперед) или «←» (назад): + - Текущее содержимое таблицы **остаётся видимым** (предыдущая страница) + - Поверх таблицы появляется **полупрозрачный overlay** с центрированным спиннером + - Кнопка пагинации показывает спиннер и блокируется +2. Когда новые данные загружены: + - Overlay исчезает с fade-out + - Таблица обновляется новыми данными +3. При первой загрузке (initial load): + - Overlay не используется (нет старых данных для показа) + - Показывается `TableSkeleton` (как сейчас) + +### Как это работает технически + +TanStack Query v5 предоставляет два флага: + +- `isLoading` — true, когда данных **нет** и идёт первый запрос (initial load) +- `isFetching` — true при любом запросе (включая фоновые refetch'и при смене cursor) + +Логика рендеринга для таблиц: + +``` +if isLoading → TableSkeleton (первая загрузка, данных нет) +if isFetching && data → TableLoadingOverlay + старые данные (переключение страниц) +иначе → рендер таблицы с данными +``` + +### Компонент TableLoadingOverlay + +```tsx +interface TableLoadingOverlayProps { + pageNumber?: number; +} + +function TableLoadingOverlay({ pageNumber }: TableLoadingOverlayProps) { + return ( +