Skip to content

Commit

Permalink
fix(modal): attempt to focus when there is no focusable element on mo…
Browse files Browse the repository at this point in the history
…dal dialog

(cherry picked from commit 3f50a06)
  • Loading branch information
xidedix committed Jun 17, 2024
1 parent 7c7fcf4 commit 9f23c3d
Show file tree
Hide file tree
Showing 9 changed files with 31 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ describe('ModalBodyComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ModalBodyComponent]
})
.compileComponents();
}).compileComponents();
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@ import { Component, HostBinding } from '@angular/core';
standalone: true
})
export class ModalBodyComponent {

@HostBinding('class')
get hostClasses(): any {
return {
'modal-body': true,
'modal-body': true
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ describe('ModalContentComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ModalContentComponent]
})
.compileComponents();
}).compileComponents();
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ describe('ModalDialogComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ModalDialogComponent]
})
.compileComponents();
}).compileComponents();
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ describe('ModalFooterComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ModalFooterComponent]
})
.compileComponents();
}).compileComponents();
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ import { Component, HostBinding } from '@angular/core';
standalone: true
})
export class ModalFooterComponent {

@HostBinding('class')
get hostClasses(): any {
return {
'modal-footer': true,
'modal-footer': true
};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ describe('ModalHeaderComponent', () => {
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ModalHeaderComponent]
})
.compileComponents();
}).compileComponents();
});

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ import { Component, HostBinding } from '@angular/core';
standalone: true
})
export class ModalHeaderComponent {

@HostBinding('class')
get hostClasses(): any {
return {
'modal-header': true
};
}

}
50 changes: 24 additions & 26 deletions projects/coreui-angular/src/lib/modal/modal/modal.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ import { ModalDialogComponent } from '../modal-dialog/modal-dialog.component';
imports: [ModalDialogComponent, ModalContentComponent, A11yModule]
})
export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {

#destroyRef = inject(DestroyRef);
#focusMonitor = inject(FocusMonitor);

Expand All @@ -64,7 +63,7 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
private hostElement: ElementRef,
private modalService: ModalService,
private backdropService: BackdropService
) { }
) {}

/**
* Align the modal in the center or top of the screen.
Expand Down Expand Up @@ -110,14 +109,15 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
* @type boolean
* @default null
*/
@Input() @HostBinding('attr.aria-modal')
@Input()
@HostBinding('attr.aria-modal')
set ariaModal(value: boolean | null) {
this.#ariaModal = value;
}

get ariaModal(): boolean | null {
return this.visible || this.#ariaModal ? true : null;
};
}

#ariaModal: boolean | null = null;

Expand Down Expand Up @@ -154,8 +154,12 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
this.#activeElement = this.document.activeElement as HTMLElement;
// this.#activeElement?.blur();
setTimeout(() => {
const focusable = this.modalContentRef.nativeElement.querySelectorAll('[tabindex]:not([tabindex="-1"]), button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled])');
this.#focusMonitor.focusVia(focusable[0], 'keyboard');
const focusable = this.modalContentRef.nativeElement.querySelectorAll(
'[tabindex]:not([tabindex="-1"]), button:not([disabled]), [href], input:not([disabled]), select:not([disabled]), textarea:not([disabled])'
);
if (focusable.length) {
this.#focusMonitor.focusVia(focusable[0], 'keyboard');
}
});
} else {
if (this.document.contains(this.#activeElement)) {
Expand Down Expand Up @@ -191,7 +195,7 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
@HostBinding('attr.aria-hidden')
get ariaHidden(): boolean | null {
return this.visible ? null : true;
};
}

@HostBinding('attr.tabindex')
get tabIndex(): string | null {
Expand Down Expand Up @@ -255,15 +259,13 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {

@HostListener('click', ['$event'])
public onClickHandler($event: MouseEvent): void {

if (this.mouseDownTarget !== $event.target) {
this.mouseDownTarget = null;
return;
}

const targetElement = $event.target;
if (targetElement === this.hostElement.nativeElement) {

if (this.backdrop === 'static') {
this.setStaticBackdrop();
return;
Expand All @@ -289,27 +291,23 @@ export class ModalComponent implements OnInit, OnDestroy, AfterViewInit {
}

private stateToggleSubscribe(): void {
this.modalService.modalState$
.pipe(
takeUntilDestroyed(this.#destroyRef)
)
.subscribe(
(action) => {
if (this === action.modal || this.id === action.id) {
if ('show' in action) {
this.visible = action?.show === 'toggle' ? !this.visible : action.show;
}
} else {
if (this.visible) {
this.visible = false;
}
}
this.modalService.modalState$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((action) => {
if (this === action.modal || this.id === action.id) {
if ('show' in action) {
this.visible = action?.show === 'toggle' ? !this.visible : action.show;
}
} else {
if (this.visible) {
this.visible = false;
}
);
}
});
}

private setBackdrop(setBackdrop: boolean): void {
this.#activeBackdrop = setBackdrop ? this.backdropService.setBackdrop('modal') : this.backdropService.clearBackdrop(this.#activeBackdrop);
this.#activeBackdrop = setBackdrop
? this.backdropService.setBackdrop('modal')
: this.backdropService.clearBackdrop(this.#activeBackdrop);
}

private setBodyStyles(open: boolean): void {
Expand Down

0 comments on commit 9f23c3d

Please sign in to comment.