import {
DOCUMENT,
ENVIRONMENT_INITIALIZER,
EnvironmentInjector,
afterNextRender,
inject,
} from '@angular/core';
import { NavigationEnd, Router } from '@angular/router';
/** Template-layer wiring (not a component): on every route change after the
initial load, moves focus to the new page's `
` (page-shell always
renders one) so screen-reader/keyboard users land on the new content
instead of wherever focus happened to be. Falls back to `#main` (the
shell's landmark) if a page has no heading. Deferred via `afterNextRender`
so it doesn't race Angular's view-transition DOM swap. */
export function provideRouteFocus() {
return {
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useValue: () => {
const router = inject(Router);
const document = inject(DOCUMENT);
const injector = inject(EnvironmentInjector);
let isInitialLoad = true;
router.events.subscribe((event) => {
if (!(event instanceof NavigationEnd)) return;
if (isInitialLoad) {
isInitialLoad = false;
return;
}
afterNextRender(
() => {
const target =
document.querySelector('#main h1') ?? document.getElementById('main');
if (!target) return;
target.setAttribute('tabindex', '-1');
target.focus({ preventScroll: true });
},
{ injector },
);
});
},
};
}