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.

| Example | What it shows |
| --- | --- |
| [Counter](https://phlex-reactive.zoolutions.llc/docs/example-counter) | State-backed — the smallest reactive component. Click → server → re-render, no DB row. |
| [Payment split](https://phlex-reactive.zoolutions.llc/docs/example-payment-split) | Nested bracketed params, auto-collected siblings, and a live `reactive_compute` + `reactive_text` preview that paints before the debounced save. |
| [Cross-tab chat](https://phlex-reactive.zoolutions.llc/docs/example-chat) | Record-backed action **and broadcast** → live cross-tab sync, zero JS. |
| [Live todo list](https://phlex-reactive.zoolutions.llc/docs/example-todo-list) | Per-row record-backed components: add / toggle / rename / archive, optimistic toggle + delete, Enter-to-add, morph-in-place, broadcast on change. |
| [Inline edit + dirty tracking](https://phlex-reactive.zoolutions.llc/docs/example-inline-edit) | Show ↔ edit (Enter saves, Escape cancels) plus an “Unsaved” badge + leave-guard with zero shipped state. |
| [Notifications / badges](https://phlex-reactive.zoolutions.llc/docs/example-notifications) | Pure broadcast — a background event pushes a live re-render, plus a `broadcast_js_to` cross-tab pulse. |
| [Reactive collections](https://phlex-reactive.zoolutions.llc/docs/example-collections) | Add / remove rows + a running count + an empty state, declared **once** with `reactive_collection`, optimistic dismiss + a self-dismissing flash. |
| [File uploads & custom types](https://phlex-reactive.zoolutions.llc/docs/example-uploads) | `: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 states](https://phlex-reactive.zoolutions.llc/docs/example-loading-states) | `disable_with:` + `busy_on` + the always-on `aria-busy`, with a latency toggle to make the pending window visible. |
| [Client-only ops](https://phlex-reactive.zoolutions.llc/docs/example-client-ops) | `on_client` tabs / outside-close menu / accessible drawer — zero fetches, zero custom JS. |
| [Failure surface](https://phlex-reactive.zoolutions.llc/docs/example-failure) | `error_flash` + `data-reactive-error` + `dismiss_after:` — what an adopter gets for free when an action fails. |
| [Team inbox (flagship)](https://phlex-reactive.zoolutions.llc/docs/example-team-inbox) | 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:

| Feature | Where it's shown (live) |
| --- | --- |
| **Client-only ops** — `on_client` + `js` (`show`/`hide`/`toggle`, `set_attr`/`toggle_attr`, `focus`, `dispatch`, transitions): zero round trips | [Client-only ops](https://phlex-reactive.zoolutions.llc/docs/example-client-ops), [Todo list](https://phlex-reactive.zoolutions.llc/docs/example-todo-list), [Team inbox](https://phlex-reactive.zoolutions.llc/docs/example-team-inbox) |
| **Client-side computes** — `reactive_compute` + `reactive_text` (a live preview / char counter that paints with no round trip) | [Payment split](https://phlex-reactive.zoolutions.llc/docs/example-payment-split) |
| **Declarative loading states** — `loading:` / `disable_with:` / `busy_on` (+ the always-on `aria-busy` / `data-reactive-busy`) | [Loading states](https://phlex-reactive.zoolutions.llc/docs/example-loading-states), [Todo list](https://phlex-reactive.zoolutions.llc/docs/example-todo-list), [Collections](https://phlex-reactive.zoolutions.llc/docs/example-collections), [Team inbox](https://phlex-reactive.zoolutions.llc/docs/example-team-inbox) |
| **Dirty-field tracking** — `dirty:` / `track_dirty:` / `warn_unsaved:` (enable Save only on change; warn before leaving) | [Inline edit](https://phlex-reactive.zoolutions.llc/docs/example-inline-edit) |
| **Optimistic visual hints** — `optimistic:` (flip a checkbox / hide a row instantly; revert on failure) | [Todo list](https://phlex-reactive.zoolutions.llc/docs/example-todo-list), [Collections](https://phlex-reactive.zoolutions.llc/docs/example-collections), [Team inbox](https://phlex-reactive.zoolutions.llc/docs/example-team-inbox) |
| **Keyboard triggers** — `event: "keydown.enter"` / `"keydown.esc"` (Enter-to-add, Escape-to-cancel) | [Todo list](https://phlex-reactive.zoolutions.llc/docs/example-todo-list), [Inline edit](https://phlex-reactive.zoolutions.llc/docs/example-inline-edit) |
| **Debounced / morph editing** — `debounce:` live-as-you-type + `reply.morph` to keep the caret | [Payment split](https://phlex-reactive.zoolutions.llc/docs/example-payment-split), [Inline edit](https://phlex-reactive.zoolutions.llc/docs/example-inline-edit) |
| **Live broadcasts** — `broadcast_replace_to` / `broadcast_append_to` / `broadcast_js_to` → cross-tab sync | [Chat](https://phlex-reactive.zoolutions.llc/docs/example-chat), [Notifications](https://phlex-reactive.zoolutions.llc/docs/example-notifications), [Todo list](https://phlex-reactive.zoolutions.llc/docs/example-todo-list), [Team inbox](https://phlex-reactive.zoolutions.llc/docs/example-team-inbox) |
| **Failure surface** — `error_flash` / `data-reactive-error` / `dismiss_after:` / timeout + offline | [Failure surface](https://phlex-reactive.zoolutions.llc/docs/example-failure), [Team inbox](https://phlex-reactive.zoolutions.llc/docs/example-team-inbox) |
| **Combobox keyboard navigation** — `listnav:` (Arrow keys move a client highlight, Enter picks) | [Searchable combobox demo](https://phlex-reactive.zoolutions.llc/demos/searchable-combobox) |
| **File uploads & custom param types** — `:file` / `[:file]` (multipart `FormData`), `Phlex::Reactive.param_type` | [File uploads & custom types](https://phlex-reactive.zoolutions.llc/docs/example-uploads) (code-first) |

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