Skip to content

Commit

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

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

it('should open and close a tooltip - default settings and content from a template', () => {
Expand All @@ -77,11 +80,14 @@ describe('ngb-tooltip', () => {
expect(windowEl).toHaveCssClass('tooltip-top');
expect(windowEl.textContent.trim()).toBe('Hello, World!');
expect(windowEl.getAttribute('role')).toBe('tooltip');
expect(windowEl.getAttribute('id')).toBe('ngb-tooltip-1');
expect(windowEl.parentNode).toBe(fixture.nativeElement);
expect(directive.nativeElement.getAttribute('aria-describedby')).toBe('ngb-tooltip-1');

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

it('should open and close a tooltip - default settings, content from a template and context supplied', () => {
Expand All @@ -96,11 +102,14 @@ describe('ngb-tooltip', () => {
expect(windowEl).toHaveCssClass('tooltip-top');
expect(windowEl.textContent.trim()).toBe('Hello, John!');
expect(windowEl.getAttribute('role')).toBe('tooltip');
expect(windowEl.getAttribute('id')).toBe('ngb-tooltip-2');
expect(windowEl.parentNode).toBe(fixture.nativeElement);
expect(directive.nativeElement.getAttribute('aria-describedby')).toBe('ngb-tooltip-2');

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

it('should not open a tooltip if content is falsy', () => {
Expand Down
15 changes: 11 additions & 4 deletions src/tooltip/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,24 @@ import {
ComponentFactoryResolver,
NgZone
} from '@angular/core';

import {listenToTriggers} from '../util/triggers';
import {positionElements} from '../util/positioning';
import {PopupService} from '../util/popup';
import {NgbTooltipConfig} from './tooltip-config';

let nextId = 0;

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

/**
Expand All @@ -53,15 +55,16 @@ export class NgbTooltip implements OnInit, OnDestroy {
*/
@Input() container: string;
/**
* Emits an event when the tooltip is shown
*/
* Emits an event when the tooltip is shown
*/
@Output() shown = new EventEmitter();
/**
* Emits an event when the tooltip is hidden
*/
@Output() hidden = new EventEmitter();

private _ngbTooltip: string | TemplateRef<any>;
private _ngbTooltipWindowId = `ngb-tooltip-${nextId++}`;
private _popupService: PopupService<NgbTooltipWindow>;
private _windowRef: ComponentRef<NgbTooltipWindow>;
private _unregisterListenersFn;
Expand Down Expand Up @@ -107,6 +110,9 @@ export class NgbTooltip implements OnInit, OnDestroy {
if (!this._windowRef && this._ngbTooltip) {
this._windowRef = this._popupService.open(this._ngbTooltip, context);
this._windowRef.instance.placement = this.placement;
this._windowRef.instance.id = this._ngbTooltipWindowId;

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

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

0 comments on commit 0883635

Please sign in to comment.