stream-chat-react-native-core
Version:
The official React Native and Expo components for Stream Chat, a service for building chat applications
55 lines (47 loc) • 1.87 kB
text/typescript
import { useCallback, useEffect, useState } from 'react';
import { Dimensions, ScaledSize } from 'react-native';
/**
* A custom hook that provides functions to calculate dimensions based on
* a percentage of the screen height (vh) and viewport width (vw). It
* dynamically updates dimensions on changes in device orientation.
*
* @returns {Object} An object containing functions vh and vw.
*/
export const useScreenDimensions = (rounded?: boolean) => {
const [screenDimensions, setScreenDimensions] = useState(() => Dimensions.get('screen'));
useEffect(() => {
const handleChange = ({ screen }: { screen: ScaledSize }) => {
setScreenDimensions((prev) => {
const { height, width } = screen;
if (prev.height !== height || prev.width !== width) {
return screen;
}
return prev;
});
};
const subscription = Dimensions.addEventListener('change', handleChange);
// We might have missed an update between calling `get` in render and
// `addEventListener` in this handler, so we set it here. If there was
// no change, React will filter out this update as a no-op.
// pattern ref: react-native-repo/packages/react-native/Libraries/Utilities/useWindowDimensions.js
handleChange({ screen: Dimensions.get('screen') });
return () => {
subscription.remove();
};
}, []);
const vw = useCallback(
(percentageWidth: number) => {
const value = screenDimensions.width * (percentageWidth / 100);
return rounded ? Math.round(value) : value;
},
[rounded, screenDimensions.width],
);
const vh = useCallback(
(percentageHeight: number) => {
const value = screenDimensions.height * (percentageHeight / 100);
return rounded ? Math.round(value) : value;
},
[rounded, screenDimensions.height],
);
return { vh, vw };
};