Plugin Timeline
Timeline component with vertical, horizontal, and Gantt-style layouts for displaying events and project timelines.
Installation
npm install @object-ui/plugin-timelineThe props an object-timeline node reads on a page are generated from the spec into the component reference; this page covers using the plugin from React.
Usage
Basic Usage
// Import once in your app entry point
import '@object-ui/plugin-timeline'
import type { TimelineSchema } from '@object-ui/types'
// Use in schemas - Vertical Timeline
const schema: TimelineSchema = {
type: 'timeline',
variant: 'vertical',
items: [
{
time: '2024-01-15',
title: 'Project Started',
description: 'Kickoff meeting',
variant: 'success'
}
]
}Features
- Three Layout Variants: Vertical, horizontal, and Gantt-style layouts
- Customizable Markers: Color-coded markers with icon support
- Date Formatting: Multiple date format options
- Gantt Charts: Project timeline visualization with task bars
- Time Scales: Hour, day, week, month, quarter, or year scales for Gantt view
- Lightweight: Pure CSS and React components
Properties
| Property | Type | Default | Description |
|---|---|---|---|
variant | string | 'vertical' | Timeline layout: vertical, horizontal, or gantt |
items | array | [] | Array of timeline items |
dateFormat | string | 'short' | Date formatting: short, long, or iso |
scale | string | 'month' | Gantt axis bucket: hour, day, week, month, quarter, or year |
rowLabel | string | 'Items' | Label for Gantt rows |
minDate | string | auto | Override min date for Gantt (YYYY-MM-DD) |
maxDate | string | auto | Override max date for Gantt (YYYY-MM-DD) |
className | string | '' | Additional Tailwind CSS classes |
Every key above is declared on the exported TimelineSchema, so an editor
completes them and a wrong value is a type error. scale is the canonical axis
key and the only one — it is @objectstack/spec's ui/TimelineConfig.json
spelling and the one the renderer reads.
timeScale, the pre-spec spelling of scale, is retired (objectui#6355).
It is no longer read, and it is no longer authorable: the key is tombstoned on
TimelineSchema, so writing it is a type error and a validation failure rather
than a chart that quietly falls back to the month default. Rename the key to
scale — the accepted values are unchanged.
events, orientation and position are retired (objectui#6170). Nothing
ever read them — a timeline authored with events rendered an empty rail — and
they are no longer authorable: each is tombstoned on TimelineSchema, so
writing one is a type error and a validation failure. Write items instead of
events (each entry { time, title, … }; the date goes in time, not
date) and variant instead of orientation. position has no replacement:
the vertical rail is always drawn on the left.
Object-bound timeline (object-timeline)
object-timeline fetches records from objectName and draws one entry per
record, from the fields its timeline config names. An authored node takes its
props in the properties bag, where @objectstack/spec's
ComponentPropsMap['object-timeline'] row declares them:
{
"type": "object-timeline",
"properties": {
"objectName": "project_task",
"timeline": { "startDateField": "start_date", "titleField": "name" },
"navigation": { "mode": "drawer" }
}
}Where the entries come from
The first record source present wins: items (authored entries, drawn as
written), then data (pre-fetched records), then a bind path, then the query
on objectName. Only the query is a fetch, so objectName is optional: a
timeline drawn from items, data or a bind path needs none to draw (entry-click
navigation still reads it, below), and a node-level dataSource binding can
supply the object instead. Records, from
data, a bind path or the query, are composed into entries through the field
bindings below; authored items are not.
| Prop | What the renderer does with it |
|---|---|
timeline | Names the record fields an entry is drawn from: startDateField (its date), endDateField (the end printed after it), titleField, groupByField (the field whose value heads each group; without it, entries group into date buckets) and colorField (the marker colour: the field's option colour for the value, or the value itself when it is a colour literal). Each outranks the flat key of the same binding. scale sets the gantt axis unit. |
mapping | { title, date, description, variant } field names. title and date are read where the timeline block leaves the binding unset, ahead of the flat keys. variant names the field whose value picks the marker colour (the record's own variant field without it); on the vertical rail a colour from colorField outranks it. |
descriptionField | The field an entry's description is read from (default description); mapping.description outranks it. |
limit | The row cap, lowered to $top (default 100). A value that is not a positive integer is ignored with a console warning. |
filter / sort | Lowered to $filter / $orderby on the query, so they do nothing when items or data supply the entries. The rail draws entries composed from records by start date, earliest first, whatever sort says. |
dateFormat | short (the default) or long, both locale-formatted, or iso. |
rowLabel, minDate, maxDate | The gantt's row-column header and its pinned axis start and end, read only by the gantt branch, which on this block draws authored items. An empty minDate / maxDate is not honoured; a value that is not a date, or a start after the end, refuses the chart with a diagnostic. |
Entry-click navigation
navigation is what an entry click opens — the spec's NavigationConfig by
reference, ViewNavigationConfig in @object-ui/types, the type
ObjectGridSchema.navigation uses: mode (drawer, page, new_window
or none) with size, openNewTab and preventNavigation.
| Member | On an entry click |
|---|---|
mode: 'drawer', or a block without mode (the spec's drawer default) | Opens the entry's record in the drawer |
mode: 'new_window', or openNewTab: true | Opens the record page in a new tab; openNewTab outranks every mode except none. On a timeline that names no objectName there is no record page: the tab opens at a slash and the entry's id alone (its _id when it has no id, undefined when it has neither) |
mode: 'page' | Opens the record page of the timeline's objectName through the record navigator the host publishes (the console publishes one on its custom pages, record pages and list views); under a host that publishes none, such as an embedded renderer, or on a timeline that names no objectName, it opens nothing |
preventNavigation: true, or mode: 'none' | Opens nothing, whatever else the block says |
size | Sets the overlay width (sm … full, or auto for the default) |
A click handler from a parent view outranks the whole key.
With the key absent a click opens nothing: unlike the board and the calendar, this renderer supplies no drawer default.
Variants
Marker Variants
Available marker/bar colors:
default- Graysuccess- Greeninfo- Bluewarning- Yellowdanger- Red
const item = {
time: '2024-01-15',
title: 'Important Milestone',
variant: 'success' // Green marker
}Date Formatting
The timeline component supports three date formats:
import type { TimelineSchema } from '@object-ui/types'
const short: TimelineSchema['dateFormat'] = 'short' // "1/15/2024"
const long: TimelineSchema['dateFormat'] = 'long' // "January 15, 2024"
const iso: TimelineSchema['dateFormat'] = 'iso' // "2024-01-15"A date-only value (2024-01-15) names a calendar day, so every face prints that day in every viewer's time zone, and the object timeline buckets and sorts it as that day. A value with a time part is an instant: short and long print its day in the viewer's zone, and iso prints its UTC day.
Without a groupByField, the object timeline groups entries into date buckets (Earlier, Today, Tomorrow, This week, Next week, Later, No date). "This week" starts on the first day of the week of the user's display locale, the day the calendar's weeks start on: Sunday under en-US, Monday under en-GB or zh-CN.
Time Scales (Gantt)
For Gantt-style timelines, choose the appropriate time scale:
import type { TimelineSchema } from '@object-ui/types'
const shortProject: TimelineSchema['scale'] = 'day' // short projects
const mediumProject: TimelineSchema['scale'] = 'week' // medium projects
const longProject: TimelineSchema['scale'] = 'month' // long projectsA date-only bar date, minDate or maxDate (2024-01-15) names a calendar day, so the axis headers, the bar positions and the bar tooltips all place it on that day in every viewer's time zone. A value with a time part is an instant and sits at its hour in the viewer's day. A plan with no bar dates and no pinned range shows a one-day axis on the viewer's today.
The headers and the bars share one axis. It runs from the start of the unit that holds the first date to the end of the unit that holds the last. Each header is as wide as its unit is long: hour, day and week columns are equal, and a month is as wide as its days. So a bar lines up under the header of the unit it starts in.
Customization
Custom Icons
const item = {
time: '2024-01-15',
title: 'Milestone',
icon: '🎯', // Any emoji or short text
variant: 'success'
}Custom Colors
Use Tailwind CSS classes for additional styling:
import type { TimelineSchema } from '@object-ui/types'
const schema: TimelineSchema = {
type: 'timeline',
variant: 'vertical',
className: 'max-w-4xl mx-auto',
items: [
{ time: '2024-01-15', title: 'Milestone', variant: 'success' }
]
}TypeScript Support
import type { TimelineSchema } from '@object-ui/types'
const timelineSchema: TimelineSchema = {
type: 'timeline',
variant: 'vertical',
items: [
{
time: '2024-01-15',
title: 'Event',
description: 'Description',
variant: 'success'
}
]
}