@riosst100/pwa-marketplace 2.1.4 → 2.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/componentOverrideMapping.js +7 -0
- package/src/components/FavoriteSeller/AddToListButton/addToListButton.js +54 -54
- package/src/components/FavoriteSeller/AddToListButton/addToListButton.module.css +17 -17
- package/src/components/FavoriteSeller/AddToListButton/index.js +1 -1
- package/src/components/FavoriteSeller/AddToListButton/useCommonToasts.js +33 -33
- package/src/components/FilterTop/CustomFilters/customFilters.js +130 -132
- package/src/components/FilterTop/filterTop.js +1 -8
- package/src/components/LinkToOtherStores/index.js +61 -0
- package/src/components/NonSportCardsSets/nonSportCardsSets.js +0 -2
- package/src/components/RFQ/index.js +6 -3
- package/src/components/SellerDetail/sellerDetail.js +18 -1
- package/src/components/SellerInformation/sellerInformation.js +5 -3
- package/src/components/SellerSocialMedia/index.js +96 -0
- package/src/overwrites/pagebuilder/lib/ContentTypes/Products/products.js +13 -0
- package/src/overwrites/peregrine/lib/talons/MagentoRoute/magentoRoute.gql.js +27 -0
- package/src/overwrites/peregrine/lib/talons/MagentoRoute/useMagentoRoute.js +193 -0
- package/src/overwrites/peregrine/lib/talons/ProductFullDetail/useProductFullDetail.js +48 -11
- package/src/overwrites/peregrine/lib/talons/ProductImageCarousel/useProductImageCarousel.js +77 -0
- package/src/overwrites/peregrine/lib/talons/ProductOptions/useOption.js +59 -0
- package/src/overwrites/peregrine/lib/talons/ProductOptions/useTile.js +47 -0
- package/src/overwrites/peregrine/lib/talons/RootComponents/Category/categoryFragments.gql.js +13 -0
- package/src/overwrites/peregrine/lib/talons/RootComponents/Product/product.gql.js +5 -2
- package/src/overwrites/peregrine/lib/talons/RootComponents/Product/productDetailFragment.gql.js +23 -0
- package/src/overwrites/peregrine/lib/talons/RootComponents/Product/useProduct.js +121 -0
- package/src/overwrites/venia-ui/lib/RootComponents/Category/categoryContent.js +0 -6
- package/src/overwrites/venia-ui/lib/components/AccountInformationPage/accountInformationPage.js +0 -1
- package/src/overwrites/venia-ui/lib/components/AccountInformationPage/editForm.js +0 -1
- package/src/overwrites/venia-ui/lib/components/Breadcrumbs/breadcrumbs.js +0 -3
- package/src/overwrites/venia-ui/lib/components/CheckoutPage/OrderSummary/orderSummary.js +0 -1
- package/src/overwrites/venia-ui/lib/components/Gallery/item.js +17 -3
- package/src/overwrites/venia-ui/lib/components/Price/price.js +113 -0
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/components/auctionDetail.js +1 -1
- package/src/overwrites/venia-ui/lib/components/ProductFullDetail/productFullDetail.js +107 -105
- package/src/overwrites/venia-ui/lib/components/ProductImageCarousel/carousel.js +3 -1
- package/src/overwrites/venia-ui/lib/components/ProductOptions/option.js +112 -0
- package/src/overwrites/venia-ui/lib/components/ProductOptions/option.module.css +30 -0
- package/src/overwrites/venia-ui/lib/components/ProductOptions/options.js +49 -0
- package/src/overwrites/venia-ui/lib/components/ProductOptions/tile.js +118 -0
- package/src/overwrites/venia-ui/lib/components/ProductOptions/tile.module.css +68 -0
- package/src/overwrites/venia-ui/lib/components/ProductOptions/tileList.js +78 -0
- package/src/overwrites/venia-ui/lib/components/ProductOptions/tileList.module.css +6 -0
- package/src/overwrites/venia-ui/lib/components/ProductOptions/tileList.shimmer.js +32 -0
- package/src/talons/CustomFilters/useCustomFilters.js +0 -2
- package/src/talons/FavoriteSeller/AddToListButton/addToListButton.gql.js +30 -30
- package/src/talons/FavoriteSeller/AddToListButton/useAddToFavoriteListButton.js +0 -1
- package/src/talons/LegoSets/useLegoSets.js +0 -5
- package/src/talons/TrainsSets/useTrainsSets.js +0 -3
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useCallback, useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
export const useTile = props => {
|
|
4
|
+
const { onClick, value_index, itemVariant, setHoveredMedia } = props;
|
|
5
|
+
|
|
6
|
+
const handleClick = useCallback(() => {
|
|
7
|
+
onClick(value_index);
|
|
8
|
+
}, [value_index, onClick]);
|
|
9
|
+
|
|
10
|
+
const handleMouseEnter = useCallback(() => {
|
|
11
|
+
var variantMedia = itemVariant
|
|
12
|
+
? itemVariant[0].product.media_gallery_entries
|
|
13
|
+
: null;
|
|
14
|
+
|
|
15
|
+
setHoveredMedia(variantMedia);
|
|
16
|
+
}, [setHoveredMedia, itemVariant, value_index]);
|
|
17
|
+
|
|
18
|
+
const handleMouseLeave = useCallback(() => {
|
|
19
|
+
setHoveredMedia(null);
|
|
20
|
+
}, [setHoveredMedia]);
|
|
21
|
+
|
|
22
|
+
const variantImg = useMemo(() => {
|
|
23
|
+
let variantImg = '';
|
|
24
|
+
if (itemVariant) {
|
|
25
|
+
if (itemVariant.length > 0) {
|
|
26
|
+
const firstVariant = itemVariant[0];
|
|
27
|
+
|
|
28
|
+
// Accessing media_gallery_entries
|
|
29
|
+
const mediaGalleryEntries = firstVariant.product.media_gallery_entries;
|
|
30
|
+
|
|
31
|
+
// Extracting file paths
|
|
32
|
+
const mediaFiles = mediaGalleryEntries.map(entry => entry.file);
|
|
33
|
+
variantImg = mediaFiles[0];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return variantImg;
|
|
37
|
+
}, [itemVariant]);
|
|
38
|
+
|
|
39
|
+
// const variantImg = "https://down-sg.img.susercontent.com/file/sg-11134207-7rbk0-lkkqr1dahoah2c";
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
handleClick,
|
|
43
|
+
handleMouseEnter,
|
|
44
|
+
handleMouseLeave,
|
|
45
|
+
variantImg
|
|
46
|
+
};
|
|
47
|
+
};
|
|
@@ -13,8 +13,11 @@ export const GET_STORE_CONFIG_DATA = gql`
|
|
|
13
13
|
`;
|
|
14
14
|
|
|
15
15
|
export const GET_PRODUCT_DETAIL_QUERY = gql`
|
|
16
|
-
query getProductDetailForProductPage($urlKey: String
|
|
17
|
-
products(
|
|
16
|
+
query getProductDetailForProductPage($urlKey: String!, $productPreviewToken: String) {
|
|
17
|
+
products(
|
|
18
|
+
product_preview_token: $productPreviewToken,
|
|
19
|
+
filter: { url_key: { eq: $urlKey } }
|
|
20
|
+
) {
|
|
18
21
|
items {
|
|
19
22
|
id
|
|
20
23
|
uid
|
package/src/overwrites/peregrine/lib/talons/RootComponents/Product/productDetailFragment.gql.js
CHANGED
|
@@ -10,6 +10,7 @@ export const ProductDetailsFragment = gql`
|
|
|
10
10
|
category_uid
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
|
+
link_to_other_stores
|
|
13
14
|
seller {
|
|
14
15
|
name
|
|
15
16
|
url_key
|
|
@@ -59,6 +60,19 @@ export const ProductDetailsFragment = gql`
|
|
|
59
60
|
amount_off
|
|
60
61
|
}
|
|
61
62
|
}
|
|
63
|
+
minimum_price {
|
|
64
|
+
final_price {
|
|
65
|
+
currency
|
|
66
|
+
value
|
|
67
|
+
}
|
|
68
|
+
regular_price {
|
|
69
|
+
currency
|
|
70
|
+
value
|
|
71
|
+
}
|
|
72
|
+
discount {
|
|
73
|
+
amount_off
|
|
74
|
+
}
|
|
75
|
+
}
|
|
62
76
|
}
|
|
63
77
|
sku
|
|
64
78
|
auction_data {
|
|
@@ -196,6 +210,15 @@ export const ProductDetailsFragment = gql`
|
|
|
196
210
|
amount_off
|
|
197
211
|
}
|
|
198
212
|
}
|
|
213
|
+
minimum_price {
|
|
214
|
+
final_price {
|
|
215
|
+
currency
|
|
216
|
+
value
|
|
217
|
+
}
|
|
218
|
+
discount {
|
|
219
|
+
amount_off
|
|
220
|
+
}
|
|
221
|
+
}
|
|
199
222
|
}
|
|
200
223
|
custom_attributes {
|
|
201
224
|
selected_attribute_options {
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { useQuery } from '@apollo/client';
|
|
2
|
+
import { useEffect, useMemo } from 'react';
|
|
3
|
+
import { useLocation } from 'react-router-dom';
|
|
4
|
+
import { useAppContext } from '@magento/peregrine/lib/context/app';
|
|
5
|
+
|
|
6
|
+
import mergeOperations from '@magento/peregrine/lib/util/shallowMerge';
|
|
7
|
+
import DEFAULT_OPERATIONS from './product.gql';
|
|
8
|
+
import { useEventingContext } from '@magento/peregrine/lib/context/eventing';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A [React Hook]{@link https://reactjs.org/docs/hooks-intro.html} that
|
|
12
|
+
* controls the logic for the Product Root Component.
|
|
13
|
+
*
|
|
14
|
+
* @kind function
|
|
15
|
+
*
|
|
16
|
+
* @param {object} props
|
|
17
|
+
* @param {Function} props.mapProduct - A function for updating products to the proper shape.
|
|
18
|
+
* @param {GraphQLAST} props.queries.getStoreConfigData - Fetches storeConfig product url suffix using a server query
|
|
19
|
+
* @param {GraphQLAST} props.queries.getProductQuery - Fetches product using a server query
|
|
20
|
+
*
|
|
21
|
+
* @returns {object} result
|
|
22
|
+
* @returns {Bool} result.error - Indicates a network error occurred.
|
|
23
|
+
* @returns {Bool} result.loading - Indicates the query is in flight.
|
|
24
|
+
* @returns {Bool} result.product - The product's details.
|
|
25
|
+
*/
|
|
26
|
+
export const useProduct = props => {
|
|
27
|
+
const { mapProduct } = props;
|
|
28
|
+
|
|
29
|
+
const operations = mergeOperations(DEFAULT_OPERATIONS, props.operations);
|
|
30
|
+
const { getStoreConfigData, getProductDetailQuery } = operations;
|
|
31
|
+
const { pathname, search } = useLocation();
|
|
32
|
+
const [
|
|
33
|
+
,
|
|
34
|
+
{
|
|
35
|
+
actions: { setPageLoading }
|
|
36
|
+
}
|
|
37
|
+
] = useAppContext();
|
|
38
|
+
|
|
39
|
+
const { data: storeConfigData } = useQuery(getStoreConfigData, {
|
|
40
|
+
fetchPolicy: 'cache-and-network',
|
|
41
|
+
nextFetchPolicy: 'cache-first'
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
const slug = pathname.split('/').pop();
|
|
45
|
+
const productUrlSuffix = storeConfigData?.storeConfig?.product_url_suffix;
|
|
46
|
+
const urlKey = productUrlSuffix ? slug.replace(productUrlSuffix, '') : slug;
|
|
47
|
+
|
|
48
|
+
const params = new URLSearchParams(search);
|
|
49
|
+
const productPreviewToken = params.get('preview');
|
|
50
|
+
|
|
51
|
+
const { error, loading, data } = useQuery(getProductDetailQuery, {
|
|
52
|
+
fetchPolicy: 'cache-and-network',
|
|
53
|
+
nextFetchPolicy: 'cache-first',
|
|
54
|
+
skip: !storeConfigData,
|
|
55
|
+
variables: {
|
|
56
|
+
urlKey,
|
|
57
|
+
productPreviewToken
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
const isBackgroundLoading = !!data && loading;
|
|
62
|
+
|
|
63
|
+
const product = useMemo(() => {
|
|
64
|
+
if (!data) {
|
|
65
|
+
// The product isn't in the cache and we don't have a response from GraphQL yet.
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Note: if a product is out of stock _and_ the backend specifies not to
|
|
70
|
+
// display OOS items, the items array will be empty.
|
|
71
|
+
|
|
72
|
+
// Only return the product that we queried for.
|
|
73
|
+
const product = data.products.items.find(
|
|
74
|
+
item => item.url_key === urlKey
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
if (!product) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
return mapProduct(product);
|
|
82
|
+
}, [data, mapProduct, urlKey]);
|
|
83
|
+
|
|
84
|
+
const [, { dispatch }] = useEventingContext();
|
|
85
|
+
|
|
86
|
+
// Update the page indicator if the GraphQL query is in flight.
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
setPageLoading(isBackgroundLoading);
|
|
89
|
+
}, [isBackgroundLoading, setPageLoading]);
|
|
90
|
+
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!error && !loading && product) {
|
|
93
|
+
dispatch({
|
|
94
|
+
type: 'PRODUCT_PAGE_VIEW',
|
|
95
|
+
payload: {
|
|
96
|
+
id: product.id,
|
|
97
|
+
name: product.name,
|
|
98
|
+
sku: product.sku,
|
|
99
|
+
currency_code:
|
|
100
|
+
product?.price_range?.maximum_price?.final_price
|
|
101
|
+
?.currency,
|
|
102
|
+
price: product.price,
|
|
103
|
+
price_range: {
|
|
104
|
+
maximum_price: {
|
|
105
|
+
final_price:
|
|
106
|
+
product?.price_range?.maximum_price?.final_price
|
|
107
|
+
?.value
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
url_key: product.url_key
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}, [error, loading, product, dispatch]);
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
error,
|
|
118
|
+
loading,
|
|
119
|
+
product
|
|
120
|
+
};
|
|
121
|
+
};
|
|
@@ -251,9 +251,6 @@ const CategoryContent = props => {
|
|
|
251
251
|
|
|
252
252
|
let isSingles = false;
|
|
253
253
|
|
|
254
|
-
// console.log(allActiveFilters)
|
|
255
|
-
|
|
256
|
-
// console.log(virtualCategoryFilters)
|
|
257
254
|
const urlKey = category?.url_key;
|
|
258
255
|
|
|
259
256
|
if (allActiveFilters && allActiveFilters.size > 0) {
|
|
@@ -281,9 +278,6 @@ const CategoryContent = props => {
|
|
|
281
278
|
|
|
282
279
|
const currentFilter = activeFilters && activeFilters.length ? activeFilters[activeFilters.length - 1].label : '';
|
|
283
280
|
|
|
284
|
-
// console.log(activeFilters.length)
|
|
285
|
-
// console.log(activeFilters.map(u => u.label).join(' - '))
|
|
286
|
-
|
|
287
281
|
let title = activeFilters && activeFilters.length ? (
|
|
288
282
|
activeFilters.length > 1 ?
|
|
289
283
|
activeFilters[activeFilters.length - 1].label
|
package/src/overwrites/venia-ui/lib/components/AccountInformationPage/accountInformationPage.js
CHANGED
|
@@ -34,7 +34,6 @@ const AccountInformationPage = props => {
|
|
|
34
34
|
recaptchaWidgetProps,
|
|
35
35
|
setShouldShowNewPassword,
|
|
36
36
|
} = talonProps;
|
|
37
|
-
console.log("🚀 ~ AccountInformationPage ~ talonProps:", talonProps)
|
|
38
37
|
const { formatMessage } = useIntl();
|
|
39
38
|
|
|
40
39
|
const errorMessage = loadDataError ? (
|
|
@@ -74,15 +74,12 @@ const Breadcrumbs = props => {
|
|
|
74
74
|
);
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
// console.log(currentFilter)
|
|
78
|
-
|
|
79
77
|
const filterBreadcrumbsElement = [];
|
|
80
78
|
|
|
81
79
|
const lastIndex = currentFilter ? currentFilter.length - 1 : 0;
|
|
82
80
|
// const filterpath = ;
|
|
83
81
|
|
|
84
82
|
currentFilter && currentFilter.length && currentFilter.map((filter, index) => {
|
|
85
|
-
console.log(filter)
|
|
86
83
|
currentProduct ? (
|
|
87
84
|
filterBreadcrumbsElement.push(
|
|
88
85
|
<>
|
|
@@ -7,7 +7,6 @@ import defaultClasses from './orderSummary.module.css';
|
|
|
7
7
|
|
|
8
8
|
const OrderSummary = props => {
|
|
9
9
|
const classes = useStyle(defaultClasses, props.classes);
|
|
10
|
-
console.log("🚀 ~ OrderSummary ~ props:", props)
|
|
11
10
|
return (
|
|
12
11
|
<div data-cy="OrderSummary-root" className={classes.root}>
|
|
13
12
|
<h2 aria-live="polite" className="text-[16px] font-medium mb-4">
|
|
@@ -81,7 +81,8 @@ const GalleryItem = props => {
|
|
|
81
81
|
|
|
82
82
|
// fallback to regular price when final price is unavailable
|
|
83
83
|
const priceSource =
|
|
84
|
-
price_range.
|
|
84
|
+
price_range.minimum_price?.final_price ||
|
|
85
|
+
price_range.minimum_price?.regular_price || price_range.maximum_price.final_price ||
|
|
85
86
|
price_range.maximum_price.regular_price;
|
|
86
87
|
|
|
87
88
|
// Hide the Rating component until it is updated with the new look and feel (PWA-2512).
|
|
@@ -144,12 +145,12 @@ const GalleryItem = props => {
|
|
|
144
145
|
currencyCode={priceSource.currency}
|
|
145
146
|
/>
|
|
146
147
|
</p>
|
|
147
|
-
<p className='old-price text-gray-400 text-xs line-through font-normal !mb-0'>
|
|
148
|
+
{/* <p className='old-price text-gray-400 text-xs line-through font-normal !mb-0'>
|
|
148
149
|
<Price
|
|
149
150
|
value={priceSource.value}
|
|
150
151
|
currencyCode={priceSource.currency}
|
|
151
152
|
/>
|
|
152
|
-
</p>
|
|
153
|
+
</p> */}
|
|
153
154
|
</div>
|
|
154
155
|
|
|
155
156
|
<div data-cy="GalleryItem-Rating" className={cn('flex gap-[5px] items-center mb-2')}>
|
|
@@ -212,6 +213,19 @@ GalleryItem.propTypes = {
|
|
|
212
213
|
discount: shape({
|
|
213
214
|
amount_off: number.isRequired
|
|
214
215
|
}).isRequired
|
|
216
|
+
}).isRequired,
|
|
217
|
+
minimum_price: shape({
|
|
218
|
+
final_price: shape({
|
|
219
|
+
value: number.isRequired,
|
|
220
|
+
currency: string.isRequired
|
|
221
|
+
}),
|
|
222
|
+
regular_price: shape({
|
|
223
|
+
value: number.isRequired,
|
|
224
|
+
currency: string.isRequired
|
|
225
|
+
}).isRequired,
|
|
226
|
+
discount: shape({
|
|
227
|
+
amount_off: number.isRequired
|
|
228
|
+
}).isRequired
|
|
215
229
|
}).isRequired
|
|
216
230
|
}).isRequired
|
|
217
231
|
}),
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React, { Fragment } from 'react';
|
|
2
|
+
import { number, string, shape } from 'prop-types';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
4
|
+
import patches from '@magento/peregrine/lib/util/intlPatches';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The **Price** component is used anywhere a price needs to be displayed.
|
|
8
|
+
*
|
|
9
|
+
* Formatting of prices and currency symbol selection is handled entirely by the ECMAScript Internationalization API available in modern browsers.
|
|
10
|
+
*
|
|
11
|
+
* A [polyfill][] is required for any JavaScript runtime that does not have [Intl.NumberFormat.prototype.formatToParts][].
|
|
12
|
+
*
|
|
13
|
+
* [polyfill]: https://www.npmjs.com/package/intl
|
|
14
|
+
* [Intl.NumberFormat.prototype.formatToParts]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat/formatToParts
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const Price = props => {
|
|
18
|
+
const { locale } = useIntl();
|
|
19
|
+
const { value, currencyCode, classes } = props;
|
|
20
|
+
|
|
21
|
+
// Check if the value contains " - "
|
|
22
|
+
if (typeof value === 'string' && value.includes(" - ")) {
|
|
23
|
+
const explodedValues = value.split(" - ");
|
|
24
|
+
const parts = patches.toParts.call(
|
|
25
|
+
new Intl.NumberFormat(locale, {
|
|
26
|
+
style: 'currency',
|
|
27
|
+
currency: currencyCode
|
|
28
|
+
}),
|
|
29
|
+
explodedValues[0]
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const children = parts.map((part, i) => {
|
|
33
|
+
const partClass = classes[part.type];
|
|
34
|
+
const key = `${i}-${part.value}`;
|
|
35
|
+
|
|
36
|
+
return (
|
|
37
|
+
<span key={key} className={partClass}>
|
|
38
|
+
{part.value}
|
|
39
|
+
</span>
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const parts2 = patches.toParts.call(
|
|
44
|
+
new Intl.NumberFormat(locale, {
|
|
45
|
+
style: 'currency',
|
|
46
|
+
currency: currencyCode
|
|
47
|
+
}),
|
|
48
|
+
explodedValues[1]
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const children2 = parts2.map((part, i) => {
|
|
52
|
+
const partClass = classes[part.type];
|
|
53
|
+
const key = `${i}-${part.value}`;
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<span key={key} className={partClass}>
|
|
57
|
+
{part.value}
|
|
58
|
+
</span>
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
return <Fragment>{children} - {children2}</Fragment>;
|
|
63
|
+
} else {
|
|
64
|
+
const parts = patches.toParts.call(
|
|
65
|
+
new Intl.NumberFormat(locale, {
|
|
66
|
+
style: 'currency',
|
|
67
|
+
currency: currencyCode
|
|
68
|
+
}),
|
|
69
|
+
value
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const children = parts.map((part, i) => {
|
|
73
|
+
const partClass = classes[part.type];
|
|
74
|
+
const key = `${i}-${part.value}`;
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<span key={key} className={partClass}>
|
|
78
|
+
{part.value}
|
|
79
|
+
</span>
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
return <Fragment>{children}</Fragment>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return null;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
Price.propTypes = {
|
|
90
|
+
/**
|
|
91
|
+
* Class names to use when styling this component
|
|
92
|
+
*/
|
|
93
|
+
classes: shape({
|
|
94
|
+
currency: string,
|
|
95
|
+
integer: string,
|
|
96
|
+
decimal: string,
|
|
97
|
+
fraction: string
|
|
98
|
+
}),
|
|
99
|
+
/**
|
|
100
|
+
* The numeric price
|
|
101
|
+
*/
|
|
102
|
+
value: number.isRequired,
|
|
103
|
+
/**
|
|
104
|
+
* A string with any of the currency code supported by Intl.NumberFormat
|
|
105
|
+
*/
|
|
106
|
+
currencyCode: string.isRequired
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
Price.defaultProps = {
|
|
110
|
+
classes: {}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export default Price;
|