Improve template Accessibility (#12891)
Add aria-label to table to give title
This commit is contained in:
parent
14f17fa7cd
commit
afcfeaf0ac
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue