feat: improve modal styling and enhance padding management in modal host component
This commit is contained in:
@@ -3,25 +3,10 @@ import { Component, inject } from '@angular/core';
|
||||
import { DOCUMENT } from '@angular/common';
|
||||
import { TestBed, getTestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import {
|
||||
BrowserTestingModule,
|
||||
platformBrowserTesting
|
||||
} from '@angular/platform-browser/testing';
|
||||
import {
|
||||
afterEach,
|
||||
beforeAll,
|
||||
beforeEach,
|
||||
describe,
|
||||
expect,
|
||||
it,
|
||||
vi
|
||||
} from 'vitest';
|
||||
import { BrowserTestingModule, platformBrowserTesting } from '@angular/platform-browser/testing';
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
|
||||
import {
|
||||
MODAL_DATA,
|
||||
ModalRef,
|
||||
ModalService
|
||||
} from '../../../core/services/modal.service';
|
||||
import { MODAL_DATA, ModalRef, ModalService } from '../../../core/services/modal.service';
|
||||
import { ModalHostComponent } from './modal-host.component';
|
||||
|
||||
@Component({
|
||||
@@ -31,7 +16,7 @@ import { ModalHostComponent } from './modal-host.component';
|
||||
<span class="modal-test-title">{{ data?.title }}</span>
|
||||
<button type="button" class="modal-test-close" (click)="close()">Cerrar</button>
|
||||
</div>
|
||||
`
|
||||
`,
|
||||
})
|
||||
class ModalContentTestComponent {
|
||||
readonly data = inject<{ title: string } | null>(MODAL_DATA);
|
||||
@@ -48,10 +33,7 @@ describe('ModalHostComponent', () => {
|
||||
|
||||
beforeAll(() => {
|
||||
try {
|
||||
getTestBed().initTestEnvironment(
|
||||
BrowserTestingModule,
|
||||
platformBrowserTesting()
|
||||
);
|
||||
getTestBed().initTestEnvironment(BrowserTestingModule, platformBrowserTesting());
|
||||
} catch {
|
||||
// Test environment may already be initialized by another setup entrypoint.
|
||||
}
|
||||
@@ -59,7 +41,7 @@ describe('ModalHostComponent', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [ModalHostComponent]
|
||||
imports: [ModalHostComponent],
|
||||
}).compileComponents();
|
||||
|
||||
service = TestBed.inject(ModalService);
|
||||
@@ -68,6 +50,7 @@ describe('ModalHostComponent', () => {
|
||||
|
||||
afterEach(() => {
|
||||
doc.body.style.overflow = '';
|
||||
doc.body.style.paddingRight = '';
|
||||
TestBed.resetTestingModule();
|
||||
});
|
||||
|
||||
@@ -84,7 +67,7 @@ describe('ModalHostComponent', () => {
|
||||
|
||||
service.open(ModalContentTestComponent, {
|
||||
title: 'Editar producto',
|
||||
data: { title: 'Contenido del modal' }
|
||||
data: { title: 'Contenido del modal' },
|
||||
});
|
||||
fixture.detectChanges();
|
||||
|
||||
@@ -99,27 +82,30 @@ describe('ModalHostComponent', () => {
|
||||
it('closes with a result from the child component', () => {
|
||||
const fixture = TestBed.createComponent(ModalHostComponent);
|
||||
const ref = service.open(ModalContentTestComponent, {
|
||||
data: { title: 'Cerrar' }
|
||||
data: { title: 'Cerrar' },
|
||||
});
|
||||
const closedSpy = vi.fn();
|
||||
|
||||
ref.afterClosed$.subscribe(closedSpy);
|
||||
fixture.detectChanges();
|
||||
|
||||
const closeButton = fixture.nativeElement.querySelector('.modal-test-close') as HTMLButtonElement;
|
||||
const closeButton = fixture.nativeElement.querySelector(
|
||||
'.modal-test-close',
|
||||
) as HTMLButtonElement;
|
||||
closeButton.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(closedSpy).toHaveBeenCalledWith('accepted');
|
||||
expect(service.activeModal()).toBeNull();
|
||||
expect(doc.body.style.overflow).toBe('');
|
||||
expect(doc.body.style.paddingRight).toBe('');
|
||||
});
|
||||
|
||||
it('closes on backdrop click when enabled', () => {
|
||||
const fixture = TestBed.createComponent(ModalHostComponent);
|
||||
const ref = service.open(ModalContentTestComponent, {
|
||||
data: { title: 'Backdrop' },
|
||||
closeOnBackdrop: true
|
||||
closeOnBackdrop: true,
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -136,7 +122,7 @@ describe('ModalHostComponent', () => {
|
||||
const fixture = TestBed.createComponent(ModalHostComponent);
|
||||
const ref = service.open(ModalContentTestComponent, {
|
||||
data: { title: 'Persistente' },
|
||||
closeOnBackdrop: false
|
||||
closeOnBackdrop: false,
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -152,7 +138,7 @@ describe('ModalHostComponent', () => {
|
||||
const fixture = TestBed.createComponent(ModalHostComponent);
|
||||
const ref = service.open(ModalContentTestComponent, {
|
||||
data: { title: 'Escape' },
|
||||
closeOnEscape: true
|
||||
closeOnEscape: true,
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -167,7 +153,7 @@ describe('ModalHostComponent', () => {
|
||||
const fixture = TestBed.createComponent(ModalHostComponent);
|
||||
const ref = service.open(ModalContentTestComponent, {
|
||||
data: { title: 'No Escape' },
|
||||
closeOnEscape: false
|
||||
closeOnEscape: false,
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -181,12 +167,13 @@ describe('ModalHostComponent', () => {
|
||||
const fixture = TestBed.createComponent(ModalHostComponent);
|
||||
const ref = service.open(ModalContentTestComponent, {
|
||||
title: 'Con cierre',
|
||||
data: { title: 'Boton' }
|
||||
data: { title: 'Boton' },
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const closeButton = fixture.debugElement.query(By.css('.btn-close')).nativeElement as HTMLButtonElement;
|
||||
const closeButton = fixture.debugElement.query(By.css('.btn-close'))
|
||||
.nativeElement as HTMLButtonElement;
|
||||
closeButton.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
|
||||
@@ -7,21 +7,17 @@ import {
|
||||
computed,
|
||||
effect,
|
||||
inject,
|
||||
viewChild
|
||||
viewChild,
|
||||
} from '@angular/core';
|
||||
|
||||
import {
|
||||
MODAL_DATA,
|
||||
ModalRef,
|
||||
ModalService
|
||||
} from '../../../core/services/modal.service';
|
||||
import { MODAL_DATA, ModalRef, ModalService } from '../../../core/services/modal.service';
|
||||
import { ModalShellComponent } from '../modal-shell/modal-shell.component';
|
||||
|
||||
@Component({
|
||||
selector: 'app-modal-host',
|
||||
imports: [NgComponentOutlet, ModalShellComponent],
|
||||
templateUrl: './modal-host.component.html',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ModalHostComponent {
|
||||
private readonly modalService = inject(ModalService);
|
||||
@@ -42,9 +38,9 @@ export class ModalHostComponent {
|
||||
return Injector.create({
|
||||
providers: [
|
||||
{ provide: ModalRef, useValue: modal.ref },
|
||||
{ provide: MODAL_DATA, useValue: modal.config.data ?? null }
|
||||
{ provide: MODAL_DATA, useValue: modal.config.data ?? null },
|
||||
],
|
||||
parent: this.injector
|
||||
parent: this.injector,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -58,6 +54,18 @@ export class ModalHostComponent {
|
||||
|
||||
const body = this.document.body;
|
||||
const previousOverflow = body.style.overflow;
|
||||
const previousPaddingRight = body.style.paddingRight;
|
||||
const view = this.document.defaultView;
|
||||
const scrollbarWidth = view
|
||||
? Math.max(0, view.innerWidth - this.document.documentElement.clientWidth)
|
||||
: 0;
|
||||
|
||||
if (scrollbarWidth > 0 && view) {
|
||||
const currentPaddingRight =
|
||||
Number.parseFloat(view.getComputedStyle(body).paddingRight) || 0;
|
||||
body.style.paddingRight = `${currentPaddingRight + scrollbarWidth}px`;
|
||||
}
|
||||
|
||||
body.style.overflow = 'hidden';
|
||||
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
@@ -75,6 +83,7 @@ export class ModalHostComponent {
|
||||
onCleanup(() => {
|
||||
this.document.removeEventListener('keydown', onKeyDown);
|
||||
body.style.overflow = previousOverflow;
|
||||
body.style.paddingRight = previousPaddingRight;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,8 +10,7 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 1rem;
|
||||
background: rgba(16, 18, 22, 0.48);
|
||||
backdrop-filter: blur(2px);
|
||||
background: rgba(16, 18, 22, 0.56);
|
||||
}
|
||||
|
||||
.modal-shell__dialog {
|
||||
|
||||
Reference in New Issue
Block a user