From e9d7c30d521d21a3b1300e14b9fd68d01039baec Mon Sep 17 00:00:00 2001 From: Luigi Date: Tue, 4 Jan 2022 14:55:19 +0100 Subject: [PATCH 1/6] Product title: add support global style #4965 --- .../blocks/product-elements/title/block.tsx | 57 +++++----- .../blocks/product-elements/title/index.ts | 31 ++++-- assets/js/utils/style-attributes-utils.ts | 105 ++++++++++++++++++ 3 files changed, 154 insertions(+), 39 deletions(-) create mode 100644 assets/js/utils/style-attributes-utils.ts diff --git a/assets/js/atomic/blocks/product-elements/title/block.tsx b/assets/js/atomic/blocks/product-elements/title/block.tsx index 86801e51fbd..793a49c422b 100644 --- a/assets/js/atomic/blocks/product-elements/title/block.tsx +++ b/assets/js/atomic/blocks/product-elements/title/block.tsx @@ -7,7 +7,6 @@ import { useInnerBlockLayoutContext, useProductDataContext, } from '@woocommerce/shared-context'; -import { getColorClassName, getFontSizeClass } from '@wordpress/block-editor'; import { isFeaturePluginBuild } from '@woocommerce/block-settings'; import { withProductDataContext } from '@woocommerce/shared-hocs'; import ProductName from '@woocommerce/base-components/product-name'; @@ -18,6 +17,11 @@ import { useStoreEvents } from '@woocommerce/base-context/hooks'; */ import './style.scss'; import { Attributes } from './types'; +import { + useSpacingProps, + useTypographyProps, + useColorProps, +} from '../../../../utils/style-attributes-utils'; type Props = Attributes & HTMLAttributes< HTMLDivElement >; @@ -49,33 +53,26 @@ const TagName = ( { * will be used if this is not provided. * @return {*} The component. */ -export const Block = ( { - className, - headingLevel = 2, - showProductLink = true, - align, - textColor, - fontSize, - style, -}: Props ): JSX.Element => { +export const Block = ( props: Props ): JSX.Element => { + const { + className, + headingLevel = 2, + showProductLink = true, + align, + } = props; + const { parentClassName } = useInnerBlockLayoutContext(); const { product } = useProductDataContext(); const { dispatchStoreEvent } = useStoreEvents(); - const colorClass = getColorClassName( 'color', textColor ); - const fontSizeClass = getFontSizeClass( fontSize ); - const titleClasses = classnames( 'wp-block-woocommerce-product-title', { - 'has-text-color': textColor || style?.color?.text || style?.color, - [ `has-font-size` ]: - fontSize || style?.typography?.fontSize || style?.fontSize, - [ colorClass ]: colorClass, - [ fontSizeClass ]: fontSizeClass, - } ); + const colorProps = useColorProps( props ); + const spacingProps = useSpacingProps( props ); + const typographyProps = useTypographyProps( props ); - const titleStyle = { - fontSize: style?.fontSize || style?.typography?.fontSize, - color: style?.color?.text || style?.color, - }; + const titleClasses = classnames( + 'wp-block-woocommerce-product-title', + colorProps.className + ); if ( ! product.id ) { return ( @@ -88,7 +85,6 @@ export const Block = ( { [ `${ parentClassName }__product-title` ]: parentClassName, [ `wc-block-components-product-title--align-${ align }` ]: align && isFeaturePluginBuild(), - [ titleClasses ]: isFeaturePluginBuild(), } ) } /> @@ -109,9 +105,7 @@ export const Block = ( { ) } > ); diff --git a/assets/js/atomic/blocks/product-elements/title/index.ts b/assets/js/atomic/blocks/product-elements/title/index.ts index bf70fbfd62c..9ee1af8b9e2 100644 --- a/assets/js/atomic/blocks/product-elements/title/index.ts +++ b/assets/js/atomic/blocks/product-elements/title/index.ts @@ -24,17 +24,26 @@ const blockConfig: BlockConfiguration = { icon: { src: icon }, attributes, edit, - supports: isFeaturePluginBuild() - ? { - html: false, - color: { - background: false, - }, - typography: { - fontSize: true, - }, - } - : sharedConfig.supports, + supports: { + typography: { + fontSize: true, + lineHeight: true, + ...( isFeaturePluginBuild() & + { + __experimentalFontWeight: true, + __experimentalTextTransform: true, + __experimentalFontFamily: true, + } ), + }, + color: { + text: false, + background: true, + gradients: true, + }, + spacing: { + margin: true, + }, + }, }; registerBlockType( 'woocommerce/product-title', blockConfig ); diff --git a/assets/js/utils/style-attributes-utils.ts b/assets/js/utils/style-attributes-utils.ts new file mode 100644 index 00000000000..15ca869a3ef --- /dev/null +++ b/assets/js/utils/style-attributes-utils.ts @@ -0,0 +1,105 @@ +/* eslint-disable @wordpress/no-unsafe-wp-apis */ +/** + * External dependencies + */ +import { __experimentalUseColorProps } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import { isFeaturePluginBuild } from '../settings/blocks/feature-flags'; +import { isString, isObject } from '../types/type-guards'; + +const parseStyle = ( style: unknown ): Record< string, unknown > => { + if ( isString( style ) ) { + return JSON.parse( style ) || {}; + } + + if ( isObject( style ) ) { + return style; + } + + return {}; +}; + +const parseSpacingStyle = ( + spacing: Record< string, unknown > +): Record< string, unknown > => { + const keys = [ 'margin' ]; + + const getValueOrDefault = ( value: unknown ) => { + return isString( value ) && value.length > 0 ? value : '0'; + }; + + return Object.keys( spacing ).reduce( ( acc, key ) => { + const spacingProperty = isObject( spacing[ key ] ) + ? ( spacing[ key ] as Record< string, unknown > ) + : {}; + + if ( keys.includes( key ) ) { + return { + ...acc, + [ key ]: `${ getValueOrDefault( + spacingProperty.top + ) } ${ getValueOrDefault( + spacingProperty.right + ) } ${ getValueOrDefault( + spacingProperty.bottom + ) } ${ getValueOrDefault( spacingProperty.left ) }`, + }; + } + + return acc; + }, {} ); +}; + +export const useSpacingProps = ( + attributes: unknown +): { + style: Record< string, unknown >; +} => { + const style = isObject( attributes ) ? parseStyle( attributes.style ) : {}; + const spacingStyles = isObject( style.spacing ) ? style.spacing : {}; + + return { + style: parseSpacingStyle( spacingStyles ), + }; +}; + +export const useTypographyProps = ( + attributes: unknown +): { + style: Record< string, unknown >; +} => { + const attributesObject = isObject( attributes ) ? attributes : {}; + const style = parseStyle( attributesObject.style ); + const typography = isObject( style.typography ) + ? ( style.typography as Record< string, unknown > ) + : {}; + + return { + style: { + fontSize: attributesObject.fontSize || typography.fontSize, + lineHeight: typography.lineHeight, + fontWeight: typography.fontWeight, + textTransform: typography.textTransform, + fontFamily: attributesObject.fontFamily, + }, + }; +}; + +export const useColorProps = ( + attributes: unknown +): { + className: string; + style: Record< string, unknown >; +} => { + if ( ! isFeaturePluginBuild() ) { + return { + className: '', + style: {}, + }; + } + + return __experimentalUseColorProps( attributes ); +}; From 517f80a11760fad95c480309b6dcc7dd5747148c Mon Sep 17 00:00:00 2001 From: Luigi Date: Tue, 4 Jan 2022 14:57:23 +0100 Subject: [PATCH 2/6] add specific type --- .../blocks/product-elements/title/block.tsx | 1 + .../blocks/product-elements/title/index.ts | 11 +++---- assets/js/utils/style-attributes-utils.ts | 32 +++++++++---------- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/title/block.tsx b/assets/js/atomic/blocks/product-elements/title/block.tsx index 793a49c422b..99369553568 100644 --- a/assets/js/atomic/blocks/product-elements/title/block.tsx +++ b/assets/js/atomic/blocks/product-elements/title/block.tsx @@ -120,6 +120,7 @@ export const Block = ( props: Props ): JSX.Element => { ? { ...spacingProps.style, ...typographyProps.style, + ...colorProps.style, } : {} } diff --git a/assets/js/atomic/blocks/product-elements/title/index.ts b/assets/js/atomic/blocks/product-elements/title/index.ts index 9ee1af8b9e2..03935b1a702 100644 --- a/assets/js/atomic/blocks/product-elements/title/index.ts +++ b/assets/js/atomic/blocks/product-elements/title/index.ts @@ -28,12 +28,11 @@ const blockConfig: BlockConfiguration = { typography: { fontSize: true, lineHeight: true, - ...( isFeaturePluginBuild() & - { - __experimentalFontWeight: true, - __experimentalTextTransform: true, - __experimentalFontFamily: true, - } ), + ...( isFeaturePluginBuild() && { + __experimentalFontWeight: true, + __experimentalTextTransform: true, + __experimentalFontFamily: true, + } ), }, color: { text: false, diff --git a/assets/js/utils/style-attributes-utils.ts b/assets/js/utils/style-attributes-utils.ts index 15ca869a3ef..ab4145af1f4 100644 --- a/assets/js/utils/style-attributes-utils.ts +++ b/assets/js/utils/style-attributes-utils.ts @@ -10,6 +10,14 @@ import { __experimentalUseColorProps } from '@wordpress/block-editor'; import { isFeaturePluginBuild } from '../settings/blocks/feature-flags'; import { isString, isObject } from '../types/type-guards'; +type WithClass = { + className: string; +}; + +type WithStyle = { + style: Record< string, unknown >; +}; + const parseStyle = ( style: unknown ): Record< string, unknown > => { if ( isString( style ) ) { return JSON.parse( style ) || {}; @@ -53,11 +61,7 @@ const parseSpacingStyle = ( }, {} ); }; -export const useSpacingProps = ( - attributes: unknown -): { - style: Record< string, unknown >; -} => { +export const useSpacingProps = ( attributes: unknown ): WithStyle => { const style = isObject( attributes ) ? parseStyle( attributes.style ) : {}; const spacingStyles = isObject( style.spacing ) ? style.spacing : {}; @@ -66,11 +70,7 @@ export const useSpacingProps = ( }; }; -export const useTypographyProps = ( - attributes: unknown -): { - style: Record< string, unknown >; -} => { +export const useTypographyProps = ( attributes: unknown ): WithStyle => { const attributesObject = isObject( attributes ) ? attributes : {}; const style = parseStyle( attributesObject.style ); const typography = isObject( style.typography ) @@ -88,12 +88,7 @@ export const useTypographyProps = ( }; }; -export const useColorProps = ( - attributes: unknown -): { - className: string; - style: Record< string, unknown >; -} => { +export const useColorProps = ( attributes: unknown ): WithStyle & WithClass => { if ( ! isFeaturePluginBuild() ) { return { className: '', @@ -101,5 +96,8 @@ export const useColorProps = ( }; } - return __experimentalUseColorProps( attributes ); + const attributesObject = isObject( attributes ) ? attributes : {}; + const style = parseStyle( attributesObject.style ); + + return __experimentalUseColorProps( { ...attributesObject, style } ); }; From 5c040921fb7b7b823c08d2d58a39dfe6416cc674 Mon Sep 17 00:00:00 2001 From: Luigi Date: Tue, 4 Jan 2022 16:52:07 +0100 Subject: [PATCH 3/6] Enable global style for category list block #4965 Enable global style for category list block --- .../blocks/product-elements/category-list/block.tsx | 12 +++++++++++- .../blocks/product-elements/category-list/edit.tsx | 7 +++++-- .../blocks/product-elements/category-list/index.ts | 11 +++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/category-list/block.tsx b/assets/js/atomic/blocks/product-elements/category-list/block.tsx index 59a4dd628fe..dc359a74c19 100644 --- a/assets/js/atomic/blocks/product-elements/category-list/block.tsx +++ b/assets/js/atomic/blocks/product-elements/category-list/block.tsx @@ -16,6 +16,10 @@ import { HTMLAttributes } from 'react'; */ import './style.scss'; import { Attributes } from './types'; +import { + useColorProps, + useTypographyProps, +} from '../../../../utils/style-attributes-utils'; type Props = Attributes & HTMLAttributes< HTMLDivElement >; @@ -26,10 +30,14 @@ type Props = Attributes & HTMLAttributes< HTMLDivElement >; * @param {string} [props.className] CSS Class name for the component. * @return {*} The component. */ -const Block = ( { className }: Props ): JSX.Element | null => { +const Block = ( props: Props ): JSX.Element | null => { + const { className } = props; const { parentClassName } = useInnerBlockLayoutContext(); const { product } = useProductDataContext(); + const colorProps = useColorProps( props ); + const typographyProps = useTypographyProps( props ); + if ( isEmpty( product.categories ) ) { return null; } @@ -39,10 +47,12 @@ const Block = ( { className }: Props ): JSX.Element | null => { className={ classnames( className, 'wc-block-components-product-category-list', + colorProps.className, { [ `${ parentClassName }__product-category-list` ]: parentClassName, } ) } + style={ { ...colorProps.style, ...typographyProps.style } } > { __( 'Categories:', 'woo-gutenberg-products-block' ) }{ ' ' }
    diff --git a/assets/js/atomic/blocks/product-elements/category-list/edit.tsx b/assets/js/atomic/blocks/product-elements/category-list/edit.tsx index d3f8266c562..eae09bc5581 100644 --- a/assets/js/atomic/blocks/product-elements/category-list/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/category-list/edit.tsx @@ -4,6 +4,7 @@ import { __ } from '@wordpress/i18n'; import { Disabled } from '@wordpress/components'; import EditProductLink from '@woocommerce/editor-components/edit-product-link'; +import { useBlockProps } from '@wordpress/block-editor'; /** * Internal dependencies @@ -18,13 +19,15 @@ interface Props { } const Edit = ( { attributes }: Props ): JSX.Element => { + const blockProps = useBlockProps(); + return ( - <> +
    - +
    ); }; diff --git a/assets/js/atomic/blocks/product-elements/category-list/index.ts b/assets/js/atomic/blocks/product-elements/category-list/index.ts index 09b7734f3d7..a582d9395f8 100644 --- a/assets/js/atomic/blocks/product-elements/category-list/index.ts +++ b/assets/js/atomic/blocks/product-elements/category-list/index.ts @@ -18,11 +18,22 @@ import { const blockConfig: BlockConfiguration = { ...sharedConfig, + apiVersion: 2, title, description, icon: { src: icon }, attributes, edit, + supports: { + color: { + text: true, + link: true, + background: false, + }, + typography: { + fontSize: true, + }, + }, }; registerExperimentalBlockType( From 7de4053d61e51fa7ddf117a6ee9db784b0012543 Mon Sep 17 00:00:00 2001 From: Luigi Date: Wed, 12 Jan 2022 14:42:07 +0100 Subject: [PATCH 4/6] fix import after merge --- .../product-elements/category-list/block.tsx | 2 +- assets/js/utils/style-attributes-utils.ts | 103 ------------------ 2 files changed, 1 insertion(+), 104 deletions(-) delete mode 100644 assets/js/utils/style-attributes-utils.ts diff --git a/assets/js/atomic/blocks/product-elements/category-list/block.tsx b/assets/js/atomic/blocks/product-elements/category-list/block.tsx index dc359a74c19..3fc4bbe8c44 100644 --- a/assets/js/atomic/blocks/product-elements/category-list/block.tsx +++ b/assets/js/atomic/blocks/product-elements/category-list/block.tsx @@ -19,7 +19,7 @@ import { Attributes } from './types'; import { useColorProps, useTypographyProps, -} from '../../../../utils/style-attributes-utils'; +} from '../../../../hooks/style-attributes'; type Props = Attributes & HTMLAttributes< HTMLDivElement >; diff --git a/assets/js/utils/style-attributes-utils.ts b/assets/js/utils/style-attributes-utils.ts deleted file mode 100644 index ab4145af1f4..00000000000 --- a/assets/js/utils/style-attributes-utils.ts +++ /dev/null @@ -1,103 +0,0 @@ -/* eslint-disable @wordpress/no-unsafe-wp-apis */ -/** - * External dependencies - */ -import { __experimentalUseColorProps } from '@wordpress/block-editor'; - -/** - * Internal dependencies - */ -import { isFeaturePluginBuild } from '../settings/blocks/feature-flags'; -import { isString, isObject } from '../types/type-guards'; - -type WithClass = { - className: string; -}; - -type WithStyle = { - style: Record< string, unknown >; -}; - -const parseStyle = ( style: unknown ): Record< string, unknown > => { - if ( isString( style ) ) { - return JSON.parse( style ) || {}; - } - - if ( isObject( style ) ) { - return style; - } - - return {}; -}; - -const parseSpacingStyle = ( - spacing: Record< string, unknown > -): Record< string, unknown > => { - const keys = [ 'margin' ]; - - const getValueOrDefault = ( value: unknown ) => { - return isString( value ) && value.length > 0 ? value : '0'; - }; - - return Object.keys( spacing ).reduce( ( acc, key ) => { - const spacingProperty = isObject( spacing[ key ] ) - ? ( spacing[ key ] as Record< string, unknown > ) - : {}; - - if ( keys.includes( key ) ) { - return { - ...acc, - [ key ]: `${ getValueOrDefault( - spacingProperty.top - ) } ${ getValueOrDefault( - spacingProperty.right - ) } ${ getValueOrDefault( - spacingProperty.bottom - ) } ${ getValueOrDefault( spacingProperty.left ) }`, - }; - } - - return acc; - }, {} ); -}; - -export const useSpacingProps = ( attributes: unknown ): WithStyle => { - const style = isObject( attributes ) ? parseStyle( attributes.style ) : {}; - const spacingStyles = isObject( style.spacing ) ? style.spacing : {}; - - return { - style: parseSpacingStyle( spacingStyles ), - }; -}; - -export const useTypographyProps = ( attributes: unknown ): WithStyle => { - const attributesObject = isObject( attributes ) ? attributes : {}; - const style = parseStyle( attributesObject.style ); - const typography = isObject( style.typography ) - ? ( style.typography as Record< string, unknown > ) - : {}; - - return { - style: { - fontSize: attributesObject.fontSize || typography.fontSize, - lineHeight: typography.lineHeight, - fontWeight: typography.fontWeight, - textTransform: typography.textTransform, - fontFamily: attributesObject.fontFamily, - }, - }; -}; - -export const useColorProps = ( attributes: unknown ): WithStyle & WithClass => { - if ( ! isFeaturePluginBuild() ) { - return { - className: '', - style: {}, - }; - } - - const attributesObject = isObject( attributes ) ? attributes : {}; - const style = parseStyle( attributesObject.style ); - - return __experimentalUseColorProps( { ...attributesObject, style } ); -}; From 7916e7f26cf9c6dd531e0960cf8b5493861d7b76 Mon Sep 17 00:00:00 2001 From: Luigi Date: Wed, 12 Jan 2022 14:58:07 +0100 Subject: [PATCH 5/6] add save function --- .../product-elements/category-list/index.ts | 4 +++- .../product-elements/category-list/save.tsx | 21 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 assets/js/atomic/blocks/product-elements/category-list/save.tsx diff --git a/assets/js/atomic/blocks/product-elements/category-list/index.ts b/assets/js/atomic/blocks/product-elements/category-list/index.ts index a582d9395f8..4350604ce76 100644 --- a/assets/js/atomic/blocks/product-elements/category-list/index.ts +++ b/assets/js/atomic/blocks/product-elements/category-list/index.ts @@ -15,6 +15,7 @@ import { BLOCK_ICON as icon, BLOCK_DESCRIPTION as description, } from './constants'; +import { Save } from './save'; const blockConfig: BlockConfiguration = { ...sharedConfig, @@ -23,7 +24,6 @@ const blockConfig: BlockConfiguration = { description, icon: { src: icon }, attributes, - edit, supports: { color: { text: true, @@ -34,6 +34,8 @@ const blockConfig: BlockConfiguration = { fontSize: true, }, }, + save: Save, + edit, }; registerExperimentalBlockType( diff --git a/assets/js/atomic/blocks/product-elements/category-list/save.tsx b/assets/js/atomic/blocks/product-elements/category-list/save.tsx new file mode 100644 index 00000000000..11135ed1bb2 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/category-list/save.tsx @@ -0,0 +1,21 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; +import { useBlockProps } from '@wordpress/block-editor'; + +type Props = { + attributes: Record< string, unknown > & { + className: string; + }; +}; + +export const Save = ( { attributes }: Props ): JSX.Element => { + return ( +
    + ); +}; From efa5faa319e4edafae7dbba22951634374adf2ce Mon Sep 17 00:00:00 2001 From: Luigi Date: Wed, 12 Jan 2022 15:10:13 +0100 Subject: [PATCH 6/6] add feature flag --- .../product-elements/category-list/index.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/category-list/index.ts b/assets/js/atomic/blocks/product-elements/category-list/index.ts index 4350604ce76..df526ff6c74 100644 --- a/assets/js/atomic/blocks/product-elements/category-list/index.ts +++ b/assets/js/atomic/blocks/product-elements/category-list/index.ts @@ -1,7 +1,10 @@ /** * External dependencies */ -import { registerExperimentalBlockType } from '@woocommerce/block-settings'; +import { + isFeaturePluginBuild, + registerExperimentalBlockType, +} from '@woocommerce/block-settings'; import { BlockConfiguration } from '@wordpress/blocks'; /** @@ -25,11 +28,13 @@ const blockConfig: BlockConfiguration = { icon: { src: icon }, attributes, supports: { - color: { - text: true, - link: true, - background: false, - }, + ...( isFeaturePluginBuild() && { + color: { + text: true, + link: true, + background: false, + }, + } ), typography: { fontSize: true, },