Example Gallery
The repository contains eight self-contained examples. Each is a standalone
index.html that imports ../../src/index.ts directly. Run them with any
TS-aware dev server:
# e.g. with Vitebunx vite serve examples/counter
# or a static server over the whole folderbunx serve examplesOverview
Section titled “Overview”| Example | Demonstrates |
|---|---|
basic | Minimal disclosure — the first example to read |
counter | signal, computed, effect, on |
disclosure | Accordion via parts(), one open at a time, external control |
modal | Native <dialog> + backdrop click + local event bus |
video-play-button | DOM media events + reactive UI swap |
toast | template() part, programmatic API, timer cleanup |
fetch-data | Async load with loading/error/data states + AbortController |
scrollspy | IntersectionObserver driving the active state |
counter — signals & effects
Section titled “counter — signals & effects”The shortest way to see the reactive system.
<div data-rivet="counter" data-rivet-id="demo"> <button data-rivet-part="dec">−</button> <output data-rivet-part="value">0</output> <button data-rivet-part="inc">+</button> <p>Doubled: <span data-rivet-part="double">0</span></p></div>import { defineComponent } from "@fullhaus/rivet";
export default defineComponent(({ part, signal, computed, effect, on }) => { const value = part("value"); const double = part("double"); const count = signal(0); const doubled = computed(() => count() * 2);
on(part("inc"), "click", () => count.update((v) => v + 1)); on(part("dec"), "click", () => count.update((v) => v - 1));
effect(() => { value.textContent = String(count()); double.textContent = String(doubled()); });
return { reset: () => count.set(0) };});fetch-data — async with AbortController
Section titled “fetch-data — async with AbortController”Async loading with three states and a clean abort on unmount.
import { defineComponent } from "@fullhaus/rivet";
export default defineComponent(({ part, signal, effect, on, cleanup }) => { const status = part("status"); const state = signal<"idle" | "loading" | "error" | "done">("idle"); const data = signal<unknown>(null); const controller = new AbortController(); cleanup(() => controller.abort());
async function load() { state.set("loading"); try { const res = await fetch("/api/items", { signal: controller.signal }); data.set(await res.json()); state.set("done"); } catch (err) { if (!controller.signal.aborted) state.set("error"); } }
on(part("load"), "click", load); effect(() => { status.textContent = state(); });
return { reload: load };});- Concepts: Signals & Effects
- Concepts: Templates — basis for
toast - Concepts: Lifecycle & Cleanup — basis for
fetch-data