UNPKG

wix-style-react

Version:
72 lines 2.46 kB
import React from 'react'; import HighlightedItem from './HighlightedItem'; import PropTypes from 'prop-types'; /** * Highlighter * * It highlights string type children by wrapping match * with strong dom element. * It remains children element structure. */ const childKeyGenerator = () => { let childKey = 0; return () => `highlighted-child-${childKey++}`; }; const ELEM_TYPES = { STRING: 'string', ARRAY: 'array', REACT_ELEMENT: 'React_element', }; const getElementType = element => { if (Array.isArray(element)) { return ELEM_TYPES.ARRAY; } if (React.isValidElement(element)) { return ELEM_TYPES.REACT_ELEMENT; } if (typeof element === 'string') { return ELEM_TYPES.STRING; } return ''; }; const highlight = (element, match, nextChildKey, props) => { if (!element) { return null; } const elementType = getElementType(element); const elementTypesMap = { [ELEM_TYPES.STRING]: (elem, _match) => (React.createElement(HighlightedItem, { key: nextChildKey(), match: _match, emphasize: props.emphasize }, elem)), [ELEM_TYPES.REACT_ELEMENT]: elem => { if (elem.props.children) { return React.cloneElement(elem, { ...elem.props, key: nextChildKey() }, highlight(elem.props.children, match, nextChildKey, props)); } return elem; }, [ELEM_TYPES.ARRAY]: elem => elem.map(el => highlight(el, match, nextChildKey, props)), }; return elementTypesMap[elementType] ? elementTypesMap[elementType](element, match) : element; }; class Highlighter extends React.PureComponent { constructor(props) { super(props); // we want to create new react keys generator for instance of highlighter this.nextChildKey = childKeyGenerator(); } render() { const { dataHook, children, match } = this.props; return (React.createElement("span", { "data-hook": dataHook }, highlight(children, match, this.nextChildKey, this.props))); } } Highlighter.propTypes = { /** Applied as data-hook HTML attribute that can be used in the tests */ dataHook: PropTypes.string, /** match to highlight */ match: PropTypes.string, /** style of highlight */ emphasize: PropTypes.oneOf(['text', 'background']), }; Highlighter.displayName = 'Highlighter'; export default Highlighter; //# sourceMappingURL=Highlighter.js.map