Package Exports
- remeasure
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (remeasure) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
remeasure
Get position and size of the DOM element for any React Component
Installation
$ npm i remeasure --save
Usage
// ES2015
import measure from 'remeasure';
// CommonJS
const measure = require('remeasure');
// script
var measure = window.Remeasure;
// apply it as a decorator
@measure
class MyComponent extends React.Component {
render() {
const {
position,
size
} = this.props;
return (
<div>
I have access to my size and position through props!
</div>
);
}
}
// or as a function wrapper
const StatelessComponent = measure(({position, size}) => {
return (
<div>
In here too!
</div>
);
});
Any component that has measure
applied to it will be wrapped in a Higher-Order Component that will pass in the props position
and size
, which contain a variety of measurements related to (you guessed it) the component's position and size. A complete list of properties:
{
position: {
bottom: Number,
clientLeft: Number,
clientTop: Number,
offsetLeft: Number,
offsetTop: Number,
left: Number,
right: Number,
scrollLeft: Number,
scrollTop: Number,
top: Number
},
size: {
clientHeight: Number,
clientWidth: Number,
height: Number,
naturalHeight: Number,
naturalWidth: Number,
offsetHeight: Number,
offsetWidth: Number,
scrollHeight: Number,
scrollWidth: Number,
width: Number
}
}
The bottom
, left
, right
, and top
properties in position
are what you would expect from the result of element.getBoundingClientRect()
. naturalHeight
and naturalWidth
are properties that are native to img
elements, and for all non-img
elements they are coalesced with scrollHeight
and scrollWidth
, respectively.
These properties are retrieved on mount, but will also automatically update if the element is resized thanks to element-resize-event.
Advanced usage
If you want to limit the items that are injected into the component, you can pass either a key or array of keys to the decorator before wrapping the component.
measure(String|Array<String>|Object[, Object]
) returns Function
Examples:
import measure from 'remeasure';
// pass a string value for a single property
const measureOnlyOffsetWidth = measure('offsetWidth');
const MyStatelessComponent = measureOnlyOffsetWidth(({size}) => {
return (
<div>
Only size is injected (because no position values were requested),
with offsetWidth as the only property
</div>
);
});
// or an array of string values for multiple properties
@measure(['top', 'height'])
class MyComponent extends Component {
render() {
const {
position,
size
} = this.props;
return (
<div>
Both the position and size props are injected (because values
from both position and size were requested), and each will have
a single property on them (top on position, height on size).
</div>
);
}
}
// or quickly select the complete list of either size or position
@measure('size')
class MySizedComponent extends Component {
render() {
const size = this.props.size;
return (
<div>
I have the size prop injected with all properties, but not
position.
</div>
);
}
}
You can also pass an object with any of the following propeties (defaults shown):
{
positionProp: String = 'position',
renderOnResize: Boolean = true,
sizeProp: String = 'size'
}
These will serve as options for the instance remeasure
is applied to. For example, if you want all position-related properties to be injected under the prop foo
and the size-related properties to be injected under the prop bar
, you can do this:
const FOO_BAR_OPTIONS = {
positionProp: 'foo',
sizeProp: 'bar'
};
// use the options by themselves
@measure(FOO_BAR_OPTIONS)
class MyComponent extends Component {
render() {
const {
foo,
bar
} = this.props;
return (
<div>
The foo and bar props now represent position and size, respectively.
</div>
);
}
}
// or you can use them with keys
const measureWithKeysAndOptions = measure(['height', 'width'], FOO_BAR_OPTIONS);
const MyStatelessComponent = measureWithKeysAndOptions(({foo, bar}) => {
return (
<div>
You can still pass options when you want to specify keys, as the
second parameter.
</div>
);
};
// you can even use the custom props with the shorthand notation
@measure('bar', FOO_BAR_OPTIONS)
class MySizedComponent extends Component {
render() {
return (
<div>
I will have access to all the size properties under the prop
bar, but foo will not be injected.
</div>
);
}
}
Support
remeasure
has been tested and confirmed to work on the following browsers:
- Chrome
- Firefox
- Opera
- Edge
- IE9+
remeasure
also works with universal / isomorphic applications.
Development
Standard stuff, clone the repo and npm i
to get the dependencies. npm scripts available:
build
=> builds the distributed JS withNODE_ENV=development
and with sourcemapsbuild-minified
=> builds the distributed JS withNODE_ENV=production
and minifiedcompile-for-publish
=> runs thelint
,test
,transpile
,dist
scriptsdev
=> runs the webpack dev server for the playgrounddist
=> runs thebuild
andbuild-minified
lint
=> runs ESLint against files in thesrc
folderprepublish
=> if in publish, runscompile-for-publish
test
=> run ava with NODE_ENV=testtest:watch
=> runstest
but with persistent watchertranspile
=> runs Babel against files insrc
to files inlib