Improve template Accessibility (#12891)

Add aria-label to table to give title
This commit is contained in:
Ryan Brandenburg 2019-08-09 14:25:25 -07:00 committed by GitHub
parent 14f17fa7cd
commit afcfeaf0ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 74 additions and 74 deletions

View File

@ -2,6 +2,6 @@
<p>This is a simple example of an Angular component.</p> <p>This is a simple example of an Angular component.</p>
<p>Current count: <strong>{{ currentCount }}</strong></p> <p aria-live="polite">Current count: <strong>{{ currentCount }}</strong></p>
<button class="btn btn-primary" (click)="incrementCounter()">Increment</button> <button class="btn btn-primary" (click)="incrementCounter()">Increment</button>

View File

@ -1,10 +1,10 @@
<h1>Weather forecast</h1> <h1 id="tableLabel">Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p> <p>This component demonstrates fetching data from the server.</p>
<p *ngIf="!forecasts"><em>Loading...</em></p> <p *ngIf="!forecasts"><em>Loading...</em></p>
<table class='table table-striped' *ngIf="forecasts"> <table class='table table-striped' aria-labelledby="tableLabel" *ngIf="forecasts">
<thead> <thead>
<tr> <tr>
<th>Date</th> <th>Date</th>

View File

@ -3,26 +3,26 @@ import React, { Component } from 'react';
export class Counter extends Component { export class Counter extends Component {
static displayName = Counter.name; static displayName = Counter.name;
constructor (props) { constructor(props) {
super(props); super(props);
this.state = { currentCount: 0 }; this.state = { currentCount: 0 };
this.incrementCounter = this.incrementCounter.bind(this); this.incrementCounter = this.incrementCounter.bind(this);
} }
incrementCounter () { incrementCounter() {
this.setState({ this.setState({
currentCount: this.state.currentCount + 1 currentCount: this.state.currentCount + 1
}); });
} }
render () { render() {
return ( return (
<div> <div>
<h1>Counter</h1> <h1>Counter</h1>
<p>This is a simple example of a React component.</p> <p>This is a simple example of a React component.</p>
<p>Current count: <strong>{this.state.currentCount}</strong></p> <p aria-live="polite">Current count: <strong>{this.state.currentCount}</strong></p>
<button className="btn btn-primary" onClick={this.incrementCounter}>Increment</button> <button className="btn btn-primary" onClick={this.incrementCounter}>Increment</button>
</div> </div>

View File

@ -17,7 +17,7 @@ export class FetchData extends Component {
static renderForecastsTable(forecasts) { static renderForecastsTable(forecasts) {
return ( return (
<table className='table table-striped'> <table className='table table-striped' aria-labelledby="tabelLabel">
<thead> <thead>
<tr> <tr>
<th>Date</th> <th>Date</th>
@ -47,7 +47,7 @@ export class FetchData extends Component {
return ( return (
<div> <div>
<h1>Weather forecast</h1> <h1 id="tabelLabel" >Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p> <p>This component demonstrates fetching data from the server.</p>
{contents} {contents}
</div> </div>

View File

@ -17,11 +17,11 @@ class Counter extends React.PureComponent<CounterProps> {
<p>This is a simple example of a React component.</p> <p>This is a simple example of a React component.</p>
<p>Current count: <strong>{this.props.count}</strong></p> <p aria-live="polite">Current count: <strong>{this.props.count}</strong></p>
<button type="button" <button type="button"
className="btn btn-primary btn-lg" className="btn btn-primary btn-lg"
onClick={() => { this.props.increment(); }}> onClick={() => { this.props.increment(); }}>
Increment Increment
</button> </button>
</React.Fragment> </React.Fragment>

View File

@ -7,78 +7,78 @@ import * as WeatherForecastsStore from '../store/WeatherForecasts';
// At runtime, Redux will merge together... // At runtime, Redux will merge together...
type WeatherForecastProps = type WeatherForecastProps =
WeatherForecastsStore.WeatherForecastsState // ... state we've requested from the Redux store WeatherForecastsStore.WeatherForecastsState // ... state we've requested from the Redux store
& typeof WeatherForecastsStore.actionCreators // ... plus action creators we've requested & typeof WeatherForecastsStore.actionCreators // ... plus action creators we've requested
& RouteComponentProps<{ startDateIndex: string }>; // ... plus incoming routing parameters & RouteComponentProps<{ startDateIndex: string }>; // ... plus incoming routing parameters
class FetchData extends React.PureComponent<WeatherForecastProps> { class FetchData extends React.PureComponent<WeatherForecastProps> {
// This method is called when the component is first added to the document // This method is called when the component is first added to the document
public componentDidMount() { public componentDidMount() {
this.ensureDataFetched(); this.ensureDataFetched();
} }
// This method is called when the route parameters change // This method is called when the route parameters change
public componentDidUpdate() { public componentDidUpdate() {
this.ensureDataFetched(); this.ensureDataFetched();
} }
public render() { public render() {
return ( return (
<React.Fragment> <React.Fragment>
<h1>Weather forecast</h1> <h1 id="tabelLabel">Weather forecast</h1>
<p>This component demonstrates fetching data from the server and working with URL parameters.</p> <p>This component demonstrates fetching data from the server and working with URL parameters.</p>
{ this.renderForecastsTable() } {this.renderForecastsTable()}
{ this.renderPagination() } {this.renderPagination()}
</React.Fragment> </React.Fragment>
); );
} }
private ensureDataFetched() { private ensureDataFetched() {
const startDateIndex = parseInt(this.props.match.params.startDateIndex, 10) || 0; const startDateIndex = parseInt(this.props.match.params.startDateIndex, 10) || 0;
this.props.requestWeatherForecasts(startDateIndex); this.props.requestWeatherForecasts(startDateIndex);
} }
private renderForecastsTable() { private renderForecastsTable() {
return ( return (
<table className='table table-striped'> <table className='table table-striped' aria-labelledby="tabelLabel">
<thead> <thead>
<tr> <tr>
<th>Date</th> <th>Date</th>
<th>Temp. (C)</th> <th>Temp. (C)</th>
<th>Temp. (F)</th> <th>Temp. (F)</th>
<th>Summary</th> <th>Summary</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{this.props.forecasts.map((forecast: WeatherForecastsStore.WeatherForecast) => {this.props.forecasts.map((forecast: WeatherForecastsStore.WeatherForecast) =>
<tr key={forecast.date}> <tr key={forecast.date}>
<td>{forecast.date}</td> <td>{forecast.date}</td>
<td>{forecast.temperatureC}</td> <td>{forecast.temperatureC}</td>
<td>{forecast.temperatureF}</td> <td>{forecast.temperatureF}</td>
<td>{forecast.summary}</td> <td>{forecast.summary}</td>
</tr> </tr>
)} )}
</tbody> </tbody>
</table> </table>
); );
} }
private renderPagination() { private renderPagination() {
const prevStartDateIndex = (this.props.startDateIndex || 0) - 5; const prevStartDateIndex = (this.props.startDateIndex || 0) - 5;
const nextStartDateIndex = (this.props.startDateIndex || 0) + 5; const nextStartDateIndex = (this.props.startDateIndex || 0) + 5;
return ( return (
<div className="d-flex justify-content-between"> <div className="d-flex justify-content-between">
<Link className='btn btn-outline-secondary btn-sm' to={`/fetch-data/${prevStartDateIndex}`}>Previous</Link> <Link className='btn btn-outline-secondary btn-sm' to={`/fetch-data/${prevStartDateIndex}`}>Previous</Link>
{this.props.isLoading && <span>Loading...</span>} {this.props.isLoading && <span>Loading...</span>}
<Link className='btn btn-outline-secondary btn-sm' to={`/fetch-data/${nextStartDateIndex}`}>Next</Link> <Link className='btn btn-outline-secondary btn-sm' to={`/fetch-data/${nextStartDateIndex}`}>Next</Link>
</div> </div>
); );
} }
} }
export default connect( export default connect(
(state: ApplicationState) => state.weatherForecasts, // Selects which state properties are merged into the component's props (state: ApplicationState) => state.weatherForecasts, // Selects which state properties are merged into the component's props
WeatherForecastsStore.actionCreators // Selects which action creators are merged into the component's props WeatherForecastsStore.actionCreators // Selects which action creators are merged into the component's props
)(FetchData as any); )(FetchData as any);