Skip to content

Commit 7e5fa2a

Browse files
committed
[fixed] Accessibility issues
closes #2
1 parent b0eca56 commit 7e5fa2a

File tree

7 files changed

+46
-31
lines changed

7 files changed

+46
-31
lines changed

examples/basic/app.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ var App = React.createClass({
5656
</MenuOption>
5757

5858
<MenuOption disabled={true} onDisabledSelect={this.handleDisabledSelect}>
59-
diabled option
59+
disabled option
6060
</MenuOption>
6161

6262
</MenuOptions>

lib/components/Menu.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ var cloneWithProps = require('react/lib/cloneWithProps');
66
var MenuTrigger = require('./MenuTrigger');
77
var MenuOptions = require('./MenuOptions');
88
var MenuOption = require('./MenuOption');
9+
var uuid = require('../helpers/uuid');
910
var injectCSS = require('../helpers/injectCSS');
1011
var buildClassName = require('../mixins/buildClassName');
1112

@@ -19,8 +20,21 @@ var Menu = module.exports = React.createClass({
1920

2021
mixins: [buildClassName],
2122

23+
childContextTypes: {
24+
id: React.PropTypes.string,
25+
active: React.PropTypes.bool
26+
},
27+
28+
getChildContext: function () {
29+
return {
30+
id: this.state.id,
31+
active: this.state.active
32+
};
33+
},
34+
2235
getInitialState: function(){
2336
return {
37+
id: uuid(),
2438
active: false,
2539
selectedIndex: 0,
2640
horizontalPlacement: 'right', // only 'right' || 'left'
@@ -93,8 +107,9 @@ var Menu = module.exports = React.createClass({
93107
React.Children.forEach(this.props.children, function(child){
94108
if (child.type === MenuTrigger.type) {
95109
trigger = cloneWithProps(child, {
96-
onToggleActive: this.handleTriggerToggle,
97-
ref: 'trigger'
110+
ref: 'trigger',
111+
owns: this.state.id,
112+
onToggleActive: this.handleTriggerToggle
98113
});
99114
}
100115
}.bind(this));
@@ -103,9 +118,6 @@ var Menu = module.exports = React.createClass({
103118
},
104119

105120
renderMenuOptions: function() {
106-
if (!this.state.active) {
107-
return null;
108-
}
109121
var options;
110122
if(this.verifyTwoChildren()) {
111123
React.Children.forEach(this.props.children, function(child){
@@ -127,7 +139,6 @@ var Menu = module.exports = React.createClass({
127139
return (
128140
<div
129141
className={this.buildClassName('Menu')}
130-
role='menu'
131142
onKeyDown={this.handleKeys}
132143
onBlur={this.handleBlur}
133144
>

lib/components/MenuOption.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,9 @@ var MenuOption = module.exports = React.createClass({
7171
onKeyDown={this.handleKeyDown}
7272
onMouseOver={this.handleHover}
7373
className={this.buildName()}
74-
role='menuitem'
75-
tabIndex='-1'
74+
role="menuitem"
75+
tabIndex="-1"
76+
aria-disabled={this.props.disabled}
7677
>
7778
{this.props.children}
7879
</div>

lib/components/MenuOptions.js

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ var buildClassName = require('../mixins/buildClassName');
77

88
var MenuOptions = module.exports = React.createClass({
99

10+
contextTypes: {
11+
id: React.PropTypes.string,
12+
active: React.PropTypes.bool
13+
},
14+
1015
getInitialState: function() {
1116
return {activeIndex: 0}
1217
},
@@ -52,16 +57,11 @@ var MenuOptions = module.exports = React.createClass({
5257
},
5358

5459
updateFocusIndexBy: function(delta) {
55-
// open menu if it's closed, and retry focus
56-
if (!this.state.active) {
57-
this.selectedIndex = 0;
58-
this.setState({active: true}, this.updateFocusIndexBy.bind(this, 0));
59-
return
60-
}
6160
var optionNodes = this.getDOMNode().querySelectorAll('.Menu__MenuOption');
6261
this.normalizeSelectedBy(delta, optionNodes.length);
63-
this.setState({activeIndex: this.selectedIndex});
64-
optionNodes[this.selectedIndex].focus();
62+
this.setState({activeIndex: this.selectedIndex}, function () {
63+
optionNodes[this.selectedIndex].focus();
64+
});
6565
},
6666

6767
renderOptions: function() {
@@ -92,6 +92,11 @@ var MenuOptions = module.exports = React.createClass({
9292
render: function() {
9393
return (
9494
<div
95+
id={this.context.id}
96+
role="menu"
97+
tabIndex="-1"
98+
aria-expanded={this.context.active}
99+
style={{visibility: this.context.active ? 'visible' : 'hidden'}}
95100
className={this.buildName()}
96101
onKeyDown={this.handleKeys}
97102
>

lib/components/MenuTrigger.js

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,14 @@ var buildClassName = require('../mixins/buildClassName');
55

66
var MenuTrigger = module.exports = React.createClass({
77

8-
getInitialState: function() {
9-
return {
10-
active: false
11-
};
8+
contextTypes: {
9+
active: React.PropTypes.bool
1210
},
1311

1412
mixins: [buildClassName],
1513

16-
notifyParent: function() {
17-
if (this.props.onToggleActive)
18-
this.props.onToggleActive(this.state.active);
19-
},
20-
2114
toggleActive: function() {
22-
this.setState({
23-
active: !this.state.active
24-
}, this.notifyParent);
15+
this.props.onToggleActive(!this.context.active);
2516
},
2617

2718
handleKeyUp: function(e) {
@@ -47,7 +38,10 @@ var MenuTrigger = module.exports = React.createClass({
4738
onClick={this.handleClick}
4839
onKeyUp={this.handleKeyUp}
4940
onKeyDown={this.handleKeyDown}
50-
tabIndex='0'
41+
tabIndex="0"
42+
role="button"
43+
aria-owns={this.props.owns}
44+
aria-haspopup="true"
5145
>
5246
{this.props.children}
5347
</div>

lib/helpers/uuid.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
var count = 0;
2+
module.exports = function () {
3+
return 'react-menu-' + count++;
4+
};

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
},
1515
"scripts": {
1616
"test": "script/test --browsers Firefox --single-run",
17-
"start": "scripts/dev-examples"
17+
"start": "script/dev-examples"
1818
},
1919
"authors": [
2020
"Jason Madsen"

0 commit comments

Comments
 (0)