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

Commit

Permalink
Merge branch 'add/4965-product-title' of github.com:woocommerce/wooco…
Browse files Browse the repository at this point in the history
…mmerce-gutenberg-products-block into add/4965-category-list
  • Loading branch information
gigitux committed Jan 4, 2022
2 parents 0c43f37 + 517f80a commit dbc8e38
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 39 deletions.
58 changes: 30 additions & 28 deletions assets/js/atomic/blocks/product-elements/title/block.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -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 >;

Expand Down Expand Up @@ -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 (
Expand All @@ -88,7 +85,6 @@ export const Block = ( {
[ `${ parentClassName }__product-title` ]: parentClassName,
[ `wc-block-components-product-title--align-${ align }` ]:
align && isFeaturePluginBuild(),
[ titleClasses ]: isFeaturePluginBuild(),
}
) }
/>
Expand All @@ -109,9 +105,7 @@ export const Block = ( {
) }
>
<ProductName
className={ classnames( {
[ titleClasses ]: isFeaturePluginBuild(),
} ) }
className={ titleClasses }
disabled={ ! showProductLink }
name={ product.name }
permalink={ product.permalink }
Expand All @@ -121,7 +115,15 @@ export const Block = ( {
product,
} );
} }
style={ isFeaturePluginBuild() ? titleStyle : {} }
style={
isFeaturePluginBuild()
? {
...spacingProps.style,
...typographyProps.style,
...colorProps.style,
}
: {}
}
/>
</TagName>
);
Expand Down
30 changes: 19 additions & 11 deletions assets/js/atomic/blocks/product-elements/title/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,25 @@ 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 );
103 changes: 103 additions & 0 deletions assets/js/utils/style-attributes-utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/* 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 } );
};

0 comments on commit dbc8e38

Please sign in to comment.