feat(report): nav scrollspy + offset-jump, чат в плавающее окно справа (#958) #2104

Merged
bot-backend merged 1 commit from feat/report-nav-scrollspy-chat-dock into main 2026-06-30 10:29:03 +00:00
Collaborator

Summary

Две UX-правки отчёта site-finder по фидбеку Anton.

1. Навигация — «прыгает надёжно + идёт за скролом»

  • Scrollspy: AnalysisSidebarNav подсвечивает активную секцию (accent-soft фон + левый accent-бар + aria-current) через IntersectionObserver (rootMargin: -72px 0px -60% 0px — активная полоса ниже sticky-шапки; берётся верхняя из пересекающихся). SSR-guard, disconnect на unmount.
  • Надёжный переход: вместо scrollIntoView({behavior:smooth}) — абсолютный window.scrollTo(getBoundingClientRect().top + scrollY − 80). Раньше «не прыгало», т.к. при клике во время async-подгрузки §6 (~20-40с) высоты сдвигались посреди smooth-scroll → промах. Абсолютный таргет + offset 80px (= sticky-хром) попадает точно.

2. Чат — «окошком справа, едет со скролом, спросить в любой момент»

  • ChatPanel больше не вмонтирован внизу колонки. Новый ChatDock оборачивает его в position: fixed сворачиваемое окно справа-снизу: лончер «Спросить по участку» (MessageSquare) → попап role="dialog" (min(420px, 100vw−32) × min(640px, 100vh−120)); закрытие по X и Esc. Доступен при любом скролле.
  • Хром дока — только close-бар (без дубля заголовка; ChatPanel несёт свой). ChatPanel не тронут.

box-shadow только на плавающих лончере/попапе (разрешено ui-tokens для popover), не на in-page карточках.

Test plan

  • tsc --noEmit clean, next lint clean, prettier
  • code-reviewer APPROVE (scrollspy без утечек, targets существуют на mount success-ветки; ChatDock Esc-listener cleaned up; токены/a11y/конвенции ок; ChatPanel без регресса)
  • post-deploy скриншот-верификация: скролл → активный пункт трекает секции; клик по пунктам (в т.ч. после загрузки §6) → заголовок ложится ~80px от верха, не под шапкой; лончер виден при любом скролле; open → ChatPanel, X/Esc закрывают.

Refs #958, эпик #1953.

## Summary Две UX-правки отчёта site-finder по фидбеку Anton. ### 1. Навигация — «прыгает надёжно + идёт за скролом» - **Scrollspy:** `AnalysisSidebarNav` подсвечивает активную секцию (accent-soft фон + левый accent-бар + `aria-current`) через `IntersectionObserver` (`rootMargin: -72px 0px -60% 0px` — активная полоса ниже sticky-шапки; берётся верхняя из пересекающихся). SSR-guard, disconnect на unmount. - **Надёжный переход:** вместо `scrollIntoView({behavior:smooth})` — абсолютный `window.scrollTo(getBoundingClientRect().top + scrollY − 80)`. Раньше «не прыгало», т.к. при клике во время async-подгрузки §6 (~20-40с) высоты сдвигались посреди smooth-scroll → промах. Абсолютный таргет + offset 80px (= sticky-хром) попадает точно. ### 2. Чат — «окошком справа, едет со скролом, спросить в любой момент» - `ChatPanel` больше не вмонтирован внизу колонки. Новый **`ChatDock`** оборачивает его в `position: fixed` сворачиваемое окно справа-снизу: лончер «Спросить по участку» (MessageSquare) → попап `role="dialog"` (`min(420px, 100vw−32)` × `min(640px, 100vh−120)`); закрытие по **X** и **Esc**. Доступен при любом скролле. - Хром дока — только close-бар (без дубля заголовка; ChatPanel несёт свой). `ChatPanel` не тронут. box-shadow только на плавающих лончере/попапе (разрешено `ui-tokens` для popover), не на in-page карточках. ## Test plan - [x] `tsc --noEmit` clean, `next lint` clean, prettier - [x] code-reviewer ✅ APPROVE (scrollspy без утечек, targets существуют на mount success-ветки; ChatDock Esc-listener cleaned up; токены/a11y/конвенции ок; ChatPanel без регресса) - [ ] post-deploy скриншот-верификация: скролл → активный пункт трекает секции; клик по пунктам (в т.ч. после загрузки §6) → заголовок ложится ~80px от верха, не под шапкой; лончер виден при любом скролле; open → ChatPanel, X/Esc закрывают. Refs #958, эпик #1953.
bot-backend added 1 commit 2026-06-30 10:25:45 +00:00
feat(report): nav scrollspy + offset-jump, чат в плавающее окно справа (#958)
All checks were successful
CI / changes (pull_request) Successful in 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 56s
CI / openapi-codegen-check (pull_request) Successful in 1m54s
185cf81d83
Навигация:
- AnalysisSidebarNav подсвечивает активную секцию через IntersectionObserver
  (rootMargin -72px/-60% — активная полоса ниже sticky-шапки) + aria-current.
- Переход по пунктам — абсолютный window.scrollTo с offset 80px вместо
  scrollIntoView: попадает точно даже после async-подгрузки §6 (высоты
  сдвигаются во время smooth-scroll → раньше «не прыгало»).

Чат:
- ChatPanel больше не вмонтирован внизу колонки. Новый ChatDock оборачивает его
  в fixed сворачиваемое окно справа-снизу (лончер «Спросить по участку», Esc / X
  закрывают) — доступен при любом скролле, едет со скролом (position: fixed).
- Хром дока — только close-бар, чтобы не дублировать собственный заголовок
  ChatPanel (без вложенных карточек). ChatPanel не тронут.
bot-backend merged commit 02f49e795c into main 2026-06-30 10:29:03 +00:00
bot-backend deleted branch feat/report-nav-scrollspy-chat-dock 2026-06-30 10:29:03 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#2104
No description provided.