Skip to content

Commit

Permalink
Merge pull request #6 from okonet/all-client-rect-props
Browse files Browse the repository at this point in the history
Pass all values of getBoundingClientRect
  • Loading branch information
okonet committed Aug 5, 2016
2 parents dd81f95 + 2c97d23 commit 5cda8f1
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.3.0

- Pass all values of getBoundingClientRect, not just `width` and `height`. (#6)

# 1.2.0

- Added React 15 to a semver range for peerDependencies (#3)
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ It is especially useful when you create components with dimensions that change o
time and you want to explicitely pass the container dimensions to the children. For example, SVG
visualization needs to be updated in order to fit into container.

It uses [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) and passes values for all `top`, `right`, `bottom`, `left`, `width`, `height` CSs attributes down the tree.

## Usage

* Wrap your existing components. Children component will recieve `width` and `height` as props.
* Wrap your existing components. Children component will recieve `top`, `right`, `bottom`, `left`, `width`, `height` as props.

```jsx
<ContainerDimensions>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-container-dimensions",
"version": "1.2.0",
"version": "1.3.0",
"description": "Wrapper component that detects element resize and passes new dimensions down the tree. Based on [element-resize-detector](https://github.com/wnr/element-resize-detector)",
"main": "lib/index.js",
"scripts": {
Expand Down
10 changes: 7 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ export default class ContainerDimensions extends Component {
children: PropTypes.oneOfType([PropTypes.element, PropTypes.func]).isRequired
}

static getDomNodeDimensions(node) {
const { top, right, bottom, left, width, height } = node.getBoundingClientRect()
return { top, right, bottom, left, width, height }
}

constructor() {
super()
this.state = {
Expand All @@ -29,11 +34,10 @@ export default class ContainerDimensions extends Component {
}

onResize() {
const clientRect = this.parentNode.getBoundingClientRect()
const clientRect = ContainerDimensions.getDomNodeDimensions(this.parentNode)
this.setState({
initiated: true,
width: clientRect.width,
height: clientRect.height
...clientRect
})
}

Expand Down
60 changes: 54 additions & 6 deletions tests/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint no-unused-expressions: 0 */
import React from 'react'
import { mount } from 'enzyme'
import { spy } from 'sinon'
import { spy, stub } from 'sinon'
import chai, { expect } from 'chai'
import ContainerDimensions from '../src/index'

Expand Down Expand Up @@ -61,11 +61,44 @@ describe('react-container-dimensions', () => {
const el = wrapper.render()
el.css('width', 10)
setTimeout(() => {
el.css('width', 100)
el.css('width', 100) // Triggering onResize event
expect(ContainerDimensions.prototype.onResize.calledTwice).to.be.true
ContainerDimensions.prototype.onResize.restore()
done()
}, 0)
}, 10)
})

it('onResize sets state with all keys and values from getBoundingClientRect', () => {
const styles = { top: 100, width: 200 }
stub(ContainerDimensions, 'getDomNodeDimensions', () => ({
top: 0,
right: 0,
bottom: 0,
left: 0,
width: 0,
height: 0,
...styles
}))
const wrapper = mount(
<div style={styles}>
<ContainerDimensions>
<MyComponent />
</ContainerDimensions>
</div>
, { attachTo: document.body })

wrapper.render()
expect(wrapper.find(MyComponent).props()).to.have.keys([
'initiated',
'top',
'right',
'bottom',
'left',
'width',
'height'])
expect(wrapper.find(MyComponent)).to.have.prop('top', 100)
expect(wrapper.find(MyComponent)).to.have.prop('width', 200)
ContainerDimensions.getDomNodeDimensions.restore()
})

it('should initially render an empty placeholder', () => {
Expand All @@ -89,34 +122,49 @@ describe('react-container-dimensions', () => {
expect(wrapper.find(MyComponent).length).to.eq(1)
})

it('should pass width and height as props to its children', () => {
it('should pass dimensions as props to its children', () => {
const wrapper = mount(
<ContainerDimensions>
<MyComponent />
</ContainerDimensions>
)
wrapper.setState({
top: 0,
right: 100,
bottom: 300,
left: 200,
width: 100,
height: 200
})
expect(wrapper.find(MyComponent)).to.have.length(1)
expect(wrapper.find(MyComponent)).to.have.prop('top', 0)
expect(wrapper.find(MyComponent)).to.have.prop('right', 100)
expect(wrapper.find(MyComponent)).to.have.prop('bottom', 300)
expect(wrapper.find(MyComponent)).to.have.prop('left', 200)
expect(wrapper.find(MyComponent)).to.have.prop('width', 100)
expect(wrapper.find(MyComponent)).to.have.prop('height', 200)
})

it('should pass width and height as function arguments', () => {
it('should pass dimensions as function arguments', () => {
const wrapper = mount(
<ContainerDimensions>
{
({ width, height }) => <MyComponent width={width + 10} height={height + 10} /> // eslint-disable-line
({ left, width, height }) => // eslint-disable-line
<MyComponent
left={left + 10}
width={width + 10}
height={height + 10}
/>
}
</ContainerDimensions>
)
wrapper.setState({
left: 20,
width: 100,
height: 200
})
expect(wrapper.find(MyComponent)).to.have.length(1)
expect(wrapper.find(MyComponent)).to.have.prop('left', 30)
expect(wrapper.find(MyComponent)).to.have.prop('width', 110)
expect(wrapper.find(MyComponent)).to.have.prop('height', 210)
})
Expand Down

0 comments on commit 5cda8f1

Please sign in to comment.