src/stories/MapAnnotations/Popup/Interactive/InteractivePopup.tsx (48 lines of code) (raw):

import { useContext, useEffect, useState, ReactNode } from 'react'; import { createRoot } from 'react-dom/client'; import atlas from 'azure-maps-control'; import { IAzureMapsContextProps, AzureMapsContext, IAzureMapPopupEvent } from 'react-azure-maps'; interface InteractivePopupProps { children: ReactNode; isVisible?: boolean; options?: atlas.PopupOptions; events?: IAzureMapPopupEvent[]; } const InteractivePopup = ({ children, isVisible = true, options, events }: InteractivePopupProps) => { const { mapRef } = useContext<IAzureMapsContextProps>(AzureMapsContext); const containerRef = document.createElement('div'); const root = createRoot(containerRef); const [popupRef] = useState<atlas.Popup>(new atlas.Popup({ ...options, content: containerRef })); // Add events to the popup when it is mounted useEffect(() => { if (mapRef) { events && events.forEach(({ eventName, callback }) => { mapRef.events.add(eventName, popupRef, callback); }); return () => { mapRef.popups.remove(popupRef); }; } }, []); // Render the popup content and set the options useEffect(() => { root.render(children); popupRef.setOptions({ ...options, content: containerRef, }); if (mapRef && isVisible && !popupRef.isOpen()) { popupRef.open(mapRef); } }, [options, children]); // Toggle the popup visibility useEffect(() => { if (mapRef) { if (isVisible && !popupRef.isOpen()) { popupRef.open(mapRef); } else if (mapRef.popups.getPopups().length && !isVisible && popupRef.isOpen()) { popupRef.close(); } } }, [isVisible]); return null; }; export default InteractivePopup;