RPopup

Usage

import { RMap, RPopup } from "maplibre-react-components";
 
const center: [number, number] = [4.8, 45.7];
 
export default function App() {
  return (
    <RMap
      className="maplibregl-theme-modern"
      initialCenter={center}
      initialZoom={2}
    >
      <RPopup longitude={center[0]} latitude={center[1]}>
        Welcome Lyon !
      </RPopup>
    </RMap>
  );
}
 

Closable Popup

For compatibility some options from PopupOptions are not available : closeButton, closeOnClick, closeOnMove. Without these deactivations, this could result map's state to deviate from its props.

As an alternative, you can listen to events onMapClick, onMapMove.

import { RMap, RPopup } from "maplibre-react-components";
import { useState } from "react";
 
const center: [number, number] = [4.8, 45.7];
 
export default function App() {
  const [showPopup, setShowPopup] = useState(true);
 
  return (
    <RMap initialCenter={center} initialZoom={2}>
      {showPopup && (
        <RPopup
          longitude={center[0]}
          latitude={center[1]}
          onMapMove={() => setShowPopup(false)}
          onMapClick={() => setShowPopup(false)}
        >
          Hello Lyon !
          <button
            className="maplibregl-popup-close-button"
            onClick={() => setShowPopup(false)}
          >
            ×
          </button>
        </RPopup>
      )}
      <div className="absolute left-4 top-4">
        <button onClick={() => setShowPopup((s) => !s)}>Toggle Popup</button>
      </div>
      <div className="absolute bottom-4 left-4 rounded-2xl bg-gray-0 p-4">
        <div>popup state : {showPopup ? "visible" : "hidden"}</div>
      </div>
    </RMap>
  );
}
 

rather use these listeners on the RPopup component rather than on RMap because they are unregistered when the popup is hidden.

import {
  RMap,
  RMarker,
  RGradientMarker,
  RPopup,
  markerPopupOffset,
  gradientMarkerPopupOffset,
} from "maplibre-react-components";
import { useState } from "react";
 
const center: [number, number] = [-14.7, 37.8];
const lyon: [number, number] = [4.8, 45.7];
const dakar: [number, number] = [-17.43, 14.6866];
 
export default function App() {
  const [showLyonPopup, setShowLyonPopup] = useState(true);
  const [showDakarPopup, setShowDakarPopup] = useState(true);
 
  return (
    <RMap initialCenter={center} initialZoom={2}>
      <RMarker
        longitude={lyon[0]}
        latitude={lyon[1]}
        onClick={(e) => {
          e.stopPropagation();
          setShowLyonPopup((s) => !s);
        }}
      />
      {showLyonPopup && (
        <RPopup
          longitude={lyon[0]}
          latitude={lyon[1]}
          offset={markerPopupOffset}
        >
          Hello Lyon !
        </RPopup>
      )}
      <RGradientMarker
        longitude={dakar[0]}
        latitude={dakar[1]}
        onClick={(e) => {
          e.stopPropagation();
          setShowDakarPopup((s) => !s);
        }}
      />
      {showDakarPopup && (
        <RPopup
          longitude={dakar[0]}
          latitude={dakar[1]}
          offset={gradientMarkerPopupOffset}
        >
          Hello Dakar !
        </RPopup>
      )}
    </RMap>
  );
}
 

you can import the markerPopupOffset utility object from the lib, based on default MapLibre Marker height.

Reference

Check the MapLibre PopupOptions reference page for details of PopupInitialOptions and PopupReactiveOptions. For compatibility some native PopupOptions are not available : closeButton, closeOnClick, closeOnMove. see Closable Popup

type RPopupProps =
  {
    longitude: number;
    latitude: number;
    /**
     * for popup element
     */
    children?: ReactNode;
  } &
  /**
   * Non reactive popup options (only used during instantiation)
   * prefixed with "initial" + first letter uppercase
   */
  PopupInitialOptions &
  /**
   * Reactive popup options.
   * they have the same name as in MapOptions
   */
  PopupReactiveOptions &
  /**
   * Listenners for popup events
   * prefixed with "on" + first letter uppercase
   */
  PopupCallbacks;
type PopupInitialOptions = {
  initialFocusAfterOpen?: boolean;
  initialAnchor?: PositionAnchor;
  initialSubpixelPositioning?: boolean;
};
 
type PopupReactiveOptions = {
  className?: string;
  offset?: PointLike;
  maxWidth?: string;
};
 
type PopupCallbacks = {
  onMapClick?: (e: MapLayerMouseEvent) => void;
  onMapMove?: (e: MapLibreEvent<MouseEvent | TouchEvent | WheelEvent | undefined>) => void;
}