Temporeum Timelinev1.0.2

API reference

The tables on this page are generated from the TypeScript source of @temporeum/timeline-element when the site is built, so they cannot fall behind it. The types themselves ship with the packages: an editor shows every one of these with its documentation.

createTimeline(container, config, options?)

Creates the live timeline in container and returns a Timeline. options.hydrate adopts a server-rendered <svg> already in the container; options.root draws into a shadow root or a fragment instead. The custom element and the React component are shells around this call.

Configuration

Every field is optional, and every field can change later through timeline.update({ … }): a key present with undefined goes back to its default, an absent key keeps its value. On the element, element.items, lanes, groups, template, gantt, resources, resourceOptions, hooks, orientation, density, theme, height, locale, timeZone, breakpoint, packMode, cluster, direction, calendar, touchAction, domain, editable, multiSelect, snapMs and selectedIds are properties, and every other field goes through element.config (setting it again replaces what the previous config set). On the React component, every field is a prop.

Apart from three, every attribute of the element has one of those properties as its pair — start and end are domain — and a property wins over its attribute until it is set to undefined. The three: aria-label is the ariaLabel field (the platform's own element.ariaLabel sets the attribute), aria-labelledby names the chart by the text of the elements it points to and follows their changes, and nonce is read when the element connects. editable, multiSelect and snapMs are each one field of editing, so setting one leaves the attributes' other fields in force.

TimelineConfig — generated from the TypeScript source
MemberTypeWhat it is
items?ItemsSource<T>The items, or a function that fetches the ones in a window. A function is asked for the domain about to be drawn and aborted when the view moves on (createItemLoader).
lanes?readonly Lane[]
groups?readonly Group[]Nested groups. Each group is a header row — click it, or press Enter, to collapse it; drag it, or press Alt with an arrow, to reorder it — and the rows of its own items, which name it as their laneId. When given, lanes is ignored.
template?((item: Item<T>) => string | null)Each item's picture as HTML — sanitised: scripts, handlers and anything outside an allow-list are dropped (templateOptions). The template replaces the item's label; its accessible name stays the label.
templateOptions?TemplateOptions
slots?boolean | ((item: Item<T>) => boolean)Leave each item — or those the function picks — an empty box a framework renders into: a <div data-tl-slot> over the item, listed by timeline.slots and the slotsChanged event after each frame that changed them. What the React and Vue components' renderItem and #item slot draw with. Needs the /items plugin, as template does.
gantt?TimelineGanttOptionsDraw the timeline as a Gantt chart: dependency arrows, each item's progress and baseline, and kind: "milestone" diamonds. The task table beside it is mountTaskGrid.
resources?readonly Resource[]Draw the timeline as a resource view: the resources are the lanes — or, with lanes or groups, they say which of those lanes are resources — and an item in a resource's lane is work assigned to it. Under each resource a load lane shows how loaded it is against its capacity; where it is overbooked its lane is banded and its items say so. With editing.crossLane, a drag or Alt and an arrow moves work between resources. The unscheduled tasks beside it are mountBacklog.
resourceOptions?TimelineResourceOptions<T>
domain?readonly [TimeInput, TimeInput]The initial view. Without one, the items' extent plus a margin; without items either, the month around the moment the timeline was created.
limits?DomainLimitsHow far the reader can pan and zoom: the earliest and latest time, the shortest and longest span.
orientation?OrientationSetting"horizontal", "vertical", or "auto" — vertical below breakpoint (640 px), horizontal above it. "auto" by default.
breakpoint?numberWidth below which orientation: "auto" turns vertical.
density?DensitySetting"comfortable", "compact", "dense", or "auto" — the one the visible items have room for.
metrics?MetricsSettingSizes over the density's: a row's height, the type, the corners, the font — { rowSize: 36, fontSize: 14, fontFamily: "Inter, sans-serif" }, or a function of the level's own. Configuration rather than CSS: the layout is measured with them.
packMode?PackModeHow overlapping items share a lane: "pack" into rows (the default), "overlap", or "single" row.
theme?ThemeSetting"light", "dark", "auto" (the reader's color scheme), or a theme of your own.
locale?stringThe language of the axis, the dates and the words, as a BCP 47 tag. "en" by default.
timeZone?stringThe IANA time zone the axis and the dates are in. UTC by default.
formatTick?((tick: Tick, timeZone: string) => string)The axis labels' text. The default writes years as ISO does (-0500 for 501 BC); a chronology writes its own.
axisContext?booleanThe month (or year, or day) the view is in, held at the start of the axis — formatTick writes it too, told by tick.context. On by default; false leaves the axis to its ticks.
touchAction?TouchActionModeWhether the timeline claims every touch gesture (own, the default) or leaves the page's vertical scroll to the page (cooperative) — for a timeline embedded in an article, which a reader has to be able to scroll past.
maxLabels?numberCeiling on drawn item labels.
labelOverflow?LabelOverflowA label longer than its room: shortened with an ellipsis ("ellipsis", the default) or given up ("drop"). The full text stays the item's accessible name either way.
ariaLabel?stringThe accessible name of the listbox.
decorations?readonly Decoration[]What is drawn besides the items: banding of the periods, the now line, eras, markers.
cluster?boolean | ClusterOptionsJoin items too close to tell apart into one cluster the reader opens; true, or the gap and size it joins at.
hooks?RenderHooks<T>
height?numberThe drawing's height in CSS pixels. Without one, the container's own height when it has one (a stylesheet set it), else DEFAULT_HEIGHT — for a vertical timeline as much as for a horizontal one.
interactions?InteractionOptionsPointer tuning. Read when the timeline is created and on update().
editing?TimelineEditingOptions<T>
selectedIds?readonly string[]The selection, when the host owns it. Changes from the user are still reported.
instanceId?stringScope for the embedded stylesheet and the drawing's ids, for a timeline in the light DOM next to another. Without one, createTimeline in the light DOM takes a scope of its own (tl-auto1, …), and a drawing taken over from the server keeps the server's. The custom element does not need one: its shadow root is the scope.
nonce?stringThe nonce of the <style>s the timeline writes, for a Content-Security-Policy without 'unsafe-inline'. In a browser the stylesheets go into adoptedStyleSheets, which such a policy allows, and no <style> is written; this is for the rest — a browser without constructable stylesheets — and for the server's markup, whose <style>s carry it. On the element it is the nonce attribute. Read once, when the timeline is created.
measureText?MeasureTextWidth of a line of label text. In a browser the instance measures with the page's own font; the server, which has no font, estimates — and the first client frame patches the labels that came out differently.
sceneSpace?boolean | "auto"Draw the items in a stable space, mapped onto the view with one transform per layer (planSceneSpace), so that a pan or a zoom frame inside what is already drawn rewrites nothing but the transform. It is what keeps a pan of 2000 visible items at 60 frames a second. The price: during a gesture the picture may be stretched by up to 1.5x, and labels are those each sixteenth of a view could place. When the gesture ends the frame is exact again, labels included: it shows every label an exact frame would. "auto" (the default) and true draw in a space; false draws every frame exact. Before 1.0.0-rc.2 "auto" drew exact below 1000 items, because a space at rest could drop a label an exact frame keeps.
hiddenDates?readonly HiddenDateRange[]Time the axis does not draw — nights, weekends, a shutdown: fixed and repeating ranges (createHiddenDates), repeated in timeZone. A pan moves by shown time and a zoom holds the instant under the pointer across a hidden stretch; frames with hidden dates are drawn exactly.
timeBars?readonly TimeBar[]The host's own lines across the timeline. Each is a slider: drag it, or focus it with Tab and move it with an arrow (PageUp/PageDown ten steps, Home/End to the view's ends). A move is timeBarMoved; the instance keeps the bar where it was put until timeBars changes.
timeBarOptions?TimelineTimeBarOptions
rolling?boolean | TimelineRollingOptionsFollow the clock: the window keeps its span and keeps now at offset (the middle by default), re-read every intervalMs. A pan or a zoom of the reader's lets go of it until follow().
zoomPresets?boolean | readonly ZoomPreset[]Buttons for named zooms — true for a day, a week, a month and a year — and zoomToPreset(id).
minimap?boolean | { readonly size?: number; }The overview strip along the far edge: the whole extent, with the view as a window to drag, press beside, or focus and move with an arrow.
rangeSelect?boolean | (RangeSelectOptions & { readonly stepMs?: number; })Range selection: a drag along the axis band selects a stretch of time instead of panning; with the timeline focused, r starts one at the middle of the view, an arrow along the axis moves its end, Enter selects and Escape lets go. Either is rangeSelected.
laneHeaders?booleanEach lane's name held at the start of the view while it is in view.
tooltip?boolean | ((item: Item<T>) => string | null)A tooltip on an item — on hover, on keyboard focus, and on a long press — that the pointer can move onto and Escape dismisses (WCAG 1.4.13). Its text is the item's label and dates, or what the function returns.
direction?"auto" | DirectionWhich way the inline axis runs. "rtl" mirrors the timeline: time flows from the right — vertically, the first lane is the rightmost — the pointer, the wheel and the left and right arrows follow the mirror, and text is laid out right to left. "auto" takes the element's computed direction (the page's dir); a server, which has none, draws "ltr". Left to right by default.
strings?Partial<Strings>The library's words in the host's language: any phrases of DEFAULT_STRINGS (/intl) — the accessible names of items, clusters, tasks and loads, the tools' labels and announcements, a new item's label. Dates and numbers are Intl's, in locale. Without it, the English the library has always said.
calendar?stringA calendar Intl knows — "hebrew", "islamic-umalqura", "persian", "chinese", "japanese", "buddhist", … The axis's months and years are then the calendar's own, and its labels Intl's in locale (formatTick still wins). "gregory" keeps the Gregorian axis with Intl labels. Without one the axis is Gregorian and its labels the deterministic default.

The instance

Timeline — generated from the TypeScript source
MemberTypeWhat it is
on<K extends TimelineInstanceEventName>(type: K, listener: (payload: TimelineInstanceEventMap<T>[K]) => void) => UnsubscribeListen to one event. Returns the unsubscribe function.
subscribe(listener: () => void) => UnsubscribeStore protocol: called after every frame whose snapshot changed.
getSnapshot() => TimelineSnapshot
update(config: TimelineUpdate<T>) => voidChange any part of the configuration. Omitted keys keep their value; a key present with undefined goes back to its default. A value equal to the one the instance already has is no change — for items that means the same array: a host that re-sends its props after an edit keeps the edit. To replace the items with the very array given before, call setItems. The option objects (editing, interactions, limits, hiddenDates, timeBars, rolling), domain and selectedIds are compared by what they say, so editing: { enabled: true } written anew on every render neither restarts a drag nor moves the view back; a new function in them (canMove) is called from then on. A new fetch function for items is the one the next fetch calls, and what was loaded stays — setItems reloads. To move the view the reader moved, zoomTo; to change the selection, select.
setItems(items: TimelineConfig<T>["items"] | undefined) => voidReplace the items — always, the same array included: edits the instance holds and the host did not write back are dropped, and the array (or the source) given is what the timeline shows. update({ items }) with an array the instance already has is no change; this is the call that says "these, again".
applyCommand(command: Command | GroupCommand) => voidApply a command's patches — command.inverse is an undo. Group commands reorder the groups.
toggleGroup(id: string, options?: { readonly collapsed?: boolean; }) => voidCollapse ({ collapsed: true }) or expand ({ collapsed: false }) a group; without collapsed, toggle it.
dropItem(payload: Partial<Item<T>> & { readonly durationMs?: number; }) => booleanAdd an item the way a drop adds one, at the keyboard's place: the middle of the view, in the focused item's lane. The keyboard twin of dragging an external element in — a host binds it to its own list's key. false when nothing was added (dropping off, vetoed, an id already there).
dropItemAt(payload: Partial<Item<T>> & { readonly durationMs?: number; }, at: { readonly clientX: number; readonly clientY: number; }) => booleanAdd an item the way a drop adds one, where a pointer let go — the time and the lane under it (a load lane counting as its resource). What a list that drags its own rows calls on release, for a mouse, a pen and a finger alike. false when nothing was added: the point is outside the timeline, dropping is off, vetoed, or the id is already there.
itemsreadonly Item<T>[]The items as they are now, edits included.
addItems(items: readonly Item<T>[]) => voidLive data: add items without reloading the others. Only the lanes the new items land in are packed again; the frame is the one setItems with the whole array would draw. Throws for an id already there, and for a fetched source, whose items are its own.
updateItems(updates: readonly ItemUpdate<T>[]) => voidLive data: change fields of items, by id. undefined takes a field away. Throws for an unknown id.
removeItems(ids: readonly string[]) => voidLive data: remove items by id. An id that is not there is not an error.
changeItems(changes: ItemChanges<T>) => voidLive data: one batch of adds, updates and removals, drawn once.
timeBarsreadonly TimeBar[]The time bars, where the reader left them.
zoomToPreset(id: string, around?: TimeInput) => booleanZoom to a named preset (zoomPresets) around the middle of the view, or a time. false for an unknown id.
follow() => voidFollow the clock again after the reader moved the view (rolling).
zoomTo(domain: readonly [TimeInput, TimeInput]) => void
zoomBy(factor: number, around?: TimeInput) => voidZoom by a factor (2 = twice as close) around a time, the middle by default.
scrollTo(time: TimeInput) => voidBring a time to the middle of the view, the way the keyboard's jump does.
select(ids: readonly string[]) => void
layoutLayout<T> | undefined
metricsDensityMetrics | undefinedThe sizes the last frame was drawn with — its density's, with config.metrics over them. A panel beside the timeline lines up with these.
slotsReadonlyMap<string, ItemSlot<T>>The slots drawn now, by item id; empty without config.slots.
focusItem(id: string) => booleanPut the keyboard's focus on an item and bring it into view — its time along the axis, its lane across. A task grid's Enter calls it. false for an item the layout does not hold.
scrollLanes(delta: number) => voidScroll the lanes across by a number of CSS pixels, as a wheel over the lanes does.
revealLane(laneId: string) => voidScroll the lanes across just enough to show one lane whole.
resultRenderResult<T> | undefinedThe last frame, for hit testing or export.
exportSvg() => stringThe current drawing as a standalone SVG document. An auto theme is pinned to what the screen shows. Throws before the first frame: there is nothing drawn to export yet.
exportPng(options?: PngOptions) => Promise<Blob>The current drawing as a PNG, scale device pixels per CSS pixel (2 by default). Rejects before the first frame, and without the export plugin.
exportPdf(options?: TimelinePrintOptions) => Promise<Uint8Array>The whole range as a PDF, with no server: vector, its text selectable, the lanes cut between rows onto as many pages as they need — each item on exactly one. The drawing is the one at the call. Rejects before the first frame, and without the export plugin, naming its import.
print(options?: TimelinePrintOptions) => Promise<void>Print the whole range through the browser's dialog, a page a sheet, cut as exportPdf cuts it. Resolves when the dialog is closed and the print view has left the document. Rejects before the first frame, and without the export plugin.
flush() => voidDraw now instead of on the next animation frame.
destroyedboolean
noncestring | undefinedThe nonce it was created with (config.nonce), for the <style>s of what is mounted beside it — mountStory, mountBacklog and mountTaskGrid take it from here.
destroy() => voidLet go of the container, the listeners and the timers. After it a method that would change something does nothing and emits nothing — one that answers with a boolean answers false — and the getters, the snapshot and the exports read the last frame.

The snapshot

What getSnapshot() returns: frozen, a new object only when something in it changed, and at most once per drawn frame.

TimelineSnapshot — generated from the TypeScript source
MemberTypeWhat it is
domainDomain
viewportViewport | undefinedundefined until the container has a size and the first frame is drawn.
orientationOrientation
densityDensity
selectedIdsreadonly string[]
focusedIdstring | null
visibleCountnumberItems represented on screen, each cluster counted by its members.
busybooleanA fetched source has a window in flight.
editingbooleanA move or resize is under way.
crossOffsetnumberHow far the lanes are scrolled across, in CSS pixels — what a task grid beside the timeline follows.

Events

timeline.on(name, listener) returns the function that removes the listener. On the element every event is also dispatched as a DOM event under its kebab-case name (itemMoved → item-moved), with the payload as detail; on the React component it is an on… prop (onItemMoved).

TimelineInstanceEventMap — generated from the TypeScript source
MemberTypeWhat it is
densityChangedDensityChangedPayloadThe density changed (density: "auto", a resize).
orientationChangedOrientationChangedPayloadThe orientation changed (orientation: "auto" past the breakpoint).
clusterOpenedClusterOpenedPayload<T>A cluster was opened.
jumpRequestJumpRequestPayloadThe reader asked to jump to a date (g): the host opens its date picker.
itemsAddedItemsAddedPayload<T>Items were added — by a double tap, a key, a drop or dropItem. command is also emitted.
itemsRemovedItemsRemovedPayload<T>Items were removed — by a remove handle or a key. command is also emitted.
itemsChangedItemsChangedPayload<T>The items are another array: an edit, an add, a removal, a command applied, new items set or a window fetched. What a list that follows the items — a backlog — listens to.
groupToggledGroupToggledPayloadA group was collapsed or expanded. View state: nothing to save.
groupMovedGroupMovedPayloadThe groups were reordered. command.inverse undoes it.
timeBarMovedTimeBarMovedPayloadA time bar was moved — let go after a drag, or a key step. The instance keeps it there.
rangeSelectedTimeRangeA range of time was selected — by a drag along the axis band, or r, the arrows and Enter.
slotsChangedSlotsChangedPayload<T>The slots drawn are others (config.slots): an item scrolled in or out, or changed. Emitted in the frame that drew them, before the browser paints it.
inputSkippedInputSkippedPayloadAn item or an option could not be read, and was left out so the rest is drawn: an item with no string id, a start or end that is not a time, a fractional sublaneSpan; a locale or timeZone the platform does not know, which falls back to the default. What was there at creation is said on the microtask after it, so a listener added right away hears it.
itemClickItemEventPayload<T>An item was clicked or tapped, or activated with Enter.
itemDblClickItemEventPayload<T>An item was double-clicked or double-tapped.
itemHoverHoverPayload<T>The pointer came onto an item, or left it (item is then null).
selectionChangedSelectionChangedPayloadThe selection changed: the ids now, and before.
viewportChangedViewportChangedPayloadThe visible range changed — by a pan, a zoom, a key or the API — and why.
layoutChangedLayoutChangedPayloadThe items were laid out again: the lanes, the items in view and the size across.
itemMovedItemMovedPayload<T>An item was moved: where from, where to.
itemResizedItemResizedPayload<T>An item was resized: its span before and after.
commandCommandPayload<T>An edit, as a command the host keeps and undoes with its inverse.

Server rendering

  • renderTimelineHtml(config, { width?, attributes? }) — the whole <temporeum-timeline> element as a string: the drawing in a declarative shadow root, and the configuration beside it as JSON.
  • renderTimelineSvg(config, { width? }) — the drawing alone, as a ServerFrame: the SVG markup with its stylesheet in .svg, the group tree in .groups, and the domain, width, height, orientation and density it was drawn with.

Plugins and the other entry points

registerPlugin(...plugins) from @temporeum/timeline-element registers plugins for the page: every instance, every <temporeum-timeline> and the server renderer draw with what is registered. hasPlugin(name) says whether one is. A configuration that needs a plugin that is not registered throws a TypeError naming the import (see entry points). Each plugin, and what else its entry point exports:

  • @temporeum/timeline-element/gantt — ganttPlugin; the task table, mountTaskGrid.
  • @temporeum/timeline-element/resources — resourcesPlugin; the unscheduled tasks, mountBacklog.
  • @temporeum/timeline-element/export — exportPlugin.
  • @temporeum/timeline-element/tools — toolsPlugin.
  • @temporeum/timeline-element/groups — groupsPlugin.
  • @temporeum/timeline-element/items — itemsPlugin.
  • @temporeum/timeline-element/intl — intlPlugin.

@temporeum/timeline-element/calendar (mountCalendarView, the week and day views), @temporeum/timeline-element/story (mountStory, the story panel) and @temporeum/timeline-element/define (registers the element) are entry points, not plugins.

The engine

@temporeum/timeline-core has its own, larger surface — the renderer, the layout, the input machine, the loader. Its types are its reference; the engine guide is the map. Its entry points — /dom, /live, /words, /groups, /items, /gantt, /schedule, /resources, /tools, /export, /intl, /calendar, /vis-compat, /story — are listed with their budgets under entry points.