@real-router/angular 0.3.0 → 0.5.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 +60 -1
- package/dist/README.md +60 -1
- package/dist/fesm2022/real-router-angular.mjs +408 -8
- package/dist/fesm2022/real-router-angular.mjs.map +1 -1
- package/dist/types/real-router-angular.d.ts +171 -4
- package/dist/types/real-router-angular.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/components/RouteView.ts +14 -0
- package/src/directives/RouteSelf.ts +6 -0
- package/src/dom-utils/direction-tracker.ts +70 -0
- package/src/dom-utils/index.ts +8 -0
- package/src/dom-utils/route-announcer.ts +1 -1
- package/src/dom-utils/view-transitions.ts +142 -0
- package/src/functions/index.ts +16 -0
- package/src/functions/injectRouteEnter.ts +129 -0
- package/src/functions/injectRouteExit.ts +118 -0
- package/src/index.ts +13 -0
- package/src/providers.ts +35 -1
package/README.md
CHANGED
|
@@ -110,6 +110,8 @@ All inject functions must be called within an injection context (constructor, fi
|
|
|
110
110
|
| `injectRouteUtils()` | `RouteUtils` | Never |
|
|
111
111
|
| `injectRouterTransition()` | `Signal<RouterTransitionSnapshot>` | On transition start/end |
|
|
112
112
|
| `injectIsActiveRoute(name, params?, opts?)` | `Signal<boolean>` | On active state change |
|
|
113
|
+
| `injectRouteExit(handler, options?)` | `void` — wraps `subscribeLeave` with abort + same-route guards | Never (handler captured at injection time) |
|
|
114
|
+
| `injectRouteEnter(handler, options?)` | `void` — fires once on nav-driven mount via `effect()` + `transition.from` | Never (handler captured at injection time) |
|
|
113
115
|
|
|
114
116
|
`RouteSignals` shape:
|
|
115
117
|
|
|
@@ -166,8 +168,48 @@ export class BackButtonComponent {
|
|
|
166
168
|
export class ProgressComponent {
|
|
167
169
|
readonly transition = injectRouterTransition();
|
|
168
170
|
}
|
|
171
|
+
|
|
172
|
+
// injectRouteExit — exit animations, draft autosave, AbortSignal-aware cleanup
|
|
173
|
+
@Component({
|
|
174
|
+
selector: "app-fade-out",
|
|
175
|
+
template: `<div #box>...</div>`,
|
|
176
|
+
})
|
|
177
|
+
export class FadeOutComponent {
|
|
178
|
+
private el = viewChild.required<ElementRef<HTMLDivElement>>("box");
|
|
179
|
+
|
|
180
|
+
constructor() {
|
|
181
|
+
injectRouteExit(async ({ signal }) => {
|
|
182
|
+
const el = this.el().nativeElement;
|
|
183
|
+
el.classList.add("fade-out");
|
|
184
|
+
const cleanup = () => el.classList.remove("fade-out");
|
|
185
|
+
signal.addEventListener("abort", cleanup, { once: true });
|
|
186
|
+
el.getBoundingClientRect(); // style flush
|
|
187
|
+
await Promise.allSettled(el.getAnimations().map((a) => a.finished));
|
|
188
|
+
cleanup();
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// injectRouteEnter — page-enter analytics, focus management, entry animations
|
|
194
|
+
@Component({ selector: "app-page-enter", template: "" })
|
|
195
|
+
export class PageEnterAnalyticsComponent {
|
|
196
|
+
constructor() {
|
|
197
|
+
injectRouteEnter(({ route, previousRoute }) => {
|
|
198
|
+
analytics.track("page_enter", {
|
|
199
|
+
route: route.name,
|
|
200
|
+
from: previousRoute.name,
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
169
205
|
```
|
|
170
206
|
|
|
207
|
+
> **Angular handler-reactivity:** `inject*` functions run once at construction,
|
|
208
|
+
> so `handler` is captured at injection time. Pass a class method (stable
|
|
209
|
+
> identity) and read signals **inside** the handler body to react to changes.
|
|
210
|
+
> See [CLAUDE.md](./CLAUDE.md) → "injectRouteExit / injectRouteEnter Handler
|
|
211
|
+
> Is Captured At Injection Time".
|
|
212
|
+
|
|
171
213
|
## Components
|
|
172
214
|
|
|
173
215
|
### `<route-view>`
|
|
@@ -358,11 +400,28 @@ bootstrapApplication(AppComponent, {
|
|
|
358
400
|
```typescript
|
|
359
401
|
interface RealRouterOptions {
|
|
360
402
|
scrollRestoration?: ScrollRestorationOptions; // { mode?, anchorScrolling?, scrollContainer? }
|
|
403
|
+
viewTransitions?: boolean;
|
|
361
404
|
}
|
|
362
405
|
```
|
|
363
406
|
|
|
364
407
|
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"manual"`. Custom containers via `scrollContainer: () => HTMLElement | null`. The utility is created by `provideEnvironmentInitializer` and torn down via `inject(DestroyRef)`. Options are a snapshot at bootstrap — not reactive to runtime changes. See [Scroll Restoration guide](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) for details.
|
|
365
408
|
|
|
409
|
+
## View Transitions
|
|
410
|
+
|
|
411
|
+
Opt-in animated route transitions via the browser's [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API):
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
import { provideRealRouter } from "@real-router/angular";
|
|
415
|
+
|
|
416
|
+
bootstrapApplication(AppComponent, {
|
|
417
|
+
providers: [
|
|
418
|
+
provideRealRouter(router, { viewTransitions: true }),
|
|
419
|
+
],
|
|
420
|
+
});
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
No-op on unsupported browsers (Firefox as of 2026-04, SSR). Utility is created by `provideEnvironmentInitializer` at bootstrap and torn down via `inject(DestroyRef)`. Option is a snapshot at bootstrap — not reactive to runtime changes. Customization is pure CSS via `::view-transition-*` pseudo-elements and `view-transition-name` for hero morphs. See [View Transitions guide](https://github.com/greydragon888/real-router/wiki/View-Transitions) for patterns.
|
|
424
|
+
|
|
366
425
|
## Angular-Specific Patterns
|
|
367
426
|
|
|
368
427
|
### Signals, Not Observables
|
|
@@ -460,7 +519,7 @@ const transitionSignal = sourceToSignal(createTransitionSource(router));
|
|
|
460
519
|
Full documentation: [Wiki](https://github.com/greydragon888/real-router/wiki)
|
|
461
520
|
|
|
462
521
|
- [RouterProvider](https://github.com/greydragon888/real-router/wiki/RouterProvider) · [RouteView](https://github.com/greydragon888/real-router/wiki/RouteView) · [RouterErrorBoundary](https://github.com/greydragon888/real-router/wiki/RouterErrorBoundary) · [Scroll Restoration](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration)
|
|
463
|
-
- [injectRouter](https://github.com/greydragon888/real-router/wiki/injectRouter) · [injectRoute](https://github.com/greydragon888/real-router/wiki/injectRoute) · [injectRouteNode](https://github.com/greydragon888/real-router/wiki/injectRouteNode) · [injectNavigator](https://github.com/greydragon888/real-router/wiki/injectNavigator) · [injectRouteUtils](https://github.com/greydragon888/real-router/wiki/injectRouteUtils) · [injectRouterTransition](https://github.com/greydragon888/real-router/wiki/injectRouterTransition)
|
|
522
|
+
- [injectRouter](https://github.com/greydragon888/real-router/wiki/injectRouter) · [injectRoute](https://github.com/greydragon888/real-router/wiki/injectRoute) · [injectRouteNode](https://github.com/greydragon888/real-router/wiki/injectRouteNode) · [injectNavigator](https://github.com/greydragon888/real-router/wiki/injectNavigator) · [injectRouteUtils](https://github.com/greydragon888/real-router/wiki/injectRouteUtils) · [injectRouterTransition](https://github.com/greydragon888/real-router/wiki/injectRouterTransition) · [injectRouteExit](https://github.com/greydragon888/real-router/wiki/injectRouteExit) · [injectRouteEnter](https://github.com/greydragon888/real-router/wiki/injectRouteEnter)
|
|
464
523
|
|
|
465
524
|
## Related Packages
|
|
466
525
|
|
package/dist/README.md
CHANGED
|
@@ -110,6 +110,8 @@ All inject functions must be called within an injection context (constructor, fi
|
|
|
110
110
|
| `injectRouteUtils()` | `RouteUtils` | Never |
|
|
111
111
|
| `injectRouterTransition()` | `Signal<RouterTransitionSnapshot>` | On transition start/end |
|
|
112
112
|
| `injectIsActiveRoute(name, params?, opts?)` | `Signal<boolean>` | On active state change |
|
|
113
|
+
| `injectRouteExit(handler, options?)` | `void` — wraps `subscribeLeave` with abort + same-route guards | Never (handler captured at injection time) |
|
|
114
|
+
| `injectRouteEnter(handler, options?)` | `void` — fires once on nav-driven mount via `effect()` + `transition.from` | Never (handler captured at injection time) |
|
|
113
115
|
|
|
114
116
|
`RouteSignals` shape:
|
|
115
117
|
|
|
@@ -166,8 +168,48 @@ export class BackButtonComponent {
|
|
|
166
168
|
export class ProgressComponent {
|
|
167
169
|
readonly transition = injectRouterTransition();
|
|
168
170
|
}
|
|
171
|
+
|
|
172
|
+
// injectRouteExit — exit animations, draft autosave, AbortSignal-aware cleanup
|
|
173
|
+
@Component({
|
|
174
|
+
selector: "app-fade-out",
|
|
175
|
+
template: `<div #box>...</div>`,
|
|
176
|
+
})
|
|
177
|
+
export class FadeOutComponent {
|
|
178
|
+
private el = viewChild.required<ElementRef<HTMLDivElement>>("box");
|
|
179
|
+
|
|
180
|
+
constructor() {
|
|
181
|
+
injectRouteExit(async ({ signal }) => {
|
|
182
|
+
const el = this.el().nativeElement;
|
|
183
|
+
el.classList.add("fade-out");
|
|
184
|
+
const cleanup = () => el.classList.remove("fade-out");
|
|
185
|
+
signal.addEventListener("abort", cleanup, { once: true });
|
|
186
|
+
el.getBoundingClientRect(); // style flush
|
|
187
|
+
await Promise.allSettled(el.getAnimations().map((a) => a.finished));
|
|
188
|
+
cleanup();
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// injectRouteEnter — page-enter analytics, focus management, entry animations
|
|
194
|
+
@Component({ selector: "app-page-enter", template: "" })
|
|
195
|
+
export class PageEnterAnalyticsComponent {
|
|
196
|
+
constructor() {
|
|
197
|
+
injectRouteEnter(({ route, previousRoute }) => {
|
|
198
|
+
analytics.track("page_enter", {
|
|
199
|
+
route: route.name,
|
|
200
|
+
from: previousRoute.name,
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
}
|
|
169
205
|
```
|
|
170
206
|
|
|
207
|
+
> **Angular handler-reactivity:** `inject*` functions run once at construction,
|
|
208
|
+
> so `handler` is captured at injection time. Pass a class method (stable
|
|
209
|
+
> identity) and read signals **inside** the handler body to react to changes.
|
|
210
|
+
> See [CLAUDE.md](./CLAUDE.md) → "injectRouteExit / injectRouteEnter Handler
|
|
211
|
+
> Is Captured At Injection Time".
|
|
212
|
+
|
|
171
213
|
## Components
|
|
172
214
|
|
|
173
215
|
### `<route-view>`
|
|
@@ -358,11 +400,28 @@ bootstrapApplication(AppComponent, {
|
|
|
358
400
|
```typescript
|
|
359
401
|
interface RealRouterOptions {
|
|
360
402
|
scrollRestoration?: ScrollRestorationOptions; // { mode?, anchorScrolling?, scrollContainer? }
|
|
403
|
+
viewTransitions?: boolean;
|
|
361
404
|
}
|
|
362
405
|
```
|
|
363
406
|
|
|
364
407
|
Restores scroll on back/forward, scrolls to top (or `#hash`) on push. Three modes: `"restore"` (default), `"top"`, `"manual"`. Custom containers via `scrollContainer: () => HTMLElement | null`. The utility is created by `provideEnvironmentInitializer` and torn down via `inject(DestroyRef)`. Options are a snapshot at bootstrap — not reactive to runtime changes. See [Scroll Restoration guide](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration) for details.
|
|
365
408
|
|
|
409
|
+
## View Transitions
|
|
410
|
+
|
|
411
|
+
Opt-in animated route transitions via the browser's [View Transitions API](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API):
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
import { provideRealRouter } from "@real-router/angular";
|
|
415
|
+
|
|
416
|
+
bootstrapApplication(AppComponent, {
|
|
417
|
+
providers: [
|
|
418
|
+
provideRealRouter(router, { viewTransitions: true }),
|
|
419
|
+
],
|
|
420
|
+
});
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
No-op on unsupported browsers (Firefox as of 2026-04, SSR). Utility is created by `provideEnvironmentInitializer` at bootstrap and torn down via `inject(DestroyRef)`. Option is a snapshot at bootstrap — not reactive to runtime changes. Customization is pure CSS via `::view-transition-*` pseudo-elements and `view-transition-name` for hero morphs. See [View Transitions guide](https://github.com/greydragon888/real-router/wiki/View-Transitions) for patterns.
|
|
424
|
+
|
|
366
425
|
## Angular-Specific Patterns
|
|
367
426
|
|
|
368
427
|
### Signals, Not Observables
|
|
@@ -460,7 +519,7 @@ const transitionSignal = sourceToSignal(createTransitionSource(router));
|
|
|
460
519
|
Full documentation: [Wiki](https://github.com/greydragon888/real-router/wiki)
|
|
461
520
|
|
|
462
521
|
- [RouterProvider](https://github.com/greydragon888/real-router/wiki/RouterProvider) · [RouteView](https://github.com/greydragon888/real-router/wiki/RouteView) · [RouterErrorBoundary](https://github.com/greydragon888/real-router/wiki/RouterErrorBoundary) · [Scroll Restoration](https://github.com/greydragon888/real-router/wiki/Scroll-Restoration)
|
|
463
|
-
- [injectRouter](https://github.com/greydragon888/real-router/wiki/injectRouter) · [injectRoute](https://github.com/greydragon888/real-router/wiki/injectRoute) · [injectRouteNode](https://github.com/greydragon888/real-router/wiki/injectRouteNode) · [injectNavigator](https://github.com/greydragon888/real-router/wiki/injectNavigator) · [injectRouteUtils](https://github.com/greydragon888/real-router/wiki/injectRouteUtils) · [injectRouterTransition](https://github.com/greydragon888/real-router/wiki/injectRouterTransition)
|
|
522
|
+
- [injectRouter](https://github.com/greydragon888/real-router/wiki/injectRouter) · [injectRoute](https://github.com/greydragon888/real-router/wiki/injectRoute) · [injectRouteNode](https://github.com/greydragon888/real-router/wiki/injectRouteNode) · [injectNavigator](https://github.com/greydragon888/real-router/wiki/injectNavigator) · [injectRouteUtils](https://github.com/greydragon888/real-router/wiki/injectRouteUtils) · [injectRouterTransition](https://github.com/greydragon888/real-router/wiki/injectRouterTransition) · [injectRouteExit](https://github.com/greydragon888/real-router/wiki/injectRouteExit) · [injectRouteEnter](https://github.com/greydragon888/real-router/wiki/injectRouteEnter)
|
|
464
523
|
|
|
465
524
|
## Related Packages
|
|
466
525
|
|