{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"relative-time","type":"registry:ui","title":"relative-time","description":"A component that displays time in various timezones.","author":"Hayden Bleasel <hello@haydenbleasel.com>","dependencies":["@radix-ui/react-use-controllable-state"],"devDependencies":[],"registryDependencies":[],"files":[{"type":"registry:ui","path":"index.tsx","content":"\"use client\";\n\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport {\n  createContext,\n  type HTMLAttributes,\n  useContext,\n  useEffect,\n} from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nconst formatDate = (\n  date: Date,\n  timeZone: string,\n  options?: Intl.DateTimeFormatOptions\n) =>\n  new Intl.DateTimeFormat(\n    \"en-US\",\n    options ?? {\n      dateStyle: \"long\",\n      timeZone,\n    }\n  ).format(date);\n\nconst formatTime = (\n  date: Date,\n  timeZone: string,\n  options?: Intl.DateTimeFormatOptions\n) =>\n  new Intl.DateTimeFormat(\n    \"en-US\",\n    options ?? {\n      hour: \"2-digit\",\n      minute: \"2-digit\",\n      second: \"2-digit\",\n      timeZone,\n    }\n  ).format(date);\n\ntype RelativeTimeContextType = {\n  time: Date;\n  dateFormatOptions?: Intl.DateTimeFormatOptions;\n  timeFormatOptions?: Intl.DateTimeFormatOptions;\n};\n\nconst RelativeTimeContext = createContext<RelativeTimeContextType>({\n  time: new Date(),\n  dateFormatOptions: {\n    dateStyle: \"long\",\n  },\n  timeFormatOptions: {\n    hour: \"2-digit\",\n    minute: \"2-digit\",\n  },\n});\n\nexport type RelativeTimeProps = HTMLAttributes<HTMLDivElement> & {\n  time?: Date;\n  defaultTime?: Date;\n  onTimeChange?: (time: Date) => void;\n  dateFormatOptions?: Intl.DateTimeFormatOptions;\n  timeFormatOptions?: Intl.DateTimeFormatOptions;\n};\n\nexport const RelativeTime = ({\n  time: controlledTime,\n  defaultTime = new Date(),\n  onTimeChange,\n  dateFormatOptions,\n  timeFormatOptions,\n  className,\n  ...props\n}: RelativeTimeProps) => {\n  const [time, setTime] = useControllableState<Date>({\n    defaultProp: defaultTime,\n    prop: controlledTime,\n    onChange: onTimeChange,\n  });\n\n  useEffect(() => {\n    if (controlledTime) {\n      return;\n    }\n\n    const interval = setInterval(() => {\n      setTime(new Date());\n    }, 1000);\n\n    return () => clearInterval(interval);\n  }, [setTime, controlledTime]);\n\n  return (\n    <RelativeTimeContext.Provider\n      value={{\n        time: time ?? defaultTime,\n        dateFormatOptions,\n        timeFormatOptions,\n      }}\n    >\n      <div className={cn(\"grid gap-2\", className)} {...props} />\n    </RelativeTimeContext.Provider>\n  );\n};\n\nexport type RelativeTimeZoneProps = HTMLAttributes<HTMLDivElement> & {\n  zone: string;\n  dateFormatOptions?: Intl.DateTimeFormatOptions;\n  timeFormatOptions?: Intl.DateTimeFormatOptions;\n};\n\nexport type RelativeTimeZoneContextType = {\n  zone: string;\n};\n\nconst RelativeTimeZoneContext = createContext<RelativeTimeZoneContextType>({\n  zone: \"UTC\",\n});\n\nexport const RelativeTimeZone = ({\n  zone,\n  className,\n  ...props\n}: RelativeTimeZoneProps) => (\n  <RelativeTimeZoneContext.Provider value={{ zone }}>\n    <div\n      className={cn(\n        \"flex items-center justify-between gap-1.5 text-xs\",\n        className\n      )}\n      {...props}\n    />\n  </RelativeTimeZoneContext.Provider>\n);\n\nexport type RelativeTimeZoneDisplayProps = HTMLAttributes<HTMLDivElement>;\n\nexport const RelativeTimeZoneDisplay = ({\n  className,\n  ...props\n}: RelativeTimeZoneDisplayProps) => {\n  const { time, timeFormatOptions } = useContext(RelativeTimeContext);\n  const { zone } = useContext(RelativeTimeZoneContext);\n  const display = formatTime(time, zone, timeFormatOptions);\n\n  return (\n    <div\n      className={cn(\"pl-8 text-muted-foreground tabular-nums\", className)}\n      {...props}\n    >\n      {display}\n    </div>\n  );\n};\n\nexport type RelativeTimeZoneDateProps = HTMLAttributes<HTMLDivElement>;\n\nexport const RelativeTimeZoneDate = ({\n  className,\n  ...props\n}: RelativeTimeZoneDateProps) => {\n  const { time, dateFormatOptions } = useContext(RelativeTimeContext);\n  const { zone } = useContext(RelativeTimeZoneContext);\n  const display = formatDate(time, zone, dateFormatOptions);\n\n  return <div {...props}>{display}</div>;\n};\n\nexport type RelativeTimeZoneLabelProps = HTMLAttributes<HTMLDivElement>;\n\nexport const RelativeTimeZoneLabel = ({\n  className,\n  ...props\n}: RelativeTimeZoneLabelProps) => (\n  <div\n    className={cn(\n      \"flex h-4 items-center justify-center rounded-xs bg-secondary px-1.5 font-mono\",\n      className\n    )}\n    {...props}\n  />\n);\n","target":"components/kibo-ui/relative-time/index.tsx"}],"css":{}}