70 lines
3.5 KiB
TypeScript
70 lines
3.5 KiB
TypeScript
export type PageKind = "letter" | "a4" | "custom";
|
|
|
|
export interface LabelSheetTemplate {
|
|
id: string;
|
|
name: string;
|
|
pageKind: PageKind;
|
|
aliases: string[];
|
|
pageWidthMm: number;
|
|
pageHeightMm: number;
|
|
rows: number;
|
|
columns: number;
|
|
labelWidthMm: number;
|
|
labelHeightMm: number;
|
|
marginTopMm: number;
|
|
marginLeftMm: number;
|
|
horizontalGapMm: number;
|
|
verticalGapMm: number;
|
|
}
|
|
|
|
export const PAGE_SIZES: Record<PageKind, { name: string; width: number; height: number }> = {
|
|
letter: { name: "US Letter", width: 215.9, height: 279.4 },
|
|
a4: { name: "A4", width: 210, height: 297 },
|
|
custom: { name: "Custom", width: 215.9, height: 279.4 },
|
|
};
|
|
|
|
export const BUILT_IN_TEMPLATES: LabelSheetTemplate[] = [
|
|
{
|
|
id: "letter-address-30", name: "Address labels · 30 per sheet", pageKind: "letter",
|
|
aliases: ["Avery 5160", "8160", "18160"], pageWidthMm: 215.9, pageHeightMm: 279.4,
|
|
rows: 10, columns: 3, labelWidthMm: 66.675, labelHeightMm: 25.4,
|
|
marginTopMm: 12.7, marginLeftMm: 4.7625, horizontalGapMm: 3.175, verticalGapMm: 0,
|
|
},
|
|
{
|
|
id: "letter-address-20", name: "Wide address labels · 20 per sheet", pageKind: "letter",
|
|
aliases: ["Avery 5161", "8161"], pageWidthMm: 215.9, pageHeightMm: 279.4,
|
|
rows: 10, columns: 2, labelWidthMm: 101.6, labelHeightMm: 25.4,
|
|
marginTopMm: 12.7, marginLeftMm: 4.7625, horizontalGapMm: 3.175, verticalGapMm: 0,
|
|
},
|
|
{
|
|
id: "letter-shipping-10", name: "Shipping labels · 10 per sheet", pageKind: "letter",
|
|
aliases: ["Avery 5163", "8163"], pageWidthMm: 215.9, pageHeightMm: 279.4,
|
|
rows: 5, columns: 2, labelWidthMm: 101.6, labelHeightMm: 50.8,
|
|
marginTopMm: 12.7, marginLeftMm: 4.7625, horizontalGapMm: 3.175, verticalGapMm: 0,
|
|
},
|
|
{
|
|
id: "a4-address-21", name: "Address labels · 21 per sheet", pageKind: "a4",
|
|
aliases: ["Avery L7160"], pageWidthMm: 210, pageHeightMm: 297,
|
|
rows: 7, columns: 3, labelWidthMm: 63.5, labelHeightMm: 38.1,
|
|
marginTopMm: 15.15, marginLeftMm: 7.25, horizontalGapMm: 2.5, verticalGapMm: 0,
|
|
},
|
|
];
|
|
|
|
export const DEFAULT_CUSTOM_TEMPLATE: LabelSheetTemplate = {
|
|
...BUILT_IN_TEMPLATES[0], id: "custom", name: "Custom template", pageKind: "letter", aliases: [],
|
|
};
|
|
|
|
export function validateTemplate(template: LabelSheetTemplate): string[] {
|
|
const errors: string[] = [];
|
|
const positive = [template.pageWidthMm, template.pageHeightMm, template.rows, template.columns, template.labelWidthMm, template.labelHeightMm];
|
|
if (positive.some((value) => !Number.isFinite(value) || value <= 0)) errors.push("Page, grid, and label dimensions must be greater than zero.");
|
|
if (![template.rows, template.columns].every(Number.isInteger)) errors.push("Rows and columns must be whole numbers.");
|
|
if (template.rows * template.columns > 1000) errors.push("A sheet cannot contain more than 1,000 label positions.");
|
|
if ([template.marginTopMm, template.marginLeftMm, template.horizontalGapMm, template.verticalGapMm].some((value) => !Number.isFinite(value) || value < 0)) errors.push("Margins and gaps cannot be negative.");
|
|
const right = template.marginLeftMm + template.columns * template.labelWidthMm + (template.columns - 1) * template.horizontalGapMm;
|
|
const bottom = template.marginTopMm + template.rows * template.labelHeightMm + (template.rows - 1) * template.verticalGapMm;
|
|
if (right > template.pageWidthMm + 0.01) errors.push(`Labels exceed the page width by ${(right - template.pageWidthMm).toFixed(2)} mm.`);
|
|
if (bottom > template.pageHeightMm + 0.01) errors.push(`Labels exceed the page height by ${(bottom - template.pageHeightMm).toFixed(2)} mm.`);
|
|
return errors;
|
|
}
|