{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "presence-sync-indicator",
  "type": "registry:component",
  "title": "Presence Sync Indicator",
  "description": "Compact pill that surfaces live connection + sync health for a collaborative canvas.",
  "dependencies": [
    "@vllnt/ui@^0.2.1"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/presence-sync-indicator/presence-sync-indicator.tsx",
      "content": "\"use client\";\n\nimport {\n  type ComponentPropsWithoutRef,\n  forwardRef,\n  type ReactNode,\n} from \"react\";\n\nimport { cn } from \"@vllnt/ui\";\n\n/**\n * Connection / sync state — drives the dot color + animation.\n *\n * @public\n */\nexport type PresenceSyncState =\n  | \"error\"\n  | \"live\"\n  | \"offline\"\n  | \"reconnecting\"\n  | \"syncing\";\n\nconst STATE_LABEL: Record<PresenceSyncState, string> = {\n  error: \"Sync error\",\n  live: \"Live\",\n  offline: \"Offline\",\n  reconnecting: \"Reconnecting\",\n  syncing: \"Syncing\",\n};\n\nconst STATE_DOT: Record<PresenceSyncState, string> = {\n  error: \"bg-red-500\",\n  live: \"bg-emerald-500\",\n  offline: \"bg-muted-foreground\",\n  reconnecting: \"bg-amber-500 animate-pulse\",\n  syncing: \"bg-blue-500 animate-pulse\",\n};\n\nconst STATE_TEXT: Record<PresenceSyncState, string> = {\n  error: \"text-red-700 dark:text-red-300\",\n  live: \"text-emerald-700 dark:text-emerald-300\",\n  offline: \"text-muted-foreground\",\n  reconnecting: \"text-amber-700 dark:text-amber-300\",\n  syncing: \"text-blue-700 dark:text-blue-300\",\n};\n\n/**\n * Localizable strings.\n *\n * @public\n */\nexport type PresenceSyncIndicatorLabels = {\n  /** Aria-label override. Defaults to `\"Presence sync\"`. */\n  region?: string;\n};\n\nconst DEFAULT_LABELS = {\n  region: \"Presence sync\",\n} as const satisfies Required<PresenceSyncIndicatorLabels>;\n\n/**\n * Props for {@link PresenceSyncIndicator}.\n *\n * @public\n */\nexport type PresenceSyncIndicatorProps = {\n  /** Optional override label (defaults to humanized state name). */\n  label?: ReactNode;\n  /** Localizable strings. */\n  labels?: PresenceSyncIndicatorLabels;\n  /** Connection state. */\n  state: PresenceSyncState;\n  /** Optional secondary line (peer count, latency). */\n  status?: ReactNode;\n} & ComponentPropsWithoutRef<\"div\">;\n\n/**\n * Compact pill that surfaces live connection + sync health for the\n * canvas. Stays calm: a single dot + one-line label, with a subtle\n * pulse for transient `syncing` / `reconnecting` states.\n *\n * Pure presentation; the host owns the websocket / CRDT loop and maps\n * its diagnostics into one of five canonical states.\n *\n * @example\n * ```tsx\n * <PresenceSyncIndicator state=\"live\" status=\"3 peers\" />\n * <PresenceSyncIndicator state=\"reconnecting\" status=\"retry 2/5\" />\n * ```\n *\n * @public\n */\nexport const PresenceSyncIndicator = forwardRef<\n  HTMLDivElement,\n  PresenceSyncIndicatorProps\n>((props, ref) => {\n  const { className, label, labels, state, status, ...rest } = props;\n  const resolvedLabels = { ...DEFAULT_LABELS, ...labels };\n  const text = label ?? STATE_LABEL[state];\n  return (\n    <div\n      aria-label={`${resolvedLabels.region}: ${STATE_LABEL[state]}`}\n      className={cn(\n        \"inline-flex items-center gap-1.5 rounded-full border border-border bg-background px-2 py-1 text-[11px] shadow-sm\",\n        className,\n      )}\n      data-presence-state={state}\n      data-presence-sync\n      ref={ref}\n      role=\"status\"\n      {...rest}\n    >\n      <span\n        aria-hidden=\"true\"\n        className={cn(\"size-1.5 rounded-full\", STATE_DOT[state])}\n        data-presence-sync-dot\n      />\n      <span className={cn(\"font-medium\", STATE_TEXT[state])}>{text}</span>\n      {status ? (\n        <span\n          className=\"text-[10px] text-muted-foreground\"\n          data-presence-sync-status\n        >\n          {status}\n        </span>\n      ) : null}\n    </div>\n  );\n});\nPresenceSyncIndicator.displayName = \"PresenceSyncIndicator\";\n",
      "type": "registry:component"
    }
  ],
  "version": "0.2.1",
  "stability": "stable"
}
