Saltar al contenido principal

<PriceChangedWarning>

Surfaced when useReservation().priceChanged is true — the server's authoritative reservation.subtotal (line items as actually held) differs from the estimate.subtotal the UI captured pre-reservation. Default UI shows the old/new totals + the delta + accept/cancel buttons. Returns null when there's nothing to warn about — safe to mount unconditionally.

Import​

import { PriceChangedWarning } from "@feelrift/react";

Basic usage​

import {
CheckoutForm,
PriceChangedWarning,
ReservationSummary,
RiftEvent,
RiftProvider,
} from "@feelrift/react";

<RiftProvider>
<RiftEvent eventId="evt_summerfest_2026">
<ReservationSummary />
<PriceChangedWarning />
<CheckoutForm returnUrl="https://your.site/checkout/return" />
</RiftEvent>
</RiftProvider>;

Props​

Accepts all HTMLAttributes<HTMLDivElement> plus:

NameTypeRequiredDefaultDescription
asChildbooleanNofalseSwap the wrapping <div> via Radix Slot.
childrenReactNodeNo—Replace the default rendering. Composed inside the wrapper.
acceptLabelReactNodeNot("reservation.priceChangedAccept")One-off label for the accept button.
cancelLabelReactNodeNot("reservation.priceChangedCancel")One-off label for the cancel button.
onAccept() => voidNo—Fires when the user accepts the new price. Consumer typically does nothing (the reservation is already at the new price).
onCancel() => voidNoclearReservation()Fires when the user cancels. Default clears the reservation; override to navigate back, etc.
classNamestringNo—Appended to the SDK's rift-price-changed-warning class.
…restHTMLAttributes<HTMLDivElement>No—Forwarded to the root element.

onAccept / onCancel​

The reservation is already at the server's new price — accepting just means the user proceeds to checkout. Cancel clears the reservation by default, which forces the user back through the picker to re-confirm intent against the new price.

<PriceChangedWarning
onAccept={() => track("price_change_accepted")}
onCancel={() => router.push("/availability")}
/>

Render output​

<div role="alert" aria-atomic="true" class="rift-price-changed-warning">
<div class="rift-price-changed-warning__title">Price has changed</div>
<div class="rift-price-changed-warning__detail">
The total updated from $40.00 to $45.00 between reservation and checkout.
<span class="rift-price-changed-warning__delta--up"> (+$5.00)</span>
</div>
<div class="rift-price-changed-warning__actions">
<button class="rift-price-changed-warning__accept">Accept new price</button>
<button class="rift-price-changed-warning__cancel">Cancel</button>
</div>
</div>

role="alert" + aria-atomic="true" so the entire region (title + detail + delta) announces as a single update on the first render where priceChanged flips to true.

Behavior​

  • Conditional render. Returns null unless useReservation().priceChanged is true AND both data and estimate are present. Safe to mount unconditionally.
  • Price comparison. Compares reservation.data.subtotal against reservation.estimate.subtotal — both are line-item totals (sum of quantity × unitPrice across reserved holds), so the warning fires only when the actual reserved line items diverge from what the picker showed. Server modifiers (fees, taxes) appear in the checkout breakdown, not here.
  • Default cancel = clear. clearReservation() removes the reservation slot from SDK state, forcing the user to restart selection. Override onCancel when "cancel" should navigate instead.

Examples​

Custom layout, default data​

<PriceChangedWarning>
<p>
The price changed. <strong>Please re-confirm</strong>.
</p>
</PriceChangedWarning>

Track delta to analytics​

function TrackedWarning() {
const { priceDelta } = useReservation();
return (
<PriceChangedWarning
onAccept={() => track("price_change_accepted", { delta: priceDelta })}
/>
);
}
  • useReservation — populates priceChanged, priceDelta, data, estimate. Public types exported from @feelrift/react.
  • <ReservationSummary> — usually rendered above this warning to show the new totals in context.
  • <CheckoutForm> — the next step after the user accepts.