@industream/timeline
v1.1.0
Published
The @industream timeline as a framework-agnostic Web Component (<industream-timeline>). Self-contained bundle (React + styles inside a Shadow DOM). Works in Angular, Vue, vanilla — no React or Tailwind setup required.
Readme
@industream/timeline
The @industream timeline as a framework-agnostic Web Component — <industream-timeline>: a band with a
movable snapshot point, a resizable [from, to] window, zoom, and Live / Timelapse modes. It
only produces times — it fetches nothing and has no API coupling.
Self-contained: React, the widget, and its styles are bundled inside a Shadow DOM. The host provides nothing — no React, no Tailwind, no CSS setup. Works in Angular, Vue, Svelte, vanilla… or a React app.
Building a React app? If you can consume the source package, prefer
@industream/timeline-react: you avoid a second React runtime and get typed hooks (useSnapshot,useStartDate…) instead of DOM events.
Install
npm i @industream/timelineUsage
A single side-effect import registers the <industream-timeline> element globally:
import "@industream/timeline";Then drop it anywhere. Drive it with attributes, read it back through events.
Attributes
| Attribute | Values | Default | Meaning |
| --- | --- | --- | --- |
| language | en | fr | de | en | UI language. |
| instant | boolean (presence) | — | Show the snapshot instant T (playhead + value bubble). |
| window | boolean (presence) | — | Show the [from,to] window and its start/end fields. |
| modes | space-separated live timelapse (absent = all; "" = Historic only) | all compatible | Animated modes on top of Historic (always on). timelapse auto-adds instant+window while it runs. |
| theme | light | dark | light | Built-in colour theme. |
| step-loading | boolean | off | Tells timelapse a snapshot is still loading, so playback waits for your data. |
If neither instant nor window is present, both default on (bare <industream-timeline> = full timeline). Historic is always on; modes lists only live / timelapse (omit the attribute for the default, "" for Historic only). Listing historic or an unknown mode throws; timelapse never throws — it auto-adds any missing content while it runs. See the full guide for every combination.
One property (an object, so set it in JS, not as an attribute): el.preview = { points, min, max } — an
optional series drawn faintly across the band.
Events
All fire as CustomEvents (they bubble and cross shadow boundaries). Times are epoch milliseconds in
event.detail.
| Event | detail | Fires when |
| --- | --- | --- |
| snapshotchange | { snapshot } | the "as of" instant changes (debounced). |
| windowchange | { from, to } | the window bounds change (debounced). |
| extentchange | { from, to } | the full navigable extent changes. |
Angular
import { Component, CUSTOM_ELEMENTS_SCHEMA, signal } from "@angular/core";
import "@industream/timeline";
@Component({
selector: "app-root",
schemas: [CUSTOM_ELEMENTS_SCHEMA], // lets Angular accept the custom tag
template: `
<industream-timeline
[attr.language]="language()"
[attr.theme]="theme()"
(snapshotchange)="onSnapshot($event)"
(windowchange)="onWindow($event)">
</industream-timeline>`,
})
export class App {
readonly language = signal<"en" | "fr" | "de">("en");
readonly theme = signal<"light" | "dark">("light");
onSnapshot(e: Event) { const { snapshot } = (e as CustomEvent).detail; /* new Date(snapshot) */ }
onWindow(e: Event) { const { from, to } = (e as CustomEvent).detail; /* … */ }
}Vanilla
<industream-timeline language="en" theme="dark"></industream-timeline>
<script type="module">
import "@industream/timeline";
const el = document.querySelector("industream-timeline");
el.addEventListener("snapshotchange", (e) => console.log(new Date(e.detail.snapshot)));
</script>Theming
The widget ships a default theme. Flip it with theme="dark", or override the CSS variables from the host —
they inherit through the shadow boundary:
industream-timeline { --primary: oklch(0.55 0.2 250); --radius: 0.3rem; }License
ISC
