woocommerce/plugins/woocommerce-blocks/assets/js/components/search-list-control/item.js

133 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* External dependencies
*/
import { escapeRegExp, first, last } from 'lodash';
import { MenuItem } from '@wordpress/components';
import PropTypes from 'prop-types';
/**
* Internal dependencies
*/
import {
IconCheckChecked,
IconCheckUnchecked,
IconRadioSelected,
IconRadioUnselected,
} from '../icons';
function getHighlightedName( name, search ) {
if ( ! search ) {
return name;
}
const re = new RegExp( escapeRegExp( search ), 'ig' );
return name.replace( re, '<strong>$&</strong>' );
}
function getBreadcrumbsForDisplay( breadcrumbs ) {
if ( breadcrumbs.length === 1 ) {
return first( breadcrumbs );
}
if ( breadcrumbs.length === 2 ) {
return first( breadcrumbs ) + ' ' + last( breadcrumbs );
}
return first( breadcrumbs ) + ' … ' + last( breadcrumbs );
}
const getInteractionIcon = ( isSingle = false, isSelected = false ) => {
if ( isSingle ) {
return isSelected ? <IconRadioSelected /> : <IconRadioUnselected />;
}
return isSelected ? <IconCheckChecked /> : <IconCheckUnchecked />;
};
const SearchListItem = ( {
className,
depth = 0,
item,
isSelected,
isSingle,
onSelect,
search = '',
showCount = false,
...props
} ) => {
const classes = [ className, 'woocommerce-search-list__item' ];
classes.push( `depth-${ depth }` );
if ( isSingle ) {
classes.push( 'is-radio-button' );
}
const hasBreadcrumbs = item.breadcrumbs && item.breadcrumbs.length;
return (
<MenuItem
role="menuitemcheckbox"
className={ classes.join( ' ' ) }
onClick={ onSelect( item ) }
isSelected={ isSelected }
{ ...props }
>
<span className="woocommerce-search-list__item-state">
{ getInteractionIcon( isSingle, isSelected ) }
</span>
<span className="woocommerce-search-list__item-label">
{ hasBreadcrumbs ? (
<span className="woocommerce-search-list__item-prefix">
{ getBreadcrumbsForDisplay( item.breadcrumbs ) }
</span>
) : null }
<span
className="woocommerce-search-list__item-name"
dangerouslySetInnerHTML={ {
__html: getHighlightedName( item.name, search ),
} }
/>
</span>
{ !! showCount && (
<span className="woocommerce-search-list__item-count">
{ item.count }
</span>
) }
</MenuItem>
);
};
SearchListItem.propTypes = {
/**
* Additional CSS classes.
*/
className: PropTypes.string,
/**
* Depth, non-zero if the list is hierarchical.
*/
depth: PropTypes.number,
/**
* Current item to display.
*/
item: PropTypes.object,
/**
* Whether this item is selected.
*/
isSelected: PropTypes.bool,
/**
* Whether this should only display a single item (controls radio vs checkbox icon).
*/
isSingle: PropTypes.bool,
/**
* Callback for selecting the item.
*/
onSelect: PropTypes.func,
/**
* Search string, used to highlight the substring in the item name.
*/
search: PropTypes.string,
/**
* Toggles the "count" bubble on/off.
*/
showCount: PropTypes.bool,
};
export default SearchListItem;