UNPKG

@eccenca/gui-elements

Version:

GUI elements based on other libraries, usable in React application, written in Typescript.

74 lines 2.81 kB
"use strict"; 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