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

Commit cbde25b

Browse files
committed
Implement discount as inner blocks
This allows for being able to edit the text portion of the discount rendering as its own entity.
1 parent 007dd6b commit cbde25b

File tree

9 files changed

+174
-33
lines changed

9 files changed

+174
-33
lines changed

assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,15 @@
77
"category": "woocommerce",
88
"keywords": [ "WooCommerce" ],
99
"textdomain": "woo-gutenberg-products-block",
10+
"supports": {
11+
"__experimentalLayout": {
12+
"allowSwitching": false,
13+
"allowInheriting": false,
14+
"default": { "type": "flex" }
15+
},
16+
"html": false
17+
18+
},
1019
"apiVersion": 2,
1120
"$schema": "https://schemas.wp.org/trunk/block.json"
1221
}
Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,49 @@
11
/**
22
* External dependencies
33
*/
4-
import { useBlockProps } from '@wordpress/block-editor';
5-
import type { HTMLAttributes, CSSProperties } from 'react';
4+
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
65
import { useProductDataContext } from '@woocommerce/shared-context';
7-
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
6+
import { useStyleProps } from '@woocommerce/base-hooks';
7+
import { useEffect } from '@wordpress/element';
88

99
/**
1010
* Internal dependencies
1111
*/
12-
import DiscountBlock from './block';
12+
import { discountAmountName } from './inner-blocks';
13+
import { TEMPLATE } from './template';
1314

14-
interface Attributes {
15-
style: CSSProperties;
16-
}
17-
18-
type Props = {
19-
attributes: Attributes;
20-
context?: { isDescendentOfSingleProductTemplate: boolean };
21-
} & HTMLAttributes< HTMLDivElement >;
22-
23-
const DiscountEdit = ( { attributes, context }: Props ): JSX.Element => {
24-
const blockProps = useBlockProps();
15+
export const Edit = ( { attributes, setAttributes } ): JSX.Element => {
16+
const { style, className } = useStyleProps( attributes );
2517
const { product } = useProductDataContext();
26-
const { isDescendentOfSingleProductTemplate = false } = context || {};
2718
const originalPrice = product?.prices?.regular_price;
2819
const currentPrice = product?.prices?.price;
2920
const showPrice = originalPrice && currentPrice !== originalPrice;
30-
const currency = isDescendentOfSingleProductTemplate
31-
? getCurrencyFromPriceResponse()
32-
: getCurrencyFromPriceResponse( product?.prices );
33-
const blockAttrs = {
34-
attributes,
35-
currency,
36-
context,
37-
originalPrice,
38-
currentPrice,
39-
};
21+
useEffect( () => {
22+
if ( ! attributes?.style ) {
23+
setAttributes( { style: { spacing: { blockGap: '0' } } } );
24+
}
25+
}, [ attributes, setAttributes ] );
4026
return (
4127
<>
4228
{ showPrice && (
43-
<div { ...blockProps }>
44-
<DiscountBlock { ...blockAttrs } />
29+
<div className={ className } style={ style }>
30+
<InnerBlocks
31+
allowedBlocks={ [
32+
discountAmountName,
33+
'core/paragraph',
34+
] }
35+
template={ TEMPLATE }
36+
/>
4537
</div>
4638
) }
4739
</>
4840
);
4941
};
5042

51-
export default DiscountEdit;
43+
export const Save = (): JSX.Element => {
44+
return (
45+
<div { ...useBlockProps.save() }>
46+
<InnerBlocks.Content />
47+
</div>
48+
);
49+
};

assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,22 @@ import { registerBlockType } from '@wordpress/blocks';
66
/**
77
* Internal dependencies
88
*/
9-
import edit from './edit';
9+
import { Edit as edit, Save as save } from './edit';
1010
import sharedConfig from '../../../shared/config';
11+
import { supports } from '../../supports';
1112
import metadata from './block.json';
1213

1314
const { ancestor, ...configuration } = sharedConfig;
1415

1516
const blockConfig = {
1617
...configuration,
1718
...metadata,
18-
edit,
1919
supports: {
20-
...configuration.supports,
21-
context: '',
20+
...supports,
21+
...metadata.supports,
2222
},
23+
edit,
24+
save,
2325
};
2426

2527
registerBlockType( metadata.name, blockConfig );
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "woocommerce/discount-amount",
3+
"version": "1.0.0",
4+
"icon": "info",
5+
"title": "Discount Amount",
6+
"description": "Display the discounted amount value.",
7+
"category": "woocommerce",
8+
"usesContext": ["woocommerce/isDescendantOfSingleProductTemplate"],
9+
"keywords": [ "WooCommerce" ],
10+
"textdomain": "woo-gutenberg-products-block",
11+
"ancestor": "woocommerce/discount",
12+
"apiVersion": 2,
13+
"$schema": "https://schemas.wp.org/trunk/block.json"
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { useBlockProps } from '@wordpress/block-editor';
5+
import type { HTMLAttributes, CSSProperties } from 'react';
6+
import { useProductDataContext } from '@woocommerce/shared-context';
7+
import { getCurrencyFromPriceResponse } from '@woocommerce/price-format';
8+
9+
/**
10+
* Internal dependencies
11+
*/
12+
import DiscountBlock from './block';
13+
14+
interface Attributes {
15+
style: CSSProperties;
16+
}
17+
18+
type Props = {
19+
attributes: Attributes;
20+
context?: { isDescendentOfSingleProductTemplate: boolean };
21+
} & HTMLAttributes< HTMLDivElement >;
22+
23+
const DiscountEdit = ( { attributes, context }: Props ): JSX.Element => {
24+
const blockProps = useBlockProps();
25+
const { product } = useProductDataContext();
26+
const { isDescendentOfSingleProductTemplate = false } = context || {};
27+
const originalPrice = product?.prices?.regular_price;
28+
const currentPrice = product?.prices?.price;
29+
const showPrice = originalPrice && currentPrice !== originalPrice;
30+
const currency = isDescendentOfSingleProductTemplate
31+
? getCurrencyFromPriceResponse()
32+
: getCurrencyFromPriceResponse( product?.prices );
33+
const blockAttrs = {
34+
attributes,
35+
currency,
36+
context,
37+
originalPrice,
38+
currentPrice,
39+
};
40+
return (
41+
<>
42+
{ showPrice && (
43+
<div { ...blockProps }>
44+
<DiscountBlock { ...blockAttrs } />
45+
</div>
46+
) }
47+
</>
48+
);
49+
};
50+
51+
export default DiscountEdit;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { registerBlockType } from '@wordpress/blocks';
5+
6+
/**
7+
* Internal dependencies
8+
*/
9+
import edit from './edit';
10+
import sharedConfig from '../../../../../shared/config';
11+
import metadata from './block.json';
12+
13+
const { ancestor, ...configuration } = sharedConfig;
14+
15+
const blockConfig = {
16+
...configuration,
17+
...metadata,
18+
edit,
19+
supports: {
20+
...configuration.supports,
21+
context: '',
22+
},
23+
};
24+
25+
registerBlockType( metadata.name, blockConfig );
26+
27+
export const BLOCK_NAME = metadata.name;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import './discount-amount/index.ts';
5+
6+
export { BLOCK_NAME as discountAmountName } from './discount-amount/index';
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { InnerBlockTemplate } from '@wordpress/blocks';
5+
import { _x, sprintf } from '@wordpress/i18n';
6+
7+
// Some hackery to both make translation clearer and to allow for RTL languages
8+
// in default template layout.
9+
const translatedContent = sprintf(
10+
// translators: %s: discount amount. The rendered value will only allow for placeholder at beginning or end of string.
11+
_x(
12+
'%s off',
13+
'post text next to discount amount',
14+
'woo-gutenberg-products-block'
15+
),
16+
':placeholder:'
17+
);
18+
19+
const templateContent = translatedContent.replace( ':placeholder:', '' );
20+
21+
const RTLtemplate: InnerBlockTemplate[] = [
22+
[ 'core/paragraph', { content: templateContent }, [] ],
23+
[ 'woocommerce/discount-amount', {}, [] ],
24+
];
25+
26+
const LTRtemplate: InnerBlockTemplate[] = [
27+
[ 'woocommerce/discount-amount', {}, [] ],
28+
[ 'core/paragraph', { content: templateContent }, [] ],
29+
];
30+
31+
export const TEMPLATE: InnerBlockTemplate[] =
32+
translatedContent.indexOf( ':placeholder:' ) === 0
33+
? LTRtemplate
34+
: RTLtemplate;

0 commit comments

Comments
 (0)