{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hotspot",
  "type": "registry:ui",
  "title": "Hotspot",
  "description": "Pulsing marker dots at absolute positions with hover tooltips — annotate screenshots and demos.",
  "dependencies": [
    "@saasflare/ui"
  ],
  "files": [
    {
      "path": "components/ui/hotspot.tsx",
      "type": "registry:ui",
      "content": "\"use client\"\n\n/**\n * @fileoverview Positioned tooltip hotspot markers on an image or container.\n * @author Saasflare™\n * Renders pulsing dot markers at absolute positions with tooltips on hover.\n * @module packages/ui/components/ui/hotspot\n * @package ui\n *\n * @component\n * @example\n * import { Hotspot, HotspotMarker } from '@saasflare/ui';\n * <Hotspot>\n *   <img src=\"/product.png\" alt=\"Product\" />\n *   <HotspotMarker x={30} y={45} label=\"Dashboard\" />\n *   <HotspotMarker x={70} y={60} label=\"Analytics\" />\n * </Hotspot>\n */\n\nimport * as React from \"react\"\nimport { useState, type ReactNode } from \"react\"\nimport { cn } from \"@saasflare/ui\"\nimport { useSaasflareProps, type SaasflareComponentProps } from \"@saasflare/ui\"\n\n/** Props for the Hotspot container. */\nexport interface HotspotProps\n  extends Omit<React.ComponentProps<\"div\">, keyof SaasflareComponentProps>,\n    SaasflareComponentProps {\n  /** Background content (image, illustration, etc.) plus HotspotMarker children. */\n  children: ReactNode\n  /** Additional class names. */\n  className?: string\n}\n\n/**\n * Container for positioned hotspot markers.\n *\n * @component\n * @package ui\n */\nexport function Hotspot({\n  children,\n  className,\n  surface,\n  radius,\n  animated,\n  iconWeight,\n  ...props\n}: HotspotProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n  return (\n    <div\n      {...props}\n      className={cn(\"relative\", className)}\n      data-slot=\"hotspot\"\n      data-surface={sf.surface}\n      data-radius={sf.radius}\n      data-animated={String(sf.animated)}\n    >\n      {children}\n    </div>\n  )\n}\n\n/** Props for a HotspotMarker. */\nexport interface HotspotMarkerProps\n  extends Omit<React.ComponentProps<\"div\">, \"color\" | keyof SaasflareComponentProps>,\n    SaasflareComponentProps {\n  /** Horizontal position as percentage (0–100). */\n  x: number\n  /** Vertical position as percentage (0–100). */\n  y: number\n  /** Tooltip label text. */\n  label: string\n  /** Detailed description shown in the tooltip. */\n  description?: string\n  /** Marker dot color. Default: `\"var(--primary)\"` */\n  color?: string\n  /** Additional class names. */\n  className?: string\n}\n\n/**\n * Pulsing dot marker with hover/focus tooltip at an absolute position.\n *\n * The pulse ring honors the `animated` axis (Pattern B): when animations are\n * disabled the ring stops pinging. The tooltip is reachable by keyboard (focus\n * reveals it) and associated to the trigger via `aria-describedby`.\n *\n * @component\n * @package ui\n */\nexport function HotspotMarker({\n  x,\n  y,\n  label,\n  description,\n  color = \"var(--primary)\",\n  className,\n  surface,\n  radius,\n  animated,\n  iconWeight,\n  ...props\n}: HotspotMarkerProps) {\n  const sf = useSaasflareProps({ surface, radius, animated, iconWeight })\n  const [active, setActive] = useState(false)\n  const tooltipId = React.useId()\n\n  return (\n    <div\n      {...props}\n      className={cn(\"absolute z-10\", className)}\n      style={{ left: `${x}%`, top: `${y}%`, transform: \"translate(-50%, -50%)\" }}\n      onMouseEnter={() => setActive(true)}\n      onMouseLeave={() => setActive(false)}\n      data-slot=\"hotspot-marker\"\n      data-surface={sf.surface}\n      data-radius={sf.radius}\n      data-animated={String(sf.animated)}\n    >\n      {/* Pulse ring — pinging gated on the animated axis */}\n      <div\n        className=\"absolute inset-0 rounded-full opacity-30 data-[animated=true]:animate-ping\"\n        data-animated={String(sf.animated)}\n        style={{ backgroundColor: color, width: 24, height: 24, margin: -4 }}\n        aria-hidden=\"true\"\n      />\n      {/* Dot */}\n      <button\n        type=\"button\"\n        className=\"relative size-4 rounded-full border-2 border-background shadow-md\"\n        style={{ backgroundColor: color }}\n        aria-label={label}\n        aria-describedby={description ? tooltipId : undefined}\n        onFocus={() => setActive(true)}\n        onBlur={() => setActive(false)}\n      />\n\n      {/* Tooltip */}\n      {active && (\n        <div\n          id={tooltipId}\n          role=\"tooltip\"\n          className=\"absolute bottom-full left-1/2 mb-2 -translate-x-1/2 whitespace-nowrap rounded-lg bg-popover px-3 py-2 text-sm shadow-lg\"\n        >\n          <p className=\"font-semibold text-popover-foreground\">{label}</p>\n          {description && (\n            <p className=\"mt-0.5 text-xs text-muted-foreground\">{description}</p>\n          )}\n        </div>\n      )}\n    </div>\n  )\n}\n",
      "target": "components/ui/hotspot.tsx"
    }
  ],
  "$meta": {
    "source": "https://ui.saasflare.io/r/hotspot.json"
  }
}
