UNPKG

wix-style-react

Version:
76 lines 2.92 kB
import React from 'react'; import PropTypes from 'prop-types'; import escapeRegExp from 'lodash/escapeRegExp'; import { st, classes } from './Highlighter.st.css'; class HighlightedItem extends React.PureComponent { renderElement() { const { children, match } = this.props; if (match) { const matchRegExp = this.getMatchRegExp(); return this.highlightChildren(children, matchRegExp); } return children; } getMatchRegExp() { const { match, caseSensitive } = this.props; return new RegExp(escapeRegExp(match), caseSensitive ? '' : 'i'); } getMatchBoundaries(subject, matchRegExp) { const matches = matchRegExp.exec(subject); if (matches) { return { first: matches.index, last: matches.index + matches[0].length, }; } } getMatchReactKey(index) { return `match-index-${index}`; } highlightChildren(children, matchRegExp) { const processedChildren = []; let matchIndex = 0; while (children) { if (!matchRegExp.test(children)) { processedChildren.push(this.renderPlain(children, this.getMatchReactKey(matchIndex++))); return processedChildren; } const boundaries = this.getMatchBoundaries(children, matchRegExp); const nonMatch = children.slice(0, boundaries.first); if (nonMatch) { processedChildren.push(this.renderPlain(nonMatch, this.getMatchReactKey(matchIndex++))); } const match = children.slice(boundaries.first, boundaries.last); if (match) { processedChildren.push(this.renderHighlight(match, this.getMatchReactKey(matchIndex++))); } children = children.slice(boundaries.last); } return processedChildren; } renderPlain(plainString, key) { return React.createElement("span", { key: key }, plainString); } renderHighlight(matchString, key) { const { emphasize = 'text' } = this.props; if (emphasize === 'background') { return (React.createElement("span", { key: key, className: st(classes.root, { emphasize, }) }, matchString)); } return React.createElement("strong", { key: key }, matchString); } render() { const { dataHook } = this.props; return React.createElement("span", { "data-hook": dataHook }, this.renderElement()); } } HighlightedItem.propTypes = { /** Applied as data-hook HTML attribute that can be used in the tests */ dataHook: PropTypes.string, match: PropTypes.string, emphasize: PropTypes.oneOf(['text', 'background']), caseSensitive: PropTypes.bool, }; export default HighlightedItem; //# sourceMappingURL=HighlightedItem.js.map