【RN】react-native-hyperlinkで電話番号をリンク化する
はじめに
以前に以下のような記事を投稿しました。
内容はReactNative
製のアプリにおいて、<Text>
中に含まれるURL
をハイパーリンク化するためにreact-native-hyperlink
というライブラリを導入した、というものです。
今回はその応用編で、テキスト中に含まれる「電話番号」をハイパーリンク化したいと思います。
linkify
を使う
react-native-hyperlink
のコンポーネントはデフォルトでいくつかのURL
フォーマットに対応していますが、電話番号には対応していません。
今回は"XXX-XXXX-XXXX"
のような形式の電話番号をリンク化(タップした場合はそのままOS内臓の電話アプリを呼びだす)していきます。
react-native-hyperlink
のコンポーネントにはlinkify
というプロパティが用意されており、ここにリンク化したいフォーマットと判定方法を指定します。
linkify
にはlinkify-it
というライブラリで定義されたオブジェクト形式で指定を行います。
linkify-it
のインストール
下記コマンドからインストールを行います。
今回はTypescript
で実装を行うため@types
も追加してあります。
yarn add linkify-it
yarn add @types/linkify-it
判定処理を記載する
判定処理は少し癖のある書き方ですがLinkifyIt().add()
で記載します。
判定の起点になる文字列を指定(ここでは電話番号の先頭文字である'0'
)して、続く文字列が目的の文字列であるかどうかを正規表現でチェックしています。
目的の文字列であることがわかった場合は、対象箇所の文字数をreturn
することでリンク化することができます。
タップした際は通常のリンクと同様にLinking.open()
で問題ありませんが、電話番号の先頭にtel:
を付けるのを忘れないようにしましょう。
import React from 'react';
import { Linking } from 'react-native';
import Hyperlink from 'react-native-hyperlink';
import LinkifyIt from 'linkify-it';
// 判定に使用する正規表現
const PHONE_REGEX = /^\d{2,3}-\d{1,4}-\d{4}/;
// 電話番号の文字列チェック処理
const PHONE_LINKIFY: LinkifyIt.LinkifyIt = LinkifyIt().add(
// 判定を行う文字列(この文字列を含んでいる場合はvalidate)処理が走る
'0',
{
// リンク化したい文字列であるかどうかの判定処理
validate: (text: string, pos: number) => {
// text -> 文字列の全体
// pos -> 目的の文字(ここでは'0')が存在するindex
// 対象箇所の切り出し
const target = '0' + text.slice(pos);
// 切り出した箇所が目的の正規表現に合致していたらリンク化する
if (target?.match?.(PHONE_REGEX)?.[0]) {
// リンク化したい場合は「リンク化させたい文字数」を返却する
return target.match(PHONE_REGEX)[0].length - 1;
}
return 0;
},
// 対象URLの整形処理
normalize: (match: LinkifyIt.Match) => {
// Linking.open用の"tel:"を付ける
match.url = 'tel:' + match.url.replaceAll('-', '');
},
}
);
const App: React.VFC = props => {
return(
<Hyperlink
linkify={PHONE_LINKIFY}
linkStyle={{color: 'red'}}
onPress={(url: string, text: string) => {
// リンクを開く
Linking.openURL(url);
}}>
{`電話番号のリンク -> 000-0000-0000`}
</Hyperlink>
)
}
実際の表示
以下のようになりました。
まとめ
今回はreact-native-hyperlink
の応用として、電話番号のハイパーリンク化の方法についてご紹介しました。
リンクであるかどうかの判定部分はlinkify-it
に任せている部分が多いようで、そちらのフォーマットに合わせた指定をする必要があります。
今回紹介した方法が役立ちましたら幸いです。
Discussion