import { createCommentVNode, defineComponent, inject, isRef, type PropType, provide, type SlotsType, watch, } from "vue"; import { componentIdSymbol, sourceIdSymbol, sourceLayerRegistry, SourceOptionProps, } from "@/lib/types"; import type { PromoteIdSpecification, VectorTileSource } from "maplibre-gl"; import { SourceLayerRegistry } from "@/lib/lib/sourceLayer.registry"; import { SourceLib } from "@/lib/lib/source.lib"; import { useSource } from "@/lib/composable/useSource"; /** * See [VectorTileSource](https://maplibre.org/maplibre-gl-js/docs/API/classes/VectorTileSource/) */ export default defineComponent({ name: "MglVectorSource", props: { sourceId: { type: String as PropType, required: true, }, url: String as PropType, tiles: Array as PropType, bounds: { type: Array as PropType, validator: function (v: number[]) { return v.length === 4; }, }, scheme: String as PropType<"xyz" | "tms">, minzoom: Number as PropType, maxzoom: Number as PropType, attribution: String as PropType, promoteId: [Object, String] as PropType, volatile: Boolean as PropType, }, slots: Object as SlotsType<{ default: unknown }>, setup(props, { slots }) { const cid = inject(componentIdSymbol)!, source = SourceLib.getSourceRef(cid, props.sourceId), registry = new SourceLayerRegistry(), opts = { ...props, type: "vector" }; provide(sourceIdSymbol, props.sourceId); provide(sourceLayerRegistry, registry); useSource(source, opts as SourceOptionProps, registry); watch( [isRef(props.tiles) ? props.tiles : () => props.tiles, source], ([v, src]) => { src?.setTiles((v as string[]) || []); }, { immediate: true }, ); watch( [isRef(props.url) ? props.url : () => props.url, source], ([v, src]) => { src?.setUrl((v as string) || ""); }, { immediate: true }, ); return () => [ createCommentVNode("Vector Source"), source.value && slots.default ? slots.default({}) : undefined, ]; }, });