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: `
@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}`;
}
}