{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "line",
  "title": "Map Line",
  "description": "Static routes and paths on the map.",
  "dependencies": ["mapbox-gl"],
  "devDependencies": ["@types/mapbox-gl"],
  "registryDependencies": ["https://www.terrae.dev/map.json"],
  "files": [
    {
      "path": "src/registry/map/line.tsx",
      "content": "\"use client\"\n\nimport type mapboxgl from \"mapbox-gl\"\n\nimport { useEffect, useId, useRef } from \"react\"\nimport { useMap } from \"./hooks\"\nimport type { MapPath } from \"./types\"\n\ntype MapLineProps = {\n  /** Array of [longitude, latitude] coordinate pairs defining the line */\n  coordinates: MapPath\n  /** Line color as CSS color value (default: \"#4285F4\") */\n  color?: string\n  /** Line width in pixels (default: 3) */\n  width?: number\n  /** Line opacity from 0 to 1 (default: 0.8) */\n  opacity?: number\n  /** Dash pattern [dash length, gap length] for dashed lines */\n  dashArray?: [number, number]\n}\n\nexport function MapLine({ coordinates, color = \"#4285F4\", width = 3, opacity = 0.8, dashArray }: MapLineProps) {\n  const { map, isLoaded } = useMap()\n  const id = useId()\n  const sourceId = `line-source-${id}`\n  const layerId = `line-layer-${id}`\n  const initializedRef = useRef(false)\n\n  useEffect(() => {\n    if (!isLoaded || !map || initializedRef.current) return\n\n    try {\n      // Create GeoJSON data\n      const geojsonData: GeoJSON.Feature<GeoJSON.LineString> = {\n        type: \"Feature\",\n        properties: {},\n        geometry: {\n          type: \"LineString\",\n          coordinates: coordinates,\n        },\n      }\n\n      // Add source\n      map.addSource(sourceId, {\n        type: \"geojson\",\n        data: geojsonData,\n      })\n\n      // Find the first symbol layer to insert the line layer before it\n      const layers = map.getStyle().layers\n      let firstSymbolId: string | undefined\n      if (layers) {\n        for (const layer of layers) {\n          if (layer.type === \"symbol\") {\n            firstSymbolId = layer.id\n            break\n          }\n        }\n      }\n\n      // Add layer\n      map.addLayer(\n        {\n          id: layerId,\n          type: \"line\",\n          source: sourceId,\n          layout: {\n            \"line-join\": \"round\",\n            \"line-cap\": \"round\",\n          },\n          paint: {\n            \"line-color\": color,\n            \"line-width\": width,\n            \"line-opacity\": opacity,\n            ...(dashArray && { \"line-dasharray\": dashArray }),\n          },\n        },\n        firstSymbolId\n      )\n\n      initializedRef.current = true\n    } catch (error) {\n      console.error(\"Error adding line layer:\", error)\n    }\n\n    return () => {\n      initializedRef.current = false\n      try {\n        if (map && map.getStyle()) {\n          if (map.getLayer(layerId)) {\n            map.removeLayer(layerId)\n          }\n          if (map.getSource(sourceId)) {\n            map.removeSource(sourceId)\n          }\n        }\n      } catch (error) {\n        console.error(\"Error removing line layer:\", error)\n      }\n    }\n  }, [isLoaded, map, sourceId, layerId, color, width, opacity, dashArray])\n\n  // Update coordinates when they change\n  useEffect(() => {\n    if (!isLoaded || !map || !initializedRef.current) return\n\n    try {\n      // Double-check map is valid and has the method\n      if (!map || !map.isStyleLoaded()) return\n\n      const source = map.getSource(sourceId)\n      if (source && \"setData\" in source && coordinates.length >= 2) {\n        ;(source as mapboxgl.GeoJSONSource).setData({\n          type: \"Feature\",\n          properties: {},\n          geometry: {\n            type: \"LineString\",\n            coordinates: coordinates,\n          },\n        })\n      }\n    } catch (error) {\n      console.error(\"Error updating line coordinates:\", error)\n    }\n  }, [isLoaded, map, coordinates, sourceId])\n\n  // Update styling when props change\n  useEffect(() => {\n    if (!isLoaded || !map || !map.isStyleLoaded() || !initializedRef.current) return\n\n    try {\n      if (map.getLayer(layerId)) {\n        map.setPaintProperty(layerId, \"line-color\", color)\n        map.setPaintProperty(layerId, \"line-width\", width)\n        map.setPaintProperty(layerId, \"line-opacity\", opacity)\n        if (dashArray) {\n          map.setPaintProperty(layerId, \"line-dasharray\", dashArray)\n        }\n      }\n    } catch (error) {\n      console.error(\"Error updating line style:\", error)\n    }\n  }, [isLoaded, map, layerId, color, width, opacity, dashArray])\n\n  return null\n}\n",
      "type": "registry:ui",
      "target": "components/ui/map/line.tsx"
    }
  ],
  "type": "registry:ui"
}
