(low) Drawer.tsx/Drawer: восстановление фокуса на close может не сработать для размонтированного триггера #1483

Closed
opened 2026-06-15 05:57:47 +00:00 by bot-backend · 0 comments
Collaborator

Severity: low · Категория: frontend · Файл: frontend/src/components/ui/Drawer.tsx:36-51

Drawer.tsx:36-51. Эффект с зависимостью [open] сохраняет document.activeElement в previousFocusRef при открытии (стр.38) и восстанавливает фокус в ветке else (стр.47-49), проверяя только instanceof HTMLElement. Если триггерный элемент (например строка таблицы конкурентов в Section3, открывшая drawer) был размонтирован/отфильтрован за время, пока drawer открыт (таблица управляется фильтрами FilterState — radiusKm/onlyUnderConstruction и т.д., смена фильтра при открытом drawer перерендерит/удалит строку), сохранённая ссылка станет detached-узлом. Проверка instanceof HTMLElement пройдёт (detached-узел всё ещё HTMLElement), но .focus() на detached-узле — no-op: фокус не вернётся куда задумано и упадёт на body. Это потеря a11y-контекста для модального drawer (заявлен focus trap, стр.29). Импакт ограничен UX/a11y → low. Чинить: проверять document.contains(previousFocusRef.current) перед .focus(), либо fallback на разумный элемент при detached, либо сбрасывать ref после восстановления.

Почему баг: Эффект зависит только от [open] и хранит ссылку на DOM-узел через несколько ре-рендеров. В Section3SettingsAndCompetitors drawer открывается по строке таблицы конкурентов, а таблица управляется фильтрами (FilterState, radiusKm/onlyUnderConstruction и т.д.) — переключение фильтра при открытом drawer может перерендерить/удалить исходную строку, и сохранённый previousFocusRef станет detached. Импакт ограничен a11y/UX (фокус не вернётся куда надо), поэтому low, но это реальный логический дефект восстановления фокуса, а не стиль.

Как чинить: Перед .focus() проверять document.contains(previousFocusRef.current) и при false фокусировать разумный fallback (триггер по id или document.body с последующим возвратом на контейнер списка). Также обнулять previousFocusRef после восстановления.


deep-audit «армия ботов 2» · verify+harden, confidence 0.7 · unit U104

**Severity:** low · **Категория:** frontend · **Файл:** `frontend/src/components/ui/Drawer.tsx:36-51` Drawer.tsx:36-51. Эффект с зависимостью [open] сохраняет document.activeElement в previousFocusRef при открытии (стр.38) и восстанавливает фокус в ветке else (стр.47-49), проверяя только instanceof HTMLElement. Если триггерный элемент (например строка таблицы конкурентов в Section3, открывшая drawer) был размонтирован/отфильтрован за время, пока drawer открыт (таблица управляется фильтрами FilterState — radiusKm/onlyUnderConstruction и т.д., смена фильтра при открытом drawer перерендерит/удалит строку), сохранённая ссылка станет detached-узлом. Проверка instanceof HTMLElement пройдёт (detached-узел всё ещё HTMLElement), но .focus() на detached-узле — no-op: фокус не вернётся куда задумано и упадёт на body. Это потеря a11y-контекста для модального drawer (заявлен focus trap, стр.29). Импакт ограничен UX/a11y → low. Чинить: проверять document.contains(previousFocusRef.current) перед .focus(), либо fallback на разумный элемент при detached, либо сбрасывать ref после восстановления. **Почему баг:** Эффект зависит только от [open] и хранит ссылку на DOM-узел через несколько ре-рендеров. В Section3SettingsAndCompetitors drawer открывается по строке таблицы конкурентов, а таблица управляется фильтрами (FilterState, radiusKm/onlyUnderConstruction и т.д.) — переключение фильтра при открытом drawer может перерендерить/удалить исходную строку, и сохранённый previousFocusRef станет detached. Импакт ограничен a11y/UX (фокус не вернётся куда надо), поэтому low, но это реальный логический дефект восстановления фокуса, а не стиль. **Как чинить:** Перед .focus() проверять document.contains(previousFocusRef.current) и при false фокусировать разумный fallback (триггер по id или document.body с последующим возвратом на контейнер списка). Также обнулять previousFocusRef после восстановления. --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.7 · unit U104</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:57:47 +00:00
bot-backend added the
scope/frontend
label 2026-06-15 11:02:11 +00:00
Sign in to join this conversation.
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#1483
No description provided.