From 08de4ff575ceddb07f982cbf37b11825783a967a Mon Sep 17 00:00:00 2001 From: Caroline Taymor Date: Wed, 19 Aug 2015 09:37:57 -0700 Subject: [PATCH] feat(modals): Modals are more accessible Adds tabbing within an open modal and aria roles and states. Signed-off-by: Kenny Wang --- spec/pivotal-ui-react/modals/modals_spec.js | 17 +-------------- src/pivotal-ui-react/modals/modals.js | 23 +++++++++++++++------ 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/spec/pivotal-ui-react/modals/modals_spec.js b/spec/pivotal-ui-react/modals/modals_spec.js index 243ea8867..91c3a80c6 100644 --- a/spec/pivotal-ui-react/modals/modals_spec.js +++ b/spec/pivotal-ui-react/modals/modals_spec.js @@ -21,7 +21,6 @@ describe('Modals', function() { }); describe('default behavior', function() { - var subject; beforeEach(function() { var MyModal = React.createClass({ propTypes: { @@ -53,7 +52,7 @@ describe('Modals', function() { } }); - subject = React.render(, root); + React.render(, root); }); @@ -61,20 +60,6 @@ describe('Modals', function() { expect('#root .modal').not.toExist(); }); - describe('when mounting', function() { - it('adds the key up event listener', function() { - expect(document.body.addEventListener).toHaveBeenCalledWith('keyup', subject.refs.modal.onKeyUp, false); - }); - }); - - describe('when unmounting', function() { - it('removes the key up event listener', function() { - var onKeyUp = subject.refs.modal.onKeyUp; - React.unmountComponentAtNode(root); - expect(document.body.removeEventListener).toHaveBeenCalledWith('keyup', onKeyUp); - }); - }); - function itOpensTheModal() { it('renders a modal', function() { expect('.modal').toExist(); diff --git a/src/pivotal-ui-react/modals/modals.js b/src/pivotal-ui-react/modals/modals.js index 9f5f0c64d..138d4400f 100644 --- a/src/pivotal-ui-react/modals/modals.js +++ b/src/pivotal-ui-react/modals/modals.js @@ -50,10 +50,12 @@ var Modal = React.createClass({ }, componentDidMount() { - document.body.addEventListener('keyup', this.onKeyUp, false); + document.body.addEventListener('focus', this.ignoreKey, true); + document.body.addEventListener('keyup', this.onKeyUp, true); }, componentWillUnmount() { + document.body.removeEventListener('focus', this.ignoreKey); document.body.removeEventListener('keyup', this.onKeyUp); }, @@ -63,15 +65,16 @@ var Modal = React.createClass({ componentWillUpdate(nextProps, nextState) { if (nextState.isVisible) { - document.body.classList.add('modal-open'); + document.body.classList.add('modal-open'); } else { - document.body.classList.remove('modal-open'); + document.body.classList.remove('modal-open'); } }, open() { this.setState({isVisible: true}); + React.findDOMNode(this.refs.modalTransitions).focus(); }, close() { @@ -84,6 +87,13 @@ var Modal = React.createClass({ } }, + ignoreKey(e) { + if ((this.state.isVisible) && (!(React.findDOMNode(this.refs.modalTransitions).contains(e.target)))) { + e.preventDefault(); + React.findDOMNode(this.refs.modalTransitions).focus(); + } + }, + onKeyUp(e) { if (e.keyCode === 27) { this.close(); @@ -95,7 +105,8 @@ var Modal = React.createClass({ let backdrop = null; if (this.state.isVisible) { modal = ( -
+
@@ -103,7 +114,7 @@ var Modal = React.createClass({ × Close - {this.props.title} + {this.props.title}
{this.props.children}
@@ -114,7 +125,7 @@ var Modal = React.createClass({ } return ( -
+
{backdrop} {modal}