@propeller-commerce/propeller-v2-react-ui 0.18.0 → 0.19.0
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/CHANGELOG.md +84 -12
- package/dist/index.cjs +332 -214
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +94 -10
- package/dist/index.d.ts +94 -10
- package/dist/index.js +334 -216
- package/dist/index.js.map +1 -1
- package/dist/pure.cjs +16 -14
- package/dist/pure.cjs.map +1 -1
- package/dist/pure.d.cts +38 -1
- package/dist/pure.d.ts +38 -1
- package/dist/pure.js +17 -15
- package/dist/pure.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/pure.d.cts
CHANGED
|
@@ -252,9 +252,22 @@ interface OrderItemCardProps {
|
|
|
252
252
|
* This component is RSC-safe (no hooks, no context), so the host has to pass
|
|
253
253
|
* it — there is nothing to read it from. Without it a non-default storefront
|
|
254
254
|
* renders default-language names and, worse, default-language slugs in the
|
|
255
|
-
* links
|
|
255
|
+
* links.
|
|
256
256
|
*/
|
|
257
257
|
language?: string;
|
|
258
|
+
/**
|
|
259
|
+
* URL builders from the host's configuration. Supply them and the item link
|
|
260
|
+
* is generated the same way every other link on the storefront is — which is
|
|
261
|
+
* what carries the locale prefix. Without it the component falls back to a
|
|
262
|
+
* bare `/product/:id/:slug`, and on a prefixed storefront that link drops the
|
|
263
|
+
* visitor onto the default language.
|
|
264
|
+
*/
|
|
265
|
+
configuration?: {
|
|
266
|
+
urls?: {
|
|
267
|
+
getProductUrl?: (product: Product, language?: string) => string;
|
|
268
|
+
getClusterUrl?: (cluster: Cluster, language?: string) => string;
|
|
269
|
+
};
|
|
270
|
+
};
|
|
258
271
|
/** Should the item title be a link to the PDP */
|
|
259
272
|
titleLinkable?: boolean;
|
|
260
273
|
/** Display a small thumbnail of the order item */
|
|
@@ -297,6 +310,12 @@ declare function OrderItemCard(props: OrderItemCardProps): React.JSX.Element;
|
|
|
297
310
|
*/
|
|
298
311
|
|
|
299
312
|
interface OrderSummaryProps {
|
|
313
|
+
/**
|
|
314
|
+
* Storefront language ('EN', 'NL', …). Decides the number format prices are
|
|
315
|
+
* rendered in — without it they fall back to Dutch separators regardless of
|
|
316
|
+
* the language the shopper is reading.
|
|
317
|
+
*/
|
|
318
|
+
language?: string;
|
|
300
319
|
/** The order object from propeller-sdk-v2 */
|
|
301
320
|
order: any;
|
|
302
321
|
/** The CSS class for the order summary container */
|
|
@@ -360,6 +379,12 @@ declare function OrderSummary(props: OrderSummaryProps): React.JSX.Element;
|
|
|
360
379
|
*/
|
|
361
380
|
|
|
362
381
|
interface OrderTotalsProps {
|
|
382
|
+
/**
|
|
383
|
+
* Storefront language ('EN', 'NL', …). Decides the number format prices are
|
|
384
|
+
* rendered in — without it they fall back to Dutch separators regardless of
|
|
385
|
+
* the language the shopper is reading.
|
|
386
|
+
*/
|
|
387
|
+
language?: string;
|
|
363
388
|
/** The order/quote used to populate the summary data */
|
|
364
389
|
order: Order;
|
|
365
390
|
/** Order summary block title */
|
|
@@ -397,6 +422,12 @@ declare function OrderTotals(props: OrderTotalsProps): React.JSX.Element;
|
|
|
397
422
|
*/
|
|
398
423
|
|
|
399
424
|
interface ProductBulkPricesProps {
|
|
425
|
+
/**
|
|
426
|
+
* Storefront language ('EN', 'NL', …). Decides the number format prices are
|
|
427
|
+
* rendered in — without it they fall back to Dutch separators regardless of
|
|
428
|
+
* the language the shopper is reading.
|
|
429
|
+
*/
|
|
430
|
+
language?: string;
|
|
400
431
|
/**
|
|
401
432
|
* Bulk price tiers from the product.
|
|
402
433
|
* Obtain from `product.bulkPrices`.
|
|
@@ -473,6 +504,12 @@ declare function ProductDownloads(props: ProductDownloadsProps): React.JSX.Eleme
|
|
|
473
504
|
*/
|
|
474
505
|
|
|
475
506
|
interface ProductPriceProps {
|
|
507
|
+
/**
|
|
508
|
+
* Storefront language ('EN', 'NL', …). Decides the number format prices are
|
|
509
|
+
* rendered in — without it they fall back to Dutch separators regardless of
|
|
510
|
+
* the language the shopper is reading.
|
|
511
|
+
*/
|
|
512
|
+
language?: string;
|
|
476
513
|
/**
|
|
477
514
|
* ProductPrice object from the product.
|
|
478
515
|
* Obtain from `product.price`.
|
package/dist/pure.d.ts
CHANGED
|
@@ -252,9 +252,22 @@ interface OrderItemCardProps {
|
|
|
252
252
|
* This component is RSC-safe (no hooks, no context), so the host has to pass
|
|
253
253
|
* it — there is nothing to read it from. Without it a non-default storefront
|
|
254
254
|
* renders default-language names and, worse, default-language slugs in the
|
|
255
|
-
* links
|
|
255
|
+
* links.
|
|
256
256
|
*/
|
|
257
257
|
language?: string;
|
|
258
|
+
/**
|
|
259
|
+
* URL builders from the host's configuration. Supply them and the item link
|
|
260
|
+
* is generated the same way every other link on the storefront is — which is
|
|
261
|
+
* what carries the locale prefix. Without it the component falls back to a
|
|
262
|
+
* bare `/product/:id/:slug`, and on a prefixed storefront that link drops the
|
|
263
|
+
* visitor onto the default language.
|
|
264
|
+
*/
|
|
265
|
+
configuration?: {
|
|
266
|
+
urls?: {
|
|
267
|
+
getProductUrl?: (product: Product, language?: string) => string;
|
|
268
|
+
getClusterUrl?: (cluster: Cluster, language?: string) => string;
|
|
269
|
+
};
|
|
270
|
+
};
|
|
258
271
|
/** Should the item title be a link to the PDP */
|
|
259
272
|
titleLinkable?: boolean;
|
|
260
273
|
/** Display a small thumbnail of the order item */
|
|
@@ -297,6 +310,12 @@ declare function OrderItemCard(props: OrderItemCardProps): React.JSX.Element;
|
|
|
297
310
|
*/
|
|
298
311
|
|
|
299
312
|
interface OrderSummaryProps {
|
|
313
|
+
/**
|
|
314
|
+
* Storefront language ('EN', 'NL', …). Decides the number format prices are
|
|
315
|
+
* rendered in — without it they fall back to Dutch separators regardless of
|
|
316
|
+
* the language the shopper is reading.
|
|
317
|
+
*/
|
|
318
|
+
language?: string;
|
|
300
319
|
/** The order object from propeller-sdk-v2 */
|
|
301
320
|
order: any;
|
|
302
321
|
/** The CSS class for the order summary container */
|
|
@@ -360,6 +379,12 @@ declare function OrderSummary(props: OrderSummaryProps): React.JSX.Element;
|
|
|
360
379
|
*/
|
|
361
380
|
|
|
362
381
|
interface OrderTotalsProps {
|
|
382
|
+
/**
|
|
383
|
+
* Storefront language ('EN', 'NL', …). Decides the number format prices are
|
|
384
|
+
* rendered in — without it they fall back to Dutch separators regardless of
|
|
385
|
+
* the language the shopper is reading.
|
|
386
|
+
*/
|
|
387
|
+
language?: string;
|
|
363
388
|
/** The order/quote used to populate the summary data */
|
|
364
389
|
order: Order;
|
|
365
390
|
/** Order summary block title */
|
|
@@ -397,6 +422,12 @@ declare function OrderTotals(props: OrderTotalsProps): React.JSX.Element;
|
|
|
397
422
|
*/
|
|
398
423
|
|
|
399
424
|
interface ProductBulkPricesProps {
|
|
425
|
+
/**
|
|
426
|
+
* Storefront language ('EN', 'NL', …). Decides the number format prices are
|
|
427
|
+
* rendered in — without it they fall back to Dutch separators regardless of
|
|
428
|
+
* the language the shopper is reading.
|
|
429
|
+
*/
|
|
430
|
+
language?: string;
|
|
400
431
|
/**
|
|
401
432
|
* Bulk price tiers from the product.
|
|
402
433
|
* Obtain from `product.bulkPrices`.
|
|
@@ -473,6 +504,12 @@ declare function ProductDownloads(props: ProductDownloadsProps): React.JSX.Eleme
|
|
|
473
504
|
*/
|
|
474
505
|
|
|
475
506
|
interface ProductPriceProps {
|
|
507
|
+
/**
|
|
508
|
+
* Storefront language ('EN', 'NL', …). Decides the number format prices are
|
|
509
|
+
* rendered in — without it they fall back to Dutch separators regardless of
|
|
510
|
+
* the language the shopper is reading.
|
|
511
|
+
*/
|
|
512
|
+
language?: string;
|
|
476
513
|
/**
|
|
477
514
|
* ProductPrice object from the product.
|
|
478
515
|
* Obtain from `product.price`.
|
package/dist/pure.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { buildClusterJsonLd, safeJsonStringify, buildItemListJsonLd, buildProductJsonLd, getLabel, getLocalizedValue, isContentHidden, formatPrice, getCountryName } from '@propeller-commerce/propeller-v2-core-ui';
|
|
1
|
+
import { buildClusterJsonLd, safeJsonStringify, buildItemListJsonLd, buildProductJsonLd, getLabel, getLocalizedValue, isContentHidden, formatPrice, localeForLanguage, getCountryName } from '@propeller-commerce/propeller-v2-core-ui';
|
|
2
2
|
import { clsx } from 'clsx';
|
|
3
3
|
import { twMerge } from 'tailwind-merge';
|
|
4
4
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
@@ -247,20 +247,21 @@ var ItemStock_default = React.memo(ItemStock);
|
|
|
247
247
|
function getProductName(orderItem, language) {
|
|
248
248
|
return getLocalizedValue(orderItem?.product?.names, language, "") || orderItem?.name || "Unknown Product";
|
|
249
249
|
}
|
|
250
|
-
function getClusterUrl(orderItem, language) {
|
|
250
|
+
function getClusterUrl(orderItem, language, urls) {
|
|
251
251
|
const cluster = orderItem?.product?.cluster;
|
|
252
252
|
if (!cluster) return "";
|
|
253
253
|
const id = cluster.clusterId;
|
|
254
254
|
const slug = getLocalizedValue(cluster.slugs, language, "");
|
|
255
255
|
if (!id || !slug) return "";
|
|
256
|
-
return `/cluster/${id}/${slug}`;
|
|
256
|
+
return urls?.getClusterUrl?.(cluster, language) || `/cluster/${id}/${slug}`;
|
|
257
257
|
}
|
|
258
|
-
function getProductUrl(orderItem, language) {
|
|
259
|
-
const cu = getClusterUrl(orderItem, language);
|
|
258
|
+
function getProductUrl(orderItem, language, urls) {
|
|
259
|
+
const cu = getClusterUrl(orderItem, language, urls);
|
|
260
260
|
if (cu) return cu;
|
|
261
|
-
const
|
|
262
|
-
const
|
|
263
|
-
|
|
261
|
+
const product = orderItem?.product;
|
|
262
|
+
const id = product?.productId;
|
|
263
|
+
const slug = getLocalizedValue(product?.slugs, language, "");
|
|
264
|
+
if (id && slug) return urls?.getProductUrl?.(product, language) || `/product/${id}/${slug}`;
|
|
264
265
|
return "";
|
|
265
266
|
}
|
|
266
267
|
function OrderItemCard(props) {
|
|
@@ -277,7 +278,7 @@ function OrderItemCard(props) {
|
|
|
277
278
|
const productName = getProductName(item, props.language);
|
|
278
279
|
const productSku = item?.product?.sku || item?.sku || "";
|
|
279
280
|
const productImage = item?.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
|
|
280
|
-
const productUrl = getProductUrl(item, props.language);
|
|
281
|
+
const productUrl = getProductUrl(item, props.language, props.configuration?.urls);
|
|
281
282
|
const quantity = item?.quantity || 0;
|
|
282
283
|
const priceTotal = item?.priceTotal || 0;
|
|
283
284
|
const discount = item?.discount || 0;
|
|
@@ -290,7 +291,7 @@ function OrderItemCard(props) {
|
|
|
290
291
|
return props.formatPrice(price);
|
|
291
292
|
}
|
|
292
293
|
if (!price && price !== 0) return "-";
|
|
293
|
-
return formatPrice(price, { symbol: props.currency ?? "\u20AC" });
|
|
294
|
+
return formatPrice(price, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
|
|
294
295
|
}
|
|
295
296
|
const discountDisplay = discountPercentage > 0 ? `${formatItemPrice(discount)} (${discountPercentage.toFixed(2).replace(".", ",")}%)` : formatItemPrice(discount);
|
|
296
297
|
return /* @__PURE__ */ jsxs("tbody", { className: "propeller-order-item-card", children: [
|
|
@@ -431,7 +432,7 @@ function OrderSummary(props) {
|
|
|
431
432
|
if (props.formatPrice) {
|
|
432
433
|
return props.formatPrice(price);
|
|
433
434
|
}
|
|
434
|
-
return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
|
|
435
|
+
return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
|
|
435
436
|
}
|
|
436
437
|
function numericDate(dateString) {
|
|
437
438
|
const d = new Date(dateString);
|
|
@@ -539,7 +540,7 @@ function OrderTotals(props) {
|
|
|
539
540
|
const postageData = props.order?.postageData;
|
|
540
541
|
function formatItemPrice(price) {
|
|
541
542
|
if (props.formatPrice) return props.formatPrice(price);
|
|
542
|
-
return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
|
|
543
|
+
return formatPrice(price || 0, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
|
|
543
544
|
}
|
|
544
545
|
const subtotal = total?.gross || 0;
|
|
545
546
|
const hasDiscount = !!total && total.discountType !== OrderDiscountType.N && total.discountValue > 0;
|
|
@@ -667,7 +668,7 @@ function ProductBulkPrices(props) {
|
|
|
667
668
|
function getPrice(tier) {
|
|
668
669
|
const value = includeTax ? tier.net : tier.gross;
|
|
669
670
|
if (value === null || value === void 0) return "";
|
|
670
|
-
return formatPrice(value, { symbol: props.currency ?? "\u20AC" });
|
|
671
|
+
return formatPrice(value, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
|
|
671
672
|
}
|
|
672
673
|
function getQuantityLabel(tier, index) {
|
|
673
674
|
const discount = tier.discount;
|
|
@@ -678,13 +679,14 @@ function ProductBulkPrices(props) {
|
|
|
678
679
|
if (nextQty) return `${qty}\u2013${nextQty - 1}`;
|
|
679
680
|
return `${qty}+`;
|
|
680
681
|
}
|
|
682
|
+
const title = props.labels?.title ?? "Volume pricing";
|
|
681
683
|
return /* @__PURE__ */ jsx(Fragment, { children: !isHidden && hasItems ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
|
|
682
684
|
"div",
|
|
683
685
|
{
|
|
684
686
|
className: cn(`propeller-product-bulk-prices ${props.className || ""}`),
|
|
685
687
|
"data-include-tax": includeTax ? "true" : "false",
|
|
686
688
|
children: [
|
|
687
|
-
|
|
689
|
+
title ? /* @__PURE__ */ jsx("h3", { className: "propeller-product-bulk-prices__title text-base font-semibold text-foreground mb-3", children: title }) : null,
|
|
688
690
|
/* @__PURE__ */ jsx("div", { className: "propeller-product-bulk-prices__table-wrapper overflow-hidden rounded-container border border-border", children: /* @__PURE__ */ jsxs("table", { className: "propeller-product-bulk-prices__table w-full text-sm", children: [
|
|
689
691
|
/* @__PURE__ */ jsx("thead", { className: "propeller-product-bulk-prices__thead bg-muted/50", children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
690
692
|
/* @__PURE__ */ jsx("th", { className: "propeller-product-bulk-prices__th propeller-product-bulk-prices__th--quantity px-4 py-2 text-left font-medium text-muted-foreground", children: getLabel(props.labels, "quantityFrom", "Qty from") }),
|
|
@@ -781,7 +783,7 @@ function ProductPriceDisplay(props) {
|
|
|
781
783
|
}
|
|
782
784
|
function formatPrice5(value) {
|
|
783
785
|
if (value === null || value === void 0) return "";
|
|
784
|
-
return formatPrice(value, { symbol: props.currency ?? "\u20AC" });
|
|
786
|
+
return formatPrice(value, { symbol: props.currency ?? "\u20AC", locale: localeForLanguage(props.language) });
|
|
785
787
|
}
|
|
786
788
|
function getOptionsTotal(useNet) {
|
|
787
789
|
const options = props.options || [];
|