import React, { ReactNode, createContext, useContext, useEffect, useMemo, useState, } from 'react'; import { Dimensions, ScaledSize } from 'react-native'; const guidelineBaseWidth = 350; const guidelineBaseHeight = 680; enum ORIENTATION { PORTRAIT = 'portrait', LANDSCAPE = 'landscape', } interface ScaleFunctions { horizontalScale: (size: number) => number; verticalScale: (size: number) => number; moderateHorizontalScale: (size: number, factor?: number) => number; moderateVerticalScale: (size: number, factor?: number) => number; } interface DimensionsContext { orientation: ORIENTATION; dimensions: ScaledSize; responsive: ScaleFunctions; } const createScaleFunctions = (dimensionsIn: ScaledSize) => { const horizontalScale = (size: number) => (dimensionsIn.width / guidelineBaseWidth) * size; const verticalScale = (size: number) => (dimensionsIn.height / guidelineBaseHeight) * size; const moderateHorizontalScale = (size: number, factor = 0.5) => size + (horizontalScale(size) - size) * factor; const moderateVerticalScale = (size: number, factor = 0.5) => size + (verticalScale(size) - size) * factor; return { horizontalScale, verticalScale, moderateHorizontalScale, moderateVerticalScale, }; }; const DimensionsContext = createContext( undefined, ); const DimensionsProvider = ({ children }: { children: ReactNode }) => { const [dimensions, setDimensions] = useState(Dimensions.get('window')); const orientation = useMemo(() => { return dimensions.width > dimensions.height ? ORIENTATION.LANDSCAPE : ORIENTATION.PORTRAIT; }, [dimensions]); const responsiveScale = createScaleFunctions(dimensions); useEffect(() => { const onChange = ({ window }: { window: ScaledSize }) => { setDimensions(window); }; const subscription = Dimensions.addEventListener('change', onChange); return () => { subscription.remove(); }; }, []); return ( {children} ); }; const useDimensions = (): DimensionsContext => { const context = useContext(DimensionsContext); if (!context) { throw new Error('useDimensions must be used within a DimensionsProvider'); } return context; }; export { ORIENTATION, DimensionsProvider, useDimensions };