Maarten LakerveldandCopilot Autofix powered by AI ac582cbfbb Run ha-map on a runtime-selected engine: MapLibre GL native or Leaflet (#54022)
* Run ha-map on a runtime-selected engine: MapLibre GL native or Leaflet

ha-map no longer drives Leaflet directly. All primitive operations -
camera, HTML element markers, meter-radius circles, history paths,
clustering with a pluggable icon builder, scale ruler, dark mode - go
through a MapEngine interface, and the engine is selected at runtime:

- MapLibreMapEngine renders the vector base map natively where WebGL2 is
  available, without Leaflet in the loop: continuous fractional zoom,
  DOM markers synced to the basemap every frame, GeoJSON zone and
  accuracy circles below the labels, GeoJSON history trails with hover
  popups, and a pixel-distance cluster grid recomputed when the camera
  settles. Dark mode swaps the style while carrying the custom layers
  over, and rotation and pitch stay disabled for north-up dashboards.
- LeafletMapEngine wraps the existing behavior unchanged (vector tiles
  through the maplibre adapter with the raster fallback, markercluster)
  for browsers without WebGL2 - the legacy floor includes iOS 12-14 and
  kiosk browsers without hardware acceleration - and for
  ha-locations-editor, which manages raw Leaflet layers with
  leaflet-draw and declares engine=leaflet.

A permanently lost WebGL context rebuilds the map on the Leaflet engine
instead of leaving a dead canvas. Zoom levels keep Leaflet semantics
across engines. MapLibre's stylesheet is shipped to /static/map for the
native engine's controls and popups.

* Enhance keyboard accessibility for icon click

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Fix dark mode style application logic

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Address code review on the map engine

A fatal engine event during setup was dropped because the in-flight
setup owned the loading flag; the fallback request is now recorded and
setup switches to Leaflet once init settles. Entity markers accept Enter
and Space, as both engines make them focusable buttons. History points
show their popup on tap as well as hover, since touch has no hover.

Tests cover the engine choice and fallback paths, including a fatal
event mid-setup, and the MapLibre engine itself against a fake map:
style swaps, queued layer work, custom layer carry-over, failed style
requests, token refusal recovery, context-loss grace, and clustering.

* Address second code review round on the map engine

A cluster whose members share a spot, or that sits at maximum zoom,
could never be opened: fitting its bounds changed nothing and the next
regroup recreated it. Activating such a cluster now opens it: all its
members are shown in a bubble with a tail pointing at their spot, each
reachable on its own, until the map moves again.

An engine whose init failed, or was abandoned by a disconnect or a fatal
event during setup, was never destroyed and could keep a WebGL context;
setup now destroys any engine that did not become the active one.

The Leaflet engine sizes the cluster element like MapLibre does, so
cluster bubbles no longer shrink to their text.

* Keep the engine's own record of its map sources and layers

Carrying zone circles and history paths over a style swap relied on
MapLibre serializing the outgoing style into transformStyle's previous
argument. The engine now keeps the source and layer specifications it
added and rebuilds them into the new style itself, so the carry-over no
longer depends on what MapLibre hands over, and a missing previous style
cannot drop them.

* Address review: setup teardown, marker input, cluster focus

An engine still setting up could not be torn down: ha-map only held it
once init resolved, so removing the element mid-load kept its WebGL
context alive and left the loading guard set, ignoring a reconnect. The
engine being set up is now tracked and destroyed on disconnect, a stale
setup notices it was superseded, and the MapLibre engine settles a
pending init when destroyed.

Non-interactive markers let pointer input through, as they do on
Leaflet. Opening a cluster from the keyboard moves focus to its first
member, and a member that has focus when the bubble closes hands it to
the icon that replaces it.

* Tear down an engine that fails while still setting up

A fatal event during setup only flagged the fallback and waited for
init to settle, which relied on MapLibre still firing style.load. The
engine being set up is destroyed instead, which settles its init, so the
setup hands over to Leaflet without depending on the failed engine.

* Make history point popups readable on MapLibre

MapLibre's stylesheet is linked into the map's shadow root and wins over
the component styles on equal specificity, property by property: its
white popup background applied while our white text color did too,
leaving the timestamp invisible. The popup rules now carry !important,
as the Leaflet tooltip rules already do for the same reason.

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-09-09 15:26:28 +03:00
2026-01-22 13:30:33 +01:00
2026-08-02 09:45:09 +02:00
2026-09-02 08:15:36 +03:00
2026-09-09 07:08:22 +02:00
…
2026-09-02 08:15:36 +03:00
2026-08-19 18:45:22 +00:00
2026-08-29 09:08:01 +02:00
2026-08-02 09:45:09 +02:00
…
2026-07-09 06:51:15 +02:00
2026-08-26 14:47:19 +02:00

Home Assistant Frontend

This is the repository for the official Home Assistant frontend.

Screenshot of the frontend

Development

  • Initial setup: script/setup
  • Development: Instructions
  • Production build: yarn build
  • Gallery: cd gallery && script/develop_gallery

Frontend development

Classic environment

A complete guide can be found at the following link. It describes a short guide for the build of project.

License

Home Assistant is open-source and Apache 2 licensed. Feel free to browse the repository, learn and reuse parts in your own projects.

We use BrowserStack to test Home Assistant on a large variety of devices.

Home Assistant - A project from the Open Home Foundation

Languages
TypeScript 98.2%
JavaScript 1.7%