Skip to content

Instantly share code, notes, and snippets.

@dagda1 dagda1/parentSize.ts
Created Mar 10, 2019

Embed
What would you like to do?
import React, { useState, useLayoutEffect, useCallback } from 'react';
import ResizeObserver from 'resize-observer-polyfill';
export interface ParentSizeState {
height: number;
width: number;
left: number;
top: number;
}
export interface ParentSizeResult {
ref: React.RefObject<HTMLDivElement>;
resize: (dimensions: ParentSizeState) => void;
}
export interface Dimensions {
width: number;
height: number;
}
type Transform = (dimensions: Dimensions) => Dimensions;
const identityTransform: Transform = (dimensions: Dimensions) => dimensions;
export interface ParentSizeProps {
ref: React.RefObject<HTMLDivElement>;
debounceTime: number;
transformFunc: ({ width, height }: Dimensions) => Dimensions;
}
function getSize(el: HTMLElement | null, transformFunc: Transform = identityTransform): Dimensions {
if (!el) {
return transformFunc({
width: 0,
height: 0
});
}
const { width, height } = el.getBoundingClientRect();
return transformFunc({
width,
height
});
}
export const useParentSize = ({ ref, debounceTime, transformFunc }: ParentSizeProps) => {
const [ParentSize, setParentSize] = useState(getSize(ref.current, transformFunc));
const handleResize = useCallback(() => {
if (ref.current) {
setParentSize(getSize(ref.current, transformFunc));
}
// tslint:disable-next-line
}, [ref]);
useLayoutEffect(() => {
let resizeObserver: ResizeObserver | null = new ResizeObserver(() => handleResize());
if (!ref.current) {
return;
}
resizeObserver.observe(ref.current);
return () => {
if (!resizeObserver) {
return;
}
resizeObserver.disconnect();
resizeObserver = null;
};
// tslint:disable-next-line
}, [ref]);
return ParentSize;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.