Skip to content

Commit

Permalink
feat(popover): add aria-describedby to popover triggering element
Browse files Browse the repository at this point in the history
Closes #1412
  • Loading branch information
giampierobono authored and pkozlowski-opensource committed Mar 28, 2017
1 parent 06850a1 commit 92e4804
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/popover/popover.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,14 @@ describe('ngb-popover', () => {
expect(windowEl).toHaveCssClass('popover-top');
expect(windowEl.textContent.trim()).toBe('TitleGreat tip!');
expect(windowEl.getAttribute('role')).toBe('tooltip');
expect(windowEl.getAttribute('id')).toBe('ngb-popover-0');
expect(windowEl.parentNode).toBe(fixture.nativeElement);
expect(directive.nativeElement.getAttribute('aria-describedby')).toBe('ngb-popover-0');

directive.triggerEventHandler('click', {});
fixture.detectChanges();
expect(getWindow(fixture.nativeElement)).toBeNull();
expect(directive.nativeElement.getAttribute('aria-describedby')).toBeNull();
});

it('should open and close a popover - default settings and content from a template', () => {
Expand All @@ -91,11 +94,14 @@ describe('ngb-popover', () => {
expect(windowEl).toHaveCssClass(`popover-${defaultConfig.placement}`);
expect(windowEl.textContent.trim()).toBe('TitleHello, World!');
expect(windowEl.getAttribute('role')).toBe('tooltip');
expect(windowEl.getAttribute('id')).toBe('ngb-popover-1');
expect(windowEl.parentNode).toBe(fixture.nativeElement);
expect(directive.nativeElement.getAttribute('aria-describedby')).toBe('ngb-popover-1');

directive.triggerEventHandler('click', {});
fixture.detectChanges();
expect(getWindow(fixture.nativeElement)).toBeNull();
expect(directive.nativeElement.getAttribute('aria-describedby')).toBeNull();
});

it('should open and close a popover - default settings, content from a template and context supplied', () => {
Expand All @@ -113,11 +119,14 @@ describe('ngb-popover', () => {
expect(windowEl).toHaveCssClass(`popover-${defaultConfig.placement}`);
expect(windowEl.textContent.trim()).toBe('TitleHello, John!');
expect(windowEl.getAttribute('role')).toBe('tooltip');
expect(windowEl.getAttribute('id')).toBe('ngb-popover-2');
expect(windowEl.parentNode).toBe(fixture.nativeElement);
expect(directive.nativeElement.getAttribute('aria-describedby')).toBe('ngb-popover-2');

directive.triggerEventHandler('click', {});
fixture.detectChanges();
expect(getWindow(fixture.nativeElement)).toBeNull();
expect(directive.nativeElement.getAttribute('aria-describedby')).toBeNull();
});

it('should properly destroy TemplateRef content', () => {
Expand Down
10 changes: 9 additions & 1 deletion src/popover/popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ import {positionElements} from '../util/positioning';
import {PopupService} from '../util/popup';
import {NgbPopoverConfig} from './popover-config';

let nextId = 0;

@Component({
selector: 'ngb-popover-window',
changeDetection: ChangeDetectionStrategy.OnPush,
host: {'[class]': '"popover show popover-" + placement', 'role': 'tooltip'},
host: {'[class]': '"popover show popover-" + placement', 'role': 'tooltip', '[id]': 'id'},
template: `
<h3 class="popover-title">{{title}}</h3><div class="popover-content"><ng-content></ng-content></div>
`
})
export class NgbPopoverWindow {
@Input() placement: 'top' | 'bottom' | 'left' | 'right' = 'top';
@Input() title: string;
@Input() id: string;
}

/**
Expand Down Expand Up @@ -70,6 +73,7 @@ export class NgbPopover implements OnInit, OnDestroy {
*/
@Output() hidden = new EventEmitter();

private _ngbPopoverWindowId = `ngb-popover-${nextId++}`;
private _popupService: PopupService<NgbPopoverWindow>;
private _windowRef: ComponentRef<NgbPopoverWindow>;
private _unregisterListenersFn;
Expand Down Expand Up @@ -103,6 +107,9 @@ export class NgbPopover implements OnInit, OnDestroy {
this._windowRef = this._popupService.open(this.ngbPopover, context);
this._windowRef.instance.placement = this.placement;
this._windowRef.instance.title = this.popoverTitle;
this._windowRef.instance.id = this._ngbPopoverWindowId;

this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-describedby', this._ngbPopoverWindowId);

if (this.container === 'body') {
window.document.querySelector(this.container).appendChild(this._windowRef.location.nativeElement);
Expand All @@ -120,6 +127,7 @@ export class NgbPopover implements OnInit, OnDestroy {
*/
close(): void {
if (this._windowRef) {
this._renderer.setElementAttribute(this._elementRef.nativeElement, 'aria-describedby', null);
this._popupService.close();
this._windowRef = null;
this.hidden.emit();
Expand Down

0 comments on commit 92e4804

Please sign in to comment.