Socket
Socket
Sign inDemoInstall

react-aria-modal

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-aria-modal - npm Package Compare versions

Comparing version 0.1.1 to 1.0.0

demo/js/demo-five.jsx

6

demo/js/demo-four.jsx
var React = require('react');
var AriaModal = require('../../');
var DemoOne = React.createClass({
var DemoFour = React.createClass({
getInitialState: function() {

@@ -29,3 +29,3 @@ return {

initialFocus='#demo-four-deactivate'
active={this.state.modalActive}
mounted={this.state.modalActive}
>

@@ -50,2 +50,2 @@ <div id='demo-four-modal' className='modal'>

React.render(<DemoOne />, document.getElementById('demo-four'));
React.render(<DemoFour />, document.getElementById('demo-four'));

@@ -24,2 +24,3 @@ var React = require('react');

onExit={this.deactivateModal}
focusDialog={true}
>

@@ -29,3 +30,2 @@ <div

className='modal'
tabIndex='0'
>

@@ -32,0 +32,0 @@ <div className='modal-header'>

@@ -5,1 +5,2 @@ require('./demo-one');

require('./demo-four');
require('./demo-five');

@@ -1,63 +0,1 @@

var React = require('react');
var Modal = require('./lib/Modal');
var container = document.createElement('div');
document.body.appendChild(container);
function deactivateModal() {
React.unmountComponentAtNode(container);
}
var ModalLoader = React.createClass({
propTypes: {
onExit: React.PropTypes.func.isRequired,
active: React.PropTypes.bool,
},
getDefaultProps: function() {
return {
active: true,
};
},
componentDidMount: function() {
if (this.props.active) {
this.activateModal();
}
},
componentDidUpdate: function(prevProps) {
if (prevProps.active && !this.props.active) {
deactivateModal();
} else if (!prevProps.active && this.props.active) {
this.activateModal();
}
},
componentWillUnmount: function() {
deactivateModal();
},
activateModal: function() {
var modalProps = {
onExit: this.props.onExit,
};
for (var key in this.props) {
if (key !== 'refs' && this.props.hasOwnProperty(key)) {
modalProps[key] = this.props[key];
}
}
React.render(
React.createElement(Modal, modalProps, this.props.children),
container
);
},
render: function() {
return false;
},
});
module.exports = ModalLoader;
module.exports = require('./lib/Modal');
var React = require('react');
var FocusTrap = require('focus-trap-react');
var displace = require('react-displace');
var noScroll = require('no-scroll');

@@ -12,7 +13,9 @@

alert: PropTypes.bool,
focusDialog: PropTypes.bool,
initialFocus: PropTypes.string,
onEnter: PropTypes.func,
titleId: PropTypes.string,
titleText: PropTypes.string,
underlayClass: PropTypes.string,
underlayColor: PropTypes.string,
underlayColor: PropTypes.oneOfType([PropTypes.string, PropTypes.bool]),
underlayClickExits: PropTypes.bool,

@@ -37,2 +40,8 @@ verticallyCenter: PropTypes.bool,

componentDidMount: function() {
if (this.props.onEnter) {
this.props.onEnter();
}
},
checkClick: function(e) {

@@ -52,3 +61,2 @@ if (React.findDOMNode(this.refs.dialog).contains(e.target)) return;

style: {
background: this.props.underlayColor,
position: 'fixed',

@@ -66,2 +74,6 @@ top: 0,

if (this.props.underlayColor) {
underlayProps.style.background = this.props.underlayColor;
}
if (this.props.underlayClickExits) {

@@ -89,2 +101,3 @@ underlayProps.style.cursor = 'pointer';

transform: transformValue,
cursor: 'default',
},

@@ -99,2 +112,7 @@ };

if (this.props.focusDialog) {
dialogProps.tabIndex = '0';
dialogProps.style.outline = 0;
}
return focusTrapFactory(

@@ -112,2 +130,2 @@ {

module.exports = Modal;
module.exports = displace(Modal);
{
"name": "react-aria-modal",
"version": "0.1.1",
"description": "A fully flexible and accessible React modal built according WAI-ARIA Authoring Practices",
"version": "1.0.0",
"description": "A fully accessible and flexible React modal built according WAI-ARIA Authoring Practices",
"main": "index.js",

@@ -11,8 +11,3 @@ "scripts": {

"demo-bs": "browser-sync start --server demo --files=\"demo/**/*.css,demo/index.html,demo/demo-bundle.js\"",
"demo-dev": "parallelshell \"npm run demo-watch\" \"npm run demo-bs\"",
"test-bundle": "browserify test -t babelify -o test/test-bundle.js --extension=.jsx",
"test-dev": "watchify test -d -t babelify -o test/test-bundle.js -v --extension=.jsx",
"test-single": "karma start --single-run",
"pretest": "npm run lint",
"test": "npm run test-bundle && npm run test-single"
"demo-dev": "parallelshell \"npm run demo-watch\" \"npm run demo-bs\""
},

@@ -38,21 +33,15 @@ "repository": {

"dependencies": {
"focus-trap-react": "^0.2.0",
"no-scroll": "^0.1.0",
"react": "0.13.x"
"focus-trap-react": "^1.0.0",
"no-scroll": "^1.0.0",
"react": "0.13.x",
"react-displace": "^1.0.0"
},
"devDependencies": {
"babelify": "6.1.3",
"babelify": "6.2.0",
"browser-sync": "2.8.2",
"browserify": "11.0.1",
"es5-shim": "4.1.10",
"eslint": "1.1.0",
"karma": "0.13.9",
"karma-phantomjs-launcher": "0.2.1",
"karma-tap": "1.0.3",
"eslint": "1.2.1",
"parallelshell": "2.0.0",
"phantomjs": "1.9.18",
"sinon": "1.15.4",
"tape": "4.2.0",
"watchify": "3.3.1"
}
}
# react-aria-modal
A fully flexible and accessible React modal built according WAI-ARIA Authoring Practices.
A fully accessible and flexible React modal built according [WAI-ARIA Authoring Practices](http://www.w3.org/TR/wai-aria-practices/#dialog_modal).
"Flexible" mostly means that this module provides minimal inline styles to get the thing working, but does not provide "complete" modal styling that would get in you way. You get to (have to) style the dialog yourself. Essentially, this module provides a "smart" minimally styled component to wrap you "dumb" fully styled component.
This module provides a "smart" minimally styled component to wrap you "dumb" fully styled component. It provides the following features, while giving you complete control of the content:
This module is built on top of some vanilla JS modules that could be used by non-React libraries:
- [focus-trap](https://github.com/davidtheclark/focus-trap)
- [no-scroll](https://github.com/davidtheclark/no-scroll)
- Focus is trapped within the modal: Tab and Shift+Tab will cycle through the modal's focusable nodes
without returning to the main document beneath.
- Escape will close the modal.
- Scrolling is frozen on the main document beneath the modal. (Although, sadly, you can still mess with the scrolling using a touch screen.)
- When the modal closes, focus returns to the element that was focused just before the modal activated.
- The dialog element has an ARIA `role` of `dialog` (or `alertdialog`).
- The dialog element has an ARIA attribute designating its title, either `aria-label` or `aria-labelledby`.
- By default, clicking on the modal's underlay (outside the dialog element) will close the modal (this can be disabled).
- The modal is appended to the end of `document.body` instead of its taking up its source-order position within the React component tree.
(It doesn't directly depend on focus-trap, but uses [focus-trap-react](https://github.com/davidtheclark/focus-trap-react),
a focus-trap wrapper which could be used by other React libraries.)
"Flexible" mostly means that this module provides absolutely minimal inline styles — just enough to get the thing working — but does not provide "complete" modal styling that would get in your way. You get to (have to) style the dialog yourself. (Maybe make a fancy-looking modal module that others could use, which depends on this one behind the scenes?)
[Check out the demo.](http://davidtheclark.github.io/react-aria-modal/demo/)
## Project Goals
- Full accessibility
- Maximum flexibility
- Absolutely minimal styling
- Modular construction: this module is built on top of a few small JS modules that could be used by other React and non-React frontend components:
- [focus-trap](https://github.com/davidtheclark/focus-trap), via [focus-trap-react](https://github.com/davidtheclark/focus-trap-react)
- [no-scroll](https://github.com/davidtheclark/no-scroll)
- [react-displace](https://github.com/davidtheclark/react-displace)
**If you like this kind of module (accessible, flexible, unstyled) you should also check out these projects:**

@@ -55,3 +70,3 @@ - [react-aria-menubutton](https://github.com/davidtheclark/react-aria-menubutton)

<AriaModal
active={this.state.modalActive}
mounted={this.state.modalActive}
titleText='demo one'

@@ -84,12 +99,12 @@ onExit={this.deactivateModal}

The modal can be activated in a couple of ways:
- mounting the component *without* an `active` prop
- passing `true` as the `active` prop
- mounting the component *without* an `mounted` prop
- passing `true` as the `mounted` prop
Similarly, the modal can be deactivated in a couple of ways:
- unmounting the component
- passing `false` as the `active` prop
- passing `false` as the `mounted` prop
Pass your dialog element as the child. And that's it.
When the modal is active, you'll notice the following:
When the modal is mounted, you'll notice the following:
- Focus is trapped: only elements within the modal will receive focus as you tab through. This is done by [focus-trap](https://github.com/davidtheclark/focus-trap), via [focus-trap-react](https://github.com/davidtheclark/focus-trap-react).

@@ -118,2 +133,12 @@ - The modal has the ARIA attributes it needs: a `role` of `dialog` (or `alertdialog`) and an `aria-label` or `aria-labelledby` attribute.

### focusDialog
Type: `Boolean`
By default, when the modal activates its first focusable child will receive focus.
However, if `focusDialog` is `true`, the dialog itself will receive initial focus —
and that focus will be hidden. (This is essentially what Bootstrap does with their modal.)
See the example below.
### initialFocus

@@ -123,6 +148,56 @@

By default, *when the modal activates its first focusable child will receive focus*. If, instead, you want to identify a specific element that should receive initial focus, pass a *selector string* to this prop. (That selector is passed to `document.querySelector()` to find the DOM node.)
By default, when the modal activates its first focusable child will receive focus. If, instead, you want to *identify a specific element that should receive initial focus*, pass a *selector string* to this prop. (That selector is passed to `document.querySelector()` to find the DOM node.)
Demo example 3 and an additional example below illustrate a good method if you want no initial visible focus. (Add `tabIndex='0'` to the modal's content and give it `outline: 0;`.)
### mounted
Type: `Boolean`
By default, the modal is active when mounted, deactivated when unmounted.
However, you can also control its active/inactive state by changing its `mounted` property instead.
The following two examples are near-equivalents — the first mounts and unmounts, while the second changes the `mounted` prop:
```js
var MyComponent = React.createClass({
..
render: function() {
..
var modal = (this.state.modalActive) ? (
<AriaModal onExit={this.myExitHandler}>
{modalContents}
</AriaModal>
) : false;
return <div>{modal}</div>;
},
});
var MyComponentTakeTwo = React.createClass({
..
render: function() {
..
return (
<div>
<AriaModal
mounted={this.state.modalActive}
onExit={this.myExitHandler}
>
{modalContents}
</AriaModal>
</div>
);
},
});
```
### onEnter
Type: `Function`
This function is called in the modal's `componentDidMount()` lifecycle method.
You can use it to do whatever diverse and sundry things you feel like doing after the modal activates.
Demo Five, for example, uses it to modify class names and enable some CSS transitions.
### titleId

@@ -160,6 +235,9 @@

Type: `String` (color value), Default: `rgba(0,0,0,0.5)`
Type: `String` (color value) or `false`, Default: `rgba(0,0,0,0.5)`
If you want to change about the underlay's color, you can do that with this prop.
If you want to change the underlay's color, you can do that with this prop.
If `false`, no background color will be applied with inline styles.
Presumably you will apply then yourself via an `underlayClass`.
### verticallyCenter

@@ -185,2 +263,3 @@

alert={true}
focusDialog={true}
titleId='modal-title'

@@ -191,3 +270,2 @@ underlayClickExists={false}

<div
tabIndex='0'
style={{ outline: 0 }}

@@ -204,6 +282,1 @@ className='my-modal-dialog'

```
## Coming soon
- Unit tests
- Function children (primarily useful for animation)

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc