Skip to content

Templates

For repeatable structures (list items, toasts, cards) Rivet uses native <template> elements. template(name) returns a factory that yields a fresh clone as a DocumentFragment on each call.

A <template> with data-rivet-part inside the component root:

<div data-rivet="toast" data-rivet-id="toaster">
<template data-rivet-part="item">
<div class="toast" role="status">
<span data-rivet-part="message"></span>
<button type="button">Close</button>
</div>
</template>
</div>
const createItem = template("item"); // get the factory
const frag = createItem(); // fresh DocumentFragment clone
root.appendChild(frag);
  • template(name) looks for a template[data-rivet-part="name"] and throws if none is found.
  • The returned function clones template.content anew on each call (cloneNode(true)).
import { defineComponent } from "@fullhaus/rivet";
export const toast = defineComponent(({ root, template, on }) => {
const createItem = template("item");
function show(message: string, ms = 3000) {
const frag = createItem();
const el = frag.querySelector<HTMLElement>(".toast");
const text = frag.querySelector<HTMLElement>('[data-rivet-part="message"]');
if (!el || !text) return;
text.textContent = message;
const closeBtn = el.querySelector("button");
on(closeBtn!, "click", () => el.remove());
root.appendChild(frag);
const id = setTimeout(() => el.remove(), ms);
// Clear the timer if the component is disposed first:
return () => clearTimeout(id);
}
return { show };
});
const app = createRivet().component("toast", toast).mount();
app.require<{ show(msg: string): void }>("toaster").show("Saved!");
  • Parts (part/parts) — for existing, one-off elements in the markup.
  • Templates (template) — for repeatable structures created at runtime any number of times.