{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "map-elevation-01",
  "title": "Trail elevation profile example",
  "description": "The elevation profile of a sample trail up Tunnel Mountain in Banff, linked to the map on hover, composed from the Unmap map and the geojson-layer and elevation-profile items.",
  "registryDependencies": [
    "https://registry.unmap.dev/r/map.json",
    "https://registry.unmap.dev/r/geojson-layer.json",
    "https://registry.unmap.dev/r/elevation-profile.json"
  ],
  "files": [
    {
      "path": "registry/blocks/map-elevation-01.tsx",
      "content": "\"use client\";\n\nimport { useState, type ReactNode } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Map } from \"@/components/ui/map\";\nimport { GeoJSONLayer } from \"@/components/ui/geojson-layer\";\nimport { ElevationProfile, formatElevation, type ElevationProfileData } from \"@/components/ui/elevation-profile\";\nimport { cn } from \"@/lib/utils\";\n\nconst COPY = {\n  en: {\n    noKey: \"Add your unmap key to load the map.\",\n    title: \"Trail elevation profile\",\n    hint: \"Hover the chart to find that point on the trail. Heights from the unmap elevation API.\",\n    result: (climb: string) => `${climb} of climb.`,\n  },\n  fr: {\n    noKey: \"Ajoutez votre clé unmap pour charger la carte.\",\n    title: \"Profil d'altitude d'un sentier\",\n    hint: \"Survolez le graphique pour trouver ce point sur le sentier. Altitudes de l'API d'élévation unmap.\",\n    result: (climb: string) => `${climb} de montée.`,\n  },\n} as const;\n\n/**\n * Sample data, not a surveyed trail: six vertices that climb Tunnel Mountain in Banff from the\n * St. Julien Road side to the summit ridge, a steady 250 m or so, without every switchback.\n */\nconst TRAIL: [number, number][] = [\n  [-115.5645, 51.1733],\n  [-115.5618, 51.1744],\n  [-115.56, 51.1756],\n  [-115.5584, 51.1764],\n  [-115.5566, 51.1771],\n  [-115.5551, 51.1776],\n];\n\nconst TRAIL_LINE = {\n  type: \"Feature\" as const,\n  properties: {},\n  geometry: { type: \"LineString\" as const, coordinates: TRAIL },\n};\n\n/**\n * Renders `children` into `slot`, below the map, while keeping them inside `<Map>`'s React tree\n * (a portal keeps context), so the chart answers the map without covering it.\n */\nfunction BelowMap({ slot, children }: { slot: HTMLElement | null; children: ReactNode }) {\n  return slot ? createPortal(children, slot) : null;\n}\n\n/**\n * A minimal example: a sample trail up Tunnel Mountain on an outdoor map of Banff, with its\n * elevation profile below. Hover the chart and a marker finds that point on the trail; hover the\n * trail and the chart follows. The trail never changes, so it makes one /elevation request when\n * it mounts.\n */\nexport function MapElevation({\n  apiKey,\n  lang = \"en\",\n  className,\n}: {\n  /** Your Unmap browser key. */\n  apiKey: string;\n  /** Language of the copy, the chart and the map labels: \"en\" (default) or \"fr\". */\n  lang?: \"en\" | \"fr\";\n  className?: string;\n}) {\n  const copy = COPY[lang];\n  const [slot, setSlot] = useState<HTMLDivElement | null>(null);\n  const [profile, setProfile] = useState<ElevationProfileData | null>(null);\n  const climb = profile?.stats ? formatElevation(profile.stats.gain, lang) : null;\n\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-80\">\n        <Map apiKey={apiKey} style=\"outdoor\" center={[-115.5598, 51.1755]} zoom={13.75} lang={lang}>\n          <GeoJSONLayer data={TRAIL_LINE} />\n          <BelowMap slot={slot}>\n            <ElevationProfile apiKey={apiKey} line={TRAIL} lang={lang} onProfile={setProfile} />\n          </BelowMap>\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      {/* No live region: the profile announces its distance and climb itself. */}\n      <p className=\"text-sm text-muted-foreground tabular-nums\">\n        {climb && <span className=\"font-medium text-foreground\">{copy.result(climb)} </span>}\n        {copy.hint}\n      </p>\n      <div ref={setSlot} className=\"@container min-w-0\" />\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "@components/unmap-map-elevation.tsx"
    }
  ],
  "docs": "Import MapElevation from your components/unmap-map-elevation file and pass apiKey (your Unmap browser key). Use lang=\"fr\" for French. Allow your site origin on the key. Makes one /elevation request when it mounts. Preview: https://unmap.dev/templates/map-elevation",
  "categories": [
    "examples",
    "maps"
  ],
  "type": "registry:block"
}