diff --git a/HyperlinkedText.js b/HyperlinkedText.js
new file mode 100644
index 0000000..24847b3
--- /dev/null
+++ b/HyperlinkedText.js
@@ -0,0 +1,113 @@
+/**
+ * @providesModule react-native-hyperlinked-text
+ */
+
+import React, { Component, PropTypes } from 'react'
+import {
+ View,
+ Text,
+ Linking,
+} from 'react-native'
+import styles from './Styles/HyperlinkedTextStyle';
+import R from 'ramda';
+
+'use strict';
+
+const textPropTypes = Text.propTypes || {}
+
+export default class HyperlinkedText extends Component {
+ constructor(props){
+ super(props)
+ this._getMatches = this._getMatches.bind(this);
+ }
+
+ render(){
+ return this._linkify(this);
+ }
+
+ _linkify(component) {
+ const matches = this._gatherMatches(component.props.children);
+ const newElements = this._replaceMatches(component, matches);
+ return ({ newElements });
+ }
+
+ _gatherMatches(text) {
+ const matches = this.props.linkDefs.reduce((matches, linkDef)=>R.concat(this._getMatches(linkDef, text), matches), []);
+ return R.sort((m1, m2)=>m1.index-m2.index, matches);
+ }
+
+ _getMatches(linkDef, text) {
+ const regex = linkDef.regex;
+ regex.lastIndex = 0; // reset the regex in case it was used before
+ let matches = [];
+ while ((regexResult = regex.exec(text)) !== null) {
+ matches.push({
+ text: regexResult[0],
+ groups: R.drop(1,regexResult),
+ index: regexResult.index,
+ lastIndex: regex.lastIndex,
+ linkDef
+ });
+ }
+ return matches;
+ }
+
+ _replaceMatches(component, matches) {
+ const componentProps = {
+ ...component.props,
+ ref: undefined,
+ key: undefined,
+ };
+ let _lastIndex = 0;
+ const elements = [];
+ for (let match of matches) {
+ const linkDef = match.linkDef;
+ const style = linkDef.style || this.props.linkStyle;
+ const onPress = linkDef.noPress? ()=>{} : (linkDef.onPress || this.props.onLinkPress);
+ const replaceText = linkDef.replaceText || R.identity;
+
+ let nonLinkedText = component.props.children.substring(_lastIndex, match.index);
+ nonLinkedText && elements.push(nonLinkedText);
+ _lastIndex = match.lastIndex;
+ elements.push(
+ onPress(match.text, ...match.groups))}
+ >
+ {linkDef.replaceText?linkDef.replaceText(match.text, ...match.groups):match.text}
+
+ );
+ }
+ elements.push(component.props.children.substring(_lastIndex, component.props.children.length))
+ return elements;
+ }
+
+ static _openWebUrl(url) {
+ Linking.canOpenURL(url).then(supported => supported && Linking.openURL(url)).catch(console.log('Failed to open url ' + url));
+ }
+
+ static get webUrlLinkDef() {
+ return {
+ regex: /(https?:\/\/[^\s]+)/mgi,
+ onPress: HyperlinkedText._openWebUrl,
+ linkStyle: styles.hyperlink
+ };
+ }
+}
+
+HyperlinkedText.propTypes = {
+ onLinkPress: PropTypes.func,
+ linkDefs: PropTypes.array,
+ linkStyle: textPropTypes.style
+}
+
+// Defaults for props
+HyperlinkedText.defaultProps = {
+ onLinkPress: HyperlinkedText._openWebUrl,
+ linkDefs: [{
+ regex: /(https?:\/\/[^\s]+)/mgi
+ }],
+ linkStyle: styles.hyperlink
+}
\ No newline at end of file
diff --git a/Styles/HyperlinkedTextStyle.js b/Styles/HyperlinkedTextStyle.js
new file mode 100644
index 0000000..219db59
--- /dev/null
+++ b/Styles/HyperlinkedTextStyle.js
@@ -0,0 +1,12 @@
+import { StyleSheet } from 'react-native'
+import { Metrics, Colors } from '../../Themes/'
+
+export default StyleSheet.create({
+ container: {
+ flex: 1,
+ paddingTop: Metrics.titlePadding
+ },
+ hyperlink: {
+ color: Colors.hyperlink
+ }
+})
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..54b3927
--- /dev/null
+++ b/package.json
@@ -0,0 +1,26 @@
+{
+ "name": "react-native-hyperlinked-text",
+ "version": "0.0.1",
+ "keywords": [
+ "react-native"
+ ],
+ "dependencies": {
+ "ramda": "^0.24.1"
+ },
+ "description": "Text component for React Native with regex defined hyperlinks",
+ "main": "HyperlinkedText.js",
+ "devDependencies": {},
+ "scripts": {
+ "test": "mocha --reporter spec"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/Kimaia/react-native-hyperlinked-text.git"
+ },
+ "author": "Doron Tohar (https://www.kimaia.com/)",
+ "license": "ISC",
+ "bugs": {
+ "url": "https://github.com/Kimaia/react-native-hyperlinked-text/issues"
+ },
+ "homepage": "https://github.com/Kimaia/react-native-hyperlinked-text#readme"
+}
diff --git a/yarn.lock b/yarn.lock
new file mode 100644
index 0000000..fe19662
--- /dev/null
+++ b/yarn.lock
@@ -0,0 +1,7 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+ramda@^0.24.1:
+ version "0.24.1"
+ resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.24.1.tgz#c3b7755197f35b8dc3502228262c4c91ddb6b857"