{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "timestamp",
  "title": "Timestamp",
  "description": "Machine-readable time with relative, date and datetime formats. SSR emits deterministic UTC text; hydration enables local and relative formatting, refreshed each minute. Standalone time has a keyboard tooltip. Activatable table rows show exact time on row or action focus and on time hover. Local and UTC use separate lines; zero-offset viewers see UTC once.",
  "registryDependencies": [
    "@waimakers/utils",
    "@waimakers/theme",
    "@waimakers/tooltip"
  ],
  "files": [
    {
      "path": "src/components/ui/timestamp.tsx",
      "content": "import type { ComponentProps } from \"react\";\nimport { useId, useSyncExternalStore } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn, focusRing } from \"../../lib/utils\";\nimport { Tooltip, TooltipContent, TooltipTrigger } from \"./tooltip\";\nimport {\n  TimestampTooltipLines,\n  TimestampTooltipTime,\n  useTimestampTooltipGroup,\n} from \"./timestamp-tooltip-group\";\n\nfunction subscribeMinute(notify: () => void) {\n  const timer = setInterval(notify, 60_000);\n  return () => clearInterval(timer);\n}\nfunction subscribeStatic() {\n  return () => {};\n}\nfunction currentMinute() {\n  return Math.floor(Date.now() / 60_000) * 60_000;\n}\nfunction serverMinute() {\n  return null;\n}\n\nfunction relativeTime(time: number, now: number) {\n  const elapsed = (time - now) / 1_000;\n  const units = [\n    [31_536_000, \"year\"],\n    [2_592_000, \"month\"],\n    [86_400, \"day\"],\n    [3_600, \"hour\"],\n    [60, \"minute\"],\n    [1, \"second\"],\n  ] as const;\n  const [seconds, unit] = units.find(([seconds]) => Math.abs(elapsed) >= seconds) ?? [1, \"second\"];\n  return new Intl.RelativeTimeFormat(undefined, { numeric: \"auto\" }).format(\n    Math.round(elapsed / seconds),\n    unit,\n  );\n}\n\nfunction Timestamp({\n  value,\n  format = \"relative\",\n  className,\n  timeZone,\n  precision = \"seconds\",\n  interactive = true,\n  tabIndex = 0,\n  ...props\n}: Omit<ComponentProps<\"time\">, \"children\" | \"dateTime\"> & {\n  value: string | Date;\n  format?: \"relative\" | \"date\" | \"datetime\" | \"time\";\n  timeZone?: string;\n  precision?: \"minutes\" | \"seconds\";\n  interactive?: boolean;\n}) {\n  const tooltipId = useId();\n  const exactId = useId();\n  const now = useSyncExternalStore(\n    format === \"relative\" ? subscribeMinute : subscribeStatic,\n    currentMinute,\n    serverMinute,\n  );\n  const date = new Date(value);\n  const iso = Number.isNaN(date.getTime()) ? null : date.toISOString();\n  const utc = iso ? [iso.slice(0, 10), iso.slice(11, 19), \"UTC\"].join(\" \") : \"\";\n  const local =\n    iso && now !== null && date.getTimezoneOffset() !== 0\n      ? new Intl.DateTimeFormat(undefined, {\n          dateStyle: \"medium\",\n          timeStyle: \"long\",\n        }).format(date)\n      : null;\n  const exact = iso ? [local, utc].filter(Boolean).join(\"; \") : null;\n  const inRow = useTimestampTooltipGroup(exactId, local, iso ? utc : null);\n  if (!iso) {\n    return <span className=\"text-muted-foreground\">Not set</span>;\n  }\n  const text =\n    now === null\n      ? format === \"date\"\n        ? iso.slice(0, 10)\n        : utc\n      : format === \"relative\"\n        ? relativeTime(date.getTime(), now)\n        : new Intl.DateTimeFormat(\n            undefined,\n            format === \"time\"\n              ? precision === \"minutes\"\n                ? { hour: \"2-digit\", minute: \"2-digit\", hourCycle: \"h23\", timeZone }\n                : { timeStyle: \"medium\", timeZone }\n              : format === \"date\"\n                ? { dateStyle: \"medium\", timeZone }\n                : { dateStyle: \"medium\", timeStyle: \"short\", timeZone },\n          ).format(date);\n  const describedBy = [props[\"aria-describedby\"], exactId].filter(Boolean).join(\" \");\n  const description = (\n    <span id={exactId} hidden>\n      {exact}\n    </span>\n  );\n  const renderedDescription = now === null ? description : createPortal(description, document.body);\n  if (inRow || !interactive) {\n    return (\n      <>\n        <TimestampTooltipTime>\n          <time\n            {...props}\n            dateTime={iso}\n            aria-describedby={describedBy}\n            title={props.title ?? (inRow ? undefined : (exact ?? undefined))}\n            className={cn(\"rounded-sm tabular-nums\", className)}\n          >\n            {text}\n          </time>\n        </TimestampTooltipTime>\n        {renderedDescription}\n      </>\n    );\n  }\n  return (\n    <Tooltip>\n      <TooltipTrigger\n        render={<time {...props} dateTime={iso} tabIndex={tabIndex} />}\n        aria-describedby={describedBy}\n        className={cn(\"rounded-sm tabular-nums\", focusRing, className)}\n      >\n        {text}\n      </TooltipTrigger>\n      {renderedDescription}\n      <TooltipContent role=\"tooltip\" id={tooltipId}>\n        <TimestampTooltipLines local={local} utc={utc} />\n      </TooltipContent>\n    </Tooltip>\n  );\n}\nexport { Timestamp };\n",
      "type": "registry:ui",
      "target": "components/ui/timestamp.tsx"
    }
  ],
  "type": "registry:ui"
}