Finance

ChequeView

A cheque drawn as printed: payee, the amount in figures and in words, date, memo, signature and the MICR line.

#finance#banking#document#payments#no-js

Demo

Preview

Dana Whitfield

12 Orchard Row

Port Ellis, ME 04101

Number 1042

Date
Pay to the order ofAna Okafor
$1,234.56
One thousand two hundred thirty-four and 56/100dollars

Fernway Credit Union

40 Quay Street, Port Ellis

ForKitchen tiles
Dana WhitfieldSignature

Dana Whitfield

Number 1043

Date
Pay to the order ofHarbour Fitness
$85.00
Eighty-five and 00/100dollars

Fernway Credit Union

ForNovember
Authorised signature

Number 000318

Date
Pay to the order ofKinoshita Builders
¥1,250,000
One million two hundred fifty thousandyen

Sakuragi Shinkin

For
T. MoriSignature

Get it

It needs theme.qwe, as every component does; or take the whole kit, quillo-ui.qwe. Each component brings its own styles to the pages that show it.

$ curl -O https://quillolang.org/components/ui/theme.qwe$ curl -O https://quillolang.org/components/ui/cheque_view.qwe
main.qwe
import ui/theme.qwe use theme_cssuse ui/cheque_view.qweroute GET / = <html><head><style>{theme_css}</style></head><body class="ui-root">...</body></html>

Example

The code of the preview above.

demos/cheque_view.qwe
view ChequeViewDemo() =    <div.demo-stack>        <ChequeView id="cheque-view-demo" number="1042" dated="2026-10-29" payee="Ana Okafor" amount={1234.56m} memo="Kitchen tiles"                    drawer={{ name: "Dana Whitfield", lines: ["12 Orchard Row", "Port Ellis, ME 04101"] }}                    bank={{ name: "Fernway Credit Union", lines: ["40 Quay Street, Port Ellis"] }}                    routing="011000015" account="40031204" signature="Dana Whitfield"/>        <ChequeView id="cheque-view-demo-void" number="1043" dated="2026-11-02" payee="Harbour Fitness" amount={85} memo="November"                    drawer={{ name: "Dana Whitfield" }} bank={{ name: "Fernway Credit Union" }} routing="011000015" account="40031204"                    void={true}/>        <ChequeView id="cheque-view-demo-yen" number="000318" dated="2026-12-01" payee="Kinoshita Builders" amount={1250000} currency="JPY"                    bank={{ name: "Sakuragi Shinkin" }} signature="T. Mori"/>    </div>

Source

ui/cheque_view.qwe
// ChequeView: a cheque drawn as it is printed: who draws it and their address,// the cheque's number and date, "Pay to the order of" the payee, the amount in// figures and in words ("One thousand two hundred thirty-four and 56/100"), the// bank, the memo, the signature, and the MICR line along the bottom (⑆ routing// ⑆ account ⑈ number). For a cheque image in an account's history, a payment's// confirmation, or a cheque to print.////   <ChequeView number="1042" dated="2026-10-29" payee="Ana Okafor" amount={1234.56m} memo="Kitchen tiles"//               drawer={{ name: "Dana Whitfield", lines: ["12 Orchard Row", "Port Ellis PE3 9QT"] }}//               bank={{ name: "Fernway Credit Union", lines: ["40 Quay Street, Port Ellis"] }}//               routing="011000015" account="40031204" signature="Dana Whitfield"/>//// number: the cheque's number, printed at the top right and in the MICR line.// dated: its date, an ISO date. payee: who it is to. amount: a number or decimal;// written in figures in its currency and in English words, with the cents over// 100 (a currency without cents has none). words: other words for the amount, as// written in another language. currency ("USD"): its word at the end of the line// ("dollars", "euros", "pounds", ...; the code for others); locale: how the// figures and the date are written. memo: the "For" line. drawer: { name, lines? };// bank: { name, lines? }. routing, account: the numbers in the MICR line.// signature: the name signed, in a hand; left out, the line is blank. void: a// cheque cancelled, crossed through with VOID. id: the element's id.import ui/theme.qwe use ui_clslet cheque_view_css = css`.ui-cheque { --ink: var(--ui-fg); position: relative; display: grid; grid-template-columns: 1fr auto; gap: 14px 24px; min-width: 0; max-width: 680px;  padding: 20px 24px 14px; overflow: hidden; border: 1px solid color-mix(in srgb, var(--ui-accent) 35%, var(--ui-border)); border-radius: 6px;  background: repeating-linear-gradient(-45deg, transparent 0 7px, color-mix(in srgb, var(--ui-accent) 5%, transparent) 7px 8px),              linear-gradient(180deg, color-mix(in srgb, var(--ui-accent-soft) 55%, var(--ui-surface)), var(--ui-surface));  color: var(--ink); font: 13px/1.35 var(--ui-font); }.ui-cheque-drawer p { margin: 0; }.ui-cheque-drawer-name { font-weight: 650; }.ui-cheque-small { color: var(--ui-muted); font-size: 11px; }.ui-cheque-corner { display: grid; justify-items: end; gap: 10px; }.ui-cheque-no { margin: 0; font: 600 14px var(--ui-mono); letter-spacing: .05em; }.ui-cheque-datebox { display: flex; align-items: baseline; gap: 8px; }.ui-cheque-cap { color: var(--ui-muted); font-size: 10px; font-weight: 600; letter-spacing: .07em; text-transform: uppercase; white-space: nowrap; }.ui-cheque-line { flex: 1; min-width: 0; padding: 0 4px 1px; border-bottom: 1px solid var(--ink); font: 500 15px var(--ui-font); overflow-wrap: anywhere; }.ui-cheque-datebox .ui-cheque-line { min-width: 120px; text-align: center; }.ui-cheque-pay { grid-column: 1 / -1; display: flex; align-items: flex-end; gap: 14px; }.ui-cheque-payto { display: flex; flex: 1; align-items: baseline; gap: 8px; min-width: 0; }.ui-cheque-payto .ui-cheque-cap { width: 64px; white-space: normal; line-height: 1.2; }.ui-cheque-figures { flex: none; display: flex; align-items: center; gap: 6px; padding: 4px 10px; border: 1.5px solid var(--ink); border-radius: 3px;  background: var(--ui-surface); font: 600 16px var(--ui-mono); font-variant-numeric: tabular-nums; }.ui-cheque-wordsrow { grid-column: 1 / -1; display: flex; align-items: baseline; gap: 8px; overflow: hidden; }.ui-cheque-words { flex: 1; min-width: 0; padding: 0 4px 1px; overflow: hidden; border-bottom: 1px solid var(--ink); font-size: 14px; font-style: italic; white-space: nowrap; }.ui-cheque-words::after { content: " ———————————————————————————" / ""; color: var(--ui-muted); font-style: normal; letter-spacing: -.1em; }.ui-cheque-unit { flex: none; font-size: 12px; font-weight: 650; letter-spacing: .06em; text-transform: uppercase; }.ui-cheque-bank { align-self: end; }.ui-cheque-bank p { margin: 0; }.ui-cheque-bank-name { font-weight: 650; }.ui-cheque-memo { display: flex; align-items: baseline; gap: 8px; margin-top: 10px; max-width: 300px; }.ui-cheque-sign { align-self: end; display: grid; gap: 2px; width: 230px; max-width: 100%; }.ui-cheque-signature { min-height: 30px; padding: 0 6px; border-bottom: 1px solid var(--ink); font: italic 24px/30px "Snell Roundhand", "Segoe Script", "Brush Script MT", cursive; overflow: hidden; white-space: nowrap; }.ui-cheque-sign .ui-cheque-cap { text-align: center; }.ui-cheque-micr { grid-column: 1 / -1; margin: 4px 0 0; padding-top: 8px; font: 15px/1 "MICR E13B", "Apple Symbols", var(--ui-mono); letter-spacing: .14em; white-space: nowrap; overflow: hidden; }.ui-cheque-void { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }.ui-cheque-void span { padding: 2px 28px; border: 4px solid var(--ui-danger); border-radius: 8px; color: var(--ui-danger); font: 800 56px/1.1 var(--ui-font);  letter-spacing: .18em; opacity: .75; transform: rotate(-14deg); }@media (max-width: 560px) { .ui-cheque { grid-template-columns: 1fr; padding: 16px; } .ui-cheque-corner { justify-items: start; } .ui-cheque-pay { flex-wrap: wrap; } }@media print { .ui-cheque { border-color: #000; background: #fff; color: #000; --ink: #000; } }`let cheque_view_ones = ["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve",                        "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]let cheque_view_tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]let cheque_view_units = { USD: "dollars", CAD: "dollars", AUD: "dollars", NZD: "dollars", SGD: "dollars", HKD: "dollars",                          EUR: "euros", GBP: "pounds", JPY: "yen", CHF: "francs", INR: "rupees", PHP: "pesos", MXN: "pesos",                          ZAR: "rand", SEK: "kronor", NOK: "kroner", DKK: "kroner", CNY: "yuan", KRW: "won", BRL: "reais" }// 0 to 999 in words: 342 is "three hundred forty-two".fn cheque_view_hundreds(n: int) -> str {    let h = int(n / 100)    let rest = n % 100    let tail = rest < 20 ? cheque_view_ones[rest] : cheque_view_tens[int(rest / 10)] + (rest % 10 > 0 ? "-" + cheque_view_ones[rest % 10] : "")    join([h > 0 ? cheque_view_ones[h] + " hundred" : "", tail] | filter((w) => w != ""), " ")}// A whole number in words: 1234 is "one thousand two hundred thirty-four".fn cheque_view_words(n: int) -> str {    if n == 0 { return "zero" }    let scales = [[1000000000000, "trillion"], [1000000000, "billion"], [1000000, "million"], [1000, "thousand"], [1, ""]]    let r = reduce(scales, { left: n, out: [] }, (acc, s) => {        let q = int(acc.left / s[0])        q == 0 ? acc : { left: acc.left - q * s[0], out: push(acc.out, trim(`${cheque_view_hundreds(q)} ${s[1]}`)) }    })    join(r.out, " ")}// An amount as a cheque writes it: "One thousand two hundred thirty-four and 56/100".fn cheque_view_amount_words(amount, currency: str) -> str {    let units = money.minor_units(currency)    let d = round(abs(dec(amount)), units, "half_up")    let whole = int(d)    let text = cheque_view_words(whole)    let first = upper(slice(text, 0, 1)) + slice(text, 1)    if units == 0 { return first }    let minor = str(int((d - whole) * pow(10, units)))    `${first} and ${repeat("0", units - len(minor))}${minor}/${pow(10, units)}`}// An amount in figures, in its currency.fn cheque_view_money(amount, currency: str, locale: str?) -> str {    let m = money.of(dec(amount), currency, "half_up")    if is_err(m) { return str(amount) }    locale != null ? money.format(m, locale) : money.format(m)}view ChequeView(payee: str, amount, number: str = "", dated: str? = null, currency: str = "USD", locale: str? = null,                words: str? = null, memo: str? = null, drawer: map? = null, bank: map? = null, routing: str? = null,                account: str? = null, signature: str? = null, void: bool = false, id: str? = null, class: str? = null) {    style global cheque_view_css    let code = upper(currency)    let figures = cheque_view_money(amount, code, locale)    let in_words = words ?? cheque_view_amount_words(amount, code)    let unit = cheque_view_units[code] ?? code    let when = dated != null ? date.format(dated, { locale: locale ?? "en-US", style: "medium" }) : ""    let micr_said = ui_cls([routing != null && `routing number ${routing}`, account != null && `account ${account}`, number != "" && `cheque ${number}`])    <figure class={ui_cls(["ui-cheque", class])} id={id} style="margin: 0"            aria-label={`${void ? "Void cheque" : "Cheque"}${number != "" ? " " + number : ""} to ${payee} for ${figures}${dated != null ? ", dated " + when : ""}`}>        <div.ui-cheque-drawer>            {drawer != null && [<p.ui-cheque-drawer-name>{drawer.name}</p>, for l in drawer.lines ?? [] => <p.ui-cheque-small key={l}>{l}</p>]}        </div>        <div.ui-cheque-corner>            {number != "" && <p.ui-cheque-no><span.ui-sr>Number </span>{number}</p>}            <div.ui-cheque-datebox><span.ui-cheque-cap>Date</span><span.ui-cheque-line>{dated != null && <time datetime={dated}>{when}</time>}</span></div>        </div>        <div.ui-cheque-pay>            <div.ui-cheque-payto><span.ui-cheque-cap>Pay to the order of</span><span.ui-cheque-line.ui-cheque-payee>{payee}</span></div>            <div.ui-cheque-figures>{figures}</div>        </div>        <div.ui-cheque-wordsrow>            <span.ui-cheque-words>{in_words}</span>            <span.ui-cheque-unit>{unit}</span>        </div>        <div.ui-cheque-bank>            {bank != null && [<p.ui-cheque-bank-name>{bank.name}</p>, for l in bank.lines ?? [] => <p.ui-cheque-small key={l}>{l}</p>]}            <div.ui-cheque-memo><span.ui-cheque-cap>For</span><span.ui-cheque-line.ui-cheque-memo-text>{memo ?? ""}</span></div>        </div>        <div.ui-cheque-sign>            <span.ui-cheque-signature>{signature ?? ""}</span>            <span.ui-cheque-cap>{signature != null ? "Signature" : "Authorised signature"}</span>        </div>        {(routing != null || account != null || number != "") && <p.ui-cheque-micr aria-label={micr_said}>            <span aria-hidden="true">{routing != null && `⑆${routing}⑆ `}{account != null && `${account}⑈ `}{number}</span>        </p>}        {void && <div.ui-cheque-void aria-hidden="true"><span>VOID</span></div>}    </figure>}
Thread
85Useful? Like it, or add to its thread below.

Thread 0 posts

On ChequeView: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.