@reblu/site-blocks 0.29.0 → 0.30.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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @reblu/site-blocks
2
2
 
3
+ ## 0.30.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 3b096d4: `CartLineList` gains an optional `lineIncludes` render prop (REB-1208): it adds a collapsed «Qué incluye» disclosure under a line (`labels.includesSummary`). New drop-in `CartLineIncludes` (term/description list plus optional `note`) and `bundleComponentsToIncludes`, which maps `ShopProductDetail.bundleComponents` to its entries. Omitting the prop renders the cart exactly as before.
8
+
3
9
  ## 0.29.0
4
10
 
5
11
  ### Minor Changes
package/README.md CHANGED
@@ -327,7 +327,8 @@ for the wiring steps and a full example app).
327
327
  | `AddToCartButton` | `./client` | `onAddToCart?`, `disabled?`, `outOfStock?`, `pending?`, `error?`, `item?`, `successDurationMs?`, `onAdded?`, `onError?` | No — carries a built-in confirmed/error timer (`useState`/`useEffect`), see below |
328
328
  | `CartIcon` | `./client` | `itemCount`, `href`, `hydrated?`, `bumpOnAdd?` | No — the bump animation needs state, see below |
329
329
  | `AddedToCartToast` | `.` | `productName`, `cartHref`, `status?`, `quantity?`, `imageUrl?` | Yes |
330
- | `CartLineList` | `.` | `items`, `onQuantityChange?`, `onRemove?`, `liveMessage?`, `notice?`, `lineMessage?` | Yes |
330
+ | `CartLineList` | `.` | `items`, `onQuantityChange?`, `onRemove?`, `liveMessage?`, `notice?`, `lineMessage?`, `lineIncludes?` | Yes |
331
+ | `CartLineIncludes` | `.` | `entries`, `note?` | Yes |
331
332
  | `CartAdjustmentsNotice` | `.` | `removed?`, `quantityChanges?`, `priceChanges?`, `labels?` | Yes |
332
333
  | `CartSummary` | `.` | `subtotal`, `discount?`, `autoDiscount?`, `shipping?`, `shippingEnabled?`, `total`, `notice?` | Yes |
333
334
  | `CheckoutLoginPrompt` | `.` | `open`, `email`, `onEmailChange`, `onClose`, `onSubmitEmail`, `onContinueAsGuest` | Yes (renders `null` when `open` is false) |
@@ -530,6 +531,36 @@ function). `currencyCode`/`locale` format the prices.
530
531
  `CartLineList`'s `lineMessage={(item) => …}` renders a message under a line,
531
532
  e.g. `validation.getLineError(item.productId, item.variantId)?.message`.
532
533
 
534
+ ### «Qué incluye» per line — `lineIncludes` + `CartLineIncludes` (REB-1208)
535
+
536
+ `CartLineList`'s `lineIncludes={(item) => …}` adds a collapsed
537
+ `<details>` under a line whose summary reads «Qué incluye»
538
+ (`labels.includesSummary`). Return `null`/`undefined` for lines with nothing
539
+ to show; omit the prop and the cart renders exactly as before.
540
+
541
+ `CartLineIncludes` is the drop-in body: a term/description list plus an
542
+ optional `note`. Build its entries from the product's own data — nothing is
543
+ fixed per product type. For a bundle, `bundleComponentsToIncludes` maps
544
+ `ShopProductDetail.bundleComponents` to name / `x{quantity}` rows:
545
+
546
+ ```tsx
547
+ import { CartLineIncludes, CartLineList, bundleComponentsToIncludes } from '@reblu/site-blocks'
548
+
549
+ // `detailsById`: the SITE's ShopProductDetail per productId (already fetched for the ficha).
550
+ <CartLineList
551
+ items={items}
552
+ lineIncludes={(item) => {
553
+ const product = detailsById[item.productId]
554
+ if (!product) return null
555
+ const entries = [
556
+ ...bundleComponentsToIncludes(product.bundleComponents),
557
+ // …plus any other `{ label, value }` row built from the product's own data.
558
+ ]
559
+ return entries.length > 0 ? <CartLineIncludes entries={entries} /> : null
560
+ }}
561
+ />
562
+ ```
563
+
533
564
  ### `OrderConfirmation` states (REB-837)
534
565
 
535
566
  `status` accepts `@reblu/site-next/shop`'s `useShopOrderStatus` hook result
package/dist/index.cjs CHANGED
@@ -24,6 +24,7 @@ __export(src_exports, {
24
24
  AddedToCartToast: () => AddedToCartToast,
25
25
  ArbitrationBadge: () => ArbitrationBadge,
26
26
  CartAdjustmentsNotice: () => CartAdjustmentsNotice,
27
+ CartLineIncludes: () => CartLineIncludes,
27
28
  CartLineList: () => CartLineList,
28
29
  CartSummary: () => CartSummary,
29
30
  CheckoutDeliveryChoice: () => CheckoutDeliveryChoice,
@@ -73,6 +74,7 @@ __export(src_exports, {
73
74
  TrustBadges: () => TrustBadges,
74
75
  buildFaqPageJsonLd: () => buildFaqPageJsonLd,
75
76
  buildShareUrls: () => buildShareUrls,
77
+ bundleComponentsToIncludes: () => bundleComponentsToIncludes,
76
78
  collectFaqItems: () => collectFaqItems,
77
79
  defaultCheckoutFulfillment: () => defaultCheckoutFulfillment,
78
80
  formatPrice: () => formatPrice,
@@ -15167,15 +15169,43 @@ function CourseCatalogFilters({
15167
15169
 
15168
15170
  // src/components/cart-line-list.tsx
15169
15171
  var import_utils17 = require("@reblu/site-ui/utils");
15170
- var import_jsx_runtime21 = require("react/jsx-runtime");
15172
+ var import_jsx_runtime21 = (
15173
+ // eslint-disable-next-line react/no-array-index-key -- entries are positional, SITE-built rows
15174
+ require("react/jsx-runtime")
15175
+ );
15171
15176
  var DEFAULT_LABELS2 = {
15172
15177
  quantityLabel: "Cantidad",
15173
15178
  decrease: "Reducir cantidad",
15174
15179
  increase: "Aumentar cantidad",
15175
15180
  remove: "Eliminar",
15176
15181
  unitPriceSuffix: "/ ud.",
15177
- cancelledNotice: "Pago cancelado: tu carrito sigue aqu\xED"
15182
+ cancelledNotice: "Pago cancelado: tu carrito sigue aqu\xED",
15183
+ includesSummary: "Qu\xE9 incluye"
15178
15184
  };
15185
+ function CartLineIncludes({ entries, note, className }) {
15186
+ const hasNote = note != null && note !== false && note !== "";
15187
+ if (entries.length === 0 && !hasNote) return null;
15188
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
15189
+ "div",
15190
+ {
15191
+ className: (0, import_utils17.cn)("mt-2 space-y-2 rounded-lg bg-muted px-4 py-3 text-sm", className),
15192
+ "data-slot": "cart-line-includes",
15193
+ children: [
15194
+ entries.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dl", { className: "grid grid-cols-[max-content_1fr] gap-x-4 gap-y-1.5", children: entries.map((entry, idx) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "contents", children: [
15195
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dt", { className: "font-semibold text-muted-foreground", children: entry.label }),
15196
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("dd", { className: "m-0", children: entry.value })
15197
+ ] }, idx)) }),
15198
+ hasNote && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-muted-foreground", children: note })
15199
+ ]
15200
+ }
15201
+ );
15202
+ }
15203
+ function bundleComponentsToIncludes(components) {
15204
+ return components.map(({ quantity, component }) => ({
15205
+ label: component.name,
15206
+ value: `x${quantity}`
15207
+ }));
15208
+ }
15179
15209
  function lineKey(productId, variantId) {
15180
15210
  return `${productId}-${variantId ?? "no-variant"}`;
15181
15211
  }
@@ -15186,6 +15216,7 @@ function CartLineList({
15186
15216
  liveMessage,
15187
15217
  notice,
15188
15218
  lineMessage,
15219
+ lineIncludes,
15189
15220
  labels,
15190
15221
  currencyCode,
15191
15222
  locale,
@@ -15209,6 +15240,7 @@ function CartLineList({
15209
15240
  const atMax = item.quantity >= maxQty;
15210
15241
  const atMin = item.quantity <= 1;
15211
15242
  const message = lineMessage?.(item);
15243
+ const includes = lineIncludes?.(item);
15212
15244
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
15213
15245
  "li",
15214
15246
  {
@@ -15273,7 +15305,11 @@ function CartLineList({
15273
15305
  "data-slot": "cart-line-list-line-message",
15274
15306
  children: message
15275
15307
  }
15276
- )
15308
+ ),
15309
+ includes != null && includes !== false && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("details", { className: "mt-2", "data-slot": "cart-line-list-includes", children: [
15310
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("summary", { className: "cursor-pointer text-sm font-semibold text-primary", children: t.includesSummary }),
15311
+ includes
15312
+ ] })
15277
15313
  ] }),
15278
15314
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-shrink-0 text-right", children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("p", { className: "text-base font-bold", children: formatPrice(item.unitPrice * item.quantity, currencyCode, locale) }) })
15279
15315
  ]
@@ -16633,6 +16669,7 @@ var import_site_contracts = require("@reblu/site-contracts");
16633
16669
  AddedToCartToast,
16634
16670
  ArbitrationBadge,
16635
16671
  CartAdjustmentsNotice,
16672
+ CartLineIncludes,
16636
16673
  CartLineList,
16637
16674
  CartSummary,
16638
16675
  CheckoutDeliveryChoice,
@@ -16682,6 +16719,7 @@ var import_site_contracts = require("@reblu/site-contracts");
16682
16719
  TrustBadges,
16683
16720
  buildFaqPageJsonLd,
16684
16721
  buildShareUrls,
16722
+ bundleComponentsToIncludes,
16685
16723
  collectFaqItems,
16686
16724
  defaultCheckoutFulfillment,
16687
16725
  formatPrice,