{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "live-cursor",
  "title": "Live Cursor",
  "description": "Remote user's cursor rendered at canvas coordinates with name + status chip.",
  "dependencies": [
    "@vllnt/ui@^0.3.0"
  ],
  "registryDependencies": [],
  "files": [
    {
      "path": "registry/default/live-cursor/live-cursor.tsx",
      "content": "\"use client\";\n\nimport type { ComponentPropsWithoutRef, ReactNode } from \"react\";\n\nimport { cn } from \"@vllnt/ui\";\n\n/**\n * Localizable strings.\n *\n * @public\n */\nexport type LiveCursorLabels = {\n  /** Aria-label override. Defaults to `\"Live cursor\"`. */\n  region?: string;\n};\n\nconst DEFAULT_LABELS = {\n  region: \"Live cursor\",\n} as const satisfies Required<LiveCursorLabels>;\n\n/**\n * Props for {@link LiveCursor}.\n *\n * @public\n */\nexport type LiveCursorProps = {\n  /** Tailwind / arbitrary CSS color used for the pointer + name chip. Defaults to `var(--foreground)`. */\n  color?: string;\n  /** Localizable strings. */\n  labels?: LiveCursorLabels;\n  /** Display name shown in the chip. Pass `null` to hide the chip. */\n  name?: ReactNode;\n  /** Optional secondary line in the chip (e.g. status, role). */\n  status?: ReactNode;\n  /** Cursor X in canvas pixels. */\n  x: number;\n  /** Cursor Y in canvas pixels. */\n  y: number;\n} & ComponentPropsWithoutRef<\"div\">;\n\n/**\n * Remote user's cursor rendered at canvas coordinates with an optional\n * name + status chip. Pure presentation; the host owns the websocket\n * stream + maps user ids to colors.\n *\n * The wrapper is `pointer-events: none` so host gestures pass through.\n *\n * @example\n * ```tsx\n * <div className=\"relative h-screen w-screen\">\n *   <Canvas />\n *   <LiveCursor x={420} y={180} name=\"Bea\" color=\"#5b8def\" />\n * </div>\n * ```\n *\n * @public\n */\nexport const LiveCursor = ({\n  ref,\n  ...props\n}: LiveCursorProps & { ref?: React.Ref<HTMLDivElement> }) => {\n  const { className, color, labels, name, status, x, y, ...rest } = props;\n  const resolvedLabels = { ...DEFAULT_LABELS, ...labels };\n  const resolvedColor = color ?? \"var(--foreground)\";\n  return (\n    <div\n      aria-label={\n        typeof name === \"string\"\n          ? `${resolvedLabels.region}: ${name}`\n          : resolvedLabels.region\n      }\n      className={cn(\n        \"pointer-events-none absolute z-30 flex items-start gap-1\",\n        className,\n      )}\n      data-live-cursor\n      ref={ref}\n      role=\"img\"\n      style={{ left: x, top: y }}\n      {...rest}\n    >\n      <svg\n        aria-hidden=\"true\"\n        className=\"-ml-1 -mt-1 drop-shadow-sm\"\n        data-live-cursor-pointer\n        fill={resolvedColor}\n        height={18}\n        viewBox=\"0 0 16 18\"\n        width={16}\n      >\n        <path d=\"M0 0 L0 14 L4 11 L7 17 L10 16 L7 10 L13 10 Z\" />\n      </svg>\n      {name === null || name === undefined ? null : (\n        <span\n          className=\"ml-2 mt-2 inline-flex flex-col rounded-md px-1.5 py-0.5 text-[10px] font-medium text-white shadow-sm\"\n          data-live-cursor-chip\n          style={{ backgroundColor: resolvedColor }}\n        >\n          <span>{name}</span>\n          {status ? (\n            <span className=\"text-[9px] opacity-80\" data-live-cursor-status>\n              {status}\n            </span>\n          ) : null}\n        </span>\n      )}\n    </div>\n  );\n};\nLiveCursor.displayName = \"LiveCursor\";\n",
      "type": "registry:component"
    }
  ],
  "type": "registry:component",
  "version": "0.3.0",
  "stability": "stable"
}
