sforkowany z mirror/soapbox
Add "useDimensions" hook
rodzic
8039772d05
commit
bdee28fd07
|
@ -0,0 +1,76 @@
|
|||
import { renderHook, act } from '@testing-library/react-hooks';
|
||||
|
||||
import { useDimensions } from '../useDimensions';
|
||||
|
||||
let listener: ((rect: any) => void) | undefined = undefined;
|
||||
|
||||
(window as any).ResizeObserver = class ResizeObserver {
|
||||
constructor(ls) {
|
||||
listener = ls;
|
||||
}
|
||||
|
||||
observe() {}
|
||||
disconnect() {}
|
||||
};
|
||||
|
||||
describe('useDimensions()', () => {
|
||||
it('defaults to 0', () => {
|
||||
const { result } = renderHook(() => useDimensions());
|
||||
|
||||
act(() => {
|
||||
const div = document.createElement('div');
|
||||
(result.current[0] as any)(div);
|
||||
});
|
||||
|
||||
expect(result.current[1]).toMatchObject({
|
||||
width: 0,
|
||||
height: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('measures the dimensions of a DOM element', () => {
|
||||
const { result } = renderHook(() => useDimensions());
|
||||
|
||||
act(() => {
|
||||
const div = document.createElement('div');
|
||||
(result.current[0] as any)(div);
|
||||
});
|
||||
|
||||
act(() => {
|
||||
listener!([
|
||||
{
|
||||
contentRect: {
|
||||
width: 200,
|
||||
height: 200,
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
expect(result.current[1]).toMatchObject({
|
||||
width: 200,
|
||||
height: 200,
|
||||
});
|
||||
});
|
||||
|
||||
it('disconnects on unmount', () => {
|
||||
const disconnect = jest.fn();
|
||||
(window as any).ResizeObserver = class ResizeObserver {
|
||||
observe() {}
|
||||
disconnect() {
|
||||
disconnect();
|
||||
}
|
||||
};
|
||||
|
||||
const { result, unmount } = renderHook(() => useDimensions());
|
||||
|
||||
act(() => {
|
||||
const div = document.createElement('div');
|
||||
(result.current[0] as any)(div);
|
||||
});
|
||||
|
||||
expect(disconnect).toHaveBeenCalledTimes(0);
|
||||
unmount();
|
||||
expect(disconnect).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
|
@ -1,6 +1,7 @@
|
|||
export { useAccount } from './useAccount';
|
||||
export { useAppDispatch } from './useAppDispatch';
|
||||
export { useAppSelector } from './useAppSelector';
|
||||
export { useDimensions } from './useDimensions';
|
||||
export { useFeatures } from './useFeatures';
|
||||
export { useOnScreen } from './useOnScreen';
|
||||
export { useOwnAccount } from './useOwnAccount';
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
import { Ref, useEffect, useMemo, useState } from 'react';
|
||||
|
||||
type UseDimensionsRect = { width: number, height: number };
|
||||
type UseDimensionsResult = [Ref<HTMLDivElement>, any]
|
||||
|
||||
const defaultState: UseDimensionsRect = {
|
||||
width: 0,
|
||||
height: 0,
|
||||
};
|
||||
|
||||
const useDimensions = (): UseDimensionsResult => {
|
||||
const [element, ref] = useState<Element | null>(null);
|
||||
const [rect, setRect] = useState<UseDimensionsRect>(defaultState);
|
||||
|
||||
const observer = useMemo(
|
||||
() =>
|
||||
new (window as any).ResizeObserver((entries: any) => {
|
||||
if (entries[0]) {
|
||||
const { width, height } = entries[0].contentRect;
|
||||
setRect({ width, height });
|
||||
}
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
useEffect((): any => {
|
||||
if (!element) return null;
|
||||
observer.observe(element);
|
||||
|
||||
return () => {
|
||||
observer.disconnect();
|
||||
};
|
||||
}, [element]);
|
||||
|
||||
return [ref, rect];
|
||||
};
|
||||
|
||||
export { useDimensions };
|
|
@ -202,6 +202,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "^5.16.4",
|
||||
"@testing-library/react-hooks": "^8.0.1",
|
||||
"@testing-library/user-event": "^14.0.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.15.0",
|
||||
"@typescript-eslint/parser": "^5.15.0",
|
||||
|
|
15
yarn.lock
15
yarn.lock
|
@ -2329,6 +2329,14 @@
|
|||
lodash "^4.17.15"
|
||||
redent "^3.0.0"
|
||||
|
||||
"@testing-library/react-hooks@^8.0.1":
|
||||
version "8.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react-hooks/-/react-hooks-8.0.1.tgz#0924bbd5b55e0c0c0502d1754657ada66947ca12"
|
||||
integrity sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
react-error-boundary "^3.1.0"
|
||||
|
||||
"@testing-library/react@^12.1.4":
|
||||
version "12.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.4.tgz#09674b117e550af713db3f4ec4c0942aa8bbf2c0"
|
||||
|
@ -9616,6 +9624,13 @@ react-dom@^17.0.2:
|
|||
object-assign "^4.1.1"
|
||||
scheduler "^0.20.2"
|
||||
|
||||
react-error-boundary@^3.1.0:
|
||||
version "3.1.4"
|
||||
resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
|
||||
integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.5"
|
||||
|
||||
react-event-listener@^0.6.0:
|
||||
version "0.6.6"
|
||||
resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.6.6.tgz#758f7b991cad9086dd39fd29fad72127e1d8962a"
|
||||
|
|
Ładowanie…
Reference in New Issue