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

Commit

Permalink
Product Title block: add support global style (#5515)
Browse files Browse the repository at this point in the history
* Product title: add support global style #4965

* add specific type

* add custom save function

* move hooks in a specific folder

* fix crash on WP 5.8

* fix global style title color (#5548)

Co-authored-by: Tung Du <[email protected]>
  • Loading branch information
gigitux and dinhtungdu authored Jan 12, 2022
1 parent 92a18e8 commit 345bfcd
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 39 deletions.
55 changes: 26 additions & 29 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 '../../../../hooks/style-attributes';

type Props = Attributes & HTMLAttributes< HTMLDivElement >;

Expand Down Expand Up @@ -49,33 +53,21 @@ 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 titleStyle = {
fontSize: style?.fontSize || style?.typography?.fontSize,
color: style?.color?.text || style?.color,
};
const colorProps = useColorProps( props );
const spacingProps = useSpacingProps( props );
const typographyProps = useTypographyProps( props );

if ( ! product.id ) {
return (
Expand All @@ -88,7 +80,6 @@ export const Block = ( {
[ `${ parentClassName }__product-title` ]: parentClassName,
[ `wc-block-components-product-title--align-${ align }` ]:
align && isFeaturePluginBuild(),
[ titleClasses ]: isFeaturePluginBuild(),
}
) }
/>
Expand All @@ -109,9 +100,7 @@ export const Block = ( {
) }
>
<ProductName
className={ classnames( {
[ titleClasses ]: isFeaturePluginBuild(),
} ) }
className={ colorProps.className }
disabled={ ! showProductLink }
name={ product.name }
permalink={ product.permalink }
Expand All @@ -121,7 +110,15 @@ export const Block = ( {
product,
} );
} }
style={ isFeaturePluginBuild() ? titleStyle : {} }
style={
isFeaturePluginBuild()
? {
...spacingProps.style,
...typographyProps.style,
...colorProps.style,
}
: {}
}
/>
</TagName>
);
Expand Down
1 change: 1 addition & 0 deletions assets/js/atomic/blocks/product-elements/title/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import Block from './block';
import withProductSelector from '../shared/with-product-selector';
import { BLOCK_TITLE, BLOCK_ICON } from './constants';
import { Attributes } from './types';
import './editor.scss';

interface Props {
attributes: Attributes;
Expand Down
3 changes: 3 additions & 0 deletions assets/js/atomic/blocks/product-elements/title/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.editor-styles-wrapper a.wc-block-components-product-name {
color: inherit;
}
37 changes: 27 additions & 10 deletions assets/js/atomic/blocks/product-elements/title/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
BLOCK_ICON as icon,
BLOCK_DESCRIPTION as description,
} from './constants';
import { Save } from './save';
import { hasSpacingStyleSupport } from '../../../../utils/global-style';

const blockConfig: BlockConfiguration = {
...sharedConfig,
Expand All @@ -24,17 +26,32 @@ const blockConfig: BlockConfiguration = {
icon: { src: icon },
attributes,
edit,
supports: isFeaturePluginBuild()
? {
html: false,
color: {
background: false,
save: Save,
supports: {
...sharedConfig.supports,
...( isFeaturePluginBuild() && {
typography: {
fontSize: true,
lineHeight: true,
__experimentalFontWeight: true,
__experimentalTextTransform: true,
__experimentalFontFamily: true,
},
color: {
text: true,
background: true,
link: false,
gradients: true,
__experimentalSkipSerialization: true,
},
...( hasSpacingStyleSupport() && {
spacing: {
margin: true,
__experimentalSkipSerialization: true,
},
typography: {
fontSize: true,
},
}
: sharedConfig.supports,
} ),
} ),
},
};

registerBlockType( 'woocommerce/product-title', blockConfig );
21 changes: 21 additions & 0 deletions assets/js/atomic/blocks/product-elements/title/save.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* External dependencies
*/
import { useBlockProps } from '@wordpress/block-editor';
import classnames from 'classnames';

type Props = {
attributes: Record< string, unknown > & {
className?: string;
};
};

export const Save = ( { attributes }: Props ): JSX.Element => {
return (
<div
{ ...useBlockProps.save( {
className: classnames( 'is-loading', attributes.className ),
} ) }
/>
);
};
9 changes: 9 additions & 0 deletions assets/js/atomic/blocks/product-elements/title/style.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.wp-block-woocommerce-product-title {
width: fit-content;
}

.wc-block-components-product-title {
margin-top: 0;
margin-bottom: $gap-small;
Expand All @@ -10,6 +14,11 @@
font-size: inherit;
display: block;
}

.wc-block-components-product-name {
color: inherit;
}

.is-loading {
.wc-block-components-product-title::before {
@include placeholder();
Expand Down
82 changes: 82 additions & 0 deletions assets/js/hooks/style-attributes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/* eslint-disable @wordpress/no-unsafe-wp-apis */
/**
* External dependencies
*/
import {
__experimentalUseColorProps,
__experimentalGetSpacingClassesAndStyles,
} from '@wordpress/block-editor';

/**
* Internal dependencies
*/
import { isFeaturePluginBuild } from '../settings/blocks/feature-flags';
import { isString, isObject } from '../types/type-guards';
import { hasSpacingStyleSupport } from '../utils/global-style';

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 {};
};

export const useSpacingProps = ( attributes: unknown ): WithStyle => {
if ( ! isFeaturePluginBuild() || ! hasSpacingStyleSupport() ) {
return {
style: {},
};
}
const attributesObject = isObject( attributes ) ? attributes : {};
const style = parseStyle( attributesObject.style );

return __experimentalGetSpacingClassesAndStyles( {
...attributesObject,
style,
} );
};

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 } );
};
8 changes: 8 additions & 0 deletions assets/js/utils/global-style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/* eslint-disable @wordpress/no-unsafe-wp-apis */
/**
* External dependencies
*/
import { __experimentalGetSpacingClassesAndStyles } from '@wordpress/block-editor';

export const hasSpacingStyleSupport = () =>
typeof __experimentalGetSpacingClassesAndStyles === 'function';

0 comments on commit 345bfcd

Please sign in to comment.