@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
JavaScript
;
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);
});
}