Change Log
A presentational timeline for product and release changes.
ChangeLog displays a list of product, release, and project changes. It is intentionally presentational: it does not include search fields, status selectors, category selectors, loading states, empty states, or pagination controls. Applications can compose those features separately when needed.
See the live Change Log showcase.
Basic usage
<ChangeLog
entries={[
{
id: '2.4.0',
date: '30 Sep 2026',
version: 'v2.4.0',
status: 'added',
title: 'Added Audio Player',
description: 'A new media component is available.',
tags: ['media'],
},
]}
/>Entries
Each entry requires a unique id, date, and title. Optional fields are description, details, version, category, status, tags, author, branch, href, and breaking.
status accepts added, changed, fixed, removed, deprecated, or security. The status changes the timeline marker and badge. breaking adds a breaking-change badge. href makes the title a link. details enables the expandable “View details” action.
const entries = [
{
id: 'fix-42',
date: '18 Aug 2026',
category: 'Security',
status: 'security',
title: 'Hardened external links',
description: 'External links now include safe attributes.',
author: 'Frontend team',
branch: 'security/hardening',
tags: ['security', 'links'],
details: <p>Details can contain any React content.</p>,
href: '/releases/fix-42',
},
];Variants, sizes, and order
size accepts sm, default, or lg. variant accepts default, timeline, compact, or bordered:
defaultrenders a bordered timeline card;timelineremoves the outer card surface for embedding in a page;compactremoves the outer surface and reduces spacing;borderedadds separators between entries.
groupBy accepts none, date, version, or category. reverse reverses the entry order without changing the source array. maxHeight limits the list and makes its content scrollable.
<ChangeLog entries={entries} size="sm" variant="compact" />
<ChangeLog entries={entries} size="lg" variant="bordered" groupBy="version" maxHeight={480} reverse />Expandable details
Entries with details can be expanded. Use defaultExpandedIds for uncontrolled initial state, or expandedIds with onExpandedChange for controlled state.
<ChangeLog
entries={entries}
defaultExpandedIds={['fix-42']}
onExpandedChange={(ids, entry) => {
console.log('Toggled', entry.id, ids);
}}
/>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
entries | ChangeLogEntry[] | required | Changes to display. |
size | 'sm' | 'default' | 'lg' | 'default' | Density and typography. |
variant | 'default' | 'timeline' | 'compact' | 'bordered' | 'default' | Surface and separator style. |
groupBy | 'none' | 'date' | 'version' | 'category' | 'none' | Groups entries by a metadata field. |
reverse | boolean | false | Reverses the visible order. |
maxHeight | number | string | — | Maximum scrollable height. |
defaultExpandedIds | string[] | [] | Initially expanded entries. |
expandedIds / onExpandedChange | string[] / callback | — | Controlled expanded state. |
aria-label / className | string | 'Change log' / — | Accessibility label and custom class. |
Accessibility
The component uses a labelled section, semantic article entries, native time elements, keyboard-accessible detail buttons, visible focus styles, and aria-expanded on detail toggles. Keep entry titles and dates meaningful for screen-reader users.