import * as React from 'react'; import * as _ from 'lodash'; import * as DefaultStyles from './style'; export namespace DropDownItem { export interface Props { /** * Indicates if the item is focused, changing the style depending on the value */ focused: boolean; /** * Chunk to be highlighted inside the value */ highlightedChunk?: string; /** * Function called when the user clicks in the component */ onClick: (event, value: { toString: () => string }) => void; /** * Function called when the mouse enters in the component */ onMouseEnter: (event, value: { toString: () => string }, position: number) => void; /** * Position of the component in the list */ position: number; /** * Prop to customize styles */ styles?: Styles; /** * Text displayed */ value: { toString: () => string }; id?: string; name?: string; } export interface Styles { /** * Styles for the highlighted chunks */ HighlightedItemChunk?: any; /** * Styles for the component if focused */ ListItemFocused?: any; /** * Styles for the component if not focused */ ListItemNotFocused?: any; /** * Styles for the not highlighted chunks */ RegularItemChunk?: any; } } /** * Component that displays an item with a description. Useful for rendering the dropdown component options * * @version 1.0.0 * */ export const DropDownItem = (props: DropDownItem.Props) => { const handleItemClick = () => { props.onClick(event, props.value); }; const handleItemMouseEnter = () => { props.onMouseEnter(event, props.value, props.position); }; /** * Renders a component with key a string inside */ const renderValue = (Component: any, value: string, className: string, index: number) => { return ( {value} ); }; /** * Divides the value in chunks, indicating which ones should be highlighted */ const processChunksDisplay = (value: string, chunkToHighlight?: string) => { const upperCaseChunkToHighlight = chunkToHighlight ? chunkToHighlight.toUpperCase() : ''; const chunksRegex = new RegExp(`(${upperCaseChunkToHighlight})`, 'i'); const chunks = value.split(chunksRegex); return chunks.filter((chunk) => (chunk !== '')).map((chunk, index) => ({ chunk, highlighted: chunk.toUpperCase() === upperCaseChunkToHighlight })); }; /** * Renders the value, highlighting the corresponding chunks */ const renderChunks = (Styles: DropDownItem.Styles) => { const chunks = processChunksDisplay(props.value.toString(), props.highlightedChunk); return chunks.map((chunkData, index) => ( chunkData.highlighted ? ( renderValue(Styles.HighlightedItemChunk, chunkData.chunk, 'drop-down-item-highlighted-value', index) ) : ( renderValue(Styles.RegularItemChunk, chunkData.chunk, 'drop-down-item-value', index) ) )) }; const Styles: DropDownItem.Styles = _.merge(DefaultStyles, props.styles); const ListItemComponent = props.focused ? Styles.ListItemFocused : Styles.ListItemNotFocused; return ( { props.highlightedChunk ? renderChunks(Styles) : renderValue(Styles.RegularItemChunk, props.value.toString(), 'drop-down-item-value', 0) } ); }