import { createCommentVNode, getCurrentInstance, inject, warn, watch, } from "vue"; import { componentIdSymbol, isLoadedSymbol, mapSymbol, sourceIdSymbol, } from "@/lib/types"; import { useDisposableLayer } from "@/lib/composable/useDisposableLayer"; import { genLayerOpts, registerLayerEvents, type LayersWithSource, type LayerProps, } from "@/lib/lib/layer.lib"; import { SourceLib } from "@/lib/lib/source.lib"; export function useLayer( name: string, props: LayerProps, ) { const sourceId = inject(sourceIdSymbol); if (!sourceId && !props.source) { warn( `${name} Layer: layer must be used inside source tag or source prop must be set`, ); return; } const ci = getCurrentInstance()!, map = inject(mapSymbol)!, isLoaded = inject(isLoadedSymbol)!, cid = inject(componentIdSymbol)!, sourceRef = SourceLib.getSourceRef(cid, props.source || sourceId); useDisposableLayer(props.layerId!, ci); watch( () => props.minzoom, () => map.value!.setLayerZoomRange( props.layerId!, props.minzoom || 0, props.maxzoom || 24, ), ); watch( () => props.maxzoom, () => map.value!.setLayerZoomRange( props.layerId!, props.minzoom || 0, props.maxzoom || 24, ), ); watch( () => props.layout, (layout) => { if (layout) { for (const [property, value] of Object.entries(layout)) { map.value!.setLayoutProperty(props.layerId!, property, value); } } }, { deep: true }, ); watch( () => props.paint, (paint) => { if (paint) { for (const [property, value] of Object.entries(paint)) { map.value!.setPaintProperty(props.layerId!, property, value); } } }, { deep: true }, ); watch( () => props.filter, (f) => map.value!.setFilter(props.layerId!, f), { deep: true }, ); watch( [isLoaded, sourceRef], ([il, src]) => { if (il && (src || src === undefined)) { map.value!.addLayer( genLayerOpts(props.layerId!, name, props, sourceId), props.before || undefined, ); registerLayerEvents(map.value!, props.layerId!, ci.vnode); } }, { immediate: true }, ); return () => createCommentVNode(`${name} Layer`); }