generated from bastian/boilerplate
szenario
This commit is contained in:
@@ -1,11 +1,18 @@
|
||||
import { Component, inject } from '@angular/core';
|
||||
import { Component, effect, inject, viewChild } from '@angular/core';
|
||||
import type { ElementRef } from '@angular/core';
|
||||
import { ToastService } from './toast.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ui-toast-host',
|
||||
standalone: true,
|
||||
template: `
|
||||
<section class="ui-toast-region" aria-live="polite" aria-label="Meldungen">
|
||||
<section
|
||||
#region
|
||||
class="ui-toast-region"
|
||||
popover="manual"
|
||||
aria-live="polite"
|
||||
aria-label="Meldungen"
|
||||
>
|
||||
@for (toast of toasts.messages(); track toast.id) {
|
||||
<article class="ui-toast" [class]="toast.tone">
|
||||
<div>
|
||||
@@ -37,6 +44,11 @@ import { ToastService } from './toast.service';
|
||||
bottom: var(--space-4);
|
||||
z-index: var(--z-toast);
|
||||
width: min(26rem, calc(100vw - var(--space-7)));
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
overflow: visible;
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
@@ -76,4 +88,24 @@ import { ToastService } from './toast.service';
|
||||
})
|
||||
export class UiToastHostComponent {
|
||||
readonly toasts = inject(ToastService);
|
||||
private readonly region = viewChild<ElementRef<HTMLElement>>('region');
|
||||
|
||||
constructor() {
|
||||
effect(() => {
|
||||
const region = this.region()?.nativeElement;
|
||||
const hasMessages = this.toasts.messages().length > 0;
|
||||
if (!region || typeof region.showPopover !== 'function') return;
|
||||
|
||||
const isOpen = region.matches(':popover-open');
|
||||
if (!hasMessages) {
|
||||
if (isOpen) region.hidePopover();
|
||||
return;
|
||||
}
|
||||
|
||||
// Erneutes Oeffnen setzt den Toast im Top Layer auch vor einen bereits
|
||||
// geoeffneten modalen Dialog.
|
||||
if (isOpen) region.hidePopover();
|
||||
region.showPopover();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,15 @@ describe('shared UI components', () => {
|
||||
expect((fixture.nativeElement as HTMLElement).textContent).not.toContain('Gespeichert');
|
||||
});
|
||||
|
||||
it('places the toast region in the browser top layer', async () => {
|
||||
await TestBed.configureTestingModule({ imports: [UiTestHostComponent] }).compileComponents();
|
||||
const fixture = TestBed.createComponent(UiTestHostComponent);
|
||||
fixture.detectChanges();
|
||||
|
||||
const region = (fixture.nativeElement as HTMLElement).querySelector('.ui-toast-region');
|
||||
expect(region?.getAttribute('popover')).toBe('manual');
|
||||
});
|
||||
|
||||
it('emits empty state and pagination actions', async () => {
|
||||
await TestBed.configureTestingModule({ imports: [UiTestHostComponent] }).compileComponents();
|
||||
const fixture = TestBed.createComponent(UiTestHostComponent);
|
||||
|
||||
Reference in New Issue
Block a user