18.1Block 18.1 · Contact
Dispatch
A contact section made as a desk unit. A machined form with a segmented topic selector and a send key that locks while the message goes, and the Receipt Printer beside it, which prints the confirmation as a ticket with a reference number.
- Version
- 0.1.0
- Size
- 68.1 KB gzipped
- Access
- With a Pass
- Needs
- dispatch.mjs + dispatch.css · Receipt Printer
- Tests
- 12 tests · 11 states
On this page
Use it
A contact form that gives something back. Name, email, topic, message and a send key that is a commit key: it drops, lights amber and locks while the message is going, and shows green when it has gone. The confirmation is a small ticket printed by the library's Receipt Printer with a reference, the topic, the time and the promise, which the visitor tears off and keeps. Validation says how to fix each field, a honeypot catches bots, and the block fires dispatch-send with the fields (and posts them if given an action), so a page can wire it to any backend and keep the key locked while it does.
Copy the dispatch folder and the printer folder from its package next to your page, link the stylesheets and mount it on an element. Every option has a default; the lab’s Code tab writes the same example at any settings, and for React, Vue, Svelte or a custom element (Using a framework).
<link rel="stylesheet" href="printer/printer.css">
<link rel="stylesheet" href="dispatch/dispatch.css">
<div id="dispatch"></div>
<script type="module">
import Printer from './printer/printer.mjs';
import { mount } from './dispatch/dispatch.mjs';
const dispatch = mount(document.getElementById('dispatch'), {
brand: 'Lode',
label: 'Contact',
title: 'Tell us what you need.',
}, { Printer });
// dispatch.update({ … }); change any option in place
// dispatch.destroy(); and take it away again
</script>Options
| Option | Type | Default | What it does |
|---|---|---|---|
| brand | text | 'Lode' | Printed in capitals at the head of the receipt. |
| label | text | 'Contact' | Label |
| title | text | 'Tell us what you need.' | Headline |
| lead | text | 'A person at Lode reads every message. Choose a topic so it reaches the right desk.' | Lead |
| topics | text | 'Sales|Support|Security|Other' | Separated by “|”: two to five. Each is a position on the segmented selector and is printed on the ticket. |
| topic | text | 'Support' | Must be one of the topics; otherwise the first is chosen. |
| action | text | '' | Empty: the block only fires dispatch-send. Set: it also POSTs the fields as JSON there, and unlocks the key with the reason if the answer is not 2xx. Only http(s) or a path. |
| reply | text | 'We reply within one working day.' | Printed on the ticket and said in the status line. |
| prefix | text | 'LDE' | Letters and digits: LDE gives references such as LDE-4F7K2M. |
| finish | auto · aluminium · graphite | 'auto' | Auto follows the page’s data-finish, then the visitor’s system. The Printer follows it too. |
Methods
mount(element, options, { Printer })- Builds the block inside the element and returns its handle. Hand it the Receipt Printer it is built with.
handle.printerhandle.update(next = {})- Change options in place.
handle.destroy()- Stops it and cleans up after it.
Events it fires, which bubble from the element: dispatch-send, dispatch-fail.
States
- At restThe panel with its four fields, the topic selector on its default, the send key with its lamp dark; the Printer idle in its bay with the caption “Your reference prints here.”
- Wrong fieldsEvery wrong field gets a red lip and aria-invalid and a hint that says how to fix it (“Add the part after the @, e.g. [email protected].”, “Write at least 20 characters… You have 0.”); focus goes to the first; typing a good value clears the mark.
- SendingThe key drops 3px, its lamp lights amber, the label says “Sending…”, aria-disabled is set and a second submit is ignored. It stays locked for at least 600 ms, and for as long as any promise a listener handed to detail.until() takes.
- SentThe Printer prints the ticket line by line (head, reference, topic, first name, time, the promise); the form empties; the key shows “Sent” with a green lamp for 2.6 s; the status line says the reference and the promise. A ticket still in the slot is torn off first.
- FailedWith an action, a non-2xx answer (or a rejected until() promise) unlocks the key, keeps the words, says “Not sent: …” in the error colour and fires dispatch-fail.
- BotA form whose hidden website field is filled looks sent, but no event fires and nothing is posted.
- Topic by keyboardThe selector is native radios in a fieldset: arrows move the chosen position, which stands proud of the cut.
- TabletOne column: the panel, then the Printer's bay below it.
- PhoneName and email stack, the topics wrap two by two, the send key fills its row; no sideways scroll.
- Reduced motionThe Printer prints at once; the key and the topics change without transitions.
- FinishesAluminium and graphite by data-finish; the Printer follows it too.
How it works
Made of: Commit style send key, Segmented radio selector, Native validation with hints, Honeypot field, Send event with until, Receipt printer confirmation, Reference number, Container query layout, Concentric radii, Finish following.
Original composition; Lode and its copy are invented. The Receipt Printer arrives in deps and is never imported by the block. The panel, the selector and the key are CSS drawn here in the kit's tokens; no image. Face: Instrument Sans (SIL OFL 1.1), the kit's own.