DEV Community

loading...

React Native Responsive UI

ajmal_hasan profile image Ajmal Hasan Updated on ・2 min read
import { useEffect, useState } from 'react';
import { Dimensions, PixelRatio, Platform } from 'react-native';

const {
    width: SCREEN_WIDTH,
    height: SCREEN_HEIGHT,
} = Dimensions.get('window');

//FONT SCALING - provide the pixel as:
//Usage: nf(16)
const scale = SCREEN_HEIGHT / 667;
const normalizeFont = (size) => Math.round(PixelRatio.roundToNearestPixel(size * scale))


//DYNAMIC DIMENSION AS PER PERCENTAGE:   
//Usage: wp(5), hp(20)
const widthPercentageToDP = widthPercent => {
    // Convert string input to decimal number
    const elemWidth = parseFloat(widthPercent);
    return PixelRatio.roundToNearestPixel(SCREEN_WIDTH * elemWidth / 100);
};

const heightPercentageToDP = heightPercent => {
    // Convert string input to decimal number
    const elemHeight = parseFloat(heightPercent);
    return PixelRatio.roundToNearestPixel(SCREEN_HEIGHT * elemHeight / 100);
};

//DYNAMIC DIMENSION AS PER PIXELS:   
//Usage: wpx(141), hpx(220)
const widthFromPixel = (widthPx, w = 375) => {
    const scale = SCREEN_WIDTH / w;
    const newSize = widthPx * scale
    return newSize
};

const heightFromPixel = (heightPx, h = 667) => {
    const scale = SCREEN_HEIGHT / h;
    const newSize = heightPx * scale
    return newSize
};


export {
    normalizeFont as nf,
    widthPercentageToDP as wp,
    heightPercentageToDP as hp,
    widthFromPixel as wpx,
    heightFromPixel as hpx,
};

USAGE:
import { hp, wp, hpx, wpx, nf, Fonts } from '../../constants/constants'



/**
 * A React Hook which updates when the orientation changes
 * @returns whether the user is in 'PORTRAIT' or 'LANDSCAPE'
 */

const isPortrait = () => {
    const dimMode = Dimensions.get('screen');
    return dimMode.height >= dimMode.width;
};

export const useOrientation = () => {
    // State to hold the connection status
    const [orientation, setOrientation] = useState(
        isPortrait() ? true : false,
    );
    const [height, setHeight] = useState(
        isPortrait() ? 667 : 375,
    );
    const [width, setWidth] = useState(
        isPortrait() ? 375 : 667,
    );
    const [fontPixel, setFontPixel] = useState(
        Dimensions.get('screen').width < 425 ? 1 : 1.5
    );

    useEffect(() => {
        const callback = () => {
            setOrientation(isPortrait() ? true : false)
            setHeight(isPortrait() ? 667 : 375)
            setWidth(isPortrait() ? 375 : 667)
            setFontPixel(Dimensions.get('screen').width < 425 ? 1 : 1.5)
        };

        Dimensions.addEventListener('change', callback);

        return () => {
            Dimensions.removeEventListener('change', callback);
        };
    }, []);

    return { orientation, height, width, fontPixel };
}

export const useOrientationHeight = (h) => {

    const screenHeight = Dimensions.get('window').height
    const screenWidth = Dimensions.get('window').width
    if (isPortrait()) {
        return (h / 667) * screenHeight
    } else {
        return (h / 375) * screenWidth
    }

}

export const useOrientationWidth = (w) => {

    const screenHeight = Dimensions.get('window').height
    const screenWidth = Dimensions.get('window').width
    if (isPortrait()) {
        return (w / 375) * screenWidth
    } else {
        return (w / 667) * screenHeight
    }
}
// USAGE:   
// const orientation = useOrientation();       returns-> true or false
// vertical calculation ==> "orientation ? oh(50) : ow(30)"
// horizontal calculation ==> "orientation ? ow(50) : oh(30)"

Enter fullscreen mode Exit fullscreen mode

Discussion (0)

Forem Open with the Forem app