react-highlighter-ts
Version:
a TypeScript rewrite of the package react-highlighter
94 lines • 4.26 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Highlight = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const helpers_1 = require("./helpers");
/**
* Highlight matches in a string
*
* See docs at https://chadlavi.github.io/react-highlighter-ts/
*/
exports.Highlight = (0, react_1.forwardRef)(function _Highlight(props, ref) {
/**
* We increment this each time there's a match -- it's used to ensure the
* keys are unique.
*/
let count = 0;
const incrementCount = () => count++;
const { search, ignoreDiacritics, diacriticsBlacklist, matchElement = "mark", matchClass = "highlight", matchStyle = {}, children, caseSensitive: _c } = props, rest = __rest(props, ["search", "ignoreDiacritics", "diacriticsBlacklist", "matchElement", "matchClass", "matchStyle", "children", "caseSensitive"]);
/**
* Responsible for rending a non-highlighted element.
*/
const renderPlain = (s) => ((0, jsx_runtime_1.jsx)("span", { children: s }, `${s}-${count}`));
/**
* Responsible for rending a highlighted element.
*/
const renderHighlight = (s) => (0, react_1.createElement)(matchElement, {
key: `${s}-${count}`,
className: matchClass,
style: matchStyle,
}, s);
/**
* Determines which strings of text should be highlighted or not.
*/
const highlightChildren = (subject, search) => {
const children = [];
let remaining = subject;
while (remaining) {
const remainingCleaned = ignoreDiacritics
? (0, helpers_1.removeDiacritics)(remaining, diacriticsBlacklist || "")
: remaining;
if (!search.test(remainingCleaned)) {
children.push(renderPlain(remaining));
return children;
}
const boundaries = (0, helpers_1.getMatchBoundaries)(remainingCleaned, search);
if ((boundaries === null || boundaries === void 0 ? void 0 : boundaries.first) === 0 && (boundaries === null || boundaries === void 0 ? void 0 : boundaries.last) === 0) {
// Regex zero-width match
return children;
}
// Capture the string that leads up to a match...
const nonMatch = remaining.slice(0, boundaries === null || boundaries === void 0 ? void 0 : boundaries.first);
if (nonMatch) {
children.push(renderPlain(nonMatch));
}
// Now, capture the matching string...
const match = remaining.slice(boundaries === null || boundaries === void 0 ? void 0 : boundaries.first, boundaries === null || boundaries === void 0 ? void 0 : boundaries.last);
if (match) {
children.push(renderHighlight(match));
}
// And if there's anything left over, recursively run this method again.
remaining = remaining.slice(boundaries === null || boundaries === void 0 ? void 0 : boundaries.last);
incrementCount();
}
return children;
};
/**
* A wrapper to the highlight method to determine when the highlighting
* process should occur.
*/
const renderElement = (children) => {
if (search)
return (0, helpers_1.deepMap)(children, (c) => {
if (typeof c === "string") {
return highlightChildren(c, (0, helpers_1.getSearch)(props));
}
return c;
});
return [children];
};
return ((0, jsx_runtime_1.jsx)("span", Object.assign({}, rest, { ref: ref }, { children: renderElement(children) }), void 0));
});
//# sourceMappingURL=highlight.js.map