Open ramanareddygopu opened 1 year ago
Any plans to resolve this issue?
I have the same problem in Angular version 13.3.12 and primeNG 13.4.1.
Regards
Finally, I modified the PrimeNG directive and added a solution for focusTrap in dialogs with Shadow DOM.
Additionally, I added some lines for the tabindex. In my project, I am using the data-tabindex attribute and ignoring the HTML tabindex because PrimeNG uses it in some components.
My directive:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[customFocusTrap]',
host: {
class: 'p-element'
}
})
export class CustomFocusTrapDirective {
@Input() pFocusTrapDisabled: boolean = false;
constructor(public el: ElementRef) {}
@HostListener('keydown.tab', ['$event'])
@HostListener('keydown.shift.tab', ['$event'])
onkeydown(e: KeyboardEvent) {
if (this.pFocusTrapDisabled !== true) {
e.preventDefault();
e.stopPropagation();
const focusableElement = this.getNextFocusableElement(this.el.nativeElement, e.shiftKey);
if (focusableElement) {
focusableElement.focus();
focusableElement.select?.();
}
}
}
public getNextFocusableElement(element: HTMLElement, reverse = false) {
const focusableElements = this.getFocusableElements(element);
let index = 0;
if (focusableElements && focusableElements.length > 0) {
let activeElement = focusableElements[0].ownerDocument.activeElement.shadowRoot
? focusableElements[0].ownerDocument.activeElement.shadowRoot.activeElement
: focusableElements[0].ownerDocument.activeElement;
const focusedIndex = focusableElements.indexOf(activeElement);
if (reverse) {
if (focusedIndex == -1 || focusedIndex === 0) {
index = focusableElements.length - 1;
} else {
index = focusedIndex - 1;
}
} else if (focusedIndex != -1 && focusedIndex !== focusableElements.length - 1) {
index = focusedIndex + 1;
}
}
return focusableElements[index];
}
protected getFocusableElements(element: HTMLElement) {
let focusableElements = this.find(
element,
`button:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
[href]:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
input:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]), select:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
textarea:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]), [tabIndex]:not([tabIndex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
[contenteditable]:not([tabIndex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]):not(.p-disabled)`
);
const elementsWithTabIndex = focusableElements
.filter((el) => el.hasAttribute('data-tabindex'))
.sort((a, b) => parseInt(a.getAttribute('data-tabindex')) - parseInt(b.getAttribute('data-tabindex')));
const elementsWithoutTabIndex = focusableElements.filter((el) => !el.hasAttribute('data-tabindex'));
focusableElements = elementsWithTabIndex.concat(elementsWithoutTabIndex);
let visibleFocusableElements = [];
for (let focusableElement of focusableElements) {
if (!!(focusableElement.offsetWidth || focusableElement.offsetHeight || focusableElement.getClientRects().length))
visibleFocusableElements.push(focusableElement);
}
return visibleFocusableElements;
}
protected find(element: any, selector: string): any[] {
return Array.from(element.querySelectorAll(selector));
}
}
Regards
Describe the bug
On a P-Dialog, I am using input fields on the modal, and few input fields rendered from the components where encapsulation: ViewEncapsulation.ShadowDom components, when i try to access the fields by clicking "TAB" key or "SHIFT + TAB" key the focus is not going to fields which are inside the components where encapsulation is ViewEncapsulation.ShadowDom.
Environment
I am using the PRIMENG with Angular.
Reproducer
No response
Angular version
12.2.0
PrimeNG version
12.0.0
Build / Runtime
Angular CLI App
Language
TypeScript
Node version (for AoT issues node --version)
16.13.0
Browser(s)
Chrome
Steps to reproduce the behavior
1) create a Shadow DOM Component with few fields 2) add the created shadow component in p-dialog as a selector 3) When modal is open try using the "tab" or "Shift + Tab" key, and check if the fields are getting focused.
Expected behavior
No response