<.leaflet_map>: an interactive map (Leaflet), through Xenia's official adapter.
Setup
Install the library in your app:
npm install leaflet --prefix assetsPass it to the adapter, and register it, in assets/js/app.js:
import { createLeaflet } from "xenia/leaflet"
const leaflet = createLeaflet({
load: () => import("leaflet"),
})
hooks: { ...colocatedHooks, ...createHooks({ Leaflet: leaflet }) },And its CSS, in assets/css/app.css:
@import "../node_modules/leaflet/dist/leaflet.css";Then import Xenia.Adapters.Leaflet in html_helpers, and render
<.leaflet_map id="..."> with the props below. Every event becomes an
on_<event> attribute; commands go through Xenia.push_to/4.
The factory returns a plain adapter object: spread it to add or change props, commands and events, without copying the adapter.
The tag uses the adapter name "Leaflet". To register it under
another name, render <.xenia adapter="..."> or declare your own tag.
Reference
Xenia's official adapter for Leaflet (v1.9): interactive maps with markers, GeoJSON layers, popups and viewport events.
Props:
center [lat, lng] applied when it differs from the current view
zoom number
tiles URL template (default OpenStreetMap) or
%{url, attribution, max_zoom, subdomains, ...}
markers [%{id, lat, lng, popup?, tooltip?, draggable?, color?,
icon_url?, icon_size?}] synced by id
geojson a GeoJSON object (Feature or FeatureCollection)
geojson_style %{color, weight, fill_color, fill_opacity, ...}, or per
feature: properties.style in the GeoJSON itself
fit "markers" | "geojson" | "all": fit the view to that data
whenever it changes (ignores center/zoom while set)
options Leaflet map options at mount: min_zoom, max_zoom,
scroll_wheel_zoom, zoom_control, dragging, ... (snake_case
or camelCase). Changing them remounts the map.Commands:
fly_to %{lat, lng, zoom?}, set_view %{lat, lng, zoom?}
fit_bounds %{bounds: [[south, west], [north, east]], padding?}
fit_markers %{padding?}, fit_geojson %{padding?}
zoom_in, zoom_out
open_popup %{id}, close_popup
locate ask the browser for the user's position
invalidate_size after the container changed size by itselfEvents:
ready %{center, zoom, bounds}
click %{lat, lng}
move_end %{center, zoom, bounds} debounced 200 ms
marker_click %{id, lat, lng}
marker_drag_end %{id, lat, lng}
feature_click %{id, properties, lat, lng}
located %{lat, lng, accuracy}
error %{source, message, code}
bounds is [[south, west], [north, east]].The container needs a height (e.g. style="height: 400px"), and Leaflet's CSS must be loaded once, e.g. in app.css:
@import "../node_modules/leaflet/dist/leaflet.css";Markers are drawn as inline SVG pins, so no marker image files are needed.
Summary
Functions
Attributes
id(:string) (required) - Stable DOM id used for adapter commands.center(:list)zoom(:any)tiles(:any)markers(:list)geojson(:map)geojson_style(:map)fit(:string)options(:map)on_ready(:string) - LiveView event triggered when the adapter emits :ready. Defaults tonil.on_click(:string) - LiveView event triggered when the adapter emits :click. Defaults tonil.on_move_end(:string) - LiveView event triggered when the adapter emits :move_end. Defaults tonil.on_marker_click(:string) - LiveView event triggered when the adapter emits :marker_click. Defaults tonil.on_marker_drag_end(:string) - LiveView event triggered when the adapter emits :marker_drag_end. Defaults tonil.on_feature_click(:string) - LiveView event triggered when the adapter emits :feature_click. Defaults tonil.on_located(:string) - LiveView event triggered when the adapter emits :located. Defaults tonil.on_error(:string) - LiveView event triggered when the adapter emits :error. Defaults tonil.shortcuts(:map) - Key combination => LiveView event, while focus is inside (see Xenia.Shortcuts). Defaults to%{}.on_crash(:string) - LiveView event sent if the adapter throws (see Xenia.Component). Defaults tonil.- Global attributes are accepted.
Slots
loading- Shown until the island's first mount finishes.error- Shown if the adapter throws; data-xenia-retry starts it again.