Skip to content
Backlit
Esc
navigateopen⌘Jpreview
On this page

Timeline

Display events with shared fields or configure each event.

Use timeline(data) for events with the same fields. Use timeline(data, callback) for events that need different fields or controls. The data order is the display order. Sort the records in the resolver.

Record timeline

import {
  defineResource,
  fields,
  timeline,
} from '@backlit/sdk'
const orders = defineResource('orders', [
  fields.date('at'),
  fields.text('title'),
  fields.text('body', { format: 'markdown' }),
])
const rows = [
  {
    at: '2026-09-01T10:00:00Z',
    title: 'Order received',
    body: '**Paid** in full.',
  },
]
orders.view('activity', () =>
  timeline(rows).setFields({
    time: orders.get('at'),
    title: orders.get('title'),
  })
)
export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "activity",
    "slots": {
      "content": [
        {
          "kind": "record-timeline",
          "fields": {
            "time": [
              {
                "kind": "date",
                "name": "at",
                "label": ""
              }
            ],
            "title": [
              {
                "kind": "text",
                "name": "title",
                "label": ""
              }
            ]
          },
          "data": [
            {
              "at": "2026-09-01T10:00:00.000Z",
              "title": "Order received"
            }
          ]
        }
      ]
    }
  }
}

setFields accepts marker, time, title, description, meta, and body. time and title are required. marker, time, and body accept one field each. meta accepts at most four fields. title and description accept one field or an array. Calling setFields replaces all positions.

Use onRowClick for a link, setRowActions for controls, and onDefect for conversion failures. setDensity('compact') omits description and body. Record timelines support setPaginator and setSorter with bindings from one scope. The resolver applies their values to the query.

Item timeline

import {
  defineResource,
  fields,
  timeline,
} from '@backlit/sdk'
const orders = defineResource('orders', [
  fields.date('at'),
  fields.text('title'),
  fields.text('body', { format: 'markdown' }),
])
const rows = [
  {
    at: '2026-09-01T10:00:00Z',
    title: 'Order received',
    body: '**Paid** in full.',
  },
]
orders.view('activity', () =>
  timeline(rows, (item, row) => {
    item.setFields({
      time: orders.get('at'),
      title: orders.get('title'),
      body: row.body ? orders.get('body') : undefined,
    })
  })
)
export default orders
{
  "kind": "success",
  "status": 200,
  "node": {
    "kind": "view",
    "resource": "orders",
    "name": "activity",
    "slots": {
      "content": [
        {
          "kind": "item-timeline",
          "data": [
            {
              "time": [
                {
                  "field": {
                    "kind": "date",
                    "name": "at",
                    "label": ""
                  },
                  "value": "2026-09-01T10:00:00.000Z"
                }
              ],
              "title": [
                {
                  "field": {
                    "kind": "text",
                    "name": "title",
                    "label": ""
                  },
                  "value": "Order received"
                }
              ],
              "body": [
                {
                  "field": {
                    "kind": "text",
                    "name": "body",
                    "label": "",
                    "format": "markdown"
                  },
                  "value": "**Paid** in full."
                }
              ]
            }
          ]
        }
      ]
    }
  }
}

The callback receives a fresh TimelineItemBuilder and the event record. Use setFields, onClick, and setActions for that event. The same position limits apply. The item timeline supports setDensity, onDefect, and setPaginator. It has no shared sorter. See Search state.

Was this page helpful?