Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions packages/printer/src/__tests__/print-html.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,33 @@ describe('buildPrintableReceiptHtml', () => {
expect(html).toContain('<main class="invoice">Hello</main>');
});

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: '<div class="receipt">Thermal</div>',
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 `<length> 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('<div class="receipt">Thermal</div>');
});

it('defers 58mm thermal output to the printer roll paper via size: auto', () => {
const html = buildPrintableReceiptHtml({
bodyHtml: '<div class="receipt">Narrow</div>',
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: '<style>.receipt{padding:24px}</style><div class="receipt">User CSS</div>',
Expand Down Expand Up @@ -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('<style>.x{color:red}</style>');
expect(html).toContain('<div>From iframe</div>');
});
Expand Down
12 changes: 11 additions & 1 deletion packages/printer/src/print-html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<length>{1,2} | auto | <page-size>`
// — 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 `<!doctype html>
Expand Down