@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 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