react-paper-ripple
Version:
Paper ripple animations inspired by Google Material Design.
731 lines (612 loc) • 25.9 kB
JavaScript
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("react"), require("prop-types"), require("react-motion"));
else if(typeof define === 'function' && define.amd)
define(["react", "prop-types", "react-motion"], factory);
else if(typeof exports === 'object')
exports["ReactPaperRipple"] = factory(require("react"), require("prop-types"), require("react-motion"));
else
root["ReactPaperRipple"] = factory(root["React"], root["PropTypes"], root["ReactMotion"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_8__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "dist/";
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = undefined;
var _PaperRipple = __webpack_require__(1);
var _PaperRipple2 = _interopRequireDefault(_PaperRipple);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = _PaperRipple2.default;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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; }; }();
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 _react = __webpack_require__(2);
var _react2 = _interopRequireDefault(_react);
var _propTypes = __webpack_require__(3);
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactDocumentEvents = __webpack_require__(4);
var _reactDocumentEvents2 = _interopRequireDefault(_reactDocumentEvents);
var _reactMotion = __webpack_require__(8);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var eventTypes = {
mousedown: 'MouseDown',
touchstart: 'touchStart'
};
var waveContainerStyles = {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
overflow: 'hidden'
};
function preventDefault(e) {
e.preventDefault();
}
function Wave(_ref) {
var data = _ref.data,
_ref$style = _ref.style,
scale = _ref$style.scale,
opacity = _ref$style.opacity;
return _react2.default.createElement('div', {
className: 'paper-ripple-wave',
style: _extends({}, data, {
WebkitTransform: 'scale(' + scale + ', ' + scale + ')',
transform: 'scale3d(' + scale + ', ' + scale + ', 1)',
opacity: opacity
})
});
}
var PaperRipple = function (_Component) {
_inherits(PaperRipple, _Component);
function PaperRipple() {
var _ref2;
var _temp, _this, _ret;
_classCallCheck(this, PaperRipple);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref2 = PaperRipple.__proto__ || Object.getPrototypeOf(PaperRipple)).call.apply(_ref2, [this].concat(args))), _this), _this.state = {
waves: []
}, _this._willLeave = function () {
var rmConfig = _this.props.rmConfig;
return {
scale: (0, _reactMotion.spring)(1, rmConfig),
opacity: (0, _reactMotion.spring)(0, rmConfig)
};
}, _this._addWave = function (e) {
if (_this._waveAdded) return;
var _this$props = _this.props,
growRatio = _this$props.growRatio,
center = _this$props.center,
color = _this$props.color,
rmConfig = _this$props.rmConfig;
var key = Date.now().toString();
var waves = [].concat(_toConsumableArray(_this.state.waves));
var rect = _this._parentNode.getBoundingClientRect();
var offsetTop = rect.top + (window ? window.pageYOffset : 0);
var offsetLeft = rect.left + (window ? window.pageXOffset : 0);
var size = Math.max(rect.width, rect.height) * growRatio;
var halfSize = size / 2;
var data = {
width: size,
height: size,
backgroundColor: color,
borderRadius: '100%',
position: 'absolute',
pointerEvents: 'none'
};
_this._waveAdded = true;
_this._currentKey = key;
if (center) {
data.top = rect.height / 2;
data.left = rect.width / 2;
data.marginTop = -halfSize;
data.marginLeft = -halfSize;
} else {
var _ref3 = e.touches && e.touches[0] || e,
pageX = _ref3.pageX,
pageY = _ref3.pageY;
data.top = pageY - offsetTop - halfSize;
data.left = pageX - offsetLeft - halfSize;
}
waves.push({
key: key,
data: data,
style: {
scale: (0, _reactMotion.spring)(1, rmConfig),
opacity: (0, _reactMotion.spring)(1, rmConfig)
}
});
_this.setState({ waves: waves });
}, _this._removeWave = function () {
if (_this._waveAdded) {
_this.setState({
waves: _this.state.waves.filter(function (wave) {
return wave.key !== _this._currentKey;
})
});
_this._waveAdded = false;
}
}, _this._handleEvent = function (e) {
var eventType = eventTypes[e.type];
var propEvent = _this.props['on' + eventType];
_this._addWave(e);
if (typeof propEvent === 'function') {
propEvent(e);
}
}, _this._handleRef = function (node) {
_this._parentNode = node && node.parentNode;
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(PaperRipple, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (this.props.filled) {
this._addWave();
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (!this.props.filled && nextProps.filled) {
this._addWave();
} else if (this.props.filled && !nextProps.filled) {
this._removeWave();
}
}
}, {
key: '_willEnter',
value: function _willEnter() {
return {
scale: 0,
opacity: 1
};
}
}, {
key: 'render',
value: function render() {
var _this2 = this;
var _props = this.props,
center = _props.center,
color = _props.color,
growRatio = _props.growRatio,
opacity = _props.opacity,
filled = _props.filled,
rmConfig = _props.rmConfig,
restProps = _objectWithoutProperties(_props, ['center', 'color', 'growRatio', 'opacity', 'filled', 'rmConfig']);
return _react2.default.createElement(
_reactMotion.TransitionMotion,
{
styles: this.state.waves,
willEnter: this._willEnter,
willLeave: this._willLeave
},
function (interpolatedWaves) {
return _react2.default.createElement(
'div',
_extends({
ref: _this2._handleRef,
className: 'paper-ripple',
style: _extends({}, waveContainerStyles, { opacity: opacity }),
onMouseDown: _this2._handleEvent,
onTouchStart: _this2._handleEvent
}, restProps),
interpolatedWaves.map(function (config) {
return _react2.default.createElement(Wave, config);
}),
_react2.default.createElement(_reactDocumentEvents2.default, {
onMouseup: _this2._removeWave,
onTouchEnd: _this2._removeWave,
onTouchCancel: _this2._removeWave
})
);
}
);
}
}]);
return PaperRipple;
}(_react.Component);
PaperRipple.propTypes = {
center: _propTypes2.default.bool,
color: _propTypes2.default.string,
opacity: _propTypes2.default.number,
growRatio: _propTypes2.default.number,
filled: _propTypes2.default.bool,
rmConfig: _propTypes2.default.objectOf(_propTypes2.default.number)
};
PaperRipple.defaultProps = {
center: false,
color: '#fff',
opacity: 0.25,
growRatio: 2.25,
filled: null,
rmConfig: { stiffness: 100, damping: 20 }
};
exports.default = PaperRipple;
/***/ }),
/* 2 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_2__;
/***/ }),
/* 3 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_3__;
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(5);
/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {
/* WEBPACK VAR INJECTION */(function(process) {'use strict';
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; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var React = __webpack_require__(2);
var PropTypes = __webpack_require__(3);
var NODE_ENV = process.env.NODE_ENV;
var EventKeys = {};
if (NODE_ENV !== 'production') {
// Gated behind flag so bundlers can strip the import
EventKeys = __webpack_require__(7); // arrays of event names
}
var DocumentEvents = function (_React$Component) {
_inherits(DocumentEvents, _React$Component);
function DocumentEvents() {
_classCallCheck(this, DocumentEvents);
return _possibleConstructorReturn(this, (DocumentEvents.__proto__ || Object.getPrototypeOf(DocumentEvents)).apply(this, arguments));
}
_createClass(DocumentEvents, [{
key: 'componentDidMount',
// propTypes are generated below from all possible events
value: function componentDidMount() {
if (this.props.enabled) this.bindHandlers();
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.unbindHandlers();
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
if (this.props.enabled && !nextProps.enabled) {
this.unbindHandlers();
} else if (!this.props.enabled && nextProps.enabled) {
this.bindHandlers();
}
}
}, {
key: 'getKeys',
value: function getKeys() {
var isWindow = this.props.target === window;
return Object.keys(this.props).filter(function (k) {
return k.slice(0, 2) === 'on';
}).map(function (k) {
if (NODE_ENV !== 'production' && EventKeys.windowEvents.indexOf(k) !== -1 && !isWindow) {
// eslint-disable-next-line
console.warn("You attached the handler " + k + ", but this handler is only valid on the Window object.");
}
return [k, k.slice(2).toLowerCase()];
});
}
}, {
key: 'bindHandlers',
value: function bindHandlers() {
this._adjustHandlers(on);
}
}, {
key: 'unbindHandlers',
value: function unbindHandlers() {
this._adjustHandlers(off);
}
}, {
key: '_adjustHandlers',
value: function _adjustHandlers(fn) {
var props = this.props;
var target = typeof props.target === 'function' ? props.target() : props.target;
if (!target) return;
// If `passive` is not supported, the third param is `useCapture`, which is a bool - and we won't
// be able to use passive at all. Otherwise, it's safe to use an object.
var options = SUPPORTS_PASSIVE ? { passive: props.passive, capture: props.capture } : props.capture;
this.getKeys().forEach(function (keyArr) {
fn(target, keyArr[1], props[keyArr[0]], options);
});
}
}, {
key: 'render',
value: function render() {
return null;
}
}]);
return DocumentEvents;
}(React.Component);
DocumentEvents.displayName = 'DocumentEvents';
DocumentEvents.defaultProps = {
capture: false,
enabled: true,
passive: false,
target: process.browser ? document : null
};
function on(element, event, callback, options) {
!element.addEventListener && (event = 'on' + event);
(element.addEventListener || element.attachEvent).call(element, event, callback, options);
return callback;
}
function off(element, event, callback, options) {
!element.removeEventListener && (event = 'on' + event);
(element.removeEventListener || element.detachEvent).call(element, event, callback, options);
return callback;
}
var SUPPORTS_PASSIVE = function passiveFeatureTest() {
try {
var support = false;
document.createElement("div").addEventListener("test", function () {}, { get passive() {
support = true;
} });
return support;
} catch (e) {
return false;
}
}();
// Generate and assign propTypes from all possible events
if (NODE_ENV !== 'production') {
var propTypes = EventKeys.allEvents.reduce(function (result, key) {
result[key] = PropTypes.func;
return result;
}, {});
propTypes.enabled = PropTypes.bool;
propTypes.target = PropTypes.oneOfType([PropTypes.object, PropTypes.func]);
propTypes.passive = PropTypes.bool;
propTypes.capture = PropTypes.bool;
DocumentEvents.propTypes = propTypes;
}
module.exports = DocumentEvents;
/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(6)))
/***/ }),
/* 6 */
/***/ (function(module, exports) {
// shim for using process in browser
var process = module.exports = {};
// cached from whatever global is present so that test runners that stub it
// don't break things. But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals. It's inside a
// function because try/catches deoptimize in certain engines.
var cachedSetTimeout;
var cachedClearTimeout;
function defaultSetTimout() {
throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
throw new Error('clearTimeout has not been defined');
}
(function () {
try {
if (typeof setTimeout === 'function') {
cachedSetTimeout = setTimeout;
} else {
cachedSetTimeout = defaultSetTimout;
}
} catch (e) {
cachedSetTimeout = defaultSetTimout;
}
try {
if (typeof clearTimeout === 'function') {
cachedClearTimeout = clearTimeout;
} else {
cachedClearTimeout = defaultClearTimeout;
}
} catch (e) {
cachedClearTimeout = defaultClearTimeout;
}
} ())
function runTimeout(fun) {
if (cachedSetTimeout === setTimeout) {
//normal enviroments in sane situations
return setTimeout(fun, 0);
}
// if setTimeout wasn't available but was latter defined
if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
cachedSetTimeout = setTimeout;
return setTimeout(fun, 0);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedSetTimeout(fun, 0);
} catch(e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedSetTimeout.call(null, fun, 0);
} catch(e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
return cachedSetTimeout.call(this, fun, 0);
}
}
}
function runClearTimeout(marker) {
if (cachedClearTimeout === clearTimeout) {
//normal enviroments in sane situations
return clearTimeout(marker);
}
// if clearTimeout wasn't available but was latter defined
if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
cachedClearTimeout = clearTimeout;
return clearTimeout(marker);
}
try {
// when when somebody has screwed with setTimeout but no I.E. maddness
return cachedClearTimeout(marker);
} catch (e){
try {
// When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
return cachedClearTimeout.call(null, marker);
} catch (e){
// same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
// Some versions of I.E. have different rules for clearTimeout vs setTimeout
return cachedClearTimeout.call(this, marker);
}
}
}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;
function cleanUpNextTick() {
if (!draining || !currentQueue) {
return;
}
draining = false;
if (currentQueue.length) {
queue = currentQueue.concat(queue);
} else {
queueIndex = -1;
}
if (queue.length) {
drainQueue();
}
}
function drainQueue() {
if (draining) {
return;
}
var timeout = runTimeout(cleanUpNextTick);
draining = true;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
while (++queueIndex < len) {
if (currentQueue) {
currentQueue[queueIndex].run();
}
}
queueIndex = -1;
len = queue.length;
}
currentQueue = null;
draining = false;
runClearTimeout(timeout);
}
process.nextTick = function (fun) {
var args = new Array(arguments.length - 1);
if (arguments.length > 1) {
for (var i = 1; i < arguments.length; i++) {
args[i - 1] = arguments[i];
}
}
queue.push(new Item(fun, args));
if (queue.length === 1 && !draining) {
runTimeout(drainQueue);
}
};
// v8 likes predictible objects
function Item(fun, array) {
this.fun = fun;
this.array = array;
}
Item.prototype.run = function () {
this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;
process.listeners = function (name) { return [] }
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
/***/ }),
/* 7 */
/***/ (function(module, exports) {
'use strict';
// Generated from:
// var SimpleEventPlugin = require('react/lib/SimpleEventPlugin')
// Object.keys(SimpleEventPlugin.eventTypes).map(function(key) { return 'on' + key[0].toUpperCase() + key.slice(1); });
var reactEvents = ['onAbort', 'onAnimationEnd', 'onAnimationIteration', 'onAnimationStart', 'onBlur', 'onCanPlay', 'onCanPlayThrough', 'onClick', 'onContextMenu', 'onCopy', 'onCut', 'onDoubleClick', 'onDrag', 'onDragEnd', 'onDragEnter', 'onDragExit', 'onDragLeave', 'onDragOver', 'onDragStart', 'onDrop', 'onDurationChange', 'onEmptied', 'onEncrypted', 'onEnded', 'onError', 'onFocus', 'onInput', 'onInvalid', 'onKeyDown', 'onKeyPress', 'onKeyUp', 'onLoad', 'onLoadedData', 'onLoadedMetadata', 'onLoadStart', 'onMouseDown', 'onMouseMove', 'onMouseOut', 'onMouseOver', 'onMouseUp', 'onPaste', 'onPause', 'onPlay', 'onPlaying', 'onProgress', 'onRateChange', 'onReset', 'onScroll', 'onSeeked', 'onSeeking', 'onStalled', 'onSubmit', 'onSuspend', 'onTimeUpdate', 'onTouchCancel', 'onTouchEnd', 'onTouchMove', 'onTouchStart', 'onTransitionEnd', 'onVolumeChange', 'onWaiting', 'onWheel'];
// Events that are specific to the window and aren't in the list above
// Added addl events from https://developer.mozilla.org/en-US/docs/Web/API/Window
var windowEvents = ['onAfterPrint', 'onBeforePrint', 'onBeforeUnload', 'onDeviceLight', 'onDeviceMotion', 'onDeviceOrientation', 'onDeviceProximity', 'onHashChange', 'onLanguageChange', 'onPopState', 'onRejectionHandled', // promises
'onResize', 'onSelect', // catches select events bubbling up
'onStorage', 'onUnhandledRejection', // promises
'onUnload', 'onUserProximity'];
// Addl document/window APIs
var extraEvents = [
// IE/FF pointer events spec
'onPointerCancel', 'onPointerDown', 'onPointerEnter', 'onPointerLeave', 'onPointerMove', 'onPointerOut', 'onPointerOver', 'onPointerUp'];
module.exports = {
allEvents: reactEvents.concat(windowEvents).concat(extraEvents),
documentEvents: reactEvents.concat(extraEvents),
windowEvents: windowEvents
};
/***/ }),
/* 8 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_8__;
/***/ })
/******/ ])
});
;