Контекст: В проекте 7 мест с ad-hoc модалками и проблема со скроллбаром на оверлее. Нужно было выбрать между починкой на месте и извлечением переиспользуемого компонента.
| Подход | Плюсы | Минусы |
|---|---|---|
Исправить на месте (добавить max-h-[90vh] overflow-y-auto в каждую) |
Минимум изменений, нет нового кода | Нарушает DRY, будущие модалки снова ad-hoc, сложнее поддерживать единообразие |
| Извлечь компонент Modal (выбрано) | DRY, единый источник стилей, новые модалки сразу правильные, упрощает рефакторинг | +1 файл, need migration 7 мест |
| Headless UI / Radix Dialog | a11y из коробки, portal, focus trap | Зависимость, переписывание всех стилей, избыточно для текущего масштаба |
Извлечение компонента Modal. Почему:
stopPropagation — явный код-смэллmax-h-[90vh] overflow-y-auto на inner div)sm/md/lg/xl), className override для кастомного фонаФайл: frontend/src/components/Modal.tsx
// Ключевая строка — скроллбар внутри контента
className={`w-full ${sizeClasses[size]} max-h-[90vh] overflow-y-auto ... ${className}`}
graph TD
A[7 ad-hoc модалок<br/>разный scroll/no-scroll] --> B[1 компонент Modal]
B --> C[Скроллбар внутри модалки]
B --> D[Единый стиль]
B --> E[Будущие модалки = 1 строчка]
Задача 2026-07-04: «Если в модалке нужен скроллбар, то он должен быть внутри модалки».
#decision #frontend #react #modal #DRY #refactoring