Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ The Javascript & TypeScript Map Control component for <a href="https://www.mapti

The _MapTiler Geocoding control_ implements a powerful search box in your maps or online forms, enabling your application users to find any place on Earth down to individual addresses. Use the search box control with [MapTiler SDK JS](https://docs.maptiler.com/sdk-js/) (or other map libraries like [Leaflet](https://docs.maptiler.com/leaflet/), [MapLibre GL JS](https://github.com/maplibre/maplibre-gl-js), [OpenLayers](https://docs.maptiler.com/openlayers/)).

> ⚠️ _MapTiler Geocoding control_ v3 support for _Leaflet_ (v1 and v2) and _OpenLayers_ is to be added soon. In the meantime, please use _MapTiler Geocoding control_ v2 with these map libraries.

[![](https://img.shields.io/npm/v/@maptiler/geocoding-control?style=for-the-badge&labelColor=D3DBEC&color=f2f6ff&logo=npm&logoColor=333359)](https://www.npmjs.com/package/@maptiler/geocoding-control)
![](https://img.shields.io/badge/-white?style=for-the-badge&logo=javascript)![](https://img.shields.io/badge/-white?style=for-the-badge&logo=typescript)![](https://img.shields.io/badge/-white?style=for-the-badge&logo=react&logoColor=61dafb)![](https://img.shields.io/badge/-white?style=for-the-badge&logo=svelte&logoColor=FF3E00)

Expand Down
1 change: 1 addition & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default defineConfig(
},
},
rules: {
"@typescript-eslint/no-namespace": "off",
"import/default-imports-only": [
"error",
{
Expand Down
115 changes: 114 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,15 @@
"tslib": "^2.8.1",
"typescript": "~5.8.3",
"typescript-eslint": "^8.46.2",
"unplugin-replace": "^0.6.3",
"vite": "^7.1.12",
"vite-plugin-dts": "^4.5.4",
"vite-plugin-externalize-deps": "^0.10.0",
"vite-plugin-static-copy": "^3.1.4",
"vitest": "^4.0.8"
},
"peerDependencies": {
"@maptiler/sdk": "1 - 4",
"@maptiler/sdk": "1.0.7 - 4",
"leaflet": "1.5 - 2",
"maplibre-gl": "2 - 5",
"ol": "6 - 10"
Expand Down
5 changes: 5 additions & 0 deletions src/controls/base-control.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export interface GeocodingControlBase<Options extends object> {
/**
* Get copy of the control options.
*/
getOptions(): Options;

/**
* Update the control options.
*
Expand Down
33 changes: 14 additions & 19 deletions src/controls/leaflet-control.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
GeoJSON,
type LatLng,
type LatLngLiteral,
type LeafletEvent,
type LeafletMouseEvent,
type Map as LMap,
Marker,
Expand All @@ -25,17 +26,7 @@ import { getMask } from "../utils/mask";

import "../geocoder/geocoder";
import type { MaptilerGeocoderElement } from "../geocoder/geocoder";
import type {
FeaturesListedEvent,
MaptilerGeocoderEventName,
MaptilerGeocoderEventNameMap,
PickEvent,
QueryChangeEvent,
RequestEvent,
ResponseEvent,
ReverseToggleEvent,
SelectEvent,
} from "../geocoder/geocoder-events";
import type { MaptilerGeocoderEvent, MaptilerGeocoderEventName, MaptilerGeocoderEventNameMap } from "../geocoder/geocoder-events";
import type { GeocodingControlBase } from "./base-control";

import "../components/marker";
Expand Down Expand Up @@ -91,6 +82,10 @@ export class LeafletGeocodingControl extends EventedControl<LeafletGeocodingCont
this.#element = undefined;
}

getOptions(): LeafletGeocodingControlOptions {
return { ...this.options };
}

setOptions(options: LeafletGeocodingControlOptions) {
Object.assign(this.options, options);
this.#setElementOptions();
Expand Down Expand Up @@ -139,14 +134,14 @@ export class LeafletGeocodingControl extends EventedControl<LeafletGeocodingCont
#resultLayer?: GeoJSON;

#elementEventListeners: { [EventName in MaptilerGeocoderEventName]: (e: MaptilerGeocoderEventNameMap[EventName]) => void } = {
reversetoggle: (event: ReverseToggleEvent) => {
reversetoggle: (event: MaptilerGeocoderEvent.ReverseToggleEvent) => {
const container = this.#map?.getContainer();
if (container) {
container.style.cursor = event.detail.reverse ? "crosshair" : "";
}
this.#dispatch("reversetoggle", event.detail);
},
querychange: (event: QueryChangeEvent) => {
querychange: (event: MaptilerGeocoderEvent.QueryChangeEvent) => {
const coords = event.detail.reverseCoords;

this.#setReverseMarker(coords ? { lng: coords.decimalLongitude, lat: coords.decimalLatitude } : undefined);
Expand All @@ -156,13 +151,13 @@ export class LeafletGeocodingControl extends EventedControl<LeafletGeocodingCont
this.#setReverseMarker(undefined);
this.#dispatch("queryclear");
},
request: (event: RequestEvent) => {
request: (event: MaptilerGeocoderEvent.RequestEvent) => {
this.#dispatch("request", event.detail);
},
response: (event: ResponseEvent) => {
response: (event: MaptilerGeocoderEvent.ResponseEvent) => {
this.#dispatch("response", event.detail);
},
select: (event: SelectEvent) => {
select: (event: MaptilerGeocoderEvent.SelectEvent) => {
const selected = event.detail.feature;
if (selected && this.#flyToEnabled && this.options.flyToSelected) {
this.#flyTo({ lng: selected.center[0], lat: selected.center[1] }, this.#computeZoom(selected));
Expand All @@ -172,7 +167,7 @@ export class LeafletGeocodingControl extends EventedControl<LeafletGeocodingCont
}
this.#dispatch("select", event.detail);
},
pick: (event: PickEvent) => {
pick: (event: MaptilerGeocoderEvent.PickEvent) => {
const picked = event.detail.feature;
if (picked && picked.id !== this.#prevIdToFly && this.#flyToEnabled) {
this.#goToPicked(picked);
Expand All @@ -189,7 +184,7 @@ export class LeafletGeocodingControl extends EventedControl<LeafletGeocodingCont
featureshide: () => {
this.#dispatch("featureshide");
},
featureslisted: (event: FeaturesListedEvent) => {
featureslisted: (event: MaptilerGeocoderEvent.FeaturesListedEvent) => {
const features = event.detail.features;
this.#markedFeatures = features;
this.#setFeatures(this.#markedFeatures, undefined);
Expand Down Expand Up @@ -247,7 +242,7 @@ export class LeafletGeocodingControl extends EventedControl<LeafletGeocodingCont
this.#map.off(this.#mapEventListeners);
}

#dispatch<E extends LeafletGeocodingControlEventName>(type: E, detail?: LeafletGeocodingControlEventNameMap[E]): this {
#dispatch<E extends LeafletGeocodingControlEventName>(type: E, detail?: Omit<LeafletGeocodingControlEventNameMap[E], keyof LeafletEvent>): this {
return super.fire(type, detail);
}

Expand Down
67 changes: 48 additions & 19 deletions src/controls/leaflet-events.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,62 @@
import type { Marker } from "leaflet";
import type { LeafletEvent, Marker } from "leaflet";

import type { MaptilerGeocoderEvent } from "../geocoder/geocoder-events";
import type { Feature } from "../types";
import type { LeafletGeocodingControl } from "./leaflet-control";

type BaseEvent = Pick<LeafletEvent, "type" | "target"> & { target: LeafletGeocodingControl };

export namespace LeafletGeocodingControlEvent {
export type ReverseToggleEvent = BaseEvent & MaptilerGeocoderEvent.ReverseToggleEvent["detail"];
export type QueryChangeEvent = BaseEvent & MaptilerGeocoderEvent.QueryChangeEvent["detail"];
export type QueryClearEvent = BaseEvent;
export type RequestEvent = BaseEvent & MaptilerGeocoderEvent.RequestEvent["detail"];
export type ResponseEvent = BaseEvent & MaptilerGeocoderEvent.ResponseEvent["detail"];
export type SelectEvent = BaseEvent & MaptilerGeocoderEvent.SelectEvent["detail"];
export type PickEvent = BaseEvent & MaptilerGeocoderEvent.PickEvent["detail"];
export type FeaturesShowEvent = BaseEvent;
export type FeaturesHideEvent = BaseEvent;
export type FeaturesListedEvent = BaseEvent & MaptilerGeocoderEvent.FeaturesListedEvent["detail"];
export type FeaturesClearEvent = BaseEvent;
export type FocusInEvent = BaseEvent;
export type FocusOutEvent = BaseEvent;
export type MarkerClickEvent = BaseEvent & { feature: Feature; marker: Marker };
export type MarkerMouseEnterEvent = BaseEvent & { feature: Feature; marker: Marker };
export type MarkerMouseLeaveEvent = BaseEvent & { feature: Feature; marker: Marker };
}

export type ReverseToggleEvent = LeafletGeocodingControlEvent.ReverseToggleEvent;
export type QueryChangeEvent = LeafletGeocodingControlEvent.QueryChangeEvent;
export type QueryClearEvent = LeafletGeocodingControlEvent.QueryClearEvent;
export type RequestEvent = LeafletGeocodingControlEvent.RequestEvent;
export type ResponseEvent = LeafletGeocodingControlEvent.ResponseEvent;
export type SelectEvent = LeafletGeocodingControlEvent.SelectEvent;
export type PickEvent = LeafletGeocodingControlEvent.PickEvent;
export type FeaturesShowEvent = LeafletGeocodingControlEvent.FeaturesShowEvent;
export type FeaturesHideEvent = LeafletGeocodingControlEvent.FeaturesHideEvent;
export type FeaturesListedEvent = LeafletGeocodingControlEvent.FeaturesListedEvent;
export type FeaturesClearEvent = LeafletGeocodingControlEvent.FeaturesClearEvent;
export type FocusInEvent = LeafletGeocodingControlEvent.FocusInEvent;
export type FocusOutEvent = LeafletGeocodingControlEvent.FocusOutEvent;
export type MarkerClickEvent = LeafletGeocodingControlEvent.MarkerClickEvent;
export type MarkerMouseEnterEvent = LeafletGeocodingControlEvent.MarkerMouseEnterEvent;
export type MarkerMouseLeaveEvent = LeafletGeocodingControlEvent.MarkerMouseLeaveEvent;

import type * as Geocoder from "../geocoder/geocoder-events";

export type ReverseToggleEvent = Geocoder.ReverseToggleEvent["detail"];
export type QueryChangeEvent = Geocoder.QueryChangeEvent["detail"];
export type FeaturesListedEvent = Geocoder.FeaturesListedEvent["detail"];
export type RequestEvent = Geocoder.RequestEvent["detail"];
export type ResponseEvent = Geocoder.ResponseEvent["detail"];
export type SelectEvent = Geocoder.SelectEvent["detail"];
export type PickEvent = Geocoder.PickEvent["detail"];
export type MarkerClickEvent = { feature: Feature; marker: Marker };
export type MarkerMouseEnterEvent = { feature: Feature; marker: Marker };
export type MarkerMouseLeaveEvent = { feature: Feature; marker: Marker };
export type LeafletGeocodingControlEventNameMap = {
reversetoggle: ReverseToggleEvent;
querychange: QueryChangeEvent;
queryclear: never;
queryclear: QueryClearEvent;
request: RequestEvent;
response: ResponseEvent;
select: SelectEvent;
pick: PickEvent;
featuresshow: never;
featureshide: never;
featuresshow: FeaturesShowEvent;
featureshide: FeaturesHideEvent;
featureslisted: FeaturesListedEvent;
featuresclear: never;
featuresclear: FeaturesClearEvent;

focusin: never;
focusout: never;
focusin: FocusInEvent;
focusout: FocusOutEvent;

markerclick: MarkerClickEvent;
markermouseenter: MarkerMouseEnterEvent;
Expand Down
Loading