Skip to content

Commit

Permalink
[added] allow users to pass aria-* attribute.
Browse files Browse the repository at this point in the history
This patch allows users to pass custom aria attributes
to be added to the modal content.

It accepts an object where the keys are the name of the attributes
without the prefix aria-*.
  • Loading branch information
diasbruno committed Jun 28, 2017
1 parent 6f73764 commit 67ee9f5
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 3 deletions.
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"react/no-find-dom-node": [0],
"react/jsx-closing-bracket-location": [0],
"react/jsx-filename-extension": ["error", {"extensions": [".js"]}],
"react/forbid-prop-types": [1, {"forbid": ["any"]}],
"react/require-default-props": 0
}
}
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,28 @@ Modal.setAppElement(appElement);
Modal.setAppElement('#your-app-element');
```

### Additional Aria Attributes

Use the property `aria` to pass any additional aria attributes. It accepts
an object where the keys are the names of the attributes without the prefix
`aria-`.

Example:

```js
<Modal
isOpen={modalIsOpen}
aria={{
labelledby: "heading",
describedby: "full_description"
}}>
<h1 id="heading">H1</h1>
<div id="full_description">
<p>Description goes here.</p>
</div>
</Modal>
```

## Styles

Styles are passed as an object with 2 keys, 'overlay' and 'content' like so
Expand Down
7 changes: 7 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,13 @@ import ReactModal from 'react-modal';
Function that will be called to get the parent element that the modal will be attached to.
*/
parentSelector={() => document.body}
/*
Additional aria attributes (optional).
*/
aria={{
labelledby: "heading",
describedby: "full_description"
}}
/>
```

Expand Down
9 changes: 8 additions & 1 deletion examples/basic/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,19 @@ class App extends Component {
</Modal>
<Modal ref="mymodal2"
id="test2"
aria={{
labelledby: "heading",
describedby: "fulldescription"
}}
closeTimeoutMS={150}
contentLabel="modalB"
isOpen={modal2}
onAfterOpen={() => {}}
onRequestClose={this.toggleModal_2}>
<p>test</p>
<h1 id="heading">This is the modal 2!</h1>
<div id="fulldescription" tabIndex="0" role="document">
<p>This is a description of what it does: nothing :)</p>
</div>
</Modal>
</div>
);
Expand Down
10 changes: 9 additions & 1 deletion specs/Modal.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ describe('State', () => {
unmountModal();
expect(!isBodyWithReactModalOpenClass()).toBeTruthy();
});

it('should not add classes to document.body for unopened modals', () => {
renderModal({ isOpen: true });
expect(isBodyWithReactModalOpenClass()).toBeTruthy();
Expand All @@ -259,6 +259,14 @@ describe('State', () => {
expect(isBodyWithReactModalOpenClass()).toBeTruthy();
});

it('additional aria attributes', () => {
const modal = renderModal({ isOpen: true, aria: { labelledby: "a" }}, 'hello');
expect(
mcontent(modal).getAttribute('aria-labelledby')
).toEqual("a");
unmountModal();
});

it('adding/removing aria-hidden without an appElement will try to fallback to document.body', () => {
ariaAppHider.documentNotReadyOrSSRTesting();
const node = document.createElement('div');
Expand Down
1 change: 1 addition & 0 deletions src/components/Modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export default class Modal extends Component {
ariaHideApp: PropTypes.bool,
shouldCloseOnOverlayClick: PropTypes.bool,
parentSelector: PropTypes.func,
aria: PropTypes.object,
role: PropTypes.string,
contentLabel: PropTypes.string.isRequired
};
Expand Down
9 changes: 8 additions & 1 deletion src/components/ModalPortal.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export default class ModalPortal extends Component {
shouldCloseOnOverlayClick: PropTypes.bool,
role: PropTypes.string,
contentLabel: PropTypes.string,
aria: PropTypes.object,
children: PropTypes.node
};

Expand Down Expand Up @@ -254,6 +255,11 @@ export default class ModalPortal extends Component {
`${className} ${additional}` : className;
}

ariaAttributes = items => Object.keys(items).reduce((acc, name) => {
acc[`aria-${name}`] = items[name];
return acc;
}, {});

render() {
const { className, overlayClassName, defaultStyles } = this.props;
const contentStyles = className ? {} : defaultStyles.content;
Expand All @@ -273,7 +279,8 @@ export default class ModalPortal extends Component {
onKeyDown={this.handleKeyDown}
onClick={this.handleContentOnClick}
role={this.props.role}
aria-label={this.props.contentLabel}>
aria-label={this.props.contentLabel}
{...this.ariaAttributes(this.props.aria || {})}>
{this.props.children}
</div>
</div>
Expand Down

0 comments on commit 67ee9f5

Please sign in to comment.