Agent docs

Timestamp

A relative time ("2h ago") that reveals the full, localized date and time on hover.

A relative time ("2h ago") that reveals the full, localized date and time on hover. absolute flips the reading: a compact absolute date in the text, the relative reading in the tooltip.

Toolkit sibling. packages/toolkit/src/date.ts (getHowLongAgo, getRelativeTime) is the same relative-time ladder this component solves in timestamp.tsx:17; the toolkit README's module table names this doc as where date belongs (packages/toolkit/README.md, "Belongs with"); the two ladders diverge only on falsy input, where the kit's renders the epoch and the toolkit's returns an empty string (docs/plan/43-toolkit-rca.md:128-137).

When to reach for it#

Reach for Timestamp anywhere a raw ISO string would otherwise be formatted by hand: table cells, activity feeds, provenance lines. It is the default reading for "when did this happen" across both apps: speedway/app/components/JobsTable.tsx:771, walmart-mvp/frontend/src/pages/Jobs.tsx:227-234, 240-247, walmart-mvp/frontend/src/pages/ActiveParts.tsx:100, and the activity rails in both apps all render it as a table or list cell.

Timestamp carries its own tooltip. Do not wrap it in another Tooltip; it stacks two. This is not a style guess, it is a documented, load-bearing comment at the one real call site that sits beside a sibling Tooltip in the same row: walmart-mvp/frontend/src/pages/Settings.tsx:519, "Timestamp carries its own tooltip; wrapping it stacks two." The mechanism is timestamp.tsx:61-66: the component's own render already wraps its <time> element in a Tooltip.

Contract#

  • iso (required): an ISO date string. Default reading: formatRelativeTime(iso) in the visible text ("2h ago", falling back to a short date past 7 days), formatDateTime(iso) (a full, locale-aware date and time, dateStyle: "full", timeStyle: "short") in the tooltip.
  • locale: a BCP 47 tag, default DEFAULT_LOCALE (en-US). Every formatter here pins the locale rather than reading the runtime's, because an undefined locale is the server's on the first render and the browser's on hydration, and React reports the mismatch; speedway pinned en-US in its own app/lib/datetime.ts for this reason before the kit did. Change it on purpose per app, never per call.
  • absolute: flips which formatter owns which slot. Visible text becomes formatCompactDateTime(iso) ("Jul 19, 12:17 AM", the year appearing only once it differs from the current one), and the tooltip becomes formatRelativeTime(iso). The doc comment on the prop calls this out as "for logs and ledgers, where the date is the datum." No shipped usage of absolute found in either app. Speedway's log page wants exactly this reading, an absolute date up front with the relative reading on hover, but builds it by hand with a local compactWhen/relativeWhen pair and a bare Tooltip, with the comment "Interim local formatter until the kit pin carries Timestamp's absolute mode" (speedway/app/routes/workspaces/review/log.tsx:459-461). Speedway is pinned to @versable-git/ui@^0.0.14 versus walmart's ^0.0.24 (speedway/package.json:36, walmart-mvp/frontend/package.json:21), which is consistent with absolute being newer than speedway's current pin.
  • className: applied to the <time> element.

Two formatter functions are also exported from the package for callers that need the raw text without the component itself: formatDateTime and formatRelativeTime (packages/ui/src/index.ts:51). A third, formatCompactDateTime, is exported too since 2026-08-18, with the pinned DEFAULT_LOCALE beside it (packages/ui/src/index.ts:65). Real usage pairs one of these with the component in the same table column: walmart-mvp/frontend/src/pages/Jobs.tsx:220-234 uses copyValue: v => formatDateTime(v.created_at) for the column's clipboard text while render shows the live <Timestamp iso={r.created_at} />, so the copied value and the displayed value stay independently correct for their two different jobs (a stable full timestamp to paste, a compact live label to read).

Sanctioned combinations#

CombinationProducesWhere usedWhy
<Timestamp iso={...} className="..." /> as a table cell's render, paired with copyValue: v => formatDateTime(v.field) on the same columnA relative-time cell that copies as a full absolute timestampwalmart-mvp/frontend/src/pages/Jobs.tsx:220-234The clipboard value and the displayed value serve different readers; pairing the exported formatter with the component keeps both correct without duplicating date logic
Inline in a sentence: Last changed <Timestamp iso={...} /> by <ActorName .../>The kit's provenance-footer preset (canon doc 5 §B)speedway/app/routes/admin/usage.tsx:340-344The exact preset canon doc 5 §B names ("Provenance footer: compact Card + 'Last changed {Timestamp} by {ActorName}'")
<Timestamp iso={...} className="..." /> rendered as a plain sibling beside another element that itself carries a Tooltip, with a comment noting the deliberate non-wrapTwo independent hovers in the same row: one on the sibling, one (built in) on the Timestampwalmart-mvp/frontend/src/pages/Settings.tsx:519-533The concrete, commented case for the banned combination below: this is what doing it correctly looks like

Banned combinations#

Do not wrap Timestamp in a second Tooltip. It already renders one internally (timestamp.tsx:62-66); nesting stacks two tooltip triggers on the same element, a live defect the Settings.tsx:519 comment exists specifically to prevent from recurring.

Do not treat walmart-mvp/frontend/src/pages/Admin.tsx:751-761's local function Timestamp({ value }) as the kit component. It shares a name only: it takes a value prop (not iso), has no tooltip, and formats with a plain toLocaleString. It is defined and used only inside Admin.tsx itself; the kit's Timestamp (imported from @versable-git/ui) is used everywhere else in the same file for iso-keyed values. Passing value to the kit component, or iso to the local one, is a silent prop mismatch, the same same-name trap empty-state.md documents for walmart's local EmptyState.

Before you adopt this#

Five questions to answer before reaching for Timestamp.

  1. Does the shell, a parent layout, or a global provider already render this? Not applicable, Timestamp is inline content; no shell already renders it.
  2. Does this app already ship a local implementation of the same thing? Admin.tsx's own local Timestamp takes value, not iso; check which one is imported.
  3. Does this app's kit pin reach the version this component or prop landed in? absolute mode postdates speedway's pin (^0.0.14 vs walmart's ^0.0.24); confirm reach.
  4. Does the component derive its own accessible name and keyboard path, or must the call site supply them? Not applicable, Timestamp is a <time> element with no keyboard path of its own.
  5. Which canon §A rules bind this surface, and which does the composition break? Not applicable, no canon §A rule is cited for Timestamp specifically.

Travels with#

Tooltip, internally, never externally (see above).

Table columns' copyValue, paired with the exported formatDateTime helper rather than a hand-written date format, whenever a Timestamp cell's copy behavior needs to differ from its display.

Snippet#

// walmart-mvp/frontend/src/pages/Jobs.tsx:220-234
{
key: "created_at",
header: "Started",
sortable: true,
width: "105px",
copyValue: v => formatDateTime(v.created_at),
render: (r) => (
<Timestamp
iso={r.created_at}
className="text-base-content/55 text-xs whitespace-nowrap"
/>
),
},
@versable-git/ui · reference, canon, and method, read in place