Every document below is a pure function of one typed object, rendered by Unlayer Elements into an email, a web page and a print document from the same component tree. The charts, QR codes, quota bars and status stamps are custom Elements tools drawn in HTML tables, so there is not one image, web font or script in any of it.
Built with Unlayer Elements. The
live studio lets you change the data and
watch all three outputs follow; npm run preview runs it locally.
Each card holds the same document three times over. Switch renderer to see what actually changes between them, which is the body width, the inbox preview text and the print rhythm, and nothing else. Drag the bottom edge of a frame to make it taller.
A partially-paid B2B invoice with a full totals ladder, a scannable pay-by-QR code and a status stamp.
Table-based HTML with Outlook MSO conditionals, ready to hand to an ESP.
Print-optimised layout; piped through Chromium to produce the PDFs.
A usage and reliability review with a table-drawn bar chart, sparkline, KPI tiles and quota bars, no image assets.
Table-based HTML with Outlook MSO conditionals, ready to hand to an ESP.
Print-optimised layout; piped through Chromium to produce the PDFs.
A long-form statement of work: phased scope with pricing, three comparison tiers, terms and a sign-by-QR block.
Table-based HTML with Outlook MSO conditionals, ready to hand to an ESP.
Print-optimised layout; piped through Chromium to produce the PDFs.
These are live, not screenshots. Each one is a custom tool registered through
registerTool(), the same definition object the Unlayer editor takes, rendering here
through the same exporter it uses inside a document. Charts in email are almost always flattened
to a PNG, which disappears the moment a client blocks images.
asterix-bar-chart
One table column per point. The bar is a colour-filled cell of an exact pixel height, pushed to the baseline by a spacer cell above it.
asterix-kpi
The delta is coloured by meaning, not direction. Latency falling is good, so it reads green. Changes inside the noise floor read neutral.
p99 ingest latency 84ms ▼ -18.2%vs May |
asterix-progress
Two cells with percentage widths, the only bar technique Outlook renders reliably. The fill escalates as the allowance runs out.
|
asterix-qr
A real, scannable code. The matrix is painted as run-length-encoded table cells with the 4-module quiet zone the spec requires. Point a phone at it.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
asterix-stamp
The status is in the word as well as the colour, so it still reads when a PDF is printed in greyscale.
|
Elements has a second JSON exporter that is easy to miss. renderRowToJson takes a
single row and returns the shape Unlayer's Block Editor works with, rather than a whole design.
So every block below is portable on its own: download one, drop it into a Block Editor, and you
have a working letterhead or totals ladder without writing any React. The badges show which
Asterix tools travel with the block.