DEV Community

Jasur Kurbanov
Jasur Kurbanov

Posted on

How To Create Custom Fully Responsive Text Component In React Native

In this article, I am going to show you how you can create your custom Text Component for your React Native Project.

Create New Project

If you are new to mobile development, the easiest way to get started is with Expo CLI.

If you are already familiar with mobile development, you may want to use React Native CLI.

Expo CLI

expo init MyApp
cd MyApp
Enter fullscreen mode Exit fullscreen mode

React Native CLI

npx react-native init MyApp
cd MyApp
Enter fullscreen mode Exit fullscreen mode

For sake of simplicity I will be using Expo for creating new React Native project. Once we created new project, we create folder src where we put folder components. Inside folder components we create another folder for our custom text component MyText. Inside this folder add index.js file. So far project looks like this:

React Native Custom Text Component

Our component index.js looks like this:

import * as React from 'react';
import { Text } from 'react-native';

const MyText = ()=> {
    return (
        <Text>Custom Component</Text>
    );
};

export { MyText }
Enter fullscreen mode Exit fullscreen mode

Now it is time to add custom props to our component. I will be adding most common props for general understanding concept.

h1 - for text size 48px
h2 - for text size 32px
h3 - for text size 20px
h4 - for text size 18px
h5 - for text size 16px
p- for smaller texts,
bold- for making text bold
italic - for making text italic
title - for passing text value
style - for custom styling
...rest - other props

import * as React from 'react';
import { Text } from 'react-native';


+ const MyText = ({ h1, h2, h3, h4, h5,  p, bold, 
+                   italic, title,style, ...rest })=> {
    return (
        <Text>{title}</Text>
    );
};

export { MyText }
Enter fullscreen mode Exit fullscreen mode

Now lets pass our props to actual body of our component with appropriate styles.

import * as React from 'react';
import { Text } from 'react-native';

const MyText = ({ h1, h2, h3, h4, h5,  p, bold, 
                 italic, title,style, ...rest })=> {
    return (
+        <Text style={[
+           h1 && { fontSize: 48 },
+           h2 && { fontSize: 32 },
+           h3 && { fontSize: 20 },
+           h4 && { fontSize: 18 },
+           h5 && { fontSize: 16 },
+           p && { fontSize: 12 },
+           bold && { fontWeight: 'bold' },
+           italic && { fontStyle: 'italic'},
+           style
+       ]}{...rest}>{title}</Text>
    );
};

export { MyText }
Enter fullscreen mode Exit fullscreen mode

Let's see what we have done so far. We will be testing our component inside App.js. First we import our component from components folder and call it inside App.js.

import React from 'react';
import { StyleSheet, View } from 'react-native';

import { MyText } from './src/components/MyText'

export default function App() {
  return (
    <View style={styles.container}>
      <MyText title={'Header 1'} h1/>
      <MyText title={'Header 2'} h2/>
      <MyText title={'Header 3'} h3/>
      <MyText title={'Header 4'} h4/>
      <MyText title={'Header 5'} h5/>
      <MyText title={'Small Text'} p/>
      <MyText title={'Header 1'} h1 italic/>
      <MyText title={'Header 1'} h1 bold/>
      <MyText title={'Header 2'} h2 italic/>
      <MyText title={'Header 2'} h2 bold/>
      <MyText title={'Header 3'} h3 italic/>
      <MyText title={'Header 3'} h3 bold/>
      <MyText title={'Header 4'} h4 italic/>
      <MyText title={'Header 4'} h4 bold/>
      <MyText title={'Header 5'} h5 italic/>
      <MyText title={'Header 5'} h5 bold/>
      <MyText title={'Small Text'} p italic/>
      <MyText title={'Small Text'} p bold/>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Enter fullscreen mode Exit fullscreen mode

Result

React Native Jasur Kurbanov

Responsiveness

We successfully created our custom Text component. Now lets handle responsiveness of our Text component.
In order to do this, create adjust.js file inside src folder.

import { PixelRatio, Dimensions} from 'react-native';

const pixelRatio = PixelRatio.get();
const deviceHeight = Dimensions.get('window').height;
const deviceWidth = Dimensions.get('window').width;


const adjust = (size) => {
    if (pixelRatio >= 2 && pixelRatio < 3) {
        // iphone 5s and older Androids
        if (deviceWidth < 360) {
            return size * 0.95;
        }
        // iphone 5
        if (deviceHeight < 667) {
            return size;
            // iphone 6-6s
        } if (deviceHeight >= 667 && deviceHeight <= 735) {
            return size * 1.15;
        }
        // older phablets
        return size * 1.25;
    } if (pixelRatio >= 3 && pixelRatio < 3.5) {
        // catch Android font scaling on small machines
        // where pixel ratio / font scale ratio => 3:3
        if (deviceWidth <= 360) {
            return size;
        }
        // Catch other weird android width sizings
        if (deviceHeight < 667) {
            return size * 1.15;
            // catch in-between size Androids and scale font up
            // a tad but not too much
        }
        if (deviceHeight >= 667 && deviceHeight <= 735) {
            return size * 1.2;
        }
        // catch larger devices
        // ie iphone 6s plus / 7 plus / mi note η­‰η­‰
        return size * 1.27;
    } if (pixelRatio >= 3.5) {
        // catch Android font scaling on small machines
        // where pixel ratio / font scale ratio => 3:3
        if (deviceWidth <= 360) {
            return size;
            // Catch other smaller android height sizings
        }
        if (deviceHeight < 667) {
            return size * 1.2;
            // catch in-between size Androids and scale font up
            // a tad but not too much
        }
        if (deviceHeight >= 667 && deviceHeight <= 735) {
            return size * 1.25;
        }
        // catch larger phablet devices
        return size * 1.4;
    } return size;
};

export default adjust
Enter fullscreen mode Exit fullscreen mode

If to explain this file succinctly, this contains function that handles text size for multiply devices and platforms.
Before passing our function to our component, it is worth to mention that currently we defined kind of 'static' value to our font size. Once we pass adjust function to our component based on device or platform it will automatically adjust Text size to the screen.

Passing adjust function to our component

import * as React from 'react';
import { Text } from 'react-native';

import adjust from "../../adjust";

const MyText = ({ h1, h2, h3, h4, h5,  p, bold, 
                 italic, title,style, ...rest })=> {
    return (
        <Text style={[
            h1 && { fontSize: adjust(48) },
            h2 && { fontSize: adjust(32) },
            h3 && { fontSize: adjust(20) },
            h4 && { fontSize: adjust(18) },
            h5 && { fontSize: adjust(16) },
            p && { fontSize: adjust(12) },
            bold && { fontWeight: 'bold' },
            italic && { fontStyle: 'italic'},
            style
        ]}{...rest}>{title}</Text>
    );
};

export { MyText }

Enter fullscreen mode Exit fullscreen mode

Final Result.

You can see in this final result, how adjust function influences to our custom text component.

Initially we passed font-size just as it is, without taking into account device or platform. However, when we pass adjust function our text component scales up.

Jasur Kurbanov

Full source code of this project: Github Link

Feel free to comment my mistakes on comment below.

References:

Adjust.js file were modified, original file given from Galio Framework

React Native Docs

Top comments (4)

Collapse
 
zeealik profile image
Zeeshan Ali Khan

medium.com/react-native-training/b...

npmjs.com/package/react-native-res...

Above links will provide best way to make screens responsive on all devices.

Collapse
 
jasurkurbanov profile image
Jasur Kurbanov

Thank you

Collapse
 
chideraike profile image
Chidera

Thanks for this

Collapse
 
jasurkurbanov profile image
Jasur Kurbanov

You're welcome