Commit 1651e582240 for woocommerce
commit 1651e582240ed70b41dbf076498e6dddbe181616
Author: Miroslav Mitev <m1r0@users.noreply.github.com>
Date: Tue Sep 22 14:15:23 2026 +0300
Add searchProps to CompareFilter and FilterPicker (#68816)
* Add searchProps to CompareFilter and FilterPicker
CompareFilter and FilterPicker filters passed type, autocompleter, and labels.placeholder to the inner Search component. Group them under searchProps (settings.searchProps for FilterPicker), so a config can pass any Search prop.
The old props still work and log a deprecation notice. When set, they take precedence over searchProps, so extensions that change them on core report filters keep working.
The Analytics report configs now use searchProps.
diff --git a/packages/js/components/changelog/32254-separate-search-props b/packages/js/components/changelog/32254-separate-search-props
new file mode 100644
index 00000000000..64070c66032
--- /dev/null
+++ b/packages/js/components/changelog/32254-separate-search-props
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add a `searchProps` prop to `CompareFilter` and a `settings.searchProps` option to `FilterPicker` filters, and deprecate the `type`, `autocompleter`, and `labels.placeholder` props they forwarded to `Search`.
diff --git a/packages/js/components/src/compare-filter/README.md b/packages/js/components/src/compare-filter/README.md
index bb3d1372a83..271f9874356 100644
--- a/packages/js/components/src/compare-filter/README.md
+++ b/packages/js/components/src/compare-filter/README.md
@@ -1,5 +1,4 @@
-CompareFilter
-===
+# CompareFilter
Displays a card + search used to filter results as a comparison between objects.
@@ -10,17 +9,20 @@ const path = ''; // from React Router
const getLabels = () => Promise.resolve( [] );
const labels = {
helpText: 'Select at least two products to compare',
- placeholder: 'Search for products to compare',
title: 'Compare Products',
update: 'Compare',
};
+const searchProps = {
+ type: 'products',
+ placeholder: 'Search for products to compare',
+};
<CompareFilter
- type="products"
param="product"
path={ path }
getLabels={ getLabels }
labels={ labels }
+ searchProps={ searchProps }
/>
```
@@ -33,4 +35,8 @@ Name | Type | Default | Description
`param` | String | `null` | (required) The parameter to use in the querystring
`path` | String | `null` | (required) The `path` parameter supplied by React-Router
`query` | Object | `{}` | The query string represented in object form
-`type` | String | `null` | (required) Which type of autocompleter should be used in the Search
+`searchProps` | Object | `{}` | Props forwarded to the `Search` component, except `selected` and `onChange`. `searchProps.type` is required. See [Search](../search/README.md) for the full list
+`type` | String | `null` | Deprecated. Use `searchProps.type` instead
+`autocompleter` | Object | `null` | Deprecated. Use `searchProps.autocompleter` instead
+
+The `labels.placeholder` label is deprecated. Use `searchProps.placeholder` instead. When a deprecated prop is set, it takes precedence over the matching `searchProps` value. The deprecated props are scheduled for removal in `@woocommerce/components` 15.0.0.
diff --git a/packages/js/components/src/compare-filter/index.js b/packages/js/components/src/compare-filter/index.js
index 92e0a41025b..51d30ba70c4 100644
--- a/packages/js/components/src/compare-filter/index.js
+++ b/packages/js/components/src/compare-filter/index.js
@@ -10,8 +10,9 @@ import {
CardFooter,
CardHeader,
} from '@wordpress/components';
-import { isEqual, isFunction } from 'lodash';
+import { isEqual, isFunction, omitBy, isUndefined } from 'lodash';
import PropTypes from 'prop-types';
+import deprecated from '@wordpress/deprecated';
import { getIdsFromQuery, updateQueryString } from '@woocommerce/navigation';
/**
@@ -90,8 +91,32 @@ export class CompareFilter extends Component {
}
}
+ getSearchProps() {
+ const { labels, type, autocompleter, searchProps } = this.props;
+ const legacySearchProps = omitBy(
+ { type, autocompleter, placeholder: labels.placeholder },
+ isUndefined
+ );
+
+ if ( Object.keys( legacySearchProps ).length > 0 ) {
+ deprecated(
+ 'Passing `type`, `autocompleter`, or `labels.placeholder` to CompareFilter',
+ {
+ since: '14.2.0',
+ version: '15.0.0',
+ alternative: 'the `searchProps` prop',
+ link: 'https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/components/src/compare-filter/README.md',
+ plugin: '@woocommerce/components',
+ }
+ );
+ }
+
+ // The deprecated props win, so older code that changes them keeps working.
+ return { ...searchProps, ...legacySearchProps };
+ }
+
render() {
- const { labels, type, autocompleter } = this.props;
+ const { labels } = this.props;
const { selected } = this.state;
return (
<Card className="woocommerce-filters__compare">
@@ -107,10 +132,8 @@ export class CompareFilter extends Component {
</CardHeader>
<CardBody>
<Search
- autocompleter={ autocompleter }
- type={ type }
+ { ...this.getSearchProps() }
selected={ selected }
- placeholder={ labels.placeholder }
onChange={ ( value ) => {
this.setState( { selected: value } );
} }
@@ -146,6 +169,8 @@ CompareFilter.propTypes = {
labels: PropTypes.shape( {
/**
* Label for the search placeholder.
+ *
+ * @deprecated Use `searchProps.placeholder` instead.
*/
placeholder: PropTypes.string,
/**
@@ -170,11 +195,32 @@ CompareFilter.propTypes = {
*/
query: PropTypes.object,
/**
- * Which type of autocompleter should be used in the Search
+ * Props forwarded to the `Search` component, except `selected` and `onChange`.
+ */
+ searchProps: PropTypes.shape( {
+ /**
+ * Which type of autocompleter should be used in the Search.
+ */
+ type: PropTypes.string,
+ /**
+ * The custom autocompleter to use when `type` is `'custom'`.
+ */
+ autocompleter: PropTypes.object,
+ /**
+ * Label for the search placeholder.
+ */
+ placeholder: PropTypes.string,
+ } ),
+ /**
+ * Which type of autocompleter should be used in the Search.
+ *
+ * @deprecated Use `searchProps.type` instead.
*/
- type: PropTypes.string.isRequired,
+ type: PropTypes.string,
/**
* The custom autocompleter to be forwarded to the `Search` component.
+ *
+ * @deprecated Use `searchProps.autocompleter` instead.
*/
autocompleter: PropTypes.object,
};
@@ -182,4 +228,5 @@ CompareFilter.propTypes = {
CompareFilter.defaultProps = {
labels: {},
query: {},
+ searchProps: {},
};
diff --git a/packages/js/components/src/compare-filter/stories/compare-filter.story.js b/packages/js/components/src/compare-filter/stories/compare-filter.story.js
index df798cb7808..05eff0067d2 100644
--- a/packages/js/components/src/compare-filter/stories/compare-filter.story.js
+++ b/packages/js/components/src/compare-filter/stories/compare-filter.story.js
@@ -10,17 +10,19 @@ import { CompareFilter } from '../';
const query = {};
const compareFilter = {
- type: 'products',
param: 'product',
getLabels() {
return Promise.resolve( [] );
},
labels: {
helpText: 'Select at least two products to compare',
- placeholder: 'Search for products to compare',
title: 'Compare Products',
update: 'Compare',
},
+ searchProps: {
+ type: 'products',
+ placeholder: 'Search for products to compare',
+ },
};
export const Basic = ( {
diff --git a/packages/js/components/src/compare-filter/test/compare-filter.js b/packages/js/components/src/compare-filter/test/compare-filter.js
index 18ab9b36057..3ed0d747d0f 100644
--- a/packages/js/components/src/compare-filter/test/compare-filter.js
+++ b/packages/js/components/src/compare-filter/test/compare-filter.js
@@ -3,6 +3,7 @@
*/
import { render } from '@testing-library/react';
import { createElement } from '@wordpress/element';
+import { logged } from '@wordpress/deprecated';
/**
* Internal dependencies
@@ -18,20 +19,26 @@ Search.mockName( 'Search' );
describe( 'CompareFilter', () => {
let props;
+ let warn;
beforeEach( () => {
+ // Reset the deprecation messages, so each test can assert its own warning.
+ Object.keys( logged ).forEach( ( key ) => delete logged[ key ] );
+ warn = jest.spyOn( console, 'warn' ).mockImplementation( () => {} );
props = {
path: '/foo/bar',
- type: 'products',
param: 'product',
getLabels() {
return Promise.resolve( [] );
},
labels: {
helpText: 'Select at least two to compare',
- placeholder: 'Search for things to compare',
title: 'Compare Things',
update: 'Compare',
},
+ searchProps: {
+ type: 'products',
+ placeholder: 'Search for things to compare',
+ },
};
} );
it( 'should render the example from the storybook', () => {
@@ -42,30 +49,84 @@ describe( 'CompareFilter', () => {
} ).not.toThrow();
} );
- it( 'should forward the `type` prop the Search component', () => {
+ it( 'should forward `searchProps` to the Search component', () => {
+ props.searchProps = {
+ type: 'custom',
+ autocompleter: productAutocompleter,
+ placeholder: 'Search for things to compare',
+ showClearButton: true,
+ };
+
+ render( <CompareFilter { ...props } /> );
+
+ // Check that Search component received the props, without checking its behavior/internals/implementation details.
+ expect( Search ).toHaveBeenLastCalledWith(
+ expect.objectContaining( {
+ type: 'custom',
+ autocompleter: productAutocompleter,
+ placeholder: 'Search for things to compare',
+ showClearButton: true,
+ } ),
+ expect.anything()
+ );
+ expect( warn ).not.toHaveBeenCalled();
+ } );
+
+ it( 'should keep control of the `selected` and `onChange` Search props', () => {
+ const onChange = jest.fn();
+ props.searchProps = {
+ type: 'products',
+ selected: [ { key: 1, label: 'Foo' } ],
+ onChange,
+ };
+
+ render( <CompareFilter { ...props } /> );
+
+ const [ searchProps ] = Search.mock.calls.slice( -1 )[ 0 ];
+ expect( searchProps.selected ).toEqual( [] );
+ expect( searchProps.onChange ).not.toBe( onChange );
+ } );
+
+ it( 'should still forward the deprecated `type`, `autocompleter`, and `labels.placeholder` props', () => {
+ delete props.searchProps;
props.type = 'custom';
+ props.autocompleter = productAutocompleter;
+ props.labels.placeholder = 'Search for things to compare';
render( <CompareFilter { ...props } /> );
- // Check that Search component received the prop, without checking its behavior/internals/implementation details.
expect( Search ).toHaveBeenLastCalledWith(
expect.objectContaining( {
type: 'custom',
+ autocompleter: productAutocompleter,
+ placeholder: 'Search for things to compare',
} ),
expect.anything()
);
+ expect( warn ).toHaveBeenCalledWith(
+ expect.stringContaining( 'to CompareFilter' )
+ );
} );
- it( 'should forward the `autocompleter` prop the Search component', () => {
+
+ it( 'should prefer the deprecated props over `searchProps`', () => {
+ props.type = 'custom';
props.autocompleter = productAutocompleter;
+ props.labels.placeholder = 'Changed placeholder';
+ props.searchProps = {
+ type: 'products',
+ placeholder: 'Search for things to compare',
+ };
render( <CompareFilter { ...props } /> );
- // Check that Search component received the prop, without checking its behavior/internals/implementation details.
expect( Search ).toHaveBeenLastCalledWith(
expect.objectContaining( {
+ type: 'custom',
autocompleter: productAutocompleter,
+ placeholder: 'Changed placeholder',
} ),
expect.anything()
);
+ expect( warn ).toHaveBeenCalled();
} );
} );
diff --git a/packages/js/components/src/filter-picker/README.md b/packages/js/components/src/filter-picker/README.md
index 080d7435855..258aa1a013f 100644
--- a/packages/js/components/src/filter-picker/README.md
+++ b/packages/js/components/src/filter-picker/README.md
@@ -1,5 +1,4 @@
-Filter Picker
-===
+# Filter Picker
Modify a url query parameter via a dropdown selection of configurable options. This component manipulates the `filter` query parameter.
@@ -78,5 +77,38 @@ The `filters` prop is an array of filter objects. Each filter object should have
- `component`: String - A custom component used instead of a button, might have special handling for filtering. TBD, not yet implemented.
- `label`: String - The label for this filter. Optional only for custom component filters.
- `path`: String - An array representing the "path" to this filter, if nested.
+- `settings`: Object - Settings for a filter with a `component`, or for a comparison filter. See the `settings` structure below.
- `subFilters`: Array - An array of more filter objects that act as "children" to this item. This set of filters is shown if the parent filter is clicked.
- `value`: String - The value for this filter, used to set the `filter` query param when clicked, if there are no `subFilters`.
+
+### `settings` structure
+
+Two kinds of filter use `settings`. A filter with `component: 'Search'` renders a `Search` component in the dropdown, and `FilterPicker` reads the keys below. A comparison filter (a filter whose `value` starts with `compare`) renders a card instead, and the `Filters` component forwards its `settings` to [CompareFilter](../compare-filter/README.md) as props (`getLabels`, `param`, `labels.title`, `labels.update`, `labels.helpText`, `searchProps`).
+
+A `component: 'Search'` filter has the following `settings` format:
+
+- `param`: String - The url parameter the selected value is stored in.
+- `getLabels`: Function - Function used to fetch labels for the selected values, returns a Promise.
+- `labels.button`: String - Label shown in the dropdown button next to the selected value.
+- `searchProps`: Object - Props forwarded to the `Search` component, except `selected`, `onChange`, `inlineTags`, and `staticResults`. `searchProps.type` is required. See [Search](../search/README.md) for the full list.
+
+```jsx
+{
+ component: 'Search',
+ value: 'single_product',
+ path: [ 'select_product' ],
+ settings: {
+ param: 'products',
+ getLabels: getProductLabels,
+ labels: {
+ button: 'Single product',
+ },
+ searchProps: {
+ type: 'products',
+ placeholder: 'Type to search for a product',
+ },
+ },
+}
+```
+
+The `type`, `autocompleter`, and `labels.placeholder` settings are deprecated. Use `searchProps.type`, `searchProps.autocompleter`, and `searchProps.placeholder` instead. When a deprecated setting is set, it takes precedence over the matching `searchProps` value, so extensions that change it on core filters keep working. The deprecated settings are scheduled for removal in `@woocommerce/components` 15.0.0.
diff --git a/packages/js/components/src/filter-picker/index.js b/packages/js/components/src/filter-picker/index.js
index f962942a3ff..277d208bd51 100644
--- a/packages/js/components/src/filter-picker/index.js
+++ b/packages/js/components/src/filter-picker/index.js
@@ -6,7 +6,16 @@ import { Button, Dropdown } from '@wordpress/components';
import { focus } from '@wordpress/dom';
import clsx from 'clsx';
import { createElement, Component } from '@wordpress/element';
-import { find, partial, last, get, includes } from 'lodash';
+import deprecated from '@wordpress/deprecated';
+import {
+ find,
+ partial,
+ last,
+ get,
+ includes,
+ omitBy,
+ isUndefined,
+} from 'lodash';
import PropTypes from 'prop-types';
import { Icon, chevronLeft } from '@wordpress/icons';
import {
@@ -24,6 +33,37 @@ import Search from '../search';
export const DEFAULT_FILTER = 'all';
+/**
+ * Get the props to forward to the `Search` component of a filter.
+ * The deprecated `type`, `autocompleter`, and `labels.placeholder` settings take precedence over `settings.searchProps`,
+ * so extensions that change them on core filters keep working.
+ *
+ * @param {Object} settings The `settings` of a filter with a `component`.
+ * @return {Object} Props for the `Search` component.
+ */
+function getSearchProps( settings ) {
+ const { type, autocompleter, labels = {}, searchProps = {} } = settings;
+ const legacySearchProps = omitBy(
+ { type, autocompleter, placeholder: labels.placeholder },
+ isUndefined
+ );
+
+ if ( Object.keys( legacySearchProps ).length > 0 ) {
+ deprecated(
+ 'Passing `type`, `autocompleter`, or `labels.placeholder` in the `settings` of a FilterPicker filter',
+ {
+ since: '14.2.0',
+ version: '15.0.0',
+ alternative: '`settings.searchProps`',
+ link: 'https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/components/src/filter-picker/README.md',
+ plugin: '@woocommerce/components',
+ }
+ );
+ }
+
+ return { ...searchProps, ...legacySearchProps };
+}
+
/**
* Modify a url query parameter via a dropdown selection of configurable options.
* This component manipulates the `filter` query parameter.
@@ -202,7 +242,7 @@ class FilterPicker extends Component {
renderButton( filter, onClose, config ) {
if ( filter.component ) {
- const { type, labels, autocompleter } = filter.settings;
+ const searchProps = getSearchProps( filter.settings );
const persistedFilter = this.getFilter();
const selectedTag =
persistedFilter.value === filter.value
@@ -211,10 +251,11 @@ class FilterPicker extends Component {
return (
<Search
- autocompleter={ autocompleter }
- className="woocommerce-filters-filter__search"
- type={ type }
- placeholder={ labels.placeholder }
+ { ...searchProps }
+ className={ clsx(
+ 'woocommerce-filters-filter__search',
+ searchProps.className
+ ) }
selected={ selectedTag ? [ selectedTag ] : [] }
onChange={ partial(
this.onTagChange,
@@ -411,6 +452,45 @@ FilterPicker.propTypes = {
* An array representing the "path" to this filter, if nested.
*/
path: PropTypes.string,
+ /**
+ * Settings for a filter with a `component`, or for a comparison filter.
+ */
+ settings: PropTypes.shape( {
+ /**
+ * The url parameter the selected value is stored in.
+ */
+ param: PropTypes.string,
+ /**
+ * Function used to fetch labels for the selected values, returns a Promise.
+ */
+ getLabels: PropTypes.func,
+ /**
+ * Object of localized labels. `button` is shown in the dropdown button next to the selected value.
+ */
+ labels: PropTypes.shape( {
+ button: PropTypes.string,
+ /**
+ * @deprecated Use `searchProps.placeholder` instead.
+ */
+ placeholder: PropTypes.string,
+ } ),
+ /**
+ * Props forwarded to the `Search` component, except `selected`, `onChange`, `inlineTags`, and `staticResults`.
+ */
+ searchProps: PropTypes.shape( {
+ type: PropTypes.string,
+ autocompleter: PropTypes.object,
+ placeholder: PropTypes.string,
+ } ),
+ /**
+ * @deprecated Use `searchProps.type` instead.
+ */
+ type: PropTypes.string,
+ /**
+ * @deprecated Use `searchProps.autocompleter` instead.
+ */
+ autocompleter: PropTypes.object,
+ } ),
/**
* An array of more filter objects that act as "children" to this item.
* This set of filters is shown if the parent filter is clicked.
diff --git a/packages/js/components/src/filter-picker/test/index.js b/packages/js/components/src/filter-picker/test/index.js
index f30395be38f..389fd50f820 100644
--- a/packages/js/components/src/filter-picker/test/index.js
+++ b/packages/js/components/src/filter-picker/test/index.js
@@ -4,6 +4,7 @@
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { createElement } from '@wordpress/element';
+import { logged } from '@wordpress/deprecated';
/**
* Internal dependencies
@@ -27,7 +28,18 @@ describe( 'FilterPicker', () => {
} );
describe( "when a config is given with a filter with `component: 'Search'`", () => {
let config;
+ let warn;
+ const openDropdown = ( { queryAllByRole } ) => {
+ // The main dropdown does not have its role defined, so we need to dig deeper into actual internals.
+ userEvent.click( queryAllByRole( 'button' )[ 0 ] );
+ };
+ const getLastSearchProps = () =>
+ Search.mock.calls.slice( -1 )[ 0 ][ 0 ];
+
beforeEach( () => {
+ // Reset the deprecation messages, so each test can assert its own warning.
+ Object.keys( logged ).forEach( ( key ) => delete logged[ key ] );
+ warn = jest.spyOn( console, 'warn' ).mockImplementation( () => {} );
config = {
label: 'Show',
staticParams: [],
@@ -41,12 +53,14 @@ describe( 'FilterPicker', () => {
chartMode: 'item-comparison',
path: 'select_product',
settings: {
- type: 'products',
param: 'products',
labels: {
- placeholder: 'Type to search for a product',
button: 'Single Product',
},
+ searchProps: {
+ type: 'products',
+ placeholder: 'Type to search for a product',
+ },
},
},
],
@@ -84,32 +98,95 @@ describe( 'FilterPicker', () => {
// Following will check if it was rendered, not neceserily being visible now.
expect( Search ).toHaveBeenCalled();
} );
- it( "for a `'custom'` type should forward autocompleter config the Search component", async () => {
- const path = '/foo/bar';
+ it( 'should forward `searchProps` to the Search component', async () => {
+ config.filters[ 1 ].settings.searchProps = {
+ type: 'custom',
+ autocompleter: productAutocompleter,
+ placeholder: 'Type to search for a product',
+ showClearButton: true,
+ };
- const customFilterSettings = config.filters[ 1 ].settings;
- customFilterSettings.type = 'custom';
- customFilterSettings.autocompleter = productAutocompleter;
+ openDropdown(
+ render( <FilterPicker path="/foo/bar" config={ config } /> )
+ );
- const { queryAllByRole } = render(
- <FilterPicker path={ path } config={ config } />
+ // Check that Search was rendered with the given props, without checking its behavior/internals/implementation details.
+ expect( getLastSearchProps() ).toMatchObject( {
+ type: 'custom',
+ autocompleter: productAutocompleter,
+ placeholder: 'Type to search for a product',
+ showClearButton: true,
+ } );
+ expect( warn ).not.toHaveBeenCalled();
+ } );
+ it( 'should render a filter without `labels`', async () => {
+ delete config.filters[ 1 ].settings.labels;
+
+ openDropdown(
+ render( <FilterPicker path="/foo/bar" config={ config } /> )
);
- // Emulate filter dropdown being opened.
- // The main dropdown does not have its role defined, so we need to dig deeper into actual internals.
- userEvent.click( queryAllByRole( 'button' )[ 0 ] );
+ expect( getLastSearchProps() ).toMatchObject( {
+ type: 'products',
+ placeholder: 'Type to search for a product',
+ } );
+ expect( warn ).not.toHaveBeenCalled();
+ } );
+ it( 'should keep its own Search props and merge `className`', async () => {
+ config.filters[ 1 ].settings.searchProps = {
+ type: 'products',
+ className: 'my-search',
+ inlineTags: false,
+ staticResults: false,
+ };
- // Check that the given component was rendered, without checking its behavior/internals/implementation details.
- //
- // In vanilla HTML, we would check
- // expect( filterPicker.querySelector('woo-search') ).to.have.a.property( 'autocompleter', autocompleter );
- //
- // Following will check if it was rendered with given props, not neceserily being visible now.
- const lastCallArgs = Search.mock.calls.slice( -1 )[ 0 ];
- expect( lastCallArgs[ 0 ] ).toHaveProperty(
- 'autocompleter',
- productAutocompleter
+ openDropdown(
+ render( <FilterPicker path="/foo/bar" config={ config } /> )
);
+
+ expect( getLastSearchProps() ).toMatchObject( {
+ className: 'woocommerce-filters-filter__search my-search',
+ inlineTags: true,
+ staticResults: true,
+ } );
+ } );
+ it( 'should still forward the deprecated `type`, `autocompleter`, and `labels.placeholder` settings', async () => {
+ const settings = config.filters[ 1 ].settings;
+ delete settings.searchProps;
+ settings.type = 'custom';
+ settings.autocompleter = productAutocompleter;
+ settings.labels.placeholder = 'Type to search for a product';
+
+ openDropdown(
+ render( <FilterPicker path="/foo/bar" config={ config } /> )
+ );
+
+ expect( getLastSearchProps() ).toMatchObject( {
+ type: 'custom',
+ autocompleter: productAutocompleter,
+ placeholder: 'Type to search for a product',
+ } );
+ expect( warn ).toHaveBeenCalledWith(
+ expect.stringContaining( 'FilterPicker filter' )
+ );
+ } );
+ it( 'should prefer the deprecated settings over `searchProps`', async () => {
+ // An extension that changes the settings of a core filter the old way.
+ const settings = config.filters[ 1 ].settings;
+ settings.type = 'custom';
+ settings.autocompleter = productAutocompleter;
+ settings.labels.placeholder = 'Changed placeholder';
+
+ openDropdown(
+ render( <FilterPicker path="/foo/bar" config={ config } /> )
+ );
+
+ expect( getLastSearchProps() ).toMatchObject( {
+ type: 'custom',
+ autocompleter: productAutocompleter,
+ placeholder: 'Changed placeholder',
+ } );
+ expect( warn ).toHaveBeenCalled();
} );
} );
describe( 'getAllFilterParams', () => {
@@ -131,9 +208,9 @@ describe( 'FilterPicker', () => {
chartMode: 'item-comparison',
path: [ 'select_product' ],
settings: {
- type: 'products',
param: 'param_1',
getLabels: () => {},
+ searchProps: { type: 'products' },
},
},
],
@@ -143,10 +220,10 @@ describe( 'FilterPicker', () => {
value: 'compare-products',
chartMode: 'item-comparison',
settings: {
- type: 'products',
param: 'param_2',
getLabels: () => {},
onClick: () => {},
+ searchProps: { type: 'products' },
},
},
],
diff --git a/packages/js/components/src/filters/stories/filters.story.js b/packages/js/components/src/filters/stories/filters.story.js
index 723e72c6229..ae984ad8082 100644
--- a/packages/js/components/src/filters/stories/filters.story.js
+++ b/packages/js/components/src/filters/stories/filters.story.js
@@ -193,17 +193,19 @@ const advancedFilters = {
};
const compareFilter = {
- type: 'products',
param: 'product',
getLabels() {
return Promise.resolve( [] );
},
labels: {
helpText: 'Select at least two products to compare',
- placeholder: 'Search for products to compare',
title: 'Compare Products',
update: 'Compare',
},
+ searchProps: {
+ type: 'products',
+ placeholder: 'Search for products to compare',
+ },
};
export const Examples = () => (
diff --git a/plugins/woocommerce/changelog/32254-separate-search-props b/plugins/woocommerce/changelog/32254-separate-search-props
new file mode 100644
index 00000000000..287c77382da
--- /dev/null
+++ b/plugins/woocommerce/changelog/32254-separate-search-props
@@ -0,0 +1,4 @@
+Significance: minor
+Type: update
+
+Deprecate the `type`, `autocompleter`, and `labels.placeholder` settings of Analytics report filters in favor of `settings.searchProps`, which the core report filters now use.
diff --git a/plugins/woocommerce/client/admin/client/analytics/report/categories/config.js b/plugins/woocommerce/client/admin/client/analytics/report/categories/config.js
index 86fd0c51c23..3e41cda271e 100644
--- a/plugins/woocommerce/client/admin/client/analytics/report/categories/config.js
+++ b/plugins/woocommerce/client/admin/client/analytics/report/categories/config.js
@@ -90,15 +90,17 @@ const filterValues = [
chartMode: 'item-comparison',
path: [ 'select_category' ],
settings: {
- type: 'categories',
param: 'categories',
getLabels: getCategoryLabels,
labels: {
+ button: __( 'Single Category', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'categories',
placeholder: __(
'Type to search for a category',
'woocommerce'
),
- button: __( 'Single Category', 'woocommerce' ),
},
},
},
@@ -109,7 +111,6 @@ const filterValues = [
value: 'compare-categories',
chartMode: 'item-comparison',
settings: {
- type: 'categories',
param: 'categories',
getLabels: getCategoryLabels,
labels: {
@@ -117,12 +118,15 @@ const filterValues = [
'Check at least two categories below to compare',
'woocommerce'
),
+ title: __( 'Compare Categories', 'woocommerce' ),
+ update: __( 'Compare', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'categories',
placeholder: __(
'Search for categories to compare',
'woocommerce'
),
- title: __( 'Compare Categories', 'woocommerce' ),
- update: __( 'Compare', 'woocommerce' ),
},
onClick: addCesSurveyForAnalytics,
},
diff --git a/plugins/woocommerce/client/admin/client/analytics/report/coupons/config.js b/plugins/woocommerce/client/admin/client/analytics/report/coupons/config.js
index 544977bba6f..c2299d6a8cb 100644
--- a/plugins/woocommerce/client/admin/client/analytics/report/coupons/config.js
+++ b/plugins/woocommerce/client/admin/client/analytics/report/coupons/config.js
@@ -78,15 +78,17 @@ const filterValues = [
chartMode: 'item-comparison',
path: [ 'select_coupon' ],
settings: {
- type: 'coupons',
param: 'coupons',
getLabels: getCouponLabels,
labels: {
+ button: __( 'Single Coupon', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'coupons',
placeholder: __(
'Type to search for a coupon',
'woocommerce'
),
- button: __( 'Single Coupon', 'woocommerce' ),
},
},
},
@@ -96,7 +98,6 @@ const filterValues = [
label: __( 'Comparison', 'woocommerce' ),
value: 'compare-coupons',
settings: {
- type: 'coupons',
param: 'coupons',
getLabels: getCouponLabels,
labels: {
@@ -107,6 +108,9 @@ const filterValues = [
'woocommerce'
),
},
+ searchProps: {
+ type: 'coupons',
+ },
onClick: addCesSurveyForAnalytics,
},
},
diff --git a/plugins/woocommerce/client/admin/client/analytics/report/customers/config.js b/plugins/woocommerce/client/admin/client/analytics/report/customers/config.js
index ee4b752a17c..79735cae4d4 100644
--- a/plugins/woocommerce/client/admin/client/analytics/report/customers/config.js
+++ b/plugins/woocommerce/client/admin/client/analytics/report/customers/config.js
@@ -49,15 +49,17 @@ export const filters = applyFilters( CUSTOMERS_REPORT_FILTERS_FILTER, [
chartMode: 'item-comparison',
path: [ 'select_customer' ],
settings: {
- type: 'customerNames',
param: 'customers',
getLabels: getCustomerLabels,
labels: {
+ button: __( 'Single Customer', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'customerNames',
placeholder: __(
'Type to search for a customer',
'woocommerce'
),
- button: __( 'Single Customer', 'woocommerce' ),
},
},
},
diff --git a/plugins/woocommerce/client/admin/client/analytics/report/products/config.js b/plugins/woocommerce/client/admin/client/analytics/report/products/config.js
index 450e2c6d0f3..f65c6af2439 100644
--- a/plugins/woocommerce/client/admin/client/analytics/report/products/config.js
+++ b/plugins/woocommerce/client/admin/client/analytics/report/products/config.js
@@ -75,15 +75,17 @@ const filterConfig = {
chartMode: 'item-comparison',
path: [ 'select_product' ],
settings: {
- type: 'products',
param: 'products',
getLabels: getProductLabels,
labels: {
+ button: __( 'Single product', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'products',
placeholder: __(
'Type to search for a product',
'woocommerce'
),
- button: __( 'Single product', 'woocommerce' ),
},
},
},
@@ -94,7 +96,6 @@ const filterConfig = {
value: 'compare-products',
chartMode: 'item-comparison',
settings: {
- type: 'products',
param: 'products',
getLabels: getProductLabels,
labels: {
@@ -102,12 +103,15 @@ const filterConfig = {
'Check at least two products below to compare',
'woocommerce'
),
+ title: __( 'Compare Products', 'woocommerce' ),
+ update: __( 'Compare', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'products',
placeholder: __(
'Search for products to compare',
'woocommerce'
),
- title: __( 'Compare Products', 'woocommerce' ),
- update: __( 'Compare', 'woocommerce' ),
},
onClick: addCesSurveyForAnalytics,
},
@@ -137,15 +141,17 @@ const variationsConfig = {
value: 'single_variation',
path: [ 'select_variation' ],
settings: {
- type: 'variations',
param: 'variations',
getLabels: getVariationLabels,
labels: {
+ button: __( 'Single variation', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'variations',
placeholder: __(
'Type to search for a variation',
'woocommerce'
),
- button: __( 'Single variation', 'woocommerce' ),
},
},
},
@@ -156,7 +162,6 @@ const variationsConfig = {
chartMode: 'item-comparison',
value: 'compare-variations',
settings: {
- type: 'variations',
param: 'variations',
getLabels: getVariationLabels,
labels: {
@@ -164,12 +169,15 @@ const variationsConfig = {
'Check at least two variations below to compare',
'woocommerce'
),
+ title: __( 'Compare Variations', 'woocommerce' ),
+ update: __( 'Compare', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'variations',
placeholder: __(
'Search for variations to compare',
'woocommerce'
),
- title: __( 'Compare Variations', 'woocommerce' ),
- update: __( 'Compare', 'woocommerce' ),
},
},
},
diff --git a/plugins/woocommerce/client/admin/client/analytics/report/taxes/config.js b/plugins/woocommerce/client/admin/client/analytics/report/taxes/config.js
index 4bafcdeec46..3be37f2938b 100644
--- a/plugins/woocommerce/client/admin/client/analytics/report/taxes/config.js
+++ b/plugins/woocommerce/client/admin/client/analytics/report/taxes/config.js
@@ -122,7 +122,6 @@ const filterValues = [
value: 'compare-taxes',
chartMode: 'item-comparison',
settings: {
- type: 'taxes',
param: 'taxes',
getLabels: getRequestByIdString(
NAMESPACE + '/taxes',
@@ -137,12 +136,15 @@ const filterValues = [
'Check at least two tax codes below to compare',
'woocommerce'
),
+ title: __( 'Compare Tax Codes', 'woocommerce' ),
+ update: __( 'Compare', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'taxes',
placeholder: __(
'Search for tax codes to compare',
'woocommerce'
),
- title: __( 'Compare Tax Codes', 'woocommerce' ),
- update: __( 'Compare', 'woocommerce' ),
},
onClick: addCesSurveyForAnalytics,
},
diff --git a/plugins/woocommerce/client/admin/client/analytics/report/variations/config.js b/plugins/woocommerce/client/admin/client/analytics/report/variations/config.js
index 24b8f643248..fb2d68b2bae 100644
--- a/plugins/woocommerce/client/admin/client/analytics/report/variations/config.js
+++ b/plugins/woocommerce/client/admin/client/analytics/report/variations/config.js
@@ -89,15 +89,17 @@ export const filters = applyFilters( VARIATIONS_REPORT_FILTERS_FILTER, [
value: 'single_variation',
path: [ 'select_variation' ],
settings: {
- type: 'variations',
param: 'variations',
getLabels: getVariationLabels,
labels: {
+ button: __( 'Single variation', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'variations',
placeholder: __(
'Type to search for a variation',
'woocommerce'
),
- button: __( 'Single variation', 'woocommerce' ),
},
},
},
@@ -108,7 +110,6 @@ export const filters = applyFilters( VARIATIONS_REPORT_FILTERS_FILTER, [
chartMode: 'item-comparison',
value: 'compare-variations',
settings: {
- type: 'variations',
param: 'variations',
getLabels: getVariationLabels,
labels: {
@@ -116,12 +117,15 @@ export const filters = applyFilters( VARIATIONS_REPORT_FILTERS_FILTER, [
'Check at least two variations below to compare',
'woocommerce'
),
+ title: __( 'Compare Variations', 'woocommerce' ),
+ update: __( 'Compare', 'woocommerce' ),
+ },
+ searchProps: {
+ type: 'variations',
placeholder: __(
'Search for variations to compare',
'woocommerce'
),
- title: __( 'Compare Variations', 'woocommerce' ),
- update: __( 'Compare', 'woocommerce' ),
},
onClick: addCesSurveyForAnalytics,
},