Files
shopit-front/src/app/shared/components/modal-shell/modal-shell.component.ts

66 lines
1.7 KiB
TypeScript

import { NgClass } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
ElementRef,
computed,
input,
output,
viewChild,
} from '@angular/core';
import { ModalSize } from '../../../core/services/modal.service';
@Component({
selector: 'app-modal-shell',
imports: [NgClass],
templateUrl: './modal-shell.component.html',
styleUrl: './modal-shell.component.scss',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ModalShellComponent {
private readonly panel = viewChild.required<ElementRef<HTMLElement>>('panel');
readonly title = input<string | undefined>();
readonly size = input<ModalSize>('md');
readonly showCloseButton = input(true);
readonly backdropClick = output<void>();
readonly closeRequested = output<void>();
protected readonly dialogClass = computed(() => {
const size = this.size();
return {
'modal-shell__dialog--qr': size === 'qr',
'modal-sm': size === 'sm',
'modal-lg': size === 'lg',
'modal-xl': size === 'xl',
'modal-shell__dialog--full': size === 'full',
};
});
protected readonly titleId = `modal-title-${Math.random().toString(36).slice(2, 9)}`;
protected get ariaLabelledBy(): string | null {
return this.title() ? this.titleId : null;
}
focusInitialElement(): void {
const panel = this.panel().nativeElement;
const focusTarget = panel.querySelector<HTMLElement>(
[
'[autofocus]',
'button:not([disabled])',
'[href]',
'input:not([disabled])',
'select:not([disabled])',
'textarea:not([disabled])',
'[tabindex]:not([tabindex="-1"])',
].join(', '),
);
(focusTarget ?? panel).focus();
}
}