Examples

Examples

Concrete, copy-pasteable examples covering the common patterns. Each is a complete, working feature — with the live reactive component rendered on its page and its source read straight off the file, so the demo and the code can never drift.

The examples#

Each page below renders its real reactive component inline — click it, it round-trips. They build from the smallest reactive component up to record-backed actions, live broadcasts, declared-once collections, and the flagship inbox that composes everything.

ExampleWhat it shows
CounterState-backed — the smallest reactive component. Click → server → re-render, no DB row.
Payment splitNested bracketed params, auto-collected siblings, and a live reactive_compute + reactive_text preview that paints before the debounced save.
Cross-tab chatRecord-backed action and broadcast → live cross-tab sync, zero JS.
Live todo listPer-row record-backed components: add / toggle / rename / archive, optimistic toggle + delete, Enter-to-add, morph-in-place, broadcast on change.
Inline edit + dirty trackingShow ↔ edit (Enter saves, Escape cancels) plus an “Unsaved” badge + leave-guard with zero shipped state.
Notifications / badgesPure broadcast — a background event pushes a live re-render, plus a broadcast_js_to cross-tab pulse.
Reactive collectionsAdd / remove rows + a running count + an empty state, declared once with reactive_collection, optimistic dismiss + a self-dismissing flash.
File uploads & custom types:file / [:file] params (multipart FormData), a nested-hash param alongside the file (#39), and a custom Phlex::Reactive.param_type. Code-first — no live demo.
Loading statesdisable_with: + busy_on + the always-on aria-busy, with a latency toggle to make the pending window visible.
Client-only opson_client tabs / outside-close menu / accessible drawer — zero fetches, zero custom JS.
Failure surfaceerror_flash + data-reactive-error + dismiss_after: — what an adopter gets for free when an action fails.
Team inbox (flagship)The whole toolkit in one UI: collection rows, optimistic archive that reverts on failure, cross-tab broadcast, an on_client kebab, and error flashes.

Every headline feature now has a live page. Pick a capability:

FeatureWhere it's shown (live)
Client-only opson_client + js (show/hide/toggle, set_attr/toggle_attr, focus, dispatch, transitions): zero round tripsClient-only ops, Todo list, Team inbox
Client-side computesreactive_compute + reactive_text (a live preview / char counter that paints with no round trip)Payment split
Declarative loading statesloading: / disable_with: / busy_on (+ the always-on aria-busy / data-reactive-busy)Loading states, Todo list, Collections, Team inbox
Dirty-field trackingdirty: / track_dirty: / warn_unsaved: (enable Save only on change; warn before leaving)Inline edit
Optimistic visual hintsoptimistic: (flip a checkbox / hide a row instantly; revert on failure)Todo list, Collections, Team inbox
Keyboard triggersevent: "keydown.enter" / "keydown.esc" (Enter-to-add, Escape-to-cancel)Todo list, Inline edit
Debounced / morph editingdebounce: live-as-you-type + reply.morph to keep the caretPayment split, Inline edit
Live broadcastsbroadcast_replace_to / broadcast_append_to / broadcast_js_to → cross-tab syncChat, Notifications, Todo list, Team inbox
Failure surfaceerror_flash / data-reactive-error / dismiss_after: / timeout + offlineFailure surface, Team inbox
Combobox keyboard navigationlistnav: (Arrow keys move a client highlight, Enter picks)Searchable combobox demo
File uploads & custom param types:file / [:file] (multipart FormData), Phlex::Reactive.param_typeFile uploads & custom types (code-first)

File uploads (:file / [:file] params, multipart FormData) and custom param types (Phlex::Reactive.param_type) have a dedicated code-first walkthrough — no live demo, because a public upload endpoint is a storage/abuse surface. The payment split is the closest live cousin: the nested-params / auto-collected sibling-fields example that a FormData upload extends.