fix: наезд подзаголовков таблицы сравнения на первую строку

Второй ряд шапки (Наименование ТМЦ/Ед.изм./Кол-во/Цена/Сумма) прибит
sticky с захардкоженным top:70px, а реальная высота ряда поставщика больше
(имя, индикатор Adata, теги валют, статус, кнопки) — из-за чего подзаголовки
наезжали на первую строку данных.

Высота row1 теперь измеряется через ResizeObserver и прокидывается в CSS
переменную --header-row1-h; sticky top использует её. Обновляется при
выборе поставщика, появлении тегов валют и изменении состояния Adata.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Тимур Городецкий
2026-09-02 11:38:58 +05:00
parent 158c007c15
commit f615ca3c95
2 changed files with 24 additions and 3 deletions
@@ -31,12 +31,31 @@ export function ComparisonMatrix({ matrix, currencyRates, isRestrictedView, adat
const totalColSpan = FIXED_COLS + suppliersWithOffer.reduce((sum, s) => sum + getSubCols(supplierCurrencies[s.id] ?? 'KZT', isRestrictedView), 0); const totalColSpan = FIXED_COLS + suppliersWithOffer.reduce((sum, s) => sum + getSubCols(supplierCurrencies[s.id] ?? 'KZT', isRestrictedView), 0);
// Высота row1 (шапка поставщика) переменная (теги валют, выбор поставщика, состояние Adata),
// а row2 прибит sticky сразу под ней. Измеряем реальную высоту и отдаём в CSS-переменную,
// иначе подзаголовки наезжают на первую строку таблицы.
const headerRow1Ref = React.useRef<HTMLTableRowElement>(null);
const [row1Height, setRow1Height] = React.useState(70);
React.useLayoutEffect(() => {
const el = headerRow1Ref.current;
if (!el) return;
const update = (): void => setRow1Height(Math.round(el.getBoundingClientRect().height));
update();
const observer = new ResizeObserver(update);
observer.observe(el);
return () => observer.disconnect();
}, []);
return ( return (
<div className={styles.tableScrollWrapper}> <div className={styles.tableScrollWrapper}>
<table className={styles.ctTable}> <table
className={styles.ctTable}
style={{ '--header-row1-h': `${row1Height}px` } as React.CSSProperties}
>
<thead> <thead>
{/* Row 1: fixed headers (rowSpan=2) + supplier group headers (colSpan varies by currency) */} {/* Row 1: fixed headers (rowSpan=2) + supplier group headers (colSpan varies by currency) */}
<tr className={styles.headerRow1}> <tr className={styles.headerRow1} ref={headerRow1Ref}>
<th rowSpan={2} className={styles.colPosition}>Наименование</th> <th rowSpan={2} className={styles.colPosition}>Наименование</th>
<th rowSpan={2} className={styles.colUnit}>Ед. изм.</th> <th rowSpan={2} className={styles.colUnit}>Ед. изм.</th>
<th rowSpan={2} className={styles.colQty}>Кол-во</th> <th rowSpan={2} className={styles.colQty}>Кол-во</th>
@@ -48,7 +48,9 @@
border-bottom: 2px solid $accent-border; border-bottom: 2px solid $accent-border;
border-right: 1px solid $border; border-right: 1px solid $border;
position: sticky; position: sticky;
top: 70px; // approximate height of row1 — adjust if needed // Высота row1 (шапка поставщика) переменная — измеряется в ComparisonMatrix и прокидывается
// сюда через CSS-переменную. Хардкод приводил к наезду подзаголовков на первую строку.
top: var(--header-row1-h, 70px);
z-index: 1; z-index: 1;
white-space: nowrap; white-space: nowrap;
min-width: 90px; min-width: 90px;