@mj-studio/react-native-scaled-layout
TypeScript icon, indicating that this package has built-in type declarations

2.0.0-alpha04 • Public • Published

react-native-scaled-layout

npm

Sorry to Api changes in 1.1.0 😢

Detail Article's Link 🔗

Flexible, Scalable layout dimensions, font sizes for React Native

@mj-studio/react-native-scaled-layout is using monkey-patch feature in javascript(typescript) and augmentation syntax in typescript.

Contents 🏆

Install 💠

npm i @mj-studio/react-native-scaled-layout

or

yarn add @mj-studio/react-native-scaled-layout

Usage 📌

0. Configure your environment or wanted behavior

If @mj-studio/react-native-scaled-layout is not imported for side-effect, then TypeError will be invoked.

index.js

import { initScaledSettings } from '@mj-studio/react-native-scaled-layout';
...
initScaledSettings(375, { min: 0.5, max: 1.5 }, { min: 0.75, max: 1.35 }, 14);
Params Type Default Required
designSpecWidth number 375 false
dimenScaleRange { min: number; max: number } [0.5, 1.5] false
fontScaleRange { min: number; max: number } [0.75, 1.3] false
defaultFontSize number 14 false

1. Number type Augmentation(Extension)

// calculated with width length of design spec
// clamped with dimenScaleRange min, max value
(36).scaled() /* or */ (36).d() 

// calculated with width length of design spec
// clamped with fontScaleRange min, max value
(24).fontScaled() /* or */ (24).f()

Example in ViewStyle

style={{
    width: (100).d(),
    height: (210).d() + safeAreaBottom,
    borderRadius: (16).d(),
    justifyContent: 'center',
    paddingBottom: safeAreaBottom + (24).d(),
}}

2. ScaledText Component

// automatically adjusted with (14).fontScaled()
<ScaledText style={{fontSize: 14}}>My Text</ScaledText> 

// ignore calculated font scale
// fixed with 28(14 * 2)
<ScaledText style={{fontSize: 14}} customFontScale={isTablet ? 2 : undefined}>My Text</ScaledText>

react-native-scaled-layout is also compatible with Styled Component

export const BoldText = styled(ScaledText)`
  font-family: ${fonts.NotoSansKRBold};
`;
...
const TutorialText = styled(BoldText)`
  left: ${(20).d()}px;
  right: ${(20).d()}px;
  position: absolute;
  font-size: 24px; // automatically adjust font size with (24).fontScaled()
  color: ${({ theme }): string => theme.white};
`;

Calculation 📐

The following is the implementation of initScaledSettings

/**
 * Set initial configuration for scaled layout behavior. If your height of design guideline spec is less than width, invert 1st, 2nd params.
 * @param designSpecWidth your design width viewport width(zeplin, pigma etc...). If your design viewport is 375 x 1000 then 375 is a right value.
 * @param dimenScaleRange dimension scale factor minimum & maximum range. default is [0.5, 1.5]..
 * @param fontScaleRange font scale factor minimum & maximum range. default is [0.75, 1.3].
 * @param defaultFontsize default `<Text>` fontSize. default is 12.
 *
 * @example
 * ```ts
 * initScaledSettings(375, 812, {min: 0.5, max: 1.5}, {min: 0.75, max: 1.3}, 12);
 * ```
 */
export function initScaledSettings(
  designSpecWidth = 375,
  dimenScaleRange: { min: number; max: number } = { min: 0.5, max: 1.5 },
  fontScaleRange: { min: number; max: number } = { min: 0.75, max: 1.3 },
  defaultFontsize = 12,
): void {
  dimenRatio = minLength / designSpecWidth;

  dimenScale = clamp(dimenRatio, dimenScaleRange.min, dimenScaleRange.max);

  fontScale =
    dimenScale >= 1 ? Math.min(dimenScale, fontScaleRange.max) : Math.max(dimenScale * dimenScale, fontScaleRange.min);
  _FONT_SCALE_ = fontScale;
  _defaultFontSize = defaultFontsize;

  /* eslint-disable no-extend-native */
  Number.prototype.scaled = function scaled(): number {
    return Math.round((this as number) * dimenScale);
  };
  Number.prototype.fontScaled = function fontScaled(): number {
    return Math.round((this as number) * fontScale);
  };
  Number.prototype.d = function d(): number {
    return (this as number).scaled();
  };
  Number.prototype.f = function f(): number {
    return (this as number).fontScaled();
  };
  /* eslint-enable no-extend-native */
}
initScaledSettings();

Trouble Shooting❗️

1. TypeError: 40.d is not a function

Please put import '@mj-studio/react-native-scaled-layout' to top of index.js or top of file which in setupFiles list of jest.config.js

Todo

  • Create ScaledView, ScaledTextInput, ScaledTouchableXXX like ScaledText

Change Logs 🔧

  • 1.2.0
    • Change customFontScale logic in ScaledText
  • 1.1.7
    • Fix ScaledText font size scaling issue. Previously, the fontSize property is multiplied to float not integer.
  • 1.1.6
    • The values are calculated with ceil() instead of round().
  • 1.1.4
    • minimumFontSize prop is added in ScaledText
  • 1.1.2
    • dimenWidthScaled(), dimenHeightScaled(), w(), h() are removed
    • designSpecHeight parameter is removed from initScaledSettings
  • 1.1.1
    • FontScale is calculated with design spec width length not design spec diagonal length
  • 1.1.0 (Sorry to API changes)
    • dimenScaled() is renamed to scaled()
    • New number type augmentation dimenWidthScaled(), dimenHeightScaled()
    • Add simple alias for functions d(), f(), w(), h()
  • 1.0.6
    • Apply round for fixing showing weird line because of floating number dimension

feel free your fork or any PR! Thanks

/@mj-studio/react-native-scaled-layout/

    Package Sidebar

    Install

    npm i @mj-studio/react-native-scaled-layout

    Weekly Downloads

    0

    Version

    2.0.0-alpha04

    License

    MIT

    Unpacked Size

    21.7 kB

    Total Files

    24

    Last publish

    Collaborators

    • mj_studio