@reblu/site-blocks 0.6.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 +82 -0
- package/README.md +196 -42
- package/dist/client.cjs +198 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +114 -1
- package/dist/client.d.ts +114 -1
- package/dist/client.js +196 -0
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +316 -238
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +140 -55
- package/dist/index.d.ts +140 -55
- package/dist/index.js +290 -216
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { ShopErrorCode, PageDetail, PageListItem, ShopProductListItem, ShopFacets, ShopOrder } from '@reblu/site-contracts';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { PageDetail, PageListItem, ShopProductListItem, ShopFacets, ShopOrder } from '@reblu/site-contracts';
|
|
3
3
|
import { ReactNode, FormEvent } from 'react';
|
|
4
4
|
|
|
5
5
|
declare function readingTime(content: string | null | undefined): number | null;
|
|
@@ -29,6 +29,30 @@ interface ShareUrls {
|
|
|
29
29
|
}
|
|
30
30
|
declare function buildShareUrls(url: string, title: string): ShareUrls;
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Default Spanish copy for every stable `ShopErrorCode` (REB-836) the shop
|
|
34
|
+
* write endpoints (`checkout`/`validateCart`/`applyDiscount`) may return in
|
|
35
|
+
* the error body's optional `code` field — see `ApiError.body.code` in
|
|
36
|
+
* `@reblu/site-client`. A SITE overrides any subset through
|
|
37
|
+
* {@link getShopErrorMessage}'s `overrides` parameter, or ignores `code`
|
|
38
|
+
* entirely and reads `ApiError.message` as before (REB-836 is additive).
|
|
39
|
+
*/
|
|
40
|
+
declare const DEFAULT_SHOP_ERROR_MESSAGES: Record<ShopErrorCode, string>;
|
|
41
|
+
/** Fallback copy used when `code` is missing or not recognised. */
|
|
42
|
+
declare const DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE = "No se ha podido completar la operaci\u00F3n. Int\u00E9ntalo de nuevo.";
|
|
43
|
+
/**
|
|
44
|
+
* Resolves the user-facing message for a checkout/validate-cart/apply-discount
|
|
45
|
+
* error `code` (REB-836) — e.g. `ApiError.body?.code` from `@reblu/site-client`.
|
|
46
|
+
*
|
|
47
|
+
* @param code - The stable error code, or `null`/`undefined` when the response
|
|
48
|
+
* carried none (an older base-api, or a non-shop error).
|
|
49
|
+
* @param overrides - Replaces any subset of {@link DEFAULT_SHOP_ERROR_MESSAGES}
|
|
50
|
+
* without having to restate every other code — e.g. for a non-Spanish SITE.
|
|
51
|
+
* @param fallback - Used when `code` is missing or unrecognised.
|
|
52
|
+
* Defaults to {@link DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE}.
|
|
53
|
+
*/
|
|
54
|
+
declare function getShopErrorMessage(code: string | null | undefined, overrides?: Partial<Record<ShopErrorCode, string>>, fallback?: string): string;
|
|
55
|
+
|
|
32
56
|
/**
|
|
33
57
|
* Canonical Blog markdown → **safe HTML** pipeline for the Reblu SITE SDK.
|
|
34
58
|
*
|
|
@@ -384,47 +408,6 @@ interface ShopFiltersProps {
|
|
|
384
408
|
declare function shouldRenderShopFilters(facets: ShopFacets, active?: ShopFiltersActive): boolean;
|
|
385
409
|
declare function ShopFilters({ facets, hrefs, active, onChange, priceBands, labels, currencyCode, locale, className, }: ShopFiltersProps): react_jsx_runtime.JSX.Element | null;
|
|
386
410
|
|
|
387
|
-
/**
|
|
388
|
-
* `AddToCartButton` — presentational add-to-cart CTA (REB-829). RSC-safe by
|
|
389
|
-
* construction (same contract as `ShopFilters`'s `OptionLink`): passing
|
|
390
|
-
* `onAddToCart` only makes sense from a Client Component, but the component
|
|
391
|
-
* itself carries no `'use client'` directive, so a Server Component may
|
|
392
|
-
* still render it WITHOUT the prop (e.g. a disabled preview state).
|
|
393
|
-
*/
|
|
394
|
-
interface AddToCartButtonLabels {
|
|
395
|
-
add: string;
|
|
396
|
-
adding: string;
|
|
397
|
-
outOfStock: string;
|
|
398
|
-
}
|
|
399
|
-
interface AddToCartButtonProps {
|
|
400
|
-
onAddToCart?: () => void;
|
|
401
|
-
disabled?: boolean;
|
|
402
|
-
outOfStock?: boolean;
|
|
403
|
-
/** True while the add-to-cart call (or a navigation it triggers) is in flight. */
|
|
404
|
-
pending?: boolean;
|
|
405
|
-
labels?: Partial<AddToCartButtonLabels>;
|
|
406
|
-
className?: string;
|
|
407
|
-
}
|
|
408
|
-
declare function AddToCartButton({ onAddToCart, disabled, outOfStock, pending, labels, className, }: AddToCartButtonProps): react_jsx_runtime.JSX.Element;
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* `CartIcon` — presentational cart badge/link (REB-829). RSC-safe (plain
|
|
412
|
-
* `<a href>`, no hooks) — a Server Component can render it directly with a
|
|
413
|
-
* value already computed server-side; a Client Component drives `itemCount`
|
|
414
|
-
* from `@reblu/site-next/cart`'s `useCart().itemCount`.
|
|
415
|
-
*/
|
|
416
|
-
interface CartIconLabels {
|
|
417
|
-
cart: string;
|
|
418
|
-
itemsSuffix: (count: number) => string;
|
|
419
|
-
}
|
|
420
|
-
interface CartIconProps {
|
|
421
|
-
itemCount: number;
|
|
422
|
-
href: string;
|
|
423
|
-
labels?: Partial<CartIconLabels>;
|
|
424
|
-
className?: string;
|
|
425
|
-
}
|
|
426
|
-
declare function CartIcon({ itemCount, href, labels, className }: CartIconProps): react_jsx_runtime.JSX.Element;
|
|
427
|
-
|
|
428
411
|
/**
|
|
429
412
|
* `CartLineList` — presentational cart lines (REB-829), container/
|
|
430
413
|
* presentational split: it takes `items` + optional `onQuantityChange`/
|
|
@@ -454,6 +437,8 @@ interface CartLineListLabels {
|
|
|
454
437
|
increase: string;
|
|
455
438
|
remove: string;
|
|
456
439
|
unitPriceSuffix: string;
|
|
440
|
+
/** REB-837 — default copy for `notice={true}`. */
|
|
441
|
+
cancelledNotice: string;
|
|
457
442
|
}
|
|
458
443
|
interface CartLineListProps {
|
|
459
444
|
items: CartLineItemView[];
|
|
@@ -466,12 +451,18 @@ interface CartLineListProps {
|
|
|
466
451
|
* only renders the live region.
|
|
467
452
|
*/
|
|
468
453
|
liveMessage?: string;
|
|
454
|
+
/**
|
|
455
|
+
* REB-837 — a notice shown above the lines. `true` renders the default
|
|
456
|
+
* "pago cancelado" copy (`labels.cancelledNotice`); pass any other
|
|
457
|
+
* `ReactNode` for custom content, or omit/`false` to render nothing.
|
|
458
|
+
*/
|
|
459
|
+
notice?: boolean | React.ReactNode;
|
|
469
460
|
labels?: Partial<CartLineListLabels>;
|
|
470
461
|
currencyCode?: string;
|
|
471
462
|
locale?: string;
|
|
472
463
|
className?: string;
|
|
473
464
|
}
|
|
474
|
-
declare function CartLineList({ items, onQuantityChange, onRemove, liveMessage, labels, currencyCode, locale, className, }: CartLineListProps): react_jsx_runtime.JSX.Element;
|
|
465
|
+
declare function CartLineList({ items, onQuantityChange, onRemove, liveMessage, notice, labels, currencyCode, locale, className, }: CartLineListProps): react_jsx_runtime.JSX.Element;
|
|
475
466
|
|
|
476
467
|
/**
|
|
477
468
|
* `CartSummary` — presentational price breakdown (REB-829): subtotal,
|
|
@@ -492,6 +483,8 @@ interface CartSummaryLabels {
|
|
|
492
483
|
*/
|
|
493
484
|
shippingCalculated: string;
|
|
494
485
|
total: string;
|
|
486
|
+
/** REB-837 — default copy for `notice={true}`. */
|
|
487
|
+
cancelledNotice: string;
|
|
495
488
|
}
|
|
496
489
|
interface CartSummaryProps {
|
|
497
490
|
/** Integer cents. */
|
|
@@ -506,12 +499,70 @@ interface CartSummaryProps {
|
|
|
506
499
|
shippingEnabled?: boolean;
|
|
507
500
|
/** Integer cents — the final charged amount. */
|
|
508
501
|
total: number;
|
|
502
|
+
/**
|
|
503
|
+
* REB-837 — a notice shown above the breakdown. `true` renders the
|
|
504
|
+
* default "pago cancelado" copy (`labels.cancelledNotice`) — the standard
|
|
505
|
+
* message for a visitor returning from a cancelled Stripe Checkout
|
|
506
|
+
* session (`useCheckoutReturn().status === 'cancelled'`). Pass any other
|
|
507
|
+
* `ReactNode` for custom content, or omit/`false` to render nothing.
|
|
508
|
+
*/
|
|
509
|
+
notice?: boolean | React.ReactNode;
|
|
509
510
|
labels?: Partial<CartSummaryLabels>;
|
|
510
511
|
currencyCode?: string;
|
|
511
512
|
locale?: string;
|
|
512
513
|
className?: string;
|
|
513
514
|
}
|
|
514
|
-
declare function CartSummary({ subtotal, discount, discountCode, shipping, shippingEnabled, total, labels, currencyCode, locale, className, }: CartSummaryProps): react_jsx_runtime.JSX.Element;
|
|
515
|
+
declare function CartSummary({ subtotal, discount, discountCode, shipping, shippingEnabled, total, notice, labels, currencyCode, locale, className, }: CartSummaryProps): react_jsx_runtime.JSX.Element;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* `AddedToCartToast` — add-to-cart feedback toast CONTENT (REB-837). Pure
|
|
519
|
+
* presentational, no hooks.
|
|
520
|
+
*
|
|
521
|
+
* Deliberately does NOT import `@reblu/site-ui`'s `Toast` (the root entry):
|
|
522
|
+
* that barrel also re-exports `Button`, which this package's own
|
|
523
|
+
* `test/rsc-safety.test.ts` bans from the RSC-safe root entry (a Radix
|
|
524
|
+
* `Slot` copy whose server-evaluability depends on a CONSUMER's resolution —
|
|
525
|
+
* see that test's docblock). `Toast`'s small shell is reproduced inline here
|
|
526
|
+
* with `cn` from the certified-React-free `@reblu/site-ui/utils`, same
|
|
527
|
+
* pattern as every other organism in this file's sibling components. A SITE
|
|
528
|
+
* that wants `@reblu/site-ui`'s standalone `Toast` directly still can — the
|
|
529
|
+
* two are independent, not layered.
|
|
530
|
+
*
|
|
531
|
+
* This is the CONTENT to pass into whatever toaster the consuming SITE
|
|
532
|
+
* already mounts (sonner's `toast.custom((id) => <AddedToCartToast ... />,
|
|
533
|
+
* { id: `cart-add-${productId}` })` — a stable per-product id lets a repeat
|
|
534
|
+
* add UPDATE the same toast instead of stacking a new one). It never renders
|
|
535
|
+
* its own `aria-live` region: the host toaster's live region owns
|
|
536
|
+
* announcement, so adding a second one here would double-announce.
|
|
537
|
+
*
|
|
538
|
+
* `imageUrl` only renders a thumbnail when it's a real, non-blank string —
|
|
539
|
+
* an empty/whitespace value (a product with no image) renders no `<img>`
|
|
540
|
+
* rather than a broken one.
|
|
541
|
+
*
|
|
542
|
+
* `cartHref` is a plain `href` the consumer builds, rendered as a real
|
|
543
|
+
* `<a>` — never a `useRouter().push(...)` call, which breaks outside the
|
|
544
|
+
* Next.js App Router and in non-router test renders.
|
|
545
|
+
*/
|
|
546
|
+
type AddedToCartToastStatus = 'success' | 'error' | 'outOfStock';
|
|
547
|
+
interface AddedToCartToastLabels {
|
|
548
|
+
success: string;
|
|
549
|
+
error: string;
|
|
550
|
+
outOfStock: string;
|
|
551
|
+
viewCart: string;
|
|
552
|
+
}
|
|
553
|
+
interface AddedToCartToastProps {
|
|
554
|
+
status?: AddedToCartToastStatus;
|
|
555
|
+
productName: string;
|
|
556
|
+
/** The resulting line quantity, e.g. from `addItem`'s outcome. Only shown when > 1. */
|
|
557
|
+
quantity?: number;
|
|
558
|
+
/** Rendered as a thumbnail ONLY when non-empty after trimming. */
|
|
559
|
+
imageUrl?: string;
|
|
560
|
+
/** "Ver carrito" link target — a real href, not a router navigation. */
|
|
561
|
+
cartHref: string;
|
|
562
|
+
labels?: Partial<AddedToCartToastLabels>;
|
|
563
|
+
className?: string;
|
|
564
|
+
}
|
|
565
|
+
declare function AddedToCartToast({ status, productName, quantity, imageUrl, cartHref, labels, className, }: AddedToCartToastProps): react_jsx_runtime.JSX.Element;
|
|
515
566
|
|
|
516
567
|
/**
|
|
517
568
|
* `CheckoutLoginPrompt` — the "login prompt hook" the checkout flow needs
|
|
@@ -594,6 +645,14 @@ interface CheckoutFormProps {
|
|
|
594
645
|
contact: CheckoutContactValues;
|
|
595
646
|
onContactChange: (values: CheckoutContactValues) => void;
|
|
596
647
|
contactErrors?: CheckoutContactErrors;
|
|
648
|
+
/** Country asserted by the SITE for national phone input; omit rather than guessing. */
|
|
649
|
+
phoneRegion?: string;
|
|
650
|
+
/** Optional raw checkout API error body; only INVALID_INPUT/customerPhone marks the phone field. */
|
|
651
|
+
checkoutError?: {
|
|
652
|
+
code?: unknown;
|
|
653
|
+
error?: unknown;
|
|
654
|
+
details?: unknown;
|
|
655
|
+
} | null;
|
|
597
656
|
discountCode: string;
|
|
598
657
|
onDiscountCodeChange: (value: string) => void;
|
|
599
658
|
onApplyDiscount: () => void;
|
|
@@ -619,18 +678,23 @@ interface CheckoutFormProps {
|
|
|
619
678
|
locale?: string;
|
|
620
679
|
className?: string;
|
|
621
680
|
}
|
|
622
|
-
declare function CheckoutForm({ contact, onContactChange, contactErrors, discountCode, onDiscountCodeChange, onApplyDiscount, onRemoveDiscount, appliedDiscount, discountApplying, discountError, loginPrompt, children, submitting, submitDisabled, onSubmit, labels, currencyCode, locale, className, }: CheckoutFormProps): react_jsx_runtime.JSX.Element;
|
|
681
|
+
declare function CheckoutForm({ contact, onContactChange, contactErrors, phoneRegion, checkoutError, discountCode, onDiscountCodeChange, onApplyDiscount, onRemoveDiscount, appliedDiscount, discountApplying, discountError, loginPrompt, children, submitting, submitDisabled, onSubmit, labels, currencyCode, locale, className, }: CheckoutFormProps): react_jsx_runtime.JSX.Element;
|
|
623
682
|
|
|
624
683
|
/**
|
|
625
|
-
* `OrderConfirmation` — presentational order-confirmation view (REB-829
|
|
626
|
-
* Pure data + status in, RSC-safe (no hooks). The
|
|
627
|
-
* actual lookup/polling
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
684
|
+
* `OrderConfirmation` — presentational order-confirmation view (REB-829,
|
|
685
|
+
* extended REB-837). Pure data + status in, RSC-safe (no hooks). The
|
|
686
|
+
* consuming SITE owns the actual lookup/polling — today via
|
|
687
|
+
* `@reblu/site-next/shop`'s `useShopOrderStatus(sessionId)` hook — and
|
|
688
|
+
* passes the resulting `status`/`order` straight through.
|
|
689
|
+
*
|
|
690
|
+
* Backward compatible: the original three states (`polling`, `found`,
|
|
691
|
+
* `timeout`) keep their EXACT existing copy and behavior. REB-837 adds
|
|
692
|
+
* `useShopOrderStatus`'s native vocabulary (`loading`/`paid` are drop-in
|
|
693
|
+
* aliases for `polling`/`found`) plus five new terminal states with their
|
|
694
|
+
* own default Spanish copy, all overridable via `labels`.
|
|
631
695
|
*/
|
|
632
696
|
type OrderConfirmationOrder = ShopOrder;
|
|
633
|
-
type OrderConfirmationStatus = 'polling' | 'found' | 'timeout';
|
|
697
|
+
type OrderConfirmationStatus = 'polling' | 'found' | 'timeout' | 'loading' | 'paid' | 'pending_timeout' | 'failed' | 'refunded' | 'partially_refunded' | 'not_found' | 'error';
|
|
634
698
|
interface OrderConfirmationLabels {
|
|
635
699
|
pollingTitle: string;
|
|
636
700
|
pollingDescription: string;
|
|
@@ -642,17 +706,38 @@ interface OrderConfirmationLabels {
|
|
|
642
706
|
totalLabel: string;
|
|
643
707
|
confirmationEmailPrefix: string;
|
|
644
708
|
sessionReferenceLabel: string;
|
|
709
|
+
/** REB-837 */
|
|
710
|
+
failedTitle: string;
|
|
711
|
+
failedDescription: string;
|
|
712
|
+
backToCartLabel: string;
|
|
713
|
+
refundedTitle: string;
|
|
714
|
+
refundedDescription: string;
|
|
715
|
+
partiallyRefundedTitle: string;
|
|
716
|
+
partiallyRefundedDescription: string;
|
|
717
|
+
pendingTimeoutTitle: string;
|
|
718
|
+
pendingTimeoutDescription: string;
|
|
719
|
+
recheckLabel: string;
|
|
720
|
+
notFoundTitle: string;
|
|
721
|
+
notFoundDescription: string;
|
|
722
|
+
errorTitle: string;
|
|
723
|
+
errorDescription: string;
|
|
724
|
+
/** REB-837 review fix — label for the neutral order-number-only reference shown on refunded/pending_timeout. */
|
|
725
|
+
orderReferenceLabel: string;
|
|
645
726
|
}
|
|
646
727
|
interface OrderConfirmationProps {
|
|
647
728
|
status: OrderConfirmationStatus;
|
|
648
729
|
order: OrderConfirmationOrder | null;
|
|
649
|
-
/** Shown as a fallback reference when
|
|
730
|
+
/** Shown as a fallback reference when there is no order to display. */
|
|
650
731
|
sessionId?: string;
|
|
732
|
+
/** "Volver al carrito" target, shown on `status === 'failed'`. Omit to render no link. */
|
|
733
|
+
cartHref?: string;
|
|
734
|
+
/** Called by the "Volver a comprobar" button on `pending_timeout`/`error`. Omit to render no button. */
|
|
735
|
+
onRecheck?: () => void;
|
|
651
736
|
labels?: Partial<OrderConfirmationLabels>;
|
|
652
737
|
currencyCode?: string;
|
|
653
738
|
locale?: string;
|
|
654
739
|
className?: string;
|
|
655
740
|
}
|
|
656
|
-
declare function OrderConfirmation({ status, order, sessionId, labels, currencyCode, locale, className, }: OrderConfirmationProps): react_jsx_runtime.JSX.Element;
|
|
741
|
+
declare function OrderConfirmation({ status, order, sessionId, cartHref, onRecheck, labels, currencyCode, locale, className, }: OrderConfirmationProps): react_jsx_runtime.JSX.Element;
|
|
657
742
|
|
|
658
|
-
export { ALLOWED_YOUTUBE_HOSTS,
|
|
743
|
+
export { ALLOWED_YOUTUBE_HOSTS, AddedToCartToast, type AddedToCartToastLabels, type AddedToCartToastProps, type AddedToCartToastStatus, type CartLineItemView, CartLineList, type CartLineListLabels, type CartLineListProps, CartSummary, type CartSummaryLabels, type CartSummaryProps, type CheckoutAppliedDiscount, type CheckoutContactErrors, type CheckoutContactValues, CheckoutForm, type CheckoutFormLabels, type CheckoutFormProps, CheckoutLoginPrompt, type CheckoutLoginPromptLabels, type CheckoutLoginPromptProps, DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE, DEFAULT_SHOP_ERROR_MESSAGES, DEFAULT_SHOP_PRICE_BANDS, MarkdownRenderer, type MarkdownRendererProps, OrderConfirmation, type OrderConfirmationLabels, type OrderConfirmationOrder, type OrderConfirmationProps, type OrderConfirmationStatus, ProductCard, type ProductCardProps, ProfileCard, type ProfileCardProps, SafeHtml, type SafeHtmlProps, type ShareUrls, type ShopFilterPriceBand, ShopFilters, type ShopFiltersActive, type ShopFiltersHrefs, type ShopFiltersLabels, type ShopFiltersProps, Specialty, type SpecialtyProps, Treatment, type TreatmentProps, buildShareUrls, formatPrice, getShopErrorMessage, isAllowedYouTubeHost, markdownToSafeHtml, readingTime, sanitizeHtml, shouldRenderShopFilters };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { ShopErrorCode, PageDetail, PageListItem, ShopProductListItem, ShopFacets, ShopOrder } from '@reblu/site-contracts';
|
|
1
2
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { PageDetail, PageListItem, ShopProductListItem, ShopFacets, ShopOrder } from '@reblu/site-contracts';
|
|
3
3
|
import { ReactNode, FormEvent } from 'react';
|
|
4
4
|
|
|
5
5
|
declare function readingTime(content: string | null | undefined): number | null;
|
|
@@ -29,6 +29,30 @@ interface ShareUrls {
|
|
|
29
29
|
}
|
|
30
30
|
declare function buildShareUrls(url: string, title: string): ShareUrls;
|
|
31
31
|
|
|
32
|
+
/**
|
|
33
|
+
* Default Spanish copy for every stable `ShopErrorCode` (REB-836) the shop
|
|
34
|
+
* write endpoints (`checkout`/`validateCart`/`applyDiscount`) may return in
|
|
35
|
+
* the error body's optional `code` field — see `ApiError.body.code` in
|
|
36
|
+
* `@reblu/site-client`. A SITE overrides any subset through
|
|
37
|
+
* {@link getShopErrorMessage}'s `overrides` parameter, or ignores `code`
|
|
38
|
+
* entirely and reads `ApiError.message` as before (REB-836 is additive).
|
|
39
|
+
*/
|
|
40
|
+
declare const DEFAULT_SHOP_ERROR_MESSAGES: Record<ShopErrorCode, string>;
|
|
41
|
+
/** Fallback copy used when `code` is missing or not recognised. */
|
|
42
|
+
declare const DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE = "No se ha podido completar la operaci\u00F3n. Int\u00E9ntalo de nuevo.";
|
|
43
|
+
/**
|
|
44
|
+
* Resolves the user-facing message for a checkout/validate-cart/apply-discount
|
|
45
|
+
* error `code` (REB-836) — e.g. `ApiError.body?.code` from `@reblu/site-client`.
|
|
46
|
+
*
|
|
47
|
+
* @param code - The stable error code, or `null`/`undefined` when the response
|
|
48
|
+
* carried none (an older base-api, or a non-shop error).
|
|
49
|
+
* @param overrides - Replaces any subset of {@link DEFAULT_SHOP_ERROR_MESSAGES}
|
|
50
|
+
* without having to restate every other code — e.g. for a non-Spanish SITE.
|
|
51
|
+
* @param fallback - Used when `code` is missing or unrecognised.
|
|
52
|
+
* Defaults to {@link DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE}.
|
|
53
|
+
*/
|
|
54
|
+
declare function getShopErrorMessage(code: string | null | undefined, overrides?: Partial<Record<ShopErrorCode, string>>, fallback?: string): string;
|
|
55
|
+
|
|
32
56
|
/**
|
|
33
57
|
* Canonical Blog markdown → **safe HTML** pipeline for the Reblu SITE SDK.
|
|
34
58
|
*
|
|
@@ -384,47 +408,6 @@ interface ShopFiltersProps {
|
|
|
384
408
|
declare function shouldRenderShopFilters(facets: ShopFacets, active?: ShopFiltersActive): boolean;
|
|
385
409
|
declare function ShopFilters({ facets, hrefs, active, onChange, priceBands, labels, currencyCode, locale, className, }: ShopFiltersProps): react_jsx_runtime.JSX.Element | null;
|
|
386
410
|
|
|
387
|
-
/**
|
|
388
|
-
* `AddToCartButton` — presentational add-to-cart CTA (REB-829). RSC-safe by
|
|
389
|
-
* construction (same contract as `ShopFilters`'s `OptionLink`): passing
|
|
390
|
-
* `onAddToCart` only makes sense from a Client Component, but the component
|
|
391
|
-
* itself carries no `'use client'` directive, so a Server Component may
|
|
392
|
-
* still render it WITHOUT the prop (e.g. a disabled preview state).
|
|
393
|
-
*/
|
|
394
|
-
interface AddToCartButtonLabels {
|
|
395
|
-
add: string;
|
|
396
|
-
adding: string;
|
|
397
|
-
outOfStock: string;
|
|
398
|
-
}
|
|
399
|
-
interface AddToCartButtonProps {
|
|
400
|
-
onAddToCart?: () => void;
|
|
401
|
-
disabled?: boolean;
|
|
402
|
-
outOfStock?: boolean;
|
|
403
|
-
/** True while the add-to-cart call (or a navigation it triggers) is in flight. */
|
|
404
|
-
pending?: boolean;
|
|
405
|
-
labels?: Partial<AddToCartButtonLabels>;
|
|
406
|
-
className?: string;
|
|
407
|
-
}
|
|
408
|
-
declare function AddToCartButton({ onAddToCart, disabled, outOfStock, pending, labels, className, }: AddToCartButtonProps): react_jsx_runtime.JSX.Element;
|
|
409
|
-
|
|
410
|
-
/**
|
|
411
|
-
* `CartIcon` — presentational cart badge/link (REB-829). RSC-safe (plain
|
|
412
|
-
* `<a href>`, no hooks) — a Server Component can render it directly with a
|
|
413
|
-
* value already computed server-side; a Client Component drives `itemCount`
|
|
414
|
-
* from `@reblu/site-next/cart`'s `useCart().itemCount`.
|
|
415
|
-
*/
|
|
416
|
-
interface CartIconLabels {
|
|
417
|
-
cart: string;
|
|
418
|
-
itemsSuffix: (count: number) => string;
|
|
419
|
-
}
|
|
420
|
-
interface CartIconProps {
|
|
421
|
-
itemCount: number;
|
|
422
|
-
href: string;
|
|
423
|
-
labels?: Partial<CartIconLabels>;
|
|
424
|
-
className?: string;
|
|
425
|
-
}
|
|
426
|
-
declare function CartIcon({ itemCount, href, labels, className }: CartIconProps): react_jsx_runtime.JSX.Element;
|
|
427
|
-
|
|
428
411
|
/**
|
|
429
412
|
* `CartLineList` — presentational cart lines (REB-829), container/
|
|
430
413
|
* presentational split: it takes `items` + optional `onQuantityChange`/
|
|
@@ -454,6 +437,8 @@ interface CartLineListLabels {
|
|
|
454
437
|
increase: string;
|
|
455
438
|
remove: string;
|
|
456
439
|
unitPriceSuffix: string;
|
|
440
|
+
/** REB-837 — default copy for `notice={true}`. */
|
|
441
|
+
cancelledNotice: string;
|
|
457
442
|
}
|
|
458
443
|
interface CartLineListProps {
|
|
459
444
|
items: CartLineItemView[];
|
|
@@ -466,12 +451,18 @@ interface CartLineListProps {
|
|
|
466
451
|
* only renders the live region.
|
|
467
452
|
*/
|
|
468
453
|
liveMessage?: string;
|
|
454
|
+
/**
|
|
455
|
+
* REB-837 — a notice shown above the lines. `true` renders the default
|
|
456
|
+
* "pago cancelado" copy (`labels.cancelledNotice`); pass any other
|
|
457
|
+
* `ReactNode` for custom content, or omit/`false` to render nothing.
|
|
458
|
+
*/
|
|
459
|
+
notice?: boolean | React.ReactNode;
|
|
469
460
|
labels?: Partial<CartLineListLabels>;
|
|
470
461
|
currencyCode?: string;
|
|
471
462
|
locale?: string;
|
|
472
463
|
className?: string;
|
|
473
464
|
}
|
|
474
|
-
declare function CartLineList({ items, onQuantityChange, onRemove, liveMessage, labels, currencyCode, locale, className, }: CartLineListProps): react_jsx_runtime.JSX.Element;
|
|
465
|
+
declare function CartLineList({ items, onQuantityChange, onRemove, liveMessage, notice, labels, currencyCode, locale, className, }: CartLineListProps): react_jsx_runtime.JSX.Element;
|
|
475
466
|
|
|
476
467
|
/**
|
|
477
468
|
* `CartSummary` — presentational price breakdown (REB-829): subtotal,
|
|
@@ -492,6 +483,8 @@ interface CartSummaryLabels {
|
|
|
492
483
|
*/
|
|
493
484
|
shippingCalculated: string;
|
|
494
485
|
total: string;
|
|
486
|
+
/** REB-837 — default copy for `notice={true}`. */
|
|
487
|
+
cancelledNotice: string;
|
|
495
488
|
}
|
|
496
489
|
interface CartSummaryProps {
|
|
497
490
|
/** Integer cents. */
|
|
@@ -506,12 +499,70 @@ interface CartSummaryProps {
|
|
|
506
499
|
shippingEnabled?: boolean;
|
|
507
500
|
/** Integer cents — the final charged amount. */
|
|
508
501
|
total: number;
|
|
502
|
+
/**
|
|
503
|
+
* REB-837 — a notice shown above the breakdown. `true` renders the
|
|
504
|
+
* default "pago cancelado" copy (`labels.cancelledNotice`) — the standard
|
|
505
|
+
* message for a visitor returning from a cancelled Stripe Checkout
|
|
506
|
+
* session (`useCheckoutReturn().status === 'cancelled'`). Pass any other
|
|
507
|
+
* `ReactNode` for custom content, or omit/`false` to render nothing.
|
|
508
|
+
*/
|
|
509
|
+
notice?: boolean | React.ReactNode;
|
|
509
510
|
labels?: Partial<CartSummaryLabels>;
|
|
510
511
|
currencyCode?: string;
|
|
511
512
|
locale?: string;
|
|
512
513
|
className?: string;
|
|
513
514
|
}
|
|
514
|
-
declare function CartSummary({ subtotal, discount, discountCode, shipping, shippingEnabled, total, labels, currencyCode, locale, className, }: CartSummaryProps): react_jsx_runtime.JSX.Element;
|
|
515
|
+
declare function CartSummary({ subtotal, discount, discountCode, shipping, shippingEnabled, total, notice, labels, currencyCode, locale, className, }: CartSummaryProps): react_jsx_runtime.JSX.Element;
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* `AddedToCartToast` — add-to-cart feedback toast CONTENT (REB-837). Pure
|
|
519
|
+
* presentational, no hooks.
|
|
520
|
+
*
|
|
521
|
+
* Deliberately does NOT import `@reblu/site-ui`'s `Toast` (the root entry):
|
|
522
|
+
* that barrel also re-exports `Button`, which this package's own
|
|
523
|
+
* `test/rsc-safety.test.ts` bans from the RSC-safe root entry (a Radix
|
|
524
|
+
* `Slot` copy whose server-evaluability depends on a CONSUMER's resolution —
|
|
525
|
+
* see that test's docblock). `Toast`'s small shell is reproduced inline here
|
|
526
|
+
* with `cn` from the certified-React-free `@reblu/site-ui/utils`, same
|
|
527
|
+
* pattern as every other organism in this file's sibling components. A SITE
|
|
528
|
+
* that wants `@reblu/site-ui`'s standalone `Toast` directly still can — the
|
|
529
|
+
* two are independent, not layered.
|
|
530
|
+
*
|
|
531
|
+
* This is the CONTENT to pass into whatever toaster the consuming SITE
|
|
532
|
+
* already mounts (sonner's `toast.custom((id) => <AddedToCartToast ... />,
|
|
533
|
+
* { id: `cart-add-${productId}` })` — a stable per-product id lets a repeat
|
|
534
|
+
* add UPDATE the same toast instead of stacking a new one). It never renders
|
|
535
|
+
* its own `aria-live` region: the host toaster's live region owns
|
|
536
|
+
* announcement, so adding a second one here would double-announce.
|
|
537
|
+
*
|
|
538
|
+
* `imageUrl` only renders a thumbnail when it's a real, non-blank string —
|
|
539
|
+
* an empty/whitespace value (a product with no image) renders no `<img>`
|
|
540
|
+
* rather than a broken one.
|
|
541
|
+
*
|
|
542
|
+
* `cartHref` is a plain `href` the consumer builds, rendered as a real
|
|
543
|
+
* `<a>` — never a `useRouter().push(...)` call, which breaks outside the
|
|
544
|
+
* Next.js App Router and in non-router test renders.
|
|
545
|
+
*/
|
|
546
|
+
type AddedToCartToastStatus = 'success' | 'error' | 'outOfStock';
|
|
547
|
+
interface AddedToCartToastLabels {
|
|
548
|
+
success: string;
|
|
549
|
+
error: string;
|
|
550
|
+
outOfStock: string;
|
|
551
|
+
viewCart: string;
|
|
552
|
+
}
|
|
553
|
+
interface AddedToCartToastProps {
|
|
554
|
+
status?: AddedToCartToastStatus;
|
|
555
|
+
productName: string;
|
|
556
|
+
/** The resulting line quantity, e.g. from `addItem`'s outcome. Only shown when > 1. */
|
|
557
|
+
quantity?: number;
|
|
558
|
+
/** Rendered as a thumbnail ONLY when non-empty after trimming. */
|
|
559
|
+
imageUrl?: string;
|
|
560
|
+
/** "Ver carrito" link target — a real href, not a router navigation. */
|
|
561
|
+
cartHref: string;
|
|
562
|
+
labels?: Partial<AddedToCartToastLabels>;
|
|
563
|
+
className?: string;
|
|
564
|
+
}
|
|
565
|
+
declare function AddedToCartToast({ status, productName, quantity, imageUrl, cartHref, labels, className, }: AddedToCartToastProps): react_jsx_runtime.JSX.Element;
|
|
515
566
|
|
|
516
567
|
/**
|
|
517
568
|
* `CheckoutLoginPrompt` — the "login prompt hook" the checkout flow needs
|
|
@@ -594,6 +645,14 @@ interface CheckoutFormProps {
|
|
|
594
645
|
contact: CheckoutContactValues;
|
|
595
646
|
onContactChange: (values: CheckoutContactValues) => void;
|
|
596
647
|
contactErrors?: CheckoutContactErrors;
|
|
648
|
+
/** Country asserted by the SITE for national phone input; omit rather than guessing. */
|
|
649
|
+
phoneRegion?: string;
|
|
650
|
+
/** Optional raw checkout API error body; only INVALID_INPUT/customerPhone marks the phone field. */
|
|
651
|
+
checkoutError?: {
|
|
652
|
+
code?: unknown;
|
|
653
|
+
error?: unknown;
|
|
654
|
+
details?: unknown;
|
|
655
|
+
} | null;
|
|
597
656
|
discountCode: string;
|
|
598
657
|
onDiscountCodeChange: (value: string) => void;
|
|
599
658
|
onApplyDiscount: () => void;
|
|
@@ -619,18 +678,23 @@ interface CheckoutFormProps {
|
|
|
619
678
|
locale?: string;
|
|
620
679
|
className?: string;
|
|
621
680
|
}
|
|
622
|
-
declare function CheckoutForm({ contact, onContactChange, contactErrors, discountCode, onDiscountCodeChange, onApplyDiscount, onRemoveDiscount, appliedDiscount, discountApplying, discountError, loginPrompt, children, submitting, submitDisabled, onSubmit, labels, currencyCode, locale, className, }: CheckoutFormProps): react_jsx_runtime.JSX.Element;
|
|
681
|
+
declare function CheckoutForm({ contact, onContactChange, contactErrors, phoneRegion, checkoutError, discountCode, onDiscountCodeChange, onApplyDiscount, onRemoveDiscount, appliedDiscount, discountApplying, discountError, loginPrompt, children, submitting, submitDisabled, onSubmit, labels, currencyCode, locale, className, }: CheckoutFormProps): react_jsx_runtime.JSX.Element;
|
|
623
682
|
|
|
624
683
|
/**
|
|
625
|
-
* `OrderConfirmation` — presentational order-confirmation view (REB-829
|
|
626
|
-
* Pure data + status in, RSC-safe (no hooks). The
|
|
627
|
-
* actual lookup/polling
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
*
|
|
684
|
+
* `OrderConfirmation` — presentational order-confirmation view (REB-829,
|
|
685
|
+
* extended REB-837). Pure data + status in, RSC-safe (no hooks). The
|
|
686
|
+
* consuming SITE owns the actual lookup/polling — today via
|
|
687
|
+
* `@reblu/site-next/shop`'s `useShopOrderStatus(sessionId)` hook — and
|
|
688
|
+
* passes the resulting `status`/`order` straight through.
|
|
689
|
+
*
|
|
690
|
+
* Backward compatible: the original three states (`polling`, `found`,
|
|
691
|
+
* `timeout`) keep their EXACT existing copy and behavior. REB-837 adds
|
|
692
|
+
* `useShopOrderStatus`'s native vocabulary (`loading`/`paid` are drop-in
|
|
693
|
+
* aliases for `polling`/`found`) plus five new terminal states with their
|
|
694
|
+
* own default Spanish copy, all overridable via `labels`.
|
|
631
695
|
*/
|
|
632
696
|
type OrderConfirmationOrder = ShopOrder;
|
|
633
|
-
type OrderConfirmationStatus = 'polling' | 'found' | 'timeout';
|
|
697
|
+
type OrderConfirmationStatus = 'polling' | 'found' | 'timeout' | 'loading' | 'paid' | 'pending_timeout' | 'failed' | 'refunded' | 'partially_refunded' | 'not_found' | 'error';
|
|
634
698
|
interface OrderConfirmationLabels {
|
|
635
699
|
pollingTitle: string;
|
|
636
700
|
pollingDescription: string;
|
|
@@ -642,17 +706,38 @@ interface OrderConfirmationLabels {
|
|
|
642
706
|
totalLabel: string;
|
|
643
707
|
confirmationEmailPrefix: string;
|
|
644
708
|
sessionReferenceLabel: string;
|
|
709
|
+
/** REB-837 */
|
|
710
|
+
failedTitle: string;
|
|
711
|
+
failedDescription: string;
|
|
712
|
+
backToCartLabel: string;
|
|
713
|
+
refundedTitle: string;
|
|
714
|
+
refundedDescription: string;
|
|
715
|
+
partiallyRefundedTitle: string;
|
|
716
|
+
partiallyRefundedDescription: string;
|
|
717
|
+
pendingTimeoutTitle: string;
|
|
718
|
+
pendingTimeoutDescription: string;
|
|
719
|
+
recheckLabel: string;
|
|
720
|
+
notFoundTitle: string;
|
|
721
|
+
notFoundDescription: string;
|
|
722
|
+
errorTitle: string;
|
|
723
|
+
errorDescription: string;
|
|
724
|
+
/** REB-837 review fix — label for the neutral order-number-only reference shown on refunded/pending_timeout. */
|
|
725
|
+
orderReferenceLabel: string;
|
|
645
726
|
}
|
|
646
727
|
interface OrderConfirmationProps {
|
|
647
728
|
status: OrderConfirmationStatus;
|
|
648
729
|
order: OrderConfirmationOrder | null;
|
|
649
|
-
/** Shown as a fallback reference when
|
|
730
|
+
/** Shown as a fallback reference when there is no order to display. */
|
|
650
731
|
sessionId?: string;
|
|
732
|
+
/** "Volver al carrito" target, shown on `status === 'failed'`. Omit to render no link. */
|
|
733
|
+
cartHref?: string;
|
|
734
|
+
/** Called by the "Volver a comprobar" button on `pending_timeout`/`error`. Omit to render no button. */
|
|
735
|
+
onRecheck?: () => void;
|
|
651
736
|
labels?: Partial<OrderConfirmationLabels>;
|
|
652
737
|
currencyCode?: string;
|
|
653
738
|
locale?: string;
|
|
654
739
|
className?: string;
|
|
655
740
|
}
|
|
656
|
-
declare function OrderConfirmation({ status, order, sessionId, labels, currencyCode, locale, className, }: OrderConfirmationProps): react_jsx_runtime.JSX.Element;
|
|
741
|
+
declare function OrderConfirmation({ status, order, sessionId, cartHref, onRecheck, labels, currencyCode, locale, className, }: OrderConfirmationProps): react_jsx_runtime.JSX.Element;
|
|
657
742
|
|
|
658
|
-
export { ALLOWED_YOUTUBE_HOSTS,
|
|
743
|
+
export { ALLOWED_YOUTUBE_HOSTS, AddedToCartToast, type AddedToCartToastLabels, type AddedToCartToastProps, type AddedToCartToastStatus, type CartLineItemView, CartLineList, type CartLineListLabels, type CartLineListProps, CartSummary, type CartSummaryLabels, type CartSummaryProps, type CheckoutAppliedDiscount, type CheckoutContactErrors, type CheckoutContactValues, CheckoutForm, type CheckoutFormLabels, type CheckoutFormProps, CheckoutLoginPrompt, type CheckoutLoginPromptLabels, type CheckoutLoginPromptProps, DEFAULT_SHOP_ERROR_FALLBACK_MESSAGE, DEFAULT_SHOP_ERROR_MESSAGES, DEFAULT_SHOP_PRICE_BANDS, MarkdownRenderer, type MarkdownRendererProps, OrderConfirmation, type OrderConfirmationLabels, type OrderConfirmationOrder, type OrderConfirmationProps, type OrderConfirmationStatus, ProductCard, type ProductCardProps, ProfileCard, type ProfileCardProps, SafeHtml, type SafeHtmlProps, type ShareUrls, type ShopFilterPriceBand, ShopFilters, type ShopFiltersActive, type ShopFiltersHrefs, type ShopFiltersLabels, type ShopFiltersProps, Specialty, type SpecialtyProps, Treatment, type TreatmentProps, buildShareUrls, formatPrice, getShopErrorMessage, isAllowedYouTubeHost, markdownToSafeHtml, readingTime, sanitizeHtml, shouldRenderShopFilters };
|