fix(ui/toasts): глобальная видимость (тон+рамка+тень) + перенос в top-center без перекрытия (#517) #528
Reference in New Issue
Block a user
Delete Branch "fix/517-toasts"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Реviewer-filed баг #517: тосты почти не видны (в светлой теме фон карточки =
var(--mantine-color-body)= тот же белый, что страница; тень едва заметна → нет видимого края) и всплывают внизу (bottom-center), перекрывая контент. closes #517. Чиним ГЛОБАЛЬНО (один механизм, без правок в 213 call-site).apps/client/src/styles/notification-overrides.css: безусловный override корня тоста (.mantine-Notification-root) даёт видимый край — рамка +shadow-xl+ лёгкий тон из--notification-color(light: ~10% на белом, dark: 14% на dark-6 + dark-3 рамка). Покрывает и бесцветные success/info, и loading/импорт-тост (у него нет акцент-полосы — слот иконки занят спиннером). Специфичность[data-mantine-color-scheme] .mantine-Notification-root= (0,2,0) выигрывает у mantine:where(...) .m_a513464= (0,1,0) для фона/рамки/тени (проверено в собранном CSS).main.tsx:bottom-center→top-center. Смещение под фикс-хром (45px шапка + опц. форматтулбар) — через CSS.mantine-Notifications-root[data-position^=top] { top: 96px }, НЕ через инлайнstyle(Mantine рендерит все шесть позиционных контейнеров, инлайнstyleпопал бы во все → нижние сtop+bottomрастянулись бы на весь вьюпорт невидимыми кликоперехватчиками — этот блокер поймало внутреннее ревью и починено). z-10000 сохранён; тост сидит ниже шапки (z-99), кликов не перехватывает.How verified
tsc -p apps/client0;vite buildзелёный. В собранном CSS:top:96pxровно один раз как[data-position^=top], в JS-бандлеtop:96ноль (инлайн убран); нижние контейнеры безtop→ height:0, оверлея нет.Осознанное ограничение
Юнит-теста нет (визуальный фикс без браузера; полный рендер
<Notifications>требует MantineProvider+store). Доказательство — собранный CSS (top-scoped offset, нижние без top) + специфичность по исходнику Mantine. Стандартные визуальные проверки — на стенде.Checklist
Тост-уведомления Mantine сливались с фоном: у бесцветных тостов фон карточки == var(--mantine-color-body) (белый, как страница) при слабой тени, поэтому на белых страницах у карточки не было видимого края. Плюс тосты всплывали снизу по центру и перекрывали контент. Чиним глобально, без правок в 213 местах вызова: - notification-overrides.css: каждому тосту даём тонированный по типу фон, рамку с контрастом WCAG >= 3:1 и усиленную тень (shadow-xl). Селектор [data-mantine-color-scheme=...] .mantine-Notification-root имеет специфичность (0,2,0) и стабильно бьёт правила Mantine (0,1,0) (у Mantine атрибут схемы обёрнут в :where()) — независимо от порядка стилей. Тон/рамка идут от --notification-color (определён на том же элементе), поэтому следуют типу тоста и покрывают loading/импортный тост (полосы-акцента нет — несут тон+рамка+тень+цветной спиннер). Обе темы; текст-с-заголовком поднят до gray-7 ради AA-контраста на тонированном фоне. - main.tsx: position bottom-center -> top-center. Вертикальное смещение контейнера ниже верхней хромы делаем НЕ инлайн-стилем, а CSS-правилом со скоупом по позиции: Mantine рендерит все шесть позиционных контейнеров одновременно, и корневой style-проп ушёл бы во все шесть — нижним (bottom:16) добавился бы top:96 → position:fixed + оба края + height:auto растянули бы их на весь вьюпорт; у корня нет pointer-events:none/фона → прозрачные оверлеи z-10000 перехватывали бы клики по всей странице. - notification-overrides.css: .mantine-Notifications-root[data-position^='top'] { top:96px } (шапка 45 + опц. тулбар 45 + зазор). Скоуп ^='top' смещает только верхние контейнеры; нижние остаются height:0 и кликов не перехватывают. Специфичность (0,2,0) бьёт mantine top:16px (0,1,0), тост z-10000 стоит ниже шапки/тулбара (z-99) и их не перекрывает. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>🤖 Авто-ревью · #528 (ui/toasts видимость + top-center, #517) — голова
51260793. Вердикт: PASS ✅Чистая, аккуратная CSS-работа — багов нет. Pure presentational (2 файла, +74), объективно-логической поверхности нет; сфокусировал веер на значимых углах (specificity-crux + coherence/regressions + conventions/doc/simplification), сверил лично + два субагента против УСТАНОВЛЕННОГО Mantine 8.3.18 CSS.
Сверено:
!important: override[data-mantine-color-scheme] .mantine-Notification-root= (0,2,0) бьёт mantine:where(...) .m_a513464= (0,1,0) для bg/border/shadow в обеих темах (mantine оборачивает scheme в:where()→ 0). Не-layerstyles.css,withStaticClassesне выключен → класс эмитится. Акцент-полоса::before(per-toast--notification-color) НЕ тронута, tint/border её же и юзают → тон по типу тоста сохраняется.top/inline-style растянул бы прозрачные bottom-* z-10000 контейнеры на весь вьюпорт и глотал бы клики по всей странице; scoping[data-position^='top']это чинит. Оффсет 96px (45 шапка + 45 тулбар + 6) сверен против реальных высот, чистит хром.gray-6→gray-7для titled-тостов (AA), консистентно с theme.ts.notifications.show; standalone<Notification>нет; in-app inbox юзает свойnotification.module.css. Override трогает только тосты.*-overrides.cssвstyles/точно следует прецедентуa11y-overrides.css(не theme-config — tint нотификейшн-скоупед).Гейт: client tsc чист (без ошибок от изменения), CSS-импорт резолвится. Для pure-CSS достаточно.
Отличный фикс. Approve.