feat(cv): harden multi-page builder
Wrap pathological content, paginate oversized entries, measure A4 and Letter previews correctly, unify section ordering, and gate stored-output actions on saved state.
This commit is contained in:
@@ -96,6 +96,35 @@ export const SECTION_LABELS: Record<string, string> = {
|
||||
interests: "Interests",
|
||||
};
|
||||
|
||||
const CSS_PIXELS_PER_MM = 96 / 25.4;
|
||||
|
||||
export type CvPageMetrics = {
|
||||
widthMm: number;
|
||||
heightMm: number;
|
||||
widthPx: number;
|
||||
heightPx: number;
|
||||
};
|
||||
|
||||
export function getCvPageMetrics(pageSize?: string | null): CvPageMetrics {
|
||||
const letter = pageSize?.trim().toLowerCase() === "letter";
|
||||
const widthMm = letter ? 215.9 : 210;
|
||||
const heightMm = letter ? 279.4 : 297;
|
||||
return {
|
||||
widthMm,
|
||||
heightMm,
|
||||
widthPx: widthMm * CSS_PIXELS_PER_MM,
|
||||
heightPx: heightMm * CSS_PIXELS_PER_MM,
|
||||
};
|
||||
}
|
||||
|
||||
// Browser layout dimensions are rounded to whole pixels. The small tolerance prevents a page whose
|
||||
// min-height rounds up by one pixel from being reported as two pages, while still using ceil for any
|
||||
// genuine spill onto the next page.
|
||||
export function getCvPageCount(contentHeightPx: number, pageHeightPx: number): number {
|
||||
if (!Number.isFinite(contentHeightPx) || !Number.isFinite(pageHeightPx) || pageHeightPx <= 0) return 1;
|
||||
return Math.max(1, Math.ceil(Math.max(0, contentHeightPx - 2) / pageHeightPx));
|
||||
}
|
||||
|
||||
export function emptyCvVariantSettings(themeId = "modern"): CvVariantSettings {
|
||||
return {
|
||||
themeId,
|
||||
|
||||
Reference in New Issue
Block a user