react-poppop
Advanced tools
Comparing version 0.4.0 to 1.0.0
@@ -1,2 +0,2 @@ | ||
"use strict"; | ||
'use strict'; | ||
@@ -7,3 +7,3 @@ Object.defineProperty(exports, "__esModule", { | ||
var _poppop = require("./poppop"); | ||
var _poppop = require('./poppop'); | ||
@@ -10,0 +10,0 @@ var _poppop2 = _interopRequireDefault(_poppop); |
@@ -6,4 +6,5 @@ 'use strict'; | ||
}); | ||
exports.default = undefined; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | ||
@@ -15,2 +16,18 @@ | ||
var _propTypes = require('prop-types'); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var _Tappable = require('react-tappable/lib/Tappable'); | ||
var _Tappable2 = _interopRequireDefault(_Tappable); | ||
var _reactTransitionGroup = require('react-transition-group'); | ||
var _portal = require('./portal'); | ||
var _portal2 = _interopRequireDefault(_portal); | ||
var _utils = require('./utils'); | ||
var _style = require('./style'); | ||
@@ -34,7 +51,22 @@ | ||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(PopPop).call(this, props)); | ||
var _this = _possibleConstructorReturn(this, (PopPop.__proto__ || Object.getPrototypeOf(PopPop)).call(this, props)); | ||
_this.handleOverlayClick = _this.handleOverlayClick.bind(_this); | ||
_this.handleCloseBtn = _this.handleCloseBtn.bind(_this); | ||
_this.handleEscKeyDown = _this.handleEscKeyDown.bind(_this); | ||
_this.handleOverlayClick = function () { | ||
if (_this.props.closeOnOverlay) { | ||
_this.props.onClose(); | ||
} | ||
}; | ||
_this.handleCloseBtn = function () { | ||
if (_this.props.onClose) { | ||
_this.props.onClose(); | ||
} | ||
}; | ||
_this.handleEscKeyDown = function (e) { | ||
if (_this.props.closeOnEsc && e.keyCode === 27) { | ||
_this.props.onClose(); | ||
} | ||
}; | ||
return _this; | ||
@@ -46,3 +78,5 @@ } | ||
value: function componentDidMount() { | ||
document.addEventListener('keydown', this.handleEscKeyDown); | ||
if (this.props.closeOnEsc) { | ||
document.addEventListener('keydown', this.handleEscKeyDown); | ||
} | ||
} | ||
@@ -52,49 +86,46 @@ }, { | ||
value: function componentWillUnmount() { | ||
document.removeEventListener('keydown', this.handleEscKeyDown); | ||
} | ||
}, { | ||
key: 'handleOverlayClick', | ||
value: function handleOverlayClick() { | ||
var overlayClick = this.props.overlayClick; | ||
if (overlayClick) { | ||
this.props.overlayClick(); | ||
if (this.props.closeOnEsc) { | ||
document.removeEventListener('keydown', this.handleEscKeyDown); | ||
} | ||
} | ||
}, { | ||
key: 'handleCloseBtn', | ||
value: function handleCloseBtn() { | ||
if (this.props.onClose) this.props.onClose(); | ||
} | ||
}, { | ||
key: 'handleEscKeyDown', | ||
value: function handleEscKeyDown(e) { | ||
if (this.props.closeOnEsc && e.keyCode === 27) { | ||
this.props.onClose(); | ||
} | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var position = this.props.position; | ||
var _this2 = this; | ||
var _contentStyle = this.props.contentStyle; | ||
var wrapperStyle = void 0, | ||
contentStyle = void 0; | ||
var _props = this.props, | ||
open = _props.open, | ||
position = _props.position, | ||
overlayStyle = _props.overlayStyle, | ||
contentStyle = _props.contentStyle; | ||
if (position !== 'full') wrapperStyle = Object.assign({}, _style2.default.wrapper, _style2.default[position]);else if (position) wrapperStyle = Object.assign({}, _style2.default.wrapper); | ||
var extractPosition = (0, _utils.extractCamelCase)(position); | ||
var mergeWrapperStyle = _extends({}, _style2.default.wrapper, _style2.default.alignItems[extractPosition[0]], _style2.default.justifyContent[extractPosition[1]]); | ||
// merge the content style and position style | ||
if (position === 'full') contentStyle = Object.assign({}, _style2.default.content, _style2.default.full, _contentStyle);else if (position === 'center') contentStyle = Object.assign({}, _style2.default.content, _style2.default.centerContent, _contentStyle); // console.log(contentStyle) | ||
var mergeOverlayStyle = _extends({}, _style2.default.overlay, overlayStyle); | ||
var mergeContentStyle = _extends({}, _style2.default.content, contentStyle); | ||
if (!open) return null; | ||
return _react2.default.createElement( | ||
'div', | ||
{ style: wrapperStyle }, | ||
this._renderOverlay(), | ||
_portal2.default, | ||
null, | ||
_react2.default.createElement( | ||
'div', | ||
{ style: contentStyle }, | ||
this._renderCloseBtn(), | ||
this.props.children | ||
_reactTransitionGroup.Transition, | ||
{ 'in': open, appear: true, timeout: 0 }, | ||
function (state) { | ||
return _react2.default.createElement( | ||
'div', | ||
{ style: _extends({}, mergeWrapperStyle, _style2.default.transitionStyles[state]) }, | ||
_react2.default.createElement(_Tappable2.default, { onTap: _this2.handleOverlayClick, | ||
style: mergeOverlayStyle }), | ||
_react2.default.createElement( | ||
'div', | ||
{ style: mergeContentStyle }, | ||
_this2._renderCloseBtn(), | ||
_this2.props.children | ||
) | ||
); | ||
} | ||
) | ||
@@ -106,29 +137,19 @@ ); | ||
value: function _renderCloseBtn() { | ||
var _props = this.props; | ||
var closeBtn = _props.closeBtn; | ||
var position = _props.position; | ||
var style = _style2.default.closeBtn; | ||
if (position === 'full') style = Object.assign({}, _style2.default.closeBtn, _style2.default.fullCloseBtn); | ||
if (closeBtn) { | ||
if (this.props.closeBtn) { | ||
return _react2.default.createElement( | ||
'div', | ||
{ style: style, onClick: this.handleCloseBtn }, | ||
'✖' | ||
{ style: _style2.default.closeBtn, onClick: this.handleCloseBtn }, | ||
_react2.default.createElement( | ||
'svg', | ||
{ viewBox: '0 0 40 40' }, | ||
_react2.default.createElement( | ||
'g', | ||
null, | ||
_react2.default.createElement('path', { d: 'm31.6 10.7l-9.3 9.3 9.3 9.3-2.3 2.3-9.3-9.3-9.3 9.3-2.3-2.3 9.3-9.3-9.3-9.3 2.3-2.3 9.3 9.3 9.3-9.3z' }) | ||
) | ||
) | ||
); | ||
} | ||
return; | ||
return null; | ||
} | ||
}, { | ||
key: '_renderOverlay', | ||
value: function _renderOverlay() { | ||
var overlay = this.props.overlay; | ||
var overlayStyle = Object.assign(_style2.default.overlay, { display: 'block' }); | ||
if (overlay) { | ||
return _react2.default.createElement('div', { style: overlayStyle, onClick: this.handleOverlayClick }); | ||
} | ||
return; | ||
} | ||
}]); | ||
@@ -139,3 +160,8 @@ | ||
PopPop.defaultProps = { | ||
position: 'topCenter', | ||
closeOnOverlay: true, | ||
overlayStyle: {} | ||
}; | ||
exports.default = PopPop; | ||
module.exports = exports['default']; |
109
lib/style.js
'use strict'; | ||
module.exports = { | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = { | ||
wrapper: { | ||
opacity: '1', | ||
transition: 'opacity .2s linear', | ||
opacity: 0, | ||
visibility: 'visible', | ||
position: 'fixed', | ||
overflow: 'auto', | ||
zIndex: '100001', | ||
transition: 'all 0.3s', | ||
overflowX: 'hidden', | ||
overflowY: 'auto', | ||
zIndex: '1000', | ||
top: '0', | ||
left: '0', | ||
right: '0', | ||
bottom: '0', | ||
display: 'flex', | ||
padding: '20px' | ||
}, | ||
overlay: { | ||
position: 'fixed', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
top: '0px', | ||
left: '0px', | ||
display: 'flex', | ||
alignItems: 'center' | ||
zIndex: 99, | ||
backgroundColor: 'rgba(0,0,0,0.6)' | ||
}, | ||
alignItems: { | ||
Top: { | ||
alignItems: 'flex-start' | ||
}, | ||
Center: { | ||
alignItems: 'center' | ||
}, | ||
Bottom: { | ||
alignItems: 'flex-end' | ||
} | ||
}, | ||
justifyContent: { | ||
Right: { | ||
justifyContent: 'flex-end' | ||
}, | ||
Left: { | ||
justifyContent: 'flex-start' | ||
}, | ||
Center: { | ||
justifyContent: 'center' | ||
} | ||
}, | ||
content: { | ||
@@ -24,46 +57,11 @@ transition: 'all 0.3s', | ||
borderRadius: '3px', | ||
zIndex: 100, | ||
zIndex: 2000, | ||
position: 'relative', | ||
boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)', | ||
overflow: 'scroll' | ||
overflow: 'scroll', | ||
maxWidth: '850px', | ||
padding: '10px 20px' | ||
}, | ||
center: { | ||
verticalAlign: 'middle', | ||
justifyContent: 'center' | ||
}, | ||
centerContent: { | ||
maxHeight: '90%' | ||
}, | ||
left_center: { | ||
verticalAlign: 'middle', | ||
justifyContent: 'flex-start' | ||
}, | ||
right_center: { | ||
verticalAlign: 'middle', | ||
justifyContent: 'flex-end' | ||
}, | ||
full: { | ||
width: '100%', | ||
height: '100%' | ||
}, | ||
overlay: { | ||
position: 'fixed', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
zIndex: 99, | ||
backgroundColor: 'rgba(0,0,0,0.3)' | ||
}, | ||
closeBtn: { | ||
position: 'absolute', | ||
right: '5px', | ||
top: '5px', | ||
float: 'right', | ||
color: '#000', | ||
@@ -79,3 +77,2 @@ textShadow: '0 1px 0 #fff', | ||
}, | ||
fullCloseBtn: { | ||
@@ -85,3 +82,9 @@ right: '0', | ||
borderRadius: '0' | ||
}, | ||
transitionStyles: { | ||
entering: { opacity: 0 }, | ||
entered: { opacity: 1 }, | ||
exited: { opacity: 0 } | ||
} | ||
}; | ||
}; | ||
module.exports = exports['default']; |
132
package.json
{ | ||
"name": "react-poppop", | ||
"version": "0.4.0", | ||
"version": "1.0.0", | ||
"description": "react poppop is a react pop up", | ||
@@ -8,6 +8,13 @@ "main": "lib/index.js", | ||
"start": "node devServer.js", | ||
"build": "rm -rf ./lib && BABEL_ENV=production babel --stage 0 src --out-dir lib", | ||
"clean": "rimraf dist", | ||
"build:watch": "rm -rf ./lib && babel -w --stage 0 src --out-dir lib", | ||
"build:webpack": "NODE_ENV=production webpack --config webpack.config.prod.js" | ||
"build": "npm run build:lib && npm run build:dist", | ||
"build:lib": "rimraf ./lib && BABEL_ENV=production babel src -d lib", | ||
"build:dist": "rimraf dist && rollup -c --environment ESBUNDLE && rollup -c --environment PRODUCTION", | ||
"lint": "eslint src example test", | ||
"test": "jest", | ||
"test:watch": "NODE_ENV=test npm test -- --watch", | ||
"gh-pages": "npm run gh-pages:build && npm run gh-pages:publish", | ||
"gh-pages:build": "NODE_ENV=production webpack --config webpack.config.prod.js", | ||
"gh-pages:publish": "git-directory-deploy --directory _gh-pages --branch gh-pages", | ||
"prepublish": "npm run build", | ||
"validate": "npm ls" | ||
}, | ||
@@ -18,2 +25,8 @@ "repository": { | ||
}, | ||
"files": [ | ||
"dist", | ||
"docs", | ||
"lib", | ||
"src" | ||
], | ||
"keywords": [ | ||
@@ -30,38 +43,85 @@ "react", | ||
"homepage": "https://github.com/ctxhou/react-poppop#readme", | ||
"peerDependencies": { | ||
"react": ">0.14.0 || >=15.0.0", | ||
"react-dom": ">0.14.0 || >=15.0.0" | ||
}, | ||
"dependencies": { | ||
"classnames": "^2.1.3" | ||
"classnames": "^2.1.3", | ||
"react-tappable": "^1.0.2", | ||
"react-transition-group": "^2.2.1" | ||
}, | ||
"devDependencies": { | ||
"babel-cli": "^6.6.5", | ||
"babel-core": "^6.5.2", | ||
"babel-eslint": "^6.1.2", | ||
"babel-cli": "^6.26.0", | ||
"babel-core": "^6.14.0", | ||
"babel-eslint": "^7.2.3", | ||
"babel-jest": "^20.0.3", | ||
"babel-loader": "^6.2.3", | ||
"babel-plugin-add-module-exports": "^0.2.1", | ||
"babel-plugin-react-transform": "^2.0.0", | ||
"babel-plugin-transform-decorators-legacy": "^1.3.4", | ||
"babel-plugin-transform-react-remove-prop-types": "^0.2.2", | ||
"babel-plugin-transform-runtime": "^6.5.2", | ||
"babel-polyfill": "^6.5.0", | ||
"babel-preset-es2015": "^6.5.0", | ||
"babel-preset-react": "^6.5.0", | ||
"babel-preset-react-hmre": "1.1.1", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"babel-register": "^6.7.2", | ||
"eslint": "^3.5.0", | ||
"eslint-plugin-react": "^2.3.0", | ||
"express": "^4.13.3", | ||
"react": "^15.0.0", | ||
"react-dom": "^15.0.0", | ||
"react-transform-catch-errors": "^1.0.2", | ||
"react-transform-hmr": "^1.0.2", | ||
"redbox-react": "^1.0.1", | ||
"rimraf": "^2.4.3", | ||
"webpack": "^1.9.6", | ||
"webpack-dev-middleware": "^1.2.0", | ||
"webpack-hot-middleware": "^2.0.0" | ||
} | ||
"babel-plugin-dynamic-import-webpack": "^1.0.1", | ||
"babel-plugin-external-helpers": "^6.22.0", | ||
"babel-plugin-transform-class-properties": "^6.16.0", | ||
"babel-plugin-transform-object-rest-spread": "^6.26.0", | ||
"babel-plugin-transform-react-remove-prop-types": "^0.4.10", | ||
"babel-polyfill": "^6.26.0", | ||
"babel-preset-es2015": "^6.24.1", | ||
"babel-preset-react": "^6.24.1", | ||
"babel-runtime": "^6.11.6", | ||
"compression-webpack-plugin": "^1.0.1", | ||
"cross-env": "^2.0.1", | ||
"enzyme": "^3.1.1", | ||
"enzyme-adapter-react-16": "^1.0.4", | ||
"enzyme-to-json": "^3.2.2", | ||
"eslint": "^3.1.1", | ||
"eslint-config-google": "^0.4.0", | ||
"eslint-config-prettier": "^2.6.0", | ||
"eslint-plugin-jest": "^21.2.0", | ||
"eslint-plugin-prettier": "^2.3.1", | ||
"eslint-plugin-react": "^6.2.0", | ||
"extract-text-webpack-plugin": "^3.0.1", | ||
"git-directory-deploy": "^1.5.1", | ||
"html-webpack-plugin": "^2.30.1", | ||
"husky": "^0.14.3", | ||
"jest": "^20.0.4", | ||
"jest-styled-components": "^4.9.0", | ||
"precommit-hook-eslint": "^3.0.0", | ||
"prettier": "^1.7.4", | ||
"react": "^16.0.0", | ||
"react-addons-test-utils": "^15.3.1", | ||
"react-dom": "^16.0.0", | ||
"react-select": "^1.0.0-rc.10", | ||
"rimraf": "^2.6.2", | ||
"rollup": "^0.49.0", | ||
"rollup-plugin-babel": "^3.0.1", | ||
"rollup-plugin-commonjs": "^8.2.6", | ||
"rollup-plugin-json": "^2.3.0", | ||
"rollup-plugin-node-resolve": "^3.0.0", | ||
"rollup-plugin-replace": "^2.0.0", | ||
"rollup-plugin-uglify": "^2.0.1", | ||
"rollup-plugin-visualizer": "^0.3.1", | ||
"uglify-js": "git://github.com/mishoo/UglifyJS2#harmony-v2.8.22", | ||
"uglifyjs-webpack-plugin": "1.0.1", | ||
"webpack": "^3.3.0", | ||
"webpack-bundle-analyzer": "^2.9.0", | ||
"webpack-dev-middleware": "^1.12.0", | ||
"webpack-hot-middleware": "^2.18.2" | ||
}, | ||
"peerDependencies": { | ||
"react": ">= 0.14.0 < 17.0.0-0" | ||
}, | ||
"jest": { | ||
"setupFiles": [ | ||
"./test/shim", | ||
"./test/enzyme-setup" | ||
], | ||
"roots": [ | ||
"<rootDir>/test/" | ||
], | ||
"unmockedModulePathPatterns": [ | ||
"node_modules/react/", | ||
"node_modules/enzyme/" | ||
], | ||
"snapshotSerializers": [ | ||
"enzyme-to-json/serializer" | ||
] | ||
}, | ||
"pre-commit": [ | ||
"lint", | ||
"test" | ||
] | ||
} |
233
README.md
@@ -1,5 +0,234 @@ | ||
# react-poppop | ||
# React Poppop | ||
> A responsive, mobile support, multi directions and easy to use modal for ReactJS. | ||
![version][version] | ||
![travis][travis] | ||
![david][david] | ||
![download][download] | ||
![gzip size][gzip size] | ||
### [Demo](https://ctxhou.github.io/react-poppop/) | ||
[version]: https://img.shields.io/npm/v/react-poppop.svg?maxAge=2592000 | ||
[travis]: https://travis-ci.org/ctxhou/react-poppop.svg?branch=master | ||
[david]: https://david-dm.org/ctxhou/react-poppop.svg | ||
[download]: https://img.shields.io/npm/dm/react-poppop.svg?maxAge=2592000 | ||
[gzip size]: http://img.badgesize.io/https://unpkg.com/react-poppop/dist/react-poppop.min.js?compression=gzip | ||
<img src="https://i.imgur.com/8HMXcOi.png" alt=""> | ||
## Features | ||
* **Mobile support** — Responsive and support tap action. | ||
* **Multi directions** — support 9 positions. ↑ ↗ ︎→ ↘ ︎↓ ↙ ︎← ↖ ︎⥁ | ||
* **Easily customize style** | ||
## Table of Contents | ||
<!-- toc --> | ||
- [Installation](#installation) | ||
- [Usage](#usage) | ||
* [Minimum Config](#minimum-config) | ||
* [Multi directions - 9 positions](#multi-directions---9-positions) | ||
* [Controllable](#controllable) | ||
- [Props](#props) | ||
- [License](#license) | ||
<!-- tocstop --> | ||
## Installation | ||
Install it with npm. | ||
```js | ||
npm install react-poppop --save | ||
``` | ||
Then, import the module by module bundler like `webpack`, `browserify` | ||
```js | ||
// es6 | ||
import PopPop from 'react-poppop'; | ||
// not using es6 | ||
var PopPop = require('react-poppop'); | ||
``` | ||
UMD build is also available. If you do this, you'll need to include the dependencies: | ||
For example: | ||
```html | ||
<script src="https://unpkg.com/react@16.0.0/umd/react.production.min.js"></script> | ||
<script src="https://unpkg.com/react-dom@16.0.0/umd/react-dom.production.min.js"></script> | ||
<script src="https://unpkg.com/prop-types@15.6/prop-types.min.js"></script> | ||
<script src="https://unpkg.com/react-poppop/dist/react-poppop.min.js"></script> | ||
``` | ||
You can reference [standalone.html](https://github.com/ctxhou/react-poppop/blob/master/docs/standalone.html) example. | ||
## Usage | ||
### Minimum Config | ||
The miminum usage of `PopPop` is set open as `true`. | ||
```js | ||
<PopPop open={true}> | ||
<h1>Title</h1> | ||
<p>Content</p> | ||
</PopPop> | ||
``` | ||
### Multi directions - 9 positions | ||
The default position of `react-poppop` is `Top Center`. | ||
There are 9 positions provided by `react-poppop`. | ||
`'topLeft', 'topCenter', 'topRight', 'centerLeft', 'centerCenter', 'centerRight', 'bottomLeft', 'bottomCenter', 'bottomRight'` | ||
Select a position you want and pass it to `position` props. | ||
**Example** | ||
```js | ||
<PopPop open={true} | ||
position="topRight"> | ||
<h1>Title</h1> | ||
<p>Content</p> | ||
</PopPop> | ||
``` | ||
### Controllable | ||
You can set `onClose` callback, close by click `close button`, `esc button` and `overlay`. | ||
```js | ||
import React, {Component} from 'react'; | ||
import PopPop from 'react-poppop'; | ||
export default class Example extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
show: false | ||
} | ||
} | ||
toggleShow = show => { | ||
this.setState({show}); | ||
} | ||
render() { | ||
const {show} = this.state; | ||
return ( | ||
<div> | ||
<button className="btn btn-default" onClick={() => this.toggleShow(true)}>Show Modal</button> | ||
<PopPop position="centerCenter" | ||
open={show} | ||
closeBtn={true} | ||
closeOnEsc={true} | ||
onClose={() => this.toggleShow(false)} | ||
closeOnOverlay={true}> | ||
<h1>title</h1> | ||
<p> | ||
content | ||
</p> | ||
</PopPop> | ||
</div> | ||
) | ||
} | ||
} | ||
``` | ||
## Props | ||
`* means required` | ||
<table> | ||
<thead> | ||
<tr> | ||
<th>Props</th> | ||
<th>Type</th> | ||
<th>Default</th> | ||
<th>Description</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td>open <b>*</b></td> | ||
<td><code>bool</code></td> | ||
<td></td> | ||
<td>Open the modal or not</td> | ||
</tr> | ||
<tr> | ||
<td>closeBtn</td> | ||
<td><code>bool</code></td> | ||
<td>false</td> | ||
<td>Whether to show close button</td> | ||
</tr> | ||
<tr> | ||
<td>closeOnOverlay</td> | ||
<td><code>bool</code></td> | ||
<td>true</td> | ||
<td>Whether to close modal on click overlay area</td> | ||
</tr> | ||
<tr> | ||
<td>closeOnEsc</td> | ||
<td><code>bool</code></td> | ||
<td>false</td> | ||
<td>Whether to close modal when click `esc`</td> | ||
</tr> | ||
<tr> | ||
<td>onClose</td> | ||
<td><code>function</code></td> | ||
<td></td> | ||
<td> | ||
close modal callback | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>position</td> | ||
<td> | ||
<code>topLeft</code><br/> | ||
<code>topCenter</code><br/> | ||
<code>topRight</code><br/> | ||
<code>centerLeft</code><br/> | ||
<code>centerCenter</code><br/> | ||
<code>centerRight</code><br/> | ||
<code>bottomLeft</code><br/> | ||
<code>bottomCenter</code><br/> | ||
<code>bottomRight</code> | ||
</td> | ||
<td>topCenter</td> | ||
<td> | ||
Modal position | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>overlayStyle</td> | ||
<td> | ||
<code>object</code> | ||
</td> | ||
<td> | ||
reference: <a href="https://github.com/ctxhou/react-poppop/blob/master/src/style.js#L17-L25">link</a> | ||
</td> | ||
<td> | ||
customize overlay style | ||
</td> | ||
</tr> | ||
<tr> | ||
<td>contentStyle</td> | ||
<td><code>object</code></td> | ||
<td>reference: <a href="https://github.com/ctxhou/react-poppop/blob/master/src/style.js#L48-L58">link</a></td> | ||
<td>customize content style</td> | ||
</tr> | ||
</tbody> | ||
</table> | ||
## License | ||
MIT | ||
MIT [@ctxhou](https://github.com/ctxhou) |
@@ -1,3 +0,3 @@ | ||
import PopPop from "./poppop"; | ||
import PopPop from './poppop'; | ||
export default PopPop; |
import React, {Component} from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import Tappable from 'react-tappable/lib/Tappable'; | ||
import {Transition} from 'react-transition-group'; | ||
import Portal from './portal'; | ||
import {extractCamelCase} from './utils'; | ||
import styles from './style'; | ||
import STYLE from './style'; | ||
export default class PopPop extends Component { | ||
constructor(props) { | ||
super(props); | ||
this.handleOverlayClick = this.handleOverlayClick.bind(this); | ||
this.handleCloseBtn = this.handleCloseBtn.bind(this); | ||
this.handleEscKeyDown = this.handleEscKeyDown.bind(this); | ||
} | ||
static defaultProps = { | ||
position: 'topCenter', | ||
closeOnOverlay: true, | ||
overlayStyle: {} | ||
}; | ||
static propTypes = { | ||
open: PropTypes.bool, | ||
closeBtn: PropTypes.bool, | ||
closeOnOverlay: PropTypes.bool, | ||
closeOnEsc: PropTypes.bool, | ||
onClose: PropTypes.func, | ||
overlayStyle: PropTypes.object, | ||
contentStyle: PropTypes.object, | ||
position: PropTypes.oneOf([ | ||
'topLeft', 'topCenter', 'topRight', | ||
'centerLeft', 'centerCenter', 'centerRight', | ||
'bottomLeft', 'bottomCenter', 'bottomRight', | ||
]) | ||
} | ||
componentDidMount() { | ||
document.addEventListener('keydown', this.handleEscKeyDown); | ||
if (this.props.closeOnEsc) { | ||
document.addEventListener('keydown', this.handleEscKeyDown); | ||
} | ||
} | ||
componentWillUnmount() { | ||
document.removeEventListener('keydown', this.handleEscKeyDown); | ||
if (this.props.closeOnEsc) { | ||
document.removeEventListener('keydown', this.handleEscKeyDown); | ||
} | ||
} | ||
handleOverlayClick() { | ||
const { | ||
overlayClick | ||
} = this.props; | ||
if (overlayClick) { | ||
this.props.overlayClick(); | ||
handleOverlayClick = () => { | ||
if (this.props.closeOnOverlay) { | ||
this.props.onClose(); | ||
} | ||
} | ||
handleCloseBtn() { | ||
if (this.props.onClose) | ||
handleCloseBtn = () => { | ||
if (this.props.onClose) { | ||
this.props.onClose(); | ||
} | ||
} | ||
handleEscKeyDown(e) { | ||
handleEscKeyDown = (e) => { | ||
if (this.props.closeOnEsc && e.keyCode === 27) { | ||
@@ -43,26 +66,40 @@ this.props.onClose(); | ||
render() { | ||
const {position} = this.props; | ||
const _contentStyle = this.props.contentStyle; | ||
let wrapperStyle, | ||
contentStyle; | ||
const {open, position, overlayStyle, contentStyle} = this.props; | ||
const extractPosition = extractCamelCase(position); | ||
const mergeWrapperStyle = { | ||
...styles.wrapper, | ||
...styles.alignItems[extractPosition[0]], | ||
...styles.justifyContent[extractPosition[1]] | ||
} | ||
if (position !== 'full') | ||
wrapperStyle = Object.assign({}, STYLE.wrapper, STYLE[position]); | ||
else if (position) | ||
wrapperStyle = Object.assign({}, STYLE.wrapper); | ||
const mergeOverlayStyle = { | ||
...styles.overlay, | ||
...overlayStyle | ||
} | ||
// merge the content style and position style | ||
if (position === 'full') | ||
contentStyle = Object.assign({}, STYLE.content, STYLE.full, _contentStyle); | ||
else if (position === 'center') | ||
contentStyle = Object.assign({}, STYLE.content, STYLE.centerContent, _contentStyle); // console.log(contentStyle) | ||
const mergeContentStyle = { | ||
...styles.content, | ||
...contentStyle | ||
} | ||
if (!open) return null; | ||
return ( | ||
<div style={wrapperStyle}> | ||
{this._renderOverlay()} | ||
<div style={contentStyle}> | ||
{this._renderCloseBtn()} | ||
{this.props.children} | ||
</div> | ||
</div> | ||
<Portal> | ||
<Transition in={open} appear timeout={0}> | ||
{state => { | ||
return <div style={{ | ||
...mergeWrapperStyle, | ||
...styles.transitionStyles[state] | ||
}}> | ||
<Tappable onTap={this.handleOverlayClick} | ||
style={mergeOverlayStyle}/> | ||
<div style={mergeContentStyle}> | ||
{this._renderCloseBtn()} | ||
{this.props.children} | ||
</div> | ||
</div> | ||
}} | ||
</Transition> | ||
</Portal> | ||
) | ||
@@ -72,25 +109,13 @@ } | ||
_renderCloseBtn() { | ||
const {closeBtn, position} = this.props; | ||
let style = STYLE.closeBtn; | ||
if (position === 'full') | ||
style = Object.assign({}, STYLE.closeBtn, STYLE.fullCloseBtn); | ||
if (closeBtn) { | ||
if (this.props.closeBtn) { | ||
return ( | ||
<div style={style} onClick={this.handleCloseBtn}>✖</div> | ||
) | ||
<div style={styles.closeBtn} onClick={this.handleCloseBtn}> | ||
<svg viewBox="0 0 40 40"> | ||
<g><path d="m31.6 10.7l-9.3 9.3 9.3 9.3-2.3 2.3-9.3-9.3-9.3 9.3-2.3-2.3 9.3-9.3-9.3-9.3 2.3-2.3 9.3 9.3 9.3-9.3z"/></g> | ||
</svg> | ||
</div> | ||
); | ||
} | ||
return; | ||
return null; | ||
} | ||
_renderOverlay() { | ||
const {overlay} = this.props; | ||
const overlayStyle = Object.assign(STYLE.overlay, {display: 'block'}); | ||
if (overlay) { | ||
return ( | ||
<div style={overlayStyle} onClick={this.handleOverlayClick}></div> | ||
) | ||
} | ||
return ; | ||
} | ||
} |
103
src/style.js
@@ -1,18 +0,48 @@ | ||
module.exports = { | ||
export default { | ||
wrapper: { | ||
opacity: '1', | ||
transition: 'opacity .2s linear', | ||
opacity: 0, | ||
visibility: 'visible', | ||
position: 'fixed', | ||
overflow: 'auto', | ||
zIndex: '100001', | ||
transition: 'all 0.3s', | ||
overflowX: 'hidden', | ||
overflowY: 'auto', | ||
zIndex: '1000', | ||
top: '0', | ||
left: '0', | ||
right: '0', | ||
bottom: '0', | ||
display: 'flex', | ||
padding: '20px' | ||
}, | ||
overlay : { | ||
position: 'fixed', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
top: '0px', | ||
left: '0px', | ||
display: 'flex', | ||
alignItems: 'center' | ||
zIndex: 99, | ||
backgroundColor: 'rgba(0,0,0,0.6)' | ||
}, | ||
alignItems: { | ||
Top: { | ||
alignItems: 'flex-start' | ||
}, | ||
Center: { | ||
alignItems: 'center' | ||
}, | ||
Bottom: { | ||
alignItems: 'flex-end' | ||
}, | ||
}, | ||
justifyContent: { | ||
Right: { | ||
justifyContent: 'flex-end' | ||
}, | ||
Left: { | ||
justifyContent: 'flex-start' | ||
}, | ||
Center: { | ||
justifyContent: 'center' | ||
} | ||
}, | ||
content: { | ||
@@ -22,46 +52,11 @@ transition: 'all 0.3s', | ||
borderRadius: '3px', | ||
zIndex: 100, | ||
zIndex: 2000, | ||
position: 'relative', | ||
boxShadow: '0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)', | ||
overflow: 'scroll' | ||
overflow: 'scroll', | ||
maxWidth: '850px', | ||
padding: '10px 20px' | ||
}, | ||
center: { | ||
verticalAlign: 'middle', | ||
justifyContent: 'center', | ||
}, | ||
centerContent: { | ||
maxHeight: '90%' | ||
}, | ||
left_center: { | ||
verticalAlign: 'middle', | ||
justifyContent: 'flex-start' | ||
}, | ||
right_center: { | ||
verticalAlign: 'middle', | ||
justifyContent: 'flex-end' | ||
}, | ||
full: { | ||
width: '100%', | ||
height: '100%' | ||
}, | ||
overlay : { | ||
position: 'fixed', | ||
top: 0, | ||
left: 0, | ||
width: '100%', | ||
height: '100%', | ||
zIndex: 99, | ||
backgroundColor: 'rgba(0,0,0,0.3)' | ||
}, | ||
closeBtn: { | ||
position: 'absolute', | ||
right: '5px', | ||
top: '5px', | ||
float: 'right', | ||
color: '#000', | ||
@@ -77,3 +72,2 @@ textShadow: '0 1px 0 #fff', | ||
}, | ||
fullCloseBtn: { | ||
@@ -83,3 +77,8 @@ right: '0', | ||
borderRadius: '0' | ||
}, | ||
transitionStyles: { | ||
entering: {opacity: 0}, | ||
entered: {opacity: 1}, | ||
exited: {opacity: 0} | ||
} | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
198671
21
3840
234
4
53
23
1
+ Addedreact-tappable@^1.0.2
+ Added@babel/runtime@7.24.5(transitive)
+ Addedcreate-react-class@15.7.0(transitive)
+ Addeddom-helpers@3.4.0(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedprop-types@15.8.1(transitive)
+ Addedreact@16.14.0(transitive)
+ Addedreact-dom@16.14.0(transitive)
+ Addedreact-is@16.13.1(transitive)
+ Addedreact-lifecycles-compat@3.0.4(transitive)
+ Addedreact-tappable@1.0.4(transitive)
+ Addedreact-transition-group@2.9.0(transitive)
+ Addedregenerator-runtime@0.14.1(transitive)
+ Addedscheduler@0.19.1(transitive)
- Removedreact@18.3.1(transitive)
- Removedreact-dom@18.3.1(transitive)
- Removedscheduler@0.23.2(transitive)