react-bkoi-gl
Version:
React components for Barikoi GL JS
95 lines • 2.82 kB
JavaScript
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