@propeller-commerce/propeller-v2-react-ui 0.4.22 → 0.4.24

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 CHANGED
@@ -8,6 +8,48 @@ once it reaches 1.0. Until then (the `0.x` line) the public API may change
8
8
  between minor versions; breaking changes are called out below and in
9
9
  [MIGRATION.md](./MIGRATION.md).
10
10
 
11
+ ## [0.4.24] - 2026-07-20
12
+
13
+ ### Fixed
14
+
15
+ - **Date formatting**: `OrderList`, `OrderSummary`, `CartOverview`,
16
+ `OrderShipments`, `PurchaseAuthorizationRequests`, `FavoriteLists` rendered
17
+ dates via locale-less/`'en-US'` `toLocaleDateString` (US M/D/YYYY) or an
18
+ inconsistent `D.M.YYYY` — Dutch readers misparse M/D by months. All now use a
19
+ consistent numeric `DD-MM-YYYY` fallback (still overridable via
20
+ `props.formatDate`).
21
+ - `CartIconAndSidebar`: new `cartItemLabels` prop, forwarded to the mini-cart's
22
+ inner `CartItem` rows so the line labels (e.g. the `qtyPrefix` "Aantal:")
23
+ localize; previously they fell back to English ("Qty:").
24
+ - `CartPaymethods`: new `paymethodLabels` prop — a code→localized-name map so
25
+ the host can override un-localized backend method names (e.g. "On pickup"→
26
+ "Bij afhalen"). Lookup: `paymethodLabels[code]` → `method.name` → `method.code`.
27
+
28
+ ## [0.4.23] - 2026-07-17
29
+
30
+ ### Fixed
31
+
32
+ - `SearchBar`: the autosuggest dropdown hardcoded `price.gross` (excl. VAT) and
33
+ ignored the Incl./Excl. toggle, under-quoting every product, and showed no
34
+ tax label. It now carries both net/gross, picks the leading price from
35
+ `includeTax` (resolved from `<PropellerProvider>`), and renders an
36
+ `incl./excl.` label — consistent with `ProductPrice`/PLP/PDP. New optional
37
+ props: `includeTax`, `priceLabels` (keys `inclTax`/`exclTax`).
38
+ - `CartIconAndSidebar`: the header mini-cart rendered line items excl. VAT
39
+ (`includeTax={false}`) while the total used `totalNet` (incl. VAT) and bonus
40
+ items were pinned incl. — the lines never reconciled with the total and none
41
+ followed the toggle. All three now share one `useTax` basis (from
42
+ `includeTax`), so lines, total, and bonus items agree and respect the toggle.
43
+
44
+ ### Changed
45
+
46
+ - `DeliveryDate`: weekday/month names in the quick-pick tiles now resolve via
47
+ `labels` (keys `day_0`…`day_6`, `month_0`…`month_11`; English fallback) so
48
+ they localize with the active locale instead of hardcoded English. New
49
+ optional `language` prop (resolved from `<PropellerProvider>`) sets the
50
+ native date-input's `lang`, localizing the browser calendar chrome
51
+ (month name, weekday headers, Today/Clear).
52
+
11
53
  ## [0.4.22] - 2026-07-17
12
54
 
13
55
  ### Fixed
package/dist/index.cjs CHANGED
@@ -6725,8 +6725,9 @@ function CartIconAndSidebar(rawProps) {
6725
6725
  (sum, item) => sum + item.quantity,
6726
6726
  0
6727
6727
  );
6728
- const totalNet = props.cart?.total?.totalNet;
6729
- const totalPrice = totalNet === void 0 || totalNet === null ? money(0) : money(totalNet);
6728
+ const useTax = !!props.includeTax;
6729
+ const totalRaw = useTax ? props.cart?.total?.totalNet : props.cart?.total?.totalGross;
6730
+ const totalPrice = totalRaw === void 0 || totalRaw === null ? money(0) : money(totalRaw);
6730
6731
  const sidebarTitle = props.cartSidebarTitle || props.labels?.["cartSidebarTitle"] || "Shopping cart";
6731
6732
  const purchaserPAC = findPurchaserPAC(props.user, props.companyId);
6732
6733
  const totalGross = props.cart?.total?.totalGross ?? 0;
@@ -6929,6 +6930,7 @@ function CartIconAndSidebar(rawProps) {
6929
6930
  language: props.language,
6930
6931
  configuration: props.configuration,
6931
6932
  companyId: props.companyId,
6933
+ labels: props.cartItemLabels,
6932
6934
  cardFrame: false,
6933
6935
  showDelete: false,
6934
6936
  readOnlyQuantity: true,
@@ -6936,7 +6938,7 @@ function CartIconAndSidebar(rawProps) {
6936
6938
  showCartItemNotesField: false,
6937
6939
  showCrossupsells: false,
6938
6940
  showStockComponent: false,
6939
- includeTax: false,
6941
+ includeTax: useTax,
6940
6942
  className: "propeller-cart-icon__item",
6941
6943
  children: [
6942
6944
  /* @__PURE__ */ jsxRuntime.jsx(CartItem_default.Image, { className: "w-20 h-20 flex-shrink-0 bg-surface-hover rounded-control overflow-hidden border border-border-subtle" }),
@@ -6957,7 +6959,7 @@ function CartIconAndSidebar(rawProps) {
6957
6959
  },
6958
6960
  item.itemId
6959
6961
  )) }),
6960
- /* @__PURE__ */ jsxRuntime.jsx(CartBonusItemsImpl, { cart: props.cart, includeTax: true, className: "mt-4" })
6962
+ /* @__PURE__ */ jsxRuntime.jsx(CartBonusItemsImpl, { cart: props.cart, includeTax: useTax, className: "mt-4" })
6961
6963
  ] }),
6962
6964
  " ",
6963
6965
  items.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-cart-icon__sidebar-footer px-5 py-4 border-t border-border space-y-3 bg-surface-hover", children: [
@@ -7034,11 +7036,11 @@ function CartOverview(props) {
7034
7036
  function requestDate() {
7035
7037
  const date = props.cart?.postageData?.requestDate;
7036
7038
  if (!date) return "";
7037
- try {
7038
- return new Date(date).toLocaleDateString();
7039
- } catch {
7040
- return date;
7041
- }
7039
+ const d = new Date(date);
7040
+ if (isNaN(d.getTime())) return date;
7041
+ const day = String(d.getDate()).padStart(2, "0");
7042
+ const month = String(d.getMonth() + 1).padStart(2, "0");
7043
+ return `${day}-${month}-${d.getFullYear()}`;
7042
7044
  }
7043
7045
  function handleTermsLinkClick(event) {
7044
7046
  event.preventDefault();
@@ -7201,6 +7203,10 @@ function CartPaymethods(rawProps) {
7201
7203
  if (props.formatPrice) return props.formatPrice(price);
7202
7204
  return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
7203
7205
  }
7206
+ function methodName(method) {
7207
+ const code = (method.code || "").toLowerCase();
7208
+ return props.paymethodLabels?.[code] || method.name || method.code || "";
7209
+ }
7204
7210
  function handleSelect(method) {
7205
7211
  setSelectedCode(method.code);
7206
7212
  if (props.onPaymethodSelect) props.onPaymethodSelect(method);
@@ -7231,10 +7237,10 @@ function CartPaymethods(rawProps) {
7231
7237
  {
7232
7238
  className: "propeller-cart-paymethods__method-logo max-h-10 max-w-[80%] w-auto object-contain",
7233
7239
  src: logoUrl,
7234
- alt: method.name || method.code
7240
+ alt: methodName(method)
7235
7241
  }
7236
7242
  ) }) : null,
7237
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-paymethods__method-name font-medium text-sm", children: method.name || method.code })
7243
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-paymethods__method-name font-medium text-sm", children: methodName(method) })
7238
7244
  ]
7239
7245
  },
7240
7246
  method.code
@@ -8400,7 +8406,8 @@ function computeUpcomingDates(count, skipWeekends) {
8400
8406
  }
8401
8407
  return days;
8402
8408
  }
8403
- function DeliveryDate(props) {
8409
+ function DeliveryDate(rawProps) {
8410
+ const props = useInfraProps(rawProps);
8404
8411
  const [selectedDate, setSelectedDate] = React6.useState("");
8405
8412
  const [modalOpen, setModalOpen] = React6.useState(false);
8406
8413
  const [customDateValue, setCustomDateValue] = React6.useState("");
@@ -8421,7 +8428,9 @@ function DeliveryDate(props) {
8421
8428
  if (!isoDate) return "";
8422
8429
  const date = new Date(isoDate);
8423
8430
  if (isNaN(date.getTime())) return "";
8424
- return `${WEEKDAYS[date.getDay()]}, ${MONTHS[date.getMonth()]} ${date.getDate()}`;
8431
+ const weekday = propellerV2CoreUi.getLabel(props.labels, `day_${date.getDay()}`, WEEKDAYS[date.getDay()]);
8432
+ const month = propellerV2CoreUi.getLabel(props.labels, `month_${date.getMonth()}`, MONTHS[date.getMonth()]);
8433
+ return `${weekday}, ${month} ${date.getDate()}`;
8425
8434
  }
8426
8435
  function handleSelect(isoDate) {
8427
8436
  setSelectedDate(isoDate);
@@ -8535,6 +8544,7 @@ function DeliveryDate(props) {
8535
8544
  "input",
8536
8545
  {
8537
8546
  type: "date",
8547
+ lang: props.language ? props.language.toLowerCase() : void 0,
8538
8548
  className: `propeller-delivery-date__input w-full border rounded-control px-3 py-2 text-sm focus:outline-none focus:ring-2 ${customDateError ? "border-destructive focus:ring-destructive focus:border-destructive" : "border-input focus:ring-secondary focus:border-secondary"}`,
8539
8549
  min: minDate,
8540
8550
  value: customDateValue,
@@ -9687,10 +9697,11 @@ function FavoriteLists(rawProps) {
9687
9697
  if (props.formatDate) return props.formatDate(dateString);
9688
9698
  if (!dateString) return "-";
9689
9699
  const d = new Date(dateString);
9700
+ if (isNaN(d.getTime())) return dateString;
9690
9701
  const day = String(d.getDate()).padStart(2, "0");
9691
9702
  const month = String(d.getMonth() + 1).padStart(2, "0");
9692
9703
  const year = d.getFullYear();
9693
- return `${day}/${month}/${year}`;
9704
+ return `${day}-${month}-${year}`;
9694
9705
  }
9695
9706
  function getProductCount(list) {
9696
9707
  const products = list.products;
@@ -11835,7 +11846,11 @@ function OrderList(rawProps) {
11835
11846
  function formatDate(dateString) {
11836
11847
  if (props.formatDate) return props.formatDate(dateString);
11837
11848
  if (!dateString) return "-";
11838
- return new Date(dateString).toLocaleDateString();
11849
+ const d = new Date(dateString);
11850
+ if (isNaN(d.getTime())) return dateString;
11851
+ const day = String(d.getDate()).padStart(2, "0");
11852
+ const month = String(d.getMonth() + 1).padStart(2, "0");
11853
+ return `${day}-${month}-${d.getFullYear()}`;
11839
11854
  }
11840
11855
  function formatPrice17(price) {
11841
11856
  if (props.formatPrice) return props.formatPrice(price);
@@ -12272,7 +12287,10 @@ function OrderShipments(props) {
12272
12287
  function formatDate(dateStr) {
12273
12288
  if (!dateStr) return "-";
12274
12289
  const d = new Date(dateStr);
12275
- return `${d.getDate()}.${d.getMonth() + 1}.${d.getFullYear()}`;
12290
+ if (isNaN(d.getTime())) return dateStr;
12291
+ const day = String(d.getDate()).padStart(2, "0");
12292
+ const month = String(d.getMonth() + 1).padStart(2, "0");
12293
+ return `${day}-${month}-${d.getFullYear()}`;
12276
12294
  }
12277
12295
  function getOrderItemForShipmentItem(shipmentItem) {
12278
12296
  if (!props.order?.items || !shipmentItem.orderItemId) return null;
@@ -12489,15 +12507,18 @@ function OrderSummary(props) {
12489
12507
  }
12490
12508
  return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
12491
12509
  }
12510
+ function numericDate(dateString) {
12511
+ const d = new Date(dateString);
12512
+ if (isNaN(d.getTime())) return dateString;
12513
+ const day = String(d.getDate()).padStart(2, "0");
12514
+ const month = String(d.getMonth() + 1).padStart(2, "0");
12515
+ return `${day}-${month}-${d.getFullYear()}`;
12516
+ }
12492
12517
  function formatOrderDate(dateString) {
12493
12518
  if (props.formatDate) {
12494
12519
  return props.formatDate(dateString);
12495
12520
  }
12496
- try {
12497
- return new Date(dateString).toLocaleDateString("en-US");
12498
- } catch {
12499
- return dateString;
12500
- }
12521
+ return numericDate(dateString);
12501
12522
  }
12502
12523
  const requestDateRaw = order?.postageData?.requestDate;
12503
12524
  let requestDate = "";
@@ -12505,11 +12526,7 @@ function OrderSummary(props) {
12505
12526
  if (props.formatDate) {
12506
12527
  requestDate = props.formatDate(requestDateRaw);
12507
12528
  } else {
12508
- try {
12509
- requestDate = new Date(requestDateRaw).toLocaleDateString("en-US");
12510
- } catch {
12511
- requestDate = requestDateRaw;
12512
- }
12529
+ requestDate = numericDate(requestDateRaw);
12513
12530
  }
12514
12531
  }
12515
12532
  const getCountryName = (code) => propellerV2CoreUi.getCountryName(code, props.countries);
@@ -15930,7 +15947,10 @@ function PurchaseAuthorizationRequests(rawProps) {
15930
15947
  if (props.formatDate) return props.formatDate(dateStr);
15931
15948
  if (!dateStr) return "-";
15932
15949
  const d = new Date(dateStr);
15933
- return `${d.getDate()}.${d.getMonth() + 1}.${d.getFullYear()}`;
15950
+ if (isNaN(d.getTime())) return dateStr;
15951
+ const day = String(d.getDate()).padStart(2, "0");
15952
+ const month = String(d.getMonth() + 1).padStart(2, "0");
15953
+ return `${day}-${month}-${d.getFullYear()}`;
15934
15954
  }
15935
15955
  function formatPrice17(price) {
15936
15956
  if (props.formatPrice) return props.formatPrice(price);
@@ -17147,11 +17167,17 @@ function mapToSearchBarResult(item) {
17147
17167
  const id = isCluster ? item.clusterId : item.productId;
17148
17168
  const slug = item.slugs?.[0]?.value || "";
17149
17169
  const url = isCluster ? "/cluster/" + id + "/" + slug : "/product/" + id + "/" + slug;
17170
+ const priceNet = displayItem?.price?.net || 0;
17171
+ const priceGross = displayItem?.price?.gross || 0;
17150
17172
  return {
17151
17173
  id,
17152
17174
  name: item.names?.[0]?.value || "Product",
17153
17175
  sku: item.sku || displayItem?.sku || "",
17154
- price: displayItem?.price?.gross || 0,
17176
+ // `price` stays the gross value for back-compat; the row picks net/gross
17177
+ // from the two explicit fields below per the toggle.
17178
+ price: priceGross,
17179
+ priceNet,
17180
+ priceGross,
17155
17181
  imageUrl: displayItem?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "",
17156
17182
  url,
17157
17183
  isCluster
@@ -17180,6 +17206,13 @@ function SearchBar(rawProps) {
17180
17206
  }
17181
17207
  return propellerV2CoreUi.formatPrice(price || 0, { symbol: props.currency ?? "\u20AC" });
17182
17208
  }
17209
+ const useTax = !!props.includeTax;
17210
+ function leadingPrice(result) {
17211
+ return useTax ? result.priceNet ?? result.price ?? 0 : result.priceGross ?? result.price ?? 0;
17212
+ }
17213
+ function priceTaxLabel() {
17214
+ return useTax ? propellerV2CoreUi.getLabel(props.priceLabels, "inclTax", "incl. VAT") : propellerV2CoreUi.getLabel(props.priceLabels, "exclTax", "excl. VAT");
17215
+ }
17183
17216
  function noImageUrl() {
17184
17217
  return props.noImageUrl || "";
17185
17218
  }
@@ -17298,7 +17331,10 @@ function SearchBar(rawProps) {
17298
17331
  result.sku
17299
17332
  ] }) : null
17300
17333
  ] }),
17301
- result.price !== void 0 && result.price !== null ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-search-bar__result-price text-sm font-semibold text-foreground flex-shrink-0", children: formatItemPrice(result.price) }) : null
17334
+ result.price !== void 0 && result.price !== null ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-search-bar__result-price text-sm font-semibold text-foreground flex-shrink-0 text-right", children: [
17335
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-search-bar__result-price-value", children: formatItemPrice(leadingPrice(result)) }),
17336
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-search-bar__result-price-label block text-xs font-normal text-muted-foreground", children: priceTaxLabel() })
17337
+ ] }) : null
17302
17338
  ]
17303
17339
  },
17304
17340
  result.id + "-" + index