@propeller-commerce/propeller-v2-react-ui 0.7.0 → 0.8.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 +56 -0
- package/dist/index.cjs +110 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +87 -2
- package/dist/index.d.ts +87 -2
- package/dist/index.js +111 -80
- package/dist/index.js.map +1 -1
- package/dist/pure.cjs +1 -1
- package/dist/pure.cjs.map +1 -1
- package/dist/pure.d.cts +5 -0
- package/dist/pure.d.ts +5 -0
- package/dist/pure.js +1 -1
- package/dist/pure.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,62 @@ 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.8.0] - 2026-07-28
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`<LoginToOrderButton>`** — a log-in call to action rendered in place of
|
|
16
|
+
add-to-cart for anonymous visitors of a semi-closed portal. Takes an
|
|
17
|
+
`onLoginClick` callback (the host owns navigation, mirroring
|
|
18
|
+
`RegisterForm.onLoginClick`) and a `loginToOrder` label. `ProductCard`,
|
|
19
|
+
`ProductInfo` and `ProductGrid` accept `onLoginClick` and forward it.
|
|
20
|
+
- **`showLoginPrompt` on `<ProductPrice>` and `<ProductBundles>`** — set
|
|
21
|
+
`false` to render nothing where the "log in to see prices" text would go.
|
|
22
|
+
Defaults to `true`, so existing behaviour is unchanged.
|
|
23
|
+
- **`portalMode` on `<ProductCard>`, `<ClusterCard>` and `<ClusterOptions>`** —
|
|
24
|
+
resolved from `<PropellerProvider>` like the other Tier 1 infra props; an
|
|
25
|
+
explicit prop still wins.
|
|
26
|
+
|
|
27
|
+
### Fixed
|
|
28
|
+
|
|
29
|
+
- **Semi-closed portals leaked price and stock in listings.** `ProductCard`
|
|
30
|
+
never received `portalMode`, so the price it renders through `<ProductPrice>`
|
|
31
|
+
and its stock row stayed visible to anonymous visitors even though the toolbar
|
|
32
|
+
and price filter were correctly gated. `ClusterCard` had the same gap, and
|
|
33
|
+
`ClusterOptions` printed option prices in its dropdown labels and selection
|
|
34
|
+
preview. All now gate on the shared `isContentHidden(portalMode, user)`.
|
|
35
|
+
- **`ProductGrid` hid add-to-cart from signed-in users of a semi-closed
|
|
36
|
+
portal.** `showAddToCart()` tested `portalMode === 'open'` rather than
|
|
37
|
+
`isContentHidden`, so authenticated shoppers lost the control along with
|
|
38
|
+
anonymous ones. Signed-in users keep add-to-cart.
|
|
39
|
+
- **The CTA slot collapsed when content was hidden.** `ProductCard` gated the
|
|
40
|
+
slot on `allowAddToCart`, which `ProductGrid` passes as `false` in that case —
|
|
41
|
+
leaving no room for the log-in action. The slot now renders either control.
|
|
42
|
+
|
|
43
|
+
## [0.7.1] - 2026-07-28
|
|
44
|
+
|
|
45
|
+
### Fixed
|
|
46
|
+
|
|
47
|
+
- **`cartUpdateAddress` rejected a blank email** — optional address fields were
|
|
48
|
+
sent as empty strings when left blank, and the API validates optional fields
|
|
49
|
+
whenever they are present, so a blank email failed with
|
|
50
|
+
`email must be an email` (400). This blocked the address step for a delivery
|
|
51
|
+
address, where the email legitimately lives on the contact / customer record
|
|
52
|
+
rather than the address. Optional fields are now omitted when blank, matching
|
|
53
|
+
how `useAddress` already built its payloads. Affects every optional field
|
|
54
|
+
(`email`, `phone`, `mobile`, `company`, `notes`, …), not just email.
|
|
55
|
+
- **`<AddressCard>` required an email on every address** — the edit and create
|
|
56
|
+
forms hardcoded `required` plus a `*` on the email input, contradicting the
|
|
57
|
+
field being optional on the address itself. Email is now optional in both
|
|
58
|
+
forms.
|
|
59
|
+
- **`<AddressCard>` accepted undeliverable emails** — `type="email"` alone
|
|
60
|
+
permits dotless domains such as `aa@gg` (valid per the HTML5 spec for
|
|
61
|
+
intranet hosts, but rejected by the API). Both email inputs now carry a
|
|
62
|
+
pattern requiring a dotted top-level domain, so invalid input is caught in
|
|
63
|
+
the form instead of surfacing as a failed mutation. Subdomains
|
|
64
|
+
(`user@sub.co.uk`) and tagged addresses (`user+tag@example.com`) remain
|
|
65
|
+
valid.
|
|
66
|
+
|
|
11
67
|
## [0.7.0] - 2026-07-27
|
|
12
68
|
|
|
13
69
|
### Added
|
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,7 @@ var propellerV2CoreUi = require('@propeller-commerce/propeller-v2-core-ui');
|
|
|
5
5
|
var React6 = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
var propellerSdkV2 = require('@propeller-commerce/propeller-sdk-v2');
|
|
8
|
+
var lucideReact = require('lucide-react');
|
|
8
9
|
|
|
9
10
|
function _interopNamespace(e) {
|
|
10
11
|
if (e && e.__esModule) return e;
|
|
@@ -888,6 +889,25 @@ function useCart(options) {
|
|
|
888
889
|
}, [graphqlClient, language, configuration, user]);
|
|
889
890
|
return { cart, cartId, loading, error, checkoutAllowed, resolveCart, addItem, updateItemQuantity, updateItemNotes, deleteItem, addActionCode, removeActionCode, requestAuthorization, processCart, getCrossupsells, getMinQuantity, getStep };
|
|
890
891
|
}
|
|
892
|
+
function buildAddressInput(type, addr) {
|
|
893
|
+
return {
|
|
894
|
+
type,
|
|
895
|
+
firstName: addr.firstName || "",
|
|
896
|
+
lastName: addr.lastName || "",
|
|
897
|
+
street: addr.street || "",
|
|
898
|
+
postalCode: addr.postalCode || "",
|
|
899
|
+
city: addr.city || "",
|
|
900
|
+
...addr.company && { company: addr.company },
|
|
901
|
+
...addr.gender && { gender: addr.gender },
|
|
902
|
+
...addr.middleName && { middleName: addr.middleName },
|
|
903
|
+
...addr.number && { number: addr.number },
|
|
904
|
+
...addr.numberExtension && { numberExtension: addr.numberExtension },
|
|
905
|
+
...addr.country && { country: addr.country },
|
|
906
|
+
...addr.email && { email: addr.email },
|
|
907
|
+
...addr.mobile && { mobile: addr.mobile },
|
|
908
|
+
...addr.phone && { phone: addr.phone }
|
|
909
|
+
};
|
|
910
|
+
}
|
|
891
911
|
function useCheckout(options) {
|
|
892
912
|
const { graphqlClient, user, companyId } = options;
|
|
893
913
|
const language = options.language ?? "NL";
|
|
@@ -928,26 +948,9 @@ function useCheckout(options) {
|
|
|
928
948
|
if (!hasInvoice) {
|
|
929
949
|
const defaultInvoice = getUserDefaultAddress("invoice");
|
|
930
950
|
if (defaultInvoice) {
|
|
931
|
-
const input = {
|
|
932
|
-
type: propellerSdkV2.CartAddressType.INVOICE,
|
|
933
|
-
firstName: defaultInvoice.firstName || "",
|
|
934
|
-
lastName: defaultInvoice.lastName || "",
|
|
935
|
-
street: defaultInvoice.street || "",
|
|
936
|
-
postalCode: defaultInvoice.postalCode || "",
|
|
937
|
-
city: defaultInvoice.city || "",
|
|
938
|
-
company: defaultInvoice.company,
|
|
939
|
-
gender: defaultInvoice.gender,
|
|
940
|
-
middleName: defaultInvoice.middleName,
|
|
941
|
-
number: defaultInvoice.number,
|
|
942
|
-
numberExtension: defaultInvoice.numberExtension,
|
|
943
|
-
country: defaultInvoice.country,
|
|
944
|
-
email: defaultInvoice.email,
|
|
945
|
-
mobile: defaultInvoice.mobile,
|
|
946
|
-
phone: defaultInvoice.phone
|
|
947
|
-
};
|
|
948
951
|
updatedCart = await cartService.updateCartAddress({
|
|
949
952
|
id: updatedCart.cartId,
|
|
950
|
-
input,
|
|
953
|
+
input: buildAddressInput(propellerSdkV2.CartAddressType.INVOICE, defaultInvoice),
|
|
951
954
|
imageVariantFilters,
|
|
952
955
|
imageSearchFilters,
|
|
953
956
|
language
|
|
@@ -957,26 +960,9 @@ function useCheckout(options) {
|
|
|
957
960
|
if (!hasDelivery) {
|
|
958
961
|
const defaultDelivery = getUserDefaultAddress("delivery");
|
|
959
962
|
if (defaultDelivery) {
|
|
960
|
-
const input = {
|
|
961
|
-
type: propellerSdkV2.CartAddressType.DELIVERY,
|
|
962
|
-
firstName: defaultDelivery.firstName || "",
|
|
963
|
-
lastName: defaultDelivery.lastName || "",
|
|
964
|
-
street: defaultDelivery.street || "",
|
|
965
|
-
postalCode: defaultDelivery.postalCode || "",
|
|
966
|
-
city: defaultDelivery.city || "",
|
|
967
|
-
company: defaultDelivery.company,
|
|
968
|
-
gender: defaultDelivery.gender,
|
|
969
|
-
middleName: defaultDelivery.middleName,
|
|
970
|
-
number: defaultDelivery.number,
|
|
971
|
-
numberExtension: defaultDelivery.numberExtension,
|
|
972
|
-
country: defaultDelivery.country,
|
|
973
|
-
email: defaultDelivery.email,
|
|
974
|
-
mobile: defaultDelivery.mobile,
|
|
975
|
-
phone: defaultDelivery.phone
|
|
976
|
-
};
|
|
977
963
|
updatedCart = await cartService.updateCartAddress({
|
|
978
964
|
id: updatedCart.cartId,
|
|
979
|
-
input,
|
|
965
|
+
input: buildAddressInput(propellerSdkV2.CartAddressType.DELIVERY, defaultDelivery),
|
|
980
966
|
imageVariantFilters,
|
|
981
967
|
imageSearchFilters,
|
|
982
968
|
language
|
|
@@ -5065,6 +5051,7 @@ function AddToFavorite(rawProps) {
|
|
|
5065
5051
|
] }) }) : null });
|
|
5066
5052
|
}
|
|
5067
5053
|
var AddToFavorite_default = AddToFavorite;
|
|
5054
|
+
var EMAIL_PATTERN = "[^@\\s]+@[^@\\s.]+(?:\\.[^@\\s.]+)*\\.[A-Za-z]{2,}";
|
|
5068
5055
|
var AddressCardContext = React6__namespace.createContext(null);
|
|
5069
5056
|
function useAddressCardContext() {
|
|
5070
5057
|
const ctx = React6__namespace.useContext(AddressCardContext);
|
|
@@ -5510,10 +5497,7 @@ function AddressCard(rawProps) {
|
|
|
5510
5497
|
] }),
|
|
5511
5498
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
5512
5499
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
5513
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5514
|
-
propellerV2CoreUi.getLabel(props.labels, "email", "Email"),
|
|
5515
|
-
" *"
|
|
5516
|
-
] }),
|
|
5500
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium mb-1", children: propellerV2CoreUi.getLabel(props.labels, "email", "Email") }),
|
|
5517
5501
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5518
5502
|
"input",
|
|
5519
5503
|
{
|
|
@@ -5523,7 +5507,7 @@ function AddressCard(rawProps) {
|
|
|
5523
5507
|
onChange: (e) => {
|
|
5524
5508
|
setEditEmail(e.target.value);
|
|
5525
5509
|
},
|
|
5526
|
-
|
|
5510
|
+
pattern: EMAIL_PATTERN
|
|
5527
5511
|
}
|
|
5528
5512
|
)
|
|
5529
5513
|
] }),
|
|
@@ -5803,10 +5787,7 @@ function AddressCard(rawProps) {
|
|
|
5803
5787
|
] }),
|
|
5804
5788
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
5805
5789
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
5806
|
-
/* @__PURE__ */ jsxRuntime.
|
|
5807
|
-
propellerV2CoreUi.getLabel(props.labels, "email", "Email"),
|
|
5808
|
-
" *"
|
|
5809
|
-
] }),
|
|
5790
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium mb-1", children: propellerV2CoreUi.getLabel(props.labels, "email", "Email") }),
|
|
5810
5791
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
5811
5792
|
"input",
|
|
5812
5793
|
{
|
|
@@ -5816,7 +5797,7 @@ function AddressCard(rawProps) {
|
|
|
5816
5797
|
onChange: (e) => {
|
|
5817
5798
|
setEditEmail(e.target.value);
|
|
5818
5799
|
},
|
|
5819
|
-
|
|
5800
|
+
pattern: EMAIL_PATTERN
|
|
5820
5801
|
}
|
|
5821
5802
|
)
|
|
5822
5803
|
] }),
|
|
@@ -7978,6 +7959,8 @@ var RESOLVE_SPEC = {
|
|
|
7978
7959
|
includeTax: { infra: "includeTax" },
|
|
7979
7960
|
language: { infra: "language", default: "NL" },
|
|
7980
7961
|
currency: { infra: "currency", default: "\u20AC" },
|
|
7962
|
+
user: { infra: "user", default: null },
|
|
7963
|
+
portalMode: { infra: "portalMode" },
|
|
7981
7964
|
columns: { grid: "columns", default: 3 },
|
|
7982
7965
|
showPrice: { grid: "showPrice" },
|
|
7983
7966
|
showStock: { grid: "showStock" },
|
|
@@ -8021,9 +8004,10 @@ function ClusterCard(rawProps) {
|
|
|
8021
8004
|
const textLabelValues = resolveAttributeValues(cluster, props.textLabels).map((value) => ({
|
|
8022
8005
|
value
|
|
8023
8006
|
}));
|
|
8024
|
-
const
|
|
8007
|
+
const contentHidden = propellerV2CoreUi.isContentHidden(props.portalMode, props.user);
|
|
8008
|
+
const defaultProductInventory = contentHidden ? void 0 : cluster?.defaultProduct?.inventory;
|
|
8025
8009
|
const useTax = props.includeTax !== void 0 ? !!props.includeTax : false;
|
|
8026
|
-
const priceObj = cluster?.defaultProduct?.price;
|
|
8010
|
+
const priceObj = contentHidden ? void 0 : cluster?.defaultProduct?.price;
|
|
8027
8011
|
const priceValue = useTax ? priceObj?.net : priceObj?.gross;
|
|
8028
8012
|
const clusterPrice = props.showPrice === false ? "" : propellerV2CoreUi.formatPrice(priceValue, { symbol: props.currency ?? "\u20AC" });
|
|
8029
8013
|
function handleClusterClick(e) {
|
|
@@ -8428,6 +8412,23 @@ function MachineCard(props) {
|
|
|
8428
8412
|
}
|
|
8429
8413
|
);
|
|
8430
8414
|
}
|
|
8415
|
+
function LoginToOrderButton(props) {
|
|
8416
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8417
|
+
"button",
|
|
8418
|
+
{
|
|
8419
|
+
type: "button",
|
|
8420
|
+
className: `propeller-login-to-order inline-flex items-center justify-center gap-2 h-10 px-4 w-full rounded-control bg-primary text-primary-foreground text-sm font-medium hover:opacity-90 transition-opacity ${props.className || ""}`,
|
|
8421
|
+
onClick: () => {
|
|
8422
|
+
if (props.onLoginClick) props.onLoginClick();
|
|
8423
|
+
},
|
|
8424
|
+
children: [
|
|
8425
|
+
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.User, { className: "propeller-login-to-order__icon w-4 h-4", "aria-hidden": "true" }),
|
|
8426
|
+
propellerV2CoreUi.getLabel(props.labels, "loginToOrder", "Log in to order")
|
|
8427
|
+
]
|
|
8428
|
+
}
|
|
8429
|
+
);
|
|
8430
|
+
}
|
|
8431
|
+
var LoginToOrderButton_default = LoginToOrderButton;
|
|
8431
8432
|
function ProductPriceDisplay(props) {
|
|
8432
8433
|
function isHidden2() {
|
|
8433
8434
|
return propellerV2CoreUi.isContentHidden(props.portalMode, props.user);
|
|
@@ -8478,7 +8479,7 @@ function ProductPriceDisplay(props) {
|
|
|
8478
8479
|
return props.includeTax ? propellerV2CoreUi.getLabel(props.labels, "exclTax", "excl. VAT") : propellerV2CoreUi.getLabel(props.labels, "inclTax", "incl. VAT");
|
|
8479
8480
|
}
|
|
8480
8481
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `propeller-product-price ${props.className || ""}`, "data-hidden": isHidden2() ? "true" : "false", children: [
|
|
8481
|
-
isHidden2() ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-product-price__login-prompt text-sm text-muted-foreground italic", children: propellerV2CoreUi.getLabel(props.labels, "loginToSeePrices", "Log in to see prices") }) : null,
|
|
8482
|
+
isHidden2() && props.showLoginPrompt !== false ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-product-price__login-prompt text-sm text-muted-foreground italic", children: propellerV2CoreUi.getLabel(props.labels, "loginToSeePrices", "Log in to see prices") }) : null,
|
|
8482
8483
|
!isHidden2() && !!getLeadingPrice() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-price__content flex flex-col gap-0.5", children: [
|
|
8483
8484
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-price__primary flex items-baseline gap-2", children: [
|
|
8484
8485
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8521,6 +8522,7 @@ var RESOLVE_SPEC2 = {
|
|
|
8521
8522
|
companyId: { infra: "companyId" },
|
|
8522
8523
|
language: { infra: "language", default: "NL" },
|
|
8523
8524
|
includeTax: { infra: "includeTax" },
|
|
8525
|
+
portalMode: { infra: "portalMode" },
|
|
8524
8526
|
configuration: { infra: "configuration" },
|
|
8525
8527
|
columns: { grid: "columns", default: 3 },
|
|
8526
8528
|
showPrice: { grid: "showPrice" },
|
|
@@ -8542,6 +8544,7 @@ var RESOLVE_SPEC2 = {
|
|
|
8542
8544
|
onCartCreated: { grid: "onCartCreated" },
|
|
8543
8545
|
afterAddToCart: { grid: "afterAddToCart" },
|
|
8544
8546
|
onProceedToCheckout: { grid: "onProceedToCheckout" },
|
|
8547
|
+
onLoginClick: { grid: "onLoginClick" },
|
|
8545
8548
|
onRequestQuoteClick: { grid: "onRequestQuoteClick" },
|
|
8546
8549
|
onProductClick: { grid: "onProductClick" },
|
|
8547
8550
|
onToggleFavorite: {
|
|
@@ -8573,6 +8576,9 @@ function ProductCardRoot(rawProps) {
|
|
|
8573
8576
|
const language = props.language || "NL";
|
|
8574
8577
|
const product = props.product;
|
|
8575
8578
|
const isRow = props.columns === 1;
|
|
8579
|
+
const contentHidden = propellerV2CoreUi.isContentHidden(props.portalMode, props.user);
|
|
8580
|
+
const showStock = !!props.showStock && !contentHidden;
|
|
8581
|
+
const showCta = props.allowAddToCart !== false || contentHidden;
|
|
8576
8582
|
const name = getProductName(product, language);
|
|
8577
8583
|
const sku = propellerV2CoreUi.getProductSku(product);
|
|
8578
8584
|
const imageUrl = propellerV2CoreUi.getProductImageUrl(product);
|
|
@@ -8643,10 +8649,10 @@ function ProductCardRoot(rawProps) {
|
|
|
8643
8649
|
] }) }),
|
|
8644
8650
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-card__footer w-full md:w-auto flex flex-col gap-2 md:flex-row md:items-center md:gap-3 px-4 py-2 md:py-0 border-t md:border-t-0 border-border-subtle", children: [
|
|
8645
8651
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-card__footer-meta flex items-center justify-between gap-3 md:contents", children: [
|
|
8646
|
-
|
|
8652
|
+
showStock && !!product.inventory ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardStock, {}) : null,
|
|
8647
8653
|
props.showPrice !== false && !!product?.price ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardPrice, { priceSize: "text-sm" }) : null
|
|
8648
8654
|
] }),
|
|
8649
|
-
|
|
8655
|
+
showCta ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-card__cta w-full md:w-auto md:flex-shrink-0 md:ml-auto", children: /* @__PURE__ */ jsxRuntime.jsx(ProductCardAddToCart, {}) }) : null
|
|
8650
8656
|
] })
|
|
8651
8657
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8652
8658
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-card__body flex flex-1 flex-col gap-1.5 p-3 sm:gap-2 sm:p-4", children: [
|
|
@@ -8654,16 +8660,16 @@ function ProductCardRoot(rawProps) {
|
|
|
8654
8660
|
props.showName !== false ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardName, { linkable: true }) : null,
|
|
8655
8661
|
/* @__PURE__ */ jsxRuntime.jsx(ProductCardBelowName, {}),
|
|
8656
8662
|
textLabelValues.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardTextLabels, {}) : null,
|
|
8657
|
-
|
|
8663
|
+
showStock && !!product.inventory ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block", children: /* @__PURE__ */ jsxRuntime.jsx(ProductCardStock, {}) }) : null,
|
|
8658
8664
|
props.showManufacturer && manufacturer ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardManufacturer, {}) : null,
|
|
8659
8665
|
props.showShortDescription && shortDescription ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardShortDescription, {}) : null,
|
|
8660
8666
|
props.showPrice !== false && !!product?.price ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-card__price mt-auto pt-1 hidden md:block", children: /* @__PURE__ */ jsxRuntime.jsx(ProductCardPrice, { priceSize: "text-base sm:text-lg" }) }) : null
|
|
8661
8667
|
] }),
|
|
8662
|
-
|
|
8663
|
-
|
|
8668
|
+
showStock && !!product.inventory || props.showPrice !== false && !!product?.price ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-card__footer-meta flex flex-wrap items-center justify-between gap-x-2 gap-y-1 px-3 pt-1 sm:px-4 md:hidden", children: [
|
|
8669
|
+
showStock && !!product.inventory ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardStock, {}) : null,
|
|
8664
8670
|
props.showPrice !== false && !!product?.price ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardPrice, { priceSize: "text-base", className: "propeller-product-card__price min-w-0 text-right" }) : null
|
|
8665
8671
|
] }) : null,
|
|
8666
|
-
|
|
8672
|
+
showCta ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-card__cta px-3 pb-3 pt-2 sm:px-4 sm:pb-4", children: /* @__PURE__ */ jsxRuntime.jsx(ProductCardAddToCart, {}) }) : null
|
|
8667
8673
|
] })
|
|
8668
8674
|
]
|
|
8669
8675
|
}
|
|
@@ -8862,12 +8868,25 @@ function ProductCardPrice(props) {
|
|
|
8862
8868
|
price: product.price,
|
|
8863
8869
|
includeTax: derived.useTax,
|
|
8864
8870
|
priceSize: props.priceSize ?? "text-base sm:text-lg",
|
|
8865
|
-
labels: resolved.priceLabels
|
|
8871
|
+
labels: resolved.priceLabels,
|
|
8872
|
+
portalMode: resolved.portalMode,
|
|
8873
|
+
user: resolved.user,
|
|
8874
|
+
showLoginPrompt: false
|
|
8866
8875
|
}
|
|
8867
8876
|
) });
|
|
8868
8877
|
}
|
|
8869
8878
|
function ProductCardAddToCart(props) {
|
|
8870
8879
|
const { product, resolved } = useProductCard();
|
|
8880
|
+
if (propellerV2CoreUi.isContentHidden(resolved.portalMode, resolved.user)) {
|
|
8881
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8882
|
+
LoginToOrderButton_default,
|
|
8883
|
+
{
|
|
8884
|
+
className: props.className,
|
|
8885
|
+
labels: resolved.addToCartLabels,
|
|
8886
|
+
onLoginClick: resolved.onLoginClick
|
|
8887
|
+
}
|
|
8888
|
+
);
|
|
8889
|
+
}
|
|
8871
8890
|
const InjectedAddToCart = resolved.addToCartComponent;
|
|
8872
8891
|
if (InjectedAddToCart) {
|
|
8873
8892
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9000,9 +9019,8 @@ function ProductGrid(rawProps) {
|
|
|
9000
9019
|
return !!props.isLoading || isLoading;
|
|
9001
9020
|
}
|
|
9002
9021
|
function showAddToCart() {
|
|
9003
|
-
const mode = props.portalMode || "open";
|
|
9004
9022
|
const allow = props.allowAddToCart !== false;
|
|
9005
|
-
return
|
|
9023
|
+
return !propellerV2CoreUi.isContentHidden(props.portalMode, props.user) && allow;
|
|
9006
9024
|
}
|
|
9007
9025
|
function getSkeletonItems() {
|
|
9008
9026
|
const cols = props.columns || 3;
|
|
@@ -9029,6 +9047,7 @@ function ProductGrid(rawProps) {
|
|
|
9029
9047
|
onCartCreated: props.onCartCreated,
|
|
9030
9048
|
afterAddToCart: props.afterAddToCart,
|
|
9031
9049
|
onProceedToCheckout: props.onProceedToCheckout,
|
|
9050
|
+
onLoginClick: props.onLoginClick,
|
|
9032
9051
|
onRequestQuoteClick: props.onRequestQuoteClick,
|
|
9033
9052
|
onToggleFavorite: (item, isFav) => props.onToggleFavorite?.(item, isFav),
|
|
9034
9053
|
onProductClick: (p) => props.onProductClick?.(p),
|
|
@@ -9677,7 +9696,7 @@ function GridToolbar(rawProps) {
|
|
|
9677
9696
|
const [currentSortOrder, setCurrentSortOrder] = React6.useState(propellerSdkV2.SortOrder.DESC);
|
|
9678
9697
|
const [currentOffset, setCurrentOffset] = React6.useState(12);
|
|
9679
9698
|
const [currentViewMode, setCurrentViewMode] = React6.useState("grid");
|
|
9680
|
-
function
|
|
9699
|
+
function getLabel56(key) {
|
|
9681
9700
|
const labels = props.labels || {};
|
|
9682
9701
|
return labels[key] !== void 0 ? labels[key] : DEFAULT_LABELS[key] || key;
|
|
9683
9702
|
}
|
|
@@ -9756,7 +9775,7 @@ function GridToolbar(rawProps) {
|
|
|
9756
9775
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-grid-toolbar__count text-sm text-muted-foreground font-medium", children: props.itemsFound > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
9757
9776
|
props.itemsFound,
|
|
9758
9777
|
"\xA0",
|
|
9759
|
-
props.itemsFound === 1 ?
|
|
9778
|
+
props.itemsFound === 1 ? getLabel56("productSingular") : getLabel56("productPlural")
|
|
9760
9779
|
] }) : null }),
|
|
9761
9780
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-grid-toolbar__controls flex flex-wrap items-center gap-3", children: [
|
|
9762
9781
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9767,7 +9786,7 @@ function GridToolbar(rawProps) {
|
|
|
9767
9786
|
onChange: (e) => handleOffsetChange(parseInt(e.target.value)),
|
|
9768
9787
|
children: getOffsetOptions()?.map((n) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: n, children: [
|
|
9769
9788
|
n,
|
|
9770
|
-
|
|
9789
|
+
getLabel56("perPage")
|
|
9771
9790
|
] }, n))
|
|
9772
9791
|
}
|
|
9773
9792
|
),
|
|
@@ -9783,7 +9802,7 @@ function GridToolbar(rawProps) {
|
|
|
9783
9802
|
{
|
|
9784
9803
|
value: field,
|
|
9785
9804
|
disabled: field === "PRICE" && isPriceSortDisabled(),
|
|
9786
|
-
children:
|
|
9805
|
+
children: getLabel56(field)
|
|
9787
9806
|
},
|
|
9788
9807
|
field
|
|
9789
9808
|
))
|
|
@@ -9796,8 +9815,8 @@ function GridToolbar(rawProps) {
|
|
|
9796
9815
|
value: currentSortOrder,
|
|
9797
9816
|
onChange: (e) => handleSortOrderChange(e.target.value),
|
|
9798
9817
|
children: [
|
|
9799
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: propellerSdkV2.SortOrder.ASC, children:
|
|
9800
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: propellerSdkV2.SortOrder.DESC, children:
|
|
9818
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: propellerSdkV2.SortOrder.ASC, children: getLabel56("ASC") }),
|
|
9819
|
+
/* @__PURE__ */ jsxRuntime.jsx("option", { value: propellerSdkV2.SortOrder.DESC, children: getLabel56("DESC") })
|
|
9801
9820
|
]
|
|
9802
9821
|
}
|
|
9803
9822
|
),
|
|
@@ -9807,7 +9826,7 @@ function GridToolbar(rawProps) {
|
|
|
9807
9826
|
type: "button",
|
|
9808
9827
|
className: "propeller-grid-toolbar__view-toggle h-9 w-9 flex items-center justify-center rounded-control border border-input bg-transparent hover:bg-accent hover:text-accent-foreground transition-colors",
|
|
9809
9828
|
onClick: (event) => handleViewChange(),
|
|
9810
|
-
title: currentViewMode === "grid" ?
|
|
9829
|
+
title: currentViewMode === "grid" ? getLabel56("switchToList") : getLabel56("switchToGrid"),
|
|
9811
9830
|
children: [
|
|
9812
9831
|
currentViewMode === "grid" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9813
9832
|
"svg",
|
|
@@ -9865,7 +9884,7 @@ function GridToolbar(rawProps) {
|
|
|
9865
9884
|
onClick: (event) => {
|
|
9866
9885
|
if (props.onClearFilters) props.onClearFilters();
|
|
9867
9886
|
},
|
|
9868
|
-
children:
|
|
9887
|
+
children: getLabel56("clearAll")
|
|
9869
9888
|
}
|
|
9870
9889
|
),
|
|
9871
9890
|
props.priceFilterMin !== void 0 || props.priceFilterMax !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -9876,7 +9895,7 @@ function GridToolbar(rawProps) {
|
|
|
9876
9895
|
if (props.onPriceFilterRemove) props.onPriceFilterRemove();
|
|
9877
9896
|
},
|
|
9878
9897
|
children: [
|
|
9879
|
-
|
|
9898
|
+
getLabel56("price"),
|
|
9880
9899
|
": \u20AC",
|
|
9881
9900
|
props.priceFilterMin ?? 0,
|
|
9882
9901
|
" \u2013 \u20AC",
|
|
@@ -9913,7 +9932,7 @@ var DEFAULT_LABELS2 = {
|
|
|
9913
9932
|
of: "of"
|
|
9914
9933
|
};
|
|
9915
9934
|
function GridPagination(props) {
|
|
9916
|
-
function
|
|
9935
|
+
function getLabel56(key) {
|
|
9917
9936
|
const labels = props.labels || {};
|
|
9918
9937
|
return labels[key] !== void 0 ? labels[key] : DEFAULT_LABELS2[key] || key;
|
|
9919
9938
|
}
|
|
@@ -9986,15 +10005,15 @@ function GridPagination(props) {
|
|
|
9986
10005
|
className: "propeller-grid-pagination__btn propeller-grid-pagination__btn--prev inline-flex items-center rounded-control border border-input bg-card px-4 py-2 text-sm font-medium text-foreground shadow-sm hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed",
|
|
9987
10006
|
disabled: currentPage === 1,
|
|
9988
10007
|
onClick: () => handlePageChange(currentPage - 1),
|
|
9989
|
-
children:
|
|
10008
|
+
children: getLabel56("previous")
|
|
9990
10009
|
}
|
|
9991
10010
|
),
|
|
9992
10011
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "propeller-grid-pagination__info px-2 text-sm font-medium text-muted-foreground", children: [
|
|
9993
|
-
|
|
10012
|
+
getLabel56("page"),
|
|
9994
10013
|
"\xA0",
|
|
9995
10014
|
currentPage,
|
|
9996
10015
|
"\xA0",
|
|
9997
|
-
|
|
10016
|
+
getLabel56("of"),
|
|
9998
10017
|
"\xA0",
|
|
9999
10018
|
totalPages
|
|
10000
10019
|
] }),
|
|
@@ -10005,7 +10024,7 @@ function GridPagination(props) {
|
|
|
10005
10024
|
className: "propeller-grid-pagination__btn propeller-grid-pagination__btn--next inline-flex items-center rounded-control border border-input bg-card px-4 py-2 text-sm font-medium text-foreground shadow-sm hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed",
|
|
10006
10025
|
disabled: currentPage === totalPages,
|
|
10007
10026
|
onClick: () => handlePageChange(currentPage + 1),
|
|
10008
|
-
children:
|
|
10027
|
+
children: getLabel56("next")
|
|
10009
10028
|
}
|
|
10010
10029
|
)
|
|
10011
10030
|
] }) : null,
|
|
@@ -10017,7 +10036,7 @@ function GridPagination(props) {
|
|
|
10017
10036
|
className: "propeller-grid-pagination__btn propeller-grid-pagination__btn--prev inline-flex items-center rounded-control border border-input bg-card px-3 py-2 text-sm font-medium text-foreground shadow-sm hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed",
|
|
10018
10037
|
disabled: currentPage === 1,
|
|
10019
10038
|
onClick: () => handlePageChange(currentPage - 1),
|
|
10020
|
-
children:
|
|
10039
|
+
children: getLabel56("previous")
|
|
10021
10040
|
}
|
|
10022
10041
|
),
|
|
10023
10042
|
getFullPages().map((item, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10044,7 +10063,7 @@ function GridPagination(props) {
|
|
|
10044
10063
|
className: "propeller-grid-pagination__btn propeller-grid-pagination__btn--next inline-flex items-center rounded-control border border-input bg-card px-3 py-2 text-sm font-medium text-foreground shadow-sm hover:bg-surface-hover disabled:opacity-40 disabled:cursor-not-allowed",
|
|
10045
10064
|
disabled: currentPage === totalPages,
|
|
10046
10065
|
onClick: () => handlePageChange(currentPage + 1),
|
|
10047
|
-
children:
|
|
10066
|
+
children: getLabel56("next")
|
|
10048
10067
|
}
|
|
10049
10068
|
)
|
|
10050
10069
|
] }) : null
|
|
@@ -10536,13 +10555,14 @@ function ClusterOptions(props) {
|
|
|
10536
10555
|
function getOptionsForRender() {
|
|
10537
10556
|
const options = props.options || [];
|
|
10538
10557
|
const sel = selectedProductIds;
|
|
10558
|
+
const hidePrices = propellerV2CoreUi.isContentHidden(props.portalMode, props.user);
|
|
10539
10559
|
return options.filter((option) => option.hidden !== propellerSdkV2.YesNo.Y).map((option) => {
|
|
10540
10560
|
const idStr = option.id.toString();
|
|
10541
10561
|
const selectedProductId = sel[idStr] || "";
|
|
10542
10562
|
const products = (option.products || []).map((p) => ({
|
|
10543
10563
|
productId: p.productId,
|
|
10544
10564
|
productIdStr: p.productId.toString(),
|
|
10545
|
-
label: `${getProductName2(p)} \u2014 ${formatPrice9(p.price?.gross || 0, props.currency ?? "\u20AC")}`
|
|
10565
|
+
label: hidePrices ? getProductName2(p) : `${getProductName2(p)} \u2014 ${formatPrice9(p.price?.gross || 0, props.currency ?? "\u20AC")}`
|
|
10546
10566
|
}));
|
|
10547
10567
|
let previewImageUrl = "";
|
|
10548
10568
|
let previewName = "";
|
|
@@ -10554,7 +10574,7 @@ function ClusterOptions(props) {
|
|
|
10554
10574
|
if (selectedProduct) {
|
|
10555
10575
|
previewImageUrl = getProductImageUrl4(selectedProduct);
|
|
10556
10576
|
previewName = getProductName2(selectedProduct);
|
|
10557
|
-
previewPrice = formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC");
|
|
10577
|
+
previewPrice = hidePrices ? "" : formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC");
|
|
10558
10578
|
}
|
|
10559
10579
|
}
|
|
10560
10580
|
const isRequired = option.isRequired === propellerSdkV2.YesNo.Y;
|
|
@@ -15026,11 +15046,11 @@ function ProductBundles(rawProps) {
|
|
|
15026
15046
|
children: addingBundleId === bundle.id ? propellerV2CoreUi.getLabel(props.labels, "adding", "Adding...") : propellerV2CoreUi.getLabel(props.labels, "addToCart", "In cart")
|
|
15027
15047
|
}
|
|
15028
15048
|
)
|
|
15029
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bundles__login-prompt text-center text-sm text-muted-foreground py-2", children: propellerV2CoreUi.getLabel(
|
|
15049
|
+
] }) : props.showLoginPrompt !== false ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "propeller-product-bundles__login-prompt text-center text-sm text-muted-foreground py-2", children: propellerV2CoreUi.getLabel(
|
|
15030
15050
|
props.labels,
|
|
15031
15051
|
"loginToSeePrices",
|
|
15032
15052
|
"Log in to see prices and add to cart"
|
|
15033
|
-
) })
|
|
15053
|
+
) }) : null
|
|
15034
15054
|
] })
|
|
15035
15055
|
] })
|
|
15036
15056
|
},
|
|
@@ -15813,6 +15833,7 @@ function ProductInfoPrice(props = {}) {
|
|
|
15813
15833
|
function ProductInfoStock(props = {}) {
|
|
15814
15834
|
const { product, resolved, derived } = useProductInfoContext();
|
|
15815
15835
|
if (!product.inventory) return null;
|
|
15836
|
+
if (propellerV2CoreUi.isContentHidden(derived.portalMode, resolved.user)) return null;
|
|
15816
15837
|
const Injected = resolved.stockComponent;
|
|
15817
15838
|
if (Injected) {
|
|
15818
15839
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15839,6 +15860,16 @@ function ProductInfoStock(props = {}) {
|
|
|
15839
15860
|
}
|
|
15840
15861
|
function ProductInfoAddToCart(props = {}) {
|
|
15841
15862
|
const { product, resolved, derived } = useProductInfoContext();
|
|
15863
|
+
if (propellerV2CoreUi.isContentHidden(derived.portalMode, resolved.user)) {
|
|
15864
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
15865
|
+
LoginToOrderButton_default,
|
|
15866
|
+
{
|
|
15867
|
+
className: props.className,
|
|
15868
|
+
labels: derived.labels,
|
|
15869
|
+
onLoginClick: resolved.onLoginClick
|
|
15870
|
+
}
|
|
15871
|
+
);
|
|
15872
|
+
}
|
|
15842
15873
|
const Injected = resolved.addToCartComponent;
|
|
15843
15874
|
if (Injected) {
|
|
15844
15875
|
return /* @__PURE__ */ jsxRuntime.jsx(Injected, { product, labels: derived.labels, className: props.className });
|
|
@@ -18716,6 +18747,7 @@ exports.GridToolbar = GridToolbar_default;
|
|
|
18716
18747
|
exports.ItemStock = ItemStock_default;
|
|
18717
18748
|
exports.ItemsOverview = ItemsOverview_default;
|
|
18718
18749
|
exports.LoginForm = LoginForm_default;
|
|
18750
|
+
exports.LoginToOrderButton = LoginToOrderButton_default;
|
|
18719
18751
|
exports.MachineCard = MachineCard;
|
|
18720
18752
|
exports.MachineGrid = MachineGrid;
|
|
18721
18753
|
exports.Menu = Menu_default;
|