@propeller-commerce/propeller-v2-react-ui 0.4.17 → 0.4.19
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 +24 -0
- package/dist/index.cjs +46 -28
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +47 -29
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -6077,6 +6077,27 @@ interface ProductSpecificationsProps {
|
|
|
6077
6077
|
* rendered above the attribute table. Omitted when empty.
|
|
6078
6078
|
*/
|
|
6079
6079
|
packageDescription?: string;
|
|
6080
|
+
/**
|
|
6081
|
+
* Render arbitrary content at the START of the specifications, before the
|
|
6082
|
+
* fetched attribute rows. Receives the active `layout` so the consumer can
|
|
6083
|
+
* return markup that fits the container:
|
|
6084
|
+
* - `'table'` → return one or more `<tr>` (injected inside `<tbody>`), e.g.
|
|
6085
|
+
* a labelled "Unit of measure" row.
|
|
6086
|
+
* - `'list'` → return block element(s) (injected inside the list stack).
|
|
6087
|
+
* In grouped mode it renders once, above the first group. Return
|
|
6088
|
+
* `null`/`undefined` to render nothing.
|
|
6089
|
+
*/
|
|
6090
|
+
beforeSpecs?: (ctx: {
|
|
6091
|
+
layout: 'table' | 'list';
|
|
6092
|
+
}) => React$1.ReactNode;
|
|
6093
|
+
/**
|
|
6094
|
+
* Render arbitrary content at the END of the specifications, after the
|
|
6095
|
+
* fetched attribute rows. Same `layout` contract as {@link beforeSpecs}.
|
|
6096
|
+
* In grouped mode it renders once, below the last group.
|
|
6097
|
+
*/
|
|
6098
|
+
afterSpecs?: (ctx: {
|
|
6099
|
+
layout: 'table' | 'list';
|
|
6100
|
+
}) => React$1.ReactNode;
|
|
6080
6101
|
/** Extra CSS class applied to the root element. */
|
|
6081
6102
|
className?: string;
|
|
6082
6103
|
}
|
|
@@ -6180,6 +6201,22 @@ interface ProductTabsProps {
|
|
|
6180
6201
|
* ProductSpecifications.
|
|
6181
6202
|
*/
|
|
6182
6203
|
specificationsPackageDescription?: string;
|
|
6204
|
+
/**
|
|
6205
|
+
* Render arbitrary content at the start of the specifications section (before
|
|
6206
|
+
* the attribute rows) — e.g. a labelled "Unit of measure" row. Passed as
|
|
6207
|
+
* `beforeSpecs` to ProductSpecifications; receives the active `layout` so the
|
|
6208
|
+
* consumer can return a `<tr>` (table) or block (list).
|
|
6209
|
+
*/
|
|
6210
|
+
specificationsBeforeSpecs?: (ctx: {
|
|
6211
|
+
layout: 'table' | 'list';
|
|
6212
|
+
}) => React$1.ReactNode;
|
|
6213
|
+
/**
|
|
6214
|
+
* Render arbitrary content at the end of the specifications section (after the
|
|
6215
|
+
* attribute rows). Passed as `afterSpecs` to ProductSpecifications.
|
|
6216
|
+
*/
|
|
6217
|
+
specificationsAfterSpecs?: (ctx: {
|
|
6218
|
+
layout: 'table' | 'list';
|
|
6219
|
+
}) => React$1.ReactNode;
|
|
6183
6220
|
/**
|
|
6184
6221
|
* Override UI strings for the Downloads section.
|
|
6185
6222
|
* Available keys: title, download
|
package/dist/index.d.ts
CHANGED
|
@@ -6077,6 +6077,27 @@ interface ProductSpecificationsProps {
|
|
|
6077
6077
|
* rendered above the attribute table. Omitted when empty.
|
|
6078
6078
|
*/
|
|
6079
6079
|
packageDescription?: string;
|
|
6080
|
+
/**
|
|
6081
|
+
* Render arbitrary content at the START of the specifications, before the
|
|
6082
|
+
* fetched attribute rows. Receives the active `layout` so the consumer can
|
|
6083
|
+
* return markup that fits the container:
|
|
6084
|
+
* - `'table'` → return one or more `<tr>` (injected inside `<tbody>`), e.g.
|
|
6085
|
+
* a labelled "Unit of measure" row.
|
|
6086
|
+
* - `'list'` → return block element(s) (injected inside the list stack).
|
|
6087
|
+
* In grouped mode it renders once, above the first group. Return
|
|
6088
|
+
* `null`/`undefined` to render nothing.
|
|
6089
|
+
*/
|
|
6090
|
+
beforeSpecs?: (ctx: {
|
|
6091
|
+
layout: 'table' | 'list';
|
|
6092
|
+
}) => React$1.ReactNode;
|
|
6093
|
+
/**
|
|
6094
|
+
* Render arbitrary content at the END of the specifications, after the
|
|
6095
|
+
* fetched attribute rows. Same `layout` contract as {@link beforeSpecs}.
|
|
6096
|
+
* In grouped mode it renders once, below the last group.
|
|
6097
|
+
*/
|
|
6098
|
+
afterSpecs?: (ctx: {
|
|
6099
|
+
layout: 'table' | 'list';
|
|
6100
|
+
}) => React$1.ReactNode;
|
|
6080
6101
|
/** Extra CSS class applied to the root element. */
|
|
6081
6102
|
className?: string;
|
|
6082
6103
|
}
|
|
@@ -6180,6 +6201,22 @@ interface ProductTabsProps {
|
|
|
6180
6201
|
* ProductSpecifications.
|
|
6181
6202
|
*/
|
|
6182
6203
|
specificationsPackageDescription?: string;
|
|
6204
|
+
/**
|
|
6205
|
+
* Render arbitrary content at the start of the specifications section (before
|
|
6206
|
+
* the attribute rows) — e.g. a labelled "Unit of measure" row. Passed as
|
|
6207
|
+
* `beforeSpecs` to ProductSpecifications; receives the active `layout` so the
|
|
6208
|
+
* consumer can return a `<tr>` (table) or block (list).
|
|
6209
|
+
*/
|
|
6210
|
+
specificationsBeforeSpecs?: (ctx: {
|
|
6211
|
+
layout: 'table' | 'list';
|
|
6212
|
+
}) => React$1.ReactNode;
|
|
6213
|
+
/**
|
|
6214
|
+
* Render arbitrary content at the end of the specifications section (after the
|
|
6215
|
+
* attribute rows). Passed as `afterSpecs` to ProductSpecifications.
|
|
6216
|
+
*/
|
|
6217
|
+
specificationsAfterSpecs?: (ctx: {
|
|
6218
|
+
layout: 'table' | 'list';
|
|
6219
|
+
}) => React$1.ReactNode;
|
|
6183
6220
|
/**
|
|
6184
6221
|
* Override UI strings for the Downloads section.
|
|
6185
6222
|
* Available keys: title, download
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { getLabel, formatPrice, getClusterSku, getClusterImageUrl, getProductSku, getProductImageUrl, createServices, err, ok,
|
|
2
|
+
import { getLabel, getLocalizedValue, formatPrice, getClusterSku, getClusterImageUrl, getProductSku, getProductImageUrl, createServices, err, ok, formatSurcharge, deriveUserMode, isContact, isCustomer, getAddresses, isContentHidden, attributeNameMatches, getAttributeDisplayName, filterProductsBySelections, extractAttributeValues, getLanguageString, collectAttributeValues, getCountryName } from '@propeller-commerce/propeller-v2-core-ui';
|
|
3
3
|
export * from '@propeller-commerce/propeller-v2-core-ui';
|
|
4
4
|
import * as React6 from 'react';
|
|
5
5
|
import { createContext, useState, useRef, useMemo, useCallback, useContext, useEffect } from 'react';
|
|
@@ -3934,7 +3934,7 @@ function AddToCart(rawProps) {
|
|
|
3934
3934
|
}
|
|
3935
3935
|
function getModalName() {
|
|
3936
3936
|
if (addedCartItem) {
|
|
3937
|
-
return addedCartItem.product?.names
|
|
3937
|
+
return getLocalizedValue(addedCartItem.product?.names, props.language, "") || getLocalizedValue(props.product?.names, props.language, "Product");
|
|
3938
3938
|
}
|
|
3939
3939
|
return getLocalizedValue(props.product?.names, props.language, "Product");
|
|
3940
3940
|
}
|
|
@@ -4287,7 +4287,7 @@ function AddToCart(rawProps) {
|
|
|
4287
4287
|
{
|
|
4288
4288
|
className: "propeller-add-to-cart__modal-child flex justify-between items-center text-xs text-muted-foreground",
|
|
4289
4289
|
children: [
|
|
4290
|
-
/* @__PURE__ */ jsx("span", { className: "line-clamp-1", children: child.product?.names
|
|
4290
|
+
/* @__PURE__ */ jsx("span", { className: "line-clamp-1", children: getLocalizedValue(child.product?.names, props.language, "Option") }),
|
|
4291
4291
|
/* @__PURE__ */ jsx("span", { className: "text-foreground-subtle whitespace-nowrap ml-2", children: formatPrice(
|
|
4292
4292
|
((props.includeTax !== void 0 ? !!props.includeTax : includeTax) ? child.totalSumNet : child.totalSum) ?? 0,
|
|
4293
4293
|
{ symbol: props.currency ?? "\u20AC" }
|
|
@@ -6040,7 +6040,7 @@ function CartItem(rawProps) {
|
|
|
6040
6040
|
const minQuantity = getMinQuantity(props.cartItem.product);
|
|
6041
6041
|
const step = getStep(props.cartItem.product);
|
|
6042
6042
|
function getProductName5() {
|
|
6043
|
-
return props.cartItem.product?.names
|
|
6043
|
+
return getLocalizedValue(props.cartItem.product?.names, props.language, "Product");
|
|
6044
6044
|
}
|
|
6045
6045
|
function getProductUrl2() {
|
|
6046
6046
|
if (props.configuration?.urls && props.cartItem.product) {
|
|
@@ -6091,7 +6091,7 @@ function CartItem(rawProps) {
|
|
|
6091
6091
|
if (!items) return "";
|
|
6092
6092
|
const leader = items.find((bi) => bi.isLeader === YesNo.Y);
|
|
6093
6093
|
if (!leader) return "";
|
|
6094
|
-
return leader.product.names
|
|
6094
|
+
return getLocalizedValue(leader.product.names, props.language, "Product");
|
|
6095
6095
|
}
|
|
6096
6096
|
function getBundleLeaderPrice() {
|
|
6097
6097
|
const items = props.cartItem.bundle?.items;
|
|
@@ -6108,7 +6108,7 @@ function CartItem(rawProps) {
|
|
|
6108
6108
|
return items.filter((bi) => bi.isLeader !== YesNo.Y);
|
|
6109
6109
|
}
|
|
6110
6110
|
function getBundleItemName(bundleItem) {
|
|
6111
|
-
return bundleItem.product.names
|
|
6111
|
+
return getLocalizedValue(bundleItem.product.names, props.language, "Product");
|
|
6112
6112
|
}
|
|
6113
6113
|
function getBundleItemPrice(bundleItem) {
|
|
6114
6114
|
const price = bundleItem.price?.net;
|
|
@@ -6117,7 +6117,7 @@ function CartItem(rawProps) {
|
|
|
6117
6117
|
}
|
|
6118
6118
|
function getCrossupsellName(item) {
|
|
6119
6119
|
const product = item?.productTo || item?.clusterTo;
|
|
6120
|
-
return product?.names
|
|
6120
|
+
return getLocalizedValue(product?.names, props.language, "Product");
|
|
6121
6121
|
}
|
|
6122
6122
|
function getCrossupsellImageUrl(item) {
|
|
6123
6123
|
const product = item?.productTo || item?.clusterTo;
|
|
@@ -6442,7 +6442,7 @@ function CartItemChildItems(props = {}) {
|
|
|
6442
6442
|
return /* @__PURE__ */ jsxs("div", { className: props.className ?? "propeller-cart-item__options mt-3 space-y-1.5 border-l-2 border-border pl-3", children: [
|
|
6443
6443
|
/* @__PURE__ */ jsx("p", { className: "propeller-cart-item__options-label text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-1", children: getLabel(resolved.labels, "includedOptions", "Included Options:") }),
|
|
6444
6444
|
(cartItem.childItems || []).map((child, idx) => /* @__PURE__ */ jsxs("div", { className: "propeller-cart-item__option flex flex-wrap gap-x-2 text-sm text-muted-foreground", children: [
|
|
6445
|
-
/* @__PURE__ */ jsx("span", { className: "font-medium", children: child.product.names
|
|
6445
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: getLocalizedValue(child.product.names, resolved.language, "Option") }),
|
|
6446
6446
|
/* @__PURE__ */ jsx("span", { className: "text-foreground-subtle hidden sm:inline", children: "-" }),
|
|
6447
6447
|
/* @__PURE__ */ jsx("span", { className: "text-foreground-subtle text-xs self-center", children: child.product.sku }),
|
|
6448
6448
|
/* @__PURE__ */ jsx("div", { className: "flex-1 border-b border-dotted border-border mx-1 mb-1" }),
|
|
@@ -15095,7 +15095,11 @@ function ProductSpecifications(rawProps) {
|
|
|
15095
15095
|
if (!props.productId || !props.graphqlClient) return;
|
|
15096
15096
|
fetchSpecs(props.productId);
|
|
15097
15097
|
}, [props.productId]);
|
|
15098
|
-
|
|
15098
|
+
const layoutMode = props.layout === "list" ? "list" : "table";
|
|
15099
|
+
const before = props.beforeSpecs?.({ layout: layoutMode });
|
|
15100
|
+
const after = props.afterSpecs?.({ layout: layoutMode });
|
|
15101
|
+
const hasSlotContent = before != null || after != null;
|
|
15102
|
+
return /* @__PURE__ */ jsx(Fragment, { children: !loading && (hasPublicAttributes() || props.packageDescription || hasSlotContent) ? /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(
|
|
15099
15103
|
"div",
|
|
15100
15104
|
{
|
|
15101
15105
|
className: `propeller-product-specifications ${props.className || ""}`,
|
|
@@ -15104,26 +15108,38 @@ function ProductSpecifications(rawProps) {
|
|
|
15104
15108
|
children: [
|
|
15105
15109
|
props.packageDescription ? /* @__PURE__ */ jsx("p", { className: "propeller-product-specifications__package-description mb-4 text-sm text-muted-foreground", children: props.packageDescription }) : null,
|
|
15106
15110
|
!props.grouping ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15107
|
-
props.layout !== "list" ? /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */
|
|
15108
|
-
|
|
15109
|
-
/* @__PURE__ */
|
|
15110
|
-
|
|
15111
|
-
|
|
15112
|
-
|
|
15113
|
-
|
|
15114
|
-
] }
|
|
15111
|
+
props.layout !== "list" ? /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsxs("tbody", { className: "divide-y divide-border", children: [
|
|
15112
|
+
before,
|
|
15113
|
+
getAttributes()?.map((attr, i) => /* @__PURE__ */ jsxs("tr", { className: "propeller-product-specifications__row odd:bg-card even:bg-muted/20", children: [
|
|
15114
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-2 font-medium text-foreground w-1/2", children: getAttributeLabel(attr) }),
|
|
15115
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-2 text-muted-foreground", children: getAttributeValue(attr) })
|
|
15116
|
+
] }, i)),
|
|
15117
|
+
after
|
|
15118
|
+
] }) }) }) : null,
|
|
15119
|
+
props.layout === "list" ? /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
15120
|
+
before,
|
|
15121
|
+
getAttributes()?.map((attr, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
15122
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: getAttributeLabel(attr) }),
|
|
15123
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-foreground", children: getAttributeValue(attr) })
|
|
15124
|
+
] }, i)),
|
|
15125
|
+
after
|
|
15126
|
+
] }) : null
|
|
15115
15127
|
] }) : null,
|
|
15116
|
-
!!props.grouping ? /* @__PURE__ */
|
|
15117
|
-
|
|
15118
|
-
|
|
15119
|
-
/* @__PURE__ */ jsx("
|
|
15120
|
-
/* @__PURE__ */ jsx("
|
|
15121
|
-
|
|
15122
|
-
|
|
15123
|
-
|
|
15124
|
-
/* @__PURE__ */ jsx("
|
|
15125
|
-
|
|
15126
|
-
|
|
15128
|
+
!!props.grouping ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15129
|
+
before ? layoutMode === "table" ? /* @__PURE__ */ jsx("div", { className: "mb-6 overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-border", children: before }) }) }) : /* @__PURE__ */ jsx("div", { className: "mb-6 space-y-3", children: before }) : null,
|
|
15130
|
+
getGroups()?.map((group) => /* @__PURE__ */ jsxs("div", { className: "mb-6", children: [
|
|
15131
|
+
!!group ? /* @__PURE__ */ jsx("h4", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2", children: group }) : null,
|
|
15132
|
+
props.layout !== "list" ? /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-border", children: getAttributesByGroup(group)?.map((attr, i) => /* @__PURE__ */ jsxs("tr", { className: "propeller-product-specifications__row odd:bg-card even:bg-muted/20", children: [
|
|
15133
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-2 font-medium text-foreground w-1/2", children: getAttributeLabel(attr) }),
|
|
15134
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-2 text-muted-foreground", children: getAttributeValue(attr) })
|
|
15135
|
+
] }, i)) }) }) }) : null,
|
|
15136
|
+
props.layout === "list" ? /* @__PURE__ */ jsx("div", { className: "space-y-3", children: getAttributesByGroup(group)?.map((attr, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-0.5", children: [
|
|
15137
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: getAttributeLabel(attr) }),
|
|
15138
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-foreground", children: getAttributeValue(attr) })
|
|
15139
|
+
] }, i)) }) : null
|
|
15140
|
+
] }, group)),
|
|
15141
|
+
after ? layoutMode === "table" ? /* @__PURE__ */ jsx("div", { className: "mb-6 overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsx("tbody", { className: "divide-y divide-border", children: after }) }) }) : /* @__PURE__ */ jsx("div", { className: "space-y-3", children: after }) : null
|
|
15142
|
+
] }) : null
|
|
15127
15143
|
]
|
|
15128
15144
|
}
|
|
15129
15145
|
) }) : null });
|
|
@@ -15332,7 +15348,9 @@ function ProductTabs(rawProps) {
|
|
|
15332
15348
|
language: props.language,
|
|
15333
15349
|
layout: props.specificationsLayout,
|
|
15334
15350
|
grouping: props.specificationsGrouping,
|
|
15335
|
-
packageDescription: props.specificationsPackageDescription
|
|
15351
|
+
packageDescription: props.specificationsPackageDescription,
|
|
15352
|
+
beforeSpecs: props.specificationsBeforeSpecs,
|
|
15353
|
+
afterSpecs: props.specificationsAfterSpecs
|
|
15336
15354
|
}
|
|
15337
15355
|
) }) : null,
|
|
15338
15356
|
isActive("downloads") && isTabVisible("downloads") ? /* @__PURE__ */ jsx(
|