diff --git a/CHANGELOG.md b/CHANGELOG.md index 8528ec79..10a5efca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ ### 🐞 Bug fixes +- Fixed an issue when clicking on a popup and then clicking on the map again - Fix modal close button possition - Fixed an issue with the generation of tranlations - _...Add new stuff here..._ diff --git a/cypress/e2e/map.cy.ts b/cypress/e2e/map.cy.ts index e200f8d2..7ce34c18 100644 --- a/cypress/e2e/map.cy.ts +++ b/cypress/e2e/map.cy.ts @@ -29,4 +29,23 @@ describe("map", () => { then(get.searchControl()).shouldBeVisible(); }); }); + + describe("popup", () => { + beforeEach(() => { + when.setStyle("rectangles"); + }) + it("should open on feature click", () => { + when.clickCenter("maplibre:map"); + then(get.elementByTestId("feature-layer-popup")).shouldBeVisible(); + }); + + it("should open a second feature after closing popup", () => { + when.clickCenter("maplibre:map"); + then(get.elementByTestId("feature-layer-popup")).shouldBeVisible(); + when.closePopup(); + then(get.elementByTestId("feature-layer-popup")).shouldNotExist(); + when.clickCenter("maplibre:map"); + then(get.elementByTestId("feature-layer-popup")).shouldBeVisible(); + }); + }); }); diff --git a/cypress/e2e/maputnik-cypress-helper.ts b/cypress/e2e/maputnik-cypress-helper.ts index 9edc9ec5..8c20bee8 100644 --- a/cypress/e2e/maputnik-cypress-helper.ts +++ b/cypress/e2e/maputnik-cypress-helper.ts @@ -21,6 +21,11 @@ export default class MaputnikCypressHelper { this.helper.when.wait(1); this.helper.get.elementByTestId(targetElement).realMouseUp(); }, + clickCenter: (element: string) => { + this.helper.get.elementByTestId(element).realMouseDown({ button: "left", position: "center" }); + this.helper.when.wait(200); + this.helper.get.elementByTestId(element).realMouseUp(); + }, ...this.helper.when, }; diff --git a/cypress/e2e/maputnik-driver.ts b/cypress/e2e/maputnik-driver.ts index 5c885815..b1991217 100644 --- a/cypress/e2e/maputnik-driver.ts +++ b/cypress/e2e/maputnik-driver.ts @@ -78,6 +78,13 @@ export class MaputnikDriver { fixture: "geojson-raster-style.json", }, }); + this.helper.given.interceptAndMockResponse({ + method: "GET", + url: baseUrl + "rectangles-style.json", + response: { + fixture: "rectangles-style.json", + }, + }); this.helper.given.interceptAndMockResponse({ method: "GET", url: "*example.local/*", @@ -107,7 +114,7 @@ export class MaputnikDriver { .selectFile("cypress/fixtures/example-style.json", { force: true }); }, setStyle: ( - styleProperties: "geojson" | "raster" | "both" | "layer" | "", + styleProperties: "geojson" | "raster" | "both" | "layer" | "rectangles" | "", zoom?: number ) => { const url = new URL(baseUrl); @@ -124,7 +131,11 @@ export class MaputnikDriver { case "layer": url.searchParams.set("style", baseUrl + "example-layer-style.json"); break; + case "rectangles": + url.searchParams.set("style", baseUrl + "rectangles-style.json"); + break; } + if (zoom) { url.hash = `${zoom}/41.3805/2.1635`; } @@ -164,6 +175,10 @@ export class MaputnikDriver { .clear() .type(text, { parseSpecialCharSequences: false }); }, + + closePopup: () => { + this.helper.get.element(".maplibregl-popup-close-button").click(); + } }; public get = { diff --git a/cypress/fixtures/rectangles-style.json b/cypress/fixtures/rectangles-style.json new file mode 100644 index 00000000..0d32e742 --- /dev/null +++ b/cypress/fixtures/rectangles-style.json @@ -0,0 +1,92 @@ +{ + "version": 8, + "sources": { + "rectangles": { + "type": "geojson", + "data": { + "type": "FeatureCollection", + "features": [ + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -130.78125, + -33.13755119234615 + ], + [ + -130.78125, + 63.548552232036414 + ], + [ + 15.468749999999998, + 63.548552232036414 + ], + [ + 15.468749999999998, + -33.13755119234615 + ], + [ + -130.78125, + -33.13755119234615 + ] + ] + ] + } + }, + { + "type": "Feature", + "properties": {}, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -48.515625, + -54.97761367069625 + ], + [ + -48.515625, + 36.5978891330702 + ], + [ + 169.45312499999997, + 36.5978891330702 + ], + [ + 169.45312499999997, + -54.97761367069625 + ], + [ + -48.515625, + -54.97761367069625 + ] + ] + ] + } + } + ] + } + } + }, + "layers": [ + { + "id": "background", + "type": "background", + "paint": { + "background-color": "white" + } + }, + { + "id": "rectangles", + "type": "fill", + "source": "rectangles", + "paint": { + "fill-opacity": 0.3 + } + } + ] +} diff --git a/src/components/MapMaplibreGl.tsx b/src/components/MapMaplibreGl.tsx index 244ce845..de4886eb 100644 --- a/src/components/MapMaplibreGl.tsx +++ b/src/components/MapMaplibreGl.tsx @@ -1,4 +1,4 @@ -import React, {type JSX} from 'react' +import React from 'react' import {createRoot} from 'react-dom/client' import MapLibreGl, {LayerSpecification, LngLat, Map, MapOptions, SourceSpecification, StyleSpecification} from 'maplibre-gl' import MaplibreInspect from '@maplibre/maplibre-gl-inspect' @@ -17,17 +17,6 @@ import { withTranslation, WithTranslation } from 'react-i18next' import i18next from 'i18next' import { Protocol } from "pmtiles"; -function renderPopup( - popupElement: JSX.Element, - mountNode: HTMLElement, - popup: MapLibreGl.Popup -): HTMLElement { - const root = createRoot(mountNode); - popup.once('close', () => root.unmount()); - root.render(popupElement); - return mountNode as HTMLElement; -} - function buildInspectStyle(originalMapStyle: StyleSpecification, coloredLayers: HighlightedLayer[], highlightedLayer?: HighlightedLayer) { const backgroundLayer = { "id": "background", @@ -179,6 +168,7 @@ class MapMaplibreGlInternal extends React.Component buildInspectStyle(originalMapStyle, coloredLayers, this.props.highlightedLayer), renderPopup: (features: InspectFeature[]) => { if(this.props.inspectModeEnabled) { - return renderPopup( - , - tmpNode, - inspectPopup - ); + inspectPopup.once('open', () => { + root.render(); + }); + return tmpNode; } else { - return renderPopup( - { + root.render(, - tmpNode, - inspectPopup - ); + />,); + }); + return tmpNode; } } }) diff --git a/src/components/MapMaplibreGlFeaturePropertyPopup.tsx b/src/components/MapMaplibreGlFeaturePropertyPopup.tsx index 3f0ab95e..57cb47dc 100644 --- a/src/components/MapMaplibreGlFeaturePropertyPopup.tsx +++ b/src/components/MapMaplibreGlFeaturePropertyPopup.tsx @@ -66,7 +66,7 @@ type FeaturePropertyPopupProps = { class FeaturePropertyPopup extends React.Component { render() { const features = removeDuplicatedFeatures(this.props.features) - return
+ return
{features.map(renderFeature)} diff --git a/src/components/MapMaplibreGlLayerPopup.tsx b/src/components/MapMaplibreGlLayerPopup.tsx index fbe665c4..d0ca0ab1 100644 --- a/src/components/MapMaplibreGlLayerPopup.tsx +++ b/src/components/MapMaplibreGlLayerPopup.tsx @@ -104,7 +104,7 @@ class FeatureLayerPopup extends React.Component { }) - return
+ return
{items}
}