@eccenca/gui-elements
Version:
GUI elements based on other libraries, usable in React application, written in Typescript.
74 lines • 2.81 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.highlighterUtils = void 0;
exports.Highlighter = Highlighter;
const react_1 = __importDefault(require("react"));
/**
* Returns a highlighted string according to the words of the search query.
* @param label The string to highlight.
* @param searchValue The mutli-word search query from which single words should be highlighted in the label.
*/
function Highlighter({ label, searchValue }) {
return react_1.default.createElement(react_1.default.Fragment, null, getSearchHighlight(label, searchValue));
}
const getSearchHighlight = (label, searchValue) => {
if (!searchValue || !label) {
return label;
}
const searchStringParts = extractSearchWords(searchValue);
if (searchStringParts.length === 0) {
return label;
}
const multiWordRegex = createMultiWordRegex(searchStringParts);
const result = [];
let offset = 0;
// loop through matches and add unmatched and matched parts to result array
let matchArray = multiWordRegex.exec(label);
let key = 0;
while (matchArray !== null) {
key++;
result.push(label.slice(offset, matchArray.index));
result.push(react_1.default.createElement("mark", { key: key }, matchArray[0]));
offset = multiWordRegex.lastIndex;
matchArray = multiWordRegex.exec(label);
}
// Add remaining unmatched string
result.push(label.slice(offset));
return result;
};
/** Escapes strings to match literally.
* taken from https://stackoverflow.com/questions/6318710/javascript-equivalent-of-perls-q-e-or-quotemeta
*/
const escapeRegexWord = (str) => {
return str.toLowerCase().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
/**
* Extracts search words separated by white space.
*/
function extractSearchWords(textQuery, toLowerCase = false) {
const words = textQuery.split(RegExp("\\s+")).filter((word) => word !== "");
return toLowerCase ? words.map((w) => w.toLowerCase()) : words;
}
/**
* Returns true if all search words are included in the given text
*/
function matchesAllWords(text, searchWords) {
return searchWords.every((w) => text.includes(w));
}
/**
* Creates a case-insensitive multi-word regex, that matches any of the given words.
*/
function createMultiWordRegex(multiWordQuery, global = true) {
const regexString = multiWordQuery.map(escapeRegexWord).join("|");
return RegExp(regexString, (global ? "g" : "") + "i");
}
exports.highlighterUtils = {
extractSearchWords,
matchesAllWords,
createMultiWordRegex,
};
exports.default = Highlighter;
//# sourceMappingURL=Highlighter.js.map