Map
The map package renders interactive maps from server-defined features. The public PHP and wire APIs use coordinates, providers, and typed features rather than Leaflet concepts. OpenStreetMap is the built-in provider; another package can add a Google Maps provider without changing page definitions.
The first release supports markers. A marker can display any Lattice component schema in a popup, including links, forms, and registered actions. Lines, polygons, editing, geocoding, routing, and clustering are outside the initial API.
Installation
Section titled “Installation”composer require lattice-php/mapComposer is the only install. The lattice() Vite plugin discovers the package through Composer
and adds only a small entry to the app bundle: the map component and its precompiled renderer —
with Leaflet bundled inside it, while React and the Lattice runtime remain shared with the host
app — load on demand the first time a page renders a map, so pages without a map never pay for
Leaflet. For a no-build app, run php artisan lattice:assets after
installation; it publishes the same self-contained renderer as a single standalone plugin.
In an app with a build step, import the map stylesheet in your application CSS — it positions the Leaflet panes and themes the controls, markers, and popups with the Lattice design tokens:
@import "@lattice-php/map/css";Map::make('offices') ->height(360) ->markers([ Marker::make('berlin') ->position(52.5200, 13.4050) ->label('Berlin office') ->popup([ Stack::make()->gap(Gap::Small)->schema([ Heading::make('Berlin office', 3), Text::make('Alexanderplatz 1'), ]), ]) ->open(), Marker::make('hamburg') ->position(53.5511, 9.9937) ->label('Hamburg office') ->color(ColorName::Warning), ]);- center:null
- height:360
- navigationControls:true
- provider:{"maximumZoom":19,"minimumZoom":1,"name":"openstreetmap","options":{"attribution":"© <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors","tileUrl":"https://tile.openstreetmap.org/{z}/{x}/{y}.png"}}
- scrollZoom:false
- zoom:null
- align:null
- direction:null
- float:null
- gap:"sm"
- height:null
- justify:null
- sticky:false
- width:null
- copyable:false
- level:3
- text:"Berlin office"
- tooltip:null
- align:null
- color:null
- copyable:false
- size:"md"
- text:"Alexanderplatz 1"
->open() marks one popup for automatic opening after the map initializes. Only one marker may be
open initially, and marker IDs must be unique. Labels supply each marker’s accessible name even
when the popup schema renders different text.
->icon() replaces the pin’s dot with any Lattice icon (a Lattice\Ui\Enums\Icon case, or the
sprite id of an app-registered icon), and ->color() tints the pin with a named Lattice color or
a CSS color. Markers without either keep the primary pin with the plain dot.
Without an explicit center, one marker opens at a practical street-level zoom and several markers are fitted into view. An empty map shows the world. Override the viewport and controls when needed:
Map::make('service-area') ->center(latitude: 52.52, longitude: 13.405) ->zoom(11) ->height(520) ->scrollZoom() ->navigationControls(false) ->markers($markers);Scroll-wheel zoom is disabled by default so a map embedded in a page does not capture normal page
scrolling — holding Cmd/Ctrl while scrolling (or a trackpad pinch) still zooms the map;
->scrollZoom() makes the plain wheel zoom too. Zoom values must fit both the general 0–24
range and the active provider’s range.
When a default zoom is set with ->zoom(), the map shows a reset control below the zoom buttons
that returns the viewport to its initial center and zoom after panning or zooming away.
->navigationControls(false) hides it together with the zoom buttons.
OpenStreetMap Tiles
Section titled “OpenStreetMap Tiles”The built-in provider uses the public OpenStreetMap tile service and includes the required attribution. This default is convenient for development and modest interactive use, but the public service has no SLA and is not a free general-purpose CDN. Production applications must follow the OpenStreetMap tile usage policy, keep attribution visible, and use a suitable commercial or self-hosted tile service when traffic or availability requirements demand it.
Override the tile endpoint without changing map definitions:
In config/map.php:
return [ 'default_provider' => 'openstreetmap', 'providers' => [ 'openstreetmap' => [ 'tile_url' => env('MAP_TILE_URL', 'https://tile.openstreetmap.org/{z}/{x}/{y}.png'), 'attribution' => '© OpenStreetMap contributors', 'minimum_zoom' => 1, 'maximum_zoom' => 19, ], ],];Adding a Provider
Section titled “Adding a Provider”A provider has one server and one client registration. The server implementation returns its stable name, provider-specific browser options, and supported zoom range:
use Lattice\Map\Contracts\MapProvider;use Lattice\Map\MapProviderData;use Lattice\Map\MapProviderRegistry;
final class GoogleMapsProvider implements MapProvider{ public function data(): MapProviderData { return new MapProviderData( name: 'google-maps', options: ['apiKey' => config('services.google_maps.key')], minimumZoom: 0, maximumZoom: 22, ); }}
app(MapProviderRegistry::class)->register(app(GoogleMapsProvider::class));Its Lattice plugin registers a React component under the matching map.providers key:
import type { Plugin } from "@lattice-php/core";import GoogleMap from "./google-map";
export default { name: "acme/google-maps", extensions: { "map.providers": { "google-maps": GoogleMap, }, },} satisfies Plugin;Applications then select it with Map::make()->provider('google-maps'). The map component keeps
the same markers, popup schemas, viewport, and controls contract; only the provider options and
renderer change.
Bundle Size
Section titled “Bundle Size”The report measures the precompiled map plugin. It includes Leaflet but externalizes React and the framework runtime, so it represents the package’s additional JavaScript — loaded only when a page actually renders a map.
48.9 KB gzipped · 192.1 KB raw JavaScript
| Dependency | Raw | Gzip | Share |
|---|---|---|---|
| @lattice-php/map | 6.1 KB | 2.1 KB | 4.3% |
| leaflet | 165.8 KB | 45.3 KB | 92.5% |
| Bundler runtime | 20.2 KB | 1.6 KB | 3.2% |
Emitted JavaScript files
| File | Raw | Gzip |
|---|---|---|
plugin.js | 192.1 KB | 48.9 KB |