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 { useAccount } from './useAccount';
|
||||||
export { useAppDispatch } from './useAppDispatch';
|
export { useAppDispatch } from './useAppDispatch';
|
||||||
export { useAppSelector } from './useAppSelector';
|
export { useAppSelector } from './useAppSelector';
|
||||||
|
export { useDimensions } from './useDimensions';
|
||||||
export { useFeatures } from './useFeatures';
|
export { useFeatures } from './useFeatures';
|
||||||
export { useOnScreen } from './useOnScreen';
|
export { useOnScreen } from './useOnScreen';
|
||||||
export { useOwnAccount } from './useOwnAccount';
|
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": {
|
"devDependencies": {
|
||||||
"@testing-library/jest-dom": "^5.16.4",
|
"@testing-library/jest-dom": "^5.16.4",
|
||||||
|
"@testing-library/react-hooks": "^8.0.1",
|
||||||
"@testing-library/user-event": "^14.0.3",
|
"@testing-library/user-event": "^14.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.15.0",
|
"@typescript-eslint/eslint-plugin": "^5.15.0",
|
||||||
"@typescript-eslint/parser": "^5.15.0",
|
"@typescript-eslint/parser": "^5.15.0",
|
||||||
|
|
15
yarn.lock
15
yarn.lock
|
@ -2329,6 +2329,14 @@
|
||||||
lodash "^4.17.15"
|
lodash "^4.17.15"
|
||||||
redent "^3.0.0"
|
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":
|
"@testing-library/react@^12.1.4":
|
||||||
version "12.1.4"
|
version "12.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.4.tgz#09674b117e550af713db3f4ec4c0942aa8bbf2c0"
|
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"
|
object-assign "^4.1.1"
|
||||||
scheduler "^0.20.2"
|
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:
|
react-event-listener@^0.6.0:
|
||||||
version "0.6.6"
|
version "0.6.6"
|
||||||
resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.6.6.tgz#758f7b991cad9086dd39fd29fad72127e1d8962a"
|
resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.6.6.tgz#758f7b991cad9086dd39fd29fad72127e1d8962a"
|
||||||
|
|
Ładowanie…
Reference in New Issue