Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-measure

Package Overview
Dependencies
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-measure - npm Package Compare versions

Comparing version 0.3.5 to 0.4.0

lib/get-clone-dimensions.js

7

bower.json
{
"name": "react-measure",
"version": "0.3.5",
"version": "0.4.0",
"homepage": "https://github.com/souporserious/react-measure",

@@ -15,3 +15,6 @@ "authors": [

"measurements",
"dimensions"
"dimensions",
"element-queries",
"container-queries",
"size"
],

@@ -18,0 +21,0 @@ "license": "MIT",

## CHANGELOG
### 0.4.0
Moved away from MutationObserver's in favor of [element-resize-detector](https://github.com/wnr/element-resize-detector)
Added a more convenient API by allowing child functions [#11](https://github.com/souporserious/react-measure/issues/11)
`measure` is now a public method available on the Measure component
`accurate` prop now returns both cloned element width and height
`shouldMeasure` now accepts only a boolean
Removed `lodash.debounce` dependency
### 0.3.5

@@ -3,0 +18,0 @@

(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("React"), require("ReactDOM"));
module.exports = factory(require("React"), require("ReactDOM"), require("createResizeDetector"));
else if(typeof define === 'function' && define.amd)
define(["React", "ReactDOM"], factory);
define(["React", "ReactDOM", "createResizeDetector"], factory);
else if(typeof exports === 'object')
exports["Measure"] = factory(require("React"), require("ReactDOM"));
exports["Measure"] = factory(require("React"), require("ReactDOM"), require("createResizeDetector"));
else
root["Measure"] = factory(root["React"], root["ReactDOM"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) {
root["Measure"] = factory(root["React"], root["ReactDOM"], root["createResizeDetector"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__, __WEBPACK_EXTERNAL_MODULE_5__) {
return /******/ (function(modules) { // webpackBootstrap

@@ -84,3 +84,3 @@ /******/ // The module cache

var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

@@ -101,16 +101,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _ResizeHandler = __webpack_require__(4);
var _resizeDetector = __webpack_require__(4);
var _ResizeHandler2 = _interopRequireDefault(_ResizeHandler);
var _resizeDetector2 = _interopRequireDefault(_resizeDetector);
var _diffConfig = __webpack_require__(7);
var _getNodeDimensions = __webpack_require__(6);
var _diffConfig2 = _interopRequireDefault(_diffConfig);
var _getNodeDimensions = __webpack_require__(8);
var _getNodeDimensions2 = _interopRequireDefault(_getNodeDimensions);
var resizeHandler = new _ResizeHandler2['default']();
var Measure = (function (_Component) {

@@ -126,23 +120,29 @@ _inherits(Measure, _Component);

this._observer = null;
this.state = {
dimensions: {}
};
this._node = null;
this._properties = this._getProperties(this.props);
this._propsToMeasure = this._getPropsToMeasure(this.props);
this._lastDimensions = {};
this._measure = function (mutations) {
var shouldMeasure = _this.props.shouldMeasure(mutations);
this.measure = function () {
var accurate = arguments.length <= 0 || arguments[0] === undefined ? _this.props.accurate : arguments[0];
// bail out if we shouldn't measure
if (!shouldMeasure) return;
if (!_this.props.shouldMeasure) return;
var dimensions = _this.getDimensions(_this._node, _this.props.accurate);
var dimensions = _this.getDimensions(_this._node, accurate);
var isChildFunction = typeof _this.props.children === 'function';
// determine if we need to update our callback with new dimensions or not
_this._properties.some(function (prop) {
_this._propsToMeasure.some(function (prop) {
if (dimensions[prop] !== _this._lastDimensions[prop]) {
// if we've found a dimension that has changed, update our callback
// we also allow shouldMeasure to return any values so the end user
// doesn't have to recalculate anything
_this.props.onMeasure(dimensions, mutations, shouldMeasure);
// update our callback if we've found a dimension that has changed
_this.props.onMeasure(dimensions);
// update state to send dimensions to child function
if (isChildFunction) {
_this.setState({ dimensions: dimensions });
}
// store last dimensions to compare changes

@@ -161,12 +161,13 @@ _this._lastDimensions = dimensions;

value: function componentDidMount() {
var _this2 = this;
this._node = _reactDom2['default'].findDOMNode(this);
// set up mutation observer
this._connectObserver(this.props.config);
// measure on first render
this._measure(null);
this.measure();
// add component to resize handler to detect changes on resize
resizeHandler.add(this);
// add component to resize detector to detect changes on resize
(0, _resizeDetector2['default'])().listenTo(this._node, function () {
return _this2.measure();
});
}

@@ -180,12 +181,6 @@ }, {

// disconnect the old observer and reconnect with new config if changed
if ((0, _diffConfig2['default'])(this.props.config, config)) {
this._disconnectObserver();
this._connectObserver(config);
}
// we store the properties ourselves so we need to update them if the
// whitelist or blacklist props have changed
if (this.props.whitelist !== whitelist || this.props.blacklist !== blacklist) {
this._properties = this._getProperties({ whitelist: whitelist, blacklist: blacklist });
this._propsToMeasure = this._getPropsToMeasure({ whitelist: whitelist, blacklist: blacklist });
}

@@ -196,4 +191,3 @@ }

value: function componentWillUnmount() {
this._disconnectObserver();
resizeHandler.remove(this);
(0, _resizeDetector2['default'])().removeAllListeners(this._node);
}

@@ -209,15 +203,4 @@ }, {

}, {
key: '_connectObserver',
value: function _connectObserver(config) {
this._observer = new MutationObserver(this._measure);
this._observer.observe(this._node, config);
}
}, {
key: '_disconnectObserver',
value: function _disconnectObserver() {
this._observer.disconnect();
}
}, {
key: '_getProperties',
value: function _getProperties(_ref2) {
key: '_getPropsToMeasure',
value: function _getPropsToMeasure(_ref2) {
var whitelist = _ref2.whitelist;

@@ -233,3 +216,5 @@ var blacklist = _ref2.blacklist;

value: function render() {
return _react.Children.only(this.props.children);
var children = this.props.children;
return _react.Children.only(typeof children === 'function' ? children(this.state.dimensions) : children);
}

@@ -239,7 +224,6 @@ }], [{

value: {
config: _react.PropTypes.object,
accurate: _react.PropTypes.bool,
whitelist: _react.PropTypes.array,
blacklist: _react.PropTypes.array,
shouldMeasure: _react.PropTypes.func,
shouldMeasure: _react.PropTypes.bool,
onMeasure: _react.PropTypes.func

@@ -251,12 +235,6 @@ },

value: {
config: {
childList: true,
attributes: true
},
accurate: false,
whitelist: ['width', 'height', 'top', 'right', 'bottom', 'left'],
blacklist: [],
shouldMeasure: function shouldMeasure() {
return true;
},
shouldMeasure: true,
onMeasure: function onMeasure() {

@@ -296,57 +274,21 @@ return null;

});
exports['default'] = resizeDetector;
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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var _elementResizeDetector = __webpack_require__(5);
var _lodashDebounce = __webpack_require__(5);
var _elementResizeDetector2 = _interopRequireDefault(_elementResizeDetector);
var _lodashDebounce2 = _interopRequireDefault(_lodashDebounce);
var instance = null;
var ResizeHandler = (function () {
function ResizeHandler() {
_classCallCheck(this, ResizeHandler);
this._queue = [];
this.update = (0, _lodashDebounce2['default'])(this.update.bind(this), 150);
if (typeof window !== 'undefined') {
window.addEventListener('resize', this.update);
}
function resizeDetector() {
if (!instance) {
instance = (0, _elementResizeDetector2['default'])({
strategy: 'scroll'
});
}
return instance;
}
_createClass(ResizeHandler, [{
key: 'destroy',
value: function destroy() {
if (typeof window !== 'undefined') {
window.removeEventListener('resize', this.update);
}
}
}, {
key: 'add',
value: function add(component) {
this._queue.push(component);
}
}, {
key: 'remove',
value: function remove(component) {
var pos = this._queue.indexOf(component);
if (pos > -1) {
this._queue.splice(pos, 1);
}
}
}, {
key: 'update',
value: function update() {
for (var i = this._queue.length; i--;) {
this._queue[i]._measure();
}
}
}]);
return ResizeHandler;
})();
exports['default'] = ResizeHandler;
module.exports = exports['default'];

@@ -356,419 +298,8 @@

/* 5 */
/***/ function(module, exports, __webpack_require__) {
/***/ function(module, exports) {
/**
* lodash 3.1.1 (Custom Build) <https://lodash.com/>
* Build: `lodash modern modularize exports="npm" -o ./`
* Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
* Available under MIT license <https://lodash.com/license>
*/
'use strict';
module.exports = __WEBPACK_EXTERNAL_MODULE_5__;
var getNative = __webpack_require__(6);
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/* Native method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
nativeNow = getNative(Date, 'now');
/**
* Gets the number of milliseconds that have elapsed since the Unix epoch
* (1 January 1970 00:00:00 UTC).
*
* @static
* @memberOf _
* @category Date
* @example
*
* _.defer(function(stamp) {
* console.log(_.now() - stamp);
* }, _.now());
* // => logs the number of milliseconds it took for the deferred function to be invoked
*/
var now = nativeNow || function () {
return new Date().getTime();
};
/**
* Creates a debounced function that delays invoking `func` until after `wait`
* milliseconds have elapsed since the last time the debounced function was
* invoked. The debounced function comes with a `cancel` method to cancel
* delayed invocations. Provide an options object to indicate that `func`
* should be invoked on the leading and/or trailing edge of the `wait` timeout.
* Subsequent calls to the debounced function return the result of the last
* `func` invocation.
*
* **Note:** If `leading` and `trailing` options are `true`, `func` is invoked
* on the trailing edge of the timeout only if the the debounced function is
* invoked more than once during the `wait` timeout.
*
* See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)
* for details over the differences between `_.debounce` and `_.throttle`.
*
* @static
* @memberOf _
* @category Function
* @param {Function} func The function to debounce.
* @param {number} [wait=0] The number of milliseconds to delay.
* @param {Object} [options] The options object.
* @param {boolean} [options.leading=false] Specify invoking on the leading
* edge of the timeout.
* @param {number} [options.maxWait] The maximum time `func` is allowed to be
* delayed before it is invoked.
* @param {boolean} [options.trailing=true] Specify invoking on the trailing
* edge of the timeout.
* @returns {Function} Returns the new debounced function.
* @example
*
* // avoid costly calculations while the window size is in flux
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
*
* // invoke `sendMail` when the click event is fired, debouncing subsequent calls
* jQuery('#postbox').on('click', _.debounce(sendMail, 300, {
* 'leading': true,
* 'trailing': false
* }));
*
* // ensure `batchLog` is invoked once after 1 second of debounced calls
* var source = new EventSource('/stream');
* jQuery(source).on('message', _.debounce(batchLog, 250, {
* 'maxWait': 1000
* }));
*
* // cancel a debounced call
* var todoChanges = _.debounce(batchLog, 1000);
* Object.observe(models.todo, todoChanges);
*
* Object.observe(models, function(changes) {
* if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) {
* todoChanges.cancel();
* }
* }, ['delete']);
*
* // ...at some point `models.todo` is changed
* models.todo.completed = true;
*
* // ...before 1 second has passed `models.todo` is deleted
* // which cancels the debounced `todoChanges` call
* delete models.todo;
*/
function debounce(func, wait, options) {
var args,
maxTimeoutId,
result,
stamp,
thisArg,
timeoutId,
trailingCall,
lastCalled = 0,
maxWait = false,
trailing = true;
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
wait = wait < 0 ? 0 : +wait || 0;
if (options === true) {
var leading = true;
trailing = false;
} else if (isObject(options)) {
leading = !!options.leading;
maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait);
trailing = 'trailing' in options ? !!options.trailing : trailing;
}
function cancel() {
if (timeoutId) {
clearTimeout(timeoutId);
}
if (maxTimeoutId) {
clearTimeout(maxTimeoutId);
}
lastCalled = 0;
maxTimeoutId = timeoutId = trailingCall = undefined;
}
function complete(isCalled, id) {
if (id) {
clearTimeout(id);
}
maxTimeoutId = timeoutId = trailingCall = undefined;
if (isCalled) {
lastCalled = now();
result = func.apply(thisArg, args);
if (!timeoutId && !maxTimeoutId) {
args = thisArg = undefined;
}
}
}
function delayed() {
var remaining = wait - (now() - stamp);
if (remaining <= 0 || remaining > wait) {
complete(trailingCall, maxTimeoutId);
} else {
timeoutId = setTimeout(delayed, remaining);
}
}
function maxDelayed() {
complete(trailing, timeoutId);
}
function debounced() {
args = arguments;
stamp = now();
thisArg = this;
trailingCall = trailing && (timeoutId || !leading);
if (maxWait === false) {
var leadingCall = leading && !timeoutId;
} else {
if (!maxTimeoutId && !leading) {
lastCalled = stamp;
}
var remaining = maxWait - (stamp - lastCalled),
isCalled = remaining <= 0 || remaining > maxWait;
if (isCalled) {
if (maxTimeoutId) {
maxTimeoutId = clearTimeout(maxTimeoutId);
}
lastCalled = stamp;
result = func.apply(thisArg, args);
} else if (!maxTimeoutId) {
maxTimeoutId = setTimeout(maxDelayed, remaining);
}
}
if (isCalled && timeoutId) {
timeoutId = clearTimeout(timeoutId);
} else if (!timeoutId && wait !== maxWait) {
timeoutId = setTimeout(delayed, wait);
}
if (leadingCall) {
isCalled = true;
result = func.apply(thisArg, args);
}
if (isCalled && !timeoutId && !maxTimeoutId) {
args = thisArg = undefined;
}
return result;
}
debounced.cancel = cancel;
return debounced;
}
/**
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(1);
* // => false
*/
function isObject(value) {
// Avoid a V8 JIT bug in Chrome 19-20.
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
module.exports = debounce;
/***/ },
/* 6 */
/***/ function(module, exports) {
/**
* lodash 3.9.1 (Custom Build) <https://lodash.com/>
* Build: `lodash modern modularize exports="npm" -o ./`
* Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
* Available under MIT license <https://lodash.com/license>
*/
/** `Object#toString` result references. */
'use strict';
var funcTag = '[object Function]';
/** Used to detect host constructors (Safari > 5). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;
/**
* Checks if `value` is object-like.
*
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
*/
function isObjectLike(value) {
return !!value && typeof value == 'object';
}
/** Used for native method references. */
var objectProto = Object.prototype;
/** Used to resolve the decompiled source of functions. */
var fnToString = Function.prototype.toString;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
* Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
* of values.
*/
var objToString = objectProto.toString;
/** Used to detect if a method is native. */
var reIsNative = RegExp('^' + fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');
/**
* Gets the native function at `key` of `object`.
*
* @private
* @param {Object} object The object to query.
* @param {string} key The key of the method to get.
* @returns {*} Returns the function if it's native, else `undefined`.
*/
function getNative(object, key) {
var value = object == null ? undefined : object[key];
return isNative(value) ? value : undefined;
}
/**
* Checks if `value` is classified as a `Function` object.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
* @example
*
* _.isFunction(_);
* // => true
*
* _.isFunction(/abc/);
* // => false
*/
function isFunction(value) {
// The use of `Object#toString` avoids issues with the `typeof` operator
// in older versions of Chrome and Safari which return 'function' for regexes
// and Safari 8 equivalents which return 'object' for typed array constructors.
return isObject(value) && objToString.call(value) == funcTag;
}
/**
* Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
* (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
* @example
*
* _.isObject({});
* // => true
*
* _.isObject([1, 2, 3]);
* // => true
*
* _.isObject(1);
* // => false
*/
function isObject(value) {
// Avoid a V8 JIT bug in Chrome 19-20.
// See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
var type = typeof value;
return !!value && (type == 'object' || type == 'function');
}
/**
* Checks if `value` is a native function.
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a native function, else `false`.
* @example
*
* _.isNative(Array.prototype.push);
* // => true
*
* _.isNative(_);
* // => false
*/
function isNative(value) {
if (value == null) {
return false;
}
if (isFunction(value)) {
return reIsNative.test(fnToString.call(value));
}
return isObjectLike(value) && reIsHostCtor.test(value);
}
module.exports = getNative;
/***/ },
/* 7 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = diffConfig;
var CONFIG_SHAPE = ['childList', 'attributes', 'characterData', 'subtree', 'attributeOldValue', 'characterDataOldValue', 'attributeFilter'];
function diffConfig(prev, next) {
for (var i = 7; i--;) {
var config = CONFIG_SHAPE[i];
var prevConfig = prev[config];
var nextConfig = next[config];
// if equal continue to the next
if (prevConfig === nextConfig) {
continue;
}
var prevUndefined = typeof prevConfig === 'undefined';
var nextUndefined = typeof nextConfig === 'undefined';
// if attributeFilter, we know it needs to be a simple array,
// so comparing lengths should be enough to know if it has changed
if (prevUndefined && !nextUndefined || !prevUndefined && nextUndefined || config === 'attributeFilter' && prevConfig.length !== nextConfig.length) {
return true;
}
}
return false;
}
module.exports = exports['default'];
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {

@@ -785,5 +316,5 @@

var _accurateHeight = __webpack_require__(9);
var _getCloneDimensions = __webpack_require__(7);
var _accurateHeight2 = _interopRequireDefault(_accurateHeight);
var _getCloneDimensions2 = _interopRequireDefault(_getCloneDimensions);

@@ -794,6 +325,14 @@ function getNodeDimensions(node) {

var rect = node.getBoundingClientRect();
var width = rect.width;
var height = rect.height;
if (accurate) {
var cloneDimensions = (0, _getCloneDimensions2['default'])(node);
width = cloneDimensions.width;
height = cloneDimensions.height;
}
return {
width: rect.width,
height: accurate ? (0, _accurateHeight2['default'])(node) : rect.height,
width: width,
height: height,
top: rect.top,

@@ -809,60 +348,5 @@ right: rect.right,

/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = accurateHeight;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _dataStore = __webpack_require__(10);
var _dataStore2 = _interopRequireDefault(_dataStore);
var _getCloneHeight = __webpack_require__(11);
var _getCloneHeight2 = _interopRequireDefault(_getCloneHeight);
function getStyle(node) {
return (0, _dataStore2['default'])(node, 'style') || (0, _dataStore2['default'])(node, 'style', getComputedStyle(node));
}
// inspired by http://stackoverflow.com/a/8235013/1461204
function accurateHeight(node) {
var children = node.children;
// if no children present on the node or an SVG element
// we need to clone it to get a true height
if (!children || children && children.length === 0 || node instanceof SVGElement) {
return (0, _getCloneHeight2['default'])(node);
}
var firstChild = children[0];
var lastChild = children[children.length - 1];
var _getStyle = getStyle(firstChild);
var marginTop = _getStyle.marginTop;
var _getStyle2 = getStyle(lastChild);
var marginBottom = _getStyle2.marginBottom;
var offsetDiff = lastChild.offsetTop - firstChild.offsetTop;
return parseInt(marginTop) + (offsetDiff + lastChild.offsetHeight) + parseInt(marginBottom);
}
module.exports = exports['default'];
/***/ },
/* 10 */
/* 7 */
/***/ function(module, exports) {
// inspired by https://github.com/julianshapiro/velocity/blob/master/velocity.js
'use strict';

@@ -873,43 +357,5 @@

});
exports['default'] = dataStore;
var expando = 'react-measure' + new Date().getTime();
var cache = {};
var uuid = 0;
exports['default'] = getCloneDimensions;
function dataStore(node, key, value) {
if (value === undefined) {
var id = node[expando];
var store = id && cache[id];
if (key === undefined) {
return store;
} else if (store) {
if (key in store) {
return store[key];
}
}
} else if (key !== undefined) {
var id = node[expando] || (node[expando] = ++uuid);
cache[id] = cache[id] || {};
cache[id][key] = value;
return value;
}
}
module.exports = exports['default'];
/***/ },
/* 11 */
/***/ function(module, exports) {
'use strict';
Object.defineProperty(exports, '__esModule', {
value: true
});
exports['default'] = getCloneHeight;
function getCloneHeight(node) {
function getCloneDimensions(node) {
var parentNode = node.parentNode;

@@ -919,2 +365,3 @@

var clone = node.cloneNode(true);
var width = 0;
var height = 0;

@@ -931,6 +378,4 @@

clone.setAttribute('name', '');
clone.setAttribute('data-reactid', '');
// set props to hide copy and get a true height calculation
clone.style.boxSizing = 'border-box';
clone.style.height = 'auto';

@@ -946,3 +391,4 @@ clone.style.position = 'absolute';

// get height
// get accurate width and height
width = clone.scrollWidth;
height = clone.scrollHeight;

@@ -953,3 +399,3 @@

return height;
return { width: width, height: height };
}

@@ -956,0 +402,0 @@

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

!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("React"),require("ReactDOM")):"function"==typeof define&&define.amd?define(["React","ReactDOM"],t):"object"==typeof exports?exports.Measure=t(require("React"),require("ReactDOM")):e.Measure=t(e.React,e.ReactDOM)}(this,function(e,t){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="dist/",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var o=n(1),i=r(o);t["default"]=i["default"],e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),a=function(e,t,n){for(var r=!0;r;){var o=e,i=t,u=n;a=l=s=void 0,r=!1,null===o&&(o=Function.prototype);var a=Object.getOwnPropertyDescriptor(o,i);if(void 0!==a){if("value"in a)return a.value;var s=a.get;return void 0===s?void 0:s.call(u)}var l=Object.getPrototypeOf(o);if(null===l)return void 0;e=l,t=i,n=u,r=!0}},s=n(2),l=(r(s),n(3)),c=r(l),f=n(4),p=r(f),d=n(7),v=r(d),h=n(8),y=r(h),b=new p["default"],Measure=function(e){function Measure(){var e=this;o(this,Measure),a(Object.getPrototypeOf(Measure.prototype),"constructor",this).apply(this,arguments),this._observer=null,this._node=null,this._properties=this._getProperties(this.props),this._lastDimensions={},this._measure=function(t){var n=e.props.shouldMeasure(t);if(n){var r=e.getDimensions(e._node,e.props.accurate);e._properties.some(function(o){return r[o]!==e._lastDimensions[o]?(e.props.onMeasure(r,t,n),e._lastDimensions=r,!0):void 0})}}}return i(Measure,e),u(Measure,[{key:"componentDidMount",value:function(){this._node=c["default"].findDOMNode(this),this._connectObserver(this.props.config),this._measure(null),b.add(this)}},{key:"componentWillReceiveProps",value:function(e){var t=e.config,n=e.whitelist,r=e.blacklist;v["default"](this.props.config,t)&&(this._disconnectObserver(),this._connectObserver(t)),(this.props.whitelist!==n||this.props.blacklist!==r)&&(this._properties=this._getProperties({whitelist:n,blacklist:r}))}},{key:"componentWillUnmount",value:function(){this._disconnectObserver(),b.remove(this)}},{key:"getDimensions",value:function(){var e=arguments.length<=0||void 0===arguments[0]?this._node:arguments[0],t=arguments.length<=1||void 0===arguments[1]?!0:arguments[1];return y["default"](e,t)}},{key:"_connectObserver",value:function(e){this._observer=new MutationObserver(this._measure),this._observer.observe(this._node,e)}},{key:"_disconnectObserver",value:function(){this._observer.disconnect()}},{key:"_getProperties",value:function(e){var t=e.whitelist,n=e.blacklist;return t.filter(function(e){return n.indexOf(e)<0})}},{key:"render",value:function(){return s.Children.only(this.props.children)}}],[{key:"propTypes",value:{config:s.PropTypes.object,accurate:s.PropTypes.bool,whitelist:s.PropTypes.array,blacklist:s.PropTypes.array,shouldMeasure:s.PropTypes.func,onMeasure:s.PropTypes.func},enumerable:!0},{key:"defaultProps",value:{config:{childList:!0,attributes:!0},accurate:!1,whitelist:["width","height","top","right","bottom","left"],blacklist:[],shouldMeasure:function(){return!0},onMeasure:function(){return null}},enumerable:!0}]),Measure}(s.Component);t["default"]=Measure,e.exports=t["default"]},function(t,n){t.exports=e},function(e,n){e.exports=t},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;n<t.length;n++){var r=t[n];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(e,r.key,r)}}return function(t,n,r){return n&&e(t.prototype,n),r&&e(t,r),t}}(),u=n(5),a=r(u),s=function(){function e(){o(this,e),this._queue=[],this.update=a["default"](this.update.bind(this),150),"undefined"!=typeof window&&window.addEventListener("resize",this.update)}return i(e,[{key:"destroy",value:function(){"undefined"!=typeof window&&window.removeEventListener("resize",this.update)}},{key:"add",value:function(e){this._queue.push(e)}},{key:"remove",value:function(e){var t=this._queue.indexOf(e);t>-1&&this._queue.splice(t,1)}},{key:"update",value:function(){for(var e=this._queue.length;e--;)this._queue[e]._measure()}}]),e}();t["default"]=s,e.exports=t["default"]},function(e,t,n){"use strict";function r(e,t,n){function r(){b&&clearTimeout(b),d&&clearTimeout(d),g=0,d=b=m=void 0}function i(t,n){n&&clearTimeout(n),d=b=m=void 0,t&&(g=l(),v=e.apply(y,p),b||d||(p=y=void 0))}function s(){var e=t-(l()-h);0>=e||e>t?i(m,d):b=setTimeout(s,e)}function c(){i(O,b)}function f(){if(p=arguments,h=l(),y=this,m=O&&(b||!w),_===!1)var n=w&&!b;else{d||w||(g=h);var r=_-(h-g),o=0>=r||r>_;o?(d&&(d=clearTimeout(d)),g=h,v=e.apply(y,p)):d||(d=setTimeout(c,r))}return o&&b?b=clearTimeout(b):b||t===_||(b=setTimeout(s,t)),n&&(o=!0,v=e.apply(y,p)),!o||b||d||(p=y=void 0),v}var p,d,v,h,y,b,m,g=0,_=!1,O=!0;if("function"!=typeof e)throw new TypeError(u);if(t=0>t?0:+t||0,n===!0){var w=!0;O=!1}else o(n)&&(w=!!n.leading,_="maxWait"in n&&a(+n.maxWait||0,t),O="trailing"in n?!!n.trailing:O);return f.cancel=r,f}function o(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var i=n(6),u="Expected a function",a=Math.max,s=i(Date,"now"),l=s||function(){return(new Date).getTime()};e.exports=r},function(e,t){"use strict";function n(e){return!!e&&"object"==typeof e}function r(e,t){var n=null==e?void 0:e[t];return u(n)?n:void 0}function o(e){return i(e)&&p.call(e)==a}function i(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function u(e){return null==e?!1:o(e)?d.test(c.call(e)):n(e)&&s.test(e)}var a="[object Function]",s=/^\[object .+?Constructor\]$/,l=Object.prototype,c=Function.prototype.toString,f=l.hasOwnProperty,p=l.toString,d=RegExp("^"+c.call(f).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=r},function(e,t){"use strict";function n(e,t){for(var n=7;n--;){var o=r[n],i=e[o],u=t[o];if(i!==u){var a="undefined"==typeof i,s="undefined"==typeof u;if(a&&!s||!a&&s||"attributeFilter"===o&&i.length!==u.length)return!0}}return!1}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=n;var r=["childList","attributes","characterData","subtree","attributeOldValue","characterDataOldValue","attributeFilter"];e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e){var t=arguments.length<=1||void 0===arguments[1]?!1:arguments[1],n=e.getBoundingClientRect();return{width:n.width,height:t?u["default"](e):n.height,top:n.top,right:n.right,bottom:n.bottom,left:n.left}}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=o;var i=n(9),u=r(i);e.exports=t["default"]},function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{"default":e}}function o(e){return a["default"](e,"style")||a["default"](e,"style",getComputedStyle(e))}function i(e){var t=e.children;if(!t||t&&0===t.length||e instanceof SVGElement)return l["default"](e);var n=t[0],r=t[t.length-1],i=o(n),u=i.marginTop,a=o(r),s=a.marginBottom,c=r.offsetTop-n.offsetTop;return parseInt(u)+(c+r.offsetHeight)+parseInt(s)}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=i;var u=n(10),a=r(u),s=n(11),l=r(s);e.exports=t["default"]},function(e,t){"use strict";function n(e,t,n){if(void 0===n){var u=e[r],a=u&&o[u];if(void 0===t)return a;if(a&&t in a)return a[t]}else if(void 0!==t){var u=e[r]||(e[r]=++i);return o[u]=o[u]||{},o[u][t]=n,n}}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=n;var r="react-measure"+(new Date).getTime(),o={},i=0;e.exports=t["default"]},function(e,t){"use strict";function n(e){var t=e.parentNode,n=document.createElement("div"),r=e.cloneNode(!0),o=0;return n.style.height=0,n.style.position="relative",n.style.overflow="hidden",r.setAttribute("id",""),r.setAttribute("name",""),r.setAttribute("data-reactid",""),r.style.boxSizing="border-box",r.style.height="auto",r.style.position="absolute",r.style.visibility="hidden",n.appendChild(r),t.appendChild(n),o=r.scrollHeight,t.removeChild(n),o}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=n,e.exports=t["default"]}])});
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("React"),require("ReactDOM"),require("createResizeDetector")):"function"==typeof define&&define.amd?define(["React","ReactDOM","createResizeDetector"],t):"object"==typeof exports?exports.Measure=t(require("React"),require("ReactDOM"),require("createResizeDetector")):e.Measure=t(e.React,e.ReactDOM,e.createResizeDetector)}(this,function(e,t,r){return function(e){function t(o){if(r[o])return r[o].exports;var n=r[o]={exports:{},id:o,loaded:!1};return e[o].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var r={};return t.m=e,t.c=r,t.p="dist/",t(0)}([function(e,t,r){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var n=r(1),i=o(n);t["default"]=i["default"],e.exports=t["default"]},function(e,t,r){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var u=function(){function e(e,t){for(var r=0;r<t.length;r++){var o=t[r];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}}return function(t,r,o){return r&&e(t.prototype,r),o&&e(t,o),t}}(),s=function(e,t,r){for(var o=!0;o;){var n=e,i=t,u=r;s=l=a=void 0,o=!1,null===n&&(n=Function.prototype);var s=Object.getOwnPropertyDescriptor(n,i);if(void 0!==s){if("value"in s)return s.value;var a=s.get;return void 0===a?void 0:a.call(u)}var l=Object.getPrototypeOf(n);if(null===l)return void 0;e=l,t=i,r=u,o=!0}},a=r(2),l=(o(a),r(3)),c=o(l),f=r(4),p=o(f),d=r(6),h=o(d),Measure=function(e){function Measure(){var e=this;n(this,Measure),s(Object.getPrototypeOf(Measure.prototype),"constructor",this).apply(this,arguments),this.state={dimensions:{}},this._node=null,this._propsToMeasure=this._getPropsToMeasure(this.props),this._lastDimensions={},this.measure=function(){var t=arguments.length<=0||void 0===arguments[0]?e.props.accurate:arguments[0];if(e.props.shouldMeasure){var r=e.getDimensions(e._node,t),o="function"==typeof e.props.children;e._propsToMeasure.some(function(t){return r[t]!==e._lastDimensions[t]?(e.props.onMeasure(r),o&&e.setState({dimensions:r}),e._lastDimensions=r,!0):void 0})}}}return i(Measure,e),u(Measure,[{key:"componentDidMount",value:function(){var e=this;this._node=c["default"].findDOMNode(this),this.measure(),p["default"]().listenTo(this._node,function(){return e.measure()})}},{key:"componentWillReceiveProps",value:function(e){var t=(e.config,e.whitelist),r=e.blacklist;(this.props.whitelist!==t||this.props.blacklist!==r)&&(this._propsToMeasure=this._getPropsToMeasure({whitelist:t,blacklist:r}))}},{key:"componentWillUnmount",value:function(){p["default"]().removeAllListeners(this._node)}},{key:"getDimensions",value:function(){var e=arguments.length<=0||void 0===arguments[0]?this._node:arguments[0],t=arguments.length<=1||void 0===arguments[1]?!0:arguments[1];return h["default"](e,t)}},{key:"_getPropsToMeasure",value:function(e){var t=e.whitelist,r=e.blacklist;return t.filter(function(e){return r.indexOf(e)<0})}},{key:"render",value:function(){var e=this.props.children;return a.Children.only("function"==typeof e?e(this.state.dimensions):e)}}],[{key:"propTypes",value:{accurate:a.PropTypes.bool,whitelist:a.PropTypes.array,blacklist:a.PropTypes.array,shouldMeasure:a.PropTypes.bool,onMeasure:a.PropTypes.func},enumerable:!0},{key:"defaultProps",value:{accurate:!1,whitelist:["width","height","top","right","bottom","left"],blacklist:[],shouldMeasure:!0,onMeasure:function(){return null}},enumerable:!0}]),Measure}(a.Component);t["default"]=Measure,e.exports=t["default"]},function(t,r){t.exports=e},function(e,r){e.exports=t},function(e,t,r){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function n(){return s||(s=u["default"]({strategy:"scroll"})),s}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=n;var i=r(5),u=o(i),s=null;e.exports=t["default"]},function(e,t){e.exports=r},function(e,t,r){"use strict";function o(e){return e&&e.__esModule?e:{"default":e}}function n(e){var t=arguments.length<=1||void 0===arguments[1]?!1:arguments[1],r=e.getBoundingClientRect(),o=r.width,n=r.height;if(t){var i=u["default"](e);o=i.width,n=i.height}return{width:o,height:n,top:r.top,right:r.right,bottom:r.bottom,left:r.left}}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=n;var i=r(7),u=o(i);e.exports=t["default"]},function(e,t){"use strict";function r(e){var t=e.parentNode,r=document.createElement("div"),o=e.cloneNode(!0),n=0,i=0;return r.style.height=0,r.style.position="relative",r.style.overflow="hidden",o.setAttribute("id",""),o.setAttribute("name",""),o.style.height="auto",o.style.position="absolute",o.style.visibility="hidden",r.appendChild(o),t.appendChild(r),n=o.scrollWidth,i=o.scrollHeight,t.removeChild(r),{width:n,height:i}}Object.defineProperty(t,"__esModule",{value:!0}),t["default"]=r,e.exports=t["default"]}])});

@@ -11,3 +11,4 @@ import React, { Component, Children, PropTypes } from 'react'

state = {
showContent: false
showChildSlideable: false,
showChildContent: false
}

@@ -21,3 +22,3 @@

const { item, style } = this.props
const { showContent } = this.state
const { showChildSlideable, showChildContent } = this.state

@@ -30,18 +31,30 @@ return(

>
<div>
<button
onClick={e => {
e.stopPropagation()
this.setState({showContent: !this.state.showContent})
}}
>
Toggle Extra Content
</button>
<Slideable show={showContent}>
<div style={{background: 'red'}}>
<p style={{margin: 0, padding: 12}}>Just another paragraph to test out height animations.</p>
<p style={{margin: 0, marginTop: 12, padding: 12}}>Just another paragraph to test out height animations.</p>
</div>
</Slideable>
</div>
<button
onClick={e => {
e.stopPropagation()
this.setState({showChildSlideable: !showChildSlideable})
}}
>
Toggle Child Slideable
</button>
<Slideable show={showChildSlideable}>
<div style={{background: 'red'}}>
<p style={{margin: 0, padding: 12}}>Just another paragraph to test out height animations.</p>
<p style={{margin: 0, marginTop: 12, padding: 12}}>Just another paragraph to test out height animations.</p>
</div>
</Slideable>
<button
onClick={e => {
e.stopPropagation()
this.setState({showChildContent: !showChildContent})
}}
>
Toggle Child Content
</button>
{ showChildContent &&
<div style={{background: 'orange'}}>
<p style={{margin: 0, padding: 12}}>Just another paragraph to test out height animations.</p>
<p style={{margin: 0, marginTop: 12, padding: 12}}>Just another paragraph to test out height animations.</p>
</div>
}
{item.contents.map((content, i) => <p key={i}>{content}</p>)}

@@ -116,3 +129,3 @@ </div>

return(
return (
Object.keys(dimensions).map((dimension, i) =>

@@ -173,2 +186,22 @@ <li key={i}>{dimension}: {dimensions[dimension]}</li>

class AnimatingChild extends Component {
render() {
const { animate } = this.props
return (
<Measure>
{dimensions =>
<div className={`square ${animate ? 'animate' : ''}`}>
<strong>
{animate ? 'Click to stop animating' : 'Click to animate'}
</strong>
{Object.keys(dimensions).map((dimension, i) =>
<div key={i}>{dimension}: {dimensions[dimension]}</div>
)}
</div>
}
</Measure>
)
}
}
class App extends Component {

@@ -201,3 +234,3 @@ state = {

render() {
const { items, active, showSVG } = this.state;
const { items, active, showSVG, animate } = this.state
const currentSelected = active === null ? 'Nothing selected' : items[active].title;

@@ -215,2 +248,8 @@

</Slideable>
<Slideable show={!showSVG}>
<svg width="36px" height="36px" viewBox="0 0 36 36">
<circle fill="#373D3F" cx="18" cy="18" r="18"/>
<polygon fill="#CDD7DB" points="14,11 26,18 14,25"/>
</svg>
</Slideable>
</div>

@@ -224,7 +263,10 @@ <strong>Current Selected:</strong> {currentSelected}

<Paragraphs />
<div onClick={() => this.setState({ animate: !animate })}>
<AnimatingChild animate={animate}/>
</div>
</div>
);
)
}
}
ReactDOM.render(<App />, document.getElementById('app'));
ReactDOM.render(<App />, document.getElementById('app'))

@@ -1,215 +0,70 @@

import React, { Component, PropTypes, createElement } from 'react'
import ReactDOM from 'react-dom'
import shallowCompare from 'react-addons-shallow-compare'
import React, { Component, PropTypes, Children, cloneElement } from 'react'
import { findDOMNode } from 'react-dom'
import { Motion, spring, presets } from 'react-motion'
import Measure from '../src/react-measure'
// PARENT always knows about children
// should change data attribute saying it is now a child
// data-slideable-child=true
const stopParentSlideables = (el) => {
while (el !== document.body) {
el = el.parentNode
const slideable = el.getAttribute('data-slideable')
if (slideable && slideable !== 'stop') {
el.setAttribute('data-slideable', 'stop')
}
class Slideable extends Component {
static propTypes = {
show: PropTypes.bool.isRequired,
springConfig: React.PropTypes.objectOf(React.PropTypes.number),
children: PropTypes.node.isRequired
}
}
class Store {
constructor() {
this.slideables = {}
static defaultProps = {
springConfig: presets.noWobble
}
getSlideables() {
return this.slideables
}
add(slideable) {
}
remove() {
}
onChange() {
}
}
class Slideable extends Component {
state = {
height: -1,
instant: false
height: -1
}
_isAnimating = false
componentWillReceiveProps({show}) {
// if we're toggling "show", measure and set state
// so we can animate from an accurate measurement
if(this.props.show !== show) {
const { height } = this.refs['measure'].getDimensions()
this.setState({height})
}
}
_instant = false
_measureComponent = null
_node = null
shouldComponentUpdate(nextProps, nextState) {
return shallowCompare(this, nextProps, nextState)
}
componentDidUpdate() {
const { stopped, instant } = this.state
if(instant) {
this.setState({instant: false})
componentWillReceiveProps(nextProps) {
// force measure so we can animate from an accurate measurement
if (this.props.show !== nextProps.show) {
this._measureComponent.measure(true)
this._instant = false
}
}
// check if any children are animating
_shouldMeasure = (mutations) => {
// we need to build a set of rules
// the last triggered Slideable always takes precedence over any others
//
// it needs to notify any parents as well as children that it is animating
// reasons why include
// 1. if a parent is in the middle of animating it needs to notify that parent to stop
// we can change a data attribute on it and it will recieve the notification
// to stop
//
// Mock API
// call methods by changing data attributes
// data-slideable={['measure', 'stop', 'animateTo', 'animateFrom']}
// [measure] - measure the component and set it's height instantly - would stop any current animations as well
// [stop] - stop animating and set height to 'auto'
// [animateTo] - animate to the last known value it has
// [animateFrom] - animate from the last known value it has
// maybe we have a needsMeasure state? We need to measure when the show prop
// has changed so something like
// show prop changes ->
// set something to not animate height just yet ->
// grab height, set that prop to false so we can animate now ->
// we've now moved from a current height
// when I fire, stop all current animations, measure myself and
// go to whatever value I was at that moment in time
// we need to measure at least once before we receive a mutation
if (!mutations) return true
// we may need to go through each mutation for instance if 3 slideables
// are all triggered at once how do we handle that
const { target, attributeName } = mutations[0]
const slideable = target.getAttribute('data-slideable')
const isSliding = target.getAttribute('data-sliding')
// stop slideables if that's what we wanted
if(slideable === 'stop') {
this.stop()
}
// stop all parent slideables
stopParentSlideables(target)
// if the mutation happened to this component we need
// to update the children so they will stop animating
if (this._node === target && isSliding) {
return true
}
// check if the target is a child of this node
if (this._node !== target) {
const isSliding = target.getAttribute('data-sliding')
// if it has finished sliding then we need to query for height
if(isSliding === 'false') {
return { target, isSliding }
}
// if this node and is a mutation from data-sliding, don't update
} else if (attributeName === 'data-sliding') {
return false
}
_onMeasure = ({ height }) => {
this.setState({ height })
}
_onMeasure = ({height}, mutations, data) => {
//if (!mutations) return this.setState({height})
this.setState({height})
//const { target, attributeName } = mutations[0]
//const isSliding = target.getAttribute('data-sliding')
// if (attributeName === 'data-slideable') {
// const slideable = target.getAttribute('data-slideable')
// // stop slideables if that's what we wanted
// if (slideable === 'stop') {
// this.stop()
// return
// }
// }
//stopParentSlideables(target)
// stop all parent slideables
// stopParentSlideables(target, anyStopped => {
// // if any slideables were stopped we can't animate yet
// // since they need to finish
// if (anyStopped) {
// } else {
// }
// })
// set height if this was a child and has finished sliding
// if (this._node !== target && isSliding === 'false') {
// this.setState({height, instant: true})
// }
}
// stops a Slideable if in the middle of animating and moves to its value
// instantly, good way to prime the slideable height without animating to it
stop() {
this.setState({instant: true})
}
render() {
const { show, children } = this.props
const { instant } = this.state
const child = React.Children.only(children)
const { style } = child.props
const { show, rmConfig, children } = this.props
const child = Children.only(children)
const childStyles = child.props.style || {}
const rmHeight = show ? this.state.height : 0
const rmConfig = presets.noWobble//[60, 22]
return(
return (
<Measure
ref="measure"
config={{
childList: true,
subtree: true,
attributes: true,
attributeFilter: ['data-slideable', 'data-sliding']
}}
accurate
ref={c => this._measureComponent = c}
// we only need to be accurate if the show prop has changed,
// otherwise something else is effecting the height change
accurate={!this._instant}
whitelist={['height']}
shouldMeasure={this._shouldMeasure}
onMeasure={this._onMeasure}
>
<Motion
defaultStyle={{height: 0}}
defaultStyle={{ height: 0 }}
style={{
height: instant ? rmHeight : spring(rmHeight, rmConfig)
height: this._instant
? rmHeight
: spring(rmHeight, { precision: 0.5, ...rmConfig })
}}
onRest={() => {
this._instant = true
}}
>
{({height}) => {
const destHeight = parseFloat(this.state.height).toFixed(2)
const currHeight = parseFloat(height).toFixed(2)
let rmStyle = {}
{({ height }) => {
let rmStyles = {}
if (destHeight !== currHeight && !instant) {
rmStyle = {
// only animate when necessary
// don't always apply style values so height works responsively
if (!show || (!this._instant && rmHeight !== height)) {
rmStyles = {
height,

@@ -219,23 +74,3 @@ overflow: 'hidden'

}
if (destHeight === currHeight || height === 0) {
this._isAnimating = false
} else {
this._isAnimating = true
}
return(
React.cloneElement(
React.Children.only(children),
{
ref: c => this._node = ReactDOM.findDOMNode(c),
style: {
...rmStyle,
...style
},
'data-sliding': this._isAnimating,
'data-slideable': true
}
)
)
return cloneElement(child, { style: { ...rmStyles, ...childStyles } })
}}

@@ -248,2 +83,2 @@ </Motion>

export default Slideable
export default Slideable

@@ -10,5 +10,5 @@ 'use strict';

var _accurateHeight = require('./accurate-height');
var _getCloneDimensions = require('./get-clone-dimensions');
var _accurateHeight2 = _interopRequireDefault(_accurateHeight);
var _getCloneDimensions2 = _interopRequireDefault(_getCloneDimensions);

@@ -19,6 +19,14 @@ function getNodeDimensions(node) {

var rect = node.getBoundingClientRect();
var width = rect.width;
var height = rect.height;
if (accurate) {
var cloneDimensions = (0, _getCloneDimensions2['default'])(node);
width = cloneDimensions.width;
height = cloneDimensions.height;
}
return {
width: rect.width,
height: accurate ? (0, _accurateHeight2['default'])(node) : rect.height,
width: width,
height: height,
top: rect.top,

@@ -25,0 +33,0 @@ right: rect.right,

@@ -9,3 +9,3 @@ 'use strict';

var _get = function get(_x3, _x4, _x5) { var _again = true; _function: while (_again) { var object = _x3, property = _x4, receiver = _x5; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x3 = parent; _x4 = property; _x5 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
var _get = function get(_x4, _x5, _x6) { var _again = true; _function: while (_again) { var object = _x4, property = _x5, receiver = _x6; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x4 = parent; _x5 = property; _x6 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

@@ -26,10 +26,6 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

var _ResizeHandler = require('./Resize-Handler');
var _resizeDetector = require('./resize-detector');
var _ResizeHandler2 = _interopRequireDefault(_ResizeHandler);
var _resizeDetector2 = _interopRequireDefault(_resizeDetector);
var _diffConfig = require('./diff-config');
var _diffConfig2 = _interopRequireDefault(_diffConfig);
var _getNodeDimensions = require('./get-node-dimensions');

@@ -39,4 +35,2 @@

var resizeHandler = new _ResizeHandler2['default']();
var Measure = (function (_Component) {

@@ -52,23 +46,29 @@ _inherits(Measure, _Component);

this._observer = null;
this.state = {
dimensions: {}
};
this._node = null;
this._properties = this._getProperties(this.props);
this._propsToMeasure = this._getPropsToMeasure(this.props);
this._lastDimensions = {};
this._measure = function (mutations) {
var shouldMeasure = _this.props.shouldMeasure(mutations);
this.measure = function () {
var accurate = arguments.length <= 0 || arguments[0] === undefined ? _this.props.accurate : arguments[0];
// bail out if we shouldn't measure
if (!shouldMeasure) return;
if (!_this.props.shouldMeasure) return;
var dimensions = _this.getDimensions(_this._node, _this.props.accurate);
var dimensions = _this.getDimensions(_this._node, accurate);
var isChildFunction = typeof _this.props.children === 'function';
// determine if we need to update our callback with new dimensions or not
_this._properties.some(function (prop) {
_this._propsToMeasure.some(function (prop) {
if (dimensions[prop] !== _this._lastDimensions[prop]) {
// if we've found a dimension that has changed, update our callback
// we also allow shouldMeasure to return any values so the end user
// doesn't have to recalculate anything
_this.props.onMeasure(dimensions, mutations, shouldMeasure);
// update our callback if we've found a dimension that has changed
_this.props.onMeasure(dimensions);
// update state to send dimensions to child function
if (isChildFunction) {
_this.setState({ dimensions: dimensions });
}
// store last dimensions to compare changes

@@ -87,12 +87,13 @@ _this._lastDimensions = dimensions;

value: function componentDidMount() {
var _this2 = this;
this._node = _reactDom2['default'].findDOMNode(this);
// set up mutation observer
this._connectObserver(this.props.config);
// measure on first render
this._measure(null);
this.measure();
// add component to resize handler to detect changes on resize
resizeHandler.add(this);
// add component to resize detector to detect changes on resize
(0, _resizeDetector2['default'])().listenTo(this._node, function () {
return _this2.measure();
});
}

@@ -106,12 +107,6 @@ }, {

// disconnect the old observer and reconnect with new config if changed
if ((0, _diffConfig2['default'])(this.props.config, config)) {
this._disconnectObserver();
this._connectObserver(config);
}
// we store the properties ourselves so we need to update them if the
// whitelist or blacklist props have changed
if (this.props.whitelist !== whitelist || this.props.blacklist !== blacklist) {
this._properties = this._getProperties({ whitelist: whitelist, blacklist: blacklist });
this._propsToMeasure = this._getPropsToMeasure({ whitelist: whitelist, blacklist: blacklist });
}

@@ -122,4 +117,3 @@ }

value: function componentWillUnmount() {
this._disconnectObserver();
resizeHandler.remove(this);
(0, _resizeDetector2['default'])().removeAllListeners(this._node);
}

@@ -135,15 +129,4 @@ }, {

}, {
key: '_connectObserver',
value: function _connectObserver(config) {
this._observer = new MutationObserver(this._measure);
this._observer.observe(this._node, config);
}
}, {
key: '_disconnectObserver',
value: function _disconnectObserver() {
this._observer.disconnect();
}
}, {
key: '_getProperties',
value: function _getProperties(_ref2) {
key: '_getPropsToMeasure',
value: function _getPropsToMeasure(_ref2) {
var whitelist = _ref2.whitelist;

@@ -159,3 +142,5 @@ var blacklist = _ref2.blacklist;

value: function render() {
return _react.Children.only(this.props.children);
var children = this.props.children;
return _react.Children.only(typeof children === 'function' ? children(this.state.dimensions) : children);
}

@@ -165,7 +150,6 @@ }], [{

value: {
config: _react.PropTypes.object,
accurate: _react.PropTypes.bool,
whitelist: _react.PropTypes.array,
blacklist: _react.PropTypes.array,
shouldMeasure: _react.PropTypes.func,
shouldMeasure: _react.PropTypes.bool,
onMeasure: _react.PropTypes.func

@@ -177,12 +161,6 @@ },

value: {
config: {
childList: true,
attributes: true
},
accurate: false,
whitelist: ['width', 'height', 'top', 'right', 'bottom', 'left'],
blacklist: [],
shouldMeasure: function shouldMeasure() {
return true;
},
shouldMeasure: true,
onMeasure: function onMeasure() {

@@ -189,0 +167,0 @@ return null;

{
"name": "react-measure",
"version": "0.3.5",
"version": "0.4.0",
"description": "Compute measurements of React components.",

@@ -24,3 +24,6 @@ "main": "lib/react-measure.js",

"measurements",
"dimensions"
"dimensions",
"element-queries",
"container-queries",
"size"
],

@@ -34,3 +37,3 @@ "author": "Travis Arnold <travis@souporserious.com> (http://souporserious.com)",

"dependencies": {
"lodash.debounce": "^3.1.1"
"element-resize-detector": "^1.1.4"
},

@@ -47,3 +50,3 @@ "devDependencies": {

"react-addons-shallow-compare": "^0.14.0",
"react-motion": "^0.3.1",
"react-motion": "^0.4.2",
"sass-loader": "^1.0.2",

@@ -50,0 +53,0 @@ "style-loader": "^0.12.3",

## React Measure
Compute measurements of React components. Uses a [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit) to detect changes of an element and return the new measurements after that mutation.
Compute measurements of React components. Uses [element-resize-detector](https://github.com/wnr/element-resize-detector) to detect changes of an element and return the new dimensions.

@@ -11,3 +11,3 @@ ## Install

## Example Usage
## Example Usage w/ state

@@ -24,16 +24,6 @@ ```javascript

const { height } = this.state.dimensions
return(
return (
<Measure
whitelist={['height']}
shouldMeasure={(mutations) => {
// don't update unless we have mutations available
if(mutations) {
return mutations[0].target
} else {
return false
}
}}
// notice how target gets passed into onMeasure now
onMeasure={(dimensions, mutations, target) => {
onMeasure={(dimensions) => {
this.setState({dimensions})

@@ -51,11 +41,29 @@ }}

## Props
## Example Usage w/ child function
#### `config`: PropTypes.object
```javascript
import Measure from 'react-measure';
Accepts a [MutationObserver configuration](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit).
class ItemToMeasure extends Component {
render() {
return (
<Measure>
{dimensions =>
<div>
{Object.keys(dimensions).map((dimension, i) =>
<div key={i}>{dimension}: {dimensions[dimension]}</div>
)}
</div>
}
</Measure>
)
}
}
```
## Props
#### `accurate`: PropTypes.bool
Tries to give the most accurate measure. Currently only works with height. Measures the content rather than the actual box of the element.
Tries to give the most accurate measure by cloning the element and measuring it. Use if you your item is hidden or you want know to find out what height/width you need to get to.

@@ -70,9 +78,9 @@ #### `whitelist`: PropTypes.array

#### `shouldMeasure`: PropTypes.func
#### `shouldMeasure`: PropTypes.bool
Determines whether or not a measurement should occur. Return `true`, `false` or a value you want returned in `onMeasure`.
Determines whether or not a measurement should occur. Useful if you only need to measure in certain cases.
#### `onMeasure`: PropTypes.func
Callback when the component has been mutated. Receives `dimensions`, `mutations`, and anything passed to `shouldMeasure`.
Callback when the component has been mutated. Receives the new `dimensions` of your component.

@@ -84,5 +92,2 @@ ## Good to knows

## Browser Support
All modern browsers supported. IE 9 & 10 support with a MutationObserver polyfill. I recommend this [one](https://github.com/megawac/MutationObserver.js)
## Run Example

@@ -89,0 +94,0 @@

@@ -1,9 +0,17 @@

import accurateHeight from './accurate-height'
import getCloneDimensions from './get-clone-dimensions'
export default function getNodeDimensions(node, accurate = false) {
const rect = node.getBoundingClientRect()
let width = rect.width
let height = rect.height
if (accurate) {
const cloneDimensions = getCloneDimensions(node)
width = cloneDimensions.width
height = cloneDimensions.height
}
return {
width: rect.width,
height: accurate ? accurateHeight(node) : rect.height,
width,
height,
top: rect.top,

@@ -10,0 +18,0 @@ right: rect.right,

import React, { Component, Children, PropTypes, createElement, cloneElement } from 'react'
import ReactDOM from 'react-dom'
import ResizeHandler from './Resize-Handler'
import diffConfig from './diff-config'
import resizeDetector from './resize-detector'
import getNodeDimensions from './get-node-dimensions'
const resizeHandler = new ResizeHandler()
class Measure extends Component {
static propTypes = {
config: PropTypes.object,
accurate: PropTypes.bool,
whitelist: PropTypes.array,
blacklist: PropTypes.array,
shouldMeasure: PropTypes.func,
shouldMeasure: PropTypes.bool,
onMeasure: PropTypes.func

@@ -20,16 +16,15 @@ }

static defaultProps = {
config: {
childList: true,
attributes: true
},
accurate: false,
whitelist: ['width', 'height', 'top', 'right', 'bottom', 'left'],
blacklist: [],
shouldMeasure: () => true,
shouldMeasure: true,
onMeasure: () => null
}
_observer = null
state = {
dimensions: {}
}
_node = null
_properties = this._getProperties(this.props)
_propsToMeasure = this._getPropsToMeasure(this.props)
_lastDimensions = {}

@@ -40,19 +35,10 @@

// set up mutation observer
this._connectObserver(this.props.config)
// measure on first render
this._measure(null)
this.measure()
// add component to resize handler to detect changes on resize
resizeHandler.add(this)
// add component to resize detector to detect changes on resize
resizeDetector().listenTo(this._node, () => this.measure())
}
componentWillReceiveProps({config, whitelist, blacklist}) {
// disconnect the old observer and reconnect with new config if changed
if (diffConfig(this.props.config, config)) {
this._disconnectObserver()
this._connectObserver(config)
}
// we store the properties ourselves so we need to update them if the

@@ -62,3 +48,3 @@ // whitelist or blacklist props have changed

this.props.blacklist !== blacklist) {
this._properties = this._getProperties({whitelist, blacklist})
this._propsToMeasure = this._getPropsToMeasure({whitelist, blacklist})
}

@@ -68,4 +54,3 @@ }

componentWillUnmount() {
this._disconnectObserver()
resizeHandler.remove(this)
resizeDetector().removeAllListeners(this._node)
}

@@ -77,18 +62,24 @@

_measure = (mutations) => {
const shouldMeasure = this.props.shouldMeasure(mutations)
_getPropsToMeasure({ whitelist, blacklist }) {
return whitelist.filter(prop => blacklist.indexOf(prop) < 0)
}
measure = (accurate = this.props.accurate) => {
// bail out if we shouldn't measure
if(!shouldMeasure) return
if (!this.props.shouldMeasure) return
const dimensions = this.getDimensions(this._node, this.props.accurate)
const dimensions = this.getDimensions(this._node, accurate)
const isChildFunction = (typeof this.props.children === 'function')
// determine if we need to update our callback with new dimensions or not
this._properties.some(prop => {
if(dimensions[prop] !== this._lastDimensions[prop]) {
// if we've found a dimension that has changed, update our callback
// we also allow shouldMeasure to return any values so the end user
// doesn't have to recalculate anything
this.props.onMeasure(dimensions, mutations, shouldMeasure)
this._propsToMeasure.some(prop => {
if (dimensions[prop] !== this._lastDimensions[prop]) {
// update our callback if we've found a dimension that has changed
this.props.onMeasure(dimensions)
// update state to send dimensions to child function
if (isChildFunction) {
this.setState({ dimensions })
}
// store last dimensions to compare changes

@@ -103,17 +94,9 @@ this._lastDimensions = dimensions

_connectObserver(config) {
this._observer = new MutationObserver(this._measure)
this._observer.observe(this._node, config)
}
_disconnectObserver() {
this._observer.disconnect()
}
_getProperties({whitelist, blacklist}) {
return whitelist.filter(prop => blacklist.indexOf(prop) < 0)
}
render() {
return Children.only(this.props.children)
const { children } = this.props
return Children.only(
typeof children === 'function'
? children(this.state.dimensions)
: children
)
}

@@ -120,0 +103,0 @@ }

@@ -28,3 +28,4 @@ var path = require('path');

'react': 'React',
'react-dom': 'ReactDOM'
'react-dom': 'ReactDOM',
'element-resize-detector': 'createResizeDetector'
},

@@ -41,3 +42,3 @@ };

mangle: {
except: ['React', 'ReactDOM', 'Measure']
except: ['React', 'ReactDOM', 'Measure', 'createResizeDetector']
}

@@ -47,2 +48,2 @@ }));

module.exports = config;
module.exports = config;

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