UNPKG

@zohodesk/components

Version:

Dot UI is a customizable React component library built to deliver a clean, accessible, and developer-friendly UI experience. It offers a growing set of reusable components designed to align with modern design systems and streamline application development

163 lines (133 loc) • 8.17 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.highlightText = highlightText; var _react = _interopRequireDefault(require("react")); var _cssJSLogic2 = _interopRequireDefault(require("../css/cssJSLogic")); var _utils = require("@zohodesk/utils"); var _TypographyModule = _interopRequireDefault(require("./../css/Typography.module.css")); var _Common = require("../../utils/Common"); var _excluded = ["customStyle"]; function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function highlightText(config) { var _ref; var sourceText = config.text, highlightData = config.data, _config$styleConfigur = config.styleConfiguration, highlightStyleConfig = _config$styleConfigur === void 0 ? _Common.DUMMY_OBJECT : _config$styleConfigur, _config$shouldExclude = config.shouldExcludeIndices, shouldExcludeIndices = _config$shouldExclude === void 0 ? false : _config$shouldExclude, _config$isCaseSensiti = config.isCaseSensitive, enableCaseSensitiveMatch = _config$isCaseSensiti === void 0 ? false : _config$isCaseSensiti, _config$isWholeWord = config.isWholeWord, matchWholeWordOnly = _config$isWholeWord === void 0 ? false : _config$isWholeWord, asTag = config.as, tagNameLegacy = config.tagName, customRenderer = config.renderHighlight; var wrapperTagName = (_ref = asTag !== null && asTag !== void 0 ? asTag : tagNameLegacy) !== null && _ref !== void 0 ? _ref : 'span'; if (!sourceText || !(highlightData !== null && highlightData !== void 0 && highlightData.length)) { return sourceText; } var cssClassCache = new Map(); var normalizedHighlightTerms = highlightData.map(function (highlightItem) { var searchTerm = typeof highlightItem === 'string' ? highlightItem : highlightItem === null || highlightItem === void 0 ? void 0 : highlightItem.text; if (!searchTerm) return null; var itemConfiguration = typeof highlightItem === 'string' ? _Common.DUMMY_OBJECT : highlightItem; var hasStyleConfigrationFromItem = itemConfiguration.styleConfiguration !== undefined; var hasRenderHighlightFromItem = itemConfiguration.renderHighlight !== undefined; var finalStyleConfig = itemConfiguration.styleConfiguration !== undefined ? itemConfiguration.styleConfiguration : highlightStyleConfig; var customStyle = finalStyleConfig.customStyle, restStyleConfig = _objectWithoutProperties(finalStyleConfig, _excluded); var cacheKey = JSON.stringify(restStyleConfig); var typographyClass; if (Object.keys(restStyleConfig).length !== 0) { if (cssClassCache.has(cacheKey)) { typographyClass = cssClassCache.get(cacheKey); } else { var _cssJSLogic = (0, _cssJSLogic2["default"])({ props: restStyleConfig, style: _TypographyModule["default"] }), computedClass = _cssJSLogic.typographyClass; typographyClass = computedClass; cssClassCache.set(cacheKey, typographyClass); } } return { searchTerm: searchTerm, targetIndices: itemConfiguration.index !== undefined ? itemConfiguration.index : _Common.DUMMY_ARRAY, shouldExcludeIndices: itemConfiguration.shouldExcludeIndices !== undefined ? itemConfiguration.shouldExcludeIndices : shouldExcludeIndices, isCaseSensitive: itemConfiguration.isCaseSensitive !== undefined ? itemConfiguration.isCaseSensitive : enableCaseSensitiveMatch, matchWholeWordOnly: itemConfiguration.isWholeWord !== undefined ? itemConfiguration.isWholeWord : matchWholeWordOnly, wrapperTagName: itemConfiguration.as !== undefined ? itemConfiguration.as : itemConfiguration.tagName !== undefined ? itemConfiguration.tagName : wrapperTagName, customStyle: customStyle, customRenderer: itemConfiguration.renderHighlight !== undefined ? itemConfiguration.renderHighlight : customRenderer, highlightClasses: typographyClass, hasStyleConfigrationFromItem: hasStyleConfigrationFromItem, hasRenderHighlightFromItem: hasRenderHighlightFromItem }; }).filter(function (highlightConfig) { return highlightConfig && highlightConfig.searchTerm.trim(); }); if (!normalizedHighlightTerms.length) { return sourceText; } var regexPatterns = normalizedHighlightTerms.map(function (highlightConfig) { // Escape special regex characters in the searchTerm so it can be safely used in a RegExp var escapedTerm = highlightConfig.searchTerm.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // If matchWholeWordOnly is true, wrap the term with word boundaries (\b) to match whole words only return highlightConfig.matchWholeWordOnly ? "\\b".concat(escapedTerm, "\\b") : escapedTerm; }); var combinedRegexPattern = regexPatterns.join('|'); var textSegments = sourceText.split(new RegExp("(".concat(combinedRegexPattern, ")"), 'gi')); var occurrenceCountByTerm = {}; return textSegments.map(function (textSegment, segmentIndex) { var matchingHighlightConfig = normalizedHighlightTerms.find(function (highlightConfig) { var segmentToCompare = highlightConfig.isCaseSensitive ? textSegment : textSegment.toLowerCase(); var termToCompare = highlightConfig.isCaseSensitive ? highlightConfig.searchTerm : highlightConfig.searchTerm.toLowerCase(); return segmentToCompare === termToCompare; }); if (!matchingHighlightConfig) { return textSegment; } var termKey = matchingHighlightConfig.searchTerm; occurrenceCountByTerm[termKey] = (occurrenceCountByTerm[termKey] || 0) + 1; var currentOccurrenceIndex = occurrenceCountByTerm[termKey]; var targetIndices = matchingHighlightConfig.targetIndices, shouldExcludeIndices = matchingHighlightConfig.shouldExcludeIndices; var isIndicesArray = Array.isArray(targetIndices); var shouldApplyHighlight; if (isIndicesArray) { shouldApplyHighlight = (targetIndices.length === 0 || targetIndices.includes(currentOccurrenceIndex)) !== shouldExcludeIndices; } else { shouldApplyHighlight = (targetIndices === 0 || targetIndices === currentOccurrenceIndex) !== shouldExcludeIndices; } if (!shouldApplyHighlight) { return textSegment; } var customStyle = matchingHighlightConfig.customStyle, highlightClasses = matchingHighlightConfig.highlightClasses, customRenderer = matchingHighlightConfig.customRenderer, hasStyleConfigrationFromItem = matchingHighlightConfig.hasStyleConfigrationFromItem, hasRenderHighlightFromItem = matchingHighlightConfig.hasRenderHighlightFromItem, WrapperTag = matchingHighlightConfig.wrapperTagName; var shouldUseCustomRenderer = false; if (customRenderer) { if (hasRenderHighlightFromItem) { shouldUseCustomRenderer = true; } else if (!hasStyleConfigrationFromItem && customRenderer) { shouldUseCustomRenderer = true; } } if (shouldUseCustomRenderer && (0, _utils.isRenderable)(customRenderer)) { return (0, _utils.renderNode)(customRenderer, textSegment); } return /*#__PURE__*/_react["default"].createElement(WrapperTag, { key: "".concat(textSegment, "_").concat(currentOccurrenceIndex), style: customStyle, className: highlightClasses }, textSegment); }); }