[Experimental] Add block text color support to interactivity filter blocks (#43068)

* [Experimental] Render headings as inner blocks of collection filters (#43109)
This commit is contained in:
Sam Seay 2023-12-28 22:06:35 +08:00 committed by GitHub
parent b36023e8aa
commit eabb27c72b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 289 additions and 127 deletions

View File

@ -2,62 +2,25 @@
* External dependencies
*/
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
import { sprintf, __ } from '@wordpress/i18n';
import { getSetting } from '@woocommerce/settings';
import type { AttributeSetting } from '@woocommerce/types';
const ATTRIBUTES = getSetting< AttributeSetting[] >( 'attributes', [] );
const firstAttribute = ATTRIBUTES.find( Boolean );
const template = [
[ 'woocommerce/collection-active-filters', {} ],
[
'core/heading',
{
content: __( 'Filter by Price', 'woocommerce' ),
level: 3,
},
],
[ 'woocommerce/collection-price-filter', {} ],
[
'core/heading',
{
content: __( 'Filter by Stock status', 'woocommerce' ),
level: 3,
},
],
[ 'woocommerce/collection-stock-filter', {} ],
[
'core/heading',
{
content: __( 'Filter by Rating', 'woocommerce' ),
level: 3,
},
],
[ 'woocommerce/collection-rating-filter', {} ],
];
const firstAttribute = ATTRIBUTES.find( Boolean );
if ( firstAttribute ) {
template.push(
[
'core/heading',
{
content: sprintf(
// translators: %s is the attribute label.
__( 'Filter by %s', 'woocommerce' ),
firstAttribute.attribute_label
),
level: 3,
},
],
[
'woocommerce/collection-attribute-filter',
{
attributeId: parseInt( firstAttribute?.attribute_id, 10 ),
},
]
);
template.push( [
'woocommerce/collection-attribute-filter',
{ attributeId: parseInt( firstAttribute?.attribute_id, 10 ) },
] );
}
const Edit = () => {

View File

@ -5,20 +5,18 @@
"title": "Collection Active Filters",
"description": "Display the currently active filters.",
"category": "woocommerce",
"keywords": [
"WooCommerce"
],
"keywords": [ "WooCommerce" ],
"textdomain": "woocommerce",
"apiVersion": 2,
"ancestor": [
"woocommerce/collection-filters"
],
"ancestor": [ "woocommerce/collection-filters" ],
"supports": {
"interactivity": true
"interactivity": true,
"color": {
"text": true,
"background": false
}
},
"usesContext": [
"queryId"
],
"usesContext": [ "queryId" ],
"attributes": {
"displayStyle": {
"type": "string",

View File

@ -1,10 +1,11 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
import { __ } from '@wordpress/i18n';
import classNames from 'classnames';
import { Disabled } from '@wordpress/components';
import { Template } from '@wordpress/blocks';
/**
* Internal dependencies
@ -20,9 +21,20 @@ const Edit = ( props: EditProps ) => {
className: 'wc-block-active-filters',
} );
const template: Template[] = [
[
'core/heading',
{ content: __( 'Active Filters', 'woocommerce' ), level: 3 },
],
];
return (
<div { ...blockProps }>
<Inspector { ...props } />
<InnerBlocks
template={ template }
allowedBlocks={ [ 'core/heading' ] }
/>
<Disabled>
<ul
className={ classNames( 'wc-block-active-filters__list', {

View File

@ -5,6 +5,7 @@ import { registerBlockType } from '@wordpress/blocks';
import { Icon } from '@wordpress/icons';
import { toggle } from '@woocommerce/icons';
import { isExperimentalBuild } from '@woocommerce/block-settings';
import { InnerBlocks } from '@wordpress/block-editor';
/**
* Internal dependencies
@ -24,5 +25,6 @@ if ( isExperimentalBuild() ) {
),
},
edit: Edit,
save: InnerBlocks.Content,
} );
}

View File

@ -5,20 +5,18 @@
"title": "Collection Attribute Filter",
"description": "Enable customers to filter the product grid by selecting one or more attributes, such as color.",
"category": "woocommerce",
"keywords": [
"WooCommerce"
],
"keywords": [ "WooCommerce" ],
"textdomain": "woocommerce",
"apiVersion": 2,
"ancestor": [
"woocommerce/collection-filters"
],
"ancestor": [ "woocommerce/collection-filters" ],
"supports": {
"interactivity": true
"interactivity": true,
"color": {
"text": true,
"background": false
}
},
"usesContext": [
"collectionData"
],
"usesContext": [ "collectionData" ],
"attributes": {
"queryParam": {
"type": "object",

View File

@ -1,25 +1,38 @@
/**
* External dependencies
*/
import styled from '@emotion/styled';
import FormTokenField from '@woocommerce/base-components/form-token-field';
import { __, sprintf } from '@wordpress/i18n';
import { Icon, chevronDown } from '@wordpress/icons';
type Props = {
label: string;
textColor: string;
};
export const AttributeDropdown = ( { label, textColor }: Props ) => {
const StyledFormTokenField = textColor
? styled( FormTokenField )`
.components-form-token-field__input::placeholder {
color: ${ textColor } !important;
}
`
: FormTokenField;
return (
<div className="wc-block-attribute-filter style-dropdown">
<StyledFormTokenField
suggestions={ [] }
placeholder={ sprintf(
/* translators: %s attribute name. */
__( 'Select %s', 'woocommerce' ),
label
) }
onChange={ () => null }
value={ [] }
/>
<Icon icon={ chevronDown } size={ 30 } />
</div>
);
};
export const AttributeDropdown = ( { label }: Props ) => (
<div className="wc-block-attribute-filter style-dropdown">
<FormTokenField
suggestions={ [] }
placeholder={ sprintf(
/* translators: %s attribute name. */
__( 'Select %s', 'woocommerce' ),
label
) }
onChange={ () => null }
value={ [] }
/>
<Icon icon={ chevronDown } size={ 30 } />
</div>
);

View File

@ -1,9 +1,13 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { __, sprintf } from '@wordpress/i18n';
import { useEffect, useState } from '@wordpress/element';
import { BlockControls, useBlockProps } from '@wordpress/block-editor';
import {
BlockControls,
InnerBlocks,
useBlockProps,
} from '@wordpress/block-editor';
import { getSetting } from '@woocommerce/settings';
import {
useCollection,
@ -21,6 +25,7 @@ import {
withSpokenMessages,
Notice,
} from '@wordpress/components';
import { Template } from '@wordpress/blocks';
/**
* Internal dependencies
@ -36,6 +41,8 @@ import { Inspector } from './components/inspector-controls';
import { AttributeCheckboxList } from './components/attribute-checkbox-list';
import { AttributeDropdown } from './components/attribute-dropdown';
import './style.scss';
import { extractBuiltInColor } from '../../utils';
import { useStyleProps } from '../../../../base/hooks';
const ATTRIBUTES = getSetting< AttributeSetting[] >( 'attributes', [] );
@ -55,6 +62,13 @@ const Edit = ( props: EditProps ) => {
showCounts,
} = blockAttributes;
const { className, style } = useStyleProps( props.attributes );
const builtInColor = extractBuiltInColor( className );
const textColor = builtInColor
? `var(--wp--preset--color--${ builtInColor })`
: style.color;
const attributeObject = getAttributeFromId( attributeId );
const [ isEditing, setIsEditing ] = useState(
@ -83,6 +97,22 @@ const Edit = ( props: EditProps ) => {
const blockProps = useBlockProps();
const template: Template[] = [
[
'core/heading',
{
content: attributeObject
? sprintf(
// translators: %s is the attribute label.
__( 'Filter by %s', 'woocommerce' ),
attributeObject.label
)
: __( 'Filter Products by Attribute', 'woocommerce' ),
level: 3,
},
],
];
useEffect( () => {
if ( ! attributeObject?.taxonomy ) {
return;
@ -226,6 +256,10 @@ const Edit = ( props: EditProps ) => {
return (
<Wrapper>
<Inspector { ...props } />
<InnerBlocks
template={ template }
allowedBlocks={ [ 'core/heading' ] }
/>
<Disabled>
{ displayStyle === 'dropdown' ? (
<AttributeDropdown
@ -233,6 +267,7 @@ const Edit = ( props: EditProps ) => {
attributeObject.label ||
__( 'attribute', 'woocommerce' )
}
textColor={ textColor || '' }
/>
) : (
<AttributeCheckboxList

View File

@ -3,6 +3,7 @@
*/
import { registerBlockType } from '@wordpress/blocks';
import { isExperimentalBuild } from '@woocommerce/block-settings';
import { InnerBlocks } from '@wordpress/block-editor';
/**
* Internal dependencies
@ -14,5 +15,6 @@ import Edit from './edit';
if ( isExperimentalBuild() ) {
registerBlockType( metadata, {
edit: Edit,
save: InnerBlocks.Content,
} );
}

View File

@ -1,8 +1,10 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import classNames from 'classnames';
import { __ } from '@wordpress/i18n';
import { Template } from '@wordpress/blocks';
/**
* Internal dependencies
@ -20,9 +22,20 @@ const Edit = ( props: EditProps ) => {
} ),
} );
const template: Template[] = [
[
'core/heading',
{ content: __( 'Filter by Price', 'woocommerce' ), level: 3 },
],
];
return (
<div { ...blockProps }>
<Inspector { ...props } />
<InnerBlocks
template={ template }
allowedBlocks={ [ 'core/heading' ] }
/>
<PriceSlider { ...props } />
</div>
);

View File

@ -4,6 +4,7 @@
import { registerBlockType } from '@wordpress/blocks';
import { Icon, currencyDollar } from '@wordpress/icons';
import { isExperimentalBuild } from '@woocommerce/block-settings';
import { InnerBlocks } from '@wordpress/block-editor';
/**
* Internal dependencies
@ -23,5 +24,6 @@ if ( isExperimentalBuild() ) {
),
},
edit: Edit,
save: InnerBlocks.Content,
} );
}

View File

@ -6,7 +6,11 @@
"category": "woocommerce",
"keywords": [ "WooCommerce" ],
"supports": {
"interactivity": true
"interactivity": true,
"color": {
"background": false,
"text": true
}
},
"ancestor": [ "woocommerce/collection-filters" ],
"usesContext": [ "collectionData" ],

View File

@ -4,8 +4,8 @@
import { __ } from '@wordpress/i18n';
import { Icon, chevronDown } from '@wordpress/icons';
import classnames from 'classnames';
import { useBlockProps } from '@wordpress/block-editor';
import type { BlockEditProps } from '@wordpress/blocks';
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import type { BlockEditProps, Template } from '@wordpress/blocks';
import Rating, {
RatingValues,
} from '@woocommerce/base-components/product-rating';
@ -20,6 +20,8 @@ import { useState, useMemo, useEffect } from '@wordpress/element';
import { CheckboxList } from '@woocommerce/blocks-components';
import FormTokenField from '@woocommerce/base-components/form-token-field';
import { Disabled, Notice, withSpokenMessages } from '@wordpress/components';
import { useStyleProps } from '@woocommerce/base-hooks';
import styled from '@emotion/styled';
/**
* Internal dependencies
@ -31,6 +33,7 @@ import { formatSlug, getActiveFilters, generateUniqueId } from './utils';
import { useSetWraperVisibility } from '../../../filter-wrapper/context';
import './editor.scss';
import { Inspector } from '../attribute-filter/components/inspector-controls';
import { extractBuiltInColor } from '../../utils';
const NoRatings = () => (
<Notice status="warning" isDismissible={ false }>
@ -47,10 +50,32 @@ const Edit = ( props: BlockEditProps< Attributes > ) => {
const { className } = props.attributes;
const blockAttributes = props.attributes;
const { className: styleClass, style } = useStyleProps( props.attributes );
const builtInColor = extractBuiltInColor( styleClass );
const textColor = builtInColor
? `var(--wp--preset--color--${ builtInColor })`
: style.color;
const StyledFormTokenField = textColor
? styled( FormTokenField )`
.components-form-token-field__input::placeholder {
color: ${ textColor } !important;
}
`
: FormTokenField;
const blockProps = useBlockProps( {
className: classnames( 'wc-block-rating-filter', className ),
} );
const template: Template[] = [
[
'core/heading',
{ content: __( 'Filter by Rating', 'woocommerce' ), level: 3 },
],
];
const isEditor = true;
const setWrapperVisibility = useSetWraperVisibility();
@ -179,6 +204,10 @@ const Edit = ( props: BlockEditProps< Attributes > ) => {
<>
<Inspector { ...props } />
<div { ...blockProps }>
<InnerBlocks
template={ template }
allowedBlocks={ [ 'core/heading' ] }
/>
<Disabled>
{ displayNoProductRatingsNotice && <NoRatings /> }
<div
@ -192,7 +221,7 @@ const Edit = ( props: BlockEditProps< Attributes > ) => {
>
{ blockAttributes.displayStyle === 'dropdown' ? (
<>
<FormTokenField
<StyledFormTokenField
key={ remountKey }
className={ classnames( {
'single-selection': ! multiple,

View File

@ -3,15 +3,13 @@
*/
import { registerBlockType } from '@wordpress/blocks';
import { Icon, starEmpty } from '@wordpress/icons';
import classNames from 'classnames';
import { useBlockProps } from '@wordpress/block-editor';
import { InnerBlocks } from '@wordpress/block-editor';
/**
* Internal dependencies
*/
import edit from './edit';
import metadata from './block.json';
import type { Attributes } from './types';
registerBlockType( metadata, {
icon: {
@ -26,16 +24,5 @@ registerBlockType( metadata, {
...metadata.attributes,
},
edit,
// Save the props to post content.
save( { attributes }: { attributes: Attributes } ) {
const { className } = attributes;
return (
<div
{ ...useBlockProps.save( {
className: classNames( 'is-loading', className ),
} ) }
/>
);
},
save: InnerBlocks.Content,
} );

View File

@ -1,14 +1,18 @@
{
"name": "woocommerce/collection-stock-filter",
"version": "1.0.0",
"title": "Stock Filter",
"title": "Collection Stock Filter",
"description": "Enable customers to filter the product collection by stock status.",
"category": "woocommerce",
"keywords": [ "WooCommerce", "filter", "stock" ],
"supports": {
"interactivity": true,
"html": false,
"multiple": false
"multiple": false,
"color": {
"text": true,
"background": false
}
},
"attributes": {
"className": {

View File

@ -3,22 +3,25 @@
*/
import { useMemo } from '@wordpress/element';
import classnames from 'classnames';
import { useBlockProps } from '@wordpress/block-editor';
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
import { Disabled } from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { Icon, chevronDown } from '@wordpress/icons';
import { CheckboxList } from '@woocommerce/blocks-components';
import Label from '@woocommerce/base-components/filter-element-label';
import FormTokenField from '@woocommerce/base-components/form-token-field';
import type { BlockEditProps } from '@wordpress/blocks';
import type { BlockEditProps, Template } from '@wordpress/blocks';
import { getSetting } from '@woocommerce/settings';
import { useCollectionData } from '@woocommerce/base-context/hooks';
import { useStyleProps } from '@woocommerce/base-hooks';
import styled from '@emotion/styled';
/**
* Internal dependencies
*/
import { BlockProps } from './types';
import { Inspector } from './components/inspector';
import { extractBuiltInColor } from '../../utils';
type CollectionData = {
// attribute_counts: null | unknown;
@ -40,6 +43,31 @@ const Edit = ( props: BlockEditProps< BlockProps > ) => {
),
} );
const template: Template[] = [
[
'core/heading',
{
content: __( 'Filter by Stock Status', 'woocommerce' ),
level: 3,
},
],
];
const { className, style } = useStyleProps( props.attributes );
const builtInColor = extractBuiltInColor( className );
const textColor = builtInColor
? `var(--wp--preset--color--${ builtInColor })`
: style.color;
const StyledFormTokenField = textColor
? styled( FormTokenField )`
.components-form-token-field__input::placeholder {
color: ${ textColor } !important;
}
`
: FormTokenField;
const { showCounts, displayStyle } = props.attributes;
const stockStatusOptions: Record< string, string > = getSetting(
'stockStatusOptions',
@ -77,6 +105,10 @@ const Edit = ( props: BlockEditProps< BlockProps > ) => {
{
<div { ...blockProps }>
<Inspector { ...props } />
<InnerBlocks
template={ template }
allowedBlocks={ [ 'core/heading' ] }
/>
<Disabled>
<div
className={ classnames(
@ -89,7 +121,7 @@ const Edit = ( props: BlockEditProps< BlockProps > ) => {
>
{ displayStyle === 'dropdown' ? (
<>
<FormTokenField
<StyledFormTokenField
className={ classnames( {
'single-selection': true,
'is-loading': false,

View File

@ -4,6 +4,7 @@
import { registerBlockType } from '@wordpress/blocks';
import { Icon, box } from '@wordpress/icons';
import { isExperimentalBuild } from '@woocommerce/block-settings';
import { InnerBlocks } from '@wordpress/block-editor';
/**
* Internal dependencies
@ -23,5 +24,6 @@ if ( isExperimentalBuild() ) {
),
},
edit,
save: InnerBlocks.Content,
} );
}

View File

@ -0,0 +1,12 @@
/**
* Extracts the built-in color from a block class name string if it exists.
* Returns null if no built-in color is found.
*
* @param blockClassString The block class name string.
* @return {string|null} The color name or null if no built-in color is found.
*/
export const extractBuiltInColor = ( blockClassString: string ) => {
const regex = /has-(?!link|text|background)([a-z-]+)-color/;
const match = blockClassString.match( regex );
return match ? match[ 1 ] : null;
};

View File

@ -0,0 +1,4 @@
Significance: patch
Type: add
Comment: Add support for text color to experimental filter blocks

View File

@ -49,7 +49,7 @@ final class CollectionActiveFilters extends AbstractBlock {
$active_filters = apply_filters( 'collection_active_filters_data', array(), $this->get_filter_query_params( $query_id ) );
if ( empty( $active_filters ) ) {
return $content;
return '';
}
$context = array(
@ -68,8 +68,8 @@ final class CollectionActiveFilters extends AbstractBlock {
ob_start();
?>
<?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div <?php echo $wrapper_attributes; ?>>
<div <?php echo $wrapper_attributes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
<?php echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<ul class="wc-block-active-filters__list %3$s">
<?php foreach ( $active_filters as $filter ) : ?>
<li>

View File

@ -2,6 +2,7 @@
namespace Automattic\WooCommerce\Blocks\BlockTypes;
use Automattic\WooCommerce\Blocks\InteractivityComponents\Dropdown;
use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils;
/**
* CollectionAttributeFilter class.
@ -132,7 +133,7 @@ final class CollectionAttributeFilter extends AbstractBlock {
empty( $block->context['collectionData']['attribute_counts'] ) ||
empty( $attributes['attributeId'] )
) {
return $content;
return '';
}
$product_attribute = wc_get_attribute( $attributes['attributeId'] );
@ -179,13 +180,14 @@ final class CollectionAttributeFilter extends AbstractBlock {
);
return sprintf(
'<div %1$s>%2$s</div>',
'<div %1$s>%2$s%3$s</div>',
get_block_wrapper_attributes(
array(
'data-wc-context' => wp_json_encode( $context ),
'data-wc-interactive' => wp_json_encode( array( 'namespace' => 'woocommerce/collection-attribute-filter' ) ),
)
),
$content,
$filter_content
);
}
@ -197,6 +199,9 @@ final class CollectionAttributeFilter extends AbstractBlock {
* @param bool $attributes Block attributes.
*/
private function render_attribute_dropdown( $options, $attributes ) {
$text_color_class_and_style = StyleAttributesUtils::get_text_color_class_and_style( $attributes );
$text_color = $text_color_class_and_style['value'] ?? '';
$list_items = array();
$selected_item = array();
@ -218,6 +223,7 @@ final class CollectionAttributeFilter extends AbstractBlock {
'items' => $list_items,
'action' => 'woocommerce/collection-attribute-filter::actions.navigate',
'selected_item' => $selected_item,
'text_color' => $text_color,
)
);
}

View File

@ -116,7 +116,7 @@ final class CollectionPriceFilter extends AbstractBlock {
empty( $block->context['collectionData'] ) ||
empty( $block->context['collectionData']['price_range'] )
) {
return $content;
return '';
}
$price_range = $block->context['collectionData']['price_range'];
@ -147,7 +147,7 @@ final class CollectionPriceFilter extends AbstractBlock {
// Max range shouldn't be 0.
if ( ! $max_range ) {
return $content;
return '';
}
// CSS variables for the range bar style.
@ -197,6 +197,7 @@ final class CollectionPriceFilter extends AbstractBlock {
ob_start();
?>
<div <?php echo $wrapper_attributes; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
<?php echo $content; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<div data-wc-context="<?php echo esc_attr( wp_json_encode( $data ) ); ?>" >
<div
class="range"

View File

@ -3,6 +3,7 @@ namespace Automattic\WooCommerce\Blocks\BlockTypes;
use Automattic\WooCommerce\Blocks\InteractivityComponents\CheckboxList;
use Automattic\WooCommerce\Blocks\InteractivityComponents\Dropdown;
use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils;
/**
* Collection Rating Filter Block
@ -110,10 +111,17 @@ final class CollectionRatingFilter extends AbstractBlock {
return '';
}
$text_color_class_and_style = StyleAttributesUtils::get_text_color_class_and_style( $attributes );
$text_color = $text_color_class_and_style['value'] ?? '';
$rating_counts = $block->context['collectionData']['rating_counts'] ?? array();
$display_style = $attributes['displayStyle'] ?? 'list';
$show_counts = $attributes['showCounts'] ?? false;
if ( empty( $rating_counts ) ) {
return '';
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here.
$selected_ratings_query_param = isset( $_GET[ self::RATING_FILTER_QUERY_VAR ] ) ? sanitize_text_field( wp_unslash( $_GET[ self::RATING_FILTER_QUERY_VAR ] ) ) : '';
@ -130,15 +138,17 @@ final class CollectionRatingFilter extends AbstractBlock {
'on_change' => 'woocommerce/collection-rating-filter::actions.onCheckboxChange',
)
) : Dropdown::render(
$this->get_dropdown_props( $rating_counts, $selected_ratings_query_param, $show_counts, $attributes['selectType'] )
$this->get_dropdown_props( $rating_counts, $selected_ratings_query_param, $show_counts, $attributes['selectType'], $text_color )
);
return sprintf(
'<div %1$s>
<div class="wc-block-rating-filter__controls">%2$s</div>
%2$s
<div class="wc-block-rating-filter__controls">%3$s</div>
<div class="wc-block-rating-filter__actions"></div>
</div>',
$wrapper_attributes,
$content,
$input
);
}
@ -209,9 +219,10 @@ final class CollectionRatingFilter extends AbstractBlock {
* @param mixed $selected_ratings_query The url query param for selected ratings.
* @param bool $show_counts Whether to show the counts.
* @param string $select_type The select type. (single|multiple).
* @param string $text_color The text color.
* @return array<array-key, array>
*/
private function get_dropdown_props( $rating_counts, $selected_ratings_query, $show_counts, $select_type ) {
private function get_dropdown_props( $rating_counts, $selected_ratings_query, $show_counts, $select_type, $text_color ) {
$ratings_array = explode( ',', $selected_ratings_query );
$selected_items = array_reduce(
@ -249,6 +260,7 @@ final class CollectionRatingFilter extends AbstractBlock {
'select_type' => $select_type,
'selected_items' => $selected_items,
'action' => 'woocommerce/collection-rating-filter::actions.onDropdownChange',
'text_color' => $text_color,
);
}
}

View File

@ -2,6 +2,7 @@
namespace Automattic\WooCommerce\Blocks\BlockTypes;
use Automattic\WooCommerce\Blocks\InteractivityComponents\Dropdown;
use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils;
/**
* CollectionStockFilter class.
@ -127,10 +128,12 @@ final class CollectionStockFilter extends AbstractBlock {
return sprintf(
'<div %1$s>
<div class="wc-block-stock-filter__controls">%2$s</div>
%2$s
<div class="wc-block-stock-filter__controls">%3$s</div>
<div class="wc-block-stock-filter__actions"></div>
</div>',
$wrapper_attributes,
$content,
$this->get_stock_filter_html( $stock_status_counts, $attributes ),
);
}
@ -147,6 +150,9 @@ final class CollectionStockFilter extends AbstractBlock {
$show_counts = $attributes['showCounts'] ?? false;
$stock_statuses = wc_get_product_stock_status_options();
$text_color_class_and_style = StyleAttributesUtils::get_text_color_class_and_style( $attributes );
$text_color = $text_color_class_and_style['value'] ?? '';
// check the url params to select initial item on page load.
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Nonce verification is not required here.
$selected_stock_status = isset( $_GET[ self::STOCK_STATUS_QUERY_VAR ] ) ? sanitize_text_field( wp_unslash( $_GET[ self::STOCK_STATUS_QUERY_VAR ] ) ) : '';
@ -236,6 +242,7 @@ final class CollectionStockFilter extends AbstractBlock {
'items' => $list_items,
'action' => 'woocommerce/collection-stock-filter::actions.navigate',
'selected_item' => $selected_item,
'text_color' => $text_color,
)
);
?>

View File

@ -18,9 +18,10 @@ class Dropdown {
wp_enqueue_script( 'wc-interactivity-dropdown' );
wp_enqueue_style( 'wc-interactivity-dropdown' );
$select_type = $props['select_type'] ?? 'single';
$selected_items = $props['selected_items'] ?? array();
$select_type = $props['select_type'] ?? 'single';
$selected_items = $props['selected_items'] ?? array();
$text_color = $props['text_color'] ?? 'inherit';
$text_color_style = "color: {$text_color};";
// Items should be an array of objects with a label and value property.
$items = $props['items'] ?? array();
@ -31,11 +32,17 @@ class Dropdown {
'selectType' => $select_type,
);
$action = $props['action'] ?? '';
$namespace = wp_json_encode( array( 'namespace' => 'woocommerce/interactivity-dropdown' ) );
$action = $props['action'] ?? '';
$namespace = wp_json_encode( array( 'namespace' => 'woocommerce/interactivity-dropdown' ) );
$wrapper_class = 'multiple' === $select_type ? '' : 'single-selection';
$input_id = wp_unique_id( 'wc-interactivity-dropdown-input-' );
wp_add_inline_style(
'wc-interactivity-dropdown',
"#$input_id::placeholder {
$text_color_style
}"
);
ob_start();
?>
@ -57,6 +64,7 @@ class Dropdown {
<span
class="components-form-token-field__token-text"
data-wc-text="context.item.label"
style="<?php echo esc_attr( $text_color_style ); ?>"
></span>
<button
type="button"
@ -76,7 +84,10 @@ class Dropdown {
data-wc-key="<?php echo esc_attr( $selected['label'] ); ?>"
data-wc-each-child
>
<span class="components-form-token-field__token-text">
<span
class="components-form-token-field__token-text"
style="<?php echo esc_attr( $text_color_style ); ?>"
>
<?php echo esc_html( $selected['label'] ); ?>
</span>
<button
@ -89,8 +100,20 @@ class Dropdown {
</button>
</span>
<?php } ?>
<?php } ?>
<input id="components-form-token-input-1" type="text" autocomplete="off" data-wc-bind--placeholder="state.placeholderText" class="components-form-token-field__input" role="combobox" aria-expanded="false" aria-autocomplete="list" aria-describedby="components-form-token-suggestions-howto-1" value="" data-wc-key="input">
<?php } ?>
<input
id="<?php echo esc_attr( $input_id ); ?>"
readonly
type="text"
autocomplete="off"
data-wc-bind--placeholder="state.placeholderText"
class="components-form-token-field__input"
role="combobox"
aria-expanded="false"
aria-autocomplete="list"
value=""
data-wc-key="input"
>
<ul hidden data-wc-bind--hidden="!context.isOpen" class="components-form-token-field__suggestions-list" id="components-form-token-suggestions-1" role="listbox" data-wc-key="ul">
<?php
foreach ( $items as $item ) :
@ -104,6 +127,7 @@ class Dropdown {
class="components-form-token-field__suggestion"
data-wc-bind--aria-selected="state.isSelected"
data-wc-context='<?php echo wp_json_encode( $context ); ?>'
style="<?php echo esc_attr( $text_color_style ); ?>"
>
<?php // This attribute supports HTML so should be sanitized by caller. ?>
<?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>