Skip to content

Commit

Permalink
Merge pull request #130 from piecyk/only-one
Browse files Browse the repository at this point in the history
Observe only one element
  • Loading branch information
souporserious committed Feb 5, 2019
2 parents 05401a0 + 9b4b574 commit 2c0cd97
Show file tree
Hide file tree
Showing 7 changed files with 2,396 additions and 35 deletions.
7 changes: 6 additions & 1 deletion .babelrc
Expand Up @@ -3,5 +3,10 @@
["@babel/preset-env", { "loose": true, "modules": false }],
["@babel/preset-react", { "useBuiltIns": true }]
],
"plugins": [["@babel/plugin-proposal-class-properties", { "loose": true }]]
"plugins": [["@babel/plugin-proposal-class-properties", { "loose": true }]],
"env": {
"test": {
"plugins": ["@babel/transform-modules-commonjs"]
}
}
}
5 changes: 5 additions & 0 deletions .prettierrc
@@ -0,0 +1,5 @@
{
"singleQuote": true,
"trailingComma": "es5",
"semi": false
}
13 changes: 13 additions & 0 deletions package.json
Expand Up @@ -10,6 +10,9 @@
],
"scripts": {
"build": "rollup -c",
"test": "jest --env=jsdom",
"test:ci": "cross-env CI=1 jest --env=jsdom",
"prettier": "prettier --write 'src/**/*.{js,json,css}'",
"prepublishOnly": "npm run build"
},
"repository": {
Expand All @@ -32,6 +35,11 @@
"url": "https://github.com/souporserious/react-measure/issues"
},
"homepage": "https://github.com/souporserious/react-measure",
"jest": {
"roots": [
"<rootDir>/src"
]
},
"peerDependencies": {
"react": ">0.13.0",
"react-dom": ">0.13.0"
Expand All @@ -49,6 +57,11 @@
"@babel/plugin-transform-runtime": "^7.2.0",
"@babel/preset-env": "^7.2.0",
"@babel/preset-react": "^7.0.0",
"cross-env": "^5.2.0",
"jest": "^24.0.0",
"prettier": "^1.16.4",
"react": "^16.7.0",
"react-dom": "^16.7.0",
"rollup": "^0.67.4",
"rollup-plugin-babel": "^4.1.0",
"rollup-plugin-node-resolve": "^4.0.0"
Expand Down
102 changes: 102 additions & 0 deletions src/__tests__/Measure.test.js
@@ -0,0 +1,102 @@
import React, { createRef } from 'react'
import { render } from 'react-dom'

describe('Measure', () => {
let container, resizeObserver, defaultChildrenFn, MeasureWith

beforeEach(() => {
jest.useFakeTimers()
jest.resetModules()

global.ResizeObserver = jest.fn(
callback =>
(resizeObserver = {
observe: jest.fn(),
unobserve: jest.fn(),
disconnect: jest.fn(),
callback,
})
)

global.requestAnimationFrame = cb => setTimeout(cb, 0)

defaultChildrenFn = jest.fn(({ measureRef, ...rest }) => (
<div ref={measureRef}>{JSON.stringify(rest, null, 2)}</div>
))
const setupMeasure = Measure => ({
children = defaultChildrenFn,
...rest
}) => <Measure {...rest}>{children}</Measure>

MeasureWith = setupMeasure(require('../Measure').default)
container = document.createElement('div')
})

it('should handel entry', () => {
const ref = createRef()
render(<MeasureWith innerRef={ref} />, container)
expect(container.firstChild).toMatchSnapshot()

resizeObserver.callback([
{ contentRect: { width: 0, height: 0 }, target: ref.current },
])
jest.runAllTimers()

expect(defaultChildrenFn).toHaveBeenCalledTimes(2)
expect(container.firstChild).toMatchSnapshot()
})

it('should handel bounds', () => {
render(<MeasureWith bounds />, container)
expect(container.firstChild).toMatchSnapshot()

resizeObserver.callback()
jest.runAllTimers()

expect(defaultChildrenFn).toHaveBeenCalledTimes(2)
expect(container.firstChild).toMatchSnapshot()
})

describe('resizeObserver', () => {
it('should trigger observe when measureRef is attached', () => {
render(<MeasureWith />, container)
expect(resizeObserver.observe).toHaveBeenCalledTimes(1)
})
it('should always un observer before observing next one', () => {
const ref = createRef()

render(<MeasureWith innerRef={ref} children={() => null} />, container)
expect(ref.current).toBe(null)

render(
<MeasureWith
innerRef={ref}
children={({ measureRef }) => (
<>
<div id={'child1'} ref={measureRef} />
<div id={'child2'} ref={measureRef} />
</>
)}
/>,
container
)
expect(resizeObserver.observe).toHaveBeenCalledTimes(2)
expect(resizeObserver.unobserve).toHaveBeenCalledTimes(1)

expect(resizeObserver.observe.mock.calls[0][0].id).toBe('child1')
expect(resizeObserver.unobserve.mock.calls[0][0].id).toBe('child1')
expect(resizeObserver.observe.mock.calls[1][0].id).toBe('child2')

expect(ref.current.id).toBe('child2')
})
it('should trigger onResize when resizeObserver callback is called', () => {
const onResize = jest.fn()

render(<MeasureWith onResize={onResize} />, container)
resizeObserver.callback()
jest.runAllTimers()

expect(onResize).toHaveBeenCalledTimes(1)
})
})
})
61 changes: 61 additions & 0 deletions src/__tests__/__snapshots__/Measure.test.js.snap
@@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Measure should handel bounds 1`] = `
<div>
{
"contentRect": {
"entry": {},
"client": {},
"offset": {},
"scroll": {},
"bounds": {},
"margin": {}
}
}
</div>
`;

exports[`Measure should handel bounds 2`] = `
<div>
{
"contentRect": {
"bounds": {
"top": 0,
"right": 0,
"bottom": 0,
"left": 0,
"width": 0,
"height": 0
}
}
}
</div>
`;

exports[`Measure should handel entry 1`] = `
<div>
{
"contentRect": {
"entry": {},
"client": {},
"offset": {},
"scroll": {},
"bounds": {},
"margin": {}
}
}
</div>
`;

exports[`Measure should handel entry 2`] = `
<div>
{
"contentRect": {
"entry": {
"width": 0,
"height": 0
}
}
}
</div>
`;
16 changes: 8 additions & 8 deletions src/with-content-rect.js
Expand Up @@ -72,22 +72,22 @@ function withContentRect(types) {
}

_handleRef = node => {
if (this._resizeObserver !== null) {
if (node !== null) {
this._resizeObserver.observe(node)
} else {
this._resizeObserver.unobserve(this._node)
}
if (this._resizeObserver !== null && this._node !== null) {
this._resizeObserver.unobserve(this._node)
}

this._node = node

if (this._resizeObserver !== null && this._node !== null) {
this._resizeObserver.observe(this._node)
}

const { innerRef } = this.props
if (innerRef) {
if (typeof innerRef === 'function') {
innerRef(node);
innerRef(this._node)
} else {
innerRef.current = node;
innerRef.current = this._node
}
}
}
Expand Down

0 comments on commit 2c0cd97

Please sign in to comment.