UNPKG

react-bkoi-gl

Version:

React components for Barikoi GL JS

95 lines 2.82 kB
import * as React from "react"; import { useContext, useEffect, useMemo, useState, useRef, cloneElement } from "react"; import { MapContext } from "./map.js"; import assert from "../utils/assert.js"; import { deepEqual } from "../utils/deep-equal.js"; let sourceCounter = 0; function createSource(map, id, props) { if (map.style && map.style._loaded) { const options = { ...props }; delete options.id; delete options.children; map.addSource(id, options); return map.getSource(id); } return null; } function updateSource(source, props, prevProps) { assert(props.id === prevProps.id, "source id changed"); assert(props.type === prevProps.type, "source type changed"); let changedKey = ""; let changedKeyCount = 0; for (const key in props) { if (key !== "children" && key !== "id" && !deepEqual(prevProps[key], props[key])) { changedKey = key; changedKeyCount++; } } if (!changedKeyCount) { return; } const type = props.type; if (type === "geojson") { source.setData(props.data); } else if (type === "image") { source.updateImage({ url: props.url, coordinates: props.coordinates }); } else { switch (changedKey) { case "coordinates": source.setCoordinates?.(props.coordinates); break; case "url": source.setUrl?.(props.url); break; case "tiles": source.setTiles?.(props.tiles); break; default: console.warn(`Unable to update <Source> prop: ${changedKey}`); } } } export function Source(props) { const map = useContext(MapContext).map.getMap(); const propsRef = useRef(props); const [, setStyleLoaded] = useState(0); const id = useMemo(() => props.id || `jsx-source-${sourceCounter++}`, []); useEffect(() => { if (map) { const forceUpdate = () => setTimeout(() => setStyleLoaded(version => version + 1), 0); map.on("styledata", forceUpdate); forceUpdate(); return () => { map.off("styledata", forceUpdate); if (map.style && map.style._loaded && map.getSource(id)) { const allLayers = map.getStyle()?.layers; if (allLayers) { for (const layer of allLayers) { if (layer.source === id) { map.removeLayer(layer.id); } } } map.removeSource(id); } }; } return undefined; }, [map]); let source = map && map.style && map.getSource(id); if (source) { updateSource(source, props, propsRef.current); } else { source = createSource(map, id, props); } propsRef.current = props; return source && React.Children.map(props.children, child => child && cloneElement(child, { source: id })) || null; } //# sourceMappingURL=source.js.map