Nawaz @mpnkhan
“People with disabilities can perceive, understand, navigate, and interact with the Web, and that they can contribute to the Web.”https://www.w3.org/WAI/intro/accessibility.php
More than 1 billion persons (15%) in the world have some form of disability.
Any Guess what’s wrong with this form?
class LoginForm extends Component {
render() {
return (
)
}
}
Source: https://blog.codeship.com/designing-user-interfaces-with-react/
Correct way to do
class LoginForm extends Component {
render() {
return (
)
}
}
.sr-only {
position: absolute;
left: -999em;
}
.sr-only {
position: absolute !important;
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
clip: rect(1px,1px,1px,1px);
}
class Focusinput extends React.Component {
componentDidMount(){
this.nameInput.focus();
}
render() {
return(
{ this.nameInput = input; }}
defaultValue="will focus"
/>
);
}
}
ReactDOM.render(
<Focusinput/>,
document.getElementById('root')
);
http://mpnkhan.github.io/test/examples/react/input_focus_componentdidMount.html
componentDidMount() {
this.timerID = setInterval(
() => this.ajaxUpdate(),
3000
);
}
ajaxUpdate() {
const id = Math.floor((Math.random()*1000)+1);
this.setState({ id: id }, () => {
this.nameInput.focus();
});
}
render() {
return (
);
}
http://mpnkhan.github.io/test/examples/react/input_focus_state.html
class Fakebutton extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
console.log(this.props.inputRef)
alert('clicked');
}
render() {
return(
Buy Now!!!
);
}
}
ReactDOM.render(
<Fakebutton />,
document.getElementById('root')
);
Buy Now!!!
class Fakebutton extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.handleKeyDown = this.handleKeyDown.bind(this);
}
handleClick(e) {
alert('clicked');
}
handleKeyDown(e) {
if(e.key=='Enter' || e.key==' ') alert('Enter/Space');
}
render() {
return(
Buy Now!!!
);
}
}
http://mpnkhan.github.io/test/examples/react/Fakebutton.html
class Menu extends React.Component {
constructor(props) {
super(props);
this.handleKeyDown = this.handleKeyDown.bind(this);
}
handleKeyDown = event => {
var menu = ReactDOM.findDOMNode(this);
var items = menu.getElementsByTagName('li');
var index = Array.prototype.indexOf.call(items, event.target);
if (!~index) index = 0
switch (event.key) {
case 'ArrowDown':
index++;
if (index == items.length) index = 0;
items.item(index).focus();
//console.log(items.item(index).children[0]);
break;
case 'ArrowUp':
index--;
if (index < 0) index = items.length - 1;
items.item(index).focus();
break;
case 'Enter':
case ' ':
items.item(index).children[0].click();
break;
case 'Escape':
//console.log(this.props.toggle);
this.props.toggle.state = {isToggleOn: false};
const cont = menu.parentNode;
cont.className = 'dropdown';
const btn = cont.querySelector('[role=button]');
btn.setAttribute('aria-expanded','false');
btn.focus();
}
}
render() {
return(
{this.props.items.map(item =>
-
{item.content}
)}
);
}
}
class Button extends React.Component{
constructor(props) {
super(props);
this.state = {isToggleOn: false};
this.handleClick = this.handleClick.bind(this);
}
handleClick(e) {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}
));
}
componentDidUpdate() {
const element = ReactDOM.findDOMNode(this);
element.querySelector('li').focus();
}
render() {
return(
);
}
}
var sports =[
{'id':1, 'content':'Cricket','link':'http://sports.yahoo.com'},
{'id':2, 'content':'Tennis','link':'http://www.bbc.com/sport'},
{'id':3, 'content':'Badminton','link':'http://bwfbadminton.com/'}
]
ReactDOM.render(
<Button key="1" items={sports}/>,
document.getElementById('container')
);
http://mpnkhan.github.io/test/examples/react/menu.html
<div aria-live="polite" aria-atomic="true" aria-relevant="additions"> Ajax Updates</div>
Implicit live roles:
<div role="alert" id="errMsgId"> Important Error Message</div>
$ eslint src webpack.config.babel.js --ext .js,.jsx
/Users/pkhan/Desktop/Nawaz/Outside/learn/react/src/shared/component/button.jsx
11:3 error The element button has an implicit role of button. Defining this explicitly is redundant and should be avoided jsx-a11y/no-redundant-roles
/Users/pkhan/Desktop/Nawaz/Outside/learn/react/src/shared/component/modal-example.jsx
6:48 error aria-modal: This attribute is an invalid ARIA attribute jsx-a11y/aria-props
17:11 error The element button has an implicit role of button. Defining this explicitly is redundant and should be avoided jsx-a11y/no-redundant-roles
/Users/pkhan/Desktop/Nawaz/Outside/learn/react/src/shared/component/nav.jsx
23:5 error The element button has an implicit role of button. Defining this explicitly is redundant and should be avoided jsx-a11y/no-redundant-roles
/Users/pkhan/Desktop/Nawaz/Outside/learn/react/src/shared/component/page/home.jsx
26:13 error The element button has an implicit role of button. Defining this explicitly is redundant and should be avoided jsx-a11y/no-redundant-roles
✖ 5 problems (5 errors, 0 warnings)
error Command failed with exit code 1.
In .eslintrc.json
{
"extends": [
"plugin:jsx-a11y/recommended"
],
"plugins": [
"jsx-a11y"
],
}
In package.json
"scripts": {
"lint": "eslint src webpack.config.babel.js --ext .js,.jsx",
}
https://github.com/evcohen/eslint-plugin-jsx-a11y
$ npm install react-a11y
In app.jsx file
import a11y from 'react-a11y' //start
.
.
.
a11y(React) //Last line
export default App
Shows error in console
$ yarn start
yarn start v0.22.0
$ yarn dev:start
yarn dev:start v0.22.0
$ nodemon -e js,jsx --ignore lib --ignore dist --exec babel-node src/server
Server running on port 8000 (development).
Keep "yarn dev:wds" running in an other terminal.
Nav You have an unlabeled element or control. Add `aria-label` or `aria-labelledby` attribute, or put some text in the element.
Nav You have an unlabeled element or control. Add `aria-label` or `aria-labelledby` attribute, or put some text in the element.
https://github.com/reactjs/react-a11y
Label Form elements in templates
template: `
`,
Dynamic elements should also be labelled
template: `
`,
-
{{hero.id}} {{hero.name}}
onKeydown(event: any): void{
if(event.key=='Enter'){
event.target.click();
}
}
or
<li *ngFor="let hero of heroes"
[class.selected]="hero === selectedHero"
#item
(keydown.enter)="item.click()">
$yarn add angular-aria@X.Y.Z
(function(angular) {
'use strict';
angular.
module('ngAria_ngModelExample', ['ngAria']);
Custom checkbox
adds Aria attributes
Custom checkbox
Angular Material Design components are better https://material.angular.io/components