@real-router/angular 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -320,6 +320,16 @@ Navigation directive for `<a>` elements. Handles click events, sets `href`, and
320
320
  | `activeClassName` | `string` | `"active"` | CSS class applied when route is active |
321
321
  | `activeStrict` | `boolean` | `false` | Exact match only (no ancestor match) |
322
322
  | `ignoreQueryParams` | `boolean` | `true` | Query params don't affect active state |
323
+ | `hash` | `string` | `undefined`| URL fragment (decoded). Tri-state: undefined preserves, `""` clears, value sets. (#532) |
324
+
325
+ #### `hash` input — URL fragment / tab-style UIs
326
+
327
+ ```html
328
+ <a [realLink]="'settings'" [hash]="'profile'">Profile</a>
329
+ <a [realLink]="'settings'" [hash]="'account'">Account</a>
330
+ ```
331
+
332
+ Active class is hash-aware — only the matching tab lights up. Live demo: [`examples/web/react/link-hash/`](../../examples/web/react/link-hash/) — behavior is identical across adapters, only template syntax differs. See the [Hash Fragment Support](https://github.com/greydragon888/real-router/wiki/Hash) wiki page for the full surface.
323
333
 
324
334
  ### `[realLinkActive]`
325
335
 
package/dist/README.md CHANGED
@@ -320,6 +320,16 @@ Navigation directive for `<a>` elements. Handles click events, sets `href`, and
320
320
  | `activeClassName` | `string` | `"active"` | CSS class applied when route is active |
321
321
  | `activeStrict` | `boolean` | `false` | Exact match only (no ancestor match) |
322
322
  | `ignoreQueryParams` | `boolean` | `true` | Query params don't affect active state |
323
+ | `hash` | `string` | `undefined`| URL fragment (decoded). Tri-state: undefined preserves, `""` clears, value sets. (#532) |
324
+
325
+ #### `hash` input — URL fragment / tab-style UIs
326
+
327
+ ```html
328
+ <a [realLink]="'settings'" [hash]="'profile'">Profile</a>
329
+ <a [realLink]="'settings'" [hash]="'account'">Account</a>
330
+ ```
331
+
332
+ Active class is hash-aware — only the matching tab lights up. Live demo: [`examples/web/react/link-hash/`](../../examples/web/react/link-hash/) — behavior is identical across adapters, only template syntax differs. See the [Hash Fragment Support](https://github.com/greydragon888/real-router/wiki/Hash) wiki page for the full surface.
323
333
 
324
334
  ### `[realLinkActive]`
325
335
 
@@ -219,12 +219,31 @@ function createScrollRestoration(router, options) {
219
219
  globalThis.scrollTo(0, top);
220
220
  }
221
221
  };
222
- const scrollToHashOrTop = () => {
222
+ const scrollToHashOrTop = (route) => {
223
+ // URL plugin path (#532): `state.context.url.hash` is the source of truth
224
+ // when one of the URL plugins (browser-plugin / navigation-plugin) is
225
+ // installed. The value is already DECODED — feeding it through
226
+ // `decodeURIComponent` again would throw on a bare `%`.
227
+ const ctxHash = route.context
228
+ ?.url?.hash;
229
+ if (ctxHash !== undefined) {
230
+ if (anchorEnabled && ctxHash.length > 0) {
231
+ // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars
232
+ const element = document.getElementById(ctxHash);
233
+ if (element) {
234
+ element.scrollIntoView();
235
+ return;
236
+ }
237
+ }
238
+ writePos(0);
239
+ return;
240
+ }
241
+ // Fallback path: no URL plugin, read the DOM. `location.hash` is
242
+ // percent-encoded; ids in the DOM are the raw string, so decode for the
243
+ // match. Fall back to the raw slice if the hash contains a malformed
244
+ // escape sequence (decodeURIComponent throws on those).
223
245
  const hash = globalThis.location.hash;
224
246
  if (anchorEnabled && hash.length > 1) {
225
- // location.hash is percent-encoded; ids in the DOM are the raw string.
226
- // Decode for the match. Fall back to the raw slice if the hash contains
227
- // a malformed escape sequence (decodeURIComponent throws on those).
228
247
  let id;
229
248
  try {
230
249
  id = decodeURIComponent(hash.slice(1));
@@ -258,7 +277,7 @@ function createScrollRestoration(router, options) {
258
277
  return;
259
278
  }
260
279
  if (mode === "top" || !nav) {
261
- scrollToHashOrTop();
280
+ scrollToHashOrTop(route);
262
281
  return;
263
282
  }
264
283
  if (nav.navigationType === "replace") {
@@ -270,7 +289,7 @@ function createScrollRestoration(router, options) {
270
289
  writePos(loadStore()[keyOf(route)] ?? 0);
271
290
  return;
272
291
  }
273
- scrollToHashOrTop();
292
+ scrollToHashOrTop(route);
274
293
  });
275
294
  });
276
295
  const onPageHide = () => {
@@ -461,22 +480,69 @@ function shouldNavigate(evt) {
461
480
  !evt.ctrlKey &&
462
481
  !evt.shiftKey);
463
482
  }
464
- function buildHref(router, routeName, routeParams) {
483
+ /**
484
+ * RFC 3986 fragment encoding: preserve sub-delims (`&`, `=`, `?`, `:`),
485
+ * encode space, `%`, control chars, non-ASCII via encodeURI; defensively
486
+ * escape `#` (encodeURI does not). Mirrors `encodeHashFragment` in
487
+ * `shared/browser-env/url-context.ts` — duplicated here because the
488
+ * shared/dom-utils symlink graph does not reach shared/browser-env.
489
+ */
490
+ function encodeFragmentInline(decoded) {
491
+ return encodeURI(decoded).replaceAll("#", "%23");
492
+ }
493
+ /**
494
+ * Builds an href for a `<Link>` element.
495
+ *
496
+ * - Prefers the URL plugin's `buildUrl` (browser-plugin, navigation-plugin,
497
+ * hash-plugin) when present.
498
+ * - Falls back to `router.buildPath` for runtimes without a URL plugin
499
+ * (memory-plugin, console UIs, NativeScript). In that fallback the hash
500
+ * is appended manually so the rendered href is still correct.
501
+ * - The optional 4th argument is an options object so the contract stays
502
+ * extensible. The `hash` option is a decoded fragment without leading "#";
503
+ * `<Link hash="#section">` is accepted defensively (leading "#" stripped).
504
+ * Frozen API: previous 3-arg call sites continue to work unchanged.
505
+ */
506
+ function buildHref(router, routeName, routeParams, options) {
465
507
  try {
508
+ const rawHash = options?.hash;
509
+ let normHash;
510
+ if (rawHash !== undefined) {
511
+ normHash = rawHash.startsWith("#") ? rawHash.slice(1) : rawHash;
512
+ }
466
513
  const buildUrl = router.buildUrl;
467
514
  if (buildUrl) {
468
- const url = buildUrl(routeName, routeParams);
515
+ const url = buildUrl(routeName, routeParams, normHash === undefined ? undefined : { hash: normHash });
469
516
  if (url !== undefined) {
470
517
  return url;
471
518
  }
472
519
  }
473
- return router.buildPath(routeName, routeParams);
520
+ const path = router.buildPath(routeName, routeParams);
521
+ return normHash ? `${path}#${encodeFragmentInline(normHash)}` : path;
474
522
  }
475
523
  catch {
476
524
  console.error(`[real-router] Route "${routeName}" is not defined. The element will render without an href attribute.`);
477
525
  return undefined;
478
526
  }
479
527
  }
528
+ function navigateWithHash(router, routeName, routeParams, hash, extraOptions) {
529
+ const opts = { ...extraOptions };
530
+ if (hash !== undefined) {
531
+ opts.hash = hash;
532
+ }
533
+ const current = router.getState();
534
+ if (current?.name === routeName &&
535
+ shallowEqual(current.params, routeParams)) {
536
+ const currentHash = current.context?.url?.hash ??
537
+ "";
538
+ const newHash = hash ?? currentHash;
539
+ if (currentHash !== newHash) {
540
+ opts.force = true;
541
+ opts.hashChange = true;
542
+ }
543
+ }
544
+ return router.navigate(routeName, routeParams, opts);
545
+ }
480
546
  function parseTokens(value) {
481
547
  return value ? (value.match(/\S+/g) ?? []) : [];
482
548
  }
@@ -650,10 +716,14 @@ function injectRouterTransition() {
650
716
 
651
717
  function injectIsActiveRoute(routeName, params, options) {
652
718
  const router = injectRouter();
653
- const source = createActiveRouteSource(router, routeName, params, {
654
- strict: options?.strict ?? false,
655
- ignoreQueryParams: options?.ignoreQueryParams ?? true,
656
- });
719
+ const strict = options?.strict ?? false;
720
+ const ignoreQueryParams = options?.ignoreQueryParams ?? true;
721
+ const hash = options?.hash;
722
+ // exactOptionalPropertyTypes forbids `{ hash: undefined }` literally — pass
723
+ // the field only when a value was provided. (#532)
724
+ const source = createActiveRouteSource(router, routeName, params, hash === undefined
725
+ ? { strict, ignoreQueryParams }
726
+ : { strict, ignoreQueryParams, hash });
657
727
  return sourceToSignal(source);
658
728
  }
659
729
 
@@ -1021,18 +1091,37 @@ class RealLink {
1021
1091
  activeClassName = input("active", ...(ngDevMode ? [{ debugName: "activeClassName" }] : /* istanbul ignore next */ []));
1022
1092
  activeStrict = input(false, ...(ngDevMode ? [{ debugName: "activeStrict" }] : /* istanbul ignore next */ []));
1023
1093
  ignoreQueryParams = input(true, ...(ngDevMode ? [{ debugName: "ignoreQueryParams" }] : /* istanbul ignore next */ []));
1094
+ /**
1095
+ * URL fragment (decoded form, no leading "#") (#532).
1096
+ * - omitted/`undefined` → preserve current fragment on same-route navigation
1097
+ * - `""` → clear fragment
1098
+ * - non-empty → set fragment
1099
+ */
1100
+ hash = input(undefined, ...(ngDevMode ? [{ debugName: "hash" }] : /* istanbul ignore next */ []));
1024
1101
  router = injectRouter();
1025
1102
  destroyRef = inject(DestroyRef);
1026
1103
  anchor = inject(ElementRef)
1027
1104
  .nativeElement;
1028
1105
  isActive = signal(false, ...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
1029
- href = computed(() => buildHref(this.router, this.routeName(), this.routeParams()), ...(ngDevMode ? [{ debugName: "href" }] : /* istanbul ignore next */ []));
1106
+ href = computed(() => {
1107
+ const hashValue = this.hash();
1108
+ return buildHref(this.router, this.routeName(), this.routeParams(), hashValue === undefined ? undefined : { hash: hashValue });
1109
+ }, ...(ngDevMode ? [{ debugName: "href" }] : /* istanbul ignore next */ []));
1030
1110
  prevActiveClass = "";
1031
1111
  ngOnInit() {
1032
- const source = createActiveRouteSource(this.router, this.routeName(), this.routeParams(), {
1033
- strict: this.activeStrict(),
1034
- ignoreQueryParams: this.ignoreQueryParams(),
1035
- });
1112
+ // Hash-aware active state (#532): pass `hash` so that tab-style links
1113
+ // (same routeName, different `hash` input) only mark the active variant.
1114
+ const hashValue = this.hash();
1115
+ const source = createActiveRouteSource(this.router, this.routeName(), this.routeParams(), hashValue === undefined
1116
+ ? {
1117
+ strict: this.activeStrict(),
1118
+ ignoreQueryParams: this.ignoreQueryParams(),
1119
+ }
1120
+ : {
1121
+ strict: this.activeStrict(),
1122
+ ignoreQueryParams: this.ignoreQueryParams(),
1123
+ hash: hashValue,
1124
+ });
1036
1125
  this.isActive.set(source.getSnapshot());
1037
1126
  this.updateDom();
1038
1127
  const unsub = source.subscribe(() => {
@@ -1049,9 +1138,7 @@ class RealLink {
1049
1138
  return;
1050
1139
  }
1051
1140
  event.preventDefault();
1052
- this.router
1053
- .navigate(this.routeName(), this.routeParams(), this.routeOptions())
1054
- .catch(() => { });
1141
+ navigateWithHash(this.router, this.routeName(), this.routeParams(), this.hash(), this.routeOptions()).catch(() => { });
1055
1142
  }
1056
1143
  updateDom() {
1057
1144
  const href = this.href();
@@ -1068,7 +1155,7 @@ class RealLink {
1068
1155
  this.prevActiveClass = activeClass;
1069
1156
  }
1070
1157
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RealLink, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1071
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: RealLink, isStandalone: true, selector: "a[realLink]", inputs: { routeName: { classPropertyName: "routeName", publicName: "routeName", isSignal: true, isRequired: false, transformFunction: null }, routeParams: { classPropertyName: "routeParams", publicName: "routeParams", isSignal: true, isRequired: false, transformFunction: null }, routeOptions: { classPropertyName: "routeOptions", publicName: "routeOptions", isSignal: true, isRequired: false, transformFunction: null }, activeClassName: { classPropertyName: "activeClassName", publicName: "activeClassName", isSignal: true, isRequired: false, transformFunction: null }, activeStrict: { classPropertyName: "activeStrict", publicName: "activeStrict", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryParams: { classPropertyName: "ignoreQueryParams", publicName: "ignoreQueryParams", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
1158
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.8", type: RealLink, isStandalone: true, selector: "a[realLink]", inputs: { routeName: { classPropertyName: "routeName", publicName: "routeName", isSignal: true, isRequired: false, transformFunction: null }, routeParams: { classPropertyName: "routeParams", publicName: "routeParams", isSignal: true, isRequired: false, transformFunction: null }, routeOptions: { classPropertyName: "routeOptions", publicName: "routeOptions", isSignal: true, isRequired: false, transformFunction: null }, activeClassName: { classPropertyName: "activeClassName", publicName: "activeClassName", isSignal: true, isRequired: false, transformFunction: null }, activeStrict: { classPropertyName: "activeStrict", publicName: "activeStrict", isSignal: true, isRequired: false, transformFunction: null }, ignoreQueryParams: { classPropertyName: "ignoreQueryParams", publicName: "ignoreQueryParams", isSignal: true, isRequired: false, transformFunction: null }, hash: { classPropertyName: "hash", publicName: "hash", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0 });
1072
1159
  }
1073
1160
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImport: i0, type: RealLink, decorators: [{
1074
1161
  type: Directive,
@@ -1078,7 +1165,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.8", ngImpor
1078
1165
  "(click)": "onClick($event)",
1079
1166
  },
1080
1167
  }]
1081
- }], propDecorators: { routeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeName", required: false }] }], routeParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeParams", required: false }] }], routeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeOptions", required: false }] }], activeClassName: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeClassName", required: false }] }], activeStrict: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStrict", required: false }] }], ignoreQueryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoreQueryParams", required: false }] }] } });
1168
+ }], propDecorators: { routeName: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeName", required: false }] }], routeParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeParams", required: false }] }], routeOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "routeOptions", required: false }] }], activeClassName: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeClassName", required: false }] }], activeStrict: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeStrict", required: false }] }], ignoreQueryParams: [{ type: i0.Input, args: [{ isSignal: true, alias: "ignoreQueryParams", required: false }] }], hash: [{ type: i0.Input, args: [{ isSignal: true, alias: "hash", required: false }] }] } });
1082
1169
 
1083
1170
  class RealLinkActive {
1084
1171
  realLinkActive = input("", ...(ngDevMode ? [{ debugName: "realLinkActive" }] : /* istanbul ignore next */ []));
@@ -1 +1 @@
1
- {"version":3,"file":"real-router-angular.mjs","sources":["../../src/dom-utils/direction-tracker.ts","../../src/dom-utils/route-announcer.ts","../../src/dom-utils/scroll-restore.ts","../../src/dom-utils/view-transitions.ts","../../src/dom-utils/link-utils.ts","../../src/sourceToSignal.ts","../../src/providers.ts","../../src/functions/injectOrThrow.ts","../../src/functions/injectRouter.ts","../../src/functions/injectNavigator.ts","../../src/functions/injectRoute.ts","../../src/functions/injectRouteNode.ts","../../src/functions/injectRouteUtils.ts","../../src/functions/injectRouterTransition.ts","../../src/functions/injectIsActiveRoute.ts","../../src/functions/injectRouteExit.ts","../../src/functions/injectRouteEnter.ts","../../src/directives/RouteMatch.ts","../../src/directives/RouteNotFound.ts","../../src/directives/RouteSelf.ts","../../src/components/RouteView.ts","../../src/components/RouterErrorBoundary.ts","../../src/components/NavigationAnnouncer.ts","../../src/directives/RealLink.ts","../../src/directives/RealLinkActive.ts","../../src/real-router-angular.ts"],"sourcesContent":["import type { Router } from \"@real-router/core\";\n\nexport interface DirectionTracker {\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: DirectionTracker = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\n/**\n * Track navigation direction (forward / back) and write it to\n * `<html data-nav-direction>` on every leave. CSS / JS readers consume\n * the attribute via `html[data-nav-direction=\"back\"]` selectors or\n * `document.documentElement.dataset.navDirection`.\n *\n * Mechanism-agnostic — works identically whether downstream UI uses CSS\n * `@keyframes`, View Transitions pseudo-elements, or library state\n * (motion's `motion.div initial={{ x: ... }}`).\n *\n * Implementation:\n * - On install, set `data-nav-direction=\"forward\"` baseline.\n * - Attach a `popstate` listener that flips an internal flag to\n * `true`. Browser back/forward navigation triggers popstate; user\n * clicks on `<Link>` / programmatic `router.navigate(...)` do not.\n * - On every `subscribeLeave`, write\n * `popstateFlag ? \"back\" : \"forward\"` and reset the flag.\n *\n * Returns `{ destroy }` to clean up the listener and clear the dataset\n * attribute.\n */\nexport function createDirectionTracker(router: Router): DirectionTracker {\n if (typeof document === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n let popstateFlag = false;\n\n document.documentElement.dataset.navDirection = \"forward\";\n\n const onPopstate = (): void => {\n popstateFlag = true;\n };\n\n // IMPORTANT — listener-ordering: `popstate` fires on `window`, which\n // has no DOM descendants, so capture phase is moot. Listeners are\n // dispatched in registration order. To beat the browser-plugin's own\n // popstate handler, this tracker must be installed **before**\n // `router.usePlugin(browserPluginFactory())` in user code. Otherwise\n // the plugin's handler runs first and synchronously fires\n // `subscribeLeave` while `popstateFlag` is still `false`.\n globalThis.addEventListener(\"popstate\", onPopstate);\n\n const offLeave = router.subscribeLeave(() => {\n document.documentElement.dataset.navDirection = popstateFlag\n ? \"back\"\n : \"forward\";\n popstateFlag = false;\n });\n\n return {\n destroy: () => {\n offLeave();\n globalThis.removeEventListener(\"popstate\", onPopstate);\n delete document.documentElement.dataset.navDirection;\n },\n };\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst CLEAR_DELAY = 7000;\nconst SAFARI_READY_DELAY = 100;\nconst ANNOUNCER_ATTR = \"data-real-router-announcer\";\nconst INTERNAL_ROUTE_PREFIX = \"@@\";\nconst VISUALLY_HIDDEN =\n \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0\";\n\nexport interface RouteAnnouncerOptions {\n prefix?: string;\n getAnnouncementText?: (route: State) => string;\n}\n\nexport function createRouteAnnouncer(\n router: Router,\n options?: RouteAnnouncerOptions,\n): { destroy: () => void } {\n const prefix = options?.prefix ?? \"Navigated to \";\n const getCustomText = options?.getAnnouncementText;\n\n let isInitialNavigation = true;\n let isReady = false;\n let isDestroyed = false;\n let lastAnnouncedText = \"\";\n let pendingText: string | null = null;\n let clearTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const announcer = getOrCreateAnnouncer();\n\n const doAnnounce = (text: string, h1: HTMLElement | null): void => {\n lastAnnouncedText = text;\n clearTimeout(clearTimeoutId);\n announcer.textContent = text;\n clearTimeoutId = setTimeout(() => {\n announcer.textContent = \"\";\n lastAnnouncedText = \"\";\n }, CLEAR_DELAY);\n\n manageFocus(h1);\n };\n\n // Safari-ready delay: announcing before VoiceOver wires up the aria-live region\n // causes the first announcement to be silently dropped. Wait SAFARI_READY_DELAY ms\n // before marking the announcer \"ready\" — any navigation during that window is\n // buffered in pendingText and flushed once the delay expires.\n const safariTimeoutId = setTimeout(() => {\n isReady = true;\n\n if (pendingText !== null && !isDestroyed) {\n const text = pendingText;\n\n pendingText = null;\n doAnnounce(text, document.querySelector<HTMLElement>(\"h1\"));\n }\n }, SAFARI_READY_DELAY);\n\n const unsubscribe = router.subscribe(({ route }) => {\n if (isInitialNavigation) {\n isInitialNavigation = false;\n\n return;\n }\n\n // Double rAF: waits for two paint frames so the incoming route's DOM\n // (including the new <h1>) is fully rendered before resolveText reads it.\n // Single rAF fires before the new route's template has been attached,\n // which would cause resolveText to pick up the OLD h1 or fall back to\n // document.title / route.name prematurely.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (isDestroyed) {\n return;\n }\n\n const h1 = document.querySelector<HTMLElement>(\"h1\");\n const text = resolveText(route, prefix, getCustomText, h1);\n\n if (!text || text === lastAnnouncedText) {\n return;\n }\n\n if (!isReady) {\n // Defer announcement until Safari-ready window elapses (see safariTimeoutId).\n pendingText = text;\n\n return;\n }\n\n doAnnounce(text, h1);\n });\n });\n });\n\n return {\n destroy() {\n isDestroyed = true;\n unsubscribe();\n clearTimeout(clearTimeoutId);\n clearTimeout(safariTimeoutId);\n removeAnnouncer();\n },\n };\n}\n\nfunction getOrCreateAnnouncer(): HTMLElement {\n const existing = document.querySelector<HTMLElement>(`[${ANNOUNCER_ATTR}]`);\n\n if (existing) {\n return existing;\n }\n\n const element = document.createElement(\"div\");\n\n element.setAttribute(\"style\", VISUALLY_HIDDEN);\n element.setAttribute(\"aria-live\", \"assertive\");\n element.setAttribute(\"aria-atomic\", \"true\");\n element.setAttribute(ANNOUNCER_ATTR, \"\");\n\n document.body.prepend(element);\n\n return element;\n}\n\nfunction removeAnnouncer(): void {\n document.querySelector(`[${ANNOUNCER_ATTR}]`)?.remove();\n}\n\nfunction resolveText(\n route: State,\n prefix: string,\n getCustomText: ((route: State) => string) | undefined,\n h1: HTMLElement | null,\n): string {\n if (getCustomText) {\n return getCustomText(route);\n }\n\n const h1Text = (h1?.textContent ?? \"\").trim();\n const routeName = route.name.startsWith(INTERNAL_ROUTE_PREFIX)\n ? \"\"\n : route.name;\n const rawText =\n h1Text || document.title || routeName || globalThis.location.pathname;\n\n return `${prefix}${rawText}`;\n}\n\nfunction manageFocus(h1: HTMLElement | null): void {\n if (!h1) {\n return;\n }\n\n if (!h1.hasAttribute(\"tabindex\")) {\n h1.setAttribute(\"tabindex\", \"-1\");\n }\n\n h1.focus({ preventScroll: true });\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst STORAGE_KEY = \"real-router:scroll\";\n\nconst NOOP_INSTANCE: { destroy: () => void } = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport type ScrollRestorationMode = \"restore\" | \"top\" | \"manual\";\n\nexport interface ScrollRestorationOptions {\n mode?: ScrollRestorationMode | undefined;\n anchorScrolling?: boolean | undefined;\n scrollContainer?: (() => HTMLElement | null) | undefined;\n}\n\ninterface NavigationContext {\n direction?: \"forward\" | \"back\" | \"unknown\";\n navigationType?: \"push\" | \"replace\" | \"traverse\" | \"reload\";\n}\n\nexport function createScrollRestoration(\n router: Router,\n options?: ScrollRestorationOptions,\n): { destroy: () => void } {\n if (typeof globalThis.window === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const mode = options?.mode ?? \"restore\";\n\n // mode \"manual\" = utility does nothing. Don't flip history.scrollRestoration,\n // don't subscribe, don't register pagehide — leave the browser's native\n // auto-restore intact for the app to override if it wants to.\n if (mode === \"manual\") {\n return NOOP_INSTANCE;\n }\n\n const anchorEnabled = options?.anchorScrolling ?? true;\n const getContainer = options?.scrollContainer;\n\n const prevScrollRestoration = history.scrollRestoration;\n\n try {\n history.scrollRestoration = \"manual\";\n } catch {\n // Ignore — some embedded contexts may reject the assignment.\n }\n\n // Resolve the container lazily on every event so containers mounted AFTER\n // the provider still get correct scroll handling. Falls back to window when\n // the getter is absent or returns null (pre-mount).\n const readPos = (): number => {\n const element = getContainer?.();\n\n return element ? element.scrollTop : globalThis.scrollY;\n };\n\n const writePos = (top: number): void => {\n const element = getContainer?.();\n\n if (element) {\n element.scrollTop = top;\n } else {\n globalThis.scrollTo(0, top);\n }\n };\n\n const scrollToHashOrTop = (): void => {\n const hash = globalThis.location.hash;\n\n if (anchorEnabled && hash.length > 1) {\n // location.hash is percent-encoded; ids in the DOM are the raw string.\n // Decode for the match. Fall back to the raw slice if the hash contains\n // a malformed escape sequence (decodeURIComponent throws on those).\n let id: string;\n\n try {\n id = decodeURIComponent(hash.slice(1));\n } catch {\n id = hash.slice(1);\n }\n\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(id);\n\n if (element) {\n element.scrollIntoView();\n\n return;\n }\n }\n\n writePos(0);\n };\n\n let destroyed = false;\n\n const unsubscribe = router.subscribe(({ route, previousRoute }) => {\n const nav = (route.context as { navigation?: NavigationContext })\n .navigation;\n\n // Browsers dispatch reload as the initial navigation after refresh, so\n // previousRoute is undefined and capture is naturally skipped. The\n // pre-refresh position was already persisted via pagehide.\n if (previousRoute) {\n putPos(keyOf(previousRoute), readPos());\n }\n\n // Single rAF so DOM is committed before we read anchors / write scroll.\n // Guard against destroy() racing with the callback.\n requestAnimationFrame(() => {\n if (destroyed) {\n return;\n }\n\n if (mode === \"top\" || !nav) {\n scrollToHashOrTop();\n\n return;\n }\n\n if (nav.navigationType === \"replace\") {\n return;\n }\n\n if (\n nav.direction === \"back\" ||\n nav.navigationType === \"traverse\" ||\n nav.navigationType === \"reload\"\n ) {\n writePos(loadStore()[keyOf(route)] ?? 0);\n\n return;\n }\n\n scrollToHashOrTop();\n });\n });\n\n const onPageHide = (): void => {\n const current = router.getState();\n\n if (current) {\n putPos(keyOf(current), readPos());\n }\n };\n\n globalThis.addEventListener(\"pagehide\", onPageHide);\n\n return {\n destroy: () => {\n if (destroyed) {\n return;\n }\n\n destroyed = true;\n unsubscribe();\n globalThis.removeEventListener(\"pagehide\", onPageHide);\n\n try {\n history.scrollRestoration = prevScrollRestoration;\n } catch {\n // Ignore.\n }\n },\n };\n}\n\nfunction keyOf(state: State): string {\n return `${state.name}:${canonicalJson(state.params)}`;\n}\n\nfunction loadStore(): Record<string, number> {\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n\n return raw ? (JSON.parse(raw) as Record<string, number>) : {};\n } catch {\n return {};\n }\n}\n\nfunction putPos(key: string, pos: number): void {\n try {\n const store = loadStore();\n\n store[key] = pos;\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(store));\n } catch {\n // Ignore quota / security errors.\n }\n}\n\nfunction canonicalJson(value: unknown): string {\n return JSON.stringify(value, canonicalReplacer);\n}\n\nfunction canonicalReplacer(_key: string, val: unknown): unknown {\n if (val !== null && typeof val === \"object\" && !Array.isArray(val)) {\n const sorted: Record<string, unknown> = {};\n // eslint-disable-next-line unicorn/no-array-sort -- ng-packagr uses pre-ES2023 lib; toSorted unavailable\n const keys = Object.keys(val as Record<string, unknown>).sort(\n (left: string, right: string) => left.localeCompare(right),\n );\n\n for (const key of keys) {\n sorted[key] = (val as Record<string, unknown>)[key];\n }\n\n return sorted;\n }\n\n return val;\n}\n","import type { Router } from \"@real-router/core\";\n\nexport interface ViewTransitions {\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: ViewTransitions = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport function createViewTransitions(router: Router): ViewTransitions {\n if (\n typeof document === \"undefined\" ||\n typeof document.startViewTransition !== \"function\"\n ) {\n return NOOP_INSTANCE;\n }\n\n let closeVT: (() => void) | null = null;\n let currentVT: { skipTransition?: () => void } | null = null;\n // Tracks whether TRANSITION_SUCCESS fired for the current leave. Used to\n // distinguish \"benign cleanup abort\" (router's async path aborts its own\n // controller in a finally block after successful navigation) from \"real\n // cancellation\" (concurrent navigate, guard rejection, dispose).\n let successFired = false;\n\n const resolveAndClear = (): void => {\n closeVT?.();\n closeVT = null;\n };\n\n const offLeave = router.subscribeLeave(({ signal }) => {\n // Reentrant abort: signal already aborted when we're called. Open no VT\n // — router will fall through to TRANSITION_CANCELLED via isCurrentNav()\n // after leave resolves. addEventListener(\"abort\", ...) does not re-fire\n // for past events, so skipping startViewTransition is the safe path.\n if (signal.aborted) {\n return;\n }\n\n successFired = false;\n resolveAndClear();\n\n // Return a Promise so the router awaits until the browser invokes\n // updateCallback. This ensures old DOM snapshot is captured BEFORE the\n // router commits the new state — giving correct exit→state→entry\n // ordering (vs fire-and-forget, where URL changes before VT captures).\n return new Promise<void>((resolveLeave) => {\n // Capture the resolver synchronously BEFORE startViewTransition() is\n // called. The browser invokes updateCallback in a later task, but\n // router.subscribe (TRANSITION_SUCCESS) can fire before that. If we\n // captured `resolve` inside the callback, subscribe would see closeVT\n // still null and skip resolving — the deferred would hang for 4s\n // until the VT API aborts with TimeoutError.\n const deferred = new Promise<void>((resolve) => {\n closeVT = resolve;\n });\n\n signal.addEventListener(\n \"abort\",\n () => {\n if (successFired) {\n // Router's async path (#finishAsyncNavigation) aborts its own\n // controller in a finally block AFTER completeTransition (and\n // thus AFTER subscribe fired). This is cleanup, not\n // cancellation — VT is progressing normally, do nothing.\n return;\n }\n\n // Real cancellation (concurrent navigate, dispose). Resolve the\n // deferred so updateCallback can complete, skip the VT so no\n // stale animation leaks, and unblock the router if the abort\n // fires before updateCallback was invoked.\n resolveAndClear();\n currentVT?.skipTransition?.();\n resolveLeave();\n },\n { once: true },\n );\n\n try {\n currentVT = document.startViewTransition(() => {\n // Resolving here unblocks the router at the moment the browser\n // enters updateCallback — by spec, old DOM snapshot is captured\n // before this callback runs. Router now proceeds through\n // activation guards and setState; the VT animation waits on\n // `deferred`, which is resolved from router.subscribe after a\n // task-queue tick (see NOTE on setTimeout below).\n resolveLeave();\n\n return deferred;\n });\n } catch {\n // Defensive: spec says startViewTransition doesn't throw under\n // normal conditions, but Chromium has had edge cases (detached\n // document, extension interference). Clean up and unblock router.\n resolveAndClear();\n resolveLeave();\n }\n });\n });\n\n const offSuccess = router.subscribe(() => {\n const resolver = closeVT;\n\n successFired = true;\n closeVT = null;\n\n if (resolver === null) {\n currentVT = null;\n } else {\n // CRITICAL: CANNOT use requestAnimationFrame here. When the router\n // takes the async path (leave returned a Promise), subscribe fires\n // AFTER the browser has already transitioned VT into the\n // \"update-callback-called\" phase. In that phase Chromium sets\n // rendering suppression to true, which ALSO blocks rAF callbacks.\n // rAF would never fire → deferred never resolves → browser aborts\n // vt.ready with TimeoutError after 4s (observed in Chromium).\n //\n // setTimeout runs on the task queue independent of the rendering\n // pipeline, so it fires regardless of suppression. React's scheduler\n // uses MessageChannel tasks, which are queued before our setTimeout,\n // so the new DOM is committed by the time our callback runs.\n setTimeout(() => {\n resolver();\n currentVT = null;\n }, 0);\n }\n });\n\n return {\n destroy: () => {\n offLeave();\n offSuccess();\n currentVT?.skipTransition?.();\n currentVT = null;\n resolveAndClear();\n },\n };\n}\n","import type { Router, Params } from \"@real-router/core\";\n\nexport function shouldNavigate(evt: MouseEvent): boolean {\n return (\n evt.button === 0 &&\n !evt.metaKey &&\n !evt.altKey &&\n !evt.ctrlKey &&\n !evt.shiftKey\n );\n}\n\ntype BuildUrlFn = (name: string, params: Params) => string | undefined;\n\nexport function buildHref(\n router: Router,\n routeName: string,\n routeParams: Params,\n): string | undefined {\n try {\n const buildUrl = router.buildUrl as BuildUrlFn | undefined;\n\n if (buildUrl) {\n const url = buildUrl(routeName, routeParams);\n\n if (url !== undefined) {\n return url;\n }\n }\n\n return router.buildPath(routeName, routeParams);\n } catch {\n console.error(\n `[real-router] Route \"${routeName}\" is not defined. The element will render without an href attribute.`,\n );\n\n return undefined;\n }\n}\n\nfunction parseTokens(value: string | undefined): string[] {\n return value ? (value.match(/\\S+/g) ?? []) : [];\n}\n\nexport function buildActiveClassName(\n isActive: boolean,\n activeClassName: string | undefined,\n baseClassName: string | undefined,\n): string | undefined {\n if (isActive && activeClassName) {\n const activeTokens = parseTokens(activeClassName);\n\n if (activeTokens.length === 0) {\n return baseClassName ?? undefined;\n }\n if (!baseClassName) {\n return activeTokens.join(\" \");\n }\n\n const baseTokens = parseTokens(baseClassName);\n const seen = new Set(baseTokens);\n\n for (const token of activeTokens) {\n if (!seen.has(token)) {\n seen.add(token);\n baseTokens.push(token);\n }\n }\n\n return baseTokens.join(\" \");\n }\n\n return baseClassName ?? undefined;\n}\n\nexport function shallowEqual(\n prev: object | undefined,\n next: object | undefined,\n): boolean {\n if (Object.is(prev, next)) {\n return true;\n }\n if (!prev || !next) {\n return false;\n }\n\n const prevKeys = Object.keys(prev);\n\n if (prevKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n const prevRecord = prev as Record<string, unknown>;\n const nextRecord = next as Record<string, unknown>;\n\n for (const key of prevKeys) {\n if (!Object.is(prevRecord[key], nextRecord[key])) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function applyLinkA11y(element: HTMLElement | null | undefined): void {\n if (!element) {\n return;\n }\n if (\n element instanceof HTMLAnchorElement ||\n element instanceof HTMLButtonElement\n ) {\n return;\n }\n if (!element.hasAttribute(\"role\")) {\n element.setAttribute(\"role\", \"link\");\n }\n if (!element.hasAttribute(\"tabindex\")) {\n element.setAttribute(\"tabindex\", \"0\");\n }\n}\n","import { signal, type Signal, inject, DestroyRef } from \"@angular/core\";\n\nimport type { RouterSource } from \"@real-router/sources\";\n\n/** Must be called within an injection context (constructor, field initializer, runInInjectionContext). */\nexport function sourceToSignal<T>(source: RouterSource<T>): Signal<T> {\n const sig = signal<T>(source.getSnapshot());\n const destroyRef = inject(DestroyRef);\n\n const unsubscribe = source.subscribe(() => {\n sig.set(source.getSnapshot());\n });\n\n destroyRef.onDestroy(() => {\n unsubscribe();\n source.destroy();\n });\n\n return sig.asReadonly();\n}\n","import {\n ApplicationRef,\n DestroyRef,\n InjectionToken,\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n type EnvironmentProviders,\n} from \"@angular/core\";\nimport { getNavigator, type Router, type Navigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\n\nimport { createScrollRestoration, createViewTransitions } from \"./dom-utils\";\nimport { sourceToSignal } from \"./sourceToSignal\";\n\nimport type { ScrollRestorationOptions } from \"./dom-utils\";\nimport type { RouteSignals } from \"./types\";\n\nexport const ROUTER = new InjectionToken<Router>(\"ROUTER\");\n\nexport const NAVIGATOR = new InjectionToken<Navigator>(\"NAVIGATOR\");\n\nexport const ROUTE = new InjectionToken<RouteSignals>(\"ROUTE\");\n\nexport interface RealRouterOptions {\n scrollRestoration?: ScrollRestorationOptions;\n viewTransitions?: boolean;\n}\n\nexport function provideRealRouter(\n router: Router,\n options?: RealRouterOptions,\n): EnvironmentProviders {\n const navigator = getNavigator(router);\n\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n { provide: ROUTER, useValue: router },\n { provide: NAVIGATOR, useValue: navigator },\n {\n provide: ROUTE,\n useFactory: (): RouteSignals => ({\n routeState: sourceToSignal(createRouteSource(router)),\n navigator,\n }),\n },\n ];\n\n if (options?.scrollRestoration) {\n const scrollOpts = options.scrollRestoration;\n\n providers.push(\n provideEnvironmentInitializer(() => {\n const sr = createScrollRestoration(router, scrollOpts);\n\n inject(DestroyRef).onDestroy(() => {\n sr.destroy();\n });\n }),\n );\n }\n\n if (options?.viewTransitions === true) {\n providers.push(\n provideEnvironmentInitializer(() => {\n const appRef = inject(ApplicationRef);\n\n // Force synchronous change detection on every transition success\n // BEFORE the VT utility resolves its deferred. The utility uses\n // `setTimeout(0)` to release the new-snapshot capture, which is\n // load-bearing because Chromium blocks rAF callbacks while VT sits\n // in the `update-callback-called` phase. Angular's zoneless CD is\n // rAF-driven by default — without this synchronous tick the new\n // DOM is not committed when the browser captures the new snapshot,\n // so old and new snapshots end up identical and animations finish\n // in ~0 ms with no visible work (the inner-route `products.list ↔\n // products.detail` morph in the example example was the canary).\n // Subscribers fire in registration order; this one runs BEFORE\n // `createViewTransitions` registers its own subscriber,\n // guaranteeing CD completes first.\n const offTick = router.subscribe(() => {\n appRef.tick();\n });\n\n const vt = createViewTransitions(router);\n\n inject(DestroyRef).onDestroy(() => {\n offTick();\n vt.destroy();\n });\n }),\n );\n }\n\n return makeEnvironmentProviders(providers);\n}\n","import { inject } from \"@angular/core\";\n\nimport type { InjectionToken } from \"@angular/core\";\n\nexport function injectOrThrow<T>(token: InjectionToken<T>, fnName: string): T {\n const value = inject(token, { optional: true });\n\n if (!value) {\n throw new Error(\n `${fnName} must be used within a provideRealRouter context`,\n );\n }\n\n return value;\n}\n","import { injectOrThrow } from \"./injectOrThrow\";\nimport { ROUTER } from \"../providers\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport function injectRouter(): Router {\n return injectOrThrow(ROUTER, \"injectRouter\");\n}\n","import { injectOrThrow } from \"./injectOrThrow\";\nimport { NAVIGATOR } from \"../providers\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport function injectNavigator(): Navigator {\n return injectOrThrow(NAVIGATOR, \"injectNavigator\");\n}\n","import { injectOrThrow } from \"./injectOrThrow\";\nimport { ROUTE } from \"../providers\";\n\nimport type { RouteSignals } from \"../types\";\nimport type { Signal } from \"@angular/core\";\nimport type { Params, State } from \"@real-router/core\";\nimport type { RouteSnapshot } from \"@real-router/sources\";\n\nexport function injectRoute<P extends Params = Params>(): Omit<\n RouteSignals<P>,\n \"routeState\"\n> & {\n readonly routeState: Signal<\n Omit<RouteSnapshot<P>, \"route\"> & { route: State<P> }\n >;\n} {\n const signals = injectOrThrow(ROUTE, \"injectRoute\") as RouteSignals<P>;\n\n if (!signals.routeState().route) {\n throw new Error(\n \"injectRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?\",\n );\n }\n\n return signals as Omit<RouteSignals<P>, \"routeState\"> & {\n readonly routeState: Signal<\n Omit<RouteSnapshot<P>, \"route\"> & { route: State<P> }\n >;\n };\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { RouteSignals } from \"../types\";\n\nexport function injectRouteNode(nodeName: string): RouteSignals {\n const router = injectRouter();\n const navigator = getNavigator(router);\n const source = createRouteNodeSource(router, nodeName);\n const routeState = sourceToSignal(source);\n\n return { routeState, navigator };\n}\n","import { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\nexport function injectRouteUtils(): RouteUtils {\n const router = injectRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n}\n","import { getTransitionSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { Signal } from \"@angular/core\";\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function injectRouterTransition(): Signal<RouterTransitionSnapshot> {\n const router = injectRouter();\n const source = getTransitionSource(router);\n\n return sourceToSignal(source);\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { Signal } from \"@angular/core\";\nimport type { Params } from \"@real-router/core\";\n\nexport function injectIsActiveRoute(\n routeName: string,\n params?: Params,\n options?: { strict?: boolean; ignoreQueryParams?: boolean },\n): Signal<boolean> {\n const router = injectRouter();\n const source = createActiveRouteSource(router, routeName, params, {\n strict: options?.strict ?? false,\n ignoreQueryParams: options?.ignoreQueryParams ?? true,\n });\n\n return sourceToSignal(source);\n}\n","import { DestroyRef, assertInInjectionContext, inject } from \"@angular/core\";\n\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { State } from \"@real-router/core\";\n\nexport interface RouteExitContext {\n /** The route being left. */\n route: State;\n /** The route being navigated to. */\n nextRoute: State;\n /**\n * AbortSignal that fires when this navigation is superseded by a later\n * one (rapid clicks). Already filtered: when the handler runs,\n * `signal.aborted` is guaranteed to be `false`. Use\n * `signal.addEventListener(\"abort\", cleanup, { once: true })` for\n * cleanup that must run on cancellation.\n */\n signal: AbortSignal;\n}\n\nexport interface UseRouteExitOptions {\n /**\n * Skip the handler when `route.name === nextRoute.name`\n * (sort/filter/query-only navigations on the same route). Default:\n * `true`.\n */\n skipSameRoute?: boolean;\n}\n\nexport type RouteExitHandler = (\n context: RouteExitContext,\n) => void | Promise<void>;\n\n/**\n * Subscribe to the router's leave-window with the universal guards baked\n * in. Wraps `router.subscribeLeave` so consumers don't repeat the same\n * boilerplate every time:\n *\n * - **Reentrant abort pre-check**: if `signal.aborted` is already `true`\n * when the handler would run (rapid navigation superseded a slower\n * one), the handler is skipped entirely.\n * - **Same-route skip**: by default, `route.name === nextRoute.name`\n * short-circuits the handler — query-only navigations skip the work.\n * Opt out with `skipSameRoute: false`.\n *\n * Cleanup is bound to the injection context's `DestroyRef`. Must be\n * called within an injection context (constructor, field initializer,\n * or `runInInjectionContext`).\n *\n * If the handler returns a Promise, the router blocks on it. If the\n * Promise resolves, navigation proceeds. If it rejects, the router emits\n * `TRANSITION_CANCELLED`.\n *\n * **Handler reactivity (Angular):** `inject*` functions run **once**\n * during component construction; `handler` is captured in closure at the\n * call site. The common Angular pattern is to pass a class method\n * (`this.onExit.bind(this)` or an arrow-property) — its identity is\n * stable across change detection. To vary behavior over time, read\n * signals **inside** the handler body — do not rely on swapping the\n * handler reference.\n *\n * @example Animation\n * ```ts\n * \\@Component({ ... })\n * class FadeOutComponent {\n * private el = inject(ElementRef<HTMLElement>);\n *\n * constructor() {\n * injectRouteExit(async ({ signal }) => {\n * const el = this.el.nativeElement;\n * el.classList.add(\"fade-out\");\n * const cleanup = () => el.classList.remove(\"fade-out\");\n * signal.addEventListener(\"abort\", cleanup, { once: true });\n * try {\n * el.getBoundingClientRect();\n * await Promise.allSettled(el.getAnimations().map((a) => a.finished));\n * } finally {\n * cleanup();\n * }\n * });\n * }\n * }\n * ```\n *\n * @example Auto-save form draft\n * ```ts\n * injectRouteExit(async ({ signal }) => {\n * if (this.formState.dirty) {\n * await this.api.saveDraft(this.formState, { signal });\n * }\n * });\n * ```\n */\nexport function injectRouteExit(\n handler: RouteExitHandler,\n options?: UseRouteExitOptions,\n): void {\n assertInInjectionContext(injectRouteExit);\n\n const router = injectRouter();\n const destroyRef = inject(DestroyRef);\n const skipSameRoute = options?.skipSameRoute ?? true;\n\n const off = router.subscribeLeave(({ route, nextRoute, signal }) => {\n if (skipSameRoute && route.name === nextRoute.name) {\n return;\n }\n\n if (signal.aborted) {\n return;\n }\n\n return handler({ route, nextRoute, signal });\n });\n\n destroyRef.onDestroy(off);\n}\n","import { assertInInjectionContext, effect } from \"@angular/core\";\n\nimport { injectRoute } from \"./injectRoute\";\n\nimport type { State } from \"@real-router/core\";\n\nexport interface RouteEnterContext {\n /** The route that was just activated. */\n route: State;\n /** The route that was active immediately before this navigation. */\n previousRoute: State;\n}\n\nexport type RouteEnterHandler = (context: RouteEnterContext) => void;\n\nexport interface UseRouteEnterOptions {\n /**\n * Skip the handler when `route.name === previousRoute.name`\n * (sort/filter/query-only navigations on the same route). Default:\n * `true`. Symmetric with `injectRouteExit`'s same-name option.\n */\n skipSameRoute?: boolean;\n}\n\n/**\n * Fire `handler` once when the component is created as a result of a\n * navigation. Mirror of `injectRouteExit` for the entry side.\n *\n * What this function covers that an ad-hoc `effect()` + `injectRoute()`\n * doesn't:\n *\n * - **Skip-initial**: handler is skipped when there is no\n * `route.transition.from` (i.e. first-load mount). Most consumers\n * want to fire side effects only on real navigations, not on\n * hydration.\n * - **Same-route skip** (default): handler is skipped when\n * `route.transition.from === route.name`. Sort/filter/query-only\n * navigations re-run the effect (because the `route` reference\n * changes), but they are not \"entries\" in the animation / analytics\n * sense. Opt out with `skipSameRoute: false`.\n * - **Mount-time `route` / `previousRoute` snapshot**: handler receives\n * the values that were live at the moment of effect activation.\n *\n * Effect cleanup is wired through the injection context's `DestroyRef`\n * (Angular's `effect()` ties into the active context automatically).\n * Must be called within an injection context (constructor, field\n * initializer, or `runInInjectionContext`).\n *\n * **Handler reactivity (Angular):** `inject*` functions run **once**\n * during component construction; `handler` is captured in closure at the\n * call site. The common Angular pattern is to pass a class method —\n * its identity is stable across change detection. To vary behavior\n * over time, read signals **inside** the handler body.\n *\n * @example Direction-aware entry animation\n * ```ts\n * \\@Component({ ... })\n * class PageComponent {\n * private el = inject(ElementRef<HTMLElement>);\n *\n * constructor() {\n * injectRouteEnter(({ route }) => {\n * const direction = route.context.browser?.direction;\n * this.el.nativeElement.classList.add(\n * direction === \"back\" ? \"slide-from-left\" : \"slide-from-right\",\n * );\n * });\n * }\n * }\n * ```\n *\n * @example Analytics page-enter event (skip-initial built-in)\n * ```ts\n * injectRouteEnter(({ route, previousRoute }) => {\n * analytics.track(\"page_enter\", {\n * route: route.name,\n * from: previousRoute.name,\n * });\n * });\n * ```\n */\nexport function injectRouteEnter(\n handler: RouteEnterHandler,\n options?: UseRouteEnterOptions,\n): void {\n assertInInjectionContext(injectRouteEnter);\n\n const { routeState } = injectRoute();\n const skipSameRoute = options?.skipSameRoute ?? true;\n let lastHandledRoute: State | null = null;\n\n effect(() => {\n const { route, previousRoute } = routeState();\n\n // Early-exit guards, top-down:\n //\n // - **Skip-initial**: `state.transition.from` is undefined only\n // for the very first state committed by `router.start()`.\n // - **Skip-same-route**: query-only navigations have\n // `transition.from === route.name`. Opt-out via\n // `skipSameRoute: false`.\n // - **Defensive dedupe + missing `previousRoute`**: same `route`\n // ref between effect re-runs is unexpected on Angular (the\n // signal only fires on real reference changes); `!previousRoute`\n // is unreachable once `transition.from` is set (core populates\n // them together). Both kept for parity with React; v8-ignored.\n if (!route.transition.from) {\n return;\n }\n if (skipSameRoute && route.transition.from === route.name) {\n return;\n }\n /* v8 ignore start */\n if (lastHandledRoute === route || !previousRoute) {\n return;\n }\n /* v8 ignore stop */\n\n lastHandledRoute = route;\n handler({ route, previousRoute });\n });\n}\n","import { Directive, TemplateRef, inject, input } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeMatch]\" })\nexport class RouteMatch {\n readonly routeMatch = input.required<string>();\n readonly templateRef = inject(TemplateRef);\n}\n","import { Directive, TemplateRef, inject } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeNotFound]\" })\nexport class RouteNotFound {\n readonly templateRef = inject(TemplateRef);\n}\n","import { Directive, TemplateRef, inject } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeSelf]\" })\nexport class RouteSelf {\n readonly templateRef = inject(TemplateRef);\n}\n","import { NgTemplateOutlet } from \"@angular/common\";\nimport {\n Component,\n computed,\n contentChildren,\n inject,\n input,\n signal,\n DestroyRef,\n type OnInit,\n type TemplateRef,\n} from \"@angular/core\";\nimport { UNKNOWN_ROUTE } from \"@real-router/core\";\nimport { startsWithSegment } from \"@real-router/route-utils\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\n\nimport { RouteMatch } from \"../directives/RouteMatch\";\nimport { RouteNotFound } from \"../directives/RouteNotFound\";\nimport { RouteSelf } from \"../directives/RouteSelf\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\nimport type { RouteSnapshot } from \"@real-router/sources\";\n\nconst EMPTY_SNAPSHOT: RouteSnapshot = Object.freeze({\n route: undefined,\n previousRoute: undefined,\n});\n\n@Component({\n selector: \"route-view\",\n template: `\n @if (activeTemplate()) {\n <ng-container [ngTemplateOutlet]=\"activeTemplate()!\" />\n }\n `,\n imports: [NgTemplateOutlet],\n})\nexport class RouteView implements OnInit {\n readonly nodeName = input<string>(\"\", { alias: \"routeNode\" });\n\n readonly matches = contentChildren(RouteMatch, { descendants: true });\n readonly selfs = contentChildren(RouteSelf, { descendants: true });\n readonly notFounds = contentChildren(RouteNotFound, { descendants: true });\n\n readonly activeTemplate = computed<TemplateRef<unknown> | null>(() => {\n const snapshot = this.routeState();\n const route = snapshot.route;\n\n if (!route) {\n return null;\n }\n\n const routeName = route.name;\n const entries = this.matchEntries();\n\n for (const { match, fullSegmentName } of entries) {\n if (startsWithSegment(routeName, fullSegmentName)) {\n return match.templateRef;\n }\n }\n\n // Self has priority over NotFound. First-wins to mirror NotFound's\n // last-wins inversion would be inconsistent with React/Preact/Solid/Vue\n // adapters where Self is \"first wins\"; Angular's contentChildren returns\n // declaration order, so picking [0] gives first-wins.\n if (routeName === this.nodeName()) {\n const first = this.selfs().at(0);\n\n if (first) {\n return first.templateRef;\n }\n }\n\n if (routeName === UNKNOWN_ROUTE) {\n const last = this.notFounds().at(-1);\n\n if (last) {\n return last.templateRef;\n }\n }\n\n return null;\n });\n\n private readonly matchEntries = computed(() => {\n const nodeName = this.nodeName();\n\n return this.matches().map((match) => {\n const segment = match.routeMatch();\n\n return {\n match,\n fullSegmentName: nodeName ? `${nodeName}.${segment}` : segment,\n };\n });\n });\n\n private readonly router = injectRouter();\n private readonly destroyRef = inject(DestroyRef);\n private readonly routeState = signal<RouteSnapshot>(EMPTY_SNAPSHOT);\n\n ngOnInit(): void {\n const source = createRouteNodeSource(this.router, this.nodeName());\n\n this.routeState.set(source.getSnapshot());\n\n const unsub = source.subscribe(() => {\n this.routeState.set(source.getSnapshot());\n });\n\n this.destroyRef.onDestroy(() => {\n unsub();\n source.destroy();\n });\n }\n}\n","import { NgTemplateOutlet } from \"@angular/common\";\nimport { Component, computed, effect, input, output } from \"@angular/core\";\nimport { createDismissableError } from \"@real-router/sources\";\n\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { sourceToSignal } from \"../sourceToSignal\";\n\nimport type { TemplateRef } from \"@angular/core\";\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { DismissableErrorSnapshot } from \"@real-router/sources\";\n\nexport interface ErrorContext {\n $implicit: RouterError;\n resetError: () => void;\n}\n\n@Component({\n selector: \"router-error-boundary\",\n template: `\n <ng-content />\n @if (errorContext() && errorTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"errorTemplate()!\"\n [ngTemplateOutletContext]=\"errorContext()!\"\n />\n }\n `,\n imports: [NgTemplateOutlet],\n})\nexport class RouterErrorBoundary {\n readonly errorTemplate = input<TemplateRef<ErrorContext>>();\n\n readonly onError = output<{\n error: RouterError;\n toRoute: State | null;\n fromRoute: State | null;\n }>();\n\n readonly errorContext = computed<ErrorContext | null>(() => {\n const snap = this.snapshot();\n\n if (!snap.error) {\n return null;\n }\n\n return {\n $implicit: snap.error,\n resetError: snap.resetError,\n };\n });\n\n private readonly router = injectRouter();\n private readonly snapshot = sourceToSignal<DismissableErrorSnapshot>(\n createDismissableError(this.router),\n );\n\n constructor() {\n effect(() => {\n const snap = this.snapshot();\n\n if (snap.error) {\n this.onError.emit({\n error: snap.error,\n toRoute: snap.toRoute,\n fromRoute: snap.fromRoute,\n });\n }\n });\n }\n}\n","import { Component, inject, DestroyRef } from \"@angular/core\";\n\nimport { createRouteAnnouncer } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\n@Component({\n selector: \"navigation-announcer\",\n template: \"\",\n})\nexport class NavigationAnnouncer {\n private readonly announcer = createRouteAnnouncer(injectRouter());\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.announcer.destroy();\n });\n }\n}\n","import {\n Directive,\n ElementRef,\n computed,\n inject,\n input,\n signal,\n DestroyRef,\n type OnInit,\n} from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { buildHref, shouldNavigate } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\nimport type { Params, NavigationOptions } from \"@real-router/core\";\n\n@Directive({\n selector: \"a[realLink]\",\n host: {\n \"(click)\": \"onClick($event)\",\n },\n})\nexport class RealLink implements OnInit {\n readonly routeName = input<string>(\"\");\n readonly routeParams = input<Params>({});\n readonly routeOptions = input<NavigationOptions>({});\n readonly activeClassName = input<string>(\"active\");\n readonly activeStrict = input(false);\n readonly ignoreQueryParams = input(true);\n\n private readonly router = injectRouter();\n private readonly destroyRef = inject(DestroyRef);\n private readonly anchor = inject(ElementRef)\n .nativeElement as HTMLAnchorElement;\n private readonly isActive = signal(false);\n private readonly href = computed(() =>\n buildHref(this.router, this.routeName(), this.routeParams()),\n );\n private prevActiveClass = \"\";\n\n ngOnInit(): void {\n const source = createActiveRouteSource(\n this.router,\n this.routeName(),\n this.routeParams(),\n {\n strict: this.activeStrict(),\n ignoreQueryParams: this.ignoreQueryParams(),\n },\n );\n\n this.isActive.set(source.getSnapshot());\n this.updateDom();\n\n const unsub = source.subscribe(() => {\n this.isActive.set(source.getSnapshot());\n this.updateDom();\n });\n\n this.destroyRef.onDestroy(() => {\n unsub();\n source.destroy();\n });\n }\n\n onClick(event: MouseEvent): void {\n if (!shouldNavigate(event) || this.anchor.target === \"_blank\") {\n return;\n }\n\n event.preventDefault();\n this.router\n .navigate(this.routeName(), this.routeParams(), this.routeOptions())\n .catch(() => {});\n }\n\n private updateDom(): void {\n const href = this.href();\n\n if (href !== undefined) {\n this.anchor.setAttribute(\"href\", href);\n }\n\n const activeClass = this.activeClassName();\n\n if (this.prevActiveClass && this.prevActiveClass !== activeClass) {\n this.anchor.classList.remove(this.prevActiveClass);\n }\n\n if (activeClass) {\n this.anchor.classList.toggle(activeClass, this.isActive());\n }\n\n this.prevActiveClass = activeClass;\n }\n}\n","import {\n Directive,\n ElementRef,\n inject,\n input,\n signal,\n DestroyRef,\n type OnInit,\n} from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { applyLinkA11y } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\nimport type { Params } from \"@real-router/core\";\n\n@Directive({ selector: \"[realLinkActive]\" })\nexport class RealLinkActive implements OnInit {\n readonly realLinkActive = input<string>(\"\");\n readonly routeName = input<string>(\"\");\n readonly routeParams = input<Params>({});\n readonly activeStrict = input(false);\n readonly ignoreQueryParams = input(true);\n\n private readonly router = injectRouter();\n private readonly destroyRef = inject(DestroyRef);\n private readonly element = inject(ElementRef).nativeElement as HTMLElement;\n private readonly isActive = signal(false);\n\n constructor() {\n applyLinkA11y(this.element);\n }\n\n ngOnInit(): void {\n const source = createActiveRouteSource(\n this.router,\n this.routeName(),\n this.routeParams(),\n {\n strict: this.activeStrict(),\n ignoreQueryParams: this.ignoreQueryParams(),\n },\n );\n\n this.isActive.set(source.getSnapshot());\n this.updateClass();\n\n const unsub = source.subscribe(() => {\n this.isActive.set(source.getSnapshot());\n this.updateClass();\n });\n\n this.destroyRef.onDestroy(() => {\n unsub();\n source.destroy();\n });\n }\n\n private updateClass(): void {\n const className = this.realLinkActive();\n\n if (!className) {\n return;\n }\n\n this.element.classList.toggle(className, this.isActive());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NOOP_INSTANCE"],"mappings":"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"}
1
+ {"version":3,"file":"real-router-angular.mjs","sources":["../../src/dom-utils/direction-tracker.ts","../../src/dom-utils/route-announcer.ts","../../src/dom-utils/scroll-restore.ts","../../src/dom-utils/view-transitions.ts","../../src/dom-utils/link-utils.ts","../../src/sourceToSignal.ts","../../src/providers.ts","../../src/functions/injectOrThrow.ts","../../src/functions/injectRouter.ts","../../src/functions/injectNavigator.ts","../../src/functions/injectRoute.ts","../../src/functions/injectRouteNode.ts","../../src/functions/injectRouteUtils.ts","../../src/functions/injectRouterTransition.ts","../../src/functions/injectIsActiveRoute.ts","../../src/functions/injectRouteExit.ts","../../src/functions/injectRouteEnter.ts","../../src/directives/RouteMatch.ts","../../src/directives/RouteNotFound.ts","../../src/directives/RouteSelf.ts","../../src/components/RouteView.ts","../../src/components/RouterErrorBoundary.ts","../../src/components/NavigationAnnouncer.ts","../../src/directives/RealLink.ts","../../src/directives/RealLinkActive.ts","../../src/real-router-angular.ts"],"sourcesContent":["import type { Router } from \"@real-router/core\";\n\nexport interface DirectionTracker {\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: DirectionTracker = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\n/**\n * Track navigation direction (forward / back) and write it to\n * `<html data-nav-direction>` on every leave. CSS / JS readers consume\n * the attribute via `html[data-nav-direction=\"back\"]` selectors or\n * `document.documentElement.dataset.navDirection`.\n *\n * Mechanism-agnostic — works identically whether downstream UI uses CSS\n * `@keyframes`, View Transitions pseudo-elements, or library state\n * (motion's `motion.div initial={{ x: ... }}`).\n *\n * Implementation:\n * - On install, set `data-nav-direction=\"forward\"` baseline.\n * - Attach a `popstate` listener that flips an internal flag to\n * `true`. Browser back/forward navigation triggers popstate; user\n * clicks on `<Link>` / programmatic `router.navigate(...)` do not.\n * - On every `subscribeLeave`, write\n * `popstateFlag ? \"back\" : \"forward\"` and reset the flag.\n *\n * Returns `{ destroy }` to clean up the listener and clear the dataset\n * attribute.\n */\nexport function createDirectionTracker(router: Router): DirectionTracker {\n if (typeof document === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n let popstateFlag = false;\n\n document.documentElement.dataset.navDirection = \"forward\";\n\n const onPopstate = (): void => {\n popstateFlag = true;\n };\n\n // IMPORTANT — listener-ordering: `popstate` fires on `window`, which\n // has no DOM descendants, so capture phase is moot. Listeners are\n // dispatched in registration order. To beat the browser-plugin's own\n // popstate handler, this tracker must be installed **before**\n // `router.usePlugin(browserPluginFactory())` in user code. Otherwise\n // the plugin's handler runs first and synchronously fires\n // `subscribeLeave` while `popstateFlag` is still `false`.\n globalThis.addEventListener(\"popstate\", onPopstate);\n\n const offLeave = router.subscribeLeave(() => {\n document.documentElement.dataset.navDirection = popstateFlag\n ? \"back\"\n : \"forward\";\n popstateFlag = false;\n });\n\n return {\n destroy: () => {\n offLeave();\n globalThis.removeEventListener(\"popstate\", onPopstate);\n delete document.documentElement.dataset.navDirection;\n },\n };\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst CLEAR_DELAY = 7000;\nconst SAFARI_READY_DELAY = 100;\nconst ANNOUNCER_ATTR = \"data-real-router-announcer\";\nconst INTERNAL_ROUTE_PREFIX = \"@@\";\nconst VISUALLY_HIDDEN =\n \"position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);clip-path:inset(50%);white-space:nowrap;border:0\";\n\nexport interface RouteAnnouncerOptions {\n prefix?: string;\n getAnnouncementText?: (route: State) => string;\n}\n\nexport function createRouteAnnouncer(\n router: Router,\n options?: RouteAnnouncerOptions,\n): { destroy: () => void } {\n const prefix = options?.prefix ?? \"Navigated to \";\n const getCustomText = options?.getAnnouncementText;\n\n let isInitialNavigation = true;\n let isReady = false;\n let isDestroyed = false;\n let lastAnnouncedText = \"\";\n let pendingText: string | null = null;\n let clearTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n const announcer = getOrCreateAnnouncer();\n\n const doAnnounce = (text: string, h1: HTMLElement | null): void => {\n lastAnnouncedText = text;\n clearTimeout(clearTimeoutId);\n announcer.textContent = text;\n clearTimeoutId = setTimeout(() => {\n announcer.textContent = \"\";\n lastAnnouncedText = \"\";\n }, CLEAR_DELAY);\n\n manageFocus(h1);\n };\n\n // Safari-ready delay: announcing before VoiceOver wires up the aria-live region\n // causes the first announcement to be silently dropped. Wait SAFARI_READY_DELAY ms\n // before marking the announcer \"ready\" — any navigation during that window is\n // buffered in pendingText and flushed once the delay expires.\n const safariTimeoutId = setTimeout(() => {\n isReady = true;\n\n if (pendingText !== null && !isDestroyed) {\n const text = pendingText;\n\n pendingText = null;\n doAnnounce(text, document.querySelector<HTMLElement>(\"h1\"));\n }\n }, SAFARI_READY_DELAY);\n\n const unsubscribe = router.subscribe(({ route }) => {\n if (isInitialNavigation) {\n isInitialNavigation = false;\n\n return;\n }\n\n // Double rAF: waits for two paint frames so the incoming route's DOM\n // (including the new <h1>) is fully rendered before resolveText reads it.\n // Single rAF fires before the new route's template has been attached,\n // which would cause resolveText to pick up the OLD h1 or fall back to\n // document.title / route.name prematurely.\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (isDestroyed) {\n return;\n }\n\n const h1 = document.querySelector<HTMLElement>(\"h1\");\n const text = resolveText(route, prefix, getCustomText, h1);\n\n if (!text || text === lastAnnouncedText) {\n return;\n }\n\n if (!isReady) {\n // Defer announcement until Safari-ready window elapses (see safariTimeoutId).\n pendingText = text;\n\n return;\n }\n\n doAnnounce(text, h1);\n });\n });\n });\n\n return {\n destroy() {\n isDestroyed = true;\n unsubscribe();\n clearTimeout(clearTimeoutId);\n clearTimeout(safariTimeoutId);\n removeAnnouncer();\n },\n };\n}\n\nfunction getOrCreateAnnouncer(): HTMLElement {\n const existing = document.querySelector<HTMLElement>(`[${ANNOUNCER_ATTR}]`);\n\n if (existing) {\n return existing;\n }\n\n const element = document.createElement(\"div\");\n\n element.setAttribute(\"style\", VISUALLY_HIDDEN);\n element.setAttribute(\"aria-live\", \"assertive\");\n element.setAttribute(\"aria-atomic\", \"true\");\n element.setAttribute(ANNOUNCER_ATTR, \"\");\n\n document.body.prepend(element);\n\n return element;\n}\n\nfunction removeAnnouncer(): void {\n document.querySelector(`[${ANNOUNCER_ATTR}]`)?.remove();\n}\n\nfunction resolveText(\n route: State,\n prefix: string,\n getCustomText: ((route: State) => string) | undefined,\n h1: HTMLElement | null,\n): string {\n if (getCustomText) {\n return getCustomText(route);\n }\n\n const h1Text = (h1?.textContent ?? \"\").trim();\n const routeName = route.name.startsWith(INTERNAL_ROUTE_PREFIX)\n ? \"\"\n : route.name;\n const rawText =\n h1Text || document.title || routeName || globalThis.location.pathname;\n\n return `${prefix}${rawText}`;\n}\n\nfunction manageFocus(h1: HTMLElement | null): void {\n if (!h1) {\n return;\n }\n\n if (!h1.hasAttribute(\"tabindex\")) {\n h1.setAttribute(\"tabindex\", \"-1\");\n }\n\n h1.focus({ preventScroll: true });\n}\n","import type { Router, State } from \"@real-router/core\";\n\nconst STORAGE_KEY = \"real-router:scroll\";\n\nconst NOOP_INSTANCE: { destroy: () => void } = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport type ScrollRestorationMode = \"restore\" | \"top\" | \"manual\";\n\nexport interface ScrollRestorationOptions {\n mode?: ScrollRestorationMode | undefined;\n anchorScrolling?: boolean | undefined;\n scrollContainer?: (() => HTMLElement | null) | undefined;\n}\n\ninterface NavigationContext {\n direction?: \"forward\" | \"back\" | \"unknown\";\n navigationType?: \"push\" | \"replace\" | \"traverse\" | \"reload\";\n}\n\nexport function createScrollRestoration(\n router: Router,\n options?: ScrollRestorationOptions,\n): { destroy: () => void } {\n if (typeof globalThis.window === \"undefined\") {\n return NOOP_INSTANCE;\n }\n\n const mode = options?.mode ?? \"restore\";\n\n // mode \"manual\" = utility does nothing. Don't flip history.scrollRestoration,\n // don't subscribe, don't register pagehide — leave the browser's native\n // auto-restore intact for the app to override if it wants to.\n if (mode === \"manual\") {\n return NOOP_INSTANCE;\n }\n\n const anchorEnabled = options?.anchorScrolling ?? true;\n const getContainer = options?.scrollContainer;\n\n const prevScrollRestoration = history.scrollRestoration;\n\n try {\n history.scrollRestoration = \"manual\";\n } catch {\n // Ignore — some embedded contexts may reject the assignment.\n }\n\n // Resolve the container lazily on every event so containers mounted AFTER\n // the provider still get correct scroll handling. Falls back to window when\n // the getter is absent or returns null (pre-mount).\n const readPos = (): number => {\n const element = getContainer?.();\n\n return element ? element.scrollTop : globalThis.scrollY;\n };\n\n const writePos = (top: number): void => {\n const element = getContainer?.();\n\n if (element) {\n element.scrollTop = top;\n } else {\n globalThis.scrollTo(0, top);\n }\n };\n\n const scrollToHashOrTop = (route: State): void => {\n // URL plugin path (#532): `state.context.url.hash` is the source of truth\n // when one of the URL plugins (browser-plugin / navigation-plugin) is\n // installed. The value is already DECODED — feeding it through\n // `decodeURIComponent` again would throw on a bare `%`.\n const ctxHash = (route.context as { url?: { hash?: string } } | undefined)\n ?.url?.hash;\n\n if (ctxHash !== undefined) {\n if (anchorEnabled && ctxHash.length > 0) {\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(ctxHash);\n\n if (element) {\n element.scrollIntoView();\n\n return;\n }\n }\n\n writePos(0);\n\n return;\n }\n\n // Fallback path: no URL plugin, read the DOM. `location.hash` is\n // percent-encoded; ids in the DOM are the raw string, so decode for the\n // match. Fall back to the raw slice if the hash contains a malformed\n // escape sequence (decodeURIComponent throws on those).\n const hash = globalThis.location.hash;\n\n if (anchorEnabled && hash.length > 1) {\n let id: string;\n\n try {\n id = decodeURIComponent(hash.slice(1));\n } catch {\n id = hash.slice(1);\n }\n\n // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars\n const element = document.getElementById(id);\n\n if (element) {\n element.scrollIntoView();\n\n return;\n }\n }\n\n writePos(0);\n };\n\n let destroyed = false;\n\n const unsubscribe = router.subscribe(({ route, previousRoute }) => {\n const nav = (route.context as { navigation?: NavigationContext })\n .navigation;\n\n // Browsers dispatch reload as the initial navigation after refresh, so\n // previousRoute is undefined and capture is naturally skipped. The\n // pre-refresh position was already persisted via pagehide.\n if (previousRoute) {\n putPos(keyOf(previousRoute), readPos());\n }\n\n // Single rAF so DOM is committed before we read anchors / write scroll.\n // Guard against destroy() racing with the callback.\n requestAnimationFrame(() => {\n if (destroyed) {\n return;\n }\n\n if (mode === \"top\" || !nav) {\n scrollToHashOrTop(route);\n\n return;\n }\n\n if (nav.navigationType === \"replace\") {\n return;\n }\n\n if (\n nav.direction === \"back\" ||\n nav.navigationType === \"traverse\" ||\n nav.navigationType === \"reload\"\n ) {\n writePos(loadStore()[keyOf(route)] ?? 0);\n\n return;\n }\n\n scrollToHashOrTop(route);\n });\n });\n\n const onPageHide = (): void => {\n const current = router.getState();\n\n if (current) {\n putPos(keyOf(current), readPos());\n }\n };\n\n globalThis.addEventListener(\"pagehide\", onPageHide);\n\n return {\n destroy: () => {\n if (destroyed) {\n return;\n }\n\n destroyed = true;\n unsubscribe();\n globalThis.removeEventListener(\"pagehide\", onPageHide);\n\n try {\n history.scrollRestoration = prevScrollRestoration;\n } catch {\n // Ignore.\n }\n },\n };\n}\n\nfunction keyOf(state: State): string {\n return `${state.name}:${canonicalJson(state.params)}`;\n}\n\nfunction loadStore(): Record<string, number> {\n try {\n const raw = sessionStorage.getItem(STORAGE_KEY);\n\n return raw ? (JSON.parse(raw) as Record<string, number>) : {};\n } catch {\n return {};\n }\n}\n\nfunction putPos(key: string, pos: number): void {\n try {\n const store = loadStore();\n\n store[key] = pos;\n sessionStorage.setItem(STORAGE_KEY, JSON.stringify(store));\n } catch {\n // Ignore quota / security errors.\n }\n}\n\nfunction canonicalJson(value: unknown): string {\n return JSON.stringify(value, canonicalReplacer);\n}\n\nfunction canonicalReplacer(_key: string, val: unknown): unknown {\n if (val !== null && typeof val === \"object\" && !Array.isArray(val)) {\n const sorted: Record<string, unknown> = {};\n // eslint-disable-next-line unicorn/no-array-sort -- ng-packagr uses pre-ES2023 lib; toSorted unavailable\n const keys = Object.keys(val as Record<string, unknown>).sort(\n (left: string, right: string) => left.localeCompare(right),\n );\n\n for (const key of keys) {\n sorted[key] = (val as Record<string, unknown>)[key];\n }\n\n return sorted;\n }\n\n return val;\n}\n","import type { Router } from \"@real-router/core\";\n\nexport interface ViewTransitions {\n destroy: () => void;\n}\n\nconst NOOP_INSTANCE: ViewTransitions = Object.freeze({\n destroy: () => {\n /* no-op */\n },\n});\n\nexport function createViewTransitions(router: Router): ViewTransitions {\n if (\n typeof document === \"undefined\" ||\n typeof document.startViewTransition !== \"function\"\n ) {\n return NOOP_INSTANCE;\n }\n\n let closeVT: (() => void) | null = null;\n let currentVT: { skipTransition?: () => void } | null = null;\n // Tracks whether TRANSITION_SUCCESS fired for the current leave. Used to\n // distinguish \"benign cleanup abort\" (router's async path aborts its own\n // controller in a finally block after successful navigation) from \"real\n // cancellation\" (concurrent navigate, guard rejection, dispose).\n let successFired = false;\n\n const resolveAndClear = (): void => {\n closeVT?.();\n closeVT = null;\n };\n\n const offLeave = router.subscribeLeave(({ signal }) => {\n // Reentrant abort: signal already aborted when we're called. Open no VT\n // — router will fall through to TRANSITION_CANCELLED via isCurrentNav()\n // after leave resolves. addEventListener(\"abort\", ...) does not re-fire\n // for past events, so skipping startViewTransition is the safe path.\n if (signal.aborted) {\n return;\n }\n\n successFired = false;\n resolveAndClear();\n\n // Return a Promise so the router awaits until the browser invokes\n // updateCallback. This ensures old DOM snapshot is captured BEFORE the\n // router commits the new state — giving correct exit→state→entry\n // ordering (vs fire-and-forget, where URL changes before VT captures).\n return new Promise<void>((resolveLeave) => {\n // Capture the resolver synchronously BEFORE startViewTransition() is\n // called. The browser invokes updateCallback in a later task, but\n // router.subscribe (TRANSITION_SUCCESS) can fire before that. If we\n // captured `resolve` inside the callback, subscribe would see closeVT\n // still null and skip resolving — the deferred would hang for 4s\n // until the VT API aborts with TimeoutError.\n const deferred = new Promise<void>((resolve) => {\n closeVT = resolve;\n });\n\n signal.addEventListener(\n \"abort\",\n () => {\n if (successFired) {\n // Router's async path (#finishAsyncNavigation) aborts its own\n // controller in a finally block AFTER completeTransition (and\n // thus AFTER subscribe fired). This is cleanup, not\n // cancellation — VT is progressing normally, do nothing.\n return;\n }\n\n // Real cancellation (concurrent navigate, dispose). Resolve the\n // deferred so updateCallback can complete, skip the VT so no\n // stale animation leaks, and unblock the router if the abort\n // fires before updateCallback was invoked.\n resolveAndClear();\n currentVT?.skipTransition?.();\n resolveLeave();\n },\n { once: true },\n );\n\n try {\n currentVT = document.startViewTransition(() => {\n // Resolving here unblocks the router at the moment the browser\n // enters updateCallback — by spec, old DOM snapshot is captured\n // before this callback runs. Router now proceeds through\n // activation guards and setState; the VT animation waits on\n // `deferred`, which is resolved from router.subscribe after a\n // task-queue tick (see NOTE on setTimeout below).\n resolveLeave();\n\n return deferred;\n });\n } catch {\n // Defensive: spec says startViewTransition doesn't throw under\n // normal conditions, but Chromium has had edge cases (detached\n // document, extension interference). Clean up and unblock router.\n resolveAndClear();\n resolveLeave();\n }\n });\n });\n\n const offSuccess = router.subscribe(() => {\n const resolver = closeVT;\n\n successFired = true;\n closeVT = null;\n\n if (resolver === null) {\n currentVT = null;\n } else {\n // CRITICAL: CANNOT use requestAnimationFrame here. When the router\n // takes the async path (leave returned a Promise), subscribe fires\n // AFTER the browser has already transitioned VT into the\n // \"update-callback-called\" phase. In that phase Chromium sets\n // rendering suppression to true, which ALSO blocks rAF callbacks.\n // rAF would never fire → deferred never resolves → browser aborts\n // vt.ready with TimeoutError after 4s (observed in Chromium).\n //\n // setTimeout runs on the task queue independent of the rendering\n // pipeline, so it fires regardless of suppression. React's scheduler\n // uses MessageChannel tasks, which are queued before our setTimeout,\n // so the new DOM is committed by the time our callback runs.\n setTimeout(() => {\n resolver();\n currentVT = null;\n }, 0);\n }\n });\n\n return {\n destroy: () => {\n offLeave();\n offSuccess();\n currentVT?.skipTransition?.();\n currentVT = null;\n resolveAndClear();\n },\n };\n}\n","import type {\n NavigationOptions,\n Params,\n Router,\n State,\n} from \"@real-router/core\";\n\nexport function shouldNavigate(evt: MouseEvent): boolean {\n return (\n evt.button === 0 &&\n !evt.metaKey &&\n !evt.altKey &&\n !evt.ctrlKey &&\n !evt.shiftKey\n );\n}\n\n/**\n * RFC 3986 fragment encoding: preserve sub-delims (`&`, `=`, `?`, `:`),\n * encode space, `%`, control chars, non-ASCII via encodeURI; defensively\n * escape `#` (encodeURI does not). Mirrors `encodeHashFragment` in\n * `shared/browser-env/url-context.ts` — duplicated here because the\n * shared/dom-utils symlink graph does not reach shared/browser-env.\n */\nfunction encodeFragmentInline(decoded: string): string {\n return encodeURI(decoded).replaceAll(\"#\", \"%23\");\n}\n\ntype BuildUrlFn = (\n name: string,\n params: Params,\n options?: { hash?: string },\n) => string | undefined;\n\n/**\n * Builds an href for a `<Link>` element.\n *\n * - Prefers the URL plugin's `buildUrl` (browser-plugin, navigation-plugin,\n * hash-plugin) when present.\n * - Falls back to `router.buildPath` for runtimes without a URL plugin\n * (memory-plugin, console UIs, NativeScript). In that fallback the hash\n * is appended manually so the rendered href is still correct.\n * - The optional 4th argument is an options object so the contract stays\n * extensible. The `hash` option is a decoded fragment without leading \"#\";\n * `<Link hash=\"#section\">` is accepted defensively (leading \"#\" stripped).\n * Frozen API: previous 3-arg call sites continue to work unchanged.\n */\nexport function buildHref(\n router: Router,\n routeName: string,\n routeParams: Params,\n options?: { hash?: string },\n): string | undefined {\n try {\n const rawHash = options?.hash;\n let normHash: string | undefined;\n\n if (rawHash !== undefined) {\n normHash = rawHash.startsWith(\"#\") ? rawHash.slice(1) : rawHash;\n }\n\n const buildUrl = router.buildUrl as BuildUrlFn | undefined;\n\n if (buildUrl) {\n const url = buildUrl(\n routeName,\n routeParams,\n normHash === undefined ? undefined : { hash: normHash },\n );\n\n if (url !== undefined) {\n return url;\n }\n }\n\n const path = router.buildPath(routeName, routeParams);\n\n return normHash ? `${path}#${encodeFragmentInline(normHash)}` : path;\n } catch {\n console.error(\n `[real-router] Route \"${routeName}\" is not defined. The element will render without an href attribute.`,\n );\n\n return undefined;\n }\n}\n\n/**\n * `<Link>` click-handler navigation helper (#532).\n *\n * Wraps `router.navigate(name, params, opts)` with same-route different-hash\n * detection: when the consumer clicks a hash-bearing Link that targets the\n * current route with the same params but a different fragment, core's\n * SAME_STATES check would otherwise reject the navigation. The helper adds\n * `force: true` and `hashChange: true` automatically — subscribers can then\n * disambiguate via `state.context.url.hashChanged`.\n *\n * For pure programmatic same-route hash-only navigation, callers are\n * documented to pass `{ force: true }` themselves; the auto-bypass here is\n * a UX convenience for `<Link hash>` that all 6 framework adapters share.\n */\n/**\n * Local extended-options type. Adapters that depend only on `@real-router/core`\n * (without a URL plugin) do not see the `NavigationOptions` augmentation that\n * declares `hash` / `hashChange`. Casting to this widened type inside the\n * helper keeps shared/dom-utils self-contained — adapters do not need to\n * augment NavigationOptions themselves to consume `<Link hash>`.\n */\ntype HashAwareNavigationOptions = NavigationOptions & {\n hash?: string;\n hashChange?: boolean;\n};\n\nexport function navigateWithHash(\n router: Router,\n routeName: string,\n routeParams: Params,\n hash: string | undefined,\n extraOptions?: NavigationOptions,\n): Promise<State> {\n const opts: HashAwareNavigationOptions = { ...extraOptions };\n\n if (hash !== undefined) {\n opts.hash = hash;\n }\n\n const current = router.getState();\n\n if (\n current?.name === routeName &&\n shallowEqual(current.params, routeParams)\n ) {\n const currentHash =\n (current.context as { url?: { hash?: string } } | undefined)?.url?.hash ??\n \"\";\n const newHash = hash ?? currentHash;\n\n if (currentHash !== newHash) {\n opts.force = true;\n opts.hashChange = true;\n }\n }\n\n return router.navigate(routeName, routeParams, opts);\n}\n\nfunction parseTokens(value: string | undefined): string[] {\n return value ? (value.match(/\\S+/g) ?? []) : [];\n}\n\nexport function buildActiveClassName(\n isActive: boolean,\n activeClassName: string | undefined,\n baseClassName: string | undefined,\n): string | undefined {\n if (isActive && activeClassName) {\n const activeTokens = parseTokens(activeClassName);\n\n if (activeTokens.length === 0) {\n return baseClassName ?? undefined;\n }\n if (!baseClassName) {\n return activeTokens.join(\" \");\n }\n\n const baseTokens = parseTokens(baseClassName);\n const seen = new Set(baseTokens);\n\n for (const token of activeTokens) {\n if (!seen.has(token)) {\n seen.add(token);\n baseTokens.push(token);\n }\n }\n\n return baseTokens.join(\" \");\n }\n\n return baseClassName ?? undefined;\n}\n\nexport function shallowEqual(\n prev: object | undefined,\n next: object | undefined,\n): boolean {\n if (Object.is(prev, next)) {\n return true;\n }\n if (!prev || !next) {\n return false;\n }\n\n const prevKeys = Object.keys(prev);\n\n if (prevKeys.length !== Object.keys(next).length) {\n return false;\n }\n\n const prevRecord = prev as Record<string, unknown>;\n const nextRecord = next as Record<string, unknown>;\n\n for (const key of prevKeys) {\n if (!Object.is(prevRecord[key], nextRecord[key])) {\n return false;\n }\n }\n\n return true;\n}\n\nexport function applyLinkA11y(element: HTMLElement | null | undefined): void {\n if (!element) {\n return;\n }\n if (\n element instanceof HTMLAnchorElement ||\n element instanceof HTMLButtonElement\n ) {\n return;\n }\n if (!element.hasAttribute(\"role\")) {\n element.setAttribute(\"role\", \"link\");\n }\n if (!element.hasAttribute(\"tabindex\")) {\n element.setAttribute(\"tabindex\", \"0\");\n }\n}\n","import { signal, type Signal, inject, DestroyRef } from \"@angular/core\";\n\nimport type { RouterSource } from \"@real-router/sources\";\n\n/** Must be called within an injection context (constructor, field initializer, runInInjectionContext). */\nexport function sourceToSignal<T>(source: RouterSource<T>): Signal<T> {\n const sig = signal<T>(source.getSnapshot());\n const destroyRef = inject(DestroyRef);\n\n const unsubscribe = source.subscribe(() => {\n sig.set(source.getSnapshot());\n });\n\n destroyRef.onDestroy(() => {\n unsubscribe();\n source.destroy();\n });\n\n return sig.asReadonly();\n}\n","import {\n ApplicationRef,\n DestroyRef,\n InjectionToken,\n inject,\n makeEnvironmentProviders,\n provideEnvironmentInitializer,\n type EnvironmentProviders,\n} from \"@angular/core\";\nimport { getNavigator, type Router, type Navigator } from \"@real-router/core\";\nimport { createRouteSource } from \"@real-router/sources\";\n\nimport { createScrollRestoration, createViewTransitions } from \"./dom-utils\";\nimport { sourceToSignal } from \"./sourceToSignal\";\n\nimport type { ScrollRestorationOptions } from \"./dom-utils\";\nimport type { RouteSignals } from \"./types\";\n\nexport const ROUTER = new InjectionToken<Router>(\"ROUTER\");\n\nexport const NAVIGATOR = new InjectionToken<Navigator>(\"NAVIGATOR\");\n\nexport const ROUTE = new InjectionToken<RouteSignals>(\"ROUTE\");\n\nexport interface RealRouterOptions {\n scrollRestoration?: ScrollRestorationOptions;\n viewTransitions?: boolean;\n}\n\nexport function provideRealRouter(\n router: Router,\n options?: RealRouterOptions,\n): EnvironmentProviders {\n const navigator = getNavigator(router);\n\n const providers: Parameters<typeof makeEnvironmentProviders>[0] = [\n { provide: ROUTER, useValue: router },\n { provide: NAVIGATOR, useValue: navigator },\n {\n provide: ROUTE,\n useFactory: (): RouteSignals => ({\n routeState: sourceToSignal(createRouteSource(router)),\n navigator,\n }),\n },\n ];\n\n if (options?.scrollRestoration) {\n const scrollOpts = options.scrollRestoration;\n\n providers.push(\n provideEnvironmentInitializer(() => {\n const sr = createScrollRestoration(router, scrollOpts);\n\n inject(DestroyRef).onDestroy(() => {\n sr.destroy();\n });\n }),\n );\n }\n\n if (options?.viewTransitions === true) {\n providers.push(\n provideEnvironmentInitializer(() => {\n const appRef = inject(ApplicationRef);\n\n // Force synchronous change detection on every transition success\n // BEFORE the VT utility resolves its deferred. The utility uses\n // `setTimeout(0)` to release the new-snapshot capture, which is\n // load-bearing because Chromium blocks rAF callbacks while VT sits\n // in the `update-callback-called` phase. Angular's zoneless CD is\n // rAF-driven by default — without this synchronous tick the new\n // DOM is not committed when the browser captures the new snapshot,\n // so old and new snapshots end up identical and animations finish\n // in ~0 ms with no visible work (the inner-route `products.list ↔\n // products.detail` morph in the example example was the canary).\n // Subscribers fire in registration order; this one runs BEFORE\n // `createViewTransitions` registers its own subscriber,\n // guaranteeing CD completes first.\n const offTick = router.subscribe(() => {\n appRef.tick();\n });\n\n const vt = createViewTransitions(router);\n\n inject(DestroyRef).onDestroy(() => {\n offTick();\n vt.destroy();\n });\n }),\n );\n }\n\n return makeEnvironmentProviders(providers);\n}\n","import { inject } from \"@angular/core\";\n\nimport type { InjectionToken } from \"@angular/core\";\n\nexport function injectOrThrow<T>(token: InjectionToken<T>, fnName: string): T {\n const value = inject(token, { optional: true });\n\n if (!value) {\n throw new Error(\n `${fnName} must be used within a provideRealRouter context`,\n );\n }\n\n return value;\n}\n","import { injectOrThrow } from \"./injectOrThrow\";\nimport { ROUTER } from \"../providers\";\n\nimport type { Router } from \"@real-router/core\";\n\nexport function injectRouter(): Router {\n return injectOrThrow(ROUTER, \"injectRouter\");\n}\n","import { injectOrThrow } from \"./injectOrThrow\";\nimport { NAVIGATOR } from \"../providers\";\n\nimport type { Navigator } from \"@real-router/core\";\n\nexport function injectNavigator(): Navigator {\n return injectOrThrow(NAVIGATOR, \"injectNavigator\");\n}\n","import { injectOrThrow } from \"./injectOrThrow\";\nimport { ROUTE } from \"../providers\";\n\nimport type { RouteSignals } from \"../types\";\nimport type { Signal } from \"@angular/core\";\nimport type { Params, State } from \"@real-router/core\";\nimport type { RouteSnapshot } from \"@real-router/sources\";\n\nexport function injectRoute<P extends Params = Params>(): Omit<\n RouteSignals<P>,\n \"routeState\"\n> & {\n readonly routeState: Signal<\n Omit<RouteSnapshot<P>, \"route\"> & { route: State<P> }\n >;\n} {\n const signals = injectOrThrow(ROUTE, \"injectRoute\") as RouteSignals<P>;\n\n if (!signals.routeState().route) {\n throw new Error(\n \"injectRoute called with no active route. Did you forget to await router.start() before rendering, or is the router stopped/disposed?\",\n );\n }\n\n return signals as Omit<RouteSignals<P>, \"routeState\"> & {\n readonly routeState: Signal<\n Omit<RouteSnapshot<P>, \"route\"> & { route: State<P> }\n >;\n };\n}\n","import { getNavigator } from \"@real-router/core\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { RouteSignals } from \"../types\";\n\nexport function injectRouteNode(nodeName: string): RouteSignals {\n const router = injectRouter();\n const navigator = getNavigator(router);\n const source = createRouteNodeSource(router, nodeName);\n const routeState = sourceToSignal(source);\n\n return { routeState, navigator };\n}\n","import { getPluginApi } from \"@real-router/core/api\";\nimport { getRouteUtils } from \"@real-router/route-utils\";\n\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { RouteUtils } from \"@real-router/route-utils\";\n\nexport function injectRouteUtils(): RouteUtils {\n const router = injectRouter();\n\n return getRouteUtils(getPluginApi(router).getTree());\n}\n","import { getTransitionSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { Signal } from \"@angular/core\";\nimport type { RouterTransitionSnapshot } from \"@real-router/sources\";\n\nexport function injectRouterTransition(): Signal<RouterTransitionSnapshot> {\n const router = injectRouter();\n const source = getTransitionSource(router);\n\n return sourceToSignal(source);\n}\n","import { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { sourceToSignal } from \"../sourceToSignal\";\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { Signal } from \"@angular/core\";\nimport type { Params } from \"@real-router/core\";\n\nexport function injectIsActiveRoute(\n routeName: string,\n params?: Params,\n options?: { strict?: boolean; ignoreQueryParams?: boolean; hash?: string },\n): Signal<boolean> {\n const router = injectRouter();\n const strict = options?.strict ?? false;\n const ignoreQueryParams = options?.ignoreQueryParams ?? true;\n const hash = options?.hash;\n // exactOptionalPropertyTypes forbids `{ hash: undefined }` literally — pass\n // the field only when a value was provided. (#532)\n const source = createActiveRouteSource(\n router,\n routeName,\n params,\n hash === undefined\n ? { strict, ignoreQueryParams }\n : { strict, ignoreQueryParams, hash },\n );\n\n return sourceToSignal(source);\n}\n","import { DestroyRef, assertInInjectionContext, inject } from \"@angular/core\";\n\nimport { injectRouter } from \"./injectRouter\";\n\nimport type { State } from \"@real-router/core\";\n\nexport interface RouteExitContext {\n /** The route being left. */\n route: State;\n /** The route being navigated to. */\n nextRoute: State;\n /**\n * AbortSignal that fires when this navigation is superseded by a later\n * one (rapid clicks). Already filtered: when the handler runs,\n * `signal.aborted` is guaranteed to be `false`. Use\n * `signal.addEventListener(\"abort\", cleanup, { once: true })` for\n * cleanup that must run on cancellation.\n */\n signal: AbortSignal;\n}\n\nexport interface UseRouteExitOptions {\n /**\n * Skip the handler when `route.name === nextRoute.name`\n * (sort/filter/query-only navigations on the same route). Default:\n * `true`.\n */\n skipSameRoute?: boolean;\n}\n\nexport type RouteExitHandler = (\n context: RouteExitContext,\n) => void | Promise<void>;\n\n/**\n * Subscribe to the router's leave-window with the universal guards baked\n * in. Wraps `router.subscribeLeave` so consumers don't repeat the same\n * boilerplate every time:\n *\n * - **Reentrant abort pre-check**: if `signal.aborted` is already `true`\n * when the handler would run (rapid navigation superseded a slower\n * one), the handler is skipped entirely.\n * - **Same-route skip**: by default, `route.name === nextRoute.name`\n * short-circuits the handler — query-only navigations skip the work.\n * Opt out with `skipSameRoute: false`.\n *\n * Cleanup is bound to the injection context's `DestroyRef`. Must be\n * called within an injection context (constructor, field initializer,\n * or `runInInjectionContext`).\n *\n * If the handler returns a Promise, the router blocks on it. If the\n * Promise resolves, navigation proceeds. If it rejects, the router emits\n * `TRANSITION_CANCELLED`.\n *\n * **Handler reactivity (Angular):** `inject*` functions run **once**\n * during component construction; `handler` is captured in closure at the\n * call site. The common Angular pattern is to pass a class method\n * (`this.onExit.bind(this)` or an arrow-property) — its identity is\n * stable across change detection. To vary behavior over time, read\n * signals **inside** the handler body — do not rely on swapping the\n * handler reference.\n *\n * @example Animation\n * ```ts\n * \\@Component({ ... })\n * class FadeOutComponent {\n * private el = inject(ElementRef<HTMLElement>);\n *\n * constructor() {\n * injectRouteExit(async ({ signal }) => {\n * const el = this.el.nativeElement;\n * el.classList.add(\"fade-out\");\n * const cleanup = () => el.classList.remove(\"fade-out\");\n * signal.addEventListener(\"abort\", cleanup, { once: true });\n * try {\n * el.getBoundingClientRect();\n * await Promise.allSettled(el.getAnimations().map((a) => a.finished));\n * } finally {\n * cleanup();\n * }\n * });\n * }\n * }\n * ```\n *\n * @example Auto-save form draft\n * ```ts\n * injectRouteExit(async ({ signal }) => {\n * if (this.formState.dirty) {\n * await this.api.saveDraft(this.formState, { signal });\n * }\n * });\n * ```\n */\nexport function injectRouteExit(\n handler: RouteExitHandler,\n options?: UseRouteExitOptions,\n): void {\n assertInInjectionContext(injectRouteExit);\n\n const router = injectRouter();\n const destroyRef = inject(DestroyRef);\n const skipSameRoute = options?.skipSameRoute ?? true;\n\n const off = router.subscribeLeave(({ route, nextRoute, signal }) => {\n if (skipSameRoute && route.name === nextRoute.name) {\n return;\n }\n\n if (signal.aborted) {\n return;\n }\n\n return handler({ route, nextRoute, signal });\n });\n\n destroyRef.onDestroy(off);\n}\n","import { assertInInjectionContext, effect } from \"@angular/core\";\n\nimport { injectRoute } from \"./injectRoute\";\n\nimport type { State } from \"@real-router/core\";\n\nexport interface RouteEnterContext {\n /** The route that was just activated. */\n route: State;\n /** The route that was active immediately before this navigation. */\n previousRoute: State;\n}\n\nexport type RouteEnterHandler = (context: RouteEnterContext) => void;\n\nexport interface UseRouteEnterOptions {\n /**\n * Skip the handler when `route.name === previousRoute.name`\n * (sort/filter/query-only navigations on the same route). Default:\n * `true`. Symmetric with `injectRouteExit`'s same-name option.\n */\n skipSameRoute?: boolean;\n}\n\n/**\n * Fire `handler` once when the component is created as a result of a\n * navigation. Mirror of `injectRouteExit` for the entry side.\n *\n * What this function covers that an ad-hoc `effect()` + `injectRoute()`\n * doesn't:\n *\n * - **Skip-initial**: handler is skipped when there is no\n * `route.transition.from` (i.e. first-load mount). Most consumers\n * want to fire side effects only on real navigations, not on\n * hydration.\n * - **Same-route skip** (default): handler is skipped when\n * `route.transition.from === route.name`. Sort/filter/query-only\n * navigations re-run the effect (because the `route` reference\n * changes), but they are not \"entries\" in the animation / analytics\n * sense. Opt out with `skipSameRoute: false`.\n * - **Mount-time `route` / `previousRoute` snapshot**: handler receives\n * the values that were live at the moment of effect activation.\n *\n * Effect cleanup is wired through the injection context's `DestroyRef`\n * (Angular's `effect()` ties into the active context automatically).\n * Must be called within an injection context (constructor, field\n * initializer, or `runInInjectionContext`).\n *\n * **Handler reactivity (Angular):** `inject*` functions run **once**\n * during component construction; `handler` is captured in closure at the\n * call site. The common Angular pattern is to pass a class method —\n * its identity is stable across change detection. To vary behavior\n * over time, read signals **inside** the handler body.\n *\n * @example Direction-aware entry animation\n * ```ts\n * \\@Component({ ... })\n * class PageComponent {\n * private el = inject(ElementRef<HTMLElement>);\n *\n * constructor() {\n * injectRouteEnter(({ route }) => {\n * const direction = route.context.browser?.direction;\n * this.el.nativeElement.classList.add(\n * direction === \"back\" ? \"slide-from-left\" : \"slide-from-right\",\n * );\n * });\n * }\n * }\n * ```\n *\n * @example Analytics page-enter event (skip-initial built-in)\n * ```ts\n * injectRouteEnter(({ route, previousRoute }) => {\n * analytics.track(\"page_enter\", {\n * route: route.name,\n * from: previousRoute.name,\n * });\n * });\n * ```\n */\nexport function injectRouteEnter(\n handler: RouteEnterHandler,\n options?: UseRouteEnterOptions,\n): void {\n assertInInjectionContext(injectRouteEnter);\n\n const { routeState } = injectRoute();\n const skipSameRoute = options?.skipSameRoute ?? true;\n let lastHandledRoute: State | null = null;\n\n effect(() => {\n const { route, previousRoute } = routeState();\n\n // Early-exit guards, top-down:\n //\n // - **Skip-initial**: `state.transition.from` is undefined only\n // for the very first state committed by `router.start()`.\n // - **Skip-same-route**: query-only navigations have\n // `transition.from === route.name`. Opt-out via\n // `skipSameRoute: false`.\n // - **Defensive dedupe + missing `previousRoute`**: same `route`\n // ref between effect re-runs is unexpected on Angular (the\n // signal only fires on real reference changes); `!previousRoute`\n // is unreachable once `transition.from` is set (core populates\n // them together). Both kept for parity with React; v8-ignored.\n if (!route.transition.from) {\n return;\n }\n if (skipSameRoute && route.transition.from === route.name) {\n return;\n }\n /* v8 ignore start */\n if (lastHandledRoute === route || !previousRoute) {\n return;\n }\n /* v8 ignore stop */\n\n lastHandledRoute = route;\n handler({ route, previousRoute });\n });\n}\n","import { Directive, TemplateRef, inject, input } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeMatch]\" })\nexport class RouteMatch {\n readonly routeMatch = input.required<string>();\n readonly templateRef = inject(TemplateRef);\n}\n","import { Directive, TemplateRef, inject } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeNotFound]\" })\nexport class RouteNotFound {\n readonly templateRef = inject(TemplateRef);\n}\n","import { Directive, TemplateRef, inject } from \"@angular/core\";\n\n@Directive({ selector: \"ng-template[routeSelf]\" })\nexport class RouteSelf {\n readonly templateRef = inject(TemplateRef);\n}\n","import { NgTemplateOutlet } from \"@angular/common\";\nimport {\n Component,\n computed,\n contentChildren,\n inject,\n input,\n signal,\n DestroyRef,\n type OnInit,\n type TemplateRef,\n} from \"@angular/core\";\nimport { UNKNOWN_ROUTE } from \"@real-router/core\";\nimport { startsWithSegment } from \"@real-router/route-utils\";\nimport { createRouteNodeSource } from \"@real-router/sources\";\n\nimport { RouteMatch } from \"../directives/RouteMatch\";\nimport { RouteNotFound } from \"../directives/RouteNotFound\";\nimport { RouteSelf } from \"../directives/RouteSelf\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\nimport type { RouteSnapshot } from \"@real-router/sources\";\n\nconst EMPTY_SNAPSHOT: RouteSnapshot = Object.freeze({\n route: undefined,\n previousRoute: undefined,\n});\n\n@Component({\n selector: \"route-view\",\n template: `\n @if (activeTemplate()) {\n <ng-container [ngTemplateOutlet]=\"activeTemplate()!\" />\n }\n `,\n imports: [NgTemplateOutlet],\n})\nexport class RouteView implements OnInit {\n readonly nodeName = input<string>(\"\", { alias: \"routeNode\" });\n\n readonly matches = contentChildren(RouteMatch, { descendants: true });\n readonly selfs = contentChildren(RouteSelf, { descendants: true });\n readonly notFounds = contentChildren(RouteNotFound, { descendants: true });\n\n readonly activeTemplate = computed<TemplateRef<unknown> | null>(() => {\n const snapshot = this.routeState();\n const route = snapshot.route;\n\n if (!route) {\n return null;\n }\n\n const routeName = route.name;\n const entries = this.matchEntries();\n\n for (const { match, fullSegmentName } of entries) {\n if (startsWithSegment(routeName, fullSegmentName)) {\n return match.templateRef;\n }\n }\n\n // Self has priority over NotFound. First-wins to mirror NotFound's\n // last-wins inversion would be inconsistent with React/Preact/Solid/Vue\n // adapters where Self is \"first wins\"; Angular's contentChildren returns\n // declaration order, so picking [0] gives first-wins.\n if (routeName === this.nodeName()) {\n const first = this.selfs().at(0);\n\n if (first) {\n return first.templateRef;\n }\n }\n\n if (routeName === UNKNOWN_ROUTE) {\n const last = this.notFounds().at(-1);\n\n if (last) {\n return last.templateRef;\n }\n }\n\n return null;\n });\n\n private readonly matchEntries = computed(() => {\n const nodeName = this.nodeName();\n\n return this.matches().map((match) => {\n const segment = match.routeMatch();\n\n return {\n match,\n fullSegmentName: nodeName ? `${nodeName}.${segment}` : segment,\n };\n });\n });\n\n private readonly router = injectRouter();\n private readonly destroyRef = inject(DestroyRef);\n private readonly routeState = signal<RouteSnapshot>(EMPTY_SNAPSHOT);\n\n ngOnInit(): void {\n const source = createRouteNodeSource(this.router, this.nodeName());\n\n this.routeState.set(source.getSnapshot());\n\n const unsub = source.subscribe(() => {\n this.routeState.set(source.getSnapshot());\n });\n\n this.destroyRef.onDestroy(() => {\n unsub();\n source.destroy();\n });\n }\n}\n","import { NgTemplateOutlet } from \"@angular/common\";\nimport { Component, computed, effect, input, output } from \"@angular/core\";\nimport { createDismissableError } from \"@real-router/sources\";\n\nimport { injectRouter } from \"../functions/injectRouter\";\nimport { sourceToSignal } from \"../sourceToSignal\";\n\nimport type { TemplateRef } from \"@angular/core\";\nimport type { RouterError, State } from \"@real-router/core\";\nimport type { DismissableErrorSnapshot } from \"@real-router/sources\";\n\nexport interface ErrorContext {\n $implicit: RouterError;\n resetError: () => void;\n}\n\n@Component({\n selector: \"router-error-boundary\",\n template: `\n <ng-content />\n @if (errorContext() && errorTemplate()) {\n <ng-container\n [ngTemplateOutlet]=\"errorTemplate()!\"\n [ngTemplateOutletContext]=\"errorContext()!\"\n />\n }\n `,\n imports: [NgTemplateOutlet],\n})\nexport class RouterErrorBoundary {\n readonly errorTemplate = input<TemplateRef<ErrorContext>>();\n\n readonly onError = output<{\n error: RouterError;\n toRoute: State | null;\n fromRoute: State | null;\n }>();\n\n readonly errorContext = computed<ErrorContext | null>(() => {\n const snap = this.snapshot();\n\n if (!snap.error) {\n return null;\n }\n\n return {\n $implicit: snap.error,\n resetError: snap.resetError,\n };\n });\n\n private readonly router = injectRouter();\n private readonly snapshot = sourceToSignal<DismissableErrorSnapshot>(\n createDismissableError(this.router),\n );\n\n constructor() {\n effect(() => {\n const snap = this.snapshot();\n\n if (snap.error) {\n this.onError.emit({\n error: snap.error,\n toRoute: snap.toRoute,\n fromRoute: snap.fromRoute,\n });\n }\n });\n }\n}\n","import { Component, inject, DestroyRef } from \"@angular/core\";\n\nimport { createRouteAnnouncer } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\n@Component({\n selector: \"navigation-announcer\",\n template: \"\",\n})\nexport class NavigationAnnouncer {\n private readonly announcer = createRouteAnnouncer(injectRouter());\n\n constructor() {\n inject(DestroyRef).onDestroy(() => {\n this.announcer.destroy();\n });\n }\n}\n","import {\n Directive,\n ElementRef,\n computed,\n inject,\n input,\n signal,\n DestroyRef,\n type OnInit,\n} from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { buildHref, navigateWithHash, shouldNavigate } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\nimport type { Params, NavigationOptions } from \"@real-router/core\";\n\n@Directive({\n selector: \"a[realLink]\",\n host: {\n \"(click)\": \"onClick($event)\",\n },\n})\nexport class RealLink implements OnInit {\n readonly routeName = input<string>(\"\");\n readonly routeParams = input<Params>({});\n readonly routeOptions = input<NavigationOptions>({});\n readonly activeClassName = input<string>(\"active\");\n readonly activeStrict = input(false);\n readonly ignoreQueryParams = input(true);\n /**\n * URL fragment (decoded form, no leading \"#\") (#532).\n * - omitted/`undefined` → preserve current fragment on same-route navigation\n * - `\"\"` → clear fragment\n * - non-empty → set fragment\n */\n readonly hash = input<string | undefined>(undefined);\n\n private readonly router = injectRouter();\n private readonly destroyRef = inject(DestroyRef);\n private readonly anchor = inject(ElementRef)\n .nativeElement as HTMLAnchorElement;\n private readonly isActive = signal(false);\n private readonly href = computed(() => {\n const hashValue = this.hash();\n\n return buildHref(\n this.router,\n this.routeName(),\n this.routeParams(),\n hashValue === undefined ? undefined : { hash: hashValue },\n );\n });\n private prevActiveClass = \"\";\n\n ngOnInit(): void {\n // Hash-aware active state (#532): pass `hash` so that tab-style links\n // (same routeName, different `hash` input) only mark the active variant.\n const hashValue = this.hash();\n const source = createActiveRouteSource(\n this.router,\n this.routeName(),\n this.routeParams(),\n hashValue === undefined\n ? {\n strict: this.activeStrict(),\n ignoreQueryParams: this.ignoreQueryParams(),\n }\n : {\n strict: this.activeStrict(),\n ignoreQueryParams: this.ignoreQueryParams(),\n hash: hashValue,\n },\n );\n\n this.isActive.set(source.getSnapshot());\n this.updateDom();\n\n const unsub = source.subscribe(() => {\n this.isActive.set(source.getSnapshot());\n this.updateDom();\n });\n\n this.destroyRef.onDestroy(() => {\n unsub();\n source.destroy();\n });\n }\n\n onClick(event: MouseEvent): void {\n if (!shouldNavigate(event) || this.anchor.target === \"_blank\") {\n return;\n }\n\n event.preventDefault();\n navigateWithHash(\n this.router,\n this.routeName(),\n this.routeParams(),\n this.hash(),\n this.routeOptions(),\n ).catch(() => {});\n }\n\n private updateDom(): void {\n const href = this.href();\n\n if (href !== undefined) {\n this.anchor.setAttribute(\"href\", href);\n }\n\n const activeClass = this.activeClassName();\n\n if (this.prevActiveClass && this.prevActiveClass !== activeClass) {\n this.anchor.classList.remove(this.prevActiveClass);\n }\n\n if (activeClass) {\n this.anchor.classList.toggle(activeClass, this.isActive());\n }\n\n this.prevActiveClass = activeClass;\n }\n}\n","import {\n Directive,\n ElementRef,\n inject,\n input,\n signal,\n DestroyRef,\n type OnInit,\n} from \"@angular/core\";\nimport { createActiveRouteSource } from \"@real-router/sources\";\n\nimport { applyLinkA11y } from \"../dom-utils\";\nimport { injectRouter } from \"../functions/injectRouter\";\n\nimport type { Params } from \"@real-router/core\";\n\n@Directive({ selector: \"[realLinkActive]\" })\nexport class RealLinkActive implements OnInit {\n readonly realLinkActive = input<string>(\"\");\n readonly routeName = input<string>(\"\");\n readonly routeParams = input<Params>({});\n readonly activeStrict = input(false);\n readonly ignoreQueryParams = input(true);\n\n private readonly router = injectRouter();\n private readonly destroyRef = inject(DestroyRef);\n private readonly element = inject(ElementRef).nativeElement as HTMLElement;\n private readonly isActive = signal(false);\n\n constructor() {\n applyLinkA11y(this.element);\n }\n\n ngOnInit(): void {\n const source = createActiveRouteSource(\n this.router,\n this.routeName(),\n this.routeParams(),\n {\n strict: this.activeStrict(),\n ignoreQueryParams: this.ignoreQueryParams(),\n },\n );\n\n this.isActive.set(source.getSnapshot());\n this.updateClass();\n\n const unsub = source.subscribe(() => {\n this.isActive.set(source.getSnapshot());\n this.updateClass();\n });\n\n this.destroyRef.onDestroy(() => {\n unsub();\n source.destroy();\n });\n }\n\n private updateClass(): void {\n const className = this.realLinkActive();\n\n if (!className) {\n return;\n }\n\n this.element.classList.toggle(className, this.isActive());\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["NOOP_INSTANCE"],"mappings":"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"}
@@ -50,6 +50,7 @@ declare function injectRouterTransition(): Signal<RouterTransitionSnapshot>;
50
50
  declare function injectIsActiveRoute(routeName: string, params?: Params, options?: {
51
51
  strict?: boolean;
52
52
  ignoreQueryParams?: boolean;
53
+ hash?: string;
53
54
  }): Signal<boolean>;
54
55
 
55
56
  interface RouteExitContext {
@@ -278,6 +279,13 @@ declare class RealLink implements OnInit {
278
279
  readonly activeClassName: _angular_core.InputSignal<string>;
279
280
  readonly activeStrict: _angular_core.InputSignal<boolean>;
280
281
  readonly ignoreQueryParams: _angular_core.InputSignal<boolean>;
282
+ /**
283
+ * URL fragment (decoded form, no leading "#") (#532).
284
+ * - omitted/`undefined` → preserve current fragment on same-route navigation
285
+ * - `""` → clear fragment
286
+ * - non-empty → set fragment
287
+ */
288
+ readonly hash: _angular_core.InputSignal<string | undefined>;
281
289
  private readonly router;
282
290
  private readonly destroyRef;
283
291
  private readonly anchor;
@@ -288,7 +296,7 @@ declare class RealLink implements OnInit {
288
296
  onClick(event: MouseEvent): void;
289
297
  private updateDom;
290
298
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<RealLink, never>;
291
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RealLink, "a[realLink]", never, { "routeName": { "alias": "routeName"; "required": false; "isSignal": true; }; "routeParams": { "alias": "routeParams"; "required": false; "isSignal": true; }; "routeOptions": { "alias": "routeOptions"; "required": false; "isSignal": true; }; "activeClassName": { "alias": "activeClassName"; "required": false; "isSignal": true; }; "activeStrict": { "alias": "activeStrict"; "required": false; "isSignal": true; }; "ignoreQueryParams": { "alias": "ignoreQueryParams"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
299
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<RealLink, "a[realLink]", never, { "routeName": { "alias": "routeName"; "required": false; "isSignal": true; }; "routeParams": { "alias": "routeParams"; "required": false; "isSignal": true; }; "routeOptions": { "alias": "routeOptions"; "required": false; "isSignal": true; }; "activeClassName": { "alias": "activeClassName"; "required": false; "isSignal": true; }; "activeStrict": { "alias": "activeStrict"; "required": false; "isSignal": true; }; "ignoreQueryParams": { "alias": "ignoreQueryParams"; "required": false; "isSignal": true; }; "hash": { "alias": "hash"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
292
300
  }
293
301
 
294
302
  declare class RealLinkActive implements OnInit {
@@ -1 +1 @@
1
- {"version":3,"file":"real-router-angular.d.ts","sources":["../../src/dom-utils/scroll-restore.ts","../../src/types.ts","../../src/providers.ts","../../src/sourceToSignal.ts","../../src/functions/injectRouter.ts","../../src/functions/injectNavigator.ts","../../src/functions/injectRoute.ts","../../src/functions/injectRouteNode.ts","../../src/functions/injectRouteUtils.ts","../../src/functions/injectRouterTransition.ts","../../src/functions/injectIsActiveRoute.ts","../../src/functions/injectRouteExit.ts","../../src/functions/injectRouteEnter.ts","../../src/directives/RouteMatch.ts","../../src/directives/RouteNotFound.ts","../../src/directives/RouteSelf.ts","../../src/components/RouteView.ts","../../src/components/RouterErrorBoundary.ts","../../src/components/NavigationAnnouncer.ts","../../src/directives/RealLink.ts","../../src/directives/RealLinkActive.ts"],"mappings":";;;;;;;;;AAUM,KAAM,qBAAqB;UAEhB,wBAAwB;AACvC,WAAO,qBAAqB;AAC5B;6BACyB,WAAW;AACrC;;UCZgB,YAAY,WAAW,MAAM,GAAG,MAAM;yBAChC,MAAM,CAAC,aAAa;AACzC,wBAAoB,SAAS;AAC9B;;ACWD,cAAa,MAAM,EAAA,cAAA,CAAA,MAAA;AAEnB,cAAa,SAAS,EAAA,cAAA,CAAA,SAAA;AAEtB,cAAa,KAAK,EAAA,cAAA,CAAA,YAAA,CAAA,kBAAA,CAAA,MAAA;UAED,iBAAiB;wBACZ,wBAAwB;;AAE7C;AAED,iBAAgB,iBAAiB,SACvB,MAAM,YACJ,iBAAiB,GAC1B,oBAAoB;;AC5BvB;AACA,iBAAgB,cAAc,YAAY,YAAY,MAAM,MAAM;;ACAlE,iBAAgB,YAAY,IAAI,MAAM;;ACAtC,iBAAgB,eAAe,IAAI,SAAS;;ACG5C,iBAAgB,WAAW,WAAW,MAAM,GAAG,MAAM,KAAK,IAAI,CAC5D,YAAY;AAGZ,yBAAqB,MAAM,CACzB,IAAI,CAAC,aAAa;AAAkB,eAAO,KAAK;AAAK;;;ACLzD,iBAAgB,eAAe,oBAAoB,YAAY;;ACD/D,iBAAgB,gBAAgB,IAAI,UAAU;;ACC9C,iBAAgB,sBAAsB,IAAI,MAAM,CAAC,wBAAwB;;ACAzE,iBAAgB,mBAAmB,6BAExB,MAAM;;;AAC4C,IAC1D,MAAM;;UCNQ,gBAAgB;;WAExB,KAAK;;eAED,KAAK;AAChB;;;;;;AAMG;YACK,WAAW;AACpB;UAEgB,mBAAmB;AAClC;;;;AAIG;;AAEJ;AAEK,KAAM,gBAAgB,aACjB,gBAAgB,YACf,OAAO;AAEnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2DG;AACH,iBAAgB,eAAe,UACpB,gBAAgB,YACf,mBAAmB;;UC1Fd,iBAAiB;;WAEzB,KAAK;;mBAEG,KAAK;AACrB;AAEK,KAAM,iBAAiB,aAAa,iBAAiB;UAE1C,oBAAoB;AACnC;;;;AAIG;;AAEJ;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwDG;AACH,iBAAgB,gBAAgB,UACrB,iBAAiB,YAChB,oBAAoB;;ACjFhC,cACa,UAAU;yBACF,aAAA,CAAA,WAAA;0BACC,WAAA;oDAFT,UAAU;sDAAV,UAAU;AAGtB;;ACJD,cACa,aAAa;0BACJ,WAAA;oDADT,aAAa;sDAAb,aAAa;AAEzB;;ACHD,cACa,SAAS;0BACA,WAAA;oDADT,SAAS;sDAAT,SAAS;AAErB;;ACuBD,cASa,SAAU,YAAW,MAAM;uBACrB,aAAA,CAAA,WAAA;sBAED,aAAA,CAAA,MAAA,UAAA,UAAA;oBACF,aAAA,CAAA,MAAA,UAAA,SAAA;wBACI,aAAA,CAAA,MAAA,UAAA,aAAA;6BAEK,aAAA,CAAA,MAAA,CAAA,WAAA;AAwCvB;AAaA;AACA;AACA;AAEA;oDAhEW,SAAS;sDAAT,SAAS;AA8ErB;;UCxGgB,YAAY;eAChB,WAAW;;AAEvB;AAED,cAaa,mBAAmB;4BACR,aAAA,CAAA,WAAA,CAAA,WAAA,CAAA,YAAA;AAEtB,sBAAgB,aAAA,CAAA,gBAAA;eACP,WAAW;AACT,iBAAA,KAAK;AACH,mBAAA,KAAK;AACb;2BAEgB,aAAA,CAAA,MAAA,CAAA,YAAA;AAarB;AACA;;oDAvBW,mBAAmB;sDAAnB,mBAAmB;AAwC/B;;AChED,cAIa,mBAAmB;AAC9B;;oDADW,mBAAmB;sDAAnB,mBAAmB;AAQ/B;;ACAD,cAMa,QAAS,YAAW,MAAM;wBACnB,aAAA,CAAA,WAAA;0BACE,aAAA,CAAA,WAAA,CAAA,MAAA;2BACC,aAAA,CAAA,WAAA,CAAA,iBAAA;8BACG,aAAA,CAAA,WAAA;2BACH,aAAA,CAAA,WAAA;gCACK,aAAA,CAAA,WAAA;AAE1B;AACA;AACA;AAEA;AACA;;AAKA;AAyBA,mBAAe,UAAU;AAWzB;oDAtDW,QAAQ;sDAAR,QAAQ;AAyEpB;;AChFD,cACa,cAAe,YAAW,MAAM;6BACpB,aAAA,CAAA,WAAA;wBACL,aAAA,CAAA,WAAA;0BACE,aAAA,CAAA,WAAA,CAAA,MAAA;2BACC,aAAA,CAAA,WAAA;gCACK,aAAA,CAAA,WAAA;AAE1B;AACA;AACA;AACA;;AAMA;AAyBA;oDAzCW,cAAc;sDAAd,cAAc;AAkD1B;;;;","names":[]}
1
+ {"version":3,"file":"real-router-angular.d.ts","sources":["../../src/dom-utils/scroll-restore.ts","../../src/types.ts","../../src/providers.ts","../../src/sourceToSignal.ts","../../src/functions/injectRouter.ts","../../src/functions/injectNavigator.ts","../../src/functions/injectRoute.ts","../../src/functions/injectRouteNode.ts","../../src/functions/injectRouteUtils.ts","../../src/functions/injectRouterTransition.ts","../../src/functions/injectIsActiveRoute.ts","../../src/functions/injectRouteExit.ts","../../src/functions/injectRouteEnter.ts","../../src/directives/RouteMatch.ts","../../src/directives/RouteNotFound.ts","../../src/directives/RouteSelf.ts","../../src/components/RouteView.ts","../../src/components/RouterErrorBoundary.ts","../../src/components/NavigationAnnouncer.ts","../../src/directives/RealLink.ts","../../src/directives/RealLinkActive.ts"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@real-router/angular",
3
- "version": "0.6.1",
3
+ "version": "0.7.0",
4
4
  "type": "commonjs",
5
5
  "description": "Angular 21 integration for Real-Router",
6
6
  "exports": {
@@ -37,7 +37,7 @@
37
37
  "dependencies": {
38
38
  "@real-router/core": "^0.51.0",
39
39
  "@real-router/route-utils": "^0.2.2",
40
- "@real-router/sources": "^0.7.3"
40
+ "@real-router/sources": "^0.8.0"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@analogjs/vitest-angular": "2.4.7",
@@ -10,7 +10,7 @@ import {
10
10
  } from "@angular/core";
11
11
  import { createActiveRouteSource } from "@real-router/sources";
12
12
 
13
- import { buildHref, shouldNavigate } from "../dom-utils";
13
+ import { buildHref, navigateWithHash, shouldNavigate } from "../dom-utils";
14
14
  import { injectRouter } from "../functions/injectRouter";
15
15
 
16
16
  import type { Params, NavigationOptions } from "@real-router/core";
@@ -28,26 +28,49 @@ export class RealLink implements OnInit {
28
28
  readonly activeClassName = input<string>("active");
29
29
  readonly activeStrict = input(false);
30
30
  readonly ignoreQueryParams = input(true);
31
+ /**
32
+ * URL fragment (decoded form, no leading "#") (#532).
33
+ * - omitted/`undefined` → preserve current fragment on same-route navigation
34
+ * - `""` → clear fragment
35
+ * - non-empty → set fragment
36
+ */
37
+ readonly hash = input<string | undefined>(undefined);
31
38
 
32
39
  private readonly router = injectRouter();
33
40
  private readonly destroyRef = inject(DestroyRef);
34
41
  private readonly anchor = inject(ElementRef)
35
42
  .nativeElement as HTMLAnchorElement;
36
43
  private readonly isActive = signal(false);
37
- private readonly href = computed(() =>
38
- buildHref(this.router, this.routeName(), this.routeParams()),
39
- );
44
+ private readonly href = computed(() => {
45
+ const hashValue = this.hash();
46
+
47
+ return buildHref(
48
+ this.router,
49
+ this.routeName(),
50
+ this.routeParams(),
51
+ hashValue === undefined ? undefined : { hash: hashValue },
52
+ );
53
+ });
40
54
  private prevActiveClass = "";
41
55
 
42
56
  ngOnInit(): void {
57
+ // Hash-aware active state (#532): pass `hash` so that tab-style links
58
+ // (same routeName, different `hash` input) only mark the active variant.
59
+ const hashValue = this.hash();
43
60
  const source = createActiveRouteSource(
44
61
  this.router,
45
62
  this.routeName(),
46
63
  this.routeParams(),
47
- {
48
- strict: this.activeStrict(),
49
- ignoreQueryParams: this.ignoreQueryParams(),
50
- },
64
+ hashValue === undefined
65
+ ? {
66
+ strict: this.activeStrict(),
67
+ ignoreQueryParams: this.ignoreQueryParams(),
68
+ }
69
+ : {
70
+ strict: this.activeStrict(),
71
+ ignoreQueryParams: this.ignoreQueryParams(),
72
+ hash: hashValue,
73
+ },
51
74
  );
52
75
 
53
76
  this.isActive.set(source.getSnapshot());
@@ -70,9 +93,13 @@ export class RealLink implements OnInit {
70
93
  }
71
94
 
72
95
  event.preventDefault();
73
- this.router
74
- .navigate(this.routeName(), this.routeParams(), this.routeOptions())
75
- .catch(() => {});
96
+ navigateWithHash(
97
+ this.router,
98
+ this.routeName(),
99
+ this.routeParams(),
100
+ this.hash(),
101
+ this.routeOptions(),
102
+ ).catch(() => {});
76
103
  }
77
104
 
78
105
  private updateDom(): void {
@@ -10,6 +10,7 @@ export {
10
10
  shouldNavigate,
11
11
  buildHref,
12
12
  buildActiveClassName,
13
+ navigateWithHash,
13
14
  shallowEqual,
14
15
  applyLinkA11y,
15
16
  } from "./link-utils";
@@ -1,4 +1,9 @@
1
- import type { Router, Params } from "@real-router/core";
1
+ import type {
2
+ NavigationOptions,
3
+ Params,
4
+ Router,
5
+ State,
6
+ } from "@real-router/core";
2
7
 
3
8
  export function shouldNavigate(evt: MouseEvent): boolean {
4
9
  return (
@@ -10,25 +15,67 @@ export function shouldNavigate(evt: MouseEvent): boolean {
10
15
  );
11
16
  }
12
17
 
13
- type BuildUrlFn = (name: string, params: Params) => string | undefined;
18
+ /**
19
+ * RFC 3986 fragment encoding: preserve sub-delims (`&`, `=`, `?`, `:`),
20
+ * encode space, `%`, control chars, non-ASCII via encodeURI; defensively
21
+ * escape `#` (encodeURI does not). Mirrors `encodeHashFragment` in
22
+ * `shared/browser-env/url-context.ts` — duplicated here because the
23
+ * shared/dom-utils symlink graph does not reach shared/browser-env.
24
+ */
25
+ function encodeFragmentInline(decoded: string): string {
26
+ return encodeURI(decoded).replaceAll("#", "%23");
27
+ }
14
28
 
29
+ type BuildUrlFn = (
30
+ name: string,
31
+ params: Params,
32
+ options?: { hash?: string },
33
+ ) => string | undefined;
34
+
35
+ /**
36
+ * Builds an href for a `<Link>` element.
37
+ *
38
+ * - Prefers the URL plugin's `buildUrl` (browser-plugin, navigation-plugin,
39
+ * hash-plugin) when present.
40
+ * - Falls back to `router.buildPath` for runtimes without a URL plugin
41
+ * (memory-plugin, console UIs, NativeScript). In that fallback the hash
42
+ * is appended manually so the rendered href is still correct.
43
+ * - The optional 4th argument is an options object so the contract stays
44
+ * extensible. The `hash` option is a decoded fragment without leading "#";
45
+ * `<Link hash="#section">` is accepted defensively (leading "#" stripped).
46
+ * Frozen API: previous 3-arg call sites continue to work unchanged.
47
+ */
15
48
  export function buildHref(
16
49
  router: Router,
17
50
  routeName: string,
18
51
  routeParams: Params,
52
+ options?: { hash?: string },
19
53
  ): string | undefined {
20
54
  try {
55
+ const rawHash = options?.hash;
56
+ let normHash: string | undefined;
57
+
58
+ if (rawHash !== undefined) {
59
+ normHash = rawHash.startsWith("#") ? rawHash.slice(1) : rawHash;
60
+ }
61
+
21
62
  const buildUrl = router.buildUrl as BuildUrlFn | undefined;
22
63
 
23
64
  if (buildUrl) {
24
- const url = buildUrl(routeName, routeParams);
65
+ const url = buildUrl(
66
+ routeName,
67
+ routeParams,
68
+ normHash === undefined ? undefined : { hash: normHash },
69
+ );
25
70
 
26
71
  if (url !== undefined) {
27
72
  return url;
28
73
  }
29
74
  }
30
75
 
31
- return router.buildPath(routeName, routeParams);
76
+ const path = router.buildPath(routeName, routeParams);
77
+
78
+ return normHash ? `${path}#${encodeFragmentInline(normHash)}` : path;
32
79
  } catch {
33
80
  console.error(
34
81
  `[real-router] Route "${routeName}" is not defined. The element will render without an href attribute.`,
@@ -38,6 +85,65 @@ export function buildHref(
38
85
  }
39
86
  }
40
87
 
88
+ /**
89
+ * `<Link>` click-handler navigation helper (#532).
90
+ *
91
+ * Wraps `router.navigate(name, params, opts)` with same-route different-hash
92
+ * detection: when the consumer clicks a hash-bearing Link that targets the
93
+ * current route with the same params but a different fragment, core's
94
+ * SAME_STATES check would otherwise reject the navigation. The helper adds
95
+ * `force: true` and `hashChange: true` automatically — subscribers can then
96
+ * disambiguate via `state.context.url.hashChanged`.
97
+ *
98
+ * For pure programmatic same-route hash-only navigation, callers are
99
+ * documented to pass `{ force: true }` themselves; the auto-bypass here is
100
+ * a UX convenience for `<Link hash>` that all 6 framework adapters share.
101
+ */
102
+ /**
103
+ * Local extended-options type. Adapters that depend only on `@real-router/core`
104
+ * (without a URL plugin) do not see the `NavigationOptions` augmentation that
105
+ * declares `hash` / `hashChange`. Casting to this widened type inside the
106
+ * helper keeps shared/dom-utils self-contained — adapters do not need to
107
+ * augment NavigationOptions themselves to consume `<Link hash>`.
108
+ */
109
+ type HashAwareNavigationOptions = NavigationOptions & {
110
+ hash?: string;
111
+ hashChange?: boolean;
112
+ };
113
+
114
+ export function navigateWithHash(
115
+ router: Router,
116
+ routeName: string,
117
+ routeParams: Params,
118
+ hash: string | undefined,
119
+ extraOptions?: NavigationOptions,
120
+ ): Promise<State> {
121
+ const opts: HashAwareNavigationOptions = { ...extraOptions };
122
+
123
+ if (hash !== undefined) {
124
+ opts.hash = hash;
125
+ }
126
+
127
+ const current = router.getState();
128
+
129
+ if (
130
+ current?.name === routeName &&
131
+ shallowEqual(current.params, routeParams)
132
+ ) {
133
+ const currentHash =
134
+ (current.context as { url?: { hash?: string } } | undefined)?.url?.hash ??
135
+ "";
136
+ const newHash = hash ?? currentHash;
137
+
138
+ if (currentHash !== newHash) {
139
+ opts.force = true;
140
+ opts.hashChange = true;
141
+ }
142
+ }
143
+
144
+ return router.navigate(routeName, routeParams, opts);
145
+ }
146
+
41
147
  function parseTokens(value: string | undefined): string[] {
42
148
  return value ? (value.match(/\S+/g) ?? []) : [];
43
149
  }
@@ -68,13 +68,38 @@ export function createScrollRestoration(
68
68
  }
69
69
  };
70
70
 
71
- const scrollToHashOrTop = (): void => {
71
+ const scrollToHashOrTop = (route: State): void => {
72
+ // URL plugin path (#532): `state.context.url.hash` is the source of truth
73
+ // when one of the URL plugins (browser-plugin / navigation-plugin) is
74
+ // installed. The value is already DECODED — feeding it through
75
+ // `decodeURIComponent` again would throw on a bare `%`.
76
+ const ctxHash = (route.context as { url?: { hash?: string } } | undefined)
77
+ ?.url?.hash;
78
+
79
+ if (ctxHash !== undefined) {
80
+ if (anchorEnabled && ctxHash.length > 0) {
81
+ // eslint-disable-next-line unicorn/prefer-query-selector -- ids may contain CSS-unsafe chars
82
+ const element = document.getElementById(ctxHash);
83
+
84
+ if (element) {
85
+ element.scrollIntoView();
86
+
87
+ return;
88
+ }
89
+ }
90
+
91
+ writePos(0);
92
+
93
+ return;
94
+ }
95
+
96
+ // Fallback path: no URL plugin, read the DOM. `location.hash` is
97
+ // percent-encoded; ids in the DOM are the raw string, so decode for the
98
+ // match. Fall back to the raw slice if the hash contains a malformed
99
+ // escape sequence (decodeURIComponent throws on those).
72
100
  const hash = globalThis.location.hash;
73
101
 
74
102
  if (anchorEnabled && hash.length > 1) {
75
- // location.hash is percent-encoded; ids in the DOM are the raw string.
76
- // Decode for the match. Fall back to the raw slice if the hash contains
77
- // a malformed escape sequence (decodeURIComponent throws on those).
78
103
  let id: string;
79
104
 
80
105
  try {
@@ -117,7 +142,7 @@ export function createScrollRestoration(
117
142
  }
118
143
 
119
144
  if (mode === "top" || !nav) {
120
- scrollToHashOrTop();
145
+ scrollToHashOrTop(route);
121
146
 
122
147
  return;
123
148
  }
@@ -136,7 +161,7 @@ export function createScrollRestoration(
136
161
  return;
137
162
  }
138
163
 
139
- scrollToHashOrTop();
164
+ scrollToHashOrTop(route);
140
165
  });
141
166
  });
142
167
 
@@ -9,13 +9,22 @@ import type { Params } from "@real-router/core";
9
9
  export function injectIsActiveRoute(
10
10
  routeName: string,
11
11
  params?: Params,
12
- options?: { strict?: boolean; ignoreQueryParams?: boolean },
12
+ options?: { strict?: boolean; ignoreQueryParams?: boolean; hash?: string },
13
13
  ): Signal<boolean> {
14
14
  const router = injectRouter();
15
- const source = createActiveRouteSource(router, routeName, params, {
16
- strict: options?.strict ?? false,
17
- ignoreQueryParams: options?.ignoreQueryParams ?? true,
18
- });
15
+ const strict = options?.strict ?? false;
16
+ const ignoreQueryParams = options?.ignoreQueryParams ?? true;
17
+ const hash = options?.hash;
18
+ // exactOptionalPropertyTypes forbids `{ hash: undefined }` literally — pass
19
+ // the field only when a value was provided. (#532)
20
+ const source = createActiveRouteSource(
21
+ router,
22
+ routeName,
23
+ params,
24
+ hash === undefined
25
+ ? { strict, ignoreQueryParams }
26
+ : { strict, ignoreQueryParams, hash },
27
+ );
19
28
 
20
29
  return sourceToSignal(source);
21
30
  }