UNPKG

@raahimkhan23/react-native-responsive-utils

Version:

A lightweight utility package for making React Native apps responsive across different screen sizes. It allows you to scale widths, heights, fonts, and images based on a configurable base screen size, enabling consistent layouts on different devices. The

186 lines (165 loc) 6.26 kB
"use strict"; /** * imports relevant libraries */ import { Dimensions, PixelRatio } from 'react-native'; /** * imports relevant types */ /** * base screen width and height (iPhone 16 Pro Portrait mode) */ let BASE_SCREEN_WIDTH = 402; let BASE_SCREEN_HEIGHT = 874; /** * retrieves and stores the device's initial screen dimensions (width and height) */ const { width: initialScreenWidth, height: initialScreenHeight } = Dimensions.get('window'); let CURRENT_SCREEN_WIDTH = initialScreenWidth; let CURRENT_SCREEN_HEIGHT = initialScreenHeight; /** * updates the base screen width and height used for scaling * @param width - the new base screen width * @param height - the new base screen height */ const setBaseScreenSize = (width, height) => { BASE_SCREEN_WIDTH = width; BASE_SCREEN_HEIGHT = height; }; /** * holds the subscription reference for the orientation change listener */ let orientationListenerSubscription; /** * listens for orientation changes and updates the orientation state accordingly * @param setOrientation - React setState function to update orientation ('portrait' or 'landscape') * @returns void */ const listenOrientationChange = setOrientation => { orientationListenerSubscription = Dimensions.addEventListener('change', newDimensions => { CURRENT_SCREEN_WIDTH = newDimensions.window.width; CURRENT_SCREEN_HEIGHT = newDimensions.window.height; setOrientation(CURRENT_SCREEN_WIDTH < CURRENT_SCREEN_HEIGHT ? 'portrait' : 'landscape'); }); }; /** * removes the orientation change listener if it exists * @returns void */ const removeOrientationListener = () => { if (orientationListenerSubscription) { orientationListenerSubscription.remove(); } }; /** * scales a given width based on the current screen width and base screen width * @param width - the original width to scale * @returns the scaled width */ const scaleWidth = width => { return width * CURRENT_SCREEN_WIDTH / BASE_SCREEN_WIDTH; }; /** * scales a given height based on the current screen height and base screen height * @param height - the original height to scale * @returns the scaled height */ const scaleHeight = height => { return height * CURRENT_SCREEN_HEIGHT / BASE_SCREEN_HEIGHT; }; /** * scales a given image width based on the current screen width and base screen width, rounded to the nearest pixel * @param width - the original image width to scale * @returns the scaled image width */ const scaleImageWidth = width => { const scaledWidth = width * CURRENT_SCREEN_WIDTH / BASE_SCREEN_WIDTH; return PixelRatio.roundToNearestPixel(scaledWidth); }; /** * scales a given image height based on the scaled image width and original aspect ratio, rounded to the nearest pixel * @param width - the original image width (to determine the aspect ratio) * @param height - the original image height to scale * @returns the scaled image height */ const scaleImageHeight = (width, height) => { // scale width first const scaledWidth = scaleImageWidth(width); // calculate aspect ratio const aspectRatio = width / height; // adjust height based on the aspect ratio return PixelRatio.roundToNearestPixel(scaledWidth / aspectRatio); }; /** * minimum and maximum clamping values for font scaling */ let MIN_FONT_SCALE = 0; let MAX_FONT_SCALE = 0; /** * updates the minimum and maximum limits for font scaling clamp values * @param minFontScale - minimum scale clamp for fonts * @param maxFontScale - maximum scale clamp for fonts */ const setFontScaleLimits = (minFontScale, maxFontScale) => { MIN_FONT_SCALE = minFontScale; MAX_FONT_SCALE = maxFontScale; }; /** * scales a given font size based on the smaller screen dimension with clamping, rounded to the nearest pixel * @param fontSize - the original font size * @returns the scaled and clamped font size */ const scaleFont = fontSize => { // calculate the scale factor using the smaller dimension ratio of current and base screens const scaleDimension = Math.min(CURRENT_SCREEN_WIDTH, CURRENT_SCREEN_HEIGHT) / Math.min(BASE_SCREEN_WIDTH, BASE_SCREEN_HEIGHT); // scale the font size const scaledSize = fontSize * scaleDimension; // clamp the scaled font size const scaledSizeWithClamp = Math.max(fontSize - MIN_FONT_SCALE, Math.min(fontSize + MAX_FONT_SCALE, scaledSize)); // return the scaled font size to the nearest pixel return PixelRatio.roundToNearestPixel(scaledSizeWithClamp); }; /** * defines supported iPhone models for dimension comparison */ /** * stores the longest side (height in portrait, width in landscape) for each iPhone model defined above */ const modelLongestSide = { iPhoneSE: 667, iPhone13Mini: 812, iPhone16Pro: 874, iPhone16ProMax: 956 }; /** * checks if the current device's longest side matches the given iPhone model longest side * @param model - the iPhone model name * @returns true if current screen's longest side matches the given iPhone model's longest side, otherwise false */ const isIphoneModel = model => { return (CURRENT_SCREEN_WIDTH < CURRENT_SCREEN_HEIGHT ? CURRENT_SCREEN_HEIGHT : CURRENT_SCREEN_WIDTH) === modelLongestSide[model]; }; /** * converts the given width percentage to device independent pixels (dp) * @param widthPercent - percentage of the screen's width (0 – 100) * @returns the corresponding dp based on the current device's screen width */ const wp = widthPercent => { return PixelRatio.roundToNearestPixel(CURRENT_SCREEN_WIDTH * widthPercent / 100); }; /** * converts the given height percentage to device independent pixels (dp) * @param heightPercent - percentage of the screen's height (0 – 100) * @returns the corresponding dp based on the current device's screen height */ const hp = heightPercent => { return PixelRatio.roundToNearestPixel(CURRENT_SCREEN_HEIGHT * heightPercent / 100); }; /** * exports constants and utility functions */ export { BASE_SCREEN_WIDTH, BASE_SCREEN_HEIGHT, CURRENT_SCREEN_WIDTH, CURRENT_SCREEN_HEIGHT, MIN_FONT_SCALE, MAX_FONT_SCALE, setBaseScreenSize, listenOrientationChange, removeOrientationListener, scaleWidth, scaleHeight, scaleImageWidth, scaleImageHeight, setFontScaleLimits, scaleFont, isIphoneModel, wp, hp }; //# sourceMappingURL=index.js.map