@propeller-commerce/propeller-v2-react-ui 0.7.1 → 0.9.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 +46 -0
- package/dist/index.cjs +115 -63
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +91 -6
- package/dist/index.d.ts +91 -6
- package/dist/index.js +116 -65
- package/dist/index.js.map +1 -1
- package/dist/pure.cjs +5 -5
- package/dist/pure.cjs.map +1 -1
- package/dist/pure.d.cts +7 -2
- package/dist/pure.d.ts +7 -2
- package/dist/pure.js +5 -5
- package/dist/pure.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,52 @@ 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.9.0] - 2026-07-29
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- **Align with `@propeller-commerce/propeller-sdk-v2` 0.14.0**, which removed the
|
|
16
|
+
entire deprecated schema surface. Category reads move to the plural localized
|
|
17
|
+
arrays — `Breadcrumbs` (`category.names` / `slugs`), `CategoryDescription`
|
|
18
|
+
(`descriptions`), `CategoryShortDescription` (`shortDescriptions`) — and the
|
|
19
|
+
hand-written menu query in `useMenu` now selects `names(language:)` /
|
|
20
|
+
`slugs(language:)`. `useClusterConfigurator` / `useProductInfo` read
|
|
21
|
+
`ClusterConfigSetting.attributeName` and `uuid` (were `name` / `id`); the
|
|
22
|
+
public `ConfiguredSetting.id` is now a `string`. Bumped the SDK dev dependency
|
|
23
|
+
to `^0.14.0` and `propeller-v2-core-ui` to `^0.4.0`; the runtime peer stays `*`.
|
|
24
|
+
|
|
25
|
+
## [0.8.0] - 2026-07-28
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **`<LoginToOrderButton>`** — a log-in call to action rendered in place of
|
|
30
|
+
add-to-cart for anonymous visitors of a semi-closed portal. Takes an
|
|
31
|
+
`onLoginClick` callback (the host owns navigation, mirroring
|
|
32
|
+
`RegisterForm.onLoginClick`) and a `loginToOrder` label. `ProductCard`,
|
|
33
|
+
`ProductInfo` and `ProductGrid` accept `onLoginClick` and forward it.
|
|
34
|
+
- **`showLoginPrompt` on `<ProductPrice>` and `<ProductBundles>`** — set
|
|
35
|
+
`false` to render nothing where the "log in to see prices" text would go.
|
|
36
|
+
Defaults to `true`, so existing behaviour is unchanged.
|
|
37
|
+
- **`portalMode` on `<ProductCard>`, `<ClusterCard>` and `<ClusterOptions>`** —
|
|
38
|
+
resolved from `<PropellerProvider>` like the other Tier 1 infra props; an
|
|
39
|
+
explicit prop still wins.
|
|
40
|
+
|
|
41
|
+
### Fixed
|
|
42
|
+
|
|
43
|
+
- **Semi-closed portals leaked price and stock in listings.** `ProductCard`
|
|
44
|
+
never received `portalMode`, so the price it renders through `<ProductPrice>`
|
|
45
|
+
and its stock row stayed visible to anonymous visitors even though the toolbar
|
|
46
|
+
and price filter were correctly gated. `ClusterCard` had the same gap, and
|
|
47
|
+
`ClusterOptions` printed option prices in its dropdown labels and selection
|
|
48
|
+
preview. All now gate on the shared `isContentHidden(portalMode, user)`.
|
|
49
|
+
- **`ProductGrid` hid add-to-cart from signed-in users of a semi-closed
|
|
50
|
+
portal.** `showAddToCart()` tested `portalMode === 'open'` rather than
|
|
51
|
+
`isContentHidden`, so authenticated shoppers lost the control along with
|
|
52
|
+
anonymous ones. Signed-in users keep add-to-cart.
|
|
53
|
+
- **The CTA slot collapsed when content was hidden.** `ProductCard` gated the
|
|
54
|
+
slot on `allowAddToCart`, which `ProductGrid` passes as `false` in that case —
|
|
55
|
+
leaving no room for the log-in action. The slot now renders either control.
|
|
56
|
+
|
|
11
57
|
## [0.7.1] - 2026-07-28
|
|
12
58
|
|
|
13
59
|
### Fixed
|
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;
|
|
@@ -1126,7 +1127,7 @@ function useClusterConfigurator(options) {
|
|
|
1126
1127
|
const previousSelections = {};
|
|
1127
1128
|
for (let i = 0; i < settingIndex; i++) {
|
|
1128
1129
|
const prev = sortedSettings[i];
|
|
1129
|
-
if (selections[prev.
|
|
1130
|
+
if (selections[prev.attributeName]) previousSelections[prev.attributeName] = selections[prev.attributeName];
|
|
1130
1131
|
}
|
|
1131
1132
|
const matching = propellerV2CoreUi.filterProductsBySelections(products, previousSelections);
|
|
1132
1133
|
return propellerV2CoreUi.collectAttributeValues(matching, attributeName);
|
|
@@ -1135,43 +1136,43 @@ function useClusterConfigurator(options) {
|
|
|
1135
1136
|
const sortedSettings = getSortedSettings();
|
|
1136
1137
|
const sel = selectedAttributes;
|
|
1137
1138
|
return sortedSettings.map((setting, index) => {
|
|
1138
|
-
const availableValues = getAvailableValuesForIndexWithSelections(setting.
|
|
1139
|
-
const selectedValue = sel[setting.
|
|
1140
|
-
const isPreviousMissing = index > 0 && sortedSettings.slice(0, index).some((prev) => !sel[prev.
|
|
1139
|
+
const availableValues = getAvailableValuesForIndexWithSelections(setting.attributeName, index, sel);
|
|
1140
|
+
const selectedValue = sel[setting.attributeName] || "";
|
|
1141
|
+
const isPreviousMissing = index > 0 && sortedSettings.slice(0, index).some((prev) => !sel[prev.attributeName]);
|
|
1141
1142
|
const isDisabled = availableValues.length === 0 || isPreviousMissing;
|
|
1142
|
-
let displayName = setting.
|
|
1143
|
+
let displayName = setting.attributeName;
|
|
1143
1144
|
let attributeType;
|
|
1144
1145
|
for (const product of products) {
|
|
1145
1146
|
const items = product.attributes?.items;
|
|
1146
1147
|
if (!items) continue;
|
|
1147
|
-
const match = items.find((a) => propellerV2CoreUi.attributeNameMatches(a, setting.
|
|
1148
|
+
const match = items.find((a) => propellerV2CoreUi.attributeNameMatches(a, setting.attributeName));
|
|
1148
1149
|
if (!match) continue;
|
|
1149
|
-
displayName = propellerV2CoreUi.getAttributeDisplayName(match, language) || setting.
|
|
1150
|
+
displayName = propellerV2CoreUi.getAttributeDisplayName(match, language) || setting.attributeName;
|
|
1150
1151
|
attributeType = match.attributeDescription?.type ?? void 0;
|
|
1151
1152
|
break;
|
|
1152
1153
|
}
|
|
1153
|
-
return { id: setting.
|
|
1154
|
+
return { id: setting.uuid, name: setting.attributeName, displayType: setting.displayType, attributeType, priority: setting.priority, displayName, availableValues, selectedValue, disabled: isDisabled };
|
|
1154
1155
|
});
|
|
1155
1156
|
}, [products, config, selectedAttributes, language]);
|
|
1156
1157
|
const handleAttributeSelect = React6.useCallback(
|
|
1157
1158
|
(settingName, value) => {
|
|
1158
1159
|
const sortedSettings = getSortedSettings();
|
|
1159
|
-
const changedIndex = sortedSettings.findIndex((s) => s.
|
|
1160
|
+
const changedIndex = sortedSettings.findIndex((s) => s.attributeName === settingName);
|
|
1160
1161
|
if (changedIndex < 0) return;
|
|
1161
1162
|
const newSelections = { ...selectedAttributes };
|
|
1162
1163
|
newSelections[settingName] = value;
|
|
1163
|
-
for (let i = changedIndex + 1; i < sortedSettings.length; i++) delete newSelections[sortedSettings[i].
|
|
1164
|
+
for (let i = changedIndex + 1; i < sortedSettings.length; i++) delete newSelections[sortedSettings[i].attributeName];
|
|
1164
1165
|
for (let i = changedIndex + 1; i < sortedSettings.length; i++) {
|
|
1165
1166
|
const next = sortedSettings[i];
|
|
1166
|
-
const available = getAvailableValuesForIndexWithSelections(next.
|
|
1167
|
+
const available = getAvailableValuesForIndexWithSelections(next.attributeName, i, newSelections);
|
|
1167
1168
|
if (available.length > 0) {
|
|
1168
|
-
newSelections[next.
|
|
1169
|
+
newSelections[next.attributeName] = available[0];
|
|
1169
1170
|
} else {
|
|
1170
1171
|
break;
|
|
1171
1172
|
}
|
|
1172
1173
|
}
|
|
1173
1174
|
setSelectedAttributes(newSelections);
|
|
1174
|
-
const allSelected = sortedSettings.every((s) => !!newSelections[s.
|
|
1175
|
+
const allSelected = sortedSettings.every((s) => !!newSelections[s.attributeName]);
|
|
1175
1176
|
if (allSelected) {
|
|
1176
1177
|
const matching = propellerV2CoreUi.filterProductsBySelections(products, newSelections);
|
|
1177
1178
|
if (matching.length > 0 && onConfigurationChange) onConfigurationChange(matching[0]);
|
|
@@ -1187,15 +1188,15 @@ function useClusterConfigurator(options) {
|
|
|
1187
1188
|
if (!attrItems) return;
|
|
1188
1189
|
const initial = {};
|
|
1189
1190
|
for (const setting of sortedSettings) {
|
|
1190
|
-
const match = attrItems.find((a) => propellerV2CoreUi.attributeNameMatches(a, setting.
|
|
1191
|
+
const match = attrItems.find((a) => propellerV2CoreUi.attributeNameMatches(a, setting.attributeName));
|
|
1191
1192
|
if (match) {
|
|
1192
1193
|
const values = propellerV2CoreUi.extractAttributeValues(match);
|
|
1193
|
-
if (values.length) initial[setting.
|
|
1194
|
+
if (values.length) initial[setting.attributeName] = values[0];
|
|
1194
1195
|
}
|
|
1195
1196
|
}
|
|
1196
1197
|
if (!Object.keys(initial).length) return;
|
|
1197
1198
|
setSelectedAttributes(initial);
|
|
1198
|
-
const allSelected = sortedSettings.every((s) => !!initial[s.
|
|
1199
|
+
const allSelected = sortedSettings.every((s) => !!initial[s.attributeName]);
|
|
1199
1200
|
if (allSelected && onConfigurationChange) {
|
|
1200
1201
|
const matching = propellerV2CoreUi.filterProductsBySelections(products, initial);
|
|
1201
1202
|
if (matching.length > 0) onConfigurationChange(matching[0]);
|
|
@@ -1531,15 +1532,15 @@ function buildCategoriesQuery(depth) {
|
|
|
1531
1532
|
categories {
|
|
1532
1533
|
categoryId
|
|
1533
1534
|
hidden
|
|
1534
|
-
|
|
1535
|
-
|
|
1535
|
+
names(language: $language) { value language }
|
|
1536
|
+
slugs(language: $language) { value }
|
|
1536
1537
|
${buildCategoriesQuery(depth - 1)}
|
|
1537
1538
|
}
|
|
1538
1539
|
`;
|
|
1539
1540
|
}
|
|
1540
1541
|
function mapCategory(raw, language) {
|
|
1541
|
-
const nameEntry = raw.
|
|
1542
|
-
const slugEntry = raw.
|
|
1542
|
+
const nameEntry = raw.names?.find((n) => n.language === language) ?? raw.names?.[0];
|
|
1543
|
+
const slugEntry = raw.slugs?.[0];
|
|
1543
1544
|
return {
|
|
1544
1545
|
categoryId: raw.categoryId,
|
|
1545
1546
|
name: nameEntry?.value ?? "",
|
|
@@ -1619,8 +1620,8 @@ function useMenu(options) {
|
|
|
1619
1620
|
category(categoryId: $categoryId) {
|
|
1620
1621
|
categoryId
|
|
1621
1622
|
hidden
|
|
1622
|
-
|
|
1623
|
-
|
|
1623
|
+
names(language: $language) { value language }
|
|
1624
|
+
slugs(language: $language) { value }
|
|
1624
1625
|
${buildCategoriesQuery(depth)}
|
|
1625
1626
|
}
|
|
1626
1627
|
}
|
|
@@ -2079,7 +2080,7 @@ function useProductInfo(options) {
|
|
|
2079
2080
|
const service = propellerV2CoreUi.createServices(graphqlClient).cluster;
|
|
2080
2081
|
const clusterConfig = await service.getClusterConfig(clusterId);
|
|
2081
2082
|
const attributeNames = (clusterConfig?.config?.settings ?? []).map(
|
|
2082
|
-
(setting) => setting.
|
|
2083
|
+
(setting) => setting.attributeName
|
|
2083
2084
|
);
|
|
2084
2085
|
const variables = {
|
|
2085
2086
|
clusterId,
|
|
@@ -6174,8 +6175,8 @@ function Breadcrumbs(props) {
|
|
|
6174
6175
|
}
|
|
6175
6176
|
const displayItems = props.showCurrent === false && items.length > 0 ? items.slice(0, items.length - 1) : items;
|
|
6176
6177
|
function getCategoryName(cat) {
|
|
6177
|
-
const match = cat.
|
|
6178
|
-
return match?.value || cat.
|
|
6178
|
+
const match = cat.names?.find((n) => n.language === lang);
|
|
6179
|
+
return match?.value || cat.names?.[0]?.value || "";
|
|
6179
6180
|
}
|
|
6180
6181
|
function getCategoryUrl(cat, index) {
|
|
6181
6182
|
if (props.getUrl) return props.getUrl(cat, index);
|
|
@@ -6183,7 +6184,7 @@ function Breadcrumbs(props) {
|
|
|
6183
6184
|
if (urls && typeof urls.getCategoryUrl === "function") {
|
|
6184
6185
|
return urls.getCategoryUrl(cat, props.language);
|
|
6185
6186
|
}
|
|
6186
|
-
const slug = cat.
|
|
6187
|
+
const slug = cat.slugs?.find((s) => s.language === lang)?.value || cat.slugs?.[0]?.value || "";
|
|
6187
6188
|
return `/category/${cat.categoryId}/${slug}`;
|
|
6188
6189
|
}
|
|
6189
6190
|
function isCurrentItem(index) {
|
|
@@ -7873,7 +7874,7 @@ function CartSummary(rawProps) {
|
|
|
7873
7874
|
var CartSummary_default = CartSummary;
|
|
7874
7875
|
function CategoryDescription(props) {
|
|
7875
7876
|
const [expanded, setExpanded] = React6.useState(false);
|
|
7876
|
-
const match = props.category?.
|
|
7877
|
+
const match = props.category?.descriptions?.find(
|
|
7877
7878
|
(d) => d.language === props.language
|
|
7878
7879
|
);
|
|
7879
7880
|
const html = match?.value || "";
|
|
@@ -7914,7 +7915,7 @@ function CategoryDescription(props) {
|
|
|
7914
7915
|
}
|
|
7915
7916
|
var CategoryDescription_default = CategoryDescription;
|
|
7916
7917
|
function CategoryShortDescription(props) {
|
|
7917
|
-
const match = props.category?.
|
|
7918
|
+
const match = props.category?.shortDescriptions?.find(
|
|
7918
7919
|
(d) => d.language === props.language
|
|
7919
7920
|
);
|
|
7920
7921
|
const html = match?.value || "";
|
|
@@ -7958,6 +7959,8 @@ var RESOLVE_SPEC = {
|
|
|
7958
7959
|
includeTax: { infra: "includeTax" },
|
|
7959
7960
|
language: { infra: "language", default: "NL" },
|
|
7960
7961
|
currency: { infra: "currency", default: "\u20AC" },
|
|
7962
|
+
user: { infra: "user", default: null },
|
|
7963
|
+
portalMode: { infra: "portalMode" },
|
|
7961
7964
|
columns: { grid: "columns", default: 3 },
|
|
7962
7965
|
showPrice: { grid: "showPrice" },
|
|
7963
7966
|
showStock: { grid: "showStock" },
|
|
@@ -8001,9 +8004,10 @@ function ClusterCard(rawProps) {
|
|
|
8001
8004
|
const textLabelValues = resolveAttributeValues(cluster, props.textLabels).map((value) => ({
|
|
8002
8005
|
value
|
|
8003
8006
|
}));
|
|
8004
|
-
const
|
|
8007
|
+
const contentHidden = propellerV2CoreUi.isContentHidden(props.portalMode, props.user);
|
|
8008
|
+
const defaultProductInventory = contentHidden ? void 0 : cluster?.defaultProduct?.inventory;
|
|
8005
8009
|
const useTax = props.includeTax !== void 0 ? !!props.includeTax : false;
|
|
8006
|
-
const priceObj = cluster?.defaultProduct?.price;
|
|
8010
|
+
const priceObj = contentHidden ? void 0 : cluster?.defaultProduct?.price;
|
|
8007
8011
|
const priceValue = useTax ? priceObj?.net : priceObj?.gross;
|
|
8008
8012
|
const clusterPrice = props.showPrice === false ? "" : propellerV2CoreUi.formatPrice(priceValue, { symbol: props.currency ?? "\u20AC" });
|
|
8009
8013
|
function handleClusterClick(e) {
|
|
@@ -8408,6 +8412,23 @@ function MachineCard(props) {
|
|
|
8408
8412
|
}
|
|
8409
8413
|
);
|
|
8410
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;
|
|
8411
8432
|
function ProductPriceDisplay(props) {
|
|
8412
8433
|
function isHidden2() {
|
|
8413
8434
|
return propellerV2CoreUi.isContentHidden(props.portalMode, props.user);
|
|
@@ -8458,7 +8479,7 @@ function ProductPriceDisplay(props) {
|
|
|
8458
8479
|
return props.includeTax ? propellerV2CoreUi.getLabel(props.labels, "exclTax", "excl. VAT") : propellerV2CoreUi.getLabel(props.labels, "inclTax", "incl. VAT");
|
|
8459
8480
|
}
|
|
8460
8481
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `propeller-product-price ${props.className || ""}`, "data-hidden": isHidden2() ? "true" : "false", children: [
|
|
8461
|
-
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,
|
|
8462
8483
|
!isHidden2() && !!getLeadingPrice() ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-price__content flex flex-col gap-0.5", children: [
|
|
8463
8484
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-price__primary flex items-baseline gap-2", children: [
|
|
8464
8485
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8501,6 +8522,7 @@ var RESOLVE_SPEC2 = {
|
|
|
8501
8522
|
companyId: { infra: "companyId" },
|
|
8502
8523
|
language: { infra: "language", default: "NL" },
|
|
8503
8524
|
includeTax: { infra: "includeTax" },
|
|
8525
|
+
portalMode: { infra: "portalMode" },
|
|
8504
8526
|
configuration: { infra: "configuration" },
|
|
8505
8527
|
columns: { grid: "columns", default: 3 },
|
|
8506
8528
|
showPrice: { grid: "showPrice" },
|
|
@@ -8522,6 +8544,7 @@ var RESOLVE_SPEC2 = {
|
|
|
8522
8544
|
onCartCreated: { grid: "onCartCreated" },
|
|
8523
8545
|
afterAddToCart: { grid: "afterAddToCart" },
|
|
8524
8546
|
onProceedToCheckout: { grid: "onProceedToCheckout" },
|
|
8547
|
+
onLoginClick: { grid: "onLoginClick" },
|
|
8525
8548
|
onRequestQuoteClick: { grid: "onRequestQuoteClick" },
|
|
8526
8549
|
onProductClick: { grid: "onProductClick" },
|
|
8527
8550
|
onToggleFavorite: {
|
|
@@ -8553,6 +8576,9 @@ function ProductCardRoot(rawProps) {
|
|
|
8553
8576
|
const language = props.language || "NL";
|
|
8554
8577
|
const product = props.product;
|
|
8555
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;
|
|
8556
8582
|
const name = getProductName(product, language);
|
|
8557
8583
|
const sku = propellerV2CoreUi.getProductSku(product);
|
|
8558
8584
|
const imageUrl = propellerV2CoreUi.getProductImageUrl(product);
|
|
@@ -8623,10 +8649,10 @@ function ProductCardRoot(rawProps) {
|
|
|
8623
8649
|
] }) }),
|
|
8624
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: [
|
|
8625
8651
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-product-card__footer-meta flex items-center justify-between gap-3 md:contents", children: [
|
|
8626
|
-
|
|
8652
|
+
showStock && !!product.inventory ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardStock, {}) : null,
|
|
8627
8653
|
props.showPrice !== false && !!product?.price ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardPrice, { priceSize: "text-sm" }) : null
|
|
8628
8654
|
] }),
|
|
8629
|
-
|
|
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
|
|
8630
8656
|
] })
|
|
8631
8657
|
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8632
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: [
|
|
@@ -8634,16 +8660,16 @@ function ProductCardRoot(rawProps) {
|
|
|
8634
8660
|
props.showName !== false ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardName, { linkable: true }) : null,
|
|
8635
8661
|
/* @__PURE__ */ jsxRuntime.jsx(ProductCardBelowName, {}),
|
|
8636
8662
|
textLabelValues.length > 0 ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardTextLabels, {}) : null,
|
|
8637
|
-
|
|
8663
|
+
showStock && !!product.inventory ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "hidden md:block", children: /* @__PURE__ */ jsxRuntime.jsx(ProductCardStock, {}) }) : null,
|
|
8638
8664
|
props.showManufacturer && manufacturer ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardManufacturer, {}) : null,
|
|
8639
8665
|
props.showShortDescription && shortDescription ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardShortDescription, {}) : null,
|
|
8640
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
|
|
8641
8667
|
] }),
|
|
8642
|
-
|
|
8643
|
-
|
|
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,
|
|
8644
8670
|
props.showPrice !== false && !!product?.price ? /* @__PURE__ */ jsxRuntime.jsx(ProductCardPrice, { priceSize: "text-base", className: "propeller-product-card__price min-w-0 text-right" }) : null
|
|
8645
8671
|
] }) : null,
|
|
8646
|
-
|
|
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
|
|
8647
8673
|
] })
|
|
8648
8674
|
]
|
|
8649
8675
|
}
|
|
@@ -8842,12 +8868,25 @@ function ProductCardPrice(props) {
|
|
|
8842
8868
|
price: product.price,
|
|
8843
8869
|
includeTax: derived.useTax,
|
|
8844
8870
|
priceSize: props.priceSize ?? "text-base sm:text-lg",
|
|
8845
|
-
labels: resolved.priceLabels
|
|
8871
|
+
labels: resolved.priceLabels,
|
|
8872
|
+
portalMode: resolved.portalMode,
|
|
8873
|
+
user: resolved.user,
|
|
8874
|
+
showLoginPrompt: false
|
|
8846
8875
|
}
|
|
8847
8876
|
) });
|
|
8848
8877
|
}
|
|
8849
8878
|
function ProductCardAddToCart(props) {
|
|
8850
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
|
+
}
|
|
8851
8890
|
const InjectedAddToCart = resolved.addToCartComponent;
|
|
8852
8891
|
if (InjectedAddToCart) {
|
|
8853
8892
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -8980,9 +9019,8 @@ function ProductGrid(rawProps) {
|
|
|
8980
9019
|
return !!props.isLoading || isLoading;
|
|
8981
9020
|
}
|
|
8982
9021
|
function showAddToCart() {
|
|
8983
|
-
const mode = props.portalMode || "open";
|
|
8984
9022
|
const allow = props.allowAddToCart !== false;
|
|
8985
|
-
return
|
|
9023
|
+
return !propellerV2CoreUi.isContentHidden(props.portalMode, props.user) && allow;
|
|
8986
9024
|
}
|
|
8987
9025
|
function getSkeletonItems() {
|
|
8988
9026
|
const cols = props.columns || 3;
|
|
@@ -9009,6 +9047,7 @@ function ProductGrid(rawProps) {
|
|
|
9009
9047
|
onCartCreated: props.onCartCreated,
|
|
9010
9048
|
afterAddToCart: props.afterAddToCart,
|
|
9011
9049
|
onProceedToCheckout: props.onProceedToCheckout,
|
|
9050
|
+
onLoginClick: props.onLoginClick,
|
|
9012
9051
|
onRequestQuoteClick: props.onRequestQuoteClick,
|
|
9013
9052
|
onToggleFavorite: (item, isFav) => props.onToggleFavorite?.(item, isFav),
|
|
9014
9053
|
onProductClick: (p) => props.onProductClick?.(p),
|
|
@@ -9657,7 +9696,7 @@ function GridToolbar(rawProps) {
|
|
|
9657
9696
|
const [currentSortOrder, setCurrentSortOrder] = React6.useState(propellerSdkV2.SortOrder.DESC);
|
|
9658
9697
|
const [currentOffset, setCurrentOffset] = React6.useState(12);
|
|
9659
9698
|
const [currentViewMode, setCurrentViewMode] = React6.useState("grid");
|
|
9660
|
-
function
|
|
9699
|
+
function getLabel56(key) {
|
|
9661
9700
|
const labels = props.labels || {};
|
|
9662
9701
|
return labels[key] !== void 0 ? labels[key] : DEFAULT_LABELS[key] || key;
|
|
9663
9702
|
}
|
|
@@ -9736,7 +9775,7 @@ function GridToolbar(rawProps) {
|
|
|
9736
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: [
|
|
9737
9776
|
props.itemsFound,
|
|
9738
9777
|
"\xA0",
|
|
9739
|
-
props.itemsFound === 1 ?
|
|
9778
|
+
props.itemsFound === 1 ? getLabel56("productSingular") : getLabel56("productPlural")
|
|
9740
9779
|
] }) : null }),
|
|
9741
9780
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "propeller-grid-toolbar__controls flex flex-wrap items-center gap-3", children: [
|
|
9742
9781
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -9747,7 +9786,7 @@ function GridToolbar(rawProps) {
|
|
|
9747
9786
|
onChange: (e) => handleOffsetChange(parseInt(e.target.value)),
|
|
9748
9787
|
children: getOffsetOptions()?.map((n) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: n, children: [
|
|
9749
9788
|
n,
|
|
9750
|
-
|
|
9789
|
+
getLabel56("perPage")
|
|
9751
9790
|
] }, n))
|
|
9752
9791
|
}
|
|
9753
9792
|
),
|
|
@@ -9763,7 +9802,7 @@ function GridToolbar(rawProps) {
|
|
|
9763
9802
|
{
|
|
9764
9803
|
value: field,
|
|
9765
9804
|
disabled: field === "PRICE" && isPriceSortDisabled(),
|
|
9766
|
-
children:
|
|
9805
|
+
children: getLabel56(field)
|
|
9767
9806
|
},
|
|
9768
9807
|
field
|
|
9769
9808
|
))
|
|
@@ -9776,8 +9815,8 @@ function GridToolbar(rawProps) {
|
|
|
9776
9815
|
value: currentSortOrder,
|
|
9777
9816
|
onChange: (e) => handleSortOrderChange(e.target.value),
|
|
9778
9817
|
children: [
|
|
9779
|
-
/* @__PURE__ */ jsxRuntime.jsx("option", { value: propellerSdkV2.SortOrder.ASC, children:
|
|
9780
|
-
/* @__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") })
|
|
9781
9820
|
]
|
|
9782
9821
|
}
|
|
9783
9822
|
),
|
|
@@ -9787,7 +9826,7 @@ function GridToolbar(rawProps) {
|
|
|
9787
9826
|
type: "button",
|
|
9788
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",
|
|
9789
9828
|
onClick: (event) => handleViewChange(),
|
|
9790
|
-
title: currentViewMode === "grid" ?
|
|
9829
|
+
title: currentViewMode === "grid" ? getLabel56("switchToList") : getLabel56("switchToGrid"),
|
|
9791
9830
|
children: [
|
|
9792
9831
|
currentViewMode === "grid" ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
9793
9832
|
"svg",
|
|
@@ -9845,7 +9884,7 @@ function GridToolbar(rawProps) {
|
|
|
9845
9884
|
onClick: (event) => {
|
|
9846
9885
|
if (props.onClearFilters) props.onClearFilters();
|
|
9847
9886
|
},
|
|
9848
|
-
children:
|
|
9887
|
+
children: getLabel56("clearAll")
|
|
9849
9888
|
}
|
|
9850
9889
|
),
|
|
9851
9890
|
props.priceFilterMin !== void 0 || props.priceFilterMax !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -9856,7 +9895,7 @@ function GridToolbar(rawProps) {
|
|
|
9856
9895
|
if (props.onPriceFilterRemove) props.onPriceFilterRemove();
|
|
9857
9896
|
},
|
|
9858
9897
|
children: [
|
|
9859
|
-
|
|
9898
|
+
getLabel56("price"),
|
|
9860
9899
|
": \u20AC",
|
|
9861
9900
|
props.priceFilterMin ?? 0,
|
|
9862
9901
|
" \u2013 \u20AC",
|
|
@@ -9893,7 +9932,7 @@ var DEFAULT_LABELS2 = {
|
|
|
9893
9932
|
of: "of"
|
|
9894
9933
|
};
|
|
9895
9934
|
function GridPagination(props) {
|
|
9896
|
-
function
|
|
9935
|
+
function getLabel56(key) {
|
|
9897
9936
|
const labels = props.labels || {};
|
|
9898
9937
|
return labels[key] !== void 0 ? labels[key] : DEFAULT_LABELS2[key] || key;
|
|
9899
9938
|
}
|
|
@@ -9966,15 +10005,15 @@ function GridPagination(props) {
|
|
|
9966
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",
|
|
9967
10006
|
disabled: currentPage === 1,
|
|
9968
10007
|
onClick: () => handlePageChange(currentPage - 1),
|
|
9969
|
-
children:
|
|
10008
|
+
children: getLabel56("previous")
|
|
9970
10009
|
}
|
|
9971
10010
|
),
|
|
9972
10011
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "propeller-grid-pagination__info px-2 text-sm font-medium text-muted-foreground", children: [
|
|
9973
|
-
|
|
10012
|
+
getLabel56("page"),
|
|
9974
10013
|
"\xA0",
|
|
9975
10014
|
currentPage,
|
|
9976
10015
|
"\xA0",
|
|
9977
|
-
|
|
10016
|
+
getLabel56("of"),
|
|
9978
10017
|
"\xA0",
|
|
9979
10018
|
totalPages
|
|
9980
10019
|
] }),
|
|
@@ -9985,7 +10024,7 @@ function GridPagination(props) {
|
|
|
9985
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",
|
|
9986
10025
|
disabled: currentPage === totalPages,
|
|
9987
10026
|
onClick: () => handlePageChange(currentPage + 1),
|
|
9988
|
-
children:
|
|
10027
|
+
children: getLabel56("next")
|
|
9989
10028
|
}
|
|
9990
10029
|
)
|
|
9991
10030
|
] }) : null,
|
|
@@ -9997,7 +10036,7 @@ function GridPagination(props) {
|
|
|
9997
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",
|
|
9998
10037
|
disabled: currentPage === 1,
|
|
9999
10038
|
onClick: () => handlePageChange(currentPage - 1),
|
|
10000
|
-
children:
|
|
10039
|
+
children: getLabel56("previous")
|
|
10001
10040
|
}
|
|
10002
10041
|
),
|
|
10003
10042
|
getFullPages().map((item, idx) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10024,7 +10063,7 @@ function GridPagination(props) {
|
|
|
10024
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",
|
|
10025
10064
|
disabled: currentPage === totalPages,
|
|
10026
10065
|
onClick: () => handlePageChange(currentPage + 1),
|
|
10027
|
-
children:
|
|
10066
|
+
children: getLabel56("next")
|
|
10028
10067
|
}
|
|
10029
10068
|
)
|
|
10030
10069
|
] }) : null
|
|
@@ -10516,13 +10555,14 @@ function ClusterOptions(props) {
|
|
|
10516
10555
|
function getOptionsForRender() {
|
|
10517
10556
|
const options = props.options || [];
|
|
10518
10557
|
const sel = selectedProductIds;
|
|
10558
|
+
const hidePrices = propellerV2CoreUi.isContentHidden(props.portalMode, props.user);
|
|
10519
10559
|
return options.filter((option) => option.hidden !== propellerSdkV2.YesNo.Y).map((option) => {
|
|
10520
10560
|
const idStr = option.id.toString();
|
|
10521
10561
|
const selectedProductId = sel[idStr] || "";
|
|
10522
10562
|
const products = (option.products || []).map((p) => ({
|
|
10523
10563
|
productId: p.productId,
|
|
10524
10564
|
productIdStr: p.productId.toString(),
|
|
10525
|
-
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")}`
|
|
10526
10566
|
}));
|
|
10527
10567
|
let previewImageUrl = "";
|
|
10528
10568
|
let previewName = "";
|
|
@@ -10534,7 +10574,7 @@ function ClusterOptions(props) {
|
|
|
10534
10574
|
if (selectedProduct) {
|
|
10535
10575
|
previewImageUrl = getProductImageUrl4(selectedProduct);
|
|
10536
10576
|
previewName = getProductName2(selectedProduct);
|
|
10537
|
-
previewPrice = formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC");
|
|
10577
|
+
previewPrice = hidePrices ? "" : formatPrice9(selectedProduct.price?.gross || 0, props.currency ?? "\u20AC");
|
|
10538
10578
|
}
|
|
10539
10579
|
}
|
|
10540
10580
|
const isRequired = option.isRequired === propellerSdkV2.YesNo.Y;
|
|
@@ -12768,7 +12808,7 @@ function Menu(rawProps) {
|
|
|
12768
12808
|
const lang = props.language || "NL";
|
|
12769
12809
|
const category = {
|
|
12770
12810
|
categoryId: cat.categoryId,
|
|
12771
|
-
|
|
12811
|
+
slugs: [{ value: cat.slug, language: lang }]
|
|
12772
12812
|
};
|
|
12773
12813
|
if (props.getUrl) return props.getUrl(category);
|
|
12774
12814
|
return props.configuration.urls.getCategoryUrl(category, lang);
|
|
@@ -12782,8 +12822,8 @@ function Menu(rawProps) {
|
|
|
12782
12822
|
const lang = props.language || "NL";
|
|
12783
12823
|
props.onMenuItemClick({
|
|
12784
12824
|
categoryId: cat.categoryId,
|
|
12785
|
-
|
|
12786
|
-
|
|
12825
|
+
names: [{ value: cat.name, language: lang }],
|
|
12826
|
+
slugs: [{ value: cat.slug, language: lang }]
|
|
12787
12827
|
});
|
|
12788
12828
|
}
|
|
12789
12829
|
}
|
|
@@ -15006,11 +15046,11 @@ function ProductBundles(rawProps) {
|
|
|
15006
15046
|
children: addingBundleId === bundle.id ? propellerV2CoreUi.getLabel(props.labels, "adding", "Adding...") : propellerV2CoreUi.getLabel(props.labels, "addToCart", "In cart")
|
|
15007
15047
|
}
|
|
15008
15048
|
)
|
|
15009
|
-
] }) : /* @__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(
|
|
15010
15050
|
props.labels,
|
|
15011
15051
|
"loginToSeePrices",
|
|
15012
15052
|
"Log in to see prices and add to cart"
|
|
15013
|
-
) })
|
|
15053
|
+
) }) : null
|
|
15014
15054
|
] })
|
|
15015
15055
|
] })
|
|
15016
15056
|
},
|
|
@@ -15793,6 +15833,7 @@ function ProductInfoPrice(props = {}) {
|
|
|
15793
15833
|
function ProductInfoStock(props = {}) {
|
|
15794
15834
|
const { product, resolved, derived } = useProductInfoContext();
|
|
15795
15835
|
if (!product.inventory) return null;
|
|
15836
|
+
if (propellerV2CoreUi.isContentHidden(derived.portalMode, resolved.user)) return null;
|
|
15796
15837
|
const Injected = resolved.stockComponent;
|
|
15797
15838
|
if (Injected) {
|
|
15798
15839
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -15819,6 +15860,16 @@ function ProductInfoStock(props = {}) {
|
|
|
15819
15860
|
}
|
|
15820
15861
|
function ProductInfoAddToCart(props = {}) {
|
|
15821
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
|
+
}
|
|
15822
15873
|
const Injected = resolved.addToCartComponent;
|
|
15823
15874
|
if (Injected) {
|
|
15824
15875
|
return /* @__PURE__ */ jsxRuntime.jsx(Injected, { product, labels: derived.labels, className: props.className });
|
|
@@ -18696,6 +18747,7 @@ exports.GridToolbar = GridToolbar_default;
|
|
|
18696
18747
|
exports.ItemStock = ItemStock_default;
|
|
18697
18748
|
exports.ItemsOverview = ItemsOverview_default;
|
|
18698
18749
|
exports.LoginForm = LoginForm_default;
|
|
18750
|
+
exports.LoginToOrderButton = LoginToOrderButton_default;
|
|
18699
18751
|
exports.MachineCard = MachineCard;
|
|
18700
18752
|
exports.MachineGrid = MachineGrid;
|
|
18701
18753
|
exports.Menu = Menu_default;
|