{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "world-clock-bar",
  "type": "registry:component",
  "title": "World Clock Bar",
  "description": "Multi-timezone display for follow-the-sun teams and operational handoffs.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/world-clock-bar/world-clock-bar.tsx",
      "content": "\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@vllnt/ui\";\nimport { Badge } from \"@vllnt/ui\";\n\nexport type WorldClockBarZone = {\n  city: string;\n  locale?: string;\n  timeZone: string;\n};\n\nexport type WorldClockBarProps = React.ComponentPropsWithoutRef<\"div\"> & {\n  now?: Date | number | string;\n  showDate?: boolean;\n  title?: string;\n  updateIntervalMs?: number;\n  zones: WorldClockBarZone[];\n};\n\nfunction normalizeDate(input: Date | number | string): Date {\n  if (input instanceof Date) {\n    return new Date(input.getTime());\n  }\n\n  return new Date(input);\n}\n\nfunction useLiveDate(now: WorldClockBarProps[\"now\"], updateIntervalMs: number) {\n  const fixedNow = React.useMemo(\n    () => (now ? normalizeDate(now) : undefined),\n    [now],\n  );\n  const [liveNow, setLiveNow] = React.useState<Date>(fixedNow ?? new Date());\n\n  React.useEffect(() => {\n    if (fixedNow) {\n      setLiveNow(fixedNow);\n      return;\n    }\n\n    const interval = window.setInterval(() => {\n      setLiveNow(new Date());\n    }, updateIntervalMs);\n\n    return () => {\n      window.clearInterval(interval);\n    };\n  }, [fixedNow, updateIntervalMs]);\n\n  return liveNow;\n}\n\nconst TIME_FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>();\nfunction getTimeFormatter(\n  locale: string,\n  timeZone: string,\n): Intl.DateTimeFormat {\n  const key = `${locale}|${timeZone}`;\n  let formatter = TIME_FORMATTER_CACHE.get(key);\n  if (!formatter) {\n    formatter = new Intl.DateTimeFormat(locale, {\n      hour: \"numeric\",\n      minute: \"2-digit\",\n      timeZone,\n      timeZoneName: \"short\",\n    });\n    TIME_FORMATTER_CACHE.set(key, formatter);\n  }\n  return formatter;\n}\n\nconst DATE_FORMATTER_CACHE = new Map<string, Intl.DateTimeFormat>();\nfunction getDateFormatter(\n  locale: string,\n  timeZone: string,\n): Intl.DateTimeFormat {\n  const key = `${locale}|${timeZone}`;\n  let formatter = DATE_FORMATTER_CACHE.get(key);\n  if (!formatter) {\n    formatter = new Intl.DateTimeFormat(locale, {\n      day: \"numeric\",\n      month: \"short\",\n      timeZone,\n      weekday: \"short\",\n    });\n    DATE_FORMATTER_CACHE.set(key, formatter);\n  }\n  return formatter;\n}\n\nfunction formatZoneDateTime(\n  zone: WorldClockBarZone,\n  date: Date,\n  showDate: boolean,\n) {\n  const locale = zone.locale ?? \"en-US\";\n  const timeFormatter = getTimeFormatter(locale, zone.timeZone);\n  const dateFormatter = getDateFormatter(locale, zone.timeZone);\n\n  return {\n    date: showDate ? dateFormatter.format(date) : \"\",\n    time: timeFormatter.format(date),\n  };\n}\n\nfunction WorldClockCard({\n  date,\n  showDate,\n  zone,\n}: {\n  date: Date;\n  showDate: boolean;\n  zone: WorldClockBarZone;\n}) {\n  const formatted = formatZoneDateTime(zone, date, showDate);\n\n  return (\n    <div className=\"min-w-[190px] rounded-lg border bg-card px-4 py-3 shadow-sm\">\n      <div className=\"text-sm font-medium\">{zone.city}</div>\n      <div className=\"mt-1 text-2xl font-semibold tracking-tight\">\n        {formatted.time}\n      </div>\n      {showDate ? (\n        <div className=\"mt-1 text-xs text-muted-foreground\">\n          {formatted.date}\n        </div>\n      ) : null}\n      <div className=\"mt-3 text-[11px] uppercase tracking-[0.16em] text-muted-foreground\">\n        {zone.timeZone}\n      </div>\n    </div>\n  );\n}\n\nexport const WorldClockBar = React.forwardRef<\n  HTMLDivElement,\n  WorldClockBarProps\n>(\n  (\n    {\n      className,\n      now,\n      showDate = true,\n      title = \"World clock\",\n      updateIntervalMs = 60_000,\n      zones,\n      ...props\n    },\n    ref,\n  ) => {\n    const liveNow = useLiveDate(now, updateIntervalMs);\n\n    return (\n      <div className={cn(\"space-y-3\", className)} ref={ref} {...props}>\n        <div className=\"flex items-center justify-between gap-3\">\n          <div>\n            <h2 className=\"text-lg font-semibold tracking-tight\">{title}</h2>\n            <p className=\"text-sm text-muted-foreground\">\n              Synchronized time across distributed teams and regions.\n            </p>\n          </div>\n          <Badge variant=\"outline\">{zones.length} zones</Badge>\n        </div>\n\n        <div className=\"flex gap-3 overflow-x-auto pb-1\">\n          {zones.map((zone) => (\n            <WorldClockCard\n              date={liveNow}\n              key={`${zone.city}-${zone.timeZone}`}\n              showDate={showDate}\n              zone={zone}\n            />\n          ))}\n        </div>\n      </div>\n    );\n  },\n);\n\nWorldClockBar.displayName = \"WorldClockBar\";\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
