From b0b059c84b6328e9f980f779f0236e6386da327a Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 1 May 2023 08:12:07 -0400 Subject: [PATCH 01/32] Rename block. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From “Product Price” to “Price” --- assets/js/atomic/blocks/product-elements/price/constants.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/atomic/blocks/product-elements/price/constants.tsx b/assets/js/atomic/blocks/product-elements/price/constants.tsx index 544becb88aa..e4dd8b76759 100644 --- a/assets/js/atomic/blocks/product-elements/price/constants.tsx +++ b/assets/js/atomic/blocks/product-elements/price/constants.tsx @@ -5,7 +5,7 @@ import { __ } from '@wordpress/i18n'; import { currencyDollar, Icon } from '@wordpress/icons'; export const BLOCK_TITLE: string = __( - 'Product Price', + 'Price', 'woo-gutenberg-products-block' ); export const BLOCK_ICON: JSX.Element = ( From 75b60fdee8d1c626151faf5529d53a56da82fcf2 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 1 May 2023 08:13:24 -0400 Subject: [PATCH 02/32] Update block description. --- assets/js/atomic/blocks/product-elements/price/constants.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/atomic/blocks/product-elements/price/constants.tsx b/assets/js/atomic/blocks/product-elements/price/constants.tsx index e4dd8b76759..79f6f6989ed 100644 --- a/assets/js/atomic/blocks/product-elements/price/constants.tsx +++ b/assets/js/atomic/blocks/product-elements/price/constants.tsx @@ -15,6 +15,6 @@ export const BLOCK_ICON: JSX.Element = ( /> ); export const BLOCK_DESCRIPTION: string = __( - 'Display the price of a product.', + 'Display the price of a product, including any discounts.', 'woo-gutenberg-products-block' ); From ba2c832f5bc06cd00a2dd3fe5971476b7ece535d Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 1 May 2023 14:47:36 -0400 Subject: [PATCH 03/32] Update Query Types Adds `include` property and makes all properties optional. --- assets/js/types/type-defs/hooks.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/assets/js/types/type-defs/hooks.ts b/assets/js/types/type-defs/hooks.ts index a9ee2aa58ef..53ee0fc8e07 100644 --- a/assets/js/types/type-defs/hooks.ts +++ b/assets/js/types/type-defs/hooks.ts @@ -63,9 +63,10 @@ export interface StoreCart { } export type Query = { - catalog_visibility: 'catalog'; - per_page: number; - page: number; - orderby: string; - order: string; + catalog_visibility?: 'catalog'; + per_page?: number; + page?: number; + orderby?: string; + order?: string; + include?: string | number; }; From 40ac73d946b1922c9973ac2891c9ff788a3ca0c4 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 1 May 2023 15:05:03 -0400 Subject: [PATCH 04/32] Account for undefined in type definitions --- assets/js/shared/context/product-data-context.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/shared/context/product-data-context.tsx b/assets/js/shared/context/product-data-context.tsx index deb6f2d8d0e..7f6979060fe 100644 --- a/assets/js/shared/context/product-data-context.tsx +++ b/assets/js/shared/context/product-data-context.tsx @@ -70,7 +70,7 @@ export const useProductDataContext = () => useContext( ProductDataContext ); interface ProductDataContextProviderProps { product: ProductResponseItem | null; - children: JSX.Element | JSX.Element[]; + children: JSX.Element | JSX.Element[] | undefined; isLoading: boolean; } From 7681268598b6aeed6a39c3663aa75976319b92c7 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Tue, 23 May 2023 10:43:04 -0400 Subject: [PATCH 05/32] Implement new price block I decided to create this refinement as a new block given the change in structure and the potential impact on styling etc. We can make a decision on whether this just replaces the existing block in the future, but for now, this allows testing both in tandem. --- assets/js/atomic/blocks/index.js | 1 + .../product-elements/price-v2/attributes.ts | 21 +++ .../price-v2/components/product-price.tsx | 58 +++++++ .../product-elements/price-v2/constants.tsx | 20 +++ .../blocks/product-elements/price-v2/edit.tsx | 148 ++++++++++++++++++ .../blocks/product-elements/price-v2/index.ts | 41 +++++ .../inner-blocks/current-price/block.json | 12 ++ .../inner-blocks/current-price/block.tsx | 59 +++++++ .../inner-blocks/current-price/edit.tsx | 47 ++++++ .../inner-blocks/current-price/index.ts | 27 ++++ .../price-v2/inner-blocks/discount/edit.tsx | 0 .../price-v2/inner-blocks/index.ts | 8 + .../inner-blocks/original-price/block.json | 12 ++ .../inner-blocks/original-price/block.tsx | 60 +++++++ .../inner-blocks/original-price/edit.tsx | 51 ++++++ .../inner-blocks/original-price/index.ts | 27 ++++ .../blocks/product-elements/price-v2/save.tsx | 17 ++ .../product-elements/price-v2/style.scss | 7 + .../product-elements/price-v2/supports.ts | 39 +++++ .../product-elements/price-v2/template.ts | 9 ++ .../blocks/product-elements/price-v2/types.ts | 30 ++++ .../product-elements/price/constants.tsx | 4 +- 22 files changed, 696 insertions(+), 2 deletions(-) create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/attributes.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/components/product-price.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/constants.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/edit.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/index.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/save.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/style.scss create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/supports.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/template.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/types.ts diff --git a/assets/js/atomic/blocks/index.js b/assets/js/atomic/blocks/index.js index 4346815ed1e..8d5878a9339 100644 --- a/assets/js/atomic/blocks/index.js +++ b/assets/js/atomic/blocks/index.js @@ -3,6 +3,7 @@ */ import './product-elements/title'; import './product-elements/price'; +import './product-elements/price-v2'; import './product-elements/image'; import './product-elements/rating'; import './product-elements/button'; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/attributes.ts b/assets/js/atomic/blocks/product-elements/price-v2/attributes.ts new file mode 100644 index 00000000000..db985052251 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/attributes.ts @@ -0,0 +1,21 @@ +/** + * External dependencies + */ +import { BlockAttributes } from '@wordpress/blocks'; + +export const blockAttributes: BlockAttributes = { + isDescendentOfSingleProductTemplate: { + type: 'boolean', + default: false, + }, + isDescendentOfSingleProductBlock: { + type: 'boolean', + default: false, + }, + productId: { + type: 'number', + default: 0, + }, +}; + +export default blockAttributes; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/components/product-price.tsx b/assets/js/atomic/blocks/product-elements/price-v2/components/product-price.tsx new file mode 100644 index 00000000000..06169c0eaae --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/components/product-price.tsx @@ -0,0 +1,58 @@ +/** + * External dependencies + */ +import type { Currency } from '@woocommerce/types'; +import type { CSSProperties } from 'react'; + +export interface ProductPriceProps { + /** + * CSS class for the wrapper + */ + wrapperClassName?: string | undefined; + /** + * Currency configuration object + */ + currency?: Currency; + /** + * The string version of the element to use for the price interpolation + * + * **Note:** It should contain `` (which is also the default value) + */ + format?: string; + /** + * The maximum price in a range + */ + maxPrice?: string | number; + /** + * The minimum price in a range + */ + minPrice?: string | number; + /** + * The current price + */ + price?: string | number; + /** + * CSS class for the price + */ + priceClassName?: string; + /** + * Custom style for the price + */ + priceStyle?: CSSProperties; + /** + * Custom style for the wrapper + */ + style?: CSSProperties; +} + +export const ProductPrice = ( { + className, + currency, + format = '', + maxPrice, + minPrice, + price, + priceClassName, + priceStyle, + style, +} ) => {}; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/constants.tsx b/assets/js/atomic/blocks/product-elements/price-v2/constants.tsx new file mode 100644 index 00000000000..79f6f6989ed --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/constants.tsx @@ -0,0 +1,20 @@ +/** + * External dependencies + */ +import { __ } from '@wordpress/i18n'; +import { currencyDollar, Icon } from '@wordpress/icons'; + +export const BLOCK_TITLE: string = __( + 'Price', + 'woo-gutenberg-products-block' +); +export const BLOCK_ICON: JSX.Element = ( + +); +export const BLOCK_DESCRIPTION: string = __( + 'Display the price of a product, including any discounts.', + 'woo-gutenberg-products-block' +); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx new file mode 100644 index 00000000000..3f5b457bd15 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx @@ -0,0 +1,148 @@ +/** + * External dependencies + */ +import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'; +import { useEffect } from '@wordpress/element'; +import { useSelect } from '@wordpress/data'; +import { + InnerBlockLayoutContextProvider, + useInnerBlockLayoutContext, + ProductDataContextProvider, +} from '@woocommerce/shared-context'; +import { useStoreProducts } from '@woocommerce/base-context/hooks'; + +/** + * Internal dependencies + */ +import { originalPriceName, currentPriceName } from './inner-blocks'; +import { TEMPLATE } from './template'; + +interface Attributes { + isDescendentOfSingleProductBlock: boolean; + isDescendentOfSingleProductTemplate: boolean; + productId?: number; +} + +interface Context { + postId?: number; + queryId?: number; +} + +interface Props { + context: Context; + attributes: Attributes; + setAttributes: ( attributes: Partial< Attributes > ) => void; +} + +interface ContextProviderProps extends Props { + children: JSX.Element | JSX.Element[] | undefined; +} + +type ProductIdProps = Partial< ContextProviderProps > & { productId: number }; + +const ProviderFromAPI = ( { + productId, + children, +}: ProductIdProps ): JSX.Element => { + // TODO: this would be good to derive from the WP entity store at some point. + const { products, productsLoading } = useStoreProducts( { + include: productId, + } ); + let product = null; + if ( products.length > 0 ) { + product = + products.find( + ( productIteration ) => productIteration.id === productId + ) || null; + } + + return ( + + { children } + + ); +}; + +const DerivedProductDataContextProvider = ( { + context, + attributes, + setAttributes, + children, +}: ContextProviderProps ): JSX.Element => { + const { queryId, postId } = context; + const { productId } = attributes; + const isDescendentOfQueryLoop = Number.isFinite( queryId ); + const id = isDescendentOfQueryLoop ? postId : productId; + const isDescendentOfSingleProductTemplate = useSelect( + ( select ) => { + const editSiteStore = select( 'core/edit-site' ); + const editorPostId = editSiteStore?.getEditedPostId< + string | undefined + >(); + + return Boolean( + editorPostId?.includes( '//single-product' ) && + ! isDescendentOfQueryLoop + ); + }, + [ isDescendentOfQueryLoop ] + ); + + useEffect( + () => + setAttributes( { + isDescendentOfSingleProductTemplate, + } ), + [ isDescendentOfSingleProductTemplate, setAttributes ] + ); + if ( id && id > 0 ) { + return { children }; + } + return ( + + { children } + + ); +}; + +const EditBlock = ( { + context, + attributes, + setAttributes, +}: Props ): JSX.Element => { + const { parentClassName } = useInnerBlockLayoutContext(); + return ( + +
+ +
+
+ ); +}; + +const Edit = ( props: Props ): JSX.Element => { + const blockProps = useBlockProps(); + return ( +
+ + + +
+ ); +}; + +export default Edit; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/index.ts new file mode 100644 index 00000000000..d7d185c9c6f --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/index.ts @@ -0,0 +1,41 @@ +/** + * External dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import sharedConfig from '../shared/config'; +import edit from './edit'; +import { save } from './save'; +import attributes from './attributes'; +import { supports } from './supports'; +import { + BLOCK_TITLE as title, + BLOCK_ICON as icon, + BLOCK_DESCRIPTION as description, +} from './constants'; + +const { ancestor, ...configuration } = sharedConfig; + +const blockConfig = { + ...configuration, + apiVersion: 2, + title, + description, + usesContext: [ 'postId', 'queryId' ], + providesContext: { + 'woocommerce/isDescendentOfSingleProductTemplate': + 'isDescendentOfSingleProductTemplate', + 'woocommerce/isDescendentOfSingleProductBlock': + 'isDescendentOfSingleProductBlock', + }, + icon: { src: icon }, + attributes, + supports, + edit, + save, +}; + +registerBlockType( 'woocommerce/product-price-v2', blockConfig ); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json new file mode 100644 index 00000000000..e97826d3822 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json @@ -0,0 +1,12 @@ +{ + "name": "woocommerce/current-price", + "version": "1.0.0", + "icon": "info", + "title": "Current Price", + "description": "Display the current price for the product", + "category": "woocommerce", + "keywords": [ "WooCommerce" ], + "textdomain": "woo-gutenberg-products-block", + "apiVersion": 2, + "$schema": "https://schemas.wp.org/trunk/block.json" +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx new file mode 100644 index 00000000000..8e351524045 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -0,0 +1,59 @@ +/** + * External dependencies + */ +import type { HTMLAttributes } from 'react'; +import classnames from 'classnames'; +import { useStyleProps } from '@woocommerce/base-hooks'; +import { useInnerBlockLayoutContext } from '@woocommerce/shared-context'; +import ProductPrice from '@woocommerce/base-components/product-price'; + +/** + * Internal dependencies + */ +import type { PriceProps } from '../../types'; + +type Props = PriceProps & HTMLAttributes< HTMLDivElement >; + +const Block = ( { + attributes, + context, + rawPrice, + currency, +}: Props ): JSX.Element | null => { + const { className } = attributes; + const { isDescendentOfSingleProductTemplate = false } = context || {}; + const { className: stylesClassName, style } = useStyleProps( attributes ); + const { parentClassName } = useInnerBlockLayoutContext(); + const wrapperClassName = classnames( + 'wc-block-product-price__original', + className, + { + [ `${ parentClassName }__product-price` ]: parentClassName, + }, + stylesClassName + ); + if ( ! rawPrice && ! isDescendentOfSingleProductTemplate ) { + return ; + } + + const pricePreview = '5000'; + const priceClassName = classnames( { + [ `${ parentClassName }__product-original-price__value` ]: + parentClassName, + } ); + + return ( + + ); +}; + +export default Block; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx new file mode 100644 index 00000000000..91410316078 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx @@ -0,0 +1,47 @@ +/** + * External dependencies + */ +import { useBlockProps } from '@wordpress/block-editor'; +import type { HTMLAttributes, CSSProperties } from 'react'; +import { useProductDataContext } from '@woocommerce/shared-context'; +import { getCurrencyFromPriceResponse } from '@woocommerce/price-format'; + +/** + * Internal dependencies + */ +import PriceBlock from './block'; + +interface Attributes { + style: CSSProperties; +} + +type Props = { + attributes: Attributes; + context?: { isDescendentOfSingleProductTemplate: boolean }; +} & HTMLAttributes< HTMLDivElement >; + +const CurrentPriceEdit = ( { attributes, context }: Props ): JSX.Element => { + const blockProps = useBlockProps(); + const { product } = useProductDataContext(); + const { isDescendentOfSingleProductTemplate = false } = context || {}; + const currentPrice = product?.prices?.price; + const currency = isDescendentOfSingleProductTemplate + ? getCurrencyFromPriceResponse() + : getCurrencyFromPriceResponse( product?.prices ); + const blockAttrs = { + attributes, + currency, + context, + rawPrice: currentPrice, + priceType: 'current', + }; + return ( + <> +
+ +
+ + ); +}; + +export default CurrentPriceEdit; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts new file mode 100644 index 00000000000..5cbea61364e --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts @@ -0,0 +1,27 @@ +/** + * External dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import edit from './edit'; +import sharedConfig from '../../../shared/config'; +import metadata from './block.json'; + +const { ancestor, ...configuration } = sharedConfig; + +const blockConfig = { + ...configuration, + ...metadata, + edit, + supports: { + ...configuration.supports, + context: '', + }, +}; + +registerBlockType( metadata.name, blockConfig ); + +export const BLOCK_NAME = metadata.name; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx new file mode 100644 index 00000000000..e69de29bb2d diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts new file mode 100644 index 00000000000..8eafc0e9f9f --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts @@ -0,0 +1,8 @@ +/** + * Internal dependencies + */ +import './original-price/index.ts'; +import './current-price/index.ts'; + +export { BLOCK_NAME as originalPriceName } from './original-price/index'; +export { BLOCK_NAME as currentPriceName } from './current-price/index'; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json new file mode 100644 index 00000000000..97db17d5bd2 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json @@ -0,0 +1,12 @@ +{ + "name": "woocommerce/original-price", + "version": "1.0.0", + "icon": "info", + "title": "Original Price", + "description": "Display the original price for the product", + "category": "woocommerce", + "keywords": [ "WooCommerce" ], + "textdomain": "woo-gutenberg-products-block", + "apiVersion": 2, + "$schema": "https://schemas.wp.org/trunk/block.json" +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx new file mode 100644 index 00000000000..9104479f1c6 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx @@ -0,0 +1,60 @@ +/** + * External dependencies + */ +import type { HTMLAttributes } from 'react'; +import classnames from 'classnames'; +import { useStyleProps } from '@woocommerce/base-hooks'; +import { useInnerBlockLayoutContext } from '@woocommerce/shared-context'; +import ProductPrice from '@woocommerce/base-components/product-price'; + +/** + * Internal dependencies + */ +import type { PriceProps } from '../../types'; + +type Props = PriceProps & HTMLAttributes< HTMLDivElement >; + +const Block = ( { + attributes, + context, + rawPrice, + priceType, + currency, +}: Props ): JSX.Element | null => { + const { className } = attributes; + const { isDescendentOfSingleProductTemplate = false } = context || {}; + const { className: stylesClassName, style } = useStyleProps( attributes ); + const { parentClassName } = useInnerBlockLayoutContext(); + const wrapperClassName = classnames( + 'wc-block-product-price__original', + className, + { + [ `${ parentClassName }__product-price` ]: parentClassName, + }, + stylesClassName + ); + if ( ! rawPrice && ! isDescendentOfSingleProductTemplate ) { + return ; + } + + const pricePreview = '5000'; + const priceClassName = classnames( { + [ `${ parentClassName }__product-${ priceType }-price__value` ]: + parentClassName, + } ); + + return ( + + ); +}; + +export default Block; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx new file mode 100644 index 00000000000..c19e38047a3 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx @@ -0,0 +1,51 @@ +/** + * External dependencies + */ +import { useBlockProps } from '@wordpress/block-editor'; +import type { HTMLAttributes, CSSProperties } from 'react'; +import { useProductDataContext } from '@woocommerce/shared-context'; +import { getCurrencyFromPriceResponse } from '@woocommerce/price-format'; + +/** + * Internal dependencies + */ +import PriceBlock from './block'; + +interface Attributes { + style: CSSProperties; +} + +type Props = { + attributes: Attributes; + context?: { isDescendentOfSingleProductTemplate: boolean }; +} & HTMLAttributes< HTMLDivElement >; + +const OriginalPriceEdit = ( { attributes, context }: Props ): JSX.Element => { + const blockProps = useBlockProps(); + const { product } = useProductDataContext(); + const { isDescendentOfSingleProductTemplate = false } = context || {}; + const originalPrice = product?.prices?.regular_price; + const currentPrice = product?.prices?.price; + const showPrice = originalPrice && currentPrice !== originalPrice; + const currency = isDescendentOfSingleProductTemplate + ? getCurrencyFromPriceResponse() + : getCurrencyFromPriceResponse( product?.prices ); + const blockAttrs = { + attributes, + currency, + context, + rawPrice: originalPrice, + priceType: 'original', + }; + return ( + <> + { showPrice && ( +
+ +
+ ) } + + ); +}; + +export default OriginalPriceEdit; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts new file mode 100644 index 00000000000..5cbea61364e --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts @@ -0,0 +1,27 @@ +/** + * External dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import edit from './edit'; +import sharedConfig from '../../../shared/config'; +import metadata from './block.json'; + +const { ancestor, ...configuration } = sharedConfig; + +const blockConfig = { + ...configuration, + ...metadata, + edit, + supports: { + ...configuration.supports, + context: '', + }, +}; + +registerBlockType( metadata.name, blockConfig ); + +export const BLOCK_NAME = metadata.name; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/save.tsx b/assets/js/atomic/blocks/product-elements/price-v2/save.tsx new file mode 100644 index 00000000000..5494846b102 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/save.tsx @@ -0,0 +1,17 @@ +/** + * External dependencies + */ +import classnames from 'classnames'; + +export const save = ( { attributes } ) => { + if ( + attributes.isDescendentOfSingleProductBlock || + attributes.isDescendentOfSingleProductTemplate + ) { + return null; + } + + return ( +
+ ); +}; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/style.scss b/assets/js/atomic/blocks/product-elements/price-v2/style.scss new file mode 100644 index 00000000000..b7b3279fbdd --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/style.scss @@ -0,0 +1,7 @@ +.wc-block-components-product-price { + display: block; + + .wc-block-all-products & { + margin-bottom: $gap-small; + } +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/supports.ts b/assets/js/atomic/blocks/product-elements/price-v2/supports.ts new file mode 100644 index 00000000000..3a1f18fd018 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/supports.ts @@ -0,0 +1,39 @@ +/** + * External dependencies + */ +import { isFeaturePluginBuild } from '@woocommerce/block-settings'; +import { __experimentalGetSpacingClassesAndStyles } from '@wordpress/block-editor'; + +/** + * Internal dependencies + */ +import sharedConfig from '../shared/config'; + +export const supports = { + ...sharedConfig.supports, + ...( isFeaturePluginBuild() && { + color: { + text: true, + background: true, + link: false, + __experimentalSkipSerialization: true, + }, + typography: { + fontSize: true, + lineHeight: true, + __experimentalFontFamily: true, + __experimentalFontWeight: true, + __experimentalFontStyle: true, + __experimentalSkipSerialization: true, + __experimentalLetterSpacing: true, + }, + __experimentalSelector: + '.wp-block-woocommerce-product-price .wc-block-components-product-price', + } ), + ...( typeof __experimentalGetSpacingClassesAndStyles === 'function' && { + spacing: { + margin: true, + padding: true, + }, + } ), +}; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/template.ts b/assets/js/atomic/blocks/product-elements/price-v2/template.ts new file mode 100644 index 00000000000..b7532ee22ba --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/template.ts @@ -0,0 +1,9 @@ +/** + * External dependencies + */ +import { InnerBlockTemplate } from '@wordpress/blocks'; + +export const TEMPLATE: InnerBlockTemplate[] = [ + [ 'woocommerce/original-price', {}, [] ], + [ 'woocommerce/current-price', {}, [] ], +]; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/types.ts b/assets/js/atomic/blocks/product-elements/price-v2/types.ts new file mode 100644 index 00000000000..941bcac660b --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/types.ts @@ -0,0 +1,30 @@ +/** + * External dependencies + */ +import type { CSSProperties } from 'react'; +import type { ProductPriceProps } from '@woocommerce/base-components/product-price'; + +// old code +export interface BlockAttributes { + productId?: number; + className?: string; + textAlign?: 'left' | 'center' | 'right'; + isDescendentOfQueryLoop?: boolean; + isDescendentOfSingleProductTemplate?: boolean; +} + +export interface PriceContext { + isDescendentOfSingleProductTemplate: boolean; +} + +export interface PriceAttributes { + className?: string; + style: CSSProperties; +} + +export interface PriceProps extends ProductPriceProps { + attributes: PriceAttributes; + context?: PriceContext; + rawPrice?: string; + priceType: 'original' | 'current'; +} diff --git a/assets/js/atomic/blocks/product-elements/price/constants.tsx b/assets/js/atomic/blocks/product-elements/price/constants.tsx index 79f6f6989ed..544becb88aa 100644 --- a/assets/js/atomic/blocks/product-elements/price/constants.tsx +++ b/assets/js/atomic/blocks/product-elements/price/constants.tsx @@ -5,7 +5,7 @@ import { __ } from '@wordpress/i18n'; import { currencyDollar, Icon } from '@wordpress/icons'; export const BLOCK_TITLE: string = __( - 'Price', + 'Product Price', 'woo-gutenberg-products-block' ); export const BLOCK_ICON: JSX.Element = ( @@ -15,6 +15,6 @@ export const BLOCK_ICON: JSX.Element = ( /> ); export const BLOCK_DESCRIPTION: string = __( - 'Display the price of a product, including any discounts.', + 'Display the price of a product.', 'woo-gutenberg-products-block' ); From a43d5aa3ce81cb9bc82d67ffc8ede5e134ee19f7 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Tue, 23 May 2023 11:40:03 -0400 Subject: [PATCH 06/32] Change default template to use the core/group block with a row layout. --- .../blocks/product-elements/price-v2/edit.tsx | 6 +++++- .../blocks/product-elements/price-v2/index.ts | 2 +- .../blocks/product-elements/price-v2/save.tsx | 17 ++++------------- .../blocks/product-elements/price-v2/style.scss | 7 ------- .../product-elements/price-v2/template.ts | 10 ++++++++-- 5 files changed, 18 insertions(+), 24 deletions(-) delete mode 100644 assets/js/atomic/blocks/product-elements/price-v2/style.scss diff --git a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx index 3f5b457bd15..4ff44da8d7b 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx @@ -122,7 +122,11 @@ const EditBlock = ( { >
diff --git a/assets/js/atomic/blocks/product-elements/price-v2/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/index.ts index d7d185c9c6f..00379c64d4c 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/index.ts @@ -8,7 +8,7 @@ import { registerBlockType } from '@wordpress/blocks'; */ import sharedConfig from '../shared/config'; import edit from './edit'; -import { save } from './save'; +import save from './save'; import attributes from './attributes'; import { supports } from './supports'; import { diff --git a/assets/js/atomic/blocks/product-elements/price-v2/save.tsx b/assets/js/atomic/blocks/product-elements/price-v2/save.tsx index 5494846b102..87b0ec215fb 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/save.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/save.tsx @@ -1,17 +1,8 @@ /** * External dependencies */ -import classnames from 'classnames'; +import { useInnerBlocksProps, useBlockProps } from '@wordpress/block-editor'; -export const save = ( { attributes } ) => { - if ( - attributes.isDescendentOfSingleProductBlock || - attributes.isDescendentOfSingleProductTemplate - ) { - return null; - } - - return ( -
- ); -}; +export default function save() { + return
; +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/style.scss b/assets/js/atomic/blocks/product-elements/price-v2/style.scss deleted file mode 100644 index b7b3279fbdd..00000000000 --- a/assets/js/atomic/blocks/product-elements/price-v2/style.scss +++ /dev/null @@ -1,7 +0,0 @@ -.wc-block-components-product-price { - display: block; - - .wc-block-all-products & { - margin-bottom: $gap-small; - } -} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/template.ts b/assets/js/atomic/blocks/product-elements/price-v2/template.ts index b7532ee22ba..8369e49c765 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/template.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/template.ts @@ -4,6 +4,12 @@ import { InnerBlockTemplate } from '@wordpress/blocks'; export const TEMPLATE: InnerBlockTemplate[] = [ - [ 'woocommerce/original-price', {}, [] ], - [ 'woocommerce/current-price', {}, [] ], + [ + 'core/group', + { layout: { type: 'flex', flexWrap: 'nowrap' } }, + [ + [ 'woocommerce/original-price', {}, [] ], + [ 'woocommerce/current-price', {}, [] ], + ], + ], ]; From 0e7ab4e174692eac152728f6a00b93d08c4578e0 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 29 May 2023 09:59:55 -0400 Subject: [PATCH 07/32] Revert using core/group block as inner block for prices --- .../atomic/blocks/product-elements/price-v2/edit.tsx | 6 +----- .../blocks/product-elements/price-v2/template.ts | 10 ++-------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx index 4ff44da8d7b..3f5b457bd15 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx @@ -122,11 +122,7 @@ const EditBlock = ( { >
diff --git a/assets/js/atomic/blocks/product-elements/price-v2/template.ts b/assets/js/atomic/blocks/product-elements/price-v2/template.ts index 8369e49c765..b7532ee22ba 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/template.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/template.ts @@ -4,12 +4,6 @@ import { InnerBlockTemplate } from '@wordpress/blocks'; export const TEMPLATE: InnerBlockTemplate[] = [ - [ - 'core/group', - { layout: { type: 'flex', flexWrap: 'nowrap' } }, - [ - [ 'woocommerce/original-price', {}, [] ], - [ 'woocommerce/current-price', {}, [] ], - ], - ], + [ 'woocommerce/original-price', {}, [] ], + [ 'woocommerce/current-price', {}, [] ], ]; From 051e083b1ad2a434d6c4ef9506f65d79870078ae Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 29 May 2023 10:41:44 -0400 Subject: [PATCH 08/32] move Block defs to block.json. This also adds a bunch of layout controls to the top-level price block. --- .../product-elements/price-v2/attributes.ts | 21 ---------- .../product-elements/price-v2/block.json | 40 +++++++++++++++++++ .../product-elements/price-v2/constants.tsx | 9 ----- .../blocks/product-elements/price-v2/index.ts | 28 +++---------- 4 files changed, 45 insertions(+), 53 deletions(-) delete mode 100644 assets/js/atomic/blocks/product-elements/price-v2/attributes.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/block.json diff --git a/assets/js/atomic/blocks/product-elements/price-v2/attributes.ts b/assets/js/atomic/blocks/product-elements/price-v2/attributes.ts deleted file mode 100644 index db985052251..00000000000 --- a/assets/js/atomic/blocks/product-elements/price-v2/attributes.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * External dependencies - */ -import { BlockAttributes } from '@wordpress/blocks'; - -export const blockAttributes: BlockAttributes = { - isDescendentOfSingleProductTemplate: { - type: 'boolean', - default: false, - }, - isDescendentOfSingleProductBlock: { - type: 'boolean', - default: false, - }, - productId: { - type: 'number', - default: 0, - }, -}; - -export default blockAttributes; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/block.json b/assets/js/atomic/blocks/product-elements/price-v2/block.json new file mode 100644 index 00000000000..684ad49ec90 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/block.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://schemas.wp.org/trunk/block.json", + "apiVersion": 2, + "name": "woocommerce/product-price-v2", + "title": "Price", + "keywords": "WooCommerce", + "category": "woocommerce-product-elements", + "textdomain": "woo-gutenberg-products-block", + "description": "Display the price of a product, including any discounts.", + "supports": { + "__experimentalLayout": { + "allowSwitching": false, + "allowInheriting": false, + "default": { "type": "flex" } + }, + "html": false + + }, + "usesContext": [ "queryId", "postId" ], + "providesContext": { + "woocommerce/isDescendentOfSingleProductTemplate": + "isDescendentOfSingleProductTemplate", + "woocommerce/isDescendentOfSingleProductBlock": + "woocommerce/isDescendentOfSingleProductBlock" + }, + "attributes": { + "isDescendentOfSingleProductTemplate": { + "type": "boolean", + "default": false + }, + "isDescendentOfSingleProductBlock": { + "type": "boolean", + "default": false + }, + "productId": { + "type": "number", + "default": 0 + } + } + } diff --git a/assets/js/atomic/blocks/product-elements/price-v2/constants.tsx b/assets/js/atomic/blocks/product-elements/price-v2/constants.tsx index 79f6f6989ed..a8a5261b1fe 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/constants.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/constants.tsx @@ -1,20 +1,11 @@ /** * External dependencies */ -import { __ } from '@wordpress/i18n'; import { currencyDollar, Icon } from '@wordpress/icons'; -export const BLOCK_TITLE: string = __( - 'Price', - 'woo-gutenberg-products-block' -); export const BLOCK_ICON: JSX.Element = ( ); -export const BLOCK_DESCRIPTION: string = __( - 'Display the price of a product, including any discounts.', - 'woo-gutenberg-products-block' -); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/index.ts index 00379c64d4c..5e38960ce4c 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/index.ts @@ -6,36 +6,18 @@ import { registerBlockType } from '@wordpress/blocks'; /** * Internal dependencies */ -import sharedConfig from '../shared/config'; import edit from './edit'; import save from './save'; -import attributes from './attributes'; import { supports } from './supports'; -import { - BLOCK_TITLE as title, - BLOCK_ICON as icon, - BLOCK_DESCRIPTION as description, -} from './constants'; - -const { ancestor, ...configuration } = sharedConfig; +import metadata from './block.json'; +import { BLOCK_ICON as icon } from './constants'; const blockConfig = { - ...configuration, - apiVersion: 2, - title, - description, - usesContext: [ 'postId', 'queryId' ], - providesContext: { - 'woocommerce/isDescendentOfSingleProductTemplate': - 'isDescendentOfSingleProductTemplate', - 'woocommerce/isDescendentOfSingleProductBlock': - 'isDescendentOfSingleProductBlock', - }, + ...metadata, icon: { src: icon }, - attributes, - supports, + supports: { ...supports, ...metadata.supports }, edit, save, }; -registerBlockType( 'woocommerce/product-price-v2', blockConfig ); +registerBlockType( metadata.name, blockConfig ); From b1ddfe6e4458fb3a19ee3378800e53b5b56e1a00 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 29 May 2023 15:38:00 -0400 Subject: [PATCH 09/32] remove unused file --- .../price-v2/components/product-price.tsx | 58 ------------------- 1 file changed, 58 deletions(-) delete mode 100644 assets/js/atomic/blocks/product-elements/price-v2/components/product-price.tsx diff --git a/assets/js/atomic/blocks/product-elements/price-v2/components/product-price.tsx b/assets/js/atomic/blocks/product-elements/price-v2/components/product-price.tsx deleted file mode 100644 index 06169c0eaae..00000000000 --- a/assets/js/atomic/blocks/product-elements/price-v2/components/product-price.tsx +++ /dev/null @@ -1,58 +0,0 @@ -/** - * External dependencies - */ -import type { Currency } from '@woocommerce/types'; -import type { CSSProperties } from 'react'; - -export interface ProductPriceProps { - /** - * CSS class for the wrapper - */ - wrapperClassName?: string | undefined; - /** - * Currency configuration object - */ - currency?: Currency; - /** - * The string version of the element to use for the price interpolation - * - * **Note:** It should contain `` (which is also the default value) - */ - format?: string; - /** - * The maximum price in a range - */ - maxPrice?: string | number; - /** - * The minimum price in a range - */ - minPrice?: string | number; - /** - * The current price - */ - price?: string | number; - /** - * CSS class for the price - */ - priceClassName?: string; - /** - * Custom style for the price - */ - priceStyle?: CSSProperties; - /** - * Custom style for the wrapper - */ - style?: CSSProperties; -} - -export const ProductPrice = ( { - className, - currency, - format = '', - maxPrice, - minPrice, - price, - priceClassName, - priceStyle, - style, -} ) => {}; From 726567fbac52c40cdf69463273786b26eba5f090 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 29 May 2023 15:39:03 -0400 Subject: [PATCH 10/32] add support for superscript style on price values --- .../product-elements/price-v2/block.json | 6 ++- .../inner-blocks/current-price/block.tsx | 1 + .../formatted-monetary-amount/index.tsx | 43 +++++++++++++++---- .../base/components/product-price/index.tsx | 22 ++++++++-- 4 files changed, 59 insertions(+), 13 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/block.json b/assets/js/atomic/blocks/product-elements/price-v2/block.json index 684ad49ec90..09ec7d931e7 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/block.json @@ -36,5 +36,9 @@ "type": "number", "default": 0 } - } + }, + "styles": [ + { "name": "default", "label": "Default", "isDefault": true }, + { "name": "price-super", "label": "Superscript", "isDefault": false } + ] } diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx index 8e351524045..1404200814f 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -49,6 +49,7 @@ const Block = ( { priceStyle={ style } priceClassName={ priceClassName } currency={ currency } + withSuperScript={ true } price={ isDescendentOfSingleProductTemplate ? pricePreview : rawPrice } diff --git a/assets/js/base/components/formatted-monetary-amount/index.tsx b/assets/js/base/components/formatted-monetary-amount/index.tsx index f4a5e97157a..21426b94845 100644 --- a/assets/js/base/components/formatted-monetary-amount/index.tsx +++ b/assets/js/base/components/formatted-monetary-amount/index.tsx @@ -18,16 +18,37 @@ import './style.scss'; interface FormattedMonetaryAmountProps extends Omit< NumberFormatProps, 'onValueChange' > { className?: string; - displayType?: NumberFormatProps[ 'displayType' ]; allowNegative?: boolean; isAllowed?: ( formattedValue: NumberFormatValues ) => boolean; value: number | string; // Value of money amount. currency: Currency | Record< string, never >; // Currency configuration object. onValueChange?: ( unit: number ) => void; // Function to call when value changes. style?: React.CSSProperties | undefined; - renderText?: ( value: string ) => JSX.Element; + renderText?: ( value: string ) => ReactElement | string; + withSuperScript?: boolean; } +const applySuperscript = + ( currency: FormattedMonetaryAmountProps[ 'currency' ] ) => + ( formattedValue: string ): ReactElement | string => { + if ( ! currency.decimalSeparator ) { + return formattedValue; + } + const pattern = new RegExp( + `^(.*)([${ currency.decimalSeparator }])(([^${ currency.decimalSeparator }]*))$` + ); + const matches = formattedValue.match( pattern ); + if ( ! matches ) { + return formattedValue; + } + return ( + <> + <>{ matches[ 1 ] } + { matches[ 3 ] } + + ); + }; + /** * Formats currency data into the expected format for NumberFormat. */ @@ -44,12 +65,7 @@ const currencyToNumberFormat = ( }; }; -type CustomFormattedMonetaryAmountProps = Omit< - FormattedMonetaryAmountProps, - 'currency' -> & { - currency: Currency | Record< string, never >; -}; +const defaultRenderText = ( formattedAmount: string ) => formattedAmount; /** * FormattedMonetaryAmount component. @@ -62,8 +78,10 @@ const FormattedMonetaryAmount = ( { currency, onValueChange, displayType = 'text', + withSuperScript = false, + renderText, ...props -}: CustomFormattedMonetaryAmountProps ): ReactElement | null => { +}: FormattedMonetaryAmountProps ): JSX.Element | null => { const value = typeof rawValue === 'string' ? parseInt( rawValue, 10 ) : rawValue; @@ -100,6 +118,12 @@ const FormattedMonetaryAmount = ( { } : () => void 0; + if ( ! renderText ) { + renderText = withSuperScript + ? applySuperscript( currency ) + : defaultRenderText; + } + return ( ); }; diff --git a/assets/js/base/components/product-price/index.tsx b/assets/js/base/components/product-price/index.tsx index 10fa139b3b7..9120fc98b18 100644 --- a/assets/js/base/components/product-price/index.tsx +++ b/assets/js/base/components/product-price/index.tsx @@ -17,7 +17,7 @@ interface PriceRangeProps { /** * Currency configuration object */ - currency: Currency | Record< string, never > | undefined; + currency: Currency | Record< string, never >; /** * The maximum price for the range */ @@ -38,6 +38,11 @@ interface PriceRangeProps { * **Note:** this excludes the dash in between the elements */ priceStyle?: React.CSSProperties | undefined; + /** + * If true, the decimal separator will be excluded and the amount after it + * will be wrapped in a superscript element. + */ + withSuperScript: boolean | undefined; } const PriceRange = ( { @@ -46,6 +51,7 @@ const PriceRange = ( { minPrice, priceClassName, priceStyle = {}, + withSuperScript = false, }: PriceRangeProps ) => { return ( <> @@ -69,6 +75,7 @@ const PriceRange = ( { currency={ currency } value={ minPrice } style={ priceStyle } + withSuperScript={ withSuperScript } />  —  @@ -89,7 +97,7 @@ interface SalePriceProps { /** * Currency configuration object */ - currency: Currency | Record< string, never > | undefined; + currency: Currency | Record< string, never >; /** * CSS class to be applied to the regular price container * @@ -121,7 +129,7 @@ interface SalePriceProps { /** * The new price during the sale */ - price: number | string | undefined; + price: number | string; } const SalePrice = ( { @@ -248,6 +256,11 @@ export interface ProductPriceProps { 'marginTop' | 'marginRight' | 'marginBottom' | 'marginLeft' > | undefined; + /** + * If true, the decimal separator will be excluded and the amount after it + * will be wrapped in a superscript element. + */ + withSuperScript: boolean | undefined; } const ProductPrice = ( { @@ -264,6 +277,7 @@ const ProductPrice = ( { regularPriceClassName, regularPriceStyle, style, + withSuperScript = false, }: ProductPriceProps ): JSX.Element => { const wrapperClassName = classNames( className, @@ -310,6 +324,7 @@ const ProductPrice = ( { minPrice={ minPrice } priceClassName={ priceClassName } priceStyle={ priceStyle } + withSuperScript={ withSuperScript } /> ); } else if ( price ) { @@ -322,6 +337,7 @@ const ProductPrice = ( { currency={ currency } value={ price } style={ priceStyle } + withSuperScript={ withSuperScript } /> ); } From ac25bb478363e69aed897a4280be32e83b3fb1fc Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 29 May 2023 15:52:52 -0400 Subject: [PATCH 11/32] Add todo about the use of __experimentalDefaultControls --- .../js/atomic/blocks/product-elements/price-v2/supports.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/supports.ts b/assets/js/atomic/blocks/product-elements/price-v2/supports.ts index 3a1f18fd018..85b2e5f254e 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/supports.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/supports.ts @@ -9,6 +9,11 @@ import { __experimentalGetSpacingClassesAndStyles } from '@wordpress/block-edito */ import sharedConfig from '../shared/config'; +/** + * todo: can use __experimentalDefaultControls to influence which controls are + * displayed by default + */ + export const supports = { ...sharedConfig.supports, ...( isFeaturePluginBuild() && { From 6fcb2a35398952b89e7b8fce54a2b95350dd8aff Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 5 Jun 2023 15:21:34 -0400 Subject: [PATCH 12/32] A bunch of styles support - switch to use spans instead of tag. - always render separator (but hide from visuals) - proper support for style (typography, colors etc). --- .../product-elements/price-v2/block.json | 7 +++- .../blocks/product-elements/price-v2/edit.tsx | 40 ++++++++++++++++--- .../inner-blocks/current-price/block.json | 1 + .../inner-blocks/current-price/block.tsx | 5 +-- .../inner-blocks/original-price/block.json | 1 + .../inner-blocks/original-price/block.tsx | 2 +- .../formatted-monetary-amount/index.tsx | 7 +++- .../formatted-monetary-amount/style.scss | 9 +++++ 8 files changed, 60 insertions(+), 12 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/block.json b/assets/js/atomic/blocks/product-elements/price-v2/block.json index 09ec7d931e7..0653c0a4bd7 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/block.json @@ -21,7 +21,8 @@ "woocommerce/isDescendentOfSingleProductTemplate": "isDescendentOfSingleProductTemplate", "woocommerce/isDescendentOfSingleProductBlock": - "woocommerce/isDescendentOfSingleProductBlock" + "isDescendentOfSingleProductBlock", + "woocommerce/withSuperScriptStyle": "withSuperScriptStyle" }, "attributes": { "isDescendentOfSingleProductTemplate": { @@ -35,6 +36,10 @@ "productId": { "type": "number", "default": 0 + }, + "withSuperScriptStyle": { + "type": "boolean", + "default": false } }, "styles": [ diff --git a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx index 3f5b457bd15..0de6c441679 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx @@ -2,7 +2,7 @@ * External dependencies */ import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'; -import { useEffect } from '@wordpress/element'; +import { useEffect, useMemo } from '@wordpress/element'; import { useSelect } from '@wordpress/data'; import { InnerBlockLayoutContextProvider, @@ -10,6 +10,7 @@ import { ProductDataContextProvider, } from '@woocommerce/shared-context'; import { useStoreProducts } from '@woocommerce/base-context/hooks'; +import { useStyleProps } from '@woocommerce/base-hooks'; /** * Internal dependencies @@ -20,6 +21,7 @@ import { TEMPLATE } from './template'; interface Attributes { isDescendentOfSingleProductBlock: boolean; isDescendentOfSingleProductTemplate: boolean; + withSuperScriptStyle: boolean; productId?: number; } @@ -40,6 +42,14 @@ interface ContextProviderProps extends Props { type ProductIdProps = Partial< ContextProviderProps > & { productId: number }; +const deriveSuperScriptFromClass = ( className: string ): boolean => { + if ( className ) { + const classList = className.split( ' ' ); + return classList.includes( 'is-style-price-super' ); + } + return false; +}; + const ProviderFromAPI = ( { productId, children, @@ -71,7 +81,7 @@ const DerivedProductDataContextProvider = ( { attributes, setAttributes, children, -}: ContextProviderProps ): JSX.Element => { +}: ContextProviderProps & { withSuperScript: boolean } ): JSX.Element => { const { queryId, postId } = context; const { productId } = attributes; const isDescendentOfQueryLoop = Number.isFinite( queryId ); @@ -112,13 +122,15 @@ const EditBlock = ( { context, attributes, setAttributes, -}: Props ): JSX.Element => { + withSuperScript, +}: Props & { withSuperScript: boolean } ): JSX.Element => { const { parentClassName } = useInnerBlockLayoutContext(); return (
{ - const blockProps = useBlockProps(); +const Edit = ( { + setAttributes, + attributes, + ...props +}: Props ): JSX.Element => { + const { style, className } = useStyleProps( attributes ); + const blockProps = useBlockProps( { style, className } ); + const withSuperScript = useMemo( + () => deriveSuperScriptFromClass( blockProps.className ), + [ blockProps.className ] + ); + useEffect( () => { + setAttributes( { withSuperScriptStyle: withSuperScript } ); + }, [ withSuperScript, setAttributes ] ); return (
- +
); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json index e97826d3822..f85de2bfc6d 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json @@ -6,6 +6,7 @@ "description": "Display the current price for the product", "category": "woocommerce", "keywords": [ "WooCommerce" ], + "usesContext": ["woocommerce/withSuperScriptStyle"], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx index 1404200814f..de5f2d1b9d1 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -25,7 +25,6 @@ const Block = ( { const { className: stylesClassName, style } = useStyleProps( attributes ); const { parentClassName } = useInnerBlockLayoutContext(); const wrapperClassName = classnames( - 'wc-block-product-price__original', className, { [ `${ parentClassName }__product-price` ]: parentClassName, @@ -38,7 +37,7 @@ const Block = ( { const pricePreview = '5000'; const priceClassName = classnames( { - [ `${ parentClassName }__product-original-price__value` ]: + [ `${ parentClassName }__product-current-price__value` ]: parentClassName, } ); @@ -49,7 +48,7 @@ const Block = ( { priceStyle={ style } priceClassName={ priceClassName } currency={ currency } - withSuperScript={ true } + withSuperScript={ context[ 'woocommerce/withSuperScriptStyle' ] } price={ isDescendentOfSingleProductTemplate ? pricePreview : rawPrice } diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json index 97db17d5bd2..9257c638974 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json @@ -6,6 +6,7 @@ "description": "Display the original price for the product", "category": "woocommerce", "keywords": [ "WooCommerce" ], + "usesContext": ["woocommerce/withSuperScriptStyle"], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx index 9104479f1c6..9c621b48681 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx @@ -26,7 +26,6 @@ const Block = ( { const { className: stylesClassName, style } = useStyleProps( attributes ); const { parentClassName } = useInnerBlockLayoutContext(); const wrapperClassName = classnames( - 'wc-block-product-price__original', className, { [ `${ parentClassName }__product-price` ]: parentClassName, @@ -50,6 +49,7 @@ const Block = ( { priceStyle={ style } priceClassName={ priceClassName } currency={ currency } + withSuperScript={ context[ 'woocommerce/withSuperScriptStyle' ] } price={ isDescendentOfSingleProductTemplate ? pricePreview : rawPrice } diff --git a/assets/js/base/components/formatted-monetary-amount/index.tsx b/assets/js/base/components/formatted-monetary-amount/index.tsx index 21426b94845..956b74f9950 100644 --- a/assets/js/base/components/formatted-monetary-amount/index.tsx +++ b/assets/js/base/components/formatted-monetary-amount/index.tsx @@ -44,7 +44,12 @@ const applySuperscript = return ( <> <>{ matches[ 1 ] } - { matches[ 3 ] } + + + ${ currency.decimalSeparator } + + { matches[ 3 ] } + ); }; diff --git a/assets/js/base/components/formatted-monetary-amount/style.scss b/assets/js/base/components/formatted-monetary-amount/style.scss index c8f02bd1bee..a7821118ea5 100644 --- a/assets/js/base/components/formatted-monetary-amount/style.scss +++ b/assets/js/base/components/formatted-monetary-amount/style.scss @@ -1,3 +1,12 @@ .wc-block-components-formatted-money-amount { white-space: nowrap; } + +.formatted-money-amount-superscript { + vertical-align: super; + font-size: .5em; +} + +.formatted-money-amount-separator { + @include visually-hidden(); +} From 13cdf51c424a78bb96e2927ed8635850d5619e55 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Fri, 9 Jun 2023 14:09:34 -0400 Subject: [PATCH 13/32] add support for blockGap --- assets/js/atomic/blocks/product-elements/price-v2/supports.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/supports.ts b/assets/js/atomic/blocks/product-elements/price-v2/supports.ts index 85b2e5f254e..3e8b0740f2c 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/supports.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/supports.ts @@ -39,6 +39,7 @@ export const supports = { spacing: { margin: true, padding: true, + blockGap: true, }, } ), }; From 6411934902246cefc7f0443063ca9913a3399d1e Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 12 Jun 2023 16:39:04 -0400 Subject: [PATCH 14/32] add discount block --- .../blocks/product-elements/price-v2/edit.tsx | 12 ++- .../price-v2/inner-blocks/discount/block.json | 12 +++ .../price-v2/inner-blocks/discount/block.tsx | 85 +++++++++++++++++++ .../price-v2/inner-blocks/discount/edit.tsx | 51 +++++++++++ .../price-v2/inner-blocks/discount/index.ts | 27 ++++++ .../price-v2/inner-blocks/index.ts | 2 + .../product-elements/price-v2/template.ts | 1 + .../blocks/product-elements/price-v2/types.ts | 4 + 8 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts diff --git a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx index 0de6c441679..582e54e3d59 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx @@ -15,7 +15,11 @@ import { useStyleProps } from '@woocommerce/base-hooks'; /** * Internal dependencies */ -import { originalPriceName, currentPriceName } from './inner-blocks'; +import { + originalPriceName, + currentPriceName, + priceDiscount, +} from './inner-blocks'; import { TEMPLATE } from './template'; interface Attributes { @@ -134,7 +138,11 @@ const EditBlock = ( { >
diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json new file mode 100644 index 00000000000..dedfd2d970c --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json @@ -0,0 +1,12 @@ +{ + "name": "woocommerce/discount", + "version": "1.0.0", + "icon": "info", + "title": "Discount", + "description": "Display the discounted amount for a product.", + "category": "woocommerce", + "keywords": [ "WooCommerce" ], + "textdomain": "woo-gutenberg-products-block", + "apiVersion": 2, + "$schema": "https://schemas.wp.org/trunk/block.json" +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.tsx new file mode 100644 index 00000000000..42c39b9cb95 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.tsx @@ -0,0 +1,85 @@ +/** + * External dependencies + */ +import type { HTMLAttributes } from 'react'; +import classnames from 'classnames'; +import { useStyleProps } from '@woocommerce/base-hooks'; +import { useInnerBlockLayoutContext } from '@woocommerce/shared-context'; +import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-monetary-amount'; + +/** + * Internal dependencies + */ +import type { PriceProps } from '../../types'; + +type Props = PriceProps & HTMLAttributes< HTMLDivElement >; + +const calculateDiscountAmount = ( originalPrice, currentPrice ) => { + // todo: this assumes currentPrice is lower than originalPrice + return parseInt( originalPrice, 10 ) - parseInt( currentPrice, 10 ); +}; + +const calculateDiscountPercentage = ( originalPrice, currentPrice ) => { + const discountAmount = calculateDiscountAmount( + originalPrice, + currentPrice + ); + return Math.floor( + ( discountAmount / parseInt( originalPrice, 10 ) ) * 100 + ); +}; + +const Block = ( { + attributes, + context, + originalPrice, + currentPrice, + currency, +}: Props ): JSX.Element | null => { + // todo: need to setup discountType and showDiscount as attributes/context + // from the parent block. + const { + className, + discountType = 'percentage', + showDiscount = true, + } = attributes; + const { isDescendentOfSingleProductTemplate = false } = context || {}; + const { className: stylesClassName, style } = useStyleProps( attributes ); + const { parentClassName } = useInnerBlockLayoutContext(); + if ( ! showDiscount ) { + return null; + } + const wrapperClassName = classnames( + className, + { + [ `${ parentClassName }__product-price` ]: parentClassName, + }, + stylesClassName + ); + const priceClassName = classnames( { + [ `${ parentClassName }__product-price_discount` ]: parentClassName, + } ); + // todo: lift all the preview pricing up to the parent block (across all the price inner blocks) + const oPrice = isDescendentOfSingleProductTemplate ? '3000' : originalPrice; + const cPrice = isDescendentOfSingleProductTemplate ? '5000' : currentPrice; + const DisplayedDiscount = + discountType === 'percentage' ? ( + + { calculateDiscountPercentage( oPrice, cPrice ) }% + + ) : ( + + ); + + return ( + + { DisplayedDiscount } + + ); +}; + +export default Block; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx index e69de29bb2d..4e1894030df 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx @@ -0,0 +1,51 @@ +/** + * External dependencies + */ +import { useBlockProps } from '@wordpress/block-editor'; +import type { HTMLAttributes, CSSProperties } from 'react'; +import { useProductDataContext } from '@woocommerce/shared-context'; +import { getCurrencyFromPriceResponse } from '@woocommerce/price-format'; + +/** + * Internal dependencies + */ +import DiscountBlock from './block'; + +interface Attributes { + style: CSSProperties; +} + +type Props = { + attributes: Attributes; + context?: { isDescendentOfSingleProductTemplate: boolean }; +} & HTMLAttributes< HTMLDivElement >; + +const DiscountEdit = ( { attributes, context }: Props ): JSX.Element => { + const blockProps = useBlockProps(); + const { product } = useProductDataContext(); + const { isDescendentOfSingleProductTemplate = false } = context || {}; + const originalPrice = product?.prices?.regular_price; + const currentPrice = product?.prices?.price; + const showPrice = originalPrice && currentPrice !== originalPrice; + const currency = isDescendentOfSingleProductTemplate + ? getCurrencyFromPriceResponse() + : getCurrencyFromPriceResponse( product?.prices ); + const blockAttrs = { + attributes, + currency, + context, + originalPrice, + currentPrice, + }; + return ( + <> + { showPrice && ( +
+ +
+ ) } + + ); +}; + +export default DiscountEdit; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts new file mode 100644 index 00000000000..5cbea61364e --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts @@ -0,0 +1,27 @@ +/** + * External dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import edit from './edit'; +import sharedConfig from '../../../shared/config'; +import metadata from './block.json'; + +const { ancestor, ...configuration } = sharedConfig; + +const blockConfig = { + ...configuration, + ...metadata, + edit, + supports: { + ...configuration.supports, + context: '', + }, +}; + +registerBlockType( metadata.name, blockConfig ); + +export const BLOCK_NAME = metadata.name; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts index 8eafc0e9f9f..39ebc0edafa 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts @@ -3,6 +3,8 @@ */ import './original-price/index.ts'; import './current-price/index.ts'; +import './discount/index.ts'; export { BLOCK_NAME as originalPriceName } from './original-price/index'; export { BLOCK_NAME as currentPriceName } from './current-price/index'; +export { BLOCK_NAME as priceDiscount } from './discount/index'; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/template.ts b/assets/js/atomic/blocks/product-elements/price-v2/template.ts index b7532ee22ba..ef992eb9ea5 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/template.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/template.ts @@ -6,4 +6,5 @@ import { InnerBlockTemplate } from '@wordpress/blocks'; export const TEMPLATE: InnerBlockTemplate[] = [ [ 'woocommerce/original-price', {}, [] ], [ 'woocommerce/current-price', {}, [] ], + [ 'woocommerce/discount', {}, [] ], ]; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/types.ts b/assets/js/atomic/blocks/product-elements/price-v2/types.ts index 941bcac660b..867a58145f0 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/types.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/types.ts @@ -15,6 +15,8 @@ export interface BlockAttributes { export interface PriceContext { isDescendentOfSingleProductTemplate: boolean; + // eslint-disable-next-line @typescript-eslint/naming-convention + 'woocommerce/withSuperScriptStyle'?: boolean; } export interface PriceAttributes { @@ -26,5 +28,7 @@ export interface PriceProps extends ProductPriceProps { attributes: PriceAttributes; context?: PriceContext; rawPrice?: string; + minPrice?: string; + maxPrice?: string; priceType: 'original' | 'current'; } From ad28e2c5953707825ab7c8510c6360699fa72111 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 12 Jun 2023 16:40:00 -0400 Subject: [PATCH 15/32] remove superfluous styles --- .../price-v2/inner-blocks/current-price/block.tsx | 1 - .../price-v2/inner-blocks/original-price/block.tsx | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx index de5f2d1b9d1..62e08ffa3a2 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -45,7 +45,6 @@ const Block = ( { ; } - const pricePreview = '5000'; + const pricePreview = '3000'; const priceClassName = classnames( { [ `${ parentClassName }__product-${ priceType }-price__value` ]: parentClassName, @@ -46,7 +46,6 @@ const Block = ( { Date: Mon, 12 Jun 2023 16:40:57 -0400 Subject: [PATCH 16/32] consider price ranges on current price --- .../price-v2/inner-blocks/current-price/block.tsx | 4 ++++ .../price-v2/inner-blocks/current-price/edit.tsx | 2 ++ 2 files changed, 6 insertions(+) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx index 62e08ffa3a2..876382039fa 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -18,6 +18,8 @@ const Block = ( { attributes, context, rawPrice, + minPrice, + maxPrice, currency, }: Props ): JSX.Element | null => { const { className } = attributes; @@ -51,6 +53,8 @@ const Block = ( { price={ isDescendentOfSingleProductTemplate ? pricePreview : rawPrice } + minPrice={ minPrice } + maxPrice={ maxPrice } /> ); }; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx index 91410316078..d72e93651ef 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx @@ -33,6 +33,8 @@ const CurrentPriceEdit = ( { attributes, context }: Props ): JSX.Element => { currency, context, rawPrice: currentPrice, + minPrice: product?.prices?.price_range?.min_amount, + maxPrice: product?.prices?.price_range?.max_amount, priceType: 'current', }; return ( From 89280456658a842abba32e1cc9f0aa763bd0de08 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 12 Jun 2023 16:41:27 -0400 Subject: [PATCH 17/32] Fix context usage Make sure to consider the context property might not be present --- .../price-v2/inner-blocks/current-price/block.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx index 876382039fa..682803316df 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -49,7 +49,7 @@ const Block = ( { style={ style } priceClassName={ priceClassName } currency={ currency } - withSuperScript={ context[ 'woocommerce/withSuperScriptStyle' ] } + withSuperScript={ context?.[ 'woocommerce/withSuperScriptStyle' ] } price={ isDescendentOfSingleProductTemplate ? pricePreview : rawPrice } From 3371590e10c7c84d82f9f3165923eba9c9c3cb5e Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 19 Jun 2023 18:23:12 -0400 Subject: [PATCH 18/32] fix missing usesContext values --- .../price-v2/inner-blocks/current-price/block.json | 2 +- .../price-v2/inner-blocks/original-price/block.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json index f85de2bfc6d..a44e2bad42b 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json @@ -6,7 +6,7 @@ "description": "Display the current price for the product", "category": "woocommerce", "keywords": [ "WooCommerce" ], - "usesContext": ["woocommerce/withSuperScriptStyle"], + "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendantOfSingleProductTemplate"], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json index 9257c638974..7b89cecb43e 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json @@ -6,7 +6,7 @@ "description": "Display the original price for the product", "category": "woocommerce", "keywords": [ "WooCommerce" ], - "usesContext": ["woocommerce/withSuperScriptStyle"], + "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendantOfSingleProductTemplate"], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" From 641193804361aed8368cc3d3b490de160ece5b14 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Mon, 19 Jun 2023 18:53:02 -0400 Subject: [PATCH 19/32] Implement discount as inner blocks This allows for being able to edit the text portion of the discount rendering as its own entity. --- .../price-v2/inner-blocks/discount/block.json | 9 +++ .../price-v2/inner-blocks/discount/edit.tsx | 56 +++++++++---------- .../price-v2/inner-blocks/discount/index.ts | 10 ++-- .../inner-blocks/discount-amount/block.json | 14 +++++ .../discount-amount}/block.tsx | 0 .../inner-blocks/discount-amount/edit.tsx | 51 +++++++++++++++++ .../inner-blocks/discount-amount/index.ts | 27 +++++++++ .../discount/inner-blocks/index.tsx | 6 ++ .../inner-blocks/discount/template.ts | 34 +++++++++++ 9 files changed, 174 insertions(+), 33 deletions(-) create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json rename assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/{ => inner-blocks/discount-amount}/block.tsx (100%) create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/index.ts create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/index.tsx create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/template.ts diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json index dedfd2d970c..480e13efa02 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json @@ -7,6 +7,15 @@ "category": "woocommerce", "keywords": [ "WooCommerce" ], "textdomain": "woo-gutenberg-products-block", + "supports": { + "__experimentalLayout": { + "allowSwitching": false, + "allowInheriting": false, + "default": { "type": "flex" } + }, + "html": false + + }, "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" } diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx index 4e1894030df..87fae2a6fc1 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx @@ -1,51 +1,49 @@ /** * External dependencies */ -import { useBlockProps } from '@wordpress/block-editor'; -import type { HTMLAttributes, CSSProperties } from 'react'; +import { useBlockProps, InnerBlocks } from '@wordpress/block-editor'; import { useProductDataContext } from '@woocommerce/shared-context'; -import { getCurrencyFromPriceResponse } from '@woocommerce/price-format'; +import { useStyleProps } from '@woocommerce/base-hooks'; +import { useEffect } from '@wordpress/element'; /** * Internal dependencies */ -import DiscountBlock from './block'; +import { discountAmountName } from './inner-blocks'; +import { TEMPLATE } from './template'; -interface Attributes { - style: CSSProperties; -} - -type Props = { - attributes: Attributes; - context?: { isDescendentOfSingleProductTemplate: boolean }; -} & HTMLAttributes< HTMLDivElement >; - -const DiscountEdit = ( { attributes, context }: Props ): JSX.Element => { - const blockProps = useBlockProps(); +export const Edit = ( { attributes, setAttributes } ): JSX.Element => { + const { style, className } = useStyleProps( attributes ); const { product } = useProductDataContext(); - const { isDescendentOfSingleProductTemplate = false } = context || {}; const originalPrice = product?.prices?.regular_price; const currentPrice = product?.prices?.price; const showPrice = originalPrice && currentPrice !== originalPrice; - const currency = isDescendentOfSingleProductTemplate - ? getCurrencyFromPriceResponse() - : getCurrencyFromPriceResponse( product?.prices ); - const blockAttrs = { - attributes, - currency, - context, - originalPrice, - currentPrice, - }; + useEffect( () => { + if ( ! attributes?.style ) { + setAttributes( { style: { spacing: { blockGap: '0' } } } ); + } + }, [ attributes, setAttributes ] ); return ( <> { showPrice && ( -
- +
+
) } ); }; -export default DiscountEdit; +export const Save = (): JSX.Element => { + return ( +
+ +
+ ); +}; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts index 5cbea61364e..40171006b72 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/index.ts @@ -6,8 +6,9 @@ import { registerBlockType } from '@wordpress/blocks'; /** * Internal dependencies */ -import edit from './edit'; +import { Edit as edit, Save as save } from './edit'; import sharedConfig from '../../../shared/config'; +import { supports } from '../../supports'; import metadata from './block.json'; const { ancestor, ...configuration } = sharedConfig; @@ -15,11 +16,12 @@ const { ancestor, ...configuration } = sharedConfig; const blockConfig = { ...configuration, ...metadata, - edit, supports: { - ...configuration.supports, - context: '', + ...supports, + ...metadata.supports, }, + edit, + save, }; registerBlockType( metadata.name, blockConfig ); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json new file mode 100644 index 00000000000..536c10795fc --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json @@ -0,0 +1,14 @@ +{ + "name": "woocommerce/discount-amount", + "version": "1.0.0", + "icon": "info", + "title": "Discount Amount", + "description": "Display the discounted amount value.", + "category": "woocommerce", + "usesContext": ["woocommerce/isDescendantOfSingleProductTemplate"], + "keywords": [ "WooCommerce" ], + "textdomain": "woo-gutenberg-products-block", + "ancestor": "woocommerce/discount", + "apiVersion": 2, + "$schema": "https://schemas.wp.org/trunk/block.json" +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx similarity index 100% rename from assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.tsx rename to assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx new file mode 100644 index 00000000000..4e1894030df --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx @@ -0,0 +1,51 @@ +/** + * External dependencies + */ +import { useBlockProps } from '@wordpress/block-editor'; +import type { HTMLAttributes, CSSProperties } from 'react'; +import { useProductDataContext } from '@woocommerce/shared-context'; +import { getCurrencyFromPriceResponse } from '@woocommerce/price-format'; + +/** + * Internal dependencies + */ +import DiscountBlock from './block'; + +interface Attributes { + style: CSSProperties; +} + +type Props = { + attributes: Attributes; + context?: { isDescendentOfSingleProductTemplate: boolean }; +} & HTMLAttributes< HTMLDivElement >; + +const DiscountEdit = ( { attributes, context }: Props ): JSX.Element => { + const blockProps = useBlockProps(); + const { product } = useProductDataContext(); + const { isDescendentOfSingleProductTemplate = false } = context || {}; + const originalPrice = product?.prices?.regular_price; + const currentPrice = product?.prices?.price; + const showPrice = originalPrice && currentPrice !== originalPrice; + const currency = isDescendentOfSingleProductTemplate + ? getCurrencyFromPriceResponse() + : getCurrencyFromPriceResponse( product?.prices ); + const blockAttrs = { + attributes, + currency, + context, + originalPrice, + currentPrice, + }; + return ( + <> + { showPrice && ( +
+ +
+ ) } + + ); +}; + +export default DiscountEdit; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/index.ts new file mode 100644 index 00000000000..be7063e7eb1 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/index.ts @@ -0,0 +1,27 @@ +/** + * External dependencies + */ +import { registerBlockType } from '@wordpress/blocks'; + +/** + * Internal dependencies + */ +import edit from './edit'; +import sharedConfig from '../../../../../shared/config'; +import metadata from './block.json'; + +const { ancestor, ...configuration } = sharedConfig; + +const blockConfig = { + ...configuration, + ...metadata, + edit, + supports: { + ...configuration.supports, + context: '', + }, +}; + +registerBlockType( metadata.name, blockConfig ); + +export const BLOCK_NAME = metadata.name; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/index.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/index.tsx new file mode 100644 index 00000000000..9f20e96872f --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/index.tsx @@ -0,0 +1,6 @@ +/** + * Internal dependencies + */ +import './discount-amount/index.ts'; + +export { BLOCK_NAME as discountAmountName } from './discount-amount/index'; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/template.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/template.ts new file mode 100644 index 00000000000..58153b03b92 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/template.ts @@ -0,0 +1,34 @@ +/** + * External dependencies + */ +import { InnerBlockTemplate } from '@wordpress/blocks'; +import { _x, sprintf } from '@wordpress/i18n'; + +// Some hackery to both make translation clearer and to allow for RTL languages +// in default template layout. +const translatedContent = sprintf( + // translators: %s: discount amount. The rendered value will only allow for placeholder at beginning or end of string. + _x( + '%s off', + 'post text next to discount amount', + 'woo-gutenberg-products-block' + ), + ':placeholder:' +); + +const templateContent = translatedContent.replace( ':placeholder:', '' ); + +const RTLtemplate: InnerBlockTemplate[] = [ + [ 'core/paragraph', { content: templateContent }, [] ], + [ 'woocommerce/discount-amount', {}, [] ], +]; + +const LTRtemplate: InnerBlockTemplate[] = [ + [ 'woocommerce/discount-amount', {}, [] ], + [ 'core/paragraph', { content: templateContent }, [] ], +]; + +export const TEMPLATE: InnerBlockTemplate[] = + translatedContent.indexOf( ':placeholder:' ) === 0 + ? LTRtemplate + : RTLtemplate; From 788855907a252b4d580c7385218df7669f178da7 Mon Sep 17 00:00:00 2001 From: Darren Ethier Date: Wed, 28 Jun 2023 14:31:04 -0400 Subject: [PATCH 20/32] =?UTF-8?q?switch=20to=20the=20stabilized=20?= =?UTF-8?q?=E2=80=9Clayout=E2=80=9D=20property.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/js/atomic/blocks/product-elements/price-v2/block.json | 2 +- .../product-elements/price-v2/inner-blocks/discount/block.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/block.json b/assets/js/atomic/blocks/product-elements/price-v2/block.json index 0653c0a4bd7..6238ce8cf90 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/block.json @@ -8,7 +8,7 @@ "textdomain": "woo-gutenberg-products-block", "description": "Display the price of a product, including any discounts.", "supports": { - "__experimentalLayout": { + "layout": { "allowSwitching": false, "allowInheriting": false, "default": { "type": "flex" } diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json index 480e13efa02..2ea7821519f 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json @@ -8,7 +8,7 @@ "keywords": [ "WooCommerce" ], "textdomain": "woo-gutenberg-products-block", "supports": { - "__experimentalLayout": { + "layout": { "allowSwitching": false, "allowInheriting": false, "default": { "type": "flex" } From ba215924e9d8d4e71bfb6d62a1d5fe9784268e12 Mon Sep 17 00:00:00 2001 From: tjcafferkey Date: Tue, 11 Jul 2023 12:51:54 +0100 Subject: [PATCH 21/32] Create server-side classes for current-price, discount-amount and original-price blocks. --- src/BlockTypes/ProductPriceCurrentPrice.php | 68 ++++++++++++++ src/BlockTypes/ProductPriceDiscountAmount.php | 92 +++++++++++++++++++ src/BlockTypes/ProductPriceOriginalPrice.php | 65 +++++++++++++ src/BlockTypesController.php | 3 + 4 files changed, 228 insertions(+) create mode 100644 src/BlockTypes/ProductPriceCurrentPrice.php create mode 100644 src/BlockTypes/ProductPriceDiscountAmount.php create mode 100644 src/BlockTypes/ProductPriceOriginalPrice.php diff --git a/src/BlockTypes/ProductPriceCurrentPrice.php b/src/BlockTypes/ProductPriceCurrentPrice.php new file mode 100644 index 00000000000..9b931c60a2f --- /dev/null +++ b/src/BlockTypes/ProductPriceCurrentPrice.php @@ -0,0 +1,68 @@ +context['postId']; + $product = wc_get_product( $post_id ); + + if ( ! $product ) { + return null; + } + + $classname = $attributes['className'] ?? ''; + $classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes ); + + // For variable products, show the price range. + if ( ! $product->is_type( 'variable' ) ) { + $price_display = wc_price( wc_get_price_to_display( $product ) ) . $product->get_price_suffix(); + } else { + $prices = $product->get_variation_prices( 'min' ); + $max_price = wc_price( $product->get_variation_price( 'max', true ) ) . $product->get_price_suffix(); + $min_price = wc_price( current( $prices['price'] ) ) . $product->get_price_suffix(); + $price_display = $min_price . ' - ' . $max_price; + } + + return sprintf( + '
%4$s
', + esc_attr( $classes_and_styles['classes'] ), + esc_attr( $classname ), + esc_attr( $classes_and_styles['styles'] ), + $price_display + ); + } +} diff --git a/src/BlockTypes/ProductPriceDiscountAmount.php b/src/BlockTypes/ProductPriceDiscountAmount.php new file mode 100644 index 00000000000..4c32cc80854 --- /dev/null +++ b/src/BlockTypes/ProductPriceDiscountAmount.php @@ -0,0 +1,92 @@ + 0 ) { + $percentage_discount = floor( ( $this->calculate_discount_value( $was_price, $is_price ) / $was_price ) * 100 ); + } else { + $percentage_discount = 0; + } + return $percentage_discount; + } + + /** + * Include and render the block. + * + * @param array $attributes Block attributes. Default empty array. + * @param string $content Block content. Default empty string. + * @param WP_Block $block Block instance. + * @return string Rendered block type output. + */ + protected function render( $attributes, $content, $block ) { + $post_id = $block->context['postId']; + $product = wc_get_product( $post_id ); + + if ( ! $product || ! $product->is_on_sale() ) { + return null; + } + + $classname = $attributes['className'] ?? ''; + $classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes ); + + if ( ! $product->is_type( 'variable' ) ) { + $percentage_discount = $this->calculate_discount_percentage( $product->get_regular_price(), wc_get_price_to_display( $product ) ); + } else { + $prices = $product->get_variation_prices( 'min' ); + $percentage_discount = $this->calculate_discount_percentage( $product->get_variation_price( 'max', true ), current( $prices['price'] ) ); + } + + return sprintf( + '
%4$s
', + esc_attr( $classes_and_styles['classes'] ), + esc_attr( $classname ), + esc_attr( $classes_and_styles['styles'] ), + $percentage_discount . '%' + ); + } +} diff --git a/src/BlockTypes/ProductPriceOriginalPrice.php b/src/BlockTypes/ProductPriceOriginalPrice.php new file mode 100644 index 00000000000..0c2d019c55d --- /dev/null +++ b/src/BlockTypes/ProductPriceOriginalPrice.php @@ -0,0 +1,65 @@ +context['postId']; + $product = wc_get_product( $post_id ); + + if ( ! $product || ! $product->is_on_sale() ) { + return null; + } + + $classname = $attributes['className'] ?? ''; + $classes_and_styles = StyleAttributesUtils::get_classes_and_styles_by_attributes( $attributes ); + + if ( ! $product->is_type( 'variable' ) ) { + $display_price = wc_price( $product->get_regular_price() ) . $product->get_price_suffix(); + } else { + // For variable products, show the max price of the variations on sale. + $display_price = wc_price( $product->get_variation_price( 'max', true ) ) . $product->get_price_suffix(); + } + + return sprintf( + '
%4$s
', + esc_attr( $classes_and_styles['classes'] ), + esc_attr( $classname ), + esc_attr( $classes_and_styles['styles'] ), + $display_price + ); + } +} diff --git a/src/BlockTypesController.php b/src/BlockTypesController.php index 5e1fdc677db..91dbca3c6dc 100644 --- a/src/BlockTypesController.php +++ b/src/BlockTypesController.php @@ -215,6 +215,9 @@ protected function get_block_types() { 'ProductDetails', 'SingleProduct', 'StockFilter', + 'ProductPriceDiscountAmount', + 'ProductPriceCurrentPrice', + 'ProductPriceOriginalPrice', ]; $block_types = array_merge( From 27f00c2b1f1f4a5fbe6da7f4c5970f2094709a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Tue, 25 Jul 2023 12:17:11 +0200 Subject: [PATCH 22/32] Add postId to context --- .../price-v2/inner-blocks/current-price/block.json | 2 +- .../price-v2/inner-blocks/original-price/block.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json index a44e2bad42b..4ca71e31f06 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json @@ -6,7 +6,7 @@ "description": "Display the current price for the product", "category": "woocommerce", "keywords": [ "WooCommerce" ], - "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendantOfSingleProductTemplate"], + "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendantOfSingleProductTemplate", "postId"], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json index 7b89cecb43e..655a9df6101 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json @@ -6,7 +6,7 @@ "description": "Display the original price for the product", "category": "woocommerce", "keywords": [ "WooCommerce" ], - "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendantOfSingleProductTemplate"], + "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendantOfSingleProductTemplate", "postId"], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" From 15b594e11bfd0d20f8a983e5db585834a6e986ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Tue, 25 Jul 2023 12:27:10 +0200 Subject: [PATCH 23/32] Fix discount class block name and add postId context --- .../product-elements/price-v2/inner-blocks/discount/block.json | 1 + src/BlockTypes/ProductPriceCurrentPrice.php | 2 +- src/BlockTypes/ProductPriceDiscountAmount.php | 3 +-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json index 2ea7821519f..ac28a733134 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json @@ -7,6 +7,7 @@ "category": "woocommerce", "keywords": [ "WooCommerce" ], "textdomain": "woo-gutenberg-products-block", + "usesContext": ["postId"], "supports": { "layout": { "allowSwitching": false, diff --git a/src/BlockTypes/ProductPriceCurrentPrice.php b/src/BlockTypes/ProductPriceCurrentPrice.php index 9b931c60a2f..9f62e80ab30 100644 --- a/src/BlockTypes/ProductPriceCurrentPrice.php +++ b/src/BlockTypes/ProductPriceCurrentPrice.php @@ -4,7 +4,7 @@ use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils; /** - * ProducePriceCurrentPrice class. + * ProductPriceCurrentPrice class. */ class ProductPriceCurrentPrice extends AbstractBlock { /** diff --git a/src/BlockTypes/ProductPriceDiscountAmount.php b/src/BlockTypes/ProductPriceDiscountAmount.php index 4c32cc80854..3a2a3f737d3 100644 --- a/src/BlockTypes/ProductPriceDiscountAmount.php +++ b/src/BlockTypes/ProductPriceDiscountAmount.php @@ -12,7 +12,7 @@ class ProductPriceDiscountAmount extends AbstractBlock { * * @var string */ - protected $block_name = 'discount-amount'; + protected $block_name = 'discount'; /** * API version name. @@ -66,7 +66,6 @@ protected function calculate_discount_percentage( $was_price, $is_price ) { protected function render( $attributes, $content, $block ) { $post_id = $block->context['postId']; $product = wc_get_product( $post_id ); - if ( ! $product || ! $product->is_on_sale() ) { return null; } From 8baaec83de578b684daa9aa0ab1dbb72e54fb355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Tue, 25 Jul 2023 15:16:56 +0200 Subject: [PATCH 24/32] Fix woocommerce/isDescendentOfSingleProductTemplate context, show preview prices Refactor needed, but for now it shows on the editor --- .../price-v2/inner-blocks/current-price/block.json | 2 +- .../price-v2/inner-blocks/current-price/block.tsx | 5 ++++- .../price-v2/inner-blocks/current-price/edit.tsx | 8 ++++++-- .../price-v2/inner-blocks/discount/block.json | 2 +- .../price-v2/inner-blocks/discount/edit.tsx | 11 +++++++++-- .../discount/inner-blocks/discount-amount/block.json | 2 +- .../discount/inner-blocks/discount-amount/block.tsx | 5 ++++- .../discount/inner-blocks/discount-amount/edit.tsx | 12 +++++++++--- .../price-v2/inner-blocks/original-price/block.json | 2 +- .../price-v2/inner-blocks/original-price/block.tsx | 5 ++++- .../price-v2/inner-blocks/original-price/edit.tsx | 12 +++++++++--- .../atomic/blocks/product-elements/price-v2/types.ts | 2 ++ 12 files changed, 51 insertions(+), 17 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json index 4ca71e31f06..774a6141515 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json @@ -6,7 +6,7 @@ "description": "Display the current price for the product", "category": "woocommerce", "keywords": [ "WooCommerce" ], - "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendantOfSingleProductTemplate", "postId"], + "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendentOfSingleProductTemplate", "postId"], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx index 682803316df..924ad406767 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -23,7 +23,10 @@ const Block = ( { currency, }: Props ): JSX.Element | null => { const { className } = attributes; - const { isDescendentOfSingleProductTemplate = false } = context || {}; + const isDescendentOfSingleProductTemplate = + ( context && + context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || + false; const { className: stylesClassName, style } = useStyleProps( attributes ); const { parentClassName } = useInnerBlockLayoutContext(); const wrapperClassName = classnames( diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx index d72e93651ef..9d706329b24 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx @@ -17,13 +17,17 @@ interface Attributes { type Props = { attributes: Attributes; - context?: { isDescendentOfSingleProductTemplate: boolean }; + // eslint-disable-next-line @typescript-eslint/naming-convention + context?: { 'woocommerce/isDescendentOfSingleProductTemplate': boolean }; } & HTMLAttributes< HTMLDivElement >; const CurrentPriceEdit = ( { attributes, context }: Props ): JSX.Element => { const blockProps = useBlockProps(); const { product } = useProductDataContext(); - const { isDescendentOfSingleProductTemplate = false } = context || {}; + const isDescendentOfSingleProductTemplate = + ( context && + context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || + false; const currentPrice = product?.prices?.price; const currency = isDescendentOfSingleProductTemplate ? getCurrencyFromPriceResponse() diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json index ac28a733134..6f8ff25070d 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json @@ -7,7 +7,7 @@ "category": "woocommerce", "keywords": [ "WooCommerce" ], "textdomain": "woo-gutenberg-products-block", - "usesContext": ["postId"], + "usesContext": ["woocommerce/isDescendentOfSingleProductTemplate" ,"postId"], "supports": { "layout": { "allowSwitching": false, diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx index 87fae2a6fc1..00c376cb80b 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx @@ -12,12 +12,19 @@ import { useEffect } from '@wordpress/element'; import { discountAmountName } from './inner-blocks'; import { TEMPLATE } from './template'; -export const Edit = ( { attributes, setAttributes } ): JSX.Element => { +export const Edit = ( { attributes, setAttributes, context } ): JSX.Element => { const { style, className } = useStyleProps( attributes ); const { product } = useProductDataContext(); const originalPrice = product?.prices?.regular_price; const currentPrice = product?.prices?.price; - const showPrice = originalPrice && currentPrice !== originalPrice; + const isDescendentOfSingleProductTemplate = + ( context && + context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || + false; + + const showPrice = + ( originalPrice && currentPrice !== originalPrice ) || + isDescendentOfSingleProductTemplate; useEffect( () => { if ( ! attributes?.style ) { setAttributes( { style: { spacing: { blockGap: '0' } } } ); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json index 536c10795fc..0c5f537017f 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json @@ -5,7 +5,7 @@ "title": "Discount Amount", "description": "Display the discounted amount value.", "category": "woocommerce", - "usesContext": ["woocommerce/isDescendantOfSingleProductTemplate"], + "usesContext": ["woocommerce/isDescendentOfSingleProductTemplate"], "keywords": [ "WooCommerce" ], "textdomain": "woo-gutenberg-products-block", "ancestor": "woocommerce/discount", diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx index 42c39b9cb95..f8e8af1e977 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx @@ -43,7 +43,10 @@ const Block = ( { discountType = 'percentage', showDiscount = true, } = attributes; - const { isDescendentOfSingleProductTemplate = false } = context || {}; + const isDescendentOfSingleProductTemplate = + ( context && + context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || + false; const { className: stylesClassName, style } = useStyleProps( attributes ); const { parentClassName } = useInnerBlockLayoutContext(); if ( ! showDiscount ) { diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx index 4e1894030df..d536ba56e5c 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx @@ -17,16 +17,22 @@ interface Attributes { type Props = { attributes: Attributes; - context?: { isDescendentOfSingleProductTemplate: boolean }; + // eslint-disable-next-line @typescript-eslint/naming-convention + context?: { 'woocommerce/isDescendentOfSingleProductTemplate': boolean }; } & HTMLAttributes< HTMLDivElement >; const DiscountEdit = ( { attributes, context }: Props ): JSX.Element => { const blockProps = useBlockProps(); const { product } = useProductDataContext(); - const { isDescendentOfSingleProductTemplate = false } = context || {}; + const isDescendentOfSingleProductTemplate = + ( context && + context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || + false; const originalPrice = product?.prices?.regular_price; const currentPrice = product?.prices?.price; - const showPrice = originalPrice && currentPrice !== originalPrice; + const showPrice = + ( originalPrice && currentPrice !== originalPrice ) || + isDescendentOfSingleProductTemplate; const currency = isDescendentOfSingleProductTemplate ? getCurrencyFromPriceResponse() : getCurrencyFromPriceResponse( product?.prices ); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json index 655a9df6101..ff00a82e6ae 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json @@ -6,7 +6,7 @@ "description": "Display the original price for the product", "category": "woocommerce", "keywords": [ "WooCommerce" ], - "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendantOfSingleProductTemplate", "postId"], + "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendentOfSingleProductTemplate", "postId"], "textdomain": "woo-gutenberg-products-block", "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx index b0988c6a229..2679d49cf37 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx @@ -22,7 +22,10 @@ const Block = ( { currency, }: Props ): JSX.Element | null => { const { className } = attributes; - const { isDescendentOfSingleProductTemplate = false } = context || {}; + const isDescendentOfSingleProductTemplate = + ( context && + context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || + false; const { className: stylesClassName, style } = useStyleProps( attributes ); const { parentClassName } = useInnerBlockLayoutContext(); const wrapperClassName = classnames( diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx index c19e38047a3..3e47353afd7 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx @@ -17,16 +17,22 @@ interface Attributes { type Props = { attributes: Attributes; - context?: { isDescendentOfSingleProductTemplate: boolean }; + // eslint-disable-next-line @typescript-eslint/naming-convention + context?: { 'woocommerce/isDescendentOfSingleProductTemplate': boolean }; } & HTMLAttributes< HTMLDivElement >; const OriginalPriceEdit = ( { attributes, context }: Props ): JSX.Element => { const blockProps = useBlockProps(); const { product } = useProductDataContext(); - const { isDescendentOfSingleProductTemplate = false } = context || {}; + const isDescendentOfSingleProductTemplate = + ( context && + context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || + false; const originalPrice = product?.prices?.regular_price; const currentPrice = product?.prices?.price; - const showPrice = originalPrice && currentPrice !== originalPrice; + const showPrice = + ( originalPrice && currentPrice !== originalPrice ) || + isDescendentOfSingleProductTemplate; const currency = isDescendentOfSingleProductTemplate ? getCurrencyFromPriceResponse() : getCurrencyFromPriceResponse( product?.prices ); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/types.ts b/assets/js/atomic/blocks/product-elements/price-v2/types.ts index 867a58145f0..809deba328f 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/types.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/types.ts @@ -17,6 +17,8 @@ export interface PriceContext { isDescendentOfSingleProductTemplate: boolean; // eslint-disable-next-line @typescript-eslint/naming-convention 'woocommerce/withSuperScriptStyle'?: boolean; + // eslint-disable-next-line @typescript-eslint/naming-convention + 'woocommerce/isDescendentOfSingleProductTemplate'?: boolean; } export interface PriceAttributes { From 629a99fd5bdb1569182d03de4e41dac53a226f72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Wed, 26 Jul 2023 13:02:47 +0200 Subject: [PATCH 25/32] Render inner block and fix class name --- ...ductPriceDiscountAmount.php => ProductPriceDiscount.php} | 6 +++--- src/BlockTypesController.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/BlockTypes/{ProductPriceDiscountAmount.php => ProductPriceDiscount.php} (96%) diff --git a/src/BlockTypes/ProductPriceDiscountAmount.php b/src/BlockTypes/ProductPriceDiscount.php similarity index 96% rename from src/BlockTypes/ProductPriceDiscountAmount.php rename to src/BlockTypes/ProductPriceDiscount.php index 3a2a3f737d3..2ff3af3e3c3 100644 --- a/src/BlockTypes/ProductPriceDiscountAmount.php +++ b/src/BlockTypes/ProductPriceDiscount.php @@ -4,9 +4,9 @@ use Automattic\WooCommerce\Blocks\Utils\StyleAttributesUtils; /** - * ProductPriceDiscountAmount class. + * ProductPriceDiscount class. */ -class ProductPriceDiscountAmount extends AbstractBlock { +class ProductPriceDiscount extends AbstractBlock { /** * Block name. * @@ -86,6 +86,6 @@ protected function render( $attributes, $content, $block ) { esc_attr( $classname ), esc_attr( $classes_and_styles['styles'] ), $percentage_discount . '%' - ); + ) . $content; } } diff --git a/src/BlockTypesController.php b/src/BlockTypesController.php index 2da692dcb88..9cc9a1a579f 100644 --- a/src/BlockTypesController.php +++ b/src/BlockTypesController.php @@ -215,7 +215,7 @@ protected function get_block_types() { 'ProductDetails', 'SingleProduct', 'StockFilter', - 'ProductPriceDiscountAmount', + 'ProductPriceDiscount', 'ProductPriceCurrentPrice', 'ProductPriceOriginalPrice', ]; From fcf326769079ace3a8578136db6795a709ed0ef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Wed, 26 Jul 2023 13:03:14 +0200 Subject: [PATCH 26/32] Fix import an ancestor type --- .../discount/inner-blocks/discount-amount/block.json | 2 +- .../discount/inner-blocks/discount-amount/block.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json index 0c5f537017f..28817262461 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.json @@ -8,7 +8,7 @@ "usesContext": ["woocommerce/isDescendentOfSingleProductTemplate"], "keywords": [ "WooCommerce" ], "textdomain": "woo-gutenberg-products-block", - "ancestor": "woocommerce/discount", + "ancestor": [ "woocommerce/discount" ], "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" } diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx index f8e8af1e977..eca4fc3e740 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx @@ -10,7 +10,7 @@ import FormattedMonetaryAmount from '@woocommerce/base-components/formatted-mone /** * Internal dependencies */ -import type { PriceProps } from '../../types'; +import { PriceProps } from '../../../../types'; type Props = PriceProps & HTMLAttributes< HTMLDivElement >; From 829eb35a67a5bf4a04eaa1b6753214bb0c6804d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Wed, 26 Jul 2023 14:02:29 +0200 Subject: [PATCH 27/32] Add color support for inner price blocks --- .../price-v2/inner-blocks/current-price/block.json | 6 ++++++ .../price-v2/inner-blocks/current-price/index.ts | 1 + .../price-v2/inner-blocks/discount/block.json | 7 +++++-- .../price-v2/inner-blocks/original-price/block.json | 6 ++++++ .../price-v2/inner-blocks/original-price/index.ts | 1 + 5 files changed, 19 insertions(+), 2 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json index 774a6141515..240792ea3c1 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.json @@ -4,6 +4,12 @@ "icon": "info", "title": "Current Price", "description": "Display the current price for the product", + "supports": { + "color": { + "background": true, + "text": true + } + }, "category": "woocommerce", "keywords": [ "WooCommerce" ], "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendentOfSingleProductTemplate", "postId"], diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts index 5cbea61364e..98e594d73e9 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts @@ -17,6 +17,7 @@ const blockConfig = { ...metadata, edit, supports: { + ...metadata.supports, ...configuration.supports, context: '', }, diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json index 6f8ff25070d..7a5acd04f42 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/block.json @@ -14,8 +14,11 @@ "allowInheriting": false, "default": { "type": "flex" } }, - "html": false - + "html": false, + "color": { + "background": true, + "text": true + } }, "apiVersion": 2, "$schema": "https://schemas.wp.org/trunk/block.json" diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json index ff00a82e6ae..2c155fafaaa 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.json @@ -4,6 +4,12 @@ "icon": "info", "title": "Original Price", "description": "Display the original price for the product", + "supports": { + "color": { + "background": true, + "text": true + } + }, "category": "woocommerce", "keywords": [ "WooCommerce" ], "usesContext": ["woocommerce/withSuperScriptStyle", "woocommerce/isDescendentOfSingleProductTemplate", "postId"], diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts index 5cbea61364e..98e594d73e9 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts @@ -17,6 +17,7 @@ const blockConfig = { ...metadata, edit, supports: { + ...metadata.supports, ...configuration.supports, context: '', }, From 20d7b5f1c876d0b7f1bb09324216ecbb5cedb6f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Thu, 27 Jul 2023 10:50:09 +0200 Subject: [PATCH 28/32] Refactor context and add color support for inner blocks The price parent block also supports color but inner blocks colors take priority --- .../js/atomic/blocks/product-elements/price-v2/block.json | 5 ++--- assets/js/atomic/blocks/product-elements/price-v2/edit.tsx | 4 +--- .../price-v2/inner-blocks/current-price/block.tsx | 5 +---- .../price-v2/inner-blocks/current-price/edit.tsx | 4 +--- .../price-v2/inner-blocks/discount/edit.tsx | 4 +--- .../discount/inner-blocks/discount-amount/block.tsx | 6 +----- .../discount/inner-blocks/discount-amount/edit.tsx | 5 ++--- .../price-v2/inner-blocks/original-price/block.tsx | 7 ++----- .../price-v2/inner-blocks/original-price/edit.tsx | 5 ++--- .../js/atomic/blocks/product-elements/price-v2/supports.ts | 2 -- assets/js/atomic/blocks/product-elements/price-v2/types.ts | 1 + 11 files changed, 14 insertions(+), 34 deletions(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/block.json b/assets/js/atomic/blocks/product-elements/price-v2/block.json index 6238ce8cf90..6179874ad62 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/block.json +++ b/assets/js/atomic/blocks/product-elements/price-v2/block.json @@ -1,9 +1,9 @@ { - "$schema": "http://schemas.wp.org/trunk/block.json", + "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 2, "name": "woocommerce/product-price-v2", "title": "Price", - "keywords": "WooCommerce", + "keywords": [ "WooCommerce" ], "category": "woocommerce-product-elements", "textdomain": "woo-gutenberg-products-block", "description": "Display the price of a product, including any discounts.", @@ -14,7 +14,6 @@ "default": { "type": "flex" } }, "html": false - }, "usesContext": [ "queryId", "postId" ], "providesContext": { diff --git a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx index 582e54e3d59..58b6a1a2aa7 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx @@ -10,7 +10,6 @@ import { ProductDataContextProvider, } from '@woocommerce/shared-context'; import { useStoreProducts } from '@woocommerce/base-context/hooks'; -import { useStyleProps } from '@woocommerce/base-hooks'; /** * Internal dependencies @@ -156,8 +155,7 @@ const Edit = ( { attributes, ...props }: Props ): JSX.Element => { - const { style, className } = useStyleProps( attributes ); - const blockProps = useBlockProps( { style, className } ); + const blockProps = useBlockProps(); const withSuperScript = useMemo( () => deriveSuperScriptFromClass( blockProps.className ), [ blockProps.className ] diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx index 924ad406767..4ad1d6f9df1 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -21,12 +21,9 @@ const Block = ( { minPrice, maxPrice, currency, + isDescendentOfSingleProductTemplate, }: Props ): JSX.Element | null => { const { className } = attributes; - const isDescendentOfSingleProductTemplate = - ( context && - context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || - false; const { className: stylesClassName, style } = useStyleProps( attributes ); const { parentClassName } = useInnerBlockLayoutContext(); const wrapperClassName = classnames( diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx index 9d706329b24..2ba87e0efd5 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx @@ -25,9 +25,7 @@ const CurrentPriceEdit = ( { attributes, context }: Props ): JSX.Element => { const blockProps = useBlockProps(); const { product } = useProductDataContext(); const isDescendentOfSingleProductTemplate = - ( context && - context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || - false; + context && context[ 'woocommerce/isDescendentOfSingleProductTemplate' ]; const currentPrice = product?.prices?.price; const currency = isDescendentOfSingleProductTemplate ? getCurrencyFromPriceResponse() diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx index 00c376cb80b..e05ef3b2f24 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx @@ -18,9 +18,7 @@ export const Edit = ( { attributes, setAttributes, context } ): JSX.Element => { const originalPrice = product?.prices?.regular_price; const currentPrice = product?.prices?.price; const isDescendentOfSingleProductTemplate = - ( context && - context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || - false; + context && context[ 'woocommerce/isDescendentOfSingleProductTemplate' ]; const showPrice = ( originalPrice && currentPrice !== originalPrice ) || diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx index eca4fc3e740..d7355b83243 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx @@ -31,10 +31,10 @@ const calculateDiscountPercentage = ( originalPrice, currentPrice ) => { const Block = ( { attributes, - context, originalPrice, currentPrice, currency, + isDescendentOfSingleProductTemplate, }: Props ): JSX.Element | null => { // todo: need to setup discountType and showDiscount as attributes/context // from the parent block. @@ -43,10 +43,6 @@ const Block = ( { discountType = 'percentage', showDiscount = true, } = attributes; - const isDescendentOfSingleProductTemplate = - ( context && - context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || - false; const { className: stylesClassName, style } = useStyleProps( attributes ); const { parentClassName } = useInnerBlockLayoutContext(); if ( ! showDiscount ) { diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx index d536ba56e5c..7b3b576e580 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/edit.tsx @@ -25,9 +25,7 @@ const DiscountEdit = ( { attributes, context }: Props ): JSX.Element => { const blockProps = useBlockProps(); const { product } = useProductDataContext(); const isDescendentOfSingleProductTemplate = - ( context && - context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || - false; + context && context[ 'woocommerce/isDescendentOfSingleProductTemplate' ]; const originalPrice = product?.prices?.regular_price; const currentPrice = product?.prices?.price; const showPrice = @@ -42,6 +40,7 @@ const DiscountEdit = ( { attributes, context }: Props ): JSX.Element => { context, originalPrice, currentPrice, + isDescendentOfSingleProductTemplate, }; return ( <> diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx index 2679d49cf37..4f1bea181fb 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx @@ -20,12 +20,9 @@ const Block = ( { rawPrice, priceType, currency, + isDescendentOfSingleProductTemplate, }: Props ): JSX.Element | null => { const { className } = attributes; - const isDescendentOfSingleProductTemplate = - ( context && - context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || - false; const { className: stylesClassName, style } = useStyleProps( attributes ); const { parentClassName } = useInnerBlockLayoutContext(); const wrapperClassName = classnames( @@ -51,7 +48,7 @@ const Block = ( { style={ style } priceClassName={ priceClassName } currency={ currency } - withSuperScript={ context[ 'woocommerce/withSuperScriptStyle' ] } + withSuperScript={ context?.[ 'woocommerce/withSuperScriptStyle' ] } price={ isDescendentOfSingleProductTemplate ? pricePreview : rawPrice } diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx index 3e47353afd7..6ebfbc16b92 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/edit.tsx @@ -25,9 +25,7 @@ const OriginalPriceEdit = ( { attributes, context }: Props ): JSX.Element => { const blockProps = useBlockProps(); const { product } = useProductDataContext(); const isDescendentOfSingleProductTemplate = - ( context && - context[ 'woocommerce/isDescendentOfSingleProductTemplate' ] ) || - false; + context && context[ 'woocommerce/isDescendentOfSingleProductTemplate' ]; const originalPrice = product?.prices?.regular_price; const currentPrice = product?.prices?.price; const showPrice = @@ -42,6 +40,7 @@ const OriginalPriceEdit = ( { attributes, context }: Props ): JSX.Element => { context, rawPrice: originalPrice, priceType: 'original', + isDescendentOfSingleProductTemplate, }; return ( <> diff --git a/assets/js/atomic/blocks/product-elements/price-v2/supports.ts b/assets/js/atomic/blocks/product-elements/price-v2/supports.ts index 3e8b0740f2c..2f5caecfe36 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/supports.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/supports.ts @@ -21,7 +21,6 @@ export const supports = { text: true, background: true, link: false, - __experimentalSkipSerialization: true, }, typography: { fontSize: true, @@ -29,7 +28,6 @@ export const supports = { __experimentalFontFamily: true, __experimentalFontWeight: true, __experimentalFontStyle: true, - __experimentalSkipSerialization: true, __experimentalLetterSpacing: true, }, __experimentalSelector: diff --git a/assets/js/atomic/blocks/product-elements/price-v2/types.ts b/assets/js/atomic/blocks/product-elements/price-v2/types.ts index 809deba328f..397f6179819 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/types.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/types.ts @@ -33,4 +33,5 @@ export interface PriceProps extends ProductPriceProps { minPrice?: string; maxPrice?: string; priceType: 'original' | 'current'; + isDescendentOfSingleProductTemplate?: boolean; } From 2e6796476b5646b1265ebe7cb97c70de61b686ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Thu, 27 Jul 2023 12:44:31 +0200 Subject: [PATCH 29/32] Add support for typography and dimension styles --- .../price-v2/inner-blocks/current-price/index.ts | 2 ++ .../price-v2/inner-blocks/original-price/index.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts index 98e594d73e9..2da5e528913 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/index.ts @@ -9,6 +9,7 @@ import { registerBlockType } from '@wordpress/blocks'; import edit from './edit'; import sharedConfig from '../../../shared/config'; import metadata from './block.json'; +import { supports } from '../../supports'; const { ancestor, ...configuration } = sharedConfig; @@ -17,6 +18,7 @@ const blockConfig = { ...metadata, edit, supports: { + ...supports, ...metadata.supports, ...configuration.supports, context: '', diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts index 98e594d73e9..1b285998a88 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts @@ -9,6 +9,7 @@ import { registerBlockType } from '@wordpress/blocks'; import edit from './edit'; import sharedConfig from '../../../shared/config'; import metadata from './block.json'; +import { supports } from '../../supports'; const { ancestor, ...configuration } = sharedConfig; @@ -19,6 +20,7 @@ const blockConfig = { supports: { ...metadata.supports, ...configuration.supports, + ...supports, context: '', }, }; From e6454bb062ac8cb6f8e427ca536ed25c826b2a70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Thu, 27 Jul 2023 14:57:06 +0200 Subject: [PATCH 30/32] Render price inner blocks inline in the editor --- .../atomic/blocks/product-elements/price-v2/edit.tsx | 1 + .../blocks/product-elements/price-v2/editor.scss | 12 ++++++++++++ .../price-v2/inner-blocks/current-price/block.tsx | 2 +- .../price-v2/inner-blocks/current-price/edit.tsx | 1 + .../price-v2/inner-blocks/discount/edit.tsx | 1 + .../price-v2/inner-blocks/discount/editor.scss | 3 +++ .../discount/inner-blocks/discount-amount/block.tsx | 4 ++-- .../price-v2/inner-blocks/original-price/block.tsx | 2 +- 8 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/editor.scss create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/editor.scss diff --git a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx index 58b6a1a2aa7..9b0132dacff 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx @@ -20,6 +20,7 @@ import { priceDiscount, } from './inner-blocks'; import { TEMPLATE } from './template'; +import './editor.scss'; interface Attributes { isDescendentOfSingleProductBlock: boolean; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/editor.scss b/assets/js/atomic/blocks/product-elements/price-v2/editor.scss new file mode 100644 index 00000000000..8ad61d24194 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/editor.scss @@ -0,0 +1,12 @@ +.wc-block-price-element { + .block-editor-inner-blocks { + .block-editor-block-list__layout { + display: flex; + + .wp-block-woocommerce-original-price, + .wp-block-woocommerce-current-price { + margin-right: $gap-smaller; + } + } + } +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx index 4ad1d6f9df1..2d83b7e6a3d 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/block.tsx @@ -37,7 +37,7 @@ const Block = ( { return ; } - const pricePreview = '5000'; + const pricePreview = '3000'; const priceClassName = classnames( { [ `${ parentClassName }__product-current-price__value` ]: parentClassName, diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx index 2ba87e0efd5..9687453ada5 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/current-price/edit.tsx @@ -38,6 +38,7 @@ const CurrentPriceEdit = ( { attributes, context }: Props ): JSX.Element => { minPrice: product?.prices?.price_range?.min_amount, maxPrice: product?.prices?.price_range?.max_amount, priceType: 'current', + isDescendentOfSingleProductTemplate, }; return ( <> diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx index e05ef3b2f24..85e7b24b807 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/edit.tsx @@ -11,6 +11,7 @@ import { useEffect } from '@wordpress/element'; */ import { discountAmountName } from './inner-blocks'; import { TEMPLATE } from './template'; +import './editor.scss'; export const Edit = ( { attributes, setAttributes, context } ): JSX.Element => { const { style, className } = useStyleProps( attributes ); diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/editor.scss b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/editor.scss new file mode 100644 index 00000000000..66bb3dd5b79 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/editor.scss @@ -0,0 +1,3 @@ +.wp-block-woocommerce-discount-amount + p { + margin: 0; +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx index d7355b83243..7835b21c450 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/discount/inner-blocks/discount-amount/block.tsx @@ -59,8 +59,8 @@ const Block = ( { [ `${ parentClassName }__product-price_discount` ]: parentClassName, } ); // todo: lift all the preview pricing up to the parent block (across all the price inner blocks) - const oPrice = isDescendentOfSingleProductTemplate ? '3000' : originalPrice; - const cPrice = isDescendentOfSingleProductTemplate ? '5000' : currentPrice; + const oPrice = isDescendentOfSingleProductTemplate ? '5000' : originalPrice; + const cPrice = isDescendentOfSingleProductTemplate ? '3000' : currentPrice; const DisplayedDiscount = discountType === 'percentage' ? ( diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx index 4f1bea181fb..f76794252d5 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/block.tsx @@ -36,7 +36,7 @@ const Block = ( { return ; } - const pricePreview = '3000'; + const pricePreview = '5000'; const priceClassName = classnames( { [ `${ parentClassName }__product-${ priceType }-price__value` ]: parentClassName, From beb62a27cd676e6f3b4f49b5b518f76f9ff6c5ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Fri, 28 Jul 2023 10:20:03 +0200 Subject: [PATCH 31/32] Add original price styles --- .../atomic/blocks/product-elements/price-v2/edit.tsx | 10 ++++------ .../atomic/blocks/product-elements/price-v2/index.ts | 1 + .../product-elements/price-v2/inner-blocks/index.ts | 10 +++------- .../price-v2/inner-blocks/original-price/index.ts | 1 + .../price-v2/inner-blocks/original-price/style.scss | 3 +++ .../atomic/blocks/product-elements/price-v2/style.scss | 8 ++++++++ 6 files changed, 20 insertions(+), 13 deletions(-) create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/style.scss create mode 100644 assets/js/atomic/blocks/product-elements/price-v2/style.scss diff --git a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx index 9b0132dacff..af47ca58b04 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx +++ b/assets/js/atomic/blocks/product-elements/price-v2/edit.tsx @@ -14,11 +14,9 @@ import { useStoreProducts } from '@woocommerce/base-context/hooks'; /** * Internal dependencies */ -import { - originalPriceName, - currentPriceName, - priceDiscount, -} from './inner-blocks'; +import { BLOCK_NAME as priceDiscountName } from './inner-blocks/discount'; +import { BLOCK_NAME as originalPriceName } from './inner-blocks/original-price'; +import { BLOCK_NAME as currentPriceName } from './inner-blocks/current-price'; import { TEMPLATE } from './template'; import './editor.scss'; @@ -141,7 +139,7 @@ const EditBlock = ( { allowedBlocks={ [ originalPriceName, currentPriceName, - priceDiscount, + priceDiscountName, ] } // todo add template for initial price layout template={ TEMPLATE } diff --git a/assets/js/atomic/blocks/product-elements/price-v2/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/index.ts index 5e38960ce4c..044b238dbee 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/index.ts @@ -11,6 +11,7 @@ import save from './save'; import { supports } from './supports'; import metadata from './block.json'; import { BLOCK_ICON as icon } from './constants'; +import './inner-blocks'; const blockConfig = { ...metadata, diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts index 39ebc0edafa..2277fbc12b6 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/index.ts @@ -1,10 +1,6 @@ /** * Internal dependencies */ -import './original-price/index.ts'; -import './current-price/index.ts'; -import './discount/index.ts'; - -export { BLOCK_NAME as originalPriceName } from './original-price/index'; -export { BLOCK_NAME as currentPriceName } from './current-price/index'; -export { BLOCK_NAME as priceDiscount } from './discount/index'; +import './original-price'; +import './current-price'; +import './discount'; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts index 1b285998a88..422736eed57 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/index.ts @@ -10,6 +10,7 @@ import edit from './edit'; import sharedConfig from '../../../shared/config'; import metadata from './block.json'; import { supports } from '../../supports'; +import './style.scss'; const { ancestor, ...configuration } = sharedConfig; diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/style.scss b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/style.scss new file mode 100644 index 00000000000..ca0fefe3a36 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/style.scss @@ -0,0 +1,3 @@ +body { + background-color: #c1d21c; +} diff --git a/assets/js/atomic/blocks/product-elements/price-v2/style.scss b/assets/js/atomic/blocks/product-elements/price-v2/style.scss new file mode 100644 index 00000000000..9796974b866 --- /dev/null +++ b/assets/js/atomic/blocks/product-elements/price-v2/style.scss @@ -0,0 +1,8 @@ +.wp-block-woocommerce-product-price-v2 { + display: flex; + + .wp-block-woocommerce-original-price, + .wp-block-woocommerce-current-price { + margin-right: $gap-smaller; + } +} From d38704c1bff66ebafc0fe5830694632cf0e90a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alba=20Rinc=C3=B3n?= Date: Fri, 28 Jul 2023 10:32:11 +0200 Subject: [PATCH 32/32] Fix css test --- .../price-v2/inner-blocks/original-price/style.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/style.scss b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/style.scss index ca0fefe3a36..42b5ecee2df 100644 --- a/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/style.scss +++ b/assets/js/atomic/blocks/product-elements/price-v2/inner-blocks/original-price/style.scss @@ -1,3 +1,3 @@ -body { +.wp-block-woocommerce-original-price { background-color: #c1d21c; }