iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
🍣

[RN] Linking phone numbers with react-native-hyperlink

に公開
2022/07/04

Introduction

I previously posted the following article.
https://zenn.dev/nekoniki/articles/7bc91d19f98cbacb0b63

The content was about introducing a library called react-native-hyperlink to hyperlink URLs included in <Text> components within ReactNative apps.

This time, as an advanced version, I would like to turn "phone numbers" contained in text into hyperlinks.

Using linkify

The react-native-hyperlink component supports several URL formats by default, but it does not support phone numbers.

https://github.com/obipawan/react-native-hyperlink

In this article, we will linkify phone numbers in a format like "XXX-XXXX-XXXX" (so that the OS's built-in phone app is called directly when tapped).

The react-native-hyperlink component provides a property called linkify, where you specify the format and detection method you want to linkify.

For linkify, you provide specifications in an object format defined by a library called linkify-it.

https://github.com/markdown-it/linkify-it

Installing linkify-it

Install it using the following command.
Since we are implementing this in TypeScript, I have also added @types.

yarn add linkify-it
yarn add @types/linkify-it

Defining the detection logic

The detection logic is written using LinkifyIt().add(), which has a slightly unique syntax.
You specify the starting character for detection (in this case, '0', the first digit of the phone number), and then use a regular expression to check if the following characters match the target format.

If it is determined to be the target string, you can linkify it by returning the number of characters for that section.

When tapped, you can use Linking.open() just like a normal link, but don't forget to prefix the phone number with tel:.

App.tsx
import React from 'react';
import { Linking } from 'react-native';
import Hyperlink from 'react-native-hyperlink';
import LinkifyIt from 'linkify-it';

// Regular expression used for detection
const PHONE_REGEX = /^\d{2,3}-\d{1,4}-\d{4}/;

// Phone number string check logic
const PHONE_LINKIFY: LinkifyIt.LinkifyIt = LinkifyIt().add(
  // The character to start detection (if this character is included, the "validate" logic runs)
  '0', 
  {
    // Logic to determine if it is a string to be hyperlinked
    validate: (text: string, pos: number) => {
      // text -> the entire string
      // pos -> the index where the target character (here, '0') is located

      // Extract the target part
      const target = '0' + text.slice(pos);
      // If the extracted part matches the target regex, linkify it
      if (target?.match?.(PHONE_REGEX)?.[0]) {
        // If you want to linkify it, return the "number of characters to be linkified"
        return target.match(PHONE_REGEX)[0].length - 1;
      }
      return 0;
    },
    // Logic for formatting the target URL
    normalize: (match: LinkifyIt.Match) => {
      // Add "tel:" for Linking.open
      match.url = 'tel:' + match.url.replaceAll('-', '');
    },
  }
);

const App: React.VFC = props => {
  return(
      <Hyperlink
        linkify={PHONE_LINKIFY}
        linkStyle={{color: 'red'}}
        onPress={(url: string, text: string) => {
	  // Open the link
          Linking.openURL(url);
        }}>
        {`Phone number link -> 000-0000-0000`}
      </Hyperlink>
  )
}

Actual appearance

It looks like this.

phone_no

Conclusion

In this article, I introduced how to hyperlink phone numbers as an application of react-native-hyperlink.
It seems that the detection logic for determining if something is a link is largely handled by linkify-it, so it is necessary to provide specifications that match its format.

I hope the method introduced in this article will be helpful to you.

Discussion