import { ChangeDetectionStrategy, Component, computed, inject, input, output, signal, } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { PiActionButtonComponent, PiIconButtonComponent, PiSegmentedControlComponent, type SegmentedControlOption, } from '@pi/ui'; import { AppearanceService } from '../core/appearance'; import type { Copy } from '../core/copy'; import type { Locale, SitePayload } from '../core/api'; /** * A section of the landing (`anchor`) or another address altogether (`href`), * such as one of the pages the panel publishes. */ export interface NavLink { label: string; anchor?: string; href?: string; } @Component({ selector: 'app-site-header', changeDetection: ChangeDetectionStrategy.OnPush, imports: [ PiActionButtonComponent, PiIconButtonComponent, PiSegmentedControlComponent, ], styleUrl: './site-header.scss', template: `
Pireon
@if (localeOptions().length > 1) { }
@if (open()) { }
`, }) export class SiteHeader { readonly copy = input.required(); readonly locale = input.required(); readonly links = input.required(); readonly locales = input.required(); /** Where the logo leads: the top of the landing when on it, the landing itself elsewhere. */ readonly brandHref = input('#top'); /** * The same page in each language, as the API's `alternates` spells it. Null * on the landing, which answers on `?lang=` instead. A language missing from * it has no translation of this page, so the switcher leads to the landing * in that language rather than to a 404. */ readonly alternates = input> | null>(null); readonly navigate = output(); protected readonly appearance = inject(AppearanceService); private readonly document = inject(DOCUMENT); protected readonly open = signal(false); protected readonly localeOptions = computed[]>( () => this.locales().map((option) => ({ value: option.code as Locale, label: option.code.toUpperCase(), })) ); /** * A full navigation rather than a client-side one: the page's content is * resolved from `?lang=` on the server, so the server has to render it again. */ protected switchLocale(next: Locale | undefined): void { if (!next || next === this.locale()) { return; } this.document.defaultView?.location.assign(this.localeHref(next)); } protected localeHref(code: string): string { return this.alternates()?.[code] ?? `/?lang=${code}`; } protected hrefOf(link: NavLink): string { return link.href ?? `#${link.anchor}`; } }