Skip to content
This repository was archived by the owner on Dec 18, 2024. It is now read-only.

Commit b6da10c

Browse files
josephperrottjelbourn
authored andcommitted
Focus page content after navigation for a11y. (#267)
1 parent 62706dc commit b6da10c

File tree

9 files changed

+56
-15
lines changed

9 files changed

+56
-15
lines changed

src/app/pages/component-page-header/component-page-header.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
<md-icon>menu</md-icon>
44
</button>
55

6-
<h1>{{getTitle()}} </h1>
6+
<h1 focusOnNavigation>{{getTitle()}} </h1>
77
</div>

src/app/pages/component-page-header/component-page-header.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {Component, EventEmitter, NgModule, Output} from '@angular/core';
22
import 'rxjs/add/operator/first';
33
import {ComponentPageTitle} from '../page-title/page-title';
4+
import {NavigationFocusModule} from '../../shared/navigation-focus/navigation-focus';
45
import {MdButtonModule, MdIconModule} from '@angular/material';
56

67
@Component({
@@ -9,7 +10,7 @@ import {MdButtonModule, MdIconModule} from '@angular/material';
910
styleUrls: ['./component-page-header.scss']
1011
})
1112
export class ComponentPageHeader {
12-
constructor(public _componentPageTitle: ComponentPageTitle) { }
13+
constructor(public _componentPageTitle: ComponentPageTitle) {}
1314

1415
@Output() toggleSidenav = new EventEmitter<void>();
1516

@@ -19,7 +20,7 @@ export class ComponentPageHeader {
1920
}
2021

2122
@NgModule({
22-
imports: [MdButtonModule, MdIconModule],
23+
imports: [MdButtonModule, MdIconModule, NavigationFocusModule],
2324
exports: [ComponentPageHeader],
2425
declarations: [ComponentPageHeader],
2526
providers: [ComponentPageTitle],
Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1-
<doc-viewer
2-
documentUrl="/assets/documents/api/{{componentViewer.componentDocItem.id}}.html"
3-
class="docs-component-view-text-content"></doc-viewer>
1+
<span class="cdk-visually-hidden" tabindex="-1" #intialFocusTarget>
2+
API for {{componentViewer.componentDocItem.id}}
3+
</span>
4+
<doc-viewer
5+
documentUrl="/assets/documents/api/{{componentViewer.componentDocItem.id}}.html"
6+
class="docs-component-view-text-content"></doc-viewer>
Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
<span class="cdk-visually-hidden" tabindex="-1" #intialFocusTarget>
2+
Examples for {{componentViewer.componentDocItem.id}}
3+
</span>
14
<example-viewer
2-
*ngFor="let example of componentViewer.componentDocItem.examples"
3-
[example]="example"></example-viewer>
5+
*ngFor="let example of componentViewer.componentDocItem.examples"
6+
[example]="example"></example-viewer>

src/app/pages/component-viewer/component-overview.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
<span class="cdk-visually-hidden" tabindex="-1" #intialFocusTarget>
2+
Overview for {{componentViewer.componentDocItem.id}}
3+
</span>
14
<doc-viewer
25
documentUrl="/assets/documents/overview/{{componentViewer.componentDocItem.id}}.html"
36
class="docs-component-view-text-content docs-component-overview"

src/app/pages/component-viewer/component-viewer.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Component, NgModule, ViewEncapsulation} from '@angular/core';
1+
import {Component, OnInit, NgModule, ElementRef, ViewEncapsulation, ViewChild} from '@angular/core';
22
import {ActivatedRoute, Router, RouterModule} from '@angular/router';
33
import {DocumentationItems, DocItem} from '../../shared/documentation-items/documentation-items';
44
import {ComponentPageTitle} from '../page-title/page-title';
@@ -38,8 +38,15 @@ export class ComponentViewer {
3838
styleUrls: ['./component-overview.scss'],
3939
encapsulation: ViewEncapsulation.None,
4040
})
41-
export class ComponentOverview {
41+
export class ComponentOverview implements OnInit {
42+
@ViewChild('intialFocusTarget') focusTarget: ElementRef;
43+
4244
constructor(public componentViewer: ComponentViewer) {}
45+
46+
ngOnInit() {
47+
// 100ms timeout is used to allow the page to settle before moving focus for screen readers.
48+
setTimeout(() => this.focusTarget.nativeElement.focus(), 100);
49+
}
4350
}
4451

4552
@Component({
@@ -62,7 +69,7 @@ export class ComponentExamples extends ComponentOverview {}
6269
RouterModule,
6370
DocViewerModule,
6471
CommonModule,
65-
TableOfContentsModule
72+
TableOfContentsModule,
6673
],
6774
exports: [ComponentViewer],
6875
declarations: [ComponentViewer, ComponentOverview, ComponentApi, ComponentExamples],
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {NgModule, Injectable, OnInit, Directive, Input, ElementRef, Renderer2} from '@angular/core';
2+
import {Subscription} from 'rxjs/Subscription';
3+
4+
/** The timeout id of the previous focus change. */
5+
let lastTimeoutId = -1;
6+
7+
@Directive({
8+
selector: '[focusOnNavigation]',
9+
host: {'tabindex': '-1'},
10+
})
11+
export class NavigationFocus implements OnInit {
12+
constructor(private el: ElementRef) {}
13+
14+
ngOnInit() {
15+
clearTimeout(lastTimeoutId);
16+
// 100ms timeout is used to allow the page to settle before moving focus for screen readers.
17+
lastTimeoutId = setTimeout(() => this.el.nativeElement.focus(), 100);
18+
}
19+
}
20+
21+
@NgModule({
22+
declarations: [NavigationFocus],
23+
exports: [NavigationFocus],
24+
})
25+
export class NavigationFocusModule {}

src/app/shared/theme-picker/theme-picker.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<button md-icon-button [md-menu-trigger-for]="themeMenu" mdTooltip="Select a theme!">
1+
<button md-icon-button [md-menu-trigger-for]="themeMenu" mdTooltip="Select a theme!"
2+
tabindex="-1">
23
<md-icon>format_color_fill</md-icon>
34
</button>
45

src/tsconfig.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
"outDir": "../dist/out-tsc",
1111
"sourceMap": true,
1212
"target": "es5",
13-
"typeRoots": [
14-
"../node_modules/@types"
15-
]
13+
"types": ["q", "selenium-driver", "jasmine"]
1614
},
1715
"exclude": [
1816
"assets"

0 commit comments

Comments
 (0)