@propeller-commerce/propeller-v2-react-ui 0.15.9 → 0.15.11
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 +38 -0
- package/dist/index.cjs +37 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +37 -23
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,44 @@ 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.15.11] - 2026-08-11
|
|
12
|
+
|
|
13
|
+
### Fixed
|
|
14
|
+
|
|
15
|
+
- **Checkout step 3 opened with nothing selected on a fresh cart (PWP-934).**
|
|
16
|
+
`CartPaymethods` and `CartCarriers` only ever adopted a value the cart already
|
|
17
|
+
stored, so a cart that had never reached step 3 — every first order, and every
|
|
18
|
+
order after the cart is recreated — rendered both grids blank and refused to
|
|
19
|
+
continue until the user clicked. They now preselect the cart's stored option
|
|
20
|
+
when there is one and otherwise the first option offered, so Continue works
|
|
21
|
+
straight away. A stored value the backend no longer offers also falls back
|
|
22
|
+
instead of leaving an invisible selection.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- The active option is now derived from the cart rather than mirrored into state
|
|
27
|
+
by an effect, so it is present in the first render (including SSR) instead of
|
|
28
|
+
appearing after hydration. `onPaymethodSelect` / `onCarrierSelect` still fire
|
|
29
|
+
once for the preselection, so hosts that persist the choice — and price the
|
|
30
|
+
transaction costs off it — keep working unchanged.
|
|
31
|
+
|
|
32
|
+
## [0.15.10] - 2026-08-11
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **The cart sidebar's "Bonus items" heading stayed English on a localized
|
|
37
|
+
page.** `CartIconAndSidebar` renders `CartBonusItems` itself but passed it no
|
|
38
|
+
`labels`, so the block always fell back to its English defaults — while the
|
|
39
|
+
same component on the cart and checkout pages, where the host passes `labels`
|
|
40
|
+
directly, translated correctly. Same shape as the `cartItemLabels` gap fixed
|
|
41
|
+
in 0.4.24.
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- `CartIconAndSidebar` accepts `cartBonusItemsLabels` (keys: `title`, `sku`),
|
|
46
|
+
forwarded to the embedded bonus-items block. Hosts already translating
|
|
47
|
+
`CartBonusItems` on the cart page can pass the same map.
|
|
48
|
+
|
|
11
49
|
## [0.15.9] - 2026-08-11
|
|
12
50
|
|
|
13
51
|
### Fixed
|
package/dist/index.cjs
CHANGED
|
@@ -6427,6 +6427,12 @@ function CartBonusItems(rawProps) {
|
|
|
6427
6427
|
] });
|
|
6428
6428
|
}
|
|
6429
6429
|
var CartBonusItems_default = CartBonusItems;
|
|
6430
|
+
|
|
6431
|
+
// src/composables/shared/utils/preselect.ts
|
|
6432
|
+
function pickPreselected(items, stored, keyOf) {
|
|
6433
|
+
const list = items || [];
|
|
6434
|
+
return (stored ? list.find((item) => keyOf(item) === stored) : void 0) || list[0];
|
|
6435
|
+
}
|
|
6430
6436
|
function CartCarriers(props) {
|
|
6431
6437
|
const [selectedName, setSelectedName] = React6.useState("");
|
|
6432
6438
|
const containerClass = props.carriersContainerClass || "cart-carriers";
|
|
@@ -6440,16 +6446,16 @@ function CartCarriers(props) {
|
|
|
6440
6446
|
setSelectedName(carrier.name);
|
|
6441
6447
|
if (props.onCarrierSelect) props.onCarrierSelect(carrier);
|
|
6442
6448
|
}
|
|
6449
|
+
const preselected = pickPreselected(
|
|
6450
|
+
carriers,
|
|
6451
|
+
props.cart?.postageData?.carrier,
|
|
6452
|
+
(c) => c.name
|
|
6453
|
+
);
|
|
6454
|
+
const activeName = selectedName || preselected?.name || "";
|
|
6443
6455
|
React6.useEffect(() => {
|
|
6444
|
-
if (
|
|
6445
|
-
|
|
6446
|
-
|
|
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]);
|
|
6456
|
+
if (selectedName || !preselected) return;
|
|
6457
|
+
if (props.onCarrierSelect) props.onCarrierSelect(preselected);
|
|
6458
|
+
}, [preselected?.name]);
|
|
6453
6459
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `propeller-cart-carriers ${containerClass}`, children: [
|
|
6454
6460
|
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
6461
|
const logoUrl = showLogo ? carrier.logo || "" : "";
|
|
@@ -6457,8 +6463,8 @@ function CartCarriers(props) {
|
|
|
6457
6463
|
"div",
|
|
6458
6464
|
{
|
|
6459
6465
|
onClick: () => handleSelect(carrier),
|
|
6460
|
-
"data-selected":
|
|
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 ${
|
|
6466
|
+
"data-selected": activeName === carrier.name ? "true" : "false",
|
|
6467
|
+
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
6468
|
children: [
|
|
6463
6469
|
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
6470
|
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,
|
|
@@ -7497,7 +7503,15 @@ function CartIconAndSidebar(rawProps) {
|
|
|
7497
7503
|
},
|
|
7498
7504
|
item.itemId
|
|
7499
7505
|
)) }),
|
|
7500
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7506
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
7507
|
+
CartBonusItemsImpl,
|
|
7508
|
+
{
|
|
7509
|
+
cart: props.cart,
|
|
7510
|
+
includeTax: useTax,
|
|
7511
|
+
className: "mt-4",
|
|
7512
|
+
labels: props.cartBonusItemsLabels
|
|
7513
|
+
}
|
|
7514
|
+
)
|
|
7501
7515
|
] }),
|
|
7502
7516
|
" ",
|
|
7503
7517
|
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: [
|
|
@@ -7754,16 +7768,16 @@ function CartPaymethods(rawProps) {
|
|
|
7754
7768
|
setSelectedCode(method.code);
|
|
7755
7769
|
if (props.onPaymethodSelect) props.onPaymethodSelect(method);
|
|
7756
7770
|
}
|
|
7771
|
+
const preselected = pickPreselected(
|
|
7772
|
+
payMethods,
|
|
7773
|
+
props.cart?.paymentData?.method,
|
|
7774
|
+
(m) => m.code
|
|
7775
|
+
);
|
|
7776
|
+
const activeCode = selectedCode || preselected?.code || "";
|
|
7757
7777
|
React6.useEffect(() => {
|
|
7758
|
-
if (
|
|
7759
|
-
|
|
7760
|
-
|
|
7761
|
-
if (props.onPaymethodSelect) {
|
|
7762
|
-
const match = payMethods.find((m) => m.code === code);
|
|
7763
|
-
if (match) props.onPaymethodSelect(match);
|
|
7764
|
-
}
|
|
7765
|
-
}
|
|
7766
|
-
}, [props.cart, selectedCode, props.onPaymethodSelect, payMethods, props]);
|
|
7778
|
+
if (selectedCode || !preselected) return;
|
|
7779
|
+
if (props.onPaymethodSelect) props.onPaymethodSelect(preselected);
|
|
7780
|
+
}, [preselected?.code]);
|
|
7767
7781
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `propeller-cart-paymethods ${containerClass}`, children: [
|
|
7768
7782
|
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) => {
|
|
7769
7783
|
const logoUrl = showLogo ? getLogoUrl(method) : "";
|
|
@@ -7771,8 +7785,8 @@ function CartPaymethods(rawProps) {
|
|
|
7771
7785
|
"div",
|
|
7772
7786
|
{
|
|
7773
7787
|
onClick: () => handleSelect(method),
|
|
7774
|
-
"data-selected":
|
|
7775
|
-
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 ${
|
|
7788
|
+
"data-selected": activeCode === method.code ? "true" : "false",
|
|
7789
|
+
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"}`,
|
|
7776
7790
|
children: [
|
|
7777
7791
|
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,
|
|
7778
7792
|
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(
|