2026-07-15 03:34:52 +04:00
|
|
|
@if (open()) {
|
|
|
|
|
<div class="app-dialog-backdrop" (click)="handleBackdropClick()">
|
|
|
|
|
<div
|
|
|
|
|
#panel
|
|
|
|
|
class="app-dialog-panel"
|
|
|
|
|
[class.app-dialog-panel--sm]="size() === 'sm'"
|
|
|
|
|
[class.app-dialog-panel--md]="size() === 'md'"
|
|
|
|
|
[class.app-dialog-panel--lg]="size() === 'lg'"
|
|
|
|
|
role="dialog"
|
|
|
|
|
aria-modal="true"
|
refactor: migrate cart payment modals to shared app-dialog primitive
Third attempt, done properly this time - first two were reverted
(one stopped cleanly on real conflicts, one botched sequencing and
deleted the old focus-trap before finishing the swap).
DialogComponent gains closeOnEscape/closeOnBackdropClick (default true,
backward-compatible with its 13 other call sites) and ariaLabel (for
dialogs with no visible title header). FOCUSABLE_SELECTOR now includes
iframe for the bank-payment panel's focus trap.
Cart wires closeOnBackdropClick=false on both dialogs (in-flight payment
shouldn't cancel on a stray click) and closeOnEscape tied to the bank
popup's open state, so Escape closes the nested bank iframe first and
falls back to the QR view - matches the original priority exactly.
Original geometry (500px QR modal/40px padding, 960x760 bank modal/
56-16-16 padding, both mobile breakpoints) preserved via :host ::ng-deep
overrides scoped per dialog instance - same pattern already used by
product-carousel-widget.component.ts.
cart.component.ts loses ~90 lines of hand-rolled ViewChild/HostListener/
focus-trap code - app-dialog owns all of it now.
Verified live in browser: dialog sizing/padding/aria-label correct at
mobile+desktop, backdrop-click confirmed inert, Escape-priority confirmed
(bank closes first, then QR), initial focus lands on close button.
83/83 tests pass, tsc/build clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 11:13:33 +04:00
|
|
|
[attr.aria-label]="titleText() ?? ariaLabel()"
|
2026-07-15 03:34:52 +04:00
|
|
|
tabindex="-1"
|
|
|
|
|
(click)="$event.stopPropagation()"
|
|
|
|
|
>
|
|
|
|
|
@if (titleText()) {
|
|
|
|
|
<div class="app-dialog-panel__header">
|
|
|
|
|
<h2 class="app-dialog-panel__title">{{ titleText() }}</h2>
|
|
|
|
|
<button
|
|
|
|
|
type="button"
|
|
|
|
|
class="app-dialog-panel__close"
|
|
|
|
|
(click)="requestClose()"
|
2026-07-25 23:54:08 +04:00
|
|
|
[attr.aria-label]="'common.closeDialog' | translate"
|
2026-07-15 03:34:52 +04:00
|
|
|
>
|
|
|
|
|
×
|
|
|
|
|
</button>
|
|
|
|
|
</div>
|
|
|
|
|
}
|
|
|
|
|
<div class="app-dialog-panel__body">
|
|
|
|
|
<ng-content />
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
}
|