diff --git a/jsconfig.json b/jsconfig.json
new file mode 100644
index 0000000..e747a0d
--- /dev/null
+++ b/jsconfig.json
@@ -0,0 +1,6 @@
+{
+ "compilerOptions": {
+ "target": "es2020",
+ "types": ["vitest/importMeta"]
+ }
+}
diff --git a/src/example.js b/src/example.js
new file mode 100644
index 0000000..014c480
--- /dev/null
+++ b/src/example.js
@@ -0,0 +1,25 @@
+// @ts-check
+///
+import { circle } from "leaflet";
+const addTo = "addTo";
+
+class Bar extends HTMLElement {
+ constructor() {
+ super();
+ this.addEventListener(addTo, (ev) => {
+ ev.detail.layer;
+ });
+ }
+
+ documentConnected() {
+ /** @type AddToEvent */
+ const event = new CustomEvent(addTo, {
+ detail: {
+ layer: circle([1, 1], { radius: 5 }),
+ },
+ });
+ this.dispatchEvent(event);
+ }
+}
+
+export default Bar;
diff --git a/src/index.d.ts b/src/index.d.ts
new file mode 100644
index 0000000..a6f1d75
--- /dev/null
+++ b/src/index.d.ts
@@ -0,0 +1,18 @@
+import type { Icon, Layer } from "leaflet";
+import type { LIcon } from "l-icon";
+
+declare global {
+ type AddToEvent = CustomEvent<{ layer: Layer }>;
+ type BindPopupEvent = CustomEvent<{ content: string }>;
+ type SetIconEvent = CustomEvent<{ icon: Icon }>;
+
+ interface HTMLElementEventMap {
+ addTo: AddToEvent;
+ bindPopup: BindPopupEvent;
+ setIcon: SetIconEvent;
+ }
+
+ interface HTMLElementTagNameMap {
+ "l-icon": LIcon;
+ }
+}
diff --git a/src/l-icon.js b/src/l-icon.js
index 1499597..dcef705 100644
--- a/src/l-icon.js
+++ b/src/l-icon.js
@@ -1,7 +1,8 @@
+// @ts-check
+///
// @vitest-environment happy-dom
import * as L from "leaflet";
-import { kebabToCamel } from "./util.js";
-
+import { kebabToCamel } from "./util.js";
class LIcon extends HTMLElement {
constructor() {
@@ -10,6 +11,7 @@ class LIcon extends HTMLElement {
}
connectedCallback() {
+ /** @type {import("leaflet").IconOptions} */
const options = {};
// Strings
@@ -42,11 +44,13 @@ class LIcon extends HTMLElement {
});
if (this.hasAttribute("cross-origin")) {
- options.crossOrigin = this.getAttribute("cross-origin") === "true";
+ let k = "crossOrigin";
+ options[k] = this.getAttribute("cross-origin") === "true";
}
this.icon = L.icon(options);
- const event = new CustomEvent("icon:add", {
+ /** @type SetIconEvent */
+ const event = new CustomEvent("setIcon", {
cancelable: true,
bubbles: true,
detail: {
@@ -75,8 +79,10 @@ if (import.meta.vitest) {
it("emits icon:add event", async () => {
const el = document.createElement("l-icon");
+ /** @type {keyof HTMLElementEventMap} */
+ const eventName = "setIcon";
let promise = new Promise((resolve) => {
- el.addEventListener("icon:add", (ev) => {
+ el.addEventListener(eventName, (ev) => {
resolve(ev.detail.icon);
});
});
diff --git a/src/l-marker.js b/src/l-marker.js
index 09947a4..fceaa5c 100644
--- a/src/l-marker.js
+++ b/src/l-marker.js
@@ -1,6 +1,8 @@
+// @ts-check
+///
// @vitest-environment happy-dom
import * as L from "leaflet";
-import { mapAddTo, popupAdd } from "./events.js";
+import { mapAddTo } from "./events.js";
import LLayer from "./l-layer.js";
class LMarker extends LLayer {
@@ -9,7 +11,7 @@ class LMarker extends LLayer {
constructor() {
super();
this.layer = null;
- this.addEventListener("icon:add", (ev) => {
+ this.addEventListener("setIcon", (ev) => {
ev.stopPropagation();
this.layer.setIcon(ev.detail.icon);
});
@@ -24,9 +26,9 @@ class LMarker extends LLayer {
this.layer.setIcon(icon);
}
- this.setAttribute("leaflet-id", L.stamp(this.layer));
+ this.setAttribute("leaflet-id", L.stamp(this.layer).toString());
- this.addEventListener(popupAdd, (ev) => {
+ this.addEventListener("bindPopup", (ev) => {
const { content } = ev.detail;
this.layer.bindPopup(content);
});
@@ -41,6 +43,11 @@ class LMarker extends LLayer {
this.dispatchEvent(event);
}
+ /**
+ * @param {string} name
+ * @param {string} _oldValue
+ * @param {string} newValue
+ */
attributeChangedCallback(name, _oldValue, newValue) {
if (this.layer !== null) {
if (name === "lat-lng") {
diff --git a/src/l-popup.js b/src/l-popup.js
index bdd5ed1..e3d83ae 100644
--- a/src/l-popup.js
+++ b/src/l-popup.js
@@ -1,5 +1,5 @@
// @ts-check
-import { popupAdd } from "./events.js";
+///
class LPopup extends HTMLElement {
constructor() {
@@ -8,7 +8,8 @@ class LPopup extends HTMLElement {
connectedCallback() {
const content = this.getAttribute("content");
- const event = new CustomEvent(popupAdd, {
+ /** @type {BindPopupEvent} */
+ const event = new CustomEvent("bindPopup", {
cancelable: true,
bubbles: true,
detail: {