<!-- Generated by scripts/gen-docs.mts from the JSDoc in registry/. Do not edit; run `pnpm run docs`. -->

# RelativeTime

How long ago (or how soon) something happens, in the reader's language: "3 days ago", "yesterday", "in 5 minutes", "now", kept current while it shows. It is a `<time>` with the exact instant, and its `title` gives the full local date and time. The server writes the UTC date (in en-US unless `locale` is set) and hydration repeats it, so the markup matches; the browser then shows the relative time in the reader's language. A calendar date with no time (`"2026-06-01"`) counts whole days from the reader's own today ("tomorrow", "in 3 days"), and its `title` and `<time>` carry that day, never moved into a time zone.

```tsx
import { RelativeTime } from "@/components/ouro/relative-time/relative-time";
```

## Example

```tsx
<RelativeTime value={comment.createdAt} />
```

## Use instead when

- Use `LocalDate` instead where the date itself matters, such as a due date.

## Props

Type: `RelativeTimeProps`.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `className` | `string` |  | Layout only. Appearance classes warn in development. |
| `locale` | `Intl.LocalesArgument` | the reader's (en-US in the server's text, until the browser takes over) | The language and region to write it in. |
| `numeric` | `"auto" \| "always"` | `"auto"` | `auto` says "yesterday" and "now"; `always` says "1 day ago" and "in 0 seconds". |
| `ref` | `Ref<HTMLTimeElement>` |  | Reaches the rendered element. |
| `value` (required) | `Date \| string \| number` |  | The instant: a `Date`, an ISO string or a timestamp in milliseconds. A calendar date with no time (`"2026-06-01"`, or `"2026-06"` for a month) counts whole days (or months) in the reader's own calendar and is never moved into a time zone. |

## Native attributes

Also accepts the attributes in React's `HTMLAttributes` and `TimeHTMLAttributes` (`id`, `aria-*`, event handlers), passed to the rendered element, except those named on this page.

## Don't use

These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.

- `date`: Not a prop. The instant is `value`: `<RelativeTime value={comment.createdAt} />`.
- `now`: Not a prop. The time updates itself; nothing to pass.

## `className` is for layout only

Pass margins, width and grid placement (`mt-4`, `w-full`, `col-span-2`). Your classes always win over Ouro UI's: RelativeTime merges `className` last with `cn` (tailwind-merge), so a class that conflicts with its own replaces it.[^layout-classes]

Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (`hover:`, `sm:`) and any `!` are removed, it starts with `bg-`, `text-`, `border-`, `rounded-`, `shadow-`, `font-`, `ring-`, `from-`, `via-`, `to-`, `fill-` or `stroke-`, or is `border`, `rounded`, `shadow` or `ring`, or has a `dark:` variant. Text wrapping, overflow and table layout classes (`text-wrap`, `text-ellipsis`, `border-collapse`) are layout and do not warn.

Alignment classes (`text-center`) warn too: set alignment on a parent element.

[^layout-classes]: test:registry/ouro/components/ouro/relative-time/relative-time.test.tsx::RelativeTime > forwards a ref and <time> attributes, and lets app layout classes win verify:testExists(registry/ouro/components/ouro/relative-time/relative-time.test.tsx::RelativeTime > forwards a ref and <time> attributes, and lets app layout classes win)
