{
  "name": "recommendation-carousel",
  "title": "RecommendationCarousel",
  "description": "Personalized product carousel powered by /activity/recommendations — frequently bought, related, trending.",
  "type": "component",
  "registryDependencies": [
    "product-card",
    "cn"
  ],
  "files": [
    {
      "path": "recommendation-carousel.tsx",
      "content": "\"use client\";\n\nimport React, { useCallback } from \"react\";\nimport type { ActivityRecommendation } from \"../activity\";\nimport { useRecommendations } from \"./hooks/use-recommendations\";\nimport { prefetchProduct } from \"./hooks/use-product\";\nimport { speculate } from \"./utils/prefetch-policy\";\nimport { useOptionalCimplifyClient } from \"@cimplify/sdk/react\";\nimport { cn } from \"@cimplify/sdk/react\";\n\nexport interface RecommendationCarouselClassNames {\n  root?: string;\n  item?: string;\n  reason?: string;\n  empty?: string;\n  loading?: string;\n}\n\nexport interface RecommendationCarouselProps {\n  /** Override recommendations (skips fetch). For SSR, pass pre-fetched data. */\n  recommendations?: ActivityRecommendation[];\n  /** Location ID for location-specific recommendations. */\n  locationId?: string;\n  /** Maximum recommendations to fetch. */\n  limit?: number;\n  /** Called when a product recommendation is clicked. */\n  onProductClick?: (recommendation: ActivityRecommendation) => void;\n  /** Custom product card renderer. */\n  renderProduct?: (recommendation: ActivityRecommendation) => React.ReactNode;\n  /** Text shown when no recommendations are available. */\n  emptyMessage?: string;\n  className?: string;\n  classNames?: RecommendationCarouselClassNames;\n}\n\n/**\n * RecommendationCarousel — displays personalized product recommendations.\n *\n * Renders a horizontal scrollable list of product cards with reason labels.\n * Returns `null` when there are no recommendations.\n */\nexport function RecommendationCarousel({\n  recommendations: recommendationsProp,\n  locationId,\n  limit,\n  onProductClick,\n  renderProduct,\n  emptyMessage,\n  className,\n  classNames,\n}: RecommendationCarouselProps): React.ReactElement | null {\n  const { recommendations: fetched, isLoading } = useRecommendations({\n    locationId,\n    limit,\n    enabled: recommendationsProp === undefined,\n  });\n\n  const recommendations = recommendationsProp ?? fetched;\n\n  const context = useOptionalCimplifyClient();\n  const warmRecommendation = useCallback(\n    (rec: ActivityRecommendation) => {\n      const productId = rec.product?.id;\n      if (!productId || !context || context.prefetch.mode === \"off\") return;\n      speculate(() => prefetchProduct(context.client, productId));\n    },\n    [context],\n  );\n\n  if (isLoading && recommendations.length === 0) {\n    return (\n      <div\n        data-cimplify-recommendation-carousel\n        aria-busy=\"true\"\n        className={cn(className, classNames?.root, classNames?.loading)}\n      />\n    );\n  }\n\n  if (recommendations.length === 0) {\n    return null;\n  }\n\n  return (\n    <div\n      data-cimplify-recommendation-carousel\n      className={cn(className, classNames?.root)}\n      style={{ display: \"flex\", overflowX: \"auto\", gap: \"1rem\" }}\n    >\n      {recommendations.map((rec, index) => {\n        const productId = rec.product?.id ?? String(index);\n        return (\n          <button\n            key={String(productId)}\n            type=\"button\"\n            onClick={() => onProductClick?.(rec)}\n            onPointerEnter={() => warmRecommendation(rec)}\n            onFocus={() => warmRecommendation(rec)}\n            data-cimplify-recommendation-item\n            className={classNames?.item}\n            style={{ flexShrink: 0 }}\n          >\n            {renderProduct ? (\n              renderProduct(rec)\n            ) : (\n              <>\n                <span data-cimplify-recommendation-name>\n                  {rec.product?.name ?? rec.product?.id ?? \"Product\"}\n                </span>\n                {rec.reason && (\n                  <span data-cimplify-recommendation-reason className={classNames?.reason}>\n                    {rec.reason}\n                  </span>\n                )}\n              </>\n            )}\n          </button>\n        );\n      })}\n    </div>\n  );\n}\n"
    }
  ]
}
