-
+
diff --git a/assets/js/blocks/cart/cart-cross-sells-product-list/index.tsx b/assets/js/blocks/cart/cart-cross-sells-product-list/index.tsx
index fe9627a4af2..fdb7cbe8d60 100644
--- a/assets/js/blocks/cart/cart-cross-sells-product-list/index.tsx
+++ b/assets/js/blocks/cart/cart-cross-sells-product-list/index.tsx
@@ -2,6 +2,7 @@
* External dependencies
*/
import { ProductResponseItem } from '@woocommerce/type-defs/product-response';
+import Noninteractive from '@woocommerce/base-components/noninteractive';
/**
* Internal dependencies
@@ -16,15 +17,19 @@ interface CrossSellsProducListProps {
crossSellsProducts: ProductResponseItem[];
isLoading: boolean;
className?: string;
+ columns: number;
}
const CartCrossSellsProductList = ( {
crossSellsProducts,
isLoading = false,
+ columns,
}: CrossSellsProducListProps ): JSX.Element => {
const products = isLoading
? placeholderRows
- : crossSellsProducts.map( ( crossSellsProduct ) => {
+ : crossSellsProducts.map( ( crossSellsProduct, i ) => {
+ if ( i >= columns ) return null;
+
return (
{ products }>;
+ return { products };
};
export default CartCrossSellsProductList;
diff --git a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-block/edit.tsx b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-block/edit.tsx
index a2ea2931276..25d8a8a9b20 100644
--- a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-block/edit.tsx
+++ b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-block/edit.tsx
@@ -1,18 +1,14 @@
/**
* External dependencies
*/
-import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
import type { TemplateArray } from '@wordpress/blocks';
import { __ } from '@wordpress/i18n';
+import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
-/**
- * Internal dependencies
- */
export const Edit = (): JSX.Element => {
const blockProps = useBlockProps( {
className: 'wc-block-cart__cross-sells',
} );
-
const defaultTemplate = [
[
'core/heading',
diff --git a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/block.json b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/block.json
index 673dbb1e4f5..aa84030ad19 100644
--- a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/block.json
+++ b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/block.json
@@ -11,6 +11,12 @@
"reusable": false,
"inserter": false
},
+ "attributes": {
+ "columns": {
+ "type": "number",
+ "default": 3
+ }
+ },
"parent": [ "woocommerce/cart-cross-sells-block" ],
"textdomain": "woo-gutenberg-products-block",
"apiVersion": 2
diff --git a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/block.tsx b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/block.tsx
index ffb4acd9e6f..33e0d4720c0 100644
--- a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/block.tsx
+++ b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/block.tsx
@@ -8,12 +8,19 @@ import { useStoreCart } from '@woocommerce/base-context/hooks';
*/
import CartCrossSellsProductList from '../../cart-cross-sells-product-list';
-const Block = ( { className }: { className: string } ): JSX.Element => {
+interface BlockProps {
+ className?: string;
+ columns: number;
+}
+
+const Block = ( { className, columns }: BlockProps ): JSX.Element => {
const { crossSellsProducts, cartIsLoading } = useStoreCart();
+
return (
);
diff --git a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/edit.tsx b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/edit.tsx
index 5f6e4d91ddf..6ee9075a260 100644
--- a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/edit.tsx
+++ b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/edit.tsx
@@ -1,7 +1,10 @@
/**
* External dependencies
*/
-import { useBlockProps } from '@wordpress/block-editor';
+import { __ } from '@wordpress/i18n';
+import { PanelBody, RangeControl } from '@wordpress/components';
+import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
+import { getSetting } from '@woocommerce/settings';
/**
* Internal dependencies
@@ -9,17 +12,41 @@ import { useBlockProps } from '@wordpress/block-editor';
import Block from './block';
import './editor.scss';
-export const Edit = ( {
- attributes,
-}: {
- attributes: { className: string };
-} ): JSX.Element => {
- const { className } = attributes;
+interface Attributes {
+ className?: string;
+ columns: number;
+}
+
+interface Props {
+ attributes: Attributes;
+ setAttributes: ( attributes: Record< string, unknown > ) => void;
+}
+
+export const Edit = ( { attributes, setAttributes }: Props ): JSX.Element => {
+ const { className, columns } = attributes;
const blockProps = useBlockProps();
return (
-
+
+
+
+ setAttributes( { columns: value } )
+ }
+ min={ getSetting( 'min_columns', 1 ) }
+ max={ getSetting( 'max_columns', 6 ) }
+ />
+
+
+
);
};
diff --git a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/editor.scss b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/editor.scss
index a964032e6a2..e2aa9cfc547 100644
--- a/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/editor.scss
+++ b/assets/js/blocks/cart/inner-blocks/cart-cross-sells-products/editor.scss
@@ -1,12 +1,12 @@
.wp-block-woocommerce-cart-cross-sells-products-block {
- display: flex;
- flex-wrap: wrap;
- >div {
- flex: 0 0 30%;
- list-style: none;
+ .cross-sells-product {
+ display: inline-block;
+ margin-bottom: 2em;
padding-right: 5%;
text-align: center;
+ vertical-align: top;
+ width: 30%;
&:nth-child(3n + 3) {
padding-right: 0%;
diff --git a/assets/js/blocks/cart/inner-blocks/cart-items-block/edit.tsx b/assets/js/blocks/cart/inner-blocks/cart-items-block/edit.tsx
index b761a8d4240..22d0c07ee69 100644
--- a/assets/js/blocks/cart/inner-blocks/cart-items-block/edit.tsx
+++ b/assets/js/blocks/cart/inner-blocks/cart-items-block/edit.tsx
@@ -13,7 +13,11 @@ import {
getAllowedBlocks,
} from '../../../cart-checkout-shared';
-export const Edit = ( { clientId }: { clientId: string } ): JSX.Element => {
+interface Props {
+ clientId: string;
+}
+
+export const Edit = ( { clientId }: Props ): JSX.Element => {
const blockProps = useBlockProps( { className: 'wc-block-cart__main' } );
const allowedBlocks = getAllowedBlocks( innerBlockAreas.CART_ITEMS );
const defaultTemplate = [
diff --git a/assets/js/previews/cart.ts b/assets/js/previews/cart.ts
index 99b34b4e270..6852a35ee9b 100644
--- a/assets/js/previews/cart.ts
+++ b/assets/js/previews/cart.ts
@@ -174,7 +174,6 @@ export const previewCart: CartResponse = {
],
cross_sells: [
{
- key: '1',
id: 1,
name: __( 'Polo', 'woo-gutenberg-products-block' ),
permalink: 'https://example.org',
@@ -210,7 +209,6 @@ export const previewCart: CartResponse = {
average_rating: 4.5,
},
{
- key: '2',
id: 2,
name: __( 'Long Sleeve Tee', 'woo-gutenberg-products-block' ),
permalink: 'https://example.org',
@@ -247,7 +245,6 @@ export const previewCart: CartResponse = {
average_rating: 4,
},
{
- key: '3',
id: 3,
name: __( 'Hoodie with Zipper', 'woo-gutenberg-products-block' ),
permalink: 'https://example.org',
@@ -285,6 +282,117 @@ export const previewCart: CartResponse = {
],
average_rating: 1,
},
+ {
+ id: 4,
+ name: __( 'Hoodie with Logo', 'woo-gutenberg-products-block' ),
+ permalink: 'https://example.org',
+ on_sale: false,
+ prices: {
+ currency_code: 'USD',
+ currency_symbol: '$',
+ currency_minor_unit: 2,
+ currency_decimal_separator: '.',
+ currency_thousand_separator: ',',
+ currency_prefix: '$',
+ currency_suffix: '',
+ price: displayWithTax ? '4500' : '4250',
+ regular_price: displayWithTax ? '4500' : '4250',
+ sale_price: displayWithTax ? '4500' : '4250',
+ raw_prices: {
+ precision: 6,
+ price: displayWithTax ? '45000000' : '42500000',
+ regular_price: displayWithTax ? '45000000' : '42500000',
+ sale_price: displayWithTax ? '45000000' : '42500000',
+ },
+ },
+ images: [
+ {
+ id: 17,
+ src: WC_BLOCKS_IMAGE_URL + 'previews/hoodie-with-logo.jpg',
+ thumbnail:
+ WC_BLOCKS_IMAGE_URL + 'previews/hoodie-with-logo.jpg',
+ srcset: '',
+ sizes: '',
+ name: '',
+ alt: '',
+ },
+ ],
+ average_rating: 5,
+ },
+ {
+ id: 5,
+ name: __( 'Hoodie with Pocket', 'woo-gutenberg-products-block' ),
+ permalink: 'https://example.org',
+ on_sale: true,
+ prices: {
+ currency_code: 'USD',
+ currency_symbol: '$',
+ currency_minor_unit: 2,
+ currency_decimal_separator: '.',
+ currency_thousand_separator: ',',
+ currency_prefix: '$',
+ currency_suffix: '',
+ price: displayWithTax ? '3500' : '3250',
+ regular_price: displayWithTax ? '4500' : '4250',
+ sale_price: displayWithTax ? '3500' : '3250',
+ raw_prices: {
+ precision: 6,
+ price: displayWithTax ? '35000000' : '32500000',
+ regular_price: displayWithTax ? '45000000' : '42500000',
+ sale_price: displayWithTax ? '35000000' : '32500000',
+ },
+ },
+ images: [
+ {
+ id: 17,
+ src:
+ WC_BLOCKS_IMAGE_URL + 'previews/hoodie-with-pocket.jpg',
+ thumbnail:
+ WC_BLOCKS_IMAGE_URL + 'previews/hoodie-with-pocket.jpg',
+ srcset: '',
+ sizes: '',
+ name: '',
+ alt: '',
+ },
+ ],
+ average_rating: 3.75,
+ },
+ {
+ id: 6,
+ name: __( 'T-Shirt', 'woo-gutenberg-products-block' ),
+ permalink: 'https://example.org',
+ on_sale: false,
+ prices: {
+ currency_code: 'USD',
+ currency_symbol: '$',
+ currency_minor_unit: 2,
+ currency_decimal_separator: '.',
+ currency_thousand_separator: ',',
+ currency_prefix: '$',
+ currency_suffix: '',
+ price: displayWithTax ? '1800' : '1500',
+ regular_price: displayWithTax ? '1800' : '1500',
+ sale_price: displayWithTax ? '1800' : '1500',
+ raw_prices: {
+ precision: 6,
+ price: displayWithTax ? '1800000' : '1500000',
+ regular_price: displayWithTax ? '1800000' : '1500000',
+ sale_price: displayWithTax ? '1800000' : '1500000',
+ },
+ },
+ images: [
+ {
+ id: 17,
+ src: WC_BLOCKS_IMAGE_URL + 'previews/tshirt.jpg',
+ thumbnail: WC_BLOCKS_IMAGE_URL + 'previews/tshirt.jpg',
+ srcset: '',
+ sizes: '',
+ name: '',
+ alt: '',
+ },
+ ],
+ average_rating: 3,
+ },
],
fees: [
{
diff --git a/assets/js/types/type-defs/hooks.ts b/assets/js/types/type-defs/hooks.ts
index 9b007723075..09cead7e6c8 100644
--- a/assets/js/types/type-defs/hooks.ts
+++ b/assets/js/types/type-defs/hooks.ts
@@ -1,3 +1,8 @@
+/**
+ * External dependencies
+ */
+import { ProductResponseItem } from '@woocommerce/type-defs/product-response';
+
/**
* Internal dependencies
*/
@@ -34,7 +39,7 @@ export interface StoreCartCoupon {
export interface StoreCart {
cartCoupons: CartResponseCoupons;
cartItems: Array< CartResponseItem >;
- crossSellsItems: Array< CartResponseItem >;
+ crossSellsProducts: Array< ProductResponseItem >;
cartFees: Array< CartResponseFeeItem >;
cartItemsCount: number;
cartItemsWeight: number;
diff --git a/composer.json b/composer.json
index f76be912842..69b22e9f166 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,8 @@
"name": "woocommerce/woocommerce-blocks",
"description": "WooCommerce blocks for the Gutenberg editor.",
"homepage": "https://woocommerce.com/",
- "type": "wordpress-plugin",
+ "type":"wordpress-plugin",
+ "version": "7.9.0-dev",
"keywords": [
"gutenberg",
"woocommerce",
diff --git a/images/previews/hoodie-with-logo.jpg b/images/previews/hoodie-with-logo.jpg
new file mode 100644
index 00000000000..9609e3bf856
Binary files /dev/null and b/images/previews/hoodie-with-logo.jpg differ
diff --git a/images/previews/hoodie-with-pocket.jpg b/images/previews/hoodie-with-pocket.jpg
new file mode 100644
index 00000000000..72c3272d0cb
Binary files /dev/null and b/images/previews/hoodie-with-pocket.jpg differ
diff --git a/images/previews/tshirt.jpg b/images/previews/tshirt.jpg
new file mode 100644
index 00000000000..d775d53efd3
Binary files /dev/null and b/images/previews/tshirt.jpg differ