import { A_Caller, A_Inject } from "@adaas/a-concept"; import { Are, AreNode } from "@adaas/are"; import { AreHTMLNode } from "src"; import { AreRoute } from "src/signals/AreRoute.signal"; /** * About page — rendered when the route is "/about". */ @Are.Condition([new AreRoute('/about')]) export class AboutPage extends Are { @Are.Template template(@A_Inject(A_Caller) node: AreNode) { node.setContent(`

About this example

This example demonstrates signal-based SPA routing using the ARE framework.

How it works

  1. Signal emitted — clicking a nav link calls bus.emit(new AreRoute('/about')) and updates the browser URL via history.pushState.
  2. AreRoot reacts — the root node is subscribed to the signal bus. When the vector matches a registered condition it replaces its inner content with the mapped component.
  3. Page renders — the new component goes through the normal ARE lifecycle: @Are.Template@Are.Data@Are.Styles → mount.

Key pieces

AreRoute(path)Signal carrying the new URL path.
AreRouteWatcherListens to popstate / pushState and re-emits the signal on browser back/forward.
AreSignalsContextFragment that maps (rootId, signal vector) → component class.
A_SignalStatePersists the last emitted signal so a fresh page load still routes correctly.
`); } @Are.Styles styles(@A_Inject(A_Caller) node: AreHTMLNode) { node.setStyles(` .page { padding: 48px 40px; max-width: 860px; margin: 0 auto; } .page-title { font-size: 32px; font-weight: 800; color: #f4f4f5; margin-bottom: 12px; } .page-subtitle { font-size: 16px; color: #a1a1aa; line-height: 1.7; margin-bottom: 36px; } .about-block { margin-bottom: 40px; } .about-block h2 { font-size: 18px; font-weight: 700; color: #e4e4e7; margin-bottom: 16px; padding-bottom: 8px; border-bottom: 1px solid #27272a; } .steps { padding-left: 24px; color: #a1a1aa; line-height: 2; font-size: 14px; } .steps li { margin-bottom: 8px; } .steps strong { color: #e4e4e7; } .steps code, .info-table code { background: #27272a; padding: 1px 6px; border-radius: 4px; color: #a78bfa; font-size: 12px; } .info-table { width: 100%; border-collapse: collapse; font-size: 14px; } .info-table tr { border-bottom: 1px solid #27272a; } .info-table th { text-align: left; padding: 10px 12px; color: #a78bfa; font-weight: 600; width: 200px; } .info-table td { padding: 10px 12px; color: #a1a1aa; } `); } }