fix(pdf): fix header overlap on new pages, force pagebreak per voltage table, and center grid titles

This commit is contained in:
2026-03-03 13:22:54 +01:00
parent 1756b630ef
commit 11723bf184
51 changed files with 17 additions and 23 deletions

View File

@@ -1199,7 +1199,8 @@ function drawKeyValueTable(args: {
if (args.title) {
page.drawText(args.title, {
x: margin + padX,
y: boxTopY - (headerPadY + 12),
// Perfectly center the 10pt text vertically inside the 28pt (10+18) header band
y: boxTopY - 18,
size: 10,
font: fontBold,
color: navy,
@@ -1283,7 +1284,7 @@ function drawKeyValueTable(args: {
}
}
return Math.max(contentMinY, boxBottomY - 18);
return Math.max(contentMinY, boxBottomY - 12);
}
// Backward compatibility wrapper for metagrid
@@ -4092,10 +4093,13 @@ async function generatePDF(product: ProductData, locale: 'en' | 'de'): Promise<B
syncCtxForPage(page);
drawPageBackground(page);
drawFooter(ctx);
y = drawHeader(ctx, height); // pass height, we override dividerY internally inside drawHeader
// stampProductName(); // Assuming this function is defined elsewhere or will be added.
if (opts?.includeProductName) y = drawProductNameOnPage(page, y); // Update y after drawing product name
return ctx.headerDividerY - 24; // spacing below header line
let newY = drawHeader(ctx, height); // pass height, we override dividerY internally inside drawHeader
if (opts?.includeProductName) {
newY = drawProductNameOnPage(page, newY); // Update y after drawing product name
} else {
newY = ctx.headerDividerY - 24; // spacing below header line
}
return newY;
};
const hasSpace = (needed: number) => y - needed >= contentMinY;
@@ -4359,24 +4363,14 @@ async function generatePDF(product: ProductData, locale: 'en' | 'de'): Promise<B
const firstColLabel = locale === 'de' ? 'Adern & Querschnitt' : 'Cores & cross-section';
for (const t of tables) {
// Only apply top margin if we aren't at the very start of the page
if (hasRenderedContent && y - 10 >= contentMinY) y -= 10;
// Check if we need a new page for this voltage table
// Estimate: meta block (if shown) + table header + at least 3 data rows
const estimateMetaH = (itemsCount: number) => {
// Always render a voltage-group header (even for single-voltage products)
// so all datasheets look consistent.
const titleH = 14;
const rowH = 14;
const cols = 3;
const rows = Math.max(1, Math.ceil(Math.max(0, itemsCount) / cols));
return titleH + rows * rowH + 8;
};
const minTableH = 16 /*header*/ + 9 * 3 /*3 rows*/ + 10; /*pad*/
const minNeeded = estimateMetaH((t.metaItems || []).length) + minTableH;
if (y - minNeeded < contentMinY) {
// ALWAYS create a new page per Cross-Section Table as requested by the user.
// We set `includeProductName: true` so the product name is visible on these new pages.
if (hasRenderedContent) {
y = newPage({ includeProductName: true, landscape: false });
} else {
// If we happen to be at the exact top of the first page (no tech data),
// we just apply a clean standard margin instead of a page break.
y -= 10;
}
// Top meta block: always render per voltage group.