Merge pull request woocommerce/woocommerce-admin#457 from woocommerce/fix/advanced-filters-i18n

i18n: Advanced Filters strings
This commit is contained in:
Paul Sealock 2018-10-16 10:54:45 +13:00 committed by GitHub
commit 4bc8c82820
9 changed files with 316 additions and 242 deletions

View File

@ -2,7 +2,7 @@
/** /**
* External dependencies * External dependencies
*/ */
import { __ } from '@wordpress/i18n'; import { __, _x } from '@wordpress/i18n';
/** /**
* Internal dependencies * Internal dependencies
@ -30,87 +30,123 @@ export const filters = [
{ label: __( 'Advanced Filters', 'wc-admin' ), value: 'advanced' }, { label: __( 'Advanced Filters', 'wc-admin' ), value: 'advanced' },
]; ];
/*eslint-disable max-len*/
export const advancedFilterConfig = { export const advancedFilterConfig = {
status: { title: _x(
labels: { 'Orders Match {{select /}} Filters',
add: __( 'Order Status', 'wc-admin' ), 'A sentence describing filters for Orders. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ',
remove: __( 'Remove order status filter', 'wc-admin' ), 'wc-admin'
rule: __( 'Select an order status filter match', 'wc-admin' ), ),
title: __( 'Order Status', 'wc-admin' ), filters: {
}, status: {
rules: [ labels: {
{ value: 'is', label: __( 'Is', 'wc-admin' ) }, add: __( 'Order Status', 'wc-admin' ),
{ value: 'is_not', label: __( 'Is Not', 'wc-admin' ) }, remove: __( 'Remove order status filter', 'wc-admin' ),
], rule: __( 'Select an order status filter match', 'wc-admin' ),
input: { /* translators: A sentence describing an Order Status filter. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ */
component: 'SelectControl', title: __( 'Order Status {{rule /}} {{filter /}}', 'wc-admin' ),
options: Object.keys( orderStatuses ).map( key => ( { filter: __( 'Select an order status', 'wc-admin' ),
value: key, },
label: orderStatuses[ key ], rules: [
} ) ), {
defaultOption: 'wc-cancelled', value: 'is',
}, /* translators: Sentence fragment, logical, "Is" refers to searching for orders matching a chosen order status. Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
}, label: _x( 'Is', 'order status', 'wc-admin' ),
product_id: { },
labels: { {
add: __( 'Products', 'wc-admin' ), value: 'is_not',
placeholder: __( 'Search products', 'wc-admin' ), /* translators: Sentence fragment, logical, "Is Not" refers to searching for orders that don\'t match a chosen order status. Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
remove: __( 'Remove products filter', 'wc-admin' ), label: _x( 'Is Not', 'order status', 'wc-admin' ),
rule: __( 'Select a product filter match', 'wc-admin' ), },
title: __( 'Product', 'wc-admin' ),
},
rules: [
{ value: 'includes', label: __( 'Includes', 'wc-admin' ) },
{ value: 'excludes', label: __( 'Excludes', 'wc-admin' ) },
{ value: 'is', label: __( 'Is', 'wc-admin' ) },
{ value: 'is_not', label: __( 'Is Not', 'wc-admin' ) },
],
input: {
component: 'Search',
type: 'products',
getLabels: getRequestByIdString( NAMESPACE + 'products', product => ( {
id: product.id,
label: product.name,
} ) ),
},
},
code: {
labels: {
add: __( 'Coupon Codes', 'wc-admin' ),
placeholder: __( 'Search coupons', 'wc-admin' ),
remove: __( 'Remove coupon filter', 'wc-admin' ),
rule: __( 'Select a coupon filter match', 'wc-admin' ),
title: __( 'Coupon Code', 'wc-admin' ),
},
rules: [
{ value: 'includes', label: __( 'Includes', 'wc-admin' ) },
{ value: 'excludes', label: __( 'Excludes', 'wc-admin' ) },
{ value: 'is', label: __( 'Is', 'wc-admin' ) },
{ value: 'is_not', label: __( 'Is Not', 'wc-admin' ) },
],
input: {
component: 'Search',
type: 'coupons',
getLabels: getRequestByIdString( NAMESPACE + 'coupons', coupon => ( {
id: coupon.id,
label: coupon.code,
} ) ),
},
},
customer: {
labels: {
add: __( 'Customer Type', 'wc-admin' ),
remove: __( 'Remove customer filter', 'wc-admin' ),
rule: __( 'Select a customer filter match', 'wc-admin' ),
title: __( 'Customer is', 'wc-admin' ),
},
input: {
component: 'SelectControl',
options: [
{ value: 'new', label: __( 'New', 'wc-admin' ) },
{ value: 'returning', label: __( 'Returning', 'wc-admin' ) },
], ],
defaultOption: 'new', input: {
component: 'SelectControl',
options: Object.keys( orderStatuses ).map( key => ( {
value: key,
label: orderStatuses[ key ],
} ) ),
},
},
product: {
labels: {
add: __( 'Products', 'wc-admin' ),
placeholder: __( 'Search products', 'wc-admin' ),
remove: __( 'Remove products filter', 'wc-admin' ),
rule: __( 'Select a product filter match', 'wc-admin' ),
/* translators: A sentence describing a Product filter. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ */
title: __( 'Product {{rule /}} {{filter /}}', 'wc-admin' ),
filter: __( 'Select products', 'wc-admin' ),
},
rules: [
{
value: 'includes',
/* translators: Sentence fragment, logical, "Includes" refers to orders including a given product(s). Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
label: _x( 'Includes', 'products', 'wc-admin' ),
},
{
value: 'excludes',
/* translators: Sentence fragment, logical, "Excludes" refers to orders excluding a given product(s). Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
label: _x( 'Excludes', 'products', 'wc-admin' ),
},
],
input: {
component: 'Search',
type: 'products',
getLabels: getRequestByIdString( NAMESPACE + 'products', product => ( {
id: product.id,
label: product.name,
} ) ),
},
},
code: {
labels: {
add: __( 'Coupon Codes', 'wc-admin' ),
placeholder: __( 'Search coupons', 'wc-admin' ),
remove: __( 'Remove coupon filter', 'wc-admin' ),
rule: __( 'Select a coupon filter match', 'wc-admin' ),
/* translators: A sentence describing a Coupon filter. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ */
title: __( 'Coupon Code {{rule /}} {{filter /}}', 'wc-admin' ),
filter: __( 'Select coupon codes', 'wc-admin' ),
},
rules: [
{
value: 'includes',
/* translators: Sentence fragment, logical, "Includes" refers to orders including a given coupon code(s). Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
label: _x( 'Includes', 'coupon code', 'wc-admin' ),
},
{
value: 'excludes',
/* translators: Sentence fragment, logical, "Excludes" refers to orders excluding a given coupon code(s). Screenshot for context: https://cloudup.com/cSsUY9VeCVJ */
label: _x( 'Excludes', 'coupon code', 'wc-admin' ),
},
],
input: {
component: 'Search',
type: 'coupons',
getLabels: getRequestByIdString( NAMESPACE + 'coupons', coupon => ( {
id: coupon.id,
label: coupon.code,
} ) ),
},
},
customer: {
labels: {
add: __( 'Customer Type', 'wc-admin' ),
remove: __( 'Remove customer filter', 'wc-admin' ),
rule: __( 'Select a customer filter match', 'wc-admin' ),
/* translators: A sentence describing a Customer filter. See screen shot for context: https://cloudup.com/cSsUY9VeCVJ */
title: __( 'Customer is {{filter /}}', 'wc-admin' ),
filter: __( 'Select a customer type', 'wc-admin' ),
},
input: {
component: 'SelectControl',
options: [
{ value: 'new', label: __( 'New', 'wc-admin' ) },
{ value: 'returning', label: __( 'Returning', 'wc-admin' ) },
],
defaultOption: 'new',
},
}, },
}, },
}; };
/*eslint-enable max-len*/

View File

@ -2,12 +2,13 @@
/** /**
* External dependencies * External dependencies
*/ */
import { __, sprintf } from '@wordpress/i18n'; import { __ } from '@wordpress/i18n';
import { Component, Fragment, createRef } from '@wordpress/element'; import { Component, createRef } from '@wordpress/element';
import { SelectControl, Button, Dropdown, IconButton } from '@wordpress/components'; import { SelectControl, Button, Dropdown, IconButton } from '@wordpress/components';
import { partial, findIndex, difference } from 'lodash'; import { partial, findIndex, difference } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import Gridicon from 'gridicons'; import Gridicon from 'gridicons';
import interpolateComponents from 'interpolate-components';
/** /**
* Internal dependencies * Internal dependencies
@ -37,7 +38,7 @@ class AdvancedFilters extends Component {
super( ...arguments ); super( ...arguments );
this.state = { this.state = {
match: query.match || 'all', match: query.match || 'all',
activeFilters: getActiveFiltersFromQuery( query, config ), activeFilters: getActiveFiltersFromQuery( query, config.filters ),
}; };
this.filterListRef = createRef(); this.filterListRef = createRef();
@ -75,30 +76,31 @@ class AdvancedFilters extends Component {
getTitle() { getTitle() {
const { match } = this.state; const { match } = this.state;
const { filterTitle } = this.props; const { config } = this.props;
return ( return interpolateComponents( {
<Fragment> mixedString: config.title,
<span>{ sprintf( __( '%s Match', 'wc-admin' ), filterTitle ) }</span> components: {
<SelectControl select: (
className="woocommerce-filters-advanced__title-select" <SelectControl
options={ matches } className="woocommerce-filters-advanced__title-select"
value={ match } options={ matches }
onChange={ this.onMatchChange } value={ match }
aria-label={ __( 'Match any or all filters', 'wc-admin' ) } onChange={ this.onMatchChange }
/> aria-label={ __( 'Choose to apply any or all filters', 'wc-admin' ) }
<span>{ __( 'Filters', 'wc-admin' ) }</span> />
</Fragment> ),
); },
} );
} }
getAvailableFilterKeys() { getAvailableFilterKeys() {
const { config } = this.props; const { config } = this.props;
const activeFilterKeys = this.state.activeFilters.map( f => f.key ); const activeFilterKeys = this.state.activeFilters.map( f => f.key );
return difference( Object.keys( config ), activeFilterKeys ); return difference( Object.keys( config.filters ), activeFilterKeys );
} }
addFilter( key, onClose ) { addFilter( key, onClose ) {
const filterConfig = this.props.config[ key ]; const filterConfig = this.props.config.filters[ key ];
const newFilter = { key }; const newFilter = { key };
if ( Array.isArray( filterConfig.rules ) && filterConfig.rules.length ) { if ( Array.isArray( filterConfig.rules ) && filterConfig.rules.length ) {
newFilter.rule = filterConfig.rules[ 0 ].value; newFilter.rule = filterConfig.rules[ 0 ].value;
@ -131,46 +133,47 @@ class AdvancedFilters extends Component {
getUpdateHref( activeFilters, matchValue ) { getUpdateHref( activeFilters, matchValue ) {
const { path, query, config } = this.props; const { path, query, config } = this.props;
const updatedQuery = getQueryFromActiveFilters( activeFilters, query, config ); const updatedQuery = getQueryFromActiveFilters( activeFilters, query, config.filters );
const match = matchValue === 'all' ? undefined : matchValue; const match = matchValue === 'all' ? undefined : matchValue;
return getNewPath( { ...updatedQuery, match }, path, query ); return getNewPath( { ...updatedQuery, match }, path, query );
} }
isEnglish() {
const { siteLocale } = wcSettings;
return /en-/.test( siteLocale );
}
render() { render() {
const { config } = this.props; const { config } = this.props;
const { activeFilters, match } = this.state; const { activeFilters, match } = this.state;
const availableFilterKeys = this.getAvailableFilterKeys(); const availableFilterKeys = this.getAvailableFilterKeys();
const updateHref = this.getUpdateHref( activeFilters, match ); const updateHref = this.getUpdateHref( activeFilters, match );
const updateDisabled = window.location.hash && window.location.hash.substr( 1 ) === updateHref; const updateDisabled = window.location.hash && window.location.hash.substr( 1 ) === updateHref;
const isEnglish = this.isEnglish();
return ( return (
<Card className="woocommerce-filters-advanced" title={ this.getTitle() }> <Card className="woocommerce-filters-advanced" title={ this.getTitle() }>
<ul className="woocommerce-filters-advanced__list" ref={ this.filterListRef }> <ul className="woocommerce-filters-advanced__list" ref={ this.filterListRef }>
{ activeFilters.map( filter => { { activeFilters.map( filter => {
const { key } = filter; const { key } = filter;
const { input, labels } = config[ key ]; const { input, labels } = config.filters[ key ];
return ( return (
<li className="woocommerce-filters-advanced__list-item" key={ key }> <li className="woocommerce-filters-advanced__list-item" key={ key }>
{ /*eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex*/ } { 'SelectControl' === input.component && (
<fieldset tabIndex="0"> <SelectFilter
{ /*eslint-enable-next-line jsx-a11y/no-noninteractive-tabindex*/ } filter={ filter }
<legend className="screen-reader-text">{ labels.title }</legend> config={ config.filters[ key ] }
<div className="woocommerce-filters-advanced__fieldset"> onFilterChange={ this.onFilterChange }
{ 'SelectControl' === input.component && ( isEnglish={ isEnglish }
<SelectFilter />
filter={ filter } ) }
config={ config[ key ] } { 'Search' === input.component && (
onFilterChange={ this.onFilterChange } <SearchFilter
/> filter={ filter }
) } config={ config.filters[ key ] }
{ 'Search' === input.component && ( onFilterChange={ this.onFilterChange }
<SearchFilter isEnglish={ isEnglish }
filter={ filter } />
config={ config[ key ] } ) }
onFilterChange={ this.onFilterChange }
/>
) }
</div>
</fieldset>
<IconButton <IconButton
className="woocommerce-filters-advanced__remove" className="woocommerce-filters-advanced__remove"
label={ labels.remove } label={ labels.remove }
@ -201,7 +204,7 @@ class AdvancedFilters extends Component {
{ availableFilterKeys.map( key => ( { availableFilterKeys.map( key => (
<li key={ key }> <li key={ key }>
<Button onClick={ partial( this.addFilter, key, onClose ) }> <Button onClick={ partial( this.addFilter, key, onClose ) }>
{ config[ key ].labels.add } { config.filters[ key ].labels.add }
</Button> </Button>
</li> </li>
) ) } ) ) }
@ -239,25 +242,25 @@ AdvancedFilters.propTypes = {
/** /**
* The configuration object required to render filters. * The configuration object required to render filters.
*/ */
config: PropTypes.objectOf( config: PropTypes.shape( {
PropTypes.shape( { title: PropTypes.string,
labels: PropTypes.shape( { filters: PropTypes.objectOf(
add: PropTypes.string, PropTypes.shape( {
placeholder: PropTypes.string, labels: PropTypes.shape( {
remove: PropTypes.string, add: PropTypes.string,
title: PropTypes.string, remove: PropTypes.string,
} ), rule: PropTypes.string,
rules: PropTypes.arrayOf( PropTypes.object ), title: PropTypes.string,
input: PropTypes.object, filter: PropTypes.string,
} ) } ),
).isRequired, rules: PropTypes.arrayOf( PropTypes.object ),
input: PropTypes.object,
} )
),
} ).isRequired,
/** /**
* Name of this filter, used in translations. * Name of this filter, used in translations.
*/ */
filterTitle: PropTypes.string.isRequired,
/**
* The `path` parameter supplied by React-Router.
*/
path: PropTypes.string.isRequired, path: PropTypes.string.isRequired,
/** /**
* The query string represented in object form. * The query string represented in object form.

View File

@ -2,11 +2,12 @@
/** /**
* External dependencies * External dependencies
*/ */
import { Component, Fragment } from '@wordpress/element'; import { Component } from '@wordpress/element';
import { SelectControl } from '@wordpress/components'; import { SelectControl } from '@wordpress/components';
import { partial } from 'lodash'; import { find, partial } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withInstanceId } from '@wordpress/compose'; import interpolateComponents from 'interpolate-components';
import classnames from 'classnames';
/** /**
* Internal dependencies * Internal dependencies
@ -41,40 +42,66 @@ class SearchFilter extends Component {
onFilterChange( filter.key, 'value', idList ); onFilterChange( filter.key, 'value', idList );
} }
getLegend( filter, config ) {
const { selected } = this.state;
const rule = find( config.rules, { value: filter.rule } ) || {};
const filterStr = selected.map( item => item.label ).join( ', ' );
return interpolateComponents( {
mixedString: config.labels.title,
components: {
filter: <span>{ filterStr }</span>,
rule: <span>{ rule.label }</span>,
},
} );
}
render() { render() {
const { config, filter, instanceId, onFilterChange } = this.props; const { config, filter, onFilterChange, isEnglish } = this.props;
const { selected } = this.state; const { selected } = this.state;
const { key, rule } = filter; const { key, rule } = filter;
const { input, labels, rules } = config; const { input, labels, rules } = config;
return ( const children = interpolateComponents( {
<Fragment> mixedString: labels.title,
<div components: {
id={ `${ key }-${ instanceId }` } rule: (
className="woocommerce-filters-advanced__fieldset-legend"
>
{ labels.title }
</div>
{ rule && (
<SelectControl <SelectControl
className="woocommerce-filters-advanced__list-specifier" className="woocommerce-filters-advanced__rule"
options={ rules } options={ rules }
value={ rule } value={ rule }
onChange={ partial( onFilterChange, key, 'rule' ) } onChange={ partial( onFilterChange, key, 'rule' ) }
aria-label={ labels.rule } aria-label={ labels.rule }
/> />
) } ),
<div className="woocommerce-filters-advanced__list-selector"> filter: (
<Search <Search
className="woocommerce-filters-advanced__input"
onChange={ this.onSearchChange } onChange={ this.onSearchChange }
type={ input.type } type={ input.type }
placeholder={ labels.placeholder } placeholder={ labels.placeholder }
selected={ selected } selected={ selected }
ariaLabelledby={ `${ key }-${ instanceId }` }
inlineTags inlineTags
aria-label={ labels.filter }
/> />
),
},
} );
/*eslint-disable jsx-a11y/no-noninteractive-tabindex*/
return (
<fieldset tabIndex="0">
<legend className="screen-reader-text">
{ this.getLegend( filter, config, selected ) }
</legend>
<div
className={ classnames( 'woocommerce-filters-advanced__fieldset', {
'is-english': isEnglish,
} ) }
>
{ children }
</div> </div>
</Fragment> </fieldset>
); );
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
} }
} }
@ -105,4 +132,4 @@ SearchFilter.propTypes = {
onFilterChange: PropTypes.func.isRequired, onFilterChange: PropTypes.func.isRequired,
}; };
export default withInstanceId( SearchFilter ); export default SearchFilter;

View File

@ -2,11 +2,12 @@
/** /**
* External dependencies * External dependencies
*/ */
import { Component, Fragment } from '@wordpress/element'; import { Component } from '@wordpress/element';
import { SelectControl, Spinner } from '@wordpress/components'; import { SelectControl, Spinner } from '@wordpress/components';
import { partial } from 'lodash'; import { find, partial } from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withInstanceId } from '@wordpress/compose'; import interpolateComponents from 'interpolate-components';
import classnames from 'classnames';
/** /**
* Internal dependencies * Internal dependencies
@ -40,42 +41,62 @@ class SelectFilter extends Component {
return options; return options;
} }
getLegend( filter, config ) {
const rule = find( config.rules, { value: filter.rule } ) || {};
const value = find( config.input.options, { value: filter.value } ) || {};
return interpolateComponents( {
mixedString: config.labels.title,
components: {
filter: <span>{ value.label }</span>,
rule: <span>{ rule.label }</span>,
},
} );
}
render() { render() {
const { config, filter, instanceId, onFilterChange } = this.props; const { config, filter, onFilterChange, isEnglish } = this.props;
const { options } = this.state; const { options } = this.state;
const { key, rule, value } = filter; const { key, rule, value } = filter;
const { labels, rules } = config; const { labels, rules } = config;
return ( const children = interpolateComponents( {
<Fragment> mixedString: labels.title,
<div components: {
id={ `${ key }-${ instanceId }` } rule: (
className="woocommerce-filters-advanced__fieldset-legend"
>
{ labels.title }
</div>
{ rule && (
<SelectControl <SelectControl
className="woocommerce-filters-advanced__list-specifier" className="woocommerce-filters-advanced__rule"
options={ rules } options={ rules }
value={ rule } value={ rule }
onChange={ partial( onFilterChange, key, 'rule' ) } onChange={ partial( onFilterChange, key, 'rule' ) }
aria-label={ labels.rule } aria-label={ labels.rule }
/> />
) } ),
<div className="woocommerce-filters-advanced__list-selector"> filter: options ? (
{ ! options && <Spinner /> } <SelectControl
{ options && ( className="woocommerce-filters-advanced__input"
<SelectControl options={ options }
className="woocommerce-filters-advanced__list-select" value={ value }
options={ options } onChange={ partial( onFilterChange, filter.key, 'value' ) }
value={ value } aria-label={ labels.filter }
onChange={ partial( onFilterChange, filter.key, 'value' ) } />
aria-labelledby={ `${ key }-${ instanceId }` } ) : (
/> <Spinner />
) } ),
},
} );
/*eslint-disable jsx-a11y/no-noninteractive-tabindex*/
return (
<fieldset tabIndex="0">
<legend className="screen-reader-text">{ this.getLegend( filter, config ) }</legend>
<div
className={ classnames( 'woocommerce-filters-advanced__fieldset', {
'is-english': isEnglish,
} ) }
>
{ children }
</div> </div>
</Fragment> </fieldset>
); );
/*eslint-enable jsx-a11y/no-noninteractive-tabindex*/
} }
} }
@ -87,6 +108,7 @@ SelectFilter.propTypes = {
labels: PropTypes.shape( { labels: PropTypes.shape( {
rule: PropTypes.string, rule: PropTypes.string,
title: PropTypes.string, title: PropTypes.string,
filter: PropTypes.string,
} ), } ),
rules: PropTypes.arrayOf( PropTypes.object ), rules: PropTypes.arrayOf( PropTypes.object ),
input: PropTypes.object, input: PropTypes.object,
@ -105,4 +127,4 @@ SelectFilter.propTypes = {
onFilterChange: PropTypes.func.isRequired, onFilterChange: PropTypes.func.isRequired,
}; };
export default withInstanceId( SelectFilter ); export default SelectFilter;

View File

@ -41,17 +41,13 @@
border-bottom: 1px solid $core-grey-light-700; border-bottom: 1px solid $core-grey-light-700;
fieldset { fieldset {
padding: $gap-smaller $gap; padding: $gap-smaller $gap-smaller $gap-smaller $gap;
} }
&:hover { &:hover {
background-color: $core-grey-light-200; background-color: $core-grey-light-200;
} }
.components-base-control {
margin: 0;
}
.woocommerce-filters-advanced__remove { .woocommerce-filters-advanced__remove {
width: 40px; width: 40px;
height: 38px; height: 38px;
@ -85,22 +81,41 @@
} }
.woocommerce-filters-advanced__fieldset { .woocommerce-filters-advanced__fieldset {
display: grid; & > div {
grid-template-columns: 100px 150px auto; padding: 0 $gap-smallest;
@include breakpoint( '<782px' ) {
display: block;
margin: 0;
width: 100%;
padding: $gap-smallest 0;
}
}
display: flex;
align-items: center;
white-space: nowrap;
@include breakpoint( '<782px' ) { @include breakpoint( '<782px' ) {
display: flex; display: block;
flex-direction: column; }
&.is-english {
display: grid;
grid-template-columns: 100px 150px auto;
@include breakpoint( '<782px' ) {
display: block;
}
} }
} }
.woocommerce-filters-advanced__fieldset-legend { .woocommerce-filters-advanced__rule {
align-self: center; width: 150px;
}
@include breakpoint( '<782px' ) { .woocommerce-filters-advanced__input {
align-self: initial; width: 100%;
padding: $gap-smallest 0;
}
} }
.woocommerce-filters-advanced__add-filter-dropdown { .woocommerce-filters-advanced__add-filter-dropdown {
@ -156,35 +171,3 @@
} }
} }
} }
.woocommerce-filters-advanced__list-selector {
@include breakpoint( '<782px' ) {
padding: $gap-smallest 0;
}
.components-spinner {
margin: auto;
display: block;
float: none;
top: 50%;
transform: translateY(-50%);
@include breakpoint( '<782px' ) {
transform: none;
}
}
}
.woocommerce-filters-advanced__list-specifier {
@include breakpoint( '<782px' ) {
padding: $gap-smallest 0;
}
& + .woocommerce-filters-advanced__list-selector {
padding: 0 0 0 $gap-smaller;
@include breakpoint( '<782px' ) {
padding: $gap-smallest 0;
}
}
}

View File

@ -45,12 +45,7 @@ class ReportFilters extends Component {
if ( 'advanced' === query.filter ) { if ( 'advanced' === query.filter ) {
return ( return (
<div className="woocommerce-filters__advanced-filters"> <div className="woocommerce-filters__advanced-filters">
<AdvancedFilters <AdvancedFilters config={ advancedConfig } path={ path } query={ query } />
config={ advancedConfig }
filterTitle={ __( 'Orders', 'wc-admin' ) }
path={ path }
query={ query }
/>
</div> </div>
); );
} }

View File

@ -17,6 +17,10 @@
} }
} }
} }
.components-base-control__field {
margin-bottom: 0;
}
} }
.woocommerce-filters-date, .woocommerce-filters-date,

View File

@ -113,14 +113,14 @@ class Search extends Component {
render() { render() {
const autocompleter = this.getAutocompleter(); const autocompleter = this.getAutocompleter();
const { placeholder, inlineTags, selected, instanceId } = this.props; const { placeholder, inlineTags, selected, instanceId, className } = this.props;
const { value = '', isActive } = this.state; const { value = '', isActive } = this.state;
const aria = { const aria = {
'aria-labelledby': this.props[ 'aria-labelledby' ], 'aria-labelledby': this.props[ 'aria-labelledby' ],
'aria-label': this.props[ 'aria-label' ], 'aria-label': this.props[ 'aria-label' ],
}; };
return ( return (
<div className="woocommerce-search"> <div className={ classnames( 'woocommerce-search', className ) }>
<Gridicon className="woocommerce-search__icon" icon="search" size={ 18 } /> <Gridicon className="woocommerce-search__icon" icon="search" size={ 18 } />
<Autocomplete completer={ autocompleter } onSelect={ this.selectResult }> <Autocomplete completer={ autocompleter } onSelect={ this.selectResult }>
{ ( { listBoxId, activeId, onChange } ) => { ( { listBoxId, activeId, onChange } ) =>
@ -186,6 +186,10 @@ class Search extends Component {
} }
Search.propTypes = { Search.propTypes = {
/**
* Class name applied to parent div.
*/
className: PropTypes.string,
/** /**
* Function called when selected results change, passed result list. * Function called when selected results change, passed result list.
*/ */

View File

@ -78,8 +78,8 @@
"history": "^4.7.2", "history": "^4.7.2",
"html-to-react": "^1.3.3", "html-to-react": "^1.3.3",
"husky": "^0.14.3", "husky": "^0.14.3",
"interpolate-components": "1.1.1",
"marked": "^0.5.0", "marked": "^0.5.0",
"interpolate-components": "^1.1.1",
"node-sass": "^4.9.3", "node-sass": "^4.9.3",
"postcss-color-function": "^4.0.1", "postcss-color-function": "^4.0.1",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",