2020-05-28 10:02:10 +00:00
|
|
|
/**
|
|
|
|
* External dependencies
|
|
|
|
*/
|
2022-12-22 07:23:11 +00:00
|
|
|
import { ProductResponseItem } from '@woocommerce/types';
|
2020-05-28 10:02:10 +00:00
|
|
|
import { createContext, useContext } from '@wordpress/element';
|
|
|
|
|
2020-07-22 12:20:54 +00:00
|
|
|
/**
|
|
|
|
* Default product shape matching API response.
|
|
|
|
*/
|
2022-12-22 07:23:11 +00:00
|
|
|
const defaultProductData: ProductResponseItem = {
|
2020-07-22 12:20:54 +00:00
|
|
|
id: 0,
|
|
|
|
name: '',
|
|
|
|
parent: 0,
|
|
|
|
type: 'simple',
|
|
|
|
variation: '',
|
|
|
|
permalink: '',
|
|
|
|
sku: '',
|
|
|
|
short_description: '',
|
|
|
|
description: '',
|
|
|
|
on_sale: false,
|
|
|
|
prices: {
|
|
|
|
currency_code: 'USD',
|
|
|
|
currency_symbol: '$',
|
|
|
|
currency_minor_unit: 2,
|
|
|
|
currency_decimal_separator: '.',
|
|
|
|
currency_thousand_separator: ',',
|
|
|
|
currency_prefix: '$',
|
|
|
|
currency_suffix: '',
|
|
|
|
price: '0',
|
|
|
|
regular_price: '0',
|
|
|
|
sale_price: '0',
|
|
|
|
price_range: null,
|
|
|
|
},
|
|
|
|
price_html: '',
|
|
|
|
average_rating: '0',
|
|
|
|
review_count: 0,
|
|
|
|
images: [],
|
|
|
|
categories: [],
|
|
|
|
tags: [],
|
|
|
|
attributes: [],
|
|
|
|
variations: [],
|
|
|
|
has_options: false,
|
|
|
|
is_purchasable: false,
|
|
|
|
is_in_stock: false,
|
|
|
|
is_on_backorder: false,
|
|
|
|
low_stock_remaining: null,
|
|
|
|
sold_individually: false,
|
|
|
|
add_to_cart: {
|
|
|
|
text: 'Add to cart',
|
|
|
|
description: 'Add to cart',
|
|
|
|
url: '',
|
2022-01-11 11:09:59 +00:00
|
|
|
minimum: 1,
|
|
|
|
maximum: 99,
|
|
|
|
multiple_of: 1,
|
2020-07-22 12:20:54 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2020-05-28 10:02:10 +00:00
|
|
|
/**
|
|
|
|
* This context is used to pass product data down to all children blocks in a given tree.
|
|
|
|
*
|
|
|
|
* @member {Object} ProductDataContext A react context object
|
|
|
|
*/
|
|
|
|
const ProductDataContext = createContext( {
|
2020-07-22 12:20:54 +00:00
|
|
|
product: defaultProductData,
|
|
|
|
hasContext: false,
|
2022-09-01 13:13:19 +00:00
|
|
|
isLoading: false,
|
2020-05-28 10:02:10 +00:00
|
|
|
} );
|
|
|
|
|
2020-06-02 11:14:46 +00:00
|
|
|
export const useProductDataContext = () => useContext( ProductDataContext );
|
2020-05-28 10:02:10 +00:00
|
|
|
|
2022-12-22 07:23:11 +00:00
|
|
|
interface ProductDataContextProviderProps {
|
|
|
|
product: ProductResponseItem | null;
|
|
|
|
isLoading: boolean;
|
|
|
|
children: React.ReactNode;
|
|
|
|
}
|
|
|
|
|
2022-09-21 06:04:15 +00:00
|
|
|
/**
|
|
|
|
* This context is used to pass product data down to all children blocks in a given tree.
|
|
|
|
*
|
|
|
|
* @param {Object} object A react context object
|
|
|
|
* @param {any|null} object.product The product data to be passed down
|
|
|
|
* @param {Object} object.children The product data to be passed down
|
|
|
|
* @param {boolean} object.isLoading The product data to be passed down
|
|
|
|
*/
|
2020-07-22 12:20:54 +00:00
|
|
|
export const ProductDataContextProvider = ( {
|
|
|
|
product = null,
|
|
|
|
children,
|
2022-09-01 13:13:19 +00:00
|
|
|
isLoading,
|
2022-12-22 07:23:11 +00:00
|
|
|
}: ProductDataContextProviderProps ) => {
|
2020-05-28 10:02:10 +00:00
|
|
|
const contextValue = {
|
2020-07-22 12:20:54 +00:00
|
|
|
product: product || defaultProductData,
|
2022-09-01 13:13:19 +00:00
|
|
|
isLoading,
|
2020-07-22 12:20:54 +00:00
|
|
|
hasContext: true,
|
2020-05-28 10:02:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return (
|
|
|
|
<ProductDataContext.Provider value={ contextValue }>
|
2020-07-22 12:20:54 +00:00
|
|
|
{ isLoading ? (
|
|
|
|
<div className="is-loading">{ children }</div>
|
|
|
|
) : (
|
|
|
|
children
|
|
|
|
) }
|
2020-05-28 10:02:10 +00:00
|
|
|
</ProductDataContext.Provider>
|
|
|
|
);
|
|
|
|
};
|