Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Add global style for Product Categories List block (#5133)
Browse files Browse the repository at this point in the history
* Add global style for product categories list block #4965

Add global style for product categories list block

* add support for link color

* add feature flag

* fix code style and PHP warning

* update doc comment

* remove empty space

* refactor StyleAttributesUtils (#5277)

Co-authored-by: Tung Du <[email protected]>
  • Loading branch information
gigitux and dinhtungdu authored Nov 30, 2021
1 parent 103442a commit d1306f2
Show file tree
Hide file tree
Showing 4 changed files with 251 additions and 7 deletions.
10 changes: 7 additions & 3 deletions assets/js/blocks/product-categories/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* External dependencies
*/
import { __ } from '@wordpress/i18n';
import { InspectorControls } from '@wordpress/block-editor';
import { InspectorControls, useBlockProps } from '@wordpress/block-editor';
import ServerSideRender from '@wordpress/server-side-render';
import PropTypes from 'prop-types';
import {
Expand Down Expand Up @@ -183,8 +183,12 @@ const ProductCategoriesBlock = ( { attributes, setAttributes, name } ) => {
);
};

const blockProps = useBlockProps( {
className: 'wc-block-product-categories',
} );

return (
<>
<div { ...blockProps }>
{ getInspectorControls() }
<Disabled>
<ServerSideRender
Expand All @@ -193,7 +197,7 @@ const ProductCategoriesBlock = ( { attributes, setAttributes, name } ) => {
EmptyResponsePlaceholder={ EmptyPlaceholder }
/>
</Disabled>
</>
</div>
);
};

Expand Down
12 changes: 12 additions & 0 deletions assets/js/blocks/product-categories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { __ } from '@wordpress/i18n';
import { createBlock, registerBlockType } from '@wordpress/blocks';
import { Icon, list } from '@woocommerce/icons';

import { isFeaturePluginBuild } from '@woocommerce/block-settings';
/**
* Internal dependencies
*/
Expand All @@ -13,6 +14,7 @@ import './style.scss';
import Block from './block.js';

registerBlockType( 'woocommerce/product-categories', {
apiVersion: 2,
title: __( 'Product Categories List', 'woo-gutenberg-products-block' ),
icon: {
src: <Icon srcElement={ list } />,
Expand All @@ -27,6 +29,16 @@ registerBlockType( 'woocommerce/product-categories', {
supports: {
align: [ 'wide', 'full' ],
html: false,
...( isFeaturePluginBuild() && {
color: {
background: false,
link: true,
},
typography: {
fontSize: true,
lineHeight: true,
},
} ),
},
example: {
attributes: {
Expand Down
26 changes: 22 additions & 4 deletions src/BlockTypes/ProductCategories.php
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<?php
namespace Automattic\WooCommerce\Blocks\BlockTypes;

use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils;

/**
* ProductCategories class.
*/
class ProductCategories extends AbstractDynamicBlock {


/**
* Block name.
*
Expand Down Expand Up @@ -42,6 +45,10 @@ protected function get_block_type_attributes() {
'hasEmpty' => $this->get_schema_boolean( false ),
'isDropdown' => $this->get_schema_boolean( false ),
'isHierarchical' => $this->get_schema_boolean( true ),
'textColor' => $this->get_schema_string(),
'fontSize' => $this->get_schema_string(),
'lineHeight' => $this->get_schema_string(),
'style' => array( 'type' => 'object' ),
)
);
}
Expand Down Expand Up @@ -77,9 +84,15 @@ protected function render( $attributes, $content ) {
}
}

$classes = $this->get_container_classes( $attributes );
$classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes(
$attributes,
array( 'line_height', 'text_color', 'font_size' )
);

$classes = $this->get_container_classes( $attributes ) . ' ' . $classes_and_styles['classes'];
$styles = $classes_and_styles['styles'];

$output = '<div class="' . esc_attr( $classes ) . '">';
$output = '<div class="wp-block-woocommerce-product-categories ' . esc_attr( $classes ) . '" style="' . esc_attr( $styles ) . '">';
$output .= ! empty( $attributes['isDropdown'] ) ? $this->renderDropdown( $categories, $attributes, $uid ) : $this->renderList( $categories, $attributes, $uid );
$output .= '</div>';

Expand All @@ -93,6 +106,7 @@ protected function render( $attributes, $content ) {
* @return string space-separated list of classes.
*/
protected function get_container_classes( $attributes = array() ) {

$classes = array( 'wc-block-product-categories' );

if ( isset( $attributes['align'] ) ) {
Expand Down Expand Up @@ -301,11 +315,15 @@ protected function renderList( $categories, $attributes, $uid, $depth = 0 ) {
protected function renderListItems( $categories, $attributes, $uid, $depth = 0 ) {
$output = '';

$link_color_class_and_style = StyleAttributesUtils::get_link_color_class_and_style( $attributes );

$link_color_style = isset( $link_color_class_and_style['style'] ) ? $link_color_class_and_style['style'] : '';

foreach ( $categories as $category ) {
$output .= '
<li class="wc-block-product-categories-list-item">
<a href="' . esc_attr( get_term_link( $category->term_id, 'product_cat' ) ) . '">' . $this->get_image_html( $category, $attributes ) . esc_html( $category->name ) . '</a>
' . $this->getCount( $category, $attributes ) . '
<a style="' . esc_attr( $link_color_style ) . '" href="' . esc_attr( get_term_link( $category->term_id, 'product_cat' ) ) . '">' . $this->get_image_html( $category, $attributes ) . esc_html( $category->name ) . '</a>
' . $this->getCount( $category, $attributes ) . '
' . ( ! empty( $category->children ) ? $this->renderList( $category->children, $attributes, $uid, $depth + 1 ) : '' ) . '
</li>
';
Expand Down
210 changes: 210 additions & 0 deletions src/Utils/StyleAttributesUtils.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
<?php
namespace Automattic\WooCommerce\Blocks\Utils;

/**
* StyleAttributesUtils class used for getting class and style from attributes.
*/
class StyleAttributesUtils {

/**
* Get class and style for font-size from attributes.
*
* @param array $attributes Block attributes.
*
* @return (array | null)
*/
public static function get_font_size_class_and_style( $attributes ) {

$font_size = $attributes['fontSize'];

$custom_font_size = isset( $attributes['style']['typography']['fontSize'] ) ? $attributes['style']['typography']['fontSize'] : null;

if ( ! isset( $font_size ) && ! isset( $custom_font_size ) ) {
return null;
};

$has_named_font_size = ! empty( $font_size );
$has_custom_font_size = isset( $custom_font_size );

if ( $has_named_font_size ) {
return array(
'class' => sprintf( 'has-font-size has-%s-font-size', $font_size ),
'style' => null,
);
} elseif ( $has_custom_font_size ) {
return array(
'class' => null,
'style' => sprintf( 'font-size: %s;', $custom_font_size ),
);
}
return null;
}

/**
* Get class and style for text-color from attributes.
*
* @param array $attributes Block attributes.
*
* @return (array | null)
*/
public static function get_text_color_class_and_style( $attributes ) {

$text_color = $attributes['textColor'];

$custom_text_color = isset( $attributes['style']['color']['text'] ) ? $attributes['style']['color']['text'] : null;

if ( ! isset( $text_color ) && ! isset( $custom_text_color ) ) {
return null;
};

$has_named_text_color = ! empty( $text_color );
$has_custom_text_color = isset( $custom_text_color );

if ( $has_named_text_color ) {
return array(
'class' => sprintf( 'has-text-color has-%s-color', $text_color ),
'style' => null,
);
} elseif ( $has_custom_text_color ) {
return array(
'class' => null,
'style' => sprintf( 'color: %s;', $custom_text_color ),
);
}
return null;
}

/**
* Get class and style for link-color from attributes.
*
* @param array $attributes Block attributes.
*
* @return (array | null)
*/
public static function get_link_color_class_and_style( $attributes ) {

if ( ! isset( $attributes['style']['elements']['link']['color']['text'] ) ) {
return null;
};

$link_color = $attributes['style']['elements']['link']['color']['text'];

// If the link color is selected from the theme color picker, the value of $link_color is var:preset|color|slug.
// If the link color is selected from the core color picker, the value of $link_color is an hex value.
// When the link color is a string var:preset|color|slug we parsed it for get the slug, otherwise we use the hex value.
$index_named_link_color = strrpos( $link_color, '|' );

if ( ! empty( $index_named_link_color ) ) {
$parsed_named_link_color = substr( $link_color, $index_named_link_color + 1 );
return array(
'class' => null,
'style' => sprintf( 'color: %s;', $parsed_named_link_color ),
);
} else {
return array(
'class' => null,
'style' => sprintf( 'color: %s;', $link_color ),
);
}
}

/**
* Get class and style for line height from attributes.
*
* @param array $attributes Block attributes.
*
* @return (array | null)
*/
public static function get_line_height_class_and_style( $attributes ) {

$line_height = isset( $attributes['style']['typography']['lineHeight'] ) ? $attributes['style']['typography']['lineHeight'] : null;

if ( ! isset( $line_height ) ) {
return null;
};

$line_height_style = sprintf( 'line-height: %s;', $line_height );

return array(
'class' => null,
'style' => $line_height_style,
);
}

/**
* Get classes and styles from attributes.
*
* @param array $attributes Block attributes.
* @param array $properties Properties to get classes/styles from.
*
* @return array
*/
public static function get_classes_and_styles_by_attributes( $attributes, $properties = array() ) {
$classes_and_styles = array(
'line_height' => self::get_line_height_class_and_style( $attributes ),
'text_color' => self::get_text_color_class_and_style( $attributes ),
'font_size' => self::get_font_size_class_and_style( $attributes ),
'link_color' => self::get_link_color_class_and_style( $attributes ),
);

if ( ! empty( $properties ) ) {
foreach ( $classes_and_styles as $key => $value ) {
if ( ! in_array( $key, $properties, true ) ) {
unset( $classes_and_styles[ $key ] );
}
}
}

$classes_and_styles = array_filter( $classes_and_styles );

$classes = array_map(
function( $item ) {
return $item['class'];
},
$classes_and_styles
);

$styles = array_map(
function( $item ) {
return $item['style'];
},
$classes_and_styles
);

$classes = array_filter( $classes );
$styles = array_filter( $styles );

return array(
'classes' => implode( ' ', $classes ),
'styles' => implode( ' ', $styles ),
);
}

/**
* Get space-separated classes from block attributes.
*
* @param array $attributes Block attributes.
* @param array $properties Properties to get classes from.
*
* @return string Space-separated classes.
*/
public static function get_classes_by_attributes( $attributes, $properties = array() ) {
$classes_and_styles = self::get_classes_and_styles_by_attributes( $attributes, $properties );

return $classes_and_styles['classes'];
}

/**
* Get space-separated style rules from block attributes.
*
* @param array $attributes Block attributes.
* @param array $properties Properties to get styles from.
*
* @return string Space-separated style rules.
*/
public static function get_styles_by_attributes( $attributes, $properties = array() ) {
$classes_and_styles = self::get_classes_and_styles_by_attributes( $attributes, $properties );

return $classes_and_styles['styles'];
}
}

0 comments on commit d1306f2

Please sign in to comment.