fix(tradein-ui): eliminate mobile horizontal overflow on estimate result (#692)

На вьюпортах ≤390px страница результата скроллилась вбок: recharts
ResponsiveContainer (~766px) не зажимался, leaflet-тайлы, широкие comp-таблицы
и top-nav выпирали — flex/grid-ребёнок с дефолтным min-width:auto не ужимался.

trade-in.css: html/body/.page overflow-x:clip (страховка, не ломает sticky);
.result-col>* min-width:0/max-width:100%; recharts-обёртки max-width:100%;
leaflet MapCard + comp-таблицы (table.dt/.offer-tbl) max-width:100%;
@≤720px top-nav flex-wrap. HouseAnalyticsSection (unclassed flex-ребёнок с
PriceHistoryChart) min-width:0. Raw-таблицы RecentSoldList/PlacementHistoryCard
(не блок-стакаются) — overflow-x:auto: скролл ВНУТРИ карточки, не страницы.
Desktop-neutral (media-scoped/shrink-only).

Closes #692
This commit is contained in:
lekss361 2026-05-30 11:39:27 +03:00
parent 10626c21ae
commit 2942c09b0e
4 changed files with 42 additions and 3 deletions

View file

@ -15,7 +15,7 @@ export function HouseAnalyticsSection({ estimateId }: Props) {
if (data.kpi.total_lots === 0) return null; if (data.kpi.total_lots === 0) return null;
return ( return (
<section style={{ marginTop: 16 }}> <section style={{ marginTop: 16, minWidth: 0, maxWidth: "100%" }}>
<header <header
style={{ style={{
marginBottom: 12, marginBottom: 12,

View file

@ -44,7 +44,7 @@ export function PlacementHistoryCard({ estimateId }: Props) {
{items.length} лот{items.length === 1 ? "" : "ов"} {items.length} лот{items.length === 1 ? "" : "ов"}
</small> </small>
</header> </header>
<div style={{ padding: "8px 16px 16px" }}> <div style={{ padding: "8px 16px 16px", overflowX: "auto" }}>
<table <table
style={{ width: "100%", fontSize: 13, borderCollapse: "collapse" }} style={{ width: "100%", fontSize: 13, borderCollapse: "collapse" }}
> >

View file

@ -28,7 +28,7 @@ export function RecentSoldList({ items }: Props) {
{items.length} лот{suffix} {items.length} лот{suffix}
</small> </small>
</header> </header>
<div style={{ padding: "8px 16px 16px" }}> <div style={{ padding: "8px 16px 16px", overflowX: "auto" }}>
<table <table
style={{ width: "100%", fontSize: 13, borderCollapse: "collapse" }} style={{ width: "100%", fontSize: 13, borderCollapse: "collapse" }}
> >

View file

@ -2215,3 +2215,42 @@
.whatif-row { grid-template-columns: 1fr; } .whatif-row { grid-template-columns: 1fr; }
} }
@keyframes ti-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } } @keyframes ti-spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
/* ============================================================
#692 Mobile horizontal-overflow guard (390px)
Root causes: recharts ResponsiveContainer / Leaflet tiles /
wide comp-tables / top-nav, все push width когда flex/grid
ребёнок имеет дефолтный min-width:auto и не может ужаться.
Эти правила desktop-neutral: на 1100px ничего не меняют
(layout уже single-col и контент влезает), только страхуют
узкие вьюпорты от бокового скролла страницы.
============================================================ */
/* Последняя линия обороны: страница никогда не скроллится вбок.
clip (не hidden) не создаёт scroll-container, не ломает sticky. */
html, body { overflow-x: clip; }
.page { max-width: 100%; overflow-x: clip; }
/* Каждая прямая карточка/секция результат-колонки должна уметь
ужиматься (flex-ребёнок по умолчанию min-width:auto). .result-col
уже min-width:0; добавляем то же его детям + клип переполнения. */
.result-col > * { min-width: 0; max-width: 100%; }
/* Recharts: контейнер графика всегда 100% ширины родителя и
не шире её ResponsiveContainer мерит этот box. */
.recharts-responsive-container,
.recharts-wrapper { max-width: 100%; }
/* Leaflet-обёртка карты (MapCard) — не даём тайлам растянуть карточку. */
.card > [aria-label="Карта аналогов и сделок"] { max-width: 100%; }
/* Comp/analog-таблицы со «склейкой» listing-ячейки шире остального:
на узких вьюпортах горизонтальный скролл ВНУТРИ карточки, не страницы. */
.card > table.dt,
.card > table.offer-tbl { max-width: 100%; }
@media (max-width: 720px) {
/* Topbar: nav переносится и не выпирает за ширину бара. */
.top-nav { flex-wrap: wrap; min-width: 0; margin-left: auto; }
.topbar-inner { max-width: 100%; }
}