ComponentsData display

Value diff

A field's value before and after a change: the old value struck through, an arrow, the new one. Values draw as the table draws them, so a stage stays a pill and money stays money.

Playground

Change the controls to try each prop. The code under the preview updates as you go and lists only the props you changed; copy it into your page.

Notice periodfrom3 monthsto1 month
import { ValueDiff } from '@/ui/value-diff';<ValueDiff label="Notice period" after="1 month" before="3 months" />

Inline

One field in a sentence or a row: the label in subtle text, the old value struck through in subtle, an arrow, then the new value in medium weight. It takes the type size of the text around it.

Notice periodfrom3 monthsto1 month
import { ValueDiff } from '@/ui/value-diff';

export default function ValueDiffInline() {
  return <ValueDiff label="Notice period" before="3 months" after="1 month" />;
}

A stage

The new value draws as the table draws it. A stage is a lozenge in its phase hue; the old stage is plain struck text.

fromLong listtoCV sent
import { Lozenge } from '@/ui/lozenge';
import { ValueDiff } from '@/ui/value-diff';

export default function ValueDiffStage() {
  return <ValueDiff before="Long list" after={<Lozenge phase="client">CV sent</Lozenge>} />;
}

Change list

Several fields: labels in a column of subtle text, each diff beside its label. Used on receipts, approval cards and Activity.

Stage
fromLong listtoCV sent
Salary
from£95,000 a yearto£110,000 a year
Notice period
1 month
Owner
fromPriya ShahtoEmpty
import { Lozenge } from '@/ui/lozenge';
import { RecordChip } from '@/ui/record-chip';
import { ValueDiffList } from '@/ui/value-diff';

export default function ValueDiffChangeList() {
  return (
    <div className="max-w-120">
      <ValueDiffList
        items={[
          { label: 'Stage', before: 'Long list', after: <Lozenge phase="client">CV sent</Lozenge> },
          { label: 'Salary', before: '£95,000 a year', after: '£110,000 a year' },
          { label: 'Notice period', after: '1 month' },
          { label: 'Owner', before: <RecordChip type="member" name="Priya Shah" />, after: null },
        ]}
      />
    </div>
  );
}

Empty before or after

A field that was empty shows only the new value. A field that was cleared reads "Empty", never a dash.

Notice period1 monthOwnerfromPriya ShahtoEmpty
import { ValueDiff } from '@/ui/value-diff';

export default function ValueDiffEmpty() {
  return (
    <div className="flex flex-col items-start gap-100">
      <ValueDiff label="Notice period" after="1 month" />
      <ValueDiff label="Owner" before="Priya Shah" after={null} />
    </div>
  );
}

Long value

A text value over 160 characters shows two lines and Show all, which opens it in place.

Summary
Leads the data platform at Halcyon Bank: a 40 TB lakehouse on Spark and Delta, a team of six, and the move off the old warehouse in 2025. Before that, four years at Northwind Labs building their streaming pipeline.
import { ValueDiffList } from '@/ui/value-diff';

const summary =
  'Leads the data platform at Halcyon Bank: a 40 TB lakehouse on Spark and Delta, a team of six, and the move off the old warehouse in 2025. Before that, four years at Northwind Labs building their streaming pipeline.';

export default function ValueDiffLong() {
  return (
    <div className="max-w-120">
      <ValueDiffList items={[{ label: 'Summary', after: summary }]} />
    </div>
  );
}

Values show as stored, with their own separators and characters. A long value with no spaces wraps instead of overflowing.

Salary
from£95,000to£1,234,567
Preferred name
fromMinhtoNguyễn Thị Minh Khai
Website
https://careers.halcyonbank.com/engineering/data-platform/senior-data-engineer-london
import { ValueDiffList } from '@/ui/value-diff';

export default function ValueDiffExtremes() {
  return (
    <div className="max-w-120">
      <ValueDiffList
        items={[
          { label: 'Salary', before: '£95,000', after: '£1,234,567' },
          { label: 'Preferred name', before: 'Minh', after: 'Nguyễn Thị Minh Khai' },
          { label: 'Website', after: 'https://careers.halcyonbank.com/engineering/data-platform/senior-data-engineer-london' },
        ]}
      />
    </div>
  );
}

On this page