Skip to content

Layout Engine

The engine is a small, HA-agnostic pipeline. Everything that knows about Home Assistant internals is quarantined in HaDomAdapter; the rest works against plain data structures and is unit-testable.

text
LayoutManager (booted once per page)
  ├─ HaDomAdapter    locate Sections views  (ALL Home Assistant coupling lives here)
  ├─ RuntimeContext  screen size, narrow, touch, fullscreen, browser_id, user
  ├─ RulesEngine     pure function: RuntimeContext → LayoutId
  └─ Renderer        apply the chosen Layout to each located view
        └─ Layout    { id; matches?; apply(target): Disposable }
             ├─ StandardLayout   no-op (native rendering)
             ├─ SwipeLayout      scroll-snap pager (1 section = 1 page)
             ├─ CarouselLayout   (later)
             └─ KioskLayout / TVLayout (later)

Layouts are pluggable

A Layout implements a single method, apply(target, context), and returns a Disposable. Switching layouts disposes the previous one — removing any injected <style> and listeners — so there are no leaks and no residue.

Layouts are CSS-first: apply typically injects a scoped stylesheet targeting the located view and returns a teardown handle. JavaScript only orchestrates (page dots, keyboard and gesture navigation, re-evaluation on resize or edit-mode toggle) — it never rebuilds the dashboard.

Runtime rules

RulesEngine is a pure function mapping the current RuntimeContext to a LayoutId. v1 ships built-in defaults only:

  • Edit mode → standard (so the native editor keeps working).
  • Touch + narrow (phones) → swipe.
  • Everything else → standard.

v2 will let Config Entries override these defaults (per device, user, or media query) without YAML.

Released under the MIT License.