UNPKG

@sap-ux/ui-components

Version:

SAP UI Components Library

112 lines 3.9 kB
import React from 'react'; const PLACEHOLDER_START = '{{{'; const PLACEHOLDER_END = '}}}'; /** * Method find all matching values. * * @param text Text to parse. * @param values Map with values to search. * @returns Array containing matched regex expressions. */ const matchAllValues = (text, values) => { const matches = []; for (const key in values) { const textWithUrlRegex = `${PLACEHOLDER_START}${key}${PLACEHOLDER_END}`; const regex = new RegExp(textWithUrlRegex, 'gi'); let match = null; do { match = regex.exec(text); if (match) { matches.push(match); } } while (match); } return matches; }; /** * Method separates given text between found values and rest unformatted text. * * @param text Text to parse. * @param values Map with values to search. * @returns Object containing separated `texts` and `formatted` arrays. */ export const parseText = (text, values) => { const result = { texts: [], bolds: [] }; if (text) { const matches = matchAllValues(text, values); matches.sort((match1, match2) => match1.index - match2.index); let charIndex = 0; if (matches.length) { for (let i = 0; i < matches.length; i++) { const match = matches[i]; if (match.index === undefined) { continue; } const original = match[0]; const resolvedText = values[original.replace(PLACEHOLDER_START, '').replace(PLACEHOLDER_END, '')]; result.texts.push(text.substring(charIndex, match.index)); result.bolds.push(resolvedText); charIndex = match.index + original.length; if (i === matches.length - 1) { result.texts.push(text.substring(charIndex, text.length)); } } } else { result.texts.push(text); } } return result; }; /** * Method formats text with callback method to provide option to use different markup to highligh matching result in text. * * @param text Text to parse. * @param values Map with values to search. * @param cb Callback method to apply text highlight. * @returns Array with formatted text parts. */ export function formatTextGeneric(text, values, cb) { const parseResult = parseText(text, values); const result = []; for (let i = 0; i < parseResult.texts.length; i++) { if (!parseResult.texts[i] && !parseResult.bolds[i]) { continue; } result.push(cb(i, parseResult.texts[i], parseResult.bolds[i])); } return result; } /** * Method formats string text with replacing matching values with same string without any highlight. * * @param text Text to parse. * @param values Map with values to search. * @returns Formatted text string. */ export function formatText(text, values) { const parseResult = formatTextGeneric(text, values, (index, textPart, match) => { return match ? textPart + match : textPart; }); return parseResult.join(''); } /** * Component to show formatted text with highlighting matching entries. * Entries with '{{{key}}}' will be replaced with passed value and wrapped in bold. * * @param props Component properties. * @returns Component to render formatted text. */ export function UIFormattedText(props) { const { children, values = {}, className } = props; const result = formatTextGeneric(children, values, (index, textPart, match) => { return (React.createElement(React.Fragment, { key: `anchor-${index}` }, textPart, match && React.createElement("b", null, match))); }); return React.createElement("div", { className: className }, result); } //# sourceMappingURL=UIFormattedText.js.map