@propeller-commerce/propeller-v2-react-ui 0.4.17 → 0.4.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -8,6 +8,20 @@ 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.4.18] - 2026-07-10
12
+
13
+ ### Added
14
+
15
+ - `ProductSpecifications`: new `beforeSpecs?` / `afterSpecs?` render-prop slots.
16
+ Each receives `{ layout: 'table' | 'list' }` and returns arbitrary content
17
+ injected at the start / end of the specifications — inside `<tbody>` for the
18
+ table layout (return a `<tr>`, e.g. a labelled "Unit of measure" row) or in
19
+ the list stack for the list layout (return a block). In grouped mode they
20
+ render once, above the first group / below the last. General replacement for
21
+ hardcoding extra rows; the existing `packageDescription` prop is unchanged.
22
+ - `ProductTabs`: `specificationsBeforeSpecs?` / `specificationsAfterSpecs?`
23
+ passthrough props that forward to the specifications section's new slots.
24
+
11
25
  ## [0.4.17] - 2026-07-09
12
26
 
13
27
  ### Added
package/dist/index.cjs CHANGED
@@ -15115,7 +15115,11 @@ function ProductSpecifications(rawProps) {
15115
15115
  if (!props.productId || !props.graphqlClient) return;
15116
15116
  fetchSpecs(props.productId);
15117
15117
  }, [props.productId]);
15118
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: !loading && (hasPublicAttributes() || props.packageDescription) ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
15118
+ const layoutMode = props.layout === "list" ? "list" : "table";
15119
+ const before = props.beforeSpecs?.({ layout: layoutMode });
15120
+ const after = props.afterSpecs?.({ layout: layoutMode });
15121
+ const hasSlotContent = before != null || after != null;
15122
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: !loading && (hasPublicAttributes() || props.packageDescription || hasSlotContent) ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(
15119
15123
  "div",
15120
15124
  {
15121
15125
  className: `propeller-product-specifications ${props.className || ""}`,
@@ -15124,26 +15128,38 @@ function ProductSpecifications(rawProps) {
15124
15128
  children: [
15125
15129
  props.packageDescription ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "propeller-product-specifications__package-description mb-4 text-sm text-muted-foreground", children: props.packageDescription }) : null,
15126
15130
  !props.grouping ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15127
- props.layout !== "list" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border", children: getAttributes()?.map((attr, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "propeller-product-specifications__row odd:bg-card even:bg-muted/20", children: [
15128
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2 font-medium text-foreground w-1/2", children: getAttributeLabel(attr) }),
15129
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2 text-muted-foreground", children: getAttributeValue(attr) })
15130
- ] }, i)) }) }) }) : null,
15131
- props.layout === "list" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: getAttributes()?.map((attr, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
15132
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: getAttributeLabel(attr) }),
15133
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-foreground", children: getAttributeValue(attr) })
15134
- ] }, i)) }) : null
15131
+ props.layout !== "list" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsxRuntime.jsxs("tbody", { className: "divide-y divide-border", children: [
15132
+ before,
15133
+ getAttributes()?.map((attr, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "propeller-product-specifications__row odd:bg-card even:bg-muted/20", children: [
15134
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2 font-medium text-foreground w-1/2", children: getAttributeLabel(attr) }),
15135
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2 text-muted-foreground", children: getAttributeValue(attr) })
15136
+ ] }, i)),
15137
+ after
15138
+ ] }) }) }) : null,
15139
+ props.layout === "list" ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
15140
+ before,
15141
+ getAttributes()?.map((attr, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
15142
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: getAttributeLabel(attr) }),
15143
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-foreground", children: getAttributeValue(attr) })
15144
+ ] }, i)),
15145
+ after
15146
+ ] }) : null
15135
15147
  ] }) : null,
15136
- !!props.grouping ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: getGroups()?.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
15137
- !!group ? /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2", children: group }) : null,
15138
- props.layout !== "list" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border", children: getAttributesByGroup(group)?.map((attr, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "propeller-product-specifications__row odd:bg-card even:bg-muted/20", children: [
15139
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2 font-medium text-foreground w-1/2", children: getAttributeLabel(attr) }),
15140
- /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2 text-muted-foreground", children: getAttributeValue(attr) })
15141
- ] }, i)) }) }) }) : null,
15142
- props.layout === "list" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: getAttributesByGroup(group)?.map((attr, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
15143
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: getAttributeLabel(attr) }),
15144
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-foreground", children: getAttributeValue(attr) })
15145
- ] }, i)) }) : null
15146
- ] }, group)) }) : null
15148
+ !!props.grouping ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
15149
+ before ? layoutMode === "table" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6 overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border", children: before }) }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6 space-y-3", children: before }) : null,
15150
+ getGroups()?.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
15151
+ !!group ? /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "text-sm font-semibold text-muted-foreground uppercase tracking-wide mb-2", children: group }) : null,
15152
+ props.layout !== "list" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border", children: getAttributesByGroup(group)?.map((attr, i) => /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "propeller-product-specifications__row odd:bg-card even:bg-muted/20", children: [
15153
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2 font-medium text-foreground w-1/2", children: getAttributeLabel(attr) }),
15154
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-4 py-2 text-muted-foreground", children: getAttributeValue(attr) })
15155
+ ] }, i)) }) }) }) : null,
15156
+ props.layout === "list" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: getAttributesByGroup(group)?.map((attr, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-0.5", children: [
15157
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wide", children: getAttributeLabel(attr) }),
15158
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-foreground", children: getAttributeValue(attr) })
15159
+ ] }, i)) }) : null
15160
+ ] }, group)),
15161
+ after ? layoutMode === "table" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6 overflow-hidden rounded-lg border border-border", children: /* @__PURE__ */ jsxRuntime.jsx("table", { className: "w-full text-sm", children: /* @__PURE__ */ jsxRuntime.jsx("tbody", { className: "divide-y divide-border", children: after }) }) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "space-y-3", children: after }) : null
15162
+ ] }) : null
15147
15163
  ]
15148
15164
  }
15149
15165
  ) }) : null });
@@ -15352,7 +15368,9 @@ function ProductTabs(rawProps) {
15352
15368
  language: props.language,
15353
15369
  layout: props.specificationsLayout,
15354
15370
  grouping: props.specificationsGrouping,
15355
- packageDescription: props.specificationsPackageDescription
15371
+ packageDescription: props.specificationsPackageDescription,
15372
+ beforeSpecs: props.specificationsBeforeSpecs,
15373
+ afterSpecs: props.specificationsAfterSpecs
15356
15374
  }
15357
15375
  ) }) : null,
15358
15376
  isActive("downloads") && isTabVisible("downloads") ? /* @__PURE__ */ jsxRuntime.jsx(