On this page
Import
import {
formatRelativeTime,
RelativeTime,
} from '@envsemble/envui';
Usage
RelativeTime's value is the moment: a Date, milliseconds since 1970 or a date string, such as an ISO 8601 timestamp; an invalid one renders nothing. The text rounds to the nearest unit and stays a count, and every RelativeTime on the page updates from one shared clock, so don't run a timer of your own. The tooltip shows the date and time in the reader's time zone; tooltip={false} leaves it out where the exact moment shows nearby.
import { useState } from 'react';
import { Button, RelativeTime, Column, Text } from '@envsemble/envui';
export default function DraftSaved() {
// The draft was last saved 20 minutes before the page opened.
const [savedAt, setSavedAt] = useState(() => Date.now() - 20 * 60_000);
return (
<Column gap={3} align="start">
<Text>
Draft saved <RelativeTime value={savedAt} />
</Text>
<Button variant="secondary" onClick={() => setSavedAt(Date.now())}>
Save draft
</Button>
</Column>
);
}Formats and languages
format is long, the default, short or narrow, in the locale's own wording from Intl.RelativeTimeFormat. locale sets the language as a BCP 47 tag, such as de for vor 3 Stunden, or a list of them; without it, EnvUIProvider's locale, else the browser's. nowLabel is the text for a moment less than 45 seconds away.
<RelativeTime value={updatedAt} format="short" locale="de" />
Text for a label
formatRelativeTime(value, options) returns the same text as a string, with the same format, locale, nowLabel and now, for a place that takes only text, such as an option's label or an accessible name. It doesn't update by itself, and runs in React Server Components; RelativeTime is a client component.
const options = versions.map((version, index) => ({
value: version.id,
label: `Version ${versions.length - index} · saved ${formatRelativeTime(version.savedAt)}`,
}));
Exact moments and tests
Where people must read the moment exactly, format the date with Intl.DateTimeFormat instead. now fixes the moment to compare with, so the text stays as it is: pass the same now to the server and the browser where their output must match, as in tests.
const date = new Intl.DateTimeFormat(undefined, { dateStyle: 'long' }).format(sentAt);
<Text>
Invoice sent on {date} (<RelativeTime value={sentAt} tooltip={false} />)
</Text>;
Composition
RelativeTime is a native <time>, env-relative-time, whose dateTime holds the exact moment, with the quiet dotted underline, env-hover-detail, that marks text with more on hover; on a time it shows only under the pointer and with keyboard focus, as times repeat down lists and read as times without it.
Accessibility
You provide
- The words around the time that say what happened.
- The exact date in visible text where it matters.
- A
localethat matches the page.
envUI provides
- A native
<time>whosedateTimeholds the exact moment. - Text that changes in place without announcements.
- Its own direction inside text of another direction.
Props
RelativeTime
A moment in a time element as text relative to now, such as "3 hours ago", with the date and time in a tooltip. One shared clock keeps every RelativeTime on the page current.
| Prop | Type | Description |
|---|---|---|
valuerequired | RelativeTimeValue | The moment to describe: a Date, milliseconds since 1970 or a date string such as an ISO 8601 timestamp. An invalid moment renders nothing. |
now | Datenumber | A fixed moment to compare with, for tests and server rendering; the text then stays as it is. Without it, or with an invalid one, the text follows the current time. |
tooltipDefault true | boolean | Show the date and time in a tooltip on hover, such as "Oct 14, 2026, 9:41 AM", in the reader's time zone and the locale. Turn it off where the exact moment shows nearby. Inside an application's own Tooltip, that one describes the time instead. |
localeDefault EnvUIProvider's locale for RelativeTime, else the runtime's language: the browser's, or the server's while rendering there | stringreadonly string[ | The language of the text, and of the date and time in RelativeTime's tooltip, as a BCP 47 tag such as "en-GB" or "de", or a list of them in order of preference. |
formatDefault 'long' | 'long''short''narrow' | How long the words are, from Intl.RelativeTimeFormat: long "3 hours ago", short "3 hr. ago" or narrow "3h ago", in the locale's own wording. |
nowLabelDefault 'just now' or 'now' in English, the locale's word for now elsewhere | string | Text for a moment less than 45 seconds away, past or coming, such as "moments ago". English says "just now" of a past moment and "now" of a coming one; other languages the locale's word. RelativeTime takes EnvUIProvider's `messages.relativeTime.now` without it. |
Also accepts the native props of <time>, such as ref, className and aria-* attributes.
formatRelativeTime
A moment as text relative to another, by default the current time, such as "in 2 days", "3 hours ago" or "just now", through Intl.RelativeTimeFormat. An invalid moment gives an empty string; an invalid now is ignored, as by RelativeTime, for the current time.
formatRelativeTime(value: RelativeTimeValue, options?: RelativeTimeOptions): string
Part names
Each part's class and state attributes are public and versioned, for an application's CSS to style.
env-relative-time- A time relative to now, with the exact time in a tooltip.
Strings
EnvUIProvider's messages overrides each, and a component's own label prop wins over it.
messages.relativeTime.now"just now"A moment that has just passed, where Intl would say now.
Changelog
- 1.0.0
RelativeTime's time, which shows the full date in a tooltip, takes the quiet dotted underline,
env-hover-detail, that marks text with more on hover. RelativeTime takes EnvUIProvider'slocaleandmessages.relativeTime.now.formatRelativeTimeruns in React Server Components; RelativeTime is a client component.- 1.0.0-prerelease.6
The dotted underline of a time with a tooltip shows only under the pointer and with keyboard focus, everywhere rather than only in a Table.