fix(labels): let the print dialog pick sheet orientation, clamp migrated margins

Two more problems from #1149.

Sheet mode set @page size to the paper's exact dimensions. A 62x34 page makes
the browser send it as landscape, and Chromium hides the orientation picker
when the page CSS sets a size. Label printer drivers disagree on which way
round a roll is: a Brother QL needed landscape, a Niimbot B1 needed portrait,
so any fixed choice prints rotated for someone. Sheet mode now uses size: auto
like v1 did, and the page is still laid out in mm. Label mode keeps its exact
size.

The v1 migration derived the label size from the raw margins. v1 users paired
-20mm margins with a 1.5mm printer margin to pull an oversized cell back onto a
62x34 page, which migrated as a 102x74 label. Margins are now clamped at
migration; the safe-zone alone gives the same content inset (max(safe, margin)
in both versions), and the label comes out at the paper size.
This commit is contained in:
Donkie committed 2026-09-13 10:55:12 +02:00
1 parent f229fd5afe
commit ff514b2c38
3 files changed
+31 -6

No files matched your search

@@ -140,6 +140,26 @@ describe('presetToDesign', () => {
expect(d.layout.columns).toBeGreaterThanOrEqual(1);
});
it('clamps v1 negative margins so the label matches the paper (#1149)', () => {
// A real preset: -20mm margins with a 1.5mm printer margin on a 62x34 roll.
// Carried over raw, the derived label came out 102x74.
const d = presetToDesign({
labelSettings: {
printSettings: {
paperSize: 'custom',
customPaperSize: { width: 62, height: 34 },
columns: 1,
rows: 1,
margin: { top: -20, bottom: -20, left: -20, right: -20 },
printerMargin: { top: 1.5, bottom: 1.5, left: 1.5, right: 1.5 }
}
}
});
expect(d.layout.margin).toEqual({ t: 0, b: 0, l: 0, r: 0 });
expect(d.layout.safe).toEqual({ t: 1.5, b: 1.5, l: 1.5, r: 1.5 });
expect(d.label).toEqual({ w: 62, h: 34 });
});
it('omits the QR element when v1 had the QR turned off', () => {
const d = presetToDesign({ labelSettings: { showQRCodeMode: 'no' } });
expect(d.elements.some((e) => e.type === 'qr')).toBe(false);
+7 -4
View File
@@ -133,11 +133,14 @@ function mapLayout(ps: V1PrintSettings): PrintLayout {
paper,
custom,
landscape: false,
// v1 users paired negative margins with a printer margin to pull an oversized
// grid cell back onto a label-sized page. Clamped, the safe-zone alone gives the
// same inset and the label is sized to the paper instead of that cell (#1149).
margin: {
t: ps.margin?.top ?? DEFAULT_LAYOUT.margin.t,
b: ps.margin?.bottom ?? DEFAULT_LAYOUT.margin.b,
l: ps.margin?.left ?? DEFAULT_LAYOUT.margin.l,
r: ps.margin?.right ?? DEFAULT_LAYOUT.margin.r
t: Math.max(0, ps.margin?.top ?? DEFAULT_LAYOUT.margin.t),
b: Math.max(0, ps.margin?.bottom ?? DEFAULT_LAYOUT.margin.b),
l: Math.max(0, ps.margin?.left ?? DEFAULT_LAYOUT.margin.l),
r: Math.max(0, ps.margin?.right ?? DEFAULT_LAYOUT.margin.r)
},
safe: {
t: ps.printerMargin?.top ?? 0,
+4 -2
View File
@@ -141,8 +141,10 @@ export async function printLabels({ design, bindings, layout, baseUrl }: PrintJo
style.textContent = pageCss(`${design.label.w}mm ${design.label.h}mm`);
} else {
buildSheetPages(root, items, design, layout);
const page = paperSize(layout);
style.textContent = pageCss(`${page.w}mm ${page.h}mm`);
// `size: auto`, as v1 did. A fixed size makes the browser pick the orientation
// and (in Chromium) hide the picker, and label printer drivers disagree on which
// way round a roll is, so any fixed choice prints rotated for someone (#1149).
style.textContent = pageCss('auto');
}
document.body.appendChild(style);