Skip to content

Commit

Permalink
Fix primefaces#16972 alter tabindex for content children
Browse files Browse the repository at this point in the history
Uses renderer2 to alter the tabindexing for all children of the
div.p-panel-content that are typically focusable
  • Loading branch information
roesnera committed Dec 7, 2024
1 parent 5f5f28c commit 336a303
Showing 1 changed file with 36 additions and 4 deletions.
40 changes: 36 additions & 4 deletions src/app/components/panel/panel.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { animate, state, style, transition, trigger } from '@angular/animations';
import { CommonModule } from '@angular/common';
import { AfterContentInit, booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, ElementRef, EventEmitter, Input, NgModule, Output, QueryList, TemplateRef, ViewEncapsulation } from '@angular/core';
import { AfterContentInit, booleanAttribute, ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ContentChildren, ElementRef, EventEmitter, Input, NgModule, OnDestroy, Output, QueryList, Renderer2, TemplateRef, ViewChild, ViewEncapsulation } from '@angular/core';
import { BlockableUI, Footer, PrimeTemplate, SharedModule } from 'primeng/api';
import { MinusIcon } from 'primeng/icons/minus';
import { PlusIcon } from 'primeng/icons/plus';
import { RippleModule } from 'primeng/ripple';
import { Nullable } from 'primeng/ts-helpers';
import { UniqueComponentId } from 'primeng/utils';
import { PanelAfterToggleEvent, PanelBeforeToggleEvent } from './panel.interface';
import { Subject, takeUntil } from 'rxjs';

/**
* Panel is a container with the optional content toggle feature.
Expand Down Expand Up @@ -66,7 +67,7 @@ import { PanelAfterToggleEvent, PanelBeforeToggleEvent } from './panel.interface
"
(@panelContent.done)="onToggleDone($event)"
>
<div class="p-panel-content">
<div class="p-panel-content" #contentContainer>
<ng-content></ng-content>
<ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
</div>
Expand Down Expand Up @@ -111,7 +112,7 @@ import { PanelAfterToggleEvent, PanelBeforeToggleEvent } from './panel.interface
class: 'p-element'
}
})
export class Panel implements AfterContentInit, BlockableUI {
export class Panel implements AfterContentInit, BlockableUI, OnDestroy {
/**
* Defines if content of panel can be expanded and collapsed.
* @group Props
Expand Down Expand Up @@ -205,6 +206,12 @@ export class Panel implements AfterContentInit, BlockableUI {

headerIconTemplate: Nullable<TemplateRef<any>>;

@ViewChild('contentContainer') contentContainer: ElementRef;

destroy$: Subject<void> = new Subject<void>();

focusableChildren: NodeListOf<Element> | null = null;

readonly id = UniqueComponentId();

get buttonAriaLabel() {
Expand All @@ -213,7 +220,8 @@ export class Panel implements AfterContentInit, BlockableUI {

constructor(
private el: ElementRef,
private cd: ChangeDetectorRef
private cd: ChangeDetectorRef,
private renderer: Renderer2
) {}

ngAfterContentInit() {
Expand Down Expand Up @@ -244,6 +252,30 @@ export class Panel implements AfterContentInit, BlockableUI {
break;
}
});

this.onBeforeToggle.pipe(takeUntil(this.destroy$)).subscribe(event => {
if (event.collapsed) this.setTabIndexesRenderer(this.contentContainer.nativeElement, 0);
});

this.onAfterToggle.pipe(takeUntil(this.destroy$)).subscribe(event => {
if (event.collapsed) this.setTabIndexesRenderer(this.contentContainer.nativeElement, -1);
});
}

ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}

setTabIndexesRenderer(parentElement: HTMLElement, tabindex: number) {
requestAnimationFrame(() => {
if (!this.focusableChildren) this.focusableChildren = parentElement.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
);

this.focusableChildren.forEach(el => {
this.renderer.setAttribute(el, 'tabindex', tabindex.toString());
});
});
}

onHeaderClick(event: MouseEvent) {
Expand Down

0 comments on commit 336a303

Please sign in to comment.