@propeller-commerce/propeller-v2-react-ui 0.15.10 → 0.16.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 CHANGED
@@ -8,6 +8,73 @@ 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.16.0] - 2026-08-12
12
+
13
+ ### Fixed
14
+
15
+ - **Localized names and slugs ignored the storefront language (PWP-936 /
16
+ PWP-940).** A localized array carries one entry per authored language in
17
+ catalog order, so `names[0]` / `slugs[0]` is the catalog's DEFAULT language,
18
+ not the storefront's. Thirteen sites read index 0 unconditionally while
19
+ eleven others resolved by language correctly. Now all of them go through
20
+ `getLocalizedValue`, which prefers the active language and falls back to any
21
+ translation that has a value:
22
+ - `ClusterOptions` — option group and option product names (PWP-936)
23
+ - `FavoriteListItem`, `FavoriteListDetails` — product and cluster names
24
+ - `ItemsOverview` — item, bundle-leader, bundle-item and child-option names
25
+ - `ProductBundles` — bundle item names
26
+ - `OrderItemCard` — item name, child-item names, and **the cluster/product
27
+ slugs used to build the item's link**
28
+ - `SearchBar` — **the slug used to build each autosuggest result's link**
29
+
30
+ The three slug sites are the ones that actually broke: they emitted
31
+ default-language URLs on every non-default locale.
32
+ - **`useCart` never adopted a cart id that arrived after mount (PWP-938 /
33
+ PWP-937).** The id was seeded once with `useState(options.cartId || '')` and
34
+ only reassigned from the hook's own cart-creation path, so a component that
35
+ mounted before the cart resolved held `''` permanently. `CartIconAndSidebar`
36
+ renders in the header on the first paint of every page, so its "Request
37
+ authorization" button rendered enabled, fired, and returned `err('No cart')`
38
+ with nothing sent — the reported "cannot submit purchase request". The id is
39
+ now derived from the prop on every render. `processCart` was affected the
40
+ same way.
41
+
42
+ ### Changed
43
+
44
+ - **BREAKING (behavioural, hosts should act):** `OrderItemCard` gains a
45
+ `language` prop. The component is exported from the RSC-safe `/pure` entry
46
+ and reads no context by design, so a host that renders it directly must pass
47
+ `language` or it keeps resolving in the catalog's default language.
48
+ `OrderBonusItems` forwards its own resolved language automatically.
49
+ - `ClusterOptions` resolves `language` from `<PropellerProvider>` via
50
+ `useInfraProps`, like the other catalog components. Passing it explicitly
51
+ still wins.
52
+ - The favorites list's add-product button default now reads "Add product to
53
+ favorite list" instead of "Add product directly to this wishlist" (PWP-939).
54
+ Hosts that translate `FavoriteListDetails.addProductDirectly` should update
55
+ their own copy — "favorite list" is the agreed term, not "wishlist".
56
+
57
+ ## [0.15.11] - 2026-08-11
58
+
59
+ ### Fixed
60
+
61
+ - **Checkout step 3 opened with nothing selected on a fresh cart (PWP-934).**
62
+ `CartPaymethods` and `CartCarriers` only ever adopted a value the cart already
63
+ stored, so a cart that had never reached step 3 — every first order, and every
64
+ order after the cart is recreated — rendered both grids blank and refused to
65
+ continue until the user clicked. They now preselect the cart's stored option
66
+ when there is one and otherwise the first option offered, so Continue works
67
+ straight away. A stored value the backend no longer offers also falls back
68
+ instead of leaving an invisible selection.
69
+
70
+ ### Changed
71
+
72
+ - The active option is now derived from the cart rather than mirrored into state
73
+ by an effect, so it is present in the first render (including SSR) instead of
74
+ appearing after hydration. `onPaymethodSelect` / `onCarrierSelect` still fire
75
+ once for the preselection, so hosts that persist the choice — and price the
76
+ transaction costs off it — keep working unchanged.
77
+
11
78
  ## [0.15.10] - 2026-08-11
12
79
 
13
80
  ### Fixed
package/dist/index.cjs CHANGED
@@ -738,7 +738,8 @@ function useCart(options) {
738
738
  const { graphqlClient, user, companyId, configuration, onCartCreated } = options;
739
739
  const language = options.language || configuration?.language || "NL";
740
740
  const [cart, setCart] = React6.useState(null);
741
- const [cartId, setCartId] = React6.useState(options.cartId || "");
741
+ const [createdCartId, setCreatedCartId] = React6.useState("");
742
+ const cartId = options.cartId || createdCartId;
742
743
  const [loading, setLoading] = React6.useState(false);
743
744
  const [error, setError] = React6.useState(null);
744
745
  const notesTimers = React6.useRef({});
@@ -774,13 +775,13 @@ function useCart(options) {
774
775
  imageVariantFilters: configuration?.imageVariantFiltersSmall,
775
776
  onCartCreated: (c) => {
776
777
  setCart(c);
777
- setCartId(c.cartId);
778
+ setCreatedCartId(c.cartId);
778
779
  onCartCreated?.(c);
779
780
  }
780
781
  };
781
782
  const resolved = await initCart(config);
782
783
  setCart(resolved);
783
- setCartId(resolved.cartId);
784
+ setCreatedCartId(resolved.cartId);
784
785
  return resolved;
785
786
  }, [graphqlClient, user, companyId, language, configuration, onCartCreated]);
786
787
  const addItem = React6.useCallback(async (opts) => {
@@ -795,7 +796,7 @@ function useCart(options) {
795
796
  if (opts.onAddToCart) {
796
797
  const resultCart2 = opts.onAddToCart(opts.product, opts.cluster?.clusterId, opts.quantity, childItemInputs, opts.notes, opts.price);
797
798
  setCart(resultCart2);
798
- setCartId(resultCart2.cartId);
799
+ setCreatedCartId(resultCart2.cartId);
799
800
  const addedItem2 = resultCart2.items?.find((i) => i.productId === opts.product.productId) ?? null;
800
801
  opts.afterAddToCart?.(resultCart2, addedItem2);
801
802
  return propellerV2CoreUi.ok({ cart: resultCart2, item: addedItem2 });
@@ -816,7 +817,7 @@ function useCart(options) {
816
817
  imageVariantFilters: configuration?.imageVariantFiltersSmall
817
818
  });
818
819
  setCart(resultCart);
819
- setCartId(resultCart.cartId);
820
+ setCreatedCartId(resultCart.cartId);
820
821
  const addedItem = resultCart.items?.find((i) => i.productId === opts.product.productId) ?? null;
821
822
  opts.afterAddToCart?.(resultCart, addedItem);
822
823
  return propellerV2CoreUi.ok({ cart: resultCart, item: addedItem });
@@ -6427,6 +6428,12 @@ function CartBonusItems(rawProps) {
6427
6428
  ] });
6428
6429
  }
6429
6430
  var CartBonusItems_default = CartBonusItems;
6431
+
6432
+ // src/composables/shared/utils/preselect.ts
6433
+ function pickPreselected(items, stored, keyOf) {
6434
+ const list = items || [];
6435
+ return (stored ? list.find((item) => keyOf(item) === stored) : void 0) || list[0];
6436
+ }
6430
6437
  function CartCarriers(props) {
6431
6438
  const [selectedName, setSelectedName] = React6.useState("");
6432
6439
  const containerClass = props.carriersContainerClass || "cart-carriers";
@@ -6440,16 +6447,16 @@ function CartCarriers(props) {
6440
6447
  setSelectedName(carrier.name);
6441
6448
  if (props.onCarrierSelect) props.onCarrierSelect(carrier);
6442
6449
  }
6450
+ const preselected = pickPreselected(
6451
+ carriers,
6452
+ props.cart?.postageData?.carrier,
6453
+ (c) => c.name
6454
+ );
6455
+ const activeName = selectedName || preselected?.name || "";
6443
6456
  React6.useEffect(() => {
6444
- if (!selectedName && props.cart?.postageData?.carrier) {
6445
- const name = props.cart.postageData.carrier;
6446
- setSelectedName(name);
6447
- if (props.onCarrierSelect) {
6448
- const match = carriers.find((c) => c.name === name);
6449
- if (match) props.onCarrierSelect(match);
6450
- }
6451
- }
6452
- }, [props.cart, selectedName, props.onCarrierSelect, carriers, props]);
6457
+ if (selectedName || !preselected) return;
6458
+ if (props.onCarrierSelect) props.onCarrierSelect(preselected);
6459
+ }, [preselected?.name]);
6453
6460
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `propeller-cart-carriers ${containerClass}`, children: [
6454
6461
  carriers.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cart-carriers__grid grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3", children: carriers.map((carrier, index) => {
6455
6462
  const logoUrl = showLogo ? carrier.logo || "" : "";
@@ -6457,8 +6464,8 @@ function CartCarriers(props) {
6457
6464
  "div",
6458
6465
  {
6459
6466
  onClick: () => handleSelect(carrier),
6460
- "data-selected": selectedName === carrier.name ? "true" : "false",
6461
- className: `propeller-cart-carriers__carrier relative cursor-pointer border rounded-container p-3 flex flex-col items-center justify-center gap-2 text-center aspect-square transition-all ${selectedName === carrier.name ? "border-secondary bg-secondary/5 shadow-sm" : "border-border hover:border-secondary/30"}`,
6467
+ "data-selected": activeName === carrier.name ? "true" : "false",
6468
+ className: `propeller-cart-carriers__carrier relative cursor-pointer border rounded-container p-3 flex flex-col items-center justify-center gap-2 text-center aspect-square transition-all ${activeName === carrier.name ? "border-secondary bg-secondary/5 shadow-sm" : "border-border hover:border-secondary/30"}`,
6462
6469
  children: [
6463
6470
  props.showPrice !== false ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-carriers__carrier-price absolute top-2 right-2 text-xs bg-surface-hover text-muted-foreground px-2 py-0.5 rounded-full", children: formatCarrierPrice(carrier.price) }) : null,
6464
6471
  logoUrl ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-carriers__carrier-logo-wrap flex items-center justify-center h-10 w-full", children: /* @__PURE__ */ jsxRuntime.jsx("img", { className: "propeller-cart-carriers__carrier-logo max-h-10 max-w-[80%] w-auto object-contain", src: logoUrl, alt: carrier.name }) }) : null,
@@ -7762,16 +7769,16 @@ function CartPaymethods(rawProps) {
7762
7769
  setSelectedCode(method.code);
7763
7770
  if (props.onPaymethodSelect) props.onPaymethodSelect(method);
7764
7771
  }
7772
+ const preselected = pickPreselected(
7773
+ payMethods,
7774
+ props.cart?.paymentData?.method,
7775
+ (m) => m.code
7776
+ );
7777
+ const activeCode = selectedCode || preselected?.code || "";
7765
7778
  React6.useEffect(() => {
7766
- if (!selectedCode && props.cart?.paymentData?.method) {
7767
- const code = props.cart.paymentData.method;
7768
- setSelectedCode(code);
7769
- if (props.onPaymethodSelect) {
7770
- const match = payMethods.find((m) => m.code === code);
7771
- if (match) props.onPaymethodSelect(match);
7772
- }
7773
- }
7774
- }, [props.cart, selectedCode, props.onPaymethodSelect, payMethods, props]);
7779
+ if (selectedCode || !preselected) return;
7780
+ if (props.onPaymethodSelect) props.onPaymethodSelect(preselected);
7781
+ }, [preselected?.code]);
7775
7782
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `propeller-cart-paymethods ${containerClass}`, children: [
7776
7783
  payMethods.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-cart-paymethods__grid grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 gap-3", children: payMethods.map((method, index) => {
7777
7784
  const logoUrl = showLogo ? getLogoUrl(method) : "";
@@ -7779,8 +7786,8 @@ function CartPaymethods(rawProps) {
7779
7786
  "div",
7780
7787
  {
7781
7788
  onClick: () => handleSelect(method),
7782
- "data-selected": selectedCode === method.code ? "true" : "false",
7783
- className: `propeller-cart-paymethods__method relative cursor-pointer border rounded-container p-3 flex flex-col items-center justify-center gap-2 text-center aspect-square transition-all ${selectedCode === method.code ? "border-secondary bg-secondary/5 shadow-sm" : "border-border hover:border-secondary/30"}`,
7789
+ "data-selected": activeCode === method.code ? "true" : "false",
7790
+ className: `propeller-cart-paymethods__method relative cursor-pointer border rounded-container p-3 flex flex-col items-center justify-center gap-2 text-center aspect-square transition-all ${activeCode === method.code ? "border-secondary bg-secondary/5 shadow-sm" : "border-border hover:border-secondary/30"}`,
7784
7791
  children: [
7785
7792
  method.price > 0 ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-paymethods__method-price absolute top-2 right-2 text-xs bg-surface-hover text-muted-foreground px-2 py-0.5 rounded-full", children: formatMethodPrice(method.price) }) : null,
7786
7793
  logoUrl ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-cart-paymethods__method-logo-wrap flex items-center justify-center h-10 w-full", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -10809,8 +10816,8 @@ var ClusterInfo_default = ClusterInfo;
10809
10816
  function formatPrice9(price, currency) {
10810
10817
  return propellerV2CoreUi.formatPrice(price, { symbol: currency });
10811
10818
  }
10812
- function getProductName2(product) {
10813
- return product.names?.[0]?.value || `Product ${product.productId}`;
10819
+ function getProductName2(product, language) {
10820
+ return propellerV2CoreUi.getLocalizedValue(product.names, language, `Product ${product.productId}`);
10814
10821
  }
10815
10822
  function getProductImageUrl4(product) {
10816
10823
  const media = product.media;
@@ -10820,9 +10827,11 @@ function getProductImageUrl4(product) {
10820
10827
  }
10821
10828
  return "";
10822
10829
  }
10823
- function ClusterOptions(props) {
10830
+ function ClusterOptions(rawProps) {
10831
+ const props = useInfraProps(rawProps);
10824
10832
  const [selectedProductIds, setSelectedProductIds] = React6.useState({});
10825
10833
  function getOptionsForRender() {
10834
+ const language = props.language;
10826
10835
  const options = props.options || [];
10827
10836
  const sel = selectedProductIds;
10828
10837
  const hidePrices = propellerV2CoreUi.isContentHidden(props.portalMode, props.user);
@@ -10832,7 +10841,7 @@ function ClusterOptions(props) {
10832
10841
  const products = (option.products || []).map((p) => ({
10833
10842
  productId: p.productId,
10834
10843
  productIdStr: p.productId.toString(),
10835
- label: hidePrices ? getProductName2(p) : `${getProductName2(p)} \u2014 ${formatPrice9(p.price?.gross || 0, props.currency ?? "\u20AC")}`
10844
+ label: hidePrices ? getProductName2(p, language) : `${getProductName2(p, language)} \u2014 ${formatPrice9(p.price?.gross || 0, props.currency ?? "\u20AC")}`
10836
10845
  }));
10837
10846
  let previewImageUrl = "";
10838
10847
  let previewName = "";
@@ -10843,7 +10852,7 @@ function ClusterOptions(props) {
10843
10852
  );
10844
10853
  if (selectedProduct) {
10845
10854
  previewImageUrl = getProductImageUrl4(selectedProduct);
10846
- previewName = getProductName2(selectedProduct);
10855
+ previewName = getProductName2(selectedProduct, language);
10847
10856
  previewPrice = hidePrices ? "" : formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC");
10848
10857
  }
10849
10858
  }
@@ -10851,7 +10860,7 @@ function ClusterOptions(props) {
10851
10860
  return {
10852
10861
  id: option.id,
10853
10862
  idStr,
10854
- name: option.names?.[0]?.value || `Option ${option.id}`,
10863
+ name: propellerV2CoreUi.getLocalizedValue(option.names, language, `Option ${option.id}`),
10855
10864
  isRequired,
10856
10865
  selectedProductId,
10857
10866
  hasSelection: !!selectedProductId,
@@ -11319,7 +11328,8 @@ function FavoriteListItem(rawProps) {
11319
11328
  const isProduct = "productId" in props.item;
11320
11329
  const product = props.item;
11321
11330
  const cluster = props.item;
11322
- const name = isProduct ? product?.names?.[0]?.value || "Product" : cluster?.names?.[0]?.value || cluster?.defaultProduct?.names?.[0]?.value || "Cluster";
11331
+ const nameLanguage = props.language;
11332
+ const name = isProduct ? propellerV2CoreUi.getLocalizedValue(product?.names, nameLanguage, "Product") : propellerV2CoreUi.getLocalizedValue(cluster?.names, nameLanguage, "") || propellerV2CoreUi.getLocalizedValue(cluster?.defaultProduct?.names, nameLanguage, "Cluster");
11323
11333
  const sku = isProduct ? product?.sku || "" : cluster?.sku || cluster?.defaultProduct?.sku || "";
11324
11334
  const imageUrl = isProduct ? product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "" : cluster?.defaultProduct?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
11325
11335
  const itemUrl = isProduct ? props.configuration?.urls?.getProductUrl?.(props.item) || "" : props.configuration?.urls?.getClusterUrl?.(props.item) || "";
@@ -11753,9 +11763,10 @@ function FavoriteListDetails(rawProps) {
11753
11763
  }
11754
11764
  }
11755
11765
  function getSearchItemName(item) {
11756
- if ("productId" in item) return item.names?.[0]?.value || "Product";
11766
+ const language = props.language;
11767
+ if ("productId" in item) return propellerV2CoreUi.getLocalizedValue(item.names, language, "Product");
11757
11768
  const cluster = item;
11758
- return cluster.names?.[0]?.value || cluster.defaultProduct?.names?.[0]?.value || "Cluster";
11769
+ return propellerV2CoreUi.getLocalizedValue(cluster.names, language, "") || propellerV2CoreUi.getLocalizedValue(cluster.defaultProduct?.names, language, "Cluster");
11759
11770
  }
11760
11771
  function getSearchItemSku(item) {
11761
11772
  if ("productId" in item) return item.sku || "";
@@ -11998,7 +12009,7 @@ function FavoriteListDetails(rawProps) {
11998
12009
  type: "button",
11999
12010
  className: "propeller-favorite-list-details__add-btn inline-flex items-center justify-center rounded-control bg-secondary px-4 py-2 text-sm font-medium text-secondary-foreground transition-colors hover:bg-secondary/90",
12000
12011
  onClick: () => setShowAddModal(true),
12001
- children: propellerV2CoreUi.getLabel(props.labels, "addProductDirectly", "Add product directly to this wishlist")
12012
+ children: propellerV2CoreUi.getLabel(props.labels, "addProductDirectly", "Add product to favorite list")
12002
12013
  }
12003
12014
  ) }),
12004
12015
  allItems.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-favorite-list-details__empty border border-border rounded-container p-12 text-center space-y-4", children: [
@@ -12874,8 +12885,8 @@ function GridTitleWithProvider(rawProps) {
12874
12885
  return /* @__PURE__ */ jsxRuntime.jsx(GridTitle_default, { ...props });
12875
12886
  }
12876
12887
  var GridTitleWithProvider_default = GridTitleWithProvider;
12877
- function getItemName(item) {
12878
- return item.product?.names?.[0]?.value || "Product";
12888
+ function getItemName(item, language) {
12889
+ return propellerV2CoreUi.getLocalizedValue(item.product?.names, language, "Product");
12879
12890
  }
12880
12891
  function getItemImageUrl(item) {
12881
12892
  const url = item.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url;
@@ -12896,6 +12907,7 @@ function getBundleNonLeaders(item) {
12896
12907
  }
12897
12908
  function ItemsOverview(rawProps) {
12898
12909
  const props = useInfraProps(rawProps);
12910
+ const language = props.language;
12899
12911
  const useTax = !!props.includeTax;
12900
12912
  const containerClass = props.itemsOverviewContainerClass || "cart-items-overview";
12901
12913
  const itemNameClickable = props.itemNameClickable !== void 0 ? props.itemNameClickable : true;
@@ -12957,7 +12969,7 @@ function ItemsOverview(rawProps) {
12957
12969
  {
12958
12970
  className: "propeller-items-overview__item-image w-full h-full object-contain p-1.5",
12959
12971
  src: getItemImageUrl(item),
12960
- alt: getItemName(item)
12972
+ alt: getItemName(item, language)
12961
12973
  }
12962
12974
  ) : /* @__PURE__ */ jsxRuntime.jsx(
12963
12975
  "svg",
@@ -12985,7 +12997,7 @@ function ItemsOverview(rawProps) {
12985
12997
  ] }),
12986
12998
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-items-overview__item-bundle mt-1.5 space-y-1 border-l-2 border-secondary/10 pl-2", children: [
12987
12999
  leader ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-items-overview__item-bundle-leader flex justify-between items-center text-xs", children: [
12988
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: leader.product.names?.[0]?.value || "Product" }),
13000
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-foreground", children: propellerV2CoreUi.getLocalizedValue(leader.product.names, language, "Product") }),
12989
13001
  money(bundlePrice(leader.price)) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground whitespace-nowrap ml-2", children: money(bundlePrice(leader.price)) }) : null
12990
13002
  ] }) : null,
12991
13003
  getBundleNonLeaders(item).map((bundleItem, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
@@ -12993,7 +13005,7 @@ function ItemsOverview(rawProps) {
12993
13005
  {
12994
13006
  className: "propeller-items-overview__item-bundle-item flex justify-between items-center text-xs text-muted-foreground",
12995
13007
  children: [
12996
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: bundleItem.product?.names?.[0]?.value || "Product" }),
13008
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: propellerV2CoreUi.getLocalizedValue(bundleItem.product?.names, language, "Product") }),
12997
13009
  money(bundlePrice(bundleItem.price)) ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-subtle whitespace-nowrap ml-2", children: money(bundlePrice(bundleItem.price)) }) : null
12998
13010
  ]
12999
13011
  },
@@ -13014,9 +13026,9 @@ function ItemsOverview(rawProps) {
13014
13026
  {
13015
13027
  className: "propeller-items-overview__item-title font-medium text-sm leading-tight cursor-pointer hover:text-secondary transition-colors line-clamp-2",
13016
13028
  onClick: () => handleItemNameClick(item),
13017
- children: getItemName(item)
13029
+ children: getItemName(item, language)
13018
13030
  }
13019
- ) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-items-overview__item-title font-medium text-sm leading-tight line-clamp-2", children: getItemName(item) }),
13031
+ ) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-items-overview__item-title font-medium text-sm leading-tight line-clamp-2", children: getItemName(item, language) }),
13020
13032
  showPrice ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-items-overview__item-price font-semibold text-sm text-foreground whitespace-nowrap", children: formatItemPrice(lineTotal(item)) }) : null
13021
13033
  ] }),
13022
13034
  showSku && itemSku ? /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "propeller-items-overview__item-sku text-xs text-muted-foreground mt-0.5", children: [
@@ -13032,7 +13044,7 @@ function ItemsOverview(rawProps) {
13032
13044
  {
13033
13045
  className: "propeller-items-overview__item-option flex justify-between items-center text-xs text-muted-foreground",
13034
13046
  children: [
13035
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: child.product?.names?.[0]?.value || "Option" }),
13047
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: propellerV2CoreUi.getLocalizedValue(child.product?.names, language, "Option") }),
13036
13048
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-subtle whitespace-nowrap ml-2", children: formatItemPrice(lineTotal(child)) })
13037
13049
  ]
13038
13050
  },
@@ -13510,22 +13522,22 @@ function OrderActions(rawProps) {
13510
13522
  );
13511
13523
  }
13512
13524
  var OrderActions_default = OrderActions;
13513
- function getProductName3(orderItem) {
13514
- return orderItem?.product?.names?.[0]?.value || orderItem?.name || "Unknown Product";
13525
+ function getProductName3(orderItem, language) {
13526
+ return propellerV2CoreUi.getLocalizedValue(orderItem?.product?.names, language, "") || orderItem?.name || "Unknown Product";
13515
13527
  }
13516
- function getClusterUrl(orderItem) {
13528
+ function getClusterUrl(orderItem, language) {
13517
13529
  const cluster = orderItem?.product?.cluster;
13518
13530
  if (!cluster) return "";
13519
13531
  const id = cluster.clusterId;
13520
- const slug = cluster.slugs?.[0]?.value || "";
13532
+ const slug = propellerV2CoreUi.getLocalizedValue(cluster.slugs, language, "");
13521
13533
  if (!id || !slug) return "";
13522
13534
  return `/cluster/${id}/${slug}`;
13523
13535
  }
13524
- function getProductUrl(orderItem) {
13525
- const cu = getClusterUrl(orderItem);
13536
+ function getProductUrl(orderItem, language) {
13537
+ const cu = getClusterUrl(orderItem, language);
13526
13538
  if (cu) return cu;
13527
13539
  const id = orderItem?.product?.productId;
13528
- const slug = orderItem?.product?.slugs?.[0]?.value || "";
13540
+ const slug = propellerV2CoreUi.getLocalizedValue(orderItem?.product?.slugs, language, "");
13529
13541
  if (id && slug) return `/product/${id}/${slug}`;
13530
13542
  return "";
13531
13543
  }
@@ -13540,10 +13552,10 @@ function OrderItemCard(props) {
13540
13552
  const showDiscount = props.showDiscount !== void 0 ? props.showDiscount : false;
13541
13553
  const showStockComponent = props.showStockComponent !== void 0 ? props.showStockComponent : false;
13542
13554
  const showItemNotes = props.showItemNotes !== void 0 ? props.showItemNotes : false;
13543
- const productName = getProductName3(item);
13555
+ const productName = getProductName3(item, props.language);
13544
13556
  const productSku = item?.product?.sku || item?.sku || "";
13545
13557
  const productImage = item?.product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
13546
- const productUrl = getProductUrl(item);
13558
+ const productUrl = getProductUrl(item, props.language);
13547
13559
  const quantity = item?.quantity || 0;
13548
13560
  const priceTotal = item?.priceTotal || 0;
13549
13561
  const discount = item?.discount || 0;
@@ -13658,7 +13670,7 @@ function OrderItemCard(props) {
13658
13670
  className: "propeller-order-item-card__child-row border-0",
13659
13671
  "data-child": "true",
13660
13672
  children: [
13661
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--product px-6 py-2 pl-28", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-order-item-card__child-title text-sm text-muted-foreground", children: child.product?.names?.[0]?.value || child.name || "Unknown" }) }),
13673
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--product px-6 py-2 pl-28", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "propeller-order-item-card__child-title text-sm text-muted-foreground", children: propellerV2CoreUi.getLocalizedValue(child.product?.names, props.language, "") || child.name || "Unknown" }) }),
13662
13674
  showQuantity ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--quantity px-6 py-2 text-center text-sm text-muted-foreground", children: child.quantity || 0 }) : null,
13663
13675
  showDiscount ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--discount px-6 py-2 text-right text-sm text-muted-foreground" }) : null,
13664
13676
  showPrice ? /* @__PURE__ */ jsxRuntime.jsx("td", { className: "propeller-order-item-card__cell propeller-order-item-card__cell--price px-6 py-2 text-right whitespace-nowrap text-sm text-muted-foreground", children: formatItemPrice(child.priceTotal || 0) }) : null
@@ -13682,7 +13694,8 @@ function OrderBonusItems(rawProps) {
13682
13694
  {
13683
13695
  orderItem: item,
13684
13696
  titleLinkable: false,
13685
- currency: props.currency
13697
+ currency: props.currency,
13698
+ language: props.language
13686
13699
  },
13687
13700
  item.id
13688
13701
  )) }) })
@@ -15053,11 +15066,12 @@ function getItemPrice(item, includeTax) {
15053
15066
  function getProductImage(product) {
15054
15067
  return product?.media?.images?.items?.[0]?.imageVariants?.[0]?.url || "";
15055
15068
  }
15056
- function getProductName4(product) {
15057
- return product?.names?.[0]?.value || "";
15069
+ function getProductName4(product, language) {
15070
+ return propellerV2CoreUi.getLocalizedValue(product?.names, language, "");
15058
15071
  }
15059
15072
  function ProductBundles(rawProps) {
15060
15073
  const props = useInfraProps(rawProps);
15074
+ const language = props.language;
15061
15075
  const currencySymbol = props.currency ?? "\u20AC";
15062
15076
  const money = (value) => propellerV2CoreUi.formatPrice(value, { symbol: currencySymbol });
15063
15077
  const [isMounted, setIsMounted] = React6.useState(false);
@@ -15196,10 +15210,10 @@ function ProductBundles(rawProps) {
15196
15210
  {
15197
15211
  className: "propeller-product-bundles__item-image w-full h-full object-contain p-2",
15198
15212
  src: getProductImage(item.product),
15199
- alt: getProductName4(item.product)
15213
+ alt: getProductName4(item.product, language)
15200
15214
  }
15201
15215
  ) : null }),
15202
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bundles__item-name text-sm font-medium text-muted-foreground leading-tight mb-1", children: getProductName4(item.product) || "Product " + item.productId }),
15216
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bundles__item-name text-sm font-medium text-muted-foreground leading-tight mb-1", children: getProductName4(item.product, language) || "Product " + item.productId }),
15203
15217
  !hidePrices && item.price ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-bundles__item-price text-sm font-semibold text-foreground", children: [
15204
15218
  money(getItemPrice(item, includeTax)),
15205
15219
  /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-normal text-muted-foreground ml-1", children: includeTax ? propellerV2CoreUi.getLabel(props.labels, "inclTax", "incl. VAT") : propellerV2CoreUi.getLabel(props.labels, "exclTax", "excl. VAT") })
@@ -15399,7 +15413,7 @@ function ProductBundles(rawProps) {
15399
15413
  {
15400
15414
  className: "propeller-product-bundles__modal-child flex justify-between items-center text-xs text-muted-foreground",
15401
15415
  children: [
15402
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: getProductName4(item.product) || "Product" }),
15416
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "line-clamp-1", children: getProductName4(item.product, language) || "Product" }),
15403
15417
  !hidePrices && item.price ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-foreground-subtle whitespace-nowrap ml-2", children: money(getItemPrice(item, includeTax)) }) : null
15404
15418
  ]
15405
15419
  },
@@ -18614,7 +18628,7 @@ function mapToSearchBarResult(item, language) {
18614
18628
  const isCluster = "clusterId" in item;
18615
18629
  const displayItem = isCluster ? item.defaultProduct : item;
18616
18630
  const id = isCluster ? item.clusterId : item.productId;
18617
- const slug = item.slugs?.[0]?.value || "";
18631
+ const slug = propellerV2CoreUi.getLocalizedValue(item.slugs, language, "");
18618
18632
  const url = isCluster ? "/cluster/" + id + "/" + slug : "/product/" + id + "/" + slug;
18619
18633
  const priceNet = displayItem?.price?.net || 0;
18620
18634
  const priceGross = displayItem?.price?.gross || 0;