fix(table+layout): TableHead alias to THEAD wrapper + kill horizontal scroll
CRITICAL bugs reported by user — table выглядела кривой, контент уезжал
за экран с горизонтальным скроллом.
Bug 1 — invalid HTML в Table:
Callsites используют <TableHead><TableRow><TableHeaderCell>... ожидая
нstart-style THEAD wrapper. Но мой alias делал TableHead = TableHeaderCell
(TH cell). Получалось <th><tr><th>...</th></tr></th> — invalid nested,
browser parser hoist'ил TableRow наружу, создавая phantom 509px column
слева от данных. Колонки выглядели misaligned, content смещён вправо.
Fix: TableHead → THEAD wrapper (alias TableHeader). TableHeaderCell
остаётся отдельным TH cell. Source semantically correct, browser parses
валидно, phantom column исчез.
Bug 2 — horizontal overflow:
Scope strip border на верху detail-страницы использовал
'-mt-6 -mx-4 sm:-mx-6 lg:-mx-8'. На lg viewport main padding только
sm:px-6 (24px), strip negative margins -mx-8 (32px) → 8px overflow each
side → body.scrollWidth > viewport → horizontal scrollbar.
Fix:
- Strip negative margins только до -mx-6 (соответствует main padding)
- main получил overflow-x-clip + max-w-7xl wrapper получил min-w-0
(защита от любых future overflow children)
Verified в preview viewport 1440 + 375: body.scrollWidth === viewport,
no h-scroll.
This commit is contained in:
@@ -36,8 +36,8 @@ function RootLayout() {
|
|||||||
<MobileSidebar open={mobileNavOpen} onClose={() => setMobileNavOpen(false)} />
|
<MobileSidebar open={mobileNavOpen} onClose={() => setMobileNavOpen(false)} />
|
||||||
<div className="flex-1 flex flex-col min-w-0">
|
<div className="flex-1 flex flex-col min-w-0">
|
||||||
<TopBar onMenuClick={() => setMobileNavOpen(true)} />
|
<TopBar onMenuClick={() => setMobileNavOpen(true)} />
|
||||||
<main className="flex-1 overflow-y-auto px-4 sm:px-6 py-4 sm:py-6">
|
<main className="flex-1 overflow-y-auto overflow-x-clip px-4 sm:px-6 py-4 sm:py-6">
|
||||||
<div className="max-w-7xl mx-auto w-full">
|
<div className="max-w-7xl mx-auto w-full min-w-0">
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -498,7 +498,7 @@ function DictionaryDetail() {
|
|||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{scope && (
|
{scope && (
|
||||||
<div
|
<div
|
||||||
className={`-mt-6 -mx-4 sm:-mx-6 lg:-mx-8 mb-2 h-1 border-t-4 ${SCOPE_BORDER_TOP[scope]}`}
|
className={`-mt-4 sm:-mt-6 -mx-4 sm:-mx-6 mb-2 h-1 border-t-4 ${SCOPE_BORDER_TOP[scope]}`}
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ export const TableHeader = React.forwardRef<
|
|||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
// nstart-compat alias: nstart использовал <TableHead> как THEAD wrapper.
|
||||||
|
// shadcn по convention использует TableHead как TH cell — это конфликтовало
|
||||||
|
// (callsites писали `<TableHead><TableRow>...` ожидая THEAD-семантику).
|
||||||
|
// Резолвим в пользу nstart-compat (callsites больше). Для TH cell — TableHeaderCell.
|
||||||
|
export const TableHead = TableHeader
|
||||||
|
|
||||||
export const TableBody = React.forwardRef<
|
export const TableBody = React.forwardRef<
|
||||||
HTMLTableSectionElement,
|
HTMLTableSectionElement,
|
||||||
@@ -104,8 +109,6 @@ export const TableHeaderCell = React.forwardRef<HTMLTableCellElement, TableHeade
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
// Alias for shadcn convention.
|
|
||||||
export const TableHead = TableHeaderCell
|
|
||||||
|
|
||||||
export const TableCell = React.forwardRef<
|
export const TableCell = React.forwardRef<
|
||||||
HTMLTableCellElement,
|
HTMLTableCellElement,
|
||||||
|
|||||||
Reference in New Issue
Block a user