diff --git a/plugins/woocommerce-blocks/assets/js/components/product-category-control/index.js b/plugins/woocommerce-blocks/assets/js/components/product-category-control/index.js index 4f12c3311d6..409dd975c08 100644 --- a/plugins/woocommerce-blocks/assets/js/components/product-category-control/index.js +++ b/plugins/woocommerce-blocks/assets/js/components/product-category-control/index.js @@ -5,16 +5,15 @@ import { __, _n, sprintf } from '@wordpress/i18n'; import { addQueryArgs } from '@wordpress/url'; import apiFetch from '@wordpress/api-fetch'; import { Component, Fragment } from '@wordpress/element'; -import { find, first, last } from 'lodash'; -import { MenuItem, SelectControl } from '@wordpress/components'; +import { find } from 'lodash'; import PropTypes from 'prop-types'; +import { SelectControl } from '@wordpress/components'; /** * Internal dependencies */ -import './style.scss'; -import { IconChecked, IconUnchecked } from '../icons'; import SearchListControl from '../search-list-control'; +import SearchListItem from '../search-list-control/item'; class ProductCategoryControl extends Component { constructor() { @@ -38,29 +37,10 @@ class ProductCategoryControl extends Component { } ); } - getBreadcrumbsForDisplay( breadcrumbs ) { - if ( breadcrumbs.length === 1 ) { - return first( breadcrumbs ); - } - if ( breadcrumbs.length === 2 ) { - return first( breadcrumbs ) + ' › ' + last( breadcrumbs ); - } - - return first( breadcrumbs ) + ' … ' + last( breadcrumbs ); - } - - renderItem( { - getHighlightedName, - isSelected, - item, - onSelect, - search, - depth = 0, - } ) { + renderItem( args ) { + const { item, search, depth = 0 } = args; const classes = [ - 'woocommerce-search-list__item', 'woocommerce-product-categories__item', - `depth-${ depth }`, ]; if ( search.length ) { classes.push( 'is-searching' ); @@ -74,12 +54,10 @@ class ProductCategoryControl extends Component { `${ item.breadcrumbs.join( ', ' ) }, ${ item.name }`; return ( - - - { isSelected ? : } - - - { !! item.breadcrumbs.length && ( - - { this.getBreadcrumbsForDisplay( item.breadcrumbs ) } - - ) } - - - - { item.count } - - + /> ); } diff --git a/plugins/woocommerce-blocks/assets/js/components/product-category-control/style.scss b/plugins/woocommerce-blocks/assets/js/components/product-category-control/style.scss deleted file mode 100644 index 7bc37a7d55e..00000000000 --- a/plugins/woocommerce-blocks/assets/js/components/product-category-control/style.scss +++ /dev/null @@ -1,97 +0,0 @@ -.woocommerce-product-categories { - .woocommerce-product-categories__item { - display: flex; - align-items: center; - } -} - -.woocommerce-product-categories__item-label { - display: flex; - flex: 1; - - // Anything deeper than 5 levels will use this fallback depth - [class*="depth-"] & { - padding-left: $gap-small * 5; - } - - .depth-0 & { - padding-left: 0; - } - - .depth-1 & { - padding-left: $gap-small; - } - - .depth-2 & { - padding-left: $gap-small * 2; - } - - .depth-3 & { - padding-left: $gap-small * 3; - } - - .depth-4 & { - padding-left: $gap-small * 4; - } -} - -.woocommerce-product-categories__item { - .woocommerce-product-categories__item-name { - display: inline-block; - } - - .woocommerce-product-categories__item-prefix { - display: none; - color: $core-grey-dark-300; - } - - &.is-searching, &.is-skip-level { - .woocommerce-product-categories__item-prefix { - display: inline-block; - margin-right: $gap-smallest; - - &:after { - content: ' ›'; - } - } - } - - &.is-searching { - .woocommerce-product-categories__item-name { - color: $core-grey-dark-900; - } - } - - .woocommerce-product-categories__item-count { - flex: 0; - padding: $gap-smallest/2 $gap-smaller; - border: 1px solid $core-grey-light-500; - border-radius: 12px; - font-size: 0.8em; - line-height: 1.4; - color: $core-grey-dark-300; - background: $white; - } -} - -.woocommerce-product-categories__operator { - margin-bottom: $gap; - text-align: left; - - .components-base-control__label, - .components-select-control__input { - display: inline-block; - margin-bottom: 0; - } - - .components-select-control__input { - margin-left: $gap; - width: auto; - min-width: 15em; - - @include breakpoint( '<480px' ) { - margin-left: 0; - min-width: 100%; - } - } -} diff --git a/plugins/woocommerce-blocks/assets/js/components/search-list-control/index.js b/plugins/woocommerce-blocks/assets/js/components/search-list-control/index.js index fab914f6d92..5a4b22b79de 100644 --- a/plugins/woocommerce-blocks/assets/js/components/search-list-control/index.js +++ b/plugins/woocommerce-blocks/assets/js/components/search-list-control/index.js @@ -4,7 +4,6 @@ import { __, _n, sprintf } from '@wordpress/i18n'; import { Button, - MenuItem, MenuGroup, Spinner, TextControl, @@ -22,7 +21,7 @@ import { Tag } from '@woocommerce/components'; */ import './style.scss'; import { buildTermsTree } from './hierarchy'; -import { IconChecked, IconUnchecked } from '../icons'; +import SearchListItem from './item'; const defaultMessages = { clear: __( 'Clear all selected items', 'woo-gutenberg-products-block' ), @@ -91,45 +90,9 @@ export class SearchListControl extends Component { return isHierarchical ? buildTermsTree( filteredList, list ) : filteredList; } - getHighlightedName( name, search ) { - if ( ! search ) { - return name; - } - const re = new RegExp( escapeRegExp( search ), 'ig' ); - return name.replace( re, '$&' ); - } - - defaultRenderItem( { - depth = 0, - getHighlightedName, - item, - isSelected, - onSelect, - search = '', - } ) { - const classes = [ 'woocommerce-search-list__item' ]; - if ( this.props.isHierarchical ) { - classes.push( `depth-${ depth }` ); - } - + defaultRenderItem( args ) { return ( - - - { isSelected ? : } - - - + ); } @@ -142,7 +105,6 @@ export class SearchListControl extends Component { return list.map( ( item ) => ( { renderItem( { - getHighlightedName: this.getHighlightedName, item, isSelected: this.isSelected( item ), onSelect: this.onSelect, diff --git a/plugins/woocommerce-blocks/assets/js/components/search-list-control/item.js b/plugins/woocommerce-blocks/assets/js/components/search-list-control/item.js new file mode 100644 index 00000000000..c58e602fc7c --- /dev/null +++ b/plugins/woocommerce-blocks/assets/js/components/search-list-control/item.js @@ -0,0 +1,113 @@ +/** + * External dependencies + */ +import { escapeRegExp, first, last } from 'lodash'; +import { MenuItem } from '@wordpress/components'; +import PropTypes from 'prop-types'; + +/** + * Internal dependencies + */ +import { IconChecked, IconUnchecked } from '../icons'; + +function getHighlightedName( name, search ) { + if ( ! search ) { + return name; + } + const re = new RegExp( escapeRegExp( search ), 'ig' ); + return name.replace( re, '$&' ); +} + +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 SearchListItem = ( { + className, + depth = 0, + item, + isSelected, + onSelect, + search = '', + showCount = false, + ...props +} ) => { + const classes = [ className, 'woocommerce-search-list__item' ]; + classes.push( `depth-${ depth }` ); + + const hasBreadcrumbs = item.breadcrumbs && item.breadcrumbs.length; + + return ( + + + { isSelected ? : } + + + + { hasBreadcrumbs ? ( + + { getBreadcrumbsForDisplay( item.breadcrumbs ) } + + ) : null } + + + + { !! showCount && ( + + { item.count } + + ) } + + ); +}; + +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, + /** + * 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; diff --git a/plugins/woocommerce-blocks/assets/js/components/search-list-control/style.scss b/plugins/woocommerce-blocks/assets/js/components/search-list-control/style.scss index cb50ff2c441..307a02a06a9 100644 --- a/plugins/woocommerce-blocks/assets/js/components/search-list-control/style.scss +++ b/plugins/woocommerce-blocks/assets/js/components/search-list-control/style.scss @@ -91,15 +91,6 @@ border-bottom: 1px solid $core-grey-light-500 !important; color: $core-grey-dark-500; - .woocommerce-search-list__item-state { - flex: 0 0 16px; - margin-right: $gap-smaller; - } - - .woocommerce-search-list__item-name { - flex: 1; - } - @include hover-state { background: $core-grey-light-100; } @@ -107,5 +98,64 @@ &:last-of-type { border-bottom: none !important; } + + .woocommerce-search-list__item-state { + flex: 0 0 16px; + margin-right: $gap-smaller; + } + + .woocommerce-search-list__item-label { + display: flex; + flex: 1; + } + + // Anything deeper than 5 levels will use this fallback depth + &[class*="depth-"] .woocommerce-search-list__item-label { + padding-left: $gap-small * 5; + } + + @for $i from 0 to 5 { + &.depth-#{$i} .woocommerce-search-list__item-label { + padding-left: $gap-small * $i; + } + } + + .woocommerce-search-list__item-name { + display: inline-block; + } + + .woocommerce-search-list__item-prefix { + display: none; + color: $core-grey-dark-300; + } + + &.is-searching, + &.is-skip-level { + .woocommerce-search-list__item-prefix { + display: inline-block; + margin-right: $gap-smallest; + + &:after { + content: " ›"; + } + } + } + + &.is-searching { + .woocommerce-search-list__item-name { + color: $core-grey-dark-900; + } + } + + .woocommerce-search-list__item-count { + flex: 0; + padding: $gap-smallest/2 $gap-smaller; + border: 1px solid $core-grey-light-500; + border-radius: 12px; + font-size: 0.8em; + line-height: 1.4; + color: $core-grey-dark-300; + background: $white; + } } } diff --git a/plugins/woocommerce-blocks/assets/js/components/search-list-control/test/__snapshots__/index.js.snap b/plugins/woocommerce-blocks/assets/js/components/search-list-control/test/__snapshots__/index.js.snap index d64a2e5169f..acadcfaafbc 100644 --- a/plugins/woocommerce-blocks/assets/js/components/search-list-control/test/__snapshots__/index.js.snap +++ b/plugins/woocommerce-blocks/assets/js/components/search-list-control/test/__snapshots__/index.js.snap @@ -56,7 +56,7 @@ exports[`SearchListControl should render a search box and list of hierarchical o > @@ -445,7 +484,7 @@ exports[`SearchListControl should render a search box and list of options 1`] = > @@ -834,7 +897,7 @@ exports[`SearchListControl should render a search box and list of options with a > @@ -1306,7 +1393,7 @@ exports[`SearchListControl should render a search box and list of options, with > @@ -1839,7 +1950,7 @@ exports[`SearchListControl should render a search box with a search term, and on > @@ -2009,7 +2128,7 @@ exports[`SearchListControl should render a search box with a search term, and on > @@ -2231,7 +2358,7 @@ exports[`SearchListControl should render a search box, a list of options, and 1 > @@ -2718,7 +2869,7 @@ exports[`SearchListControl should render a search box, a list of options, and 2 >