@real-router/angular 0.6.0 → 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 +10 -0
- package/dist/README.md +10 -0
- package/dist/fesm2022/real-router-angular.mjs +110 -23
- package/dist/fesm2022/real-router-angular.mjs.map +1 -1
- package/dist/types/real-router-angular.d.ts +9 -1
- package/dist/types/real-router-angular.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/directives/RealLink.ts +38 -11
- package/src/dom-utils/index.ts +1 -0
- package/src/dom-utils/link-utils.ts +110 -4
- package/src/dom-utils/scroll-restore.ts +31 -6
- package/src/functions/injectIsActiveRoute.ts +14 -5
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
|
-
|
|
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
|
-
|
|
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
|
|
654
|
-
|
|
655
|
-
|
|
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(() =>
|
|
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
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
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
|
|
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.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"description": "Angular 21 integration for Real-Router",
|
|
6
6
|
"exports": {
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"license": "MIT",
|
|
36
36
|
"sideEffects": false,
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@real-router/core": "^0.
|
|
39
|
-
"@real-router/route-utils": "^0.2.
|
|
40
|
-
"@real-router/sources": "^0.
|
|
38
|
+
"@real-router/core": "^0.51.0",
|
|
39
|
+
"@real-router/route-utils": "^0.2.2",
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
|
|
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
|
-
|
|
74
|
-
|
|
75
|
-
.
|
|
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 {
|
package/src/dom-utils/index.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
16
|
-
|
|
17
|
-
|
|
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
|
}
|