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

Commit 3a67f0d

Browse files
committed
latest work (will roll back on resume)
1 parent dfd77df commit 3a67f0d

File tree

17 files changed

+472
-1
lines changed

17 files changed

+472
-1
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { BlockAttributes } from '@wordpress/blocks';
5+
6+
export const blockAttributes: BlockAttributes = {
7+
isDescendentOfSingleProductTemplate: {
8+
type: 'boolean',
9+
default: false,
10+
},
11+
isDescendentOfSingleProductBlock: {
12+
type: 'boolean',
13+
default: false,
14+
},
15+
productId: {
16+
type: 'number',
17+
default: 0,
18+
},
19+
};
20+
21+
export default blockAttributes;
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
5+
import { useEffect } from '@wordpress/element';
6+
import { useSelect } from '@wordpress/data';
7+
import {
8+
InnerBlockLayoutContextProvider,
9+
useInnerBlockLayoutContext,
10+
ProductDataContextProvider,
11+
} from '@woocommerce/shared-context';
12+
import { useStoreProducts } from '@woocommerce/base-context/hooks';
13+
14+
/**
15+
* Internal dependencies
16+
*/
17+
import { originalPriceName } from './inner-blocks';
18+
import { TEMPLATE } from './template';
19+
20+
interface Attributes {
21+
isDescendentOfSingleProductBlock: boolean;
22+
isDescendentOfSingleProductTemplate: boolean;
23+
productId?: number;
24+
}
25+
26+
interface Context {
27+
postId?: number;
28+
queryId?: number;
29+
}
30+
31+
interface Props {
32+
context: Context;
33+
attributes: Attributes;
34+
setAttributes: ( attributes: Partial< Attributes > ) => void;
35+
}
36+
37+
interface ContextProviderProps extends Props {
38+
children: JSX.Element | JSX.Element[] | undefined;
39+
}
40+
41+
type ProductIdProps = Partial< ContextProviderProps > & { productId: number };
42+
43+
const ProviderFromAPI = ( {
44+
productId,
45+
children,
46+
}: ProductIdProps ): JSX.Element => {
47+
// TODO: this would be good to derive from the WP entity store at some point.
48+
const { products, productsLoading } = useStoreProducts( {
49+
include: productId,
50+
} );
51+
let product = null;
52+
if ( products.length > 0 ) {
53+
product =
54+
products.find(
55+
( productIteration ) => productIteration.id === productId
56+
) || null;
57+
}
58+
59+
return (
60+
<ProductDataContextProvider
61+
product={ product }
62+
isLoading={ productsLoading }
63+
>
64+
{ children }
65+
</ProductDataContextProvider>
66+
);
67+
};
68+
69+
const DerivedProductDataContextProvider = ( {
70+
context,
71+
attributes,
72+
setAttributes,
73+
children,
74+
}: ContextProviderProps ): JSX.Element => {
75+
const { queryId, postId } = context;
76+
const { productId } = attributes;
77+
const isDescendentOfQueryLoop = Number.isFinite( queryId );
78+
const id = isDescendentOfQueryLoop ? postId : productId;
79+
const isDescendentOfSingleProductTemplate = useSelect(
80+
( select ) => {
81+
const editSiteStore = select( 'core/edit-site' );
82+
const editorPostId = editSiteStore?.getEditedPostId<
83+
string | undefined
84+
>();
85+
86+
return Boolean(
87+
editorPostId?.includes( '//single-product' ) &&
88+
! isDescendentOfQueryLoop
89+
);
90+
},
91+
[ isDescendentOfQueryLoop ]
92+
);
93+
94+
useEffect(
95+
() =>
96+
setAttributes( {
97+
isDescendentOfSingleProductTemplate,
98+
} ),
99+
[ isDescendentOfSingleProductTemplate, setAttributes ]
100+
);
101+
if ( id && id > 0 ) {
102+
return <ProviderFromAPI productId={ id }>{ children }</ProviderFromAPI>;
103+
}
104+
return (
105+
<ProductDataContextProvider isLoading={ false }>
106+
{ children }
107+
</ProductDataContextProvider>
108+
);
109+
};
110+
111+
const EditBlock = ( {
112+
context,
113+
attributes,
114+
setAttributes,
115+
}: Props ): JSX.Element => {
116+
const blockProps = useBlockProps();
117+
const { parentClassName } = useInnerBlockLayoutContext();
118+
return (
119+
<DerivedProductDataContextProvider
120+
context={ context }
121+
attributes={ attributes }
122+
setAttributes={ setAttributes }
123+
>
124+
<div { ...blockProps } className={ parentClassName }>
125+
<InnerBlocks
126+
allowedBlocks={ [ originalPriceName ] }
127+
// todo add template for initial price layout
128+
template={ TEMPLATE }
129+
/>
130+
</div>
131+
</DerivedProductDataContextProvider>
132+
);
133+
};
134+
135+
const Edit = ( props: Props ): JSX.Element => {
136+
return (
137+
<InnerBlockLayoutContextProvider
138+
parentName={ 'woocommerce/price-block' }
139+
parentClassName={ 'wc-block-price-element' }
140+
>
141+
<EditBlock { ...props } />
142+
</InnerBlockLayoutContextProvider>
143+
);
144+
};
145+
146+
export default Edit;
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import type { Currency } from '@woocommerce/types';
5+
import type { CSSProperties } from 'react';
6+
7+
export interface ProductPriceProps {
8+
/**
9+
* CSS class for the wrapper
10+
*/
11+
wrapperClassName?: string | undefined;
12+
/**
13+
* Currency configuration object
14+
*/
15+
currency?: Currency;
16+
/**
17+
* The string version of the element to use for the price interpolation
18+
*
19+
* **Note:** It should contain `<price/>` (which is also the default value)
20+
*/
21+
format?: string;
22+
/**
23+
* The maximum price in a range
24+
*/
25+
maxPrice?: string | number;
26+
/**
27+
* The minimum price in a range
28+
*/
29+
minPrice?: string | number;
30+
/**
31+
* The current price
32+
*/
33+
price?: string | number;
34+
/**
35+
* CSS class for the price
36+
*/
37+
priceClassName?: string;
38+
/**
39+
* Custom style for the price
40+
*/
41+
priceStyle?: CSSProperties;
42+
/**
43+
* Custom style for the wrapper
44+
*/
45+
style?: CSSProperties;
46+
}
47+
48+
export const ProductPrice = ( {
49+
className,
50+
currency,
51+
format = '<price/>',
52+
maxPrice,
53+
minPrice,
54+
price,
55+
priceClassName,
56+
priceStyle,
57+
style,
58+
} ) => {};
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import { registerBlockType } from '@wordpress/blocks';
5+
6+
/**
7+
* Internal dependencies
8+
*/
9+
import sharedConfig from '../shared/config';
10+
import edit from './block-new-edit';
11+
import { save } from './save';
12+
import attributes from './attributes-new';
13+
import { supports } from './supports';
14+
import {
15+
BLOCK_TITLE as title,
16+
BLOCK_ICON as icon,
17+
BLOCK_DESCRIPTION as description,
18+
} from './constants';
19+
20+
const { ancestor, ...configuration } = sharedConfig;
21+
22+
const blockConfig = {
23+
...configuration,
24+
apiVersion: 2,
25+
title,
26+
description,
27+
usesContext: [ 'postId', 'queryId' ],
28+
providesContext: {
29+
'woocommerce/isDescendentOfSingleProductTemplate':
30+
'isDescendentOfSingleProductTemplate',
31+
'woocommerce/isDescendentOfSingleProductBlock':
32+
'isDescendentOfSingleProductBlock',
33+
},
34+
icon: { src: icon },
35+
attributes,
36+
supports,
37+
edit,
38+
save,
39+
};
40+
41+
console.log( 'IN HERE - REGISTERING' );
42+
43+
registerBlockType( 'woocommerce/product-price', blockConfig );

assets/js/atomic/blocks/product-elements/price/inner-blocks/current-price/edit.tsx

Whitespace-only changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { Edit } from './edit';

assets/js/atomic/blocks/product-elements/price/inner-blocks/discount/edit.tsx

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* Internal dependencies
3+
*/
4+
import './original-price/index.ts';
5+
6+
export { BLOCK_NAME as originalPriceName } from './original-price/index';
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "woocommerce/original-price",
3+
"version": "1.0.0",
4+
"icon": "info",
5+
"title": "Original Price",
6+
"description": "Display the original price for the product",
7+
"category": "woocommerce",
8+
"keywords": [ "WooCommerce" ],
9+
"textdomain": "woo-gutenberg-products-block",
10+
"apiVersion": 2,
11+
"$schema": "https://schemas.wp.org/trunk/block.json"
12+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/**
2+
* External dependencies
3+
*/
4+
import type { HTMLAttributes } from 'react';
5+
import classnames from 'classnames';
6+
import { useStyleProps } from '@woocommerce/base-hooks';
7+
import { useInnerBlockLayoutContext } from '@woocommerce/shared-context';
8+
import ProductPrice from '@woocommerce/base-components/product-price';
9+
10+
/**
11+
* Internal dependencies
12+
*/
13+
import type { PriceProps } from '../../types';
14+
//import './style.scss';
15+
16+
type Props = PriceProps & HTMLAttributes< HTMLDivElement >;
17+
18+
const Block = ( {
19+
attributes,
20+
context,
21+
rawPrice,
22+
currency,
23+
}: Props ): JSX.Element | null => {
24+
const { className } = attributes;
25+
const { isDescendentOfSingleProductTemplate = false } = context || {};
26+
const { className: stylesClassName, style } = useStyleProps( attributes );
27+
const { parentClassName } = useInnerBlockLayoutContext();
28+
const wrapperClassName = classnames(
29+
'wc-block-product-price__original',
30+
className,
31+
{
32+
[ `${ parentClassName }__product-price` ]: parentClassName,
33+
},
34+
stylesClassName
35+
);
36+
if ( ! rawPrice && ! isDescendentOfSingleProductTemplate ) {
37+
return <ProductPrice className={ wrapperClassName } />;
38+
}
39+
40+
const pricePreview = '5000';
41+
const priceClassName = classnames( {
42+
[ `${ parentClassName }__product-original-price__value` ]:
43+
parentClassName,
44+
} );
45+
46+
return (
47+
<ProductPrice
48+
className={ wrapperClassName }
49+
style={ style }
50+
priceStyle={ style }
51+
priceClassName={ priceClassName }
52+
currency={ currency }
53+
price={
54+
isDescendentOfSingleProductTemplate ? pricePreview : rawPrice
55+
}
56+
/>
57+
);
58+
};
59+
60+
export default Block;

0 commit comments

Comments
 (0)