refactor: migrate cart payment modals to shared app-dialog primitive
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
Some checks failed
Architecture Governance / architecture (push) Has been cancelled
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>
This commit is contained in:
@@ -195,9 +195,15 @@
|
||||
</div>
|
||||
|
||||
<!-- Payment Popup Modal -->
|
||||
@if (showPaymentPopup()) {
|
||||
<div class="payment-modal-overlay">
|
||||
<div class="payment-modal" #paymentModalPanel role="dialog" aria-modal="true" [attr.aria-label]="'cart.checkout' | translate" tabindex="-1">
|
||||
<app-dialog
|
||||
class="payment-dialog"
|
||||
[open]="showPaymentPopup()"
|
||||
size="md"
|
||||
[ariaLabel]="'cart.checkout' | translate"
|
||||
[closeOnBackdropClick]="false"
|
||||
[closeOnEscape]="!showBankPaymentPopup()"
|
||||
(closed)="closePaymentPopup()"
|
||||
>
|
||||
<button class="close-modal-btn" (click)="closePaymentPopup()" [attr.aria-label]="'cart.close' | translate">
|
||||
<app-icon name="x" [size]="20" />
|
||||
</button>
|
||||
@@ -276,19 +282,22 @@
|
||||
<p class="auto-close">{{ 'cart.autoClose' | translate }}</p>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</app-dialog>
|
||||
|
||||
@if (showBankPaymentPopup() && bankPaymentFrameUrl()) {
|
||||
<div class="bank-payment-modal-overlay">
|
||||
<div class="bank-payment-modal" #bankPaymentModalPanel role="dialog" aria-modal="true" [attr.aria-label]="'cart.payViaCard' | translate" tabindex="-1">
|
||||
<button class="close-modal-btn" (click)="closeBankPaymentPopup()" [attr.aria-label]="'cart.close' | translate">
|
||||
<app-icon name="x" [size]="20" />
|
||||
</button>
|
||||
<iframe [src]="bankPaymentFrameUrl()" class="bank-payment-frame" [attr.title]="'common.bankCardPayment' | translate"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
@if (showBankPaymentPopup() && bankPaymentFrameUrl()) {
|
||||
<app-dialog
|
||||
class="bank-payment-dialog"
|
||||
[open]="showBankPaymentPopup()"
|
||||
size="lg"
|
||||
[ariaLabel]="'cart.payViaCard' | translate"
|
||||
[closeOnBackdropClick]="false"
|
||||
(closed)="closeBankPaymentPopup()"
|
||||
>
|
||||
<button class="close-modal-btn" (click)="closeBankPaymentPopup()" [attr.aria-label]="'cart.close' | translate">
|
||||
<app-icon name="x" [size]="20" />
|
||||
</button>
|
||||
<iframe [src]="bankPaymentFrameUrl()" class="bank-payment-frame" [attr.title]="'common.bankCardPayment' | translate"></iframe>
|
||||
</app-dialog>
|
||||
}
|
||||
|
||||
<app-telegram-login />
|
||||
|
||||
Reference in New Issue
Block a user