Fix first city click handling on flights map
This commit is contained in:
@@ -313,6 +313,8 @@
|
||||
border: none;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
font-family: 'Inter', 'Roboto', Arial, sans-serif;
|
||||
color: colors.$text-color;
|
||||
font-size: fonts.$font-size-s;
|
||||
@@ -323,7 +325,6 @@
|
||||
1px 0 rgba(255, 255, 255, 0.53),
|
||||
0 1px rgba(255, 255, 255, 0.53),
|
||||
0 -1px rgba(255, 255, 255, 0.53);
|
||||
pointer-events: none;
|
||||
|
||||
&::before { display: none; }
|
||||
}
|
||||
|
||||
@@ -13,15 +13,17 @@ import type { IMapMarker } from "../types.js";
|
||||
interface MockMarker {
|
||||
icon: unknown;
|
||||
tooltipArgs: unknown[] | null;
|
||||
tooltipHandlers: Record<string, Array<(e?: unknown) => void>>;
|
||||
addTo: ReturnType<typeof vi.fn>;
|
||||
on: ReturnType<typeof vi.fn>;
|
||||
bindTooltip: ReturnType<typeof vi.fn>;
|
||||
getTooltip: ReturnType<typeof vi.fn>;
|
||||
openTooltip: ReturnType<typeof vi.fn>;
|
||||
closeTooltip: ReturnType<typeof vi.fn>;
|
||||
setIcon: ReturnType<typeof vi.fn>;
|
||||
setLatLng: ReturnType<typeof vi.fn>;
|
||||
getLatLng: ReturnType<typeof vi.fn>;
|
||||
options: { title?: string };
|
||||
options: { title?: string; autoPanOnFocus?: boolean };
|
||||
}
|
||||
|
||||
interface MockLayerGroup {
|
||||
@@ -71,10 +73,22 @@ function resetLeafletMockState() {
|
||||
vi.mock("leaflet/dist/leaflet.css", () => ({}));
|
||||
|
||||
vi.mock("leaflet", () => {
|
||||
function marker(_latlng: unknown, opts: { icon?: unknown; title?: string } = {}) {
|
||||
function marker(
|
||||
_latlng: unknown,
|
||||
opts: { icon?: unknown; title?: string; autoPanOnFocus?: boolean } = {},
|
||||
) {
|
||||
const tooltip = {
|
||||
on: vi.fn((evt: string, fn: (e?: unknown) => void) => {
|
||||
m.tooltipHandlers[evt] ??= [];
|
||||
m.tooltipHandlers[evt]!.push(fn);
|
||||
return tooltip;
|
||||
}),
|
||||
};
|
||||
|
||||
const m: MockMarker = {
|
||||
icon: opts.icon,
|
||||
tooltipArgs: null,
|
||||
tooltipHandlers: {},
|
||||
addTo: vi.fn((target: { addLayer?: (l: MockMarker) => unknown }) => {
|
||||
target.addLayer?.(m);
|
||||
return m;
|
||||
@@ -84,6 +98,7 @@ vi.mock("leaflet", () => {
|
||||
m.tooltipArgs = args;
|
||||
return m;
|
||||
}),
|
||||
getTooltip: vi.fn(() => tooltip),
|
||||
openTooltip: vi.fn(() => m),
|
||||
closeTooltip: vi.fn(() => m),
|
||||
setIcon: vi.fn((ic: unknown) => {
|
||||
@@ -92,7 +107,10 @@ vi.mock("leaflet", () => {
|
||||
}),
|
||||
setLatLng: vi.fn(() => m),
|
||||
getLatLng: vi.fn(() => ({ lat: 0, lng: 0 })),
|
||||
options: opts.title !== undefined ? { title: opts.title } : {},
|
||||
options: {
|
||||
...(opts.title !== undefined ? { title: opts.title } : {}),
|
||||
...(opts.autoPanOnFocus !== undefined ? { autoPanOnFocus: opts.autoPanOnFocus } : {}),
|
||||
},
|
||||
};
|
||||
createdMarkers.push(m);
|
||||
return m;
|
||||
@@ -192,7 +210,11 @@ vi.mock("leaflet", () => {
|
||||
};
|
||||
}
|
||||
|
||||
const L = { marker, layerGroup, map: mapFn, tileLayer, icon, latLng, polyline, popup };
|
||||
const DomEvent = {
|
||||
stop: vi.fn(),
|
||||
};
|
||||
|
||||
const L = { marker, layerGroup, map: mapFn, tileLayer, icon, latLng, polyline, popup, DomEvent };
|
||||
return { default: L, ...L };
|
||||
});
|
||||
|
||||
@@ -254,6 +276,35 @@ describe("MapCanvas — legacy (flat) path", () => {
|
||||
const allMarkers = createdLayerGroups.flatMap((l) => l._markers);
|
||||
expect(allMarkers).toContain(createdMarkers[0]);
|
||||
});
|
||||
|
||||
it("creates markers with no auto-pan on focus and interactive city labels", () => {
|
||||
renderCanvas([
|
||||
{ id: "MOW", lat: 1, lng: 2, style: "blue-small", label: "Москва", tooltipPermanent: true },
|
||||
]);
|
||||
|
||||
const marker = createdMarkers[0];
|
||||
expect(marker).toBeTruthy();
|
||||
if (!marker) return;
|
||||
expect(marker.options).toMatchObject({ title: "MOW", autoPanOnFocus: false });
|
||||
expect(marker.tooltipArgs?.[1]).toMatchObject({ interactive: true });
|
||||
});
|
||||
|
||||
it("treats city-label click as marker click", () => {
|
||||
const onMarkerClick = vi.fn();
|
||||
renderCanvas(
|
||||
[{ id: "MOW", lat: 1, lng: 2, style: "blue-small", label: "Москва", tooltipPermanent: true }],
|
||||
{ onMarkerClick },
|
||||
);
|
||||
|
||||
const marker = createdMarkers[0];
|
||||
if (!marker) {
|
||||
throw new Error("expected marker to be created");
|
||||
}
|
||||
const clickHandlers = marker?.tooltipHandlers["click"];
|
||||
expect(clickHandlers?.length).toBeGreaterThan(0);
|
||||
clickHandlers?.[0]?.({} as unknown);
|
||||
expect(onMarkerClick).toHaveBeenCalledWith("MOW");
|
||||
});
|
||||
});
|
||||
|
||||
describe("MapCanvas — categorized: visibility predicate", () => {
|
||||
|
||||
@@ -376,6 +376,7 @@ export const MapCanvas: FC<MapCanvasProps> = ({
|
||||
const marker = L.marker([m.lat, m.lng], {
|
||||
icon: getIcon(iconStyle),
|
||||
title: m.id,
|
||||
autoPanOnFocus: false,
|
||||
});
|
||||
|
||||
if (m.label) {
|
||||
@@ -383,6 +384,13 @@ export const MapCanvas: FC<MapCanvasProps> = ({
|
||||
permanent: m.tooltipPermanent ?? false,
|
||||
direction: "top",
|
||||
className: "city-label",
|
||||
interactive: true,
|
||||
});
|
||||
|
||||
const tooltip = marker.getTooltip();
|
||||
tooltip?.on("click", (event: L.LeafletMouseEvent) => {
|
||||
L.DomEvent.stop(event);
|
||||
onMarkerClickRef.current?.(m.id);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user