angular/adev/shared-docs/components/top-level-banner/top-level-banner.component.ts
kirjs 6ff53b7437 docs(docs-infra): Drop standalone: true (#58914)
This is now the default value, so safe to remove

PR Close #58914
2024-11-28 09:43:28 +01:00

68 lines
2.3 KiB
TypeScript

import {ChangeDetectionStrategy, Component, inject, input, OnInit, signal} from '@angular/core';
import {ExternalLink} from '../../directives';
import {LOCAL_STORAGE} from '../../providers';
import {IconComponent} from '../icon/icon.component';
export const STORAGE_KEY_PREFIX = 'docs-was-closed-top-banner-';
@Component({
selector: 'docs-top-level-banner',
imports: [ExternalLink, IconComponent],
templateUrl: './top-level-banner.component.html',
styleUrl: './top-level-banner.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TopLevelBannerComponent implements OnInit {
private readonly localStorage = inject(LOCAL_STORAGE);
/**
* Unique identifier for the banner. This ID is required to ensure that
* the state of the banner (e.g., whether it has been closed) is tracked
* separately for different events or instances. Without a unique ID,
* closing one banner could inadvertently hide other banners for different events.
*/
id = input.required<string>();
// Optional URL link that the banner should navigate to when clicked.
link = input<string>();
// Text content to be displayed in the banner.
text = input.required<string>();
// Optional expiry date. Setting the default expiry as a future date so we
// don't have to deal with undefined signal values.
expiry = input(new Date('3000-01-01'), {transform: parseDate});
// Whether the user has closed the banner or the survey has expired.
hasClosed = signal<boolean>(false);
ngOnInit(): void {
const expired = Date.now() > this.expiry().getTime();
// Needs to be in a try/catch, because some browsers will
// throw when using `localStorage` in private mode.
try {
this.hasClosed.set(
this.localStorage?.getItem(this.getBannerStorageKey()) === 'true' || expired,
);
} catch {
this.hasClosed.set(false);
}
}
close(): void {
this.localStorage?.setItem(this.getBannerStorageKey(), 'true');
this.hasClosed.set(true);
}
private getBannerStorageKey(): string {
return `${STORAGE_KEY_PREFIX}${this.id()}`;
}
}
const parseDate = (inputDate: string | Date): Date => {
if (inputDate instanceof Date) {
return inputDate;
}
const outputDate = new Date(inputDate);
if (isNaN(outputDate.getTime())) {
throw new Error(`Invalid date string: ${inputDate}`);
}
return outputDate;
};