Skip to content

RelativeTime ​

A moment as its age, 5m ago, with the exact date and time in a tooltip. For the right edge of a row: when a run finished, when a release was last seen, when a token was used.

tsx
import { RelativeTime } from '@adecore/ui';
tsx
import { useState } from 'react';
import { RelativeTime } from '@adecore/ui';

const MINUTE = 60_000;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;

const ROWS: { name: string; ago: number | null }[] = [
    { name: 'Deploy to production', ago: 20_000 },
    { name: 'Rotate the signing key', ago: 7 * MINUTE },
    { name: 'Nightly backup', ago: 5 * HOUR },
    { name: 'Release 2.4.0', ago: 3 * DAY },
    { name: 'Migrate the archive', ago: 40 * DAY },
    { name: 'First sign-in', ago: null }
];

export default function RelativeTimeDemo() {
    const [now] = useState(Date.now);
    return (
        <ul className="flex w-full max-w-80 flex-col gap-1.5 text-sm">
            {ROWS.map((row) => (
                <li key={row.name} className="flex items-center justify-between gap-4">
                    <span className="text-text">{row.name}</span>
                    <RelativeTime at={row.ago === null ? null : now - row.ago} className="text-xs text-text-faint tabular-nums" />
                </li>
            ))}
        </ul>
    );
}

The age is formatAge and the tooltip is formatDayClockWithYear, both from the date formatters, so the language and the region a person set write both. Past a week the age turns into the day itself, with the year once it is not this one.

tsx
<RelativeTime at={run.finishedAt} className="text-xs text-text-faint tabular-nums" />

It keeps its age current while it is on screen, on a clock that ticks every thirty seconds, so a page left open does not keep saying 2m ago. A region change draws it again.

It is a <time> with the moment in dateTime. Text is no tab stop of its own, so it is one, with the accent outline: the tooltip opens on keyboard focus as it does on hover. A moment that is not known, null, undefined or an invalid date, is a dash with no tooltip and no tab stop.

Inside a row that has the focus itself, such as an option of a command palette or a menu item, a tab stop of its own would leave the row's keys behind. Pass tooltip={false} there: the age still counts on, and the row carries the exact time in its own tooltip or description, written with formatDayClockWithYear.

tsx
<RelativeTime at={session.updatedAt} tooltip={false} />

Give it the size and the color through className. An age inside a sentence ("ended 5m ago") is a string, not this component: write it with formatAgo or formatAge.

Props ​

PropTypeDefault
atDate | number | null | undefinedRequired. A number is milliseconds since the epoch.
tooltipbooleantruefalse drops the tooltip and the tab stop.
tooltipSideTooltipSide'top'
classNamestring
refRef<HTMLElement>The <time>, or the <span> of the dash.

RelativeTimeProps is an exported type.

Licenses and third-party notices are listed in each package.