forked from iansinnott/react-string-replace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
65 lines (56 loc) · 1.99 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
/* eslint-disable vars-on-top, no-var, prefer-template */
var isRegExp = require('lodash/isRegExp');
var escapeRegExp = require('lodash/escapeRegExp');
var isString = require('lodash/isString');
var flatten = require('lodash/flatten');
/**
* Given a string, replace every substring that is matched by the `match` regex
* with the result of calling `fn` on matched substring. The result will be an
* array with all odd indexed elements containing the replacements. The primary
* use case is similar to using String.prototype.replace except for React.
*
* React will happily render an array as children of a react element, which
* makes this approach very useful for tasks like surrounding certain text
* within a string with react elements.
*
* Example:
* matchReplace(
* 'Emphasize all phone numbers like 884-555-4443.',
* /([\d|-]+)/g,
* (number, i) => <strong key={i}>{number}</strong>
* );
* // => ['Emphasize all phone numbers like ', <strong>884-555-4443</strong>, '.'
*
* @param {string} str
* @param {regexp|str} match Must contain a matching group
* @param {function} fn
* @return {array}
*/
function replaceString(str, match, fn) {
var curCharStart = 0;
var curCharLen = 0;
if (str === '') {
return str;
} else if (!str || !isString(str)) {
throw new TypeError('First argument to react-string-replace#replaceString must be a string');
}
var re = match;
if (!isRegExp(re)) {
re = new RegExp('(' + escapeRegExp(re) + ')', 'gi');
}
var result = str.split(re);
// Apply fn to all odd elements
for (var i = 1, length = result.length; i < length; i += 2) {
curCharLen = result[i].length;
curCharStart += result[i - 1].length;
result[i] = fn(result[i], i, curCharStart);
curCharStart += curCharLen;
}
return result;
}
module.exports = function reactStringReplace(source, match, fn) {
if (!Array.isArray(source)) source = [source];
return flatten(source.map(function(x) {
return isString(x) ? replaceString(x, match, fn) : x;
}));
};