The shared body of every layer component.
MapLibre's eight layer types differ only in which paint and layout
properties they accept. The specification shape, the update rules and the
event surface are identical. Rather than repeat that eight times, each layer
component is one use away from the whole thing:
defmodule HoloMap.Layer.Fill do
use HoloMap.Layer.Base, type: "fill"
endPassing no :type produces HoloMap.Layer, where the caller supplies it.
How the type is fixed
A type-specific component does not declare a type prop at all. The literal
is baked into its template when the macro expands. That is deliberate: a
values: ["fill"] constraint would only be checked while rendering, and this
way there is nothing to check, because there is no way to pass a type in.
What the injected component does
It renders one definition element whose data-hm-spec is a MapLibre layer
object. When a prop changes, the reconciler picks the narrowest update
available: setPaintProperty for a paint change, setLayoutProperty for
layout, setFilter for a filter, setLayerZoomRange for a zoom range. Only
a change to type, source or source_layer, none of which MapLibre can
change in place, forces a remove-and-re-add.
Summary
Functions
Injects the props, template and specification builder of a layer component.
Builds the JSON layer specification for a definition element.
Functions
Injects the props, template and specification builder of a layer component.
Options
:type, the MapLibre layer type this component is locked to. When given, the type is a literal in the generated template and there is notypeprop. When omitted,typebecomes a required prop.
Builds the JSON layer specification for a definition element.
Paint and layout maps are dasherized (fill_color becomes "fill-color"),
the visible prop is folded into layout.visibility, and empty paint or
layout maps are dropped so an untouched layer keeps MapLibre's defaults.
iex> HoloMap.Layer.Base.build(%{type: "fill", source: "parcels", paint: %{fill_color: "#f00"},
...> layout: %{}, filter: nil, min_zoom: nil, max_zoom: nil, before_id: nil,
...> visible: nil, metadata: nil, source_layer: nil})
~s({"paint":{"fill-color":"#f00"},"source":"parcels","type":"fill"})