This commit is contained in:
Kelly Dwan 2018-09-07 15:39:04 -04:00 committed by GitHub
parent 069fcb7fe6
commit cbce093df1
5 changed files with 87 additions and 15 deletions

View File

@ -3,3 +3,4 @@
* Export all autocompleters
*/
export { default as product } from './product';
export { default as productCategory } from './product-cat';

View File

@ -0,0 +1,60 @@
/** @format */
/**
* External dependencies
*/
import apiFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
import { computeSuggestionMatch } from './utils';
import { stringifyQuery } from 'lib/nav-utils';
/**
* A product categories completer.
* See https://github.com/WordPress/gutenberg/tree/master/packages/components/src/autocomplete#the-completer-interface
*
* @type {Completer}
*/
export default {
name: 'product_cats',
className: 'woocommerce-search__product-result',
options( search ) {
let payload = '';
if ( search ) {
const query = {
search: encodeURIComponent( search ),
per_page: 10,
orderby: 'count',
};
payload = stringifyQuery( query );
}
return apiFetch( { path: '/wc/v3/products/categories' + payload } );
},
isDebounced: true,
getOptionKeywords( cat ) {
return [ cat.name ];
},
getOptionLabel( cat, query ) {
const match = computeSuggestionMatch( cat.name, query ) || {};
// @todo bring back ProductImage, but allow for product category image
return [
<span key="name" className="woocommerce-search__result-name" aria-label={ cat.name }>
{ match.suggestionBeforeMatch }
<strong className="components-form-token-field__suggestion-match">
{ match.suggestionMatch }
</strong>
{ match.suggestionAfterMatch }
</span>,
];
},
// This is slightly different than gutenberg/Autocomplete, we don't support different methods
// of replace/insertion, so we can just return the value.
getOptionCompletion( cat ) {
const value = {
id: cat.id,
label: cat.name,
};
return value;
},
};

View File

@ -7,22 +7,10 @@ import apiFetch from '@wordpress/api-fetch';
/**
* Internal dependencies
*/
import { computeSuggestionMatch } from './utils';
import ProductImage from 'components/product-image';
import { stringifyQuery } from 'lib/nav-utils';
const computeSuggestionMatch = ( suggestion, query ) => {
if ( ! query ) {
return null;
}
const indexOfMatch = suggestion.toLocaleLowerCase().indexOf( query.toLocaleLowerCase() );
return {
suggestionBeforeMatch: suggestion.substring( 0, indexOfMatch ),
suggestionMatch: suggestion.substring( indexOfMatch, indexOfMatch + query.length ),
suggestionAfterMatch: suggestion.substring( indexOfMatch + query.length ),
};
};
/**
* A products completer.
* See https://github.com/WordPress/gutenberg/tree/master/packages/components/src/autocomplete#the-completer-interface

View File

@ -0,0 +1,21 @@
/** @format */
/**
* Parse a string suggestion, split apart by where the first matching query is.
* Used to display matched partial in bold.
*
* @param {string} suggestion The item's label as returned from the API.
* @param {string} query The search term to match in the string.
* @return {object} A list in three parts: before, match, and after.
*/
export function computeSuggestionMatch( suggestion, query ) {
if ( ! query ) {
return null;
}
const indexOfMatch = suggestion.toLocaleLowerCase().indexOf( query.toLocaleLowerCase() );
return {
suggestionBeforeMatch: suggestion.substring( 0, indexOfMatch ),
suggestionMatch: suggestion.substring( indexOfMatch, indexOfMatch + query.length ),
suggestionAfterMatch: suggestion.substring( indexOfMatch + query.length ),
};
}

View File

@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
* Internal dependencies
*/
import Autocomplete from './autocomplete';
import { product } from './autocompleters';
import { product, productCategory } from './autocompleters';
import Tag from 'components/tag';
import './style.scss';
@ -61,6 +61,8 @@ class Search extends Component {
switch ( this.props.type ) {
case 'products':
return product;
case 'product_cats':
return productCategory;
default:
return {};
}
@ -119,7 +121,7 @@ Search.propTypes = {
/**
* The object type to be used in searching.
*/
type: PropTypes.oneOf( [ 'products', 'orders', 'customers' ] ).isRequired,
type: PropTypes.oneOf( [ 'products', 'product_cats', 'orders', 'customers' ] ).isRequired,
/**
* An array of objects describing selected values
*/