import React, { useEffect } from "react"; import type { WidgetProps } from "widgets/BaseWidget"; import styled from "styled-components"; import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet"; import "leaflet/dist/leaflet.css"; import L from "leaflet"; import { FullScreen, useFullScreenHandle } from "react-full-screen"; import { Icon } from "@blueprintjs/core"; // Контейнер для карты с относительным позиционированием const MapWrapper = styled.div` position: relative; width: 100%; height: 100%; `; // Кнопка для переключения полноэкранного режима const FullscreenButton = styled.button` position: absolute; top: 10px; right: 10px; z-index: 1000; background: white; border: 1px solid #ccc; border-radius: 4px; padding: 8px; cursor: pointer; display: flex; align-items: center; justify-content: center; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); transition: background-color 0.2s; &:hover { background-color: #f0f0f0; } &:active { background-color: #e0e0e0; } `; // 🧩 фикс, чтобы маркеры отображались (иначе пустые иконки) delete (L.Icon.Default.prototype as any)._getIconUrl; L.Icon.Default.mergeOptions({ iconRetinaUrl: require("leaflet/dist/images/marker-icon-2x.png"), iconUrl: require("leaflet/dist/images/marker-icon.png"), shadowUrl: require("leaflet/dist/images/marker-shadow.png"), }); // Компонент для обновления размера карты при изменении размера контейнера function MapResizer() { const map = useMap(); useEffect(() => { // Обновляем размер карты при монтировании const timer = setTimeout(() => { map.invalidateSize(); }, 100); return () => clearTimeout(timer); }, [map]); // Обновляем размер при изменении размера окна useEffect(() => { const handleResize = () => { map.invalidateSize(); }; window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, [map]); // Обновляем размер при переключении полноэкранного режима useEffect(() => { const handleFullscreenChange = () => { // Небольшая задержка, чтобы контейнер успел изменить размер setTimeout(() => { map.invalidateSize(); }, 200); }; document.addEventListener("fullscreenchange", handleFullscreenChange); document.addEventListener("webkitfullscreenchange", handleFullscreenChange); document.addEventListener("mozfullscreenchange", handleFullscreenChange); document.addEventListener("MSFullscreenChange", handleFullscreenChange); return () => { document.removeEventListener("fullscreenchange", handleFullscreenChange); document.removeEventListener("webkitfullscreenchange", handleFullscreenChange); document.removeEventListener("mozfullscreenchange", handleFullscreenChange); document.removeEventListener("MSFullscreenChange", handleFullscreenChange); }; }, [map]); return null; } function OpenStreetMapComponent(props: OpenStreetMapComponentProps) { // Получаем значения из props или используем значения по умолчанию const centerLat = props.centerLat ?? 55.751244; const centerLng = props.centerLng ?? 37.618423; const zoom = props.zoom ?? 7; const markerLat = props.markerLat ?? centerLat; const markerLng = props.markerLng ?? centerLng; const markerText = props.markerText ?? "Привет! Это Москва 🏙️"; const center: [number, number] = [centerLat, centerLng]; const markerPosition: [number, number] = [markerLat, markerLng]; // Хук для управления полноэкранным режимом const fullScreenHandle = useFullScreenHandle(); return ( {markerText} {/* Кнопка для переключения полноэкранного режима */} ); } export interface OpenStreetMapComponentProps extends WidgetProps { centerLat?: number; centerLng?: number; zoom?: number; markerLat?: number; markerLng?: number; markerText?: string; } export default OpenStreetMapComponent;