diff --git a/README.md b/README.md index 8ca0dbc..7e6c594 100644 --- a/README.md +++ b/README.md @@ -35,16 +35,17 @@ import SizeMe from 'react-sizeme'; class MyComponent extends Component { render() { - // Receive width and height via "size" prop! - const { width, height } = this.props.size; + // We receive width and height via "size" prop! + const { width } = this.props.size; return ( -
My dimensions are {width}px by {height}px
+
My width is {width}px
); } } -export default SizeMe()(MyComponent); // Wired up here! +// Wired up here! +export default SizeMe()(MyComponent); ``` ## Usage and API Details @@ -65,19 +66,32 @@ You first have to pass the `SizeMe` function a configuration object. The entire ```javascript const SizeMeHOC = SizeMe({ - // If true any changes to `width` will result in a new `size` prop being - // passed to your Component. + // If true, then any changes to your Components rendered width will cause an + // recalculation of the "size" prop which will then be be passed into + // your Component. + // If false, then any changes to your Components rendered width will NOT + // cause any recalculation of the "size" prop. Additionally any "size" prop + // that is passed into your Component will always have a `null` value + // for the "width" property. monitorWidth: true, - // If true any changes to `height` will result in a new `size` prop being - // passed to your Component. + // If true, then any changes to your Components rendered height will cause an + // recalculation of the "size" prop which will then be be passed into + // your Component. + // If false, then any changes to your Components rendered height will NOT + // cause any recalculation of the "size" prop. Additionally any "size" prop + // that is passed into your Component will always have a `null` value + // for the "height" property. monitorHeight: false, - // The maximum speed, in milliseconds, at which size changes should be - // propogated to your Components. This should not be set to lower than 16. + // The maximum frequency, in milliseconds, at which size changes should be + // recalculated when changes in your Component's rendered size are being + // detected. This should not be set to lower than 16. refreshRate: 16 }); ``` -__IMPORTANT__: We don't monitor height by default, so if you use the default settings and your component only changes in height it won't recieve an updated `size` prop. I figured that in most cases we care about the width only and it would be annoying if vertical text spanning kept throwing out updates. +__IMPORTANT__: We don't monitor height by default, so if you use the default settings and your component only changes in height it won't cause a recalculation of the `size` prop. I figured that in most cases we care about the width only and it would be annoying if vertical text spanning kept throwing out updates. + +__IMPORTANT__: If you aren't monitoring a specific dimension (width or height) you will be provided `null` values for the respective dimension. This is to avoid any possible misconfigured implementation whoopsies. __IMPORTANT__: `refreshRate` is set very low. If you are using this library in a manner where you expect loads of active changes to your components dimensions you may need to tweak this value to avoid browser spamming. diff --git a/src/SizeMe.js b/src/SizeMe.js index 14327d1..6d69e2a 100644 --- a/src/SizeMe.js +++ b/src/SizeMe.js @@ -172,7 +172,10 @@ function SizeMe(config = defaultConfig) { checkIfSizeChanged = throttle((el) => { const { width, height } = el.getBoundingClientRect(); - const next = { width, height }; + const next = { + width: monitorWidth ? width : null, + height: monitorHeight ? height : null + }; if (this.hasSizeChanged(this.state, next)) { this.setState(next); diff --git a/test/SizeMe.test.js b/test/SizeMe.test.js index b393e87..659c869 100644 --- a/test/SizeMe.test.js +++ b/test/SizeMe.test.js @@ -66,9 +66,7 @@ describeWithDOM(`Given the SizeMe library`, () => { describe(`And the resize detector`, () => { describe(`When mounting and unmounting the placeholder component`, () => { it(`Then the resizeDetector registration and deregistration should be called`, () => { - const SizeAwareComponent = SizeMe()( - ({ size: { width, height } }) =>
{width} x {height}
- ); + const SizeAwareComponent = SizeMe()(() =>
); const mounted = mount(); @@ -84,7 +82,7 @@ describeWithDOM(`Given the SizeMe library`, () => { describe(`When mounting and unmounting a size aware component`, () => { it(`Then the resizeDetector registration and deregistration should be called`, () => { - const SizeAwareComponent = SizeMe()( + const SizeAwareComponent = SizeMe({ monitorHeight: true })( ({ size: { width, height } }) =>
{width} x {height}
); @@ -123,9 +121,7 @@ describeWithDOM(`Given the SizeMe library`, () => { describe(`When rendering a size aware component`, () => { describe(`And no className or style has been provided`, () => { it(`Then it should render the default placeholder`, () => { - const SizeAwareComponent = SizeMe()( - ({ size: { width, height } }) =>
{width} x {height}
- ); + const SizeAwareComponent = SizeMe()(() =>
); const mounted = mount(); @@ -136,9 +132,7 @@ describeWithDOM(`Given the SizeMe library`, () => { describe(`And only a className has been provided`, () => { it(`Then it should render a placeholder with the className`, () => { - const SizeAwareComponent = SizeMe()( - ({ size: { width, height } }) =>
{width} x {height}
- ); + const SizeAwareComponent = SizeMe()(() =>
); const mounted = mount(); @@ -149,9 +143,7 @@ describeWithDOM(`Given the SizeMe library`, () => { describe(`And only a style has been provided`, () => { it(`Then it should render a placeholder with the style`, () => { - const SizeAwareComponent = SizeMe()( - ({ size: { width, height } }) =>
{width} x {height}
- ); + const SizeAwareComponent = SizeMe()(() =>
); const mounted = mount(); @@ -162,9 +154,7 @@ describeWithDOM(`Given the SizeMe library`, () => { describe(`And a className and style have been provided`, () => { it(`Then it should render a placeholder with both`, () => { - const SizeAwareComponent = SizeMe()( - ({ size: { width, height } }) =>
{width} x {height}
- ); + const SizeAwareComponent = SizeMe()(() =>
); const mounted = mount( @@ -175,11 +165,53 @@ describeWithDOM(`Given the SizeMe library`, () => { }); }); - describe(`And the size event has occurred`, () => { - it(`Then the actual size aware component should render`, () => { - const refreshRate = 30; + describe(`And the size event has occurred when only width is being monitored`, () => { + it(`Then expected sizes should be provided to the rendered component`, () => { + const SizeAwareComponent = SizeMe({ monitorWidth: true, monitorHeight: false })( + ({ size: { width, height } }) =>
{width} x {height || `null`}
+ ); + + const mounted = mount(); + + // Initial render should be as expected. + expect(mounted.html()).to.equal(placeholderHtml); + + // Get the callback for size changes. + const checkIfSizeChangedCallback = resizeDetectorMock.listenTo.args[0][1]; + checkIfSizeChangedCallback({ + getBoundingClientRect: () => ({ width: 100, height: 150 }) + }); + + // Update should have occurred immediately. + expect(mounted.text()).to.equal(`100 x null`); + }); + }); + + describe(`And the size event has occurred when only height is being monitored`, () => { + it(`Then expected sizes should be provided to the rendered component`, () => { + const SizeAwareComponent = SizeMe({ monitorWidth: false, monitorHeight: true })( + ({ size: { width, height } }) =>
{width || `null`} x {height}
+ ); + + const mounted = mount(); + + // Initial render should be as expected. + expect(mounted.html()).to.equal(placeholderHtml); + + // Get the callback for size changes. + const checkIfSizeChangedCallback = resizeDetectorMock.listenTo.args[0][1]; + checkIfSizeChangedCallback({ + getBoundingClientRect: () => ({ width: 100, height: 150 }) + }); - const SizeAwareComponent = SizeMe({ refreshRate })( + // Update should have occurred immediately. + expect(mounted.text()).to.equal(`null x 150`); + }); + }); + + describe(`And the size event has occurred when width and height are being monitored`, () => { + it(`Then expected sizes should be provided to the rendered component`, () => { + const SizeAwareComponent = SizeMe({ monitorWidth: true, monitorHeight: true })( ({ size: { width, height } }) =>
{width} x {height}
); @@ -191,19 +223,17 @@ describeWithDOM(`Given the SizeMe library`, () => { // Get the callback for size changes. const checkIfSizeChangedCallback = resizeDetectorMock.listenTo.args[0][1]; checkIfSizeChangedCallback({ - getBoundingClientRect: () => ({ width: 100, height: 100 }) + getBoundingClientRect: () => ({ width: 100, height: 150 }) }); // Update should have occurred immediately. - expect(mounted.text()).to.equal(`100 x 100`); + expect(mounted.text()).to.equal(`100 x 150`); }); }); describe(`And it receives new non-size props`, () => { it(`Then the new props should be passed into the component`, () => { - const refreshRate = 16; - - const SizeAwareComponent = SizeMe({ refreshRate })( + const SizeAwareComponent = SizeMe({ monitorHeight: true, monitorWidth: true })( function ({ size: { width, height }, otherProp }) { return
{width} x {height} & {otherProp}
; }