diff --git a/packages/printer/src/__tests__/print-html.test.ts b/packages/printer/src/__tests__/print-html.test.ts index ac335eee2..a4ea53d1c 100644 --- a/packages/printer/src/__tests__/print-html.test.ts +++ b/packages/printer/src/__tests__/print-html.test.ts @@ -32,17 +32,33 @@ describe('buildPrintableReceiptHtml', () => { expect(html).toContain('
Hello
'); }); - it('wraps 80mm thermal output with physical page size and no A4 width rule', () => { + it('defers 80mm thermal output to the printer roll paper via size: auto', () => { const html = buildPrintableReceiptHtml({ bodyHtml: '
Thermal
', paperWidth: '80mm', }); - expect(html).toContain('@page { size: 80mm; margin: 0; }'); + // Must be `size: auto` — NOT `80mm` (a valid but square 80mm×80mm page) and + // NOT `80mm auto` (invalid ` auto`, silently ignored → Letter/A4). + // Both broken forms render the receipt tiny. + expect(html).toContain('@page { size: auto; margin: 0; }'); + expect(html).not.toContain('@page { size: 80mm; margin: 0; }'); + expect(html).not.toContain('@page { size: 80mm auto; margin: 0; }'); expect(html).not.toContain('body > * { width: 210mm; }'); expect(html).toContain('
Thermal
'); }); + it('defers 58mm thermal output to the printer roll paper via size: auto', () => { + const html = buildPrintableReceiptHtml({ + bodyHtml: '
Narrow
', + paperWidth: '58mm', + }); + + expect(html).toContain('@page { size: auto; margin: 0; }'); + expect(html).not.toContain('@page { size: 58mm; margin: 0; }'); + expect(html).not.toContain('@page { size: 58mm auto; margin: 0; }'); + }); + it('keeps print mechanics outside user template content', () => { const html = buildPrintableReceiptHtml({ bodyHtml: '
User CSS
', @@ -71,7 +87,7 @@ describe('prepareSystemPrintHtml', () => { paperWidth: '80mm', }); - expect(html).toContain('@page { size: 80mm; margin: 0; }'); + expect(html).toContain('@page { size: auto; margin: 0; }'); expect(html).toContain(''); expect(html).toContain('
From iframe
'); }); diff --git a/packages/printer/src/print-html.ts b/packages/printer/src/print-html.ts index 3f32e97ca..ef50be29f 100644 --- a/packages/printer/src/print-html.ts +++ b/packages/printer/src/print-html.ts @@ -18,7 +18,17 @@ export function buildPrintableReceiptHtml({ paperWidth, }: BuildPrintableReceiptHtmlOptions): string { const normalizedPaperWidth = normalizeReceiptPaperWidth(paperWidth); - const pageSize = normalizedPaperWidth === 'a4' ? 'A4' : normalizedPaperWidth; + // Thermal receipts defer to the printer's selected roll paper via `size: auto`. + // + // The CSS `@page size` descriptor grammar is `{1,2} | auto | ` + // — there is no "fixed width, flowing height" form: + // - `80mm auto` is INVALID (length + keyword); browsers ignore it and fall + // back to the default paper (Letter/A4), printing the receipt tiny. + // - `80mm` is valid but makes BOTH dimensions 80mm — an 80mm×80mm square — + // which the print dialog shrinks onto the roll, also printing it tiny. + // `auto` lets the browser use the thermal printer's own paper (e.g. 80×297mm) and + // shrink-fits the content to the roll width, which is what we actually want. + const pageSize = normalizedPaperWidth === 'a4' ? 'A4' : 'auto'; const widthRule = normalizedPaperWidth === 'a4' ? '\nbody > * { width: 210mm; }' : ''; return `