fix(catalog): make columns view height dynamic — drop hardcoded 320/420 caps

Both the catalog flow ($brandName/$modelId) and the VIN-decode flow
(vehicles/$id) render the same CategoryColumns. It was stuck inside a fixed
visual window: container min-height 320px, each column max-height 420px. With
20+ root categories the user saw an internal scrollbar inside an otherwise
short rectangle even though there was plenty of page room.

Make it flex naturally:
- Outer container: min-h-[24rem] keeps a solid floor for empty/cold state,
  max-h-[calc(100dvh-220px)] keeps a 200-leaf catalog from running off the
  bottom of the page. Within that band, height tracks the tallest column's
  natural content (flex stretch — siblings share the height).
- Inner column panels: drop the 420px max-height. Each column flexes to the
  shared height; overflow-y-auto only kicks in when the outer viewport cap
  compresses the row.

Net result: small catalogs render a short, tight columns view; large
catalogs grow to fill the available height up to the viewport cap, then
the columns scroll individually. Same component fixes /catalog/.../$modelId,
/vehicles/$id, and the nested /categories/$categoryId drill.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-06 10:03:09 +03:00
parent 88aa9271a3
commit 6daf59fe8a

View File

@@ -109,8 +109,11 @@ export function CategoryColumns({
return (
<div
ref={scrollRef}
className="flex overflow-x-auto border rounded-md"
style={{ minHeight: 320 }}
// Dynamic height — the outer container stretches to the tallest column's
// natural content (flex children share height), capped at viewport - chrome
// so a 200-leaf catalog can't overflow the page. min-h keeps an empty/cold
// state from collapsing to nothing.
className="flex overflow-x-auto rounded-md border min-h-[24rem] max-h-[calc(100dvh-220px)]"
>
{columns.map((col, colIdx) => (
<ColumnPanel
@@ -212,8 +215,10 @@ function ColumnPanel({
return (
<div
// No fixed maxHeight — each column flexes to the tallest column's height
// (default flex stretch), and overflow-y-auto only kicks in once the outer
// viewport-based cap on the parent compresses the row.
className={cn("w-[220px] shrink-0 overflow-y-auto", !isLast && "border-r")}
style={{ maxHeight: 420 }}
>
{categories.map((category) => {
const isSelected = selectedId === category.id;