Skip to content

Quick Start

Rivet is three steps: mark up the HTML, define the component, mount the app. That’s it.

Server-rendered HTML (e.g. from a Fluid partial) gets three attributes:

<div data-rivet="disclosure" data-rivet-id="main-menu">
<button data-rivet-part="button" aria-expanded="false">Toggle</button>
<div data-rivet-part="panel">Content</div>
</div>
  • data-rivet marks the root of a component and names its type.
  • data-rivet-part marks named elements inside the root.
  • data-rivet-id assigns an ID through which the public API is retrievable.

More on this: HTML Attributes.

A component is a function that receives a context and returns its public API.

import { defineComponent } from "@fullhaus/rivet";
export const disclosure = defineComponent(({ part, signal, on, effect }) => {
const button = part("button");
const panel = part("panel");
const open = signal(false);
on(button, "click", () => open.update((v) => !v));
effect(() => {
panel.hidden = !open();
button.setAttribute("aria-expanded", String(open()));
});
// Public API — reachable from the outside via the component ID.
return {
show: () => open.set(true),
hide: () => open.set(false),
};
});
import { createRivet } from "@fullhaus/rivet";
import { disclosure } from "./disclosure";
const app = createRivet()
.component("disclosure", disclosure)
.mount();

mount() scans the document for [data-rivet] elements, matches each one to its registered component and instantiates it.

Components with a data-rivet-id expose their returned API:

const menu = app.require("main-menu");
menu.hide();
  • app.get(id)T | undefined
  • app.require(id)T or throws a clear error
import { createRivet, defineComponent } from "@fullhaus/rivet";
const disclosure = defineComponent(({ part, signal, on, effect }) => {
const button = part("button");
const panel = part("panel");
const open = signal(false);
on(button, "click", () => open.update((v) => !v));
effect(() => {
panel.hidden = !open();
button.setAttribute("aria-expanded", String(open()));
});
return { show: () => open.set(true), hide: () => open.set(false) };
});
const app = createRivet().component("disclosure", disclosure).mount();
app.require("main-menu").hide();