{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "map-clusters-01",
  "title": "Clustered points example",
  "description": "60 illustrative points in Montréal, in clusters that zoom in until they split, composed from the Unmap map and the cluster-layer item.",
  "registryDependencies": [
    "https://registry.unmap.dev/r/map.json",
    "https://registry.unmap.dev/r/cluster-layer.json"
  ],
  "files": [
    {
      "path": "registry/blocks/map-clusters-01.tsx",
      "content": "\"use client\";\n\nimport { Map } from \"@/components/ui/map\";\nimport { ClusterLayer } from \"@/components/ui/cluster-layer\";\nimport { cn } from \"@/lib/utils\";\n\nconst COPY = {\n  en: {\n    noKey: \"Add your unmap key to load the map.\",\n    title: \"Clustered points\",\n    hint: \"Click a cluster to zoom in until it splits.\",\n    data: \"60 illustrative points across Montréal.\",\n  },\n  fr: {\n    noKey: \"Ajoutez votre clé unmap pour charger la carte.\",\n    title: \"Points regroupés\",\n    hint: \"Cliquez sur un groupe pour zoomer jusqu'à ce qu'il se sépare.\",\n    data: \"60 points illustratifs répartis dans Montréal.\",\n  },\n} as const;\n\n/** Deterministic sample points around a centre: the same 60 points on every load. */\nfunction samplePoints(center: [number, number], count: number, spread: number) {\n  let seed = 7;\n  const next = () => ((seed = (seed * 16807) % 2147483647) - 1) / 2147483646;\n  return {\n    type: \"FeatureCollection\" as const,\n    features: Array.from({ length: count }, (_, i) => ({\n      type: \"Feature\" as const,\n      id: i,\n      properties: { weight: 1 + Math.round(next() * 4) },\n      geometry: { type: \"Point\" as const, coordinates: [center[0] + (next() - 0.5) * spread, center[1] + (next() - 0.5) * spread * 0.7] },\n    })),\n  };\n}\n\n/** Illustrative data: 60 points scattered over the island of Montréal around the Plateau, not real places. */\nconst POINTS = samplePoints([-73.64, 45.52], 60, 0.09);\n\n/**\n * A minimal example: 60 illustrative points around Montréal, grouped into clusters that show how\n * many points they hold. Click a cluster and the map zooms in until it splits. Clustering happens\n * in the browser: the only requests are the map's own.\n */\nexport function MapClusters({\n  apiKey,\n  lang = \"en\",\n  className,\n}: {\n  /** Your Unmap browser key. */\n  apiKey: string;\n  /** Language of the copy and the map labels: \"en\" (default) or \"fr\". */\n  lang?: \"en\" | \"fr\";\n  className?: string;\n}) {\n  const copy = COPY[lang];\n  return (\n    <div className={cn(\"flex min-w-0 flex-col gap-3\", className)}>\n      <div role=\"region\" aria-label={copy.title} className=\"relative h-96\">\n        <Map apiKey={apiKey} center={[-73.64, 45.52]} zoom={11} lang={lang}>\n          <ClusterLayer data={POINTS} />\n        </Map>\n      </div>\n      {/* No key, no map: one line says what to add. */}\n      {apiKey.trim() === \"\" ? <p className=\"text-xs text-muted-foreground\">{copy.noKey}</p> : null}\n      <p className=\"text-sm text-muted-foreground\">\n        {copy.hint} {copy.data}\n      </p>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/unmap-map-clusters.tsx"
    }
  ],
  "docs": "Import MapClusters from your components/unmap-map-clusters file and pass apiKey (your Unmap browser key). Use lang=\"fr\" for French. Allow your site origin on the key. Preview: https://unmap.dev/templates/map-clusters",
  "categories": [
    "examples",
    "maps"
  ],
  "type": "registry:block"
}