UNPKG

vue-yandex-maps

Version:
1,855 lines (1,854 loc) 91.3 kB
import { t as throwException, g as getException, c as createYmapsOptions, i as initYmaps, V as VueYandexMaps, s as setFragment, a as copy, e as excludeKeys, h as hVue2, b as hF, d as getAttrsForVueVersion, f as sleep, j as isVue2, k as importYmapsCDNModule } from "./vue-yandex-maps-BL2NZ0tm.js"; import { getCurrentInstance, watch, inject, isRef, defineComponent, shallowRef, ref, provide, computed, nextTick, onMounted, onBeforeUnmount, h, onUpdated, triggerRef } from "vue"; import './vue-yandex-maps.css';function applyModifier(coords, modifier) { const result = { x: 0, y: 0 }; result.x = coords.x * modifier; result.y = coords.y * modifier; return result; } function applyFunctionModifier(coords, functionModifier) { const result = { x: 0, y: 0 }; result.x = functionModifier(coords.x, 1); result.y = functionModifier(coords.y, 2); return result; } function worldToPixels(coords, modifier) { const i = 2 ** modifier / 2 * 256; return applyModifier({ x: coords.x + 1, y: 1 - coords.y }, i); } function convertWorldCoordinates(projection, coordinates, modifier) { const worldCoordinates = projection.toWorldCoordinates(coordinates); return worldToPixels(worldCoordinates, modifier); } function pixelsToWorld(coords, modifier) { const i = 2 ** modifier / 2 * 256; return { x: coords.x / i - 1, y: 1 - coords.y / i }; } function findNeededValue(t, e, i) { return Math.max(Math.min(t, i), e); } function worldCoordsFromModifier(projection, coords, modifier) { const resultCoords = applyFunctionModifier(pixelsToWorld(coords, modifier), ((value) => findNeededValue(value, -1, 1 - 1e-15))); return projection.fromWorldCoordinates(resultCoords); } function convertBounds(projection, bounds, modifier) { const topLeft = convertWorldCoordinates(projection, bounds[0], modifier); const bottomRight = convertWorldCoordinates(projection, bounds[1], modifier); const modified = 2 ** modifier * 256; const updatedBounds = [[topLeft.x, topLeft.y], [bottomRight.x, bottomRight.y]]; if (topLeft.x > bottomRight.x) { updatedBounds[0][0] = topLeft.x; updatedBounds[1][0] = bottomRight.x + modified; } if (topLeft.y > bottomRight.y) { updatedBounds[0][1] = bottomRight.y; updatedBounds[1][1] = topLeft.y; } return updatedBounds; } function applyMarginToCoords(coords, margin) { return { x: Math.max(coords.x - (margin ? margin[1] + margin[3] : 0), 1), y: Math.max(coords.y - (margin ? margin[0] + margin[2] : 0), 1) }; } function findZoom(projection, bounds, coords, isSnap, zoomRange) { const [[topLeftFirst, topLeftSecond], [bottomRightFirst, bottomRightSecond]] = convertBounds(projection, bounds, 0); const firstCalc = Math.max(Math.abs(bottomRightFirst - topLeftFirst), 1e-10); const secondCalc = Math.max(Math.abs(bottomRightSecond - topLeftSecond), 1e-10); const zoom = findNeededValue(Math.min(Math.log2(coords.x / firstCalc), Math.log2(coords.y / secondCalc)), zoomRange.min, zoomRange.max); return isSnap ? Math.floor(zoom + 1e-6) : zoom; } function findCenter(projection, bounds, zoom) { const [[topLeftFirst, topLeftSecond], [bottomRightFirst, bottomRightSecond]] = convertBounds(projection, bounds, zoom); return worldCoordsFromModifier(projection, { x: (topLeftFirst + bottomRightFirst) / 2, y: (topLeftSecond + bottomRightSecond) / 2 }, zoom); } async function getLocationFromBounds({ bounds, map, roundZoom, comfortZoomLevel }) { const ctxMap = Object.keys(map).find((x) => x.endsWith("CtxMap")); if (!ctxMap) { throwException({ text: "CtxMap was not found in useYMapsGetCenterAndZoomFromBounds", isInternal: true }); } const ctx = map[ctxMap]; const mapZoom = map.zoom; const ctxItem = await new Promise((resolve, reject) => { ctx.forEach((item, { name }) => { if (name !== "map") return; resolve(item); }); reject(getException({ text: "Map item was not found in useYMapsGetCenterAndZoomFromBounds", isInternal: true })); }); const ctxItemMapKey = Object.keys(ctxItem).find((x) => x.endsWith("_context")); if (!ctxItemMapKey) { throwException({ text: "CtxMapKey was not found in useYMapsGetCenterAndZoomFromBounds", isInternal: true }); } const ctxItemMap = ctxItem[ctxItemMapKey].map; const projection = ctxItemMap.projection; const size = ctxItemMap.size; const margin = ctxItemMap.margin; const isSnap = ctxItemMap.effectiveZoomRounding === "snap"; const zoomRange = ctxItemMap.zoomRange; let zoom = findZoom(projection, bounds, applyMarginToCoords(size, margin), isSnap, zoomRange); const center = findCenter(projection, bounds, zoom); if (roundZoom || comfortZoomLevel) { const originalZoom = zoom; let roundedZoom = Math[typeof roundZoom === "string" ? roundZoom : "floor"](zoom); if (roundZoom) zoom = roundedZoom; if (comfortZoomLevel) { const userSettings = typeof comfortZoomLevel === "object" ? comfortZoomLevel : {}; if (userSettings.roundStrategy) roundedZoom = Math[userSettings.roundStrategy](originalZoom); const diff2 = originalZoom - roundedZoom; const settings = { diff: 0.5, correction: 1, ...userSettings }; if (diff2 < settings.diff) { zoom -= settings.correction; } if (zoom <= mapZoom) { zoom = originalZoom; } } } return { zoom, center }; } const useYMapsLocationFromBounds = getLocationFromBounds; function getCenterFromCoords(coordinates) { if (coordinates.length === 1) return coordinates[0]; if (!coordinates.length) { throwException({ text: "Invalid parameters in getCenterFromCoords: you must pass at least one LngLat" }); } const sum = coordinates.reduce(([accLng, accLat], [lng, lat]) => [ accLng + lng, accLat + lat ], [0, 0]); return [ sum[0] / coordinates.length, sum[1] / coordinates.length ]; } function getBoundsFromCoords(coordinates) { if (coordinates.length < 2) { throwException({ text: "Invalid parameters in getBoundsFromCoords: you must pass at least two LngLat" }); } const { minLongitude, minLatitude, maxLongitude, maxLatitude } = coordinates.reduce( (acc, [longitude, latitude]) => ({ minLongitude: Math.min(acc.minLongitude, longitude), minLatitude: Math.min(acc.minLatitude, latitude), maxLongitude: Math.max(acc.maxLongitude, longitude), maxLatitude: Math.max(acc.maxLatitude, latitude) }), { minLongitude: Infinity, minLatitude: Infinity, maxLongitude: -Infinity, maxLatitude: -Infinity } ); return [[minLongitude, minLatitude], [maxLongitude, maxLatitude]]; } function createYmaps(settings) { return { install(app) { createYmapsOptions(settings); if (settings.initializeOn === "onPluginInit") { initYmaps().catch(console.error); } } }; } function createYmapsVue2(settings) { return { install(Vue) { createYmapsOptions(settings); if (settings.initializeOn === "onPluginInit") { initYmaps().catch(console.error); } } }; } const isDate = (d) => d instanceof Date; const isEmpty = (o) => Object.keys(o).length === 0; const isObject = (o) => o != null && typeof o === "object"; const hasOwnProperty = (o, ...args) => Object.prototype.hasOwnProperty.call(o, ...args); const isEmptyObject = (o) => isObject(o) && isEmpty(o); const makeObjectWithoutPrototype = () => /* @__PURE__ */ Object.create(null); const diff = (lhs, rhs) => { if (lhs === rhs) return {}; if (!isObject(lhs) || !isObject(rhs)) return rhs; const deletedValues = Object.keys(lhs).reduce((acc, key) => { if (!hasOwnProperty(rhs, key)) { acc[key] = void 0; } return acc; }, makeObjectWithoutPrototype()); if (isDate(lhs) || isDate(rhs)) { if (lhs.valueOf() == rhs.valueOf()) return {}; return rhs; } return Object.keys(rhs).reduce((acc, key) => { if (!hasOwnProperty(lhs, key)) { acc[key] = rhs[key]; return acc; } const difference = diff(lhs[key], rhs[key]); if (isEmptyObject(difference) && !isDate(difference) && (isEmptyObject(lhs[key]) || !isEmptyObject(rhs[key]))) return acc; acc[key] = difference; return acc; }, deletedValues); }; function injectMap() { if (!getCurrentInstance()) { throwException({ text: "injectMap must be only called on runtime.", isInternal: true }); } const map = inject("map"); if (!map || !isRef(map)) { throwException({ text: "Was not able to inject valid map in injectMap.", isInternal: true }); } return map; } function injectLayers() { if (!getCurrentInstance()) { throwException({ text: "injectLayers must be only called on runtime.", isInternal: true }); } const layers = inject("layers"); if (!layers || !isRef(layers)) { throwException({ text: "Was not able to inject valid layers in injectLayers.", isInternal: true }); } return layers; } async function waitTillYmapInit({ timeoutCallback, waitDuration } = {}) { if (typeof window === "undefined") { throwException({ text: "waitTillYmapInit cannot be called on SSR.", isInternal: true }); } if (typeof ymaps3 !== "undefined") return; return new Promise((resolve, reject) => { if (typeof ymaps3 === "undefined") { let timeout; waitDuration = typeof waitDuration !== "undefined" ? waitDuration : VueYandexMaps.settings.value.mapsScriptWaitDuration; if (waitDuration !== false) { timeout = setTimeout(() => { timeoutCallback?.(timeout, true); reject(new VueYandexMaps.YandexMapException("Was not able to wait for map initialization in waitTillYmapInit. Ensure that map was initialized. You can change this behavior by using mapsScriptWaitDuration.")); }, typeof waitDuration === "number" ? waitDuration : 5e3); timeoutCallback?.(timeout, false); } watch(VueYandexMaps.isLoaded, () => { if (timeout) { clearTimeout(timeout); timeoutCallback?.(timeout, true); } if (VueYandexMaps.loadStatus.value === "loaded") { resolve(); } else { reject(VueYandexMaps.loadError); } }, { immediate: true }); } else { resolve(); } }); } async function waitTillMapInit({ map: _map, timeoutCallback, waitDuration } = {}) { if (!_map && !getCurrentInstance()) { throwException({ text: "onMapInit must be only called on runtime.", isInternal: true }); } if (typeof window === "undefined") { throwException({ text: "waitTillMapInit cannot be called on SSR.", isInternal: true }); } const map = _map || injectMap(); if (map.value) return; return new Promise((resolve, reject) => { let timeout; waitDuration = typeof waitDuration !== "undefined" ? waitDuration : VueYandexMaps.settings.value.mapsRenderWaitDuration; if (waitDuration !== false) { timeout = setTimeout(() => { timeoutCallback?.(timeout, true); reject(new VueYandexMaps.YandexMapException("Was not able to wait for map initialization in waitTillMapInit. You can change this behavior by using mapsRenderWaitDuration.")); }, typeof waitDuration === "number" ? waitDuration : 5e3); timeoutCallback?.(timeout, false); } let watcher; watcher = watch(map, () => { if (map.value) { watcher?.(); if (timeout) { clearTimeout(timeout); timeoutCallback?.(timeout, true); } resolve(); } }, { immediate: true }); }); } function deleteMapChild({ children, isMercator, root }) { if (!root) { throwException({ text: "Failed to execute deleteMapChild due to destroyed root", isInternal: true }); } if (children && !isMercator) { if (typeof root?.value === "object" && Array.isArray(root.value)) { root.value = root.value.filter((x) => x !== children); } else { root.value?.removeChild(children); } } else if (root.value && children && isMercator && "update" in root.value) { root.value.update({ projection: void 0 }); } } const _sfc_main$G = defineComponent({ name: "YandexMap", props: { modelValue: { type: Object, default: null }, value: { type: Object, default: null }, tag: { type: String, default: "div" }, width: { type: String, default: "100%" }, height: { type: String, default: "100%" }, // z-index for Map Container. Without this, elements of the map will be displayed under your site's elements due to high z-index inside of them zIndex: { type: Number, default: 0 }, /** * @description Settings for cart initialization., * * You can modify this object or use map methods, such as setLocation/setBehaviors e.t.c. * @see https://yandex.ru/dev/maps/jsapi/doc/3.0/dg/concepts/map.html#map-parms * @see https://yandex.com/dev/maps/jsapi/doc/3.0/dg/concepts/map.html#map-parms */ settings: { type: Object, required: true }, /** * @description Makes settings readonly. Enable this if reactivity causes problems */ readonlySettings: { type: Boolean, default: false }, /** * @description Always inserts actual user center or bounds (based on your input) on every location change * @note This prop will cause user location change on every settings update (if user did move since last time). Use it with caution. */ realSettingsLocation: { type: Boolean, default: false }, /** * @description You can also add layers through <yandex-*> components * * Modifying this object after mount will cause no effect. * * Instead, please use map methods, such as addChild. * @see https://yandex.ru/dev/maps/jsapi/doc/3.0/dg/concepts/map.html#layers * @see https://yandex.com/dev/maps/jsapi/doc/3.0/dg/concepts/map.html#layers */ layers: { type: Array, default: (() => []) }, /** * @description Adds cursor: grab/grabbing to ymaps scheme layer */ cursorGrab: { type: Boolean, default: false } }, /** * @description Other events are NOT available. You can listen to events via layers prop, addChildren prop or by adding <ymap-listener> as children. * @see https://yandex.ru/dev/maps/jsapi/doc/3.0/dg/concepts/events.html * @see https://yandex.com/dev/maps/jsapi/doc/3.0/dg/concepts/events.html */ emits: { "input"(map) { return !map || typeof ymaps3 === "undefined" || map instanceof ymaps3.YMap; }, "update:modelValue"(map) { return !map || typeof ymaps3 === "undefined" || map instanceof ymaps3.YMap; } }, slots: Object, setup(props, { slots, emit }) { const map = shallowRef(null); const mapRef = shallowRef(null); const layers = shallowRef([]); const projection = shallowRef(null); const ymapContainer = shallowRef(null); const mounted = shallowRef(false); const needsToHold = ref(0); provide("map", map); provide("layers", layers); provide("projection", projection); provide("needsToHold", needsToHold); emit("input", null); emit("update:modelValue", null); const getSettings = computed(() => ({ ...props.settings, projection: void 0 })); const init = async () => { if (!props.settings.location) { throwException({ text: "You must specify location in YandexMap settings" }); } if (map.value) map.value.destroy(); const container = ymapContainer.value; if (!container) return; const settings = getSettings.value; if (projection.value) settings.projection = projection.value; map.value = new ymaps3.YMap(container, settings, [ ...layers.value, ...props.layers ]); emit("input", map.value); emit("update:modelValue", map.value); }; let listener; let watcher; let cursorGrabTimeout = null; async function setupCursorGrab() { await waitTillMapInit({ map, timeoutCallback: (_timeout, isDelete) => { if (isDelete) { cursorGrabTimeout = null; } else { cursorGrabTimeout = _timeout; } } }).catch(() => { }); if (!map.value) return; if (props.cursorGrab) { listener = new ymaps3.YMapListener({ onActionStart: (e) => { if (e.type === "drag" && props.cursorGrab) mapRef.value?.classList.add("__ymap--grabbing"); }, onActionEnd: (e) => { if (e.type === "drag") mapRef.value?.classList.remove("__ymap--grabbing"); } }); map.value.addChild(listener); } else if (listener) map.value.removeChild(listener); } let reInit = false; watch(VueYandexMaps.loadStatus, async (val) => { if (val === "pending") { reInit = true; mounted.value = false; return; } if (val !== "loaded" && !reInit) return; mounted.value = true; await nextTick(); if (needsToHold.value) { await new Promise((resolve) => watch(needsToHold, () => { if (!needsToHold.value) resolve(); }, { immediate: true })); } await init(); }); onMounted(async () => { const setupWatcher = () => { watcher?.(); let settings = copy(getSettings); watcher = watch(getSettings, (val) => { if (!map.value) return; const clonedSettings = copy(val); if (props.realSettingsLocation && clonedSettings.location) { if ("center" in clonedSettings.location && "center" in settings.location) { settings.location.center = map.value.center; } else if ("bounds" in clonedSettings.location && "bounds" in settings.location) { settings.location.bounds = map.value.bounds; } if ("zoom" in clonedSettings.location && "zoom" in settings.location) settings.location.zoom = map.value.zoom; } const settingsDiff = Object.keys(diff(settings, clonedSettings)); if (settingsDiff.length === 0) return; const updatedSettings = { ...clonedSettings }; for (const key in updatedSettings) { if (!settingsDiff.includes(key)) delete updatedSettings[key]; } settings = clonedSettings; map.value?.update(updatedSettings); }, { deep: true }); }; if (!props.readonlySettings) { setupWatcher(); } watch(() => props.readonlySettings, (val) => { if (!val) { watcher?.(); } else { setupWatcher(); } }); watch(() => props.cursorGrab, setupCursorGrab, { immediate: true }); await setFragment(); if (!VueYandexMaps.isLoaded.value) { if (VueYandexMaps.settings.value.initializeOn === "onComponentMount") { try { await initYmaps(); } catch (e) { console.error("An error occured while initializing Yandex Map with onComponentMount setting"); console.error(e); return; } } else if (VueYandexMaps.loadStatus.value === "loading" || VueYandexMaps.settings.value.initializeOn === "onPluginInit") { if (VueYandexMaps.settings.value.initializeOn === "onPluginInit" && VueYandexMaps.loadStatus.value !== "loading") await nextTick(); await initYmaps(); } if (!VueYandexMaps.isLoaded.value) { throwException({ text: "You have set up <yandex-map> component without initializing Yandex maps. Please check initializeOn setting or call initYmaps manually before registering this component." }); } } mounted.value = true; await nextTick(); if (needsToHold.value) { await new Promise((resolve) => watch(needsToHold, () => { if (!needsToHold.value) resolve(); }, { immediate: true })); } await init(); }); onBeforeUnmount(() => { if (cursorGrabTimeout) clearTimeout(cursorGrabTimeout); if (map.value) map.value.destroy(); map.value = null; emit("input", map.value); emit("update:modelValue", map.value); }); return () => { const mapNodeProps = { class: [ "__ymap", { "__ymap--grab": props.cursorGrab } ], ref: mapRef, style: { width: props.width, height: props.height, "z-index": props.zIndex.toString() } }; const containerNode = h("div", { class: "__ymap_container", ref: ymapContainer }); const slotsNodeProps = { class: "__ymap_slots", style: { display: "none" } }; if (!mounted.value) return h(props.tag, mapNodeProps, [containerNode, h("div", slotsNodeProps)]); return h(props.tag, mapNodeProps, [ containerNode, h("div", slotsNodeProps, slots.default?.({})) ]); }; } }); async function setupMapChildren({ returnOnly, willDeleteByHand, strictMapRoot, requiredImport, createFunction, settings, settingsUpdateIgnoreKeys, settingsUpdateFull, isLayer, isMercator, isMapRoot, mapRootRef, duplicateInit }) { if (!getCurrentInstance()) { throwException({ text: "setupMapChildren must be only called on runtime.", isInternal: true }); } try { const children = shallowRef(); const mapRoot = inject("mapRoot", null); const initPromises = inject("mapRootInitPromises", null); let childrenPromises; const map = injectMap(); const layers = injectLayers(); let timeouts = null; const timeoutCallback = (timeout, isDelete) => { if (!timeouts) timeouts = /* @__PURE__ */ new Set(); if (!isDelete) timeouts.add(timeout); else timeouts.delete(timeout); }; if (isMapRoot && !duplicateInit) { provide("mapRoot", mapRootRef || children); childrenPromises = shallowRef([]); provide("mapRootInitPromises", childrenPromises); } if (!returnOnly && !willDeleteByHand) { onBeforeUnmount(() => { if (children.value) { deleteMapChild({ children: children.value, isMercator, root: mapRoot?.value ? mapRoot : map }); } if (timeouts?.size) { timeouts.forEach((timeout) => clearTimeout(timeout)); timeouts.clear(); } }); } if (settings) { let lastSettings = copy(settings); watch(settings, (value) => { if (!value) return; if (settingsUpdateFull) { console.log(value); if (children.value && "update" in children.value) children.value.update(value); return; } const settingsDiff = Object.keys(diff(lastSettings, value)); if (settingsDiff.length === 0) return; const updatedSettings = copy(value); for (const key in updatedSettings) { if (!settingsDiff.includes(key)) delete updatedSettings[key]; } const ignoreKeys = settingsUpdateIgnoreKeys && (isRef(settingsUpdateIgnoreKeys) ? settingsUpdateIgnoreKeys.value : settingsUpdateIgnoreKeys); if (ignoreKeys) excludeKeys(updatedSettings, ignoreKeys); if (Object.keys(updatedSettings).length === 0) return; lastSettings = copy(value); if (children.value && "update" in children.value) children.value.update(updatedSettings); }, { deep: true }); } if (!isLayer && !isMercator) { await waitTillMapInit({ timeoutCallback }); if (!map.value) { throwException({ text: "map is undefined in setupMapChildren. Please verify that Yandex Maps were initialized successfully and you only use components inside <yandex-map>." }); } } else { await waitTillYmapInit({ timeoutCallback }); } if (strictMapRoot) { if (!mapRoot?.value) await nextTick(); if (!mapRoot?.value) { throwException({ text: `mapRoot is undefined in setupMapChildren. Please verify that you are using component inside it's root: for example, don't use Controls outside <yandex-map-controls>.` }); } } if (isMapRoot) { await nextTick(); await Promise.all(childrenPromises?.value || []); } let importData; if (requiredImport) { const importPromise = requiredImport(); if (initPromises?.value) initPromises.value.push(Promise.resolve(importPromise)); importData = await importPromise; } children.value = createFunction(importData); if (!returnOnly && map.value && !isMercator) { if (initPromises?.value) { await Promise.all(initPromises.value); if (!requiredImport) await nextTick(); } if (typeof mapRoot?.value === "object" && Array.isArray(mapRoot.value)) { mapRoot.value = [ ...mapRoot.value, children.value ]; } else { (mapRoot?.value || map.value).addChild(children.value); } } else if (isLayer) { layers.value.push(children.value); } else if (isMercator && map.value) { map.value.update({ projection: children.value }); } return children.value; } catch (e) { console.error("Error during map children loading", e); throw e; } } const _sfc_main$F = defineComponent({ name: "YandexMapListener", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { let mapListener; onMounted(async () => { mapListener = await setupMapChildren({ createFunction: () => new ymaps3.YMapListener(props.settings || {}), settings: computed(() => props.settings) }); emit("input", mapListener); emit("update:modelValue", mapListener); }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$E = defineComponent({ name: "YandexMapDefaultFeaturesLayer", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const hold = inject("needsToHold"); hold.value++; let mapLayer; onMounted(async () => { mapLayer = await setupMapChildren({ createFunction: () => new ymaps3.YMapDefaultFeaturesLayer(props.settings || {}), settings: computed(() => props.settings), isLayer: true }); emit("input", mapLayer); emit("update:modelValue", mapLayer); hold.value--; }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$D = defineComponent({ name: "YandexMapDefaultSchemeLayer", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const hold = inject("needsToHold"); hold.value++; let mapLayer; onMounted(async () => { mapLayer = await setupMapChildren({ createFunction: () => new ymaps3.YMapDefaultSchemeLayer(props.settings || {}), settings: computed(() => props.settings), isLayer: true }); emit("input", mapLayer); emit("update:modelValue", mapLayer); hold.value--; }); return () => slots.default?.({}); } }); const _sfc_main$C = defineComponent({ name: "YandexMapDefaultSatelliteLayer", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const hold = inject("needsToHold"); hold.value++; let mapLayer; onMounted(async () => { mapLayer = await setupMapChildren({ createFunction: () => new ymaps3.YMapDefaultSatelliteLayer(props.settings || {}), settings: computed(() => props.settings), isLayer: true }); emit("input", mapLayer); emit("update:modelValue", mapLayer); hold.value--; }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$B = defineComponent({ name: "YandexMapTileDataSource", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, required: true } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const hold = inject("needsToHold"); hold.value++; let mapChildren; onMounted(async () => { if (!props.settings.id) { throwException({ text: "You must specify id in YandexMapTileDataSource settings" }); } mapChildren = await setupMapChildren({ createFunction: () => new ymaps3.YMapTileDataSource(props.settings), settings: computed(() => props.settings), isLayer: true }); emit("input", mapChildren); emit("update:modelValue", mapChildren); hold.value--; }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$A = defineComponent({ name: "YandexMapFeatureDataSource", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, required: true } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const hold = inject("needsToHold"); hold.value++; let mapChildren; onMounted(async () => { if (!props.settings.id) { throwException({ text: "You must specify id in YandexMapFeatureDataSource settings" }); } mapChildren = await setupMapChildren({ createFunction: () => new ymaps3.YMapFeatureDataSource(props.settings), settings: computed(() => props.settings), isLayer: true }); emit("input", mapChildren); emit("update:modelValue", mapChildren); hold.value--; }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$z = defineComponent({ name: "YandexMapLayer", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, required: true } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const hold = inject("needsToHold"); hold.value++; let mapLayer; onMounted(async () => { if (!props.settings.type) { throwException({ text: "You must specify type in YandexMapLayer settings" }); } mapLayer = await setupMapChildren({ createFunction: () => new ymaps3.YMapLayer(props.settings || {}), settings: computed(() => props.settings), isLayer: true }); emit("input", mapLayer); emit("update:modelValue", mapLayer); hold.value--; }); return () => hVue2(slots.default?.({})); } }); function getMarkerContainerProps({ position, containerAttrs, wrapperAttrs, zeroSizes }) { const root = { class: ["__ymap-marker"], style: {} }; const children = { class: ["__ymap-marker_wrapper"], style: {} }; const isDefaultPosition = position === "default" || position === "default default"; if (position && !isDefaultPosition) { if (position.startsWith("translate")) { children.style.transform = position; } else { let translateX = 0; let translateY = 0; const splitted = position.split(" "); for (let i = 0; i < splitted.length; i++) { let local = 0; const item = splitted[i]; switch (item) { case "top": case "left": local = -100; break; case "top-center": case "left-center": local = -50; break; case "bottom": case "right": local = 100; break; case "bottom-center": case "right-center": local = 50; break; default: local = 0; } if (item.startsWith("left") || item.startsWith("right")) translateX = local; else translateY = local; } children.style.transform = `translate(${translateX}%, ${translateY}%)`; } } if (zeroSizes === true || zeroSizes !== false && position && !isDefaultPosition) { root.style.width = "0"; root.style.height = "0"; if (children.style.transform) children.style.width = "fit-content"; } const attrs = { root: { ...containerAttrs ?? {} }, children: { ...wrapperAttrs ?? {} } }; for (const [key, value] of Object.entries(attrs)) { const obj = key === "root" ? root : children; if (value.class) { if (!Array.isArray(value.class)) value.class = [value.class]; value.class = [ ...obj.class, ...value.class ]; } if (value?.style) { if (typeof value.style !== "object" || Array.isArray(value.style)) { console.warn(`Style property was given in ${key} of marker, but it is not an object. Style of this prop can only be an object, therefore it was ignored.`); } else { value.style = { ...obj.style, ...value.style }; } } Object.assign(obj, value); } return { root, children }; } function excludeYandexMarkerProps(props) { props = { ...props }; const toExclude = { position: true, containerAttrs: true, wrapperAttrs: true, zeroSizes: true }; for (const excluded in toExclude) { if (excluded in props) delete props[excluded]; } return props; } const _sfc_main$y = defineComponent({ name: "YandexMapMarker", inheritAttrs: false, props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, required: true }, /** * @description Sets translate(%, %) to marker to align it properly. * * If you want to make aligment to be like Yandex Maps 2.0, set this property to "top left-center". * @default default (as goes in Yandex by default) */ position: { type: String }, /** * @description Allows you to add any attributes to <div class="__ymap-marker"> container. * * Important: to pass styles, you must use object-style prop instead of string. */ containerAttrs: { type: Object, default: () => ({}) }, /** * @description Allows you to add any attributes to <div class="__ymap-marker_wrapper"> container. * * Important: to pass styles, you must use object-style prop instead of string. */ wrapperAttrs: { type: Object, default: () => ({}) }, /** * @description Will add width and height: 0 to container. * * Null enables default behavior, false disables it completely (even if position is specified). * * @default true if position is specified, false otherwise */ zeroSizes: { type: Boolean, default: null } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit, attrs }) { let mapChildren; const element = ref(null); function clearElement() { if (!element.value?.parentElement?.closest("ymaps")) element.value?.remove(); } onMounted(async () => { if (!props.settings.coordinates) { throwException({ text: "You must specify coordinates in YandexMapMarker settings" }); } mapChildren = await setupMapChildren({ settings: computed(() => props.settings), createFunction: () => new ymaps3.YMapMarker(props.settings, element.value) }); clearElement(); emit("input", mapChildren); emit("update:modelValue", mapChildren); }); let mapParent = void 0; onUpdated(() => { if (!mapParent && element.value?.parentElement?.closest("ymaps")) mapParent = element.value.parentElement; else if (mapParent && element.value && !element.value?.parentElement?.closest("ymaps")) mapParent.appendChild(element.value); clearElement(); }); const rootProps = computed(() => getMarkerContainerProps({ position: props.position, containerAttrs: props.containerAttrs, wrapperAttrs: props.wrapperAttrs, zeroSizes: props.zeroSizes })); return () => hF([ h("div", { ...rootProps.value.root, ref: element, ...getAttrsForVueVersion(attrs) }, [ h("div", { ...rootProps.value.children }, slots.default?.({})) ]) ]); } }); const _sfc_main$x = defineComponent({ name: "YandexMapDefaultMarker", inheritAttrs: false, props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, required: true } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit, attrs }) { let mapChildren; const popup = ref(null); const closeFunc = ref(() => { }); const contentFunc = (close) => { closeFunc.value = close; return popup.value; }; const getSettings = computed(() => { const settings = { ...props.settings }; if (settings.popup && (typeof settings.popup.content === "undefined" || settings.popup.content === "fromSlot") && popup.value) { settings.popup = { ...settings.popup, content: contentFunc }; } return settings; }); onMounted(async () => { if (!props.settings.coordinates) { throwException({ text: "You must specify coordinates in YandexMapDefaultMarker settings" }); } mapChildren = await setupMapChildren({ createFunction: ({ YMapDefaultMarker: Marker }) => new Marker(getSettings.value), requiredImport: () => ymaps3.import("@yandex/ymaps3-markers@0.0.1"), settings: getSettings }); emit("input", mapChildren); emit("update:modelValue", mapChildren); }); watch(popup, () => { if (popup.value) popup.value.parentNode?.removeChild(popup.value); }); return () => { if (slots.popup) { return hF([ h("div", { ref: popup }, slots.popup?.({ close: closeFunc.value })) ]); } return void 0; }; } }); const _sfc_main$w = defineComponent({ name: "YandexMapFeature", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, required: true } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { let mapChildren; onMounted(async () => { if (!props.settings.geometry) { throwException({ text: "You must specify geometry in YandexMapFeature settings" }); } mapChildren = await setupMapChildren({ createFunction: () => new ymaps3.YMapFeature(props.settings), settings: computed(() => props.settings) }); emit("input", mapChildren); emit("update:modelValue", mapChildren); }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$v = defineComponent({ name: "YandexMapControls", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, required: true } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const mapChildren = shallowRef(null); onMounted(async () => { if (!props.settings.position) { throwException({ text: "You must specify position in YandexMapControls settings" }); } mapChildren.value = await setupMapChildren({ createFunction: () => new ymaps3.YMapControls(props.settings), isMapRoot: true, settings: computed(() => props.settings) }); emit("input", mapChildren.value); emit("update:modelValue", mapChildren.value); }); return () => mapChildren.value ? hVue2(slots.default?.({})) : h("div"); } }); const _sfc_main$u = defineComponent({ name: "YandexMapControl", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit, attrs }) { let mapChildren; const element = ref(null); onMounted(async () => { mapChildren = await setupMapChildren({ createFunction: () => new ymaps3.YMapControl(props.settings, element.value), settings: computed(() => props.settings), strictMapRoot: true }); emit("input", mapChildren); emit("update:modelValue", mapChildren); }); return () => hF([ h("div", { ref: element, ...getAttrsForVueVersion(attrs) }, slots.default?.({})) ]); } }); const _sfc_main$t = defineComponent({ name: "YandexMapControlButton", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit, attrs }) { let mapChildren; const element = ref(null); onMounted(async () => { mapChildren = await setupMapChildren({ createFunction: () => new ymaps3.YMapControlButton({ ...props.settings, element: element.value }), settings: computed(() => ({ ...props.settings, element: element.value })), strictMapRoot: true }); emit("input", mapChildren); emit("update:modelValue", mapChildren); }); return () => hF([ h("div", { ref: element, ...getAttrsForVueVersion(attrs) }, slots.default?.({})) ]); } }); const _sfc_main$s = defineComponent({ name: "YandexMapGeolocationControl", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { let mapChildren; onMounted(async () => { mapChildren = await setupMapChildren({ createFunction: (controls) => new controls.YMapGeolocationControl(props.settings), requiredImport: () => ymaps3.import("@yandex/ymaps3-controls@0.0.1"), settings: computed(() => props.settings), strictMapRoot: true }); emit("input", mapChildren); emit("update:modelValue", mapChildren); }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$r = defineComponent({ name: "YandexMapZoomControl", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { let mapChildren; onMounted(async () => { mapChildren = await setupMapChildren({ createFunction: (controls) => new controls.YMapZoomControl(props.settings), requiredImport: () => ymaps3.import("@yandex/ymaps3-controls@0.0.1"), settings: computed(() => props.settings), strictMapRoot: true }); emit("input", mapChildren); emit("update:modelValue", mapChildren); }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$q = defineComponent({ name: "YandexMapScaleControl", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, settings: { type: Object, default: () => ({}) } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { let mapChildren; onMounted(async () => { mapChildren = await setupMapChildren({ createFunction: () => new ymaps3.YMapScaleControl(props.settings), settings: computed(() => props.settings), strictMapRoot: true }); emit("input", mapChildren); emit("update:modelValue", mapChildren); }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$p = defineComponent({ name: "YandexMapCartesianProjection", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, bounds: { type: Array, required: true }, cycled: { type: Array } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const hold = inject("needsToHold"); hold.value++; const projection = inject("projection"); onMounted(async () => { if (!projection) return; const cartesian = await setupMapChildren({ isMercator: true, createFunction: ({ Cartesian: CartesianClass }) => new CartesianClass(props.bounds, props.cycled), requiredImport: () => ymaps3.import("@yandex/ymaps3-cartesian-projection@0.0.1") }); projection.value = cartesian; emit("input", cartesian); emit("update:modelValue", cartesian); hold.value--; }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$o = defineComponent({ name: "YandexMapSphericalMercatorProjection", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; } }, slots: Object, setup(props, { slots, emit }) { const hold = inject("needsToHold"); hold.value++; const projection = inject("projection"); onMounted(async () => { if (!projection) { hold.value--; return; } const mercator = await setupMapChildren({ isMercator: true, createFunction: ({ SphericalMercator: Mercator }) => new Mercator(), requiredImport: () => ymaps3.import("@yandex/ymaps3-spherical-mercator-projection@0.0.1") }); projection.value = mercator; emit("input", mercator); emit("update:modelValue", mercator); hold.value--; }); return () => hVue2(slots.default?.({})); } }); const _sfc_main$n = defineComponent({ name: "YandexMapHint", props: { value: { type: Object, default: null }, modelValue: { type: Object, default: null }, // Property that you will set on YandexMapMarker or YandexMapFeature to display hint content hintProperty: { type: String, required: true } }, emits: { "input"(item) { return true; }, "update:modelValue"(item) { return true; }