react-dom-resize-observer
Advanced tools
Comparing version 0.2.0 to 0.2.1
"use strict"; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
@@ -8,13 +24,20 @@ Object.defineProperty(exports, "__esModule", { value: true }); | ||
const react_1 = require("@testing-library/react"); | ||
const react_2 = __importDefault(require("react")); | ||
const react_2 = __importStar(require("react")); | ||
let mockObserve = jest.fn(); | ||
let mockDisconnect = jest.fn(); | ||
let mockUnobserve = jest.fn(); | ||
let mockOnResize = jest.fn((el) => el); | ||
let mockObserverCallback = jest.fn((entries, observer) => { | ||
return entries; | ||
}); | ||
class ResizeObserver { | ||
observe() { | ||
mockObserve(); | ||
constructor(callback) { | ||
mockObserverCallback = callback; | ||
} | ||
unobserve() { | ||
mockUnobserve(); | ||
observe(target) { | ||
mockObserve(target); | ||
} | ||
unobserve(target, options) { | ||
mockUnobserve(target, options); | ||
} | ||
disconnect() { | ||
@@ -26,8 +49,27 @@ mockDisconnect(); | ||
const MockComponent = (props) => { | ||
const result = (0, useResizeObserver_1.useResizeObserver)(props.elementRef); | ||
var _a; | ||
const elRef = (0, react_2.useRef)(null); | ||
const result = (0, useResizeObserver_1.useResizeObserver)({ | ||
elementRef: props.elementRef === true ? elRef : undefined, | ||
onResize: el => { | ||
mockOnResize(el); | ||
} | ||
}); | ||
if (props.elementRef === null) | ||
return <div>Mock</div>; | ||
return (<div> | ||
<div ref={props.elementRef === undefined ? result.observer : undefined}> | ||
Mock | ||
</div> | ||
<button onClick={result.disconnect}>Disconnect</button> | ||
<div ref={props.elementRef === true ? elRef : result.observe}>Mock</div> | ||
<button onClick={() => { | ||
if (result.disconnect) | ||
result.disconnect(); | ||
if (result.unobserve) | ||
result.unobserve(); | ||
}}> | ||
Disconnect | ||
</button> | ||
{((_a = result.entry) === null || _a === void 0 ? void 0 : _a.contentBoxSize) && (<div> | ||
<div>Entry</div> | ||
<div>{result.entry.contentBoxSize[0].blockSize}</div> | ||
<div>{result.entry.contentBoxSize[0].inlineSize}</div> | ||
</div>)} | ||
</div>); | ||
@@ -41,16 +83,64 @@ }; | ||
}); | ||
it("does nothing without an element", () => { | ||
const { rerender } = (0, react_1.render)(<MockComponent elementRef={null}/>); | ||
expect(mockUnobserve).not.toHaveBeenCalled(); | ||
expect(mockDisconnect).not.toHaveBeenCalled(); | ||
expect(mockObserve).not.toHaveBeenCalled(); | ||
}); | ||
it("does not render an entry if none returned", () => { | ||
const { rerender, getByText } = (0, react_1.render)(<MockComponent />); | ||
(0, react_1.act)(() => { | ||
mockObserverCallback([], new ResizeObserver(mockObserverCallback)); | ||
}); | ||
rerender(<MockComponent />); | ||
expect(() => getByText("Entry")).toThrow(); | ||
}); | ||
it("observes the DOM element passed into the observer callback.", () => { | ||
(0, react_1.render)(<MockComponent />); | ||
const { rerender, getByText } = (0, react_1.render)(<MockComponent />); | ||
// Pretend a user has resized the element, calling the observer. | ||
(0, react_1.act)(() => { | ||
mockObserverCallback( | ||
// Add a new entry | ||
[ | ||
{ | ||
contentBoxSize: [{ inlineSize: 500, blockSize: 900 }], | ||
borderBoxSize: [], | ||
contentRect: {} | ||
} | ||
], new ResizeObserver(mockObserverCallback)); | ||
}); | ||
rerender(<MockComponent />); | ||
expect(mockObserve).toHaveBeenCalledTimes(1); | ||
// The observe callback was called on the dom ref attribute. | ||
expect(mockObserve).toHaveBeenCalledWith(expect.any(Element)); | ||
expect(() => getByText("500")).not.toThrow(); | ||
expect(() => getByText("900")).not.toThrow(); | ||
}); | ||
it("observes the DOM element reference passed as a parameter.", () => { | ||
const elRef = { current: document.createElement("div") }; | ||
(0, react_1.render)(<MockComponent elementRef={elRef}/>); | ||
const { rerender, getByText } = (0, react_1.render)(<MockComponent elementRef={true}/>); | ||
// Pretend a user has resized the element, calling the observer. | ||
(0, react_1.act)(() => { | ||
mockObserverCallback( | ||
// Add a new entry | ||
[ | ||
{ | ||
contentBoxSize: [{ inlineSize: 500, blockSize: 900 }], | ||
borderBoxSize: [], | ||
contentRect: {} | ||
} | ||
], new ResizeObserver(mockObserverCallback)); | ||
}); | ||
rerender(<MockComponent elementRef={true}/>); | ||
expect(mockObserve).toHaveBeenCalledTimes(1); | ||
// An element was passed directly into the hook and is using that ref. | ||
expect(mockObserve).toHaveBeenCalledWith(expect.any(Element)); | ||
expect(() => getByText("500")).not.toThrow(); | ||
expect(() => getByText("900")).not.toThrow(); | ||
}); | ||
it("disconnects when callback invoked", () => { | ||
it("calls disconnect and unobserve onClick", () => { | ||
const { getByText, rerender } = (0, react_1.render)(<MockComponent />); | ||
// The disconnect callback implementation uses a ref. rerender to get the next update. | ||
rerender(<MockComponent />); | ||
react_1.fireEvent.click(getByText("Disconnect")); | ||
expect(mockUnobserve).toHaveBeenCalledTimes(1); | ||
expect(mockDisconnect).toHaveBeenCalledTimes(1); | ||
@@ -60,2 +150,3 @@ }); | ||
const { unmount } = (0, react_1.render)(<MockComponent />); | ||
expect(mockDisconnect).toHaveBeenCalledTimes(0); | ||
unmount(); | ||
@@ -66,152 +157,10 @@ expect(mockDisconnect).toHaveBeenCalledTimes(1); | ||
const { unmount } = (0, react_1.render)(<MockComponent />); | ||
expect(mockUnobserve).toHaveBeenCalledTimes(0); | ||
unmount(); | ||
expect(mockUnobserve).toHaveBeenCalledTimes(1); | ||
}); | ||
it("returns the entry from the observer callback", () => { | ||
let observerCallback = entries => { | ||
return entries; | ||
}; | ||
class ResizeObserver { | ||
constructor(callback) { | ||
observerCallback = callback; | ||
} | ||
observe() { } | ||
disconnect() { } | ||
unobserve() { } | ||
} | ||
window.ResizeObserver = ResizeObserver; | ||
const { result, rerender } = (0, react_1.renderHook)(() => (0, useResizeObserver_1.useResizeObserver)()); | ||
(0, react_1.act)(() => { | ||
const el = document.createElement("div"); | ||
result.current.observer(el); | ||
}); | ||
(0, react_1.act)(() => { | ||
observerCallback([ | ||
{ | ||
contentBoxSize: [ | ||
{ | ||
blockSize: 0, | ||
inlineSize: 0 | ||
} | ||
], | ||
contentRect: { | ||
bottom: 0, | ||
height: 0, | ||
left: 0, | ||
right: 0, | ||
top: 0, | ||
width: 0, | ||
x: 0, | ||
y: 0 | ||
}, | ||
target: <div /> | ||
} | ||
], new ResizeObserver(observerCallback)); | ||
}); | ||
rerender(); | ||
expect(result.current.entry).toEqual({ | ||
contentBoxSize: [ | ||
{ | ||
blockSize: 0, | ||
inlineSize: 0 | ||
} | ||
], | ||
contentRect: { | ||
bottom: 0, | ||
height: 0, | ||
left: 0, | ||
right: 0, | ||
top: 0, | ||
width: 0, | ||
x: 0, | ||
y: 0 | ||
}, | ||
target: <div /> | ||
}); | ||
}); | ||
it("calls onResize callback if there are entries", () => { | ||
let observerCallback = entries => { | ||
return entries; | ||
}; | ||
class ResizeObserver { | ||
constructor(callback) { | ||
observerCallback = callback; | ||
} | ||
observe() { } | ||
disconnect() { } | ||
unobserve() { } | ||
} | ||
window.ResizeObserver = ResizeObserver; | ||
const mockOnResize = jest.fn(); | ||
const { result } = (0, react_1.renderHook)(() => (0, useResizeObserver_1.useResizeObserver)(undefined, mockOnResize)); | ||
(0, react_1.act)(() => { | ||
const el = document.createElement("div"); | ||
result.current.observer(el); | ||
}); | ||
(0, react_1.act)(() => { | ||
observerCallback([ | ||
{ | ||
contentBoxSize: [ | ||
{ | ||
blockSize: 0, | ||
inlineSize: 0 | ||
} | ||
], | ||
contentRect: { | ||
bottom: 0, | ||
height: 0, | ||
left: 0, | ||
right: 0, | ||
top: 0, | ||
width: 0, | ||
x: 0, | ||
y: 0 | ||
}, | ||
target: <div /> | ||
} | ||
], new ResizeObserver(observerCallback)); | ||
}); | ||
it("calls onResize with the element", () => { | ||
(0, react_1.render)(<MockComponent />); | ||
expect(mockOnResize).toHaveBeenCalledTimes(1); | ||
expect(mockOnResize).toHaveBeenCalledWith({ | ||
contentBoxSize: [ | ||
{ | ||
blockSize: 0, | ||
inlineSize: 0 | ||
} | ||
], | ||
contentRect: { | ||
bottom: 0, | ||
height: 0, | ||
left: 0, | ||
right: 0, | ||
top: 0, | ||
width: 0, | ||
x: 0, | ||
y: 0 | ||
}, | ||
target: <div /> | ||
}); | ||
expect(mockOnResize).toHaveBeenCalledWith(expect.any(HTMLDivElement)); | ||
}); | ||
it("returns a null entry and does not call onResize if no rentries were called back", () => { | ||
let observerCallback = () => { }; | ||
class ResizeObserver { | ||
constructor(callback) { | ||
observerCallback = callback; | ||
} | ||
observe() { } | ||
disconnect() { } | ||
unobserve() { } | ||
} | ||
window.ResizeObserver = ResizeObserver; | ||
const mockOnResize = jest.fn(); | ||
const { result } = (0, react_1.renderHook)(() => (0, useResizeObserver_1.useResizeObserver)(undefined, mockOnResize)); | ||
(0, react_1.act)(() => { | ||
const el = document.createElement("div"); | ||
result.current.observer(el); | ||
}); | ||
(0, react_1.act)(() => { | ||
observerCallback([], new ResizeObserver(observerCallback)); | ||
}); | ||
expect(result.current.entry).toBeNull(); | ||
expect(mockOnResize).not.toHaveBeenCalled(); | ||
}); |
import React from "react"; | ||
export declare function useResizeObserver<T extends Element | null>(elementRef?: React.MutableRefObject<T>, onResize?: (entry: ResizeObserverEntry) => void): { | ||
/** | ||
* useResizeObserver is an abstraction to subscribe an element to the ResizeObserver API. | ||
* This hook internally uses only `useRef` and will not trigger a re-render. | ||
*/ | ||
export declare function useResizeObserver<T extends Element | null>(params?: { | ||
elementRef?: React.MutableRefObject<T>; | ||
onResize?: (el: T) => void; | ||
}): { | ||
entry: ResizeObserverEntry | null; | ||
observer: (el: T) => void; | ||
disconnect: () => void; | ||
observe: (el: T) => void; | ||
disconnect?: (() => void) | null; | ||
unobserve?: (() => void) | null; | ||
}; | ||
//# sourceMappingURL=useResizeObserver.d.ts.map |
@@ -5,52 +5,62 @@ "use strict"; | ||
const react_1 = require("react"); | ||
function useResizeObserver(elementRef, onResize) { | ||
/** | ||
* useResizeObserver is an abstraction to subscribe an element to the ResizeObserver API. | ||
* This hook internally uses only `useRef` and will not trigger a re-render. | ||
*/ | ||
function useResizeObserver(params) { | ||
/** A local element reference to set if they did not pass one. */ | ||
const currentElement = (0, react_1.useRef)(null); | ||
/** The resize observer instance */ | ||
const resizeObserver = (0, react_1.useRef)(null); | ||
/** The actual observer entry returned on resize. */ | ||
const observerEntry = (0, react_1.useRef)(null); | ||
const disconnect = (0, react_1.useRef)(() => { | ||
/** Initialized as a no-op */ | ||
}); | ||
const unobserve = (0, react_1.useRef)(() => { | ||
/** Initialized as a no-op */ | ||
}); | ||
/** Ref to close over the disconnect. */ | ||
const disconnect = (0, react_1.useRef)(null); | ||
/** Ref to close over the unobserve and its element. */ | ||
const unobserve = (0, react_1.useRef)(null); | ||
/** If they pass their own ref, set it to the current element */ | ||
(0, react_1.useEffect)(() => { | ||
var _a; | ||
if (((_a = params === null || params === void 0 ? void 0 : params.elementRef) === null || _a === void 0 ? void 0 : _a.current) !== undefined && | ||
params.elementRef.current !== null) | ||
currentElement.current = params.elementRef.current; | ||
}, [params === null || params === void 0 ? void 0 : params.elementRef]); | ||
/** Callback with the same signature as an elements `ref` attribute. */ | ||
const observer = (0, react_1.useCallback)((el) => { | ||
const observe = (0, react_1.useCallback)((el) => { | ||
if (el === null) | ||
return; | ||
resizeObserver.current = new ResizeObserver(entries => { | ||
currentElement.current = el; | ||
}, []); | ||
(0, react_1.useEffect)(() => { | ||
const el = currentElement.current; | ||
if (el === null) | ||
return; | ||
const resize = (resizeObserver.current = new ResizeObserver(entries => { | ||
if (entries.length === 0) | ||
return; | ||
observerEntry.current = entries[0]; | ||
if (onResize) { | ||
onResize(entries[0]); | ||
} | ||
}); | ||
resizeObserver.current.observe(el); | ||
})); | ||
resize.observe(el); | ||
disconnect.current = () => { | ||
var _a; | ||
(_a = resizeObserver.current) === null || _a === void 0 ? void 0 : _a.disconnect(); | ||
resize.disconnect(); | ||
}; | ||
unobserve.current = () => { | ||
var _a; | ||
(_a = resizeObserver.current) === null || _a === void 0 ? void 0 : _a.unobserve(el); | ||
resize.unobserve(el); | ||
}; | ||
}, [onResize]); | ||
/** If they have provided a ref of their own, set it the observer here. */ | ||
(0, react_1.useEffect)(() => { | ||
if ((elementRef === null || elementRef === void 0 ? void 0 : elementRef.current) === undefined || elementRef.current === null) | ||
return; | ||
observer(elementRef.current); | ||
}, [observer, elementRef]); | ||
/** Unobserve and disconnect when unmounted. */ | ||
(0, react_1.useEffect)(() => { | ||
return () => { | ||
unobserve.current(); | ||
disconnect.current(); | ||
resize.disconnect(); | ||
resize.unobserve(el); | ||
}; | ||
}, []); | ||
(0, react_1.useEffect)(() => { | ||
if (currentElement.current && (params === null || params === void 0 ? void 0 : params.onResize)) | ||
params.onResize(currentElement.current); | ||
}, [params]); | ||
return { | ||
entry: observerEntry.current, | ||
observer, | ||
disconnect: disconnect.current | ||
observe, | ||
disconnect: disconnect.current, | ||
unobserve: unobserve.current | ||
}; | ||
} | ||
exports.useResizeObserver = useResizeObserver; |
{ | ||
"name": "react-dom-resize-observer", | ||
"version": "0.2.0", | ||
"version": "0.2.1", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
@@ -29,8 +29,7 @@ # React Resize Observer | ||
unobserve | ||
} = useResizeObserver<HTMLDivElement>(onResize) | ||
const { entry, disconnect, unobserve, observe } = | ||
} = | ||
useResizeObserver<HTMLDivElement | null>({ | ||
// You can optionally pass your own ref if you already have one. | ||
elementRef: ref, | ||
// You can optionally pass a callback to access the raw DOM element on resize. | ||
onResize: (el) => { /** Do something with the element... */ }, | ||
@@ -37,0 +36,0 @@ }); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
15015
293
46
1