Manage custom widgets
The viewer allows you to manage finely its widgets, you can either add or replace all widgets offered by the viewer.
We use internally slots to make this possible. Each corner of the viewer is identified uniquely, so you can add in the exact place you'd like. This is in a similar fashion to MapLibre GL or Leaflet widgets management.
Note
This is only available for Viewer & Photo Viewer components, not for Coverage Map or Editor.
Add a new widget
Let's say you want to add a custom widget without removing existing viewer ones. You can insert your element inside of the viewer markup:
<pnx-viewer
endpoint="https://panoramax.openstreetmap.fr/"
>
<p slot="top-right">My custom text</p>
</pnx-viewer>
The magic happens here thanks to the slop="top-right" attribute on your element. You can use any corner you like (top-left, top, top-right, bottom-left, bottom, bottom-right), and add several elements on a same corner (they will stack depending of existing CSS styles).
Replace all widgets
For finer control, you may want to get rid of all existing widgets before adding your own ones. This is also possible by setting widgets="false" attribute on the viewer:
<pnx-viewer
endpoint="https://panoramax.openstreetmap.fr/"
widgets="false"
>
<p slot="top-right">My custom text</p>
</pnx-viewer>
Note that this keeps only the Mini map/picture display (in bottom-left corner).
Note
If you don't need map at all, you can also use the Photo Viewer component, which is a picture display without any map.
Reuse default widgets
You may also want to reuse differently existing widgets. Note that all of them are listed in the API reference. Just insert them as slotted components inside the viewer:
<pnx-viewer
endpoint="https://panoramax.openstreetmap.fr/"
widgets="false"
>
<pnx-widget-zoom slot="top-right" />
</pnx-viewer>
Note that parent variables (_parent and _t) are automatically passed through by the viewer, no need to add it manually.
Append content inside a menu
Some menus expose an extra slot so you can append your own controls at the end of the menu, without fighting the component's shadow DOM. Slotted content is owned by the light DOM, so it survives the menu's internal re-renders. Available on:
- the Semantics filters menu (pnx-map-semantics-filters-menu)
- the Share menu (pnx-share-menu)
Example, for the Semantics filters menu:
// Find menu div from viewer object
// given that your viewer is stored in "viewer" variable
const semFiltButton = [...viewer.grid.childNodes].find(e => e.tagName.toLowerCase() === "pnx-widget-semantics-filters");
const semFiltMenu = semFiltButton.shadowRoot.querySelector("pnx-map-semantics-filters-menu");
// Create extra panel
const panel = document.createElement("div");
panel.slot = "extra"; // projected into the menu through the `extra` slot
panel.append(/* your own controls */);
// Add to menu
semFiltMenu.appendChild(panel);
Or for the Share menu:
// Find menu div from viewer object
// given that your viewer is stored in "viewer" variable
// and that the share menu is opened
const shareMenu = viewer.popup.querySelector("pnx-share-menu");
// Create extra panel
const panel = document.createElement("div");
panel.slot = "extra"; // projected into the menu through the `extra` slot
panel.append(/* your own controls */);
// Add to menu
shareMenu.appendChild(panel);