04.3Block 04.3 · Loaders
Processing State
A long job’s progress card, crowned by ferrofluid. The dish breathes with the work, surges as each of four steps completes, and settles to a mirror under the word “Balanced.”
- Version
- 0.1.0
- Size
- 145.8 KB gzipped
- Access
- With a Pass
- Needs
- processing-state.mjs + processing-state.css · Ferrofluid
- Tests
- 12 tests · 11 states
On this page
Use it
Make a necessary wait feel held rather than stalled: the numbers say exactly where the job is, and a small physical thing does the waiting with the person (its agitation tracking the work, its stillness meaning done), so the outcome lands as relief.
Copy the processing-state folder and the ferrofluid 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="ferrofluid/ferrofluid.css">
<link rel="stylesheet" href="processing-state/processing-state.css">
<div id="processing-state"></div>
<script type="module">
import Ferrofluid from './ferrofluid/ferrofluid.mjs';
import { mount } from './processing-state/processing-state.mjs';
const processingState = mount(document.getElementById('processing-state'), {
app: 'Ledgewell',
kicker: 'Closing Q3 2026',
title: 'Balancing your books',
}, { Ferrofluid });
// processingState.update({ … }); change any option in place
// processingState.destroy(); and take it away again
</script>Options
| Option | Type | Default | What it does |
|---|---|---|---|
| app | text | 'Ledgewell' | In the app behind the card. |
| kicker | text | 'Closing Q3 2026' | Kicker |
| title | text | 'Balancing your books' | Title while working |
| sub | text | '48,210 transactions across 4 accounts' | Line under it |
| doneTitle | text | 'Balanced' | Gets a full stop. |
| doneSub | text | '3 items need a look before you close the quarter.' | Line when done |
| review | text | 'Review 3 items' | Button when done |
| steps | text | 'Read bank feeds: 4 accounts; Match invoices: 31,206 lines; Flag duplicates: 48,210 checks; Balance ledgers: 12 ledgers' | “Label: count unit; …”, up to four. |
| seconds | number, 6 to 40 | 14 | The demo’s job. In production, drive it from your own progress events. |
| palette | paper · night · sage | 'paper' | Paper or night with a ceramic dish, sage with polished steel. |
| density | number, 9 to 20 | 13 | Spike density |
| sharpness | number, 0.3 to 1 | 0.75 | Spike sharpness |
| light | number, 0 to 345 | 330 | 0 is from above, clockwise. |
Methods
mount(element, options, { Ferrofluid })- Builds the block inside the element and returns its handle. Hand it the Ferrofluid it is built with.
handle.update(next = {})- Change options in place.
handle.phasehandle.progresshandle.fluidhandle.roothandle.destroy()- Stops it and cleans up after it.
States
- Waiting to startThe working title at 0% and “Starting…”, every step waiting; nothing runs until 40% of the card is on screen.
- WorkingPercent, time left and per-step counts advance along a timeline that eases within each step; the active step's icon turns; the dish's magnet breathes at 0.9 Hz, deeper as the job advances, so early spikes rise and sink flat and late ones stay up; each step's name is announced once.
- Step completeThe step gets a filled check in the success colour and the magnet surges for half a second.
- DoneThe field is let go and zeroed: the spikes melt and the pool settles to a mirror and sleeps; the title turns to the done title in the success colour, 100% and “Done”, a badge scales in over the dish, the outcome is announced once; Run again / Review.
- CancelledStops at once, releases the dish, says nothing was changed; Close / Start again.
- PalettePaper and night with a ceramic dish (graphite vanished into the dark card), sage with a polished steel dish.
- TabletFrom container width 560px a 480px card centred over the app's main area.
- PhoneUnder 560px a full-width bottom sheet with a 22px top radius over the app's header.
- DesktopFrom 900px a 520px card over the whole app (a sidebar and the table, blurred under a scrim).
- Reduced motionThe numbers still advance, in whole percents with no easing; the icon does not turn; the dish never moves: its still is spiked while working and smooth once done.
- Off screen or hiddenThe dish pauses itself; the block's frame loop runs only while the job runs.
How it works
Made of: Progress driven magnet, Step surge, Settle on completion, Pure job timeline, Polite per step announcements, Container query sheet to card.
Original composition; Ledgewell, the job and all copy are invented. The only imagery is the Ferrofluid and a CSS skeleton of an app. The job is simulated from a pure timeline for the demo; the card is meant to be driven by real progress events. Faces: Work Sans and DM Mono (SIL OFL 1.1) as WOFF2, licences beside them.
Built with
More blocks on the same object: