Skip to content

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:

Terminal window
# e.g. with Vite
bunx vite serve examples/counter
# or a static server over the whole folder
bunx serve examples
ExampleDemonstrates
basicMinimal disclosure — the first example to read
countersignal, computed, effect, on
disclosureAccordion via parts(), one open at a time, external control
modalNative <dialog> + backdrop click + local event bus
video-play-buttonDOM media events + reactive UI swap
toasttemplate() part, programmatic API, timer cleanup
fetch-dataAsync load with loading/error/data states + AbortController
scrollspyIntersectionObserver driving the active state

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) };
});

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 };
});