diff --git a/demo/index.tsx b/demo/index.tsx
index 4262ac2..504e7c5 100644
--- a/demo/index.tsx
+++ b/demo/index.tsx
@@ -1,31 +1,39 @@
-import { Component, createSignal } from "solid-js";
-import { render } from "solid-js/web";
-import { LMap, LMarker } from "../lib";
-
-import { LatLng } from "leaflet";
-import "leaflet/dist/leaflet.css";
-
-const Demo: Component = () => {
- const [op, setOp] = createSignal(1);
-
- // const opacity = (delta: number) => {
- // setOp(Math.abs(Math.sin(delta / 1000)));
- // requestAnimationFrame(opacity);
- // };
- // requestAnimationFrame(opacity);
-
- return (
-
-
-
-
- );
-};
-
-render(() => , document.getElementById("app")!);
+import { Component, createSignal } from "solid-js";
+import { render } from "solid-js/web";
+import { LMap, LMarker, LTileLayer } from "../lib";
+
+import { LatLng } from "leaflet";
+import "leaflet/dist/leaflet.css";
+
+const Demo: Component = () => {
+ const [op, setOp] = createSignal(1);
+
+ //const opacity = (delta: number) => {
+ // setOp(Math.abs(Math.sin(delta / 1000)));
+ // requestAnimationFrame(opacity);
+ //};
+ //requestAnimationFrame(opacity);
+
+ return (
+
+ OpenStreetMap",
+ }}
+ />
+
+
+
+ );
+};
+
+render(() => , document.getElementById("app")!);
diff --git a/lib/LTileLayer/LTileLayer.tsx b/lib/LTileLayer/LTileLayer.tsx
new file mode 100644
index 0000000..2243e71
--- /dev/null
+++ b/lib/LTileLayer/LTileLayer.tsx
@@ -0,0 +1,39 @@
+import { TileLayer, TileLayerOptions } from "leaflet";
+import { Component, createEffect, JSX, onCleanup, onMount } from "solid-js";
+import { useMapContext } from "../MapContext";
+import { setupEventListeners } from "../_utils/events";
+import { LTileLayerListeners, events } from "./events";
+
+type LTileLayerProps = {
+ options?: TileLayerOptions;
+ children?: JSX.Element;
+ urlTemplate: string;
+} & LTileLayerListeners;
+
+export const LTileLayer: Component = (p) => {
+ const [{ map }] = useMapContext();
+
+ let tileLayer: TileLayer;
+
+ onMount(() => {
+ tileLayer = new TileLayer(p.urlTemplate, p.options);
+ tileLayer.addTo(map);
+
+ const { cleanup } = setupEventListeners(tileLayer, events, p);
+
+ onCleanup(() => {
+ tileLayer.remove();
+ cleanup();
+ });
+ });
+
+ createEffect(
+ () =>
+ p.options?.opacity !== undefined &&
+ tileLayer.setOpacity(p.options.opacity)
+ );
+
+ createEffect(() => tileLayer.setUrl(p.urlTemplate));
+
+ return undefined;
+};
diff --git a/lib/LTileLayer/events.ts b/lib/LTileLayer/events.ts
new file mode 100644
index 0000000..85f994e
--- /dev/null
+++ b/lib/LTileLayer/events.ts
@@ -0,0 +1,21 @@
+import { ListenerProps } from "../types";
+
+export const events = [
+ "tileabort",
+ "loading",
+ "tileunload",
+ "tileloadstart",
+ "tileerror",
+ "tileload",
+ "load",
+ "add",
+ "remove",
+ "popupopen",
+ "popupclose",
+ "tooltipopen",
+ "tooltipclose",
+] as const;
+
+type LTileLayerEvents = (typeof events)[number];
+
+export type LTileLayerListeners = ListenerProps;
diff --git a/lib/index.tsx b/lib/index.tsx
index 558c37c..1039fe6 100644
--- a/lib/index.tsx
+++ b/lib/index.tsx
@@ -1,2 +1,3 @@
-export * from "./LMap/LMap";
-export * from "./LMarker/LMarker";
+export * from "./LMap/LMap";
+export * from "./LMarker/LMarker";
+export * from "./LTileLayer/LTileLayer";
diff --git a/lib/types.ts b/lib/types.ts
index 20da1d4..2d04ade 100644
--- a/lib/types.ts
+++ b/lib/types.ts
@@ -1,75 +1,83 @@
-import {
- DragEndEventHandlerFn,
- ErrorEventHandlerFn,
- LayerEventHandlerFn,
- LayersControlEventHandlerFn,
- LeafletEventHandlerFn,
- LeafletKeyboardEventHandlerFn,
- LeafletMouseEventHandlerFn,
- LocationEventHandlerFn,
- PopupEventHandlerFn,
- ResizeEventHandlerFn,
- TooltipEventHandlerFn,
- ZoomAnimEventHandlerFn,
-} from "leaflet";
-
-export type LeafletEvents = {
- // layer events
- baselayerchange: LayersControlEventHandlerFn;
- overlayadd: LayersControlEventHandlerFn;
- overlayremove: LayersControlEventHandlerFn;
- layeradd: LayerEventHandlerFn;
- layerremove: LayerEventHandlerFn;
- // map state change events
- zoomlevelschange: LeafletEventHandlerFn;
- resize: ResizeEventHandlerFn;
- unload: LeafletEventHandlerFn;
- viewreset: LeafletEventHandlerFn;
- load: LeafletEventHandlerFn;
- zoomstart: LeafletEventHandlerFn;
- movestart: LeafletEventHandlerFn;
- zoom: LeafletEventHandlerFn;
- move: LeafletEventHandlerFn;
- zoomend: LeafletEventHandlerFn;
- moveend: LeafletEventHandlerFn;
- // popup events
- popupopen: PopupEventHandlerFn;
- popupclose: PopupEventHandlerFn;
- autopanstart: LeafletEventHandlerFn;
- // tooltip events
- tooltipopen: TooltipEventHandlerFn;
- tooltipclose: TooltipEventHandlerFn;
- // location events
- locationerror: ErrorEventHandlerFn;
- locationfound: LocationEventHandlerFn;
- // interaction events
- click: LeafletMouseEventHandlerFn;
- dblclick: LeafletMouseEventHandlerFn;
- mousedown: LeafletMouseEventHandlerFn;
- mouseup: LeafletMouseEventHandlerFn;
- mouseover: LeafletMouseEventHandlerFn;
- mouseout: LeafletMouseEventHandlerFn;
- mousemove: LeafletMouseEventHandlerFn;
- contextmenu: LeafletMouseEventHandlerFn;
- keypress: LeafletKeyboardEventHandlerFn;
- keydown: LeafletKeyboardEventHandlerFn;
- keyup: LeafletKeyboardEventHandlerFn;
- preclick: LeafletMouseEventHandlerFn;
- // other events
- zoomanim: ZoomAnimEventHandlerFn;
- // dragging events
- dragstart: LeafletEventHandlerFn;
- drag: LeafletEventHandlerFn;
- dragend: DragEndEventHandlerFn;
- // layer events
- add: LeafletEventHandlerFn;
- remove: LeafletEventHandlerFn;
-};
-
-export type LeafletEventName = keyof LeafletEvents;
-
-export type ListenerPropName = `l${Capitalize}`;
-
-export type ListenerProps = {
- [Property in T as ListenerPropName]?: LeafletEvents[Property];
-};
+import {
+ DragEndEventHandlerFn,
+ ErrorEventHandlerFn,
+ LayerEventHandlerFn,
+ LayersControlEventHandlerFn,
+ LeafletEventHandlerFn,
+ LeafletKeyboardEventHandlerFn,
+ LeafletMouseEventHandlerFn,
+ LocationEventHandlerFn,
+ PopupEventHandlerFn,
+ ResizeEventHandlerFn,
+ TooltipEventHandlerFn,
+ ZoomAnimEventHandlerFn,
+} from "leaflet";
+
+export type LeafletEvents = {
+ // layer events
+ baselayerchange: LayersControlEventHandlerFn;
+ overlayadd: LayersControlEventHandlerFn;
+ overlayremove: LayersControlEventHandlerFn;
+ layeradd: LayerEventHandlerFn;
+ layerremove: LayerEventHandlerFn;
+ // map state change events
+ zoomlevelschange: LeafletEventHandlerFn;
+ resize: ResizeEventHandlerFn;
+ unload: LeafletEventHandlerFn;
+ viewreset: LeafletEventHandlerFn;
+ load: LeafletEventHandlerFn;
+ zoomstart: LeafletEventHandlerFn;
+ movestart: LeafletEventHandlerFn;
+ zoom: LeafletEventHandlerFn;
+ move: LeafletEventHandlerFn;
+ zoomend: LeafletEventHandlerFn;
+ moveend: LeafletEventHandlerFn;
+ // popup events
+ popupopen: PopupEventHandlerFn;
+ popupclose: PopupEventHandlerFn;
+ autopanstart: LeafletEventHandlerFn;
+ // tooltip events
+ tooltipopen: TooltipEventHandlerFn;
+ tooltipclose: TooltipEventHandlerFn;
+ // location events
+ locationerror: ErrorEventHandlerFn;
+ locationfound: LocationEventHandlerFn;
+ // interaction events
+ click: LeafletMouseEventHandlerFn;
+ dblclick: LeafletMouseEventHandlerFn;
+ mousedown: LeafletMouseEventHandlerFn;
+ mouseup: LeafletMouseEventHandlerFn;
+ mouseover: LeafletMouseEventHandlerFn;
+ mouseout: LeafletMouseEventHandlerFn;
+ mousemove: LeafletMouseEventHandlerFn;
+ contextmenu: LeafletMouseEventHandlerFn;
+ keypress: LeafletKeyboardEventHandlerFn;
+ keydown: LeafletKeyboardEventHandlerFn;
+ keyup: LeafletKeyboardEventHandlerFn;
+ preclick: LeafletMouseEventHandlerFn;
+ // other events
+ zoomanim: ZoomAnimEventHandlerFn;
+ // dragging events
+ dragstart: LeafletEventHandlerFn;
+ drag: LeafletEventHandlerFn;
+ dragend: DragEndEventHandlerFn;
+ // layer events
+ add: LeafletEventHandlerFn;
+ remove: LeafletEventHandlerFn;
+ // grid layer events
+ loading: LeafletEventHandlerFn;
+ tileunload: LeafletEventHandlerFn;
+ tileloadstart: LeafletEventHandlerFn;
+ tileerror: ErrorEventHandlerFn;
+ tileload: LeafletEventHandlerFn;
+ // tile layer events
+ tileabort: LeafletEventHandlerFn;
+};
+
+export type LeafletEventName = keyof LeafletEvents;
+
+export type ListenerPropName = `l${Capitalize}`;
+
+export type ListenerProps = {
+ [Property in T as ListenerPropName]?: LeafletEvents[Property];
+};